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/09/12 17:54:44 UTC

[groovy] branch GROOVY_3_0_X updated: GROOVY-10052: STC: resolve SAM return type before extracing conections

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 3173d7312b GROOVY-10052: STC: resolve SAM return type before extracing conections
3173d7312b is described below

commit 3173d7312b81af498cd3fe3f846103757f2f1bf9
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Sep 12 12:18:53 2022 -0500

    GROOVY-10052: STC: resolve SAM return type before extracing conections
---
 .../transform/stc/StaticTypeCheckingSupport.java   |  9 +++----
 .../transform/stc/StaticTypeCheckingVisitor.java   | 10 +++++++-
 src/test/groovy/bugs/Groovy8310.groovy             | 30 ++++++++++------------
 .../groovy/transform/stc/ClosuresSTCTest.groovy    |  4 +--
 4 files changed, 26 insertions(+), 27 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 df46cfe2b9..6ca1e6bc04 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -94,7 +94,6 @@ import static org.codehaus.groovy.ast.ClassHelper.boolean_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.byte_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.char_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.double_TYPE;
-import static org.codehaus.groovy.ast.ClassHelper.findSAM;
 import static org.codehaus.groovy.ast.ClassHelper.float_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.getUnwrapper;
 import static org.codehaus.groovy.ast.ClassHelper.getWrapper;
@@ -1702,17 +1701,15 @@ public abstract class StaticTypeCheckingSupport {
         if (target == null || target == type || !isUsingGenericsOrIsArrayUsingGenerics(target)) return;
         if (type == null || type == UNKNOWN_PARAMETER_TYPE) return;
 
-        MethodNode sam;
-
         if (target.isGenericsPlaceHolder()) {
             connections.put(new GenericsTypeName(target.getUnresolvedName()), new GenericsType(type));
 
         } else if (type.isArray() && target.isArray()) {
             extractGenericsConnections(connections, type.getComponentType(), target.getComponentType());
 
-        } else if (type.equals(CLOSURE_TYPE) && (sam = findSAM(target)) != null) {
-            // GROOVY-9974: Lambda, Closure, Pointer or Reference for SAM-type receiver
-            ClassNode returnType = StaticTypeCheckingVisitor.wrapTypeIfNecessary(sam.getReturnType());
+        } else if (type.equals(CLOSURE_TYPE) && isSAMType(target)) {
+            // GROOVY-9974, GROOVY-10052: Lambda, Closure, Pointer or Reference for SAM-type receiver
+            ClassNode returnType = StaticTypeCheckingVisitor.wrapTypeIfNecessary(GenericsUtils.parameterizeSAM(target).getV2());
             extractGenericsConnections(connections, type.getGenericsTypes(), new GenericsType[] {new GenericsType(returnType)});
 
         } else if (type.equals(target) || !implementsInterfaceOrIsSubclassOf(type, target)) {
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 75f8027297..3c44234b0b 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -3530,9 +3530,17 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                         ClassNode returnType = getType(directMethodCallCandidate);
                         if (isUsingGenericsOrIsArrayUsingGenerics(returnType)) {
                             visitMethodCallArguments(chosenReceiver.getType(), argumentList, true, directMethodCallCandidate);
+                            for (Expression argument : argumentList.getExpressions()) {
+                                if (argument instanceof ClosureExpression) {
+                                    // GROOVY-10052: return type known now
+                                    args = getArgumentTypes(argumentList);
+                                    break;
+                                }
+                            }
+                            callArgsVisited = true;
+
                             ClassNode irtg = inferReturnTypeGenerics(chosenReceiver.getType(), directMethodCallCandidate, callArguments, call.getGenericsTypes());
                             returnType = (irtg != null && implementsInterfaceOrIsSubclassOf(irtg, returnType) ? irtg : returnType);
-                            callArgsVisited = true;
                         }
                         // GROOVY-6091: use of "delegate" or "getDelegate()" does not make use of @DelegatesTo metadata
                         if (directMethodCallCandidate == GET_DELEGATE && typeCheckingContext.getEnclosingClosure() != null) {
diff --git a/src/test/groovy/bugs/Groovy8310.groovy b/src/test/groovy/bugs/Groovy8310.groovy
index 838566faf8..5a142eeae7 100644
--- a/src/test/groovy/bugs/Groovy8310.groovy
+++ b/src/test/groovy/bugs/Groovy8310.groovy
@@ -18,13 +18,11 @@
  */
 package groovy.bugs
 
-import groovy.transform.CompileStatic
 import org.junit.Test
 
 import static groovy.test.GroovyAssert.assertScript
 import static groovy.test.GroovyAssert.shouldFail
 
-@CompileStatic
 final class Groovy8310 {
 
     @Test
@@ -35,84 +33,82 @@ final class Groovy8310 {
             }
 
             @groovy.transform.CompileStatic
-            def use() {
+            def foo() {
                 bar {
                     [1]
                 }
             }
         '''
-
         assert err =~ /Cannot find matching method \w+#bar\(groovy.lang.Closure <java.util.List>\)/
     }
 
     @Test
     void testClosureReturnType2() {
         def err = shouldFail '''
-            public <T> T bar(Closure<Collection<Integer>> block) {
+            def <T> T bar(Closure<Collection<Integer>> block) {
                 block()
             }
 
             @groovy.transform.CompileStatic
-            def use() {
+            def foo() {
                 bar {
                     [1]
                 }
             }
         '''
-
-        assert err =~ /Cannot find matching method \w+#bar\(groovy.lang.Closure <java.util.List>\)/
+        assert err =~ /Cannot call <T> \w+#bar\(groovy.lang.Closure <java.util.Collection>\) with arguments \[groovy.lang.Closure <java.util.List>\]/
     }
 
     @Test
     void testClosureReturnType3() {
         assertScript '''
-            public <T> T bar(Closure<? extends Collection<Integer>> block) {
+            def <T> T bar(Closure<? extends Collection<Integer>> block) {
                 block()
             }
 
             @groovy.transform.CompileStatic
-            def use() {
+            def foo() {
                 bar {
                     [1]
                 }
             }
 
-            assert use() == [1]
+            assert foo() == [1]
         '''
     }
 
     @Test
     void testClosureReturnType4() {
         assertScript '''
-            public <T> T bar(Closure<Collection<Integer>> block) {
+            def <T> T bar(Closure<Collection<Integer>> block) {
                 block()
             }
 
             @groovy.transform.CompileStatic
-            def use() {
+            def foo() {
                 bar {
                     (Collection<Integer>) [1]
                 }
             }
 
-            assert use() == [1]
+            assert foo() == [1]
         '''
     }
 
     @Test
     void testClosureReturnType5() {
         assertScript '''
-            public <T> T bar(Closure<Collection<Integer>> block) {
+            def <T> T bar(Closure<Collection<Integer>> block) {
                 block()
             }
 
-            def use() {
+            def foo() {
                 bar {
                     [1] as Collection<Integer>
                 }
             }
 
-            assert use() == [1]
+            assert foo() == [1]
         '''
     }
 }
diff --git a/src/test/groovy/transform/stc/ClosuresSTCTest.groovy b/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
index 0cdefd461b..c60c723b8b 100644
--- a/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
@@ -18,8 +18,6 @@
  */
 package groovy.transform.stc
 
-import groovy.test.NotYetImplemented
-
 /**
  * Unit tests for static type checking : closures.
  */
@@ -351,7 +349,7 @@ class ClosuresSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    @NotYetImplemented // GROOVY-10052
+    // GROOVY-10052
     void testClosureSharedVariable5() {
         assertScript '''
             def x