/* * whenCondition * : expression * : ("in" | "!in") expression * : ("is" | "!is") isRHS * ; */ private void parseWhenCondition() { PsiBuilder.Marker condition = mark(); myBuilder.disableNewlines(); if (at(IN_KEYWORD) || at(NOT_IN)) { PsiBuilder.Marker mark = mark(); advance(); // IN_KEYWORD or NOT_IN mark.done(OPERATION_REFERENCE); if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) { error("Expecting an element"); } else { parseExpression(); } condition.done(WHEN_CONDITION_IN_RANGE); } else if (at(IS_KEYWORD) || at(NOT_IS)) { advance(); // IS_KEYWORD or NOT_IS if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) { error("Expecting a type"); } else { myJetParsing.parseTypeRef(); } condition.done(WHEN_CONDITION_IS_PATTERN); } else { if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) { error("Expecting an expression, is-condition or in-condition"); } else { parseExpression(); } condition.done(WHEN_CONDITION_EXPRESSION); } myBuilder.restoreNewlinesState(); }
/* * "this" ("<" type ">")? label? */ private void parseSuperExpression() { assert _at(SUPER_KEYWORD); PsiBuilder.Marker mark = mark(); PsiBuilder.Marker superReference = mark(); advance(); // SUPER_KEYWORD superReference.done(REFERENCE_EXPRESSION); if (at(LT)) { // This may be "super < foo" or "super<foo>", thus the backtracking PsiBuilder.Marker supertype = mark(); myBuilder.disableNewlines(); advance(); // LT myJetParsing.parseTypeRef(); if (at(GT)) { advance(); // GT supertype.drop(); } else { supertype.rollbackTo(); } myBuilder.restoreNewlinesState(); } parseLabelOnTheSameLine(); mark.done(SUPER_EXPRESSION); }
/* * SimpleName{,} */ private void parseFunctionLiteralShorthandParameterList() { PsiBuilder.Marker parameterList = mark(); while (!eof()) { PsiBuilder.Marker parameter = mark(); // int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new // At(IDENTIFIER), new AtOffset(doubleArrowPos))); // createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, // false); expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW)); parameter.done(VALUE_PARAMETER); if (at(COLON)) { PsiBuilder.Marker errorMarker = mark(); advance(); // COLON myJetParsing.parseTypeRef(); errorMarker.error( "To specify a type of a parameter or a return type, use the full notation: {(parameter : Type) : ReturnType -> ...}"); } else if (at(ARROW)) { break; } else if (at(COMMA)) { advance(); // COMMA } else { error("Expecting '->' or ','"); break; } } parameterList.done(VALUE_PARAMETER_LIST); }
/* * (":" type)? */ private void parseOptionalFunctionLiteralType() { if (at(COLON)) { advance(); // COLON if (at(ARROW)) { error("Expecting a type"); } else { myJetParsing.parseTypeRef(); } } }
/** * "(" (modifiers SimpleName (":" type)?){","} ")" * * @return true if at least one comma was found */ private boolean parseFunctionLiteralParameterList() { PsiBuilder.Marker list = mark(); expect(LPAR, "Expecting a parameter list in parentheses (...)", TokenSet.create(ARROW, COLON)); boolean hasComma = false; myBuilder.disableNewlines(); if (!at(RPAR)) { while (true) { if (at(COMMA)) errorAndAdvance("Expecting a parameter declaration"); PsiBuilder.Marker parameter = mark(); int parameterNamePos = matchTokenStreamPredicate( new LastBefore( new At(IDENTIFIER), new AtSet(COMMA, RPAR, COLON, ARROW, RBRACE, LBRACE))); createTruncatedBuilder(parameterNamePos) .parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS); expect(IDENTIFIER, "Expecting parameter declaration"); if (at(COLON)) { advance(); // COLON myJetParsing.parseTypeRef(); } parameter.done(VALUE_PARAMETER); if (!at(COMMA)) break; advance(); // COMMA hasComma = true; if (at(RPAR)) { error("Expecting a parameter declaration"); break; } } } myBuilder.restoreNewlinesState(); expect(RPAR, "Expecting ')'", TokenSet.create(ARROW, COLON)); list.done(VALUE_PARAMETER_LIST); return hasComma; }
/* * for * : "for" "(" annotations ("val" | "var")? (multipleVariableDeclarations | variableDeclarationEntry) "in" expression ")" expression * ; * * TODO: empty loop body (at the end of the block)? */ private void parseFor() { assert _at(FOR_KEYWORD); PsiBuilder.Marker loop = mark(); advance(); // FOR_KEYWORD if (expect(LPAR, "Expecting '(' to open a loop range", EXPRESSION_FIRST)) { myBuilder.disableNewlines(); if (!at(RPAR)) { PsiBuilder.Marker parameter = mark(); if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) advance(); // VAL_KEYWORD or VAR_KEYWORD if (at(LPAR)) { myJetParsing.parseMultiDeclarationName(TokenSet.create(IN_KEYWORD, LBRACE)); parameter.done(MULTI_VARIABLE_DECLARATION); } else { expect(IDENTIFIER, "Expecting a variable name", TokenSet.create(COLON, IN_KEYWORD)); if (at(COLON)) { advance(); // COLON myJetParsing.parseTypeRef(TokenSet.create(IN_KEYWORD)); } parameter.done(VALUE_PARAMETER); } if (expect(IN_KEYWORD, "Expecting 'in'", TokenSet.create(LPAR, LBRACE, RPAR))) { PsiBuilder.Marker range = mark(); parseExpression(); range.done(LOOP_RANGE); } } else { error("Expecting a variable name"); } expectNoAdvance(RPAR, "Expecting ')'"); myBuilder.restoreNewlinesState(); } parseControlStructureBody(); loop.done(FOR); }