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/15 17:10:34 UTC

[groovy] branch danielsun/tweak-build updated: Fix calling method of 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


The following commit(s) were added to refs/heads/danielsun/tweak-build by this push:
     new 2adf1b8  Fix calling method of super type
2adf1b8 is described below

commit 2adf1b8bc5dc43ee6ec55c41e5678ba5785ebdcf
Author: Daniel Sun <su...@apache.org>
AuthorDate: Wed Jun 16 01:10:14 2021 +0800

    Fix calling method of super type
---
 .../groovy/runtime/ScriptBytecodeAdapter.java      | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java b/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java
index 9c19475..5ff0401 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java
@@ -39,6 +39,10 @@ import org.codehaus.groovy.runtime.wrappers.GroovyObjectWrapper;
 import org.codehaus.groovy.runtime.wrappers.PojoWrapper;
 import org.codehaus.groovy.runtime.wrappers.Wrapper;
 
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -142,12 +146,38 @@ public class ScriptBytecodeAdapter {
         Object result = null;
         try {
             result = metaClass.invokeMethod(senderClass, receiver, messageName, messageArguments, true, true);
+        } catch (MissingMethodException ex) {
+            try {
+                MethodHandles.Lookup lookup = (MethodHandles.Lookup) MethodHandles.lookup()
+                        .findStatic(receiver.getClass(), "$getLookup", MethodType.methodType(MethodHandles.Lookup.class, new Class[0]))
+                        .invokeExact();
+
+                Method superMethod = findSuperMethod(senderClass, messageName, messageArguments);
+                if (null == superMethod) {
+                    throw unwrap(ex);
+                }
+                MethodHandle superMethodHandle = lookup.unreflectSpecial(superMethod, receiver.getClass());
+                return superMethodHandle.bindTo(receiver).invokeWithArguments(messageArguments);
+            } catch (NoSuchMethodException | IllegalAccessException e) {
+                throw e;
+            }
         } catch (GroovyRuntimeException gre) {
             throw unwrap(gre);
         }
         return result;
     }
 
+    private static Method findSuperMethod(Class senderClass, String messageName, Object[] messageArguments) {
+        Class[] parameterTypes = MetaClassHelper.castArgumentsToClassArray(messageArguments);
+        for (Class<?> c = senderClass; null != c; c = c.getSuperclass()) {
+            try {
+                return c.getDeclaredMethod(messageName, parameterTypes);
+            } catch (NoSuchMethodException ignored) {
+            }
+        }
+        return null;
+    }
+
     public static Object invokeMethodOnSuperNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
         return invokeMethodOnSuperN(senderClass, receiver, messageName, messageArguments);
     }