fun parseStatementBase()

in flex/src/com/intellij/lang/actionscript/parsing/ActionScriptStatementParser.kt [24:205]


  fun parseStatementBase() {
    val startOffset = builder.currentOffset
    val firstToken = builder.tokenType

    if (firstToken == null) {
      builder.error(message("javascript.parser.message.expected.statement"))
      return
    }

    if (firstToken === JSTokenTypes.LBRACE) {
      parseBlock()
      return
    }

    if (firstToken === JSTokenTypes.SEMICOLON) {
      parseEmptyStatement()
      return
    }

    if (firstToken === JSTokenTypes.IF_KEYWORD) {
      parseIfStatement()
      return
    }

    if (firstToken === JSTokenTypes.DO_KEYWORD
        || firstToken === JSTokenTypes.WHILE_KEYWORD
        || firstToken === JSTokenTypes.FOR_KEYWORD
    ) {
      parseIterationStatement()
      return
    }

    if (firstToken === JSTokenTypes.CONTINUE_KEYWORD) {
      parseContinueStatement()
      return
    }

    if (firstToken === JSTokenTypes.BREAK_KEYWORD) {
      parseBreakStatement()
      return
    }

    if (firstToken === JSTokenTypes.RETURN_KEYWORD) {
      parseReturnStatement()
      return
    }

    if (firstToken === JSTokenTypes.WITH_KEYWORD) {
      parseWithStatement()
      return
    }

    if (firstToken === JSTokenTypes.SWITCH_KEYWORD) {
      parseSwitchStatement()
      return
    }

    if (firstToken === JSTokenTypes.THROW_KEYWORD) {
      parseThrowStatement()
      return
    }

    if (firstToken === JSTokenTypes.TRY_KEYWORD) {
      parseTryStatement()
      return
    }

    if (firstToken === JSTokenTypes.DEBUGGER_KEYWORD) {
      val stmt = builder.mark()
      builder.advanceLexer()
      forceCheckForSemicolon()
      stmt.done(JSElementTypes.DEBUGGER_STATEMENT)
      return
    }

    val functionParser = parser.functionParser
    if ((JSTokenTypes.IDENTIFIER === firstToken
         || isPossibleStartStatementModifier(firstToken)
         || JSTokenTypes.LBRACKET === firstToken
        )
    ) {
      do {
        val marker = builder.mark()
        val methodEmptiness = builder.getUserData(ActionScriptFunctionParser.methodsEmptinessKey)
        if (!functionParser.parseAttributesList()) {
          marker.rollbackTo() // lbracket might be array literal!
          break
        }

        try {
          if (builder.eof()) {
            marker.drop()
            return
          }

          val tokenType = builder.tokenType
          if (tokenType === JSTokenTypes.FUNCTION_KEYWORD) {
            functionParser.parseFunctionNoMarker(ActionScriptFunctionParser.Context.SOURCE_ELEMENT, marker)
            return
          }
          else if (JSTokenTypes.VAR_MODIFIERS_WITHOUT_USING.contains(tokenType)) {
            parseVarStatementNoMarker(false, marker)
            return
          }
          else if (parseDialectSpecificSourceElements(marker)) {
            return
          }
          else if (tokenType === JSTokenTypes.CLASS_KEYWORD || tokenType === JSTokenTypes.INTERFACE_KEYWORD) {
            parseClassOrInterfaceNoMarker(marker)
            return
          }
          else {
            builder.putUserData(ActionScriptFunctionParser.methodsEmptinessKey, null)

            if (firstToken === JSTokenTypes.IDENTIFIER) {
              marker.rollbackTo()
            }
            else if (JSTokenTypes.COLON_COLON === builder.tokenType) {
              marker.rollbackTo()
              if (parseExpressionStatement()) return
            }
            else {
              builder.error(message("javascript.parser.message.expected.declaration"))
              marker.drop()
            }
          }
        }
        finally {
          builder.putUserData(ActionScriptFunctionParser.methodsEmptinessKey, methodEmptiness)
        }
      }
      while (false)
    }
    else if (firstToken === JSTokenTypes.CLASS_KEYWORD || firstToken === JSTokenTypes.INTERFACE_KEYWORD) {
      val marker = startAttributeListOwner()
      parseClassOrInterfaceNoMarker(marker)
      return
    }
    else if (JSTokenTypes.VAR_MODIFIERS_WITHOUT_USING.contains(firstToken)) {
      val marker = startAttributeListOwner()
      parseVarStatementNoMarker(false, marker)
      return
    }
    else if (firstToken === JSTokenTypes.FUNCTION_KEYWORD) {
      val marker = startAttributeListOwner()
      functionParser.parseFunctionNoMarker(ActionScriptFunctionParser.Context.SOURCE_ELEMENT, marker)
      return
    }

    if (builder.tokenType === JSTokenTypes.FUNCTION_KEYWORD) {
      functionParser.parseFunctionDeclaration()
      return
    }

    if (isIdentifierToken(firstToken)) {
      // Try labeled statement:
      val labeledStatement = builder.mark()
      builder.advanceLexer()
      if (builder.tokenType === JSTokenTypes.COLON) {
        builder.advanceLexer()
        parseStatement()
        labeledStatement.done(JSElementTypes.LABELED_STATEMENT)
        return
      }
      else {
        labeledStatement.rollbackTo()
      }
    }

    if (firstToken !== JSTokenTypes.FUNCTION_KEYWORD) {
      if (parseExpressionStatement()) return
    }

    builder.error(message("javascript.parser.message.expected.statement"))
    if (builder.currentOffset == startOffset
        // We don't want to eat dangling right brace if we are within a block.
        // Braces has already been counted and should match.
        && (builder.tokenType !== JSTokenTypes.RBRACE || builder.getUserData(IS_BLOCK_BODY_CONTEXT) == null)
    ) {
      builder.advanceLexer()
    }
  }