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 18:08:26 UTC

[groovy] branch master updated: 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 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 f247aec7cc GROOVY-10714: STC: ptr/ref: disambiguate overloads using parameter count
f247aec7cc is described below

commit f247aec7cc112f7d29567effbf0561e586ab581a
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 ebaf96fb9b..da69f7e525 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -2462,10 +2462,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, '''