/* * initializer * : attributes "this" valueArguments * : attributes constructorInvocation // type parameters may (must?) be omitted * ; */ private void parseInitializer() { PsiBuilder.Marker initializer = mark(); parseAnnotations(false); IElementType type; if (at(THIS_KEYWORD)) { PsiBuilder.Marker mark = mark(); advance(); // THIS_KEYWORD mark.done(THIS_CONSTRUCTOR_REFERENCE); type = THIS_CALL; } else if (atSet(TYPE_REF_FIRST)) { PsiBuilder.Marker reference = mark(); parseTypeRef(); reference.done(CONSTRUCTOR_CALLEE); type = DELEGATOR_SUPER_CALL; } else { errorWithRecovery( "Expecting constructor call (this(...)) or supertype initializer", TokenSet.create(LBRACE, COMMA)); initializer.drop(); return; } myExpressionParsing.parseValueArgumentList(); initializer.done(type); }
/* * typeConstraint * : attributes SimpleName ":" type * : attributes "class" "object" SimpleName ":" type * ; */ private void parseTypeConstraint() { PsiBuilder.Marker constraint = mark(); parseAnnotations(false); if (at(CLASS_KEYWORD)) { advance(); // CLASS_KEYWORD expect(OBJECT_KEYWORD, "Expecting 'object'", TYPE_REF_FIRST); } PsiBuilder.Marker reference = mark(); if (expect( IDENTIFIER, "Expecting type parameter name", TokenSet.orSet(TokenSet.create(COLON, COMMA), TYPE_REF_FIRST))) { reference.done(REFERENCE_EXPRESSION); } else { reference.drop(); } expect(COLON, "Expecting ':' before the upper bound", TYPE_REF_FIRST); parseTypeRef(); constraint.done(TYPE_CONSTRAINT); }
/* * (type "." | attributes)? */ private void parseReceiverType(String title, TokenSet nameFollow, int lastDot) { if (lastDot == -1) { // There's no explicit receiver type specified parseAnnotations(false); } else { if (parseIdeTemplate()) { expect(DOT, "Expecting '.' after receiver template"); } else { createTruncatedBuilder(lastDot).parseTypeRef(); if (atSet(RECEIVER_TYPE_TERMINATORS)) { advance(); // expectation } else { errorWithRecovery("Expecting '.' before a " + title + " name", nameFollow); } } } }
/* * attributes delegationSpecifier * * delegationSpecifier * : constructorInvocation // type and constructor arguments * : userType * : explicitDelegation * ; * * explicitDelegation * : userType "by" element * ; */ private void parseDelegationSpecifier() { PsiBuilder.Marker delegator = mark(); parseAnnotations(false); PsiBuilder.Marker reference = mark(); parseTypeRef(); if (at(BY_KEYWORD)) { reference.drop(); advance(); // BY_KEYWORD createForByClause(myBuilder).myExpressionParsing.parseExpression(); delegator.done(DELEGATOR_BY); } else if (at(LPAR)) { reference.done(CONSTRUCTOR_CALLEE); myExpressionParsing.parseValueArgumentList(); delegator.done(DELEGATOR_SUPER_CALL); } else { reference.drop(); delegator.done(DELEGATOR_SUPER_CLASS); } }
// The extraRecoverySet is needed for the foo(bar<x, 1, y>(z)) case, to tell whether we should // stop // on expression-indicating symbols or not private PsiBuilder.Marker parseTypeRefContents(TokenSet extraRecoverySet) { // Disabling token merge is required for cases like // Int?.(Foo) -> Bar // we don't support this case now // myBuilder.disableJoiningComplexTokens(); PsiBuilder.Marker typeRefMarker = mark(); parseAnnotations(false); if (at(IDENTIFIER) || at(PACKAGE_KEYWORD)) { parseUserType(); } else if (at(HASH)) { parseTupleType(); } else if (at(LPAR)) { PsiBuilder.Marker functionOrParenthesizedType = mark(); // This may be a function parameter list or just a prenthesized type advance(); // LPAR parseTypeRefContents(TokenSet.EMPTY) .drop(); // parenthesized types, no reference element around it is needed if (at(RPAR)) { advance(); // RPAR if (at(ARROW)) { // It's a function type with one parameter specified // (A) -> B functionOrParenthesizedType.rollbackTo(); parseFunctionType(); } else { // It's a parenthesized type // (A) functionOrParenthesizedType.drop(); } } else { // This must be a function type // (A, B) -> C // or // (a : A) -> C functionOrParenthesizedType.rollbackTo(); parseFunctionType(); } } else if (at(CAPITALIZED_THIS_KEYWORD)) { parseSelfType(); } else { errorWithRecovery( "Type expected", TokenSet.orSet( TOPLEVEL_OBJECT_FIRST, TokenSet.create(EQ, COMMA, GT, RBRACKET, DOT, RPAR, RBRACE, LBRACE, SEMICOLON), extraRecoverySet)); } while (at(QUEST)) { PsiBuilder.Marker precede = typeRefMarker.precede(); advance(); // QUEST typeRefMarker.done(NULLABLE_TYPE); typeRefMarker = precede; } if (at(DOT)) { // This is a receiver for a function type // A.(B) -> C // ^ PsiBuilder.Marker functionType = typeRefMarker.precede(); PsiBuilder.Marker receiverType = typeRefMarker.precede(); typeRefMarker.done(TYPE_REFERENCE); receiverType.done(FUNCTION_TYPE_RECEIVER); advance(); // DOT if (at(LPAR)) { parseFunctionTypeContents().drop(); } else { error("Expecting function type"); } typeRefMarker = functionType.precede(); functionType.done(FUNCTION_TYPE); } // myBuilder.restoreJoiningComplexTokensState(); return typeRefMarker; }