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 2021/06/16 08:01:52 UTC

[groovy] 01/01: Fix calling method derived from super type

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

sunlan pushed a commit to branch danielsun/tweak-build
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 99b6d743646bda153b9b30bf27dfccad793ac32a
Author: Daniel Sun <su...@apache.org>
AuthorDate: Wed Jun 16 14:39:08 2021 +0800

    Fix calling method derived from super type
---
 src/main/java/groovy/lang/MetaClassImpl.java | 55 +++++++++++++++++++---------
 1 file changed, 37 insertions(+), 18 deletions(-)

diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java
index 1394318..533045d 100644
--- a/src/main/java/groovy/lang/MetaClassImpl.java
+++ b/src/main/java/groovy/lang/MetaClassImpl.java
@@ -1134,36 +1134,55 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
     public Object invokeMethod(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, boolean fromInsideClass) {
         try {
             return doInvokeMethod(sender, object, methodName, originalArguments, isCallToSuper, fromInsideClass);
-        } catch (MissingMethodException ex) {
-            if (!isCallToSuper) {
-                throw ex;
-            }
-
-            if (!(object instanceof GroovyObject)) {
-                throw ex;
-            }
+        } catch (MissingMethodException mme) {
+            return doInvokeMethodFallback(sender, object, methodName, originalArguments, isCallToSuper, mme);
+        }
+    }
 
+    private Object doInvokeMethodFallback(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, MissingMethodException mme) {
+        MethodHandles.Lookup lookup = null;
+        if (object instanceof GroovyObject) {
             Optional<MethodHandles.Lookup> lookupOptional = GroovyObjectHelper.lookup((GroovyObject) object);
-            if (!lookupOptional.isPresent()) {
-                throw ex;
-            }
-            MethodHandles.Lookup lookup = lookupOptional.get();
-            Method superMethod = findSuperMethod(sender, methodName, originalArguments);
-            if (null == superMethod) {
-                throw ex;
+            if (!lookupOptional.isPresent()) throw mme;
+            lookup = lookupOptional.get();
+        }
+
+        if (isCallToSuper) {
+            if (null == lookup) throw mme;
+            Method superMethod = findMethod(sender, methodName, originalArguments);
+            if (null == superMethod) throw mme;
+            MethodHandle superMethodHandle;
+            try {
+                superMethodHandle = lookup.unreflectSpecial(superMethod, object.getClass());
+            } catch (IllegalAccessException e) {
+                throw mme;
             }
             try {
-                MethodHandle superMethodHandle = lookup.unreflectSpecial(superMethod, object.getClass());
                 return superMethodHandle.bindTo(object).invokeWithArguments(originalArguments);
             } catch (Throwable t) {
                 throw new GroovyRuntimeException(t);
             }
+        } else {
+            if (null == lookup) lookup = MethodHandles.lookup().in(object.getClass());
+            Method thisMethod = findMethod(object.getClass(), methodName, originalArguments);
+            if (null == thisMethod) throw mme;
+            MethodHandle thisMethodHandle;
+            try {
+                thisMethodHandle = lookup.unreflect(thisMethod);
+            } catch (IllegalAccessException e) {
+                throw mme;
+            }
+            try {
+                return thisMethodHandle.bindTo(object).invokeWithArguments(originalArguments);
+            } catch (Throwable t) {
+                throw new GroovyRuntimeException(t);
+            }
         }
     }
 
-    private static Method findSuperMethod(Class senderClass, String messageName, Object[] messageArguments) {
+    private static Method findMethod(Class clazz, String messageName, Object[] messageArguments) {
         Class[] parameterTypes = MetaClassHelper.castArgumentsToClassArray(messageArguments);
-        for (Class<?> c = senderClass; null != c; c = c.getSuperclass()) {
+        for (Class<?> c = clazz; null != c; c = c.getSuperclass()) {
             List<Method> declaredMethodList = ReflectionUtils.getDeclaredMethods(c, messageName, parameterTypes);
             if (!declaredMethodList.isEmpty()) {
                 Method superMethod = declaredMethodList.get(0);