Fix recovery in enum initializers

This commit is contained in:
Nikolay Krasko
2014-04-29 17:27:48 +04:00
parent ad0e6dadf4
commit 5839fda22f
5 changed files with 324 additions and 15 deletions
@@ -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);
@@ -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;
}
@@ -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
}
@@ -0,0 +1,256 @@
JetFile: EnumEntryInitList.kt
PACKAGE_DIRECTIVE
<empty list>
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
<empty list>
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
<empty list>
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
<empty list>
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
<empty list>
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
<empty list>
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
<empty list>
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
<empty 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
<empty list>
PsiElement(RBRACE)('}')
@@ -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");