You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2020/02/12 05:01:15 UTC
[groovy] branch GROOVY_2_5_X updated: GROOVY-9387:
MissingMethodException: try one more metaClass.invokeMethod
This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
new 75c0682 GROOVY-9387: MissingMethodException: try one more metaClass.invokeMethod
75c0682 is described below
commit 75c068207ba24648ea2d698c520601c6fcf0a45b
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Feb 8 10:30:49 2020 -0600
GROOVY-9387: MissingMethodException: try one more metaClass.invokeMethod
---
.../groovy/runtime/callsite/PogoMetaClassSite.java | 15 ++-
src/test/groovy/bugs/Groovy9387.groovy | 102 +++++++++++++++++++++
2 files changed, 113 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/runtime/callsite/PogoMetaClassSite.java b/src/main/java/org/codehaus/groovy/runtime/callsite/PogoMetaClassSite.java
index 4b16fcb..7a52680 100644
--- a/src/main/java/org/codehaus/groovy/runtime/callsite/PogoMetaClassSite.java
+++ b/src/main/java/org/codehaus/groovy/runtime/callsite/PogoMetaClassSite.java
@@ -49,7 +49,7 @@ public class PogoMetaClassSite extends MetaClassSite {
throw ScriptBytecodeAdapter.unwrap(gre);
}
} else {
- return CallSiteArray.defaultCall(this, receiver, args);
+ return CallSiteArray.defaultCall(this, receiver, args);
}
}
@@ -66,8 +66,15 @@ public class PogoMetaClassSite extends MetaClassSite {
if (e instanceof MissingMethodExecutionFailed) {
throw (MissingMethodException)e.getCause();
} else if (receiver.getClass() == e.getType() && e.getMethod().equals(name)) {
- // in case there's nothing else, invoke the object's own invokeMethod()
- return ((GroovyObject)receiver).invokeMethod(name, args);
+ // in case there's nothing else, invoke the receiver's own invokeMethod()
+ try {
+ return receiver.invokeMethod(name, args);
+ } catch (MissingMethodException mme) {
+ if (mme instanceof MissingMethodExecutionFailed)
+ throw (MissingMethodException) mme.getCause();
+ // GROOVY-9387: in rare cases, this form still works
+ return metaClass.invokeMethod(receiver, name, args);
+ }
} else {
throw e;
}
@@ -76,7 +83,7 @@ public class PogoMetaClassSite extends MetaClassSite {
throw ScriptBytecodeAdapter.unwrap(gre);
}
} else {
- return CallSiteArray.defaultCallCurrent(this, receiver, args);
+ return CallSiteArray.defaultCallCurrent(this, receiver, args);
}
}
}
diff --git a/src/test/groovy/bugs/Groovy9387.groovy b/src/test/groovy/bugs/Groovy9387.groovy
new file mode 100644
index 0000000..ea0df36
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9387.groovy
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package groovy.bugs
+
+import groovy.transform.CompileStatic
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+@CompileStatic
+final class Groovy9387 {
+
+ private static final String SUPPORT_ADAPTER = '''
+ class BuilderSupportAdapter extends BuilderSupport {
+ def createNode(a, b) {}
+ def createNode(a) {}
+ def createNode(a, Map b) {}
+ def createNode(a, Map b, c) {}
+ void setParent(a, b) {}
+ }
+ '''
+
+ @Test
+ void testThisPropertySet() {
+ assertScript SUPPORT_ADAPTER + '''
+ class C extends BuilderSupportAdapter {
+ String value = 'abc'
+ void test() {
+ def b = { -> this.'value' = 'def' }
+ b()
+ }
+ }
+
+ def c = new C()
+ def v = c.value
+ assert v == 'abc'
+
+ c.test()
+ v = c.value
+ assert v == 'def'
+ '''
+ }
+
+ @Test
+ void testThisSetProperty() {
+ assertScript SUPPORT_ADAPTER + '''
+ class C extends BuilderSupportAdapter {
+ String value = 'abc'
+ void test() {
+ def b = { -> this.setProperty('value', 'def') }
+ b()
+ }
+ }
+
+ def c = new C()
+ def v = c.value
+ assert v == 'abc'
+
+ c.test()
+ v = c.value
+ assert v == 'def'
+ '''
+ }
+
+ @Test
+ void testThatSetProperty() {
+ assertScript SUPPORT_ADAPTER + '''
+ class C extends BuilderSupportAdapter {
+ private C that = this
+ String value = 'abc'
+ void test() {
+ def b = { -> that.setProperty('value', 'def') }
+ b()
+ }
+ }
+
+ def c = new C()
+ def v = c.value
+ assert v == 'abc'
+
+ c.test()
+ v = c.value
+ assert v == 'def'
+ '''
+ }
+}
\ No newline at end of file