You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/08/02 19:19:44 UTC
[groovy] 01/02: GROOVY-10714: STC: ptr/ref: disambiguate overloads using parameter count
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
commit 34460160ef15b2ab79e640b8718decc8c69afa01
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Aug 2 12:29:28 2022 -0500
GROOVY-10714: STC: ptr/ref: disambiguate overloads using parameter count
---
.../transform/stc/StaticTypeCheckingVisitor.java | 5 +++-
.../transform/stc/MethodReferenceTest.groovy | 32 ++++++++++++++++++++++
2 files changed, 36 insertions(+), 1 deletion(-)
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 64fd0f83cb..d5e2fb5ee7 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -2467,10 +2467,13 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
if (!candidates.isEmpty()) {
+ int nParameters = candidates.stream().mapToInt(m -> m.getParameters().length).reduce((i,j) -> i == j ? i : -1).getAsInt();
Map<GenericsTypeName, GenericsType> gts = GenericsUtils.extractPlaceholders(receiverType);
candidates.stream().map(candidate -> applyGenericsContext(gts, candidate.getReturnType()))
.reduce(WideningCategories::lowestUpperBound).ifPresent(returnType -> {
- storeType(expression, wrapClosureType(returnType));
+ ClassNode closureType = wrapClosureType(returnType);
+ closureType.putNodeMetaData(CLOSURE_ARGUMENTS, nParameters); // GROOVY-10714
+ storeType(expression, closureType);
});
expression.putNodeMetaData(MethodNode.class, candidates);
} else if (!(expression instanceof MethodReferenceExpression)) {
diff --git a/src/test/groovy/transform/stc/MethodReferenceTest.groovy b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
index fc9f07d58c..8758987fc3 100644
--- a/src/test/groovy/transform/stc/MethodReferenceTest.groovy
+++ b/src/test/groovy/transform/stc/MethodReferenceTest.groovy
@@ -827,6 +827,38 @@ final class MethodReferenceTest {
assert err.message.contains('Failed to find the expected method[toLowerCaseX(java.lang.String)] in the type[java.lang.String]')
}
+ @Test // GROOVY-10714
+ void testMethodSelection() {
+ assertScript shell, '''
+ class C {
+ String which
+ void m(int i) { which = 'int' }
+ void m(Number n) { which = 'Number' }
+ }
+ interface I {
+ I andThen(Consumer<? super Number> c)
+ I andThen(BiConsumer<? super Number, ?> bc)
+ }
+ @CompileStatic
+ void test(I i, C c) {
+ i = i.andThen(c::m) // "andThen" is ambiguous unless parameters of "m" overloads are taken into account
+ }
+
+ C x= new C()
+ test(new I() {
+ I andThen(Consumer<? super Number> c) {
+ c.accept(42)
+ return this
+ }
+ I andThen(BiConsumer<? super Number, ?> bc) {
+ bc.accept(42, null)
+ return this
+ }
+ }, x)
+ assert x.which == 'Number'
+ '''
+ }
+
@Test // GROOVY-10269
void testNotFunctionalInterface() {
def err = shouldFail shell, '''