You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2019/01/31 10:33:19 UTC

[groovy] 01/02: GROOVY-8272: Extending trait can't execute static method (closes #865)

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

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

commit cf89b26ba38f16fc96d51386ef402ba278173be8
Author: Paul King <pa...@asert.com.au>
AuthorDate: Tue Jan 29 15:57:09 2019 +1000

    GROOVY-8272: Extending trait can't execute static method (closes #865)
---
 .../transform/stc/TraitTypeCheckingExtension.java  | 27 ++++++++++++++--------
 .../traitx/TraitASTTransformationTest.groovy       | 25 ++++++++++++++++++++
 2 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/TraitTypeCheckingExtension.java b/src/main/java/org/codehaus/groovy/transform/stc/TraitTypeCheckingExtension.java
index 7922770..f364c1e 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/TraitTypeCheckingExtension.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/TraitTypeCheckingExtension.java
@@ -29,6 +29,8 @@ import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.transform.trait.TraitASTTransformation;
 import org.codehaus.groovy.transform.trait.Traits;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -77,15 +79,22 @@ public class TraitTypeCheckingExtension extends AbstractTypeCheckingExtension {
                     type = receiver;
                 }
                 if (Traits.isTrait(type) && !(type instanceof UnionTypeClassNode)) {
-                    ClassNode helper = Traits.findHelper(type);
-                    Parameter[] params = new Parameter[argumentTypes.length + 1];
-                    params[0] = new Parameter(ClassHelper.CLASS_Type.getPlainNodeReference(), "staticSelf");
-                    for (int i = 1; i < params.length; i++) {
-                        params[i] = new Parameter(argumentTypes[i-1], "p" + i);
-                    }
-                    MethodNode method = helper.getDeclaredMethod(name, params);
-                    if (method != null) {
-                        return Collections.singletonList(makeDynamic(call, method.getReturnType()));
+                    List<ClassNode> candidates = new ArrayList<ClassNode>();
+                    candidates.add(type);
+                    while (!candidates.isEmpty()) {
+                        ClassNode next = candidates.remove(0);
+                        ClassNode helper = Traits.findHelper(next);
+                        Parameter[] params = new Parameter[argumentTypes.length + 1];
+                        params[0] = new Parameter(ClassHelper.CLASS_Type.getPlainNodeReference(), "staticSelf");
+                        for (int i = 1; i < params.length; i++) {
+                            params[i] = new Parameter(argumentTypes[i-1], "p" + i);
+                        }
+                        MethodNode method = helper.getDeclaredMethod(name, params);
+                        if (method != null) {
+                            return Collections.singletonList(makeDynamic(call, method.getReturnType()));
+                        }
+                        // GROOVY-8272 support inherited static methods
+                        candidates.addAll(Arrays.asList(next.getInterfaces()));
                     }
                 }
             }
diff --git a/src/test/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy b/src/test/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
index d4c27b3..ca785f0 100644
--- a/src/test/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
@@ -2688,4 +2688,29 @@ assert c.b() == 2
             assert new CustomProp() {}
         '''
     }
+
+    //GROOVY-8272
+    void testTraitAccessToInheritedStaticMethods() {
+        assertScript '''
+            import groovy.transform.CompileStatic
+
+            @CompileStatic
+            trait Foo {
+                static String go() {
+                    'Go!'
+                }
+            }
+
+            @CompileStatic
+            trait Bar extends Foo {
+                String doIt() {
+                    go().toUpperCase()
+                }
+            }
+
+            class Main implements Bar {}
+
+            assert new Main().doIt() == 'GO!'
+        '''
+    }
 }