private void newlineOutsideExpression()

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");
      }
    }
  }