@Nullable private PsiBuilder.Marker parseLambdaAfterParenth( final PsiBuilder builder, @Nullable final PsiBuilder.Marker typeList) { final boolean isLambda; final boolean isTyped; final IElementType nextToken1 = builder.lookAhead(1); final IElementType nextToken2 = builder.lookAhead(2); if (nextToken1 == JavaTokenType.RPARENTH && nextToken2 == JavaTokenType.ARROW) { isLambda = true; isTyped = false; } else if (nextToken1 == JavaTokenType.AT || ElementType.MODIFIER_BIT_SET.contains(nextToken1) || ElementType.PRIMITIVE_TYPE_BIT_SET.contains(nextToken1)) { isLambda = true; isTyped = true; } else if (nextToken1 == JavaTokenType.IDENTIFIER) { if (nextToken2 == JavaTokenType.COMMA || nextToken2 == JavaTokenType.RPARENTH && builder.lookAhead(3) == JavaTokenType.ARROW) { isLambda = true; isTyped = false; } else if (nextToken2 == JavaTokenType.ARROW) { isLambda = false; isTyped = false; } else { boolean arrow = false; final PsiBuilder.Marker marker = builder.mark(); while (!builder.eof()) { builder.advanceLexer(); final IElementType tokenType = builder.getTokenType(); if (tokenType == JavaTokenType.ARROW) { arrow = true; break; } if (tokenType == JavaTokenType.RPARENTH) { arrow = builder.lookAhead(1) == JavaTokenType.ARROW; break; } else if (tokenType == JavaTokenType.LPARENTH || tokenType == JavaTokenType.SEMICOLON || tokenType == JavaTokenType.LBRACE || tokenType == JavaTokenType.RBRACE) { break; } } marker.rollbackTo(); isLambda = arrow; isTyped = true; } } else { isLambda = false; isTyped = false; } return isLambda ? parseLambdaExpression(builder, isTyped, typeList) : null; }
@Nullable private PsiBuilder.Marker parseClassAccessOrMethodReference(final PsiBuilder builder) { final PsiBuilder.Marker expr = builder.mark(); final boolean primitive = ElementType.PRIMITIVE_TYPE_BIT_SET.contains(builder.getTokenType()); if (myParser.getReferenceParser().parseType(builder, 0) == null) { expr.drop(); return null; } final PsiBuilder.Marker result = continueClassAccessOrMethodReference(builder, expr, primitive); if (result == null) expr.rollbackTo(); return result; }
@NotNull private static PsiBuilder.Marker parseNew( final PsiBuilder builder, final PsiBuilder.Marker start) { final PsiBuilder.Marker newExpr = (start != null ? start.precede() : builder.mark()); builder.advanceLexer(); final boolean parseDiamonds = areDiamondsSupported(builder); ReferenceParser.parseReferenceParameterList(builder, false, parseDiamonds); final PsiBuilder.Marker refOrType; final boolean parseAnnotations = areTypeAnnotationsSupported(builder) && builder.getTokenType() == JavaTokenType.AT; final IElementType tokenType = builder.getTokenType(); if (tokenType == JavaTokenType.IDENTIFIER || parseAnnotations) { refOrType = ReferenceParser.parseJavaCodeReference( builder, true, true, parseAnnotations, true, parseDiamonds); if (refOrType == null) { error(builder, JavaErrorMessages.message("expected.identifier")); newExpr.done(JavaElementType.NEW_EXPRESSION); return newExpr; } } else if (ElementType.PRIMITIVE_TYPE_BIT_SET.contains(tokenType)) { refOrType = null; builder.advanceLexer(); } else { error(builder, JavaErrorMessages.message("expected.identifier")); newExpr.done(JavaElementType.NEW_EXPRESSION); return newExpr; } if (refOrType != null && builder.getTokenType() == JavaTokenType.LPARENTH) { parseArgumentList(builder); if (builder.getTokenType() == JavaTokenType.LBRACE) { final PsiBuilder.Marker classElement = refOrType.precede(); DeclarationParser.parseClassBodyWithBraces(builder, false, false); classElement.done(JavaElementType.ANONYMOUS_CLASS); } } else { if (builder.getTokenType() != JavaTokenType.LBRACKET) { error( builder, refOrType == null ? JavaErrorMessages.message("expected.lbracket") : JavaErrorMessages.message("expected.lparen.or.lbracket")); newExpr.done(JavaElementType.NEW_EXPRESSION); return newExpr; } int bracketCount = 0; int dimCount = 0; while (true) { if (builder.getTokenType() != JavaTokenType.LBRACKET) break; builder.advanceLexer(); if (bracketCount == dimCount) { final PsiBuilder.Marker dimExpr = parse(builder); if (dimExpr != null) { dimCount++; } } bracketCount++; if (!JavaParserUtil.expectOrError( builder, JavaTokenType.RBRACKET, JavaErrorMessages.message("expected.rbracket"))) { newExpr.done(JavaElementType.NEW_EXPRESSION); return newExpr; } } if (dimCount == 0) { if (builder.getTokenType() == JavaTokenType.LBRACE) { parseArrayInitializer(builder); } else { error(builder, JavaErrorMessages.message("expected.array.initializer")); } } } newExpr.done(JavaElementType.NEW_EXPRESSION); return newExpr; }
@NotNull private PsiBuilder.Marker parseNew(PsiBuilder builder, @Nullable PsiBuilder.Marker start) { PsiBuilder.Marker newExpr = (start != null ? start.precede() : builder.mark()); builder.advanceLexer(); myParser.getReferenceParser().parseReferenceParameterList(builder, false, true); PsiBuilder.Marker refOrType; PsiBuilder.Marker anno = myParser.getDeclarationParser().parseAnnotations(builder); IElementType tokenType = builder.getTokenType(); if (tokenType == JavaTokenType.IDENTIFIER) { if (anno != null) { anno.rollbackTo(); } refOrType = myParser.getReferenceParser().parseJavaCodeReference(builder, true, true, true, true); if (refOrType == null) { error(builder, JavaErrorMessages.message("expected.identifier")); newExpr.done(JavaElementType.NEW_EXPRESSION); return newExpr; } } else if (ElementType.PRIMITIVE_TYPE_BIT_SET.contains(tokenType)) { refOrType = null; builder.advanceLexer(); } else { error(builder, JavaErrorMessages.message("expected.identifier")); newExpr.done(JavaElementType.NEW_EXPRESSION); return newExpr; } if (refOrType != null && builder.getTokenType() == JavaTokenType.LPARENTH) { parseArgumentList(builder); if (builder.getTokenType() == JavaTokenType.LBRACE) { final PsiBuilder.Marker classElement = refOrType.precede(); myParser.getDeclarationParser().parseClassBodyWithBraces(builder, false, false); classElement.done(JavaElementType.ANONYMOUS_CLASS); } newExpr.done(JavaElementType.NEW_EXPRESSION); return newExpr; } myParser.getDeclarationParser().parseAnnotations(builder); if (builder.getTokenType() != JavaTokenType.LBRACKET) { error( builder, refOrType == null ? JavaErrorMessages.message("expected.lbracket") : JavaErrorMessages.message("expected.lparen.or.lbracket")); newExpr.done(JavaElementType.NEW_EXPRESSION); return newExpr; } int bracketCount = 0; int dimCount = 0; while (true) { myParser.getDeclarationParser().parseAnnotations(builder); if (builder.getTokenType() != JavaTokenType.LBRACKET) break; builder.advanceLexer(); if (bracketCount == dimCount) { final PsiBuilder.Marker dimExpr = parse(builder); if (dimExpr != null) { dimCount++; } } bracketCount++; if (!expectOrError(builder, JavaTokenType.RBRACKET, "expected.rbracket")) { newExpr.done(JavaElementType.NEW_EXPRESSION); return newExpr; } } if (dimCount == 0) { if (builder.getTokenType() == JavaTokenType.LBRACE) { parseArrayInitializer(builder); } else { error(builder, JavaErrorMessages.message("expected.array.initializer")); } } newExpr.done(JavaElementType.NEW_EXPRESSION); return newExpr; }
@Nullable private static PsiBuilder.Marker parsePrimaryExpressionStart(final PsiBuilder builder) { IElementType tokenType = builder.getTokenType(); if (LITERALS.contains(tokenType)) { final PsiBuilder.Marker literal = builder.mark(); builder.advanceLexer(); literal.done(JavaElementType.LITERAL_EXPRESSION); return literal; } if (tokenType == JavaTokenType.LPARENTH) { final PsiBuilder.Marker parenth = builder.mark(); builder.advanceLexer(); final PsiBuilder.Marker inner = parse(builder); if (inner == null) { error(builder, JavaErrorMessages.message("expected.expression")); } if (!expect(builder, JavaTokenType.RPARENTH)) { if (inner != null) { error(builder, JavaErrorMessages.message("expected.rparen")); } } parenth.done(JavaElementType.PARENTH_EXPRESSION); return parenth; } if (tokenType == JavaTokenType.LBRACE) { return parseArrayInitializer(builder); } PsiBuilder.Marker annotation = null; final PsiBuilder.Marker beforeAnnotation = builder.mark(); if (tokenType == JavaTokenType.AT) { annotation = DeclarationParser.parseAnnotations(builder); tokenType = builder.getTokenType(); } if (tokenType == JavaTokenType.IDENTIFIER) { final PsiBuilder.Marker refExpr; if (annotation != null) { final PsiBuilder.Marker refParam = annotation.precede(); refParam.doneBefore(JavaElementType.REFERENCE_PARAMETER_LIST, annotation); refExpr = refParam.precede(); } else { refExpr = builder.mark(); builder.mark().done(JavaElementType.REFERENCE_PARAMETER_LIST); } builder.advanceLexer(); refExpr.done(JavaElementType.REFERENCE_EXPRESSION); beforeAnnotation.drop(); return refExpr; } if (annotation != null) { beforeAnnotation.rollbackTo(); tokenType = builder.getTokenType(); } else { beforeAnnotation.drop(); } PsiBuilder.Marker expr = null; if (tokenType == JavaTokenType.LT) { expr = builder.mark(); if (!ReferenceParser.parseReferenceParameterList(builder, false, false)) { expr.rollbackTo(); return null; } tokenType = builder.getTokenType(); if (!CONSTRUCTOR_CALL.contains(tokenType)) { expr.rollbackTo(); return null; } } if (CONSTRUCTOR_CALL.contains(tokenType)) { if (expr == null) { expr = builder.mark(); builder.mark().done(JavaElementType.REFERENCE_PARAMETER_LIST); } builder.advanceLexer(); expr.done( builder.getTokenType() == JavaTokenType.LPARENTH ? JavaElementType.REFERENCE_EXPRESSION : tokenType == JavaTokenType.THIS_KEYWORD ? JavaElementType.THIS_EXPRESSION : JavaElementType.SUPER_EXPRESSION); return expr; } if (tokenType == JavaTokenType.NEW_KEYWORD) { return parseNew(builder, null); } if (ElementType.PRIMITIVE_TYPE_BIT_SET.contains(tokenType)) { return parseClassObjectAccess(builder); } return null; }