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 2024/06/10 20:06:43 UTC

(groovy) branch GROOVY_4_0_X updated: GROOVY-11401: STC: don't continue member search after map-based receiver

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 972d0f23c6 GROOVY-11401: STC: don't continue member search after map-based receiver
972d0f23c6 is described below

commit 972d0f23c6cf8f4ee37079bcfdde7d2cd910d493
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Jun 10 14:34:35 2024 -0500

    GROOVY-11401: STC: don't continue member search after map-based receiver
---
 .../transform/stc/StaticTypeCheckingVisitor.java      |  7 +++++--
 .../transform/stc/FieldsAndPropertiesSTCTest.groovy   | 19 +++++++++++++++++++
 2 files changed, 24 insertions(+), 2 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 832a201320..c4c1108d10 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1658,7 +1658,10 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                 foundGetterOrSetter = (foundGetterOrSetter || getter != null || !setters.isEmpty());
             }
 
-            if (readMode && !isMapProperty(pexp, receiverType)) { // GROOVY-11369, GROOVY-11370, GROOVY-11372
+            // GROOVY-11369, GROOVY-11370, GROOVY-11372, GROOVY-11401: map entry
+            if (isMapProperty(pexp, receiverType)) break;
+
+            if (readMode) {
                 // GROOVY-5568, GROOVY-9115, GROOVY-9123: the property may be provided by an extension method
                 for (ClassNode dgmReceiver : isPrimitiveType(receiverType) ? new ClassNode[]{receiverType, getWrapper(receiverType)} : new ClassNode[]{receiverType}) {
                     Set<MethodNode> methods = findDGMMethodsForClassNode(getSourceUnit().getClassLoader(), dgmReceiver, getterName);
@@ -1690,7 +1693,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                 }
             }
 
-            // GROOVY-7996: check if receiver implements get(String)/set(String,Object) or propertyMissing(String) or $static_propertyMissing(String)?
+            // GROOVY-7996: check if receiver implements get(String)/set(String,Object) or propertyMissing(String)
             if (!receiverType.isArray() && !isPrimitiveType(getUnwrapper(receiverType))
                     && pexp.isImplicitThis() && typeCheckingContext.getEnclosingClosure() != null) {
                 MethodNode mopMethod;
diff --git a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index c027a9ef36..977e728e6d 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -1040,6 +1040,25 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-11401
+    void testMapPropertyAccess13() {
+        assertScript '''
+            class C {
+                private Object obj = 'field'
+                def m() {
+                    Map<String,String> map = [:].withDefault{'entry'}
+                    map.with {
+                        @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                            assert node.getNodeMetaData(INFERRED_TYPE) == STRING_TYPE
+                        })
+                        def xxx = obj
+                    }
+                }
+            }
+            assert new C().m() == 'entry'
+        '''
+    }
+
     void testTypeCheckerDoesNotThinkPropertyIsReadOnly() {
         assertScript '''
             // a base class defining a read-only property