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 d82ae1715e GROOVY-11341: select non-bridge method from super class
d82ae1715e is described below

commit d82ae1715efff292e48f712d71aee8f4b9d7ab77
Author: Eric Milles <eric.mil...@thomsonreuters.com>
AuthorDate: Fri Mar 22 09:45:45 2024 -0500

    GROOVY-11341: select non-bridge method from super class
---
 .../java/org/codehaus/groovy/ast/ClassNode.java    | 22 +++---
 .../transform/stc/StaticTypeCheckingSupport.java   |  2 +-
 .../groovy/transform/stc/MethodCallsSTCTest.groovy | 80 +++++++++++++++++++---
 .../transform/stc/vm6/MethodCallsSTCTest.groovy    | 40 -----------
 .../sc/vm6/MethodCallsStaticCompilationTest.groovy | 25 -------
 5 files changed, 85 insertions(+), 84 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/ClassNode.java 
b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
index 2e843e7bb6..47220eb468 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
@@ -1044,29 +1044,35 @@ public class ClassNode extends AnnotatedNode {
 
     public MethodNode getGetterMethod(String getterName, boolean 
searchSuperClasses) {
         MethodNode getterMethod = null;
+
+        java.util.function.Predicate<MethodNode> isNullOrSynthetic = (method) 
->
+                (method == null || (method.getModifiers() & ACC_SYNTHETIC) != 
0);
+
         boolean booleanReturnOnly = getterName.startsWith("is");
         for (MethodNode method : getDeclaredMethods(getterName)) {
             if (method.getName().equals(getterName) && 
method.getParameters().length == 0
                     && (booleanReturnOnly ? 
ClassHelper.isPrimitiveBoolean(method.getReturnType()) : 
!method.isVoidMethod())) {
-                // GROOVY-7363: There can be multiple matches for a getter 
returning a generic parameter type, due to
+                // GROOVY-7363, GROOVY-11341: There can be multiple matches if 
a method returns a non-final type due to
                 // the generation of a bridge method. The real getter is 
really the non-bridge, non-synthetic one as it
                 // has the most specific and exact return type of the two. 
Picking the bridge method results in loss of
                 // type information, as it down-casts the return type to the 
lower bound of the generic parameter.
-                if (getterMethod == null || getterMethod.isSynthetic()) {
+                if (isNullOrSynthetic.test(getterMethod)) {
                     getterMethod = method;
                 }
             }
         }
-        if (getterMethod != null) {
-            return getterMethod;
-        }
-        if (searchSuperClasses) {
+
+        if (searchSuperClasses && isNullOrSynthetic.test(getterMethod)) {
             ClassNode parent = getSuperClass();
             if (parent != null) {
-                return parent.getGetterMethod(getterName);
+                MethodNode method = parent.getGetterMethod(getterName);
+                if (getterMethod == null || !isNullOrSynthetic.test(method)) {
+                    getterMethod = method;
+                }
             }
         }
-        return null;
+
+        return getterMethod;
     }
 
     public MethodNode getSetterMethod(String setterName) {
diff --git 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 55c293cd5c..daf7b32818 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1208,7 +1208,7 @@ public abstract class StaticTypeCheckingSupport {
                 if (toBeRemoved.contains(two)) continue;
                 if (one.getParameters().length == two.getParameters().length) {
                     ClassNode oneDC = one.getDeclaringClass(), twoDC = 
two.getDeclaringClass();
-                    if (oneDC == twoDC) {
+                    if (oneDC == twoDC || 
isSynthetic(one,two)||isSynthetic(two,one)) { // GROOVY-11341
                         if 
(ParameterUtils.parametersEqual(one.getParameters(), two.getParameters())) {
                             ClassNode oneRT = one.getReturnType(), twoRT = 
two.getReturnType();
                             if (isCovariant(oneRT, twoRT)) {
diff --git a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy 
b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
index c5876589cd..544bbbfe7d 100644
--- a/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/MethodCallsSTCTest.groovy
@@ -19,6 +19,7 @@
 package groovy.transform.stc
 
 import org.codehaus.groovy.control.MultipleCompilationErrorsException
+import org.codehaus.groovy.tools.javac.JavaAwareCompilationUnit
 
 import static 
org.codehaus.groovy.control.customizers.builder.CompilerCustomizationBuilder.withConfig
 
@@ -1602,6 +1603,18 @@ class MethodCallsSTCTest extends 
StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-5525
+    void testShouldFindArraysCopyOf() {
+        assertScript '''
+            class CopyOf {
+                public static void main(String[] args) {
+                    def copy = Arrays.copyOf(args, 1)
+                    assert copy.length == 1
+                }
+            }
+        '''
+    }
+
     // GROOVY-5702
     void testShouldFindInterfaceMethod() {
         assertScript '''
@@ -1884,24 +1897,71 @@ class MethodCallsSTCTest extends 
StaticTypeCheckingTestCase {
     }
 
     // GROOVY-6751
-    void testMethodInBothInterfaceAndSuperclass() {
+    void testMethodInBothInterfaceAndSuperclass1() {
         assertScript '''
-            interface Ifc {
+            interface Face {
               Object getProperty(String s)
             }
-
-            class DuplicateMethodInIfc implements Ifc {}  // implemented in 
groovy.lang.GroovyObject
-
-            class Tester {
-              DuplicateMethodInIfc dup = new DuplicateMethodInIfc()
-              Object obj = dup.getProperty("foo")
+            class Impl implements Face { // implemented in 
groovy.lang.GroovyObject
             }
 
-            try { new Tester()}
-            catch(groovy.lang.MissingPropertyException expected) {}
+            try {
+                Impl impl = new Impl()
+                impl.getProperty('xx')
+            }
+            catch(MissingPropertyException expected) {
+            }
         '''
     }
 
+    // GROOVY-11341
+    void testMethodInBothInterfaceAndSuperclass2() {
+        File parentDir = File.createTempDir()
+        config.with {
+            targetDirectory = File.createTempDir()
+            jointCompilationOptions = [memStub: true]
+        }
+        try {
+            new File(parentDir, 'p').mkdir()
+
+            def a = new File(parentDir, 'p/A.java')
+            a.write '''package p;
+                public interface A {
+                    Object getValue();
+                }
+            '''
+            def b = new File(parentDir, 'p/B.java')
+            b.write '''package p;
+                public class B {
+                    public Long getValue() { return 21L; }
+                }
+            '''
+            def c = new File(parentDir, 'p/C.java')
+            c.write '''package p;
+                public class C extends B implements A {
+                    // public bridge Object getValue() { ... }
+                }
+            '''
+            def d = new File(parentDir, 'D.groovy')
+            d.write '''
+                def pojo = new p.C()
+                Long value = pojo.getValue() // Cannot assign value of type 
Object to variable of type Long
+                value += pojo.value
+                assert value == 42L
+            '''
+
+            def loader = new GroovyClassLoader(this.class.classLoader)
+            def cu = new JavaAwareCompilationUnit(config, loader)
+            cu.addSources(a, b, c, d)
+            cu.compile()
+
+            loader.loadClass('D').main()
+        } finally {
+            parentDir.deleteDir()
+            config.targetDirectory.deleteDir()
+        }
+    }
+
     // GROOVY-7987
     void testNonStaticMethodViaStaticReceiver() {
         shouldFailWithMessages '''
diff --git a/src/test/groovy/transform/stc/vm6/MethodCallsSTCTest.groovy 
b/src/test/groovy/transform/stc/vm6/MethodCallsSTCTest.groovy
deleted file mode 100644
index 0e1bcfac66..0000000000
--- a/src/test/groovy/transform/stc/vm6/MethodCallsSTCTest.groovy
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package groovy.transform.stc.vm6
-
-import groovy.transform.stc.StaticTypeCheckingTestCase
-
-/**
- * Unit tests for static type checking : method calls.
- */
-class MethodCallsSTCTest extends StaticTypeCheckingTestCase {
-    // GROOVY-5525
-    void testFindMethodFromArraysClass() {
-        assertScript '''import groovy.transform.TypeChecked
-        import java.util.Arrays
-
-        class ArrayCopying {
-            public static void main(String[] args) {
-                def acopy = Arrays.copyOf(args, 1)
-            }
-
-        }
-        '''
-    }
-}
diff --git 
a/src/test/org/codehaus/groovy/classgen/asm/sc/vm6/MethodCallsStaticCompilationTest.groovy
 
b/src/test/org/codehaus/groovy/classgen/asm/sc/vm6/MethodCallsStaticCompilationTest.groovy
deleted file mode 100644
index ff759c175e..0000000000
--- 
a/src/test/org/codehaus/groovy/classgen/asm/sc/vm6/MethodCallsStaticCompilationTest.groovy
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.codehaus.groovy.classgen.asm.sc.vm6
-
-import groovy.transform.stc.vm6.MethodCallsSTCTest
-import org.codehaus.groovy.classgen.asm.sc.StaticCompilationTestSupport
-
-public class MethodCallsStaticCompilationTest extends MethodCallsSTCTest 
implements StaticCompilationTestSupport {
-}

Reply via email to