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/11/05 20:16:09 UTC

[groovy] branch GROOVY_2_5_X updated: GROOVY-7789: STC: apply method call type arguments to `@ClosureParams`

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

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


The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
     new 804f8f64ad GROOVY-7789: STC: apply method call type arguments to `@ClosureParams`
804f8f64ad is described below

commit 804f8f64ad3718f8f566d321b991bfff697efe97
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Nov 5 14:49:17 2022 -0500

    GROOVY-7789: STC: apply method call type arguments to `@ClosureParams`
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 11 +++-
 .../stc/ClosureParamTypeInferenceSTCTest.groovy    | 65 ++++++++++++++--------
 2 files changed, 52 insertions(+), 24 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 f3d39449ff..9b458c0b57 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -3215,6 +3215,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
             genericTypes[i] = new GenericsType(signature[i]);
         }
         dummyResultNode.setGenericsTypes(genericTypes);
+
         MethodNode dummyMN = selectedMethod instanceof ExtensionMethodNode ? ((ExtensionMethodNode) selectedMethod).getExtensionMethodNode() : selectedMethod;
         dummyMN = new MethodNode(
                 dummyMN.getName(),
@@ -3241,7 +3242,15 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
             dummyMN.setDeclaringClass(orig.getDeclaringClass());
             dummyMN.setGenericsTypes(orig.getGenericsTypes());
         }
-        ClassNode returnType = inferReturnTypeGenerics(receiver, dummyMN, arguments);
+
+        GenericsType[] typeArguments = null; // GROOVY-7789
+        Expression emc = typeCheckingContext.getEnclosingMethodCall();
+        if (emc instanceof MethodCallExpression) {
+            MethodCallExpression call = (MethodCallExpression) emc;
+            if (arguments == call.getArguments()) typeArguments = call.getGenericsTypes();
+        }
+
+        ClassNode returnType = inferReturnTypeGenerics(receiver, dummyMN, arguments, typeArguments);
         GenericsType[] returnTypeGenerics = returnType.getGenericsTypes();
         ClassNode[] inferred = new ClassNode[returnTypeGenerics.length];
         for (int i = 0, n = returnTypeGenerics.length; i < n; i += 1) {
diff --git a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
index eab26a35ed..f65b2f19e4 100644
--- a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
@@ -261,21 +261,40 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         'Expected parameter of type java.util.List <java.lang.String> but got java.util.List <Date>'
     }
 
-    void testFromStringWithDirectGenericPlaceholder() {
+    void testFromStringWithTypeParameter1() {
         assertScript '''import groovy.transform.stc.FromString
             def <T> void foo(T t, @ClosureParams(value=FromString,options="T") Closure cl) { cl.call(t) }
             foo('hey') { println it.toUpperCase() }
         '''
     }
 
-    void testFromStringWithGenericPlaceholder() {
+    void testFromStringWithTypeParameter2() {
         assertScript '''import groovy.transform.stc.FromString
             def <T> void foo(T t, @ClosureParams(value=FromString,options="java.util.List<T>") Closure cl) { cl.call([t,t]) }
             foo('hey') { List<String> str -> str.each { println it.toUpperCase() } }
         '''
     }
 
-    void testFromStringWithGenericPlaceholderFromClass() {
+    // GROOVY-7789
+    void testFromStringWithTypeParameter3() {
+        assertScript '''import groovy.transform.stc.FromString
+            class Monad<T> {  private final Closure c
+                Monad(@ClosureParams(value=FromString, options='T') Closure c) {
+                    this.c = c
+                }
+                def call(T t) {
+                    c.call(t)
+                }
+            }
+            def <U> Monad<U> wrap(@ClosureParams(value=FromString, options='U') Closure c) {
+                new Monad<>(c)
+            }
+            def list_size = this.<List>wrap({ list -> list.size() })
+            assert list_size([]) == 0
+        '''
+    }
+
+    void testFromStringWithTypeParameterFromClass() {
         assertScript '''import groovy.transform.stc.FromString
             class Foo<T> {
                 void foo(@ClosureParams(value=FromString,options="java.util.List<T>") Closure cl) { cl.call(['hey','ya']) }
@@ -285,7 +304,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    void testFromStringWithGenericPlaceholderFromClassWithTwoGenerics() {
+    void testFromStringWithTypeParameterFromClassWithTwoGenerics() {
         assertScript '''import groovy.transform.stc.FromString
             class Foo<T,U> {
                 void foo(@ClosureParams(value=FromString,options="java.util.List<U>") Closure cl) { cl.call(['hey','ya']) }
@@ -295,7 +314,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    void testFromStringWithGenericPlaceholderFromClassWithTwoGenericsAndNoExplicitSignature() {
+    void testFromStringWithTypeParameterFromClassWithTwoGenericsAndNoExplicitSignature() {
         assertScript '''import groovy.transform.stc.FromString
             class Foo<T,U> {
                 void foo(@ClosureParams(value=FromString,options="java.util.List<U>") Closure cl) { cl.call(['hey','ya']) }
@@ -305,7 +324,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    void testFromStringWithGenericPlaceholderFromClassWithTwoGenericsAndNoExplicitSignatureAndNoFQN() {
+    void testFromStringWithTypeParameterFromClassWithTwoGenericsAndNoExplicitSignatureAndNoFQN() {
         assertScript '''import groovy.transform.stc.FromString
             class Foo<T,U> {
                 void foo(@ClosureParams(value=FromString,options="List<U>") Closure cl) { cl.call(['hey','ya']) }
@@ -315,7 +334,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    void testFromStringWithGenericPlaceholderFromClassWithTwoGenericsAndNoExplicitSignatureAndNoFQNAndReferenceToSameUnitClass() {
+    void testFromStringWithTypeParameterFromClassWithTwoGenericsAndNoExplicitSignatureAndNoFQNAndReferenceToSameUnitClass() {
         assertScript '''import groovy.transform.stc.FromString
             class Foo {
                 void bar() {
@@ -330,7 +349,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    void testFromStringWithGenericPlaceholderFromClassWithTwoGenericsAndNoExplicitSignatureAndNoFQNAndReferenceToSameUnitClassAndTwoArgs() {
+    void testFromStringWithTypeParameterFromClassWithTwoGenericsAndNoExplicitSignatureAndNoFQNAndReferenceToSameUnitClassAndTwoArgs() {
         assertScript '''import groovy.transform.stc.FromString
             class Foo {
                 void bar() {
@@ -345,7 +364,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    void testFromStringWithGenericPlaceholderFromClassWithTwoGenericsAndPolymorphicSignature() {
+    void testFromStringWithTypeParameterFromClassWithTwoGenericsAndPolymorphicSignature() {
         assertScript '''import groovy.transform.stc.FromString
             class Foo {
                 void bar() {
@@ -380,6 +399,20 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         'Expected parameter of type java.lang.String but got java.util.Date'
     }
 
+    void testFromStringInSameSourceUnit() {
+        assertScript '''import groovy.transform.stc.FromString
+            def <T> void doSomething(T val, @ClosureParams(value=FromString, options="T") Closure cl) {
+                cl(val)
+            }
+            doSomething('foo') {
+                println it.toUpperCase()
+            }
+            doSomething(new Date()) {
+                println it.time
+            }
+        '''
+    }
+
     void testStringGroovyMethodsFindMethodWithList() {
         assertScript '''
             "75001 Paris".find(/(\\d{5}\\s(\\w+))/) { List<String> all -> println all*.toUpperCase() }
@@ -1167,20 +1200,6 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    void testFromStringInSameSourceUnit() {
-        assertScript '''import groovy.transform.stc.FromString
-            def <T> void doSomething(T val, @ClosureParams(value=FromString, options="T") Closure cl) {
-                cl(val)
-            }
-            doSomething('foo') {
-                println it.toUpperCase()
-            }
-            doSomething(new Date()) {
-                println it.time
-            }
-        '''
-    }
-
     // GROOVY-7141
     void testInferenceWithSAMTypeCoercion1() {
         String sam = '''