Introduce ArrayHelper.clone()

This simplifies the common cloning pattern.

PiperOrigin-RevId: 373830751
Change-Id: Ic31e97de6c8f046b46cab5f4fe8e2fbe58463ac5
diff --git a/user/super/com/google/gwt/emul/java/util/ArrayList.java b/user/super/com/google/gwt/emul/java/util/ArrayList.java
index c8ced03..5d021cf 100644
--- a/user/super/com/google/gwt/emul/java/util/ArrayList.java
+++ b/user/super/com/google/gwt/emul/java/util/ArrayList.java
@@ -257,7 +257,7 @@
 
   @Override
   public Object[] toArray() {
-    return ArrayHelper.clone(array, 0, array.length);
+    return ArrayHelper.clone(array);
   }
 
   /*
diff --git a/user/super/com/google/gwt/emul/java/util/Arrays.java b/user/super/com/google/gwt/emul/java/util/Arrays.java
index f0fa2fa..7c15f86 100644
--- a/user/super/com/google/gwt/emul/java/util/Arrays.java
+++ b/user/super/com/google/gwt/emul/java/util/Arrays.java
@@ -600,9 +600,7 @@
   }
 
   private static <T> T[] copyObjectArray(T[] original, int from, int to) {
-    T[] copy = ArrayHelper.clone(original, from, to);
-    ArrayHelper.setLength(copy, to - from);
-    return copy;
+    return ArrayHelper.clone(original, from, to);
   }
 
   private static void checkCopyOfRange(Object original, int from, int to) {
diff --git a/user/super/com/google/gwt/emul/java/util/EnumMap.java b/user/super/com/google/gwt/emul/java/util/EnumMap.java
index c9140a4..0dbd223 100644
--- a/user/super/com/google/gwt/emul/java/util/EnumMap.java
+++ b/user/super/com/google/gwt/emul/java/util/EnumMap.java
@@ -210,7 +210,7 @@
 
   private void init(EnumMap<K, ? extends V> m) {
     keySet = m.keySet.clone();
-    values = ArrayHelper.clone(m.values, 0, m.values.length);
+    values = ArrayHelper.clone(m.values);
   }
 
   private V set(int ordinal, V value) {
diff --git a/user/super/com/google/gwt/emul/java/util/EnumSet.java b/user/super/com/google/gwt/emul/java/util/EnumSet.java
index e3594ef..6badd31 100644
--- a/user/super/com/google/gwt/emul/java/util/EnumSet.java
+++ b/user/super/com/google/gwt/emul/java/util/EnumSet.java
@@ -129,7 +129,7 @@
 
     @Override
     public EnumSet<E> clone() {
-      E[] clonedSet = ArrayHelper.clone(set, 0, set.length);
+      E[] clonedSet = ArrayHelper.clone(set);
       return new EnumSetImpl<E>(all, clonedSet, size);
     }
 
@@ -176,7 +176,7 @@
 
   public static <E extends Enum<E>> EnumSet<E> allOf(Class<E> elementType) {
     E[] all = elementType.getEnumConstants();
-    E[] set = ArrayHelper.clone(all, 0, all.length);
+    E[] set = ArrayHelper.clone(all);
     return new EnumSetImpl<E>(all, set, all.length);
   }
 
diff --git a/user/super/com/google/gwt/emul/javaemul/internal/ArrayHelper.java b/user/super/com/google/gwt/emul/javaemul/internal/ArrayHelper.java
index 8f40c34..c474c9a 100644
--- a/user/super/com/google/gwt/emul/javaemul/internal/ArrayHelper.java
+++ b/user/super/com/google/gwt/emul/javaemul/internal/ArrayHelper.java
@@ -25,14 +25,21 @@
 
   public static final int ARRAY_PROCESS_BATCH_SIZE = 10000;
 
+  public static <T> T[] clone(T[] array) {
+    Object result = asNativeArray(array).slice();
+    return ArrayStamper.stampJavaTypeInfo(result, array);
+  }
+
   public static <T> T[] clone(T[] array, int fromIndex, int toIndex) {
     Object result = unsafeClone(array, fromIndex, toIndex);
+    // array.slice doesn't expand if toIndex > array.length
+    setLength(result, toIndex - fromIndex);
     return ArrayStamper.stampJavaTypeInfo(result, array);
   }
 
   /**
-   * Unlike clone, this method returns a copy of the array that is not type marked. This is only
-   * safe for temp arrays as returned array will not do any type checks.
+   * Unlike clone, this method returns a copy of the array that is not type marked, nor size
+   * guaranteed. This is only safe for temp arrays as returned array will not do any type checks.
    */
   public static Object[] unsafeClone(Object array, int fromIndex, int toIndex) {
     return asNativeArray(array).slice(fromIndex, toIndex);
@@ -128,6 +135,8 @@
 
     native void push(Object item);
 
+    native Object[] slice();
+
     native Object[] slice(int fromIndex, int toIndex);
 
     native void splice(int index, int deleteCount, Object... value);