IDEA-384571 [java-psi] 'value' is parsed as keyword inside lambda parameters

GitOrigin-RevId: ffde5f942ff03a1e9eed6d78b82c8374b02a9936
This commit is contained in:
Tagir Valeev
2026-01-14 09:55:44 +00:00
committed by intellij-monorepo-bot
parent 6a2b91c1bc
commit e63a99fef1
6 changed files with 429 additions and 3 deletions
@@ -81,6 +81,7 @@ public abstract class AbstractBasicClassParsingTest extends AbstractBasicJavaPar
}
public void testValueClass() { doTest(true); }
public void testNoSoftKeywordInLambdaParameters() { doTest(true); }
public void testSealedInterface() { doTest(true); }
public void testSealedClassOldLanguageLevel() {
@@ -43,6 +43,11 @@ object SyntaxElementTypes {
JToken.VOLATILE_KEYWORD, JToken.DEFAULT_KEYWORD, JToken.SEALED_KEYWORD, JToken.NON_SEALED_KEYWORD, JToken.VALUE_KEYWORD
)
// While only 'final' modifier is acceptable in the (method or lambda) parameter modifier list, we still parse any modifier,
// except the soft ones, as they should be parsed as variable name in lambda parameter list.
val PARAMETER_MODIFIER_BIT_SET: SyntaxElementTypeSet =
MODIFIER_BIT_SET - setOf(JToken.SEALED_KEYWORD, JToken.NON_SEALED_KEYWORD, JToken.VALUE_KEYWORD)
val PRIMITIVE_TYPE_BIT_SET: SyntaxElementTypeSet = syntaxElementTypeSetOf(
JToken.BOOLEAN_KEYWORD, JToken.BYTE_KEYWORD, JToken.SHORT_KEYWORD, JToken.INT_KEYWORD, JToken.LONG_KEYWORD, JToken.CHAR_KEYWORD,
JToken.FLOAT_KEYWORD, JToken.DOUBLE_KEYWORD, JToken.VOID_KEYWORD
@@ -8,6 +8,7 @@ import com.intellij.java.syntax.element.JavaSyntaxTokenType
import com.intellij.java.syntax.element.SyntaxElementTypes.CLASS_KEYWORD_BIT_SET
import com.intellij.java.syntax.element.SyntaxElementTypes.KEYWORD_BIT_SET
import com.intellij.java.syntax.element.SyntaxElementTypes.MODIFIER_BIT_SET
import com.intellij.java.syntax.element.SyntaxElementTypes.PARAMETER_MODIFIER_BIT_SET
import com.intellij.java.syntax.element.SyntaxElementTypes.PRIMITIVE_TYPE_BIT_SET
import com.intellij.platform.syntax.SyntaxElementType
import com.intellij.platform.syntax.SyntaxElementTypeSet
@@ -423,11 +424,11 @@ open class DeclarationParser(private val myParser: JavaParser) {
while (true) {
var tokenType = builder.tokenType ?: break
if (isValueToken(builder, tokenType)) {
if (isValueToken(builder, tokenType) && modifiers.contains(JavaSyntaxTokenType.VALUE_KEYWORD)) {
builder.remapCurrentToken(JavaSyntaxTokenType.VALUE_KEYWORD)
tokenType = JavaSyntaxTokenType.VALUE_KEYWORD
}
else if (isSealedToken(builder, tokenType)) {
else if (isSealedToken(builder, tokenType) && modifiers.contains(JavaSyntaxTokenType.SEALED_KEYWORD)) {
builder.remapCurrentToken(JavaSyntaxTokenType.SEALED_KEYWORD)
tokenType = JavaSyntaxTokenType.SEALED_KEYWORD
}
@@ -697,7 +698,8 @@ open class DeclarationParser(private val myParser: JavaParser) {
): SyntaxTreeBuilder.Marker? {
val param = builder.mark()
val modListInfo = parseModifierList(builder)
val modListInfo = parseModifierList(
builder, if (type === JavaSyntaxElementType.PARAMETER) PARAMETER_MODIFIER_BIT_SET else MODIFIER_BIT_SET)
val typeInfo: ReferenceParser.TypeInfo?
if (typed) {
@@ -0,0 +1,12 @@
public class ValueInLambda {
void test() {
Fn fn = value -> value;
Fn fn2 = (value) -> value;
Fn fn3 = (int value) -> value;
Fn fn4 = sealed -> sealed;
}
interface Fn {
int x(int y);
}
}
@@ -0,0 +1,203 @@
PsiJavaFile:NoSoftKeywordInLambdaParameters.java
PsiImportList
<empty list>
PsiClass:ValueInLambda
PsiModifierList:public
PsiKeyword:public('public')
PsiWhiteSpace(' ')
PsiKeyword:class('class')
PsiWhiteSpace(' ')
PsiIdentifier:ValueInLambda('ValueInLambda')
PsiTypeParameterList
<empty list>
PsiReferenceList
<empty list>
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:LBRACE('{')
PsiWhiteSpace('\n ')
PsiMethod:test
PsiModifierList:
<empty list>
PsiTypeParameterList
<empty list>
PsiTypeElement:void
PsiKeyword:void('void')
PsiWhiteSpace(' ')
PsiIdentifier:test('test')
PsiParameterList:()
PsiJavaToken:LPARENTH('(')
PsiJavaToken:RPARENTH(')')
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiCodeBlock
PsiJavaToken:LBRACE('{')
PsiWhiteSpace('\n ')
PsiDeclarationStatement
PsiLocalVariable:fn
PsiModifierList:
<empty list>
PsiTypeElement:Fn
PsiJavaCodeReferenceElement:Fn
PsiIdentifier:Fn('Fn')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:fn('fn')
PsiWhiteSpace(' ')
PsiJavaToken:EQ('=')
PsiWhiteSpace(' ')
PsiLambdaExpression
PsiParameterList:value
PsiParameter:value
PsiModifierList:
<empty list>
PsiIdentifier:value('value')
PsiWhiteSpace(' ')
PsiJavaToken:ARROW('->')
PsiWhiteSpace(' ')
PsiReferenceExpression:value
PsiReferenceParameterList
<empty list>
PsiIdentifier:value('value')
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace('\n ')
PsiDeclarationStatement
PsiLocalVariable:fn2
PsiModifierList:
<empty list>
PsiTypeElement:Fn
PsiJavaCodeReferenceElement:Fn
PsiIdentifier:Fn('Fn')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:fn2('fn2')
PsiWhiteSpace(' ')
PsiJavaToken:EQ('=')
PsiWhiteSpace(' ')
PsiLambdaExpression
PsiParameterList:(value)
PsiJavaToken:LPARENTH('(')
PsiParameter:value
PsiModifierList:
<empty list>
PsiIdentifier:value('value')
PsiJavaToken:RPARENTH(')')
PsiWhiteSpace(' ')
PsiJavaToken:ARROW('->')
PsiWhiteSpace(' ')
PsiReferenceExpression:value
PsiReferenceParameterList
<empty list>
PsiIdentifier:value('value')
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace('\n ')
PsiDeclarationStatement
PsiLocalVariable:fn3
PsiModifierList:
<empty list>
PsiTypeElement:Fn
PsiJavaCodeReferenceElement:Fn
PsiIdentifier:Fn('Fn')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:fn3('fn3')
PsiWhiteSpace(' ')
PsiJavaToken:EQ('=')
PsiWhiteSpace(' ')
PsiLambdaExpression
PsiParameterList:(int value)
PsiJavaToken:LPARENTH('(')
PsiParameter:value
PsiModifierList:
<empty list>
PsiTypeElement:int
PsiKeyword:int('int')
PsiWhiteSpace(' ')
PsiIdentifier:value('value')
PsiJavaToken:RPARENTH(')')
PsiWhiteSpace(' ')
PsiJavaToken:ARROW('->')
PsiWhiteSpace(' ')
PsiReferenceExpression:value
PsiReferenceParameterList
<empty list>
PsiIdentifier:value('value')
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace('\n ')
PsiDeclarationStatement
PsiLocalVariable:fn4
PsiModifierList:
<empty list>
PsiTypeElement:Fn
PsiJavaCodeReferenceElement:Fn
PsiIdentifier:Fn('Fn')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:fn4('fn4')
PsiWhiteSpace(' ')
PsiJavaToken:EQ('=')
PsiWhiteSpace(' ')
PsiLambdaExpression
PsiParameterList:sealed
PsiParameter:sealed
PsiModifierList:
<empty list>
PsiIdentifier:sealed('sealed')
PsiWhiteSpace(' ')
PsiJavaToken:ARROW('->')
PsiWhiteSpace(' ')
PsiReferenceExpression:sealed
PsiReferenceParameterList
<empty list>
PsiIdentifier:sealed('sealed')
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace('\n ')
PsiJavaToken:RBRACE('}')
PsiWhiteSpace('\n\n ')
PsiClass:Fn
PsiModifierList:
<empty list>
PsiKeyword:interface('interface')
PsiWhiteSpace(' ')
PsiIdentifier:Fn('Fn')
PsiTypeParameterList
<empty list>
PsiReferenceList
<empty list>
PsiReferenceList
<empty list>
PsiWhiteSpace(' ')
PsiJavaToken:LBRACE('{')
PsiWhiteSpace('\n ')
PsiMethod:x
PsiModifierList:
<empty list>
PsiTypeParameterList
<empty list>
PsiTypeElement:int
PsiKeyword:int('int')
PsiWhiteSpace(' ')
PsiIdentifier:x('x')
PsiParameterList:(int y)
PsiJavaToken:LPARENTH('(')
PsiParameter:y
PsiModifierList:
<empty list>
PsiTypeElement:int
PsiKeyword:int('int')
PsiWhiteSpace(' ')
PsiIdentifier:y('y')
PsiJavaToken:RPARENTH(')')
PsiReferenceList
<empty list>
PsiJavaToken:SEMICOLON(';')
PsiWhiteSpace('\n ')
PsiJavaToken:RBRACE('}')
PsiWhiteSpace('\n')
PsiJavaToken:RBRACE('}')
@@ -0,0 +1,203 @@
java.FILE
IMPORT_LIST
<empty list>
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
<empty list>
TYPE_PARAMETER_LIST
<empty list>
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
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
WHITE_SPACE
IDENTIFIER
WHITE_SPACE
EQ
WHITE_SPACE
LAMBDA_EXPRESSION
PARAMETER_LIST
PARAMETER
MODIFIER_LIST
<empty list>
IDENTIFIER
WHITE_SPACE
ARROW
WHITE_SPACE
REFERENCE_EXPRESSION
REFERENCE_PARAMETER_LIST
<empty list>
IDENTIFIER
SEMICOLON
WHITE_SPACE
DECLARATION_STATEMENT
LOCAL_VARIABLE
MODIFIER_LIST
<empty list>
TYPE
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
WHITE_SPACE
IDENTIFIER
WHITE_SPACE
EQ
WHITE_SPACE
LAMBDA_EXPRESSION
PARAMETER_LIST
LPARENTH
PARAMETER
MODIFIER_LIST
<empty list>
IDENTIFIER
RPARENTH
WHITE_SPACE
ARROW
WHITE_SPACE
REFERENCE_EXPRESSION
REFERENCE_PARAMETER_LIST
<empty list>
IDENTIFIER
SEMICOLON
WHITE_SPACE
DECLARATION_STATEMENT
LOCAL_VARIABLE
MODIFIER_LIST
<empty list>
TYPE
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
WHITE_SPACE
IDENTIFIER
WHITE_SPACE
EQ
WHITE_SPACE
LAMBDA_EXPRESSION
PARAMETER_LIST
LPARENTH
PARAMETER
MODIFIER_LIST
<empty list>
TYPE
INT_KEYWORD
WHITE_SPACE
IDENTIFIER
RPARENTH
WHITE_SPACE
ARROW
WHITE_SPACE
REFERENCE_EXPRESSION
REFERENCE_PARAMETER_LIST
<empty list>
IDENTIFIER
SEMICOLON
WHITE_SPACE
DECLARATION_STATEMENT
LOCAL_VARIABLE
MODIFIER_LIST
<empty list>
TYPE
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
WHITE_SPACE
IDENTIFIER
WHITE_SPACE
EQ
WHITE_SPACE
LAMBDA_EXPRESSION
PARAMETER_LIST
PARAMETER
MODIFIER_LIST
<empty list>
IDENTIFIER
WHITE_SPACE
ARROW
WHITE_SPACE
REFERENCE_EXPRESSION
REFERENCE_PARAMETER_LIST
<empty list>
IDENTIFIER
SEMICOLON
WHITE_SPACE
RBRACE
WHITE_SPACE
CLASS
MODIFIER_LIST
<empty list>
INTERFACE_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
<empty list>
TYPE_PARAMETER_LIST
<empty list>
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>
SEMICOLON
WHITE_SPACE
RBRACE
WHITE_SPACE
RBRACE