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 19:27:38 UTC

[groovy] branch GROOVY_3_0_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_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new 20850bd  GROOVY-7996: correct metadata for accessed variable and property owner
20850bd is described below

commit 20850bd6be461878c17c66d0c3b572db63f69175
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   |  7 ++--
 src/test/groovy/bugs/Groovy7996.groovy             | 41 +++++++++++++++++++++-
 2 files changed, 45 insertions(+), 3 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 a609978..1f7d9a4 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -671,8 +671,10 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
             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)) {
+            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;
@@ -1616,6 +1618,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                     pexp.putNodeMetaData(DYNAMIC_RESOLUTION, Boolean.TRUE);
                     pexp.removeNodeMetaData(DECLARATION_INFERRED_TYPE);
                     pexp.removeNodeMetaData(INFERRED_TYPE);
+                    visitor.visitMethod(mopMethod);
                     return true;
                 }
             }
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()
+        '''
+    }
 }