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 2020/08/26 01:53:35 UTC

[groovy] 01/01: GROOVY-9570: collect context generics starting at innermost class/method

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

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

commit 719d3138ae6bf991698f15db6e92f2255cdf157c
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Aug 25 20:51:55 2020 -0500

    GROOVY-9570: collect context generics starting at innermost class/method
---
 .../transform/stc/StaticTypeCheckingSupport.java   | 12 ++++++++++-
 .../transform/stc/StaticTypeCheckingVisitor.java   |  4 ++--
 .../stc/ClosureParamTypeInferenceSTCTest.groovy    | 24 ++++++++++++++++++++++
 3 files changed, 37 insertions(+), 3 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 959f7a3..d11aae4 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1998,7 +1998,17 @@ public abstract class StaticTypeCheckingSupport {
         return false;
     }
 
-    static Map<GenericsTypeName, GenericsType> extractGenericsParameterMapOfThis(final MethodNode mn) {
+    static Map<GenericsTypeName, GenericsType> extractGenericsParameterMapOfThis(final TypeCheckingContext context) {
+        ClassNode cn = context.getEnclosingClassNode();
+        MethodNode mn = context.getEnclosingMethod();
+        // GROOVY-9570: find the innermost class or method
+        if (cn != null && cn.getEnclosingMethod() == mn) {
+            return getGenericsParameterMapOfThis(cn);
+        }
+        return extractGenericsParameterMapOfThis(mn);
+    }
+
+    private static Map<GenericsTypeName, GenericsType> extractGenericsParameterMapOfThis(final MethodNode mn) {
         if (mn == null) return null;
 
         Map<GenericsTypeName, GenericsType> map;
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 d237f31..62068c9 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -5104,7 +5104,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         if (resolvedPlaceholders.isEmpty()) {
             return boundUnboundedWildcards(returnType);
         }
-        Map<GenericsTypeName, GenericsType> placeholdersFromContext = extractGenericsParameterMapOfThis(typeCheckingContext.getEnclosingMethod());
+        Map<GenericsTypeName, GenericsType> placeholdersFromContext = extractGenericsParameterMapOfThis(typeCheckingContext);
         applyGenericsConnections(placeholdersFromContext, resolvedPlaceholders);
 
         // then resolve receivers from method arguments
@@ -5277,7 +5277,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
     }
 
     private ClassNode resolveGenericsWithContext(final Map<GenericsTypeName, GenericsType> resolvedPlaceholders, final ClassNode currentType) {
-        Map<GenericsTypeName, GenericsType> placeholdersFromContext = extractGenericsParameterMapOfThis(typeCheckingContext.getEnclosingMethod());
+        Map<GenericsTypeName, GenericsType> placeholdersFromContext = extractGenericsParameterMapOfThis(typeCheckingContext);
         return resolveClassNodeGenerics(resolvedPlaceholders, placeholdersFromContext, currentType);
     }
 
diff --git a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
index 618f46f..d991a6f 100644
--- a/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosureParamTypeInferenceSTCTest.groovy
@@ -1376,6 +1376,30 @@ method()
         '''
     }
 
+    void testGroovy9570() {
+        assertScript '''
+            interface Item {}
+
+            class C<I extends Item> {
+                Queue<I> queue
+
+                def c = { ->
+                    queue.each { I item ->
+                        println item
+                    }
+                }
+
+                def m() {
+                    queue.each { I item ->
+                        println item
+                    }
+                }
+            }
+
+            new C()
+        '''
+    }
+
     void testGroovy9597a() {
         assertScript '''
             import groovy.transform.stc.*