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/05/17 00:07:58 UTC

[groovy] branch master updated: GROOVY-10364: STC: keep type parameter from enclosing context

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 8b44c0af6f GROOVY-10364: STC: keep type parameter from enclosing context
8b44c0af6f is described below

commit 8b44c0af6f167892a239804d99149a5f6323d984
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon May 16 18:41:56 2022 -0500

    GROOVY-10364: STC: keep type parameter from enclosing context
---
 .../transform/stc/StaticTypeCheckingSupport.java   | 52 +++++++++++++---------
 .../stc/DefaultGroovyMethodsSTCTest.groovy         |  4 +-
 .../groovy/transform/stc/GenericsSTCTest.groovy    | 19 ++++++++
 3 files changed, 51 insertions(+), 24 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 6738bfcf37..a842fba3ea 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1337,31 +1337,39 @@ public abstract class StaticTypeCheckingSupport {
         if (type.isArray()) {
             return fullyResolveType(type.getComponentType(), placeholders).makeArray();
         }
-        if (type.isUsingGenerics()) {
-            if (type.isGenericsPlaceHolder()) {
-                GenericsType gt = placeholders.get(new GenericsTypeName(type.getUnresolvedName()));
-                if (gt != null) {
-                    return gt.getType();
-                }
-                ClassNode cn = type.redirect();
-                return cn != type ? cn : OBJECT_TYPE;
-            } else {
-                GenericsType[] gts = type.getGenericsTypes();
-                if (gts != null) {
-                    gts = Arrays.stream(gts).map(gt -> {
-                        if (gt.isPlaceholder()) {
-                            GenericsTypeName gtn = new GenericsTypeName(gt.getName());
-                            return placeholders.getOrDefault(gtn, extractType(gt).asGenericsType());
-                        }
-                        return fullyResolve(gt, placeholders);
-                    }).toArray(GenericsType[]::new);
+        if (!type.isUsingGenerics()) {
+            return type;
+        }
+        if (type.isGenericsPlaceHolder()) {
+            GenericsType gt = placeholders.get(new GenericsTypeName(type.getUnresolvedName()));
+            if (gt != null) {
+                return gt.getType();
+            }
+            ClassNode cn = type.redirect();
+            return cn != type ? cn : OBJECT_TYPE;
+        }
+
+        GenericsType[] gts = type.getGenericsTypes();
+        if (asBoolean(gts)) {
+            gts = gts.clone();
+            for (int i = 0, n = gts.length; i < n; i += 1) {
+                GenericsType gt = gts[i];
+                if (gt.isPlaceholder()) { String name = gt.getName();
+                    gt = placeholders.get(new GenericsTypeName(name));
+                    if (gt == null) gt = extractType(gts[i]).asGenericsType();
+                    // GROOVY-10364: skip placeholder from the enclosing context
+                    if (gt.isPlaceholder() && gt.getName().equals(name)) continue;
+
+                    gts[i] = gt;
+                } else {
+                    gts[i] = fullyResolve(gt, placeholders);
                 }
-                ClassNode cn = type.getPlainNodeReference();
-                cn.setGenericsTypes(gts);
-                return cn;
             }
         }
-        return type;
+
+        ClassNode cn = type.getPlainNodeReference();
+        cn.setGenericsTypes(gts);
+        return cn;
     }
 
     /**
diff --git a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
index 5b2a702678..a2b639a9ec 100644
--- a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
@@ -114,8 +114,8 @@ class DefaultGroovyMethodsSTCTest extends StaticTypeCheckingTestCase {
             numbers.sequence
             numbers.string
         ''',
-        '#getSequence(java.util.List<CS extends java.lang.CharSequence>) with arguments [java.util.ArrayList<java.lang.Number>]',
-        '#getString(java.util.List<java.lang.String>) with arguments [java.util.ArrayList<java.lang.Number>]',
+        'Cannot call <CS extends java.lang.CharSequence> org.codehaus.groovy.runtime.m12n.TestStringExtension#getSequence(java.util.List<CS>) with arguments [java.util.ArrayList<java.lang.Number>]',
+        'Cannot call org.codehaus.groovy.runtime.m12n.TestStringExtension#getString(java.util.List<java.lang.String>) with arguments [java.util.ArrayList<java.lang.Number>]',
         'No such property: sequence for class: java.util.ArrayList',
         'No such property: string for class: java.util.ArrayList'
     }
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 7a66f1ad02..98977f83d2 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -2164,6 +2164,25 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         }
     }
 
+    // GROOVY-10364
+    void testShouldUseMethodGenericType15() {
+        assertScript '''
+            class A<T> {
+            }
+            class B<T> {
+                void m(A<T> a_of_t, T t) {
+                }
+            }
+            class C<X, Y extends X> {
+                void test() {
+                    B<Y> b_of_y = new B<Y>()
+                    b_of_y.m(new A<Y>(), (Y) null) // Cannot call B#m(A<Y extends X>, Y) with arguments [A<Y>, Y]
+                }
+            }
+            new C<Number,Integer>().test()
+        '''
+    }
+
     // GROOVY-5516
     void testAddAllWithCollectionShouldBeAllowed() {
         assertScript '''import org.codehaus.groovy.transform.stc.ExtensionMethodNode