[groovy] add separate element for method reference expressions

This commit is contained in:
Daniil Ovchinnikov
2018-06-02 22:21:50 +03:00
parent 35c5674928
commit d3f55d085c
7 changed files with 236 additions and 122 deletions
@@ -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) <<mb_nl_group (type_argument_list? <<identifiers>>)>>
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? <<identifiers>>
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) <<mb_nl_group (type_argument_list? qualified_reference_expression_identifiers)>>
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) <<mb_nl_group (type_argument_list? property_expression_identifiers)>>
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;
}
// <<parseBlockLazy closure 'CLOSURE'>>
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() {
@@ -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");
@@ -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);
@@ -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 <<qualified_reference_op qualified_reference_expression_identifiers>>
property_expression ::= expression <<qualified_reference_op property_expression_identifiers>>
private meta qualified_reference_op ::= (mb_nl dot) <<mb_nl_group (type_argument_list? <<identifiers>>)>>
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) <<mb_nl_group (type_argument_list? qualified_reference_expression_identifiers)>>
{
consumeTokenMethod = 'consumeTokenFast'
elementType = reference_expression
}
property_expression ::= expression (mb_nl property_dot) <<mb_nl_group (type_argument_list? property_expression_identifiers)>>
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
@@ -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"
}
@@ -479,7 +479,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
@Override
public boolean hasMemberPointer() {
return findChildByType(GroovyTokenTypes.mMEMBER_POINTER) != null;
return false;
}
@Override
@@ -32,7 +32,7 @@ Groovy script
PsiElement(*.)('*.')
PsiElement(identifier)('bar')
PsiElement(new line)('\n\n')
Reference expression
Method reference expression
Reference expression
PsiElement(identifier)('foo')
PsiElement(new line)('\n ')