You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2019/11/09 07:18:43 UTC
[groovy] 12/12: GROOVY-7996: check for get(String)/set(String,
Object) or propertyMissing
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 94bc65cb81d0bd613aaf1700c2a75f6be8c9b4da
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Nov 5 18:56:17 2019 -0600
GROOVY-7996: check for get(String)/set(String,Object) or propertyMissing
(cherry picked from commit 8b0e5b7bc9aa7af2c08faee5dad482899a6a0265)
---
.../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