From 4af608ef84a2af5f58ec89e3d24c06db58055f07 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 3 Apr 2015 15:51:50 +0300 Subject: [PATCH] Parser: Recovery for parameter with missing name --- .../kotlin/parsing/JetExpressionParsing.java | 9 ++- .../jetbrains/kotlin/parsing/JetParsing.java | 19 +++-- .../unnamedParameter/firstInFunction.kt | 3 + .../unnamedParameter/firstInFunction.txt | 24 ++++++ .../unnamedParameter/firstInFunctionalType.kt | 1 + .../firstInFunctionalType.txt | 30 ++++++++ .../unnamedParameter/firstInLambda.kt | 1 + .../unnamedParameter/firstInLambda.txt | 32 ++++++++ .../firstInPrimaryConstructor.kt | 3 + .../firstInPrimaryConstructor.txt | 25 ++++++ .../firstInSecondaryConstructor.kt | 5 ++ .../firstInSecondaryConstructor.txt | 35 +++++++++ .../unnamedParameter/firstInSetter.kt | 4 + .../unnamedParameter/firstInSetter.txt | 33 ++++++++ .../unnamedParameter/secondInFunction.kt | 3 + .../unnamedParameter/secondInFunction.txt | 34 +++++++++ .../secondInFunctionalType.kt | 1 + .../secondInFunctionalType.txt | 40 ++++++++++ .../unnamedParameter/secondInLambda.kt | 1 + .../unnamedParameter/secondInLambda.txt | 42 ++++++++++ .../secondInPrimaryConstructor.kt | 3 + .../secondInPrimaryConstructor.txt | 35 +++++++++ .../secondInSecondaryConstructor.kt | 5 ++ .../secondInSecondaryConstructor.txt | 45 +++++++++++ .../parsing/JetParsingTestGenerated.java | 76 +++++++++++++++++++ .../autoImports/beforeNamelessParameter.kt | 1 - 26 files changed, 501 insertions(+), 9 deletions(-) create mode 100644 compiler/testData/psi/recovery/unnamedParameter/firstInFunction.kt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/firstInFunction.txt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/firstInFunctionalType.kt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/firstInFunctionalType.txt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/firstInLambda.kt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/firstInLambda.txt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/firstInPrimaryConstructor.kt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/firstInPrimaryConstructor.txt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/firstInSecondaryConstructor.kt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/firstInSecondaryConstructor.txt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/firstInSetter.kt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/firstInSetter.txt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/secondInFunction.kt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/secondInFunction.txt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/secondInFunctionalType.kt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/secondInFunctionalType.txt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/secondInLambda.kt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/secondInLambda.txt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/secondInPrimaryConstructor.kt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/secondInPrimaryConstructor.txt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/secondInSecondaryConstructor.kt create mode 100644 compiler/testData/psi/recovery/unnamedParameter/secondInSecondaryConstructor.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetExpressionParsing.java b/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetExpressionParsing.java index 16a5d9613f2..84796575a5b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetExpressionParsing.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetExpressionParsing.java @@ -1040,7 +1040,7 @@ public class JetExpressionParsing extends AbstractJetParsing { } } else { - if (at(IDENTIFIER)) { + if (at(IDENTIFIER) || at(COLON)) { // Try to parse a simple name list followed by an ARROW // {a -> ...} // {a, b -> ...} @@ -1123,7 +1123,12 @@ public class JetExpressionParsing extends AbstractJetParsing { // int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtOffset(doubleArrowPos))); // createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, false); - expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW)); + if (at(COLON)) { + error("Expecting parameter name"); + } + else { + expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW)); + } if (at(COLON)) { advance(); // COLON diff --git a/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParsing.java b/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParsing.java index bca675a79e7..e74f0bb572b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParsing.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetParsing.java @@ -638,7 +638,7 @@ public class JetParsing extends AbstractJetParsing { beforeConstructorModifiers.drop(); if (at(LPAR)) { - parseValueParameterList(false, /* typeRequired = */ true, TokenSet.create(COLON, LBRACE)); + parseValueParameterList(false, /* typeRequired = */ true, TokenSet.create(LBRACE)); primaryConstructorMarker.done(PRIMARY_CONSTRUCTOR); } else if (hasConstructorModifiers) { @@ -877,12 +877,12 @@ public class JetParsing extends AbstractJetParsing { advance(); // CONSTRUCTOR_KEYWORD - TokenSet valueArgsRecoverySet = TokenSet.create(COLON, LBRACE, SEMICOLON, RPAR, EOL_OR_SEMICOLON, RBRACE); + TokenSet valueArgsRecoverySet = TokenSet.create(LBRACE, SEMICOLON, RPAR, EOL_OR_SEMICOLON, RBRACE); if (at(LPAR)) { parseValueParameterList(false, /*typeRequired = */ true, valueArgsRecoverySet); } else { - errorWithRecovery("Expecting '('", valueArgsRecoverySet); + errorWithRecovery("Expecting '('", TokenSet.orSet(valueArgsRecoverySet, TokenSet.create(COLON))); } if (at(COLON)) { @@ -1264,7 +1264,7 @@ public class JetParsing extends AbstractJetParsing { myBuilder.restoreJoiningComplexTokensState(); - TokenSet valueParametersFollow = TokenSet.create(COLON, EQ, LBRACE, SEMICOLON, RPAR); + TokenSet valueParametersFollow = TokenSet.create(EQ, LBRACE, SEMICOLON, RPAR); if (at(LT)) { PsiBuilder.Marker error = mark(); @@ -2056,10 +2056,17 @@ public class JetParsing extends AbstractJetParsing { boolean noErrors = true; // Recovery for the case 'fun foo(Array) {}' - if (at(IDENTIFIER) && lookahead(1) == LT) { + // Recovery for the case 'fun foo(: Int) {}' + if ((at(IDENTIFIER) && lookahead(1) == LT) || at(COLON)) { error("Parameter name expected"); + if (at(COLON)) { + // We keep noErrors == true so that unnamed parameters starting with ":" are not rolled back during parsing of functional types + advance(); // COLON + } + else { + noErrors = false; + } parseTypeRef(); - noErrors = false; } else { expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET); diff --git a/compiler/testData/psi/recovery/unnamedParameter/firstInFunction.kt b/compiler/testData/psi/recovery/unnamedParameter/firstInFunction.kt new file mode 100644 index 00000000000..73f22b7f58d --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/firstInFunction.kt @@ -0,0 +1,3 @@ +fun foo(: Int) { + +} \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/firstInFunction.txt b/compiler/testData/psi/recovery/unnamedParameter/firstInFunction.txt new file mode 100644 index 00000000000..705f550bff3 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/firstInFunction.txt @@ -0,0 +1,24 @@ +JetFile: firstInFunction.kt + PACKAGE_DIRECTIVE + + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiErrorElement:Parameter name expected + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/firstInFunctionalType.kt b/compiler/testData/psi/recovery/unnamedParameter/firstInFunctionalType.kt new file mode 100644 index 00000000000..6ab739cb58e --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/firstInFunctionalType.kt @@ -0,0 +1 @@ +val foo: (: Int) -> Int \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/firstInFunctionalType.txt b/compiler/testData/psi/recovery/unnamedParameter/firstInFunctionalType.txt new file mode 100644 index 00000000000..1e8e7a76079 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/firstInFunctionalType.txt @@ -0,0 +1,30 @@ +JetFile: firstInFunctionalType.kt + PACKAGE_DIRECTIVE + + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + FUNCTION_TYPE + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiErrorElement:Parameter name expected + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/firstInLambda.kt b/compiler/testData/psi/recovery/unnamedParameter/firstInLambda.kt new file mode 100644 index 00000000000..42fb014d1a7 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/firstInLambda.kt @@ -0,0 +1 @@ +val foo = { : Int -> 0 } \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/firstInLambda.txt b/compiler/testData/psi/recovery/unnamedParameter/firstInLambda.txt new file mode 100644 index 00000000000..86704adf1d0 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/firstInLambda.txt @@ -0,0 +1,32 @@ +JetFile: firstInLambda.kt + PACKAGE_DIRECTIVE + + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + PsiWhiteSpace(' ') + VALUE_PARAMETER_LIST + VALUE_PARAMETER + PsiErrorElement:Expecting parameter name + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + BLOCK + INTEGER_CONSTANT + PsiElement(INTEGER_LITERAL)('0') + PsiWhiteSpace(' ') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/firstInPrimaryConstructor.kt b/compiler/testData/psi/recovery/unnamedParameter/firstInPrimaryConstructor.kt new file mode 100644 index 00000000000..75e2067bb12 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/firstInPrimaryConstructor.kt @@ -0,0 +1,3 @@ +class A(: Int) { + +} \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/firstInPrimaryConstructor.txt b/compiler/testData/psi/recovery/unnamedParameter/firstInPrimaryConstructor.txt new file mode 100644 index 00000000000..34baff7a002 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/firstInPrimaryConstructor.txt @@ -0,0 +1,25 @@ +JetFile: firstInPrimaryConstructor.kt + PACKAGE_DIRECTIVE + + CLASS + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('A') + PRIMARY_CONSTRUCTOR + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiErrorElement:Parameter name expected + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/firstInSecondaryConstructor.kt b/compiler/testData/psi/recovery/unnamedParameter/firstInSecondaryConstructor.kt new file mode 100644 index 00000000000..dd477486f65 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/firstInSecondaryConstructor.kt @@ -0,0 +1,5 @@ +class A { + constructor(: Int) { + + } +} \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/firstInSecondaryConstructor.txt b/compiler/testData/psi/recovery/unnamedParameter/firstInSecondaryConstructor.txt new file mode 100644 index 00000000000..122edfde6d8 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/firstInSecondaryConstructor.txt @@ -0,0 +1,35 @@ +JetFile: firstInSecondaryConstructor.kt + PACKAGE_DIRECTIVE + + CLASS + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('A') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + SECONDARY_CONSTRUCTOR + PsiElement(constructor)('constructor') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiErrorElement:Parameter name expected + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + CONSTRUCTOR_DELEGATION_CALL + CONSTRUCTOR_DELEGATION_REFERENCE + + BLOCK + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/firstInSetter.kt b/compiler/testData/psi/recovery/unnamedParameter/firstInSetter.kt new file mode 100644 index 00000000000..7883c745314 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/firstInSetter.kt @@ -0,0 +1,4 @@ +val foo: Int + set(: Int) { + + } \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/firstInSetter.txt b/compiler/testData/psi/recovery/unnamedParameter/firstInSetter.txt new file mode 100644 index 00000000000..c696f5bf9af --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/firstInSetter.txt @@ -0,0 +1,33 @@ +JetFile: firstInSetter.kt + PACKAGE_DIRECTIVE + + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiWhiteSpace('\n ') + PROPERTY_ACCESSOR + PsiElement(set)('set') + PsiElement(LPAR)('(') + VALUE_PARAMETER_LIST + VALUE_PARAMETER + PsiErrorElement:Expecting parameter name + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n ') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/secondInFunction.kt b/compiler/testData/psi/recovery/unnamedParameter/secondInFunction.kt new file mode 100644 index 00000000000..bef7750ea27 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/secondInFunction.kt @@ -0,0 +1,3 @@ +fun foo(s: String, : Int) { + +} \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/secondInFunction.txt b/compiler/testData/psi/recovery/unnamedParameter/secondInFunction.txt new file mode 100644 index 00000000000..a50e0d9e005 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/secondInFunction.txt @@ -0,0 +1,34 @@ +JetFile: secondInFunction.kt + PACKAGE_DIRECTIVE + + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('s') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('String') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiErrorElement:Parameter name expected + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/secondInFunctionalType.kt b/compiler/testData/psi/recovery/unnamedParameter/secondInFunctionalType.kt new file mode 100644 index 00000000000..9189bf68750 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/secondInFunctionalType.kt @@ -0,0 +1 @@ +val foo: (s: String, : Int) -> Int \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/secondInFunctionalType.txt b/compiler/testData/psi/recovery/unnamedParameter/secondInFunctionalType.txt new file mode 100644 index 00000000000..b55339071f4 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/secondInFunctionalType.txt @@ -0,0 +1,40 @@ +JetFile: secondInFunctionalType.kt + PACKAGE_DIRECTIVE + + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + FUNCTION_TYPE + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('s') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('String') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiErrorElement:Parameter name expected + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/secondInLambda.kt b/compiler/testData/psi/recovery/unnamedParameter/secondInLambda.kt new file mode 100644 index 00000000000..640ec939f49 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/secondInLambda.kt @@ -0,0 +1 @@ +val foo = { s: String, : Int -> 0 } \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/secondInLambda.txt b/compiler/testData/psi/recovery/unnamedParameter/secondInLambda.txt new file mode 100644 index 00000000000..b1153249e27 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/secondInLambda.txt @@ -0,0 +1,42 @@ +JetFile: secondInLambda.kt + PACKAGE_DIRECTIVE + + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + PsiWhiteSpace(' ') + VALUE_PARAMETER_LIST + VALUE_PARAMETER + PsiElement(IDENTIFIER)('s') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('String') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiErrorElement:Expecting parameter name + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + BLOCK + INTEGER_CONSTANT + PsiElement(INTEGER_LITERAL)('0') + PsiWhiteSpace(' ') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/secondInPrimaryConstructor.kt b/compiler/testData/psi/recovery/unnamedParameter/secondInPrimaryConstructor.kt new file mode 100644 index 00000000000..f4c9117f6a0 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/secondInPrimaryConstructor.kt @@ -0,0 +1,3 @@ +class A(s: String, : Int) { + +} \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/secondInPrimaryConstructor.txt b/compiler/testData/psi/recovery/unnamedParameter/secondInPrimaryConstructor.txt new file mode 100644 index 00000000000..3a629c1e68d --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/secondInPrimaryConstructor.txt @@ -0,0 +1,35 @@ +JetFile: secondInPrimaryConstructor.kt + PACKAGE_DIRECTIVE + + CLASS + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('A') + PRIMARY_CONSTRUCTOR + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('s') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('String') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiErrorElement:Parameter name expected + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/secondInSecondaryConstructor.kt b/compiler/testData/psi/recovery/unnamedParameter/secondInSecondaryConstructor.kt new file mode 100644 index 00000000000..3773cdc71ce --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/secondInSecondaryConstructor.kt @@ -0,0 +1,5 @@ +class A { + constructor(s: String, : Int) { + + } +} \ No newline at end of file diff --git a/compiler/testData/psi/recovery/unnamedParameter/secondInSecondaryConstructor.txt b/compiler/testData/psi/recovery/unnamedParameter/secondInSecondaryConstructor.txt new file mode 100644 index 00000000000..4fcd5a24524 --- /dev/null +++ b/compiler/testData/psi/recovery/unnamedParameter/secondInSecondaryConstructor.txt @@ -0,0 +1,45 @@ +JetFile: secondInSecondaryConstructor.kt + PACKAGE_DIRECTIVE + + CLASS + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('A') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + SECONDARY_CONSTRUCTOR + PsiElement(constructor)('constructor') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('s') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('String') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiErrorElement:Parameter name expected + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + CONSTRUCTOR_DELEGATION_CALL + CONSTRUCTOR_DELEGATION_REFERENCE + + BLOCK + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java index 5fa9ce7ca14..0e2d7c54549 100644 --- a/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/parsing/JetParsingTestGenerated.java @@ -1450,6 +1450,7 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest { @InnerTestClasses({ Recovery.Objects.class, Recovery.QualifiedExpression.class, + Recovery.UnnamedParameter.class, }) @RunWith(JUnit3RunnerWithInners.class) public static class Recovery extends AbstractJetParsingTest { @@ -1838,6 +1839,81 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest { doParsingTest(fileName); } } + + @TestMetadata("compiler/testData/psi/recovery/unnamedParameter") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class UnnamedParameter extends AbstractJetParsingTest { + public void testAllFilesPresentInUnnamedParameter() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/psi/recovery/unnamedParameter"), Pattern.compile("^(.*)\\.kts?$"), true); + } + + @TestMetadata("firstInFunction.kt") + public void testFirstInFunction() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/recovery/unnamedParameter/firstInFunction.kt"); + doParsingTest(fileName); + } + + @TestMetadata("firstInFunctionalType.kt") + public void testFirstInFunctionalType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/recovery/unnamedParameter/firstInFunctionalType.kt"); + doParsingTest(fileName); + } + + @TestMetadata("firstInLambda.kt") + public void testFirstInLambda() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/recovery/unnamedParameter/firstInLambda.kt"); + doParsingTest(fileName); + } + + @TestMetadata("firstInPrimaryConstructor.kt") + public void testFirstInPrimaryConstructor() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/recovery/unnamedParameter/firstInPrimaryConstructor.kt"); + doParsingTest(fileName); + } + + @TestMetadata("firstInSecondaryConstructor.kt") + public void testFirstInSecondaryConstructor() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/recovery/unnamedParameter/firstInSecondaryConstructor.kt"); + doParsingTest(fileName); + } + + @TestMetadata("firstInSetter.kt") + public void testFirstInSetter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/recovery/unnamedParameter/firstInSetter.kt"); + doParsingTest(fileName); + } + + @TestMetadata("secondInFunction.kt") + public void testSecondInFunction() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/recovery/unnamedParameter/secondInFunction.kt"); + doParsingTest(fileName); + } + + @TestMetadata("secondInFunctionalType.kt") + public void testSecondInFunctionalType() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/recovery/unnamedParameter/secondInFunctionalType.kt"); + doParsingTest(fileName); + } + + @TestMetadata("secondInLambda.kt") + public void testSecondInLambda() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/recovery/unnamedParameter/secondInLambda.kt"); + doParsingTest(fileName); + } + + @TestMetadata("secondInPrimaryConstructor.kt") + public void testSecondInPrimaryConstructor() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/recovery/unnamedParameter/secondInPrimaryConstructor.kt"); + doParsingTest(fileName); + } + + @TestMetadata("secondInSecondaryConstructor.kt") + public void testSecondInSecondaryConstructor() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/recovery/unnamedParameter/secondInSecondaryConstructor.kt"); + doParsingTest(fileName); + } + } } @TestMetadata("compiler/testData/psi/script") diff --git a/idea/testData/quickfix/autoImports/beforeNamelessParameter.kt b/idea/testData/quickfix/autoImports/beforeNamelessParameter.kt index 1d2046b6ca7..f4708441fbd 100644 --- a/idea/testData/quickfix/autoImports/beforeNamelessParameter.kt +++ b/idea/testData/quickfix/autoImports/beforeNamelessParameter.kt @@ -1,5 +1,4 @@ // "class com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFixBase" "false" -// ERROR: Function 'f' must have a body // ERROR: Unresolved reference: TTT fun f(: Int) {