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 10:47:10 UTC
[groovy] branch danielsun/tweak-build updated: Support clone array
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 92ab4dc Support clone array
92ab4dc is described below
commit 92ab4dc283219f952ae2730f36eb110c9e80bb9b
Author: Daniel Sun <su...@apache.org>
AuthorDate: Wed Jun 16 18:46:49 2021 +0800
Support clone array
---
src/main/java/groovy/lang/MetaClassImpl.java | 44 ++++++++++++++++++++--
.../org/codehaus/groovy/runtime/ArrayUtil.java | 7 +++-
2 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java
index 533045d..04f7ff5 100644
--- a/src/main/java/groovy/lang/MetaClassImpl.java
+++ b/src/main/java/groovy/lang/MetaClassImpl.java
@@ -39,6 +39,7 @@ 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.ArrayUtil;
import org.codehaus.groovy.runtime.ConvertedClosure;
import org.codehaus.groovy.runtime.CurriedClosure;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
@@ -1139,6 +1140,18 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
}
}
+ private static class MethodHolder {
+ private static final Method CLONE_ARRAY_METHOD;
+ static {
+ Optional<Method> methodOptional = Arrays.stream(ArrayUtil.class.getDeclaredMethods()).filter(m -> "cloneArray".equals(m.getName())).findFirst();
+ if (!methodOptional.isPresent()) {
+ throw new GroovyBugError("Failed to find `cloneArray` method in class `" + ArrayUtil.class.getName() + "`");
+ }
+ CLONE_ARRAY_METHOD = methodOptional.get();
+ }
+ private MethodHolder() {}
+ }
+
private Object doInvokeMethodFallback(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, MissingMethodException mme) {
MethodHandles.Lookup lookup = null;
if (object instanceof GroovyObject) {
@@ -1147,13 +1160,14 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
lookup = lookupOptional.get();
}
+ final Class<?> receiverClass = object.getClass();
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());
+ superMethodHandle = lookup.unreflectSpecial(superMethod, receiverClass);
} catch (IllegalAccessException e) {
throw mme;
}
@@ -1163,8 +1177,32 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
throw new GroovyRuntimeException(t);
}
} else {
- if (null == lookup) lookup = MethodHandles.lookup().in(object.getClass());
- Method thisMethod = findMethod(object.getClass(), methodName, originalArguments);
+ if (receiverClass.isArray()) {
+ if ("clone".equals(methodName) && 0 == originalArguments.length) {
+ MethodHandle cloneArrayMethodHandle;
+ try {
+ cloneArrayMethodHandle = MethodHandles.lookup().in(ArrayUtil.class).unreflect(MethodHolder.CLONE_ARRAY_METHOD);
+ } catch (IllegalAccessException e) {
+ throw mme;
+ }
+ try {
+ Object[] array = (Object[]) object;
+ Object[] result = (Object[]) cloneArrayMethodHandle.invokeExact(array);
+ return result;
+ } catch (Throwable t) {
+ throw new GroovyRuntimeException(t);
+ }
+ }
+ }
+
+ if (null == lookup) {
+ try {
+ lookup = MethodHandles.lookup().in(receiverClass);
+ } catch (IllegalArgumentException e) {
+ throw mme;
+ }
+ }
+ Method thisMethod = findMethod(receiverClass, methodName, originalArguments);
if (null == thisMethod) throw mme;
MethodHandle thisMethodHandle;
try {
diff --git a/src/main/java/org/codehaus/groovy/runtime/ArrayUtil.java b/src/main/java/org/codehaus/groovy/runtime/ArrayUtil.java
index aa8096f..d0697de 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ArrayUtil.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ArrayUtil.java
@@ -53,8 +53,11 @@ package org.codehaus.groovy.runtime;
* absolutely no sense in normal Java. But it is not used in normal Java, but from the bytecode.
*/
public class ArrayUtil {
- private static final Object[] EMPTY = new Object[0]
- ;
+ private static final Object[] EMPTY = new Object[0];
+
+ public static <T> T[] cloneArray(T[] array) {
+ return array.clone();
+ }
public static Object[] createArray() {
return EMPTY;