From d3f55d085c5d49bb5ee85fcba69163c9cd1704a3 Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Sat, 2 Jun 2018 22:09:26 +0300 Subject: [PATCH] [groovy] add separate element for method reference expressions --- .../lang/parser/GroovyGeneratedParser.java | 320 ++++++++++++------ .../groovy/lang/psi/GroovyElementTypes.java | 1 + .../groovy/lang/parser/GroovyPsiCreator.java | 2 + .../plugins/groovy/lang/parser/groovy.bnf | 19 +- .../impl/GrMethodReferenceExpressionImpl.kt | 12 + .../GrReferenceExpressionImpl.java | 2 +- .../groovy/expressions/path/path15.test | 2 +- 7 files changed, 236 insertions(+), 122 deletions(-) create mode 100644 plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMethodReferenceExpressionImpl.kt diff --git a/plugins/groovy/groovy-psi/gen/org/jetbrains/plugins/groovy/lang/parser/GroovyGeneratedParser.java b/plugins/groovy/groovy-psi/gen/org/jetbrains/plugins/groovy/lang/parser/GroovyGeneratedParser.java index e5195368e06c..778e2a3c1bc6 100644 --- a/plugins/groovy/groovy-psi/gen/org/jetbrains/plugins/groovy/lang/parser/GroovyGeneratedParser.java +++ b/plugins/groovy/groovy-psi/gen/org/jetbrains/plugins/groovy/lang/parser/GroovyGeneratedParser.java @@ -270,11 +270,11 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser { CLOSURE, CONSTRUCTOR_CALL_EXPRESSION, ELVIS_EXPRESSION, EQUALITY_EXPRESSION, EXPRESSION, GSTRING, INDEX_EXPRESSION, INSTANCEOF_EXPRESSION, IN_EXPRESSION, LAND_EXPRESSION, LIST_OR_MAP, LITERAL, - LOR_EXPRESSION, METHOD_CALL_EXPRESSION, MULTIPLICATIVE_EXPRESSION, NEW_EXPRESSION, - PARENTHESIZED_EXPRESSION, POWER_EXPRESSION, PROPERTY_EXPRESSION, RANGE_EXPRESSION, - REFERENCE_EXPRESSION, REGEX, REGEX_FIND_EXPRESSION, REGEX_MATCH_EXPRESSION, - RELATIONAL_EXPRESSION, SHIFT_EXPRESSION, TERNARY_EXPRESSION, TUPLE_ASSIGNMENT_EXPRESSION, - UNARY_EXPRESSION, XOR_EXPRESSION), + LOR_EXPRESSION, METHOD_CALL_EXPRESSION, METHOD_REFERENCE_EXPRESSION, MULTIPLICATIVE_EXPRESSION, + NEW_EXPRESSION, PARENTHESIZED_EXPRESSION, POWER_EXPRESSION, PROPERTY_EXPRESSION, + RANGE_EXPRESSION, REFERENCE_EXPRESSION, REGEX, REGEX_FIND_EXPRESSION, + REGEX_MATCH_EXPRESSION, RELATIONAL_EXPRESSION, SHIFT_EXPRESSION, TERNARY_EXPRESSION, + TUPLE_ASSIGNMENT_EXPRESSION, UNARY_EXPRESSION, XOR_EXPRESSION), }; /* ********************************************************** */ @@ -2767,56 +2767,6 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser { return compound_string(b, l + 1, DOLLAR_SLASHY_BEGIN_parser_, fast_dollar_slashy_content_parser_, DOLLAR_SLASHY_END_parser_); } - /* ********************************************************** */ - // '.' attribute_dot? | '?.' attribute_dot? | '.&' | '*.' - static boolean dot(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "dot")) return false; - boolean r; - Marker m = enter_section_(b); - r = dot_0(b, l + 1); - if (!r) r = dot_1(b, l + 1); - if (!r) r = consumeTokenFast(b, T_METHOD_CLOSURE); - if (!r) r = consumeTokenFast(b, T_SPREAD_DOT); - exit_section_(b, m, null, r); - return r; - } - - // '.' attribute_dot? - private static boolean dot_0(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "dot_0")) return false; - boolean r; - Marker m = enter_section_(b); - r = consumeTokenFast(b, T_DOT); - r = r && dot_0_1(b, l + 1); - exit_section_(b, m, null, r); - return r; - } - - // attribute_dot? - private static boolean dot_0_1(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "dot_0_1")) return false; - attribute_dot(b, l + 1); - return true; - } - - // '?.' attribute_dot? - private static boolean dot_1(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "dot_1")) return false; - boolean r; - Marker m = enter_section_(b); - r = consumeTokenFast(b, T_SAFE_DOT); - r = r && dot_1_1(b, l + 1); - exit_section_(b, m, null, r); - return r; - } - - // attribute_dot? - private static boolean dot_1_1(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "dot_1_1")) return false; - attribute_dot(b, l + 1); - return true; - } - /* ********************************************************** */ // '...' static boolean ellipsis(PsiBuilder b, int l) { @@ -4088,6 +4038,12 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser { return r; } + /* ********************************************************** */ + // '.&' + static boolean method_reference_dot(PsiBuilder b, int l) { + return consumeTokenFast(b, T_METHOD_CLOSURE); + } + /* ********************************************************** */ // constructor | method static boolean methods_tail(PsiBuilder b, int l) { @@ -4963,6 +4919,16 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser { return r; } + /* ********************************************************** */ + // reference_dot | method_reference_dot + static boolean property_dot(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "property_dot")) return false; + boolean r; + r = reference_dot(b, l + 1); + if (!r) r = method_reference_dot(b, l + 1); + return r; + } + /* ********************************************************** */ // parenthesized_expression | lazy_block | gstring | regex static boolean property_expression_identifiers(PsiBuilder b, int l) { @@ -5071,51 +5037,6 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser { return r; } - /* ********************************************************** */ - // (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_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; - } - - // mb_nl dot - private static boolean qualified_reference_op_0(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "qualified_reference_op_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; - } - - // 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_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; - } - /* ********************************************************** */ // !')' static boolean r_par_recovery(PsiBuilder b, int l) { @@ -5127,6 +5048,55 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser { return r; } + /* ********************************************************** */ + // '.' attribute_dot? | '?.' attribute_dot? | '*.' + static boolean reference_dot(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "reference_dot")) return false; + boolean r; + Marker m = enter_section_(b); + r = reference_dot_0(b, l + 1); + if (!r) r = reference_dot_1(b, l + 1); + if (!r) r = consumeTokenFast(b, T_SPREAD_DOT); + exit_section_(b, m, null, r); + return r; + } + + // '.' attribute_dot? + private static boolean reference_dot_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "reference_dot_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokenFast(b, T_DOT); + r = r && reference_dot_0_1(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // attribute_dot? + private static boolean reference_dot_0_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "reference_dot_0_1")) return false; + attribute_dot(b, l + 1); + return true; + } + + // '?.' attribute_dot? + private static boolean reference_dot_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "reference_dot_1")) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokenFast(b, T_SAFE_DOT); + r = r && reference_dot_1_1(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // attribute_dot? + private static boolean reference_dot_1_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "reference_dot_1_1")) return false; + attribute_dot(b, l + 1); + return true; + } + /* ********************************************************** */ // slashy_literal | dollar_slashy_literal static boolean regex_literal(PsiBuilder b, int l) { @@ -6641,7 +6611,7 @@ public class GroovyGeneratedParser 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) + // 16: POSTFIX(method_reference_expression) 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) @@ -6769,11 +6739,15 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser { r = true; exit_section_(b, l, m, UNARY_EXPRESSION, r, true, null); } - else if (g < 16 && qualified_reference_op(b, l + 1, qualified_reference_expression_identifiers_parser_)) { + else if (g < 16 && method_reference_expression_0(b, l + 1)) { + r = true; + exit_section_(b, l, m, METHOD_REFERENCE_EXPRESSION, r, true, null); + } + else if (g < 16 && qualified_reference_expression_0(b, l + 1)) { r = true; exit_section_(b, l, m, REFERENCE_EXPRESSION, r, true, null); } - else if (g < 16 && qualified_reference_op(b, l + 1, property_expression_identifiers_parser_)) { + else if (g < 16 && property_expression_0(b, l + 1)) { r = true; exit_section_(b, l, m, PROPERTY_EXPRESSION, r, true, null); } @@ -7108,6 +7082,119 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser { return r; } + // (mb_nl method_reference_dot) (mb_nl qualified_reference_expression_identifiers) + private static boolean method_reference_expression_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "method_reference_expression_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = method_reference_expression_0_0(b, l + 1); + r = r && method_reference_expression_0_1(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // mb_nl method_reference_dot + private static boolean method_reference_expression_0_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "method_reference_expression_0_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = mb_nl(b, l + 1); + r = r && method_reference_dot(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // mb_nl qualified_reference_expression_identifiers + private static boolean method_reference_expression_0_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "method_reference_expression_0_1")) return false; + boolean r; + Marker m = enter_section_(b); + r = mb_nl(b, l + 1); + r = r && qualified_reference_expression_identifiers(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // (mb_nl reference_dot) <> + private static boolean qualified_reference_expression_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "qualified_reference_expression_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = qualified_reference_expression_0_0(b, l + 1); + r = r && mb_nl_group(b, l + 1, qualified_reference_expression_0_1_0_parser_); + exit_section_(b, m, null, r); + return r; + } + + // mb_nl reference_dot + private static boolean qualified_reference_expression_0_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "qualified_reference_expression_0_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = mb_nl(b, l + 1); + r = r && reference_dot(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // type_argument_list? qualified_reference_expression_identifiers + private static boolean qualified_reference_expression_0_1_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "qualified_reference_expression_0_1_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = qualified_reference_expression_0_1_0_0(b, l + 1); + r = r && qualified_reference_expression_identifiers(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // type_argument_list? + private static boolean qualified_reference_expression_0_1_0_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "qualified_reference_expression_0_1_0_0")) return false; + type_argument_list(b, l + 1); + return true; + } + + // (mb_nl property_dot) <> + private static boolean property_expression_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "property_expression_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = property_expression_0_0(b, l + 1); + r = r && mb_nl_group(b, l + 1, property_expression_0_1_0_parser_); + exit_section_(b, m, null, r); + return r; + } + + // mb_nl property_dot + private static boolean property_expression_0_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "property_expression_0_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = mb_nl(b, l + 1); + r = r && property_dot(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // type_argument_list? property_expression_identifiers + private static boolean property_expression_0_1_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "property_expression_0_1_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = property_expression_0_1_0_0(b, l + 1); + r = r && property_expression_identifiers(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // type_argument_list? + private static boolean property_expression_0_1_0_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "property_expression_0_1_0_0")) return false; + type_argument_list(b, l + 1); + return true; + } + // <> public static boolean lazy_closure(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "lazy_closure")) return false; @@ -7211,7 +7298,7 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser { // IDENTIFIER // | 'this' // | 'super' - // | ('in' | 'def' | 'trait') &dot + // | ('in' | 'def' | 'trait') &(reference_dot | '.&') // | (STR_SQ | STR_DQ) &string_literal_as_reference public static boolean unqualified_reference_expression(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "unqualified_reference_expression")) return false; @@ -7226,7 +7313,7 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser { return r; } - // ('in' | 'def' | 'trait') &dot + // ('in' | 'def' | 'trait') &(reference_dot | '.&') private static boolean unqualified_reference_expression_3(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "unqualified_reference_expression_3")) return false; boolean r; @@ -7249,16 +7336,27 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser { return r; } - // &dot + // &(reference_dot | '.&') private static boolean unqualified_reference_expression_3_1(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "unqualified_reference_expression_3_1")) return false; boolean r; Marker m = enter_section_(b, l, _AND_); - r = dot(b, l + 1); + r = unqualified_reference_expression_3_1_0(b, l + 1); exit_section_(b, l, m, r, false, null); return r; } + // reference_dot | '.&' + private static boolean unqualified_reference_expression_3_1_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "unqualified_reference_expression_3_1_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = reference_dot(b, l + 1); + if (!r) r = consumeTokenSmart(b, T_METHOD_CLOSURE); + exit_section_(b, m, null, r); + return r; + } + // (STR_SQ | STR_DQ) &string_literal_as_reference private static boolean unqualified_reference_expression_4(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "unqualified_reference_expression_4")) return false; @@ -7679,14 +7777,14 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser { return parse_parameter(b, l + 1); } }; - final static Parser property_expression_identifiers_parser_ = new Parser() { + final static Parser property_expression_0_1_0_parser_ = new Parser() { public boolean parse(PsiBuilder b, int l) { - return property_expression_identifiers(b, l + 1); + return property_expression_0_1_0(b, l + 1); } }; - final static Parser qualified_reference_expression_identifiers_parser_ = new Parser() { + final static Parser qualified_reference_expression_0_1_0_parser_ = new Parser() { public boolean parse(PsiBuilder b, int l) { - return qualified_reference_expression_identifiers(b, l + 1); + return qualified_reference_expression_0_1_0(b, l + 1); } }; final static Parser r_par_recovery_parser_ = new Parser() { diff --git a/plugins/groovy/groovy-psi/gen/org/jetbrains/plugins/groovy/lang/psi/GroovyElementTypes.java b/plugins/groovy/groovy-psi/gen/org/jetbrains/plugins/groovy/lang/psi/GroovyElementTypes.java index c5b10c44da1b..659d51e14f83 100644 --- a/plugins/groovy/groovy-psi/gen/org/jetbrains/plugins/groovy/lang/psi/GroovyElementTypes.java +++ b/plugins/groovy/groovy-psi/gen/org/jetbrains/plugins/groovy/lang/psi/GroovyElementTypes.java @@ -111,6 +111,7 @@ public interface GroovyElementTypes { GroovyElementType LOR_EXPRESSION = new GroovyElementType("LOR_EXPRESSION"); GrMethodElementType METHOD = new GrMethodElementType("METHOD"); GroovyElementType METHOD_CALL_EXPRESSION = new GroovyElementType("METHOD_CALL_EXPRESSION"); + GroovyElementType METHOD_REFERENCE_EXPRESSION = new GroovyElementType("METHOD_REFERENCE_EXPRESSION"); GrModifierListElementType MODIFIER_LIST = new GrModifierListElementType("MODIFIER_LIST"); GroovyElementType MULTIPLICATIVE_EXPRESSION = new GroovyElementType("MULTIPLICATIVE_EXPRESSION"); GroovyElementType NAMED_ARGUMENT = new GroovyElementType("NAMED_ARGUMENT"); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java index 458db354e1e3..44e399250953 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java @@ -10,6 +10,7 @@ import org.jetbrains.plugins.groovy.lang.groovydoc.psi.GroovyDocPsiCreator; import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType; import org.jetbrains.plugins.groovy.lang.psi.impl.GrImportAliasImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.GrInExpressionImpl; +import org.jetbrains.plugins.groovy.lang.psi.impl.GrMethodReferenceExpressionImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyASTPsiElementImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.GrListOrMapImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.GrThrowsClauseImpl; @@ -205,6 +206,7 @@ public class GroovyPsiCreator { //Paths if (elem == REFERENCE_EXPRESSION) return new GrReferenceExpressionImpl(node); + if (elem == METHOD_REFERENCE_EXPRESSION) return new GrMethodReferenceExpressionImpl(node); if (elem == PROPERTY_EXPRESSION) return new GrPropertySelectionImpl(node); if (elem == METHOD_CALL_EXPRESSION) return new GrMethodCallExpressionImpl(node); if (elem == INDEX_EXPRESSION) return new GrIndexPropertyImpl(node); 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 3318a2cba0c6..d08652f1e307 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 @@ -173,7 +173,6 @@ extends(".*_expression") = expression extends(".*_type_element") = type_element elementType('.*_modifier_list') = modifier_list - elementType('.*_reference_expression') = reference_expression elementType('.*_class_type_element') = class_type_element consumeTokenMethod('.*_expression') = 'consumeTokenFast' consumeTokenMethod('.*_expression_tail') = 'consumeTokenFast' @@ -851,7 +850,7 @@ private priority0 ::= unqualified_reference_expression unqualified_reference_expression ::= IDENTIFIER | 'this' | 'super' - | ('in' | 'def' | 'trait') &dot + | ('in' | 'def' | 'trait') &(reference_dot | '.&') | (STR_SQ | STR_DQ) &string_literal_as_reference { elementType = reference_expression @@ -968,15 +967,17 @@ private non_empty_list_or_map ::= '[' bracket_argument_list_item bracket_argumen pin = 2 } -private qualified_expressions ::= qualified_reference_expression | property_expression -qualified_reference_expression ::= expression <> -property_expression ::= expression <> -private meta qualified_reference_op ::= (mb_nl dot) <>)>> -private dot ::= '.' attribute_dot? | '?.' attribute_dot? | '.&' | '*.' { consumeTokenMethod = 'consumeTokenFast' } -private attribute_dot ::= mb_nl ('@') +private qualified_expressions ::= method_reference_expression | qualified_reference_expression | property_expression +method_reference_expression ::= expression (mb_nl method_reference_dot) (mb_nl qualified_reference_expression_identifiers) +qualified_reference_expression ::= expression (mb_nl reference_dot) <> { - consumeTokenMethod = 'consumeTokenFast' + elementType = reference_expression } +property_expression ::= expression (mb_nl property_dot) <> +private method_reference_dot ::= '.&' { consumeTokenMethod = 'consumeTokenFast' } +private reference_dot ::= '.' attribute_dot? | '?.' attribute_dot? | '*.' { consumeTokenMethod = 'consumeTokenFast' } +private attribute_dot ::= mb_nl ('@') { consumeTokenMethod = 'consumeTokenFast' } +private property_dot ::= reference_dot | method_reference_dot private qualified_reference_expression_identifiers ::= IDENTIFIER | STR_SQ | STR_DQ | regex_literal diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMethodReferenceExpressionImpl.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMethodReferenceExpressionImpl.kt new file mode 100644 index 000000000000..0c1696e094a0 --- /dev/null +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/GrMethodReferenceExpressionImpl.kt @@ -0,0 +1,12 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.jetbrains.plugins.groovy.lang.psi.impl + +import com.intellij.lang.ASTNode +import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceExpressionImpl + +class GrMethodReferenceExpressionImpl(node: ASTNode) : GrReferenceExpressionImpl(node) { + + override fun hasMemberPointer(): Boolean = true + + override fun toString(): String = "Method reference expression" +} diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java index 27d01cb956a9..64c379f1f7ee 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java @@ -479,7 +479,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl