private PsiBuilder.Marker parseFunctionTypeContents() { assert _at(LPAR) : tt(); PsiBuilder.Marker functionType = mark(); // advance(); // LPAR // // int lastLPar = findLastBefore(TokenSet.create(LPAR), TokenSet.create(COLON), false); // if (lastLPar >= 0 && lastLPar > myBuilder.getCurrentOffset()) { // TODO : -1 is a hack? // createTruncatedBuilder(lastLPar - 1).parseTypeRef(); // advance(); // DOT // } parseValueParameterList(true, TokenSet.EMPTY); // if (at(COLON)) { // advance(); // COLON // expect(COLON, "Expecting ':' followed by a return type", // TYPE_REF_FIRST); expect(ARROW, "Expecting '->' to specify return type of a function type", TYPE_REF_FIRST); parseTypeRef(); // } return functionType; // .done(FUNCTION_TYPE); }
/* * class * : modifiers ("class" | "trait") SimpleName * typeParameters? * modifiers ("(" primaryConstructorParameter{","} ")")? * (":" attributes delegationSpecifier{","})? * typeConstraints * (classBody? | enumClassBody) * ; */ IElementType parseClass(boolean enumClass) { assert _atSet(CLASS_KEYWORD, TRAIT_KEYWORD); advance(); // CLASS_KEYWORD or TRAIT_KEYWORD if (!parseIdeTemplate()) { expect(IDENTIFIER, "Class name expected", CLASS_NAME_RECOVERY_SET); } boolean typeParametersDeclared = parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET); PsiBuilder.Marker beforeConstructorModifiers = mark(); boolean hasConstructorModifiers = parseModifierList(PRIMARY_CONSTRUCTOR_MODIFIER_LIST, false); // Some modifiers found, but no parentheses following: class has already ended, and we are // looking at something else if (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON)) { beforeConstructorModifiers.rollbackTo(); return CLASS; } // We are still inside a class declaration beforeConstructorModifiers.drop(); if (at(LPAR)) { parseValueParameterList(false, TokenSet.create(COLON, LBRACE)); } else if (hasConstructorModifiers) { // A comprehensive error message for cases like: // class A private : Foo // or // class A private { error("Expecting primary constructor parameter list"); } if (at(COLON)) { advance(); // COLON parseDelegationSpecifierList(); } parseTypeConstraintsGuarded(typeParametersDeclared); if (at(LBRACE)) { if (enumClass) { parseEnumClassBody(); } else { parseClassBody(); } } return CLASS; }
/* * function * : modifiers "fun" typeParameters? * (type "." | attributes)? * SimpleName * typeParameters? functionParameters (":" type)? * typeConstraints * functionBody? * ; */ IElementType parseFunction() { assert _at(FUN_KEYWORD); advance(); // FUN_KEYWORD // Recovery for the case of class A { fun| } if (at(RBRACE)) { error("Function body expected"); return FUN; } boolean typeParameterListOccurred = false; if (at(LT)) { parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, LPAR)); typeParameterListOccurred = true; } myBuilder.disableJoiningComplexTokens(); int lastDot = findLastBefore(RECEIVER_TYPE_TERMINATORS, TokenSet.create(LPAR), true); TokenSet functionNameFollow = TokenSet.create(LT, LPAR, COLON, EQ); parseReceiverType("function", functionNameFollow, lastDot); parseFunctionOrPropertyName(lastDot != -1, "function", functionNameFollow); myBuilder.restoreJoiningComplexTokensState(); TokenSet valueParametersFollow = TokenSet.create(COLON, EQ, LBRACE, SEMICOLON, RPAR); if (at(LT)) { PsiBuilder.Marker error = mark(); parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow)); errorIf( error, typeParameterListOccurred, "Only one type parameter list is allowed for a function"); typeParameterListOccurred = true; } if (at(LPAR)) { parseValueParameterList(false, valueParametersFollow); } else { error("Expecting '('"); } if (at(COLON)) { advance(); // COLON if (!parseIdeTemplate()) { parseTypeRef(); } } parseTypeConstraintsGuarded(typeParameterListOccurred); if (at(SEMICOLON)) { advance(); // SEMICOLON } else if (at(EQ) || at(LBRACE)) { parseFunctionBody(); } return FUN; }