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 2021/02/22 20:31:18 UTC
[groovy] branch GROOVY_2_5_X updated: GROOVY-7996: correct metadata
for accessed variable and property owner
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
new a001a0c GROOVY-7996: correct metadata for accessed variable and property owner
a001a0c is described below
commit a001a0c3e9067eb4f4cd4bae2ebeb7130ad5adc3
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Feb 22 12:32:16 2021 -0600
GROOVY-7996: correct metadata for accessed variable and property owner
---
.../transform/stc/StaticTypeCheckingVisitor.java | 12 ++++---
src/test/groovy/bugs/Groovy7996.groovy | 41 +++++++++++++++++++++-
2 files changed, 48 insertions(+), 5 deletions(-)
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 819d9ff..4b97e96 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -264,6 +264,7 @@ import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.typeCh
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.typeCheckMethodsWithGenerics;
import static org.codehaus.groovy.transform.stc.StaticTypesMarker.DECLARATION_INFERRED_TYPE;
import static org.codehaus.groovy.transform.stc.StaticTypesMarker.DIRECT_METHOD_CALL_TARGET;
+import static org.codehaus.groovy.transform.stc.StaticTypesMarker.DYNAMIC_RESOLUTION;
import static org.codehaus.groovy.transform.stc.StaticTypesMarker.IMPLICIT_RECEIVER;
import static org.codehaus.groovy.transform.stc.StaticTypesMarker.INFERRED_TYPE;
import static org.codehaus.groovy.transform.stc.StaticTypesMarker.PV_FIELDS_ACCESS;
@@ -721,8 +722,10 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
storeType(vexp, type != null ? type: 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)) {
+ Boolean dynamic = pexp.getNodeMetaData(DYNAMIC_RESOLUTION);
+ // GROOVY-7701, GROOVY-7996: correct false assumption made by VariableScopeVisitor
+ if (((receiver != null && !receiver.endsWith("owner")) || Boolean.TRUE.equals(dynamic))
+ && !(vexp.getAccessedVariable() instanceof DynamicVariable)) {
vexp.setAccessedVariable(new DynamicVariable(dynName, false));
}
return true;
@@ -1602,9 +1605,10 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
if (mopMethod == null) mopMethod = receiverType.getMethod("propertyMissing", new Parameter[]{new Parameter(STRING_TYPE, "propertyName")});
if (mopMethod != null && !mopMethod.isStatic() && !mopMethod.isSynthetic()) {
- pexp.putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, Boolean.TRUE);
+ pexp.putNodeMetaData(DYNAMIC_RESOLUTION, Boolean.TRUE);
pexp.removeNodeMetaData(DECLARATION_INFERRED_TYPE);
pexp.removeNodeMetaData(INFERRED_TYPE);
+ visitor.visitMethod(mopMethod);
return true;
}
}
@@ -3398,7 +3402,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
mn = disambiguateMethods(mn, chosenReceiver != null ? chosenReceiver.getType() : null, args, call);
if (mn.size() == 1) {
MethodNode directMethodCallCandidate = mn.get(0);
- if (call.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION) == null &&
+ if (call.getNodeMetaData(DYNAMIC_RESOLUTION) == null &&
!directMethodCallCandidate.isStatic() && objectExpression instanceof ClassExpression &&
!"java.lang.Class".equals(directMethodCallCandidate.getDeclaringClass().getName())) {
ClassNode owner = directMethodCallCandidate.getDeclaringClass();
diff --git a/src/test/groovy/bugs/Groovy7996.groovy b/src/test/groovy/bugs/Groovy7996.groovy
index 39de261..3c2d443 100644
--- a/src/test/groovy/bugs/Groovy7996.groovy
+++ b/src/test/groovy/bugs/Groovy7996.groovy
@@ -171,7 +171,7 @@ final class Groovy7996 {
}
@Test // GROOVY-8073
- void testDelegatePropertyAccessFromClosure() {
+ void testDelegatePropertyAccessFromClosure1() {
assertScript '''
@groovy.transform.CompileStatic
class Main {
@@ -184,4 +184,43 @@ final class Groovy7996 {
}
'''
}
+
+ @Test
+ void testDelegatePropertyAccessFromClosure2() {
+ assertScript '''
+ import groovy.transform.*
+ import org.codehaus.groovy.ast.DynamicVariable
+ import org.codehaus.groovy.ast.expr.VariableExpression
+ import static org.codehaus.groovy.ast.ClassHelper.OBJECT_TYPE
+ import static org.codehaus.groovy.transform.stc.StaticTypesMarker.INFERRED_TYPE
+ import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.PROPERTY_OWNER
+
+ class JSON {
+ def get(String name) {
+ new JSON()
+ }
+ }
+
+ class POGO {
+ Number getAnswer() {
+ 42
+ }
+ @CompileStatic
+ void usage() {
+ new JSON().with {
+ @ASTTest(phase=CLASS_GENERATION, value={
+ def vexp = node.rightExpression
+ assert vexp instanceof VariableExpression
+ assert vexp.accessedVariable instanceof DynamicVariable
+ assert vexp.getNodeMetaData(INFERRED_TYPE) == OBJECT_TYPE
+ assert vexp.getNodeMetaData(PROPERTY_OWNER).name == 'JSON'
+ })
+ def result = answer // "answer" accessed from JSON; "getAnswer()" invoked from POGO
+ }
+ }
+ }
+
+ new POGO().usage()
+ '''
+ }
}