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() {