Add missing JRE pieces, fix long sort bug, add test for long sort.

Patch by: jat
Review by: spoon (desk review)


git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/1.5@3075 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/super/com/google/gwt/lang/LongLib.java b/dev/core/super/com/google/gwt/lang/LongLib.java
index ddfacc0..5f0f3f2 100644
--- a/dev/core/super/com/google/gwt/lang/LongLib.java
+++ b/dev/core/super/com/google/gwt/lang/LongLib.java
@@ -48,12 +48,6 @@
    */
 
   /**
-   * Number of bits we expect to be accurate for a double representing a large
-   * integer.
-   */
-  private static final int PRECISION_BITS = 48;
-
-  /**
    * Use nested class to avoid clinit on outer.
    */
   static class CachedInts {
@@ -86,6 +80,12 @@
   public static boolean RUN_IN_JVM = false;
 
   /**
+   * Number of bits we expect to be accurate for a double representing a large
+   * integer.
+   */
+  private static final int PRECISION_BITS = 48;
+
+  /**
    * Index of the high bits in a 2-double array.
    */
   private static final int HIGH = 1;
@@ -117,6 +117,35 @@
     return makeFromBits(highBits(a) & highBits(b), lowBits(a) & lowBits(b));
   }
 
+  /**
+   * Compare the receiver to the argument.
+   * 
+   * @return 0 if they are the same, 1 if the receiver is greater, -1 if the
+   *         argument is greater.
+   */
+  public static int compare(double[] a, double[] b) {
+    if (eq(a, b)) {
+      return 0;
+    }
+
+    boolean nega = isNegative(a);
+    boolean negb = isNegative(b);
+    if (nega && !negb) {
+      return -1;
+    }
+    if (!nega && negb) {
+      return 1;
+    }
+
+    // at this point, the signs are the same, so subtraction will not overflow
+    assert (nega == negb);
+    if (isNegative(sub(a, b))) {
+      return -1;
+    } else {
+      return 1;
+    }
+  }
+
   public static double[] div(double[] a, double[] b) {
     if (isZero(b)) {
       throw new ArithmeticException("/ by zero");
@@ -469,35 +498,6 @@
     return add(accum, create(a * b, 0.0));
   }
 
-  /**
-   * Compare the receiver to the argument.
-   * 
-   * @return 0 if they are the same, 1 if the receiver is greater, -1 if the
-   *         argument is greater.
-   */
-  private static int compare(double[] a, double[] b) {
-    if (eq(a, b)) {
-      return 0;
-    }
-
-    boolean nega = isNegative(a);
-    boolean negb = isNegative(b);
-    if (nega && !negb) {
-      return -1;
-    }
-    if (!nega && negb) {
-      return 1;
-    }
-
-    // at this point, the signs are the same, so subtraction will not overflow
-    assert (nega == negb);
-    if (isNegative(sub(a, b))) {
-      return -1;
-    } else {
-      return 1;
-    }
-  }
-
   /*
    * Make a new instance equal to valueLow+valueHigh. The arguments do not need
    * to be normalized, though by convention valueHigh and valueLow will hold the
diff --git a/eclipse/lang/.classpath b/eclipse/lang/.classpath
index 571f299..2c076cc 100644
--- a/eclipse/lang/.classpath
+++ b/eclipse/lang/.classpath
@@ -6,5 +6,6 @@
 	<classpathentry kind="src" path="user/super/com/google/gwt/junit/translatable"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/gwt-user"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/gwt-dev-windows"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/user/super/com/google/gwt/emul/java/lang/Float.java b/user/super/com/google/gwt/emul/java/lang/Float.java
index 96e3fc0..8d9e849 100644
--- a/user/super/com/google/gwt/emul/java/lang/Float.java
+++ b/user/super/com/google/gwt/emul/java/lang/Float.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 Google Inc.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
@@ -72,6 +72,10 @@
 
   private final transient float value;
 
+  public Float(double value) {
+    this.value = (float) value;
+  }
+
   public Float(float value) {
     this.value = value;
   }
diff --git a/user/super/com/google/gwt/emul/java/lang/IllegalArgumentException.java b/user/super/com/google/gwt/emul/java/lang/IllegalArgumentException.java
index 919f310..3774dd9 100644
--- a/user/super/com/google/gwt/emul/java/lang/IllegalArgumentException.java
+++ b/user/super/com/google/gwt/emul/java/lang/IllegalArgumentException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 Google Inc.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
@@ -29,4 +29,11 @@
     super(message);
   }
 
+  public IllegalArgumentException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  public IllegalArgumentException(Throwable cause) {
+    super(cause);
+  }
 }
diff --git a/user/super/com/google/gwt/emul/java/lang/Integer.java b/user/super/com/google/gwt/emul/java/lang/Integer.java
index e9481d2..28e57ee 100644
--- a/user/super/com/google/gwt/emul/java/lang/Integer.java
+++ b/user/super/com/google/gwt/emul/java/lang/Integer.java
@@ -169,6 +169,10 @@
     return toPowerOfTwoString(value, 4);
   }
 
+  public static String toOctalString(int value) {
+    return toPowerOfTwoString(value, 3);
+  }
+
   public static String toString(int value) {
     return String.valueOf(value);
   }
diff --git a/user/super/com/google/gwt/emul/java/lang/Long.java b/user/super/com/google/gwt/emul/java/lang/Long.java
index 97c1f88..359fc44 100644
--- a/user/super/com/google/gwt/emul/java/lang/Long.java
+++ b/user/super/com/google/gwt/emul/java/lang/Long.java
@@ -19,6 +19,7 @@
  * Wraps a primitive <code>long</code> as an object.
  */
 public final class Long extends Number implements Comparable<Long> {
+
   /**
    * Use nested class to avoid clinit on outer.
    */
@@ -204,6 +205,10 @@
     return toPowerOfTwoString(value, 4);
   }
 
+  public static String toOctalString(long value) {
+    return toPowerOfTwoString(value, 3);
+  }
+
   public static String toString(long value) {
     return String.valueOf(value);
   }
diff --git a/user/super/com/google/gwt/emul/java/lang/Number.java b/user/super/com/google/gwt/emul/java/lang/Number.java
index f3d2e3a..2628318 100644
--- a/user/super/com/google/gwt/emul/java/lang/Number.java
+++ b/user/super/com/google/gwt/emul/java/lang/Number.java
@@ -159,7 +159,7 @@
    * 
    * @return The floating-point representation of <code>str</code> or
    *         <code>Number.NaN</code> if the string does not match
-   *         {@link floatRegex}.
+   *         {@link #floatRegex}.
    */
   private static native double __parseDouble(String str) /*-{
     var floatRegex = @java.lang.Number::floatRegex;
@@ -184,7 +184,9 @@
 
   // CHECKSTYLE_ON
 
-  public abstract byte byteValue();
+  public byte byteValue() {
+    return (byte) intValue();
+  }
 
   public abstract double doubleValue();
 
@@ -194,5 +196,7 @@
 
   public abstract long longValue();
 
-  public abstract short shortValue();
+  public short shortValue() {
+    return (short) intValue();
+  }
 }
diff --git a/user/super/com/google/gwt/emul/java/lang/String.java b/user/super/com/google/gwt/emul/java/lang/String.java
index fb322f2..7dd5f8c 100644
--- a/user/super/com/google/gwt/emul/java/lang/String.java
+++ b/user/super/com/google/gwt/emul/java/lang/String.java
@@ -161,9 +161,17 @@
     }
   };
 
+  public static String copyValueOf(char[] v) {
+    return valueOf(v);
+  }
+
+  public static String copyValueOf(char[] v, int offset, int count) {
+    return valueOf(v, offset, count);
+  }
+
   public static String valueOf(boolean x) {
     return "" + x;
-  };
+  }
 
   public static native String valueOf(char x) /*-{
     return String.fromCharCode(x);
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 93d7880..97a1ce1 100644
--- a/user/super/com/google/gwt/emul/java/util/Arrays.java
+++ b/user/super/com/google/gwt/emul/java/util/Arrays.java
@@ -17,6 +17,7 @@
 package java.util;
 
 import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.UnsafeNativeLong;
 import com.google.gwt.lang.Array;
 
 import java.io.Serializable;
@@ -909,6 +910,15 @@
     nativeNumberSort(array, fromIndex, toIndex);
   }
 
+  public static void sort(char[] array) {
+    nativeNumberSort(array);
+  }
+
+  public static void sort(char[] array, int fromIndex, int toIndex) {
+    verifySortIndices(fromIndex, toIndex, array.length);
+    nativeNumberSort(array, fromIndex, toIndex);
+  }
+
   public static void sort(double[] array) {
     nativeNumberSort(array);
   }
@@ -937,35 +947,29 @@
   }
 
   public static void sort(long[] array) {
-    /*
-     * TODO: if we emulate long in JS rather than using a native primitive, we
-     * will need to change this.
-     */
-    nativeNumberSort(array);
+    nativeLongSort(array);
   }
 
   public static void sort(long[] array, int fromIndex, int toIndex) {
-    /*
-     * TODO: if we emulate long in JS rather than using a native primitive, we
-     * will need to change this.
-     */
     verifySortIndices(fromIndex, toIndex, array.length);
-    nativeNumberSort(array, fromIndex, toIndex);
+    nativeLongSort(array, fromIndex, toIndex);
   }
 
   public static void sort(Object[] array) {
-    // Commented out implementation that uses the native sort with a fixup.
+    // Can't use native JS sort because it isn't stable.
 
+    // -- Commented out implementation that uses the native sort with a fixup.
     // nativeObjSort(array, 0, array.length, getNativeComparator(array,
-    // Comparators.natural()));
+    //     Comparators.natural()));
     mergeSort(array, 0, array.length, Comparators.natural());
   }
 
   public static void sort(Object[] x, int fromIndex, int toIndex) {
-    // Commented out implementation that uses the native sort with a fixup.
+    // Can't use native JS sort because it isn't stable.
 
+    // -- Commented out implementation that uses the native sort with a fixup.
     // nativeObjSort(x, fromIndex, toIndex, getNativeComparator(x,
-    // Comparators.natural()));
+    //     Comparators.natural()));
     mergeSort(x, fromIndex, toIndex, Comparators.natural());
   }
 
@@ -1133,7 +1137,7 @@
   }
 
   /**
-   * Recursive helper function for {@link deepToString(Object[])}.
+   * Recursive helper function for {@link Arrays#deepToString(Object[])}.
    */
   private static String deepToString(Object[] a, Set<Object[]> arraysIveSeen) {
     if (a == null) {
@@ -1287,7 +1291,7 @@
 
   /**
    * Recursive helper function for
-   * {@link mergeSort(Object[],int,int,Comparator<?>)}.
+   * {@link Arrays#mergeSort(Object[], int, int, Comparator)}.
    * 
    * @param temp temporary space, as large as the range of elements being
    *          sorted. On entry, temp should contain a copy of the sort range
@@ -1332,6 +1336,28 @@
   /**
    * Sort an entire array of number primitives.
    */
+  @UnsafeNativeLong
+  private static native void nativeLongSort(Object array) /*-{
+    array.sort(@com.google.gwt.lang.LongLib::compare([D[D));
+  }-*/;
+
+  /**
+   * Sort a subset of an array of number primitives.
+   */
+  @UnsafeNativeLong
+  private static native void nativeLongSort(Object array, int fromIndex,
+      int toIndex) /*-{
+    var temp = array.slice(fromIndex, toIndex);
+    temp.sort(@com.google.gwt.lang.LongLib::compare([D[D));
+    var n = toIndex - fromIndex;
+    // Do the equivalent of array.splice(fromIndex, n, temp) except
+    // flattening the temp slice.
+    Array.prototype.splice.apply(array, [fromIndex, n].concat(temp));
+  }-*/;
+
+  /**
+   * Sort an entire array of number primitives.
+   */
   private static native void nativeNumberSort(Object array) /*-{
     array.sort(function(a,b) { return a - b; });
   }-*/;
@@ -1344,7 +1370,7 @@
     var temp = array.slice(fromIndex, toIndex);
     temp.sort(function(a,b) { return a - b; });
     var n = toIndex - fromIndex;
-    // Do the equivalent of array.splice(fromIndex, n, temp.slice(0, n)) except
+    // Do the equivalent of array.splice(fromIndex, n, temp) except
     // flattening the temp slice.
     Array.prototype.splice.apply(array, [fromIndex, n].concat(temp.slice(0, n)));
   }-*/;
diff --git a/user/super/com/google/gwt/emul/java/util/Collections.java b/user/super/com/google/gwt/emul/java/util/Collections.java
index f976462..e0e5ef4 100644
--- a/user/super/com/google/gwt/emul/java/util/Collections.java
+++ b/user/super/com/google/gwt/emul/java/util/Collections.java
@@ -235,17 +235,17 @@
     return true;
   }
 
-  @SuppressWarnings("unchecked")
+  @SuppressWarnings({"unchecked", "cast"})
   public static <T> List<T> emptyList() {
     return (List<T>) EMPTY_LIST;
   }
 
-  @SuppressWarnings("unchecked")
+  @SuppressWarnings({"unchecked", "cast"})
   public static <K, V> Map<K, V> emptyMap() {
     return (Map<K, V>) EMPTY_MAP;
   }
 
-  @SuppressWarnings("unchecked")
+  @SuppressWarnings({"unchecked", "cast"})
   public static <T> Set<T> emptySet() {
     return (Set<T>) EMPTY_SET;
   }
@@ -280,6 +280,14 @@
     return count;
   }
 
+  public static <T> ArrayList<T> list(Enumeration<T> e) {
+    ArrayList<T> arrayList = new ArrayList<T>();
+    while (e.hasMoreElements()) {
+      arrayList.add(e.nextElement());
+    }
+    return arrayList;
+  }
+
   public static <T extends Object & Comparable<? super T>> T max(
       Collection<? extends T> coll) {
     return max(coll, null);
@@ -590,7 +598,7 @@
         return list.toArray(array);
       }
     };
-  };
+  }
 
   public static <K, V> Map<K, V> unmodifiableMap(
       final Map<? extends K, ? extends V> map) {
diff --git a/user/test/com/google/gwt/emultest/java/util/ArraysTest.java b/user/test/com/google/gwt/emultest/java/util/ArraysTest.java
index 0f67076..3592513 100644
--- a/user/test/com/google/gwt/emultest/java/util/ArraysTest.java
+++ b/user/test/com/google/gwt/emultest/java/util/ArraysTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 Google Inc.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
@@ -50,11 +50,13 @@
       index = val;
     }
 
+    @Override
     public String toString() {
       return value + "@" + index;
     }
   }
 
+  @Override
   public String getModuleName() {
     return "com.google.gwt.emultest.EmulSuite";
   }
@@ -426,6 +428,20 @@
   }
 
   /**
+   * Tests sorting of long primitives.
+   */
+  public void testLongSort() {
+    long[] x = {3, 11, 2, 1, 22, 3};
+    Arrays.sort(x);
+    assertEquals(1, x[0]);
+    assertEquals(2, x[1]);
+    assertEquals(3, x[2]);
+    assertEquals(3, x[3]);
+    assertEquals(11, x[4]);
+    assertEquals(22, x[5]);
+  }
+
+  /**
    * Verifies that values are sorted numerically rather than as strings.
    */
   public void testNumericSort() {