diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java index 997bf1e09d0..01fa290c336 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2013 JetBrains s.r.o. + * Copyright 2010-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1732,22 +1732,24 @@ public class JetExpressionParsing extends AbstractJetParsing { PsiBuilder.Marker list = mark(); myBuilder.disableNewlines(); - expect(LPAR, "Expecting an argument list", EXPRESSION_FOLLOW); - if (!at(RPAR)) { - while (true) { - while (at(COMMA)) errorAndAdvance("Expecting an argument"); - parseValueArgument(); - if (!at(COMMA)) break; - advance(); // COMMA - if (at(RPAR)) { - error("Expecting an argument"); - break; + if (expect(LPAR, "Expecting an argument list", EXPRESSION_FOLLOW)) { + if (!at(RPAR)) { + while (true) { + while (at(COMMA)) errorAndAdvance("Expecting an argument"); + parseValueArgument(); + if (!at(COMMA)) break; + advance(); // COMMA + if (at(RPAR)) { + error("Expecting an argument"); + break; + } } } + + expect(RPAR, "Expecting ')'", EXPRESSION_FOLLOW); } - expect(RPAR, "Expecting ')'", EXPRESSION_FOLLOW); myBuilder.restoreNewlinesState(); list.done(VALUE_ARGUMENT_LIST); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java index 8f83717c3ca..0ebadcd66c5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2013 JetBrains s.r.o. + * Copyright 2010-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,7 +48,7 @@ public class JetParsing extends AbstractJetParsing { private static final TokenSet PARAMETER_NAME_RECOVERY_SET = TokenSet.create(COLON, EQ, COMMA, RPAR); private static final TokenSet PACKAGE_NAME_RECOVERY_SET = TokenSet.create(DOT, EOL_OR_SEMICOLON); private static final TokenSet IMPORT_RECOVERY_SET = TokenSet.create(AS_KEYWORD, DOT, EOL_OR_SEMICOLON); - /*package*/ static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, FUN_KEYWORD, LPAR, CAPITALIZED_THIS_KEYWORD, HASH); + /*package*/ static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, LPAR, CAPITALIZED_THIS_KEYWORD, HASH); private static final TokenSet RECEIVER_TYPE_TERMINATORS = TokenSet.create(DOT, SAFE_ACCESS); private static final TokenSet VALUE_PARAMETER_FIRST = TokenSet.orSet(TokenSet.create(IDENTIFIER, LBRACKET, VAL_KEYWORD, VAR_KEYWORD), MODIFIER_KEYWORDS); @@ -788,7 +788,8 @@ public class JetParsing extends AbstractJetParsing { type = DELEGATOR_SUPER_CALL; } else { - errorWithRecovery("Expecting constructor call (this(...)) or supertype initializer", TokenSet.create(LBRACE, COMMA)); + errorWithRecovery("Expecting constructor call (this(...)) or supertype initializer", + TokenSet.orSet(TOPLEVEL_OBJECT_FIRST, TokenSet.create(RBRACE, LBRACE, COMMA, SEMICOLON))); initializer.drop(); return; } diff --git a/compiler/testData/psi/recovery/EnumEntryInitList.kt b/compiler/testData/psi/recovery/EnumEntryInitList.kt new file mode 100644 index 00000000000..9a135713535 --- /dev/null +++ b/compiler/testData/psi/recovery/EnumEntryInitList.kt @@ -0,0 +1,45 @@ +enum class E1 { + FIRST: +} + +enum class E2 { + FIRST: + + fun some() {} +} + +enum class E3 { + FIRST: + + val some = 1 +} + +enum class E4 { + FIRST: + + class Other +} + +enum class E5 { + FIRST: E5(), + + class Other +} + +enum class E6 { + FIRST: E6(),; + + class Other +} + +enum class E7 { + FIRST: + + [Some] + SECOND +} + +enum class E8 { + FIRST: + SECOND +} \ No newline at end of file diff --git a/compiler/testData/psi/recovery/EnumEntryInitList.txt b/compiler/testData/psi/recovery/EnumEntryInitList.txt new file mode 100644 index 00000000000..082409cb7f2 --- /dev/null +++ b/compiler/testData/psi/recovery/EnumEntryInitList.txt @@ -0,0 +1,256 @@ +JetFile: EnumEntryInitList.kt + PACKAGE_DIRECTIVE + + CLASS + MODIFIER_LIST + PsiElement(enum)('enum') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('E1') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + ENUM_ENTRY + OBJECT_DECLARATION_NAME + PsiElement(IDENTIFIER)('FIRST') + PsiElement(COLON)(':') + PsiWhiteSpace('\n') + INITIALIZER_LIST + PsiErrorElement:Expecting constructor call (this(...)) or supertype initializer + + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + CLASS + MODIFIER_LIST + PsiElement(enum)('enum') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('E2') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + ENUM_ENTRY + OBJECT_DECLARATION_NAME + PsiElement(IDENTIFIER)('FIRST') + PsiElement(COLON)(':') + PsiWhiteSpace('\n\n ') + INITIALIZER_LIST + PsiErrorElement:Expecting constructor call (this(...)) or supertype initializer + + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('some') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + CLASS + MODIFIER_LIST + PsiElement(enum)('enum') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('E3') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + ENUM_ENTRY + OBJECT_DECLARATION_NAME + PsiElement(IDENTIFIER)('FIRST') + PsiElement(COLON)(':') + PsiWhiteSpace('\n\n ') + INITIALIZER_LIST + PsiErrorElement:Expecting constructor call (this(...)) or supertype initializer + + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('some') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + INTEGER_CONSTANT + PsiElement(INTEGER_LITERAL)('1') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + CLASS + MODIFIER_LIST + PsiElement(enum)('enum') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('E4') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + ENUM_ENTRY + OBJECT_DECLARATION_NAME + PsiElement(IDENTIFIER)('FIRST') + PsiElement(COLON)(':') + PsiWhiteSpace('\n\n ') + INITIALIZER_LIST + PsiErrorElement:Expecting constructor call (this(...)) or supertype initializer + + CLASS + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('Other') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + CLASS + MODIFIER_LIST + PsiElement(enum)('enum') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('E5') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + ENUM_ENTRY + OBJECT_DECLARATION_NAME + PsiElement(IDENTIFIER)('FIRST') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + INITIALIZER_LIST + DELEGATOR_SUPER_CALL + CONSTRUCTOR_CALLEE + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('E5') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiElement(COMMA)(',') + PsiErrorElement:Expecting constructor call (this(...)) or supertype initializer + + PsiWhiteSpace('\n\n ') + CLASS + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('Other') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + CLASS + MODIFIER_LIST + PsiElement(enum)('enum') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('E6') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + ENUM_ENTRY + OBJECT_DECLARATION_NAME + PsiElement(IDENTIFIER)('FIRST') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + INITIALIZER_LIST + DELEGATOR_SUPER_CALL + CONSTRUCTOR_CALLEE + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('E6') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiElement(COMMA)(',') + PsiErrorElement:Expecting constructor call (this(...)) or supertype initializer + + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n\n ') + CLASS + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('Other') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + CLASS + MODIFIER_LIST + PsiElement(enum)('enum') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('E7') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + ENUM_ENTRY + OBJECT_DECLARATION_NAME + PsiElement(IDENTIFIER)('FIRST') + PsiElement(COLON)(':') + PsiWhiteSpace('\n\n ') + INITIALIZER_LIST + DELEGATOR_SUPER_CALL + ANNOTATION + PsiElement(LBRACKET)('[') + ANNOTATION_ENTRY + CONSTRUCTOR_CALLEE + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Some') + PsiElement(RBRACKET)(']') + PsiWhiteSpace('\n ') + CONSTRUCTOR_CALLEE + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('SECOND') + PsiWhiteSpace('\n') + VALUE_ARGUMENT_LIST + PsiErrorElement:Expecting an argument list + + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + CLASS + MODIFIER_LIST + PsiElement(enum)('enum') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('E8') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + ENUM_ENTRY + OBJECT_DECLARATION_NAME + PsiElement(IDENTIFIER)('FIRST') + PsiElement(COLON)(':') + PsiWhiteSpace('\n ') + INITIALIZER_LIST + DELEGATOR_SUPER_CALL + CONSTRUCTOR_CALLEE + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('SECOND') + PsiWhiteSpace('\n') + VALUE_ARGUMENT_LIST + PsiErrorElement:Expecting an argument list + + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/parsing/JetParsingTestGenerated.java b/compiler/tests/org/jetbrains/jet/parsing/JetParsingTestGenerated.java index f4a97b1ee11..a816c56137e 100644 --- a/compiler/tests/org/jetbrains/jet/parsing/JetParsingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/parsing/JetParsingTestGenerated.java @@ -880,6 +880,11 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/psi/recovery"), Pattern.compile("^(.*)\\.kts?$"), true); } + @TestMetadata("EnumEntryInitList.kt") + public void testEnumEntryInitList() throws Exception { + doParsingTest("compiler/testData/psi/recovery/EnumEntryInitList.kt"); + } + @TestMetadata("ForRecovery.kt") public void testForRecovery() throws Exception { doParsingTest("compiler/testData/psi/recovery/ForRecovery.kt");