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

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

commit 549ea8f4c874c4d5bbee951b9b591e412c72e55a
Author: Eric Milles <[email protected]>
AuthorDate: Tue Sep 9 11:44:46 2025 -0500

    GROOVY-11753: covariant method of super class parameterized interface
---
 .../java/org/codehaus/groovy/classgen/Verifier.java | 18 +++++++++++++++---
 src/test/groovy/groovy/InterfaceTest.groovy         | 21 +++++++++++++++++++++
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java 
b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index daff243dfe..a7b08f0310 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -122,6 +122,7 @@ import static 
org.codehaus.groovy.ast.tools.GeneralUtils.varX;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.addMethodGenerics;
 import static 
org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
+import static org.codehaus.groovy.ast.tools.GenericsUtils.parameterizeType;
 import static 
org.codehaus.groovy.ast.tools.PropertyNodeUtils.adjustPropertyModifiersForMethod;
 
 /**
@@ -1495,9 +1496,16 @@ public class Verifier implements GroovyClassVisitor, 
Opcodes {
             storeMissingCovariantMethods(declaredMethods, methodsToAdd, 
genericsSpec, scMethods);
             // add bridge methods in original class for any interface methods 
overridden by super
             if (!interfaceMethods.isEmpty()) {
-                for (MethodNode method : scMethods) {
-                    if (!method.isStatic())
-                        
storeMissingCovariantMethods(interfaceMethods.values(), method, methodsToAdd, 
Collections.emptyMap(), true);
+                for (MethodNode scMethod : scMethods) {
+                    if (isPossibleOverride(scMethod)) {
+                        for (MethodNode ifMethod : interfaceMethods.values()) {
+                            if 
(!ifMethod.getName().equals(scMethod.getName())) continue;
+                            // GROOVY-11753: create generics specification 
from classNode
+                            ClassNode face = parameterizeType(classNode, 
ifMethod.getDeclaringClass());
+                            Map<String, ClassNode> interfaceGenericsSpec = 
createGenericsSpec(face, oldGenericsSpec);
+                            
storeMissingCovariantMethods(Collections.singletonList(ifMethod), scMethod, 
methodsToAdd, interfaceGenericsSpec, true);
+                        }
+                    }
                 }
             }
 
@@ -1512,6 +1520,10 @@ public class Verifier implements GroovyClassVisitor, 
Opcodes {
         }
     }
 
+    private static boolean isPossibleOverride(final MethodNode methodNode) {
+        return (methodNode.getModifiers() & (ACC_BRIDGE | ACC_PRIVATE | 
ACC_STATIC)) == 0;
+    }
+
     private void storeMissingCovariantMethods(final List<MethodNode> 
declaredMethods, final Map<String, MethodNode> methodsToAdd, final Map<String, 
ClassNode> genericsSpec, final List<MethodNode> superClassMethods) {
         for (MethodNode declaredMethod : declaredMethods) {
             if (!declaredMethod.isStatic())
diff --git a/src/test/groovy/groovy/InterfaceTest.groovy 
b/src/test/groovy/groovy/InterfaceTest.groovy
index 7938e8bdd6..2b55ab0cf0 100644
--- a/src/test/groovy/groovy/InterfaceTest.groovy
+++ b/src/test/groovy/groovy/InterfaceTest.groovy
@@ -134,4 +134,25 @@ final class InterfaceTest extends CompilableTestSupport {
             }
         '''
     }
+
+    // GROOVY-11753
+    void testSuperClassCovariantOfParameterizedInterface() {
+        assertScript '''
+            class A extends B {
+            }
+            class B implements C<String> {
+                static class NestMate {
+                }
+                @Override
+                void p(String s) {
+                    print(s)
+                }
+            }
+            interface C<T> {
+                void p(T t)
+            }
+
+            new A().p("")
+        '''
+    }
 }

Reply via email to