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 2022/02/24 15:28:41 UTC

[groovy] 02/03: GROOVY-10478: SC: indicate dynamic resolution of trait super fallback

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

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

commit b43162677754ea606012cdba62b377f6efd6bf6b
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed Feb 23 17:57:23 2022 -0600

    GROOVY-10478: SC: indicate dynamic resolution of trait super fallback
---
 .../classgen/asm/sc/StaticInvocationWriter.java    |  3 +-
 .../groovy/transform/trait/TraitComposer.java      |  2 ++
 src/test/groovy/bugs/Groovy10478.groovy            | 32 ++++++++++++++++++++++
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
index 6fee1be..ea3c60f 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
@@ -512,8 +512,7 @@ public class StaticInvocationWriter extends InvocationWriter {
 
     @Override
     public void makeCall(final Expression origin, final Expression receiver, final Expression message, final Expression arguments, final MethodCallerMultiAdapter adapter, final boolean safe, final boolean spreadSafe, final boolean implicitThis) {
-        ClassNode dynamicCallReturnType = origin.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION);
-        if (dynamicCallReturnType != null) {
+        if (origin.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION) != null) {
             StaticTypesWriterController staticController = (StaticTypesWriterController) controller;
             if (origin instanceof MethodCallExpression) {
                 ((MethodCallExpression) origin).setMethodTarget(null);
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java b/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
index 67f0701..07cd228 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
@@ -53,6 +53,7 @@ import org.codehaus.groovy.syntax.Token;
 import org.codehaus.groovy.syntax.Types;
 import org.codehaus.groovy.transform.ASTTransformationCollectorCodeVisitor;
 import org.codehaus.groovy.transform.sc.StaticCompileTransformation;
+import org.codehaus.groovy.transform.stc.StaticTypesMarker;
 import org.objectweb.asm.Opcodes;
 
 import java.util.ArrayList;
@@ -519,6 +520,7 @@ public abstract class TraitComposer {
         );
 
         MethodCallExpression superCall = callX(varX("super"), forwarderMethod.getName(), paramTuple);
+        superCall.putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, Boolean.TRUE); //GROOVY-10478
         superCall.setImplicitThis(false);
 
         // if (this instanceof GeneratedGroovyProxy)
diff --git a/src/test/groovy/bugs/Groovy10478.groovy b/src/test/groovy/bugs/Groovy10478.groovy
new file mode 100644
index 0000000..a7e5868
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy10478.groovy
@@ -0,0 +1,32 @@
+package groovy.bugs
+
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+final class Groovy10478 {
+
+    @Test
+    void testIndirectInterface() {
+        assertScript '''
+            trait A {
+                final String string = 'works'
+            }
+            interface B {
+            }
+            trait C implements A, B {
+            }
+            @groovy.transform.CompileStatic
+            class D implements C {
+            }
+
+            // VerifyError: Bad invokespecial instruction: interface method reference is in an indirect superinterface
+            //    Location: D.Atrait$super$getString()Ljava/lang/String; @37: invokespecial
+            def cls = D.class
+            cls.name
+
+            String result = new D().string
+            assert result == 'works'
+        '''
+    }
+}