You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2023/11/25 17:28:29 UTC

(groovy) branch GROOVY-11229 updated: Support parsing `instanceof` with pattern variable

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY-11229
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY-11229 by this push:
     new 6fbf01494a Support parsing `instanceof` with pattern variable
6fbf01494a is described below

commit 6fbf01494a2985fea7fbd68cad1e72a48367c140
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sun Nov 26 01:27:58 2023 +0800

    Support parsing `instanceof` with pattern variable
---
 src/antlr/GroovyParser.g4                          |  7 ++++-
 .../apache/groovy/parser/antlr4/AstBuilder.java    | 35 +++++++++++++++++++++-
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/src/antlr/GroovyParser.g4 b/src/antlr/GroovyParser.g4
index 71eeefcecc..bfa6751f56 100644
--- a/src/antlr/GroovyParser.g4
+++ b/src/antlr/GroovyParser.g4
@@ -343,6 +343,10 @@ options { baseContext = type; }
         emptyDimsOpt
     ;
 
+patternVariableDeclaration
+    :   type variableDeclaratorId? // TODO support destructing
+    ;
+
 type
     :   annotationsOpt
         (
@@ -815,7 +819,8 @@ expression
         right=expression                                                                    #shiftExprAlt
 
     // boolean relational expressions (level 7)
-    |   left=expression nls op=(AS | INSTANCEOF | NOT_INSTANCEOF) nls type                  #relationalExprAlt
+    |   left=expression nls op=INSTANCEOF nls patternVariableDeclaration                    #relationalExprAlt
+    |   left=expression nls op=(AS | NOT_INSTANCEOF) nls type                               #relationalExprAlt
     |   left=expression nls op=(LE | GE | GT | LT | IN | NOT_IN)  nls right=expression      #relationalExprAlt
 
     // equality/inequality (==/!=) (level 8)
diff --git a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index 5c98d8d383..75bc5992e8 100644
--- a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -20,7 +20,11 @@ package org.apache.groovy.parser.antlr4;
 
 import groovy.lang.Tuple2;
 import groovy.lang.Tuple3;
-import groovy.transform.*;
+import groovy.transform.CompileStatic;
+import groovy.transform.NonSealed;
+import groovy.transform.Sealed;
+import groovy.transform.Trait;
+import groovy.transform.TupleConstructor;
 import org.antlr.v4.runtime.ANTLRErrorListener;
 import org.antlr.v4.runtime.CharStream;
 import org.antlr.v4.runtime.CharStreams;
@@ -87,6 +91,7 @@ import org.codehaus.groovy.ast.expr.MethodPointerExpression;
 import org.codehaus.groovy.ast.expr.MethodReferenceExpression;
 import org.codehaus.groovy.ast.expr.NamedArgumentListExpression;
 import org.codehaus.groovy.ast.expr.NotExpression;
+import org.codehaus.groovy.ast.expr.PatternVariableExpression;
 import org.codehaus.groovy.ast.expr.PostfixExpression;
 import org.codehaus.groovy.ast.expr.PrefixExpression;
 import org.codehaus.groovy.ast.expr.PropertyExpression;
@@ -3062,6 +3067,17 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
             return configureAST(cast, ctx);
 
           case INSTANCEOF:
+              ctx.patternVariableDeclaration().putNodeMetaData(IS_INSIDE_INSTANCEOF_EXPR, Boolean.TRUE);
+              PatternVariableExpression patternVariableExpression = this.visitPatternVariableDeclaration(ctx.patternVariableDeclaration());
+              ClassNode type = patternVariableExpression.getType();
+              ClassExpression classExpression = configureAST(new ClassExpression(type), type);
+              classExpression.setPatternVariableExpression(patternVariableExpression);
+              return configureAST(
+                  new BinaryExpression(
+                      (Expression) this.visit(ctx.left),
+                      this.createGroovyToken(ctx.op),
+                      classExpression),
+                  ctx);
           case NOT_INSTANCEOF:
             ctx.type().putNodeMetaData(IS_INSIDE_INSTANCEOF_EXPR, Boolean.TRUE);
             return configureAST(
@@ -4000,6 +4016,23 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
         return this.visitEmptyDims(ctx.emptyDims());
     }
 
+    @Override
+    public PatternVariableExpression visitPatternVariableDeclaration(PatternVariableDeclarationContext ctx) {
+        if (isTrue(ctx, IS_INSIDE_INSTANCEOF_EXPR)) {
+            ctx.type().putNodeMetaData(IS_INSIDE_INSTANCEOF_EXPR, Boolean.TRUE);
+        }
+        ClassNode type = this.visitType(ctx.type());
+        PatternVariableExpression patternVariableExpression;
+        if (asBoolean(ctx.variableDeclaratorId())) {
+            VariableExpression variable = this.visitVariableDeclaratorId(ctx.variableDeclaratorId());
+            patternVariableExpression = new PatternVariableExpression(variable.getName(), type);
+        } else {
+            patternVariableExpression = new PatternVariableExpression(type);
+        }
+
+        return configureAST(patternVariableExpression, ctx);
+    }
+
     // type { ------------------------------------------------------------------
 
     @Override