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 2020/07/02 23:42:34 UTC
[groovy] branch master updated: GROOVY-4945,
GROOVY-9615: call invokeMissingMethod on MetaClass of super
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 3313e12 GROOVY-4945, GROOVY-9615: call invokeMissingMethod on MetaClass of super
3313e12 is described below
commit 3313e1261d1a77d3b2add209761b0199a3a946b4
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed Jul 1 17:26:18 2020 -0500
GROOVY-4945, GROOVY-9615: call invokeMissingMethod on MetaClass of super
---
src/main/java/groovy/lang/MetaClassImpl.java | 59 +++++++++++++-------------
src/test/groovy/bugs/Groovy9615.groovy | 63 ++++++++++++++++++++++++++++
2 files changed, 94 insertions(+), 28 deletions(-)
diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java
index 85a321a..63f95d3 100644
--- a/src/main/java/groovy/lang/MetaClassImpl.java
+++ b/src/main/java/groovy/lang/MetaClassImpl.java
@@ -906,39 +906,42 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
}
private Object invokeMissingMethod(Object instance, String methodName, Object[] arguments, RuntimeException original, boolean isCallToSuper) {
- if (!isCallToSuper) {
- Class instanceKlazz = instance.getClass();
- if (theClass != instanceKlazz && theClass.isAssignableFrom(instanceKlazz))
- instanceKlazz = theClass;
+ if (isCallToSuper) {
+ MetaClass metaClass = InvokerHelper.getMetaClass(theClass.getSuperclass());
+ return metaClass.invokeMissingMethod(instance, methodName, arguments);
+ }
- Class[] argClasses = MetaClassHelper.castArgumentsToClassArray(arguments);
+ Class instanceKlazz = instance.getClass();
+ if (theClass != instanceKlazz && theClass.isAssignableFrom(instanceKlazz))
+ instanceKlazz = theClass;
- MetaMethod method = findMixinMethod(methodName, argClasses);
- if (method != null) {
- onMixinMethodFound(method);
- return method.invoke(instance, arguments);
- }
+ Class[] argClasses = MetaClassHelper.castArgumentsToClassArray(arguments);
- method = findMethodInClassHierarchy(instanceKlazz, methodName, argClasses, this);
- if (method != null) {
- onSuperMethodFoundInHierarchy(method);
- return method.invoke(instance, arguments);
- }
+ MetaMethod method = findMixinMethod(methodName, argClasses);
+ if (method != null) {
+ onMixinMethodFound(method);
+ return method.invoke(instance, arguments);
+ }
- // still not method here, so see if there is an invokeMethod method up the hierarchy
- final Class[] invokeMethodArgs = {String.class, Object[].class};
- method = findMethodInClassHierarchy(instanceKlazz, INVOKE_METHOD_METHOD, invokeMethodArgs, this);
- if (method instanceof ClosureMetaMethod) {
- onInvokeMethodFoundInHierarchy(method);
- return method.invoke(instance, invokeMethodArgs);
- }
+ method = findMethodInClassHierarchy(instanceKlazz, methodName, argClasses, this);
+ if (method != null) {
+ onSuperMethodFoundInHierarchy(method);
+ return method.invoke(instance, arguments);
+ }
- // last resort look in the category
- if (method == null && GroovyCategorySupport.hasCategoryInCurrentThread()) {
- method = getCategoryMethodMissing(instanceKlazz);
- if (method != null) {
- return method.invoke(instance, new Object[]{methodName, arguments});
- }
+ // still not method here, so see if there is an invokeMethod method up the hierarchy
+ final Class[] invokeMethodArgs = {String.class, Object[].class};
+ method = findMethodInClassHierarchy(instanceKlazz, INVOKE_METHOD_METHOD, invokeMethodArgs, this);
+ if (method instanceof ClosureMetaMethod) {
+ onInvokeMethodFoundInHierarchy(method);
+ return method.invoke(instance, invokeMethodArgs);
+ }
+
+ // last resort look in the category
+ if (method == null && GroovyCategorySupport.hasCategoryInCurrentThread()) {
+ method = getCategoryMethodMissing(instanceKlazz);
+ if (method != null) {
+ return method.invoke(instance, new Object[]{methodName, arguments});
}
}
diff --git a/src/test/groovy/bugs/Groovy9615.groovy b/src/test/groovy/bugs/Groovy9615.groovy
new file mode 100644
index 0000000..fd8e6ab
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9615.groovy
@@ -0,0 +1,63 @@
+/*
+ * 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 org.junit.Test
+
+import static groovy.test.GroovyAssert.shouldFail
+
+final class Groovy9615 {
+
+ @Test // GROOVY-4945
+ void testCallSuperMethod1() {
+ def err = shouldFail MissingMethodException, '''
+ class C {
+ void test() {
+ super.whatever()
+ }
+ void whatever() {
+ assert false : 'should not have been called!'
+ }
+ }
+ new C().test()
+ '''
+
+ assert err =~ /No signature of method: java\.lang\.Object\.whatever\(\) is applicable for argument types: \(\) values: \[\]
+Possible solutions: every\(\)$/
+ }
+
+ @Test // GROOVY-9615
+ void testCallSuperMethod2() {
+ def err = shouldFail MissingMethodException, '''
+ class Outer {
+ class Inner {
+ void test() {
+ super.whatever()
+ }
+ }
+ void whatever() {
+ assert false : 'should not have been called!'
+ }
+ }
+ new Outer.Inner(new Outer()).test()
+ '''
+
+ assert err =~ /No signature of method: java\.lang\.Object\.whatever\(\) is applicable for argument types: \(\) values: \[\]/
+ }
+}