Add recovery for missing comma between arguments

^KT-13497 Fixed
This commit is contained in:
Denis Zharkov
2019-01-15 15:23:04 +03:00
parent 37614254d7
commit 82537cdc8b
7 changed files with 270 additions and 50 deletions
@@ -1816,7 +1816,15 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
if (at(COLON) && lookahead(1) == IDENTIFIER) {
errorAndAdvance("Unexpected type specification", 2);
}
if (!at(COMMA)) break;
if (!at(COMMA)) {
if (atSet(EXPRESSION_FIRST)) {
error("Expecting ','");
continue;
}
else {
break;
}
}
advance(); // COMMA
if (at(RPAR)) {
error("Expecting an argument");
+4 -4
View File
@@ -4,10 +4,10 @@ fun test(<!UNUSED_PARAMETER!>c<!> : Char) {
test(<!TOO_MANY_CHARACTERS_IN_CHARACTER_LITERAL!>'aa'<!>)
test(<!INCORRECT_CHARACTER_LITERAL!>'a)<!>
<!UNRESOLVED_REFERENCE!>test<!>(<!INCORRECT_CHARACTER_LITERAL!>'<!>
<!UNRESOLVED_REFERENCE!>test<!>(0<!SYNTAX!><!SYNTAX!><!>'<!>
test('\n')
test('\\')
test(<!EMPTY_CHARACTER_LITERAL!>''<!><!SYNTAX!>''<!><!SYNTAX!>)<!>
<!UNRESOLVED_REFERENCE!>test<!>(0<!INCORRECT_CHARACTER_LITERAL!><!SYNTAX!><!>'<!>
<!UNRESOLVED_REFERENCE!>test<!>('\n')
<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>test<!>('\\')
<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>test<!>(<!EMPTY_CHARACTER_LITERAL!>''<!><!EMPTY_CHARACTER_LITERAL, TOO_MANY_ARGUMENTS!><!SYNTAX!><!>''<!>)
test('\'')
test('\"')
}
+46 -43
View File
@@ -575,61 +575,64 @@ KtFile: FunctionExpressions_ERR.kt
PsiElement(RPAR)(')')
PsiWhiteSpace('\n\n\n ')
CALL_EXPRESSION
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('public')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting ')'
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('public')
PsiErrorElement:Expecting ','
<empty list>
PsiWhiteSpace(' ')
VALUE_ARGUMENT
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RPAR)(')')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('open')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting ')'
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('open')
PsiErrorElement:Expecting ','
<empty list>
PsiWhiteSpace(' ')
VALUE_ARGUMENT
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RPAR)(')')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('final')
PsiWhiteSpace(' ')
PsiErrorElement:Expecting ')'
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('final')
PsiErrorElement:Expecting ','
<empty list>
PsiWhiteSpace(' ')
VALUE_ARGUMENT
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RPAR)(')')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(RPAR)(')')
PsiWhiteSpace('\n\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
@@ -659,4 +662,4 @@ KtFile: FunctionExpressions_ERR.kt
PsiElement(IDENTIFIER)('V')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiElement(RBRACE)('}')
+22
View File
@@ -0,0 +1,22 @@
fun foo() {
bar1(
A()
A()
)
bar2(A() A())
bar3(x y)
bar4(x
y
)
bar5("" "")
bar6(""
""
)
bar7({} {})
bar8({}
{}
)
}
+182
View File
@@ -0,0 +1,182 @@
KtFile: noCommaBetweenArguments.kt
PACKAGE_DIRECTIVE
<empty list>
IMPORT_LIST
<empty list>
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar1')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiWhiteSpace('\n ')
VALUE_ARGUMENT
BINARY_EXPRESSION
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('A')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
OPERATION_REFERENCE
PsiElement(IDENTIFIER)('A')
PARENTHESIZED
PsiElement(LPAR)('(')
PsiErrorElement:Expecting an expression
<empty list>
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar2')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
BINARY_EXPRESSION
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('A')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(IDENTIFIER)('A')
PARENTHESIZED
PsiElement(LPAR)('(')
PsiErrorElement:Expecting an expression
<empty list>
PsiElement(RPAR)(')')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar3')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
BINARY_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(IDENTIFIER)('y')
PsiErrorElement:Expecting an element
<empty list>
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar4')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
BINARY_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace('\n ')
OPERATION_REFERENCE
PsiElement(IDENTIFIER)('y')
PsiErrorElement:Expecting an element
<empty list>
PsiWhiteSpace('\n ')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar5')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
STRING_TEMPLATE
PsiElement(OPEN_QUOTE)('"')
PsiElement(CLOSING_QUOTE)('"')
PsiErrorElement:Expecting ','
<empty list>
PsiWhiteSpace(' ')
VALUE_ARGUMENT
STRING_TEMPLATE
PsiElement(OPEN_QUOTE)('"')
PsiElement(CLOSING_QUOTE)('"')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar6')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
STRING_TEMPLATE
PsiElement(OPEN_QUOTE)('"')
PsiElement(CLOSING_QUOTE)('"')
PsiErrorElement:Expecting ','
<empty list>
PsiWhiteSpace('\n ')
VALUE_ARGUMENT
STRING_TEMPLATE
PsiElement(OPEN_QUOTE)('"')
PsiElement(CLOSING_QUOTE)('"')
PsiWhiteSpace('\n ')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar7')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
CALL_EXPRESSION
LAMBDA_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
BLOCK
<empty list>
PsiElement(RBRACE)('}')
PsiWhiteSpace(' ')
LAMBDA_ARGUMENT
LAMBDA_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
BLOCK
<empty list>
PsiElement(RBRACE)('}')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('bar8')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
CALL_EXPRESSION
LAMBDA_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
BLOCK
<empty list>
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n ')
LAMBDA_ARGUMENT
LAMBDA_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')
BLOCK
<empty list>
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n ')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
@@ -521,6 +521,11 @@ public class ParsingTestGenerated extends AbstractParsingTest {
runTest("compiler/testData/psi/NewlinesInParentheses.kt");
}
@TestMetadata("noCommaBetweenArguments.kt")
public void testNoCommaBetweenArguments() throws Exception {
runTest("compiler/testData/psi/noCommaBetweenArguments.kt");
}
@TestMetadata("NonTypeBeforeDotInBaseClass.kt")
public void testNonTypeBeforeDotInBaseClass() throws Exception {
runTest("compiler/testData/psi/NonTypeBeforeDotInBaseClass.kt");
@@ -2,5 +2,5 @@ annotation class A
class B
@A(B.class<error>)</error>
<error>fun</error> <error>f</error><error>(</error><error>)</error> <error><error>{</error>}</error>
@A(B.class<error descr="Name expected">)</error><EOLError descr="Expecting ','"></EOLError>
<error descr="[TOO_MANY_ARGUMENTS] Too many arguments for public constructor A() defined in A"><error descr="[TOO_MANY_ARGUMENTS] Too many arguments for public constructor A() defined in A">fun <error descr="[ANONYMOUS_FUNCTION_WITH_NAME] Anonymous functions with names are prohibited">f</error>() {}</error></error><EOLError descr="Expecting a top level declaration"></EOLError><EOLError descr="Expecting ')'"></EOLError>