Java: parse parentheses with a call with lambda argument correctly (IDEA-200212)

GitOrigin-RevId: 98fcbb3b793ebfcfa636ac7d27ef21158c64eee7
This commit is contained in:
Bas Leijdekkers
2024-08-03 15:48:09 +02:00
committed by intellij-monorepo-bot
parent 32fde2980c
commit d335ac32c4
6 changed files with 404 additions and 65 deletions

View File

@@ -916,14 +916,12 @@ public class BasicOldExpressionParser {
PsiBuilder.Marker marker = builder.mark();
builder.advanceLexer();
BasicReferenceParser.TypeInfo typeInfo = myParser.getReferenceParser().parseTypeInfo(
builder, BasicReferenceParser.EAT_LAST_DOT | BasicReferenceParser.ELLIPSIS | BasicReferenceParser.WILDCARD);
builder, BasicReferenceParser.ELLIPSIS | BasicReferenceParser.WILDCARD);
if (typeInfo != null) {
IElementType t = builder.getTokenType();
if (t == JavaTokenType.IDENTIFIER ||
t == JavaTokenType.THIS_KEYWORD ||
t == JavaTokenType.RPARENTH && builder.lookAhead(1) == JavaTokenType.ARROW) {
lambda = true;
}
lambda = t == JavaTokenType.IDENTIFIER ||
t == JavaTokenType.THIS_KEYWORD ||
t == JavaTokenType.RPARENTH && builder.lookAhead(1) == JavaTokenType.ARROW;
}
marker.rollbackTo();

View File

@@ -821,14 +821,12 @@ public class BasicPrattExpressionParser {
PsiBuilder.Marker marker = builder.mark();
builder.advanceLexer();
BasicReferenceParser.TypeInfo typeInfo = myParser.getReferenceParser().parseTypeInfo(
builder, BasicReferenceParser.EAT_LAST_DOT | BasicReferenceParser.ELLIPSIS | BasicReferenceParser.WILDCARD);
builder, BasicReferenceParser.ELLIPSIS | BasicReferenceParser.WILDCARD);
if (typeInfo != null) {
IElementType t = builder.getTokenType();
if (t == JavaTokenType.IDENTIFIER ||
t == JavaTokenType.THIS_KEYWORD ||
t == JavaTokenType.RPARENTH && builder.lookAhead(1) == JavaTokenType.ARROW) {
lambda = true;
}
lambda = t == JavaTokenType.IDENTIFIER ||
t == JavaTokenType.THIS_KEYWORD ||
t == JavaTokenType.RPARENTH && builder.lookAhead(1) == JavaTokenType.ARROW;
}
marker.rollbackTo();

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.parser;
import org.jetbrains.annotations.NotNull;
@@ -9,146 +9,95 @@ public abstract class AbstractBasicExpressionParsingTest extends AbstractBasicJa
}
public void testAssignment0() { doTest(true); }
public void testAssignment1() { doTest(true); }
public void testCond0() { doTest(true); }
public void testCond1() { doTest(true); }
public void testCond2() { doTest(true); }
public void testCond3() { doTest(true); }
public void testCondOr0() { doTest(true); }
public void testCondOr1() { doTest(true); }
public void testCondAnd0() { doTest(true); }
public void testCondAnd1() { doTest(true); }
public void testOr0() { doTest(true); }
public void testOr1() { doTest(true); }
public void testXor0() { doTest(true); }
public void testXor1() { doTest(true); }
public void testAnd0() { doTest(true); }
public void testAnd1() { doTest(true); }
public void testInstanceOf0() { doTest(true); }
public void testInstanceOf1() { doTest(true); }
public void testNot0() { doTest(true); }
public void testNot1() { doTest(true); }
public void testCast0() { doTest(true); }
public void testParenth() { doTest(true); }
public void testParenth1() { doTest(true); }
public void testNewInExprList() { doTest(true); }
public void testNew0() { doTest(true); }
public void testNew1() { doTest(true); }
public void testNew2() { doTest(true); }
public void testNew3() { doTest(true); }
public void testNew4() { doTest(true); }
public void testNew5() { doTest(true); }
public void testNew6() { doTest(true); }
public void testNew7() { doTest(true); }
public void testNew8() { doTest(true); }
public void testNew9() { doTest(true); }
public void testNew10() { doTest(true); }
public void testNew11() { doTest(true); }
public void testNew12() { doTest(true); }
public void testNew13() { doTest(true); }
public void testNew14() { doTest(true); }
public void testNew15() { doTest(true); }
public void testExprList0() { doTest(true); }
public void testExprList1() { doTest(true); }
public void testExprList2() { doTest(true); }
public void testExprList3() { doTest(true); }
public void testExprList4() { doTest(true); }
public void testExprList5() { doTest(true); }
public void testExprList6() { doTest(true); }
public void testArrayInitializer0() { doTest(true); }
public void testArrayInitializer1() { doTest(true); }
public void testArrayInitializer2() { doTest(true); }
public void testArrayInitializer3() { doTest(true); }
public void testArrayInitializer4() { doTest(true); }
public void testArrayInitializer5() { doTest(true); }
public void testArrayInitializer6() { doTest(true); }
public void testArrayInitializer7() { doTest(true); }
public void testPinesInReferenceExpression0() { doTest(true); }
public void testPinesInReferenceExpression1() { doTest(true); }
public void testGE() { doTest(true); }
public void testIncompleteCast() { doTest(true); }
public void testShiftRight() { doTest(true); }
public void testAnonymousErrors() { doTest(true); }
public void testAnonymousErrors1() { doTest(true); }
public void testAnonymousWithTypeParams() { doTest(true); }
public void testAnonymous2() { doTest(true); }
public void testIncompleteDecl() { doTest(true); }
public void testLambdaConfusion() { doTest(true); }
public void testIllegalWildcard() { doTest(true); }
public void testQualifiedSuperMethodCall() { doTest(true); }
public void testQualifiedSuperMethodCall1() { doTest(true); }
public void testSuperMethodCallTypeParameterList() { doTest(true); }
public void testPrimitiveClassObjectAccess() { doTest(true); }
public void testPrimitiveClassObjectAccessError() { doTest(true); }
public void testPrimitiveArrayClassObjectAccessError() { doTest(true); }
}

View File

@@ -0,0 +1,16 @@
class X {
private int foo(Runnable r) {
return 1;
}
public int boo(int a) {
return a;
}
public class Inner {
public void run() {
int a = ((X.this.boo(foo(() -> {
}))));
}
}
}

View File

@@ -0,0 +1,191 @@
PsiJavaFile:LambdaConfusion.java
PsiImportList
<empty list>
PsiClass:X
PsiModifierList:
<empty list>
PsiKeyword:class('class')
PsiWhiteSpace(' ')
PsiIdentifier:X('X')
PsiTypeParameterList
<empty list>
PsiReferenceList
<empty list>
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:LBRACE('{')
PsiWhiteSpace('\n ')
PsiMethod:foo
PsiModifierList:private
PsiKeyword:private('private')
PsiTypeParameterList
<empty list>
PsiWhiteSpace(' ')
PsiTypeElement:int
PsiKeyword:int('int')
PsiWhiteSpace(' ')
PsiIdentifier:foo('foo')
PsiParameterList:(Runnable r)
PsiJavaToken:LPARENTH('(')
PsiParameter:r
PsiModifierList:
<empty list>
PsiTypeElement:Runnable
PsiJavaCodeReferenceElement:Runnable
PsiIdentifier:Runnable('Runnable')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:r('r')
PsiJavaToken:RPARENTH(')')
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiCodeBlock
PsiJavaToken:LBRACE('{')
PsiWhiteSpace('\n ')
PsiReturnStatement
PsiKeyword:return('return')
PsiWhiteSpace(' ')
PsiLiteralExpression:1
PsiJavaToken:INTEGER_LITERAL('1')
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace('\n ')
PsiJavaToken:RBRACE('}')
PsiWhiteSpace('\n\n ')
PsiMethod:boo
PsiModifierList:public
PsiKeyword:public('public')
PsiTypeParameterList
<empty list>
PsiWhiteSpace(' ')
PsiTypeElement:int
PsiKeyword:int('int')
PsiWhiteSpace(' ')
PsiIdentifier:boo('boo')
PsiParameterList:(int a)
PsiJavaToken:LPARENTH('(')
PsiParameter:a
PsiModifierList:
<empty list>
PsiTypeElement:int
PsiKeyword:int('int')
PsiWhiteSpace(' ')
PsiIdentifier:a('a')
PsiJavaToken:RPARENTH(')')
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiCodeBlock
PsiJavaToken:LBRACE('{')
PsiWhiteSpace('\n ')
PsiReturnStatement
PsiKeyword:return('return')
PsiWhiteSpace(' ')
PsiReferenceExpression:a
PsiReferenceParameterList
<empty list>
PsiIdentifier:a('a')
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace('\n ')
PsiJavaToken:RBRACE('}')
PsiWhiteSpace('\n\n ')
PsiClass:Inner
PsiModifierList:public
PsiKeyword:public('public')
PsiWhiteSpace(' ')
PsiKeyword:class('class')
PsiWhiteSpace(' ')
PsiIdentifier:Inner('Inner')
PsiTypeParameterList
<empty list>
PsiReferenceList
<empty list>
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:LBRACE('{')
PsiWhiteSpace('\n ')
PsiMethod:run
PsiModifierList:public
PsiKeyword:public('public')
PsiTypeParameterList
<empty list>
PsiWhiteSpace(' ')
PsiTypeElement:void
PsiKeyword:void('void')
PsiWhiteSpace(' ')
PsiIdentifier:run('run')
PsiParameterList:()
PsiJavaToken:LPARENTH('(')
PsiJavaToken:RPARENTH(')')
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiCodeBlock
PsiJavaToken:LBRACE('{')
PsiWhiteSpace('\n ')
PsiDeclarationStatement
PsiLocalVariable:a
PsiModifierList:
<empty list>
PsiTypeElement:int
PsiKeyword:int('int')
PsiWhiteSpace(' ')
PsiIdentifier:a('a')
PsiWhiteSpace(' ')
PsiJavaToken:EQ('=')
PsiWhiteSpace(' ')
PsiParenthesizedExpression:((X.this.boo(foo(() -> {
}))))
PsiJavaToken:LPARENTH('(')
PsiParenthesizedExpression:(X.this.boo(foo(() -> {
})))
PsiJavaToken:LPARENTH('(')
PsiMethodCallExpression:X.this.boo(foo(() -> {
}))
PsiReferenceExpression:X.this.boo
PsiThisExpression:X.this
PsiJavaCodeReferenceElement:X
PsiIdentifier:X('X')
PsiReferenceParameterList
<empty list>
PsiJavaToken:DOT('.')
PsiKeyword:this('this')
PsiJavaToken:DOT('.')
PsiReferenceParameterList
<empty list>
PsiIdentifier:boo('boo')
PsiExpressionList
PsiJavaToken:LPARENTH('(')
PsiMethodCallExpression:foo(() -> {
})
PsiReferenceExpression:foo
PsiReferenceParameterList
<empty list>
PsiIdentifier:foo('foo')
PsiExpressionList
PsiJavaToken:LPARENTH('(')
PsiLambdaExpression
PsiParameterList:()
PsiJavaToken:LPARENTH('(')
PsiJavaToken:RPARENTH(')')
PsiWhiteSpace(' ')
PsiJavaToken:ARROW('->')
PsiWhiteSpace(' ')
PsiCodeBlock
PsiJavaToken:LBRACE('{')
PsiWhiteSpace('\n ')
PsiJavaToken:RBRACE('}')
PsiJavaToken:RPARENTH(')')
PsiJavaToken:RPARENTH(')')
PsiJavaToken:RPARENTH(')')
PsiJavaToken:RPARENTH(')')
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace('\n ')
PsiJavaToken:RBRACE('}')
PsiWhiteSpace('\n ')
PsiJavaToken:RBRACE('}')
PsiWhiteSpace('\n')
PsiJavaToken:RBRACE('}')

View File

@@ -0,0 +1,187 @@
java.FILE
IMPORT_LIST
<empty list>
CLASS
MODIFIER_LIST
<empty list>
CLASS_KEYWORD
WHITE_SPACE
IDENTIFIER
TYPE_PARAMETER_LIST
<empty list>
EXTENDS_LIST
<empty list>
IMPLEMENTS_LIST
<empty list>
WHITE_SPACE
LBRACE
WHITE_SPACE
METHOD
MODIFIER_LIST
PRIVATE_KEYWORD
TYPE_PARAMETER_LIST
<empty list>
WHITE_SPACE
TYPE
INT_KEYWORD
WHITE_SPACE
IDENTIFIER
PARAMETER_LIST
LPARENTH
PARAMETER
MODIFIER_LIST
<empty list>
TYPE
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
WHITE_SPACE
IDENTIFIER
RPARENTH
THROWS_LIST
<empty list>
WHITE_SPACE
CODE_BLOCK
LBRACE
WHITE_SPACE
RETURN_STATEMENT
RETURN_KEYWORD
WHITE_SPACE
LITERAL_EXPRESSION
INTEGER_LITERAL
SEMICOLON
WHITE_SPACE
RBRACE
WHITE_SPACE
METHOD
MODIFIER_LIST
PUBLIC_KEYWORD
TYPE_PARAMETER_LIST
<empty list>
WHITE_SPACE
TYPE
INT_KEYWORD
WHITE_SPACE
IDENTIFIER
PARAMETER_LIST
LPARENTH
PARAMETER
MODIFIER_LIST
<empty list>
TYPE
INT_KEYWORD
WHITE_SPACE
IDENTIFIER
RPARENTH
THROWS_LIST
<empty list>
WHITE_SPACE
CODE_BLOCK
LBRACE
WHITE_SPACE
RETURN_STATEMENT
RETURN_KEYWORD
WHITE_SPACE
REFERENCE_EXPRESSION
REFERENCE_PARAMETER_LIST
<empty list>
IDENTIFIER
SEMICOLON
WHITE_SPACE
RBRACE
WHITE_SPACE
CLASS
MODIFIER_LIST
PUBLIC_KEYWORD
WHITE_SPACE
CLASS_KEYWORD
WHITE_SPACE
IDENTIFIER
TYPE_PARAMETER_LIST
<empty list>
EXTENDS_LIST
<empty list>
IMPLEMENTS_LIST
<empty list>
WHITE_SPACE
LBRACE
WHITE_SPACE
METHOD
MODIFIER_LIST
PUBLIC_KEYWORD
TYPE_PARAMETER_LIST
<empty list>
WHITE_SPACE
TYPE
VOID_KEYWORD
WHITE_SPACE
IDENTIFIER
PARAMETER_LIST
LPARENTH
RPARENTH
THROWS_LIST
<empty list>
WHITE_SPACE
CODE_BLOCK
LBRACE
WHITE_SPACE
DECLARATION_STATEMENT
LOCAL_VARIABLE
MODIFIER_LIST
<empty list>
TYPE
INT_KEYWORD
WHITE_SPACE
IDENTIFIER
WHITE_SPACE
EQ
WHITE_SPACE
PARENTH_EXPRESSION
LPARENTH
PARENTH_EXPRESSION
LPARENTH
METHOD_CALL_EXPRESSION
REFERENCE_EXPRESSION
THIS_EXPRESSION
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
DOT
THIS_KEYWORD
DOT
REFERENCE_PARAMETER_LIST
<empty list>
IDENTIFIER
EXPRESSION_LIST
LPARENTH
METHOD_CALL_EXPRESSION
REFERENCE_EXPRESSION
REFERENCE_PARAMETER_LIST
<empty list>
IDENTIFIER
EXPRESSION_LIST
LPARENTH
LAMBDA_EXPRESSION
PARAMETER_LIST
LPARENTH
RPARENTH
WHITE_SPACE
ARROW
WHITE_SPACE
CODE_BLOCK
LBRACE
WHITE_SPACE
RBRACE
RPARENTH
RPARENTH
RPARENTH
RPARENTH
SEMICOLON
WHITE_SPACE
RBRACE
WHITE_SPACE
RBRACE
WHITE_SPACE
RBRACE