[java-parser] IDEA-332589 Support when as identifier in patterns

- allow to use `when` after type test patterns. Deconstruction pattern is supposed to have when as keyword afterward

GitOrigin-RevId: 4c385125385238f9ea69bc8f69279e8900a2a9e5
This commit is contained in:
Mikhail Pyltsin
2023-09-18 23:01:38 +00:00
committed by intellij-monorepo-bot
parent 2f980484c8
commit 9fed3df3e2
13 changed files with 312 additions and 32 deletions
@@ -157,7 +157,7 @@ public class BasicPatternParser {
final boolean hasIdentifier;
if (builder.getTokenType() == JavaTokenType.IDENTIFIER &&
(!PsiKeyword.WHEN.equals(builder.getTokenText()) || isWhenAfterWhen(builder))) {
(!PsiKeyword.WHEN.equals(builder.getTokenText()) || isWhenAsIdentifier(isRecord))) {
// pattern variable after the record structure pattern
if (isRecord) {
PsiBuilder.Marker variable = builder.mark();
@@ -189,15 +189,15 @@ public class BasicPatternParser {
return pattern;
}
// There may be a valid code sample:
// Rec(int i) when when when.foo() -> {}
// There may be valid code samples:
// Rec(int i) when when when.foo() -> {} //now it is unsupported, let's skip it
// ^name ^keyword ^guard expr
private static boolean isWhenAfterWhen(final PsiBuilder builder) {
if (builder.lookAhead(1) != JavaTokenType.IDENTIFIER) return false;
PsiBuilder.Marker mark = builder.mark();
builder.advanceLexer();
boolean isWhenAfterWhen = builder.getTokenType() == JavaTokenType.IDENTIFIER && PsiKeyword.WHEN.equals(builder.getTokenText());
mark.rollbackTo();
return isWhenAfterWhen;
//case When when -> {}
// ^name
//case When(when) when when ->{}
// ^keyword ^guard expr
private static boolean isWhenAsIdentifier(boolean previousIsRecord) {
if(previousIsRecord) return false;
return true;
}
}
@@ -157,6 +157,10 @@ public abstract class AbstractBasicStatementParserTest extends AbstractBasicJava
public void testSwitchRulesWithPattern6() { doParserTest("case Integer i when true -> { }"); }
public void testSwitchRulesWithPattern7() { doParserTest("case R(int i) when true -> {}"); }
public void testSwitchRulesWithPattern8() { doParserTest("case R(int i) when a < b -> {}"); }
public void testSwitchRulesWithPattern9() { doParserTest("case A when when when.foo() -> {}"); }
public void testSwitchRulesWithPattern10() { doParserTest("case when(boolean when) when when -> {}"); }
public void testSwitchRulesWithPattern11() { doParserTest("case when when when when(when) -> {}"); }
public void testSwitchRulesWithPattern12() { doParserTest("case when when -> {}"); }
public void testSwitchRulesWithPatternIncomplete1() { doParserTest("case (Integer i -> { }"); }
public void testSwitchRulesWithPatternIncomplete2() { doParserTest("case Integer i, -> { }"); }
public void testSwitchRulesWithPatternIncomplete3() { doParserTest("case Integer i when -> { }"); }
@@ -11,6 +11,8 @@ public abstract class AbstractBasicSwitchParsingTest extends AbstractBasicJavaPa
}
public void testNormal() { doTest(true); }
public void testNormalManyWhen() { doTest(true); }
public void testUncomplete1() { doTest(true); }
public void testUncomplete2() { doTest(true); }
@@ -62,17 +62,16 @@ PsiJavaFile:Uncomplete7.java
PsiWhiteSpace(' ')
PsiCaseLabelElementList
PsiTypeTestPattern
PsiModifierList:
<empty list>
PsiTypeElement:Point
PsiJavaCodeReferenceElement:Point
PsiIdentifier:Point('Point')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiKeyword:when('when')
PsiErrorElement:Expression expected
<empty list>
PsiPatternVariable:when
PsiModifierList:
<empty list>
PsiTypeElement:Point
PsiJavaCodeReferenceElement:Point
PsiIdentifier:Point('Point')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:when('when')
PsiErrorElement:':' or '->' expected
<empty list>
PsiWhiteSpace('\n ')
@@ -62,17 +62,16 @@ java.FILE
WHITE_SPACE
CASE_LABEL_ELEMENT_LIST
TYPE_TEST_PATTERN
MODIFIER_LIST
<empty list>
TYPE
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
WHITE_SPACE
WHEN_KEYWORD
ERROR_ELEMENT
<empty list>
PATTERN_VARIABLE
MODIFIER_LIST
<empty list>
TYPE
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
WHITE_SPACE
IDENTIFIER
ERROR_ELEMENT
<empty list>
WHITE_SPACE
@@ -0,0 +1,38 @@
PsiJavaFile:SwitchRulesWithPattern10.java
PsiSwitchLabeledRule
PsiKeyword:case('case')
PsiWhiteSpace(' ')
PsiCaseLabelElementList
PsiDeconstructionPattern
PsiModifierList:
<empty list>
PsiTypeElement:when
PsiJavaCodeReferenceElement:when
PsiIdentifier:when('when')
PsiReferenceParameterList
<empty list>
PsiDeconstructionList
PsiJavaToken:LPARENTH('(')
PsiTypeTestPattern
PsiPatternVariable:when
PsiModifierList:
<empty list>
PsiTypeElement:boolean
PsiKeyword:boolean('boolean')
PsiWhiteSpace(' ')
PsiIdentifier:when('when')
PsiJavaToken:RPARENTH(')')
PsiWhiteSpace(' ')
PsiKeyword:when('when')
PsiWhiteSpace(' ')
PsiReferenceExpression:when
PsiReferenceParameterList
<empty list>
PsiIdentifier:when('when')
PsiWhiteSpace(' ')
PsiJavaToken:ARROW('->')
PsiWhiteSpace(' ')
PsiBlockStatement
PsiCodeBlock
PsiJavaToken:LBRACE('{')
PsiJavaToken:RBRACE('}')
@@ -0,0 +1,38 @@
test.java.file
SWITCH_LABELED_RULE
CASE_KEYWORD
WHITE_SPACE
CASE_LABEL_ELEMENT_LIST
DECONSTRUCTION_PATTERN
MODIFIER_LIST
<empty list>
TYPE
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
DECONSTRUCTION_LIST
LPARENTH
TYPE_TEST_PATTERN
PATTERN_VARIABLE
MODIFIER_LIST
<empty list>
TYPE
BOOLEAN_KEYWORD
WHITE_SPACE
IDENTIFIER
RPARENTH
WHITE_SPACE
WHEN_KEYWORD
WHITE_SPACE
REFERENCE_EXPRESSION
REFERENCE_PARAMETER_LIST
<empty list>
IDENTIFIER
WHITE_SPACE
ARROW
WHITE_SPACE
BLOCK_STATEMENT
CODE_BLOCK
LBRACE
RBRACE
@@ -0,0 +1,38 @@
PsiJavaFile:SwitchRulesWithPattern11.java
PsiSwitchLabeledRule
PsiKeyword:case('case')
PsiWhiteSpace(' ')
PsiCaseLabelElementList
PsiTypeTestPattern
PsiPatternVariable:when
PsiModifierList:
<empty list>
PsiTypeElement:when
PsiJavaCodeReferenceElement:when
PsiIdentifier:when('when')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:when('when')
PsiWhiteSpace(' ')
PsiKeyword:when('when')
PsiWhiteSpace(' ')
PsiMethodCallExpression:when(when)
PsiReferenceExpression:when
PsiReferenceParameterList
<empty list>
PsiIdentifier:when('when')
PsiExpressionList
PsiJavaToken:LPARENTH('(')
PsiReferenceExpression:when
PsiReferenceParameterList
<empty list>
PsiIdentifier:when('when')
PsiJavaToken:RPARENTH(')')
PsiWhiteSpace(' ')
PsiJavaToken:ARROW('->')
PsiWhiteSpace(' ')
PsiBlockStatement
PsiCodeBlock
PsiJavaToken:LBRACE('{')
PsiJavaToken:RBRACE('}')
@@ -0,0 +1,38 @@
test.java.file
SWITCH_LABELED_RULE
CASE_KEYWORD
WHITE_SPACE
CASE_LABEL_ELEMENT_LIST
TYPE_TEST_PATTERN
PATTERN_VARIABLE
MODIFIER_LIST
<empty list>
TYPE
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
WHITE_SPACE
IDENTIFIER
WHITE_SPACE
WHEN_KEYWORD
WHITE_SPACE
METHOD_CALL_EXPRESSION
REFERENCE_EXPRESSION
REFERENCE_PARAMETER_LIST
<empty list>
IDENTIFIER
EXPRESSION_LIST
LPARENTH
REFERENCE_EXPRESSION
REFERENCE_PARAMETER_LIST
<empty list>
IDENTIFIER
RPARENTH
WHITE_SPACE
ARROW
WHITE_SPACE
BLOCK_STATEMENT
CODE_BLOCK
LBRACE
RBRACE
@@ -0,0 +1,23 @@
PsiJavaFile:SwitchRulesWithPattern12.java
PsiSwitchLabeledRule
PsiKeyword:case('case')
PsiWhiteSpace(' ')
PsiCaseLabelElementList
PsiTypeTestPattern
PsiPatternVariable:when
PsiModifierList:
<empty list>
PsiTypeElement:when
PsiJavaCodeReferenceElement:when
PsiIdentifier:when('when')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:when('when')
PsiWhiteSpace(' ')
PsiJavaToken:ARROW('->')
PsiWhiteSpace(' ')
PsiBlockStatement
PsiCodeBlock
PsiJavaToken:LBRACE('{')
PsiJavaToken:RBRACE('}')
@@ -0,0 +1,23 @@
test.java.file
SWITCH_LABELED_RULE
CASE_KEYWORD
WHITE_SPACE
CASE_LABEL_ELEMENT_LIST
TYPE_TEST_PATTERN
PATTERN_VARIABLE
MODIFIER_LIST
<empty list>
TYPE
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
WHITE_SPACE
IDENTIFIER
WHITE_SPACE
ARROW
WHITE_SPACE
BLOCK_STATEMENT
CODE_BLOCK
LBRACE
RBRACE
@@ -0,0 +1,39 @@
PsiJavaFile:SwitchRulesWithPattern9.java
PsiSwitchLabeledRule
PsiKeyword:case('case')
PsiWhiteSpace(' ')
PsiCaseLabelElementList
PsiTypeTestPattern
PsiPatternVariable:when
PsiModifierList:
<empty list>
PsiTypeElement:A
PsiJavaCodeReferenceElement:A
PsiIdentifier:A('A')
PsiReferenceParameterList
<empty list>
PsiWhiteSpace(' ')
PsiIdentifier:when('when')
PsiWhiteSpace(' ')
PsiKeyword:when('when')
PsiWhiteSpace(' ')
PsiMethodCallExpression:when.foo()
PsiReferenceExpression:when.foo
PsiReferenceExpression:when
PsiReferenceParameterList
<empty list>
PsiIdentifier:when('when')
PsiJavaToken:DOT('.')
PsiReferenceParameterList
<empty list>
PsiIdentifier:foo('foo')
PsiExpressionList
PsiJavaToken:LPARENTH('(')
PsiJavaToken:RPARENTH(')')
PsiWhiteSpace(' ')
PsiJavaToken:ARROW('->')
PsiWhiteSpace(' ')
PsiBlockStatement
PsiCodeBlock
PsiJavaToken:LBRACE('{')
PsiJavaToken:RBRACE('}')
@@ -0,0 +1,39 @@
test.java.file
SWITCH_LABELED_RULE
CASE_KEYWORD
WHITE_SPACE
CASE_LABEL_ELEMENT_LIST
TYPE_TEST_PATTERN
PATTERN_VARIABLE
MODIFIER_LIST
<empty list>
TYPE
JAVA_CODE_REFERENCE
IDENTIFIER
REFERENCE_PARAMETER_LIST
<empty list>
WHITE_SPACE
IDENTIFIER
WHITE_SPACE
WHEN_KEYWORD
WHITE_SPACE
METHOD_CALL_EXPRESSION
REFERENCE_EXPRESSION
REFERENCE_EXPRESSION
REFERENCE_PARAMETER_LIST
<empty list>
IDENTIFIER
DOT
REFERENCE_PARAMETER_LIST
<empty list>
IDENTIFIER
EXPRESSION_LIST
LPARENTH
RPARENTH
WHITE_SPACE
ARROW
WHITE_SPACE
BLOCK_STATEMENT
CODE_BLOCK
LBRACE
RBRACE