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 364117de5e GROOVY-11369: map entry comes before access method (pt.2)
364117de5e is described below

commit 364117de5ea44d570fd6c10b719d979e04673ca6
Author: Eric Milles <[email protected]>
AuthorDate: Tue May 14 15:49:53 2024 -0500

    GROOVY-11369: map entry comes before access method (pt.2)
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 34 ++++++++++++++--------
 .../stc/FieldsAndPropertiesSTCTest.groovy          | 20 +++++++++++++
 .../sc/FieldsAndPropertiesStaticCompileTest.groovy | 21 +++++++++++++
 3 files changed, 63 insertions(+), 12 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 9a6eb6b26f..397189ea7e 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -257,6 +257,7 @@ import static org.codehaus.groovy.syntax.Types.MINUS_MINUS;
 import static org.codehaus.groovy.syntax.Types.MOD;
 import static org.codehaus.groovy.syntax.Types.MOD_EQUAL;
 import static org.codehaus.groovy.syntax.Types.PLUS_PLUS;
+import static 
org.codehaus.groovy.transform.sc.StaticCompilationVisitor.COMPILESTATIC_CLASSNODE;
 import static 
org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.ArrayList_TYPE;
 import static 
org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.Collection_TYPE;
 import static 
org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.LinkedHashMap_TYPE;
@@ -1582,20 +1583,20 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
                     }
                 }
 
-                MethodNode getter = findGetter(current, isserName, 
pexp.isImplicitThis());
-                getter = allowStaticAccessToMember(getter, staticOnly);
-                if (getter == null) getter = findGetter(current, getterName, 
pexp.isImplicitThis());
-                getter = allowStaticAccessToMember(getter, staticOnly);
-                if (getter != null
-                        // GROOVY-11319:
-                        && 
(!hasAccessToMember(typeCheckingContext.getEnclosingClassNode(), 
getter.getDeclaringClass(), getter.getModifiers())
-                        // GROOVY-11369:
-                        || (!isThisExpression(objectExpression) && 
!isSuperExpression(objectExpression) && isOrImplements(objectExpressionType, 
MAP_TYPE)))) {
-                    getter = null;
+                MethodNode getter = null;
+                if (!isMapProperty(pexp)) { // GROOVY-11369: map entry before 
getter
+                    getter = findGetter(current, isserName, 
pexp.isImplicitThis());
+                    getter = allowStaticAccessToMember(getter, staticOnly);
+                    if (getter == null) {
+                        getter = findGetter(current, getterName, 
pexp.isImplicitThis());
+                        getter = allowStaticAccessToMember(getter, staticOnly);
+                    }
+                    if (getter != null && 
!hasAccessToMember(typeCheckingContext.getEnclosingClassNode(), 
getter.getDeclaringClass(), getter.getModifiers())) {
+                        getter = null; // GROOVY-11319
+                    }
+                    if (readMode && getter != null && visitor != null) 
visitor.visitMethod(getter);
                 }
 
-                if (readMode && getter != null && visitor != null) 
visitor.visitMethod(getter);
-
                 PropertyNode property = current.getProperty(propertyName);
                 property = allowStaticAccessToMember(property, staticOnly);
                 // prefer explicit getter or setter over property if receiver 
is not 'this'
@@ -1825,6 +1826,15 @@ public class StaticTypeCheckingVisitor extends 
ClassCodeVisitorSupport {
         return null;
     }
 
+    private boolean isMapProperty(final PropertyExpression pexp) {
+        final Expression objectExpression = pexp.getObjectExpression();
+        if ((isThisExpression(objectExpression) || 
isSuperExpression(objectExpression))
+                && 
Arrays.asList(getTypeCheckingAnnotations()).contains(COMPILESTATIC_CLASSNODE)) {
+            return false;
+        }
+        return isOrImplements(getType(objectExpression), MAP_TYPE);
+    }
+
     /**
      * Filters search result to prevent access to instance members from a 
static
      * context.
diff --git a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy 
b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index a9ee27e763..8a9d097ec1 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -711,6 +711,26 @@ class FieldsAndPropertiesSTCTest extends 
StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-11369
+    void testMapPropertyAccess5a() {
+        for (mod in ['def', 'public', 'protected', 
'@groovy.transform.PackageScope', 'private']) {
+            assertScript """
+                class C implements Map<String,String> {
+                    @Delegate Map<String,String> impl = 
[:].withDefault{'entry'}
+                    $mod getFoo() { 'getter' }
+                    void test() {
+                        @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                            assert node.getNodeMetaData(INFERRED_TYPE) == 
STRING_TYPE
+                        })
+                        def which = this.foo
+                        assert which == 'entry'
+                    }
+                }
+                new C().test()
+            """
+        }
+    }
+
     // GROOVY-8074
     void testMapPropertyAccess6() {
         assertScript '''
diff --git 
a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
 
b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
index 0cd7e9ba50..4cab93b46e 100644
--- 
a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
+++ 
b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
@@ -866,6 +866,27 @@ final class FieldsAndPropertiesStaticCompileTest extends 
FieldsAndPropertiesSTCT
         super.testPublicFieldVersusPrivateGetter()
     }
 
+    // GROOVY-11369
+    @Override
+    void testMapPropertyAccess5a() {
+        for (mod in ['def', 'public', 'protected', 
'@groovy.transform.PackageScope', 'private']) {
+            assertScript """
+                class C implements Map<String,String> {
+                    @Delegate Map<String,String> impl = 
[:].withDefault{'entry'}
+                    $mod getFoo() { 'getter' }
+                    void test() {
+                        @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                            assert node.getNodeMetaData(INFERRED_TYPE) == 
OBJECT_TYPE
+                        })
+                        def which = this.foo
+                        assert which == 'getter'
+                    }
+                }
+                new C().test()
+            """
+        }
+    }
+
     // GROOVY-11223, GROOVY-11373
     @Override
     void testMapPropertyAccess10() {

Reply via email to