[groovy] IDEA-202693 Fix parsing varargs in lambda expressions

This commit is contained in:
alexey.afanasiev
2019-02-05 12:11:43 +03:00
parent d472470240
commit df691937fe
4 changed files with 115 additions and 19 deletions
@@ -4377,20 +4377,7 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
}
/* ********************************************************** */
// modifier_list mb_type_element var
public static boolean lambda_parameter(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "lambda_parameter")) return false;
boolean r;
Marker m = enter_section_(b, l, _NONE_, PARAMETER, "<lambda parameter>");
r = modifier_list(b, l + 1);
r = r && mb_type_element(b, l + 1);
r = r && var(b, l + 1);
exit_section_(b, l, m, r, false, null);
return r;
}
/* ********************************************************** */
// empty_parens | '(' <<comma_list (mb_nl lambda_parameter)>> ')'
// empty_parens | '(' <<comma_list (mb_nl parse_parameter)>> ')'
public static boolean lambda_parameter_list(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "lambda_parameter_list")) return false;
if (!nextTokenIs(b, T_LPAREN)) return false;
@@ -4402,7 +4389,7 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
return r;
}
// '(' <<comma_list (mb_nl lambda_parameter)>> ')'
// '(' <<comma_list (mb_nl parse_parameter)>> ')'
private static boolean lambda_parameter_list_1(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "lambda_parameter_list_1")) return false;
boolean r;
@@ -4414,13 +4401,13 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
return r;
}
// mb_nl lambda_parameter
// mb_nl parse_parameter
private static boolean lambda_parameter_list_1_1_0(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "lambda_parameter_list_1_1_0")) return false;
boolean r;
Marker m = enter_section_(b);
r = mb_nl(b, l + 1);
r = r && lambda_parameter(b, l + 1);
r = r && parse_parameter(b, l + 1);
exit_section_(b, m, null, r);
return r;
}
@@ -946,8 +946,7 @@ private call_tail ::= call_argument_list (mb_nl lazy_closure)* | empty_argument_
lambda_expression ::= lambda_expression_base | clear_variants_and_fail
private lambda_expression_base ::= lambda_expression_head mb_nl lambda_body { pin = 1 }
private lambda_expression_head ::= lambda_parameter_list mb_nl '->' { consumeTokenMethod = 'consumeTokenFast' }
lambda_parameter_list ::= empty_parens | '(' <<comma_list (mb_nl lambda_parameter)>> ')' { elementType = parameter_list }
lambda_parameter ::= modifier_list mb_type_element var { elementType = parameter }
lambda_parameter_list ::= empty_parens | '(' <<comma_list (mb_nl parse_parameter)>> ')' { elementType = parameter_list }
private lambda_body ::= (!<<isParameterizedClosure>> lazy_lambda_block) | expression_or_application
single_argument_lambda_expression::= single_argument_lambda_expression_base | clear_variants_and_fail { elementType = lambda_expression }
@@ -798,6 +798,8 @@ class ExpressionsParsingTest extends GroovyParsingTestCase {
void testlambda$assign6() { doTest() }
void testlambda$assign7() { doTest() }
void testlambda$methodCall1() { doTest() }
void testlambda$methodCall2() { doTest() }
@@ -0,0 +1,108 @@
def bar = (String a, Date b = null, int i = -1, String c, String d = 'd', String e, String ... f) -> {}
-----
Groovy script
Variable definitions
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
Variable
PsiElement(identifier)('bar')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Lambda expression
Parameter list
PsiElement(()('(')
Parameter
Modifiers
<empty list>
Type element
Reference element
PsiElement(identifier)('String')
PsiWhiteSpace(' ')
PsiElement(identifier)('a')
PsiElement(,)(',')
PsiWhiteSpace(' ')
Parameter
Modifiers
<empty list>
Type element
Reference element
PsiElement(identifier)('Date')
PsiWhiteSpace(' ')
PsiElement(identifier)('b')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Literal
PsiElement(null)('null')
PsiElement(,)(',')
PsiWhiteSpace(' ')
Parameter
Modifiers
<empty list>
Built in type
PsiElement(int)('int')
PsiWhiteSpace(' ')
PsiElement(identifier)('i')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Unary expression
PsiElement(-)('-')
Literal
PsiElement(Integer)('1')
PsiElement(,)(',')
PsiWhiteSpace(' ')
Parameter
Modifiers
<empty list>
Type element
Reference element
PsiElement(identifier)('String')
PsiWhiteSpace(' ')
PsiElement(identifier)('c')
PsiElement(,)(',')
PsiWhiteSpace(' ')
Parameter
Modifiers
<empty list>
Type element
Reference element
PsiElement(identifier)('String')
PsiWhiteSpace(' ')
PsiElement(identifier)('d')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Literal
PsiElement(single quoted string)(''d'')
PsiElement(,)(',')
PsiWhiteSpace(' ')
Parameter
Modifiers
<empty list>
Type element
Reference element
PsiElement(identifier)('String')
PsiWhiteSpace(' ')
PsiElement(identifier)('e')
PsiElement(,)(',')
PsiWhiteSpace(' ')
Parameter
Modifiers
<empty list>
Type element
Reference element
PsiElement(identifier)('String')
PsiWhiteSpace(' ')
PsiElement(...)('...')
PsiWhiteSpace(' ')
PsiElement(identifier)('f')
PsiElement())(')')
PsiWhiteSpace(' ')
PsiElement(->)('->')
PsiWhiteSpace(' ')
Lambda body block
PsiElement({)('{')
PsiElement(})('}')