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


The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
     new e60fbb082a GROOVY-11683: STC: method reference: no covariants or 
equivalents
e60fbb082a is described below

commit e60fbb082a8572dfcec2dffd96ae9966be198297
Author: Eric Milles <[email protected]>
AuthorDate: Tue Jun 10 14:53:19 2025 -0500

    GROOVY-11683: STC: method reference: no covariants or equivalents
---
 .../groovy/transform/stc/StaticTypeCheckingSupport.java | 10 ++++++++--
 .../groovy/transform/stc/StaticTypeCheckingVisitor.java |  4 ++--
 .../groovy/transform/stc/MethodReferenceTest.groovy     | 17 +++++++++++++++++
 3 files changed, 27 insertions(+), 4 deletions(-)

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 c699a32c12..1969c8665e 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -127,6 +127,7 @@ import static 
org.codehaus.groovy.ast.tools.WideningCategories.isFloatingCategor
 import static org.codehaus.groovy.ast.tools.WideningCategories.isLongCategory;
 import static 
org.codehaus.groovy.ast.tools.WideningCategories.lowestUpperBound;
 import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asBoolean;
+import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asList;
 import static 
org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport.closeQuietly;
 import static org.codehaus.groovy.syntax.Types.BITWISE_AND;
 import static org.codehaus.groovy.syntax.Types.BITWISE_AND_EQUAL;
@@ -1044,12 +1045,17 @@ public abstract class StaticTypeCheckingSupport {
             return Collections.emptyList();
         }
 
-        int bestDist = Integer.MAX_VALUE;
-        List<MethodNode> bestChoices = new LinkedList<>();
         boolean duckType = receiver instanceof UnionTypeClassNode; // 
GROOVY-8965: type disjunction
         boolean noCulling = methods.size() <= 1 || 
"<init>".equals(methods.iterator().next().getName());
         Iterable<MethodNode> candidates = noCulling ? methods : 
removeCovariantsAndInterfaceEquivalents(methods, duckType);
 
+        if (argumentTypes == null) {
+            return asList(candidates); // GROOVY-11683: methods without 
covariants and equivalents
+        }
+
+        int bestDist = Integer.MAX_VALUE;
+        List<MethodNode> bestChoices = new LinkedList<>();
+
         for (MethodNode candidate : candidates) {
             MethodNode  safeNode = candidate;
             ClassNode[] safeArgs = argumentTypes;
diff --git 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 0b25cfa640..3b4fb270d7 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -2632,7 +2632,7 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
     private List<MethodNode> filterMethodCandidates(final List<MethodNode> 
candidates, final Expression objectOrType, /*@Nullable*/ ClassNode[] signature) 
{
         List<MethodNode> result = filterMethodsByVisibility(candidates, 
typeCheckingContext.getEnclosingClassNode());
         // assignment or parameter target type may help reduce the list
-        if (result.size() > 1 && signature != null) {
+        if (result.size() > 1) {
             ClassNode type = getType(objectOrType);
             if (!isClassClassNodeWrappingConcreteType(type)) {
                 result = chooseBestMethod(type, result, signature);
@@ -2643,7 +2643,7 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
                 result = new ArrayList<>(result.size());
                 result.addAll(chooseBestMethod(type, 
staticAndNonStatic.get(Boolean.TRUE), signature));
                 if (result.isEmpty() && 
!staticAndNonStatic.get(Boolean.FALSE).isEmpty()) { // GROOVY-11009
-                    if (signature.length > 0) signature= 
Arrays.copyOfRange(signature, 1, signature.length);
+                    if (asBoolean(signature)) signature= 
Arrays.copyOfRange(signature, 1, signature.length);
                     result.addAll(chooseBestMethod(type, 
staticAndNonStatic.get(Boolean.FALSE), signature));
                 }
             }
diff --git a/src/test/groovy/groovy/transform/stc/MethodReferenceTest.groovy 
b/src/test/groovy/groovy/transform/stc/MethodReferenceTest.groovy
index 1c7da51f6c..50fc8df9a8 100644
--- a/src/test/groovy/groovy/transform/stc/MethodReferenceTest.groovy
+++ b/src/test/groovy/groovy/transform/stc/MethodReferenceTest.groovy
@@ -353,6 +353,23 @@ final class MethodReferenceTest {
         '''
     }
 
+    // GROOVY-11683
+    @Test // class::instanceMethod
+    void testFunctionCI12() {
+        assertScript shell, '''import java.util.stream.Stream
+            @CompileStatic
+            List<Integer> test(List<String> strings) {
+                
Stream.of(strings).flatMap(List::stream).map(Integer::valueOf).toList()
+                //                                           ^^^^^^^^^^^^^^^^
+                // Failed to find class method 'valueOf(Object)' or instance 
method 'valueOf()'
+            }
+
+            def numbers = test(['1','2','3'])
+            assert numbers.size() == 3
+            assert numbers == [1,2,3]
+        '''
+    }
+
     // GROOVY-9974
     @Test // class::instanceMethod
     void testPredicateCI1() {

Reply via email to