This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new ef324616e2 GROOVY-10436: STC: closure parameter as type witness for 
SAM-type target
ef324616e2 is described below

commit ef324616e2da53cea36762425b5c9743ed086344
Author: Eric Milles <eric.mil...@thomsonreuters.com>
AuthorDate: Thu Jun 16 15:32:35 2022 -0500

    GROOVY-10436: STC: closure parameter as type witness for SAM-type target
---
 .../transform/stc/StaticTypeCheckingVisitor.java      | 10 +++++++++-
 src/test/groovy/transform/stc/GenericsSTCTest.groovy  | 19 +++++++++++++++----
 2 files changed, 24 insertions(+), 5 deletions(-)

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 23f95c673c..f421fabc0e 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -2933,11 +2933,19 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
                     // check for implicit type arguments
                     int i = -1; Parameter[] p = method.getParameters();
                     for (Expression argument : (ArgumentListExpression) 
arguments) { i += 1;
-                        if (argument instanceof ClosureExpression || 
isNullConstant(argument)) continue;
+                        if (isNullConstant(argument)) continue;
 
                         ClassNode pType = p[Math.min(i, p.length - 
1)].getType();
                         Map<GenericsTypeName, GenericsType> gc = new 
HashMap<>();
                         extractGenericsConnections(gc, 
wrapTypeIfNecessary(getType(argument)), pType);
+                        // GROOVY-10436: extract generics connections from 
closure parameter declaration(s)
+                        if (argument == expression || (argument instanceof 
ClosureExpression && isSAMType(pType))) {
+                            Parameter[] q = 
getParametersSafe((ClosureExpression) argument);
+                            ClassNode[] r = extractTypesFromParameters(q); // 
maybe typed
+                            ClassNode[] s = 
GenericsUtils.parameterizeSAM(pType).getV1();
+                            for (int j = 0; j < r.length && j < s.length; j += 
1)
+                                if (!q[j].isDynamicTyped()) 
extractGenericsConnections(gc, r[j], s[j]);
+                        }
 
                         gc.forEach((key, gt) -> {
                             for (GenericsType tp : typeParameters) {
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy 
b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index f021659414..06a5b3ab39 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -3269,6 +3269,21 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase 
{
         '''
     }
 
+    // GROOVY-10436
+    void testReturnTypeInferenceWithClosure3() {
+        String method = '''import java.util.function.BiConsumer
+
+            def <T> void m(BiConsumer<String, ? super T> consumer) { }
+        '''
+        assertScript method + '''
+            this.<Number>m { string, number -> number.toBigDecimal() }
+        '''
+        assertScript method + '''
+            // the only type witness for T is the closure parameter
+            m { string, Number number -> number.toBigDecimal() }
+        '''
+    }
+
     // GROOVY-6129
     void testShouldNotThrowNPE() {
         assertScript '''
@@ -3706,10 +3721,6 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase 
{
 
     void testConcreteTypeInsteadOfGenerifiedInterface() {
         assertScript '''
-            import groovy.transform.ASTTest
-            import static org.codehaus.groovy.transform.stc.StaticTypesMarker.*
-            import static org.codehaus.groovy.ast.ClassHelper.*
-
             interface Converter<F, T> {
             T convertC(F from)
             }

Reply via email to