Improve parser recovery for list of value parameters/arguments

This commit is contained in:
Alexey Sedunov
2013-05-31 19:32:21 +04:00
parent a2ee65e64c
commit 3a2e30152a
7 changed files with 176 additions and 85 deletions
@@ -53,7 +53,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD, TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD,
CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD, TRY_KEYWORD, ELSE_KEYWORD, WHILE_KEYWORD, DO_KEYWORD, CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD, TRY_KEYWORD, ELSE_KEYWORD, WHILE_KEYWORD, DO_KEYWORD,
WHEN_KEYWORD, RBRACKET, RBRACE, RPAR, PLUSPLUS, MINUSMINUS, EXCLEXCL, WHEN_KEYWORD, RBRACKET, RBRACE, RPAR, PLUSPLUS, MINUSMINUS, EXCLEXCL,
// MUL, // MUL,
PLUS, MINUS, EXCL, DIV, PERC, LTEQ, PLUS, MINUS, EXCL, DIV, PERC, LTEQ,
// TODO GTEQ, foo<bar, baz>=x // TODO GTEQ, foo<bar, baz>=x
EQEQEQ, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR, SAFE_ACCESS, ELVIS, EQEQEQ, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR, SAFE_ACCESS, ELVIS,
@@ -174,7 +174,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
EQUALITY(EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ), EQUALITY(EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ),
CONJUNCTION(ANDAND), CONJUNCTION(ANDAND),
DISJUNCTION(OROR), DISJUNCTION(OROR),
// ARROW(JetTokens.ARROW), // ARROW(JetTokens.ARROW),
ASSIGNMENT(EQ, PLUSEQ, MINUSEQ, MULTEQ, DIVEQ, PERCEQ), ASSIGNMENT(EQ, PLUSEQ, MINUSEQ, MULTEQ, DIVEQ, PERCEQ),
; ;
@@ -287,7 +287,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
* see the precedence table * see the precedence table
*/ */
private void parseBinaryExpression(Precedence precedence) { private void parseBinaryExpression(Precedence precedence) {
// System.out.println(precedence.name() + " at " + myBuilder.getTokenText()); // System.out.println(precedence.name() + " at " + myBuilder.getTokenText());
PsiBuilder.Marker expression = mark(); PsiBuilder.Marker expression = mark();
@@ -310,7 +310,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
* operation? prefixExpression * operation? prefixExpression
*/ */
private void parsePrefixExpression() { private void parsePrefixExpression() {
// System.out.println("pre at " + myBuilder.getTokenText()); // System.out.println("pre at " + myBuilder.getTokenText());
if (at(LBRACKET)) { if (at(LBRACKET)) {
if (!parseLocalDeclaration()) { if (!parseLocalDeclaration()) {
@@ -485,8 +485,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
*/ */
protected boolean parseCallWithClosure() { protected boolean parseCallWithClosure() {
boolean success = false; boolean success = false;
// while (!myBuilder.newlineBeforeCurrentToken() // while (!myBuilder.newlineBeforeCurrentToken()
// && (at(LBRACE) // && (at(LBRACE)
while ((at(LBRACE) while ((at(LBRACE)
|| atSet(LABELS) && lookahead(1) == LBRACE)) { || atSet(LABELS) && lookahead(1) == LBRACE)) {
if (!at(LBRACE)) { if (!at(LBRACE)) {
@@ -520,7 +520,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
* ; * ;
*/ */
private void parseAtomicExpression() { private void parseAtomicExpression() {
// System.out.println("atom at " + myBuilder.getTokenText()); // System.out.println("atom at " + myBuilder.getTokenText());
if (at(LPAR)) { if (at(LPAR)) {
parseParenthesizedExpression(); parseParenthesizedExpression();
@@ -1074,8 +1074,8 @@ public class JetExpressionParsing extends AbstractJetParsing {
while (!eof()) { while (!eof()) {
PsiBuilder.Marker parameter = mark(); PsiBuilder.Marker parameter = mark();
// int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtOffset(doubleArrowPos))); // int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtOffset(doubleArrowPos)));
// createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, false); // createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, false);
expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW)); expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW));
@@ -50,6 +50,7 @@ public class JetParsing extends AbstractJetParsing {
private static final TokenSet IMPORT_RECOVERY_SET = TokenSet.create(AS_KEYWORD, 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, FUN_KEYWORD, LPAR, CAPITALIZED_THIS_KEYWORD, HASH);
private static final TokenSet RECEIVER_TYPE_TERMINATORS = TokenSet.create(DOT, SAFE_ACCESS); 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), MODIFIER_KEYWORDS);
static JetParsing createForTopLevel(SemanticWhitespaceAwarePsiBuilder builder) { static JetParsing createForTopLevel(SemanticWhitespaceAwarePsiBuilder builder) {
JetParsing jetParsing = new JetParsing(builder); JetParsing jetParsing = new JetParsing(builder);
@@ -1722,9 +1723,11 @@ public class JetParsing extends AbstractJetParsing {
else { else {
parseValueParameter(); parseValueParameter();
} }
if (!at(COMMA)) break; if (at(COMMA)) {
advance(); // COMMA advance(); // COMMA
} }
else if (!atSet(VALUE_PARAMETER_FIRST)) break;
}
} }
} }
@@ -114,7 +114,7 @@ public interface JetTokens {
JetToken SAFE_ACCESS = new JetToken("SAFE_ACCESS"); JetToken SAFE_ACCESS = new JetToken("SAFE_ACCESS");
JetToken ELVIS = new JetToken("ELVIS"); JetToken ELVIS = new JetToken("ELVIS");
// JetToken MAP = new JetToken("MAP"); // JetToken MAP = new JetToken("MAP");
// JetToken FILTER = new JetToken("FILTER"); // JetToken FILTER = new JetToken("FILTER");
JetToken QUEST = new JetToken("QUEST"); JetToken QUEST = new JetToken("QUEST");
JetToken COLONCOLON = new JetToken("COLONCOLON"); JetToken COLONCOLON = new JetToken("COLONCOLON");
JetToken COLON = new JetToken("COLON"); JetToken COLON = new JetToken("COLON");
@@ -198,7 +198,7 @@ public interface JetTokens {
TokenSet OPERATIONS = TokenSet.create(AS_KEYWORD, AS_SAFE, IS_KEYWORD, IN_KEYWORD, DOT, PLUSPLUS, MINUSMINUS, EXCLEXCL, MUL, PLUS, TokenSet OPERATIONS = TokenSet.create(AS_KEYWORD, AS_SAFE, IS_KEYWORD, IN_KEYWORD, DOT, PLUSPLUS, MINUSMINUS, EXCLEXCL, MUL, PLUS,
MINUS, EXCL, DIV, PERC, LT, GT, LTEQ, GTEQ, EQEQEQ, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR, MINUS, EXCL, DIV, PERC, LT, GT, LTEQ, GTEQ, EQEQEQ, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR,
SAFE_ACCESS, ELVIS, SAFE_ACCESS, ELVIS,
// MAP, FILTER, // MAP, FILTER,
COLON, COLON,
RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ, RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ,
NOT_IN, NOT_IS, NOT_IN, NOT_IS,
@@ -0,0 +1,5 @@
val x = foo(
a,
b
c
)
@@ -0,0 +1,32 @@
JetFile: MissingCommaInValueArgumentList.kt
NAMESPACE_HEADER
<empty list>
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('foo')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiWhiteSpace('\n ')
VALUE_ARGUMENT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
VALUE_ARGUMENT
BINARY_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('b')
PsiWhiteSpace('\n ')
OPERATION_REFERENCE
PsiElement(IDENTIFIER)('c')
PsiErrorElement:Expecting an element
<empty list>
PsiWhiteSpace('\n')
PsiElement(RPAR)(')')
@@ -0,0 +1,7 @@
fun foo(
a: Any,
b: Int
c: String
) {
}
@@ -0,0 +1,44 @@
JetFile: MissingCommaInValueParameterList.kt
NAMESPACE_HEADER
<empty list>
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('a')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Any')
PsiElement(COMMA)(',')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('b')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiWhiteSpace('\n ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('c')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('String')
PsiWhiteSpace('\n')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n\n')
PsiElement(RBRACE)('}')