mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[groovy] 'for': parse expression list in update (IDEA-188433)
This commit is contained in:
+46
-3
@@ -141,6 +141,9 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
else if (t == EXPRESSION) {
|
||||
r = expression(b, 0, -1);
|
||||
}
|
||||
else if (t == EXPRESSION_LIST) {
|
||||
r = expression_list(b, 0);
|
||||
}
|
||||
else if (t == FIELD) {
|
||||
r = field(b, 0);
|
||||
}
|
||||
@@ -3161,6 +3164,40 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// expression (',' expression)*
|
||||
public static boolean expression_list(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "expression_list")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b, l, _NONE_, EXPRESSION_LIST, "<expression list>");
|
||||
r = expression(b, l + 1, -1);
|
||||
r = r && expression_list_1(b, l + 1);
|
||||
exit_section_(b, l, m, r, false, null);
|
||||
return r;
|
||||
}
|
||||
|
||||
// (',' expression)*
|
||||
private static boolean expression_list_1(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "expression_list_1")) return false;
|
||||
while (true) {
|
||||
int c = current_position_(b);
|
||||
if (!expression_list_1_0(b, l + 1)) break;
|
||||
if (!empty_element_parsed_guard_(b, "expression_list_1", c)) break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ',' expression
|
||||
private static boolean expression_list_1_0(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "expression_list_1_0")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b);
|
||||
r = consumeToken(b, T_COMMA);
|
||||
r = r && expression(b, l + 1, -1);
|
||||
exit_section_(b, m, null, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// <<notApplicationArguments expression_or_application_inner>>
|
||||
public static boolean expression_or_application(PsiBuilder b, int l) {
|
||||
@@ -3462,6 +3499,12 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// expression_list
|
||||
static boolean for_clause_update(PsiBuilder b, int l) {
|
||||
return expression_list(b, l + 1);
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// '(' mb_nl for_clause mb_nl ')'
|
||||
static boolean for_header(PsiBuilder b, int l) {
|
||||
@@ -6044,7 +6087,7 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// empty for_clause_initialization? ';' expression? ';' mb_nl expression?
|
||||
// empty for_clause_initialization? ';' expression? ';' mb_nl for_clause_update?
|
||||
public static boolean traditional_for_clause(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "traditional_for_clause")) return false;
|
||||
boolean r, p;
|
||||
@@ -6075,10 +6118,10 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
return true;
|
||||
}
|
||||
|
||||
// expression?
|
||||
// for_clause_update?
|
||||
private static boolean traditional_for_clause_6(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "traditional_for_clause_6")) return false;
|
||||
expression(b, l + 1, -1);
|
||||
for_clause_update(b, l + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -90,6 +90,7 @@ public interface GroovyElementTypes {
|
||||
GrEnumDefinitionElementType ENUM_TYPE_DEFINITION = new GrEnumDefinitionElementType("ENUM_TYPE_DEFINITION");
|
||||
GroovyElementType EQUALITY_EXPRESSION = new GroovyElementType("EQUALITY_EXPRESSION");
|
||||
GroovyElementType EXPRESSION = new GroovyElementType("EXPRESSION");
|
||||
GroovyElementType EXPRESSION_LIST = new GroovyElementType("EXPRESSION_LIST");
|
||||
GrExtendsClauseElementType EXTENDS_CLAUSE = new GrExtendsClauseElementType("EXTENDS_CLAUSE");
|
||||
GrFieldElementType FIELD = new GrFieldElementType("FIELD");
|
||||
GroovyElementType FINALLY_CLAUSE = new GroovyElementType("FINALLY_CLAUSE");
|
||||
|
||||
+1
@@ -97,6 +97,7 @@ public class GroovyPsiCreator {
|
||||
if (elem == FOR_STATEMENT) return new GrForStatementImpl(node);
|
||||
if (elem == FOR_IN_CLAUSE) return new GrForInClauseImpl(node);
|
||||
if (elem == TRADITIONAL_FOR_CLAUSE) return new GrTraditionalForClauseImpl(node);
|
||||
if (elem == EXPRESSION_LIST) return new GrExpressionListImpl(node);
|
||||
if (elem == WHILE_STATEMENT) return new GrWhileStatementImpl(node);
|
||||
if (elem == DO_WHILE_STATEMENT) return new GrDoWhileStatementImpl(node);
|
||||
if (elem == TRY_STATEMENT) return new GrTryCatchStatementImpl(node);
|
||||
|
||||
@@ -746,11 +746,15 @@ private for_clause ::= for_in_clause | traditional_for_clause
|
||||
for_in_clause ::= for_in_parameter (':' | 'in') expression { consumeTokenMethod = 'consumeTokenFast' }
|
||||
for_in_parameter ::= modifier_list mb_type_element IDENTIFIER | clear_variants_and_fail { elementType = parameter }
|
||||
|
||||
traditional_for_clause ::= empty for_clause_initialization? ';' expression? ';' mb_nl expression? { pin = 1 }
|
||||
traditional_for_clause ::= empty for_clause_initialization? ';' expression? ';' mb_nl for_clause_update? { pin = 1 }
|
||||
private for_clause_initialization ::= traditional_for_parameter | expression | clear_variants_and_fail
|
||||
traditional_for_parameter ::= traditional_for_parameter_inner mb_initializer { elementType = parameter }
|
||||
private traditional_for_parameter_inner ::= non_empty_modifier_list mb_type_element IDENTIFIER
|
||||
| empty_modifier_list type_element IDENTIFIER
|
||||
|
||||
private for_clause_update ::= expression_list
|
||||
expression_list ::= expression (',' expression)*
|
||||
|
||||
// FIXME get rid of this weird logic
|
||||
private for_body ::= &<<extendedStatement>> | &';' | block_or_statement { name = 'loop body' }
|
||||
|
||||
|
||||
+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.GroovyPsiElement;
|
||||
|
||||
public interface GrExpressionList extends GroovyPsiElement {
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// 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.GrExpressionList
|
||||
|
||||
class GrExpressionListImpl(node: ASTNode) : GroovyPsiElementImpl(node), GrExpressionList {
|
||||
|
||||
override fun toString(): String = "Expression list"
|
||||
}
|
||||
+2
@@ -121,6 +121,8 @@ class StatementsParsingTest extends GroovyParsingTestCase {
|
||||
|
||||
void testFor$for9() throws Throwable { doTest() }
|
||||
|
||||
void testFor$for14() throws Throwable { doTest() }
|
||||
|
||||
void testFor$idenfierAfterLParen() { doTest() }
|
||||
|
||||
void testFor$keywordOnly() { doTest() }
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
for (;; 1, 2, 3) {}
|
||||
-----
|
||||
Groovy script
|
||||
For statement
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(()('(')
|
||||
Traditional FOR clause
|
||||
PsiElement(;)(';')
|
||||
PsiElement(;)(';')
|
||||
PsiWhiteSpace(' ')
|
||||
Expression list
|
||||
Literal
|
||||
PsiElement(Integer)('1')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
Literal
|
||||
PsiElement(Integer)('2')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
Literal
|
||||
PsiElement(Integer)('3')
|
||||
PsiElement())(')')
|
||||
PsiWhiteSpace(' ')
|
||||
Block statement
|
||||
Open block
|
||||
PsiElement({)('{')
|
||||
PsiElement(})('}')
|
||||
@@ -26,10 +26,11 @@ Groovy script
|
||||
PsiElement(Integer)('5')
|
||||
PsiElement(;)(';')
|
||||
PsiWhiteSpace(' ')
|
||||
Unary expression
|
||||
Reference expression
|
||||
PsiElement(identifier)('i')
|
||||
PsiElement(++)('++')
|
||||
Expression list
|
||||
Unary expression
|
||||
Reference expression
|
||||
PsiElement(identifier)('i')
|
||||
PsiElement(++)('++')
|
||||
PsiElement())(')')
|
||||
Block statement
|
||||
Open block
|
||||
|
||||
Reference in New Issue
Block a user