GROOVY-7701: SC: replace field/property reference with dynamic variable
- VariableScopeVisitor lacks closure delegation information
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 da55cbf..be84a4c 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -664,6 +664,12 @@
vexp.removeNodeMetaData(INFERRED_TYPE);
ClassNode type = pexp.getNodeMetaData(INFERRED_TYPE);
storeType(vexp, Optional.ofNullable(type).orElseGet(pexp::getType));
+
+ String receiver = vexp.getNodeMetaData(IMPLICIT_RECEIVER);
+ // GROOVY-7701: correct false assumption made by VariableScopeVisitor
+ if (receiver != null && !receiver.endsWith("owner") && !(vexp.getAccessedVariable() instanceof DynamicVariable)) {
+ vexp.setAccessedVariable(new DynamicVariable(dynName, false));
+ }
return true;
}
return false;
diff --git a/src/test/groovy/transform/stc/ClosuresSTCTest.groovy b/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
index 80bd2bc..17b7a33 100644
--- a/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
+++ b/src/test/groovy/transform/stc/ClosuresSTCTest.groovy
@@ -127,6 +127,36 @@
'''
}
+ // GROOVY-7701
+ void testWithDelegateVsOwnerField() {
+ assertScript '''
+ class Foo {
+ List type
+ }
+
+ class Bar {
+ int type = 10
+
+ @Lazy
+ List<Foo> something = { ->
+ List<Foo> tmp = []
+ def foo = new Foo()
+ foo.with {
+ type = ['String']
+ // ^^^^ should be Foo.type, not Bar.type
+ }
+ tmp.add(foo)
+ tmp
+ }()
+ }
+
+ def bar = new Bar()
+ assert bar.type == 10
+ assert bar.something*.type == [['String']]
+ assert bar.type == 10
+ '''
+ }
+
void testClosureShouldNotChangeInferredType() {
assertScript '''
def x = '123';