mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[groovy] parse negated in and instanceof (IDEA-188424)
This commit is contained in:
+70
-25
@@ -269,12 +269,12 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
BAND_EXPRESSION, BOR_EXPRESSION, BUILT_IN_TYPE_EXPRESSION, CAST_EXPRESSION,
|
||||
CLOSURE, CONSTRUCTOR_CALL_EXPRESSION, ELVIS_EXPRESSION, EQUALITY_EXPRESSION,
|
||||
EXPRESSION, GSTRING, INDEX_EXPRESSION, INSTANCEOF_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),
|
||||
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),
|
||||
};
|
||||
|
||||
/* ********************************************************** */
|
||||
@@ -3758,6 +3758,40 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// mb_not ('instanceof') (type_element | expect_type)
|
||||
static boolean instanceof_expression_tail(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "instanceof_expression_tail")) return false;
|
||||
if (!nextTokenIsFast(b, T_NOT, KW_INSTANCEOF)) return false;
|
||||
boolean r, p;
|
||||
Marker m = enter_section_(b, l, _NONE_);
|
||||
r = mb_not(b, l + 1);
|
||||
r = r && instanceof_expression_tail_1(b, l + 1);
|
||||
p = r; // pin = 2
|
||||
r = r && instanceof_expression_tail_2(b, l + 1);
|
||||
exit_section_(b, l, m, r, p, null);
|
||||
return r || p;
|
||||
}
|
||||
|
||||
// ('instanceof')
|
||||
private static boolean instanceof_expression_tail_1(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "instanceof_expression_tail_1")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b);
|
||||
r = consumeTokenFast(b, KW_INSTANCEOF);
|
||||
exit_section_(b, m, null, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
// type_element | expect_type
|
||||
private static boolean instanceof_expression_tail_2(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "instanceof_expression_tail_2")) return false;
|
||||
boolean r;
|
||||
r = type_element(b, l + 1);
|
||||
if (!r) r = expect_type(b, l + 1);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// <<classIdentifier>> type_parameter_list? nl_extends nl_non_empty_implements?
|
||||
static boolean interface_definition_header(PsiBuilder b, int l) {
|
||||
@@ -3940,6 +3974,14 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// '!'?
|
||||
static boolean mb_not(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "mb_not")) return false;
|
||||
consumeTokenFast(b, T_NOT);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// '?'?
|
||||
static boolean mb_question(PsiBuilder b, int l) {
|
||||
@@ -5097,7 +5139,7 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// '<' !'<' | '<=' | '>' !'>' | '>=' | 'in'
|
||||
// '<' !'<' | '<=' | '>' !'>' | '>='
|
||||
static boolean relational_operator(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "relational_operator")) return false;
|
||||
boolean r;
|
||||
@@ -5106,7 +5148,6 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
if (!r) r = consumeTokenFast(b, T_LE);
|
||||
if (!r) r = relational_operator_2(b, l + 1);
|
||||
if (!r) r = consumeTokenFast(b, T_GE);
|
||||
if (!r) r = consumeTokenFast(b, KW_IN);
|
||||
exit_section_(b, m, null, r);
|
||||
return r;
|
||||
}
|
||||
@@ -6592,7 +6633,7 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
// 5: BINARY(xor_expression)
|
||||
// 6: BINARY(band_expression)
|
||||
// 7: BINARY(equality_expression) BINARY(compare_expression) BINARY(regex_find_expression) BINARY(regex_match_expression)
|
||||
// 8: BINARY(relational_expression) POSTFIX(instanceof_expression) POSTFIX(as_expression)
|
||||
// 8: BINARY(relational_expression) BINARY(in_expression) POSTFIX(instanceof_expression) POSTFIX(as_expression)
|
||||
// 9: BINARY(shift_expression) BINARY(range_expression)
|
||||
// 10: BINARY(additive_expression)
|
||||
// 11: BINARY(multiplicative_expression)
|
||||
@@ -6688,7 +6729,11 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
r = expression(b, l, 8);
|
||||
exit_section_(b, l, m, RELATIONAL_EXPRESSION, r, true, null);
|
||||
}
|
||||
else if (g < 8 && instanceof_expression_0(b, l + 1)) {
|
||||
else if (g < 8 && in_expression_0(b, l + 1)) {
|
||||
r = expression(b, l, 8);
|
||||
exit_section_(b, l, m, IN_EXPRESSION, r, true, null);
|
||||
}
|
||||
else if (g < 8 && instanceof_expression_tail(b, l + 1)) {
|
||||
r = true;
|
||||
exit_section_(b, l, m, INSTANCEOF_EXPRESSION, r, true, null);
|
||||
}
|
||||
@@ -6842,24 +6887,24 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
return r;
|
||||
}
|
||||
|
||||
// 'instanceof' (type_element | expect_type)
|
||||
private static boolean instanceof_expression_0(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "instanceof_expression_0")) return false;
|
||||
boolean r, p;
|
||||
Marker m = enter_section_(b, l, _NONE_);
|
||||
r = consumeTokenSmart(b, KW_INSTANCEOF);
|
||||
p = r; // pin = 1
|
||||
r = r && instanceof_expression_0_1(b, l + 1);
|
||||
exit_section_(b, l, m, r, p, null);
|
||||
return r || p;
|
||||
// mb_not ('in')
|
||||
private static boolean in_expression_0(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "in_expression_0")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b);
|
||||
r = mb_not(b, l + 1);
|
||||
r = r && in_expression_0_1(b, l + 1);
|
||||
exit_section_(b, m, null, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
// type_element | expect_type
|
||||
private static boolean instanceof_expression_0_1(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "instanceof_expression_0_1")) return false;
|
||||
// ('in')
|
||||
private static boolean in_expression_0_1(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "in_expression_0_1")) return false;
|
||||
boolean r;
|
||||
r = type_element(b, l + 1);
|
||||
if (!r) r = expect_type(b, l + 1);
|
||||
Marker m = enter_section_(b);
|
||||
r = consumeTokenSmart(b, KW_IN);
|
||||
exit_section_(b, m, null, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -102,6 +102,7 @@ public interface GroovyElementTypes {
|
||||
GroovyElementType INDEX_EXPRESSION = new GroovyElementType("INDEX_EXPRESSION");
|
||||
GroovyElementType INSTANCEOF_EXPRESSION = new GroovyElementType("INSTANCEOF_EXPRESSION");
|
||||
GrInterfaceDefinitionElementType INTERFACE_TYPE_DEFINITION = new GrInterfaceDefinitionElementType("INTERFACE_TYPE_DEFINITION");
|
||||
GroovyElementType IN_EXPRESSION = new GroovyElementType("IN_EXPRESSION");
|
||||
GroovyElementType LABELED_STATEMENT = new GroovyElementType("LABELED_STATEMENT");
|
||||
GroovyElementType LAND_EXPRESSION = new GroovyElementType("LAND_EXPRESSION");
|
||||
GroovyElementType LEFT_SHIFT_SIGN = new GroovyElementType("LEFT_SHIFT_SIGN");
|
||||
|
||||
+2
@@ -9,6 +9,7 @@ import org.jetbrains.plugins.groovy.lang.groovydoc.lexer.IGroovyDocElementType;
|
||||
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.GroovyASTPsiElementImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.GrListOrMapImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.GrThrowsClauseImpl;
|
||||
@@ -182,6 +183,7 @@ public class GroovyPsiCreator {
|
||||
if (elem == REGEX_FIND_EXPRESSION) return new GrRegexFindExpressionImpl(node);
|
||||
if (elem == EQUALITY_EXPRESSION) return new GrRelationalExpressionImpl(node);
|
||||
if (elem == RELATIONAL_EXPRESSION) return new GrRelationalExpressionImpl(node);
|
||||
if (elem == IN_EXPRESSION) return new GrInExpressionImpl(node);
|
||||
if (elem == SHIFT_EXPRESSION) return new GrShiftExpressionImpl(node);
|
||||
if (elem == RANGE_EXPRESSION) return new GrRangeExpressionImpl(node);
|
||||
if (elem == ADDITIVE_EXPRESSION) return new GrAdditiveExpressionImpl(node);
|
||||
|
||||
@@ -176,6 +176,7 @@
|
||||
elementType('.*_reference_expression') = reference_expression
|
||||
elementType('.*_class_type_element') = class_type_element
|
||||
consumeTokenMethod('.*_expression') = 'consumeTokenFast'
|
||||
consumeTokenMethod('.*_expression_tail') = 'consumeTokenFast'
|
||||
consumeTokenMethod('.*_shift.*_sign') = 'consumeTokenFast'
|
||||
consumeTokenMethod('fast.*') = 'consumeTokenFast'
|
||||
consumeTokenMethod('.*_type_definition') = 'consumeTokenFast'
|
||||
@@ -1039,14 +1040,12 @@ right_shift_sign ::= '>' '>'
|
||||
right_shift_unsigned_sign ::= '>' '>' '>'
|
||||
range_expression ::= expression ('..' | '..<') expression
|
||||
|
||||
private priority7 ::= relational_expression | instanceof_expression | as_expression
|
||||
private priority7 ::= relational_expression | in_expression | instanceof_expression | as_expression
|
||||
relational_expression ::= expression relational_operator mb_nl expression
|
||||
private relational_operator ::= '<' !'<' | '<=' | '>' !'>' | '>=' | 'in' { consumeTokenMethod = 'consumeTokenFast' }
|
||||
|
||||
instanceof_expression ::= expression ('instanceof' (type_element | expect_type))
|
||||
{
|
||||
pin('.*') = 1
|
||||
}
|
||||
private relational_operator ::= '<' !'<' | '<=' | '>' !'>' | '>=' { consumeTokenMethod = 'consumeTokenFast' }
|
||||
in_expression ::= expression mb_not ('in') expression
|
||||
instanceof_expression ::= expression instanceof_expression_tail
|
||||
private instanceof_expression_tail ::= mb_not ('instanceof') (type_element | expect_type) { pin = 2 }
|
||||
as_expression ::= expression 'as' type_element
|
||||
|
||||
private priority8 ::= equality_expression | compare_expression | regex_find_expression | regex_match_expression
|
||||
@@ -1239,6 +1238,7 @@ private meta mb_nl_group ::= <<something>> | <<withProtectedLastVariantPos (nl <
|
||||
private empty ::= ()
|
||||
|
||||
private mb_question ::= '?'? { consumeTokenMethod = 'consumeTokenFast' }
|
||||
private mb_not ::= '!'? { consumeTokenMethod = 'consumeTokenFast' }
|
||||
|
||||
private fast_colon ::= ':'
|
||||
private fast_comma ::= ','
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// 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.api;
|
||||
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
|
||||
|
||||
public interface GrInExpression extends GrBinaryExpression {
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// 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.api.GrInExpression
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrBinaryExpressionImpl
|
||||
|
||||
class GrInExpressionImpl(node: ASTNode) : GrBinaryExpressionImpl(node), GrInExpression {
|
||||
|
||||
override fun toString(): String = "${javaClass.simpleName}(${node.elementType})"
|
||||
}
|
||||
+6
@@ -464,6 +464,12 @@ class ExpressionsParsingTest extends GroovyParsingTestCase {
|
||||
|
||||
void testrelational$noRValue() { doTest() }
|
||||
|
||||
void testrelational$exclamationAfterExpression() { doTest() }
|
||||
|
||||
void testrelational$inNegated() { doTest() }
|
||||
|
||||
void testrelational$instanceOfNegated() { doTest() }
|
||||
|
||||
void testspecial$grvy1173() throws Throwable { doTest() }
|
||||
|
||||
void testspecial$list1() throws Throwable { doTest() }
|
||||
|
||||
@@ -3,9 +3,9 @@ if (i in String) i = i.substring(2)
|
||||
0(1) element: null
|
||||
1(2) element: IF statement
|
||||
2(3) READ i
|
||||
3(4,6) Condition Relational expression
|
||||
3(4,6) Condition GrInExpressionImpl(IN_EXPRESSION)
|
||||
4(5) instanceof: i in String
|
||||
5(10) Negating goto instruction, condition=3Relational expression
|
||||
5(10) Negating goto instruction, condition=3GrInExpressionImpl(IN_EXPRESSION)
|
||||
6(7) instanceof: i in String
|
||||
7(8) READ i
|
||||
8(9) WRITE i
|
||||
|
||||
@@ -10,7 +10,7 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(=)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
Relational expression
|
||||
GrInExpressionImpl(IN_EXPRESSION)
|
||||
Method call
|
||||
Reference expression
|
||||
PsiElement(identifier)('abc')
|
||||
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
a !
|
||||
-----
|
||||
Groovy script
|
||||
Call expression
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
Command arguments
|
||||
Unary expression
|
||||
PsiElement(!)('!')
|
||||
PsiErrorElement:<expression> expected
|
||||
<empty list>
|
||||
@@ -0,0 +1,12 @@
|
||||
a !in b
|
||||
-----
|
||||
Groovy script
|
||||
GrInExpressionImpl(IN_EXPRESSION)
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(!)('!')
|
||||
PsiElement(in)('in')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('b')
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
a !instanceof b
|
||||
-----
|
||||
Groovy script
|
||||
Instanceof expression
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(!)('!')
|
||||
PsiElement(instanceof)('instanceof')
|
||||
PsiWhiteSpace(' ')
|
||||
Type element
|
||||
Reference element
|
||||
PsiElement(identifier)('b')
|
||||
Reference in New Issue
Block a user