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 fc776ff11b GROOVY-11579: skip bridge method in final method override 
checking
fc776ff11b is described below

commit fc776ff11b974335b522080319f3009aedced34d
Author: Eric Milles <[email protected]>
AuthorDate: Sun Mar 9 12:34:39 2025 -0500

    GROOVY-11579: skip bridge method in final method override checking
---
 .../groovy/classgen/ClassCompletionVerifier.java   | 33 ++++++++++++----------
 src/test/groovy/OverrideTest.groovy                | 17 +++++++++++
 2 files changed, 35 insertions(+), 15 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java 
b/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
index 30ca775504..100118cdd5 100644
--- a/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
@@ -74,6 +74,7 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
 import static org.objectweb.asm.Opcodes.ACC_STATIC;
 import static org.objectweb.asm.Opcodes.ACC_STRICT;
 import static org.objectweb.asm.Opcodes.ACC_SYNCHRONIZED;
+import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
 import static org.objectweb.asm.Opcodes.ACC_TRANSIENT;
 import static org.objectweb.asm.Opcodes.ACC_VOLATILE;
 
@@ -404,26 +405,27 @@ public class ClassCompletionVerifier extends 
ClassCodeVisitorSupport {
 
     private void checkMethodsForOverridingFinal(final ClassNode cn) {
         for (MethodNode method : cn.getMethods()) {
+            if ((method.getModifiers() & ACC_SYNTHETIC) != 0) continue; // 
GROOVY-11579: bridge method
+
+            ClassNode sc = cn.getSuperClass();
             Parameter[] params = method.getParameters();
-            for (MethodNode superMethod : 
cn.getSuperClass().getMethods(method.getName())) {
-                Parameter[] superParams = superMethod.getParameters();
-                if (!ParameterUtils.parametersEqual(params, superParams)) 
continue;
-                if (!superMethod.isFinal()) break;
-                addInvalidUseOfFinalError(method, params, 
superMethod.getDeclaringClass());
-                return;
+            for (MethodNode superMethod : sc.getMethods(method.getName())) {
+                if (superMethod.isFinal()
+                        && ParameterUtils.parametersEqual(params, 
superMethod.getParameters())) {
+                    StringBuilder sb = new StringBuilder();
+                    sb.append("You are not allowed to override the final 
method ");
+                    sb.append(method.getName());
+                    appendParamsDescription(params, sb);
+                    sb.append(" from ");
+                    sb.append(getDescription(sc));
+                    sb.append(".");
+
+                    addError(sb.toString(), method.getLineNumber() > 0 ? 
method : cn);
+                }
             }
         }
     }
 
-    private void addInvalidUseOfFinalError(final MethodNode method, final 
Parameter[] parameters, final ClassNode superCN) {
-        StringBuilder msg = new StringBuilder();
-        msg.append("You are not allowed to override the final method 
").append(method.getName());
-        appendParamsDescription(parameters, msg);
-        msg.append(" from ").append(getDescription(superCN));
-        msg.append(".");
-        addError(msg.toString(), method);
-    }
-
     private void appendParamsDescription(final Parameter[] parameters, final 
StringBuilder msg) {
         msg.append('(');
         boolean needsComma = false;
@@ -450,6 +452,7 @@ public class ClassCompletionVerifier extends 
ClassCodeVisitorSupport {
         msg.append(superMethod.getDeclaringClass().getName());
         msg.append("; attempting to assign weaker access privileges; was ");
         msg.append(superMethod.isPublic() ? "public" : 
(superMethod.isProtected() ? "protected" : "package-private"));
+
         addError(msg.toString(), method);
     }
 
diff --git a/src/test/groovy/OverrideTest.groovy 
b/src/test/groovy/OverrideTest.groovy
index 6b66b126f2..bbca486049 100644
--- a/src/test/groovy/OverrideTest.groovy
+++ b/src/test/groovy/OverrideTest.groovy
@@ -225,6 +225,23 @@ final class OverrideTest {
         '''
     }
 
+    // GROOVY-11579
+    @Test
+    void testCovariantReturnType() {
+        assertScript '''
+            interface I<T> {
+                T m()
+            }
+            abstract class A {
+                final String m() { 'A' }
+            }
+            class C extends A implements I<String> {
+            }
+
+            assert new C().m() == 'A'
+        '''
+    }
+
     @Test
     void testOverrideOnMethodWithDefaultParameters() {
         assertScript '''

Reply via email to