Implemented Collection.toArray(Object[]).

Patch by: scottb
Review by: knorton (pair prog)


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1270 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Array.java b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Array.java
index 85c9052..cd923f7 100644
--- a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Array.java
+++ b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Array.java
@@ -24,6 +24,15 @@
 public final class Array {
 
   /**
+   * Construct a new array of the exact same type as a given array, specifying
+   * the desired length of the new array.
+   */
+  public static native Object[] clonify(Object[] a, int length) /*-{
+    // Use JSNI magic to effect a castless type change.
+    return @com.google.gwt.lang.Array::clonify(Lcom/google/gwt/lang/Array;I)(a, length);
+  }-*/;
+
+  /**
    * Creates an array like "new T[a][b][c][][]" by passing in javascript objects
    * as follows: [a, b, c].
    */
@@ -67,6 +76,10 @@
     return array[index] = value;
   }-*/;
 
+  private static Array clonify(Array a, int length) {
+    return new Array(length, a.typeId, a.queryId, a.typeName);
+  }
+
   /**
    * Gets an the first value from a JSON int array.
    */
diff --git a/user/super/com/google/gwt/emul/java/util/AbstractCollection.java b/user/super/com/google/gwt/emul/java/util/AbstractCollection.java
index 31c2cd3..549e295 100644
--- a/user/super/com/google/gwt/emul/java/util/AbstractCollection.java
+++ b/user/super/com/google/gwt/emul/java/util/AbstractCollection.java
@@ -15,6 +15,8 @@
  */
 package java.util;
 
+import com.google.gwt.lang.Array;
+
 /**
  * Abstract base class for collection implementations.
  */
@@ -100,14 +102,22 @@
   public abstract int size();
 
   public Object[] toArray() {
-    int n = size();
-    int i = 0;
-    Object[] array = new Object[n];
-    for (Iterator iter = iterator(); iter.hasNext();) {
-      Object o = iter.next();
-      array[i++] = o;
+    return toArray(new Object[size()]);
+  }
+
+  public Object[] toArray(Object[] a) {
+    int size = size();
+    if (a.length < size) {
+      a = Array.clonify(a, size);
     }
-    return array;
+    int i = 0;
+    for (Iterator it = iterator(); it.hasNext(); ) {
+      a[i++] = it.next();
+    }
+    if (a.length > size) {
+      a[size] = null;
+    }
+    return a;
   }
 
   public String toString() {
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 d3eff10..ef0b51c 100644
--- a/user/super/com/google/gwt/emul/java/util/ArrayList.java
+++ b/user/super/com/google/gwt/emul/java/util/ArrayList.java
@@ -16,6 +16,7 @@
 package java.util;
 
 import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.lang.Array;
 
 /**
  * See Sun's JDK 1.4 documentation for documentation.
@@ -169,6 +170,22 @@
     return size;
   }
 
+  /*
+   * Faster than the iterator-based implementation in AbstractCollection.
+   */
+  public Object[] toArray(Object[] a) {
+    if (a.length < size) {
+      a = Array.clonify(a, size);
+    }
+    for (int i = 0; i < size; ++i) {
+      a[i] = getImpl(array, i);
+    }
+    if (a.length > size) {
+      a[size] = null;
+    }
+    return a;
+  }
+
   protected int indexOf(Object o, int index) {
     if (index < 0) {
       indexOutOfBounds(index);
diff --git a/user/super/com/google/gwt/emul/java/util/Collection.java b/user/super/com/google/gwt/emul/java/util/Collection.java
index ff0cb43..95c65da 100644
--- a/user/super/com/google/gwt/emul/java/util/Collection.java
+++ b/user/super/com/google/gwt/emul/java/util/Collection.java
@@ -48,4 +48,5 @@
 
   Object[] toArray();
 
+  Object[] toArray(Object[] a);
 }
diff --git a/user/test/com/google/gwt/emultest/java/util/ArrayListTest.java b/user/test/com/google/gwt/emultest/java/util/ArrayListTest.java
index 524a143..fe0d5a5 100644
--- a/user/test/com/google/gwt/emultest/java/util/ArrayListTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/ArrayListTest.java
@@ -125,7 +125,7 @@
       fail();
     } catch (IndexOutOfBoundsException expected) {
     }
-    
+
     try {
       l.removeRange(2, 1);
       fail();
@@ -150,6 +150,48 @@
     }
   }
 
+  public void testToArray() {
+    ArrayList l = new ArrayList();
+    for (int i = 0; i < 10; i++) {
+      l.add(new Integer(i));
+    }
+
+    {
+      Object[] objArray = l.toArray();
+      assertEquals(10, objArray.length);
+      for (int i = 0; i < 10; i++) {
+        Integer elem = (Integer) objArray[i];
+        assertEquals(i, elem.intValue());
+      }
+    }
+
+    {
+      Integer[] intArray = new Integer[13];
+      intArray[10] = new Integer(10);
+      intArray[11] = new Integer(11);
+      intArray[12] = new Integer(12);
+      intArray = (Integer[]) l.toArray(intArray);
+      assertEquals(13, intArray.length);
+      for (int i = 0; i < 13; i++) {
+        if (i == 10) {
+          assertNull(intArray[i]);
+        } else {
+          Integer elem = intArray[i];
+          assertEquals(i, elem.intValue());
+        }
+      }
+    }
+
+    {
+      Integer[] intArray = (Integer[]) l.toArray(new Integer[0]);
+      assertEquals(10, intArray.length);
+      for (int i = 0; i < 10; i++) {
+        Integer elem = intArray[i];
+        assertEquals(i, elem.intValue());
+      }
+    }
+  }
+
   protected List makeEmptyList() {
     return new ArrayList();
   }
diff --git a/user/test/com/google/gwt/emultest/java/util/CollectionsTest.java b/user/test/com/google/gwt/emultest/java/util/CollectionsTest.java
index 17d9ab4..2b2aa20 100644
--- a/user/test/com/google/gwt/emultest/java/util/CollectionsTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/CollectionsTest.java
@@ -111,7 +111,6 @@
     assertEquals(3, ret);
   }
 
-
   public void testReverse() {
     List a = createSortedList();
     Collections.reverse(a);
diff --git a/user/test/com/google/gwt/emultest/java/util/EmulTestBase.java b/user/test/com/google/gwt/emultest/java/util/EmulTestBase.java
index 74616df..0382f40 100644
--- a/user/test/com/google/gwt/emultest/java/util/EmulTestBase.java
+++ b/user/test/com/google/gwt/emultest/java/util/EmulTestBase.java
@@ -31,7 +31,9 @@
     }
   }
 
-  /** Easy way to test what should be in a list */
+  /**
+   * Easy way to test what should be in a list.
+   */
   protected static void assertEquals(Object[] array, List target) {
     assertEquals(array.length, target.size());
     for (int i = 0; i < array.length; i++) {