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 05:48:02 UTC

[groovy] branch danielsun/tweak-build updated: Minor refactoring

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 298b68d  Minor refactoring
298b68d is described below

commit 298b68d6639478ce08c4eb2e172c1b3d60f49f62
Author: Daniel Sun <su...@apache.org>
AuthorDate: Wed Jun 16 13:47:48 2021 +0800

    Minor refactoring
---
 src/main/java/groovy/lang/MetaClassImpl.java       | 50 ++++++++++++++++++++++
 .../groovy/runtime/ScriptBytecodeAdapter.java      | 39 -----------------
 2 files changed, 50 insertions(+), 39 deletions(-)

diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java
index 2046b3e..1394318 100644
--- a/src/main/java/groovy/lang/MetaClassImpl.java
+++ b/src/main/java/groovy/lang/MetaClassImpl.java
@@ -19,6 +19,7 @@
 package groovy.lang;
 
 import org.apache.groovy.internal.util.UncheckedThrow;
+import org.apache.groovy.lang.GroovyObjectHelper;
 import org.apache.groovy.util.BeanUtils;
 import org.apache.groovy.util.SystemUtil;
 import org.codehaus.groovy.GroovyBugError;
@@ -35,6 +36,7 @@ import org.codehaus.groovy.reflection.ClassInfo;
 import org.codehaus.groovy.reflection.GeneratedMetaMethod;
 import org.codehaus.groovy.reflection.ParameterTypes;
 import org.codehaus.groovy.reflection.ReflectionCache;
+import org.codehaus.groovy.reflection.ReflectionUtils;
 import org.codehaus.groovy.reflection.android.AndroidSupport;
 import org.codehaus.groovy.runtime.ArrayTypeUtils;
 import org.codehaus.groovy.runtime.ConvertedClosure;
@@ -85,6 +87,8 @@ import java.beans.BeanInfo;
 import java.beans.EventSetDescriptor;
 import java.beans.Introspector;
 import java.beans.PropertyDescriptor;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
 import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
@@ -106,6 +110,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -1127,6 +1132,51 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
      */
     @Override
     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;
+            }
+
+            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;
+            }
+            try {
+                MethodHandle superMethodHandle = lookup.unreflectSpecial(superMethod, object.getClass());
+                return superMethodHandle.bindTo(object).invokeWithArguments(originalArguments);
+            } catch (Throwable t) {
+                throw new GroovyRuntimeException(t);
+            }
+        }
+    }
+
+    private static Method findSuperMethod(Class senderClass, String messageName, Object[] messageArguments) {
+        Class[] parameterTypes = MetaClassHelper.castArgumentsToClassArray(messageArguments);
+        for (Class<?> c = senderClass; null != c; c = c.getSuperclass()) {
+            List<Method> declaredMethodList = ReflectionUtils.getDeclaredMethods(c, messageName, parameterTypes);
+            if (!declaredMethodList.isEmpty()) {
+                Method superMethod = declaredMethodList.get(0);
+                if (Modifier.isAbstract(superMethod.getModifiers())) {
+                    continue;
+                }
+                return superMethod;
+            }
+        }
+        return null;
+    }
+
+    private Object doInvokeMethod(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, boolean fromInsideClass) {
         checkInitalised();
         if (object == null) {
             throw new NullPointerException("Cannot invoke method: " + methodName + " on null object");
diff --git a/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java b/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java
index 742c7ba..9c19475 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java
@@ -31,8 +31,6 @@ import groovy.lang.MissingPropertyException;
 import groovy.lang.NumberRange;
 import groovy.lang.ObjectRange;
 import groovy.lang.Tuple;
-import org.apache.groovy.lang.GroovyObjectHelper;
-import org.codehaus.groovy.reflection.ReflectionUtils;
 import org.codehaus.groovy.runtime.metaclass.MissingMethodExceptionNoStack;
 import org.codehaus.groovy.runtime.metaclass.MissingMethodExecutionFailed;
 import org.codehaus.groovy.runtime.metaclass.MissingPropertyExceptionNoStack;
@@ -41,16 +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.MethodHandles.Lookup;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -150,43 +142,12 @@ public class ScriptBytecodeAdapter {
         Object result = null;
         try {
             result = metaClass.invokeMethod(senderClass, receiver, messageName, messageArguments, true, true);
-        } catch (MissingMethodException ex) {
-            try {
-                Optional<MethodHandles.Lookup> lookupOptional = GroovyObjectHelper.lookup(receiver);
-                if (!lookupOptional.isPresent()) {
-                    throw unwrap(ex);
-                }
-                Lookup lookup = lookupOptional.get();
-                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()) {
-            List<Method> declaredMethodList = ReflectionUtils.getDeclaredMethods(c, messageName, parameterTypes);
-            if (!declaredMethodList.isEmpty()) {
-                Method superMethod = declaredMethodList.get(0);
-                if (Modifier.isAbstract(superMethod.getModifiers())) {
-                    continue;
-                }
-                return superMethod;
-            }
-        }
-        return null;
-    }
-
     public static Object invokeMethodOnSuperNSafe(Class senderClass, GroovyObject receiver, String messageName, Object[] messageArguments) throws Throwable {
         return invokeMethodOnSuperN(senderClass, receiver, messageName, messageArguments);
     }