in base/src/com/google/idea/blaze/base/lang/buildfile/lexer/BuildLexerBase.java [181:240]
private void newlineOutsideExpression() {
int oldPos = pos - 1;
if (pos > 1) { // skip over newline at start of file
addToken(TokenKind.NEWLINE, oldPos, pos);
oldPos = pos;
}
// we're in a stmt: suck up space at beginning of next line
int indentLen = 0;
while (pos < buffer.length) {
char c = buffer[pos];
if (c == ' ') {
indentLen++;
pos++;
} else if (c == '\t') {
indentLen += 8 - indentLen % 8;
pos++;
} else if (c == '\n') { // entirely blank line: ignore
indentLen = 0;
pos++;
} else if (c == '#') { // line containing only indented comment
if (oldPos != pos) {
addToken(TokenKind.WHITESPACE, oldPos, pos);
oldPos = pos;
}
while (pos < buffer.length && c != '\n') {
c = buffer[pos++];
}
addToken(TokenKind.COMMENT, oldPos, pos - 1, bufferSlice(oldPos, pos - 1));
oldPos = pos - 1;
indentLen = 0;
} else { // printing character
break;
}
}
if (oldPos != pos) {
addToken(TokenKind.WHITESPACE, oldPos, pos);
}
if (pos == buffer.length) {
indentLen = 0;
} // trailing space on last line
int peekedIndent = indentStack.peek();
if (peekedIndent < indentLen) { // push a level
indentStack.push(indentLen);
addToken(TokenKind.INDENT, pos, pos);
} else if (peekedIndent > indentLen) { // pop one or more levels
while (peekedIndent > indentLen) {
indentStack.pop();
addToken(TokenKind.DEDENT, pos, pos);
peekedIndent = indentStack.peek();
}
if (peekedIndent < indentLen) {
error("indentation error");
}
}
}