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

sunlan 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 c7cc2a069a GROOVY-11711: restore outer class generics after inner 
class visit
c7cc2a069a is described below

commit c7cc2a069a7e41762b4c7c00bb7b1b676af7a5e6
Author: Eric Milles <eric.mil...@thomsonreuters.com>
AuthorDate: Tue Jul 8 08:40:32 2025 -0500

    GROOVY-11711: restore outer class generics after inner class visit
---
 .../org/codehaus/groovy/control/ResolveVisitor.java   |  9 ++++++++-
 src/test/groovy/gls/innerClass/InnerClassTest.groovy  | 19 +++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java 
b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
index d671816f9f..f8bbf25e17 100644
--- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
@@ -1294,8 +1294,14 @@ public class ResolveVisitor extends 
ClassCodeExpressionTransformer {
 
         if (phase < 2) node.putNodeMetaData(AnnotationNode[].class, new 
LinkedHashSet<>());
 
-        if (!(node instanceof InnerClassNode) || 
Modifier.isStatic(node.getModifiers())) {
+        Map<GenericsTypeName, GenericsType> outerNames = null;
+        if (node instanceof InnerClassNode) {
+            outerNames = genericParameterNames;
             genericParameterNames = new HashMap<>();
+            if (!Modifier.isStatic(node.getModifiers()))
+                genericParameterNames.putAll(outerNames); // outer names 
visible
+        } else {
+            genericParameterNames.clear(); // outer class: new generic 
namespace
         }
         resolveGenericsHeader(node.getGenericsTypes());
         switch (phase) { // GROOVY-9866, GROOVY-10466
@@ -1342,6 +1348,7 @@ public class ResolveVisitor extends 
ClassCodeExpressionTransformer {
             // GROOVY-10750, GROOVY-11179: resolve and inline
             headerAnnotations.forEach(this::visitAnnotation);
         }
+        if (outerNames != null) genericParameterNames = outerNames;
         currentClass = oldNode;
     }
 
diff --git a/src/test/groovy/gls/innerClass/InnerClassTest.groovy 
b/src/test/groovy/gls/innerClass/InnerClassTest.groovy
index d834cb11e3..ed3645535d 100644
--- a/src/test/groovy/gls/innerClass/InnerClassTest.groovy
+++ b/src/test/groovy/gls/innerClass/InnerClassTest.groovy
@@ -1381,6 +1381,25 @@ final class InnerClassTest {
         assert err =~ /No enclosing instance passed in constructor call of a 
non-static inner class/
     }
 
+    // GROOVY-11711
+    @Test
+    void testUsageOfOuterType6() {
+        assertScript '''
+            class Foo<T> {
+                static class Bar {
+                }
+                /*non-static*/ class Baz
+                    implements java.util.concurrent.Callable<T> {
+                    T call() {
+                    }
+                }
+            }
+            def foo = new Foo<Short>()
+            def baz = new Foo.Baz(foo)
+            assert baz.call() == null
+        '''
+    }
+
     @Test
     void testClassOutputOrdering() {
         // this does actually not do much, but before this

Reply via email to