[groovy] branch master updated: GROOVY-7996: check for get(String)/set(String, Object) or propertyMissing

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[groovy] branch master updated: GROOVY-7996: check for get(String)/set(String, Object) or propertyMissing

Daniel.Sun
This is an automated email from the ASF dual-hosted git repository.

sunlan 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 8b0e5b7  GROOVY-7996: check for get(String)/set(String,Object) or propertyMissing
8b0e5b7 is described below

commit 8b0e5b7bc9aa7af2c08faee5dad482899a6a0265
Author: Eric Milles <[hidden email]>
AuthorDate: Tue Nov 5 18:56:17 2019 -0600

    GROOVY-7996: check for get(String)/set(String,Object) or propertyMissing
---
 .../transform/stc/StaticTypeCheckingVisitor.java      | 19 +++++++++++++++++++
 src/test/groovy/bugs/Groovy7996.groovy                | 14 +++++++++-----
 2 files changed, 28 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 b8d7a8c..ae8bee4 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1694,6 +1694,25 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                     }
                 }
             }
+
+            // GROOVY-7996: check if receiver implements get(String)/set(String,Object) or propertyMissing(String)
+            if (!testClass.isArray() && !isPrimitiveType(getUnwrapper(testClass))
+                    && pexp.isImplicitThis() && typeCheckingContext.getEnclosingClosure() != null) {
+                MethodNode mopMethod;
+                if (readMode) {
+                    mopMethod = testClass.getMethod("get", new Parameter[]{new Parameter(STRING_TYPE, "name")});
+                } else {
+                    mopMethod = testClass.getMethod("set", new Parameter[]{new Parameter(STRING_TYPE, "name"), new Parameter(OBJECT_TYPE, "value")});
+                }
+                if (mopMethod == null) mopMethod = testClass.getMethod("propertyMissing", new Parameter[]{new Parameter(STRING_TYPE, "propertyName")});
+
+                if (mopMethod != null) {
+                    pexp.putNodeMetaData(DYNAMIC_RESOLUTION, Boolean.TRUE);
+                    pexp.removeNodeMetaData(DECLARATION_INFERRED_TYPE);
+                    pexp.removeNodeMetaData(INFERRED_TYPE);
+                    return true;
+                }
+            }
         }
 
         for (Receiver<String> receiver : receivers) {
diff --git a/src/test/groovy/bugs/Groovy7996.groovy b/src/test/groovy/bugs/Groovy7996.groovy
index fc0872f..39de261 100644
--- a/src/test/groovy/bugs/Groovy7996.groovy
+++ b/src/test/groovy/bugs/Groovy7996.groovy
@@ -18,16 +18,18 @@
  */
 package groovy.bugs
 
-import groovy.test.NotYetImplemented
+import groovy.transform.CompileStatic
 import org.junit.Test
 
 import static groovy.test.GroovyAssert.assertScript
+import static groovy.test.GroovyAssert.shouldFail
 
+@CompileStatic
 final class Groovy7996 {
 
-    @Test @NotYetImplemented
+    @Test
     void testFieldAccessFromClosure1() {
-        assertScript '''
+        def err = shouldFail '''
             class Foo {
                 def build(@DelegatesTo(value=Foo, strategy=Closure.DELEGATE_FIRST) Closure block) {
                     this.with(block)
@@ -45,13 +47,15 @@ final class Groovy7996 {
                 boolean doStuff() {
                     Foo foo = new Foo()
                     foo.build {
-                        bar.isEmpty() // "ClassCastException: java.lang.String cannot be cast to java.util.List"
+                        bar.isEmpty() // ClassCastException: java.lang.String cannot be cast to java.util.List
                     }
                 }
             }
 
-            assert new Bar().doStuff()
+            new Bar().doStuff()
         '''
+
+        assert err =~ /Cannot find matching method java.lang.Object#isEmpty\(\)/
     }
 
     @Test

Apache Groovy committer & PMC member

Blog: http://blog.sunlan.me
Twitter: @daniel_sun