You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2023/05/16 15:42:47 UTC

[groovy] branch master updated: GROOVY-11056: in-closure reference to static import of callable property

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 7a11801059 GROOVY-11056: in-closure reference to static import of callable property
7a11801059 is described below

commit 7a118010591ca469f0394d8d6946b44201d04ebd
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue May 16 10:21:02 2023 -0500

    GROOVY-11056: in-closure reference to static import of callable property
---
 .../groovy/control/StaticImportVisitor.java        | 23 ++++---
 src/test/groovy/StaticImportTest.groovy            | 79 +++++++++++++---------
 2 files changed, 58 insertions(+), 44 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
index 0dfa7dba6d..ef71676a2a 100644
--- a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
@@ -72,16 +72,19 @@ import static org.codehaus.groovy.ast.tools.GeneralUtils.getSetterName;
  * Visitor to resolve constants and method calls from static imports.
  */
 public class StaticImportVisitor extends ClassCodeExpressionTransformer {
-    private ClassNode currentClass;
-    private MethodNode currentMethod;
+
     private SourceUnit sourceUnit;
-    private boolean inSpecialConstructorCall;
-    private boolean inClosure;
-    private boolean inPropertyExpression;
-    private Expression foundConstant;
+    private ClassNode  currentClass;
+    private MethodNode currentMethod;
+
     private Expression foundArgs;
+    private Expression foundConstant;
+
+    private boolean inClosure;
     private boolean inAnnotation;
     private boolean inLeftExpression;
+    private boolean inPropertyExpression;
+    private boolean inSpecialConstructorCall;
 
     public StaticImportVisitor(final ClassNode classNode, final SourceUnit sourceUnit) {
         this.currentClass = classNode;
@@ -437,10 +440,8 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
         if (staticImports.containsKey(name)) {
             ImportNode importNode = staticImports.get(name);
             expression = findStaticMethod(importNode.getType(), importNode.getFieldName(), args);
-            if (expression != null) {
-                return expression;
-            }
-            if (!inClosure && !inLeftExpression) {
+            if (expression != null) return expression;
+            if (!inLeftExpression) { // GROOVY-11056, et al.
                 expression = findStaticPropertyOrField(importNode.getType(), importNode.getFieldName());
                 if (expression != null) { // assume name refers to a callable static field/property
                     MethodCallExpression call = new MethodCallExpression(expression, "call", args);
@@ -491,7 +492,7 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
             ClassNode importType = importNode.getType();
             expression = findStaticMethod(importType, name, args);
             if (expression != null) return expression;
-            if (!inClosure && !inLeftExpression) { // GROOVY-10329
+            if (!inLeftExpression) { // GROOVY-10329, et al.
                 expression = findStaticPropertyOrField(importType, name);
                 if (expression != null) { // assume name refers to a callable static field/property
                     MethodCallExpression call = new MethodCallExpression(expression, "call", args);
diff --git a/src/test/groovy/StaticImportTest.groovy b/src/test/groovy/StaticImportTest.groovy
index 5110c69af0..b03962927e 100644
--- a/src/test/groovy/StaticImportTest.groovy
+++ b/src/test/groovy/StaticImportTest.groovy
@@ -37,6 +37,7 @@ import static java.util.jar.Attributes.*
 import static java.util.jar.Attributes.Name as AttrName
 import static groovy.Container5087.*
 import static Foo4964.*
+
 import org.codehaus.groovy.runtime.DefaultGroovyMethods as DGM
 
 final class StaticImportTest extends groovy.test.GroovyTestCase {
@@ -350,21 +351,23 @@ final class StaticImportTest extends groovy.test.GroovyTestCase {
     // GROOVY-8389, GROOVY-10329
     void testStaticImportPropertyWithClosure() {
         for (imports in ['import static Foo.bar; import static Foo.baz', 'import static Foo.*']) {
-            assertScript """$imports
-                class Foo {
-                    static Closure<String> bar = { -> 'property' }
-                    static Closure<String> baz = { -> 'property' }
-                }
-                String bar() {
-                    'method'
-                }
-                @groovy.transform.CompileStatic
-                def test() {
-                    bar() + ':' + baz()
-                }
-                String result = test()
-                assert result == 'method:property'
-            """
+            for (tag in ['@groovy.transform.CompileDynamic', '@groovy.transform.CompileStatic']) {
+                assertScript """$imports
+                    class Foo {
+                        static Closure<String> bar = { -> 'property' }
+                        static Closure<String> baz = { -> 'property' }
+                    }
+                    String bar() {
+                        'method'
+                    }
+                    $tag
+                    String test() {
+                        bar() + ':' + baz()
+                    }
+                    String result = test()
+                    assert result == 'method:property'
+                """
+            }
         }
     }
 
@@ -463,36 +466,46 @@ final class StaticImportTest extends groovy.test.GroovyTestCase {
         } catch (MissingMethodException expected) {}
     }
 
-    // GROOVY-3945, GROOVY-10329
+    // GROOVY-3945, GROOVY-10329, GROOVY-11056
     void testStaticImportOfClosureProperty() {
         for (imports in ['import static groovy.StaticImportTarget.cl', 'import static groovy.StaticImportTarget.*']) {
             assertScript """$imports
                 String result = cl()
                 assert result == 'StaticImportTarget#static closure called'
             """
+            assertScript """$imports
+                def fn = { -> cl() }
+                String result = fn()
+                assert result == 'StaticImportTarget#static closure called'
+            """
         }
+
+        assertScript """import static groovy.StaticImportTarget.cl as fn
+            String result = fn()
+            assert result == 'StaticImportTarget#static closure called'
+        """
     }
 
-    // GROOVY-7490, GROOVY-10329
+    // GROOVY-7490, GROOVY-10329, GROOVY-11056
     void testStaticImportOfCallableProperty() {
         for (imports in ['import static Pogo.callable_property', 'import static Pogo.*']) {
-            assertScript """$imports
-                class WithCall {
-                    String call(String input) {
-                        return input
+            for (use in ['@groovy.transform.CompileStatic caller()', 'def caller()', 'def caller =']) {
+                assertScript """$imports
+                    class WithCall {
+                        String call(String input) {
+                            return input
+                        }
                     }
-                }
-                class Pogo {
-                    static final WithCall callable_property = new WithCall()
-                }
-
-                @groovy.transform.CompileStatic
-                def usage() {
-                    callable_property('works')
-                }
-                String result = usage()
-                assert result == 'works'
-            """
+                    class Pogo {
+                        static final WithCall callable_property = new WithCall()
+                    }
+                    $use {
+                        callable_property('works')
+                    }
+                    String result = caller()
+                    assert result == 'works'
+                """
+            }
         }
     }