diff --git a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java index 383c0bffa78..1af01a97d9e 100644 --- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java +++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java @@ -1272,14 +1272,8 @@ public void visitClass(final ClassNode node) { // - Map outerNames = null; - if (node instanceof InnerClassNode) { - outerNames = genericParameterNames; + if (!(node instanceof InnerClassNode) || Modifier.isStatic(node.getModifiers())) { 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 @@ -1322,7 +1316,6 @@ public void visitClass(final ClassNode node) { 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 4378c49efa7..148a562bea6 100644 --- a/src/test/groovy/gls/innerClass/InnerClassTest.groovy +++ b/src/test/groovy/gls/innerClass/InnerClassTest.groovy @@ -1265,25 +1265,6 @@ 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 { - static class Bar { - } - /*non-static*/ class Baz - implements java.util.concurrent.Callable { - T call() { - } - } - } - def foo = new Foo() - def baz = new Foo.Baz(foo) - assert baz.call() == null - ''' - } - @Test void testClassOutputOrdering() { // this does actually not do much, but before this diff --git a/src/test/groovy/groovy/util/GroovyScriptEngineReloadingTest.groovy b/src/test/groovy/groovy/util/GroovyScriptEngineReloadingTest.groovy index 660f4ddcf0c..935d99abc8e 100644 --- a/src/test/groovy/groovy/util/GroovyScriptEngineReloadingTest.groovy +++ b/src/test/groovy/groovy/util/GroovyScriptEngineReloadingTest.groovy @@ -182,6 +182,39 @@ final class GroovyScriptEngineReloadingTest { } + @Test + void testRecompilingWithGenericsAndConstants() { + MapFileSystem.instance.modFile('BaseClass.groovy', 'class BaseClass {}', gse.@time) + + def tertiaryClassText = ''' + class NotGeneric { + /** + * Not typed on purpose - if typed as String then NotGeneric is no longer a dependency of + * ParameterisedClass for some reason... + */ + public static final Object CONSTANT = "not generic" + } + ''' + MapFileSystem.instance.modFile('NotGeneric.groovy', tertiaryClassText, gse.@time) + + def subClassText = ''' + class SubClass extends BaseClass { + public static final String CONSTANT = NotGeneric.CONSTANT + } + ''' + MapFileSystem.instance.modFile('SubClass.groovy', subClassText, gse.@time) + + MapFileSystem.instance.modFile('scriptUsingGeneric.groovy', 'SubClass.CONSTANT', gse.@time) + + + gse.loadScriptByName('scriptUsingGeneric.groovy') + sleep 1000 + + // make a change to the sub-class so that it gets recompiled + MapFileSystem.instance.modFile('SubClass.groovy', subClassText + '\n', gse.@time) + gse.loadScriptByName('scriptUsingGeneric.groovy') + } + @Test void testDeleteDependent() { sleep 10000