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 2020/08/23 23:52:45 UTC

[groovy] 01/02: GROOVY-9692: "call" method call for non-string expression w/ closure arg

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

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

commit 3ddc1a27f6af4c24776045dad737adcbf0d379b7
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Aug 23 15:11:02 2020 -0500

    GROOVY-9692: "call" method call for non-string expression w/ closure arg
    
    closes #1348
    
    (cherry picked from commit 0a690d58462d4d8e8bae936b1a9b330491ab4a57)
---
 .../apache/groovy/parser/antlr4/AstBuilder.java    | 110 +++++++++------------
 1 file changed, 45 insertions(+), 65 deletions(-)

diff --git a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index 0721c14..dff4de2 100644
--- a/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/subprojects/parser-antlr4/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -2265,15 +2265,13 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
 
 
             if (asBoolean(ctx.DOT())) {
-                boolean isSafeChain = isTrue(baseExpr, PATH_EXPRESSION_BASE_EXPR_SAFE_CHAIN);
-
-                return createDotExpression(ctx, baseExpr, namePartExpr, genericsTypes, isSafeChain);
+                boolean isSafeChain = this.isTrue(baseExpr, PATH_EXPRESSION_BASE_EXPR_SAFE_CHAIN);
+                return this.createDotExpression(ctx, baseExpr, namePartExpr, genericsTypes, isSafeChain);
             } else if (asBoolean(ctx.SAFE_DOT())) {
-                return createDotExpression(ctx, baseExpr, namePartExpr, genericsTypes, true);
+                return this.createDotExpression(ctx, baseExpr, namePartExpr, genericsTypes, true);
             } else if (asBoolean(ctx.SAFE_CHAIN_DOT())) { // e.g. obj??.a  OR obj??.@a
                 Expression expression = createDotExpression(ctx, baseExpr, namePartExpr, genericsTypes, true);
                 expression.putNodeMetaData(PATH_EXPRESSION_BASE_EXPR_SAFE_CHAIN, true);
-
                 return expression;
             } else if (asBoolean(ctx.METHOD_POINTER())) { // e.g. obj.&m
                 return configureAST(new MethodPointerExpression(baseExpr, namePartExpr), ctx);
@@ -2282,34 +2280,27 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
             } else if (asBoolean(ctx.SPREAD_DOT())) {
                 if (asBoolean(ctx.AT())) { // e.g. obj*.@a
                     AttributeExpression attributeExpression = new AttributeExpression(baseExpr, namePartExpr, true);
-
                     attributeExpression.setSpreadSafe(true);
-
                     return configureAST(attributeExpression, ctx);
                 } else { // e.g. obj*.p
                     PropertyExpression propertyExpression = new PropertyExpression(baseExpr, namePartExpr, true);
                     propertyExpression.putNodeMetaData(PATH_EXPRESSION_BASE_EXPR_GENERICS_TYPES, genericsTypes);
-
                     propertyExpression.setSpreadSafe(true);
-
                     return configureAST(propertyExpression, ctx);
                 }
             }
         } else if (asBoolean(ctx.creator())) {
             CreatorContext creatorContext = ctx.creator();
             creatorContext.putNodeMetaData(ENCLOSING_INSTANCE_EXPRESSION, baseExpr);
-
             return configureAST(this.visitCreator(creatorContext), ctx);
         } else if (asBoolean(ctx.indexPropertyArgs())) { // e.g. list[1, 3, 5]
             Tuple2<Token, Expression> tuple = this.visitIndexPropertyArgs(ctx.indexPropertyArgs());
-            boolean isSafeChain = isTrue(baseExpr, PATH_EXPRESSION_BASE_EXPR_SAFE_CHAIN);
-
+            boolean isSafeChain = this.isTrue(baseExpr, PATH_EXPRESSION_BASE_EXPR_SAFE_CHAIN);
             return configureAST(
                     new BinaryExpression(baseExpr, createGroovyToken(tuple.getV1()), tuple.getV2(), isSafeChain || asBoolean(ctx.indexPropertyArgs().QUESTION())),
                     ctx);
         } else if (asBoolean(ctx.namedPropertyArgs())) { // this is a special way to signify a cast, e.g. Person[name: 'Daniel.Sun', location: 'Shanghai']
-            List<MapEntryExpression> mapEntryExpressionList =
-                    this.visitNamedPropertyArgs(ctx.namedPropertyArgs());
+            List<MapEntryExpression> mapEntryExpressionList = this.visitNamedPropertyArgs(ctx.namedPropertyArgs());
 
             Expression right;
             Expression firstKeyExpression;
@@ -2356,32 +2347,28 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
             if (baseExpr instanceof AttributeExpression) { // e.g. obj.@a(1, 2)
                 AttributeExpression attributeExpression = (AttributeExpression) baseExpr;
                 attributeExpression.setSpreadSafe(false); // whether attributeExpression is spread safe or not, we must reset it as false
-
                 return configureAST(createCallMethodCallExpression(attributeExpression, argumentsExpr, true), ctx);
             }
 
             if (baseExpr instanceof PropertyExpression) { // e.g. obj.a(1, 2)
-                MethodCallExpression methodCallExpression =
-                        this.createMethodCallExpression((PropertyExpression) baseExpr, argumentsExpr);
-
+                MethodCallExpression methodCallExpression = this.createMethodCallExpression((PropertyExpression) baseExpr, argumentsExpr);
                 return configureAST(methodCallExpression, ctx);
             }
 
             if (baseExpr instanceof VariableExpression) { // void and primitive type AST node must be an instance of VariableExpression
                 String baseExprText = baseExpr.getText();
                 if (VOID_STR.equals(baseExprText)) { // e.g. void()
-                    return configureAST(createCallMethodCallExpression(this.createConstantExpression(baseExpr), argumentsExpr), ctx);
+                    return configureAST(this.createCallMethodCallExpression(this.createConstantExpression(baseExpr), argumentsExpr), ctx);
                 } else if (isPrimitiveType(baseExprText)) { // e.g. int(), long(), float(), etc.
-                    throw createParsingFailedException("Primitive type literal: " + baseExprText + " cannot be used as a method name", ctx);
+                    throw this.createParsingFailedException("Primitive type literal: " + baseExprText + " cannot be used as a method name", ctx);
                 }
             }
 
-            if (baseExpr instanceof VariableExpression
-                    || baseExpr instanceof GStringExpression
-                    || (baseExpr instanceof ConstantExpression && isTrue(baseExpr, IS_STRING))) { // e.g. m(), "$m"(), "m"()
-
+            if (baseExpr instanceof VariableExpression // e.g. m()
+                    || baseExpr instanceof GStringExpression // e.g. "$m"()
+                    || (baseExpr instanceof ConstantExpression && this.isTrue(baseExpr, IS_STRING))) { // e.g. "m"()
                 String baseExprText = baseExpr.getText();
-                if (SUPER_STR.equals(baseExprText) || THIS_STR.equals(baseExprText)) { // e.g. this(...), super(...)
+                if (THIS_STR.equals(baseExprText) || SUPER_STR.equals(baseExprText)) { // e.g. this(...), super(...)
                     // class declaration is not allowed in the closure,
                     // so if this and super is inside the closure, it will not be constructor call.
                     // e.g. src/test/org/codehaus/groovy/transform/MapConstructorTransformTest.groovy:
@@ -2406,14 +2393,13 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
                             ctx);
                 }
 
-                MethodCallExpression methodCallExpression =
-                        this.createMethodCallExpression(baseExpr, argumentsExpr);
-
+                MethodCallExpression methodCallExpression = this.createMethodCallExpression(baseExpr, argumentsExpr);
                 return configureAST(methodCallExpression, ctx);
             }
 
             // e.g. 1(), 1.1(), ((int) 1 / 2)(1, 2), {a, b -> a + b }(1, 2), m()()
-            return configureAST(createCallMethodCallExpression(baseExpr, argumentsExpr), ctx);
+            return configureAST(this.createCallMethodCallExpression(baseExpr, argumentsExpr), ctx);
+
         } else if (asBoolean(ctx.closureOrLambdaExpression())) {
             ClosureExpression closureExpression = this.visitClosureOrLambdaExpression(ctx.closureOrLambdaExpression());
 
@@ -2424,7 +2410,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
                 if (argumentsExpression instanceof ArgumentListExpression) { // normal arguments, e.g. 1, 2
                     ArgumentListExpression argumentListExpression = (ArgumentListExpression) argumentsExpression;
                     argumentListExpression.getExpressions().add(closureExpression);
-
                     return configureAST(methodCallExpression, ctx);
                 }
 
@@ -2436,13 +2421,11 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
                         methodCallExpression.setArguments(
                                 configureAST(
                                         new ArgumentListExpression(
-                                                Stream.of(
-                                                        configureAST(
-                                                                new MapExpression(namedArgumentListExpression.getMapEntryExpressions()),
-                                                                namedArgumentListExpression
-                                                        ),
-                                                        closureExpression
-                                                ).collect(Collectors.toList())
+                                                configureAST(
+                                                        new MapExpression(namedArgumentListExpression.getMapEntryExpressions()),
+                                                        namedArgumentListExpression
+                                                ),
+                                                closureExpression
                                         ),
                                         tupleExpression
                                 )
@@ -2452,32 +2435,34 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
                         methodCallExpression.setArguments(
                                 configureAST(
                                         new ArgumentListExpression(closureExpression),
-                                        tupleExpression));
+                                        tupleExpression
+                                )
+                        );
                     }
 
-
                     return configureAST(methodCallExpression, ctx);
                 }
-
-            }
-
-            // e.g. 1 {}, 1.1 {}
-            if (baseExpr instanceof ConstantExpression && isTrue(baseExpr, IS_NUMERIC)) {
-                return configureAST(this.createCallMethodCallExpression(
-                        baseExpr,
-                        configureAST(
-                                new ArgumentListExpression(closureExpression),
-                                closureExpression)
-                ), ctx);
             }
 
+            if (baseExpr instanceof PropertyExpression) { // e.g. obj.m { }
+                MethodCallExpression methodCallExpression =
+                        this.createMethodCallExpression(
+                                (PropertyExpression) baseExpr,
+                                configureAST(
+                                        new ArgumentListExpression(closureExpression),
+                                        closureExpression
+                                )
+                        );
 
-            if (baseExpr instanceof PropertyExpression) { // e.g. obj.m {  }
-                PropertyExpression propertyExpression = (PropertyExpression) baseExpr;
+                return configureAST(methodCallExpression, ctx);
+            }
 
+            if (baseExpr instanceof VariableExpression // e.g. m { }
+                    || baseExpr instanceof GStringExpression // e.g. "$m" { }
+                    || (baseExpr instanceof ConstantExpression && this.isTrue(baseExpr, IS_STRING))) { // e.g. "m" { }
                 MethodCallExpression methodCallExpression =
                         this.createMethodCallExpression(
-                                propertyExpression,
+                                baseExpr,
                                 configureAST(
                                         new ArgumentListExpression(closureExpression),
                                         closureExpression
@@ -2487,14 +2472,13 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
                 return configureAST(methodCallExpression, ctx);
             }
 
-            // e.g.  m { return 1; }
+            // e.g. 1 { }, 1.1 { }, (1 / 2) { }, m() { }, { -> ... } { }
             MethodCallExpression methodCallExpression =
-                    createMethodCallExpression(
-                            baseExpr,
-                            configureAST(
-                                    new ArgumentListExpression(closureExpression),
-                                    closureExpression
-                            )
+                    this.createCallMethodCallExpression(
+                        baseExpr,
+                        configureAST(
+                                new ArgumentListExpression(closureExpression),
+                                closureExpression)
                     );
 
             return configureAST(methodCallExpression, ctx);
@@ -2509,7 +2493,6 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
         } else { // e.g. obj.p  OR  obj?.p
             PropertyExpression propertyExpression = new PropertyExpression(baseExpr, namePartExpr, safe);
             propertyExpression.putNodeMetaData(PATH_EXPRESSION_BASE_EXPR_GENERICS_TYPES, genericsTypes);
-
             return configureAST(propertyExpression, ctx);
         }
     }
@@ -2519,11 +2502,8 @@ public class AstBuilder extends GroovyParserBaseVisitor<Object> {
     }
 
     private MethodCallExpression createCallMethodCallExpression(Expression baseExpr, Expression argumentsExpr, boolean implicitThis) {
-        MethodCallExpression methodCallExpression =
-                new MethodCallExpression(baseExpr, CALL_STR, argumentsExpr);
-
+        MethodCallExpression methodCallExpression = new MethodCallExpression(baseExpr, CALL_STR, argumentsExpr);
         methodCallExpression.setImplicitThis(implicitThis);
-
         return methodCallExpression;
     }