This is an automated email from the ASF dual-hosted git repository. emilles pushed a commit to branch GROOVY_4_0_X in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push: new 33064484cc GROOVY-11711: restore outer class generics after inner class visit 33064484cc is described below commit 33064484cc043bfb7c2ad75ee8fccbcbc6329b76 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 4_0_X backport --- .../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 1af01a97d9..383c0bffa7 100644 --- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java +++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java @@ -1272,8 +1272,14 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer { // - 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 @@ -1316,6 +1322,7 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer { visitObjectInitializerStatements(node); visitAnnotations(node); // GROOVY-10750, GROOVY-11206 } + 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 148a562bea..4378c49efa 100644 --- a/src/test/groovy/gls/innerClass/InnerClassTest.groovy +++ b/src/test/groovy/gls/innerClass/InnerClassTest.groovy @@ -1265,6 +1265,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