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 21:19:59 UTC

(groovy) branch master 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 master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new baf06b5186 GROOVY-11401: STC: don't continue member search after map-based receiver
baf06b5186 is described below

commit baf06b5186f4c0f11f126ba975071dd2db69c520
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Jun 10 15:35:30 2024 -0500

    GROOVY-11401: STC: don't continue member search after map-based receiver
---
 .../transform/stc/StaticTypeCheckingVisitor.java   |   3 +
 .../stc/FieldsAndPropertiesSTCTest.groovy          | 107 ++++++++++++++++++++-
 .../sc/FieldsAndPropertiesStaticCompileTest.groovy |  38 --------
 3 files changed, 106 insertions(+), 42 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 7442c4ae28..f81ff5c3d6 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1789,6 +1789,9 @@ out:    if ((samParameterTypes.length == 1 && isOrImplements(samParameterTypes[0
                     return true;
                 }
             }
+
+            // GROOVY-11401
+            if (!staticOnly && isOrImplements(receiverType, MAP_TYPE)) break;
         }
 
         for (Receiver<String> receiver : receivers) {
diff --git a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
index 71f244e7b1..70ca5a9eca 100644
--- a/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
+++ b/src/test/groovy/transform/stc/FieldsAndPropertiesSTCTest.groovy
@@ -842,6 +842,10 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
             assert xxx == null
             assert yyy == null
         '''
+    }
+
+    // GROOVY-11387
+    void testMapPropertyAccess12() {
         assertScript '''
             class HttpHeaders extends HashMap<String,List<String>> {
                 protected static final String ACCEPT = 'Accept'
@@ -854,6 +858,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
@@ -1224,8 +1247,7 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
             class C {
                 private int x
                 void test() {
-                    def func = { -> x = 666 }
-                    func()
+                    {-> x = 666 }()
                     assert x == 666
                 }
             }
@@ -1233,21 +1255,98 @@ class FieldsAndPropertiesSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    // GROOVY-9683
     void testPrivateFieldAccessInClosure2() {
+        assertScript '''
+            class C {
+                private static int x
+                static test() {
+                    {-> x = 666 }()
+                    assert x == 666
+                }
+            }
+            C.test()
+        '''
+    }
+
+    // GROOVY-9683
+    void testPrivateFieldAccessInClosure3() {
         assertScript '''
             class C {
                 private static X = 'xxx'
                 void test() {
-                    [:].withDefault { throw new MissingPropertyException(it.toString()) }.with {
+                    {->
+                        assert X == 'xxx'
+                    }()
+                }
+            }
+            new C().test()
+        '''
+    }
+
+    // GROOVY-9695
+    void testPrivateFieldAccessInClosure4() {
+        assertScript '''
+            class C {
+                private static final X = 'xxx'
+                void test() {
+                    Map m = [:];
+                    {->
                         assert X == 'xxx'
+                        m[X] = 123
+                    }()
+                    assert m == [xxx:123]
+                }
+            }
+            new C().test()
+
+            class D extends C {
+            }
+            new D().test()
+        '''
+    }
+
+    // GROOVY-9768
+    void testPrivateFieldAccessInClosure5() {
+        assertScript '''import groovy.transform.stc.FirstParam
+            class C {
+                private <T> void foo(
+                        @DelegatesTo.Target T target,
+                        @DelegatesTo(strategy=Closure.OWNER_FIRST)
+                        @ClosureParams(FirstParam.class) Closure action) {
+                    action.setResolveStrategy(Closure.OWNER_FIRST)
+                    action.setDelegate(target)
+                    action.call(target)
+                }
+                void test() {
+                    def map = [V: 'val']
+                    foo(map) {
+                        assert V == 'val'
+                        assert X == 'xxx'
+                        assert it.X == null
                     }
                 }
+                private static final X = 'xxx'
             }
             new C().test()
         '''
     }
 
+    // GROOVY-11144
+    void testPrivateFieldAccessInClosure6() {
+        assertScript '''
+            abstract class A {
+                private static final String NAME = 'name'
+                final String name
+                A() {
+                    name = { -> NAME }()
+                }
+            }
+            class C extends A {
+            }
+            assert new C().name == 'name'
+        '''
+    }
+
     // GROOVY-11198
     void testPrivateFieldAccessInEnumInit() {
         for (mode in ['public', 'private', 'protected', '@groovy.transform.PackageScope']) {
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 d1bf593656..0767c5ed30 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/FieldsAndPropertiesStaticCompileTest.groovy
@@ -821,44 +821,6 @@ final class FieldsAndPropertiesStaticCompileTest extends FieldsAndPropertiesSTCT
         '''
     }
 
-    // GROOVY-9683
-    void testPrivateFieldAccessInClosure3() {
-        assertScript '''
-            class C {
-                private static X = 'xxx'
-                void test() {
-                    [:].with {
-                        assert X == 'xxx'
-                    }
-                }
-            }
-            new C().test()
-        '''
-    }
-
-    // GROOVY-9695
-    void testPrivateFieldAccessInClosure4() {
-        assertScript '''
-            class C {
-                private static final X = 'xxx'
-                void test() {
-                    Map m = [:]
-                    def c = { ->
-                        assert X == 'xxx'
-                        m[X] = 123
-                    }
-                    c()
-                    assert m == [xxx:123]
-                }
-            }
-            new C().test()
-
-            class D extends C {
-            }
-            new D().test()
-        '''
-    }
-
     // GROOVY-5001, GROOVY-5491, GROOVY-11367, GROOVY-11369, GROOVY-11370
     void testMapPropertyAccess() {
         assertScript '''