From da660dc08e883a4d4264bb21c5d47ac06a694c3c Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Mon, 21 May 2018 17:34:23 +0300 Subject: [PATCH] [groovy] parser: don't create reference expressions without name --- .../groovy/lang/parser/GroovyBnfParser.java | 90 +++++++++---------- .../plugins/groovy/lang/parser/groovy.bnf | 12 +-- ...opertyWithUnfinishedInvokedExpression.test | 40 ++++----- .../parsing/groovy/expressions/numbers.test | 34 +++---- 4 files changed, 79 insertions(+), 97 deletions(-) diff --git a/plugins/groovy/groovy-psi/gen/org/jetbrains/plugins/groovy/lang/parser/GroovyBnfParser.java b/plugins/groovy/groovy-psi/gen/org/jetbrains/plugins/groovy/lang/parser/GroovyBnfParser.java index dea63fe24abc..4edf801614cf 100644 --- a/plugins/groovy/groovy-psi/gen/org/jetbrains/plugins/groovy/lang/parser/GroovyBnfParser.java +++ b/plugins/groovy/groovy-psi/gen/org/jetbrains/plugins/groovy/lang/parser/GroovyBnfParser.java @@ -3741,6 +3741,29 @@ public class GroovyBnfParser implements PsiParser, LightPsiParser { return true; } + /* ********************************************************** */ + // <> | nl <> + static boolean mb_nl_group(PsiBuilder b, int l, Parser _something) { + if (!recursion_guard_(b, l, "mb_nl_group")) return false; + boolean r; + Marker m = enter_section_(b); + r = _something.parse(b, l); + if (!r) r = mb_nl_group_1(b, l + 1, _something); + exit_section_(b, m, null, r); + return r; + } + + // nl <> + private static boolean mb_nl_group_1(PsiBuilder b, int l, Parser _something) { + if (!recursion_guard_(b, l, "mb_nl_group_1")) return false; + boolean r; + Marker m = enter_section_(b); + r = nl(b, l + 1); + r = r && _something.parse(b, l); + exit_section_(b, m, null, r); + return r; + } + /* ********************************************************** */ // separator* static boolean mb_separators(PsiBuilder b, int l) { @@ -4168,42 +4191,6 @@ public class GroovyBnfParser implements PsiParser, LightPsiParser { return r; } - /* ********************************************************** */ - // (mb_nl dot) mb_nl &expression_start fail - static boolean no_ref_qualified_reference_expression_pin(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "no_ref_qualified_reference_expression_pin")) return false; - boolean r, p; - Marker m = enter_section_(b, l, _NONE_); - r = no_ref_qualified_reference_expression_pin_0(b, l + 1); - r = r && mb_nl(b, l + 1); - r = r && no_ref_qualified_reference_expression_pin_2(b, l + 1); - p = r; // pin = 3 - r = r && noMatch(b, l + 1); - exit_section_(b, l, m, r, p, null); - return r || p; - } - - // mb_nl dot - private static boolean no_ref_qualified_reference_expression_pin_0(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "no_ref_qualified_reference_expression_pin_0")) return false; - boolean r; - Marker m = enter_section_(b); - r = mb_nl(b, l + 1); - r = r && dot(b, l + 1); - exit_section_(b, m, null, r); - return r; - } - - // &expression_start - private static boolean no_ref_qualified_reference_expression_pin_2(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "no_ref_qualified_reference_expression_pin_2")) return false; - boolean r; - Marker m = enter_section_(b, l, _AND_); - r = expression_start(b, l + 1); - exit_section_(b, l, m, r, false, null); - return r; - } - /* ********************************************************** */ // <> static boolean no_type_args_code_reference(PsiBuilder b, int l) { @@ -4791,15 +4778,17 @@ public class GroovyBnfParser implements PsiParser, LightPsiParser { } /* ********************************************************** */ - // (mb_nl dot) mb_nl type_argument_list? <> + // (mb_nl dot) <>)>> static boolean qualified_reference_op(PsiBuilder b, int l, Parser _identifiers) { if (!recursion_guard_(b, l, "qualified_reference_op")) return false; boolean r; Marker m = enter_section_(b); r = qualified_reference_op_0(b, l + 1); - r = r && mb_nl(b, l + 1); - r = r && qualified_reference_op_2(b, l + 1); - r = r && _identifiers.parse(b, l); + r = r && mb_nl_group(b, l + 1, new Parser() { + public boolean parse(PsiBuilder b, int l) { + return qualified_reference_op_1_0(b, l + 1, _identifiers); + } + }); exit_section_(b, m, null, r); return r; } @@ -4815,9 +4804,20 @@ public class GroovyBnfParser implements PsiParser, LightPsiParser { return r; } + // type_argument_list? <> + private static boolean qualified_reference_op_1_0(PsiBuilder b, int l, Parser _identifiers) { + if (!recursion_guard_(b, l, "qualified_reference_op_1_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = qualified_reference_op_1_0_0(b, l + 1); + r = r && _identifiers.parse(b, l); + exit_section_(b, m, null, r); + return r; + } + // type_argument_list? - private static boolean qualified_reference_op_2(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "qualified_reference_op_2")) return false; + private static boolean qualified_reference_op_1_0_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "qualified_reference_op_1_0_0")) return false; type_argument_list(b, l + 1); return true; } @@ -6312,7 +6312,7 @@ public class GroovyBnfParser implements PsiParser, LightPsiParser { // 13: PREFIX(prefix_unary_expression) // 14: PREFIX(not_expression) ATOM(cast_expression) // 15: POSTFIX(index_expression) POSTFIX(postfix_unary_expression) - // 16: POSTFIX(qualified_reference_expression) POSTFIX(property_expression) POSTFIX(no_ref_qualified_reference_expression) + // 16: POSTFIX(qualified_reference_expression) POSTFIX(property_expression) // 17: POSTFIX(method_call_expression) ATOM(lazy_closure) ATOM(list_or_map) // 18: ATOM(new_anonymous_expression) ATOM(new_expression) // 19: ATOM(unqualified_reference_expression) ATOM(built_in_type_expression) ATOM(literal) ATOM(gstring) @@ -6445,10 +6445,6 @@ public class GroovyBnfParser implements PsiParser, LightPsiParser { r = true; exit_section_(b, l, m, PROPERTY_EXPRESSION, r, true, null); } - else if (g < 16 && no_ref_qualified_reference_expression_pin(b, l + 1)) { - r = true; - exit_section_(b, l, m, REFERENCE_EXPRESSION, r, true, null); - } else if (g < 17 && call_tail(b, l + 1)) { r = true; exit_section_(b, l, m, METHOD_CALL_EXPRESSION, r, true, null); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/parser/groovy.bnf b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/parser/groovy.bnf index d2d695064b6a..872526e784f4 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/parser/groovy.bnf +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/parser/groovy.bnf @@ -957,17 +957,10 @@ private non_empty_list_or_map ::= '[' parse_bracket_argument_list ']' pin = 2 } -private qualified_expressions ::= qualified_reference_expression | property_expression | no_ref_qualified_reference_expression +private qualified_expressions ::= qualified_reference_expression | property_expression qualified_reference_expression ::= expression <> property_expression ::= expression <> -no_ref_qualified_reference_expression ::= expression no_ref_qualified_reference_expression_pin -// TODO decide whether to create references without reference element -private no_ref_qualified_reference_expression_pin ::= (mb_nl dot) mb_nl &expression_start fail -{ - pin = 3 - consumeTokenMethod = 'consumeTokenFast' -} -private meta qualified_reference_op ::= (mb_nl dot) mb_nl type_argument_list? <> +private meta qualified_reference_op ::= (mb_nl dot) <>)>> private dot ::= '.' attribute_dot? | '?.' attribute_dot? | '.&' | '*.' { consumeTokenMethod = 'consumeTokenFast' } private attribute_dot ::= mb_nl ('@') { @@ -1250,6 +1243,7 @@ private mb_initializer ::= ['=' mb_nl expression_or_application] // region Other private mb_nl ::= nl? private nl ::= NL { consumeTokenMethod = 'consumeTokenFast' } +private meta mb_nl_group ::= <> | nl <> // allows error reporting in position before the new line private empty ::= () private external fail ::= noMatch private empty_pars ::= '(' ')' { consumeTokenMethod = 'consumeTokenFast' } diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/indexpropertyWithUnfinishedInvokedExpression.test b/plugins/groovy/testdata/parsing/groovy/expressions/indexpropertyWithUnfinishedInvokedExpression.test index 1ad63a68ea57..2dd63f18878b 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/indexpropertyWithUnfinishedInvokedExpression.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/indexpropertyWithUnfinishedInvokedExpression.test @@ -2,27 +2,25 @@ Abc.findAll(). [a, b] ----- Groovy script - Property by index + Method call Reference expression - Method call - Reference expression - Reference expression - PsiElement(identifier)('Abc') - PsiElement(.)('.') - PsiElement(identifier)('findAll') - Arguments - PsiElement(()('(') - PsiElement())(')') + Reference expression + PsiElement(identifier)('Abc') PsiElement(.)('.') - PsiElement(new line)('\n') - PsiErrorElement: expected, got '[' - + PsiElement(identifier)('findAll') Arguments - PsiElement([)('[') - Reference expression - PsiElement(identifier)('a') - PsiElement(,)(',') - PsiWhiteSpace(' ') - Reference expression - PsiElement(identifier)('b') - PsiElement(])(']') \ No newline at end of file + PsiElement(()('(') + PsiElement())(')') + PsiElement(.)('.') + PsiErrorElement: expected + + PsiElement(new line)('\n') + Generalized list + PsiElement([)('[') + Reference expression + PsiElement(identifier)('a') + PsiElement(,)(',') + PsiWhiteSpace(' ') + Reference expression + PsiElement(identifier)('b') + PsiElement(])(']') \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/numbers.test b/plugins/groovy/testdata/parsing/groovy/expressions/numbers.test index 885c0d3803bd..b0d0a6e67730 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/numbers.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/numbers.test @@ -65,16 +65,13 @@ Groovy script Literal PsiElement(Integer)('0x1_7___9____8i') PsiElement(new line)('\n\n') - Call expression - Reference expression - Literal - PsiElement(Integer)('0x1_7___9') - PsiElement(.)('.') - PsiErrorElement: expected, got '3___9_8e+5_6' - - Command arguments - Literal - PsiElement(BigDecimal)('3___9_8e+5_6') + Literal + PsiElement(Integer)('0x1_7___9') + PsiElement(.)('.') + PsiErrorElement: expected, got '3___9_8e+5_6' + + Literal + PsiElement(BigDecimal)('3___9_8e+5_6') PsiElement(new line)('\n') Literal PsiElement(BigDecimal)('1_7___9.3___9_8e+5_6') @@ -82,16 +79,13 @@ Groovy script Literal PsiElement(BigDecimal)('01_7___4.3___2_5') PsiElement(new line)('\n\n') - Call expression - Reference expression - Literal - PsiElement(Integer)('0x1_7___9') - PsiElement(.)('.') - PsiErrorElement: expected, got '3___9_8' - - Command arguments - Literal - PsiElement(Integer)('3___9_8') + Literal + PsiElement(Integer)('0x1_7___9') + PsiElement(.)('.') + PsiErrorElement: expected, got '3___9_8' + + Literal + PsiElement(Integer)('3___9_8') PsiElement(new line)('\n') Literal PsiElement(Integer)('078')