From 8aec99f4b5c84effa7856b6b5924b72a3a2723ad Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Mon, 23 Oct 2017 14:13:06 +0300 Subject: [PATCH] Fix parsing variable declaration in when subject - parse destructuring declarations - parse annotations on variable declaration in when subject --- .../parsing/KotlinExpressionParsing.java | 10 +- .../psi/KtDestructuringDeclarationEntry.java | 3 +- .../testData/psi/WhenWithSubjectVariable.kt | 14 + .../testData/psi/WhenWithSubjectVariable.txt | 341 ++++++++++++++++++ .../psi/WhenWithSubjectVariable_ERR.kt | 12 + .../psi/WhenWithSubjectVariable_ERR.txt | 0 .../kotlin/parsing/ParsingTestGenerated.java | 12 + 7 files changed, 387 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/psi/WhenWithSubjectVariable.kt create mode 100644 compiler/testData/psi/WhenWithSubjectVariable.txt create mode 100644 compiler/testData/psi/WhenWithSubjectVariable_ERR.kt create mode 100644 compiler/testData/psi/WhenWithSubjectVariable_ERR.txt diff --git a/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinExpressionParsing.java b/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinExpressionParsing.java index d9f1af4fb2d..8eeab4926a3 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinExpressionParsing.java +++ b/compiler/psi/src/org/jetbrains/kotlin/parsing/KotlinExpressionParsing.java @@ -849,14 +849,16 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing { if (at(LPAR)) { advanceAt(LPAR); - PsiBuilder.Marker property = mark(); + PsiBuilder.Marker atWhenStart = mark(); myKotlinParsing.parseModifierList(DEFAULT, TokenSet.create(EQ, RPAR)); if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) { - myKotlinParsing.parseLocalProperty(false); - property.done(PROPERTY); + IElementType declType = myKotlinParsing.parseProperty(KotlinParsing.PropertyParsingMode.LOCAL); + + atWhenStart.done(declType); + atWhenStart.setCustomEdgeTokenBinders(PrecedingDocCommentsBinder.INSTANCE, TrailingCommentsBinder.INSTANCE); } else { - property.rollbackTo(); + atWhenStart.drop(); parseExpression(); } diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtDestructuringDeclarationEntry.java b/compiler/psi/src/org/jetbrains/kotlin/psi/KtDestructuringDeclarationEntry.java index 9b2c4c0a56c..addaf42d0a7 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtDestructuringDeclarationEntry.java +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtDestructuringDeclarationEntry.java @@ -122,7 +122,8 @@ public class KtDestructuringDeclarationEntry extends KtNamedDeclarationNotStubbe @NotNull private ASTNode getParentNode() { ASTNode parent = getNode().getTreeParent(); - assert parent.getElementType() == KtNodeTypes.DESTRUCTURING_DECLARATION; + assert parent.getElementType() == KtNodeTypes.DESTRUCTURING_DECLARATION : + "parent is " + parent.getElementType(); return parent; } diff --git a/compiler/testData/psi/WhenWithSubjectVariable.kt b/compiler/testData/psi/WhenWithSubjectVariable.kt new file mode 100644 index 00000000000..fd88616dc60 --- /dev/null +++ b/compiler/testData/psi/WhenWithSubjectVariable.kt @@ -0,0 +1,14 @@ +fun test() { + when (val x1 = foo) {} + when (val x2t: T) {} + when (val y2t: T = foo) {} + when (val (x3, x4) = foo) {} + when (val (y3t: T, y4) = foo) {} + when (val (z3, z4t: T) = foo) {} + when (val (w3t: T, w4t: T) = foo) {} + when (val T.x5 = foo) {} + when (val T1.x5t: T2 = foo) {} + when (@Ann val x6a = foo) {} + when (val x7a: @Ann T = foo) {} + when (val x8a = @Ann foo) {} +} diff --git a/compiler/testData/psi/WhenWithSubjectVariable.txt b/compiler/testData/psi/WhenWithSubjectVariable.txt new file mode 100644 index 00000000000..67e6b3b0d45 --- /dev/null +++ b/compiler/testData/psi/WhenWithSubjectVariable.txt @@ -0,0 +1,341 @@ +KtFile: WhenWithSubjectVariable.kt + PACKAGE_DIRECTIVE + + IMPORT_LIST + + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('test') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + WHEN + PsiElement(when)('when') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('x1') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + WHEN + PsiElement(when)('when') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('x2t') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + WHEN + PsiElement(when)('when') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('y2t') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + WHEN + PsiElement(when)('when') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + DESTRUCTURING_DECLARATION + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + DESTRUCTURING_DECLARATION_ENTRY + PsiElement(IDENTIFIER)('x3') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + DESTRUCTURING_DECLARATION_ENTRY + PsiElement(IDENTIFIER)('x4') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + WHEN + PsiElement(when)('when') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + DESTRUCTURING_DECLARATION + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + DESTRUCTURING_DECLARATION_ENTRY + PsiElement(IDENTIFIER)('y3t') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + DESTRUCTURING_DECLARATION_ENTRY + PsiElement(IDENTIFIER)('y4') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + WHEN + PsiElement(when)('when') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + DESTRUCTURING_DECLARATION + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + DESTRUCTURING_DECLARATION_ENTRY + PsiElement(IDENTIFIER)('z3') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + DESTRUCTURING_DECLARATION_ENTRY + PsiElement(IDENTIFIER)('z4t') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + WHEN + PsiElement(when)('when') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + DESTRUCTURING_DECLARATION + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + DESTRUCTURING_DECLARATION_ENTRY + PsiElement(IDENTIFIER)('w3t') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + DESTRUCTURING_DECLARATION_ENTRY + PsiElement(IDENTIFIER)('w4t') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + WHEN + PsiElement(when)('when') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('x5') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + WHEN + PsiElement(when)('when') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T1') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('x5t') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T2') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + WHEN + PsiElement(when)('when') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + PROPERTY + MODIFIER_LIST + ANNOTATION_ENTRY + PsiElement(AT)('@') + CONSTRUCTOR_CALLEE + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Ann') + PsiWhiteSpace(' ') + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('x6a') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + WHEN + PsiElement(when)('when') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('x7a') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + MODIFIER_LIST + ANNOTATION_ENTRY + PsiElement(AT)('@') + CONSTRUCTOR_CALLEE + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Ann') + PsiWhiteSpace(' ') + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + WHEN + PsiElement(when)('when') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('x8a') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + ANNOTATED_EXPRESSION + ANNOTATION_ENTRY + PsiElement(AT)('@') + CONSTRUCTOR_CALLEE + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Ann') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/WhenWithSubjectVariable_ERR.kt b/compiler/testData/psi/WhenWithSubjectVariable_ERR.kt new file mode 100644 index 00000000000..ed730e120d8 --- /dev/null +++ b/compiler/testData/psi/WhenWithSubjectVariable_ERR.kt @@ -0,0 +1,12 @@ +fun test() { + when (val) {} + when (val x1) {} + when (val x2 = ) {} + when (val x3: ) {} + + when (fun foo() {}) {} + when (class C {}) {} + when (interface I {}) {} + when (object Obj {}) {} + when (typealias TA = T) {} +} diff --git a/compiler/testData/psi/WhenWithSubjectVariable_ERR.txt b/compiler/testData/psi/WhenWithSubjectVariable_ERR.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/compiler/tests/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java index 60a9fe03c66..08745305271 100644 --- a/compiler/tests/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java @@ -711,6 +711,18 @@ public class ParsingTestGenerated extends AbstractParsingTest { runTest("compiler/testData/psi/When.kt"); } + @TestMetadata("WhenWithSubjectVariable.kt") + public void testWhenWithSubjectVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/WhenWithSubjectVariable.kt"); + doParsingTest(fileName); + } + + @TestMetadata("WhenWithSubjectVariable_ERR.kt") + public void testWhenWithSubjectVariable_ERR() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/psi/WhenWithSubjectVariable_ERR.kt"); + doParsingTest(fileName); + } + @TestMetadata("When_ERR.kt") public void testWhen_ERR() throws Exception { runTest("compiler/testData/psi/When_ERR.kt");