AutoboxUtils cleanup

http://gwt-code-reviews.appspot.com/1443808/


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10232 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/javac/testing/impl/JavaResourceBase.java b/dev/core/src/com/google/gwt/dev/javac/testing/impl/JavaResourceBase.java
index 63ecdd5..ee1c256 100644
--- a/dev/core/src/com/google/gwt/dev/javac/testing/impl/JavaResourceBase.java
+++ b/dev/core/src/com/google/gwt/dev/javac/testing/impl/JavaResourceBase.java
@@ -24,7 +24,7 @@
       "java.lang.annotation.Annotation") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang.annotation;\n");
       code.append("public interface Annotation {\n");
       code.append("}\n");
@@ -34,7 +34,7 @@
   public static final MockJavaResource BAR = new MockJavaResource("test.Bar") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package test;\n");
       code.append("public class Bar extends Foo {\n");
       code.append("  public String value() { return \"Bar\"; }\n");
@@ -45,18 +45,23 @@
   public static final MockJavaResource BOOLEAN = new MockJavaResource("java.lang.Boolean") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Boolean {\n");
+      code.append("  private boolean value;\n");
+      code.append("  public Boolean(boolean value) {\n");
+      code.append("    this.value = value;\n");
+      code.append("  }\n");
+      code.append("  public static Boolean valueOf(boolean b) { return new Boolean(b); }\n");
+      code.append("  public boolean booleanValue() { return value; }\n");
       code.append("}\n");
       return code;
     }
   };
-  public static final MockJavaResource BYTE = new MockJavaResource(
-      "java.lang.Byte") {
+  public static final MockJavaResource BYTE = new MockJavaResource("java.lang.Byte") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Byte extends Number {\n");
       code.append("  private byte value;\n");
@@ -69,11 +74,10 @@
       return code;
     }
   };
-  public static final MockJavaResource CHARACTER = new MockJavaResource(
-      "java.lang.Character") {
+  public static final MockJavaResource CHARACTER = new MockJavaResource("java.lang.Character") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Character {\n");
       code.append("  private char value;\n");
@@ -86,11 +90,10 @@
       return code;
     }
   };
-  public static final MockJavaResource CLASS = new MockJavaResource(
-      "java.lang.Class") {
+  public static final MockJavaResource CLASS = new MockJavaResource("java.lang.Class") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Class<T> {\n");
       code.append("  public String getName() { return null; }\n");
@@ -103,7 +106,7 @@
       "java.lang.ClassNotFoundException") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class ClassNotFoundException extends Exception {\n");
       code.append("  public ClassNotFoundException() {}\n");
@@ -115,22 +118,20 @@
       return code;
     }
   };
-  public static final MockJavaResource COLLECTION = new MockJavaResource(
-      "java.util.Collection") {
+  public static final MockJavaResource COLLECTION = new MockJavaResource("java.util.Collection") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.util;\n");
       code.append("public interface Collection<E> {\n");
       code.append("}\n");
       return code;
     }
   };
-  public static final MockJavaResource DOUBLE = new MockJavaResource(
-      "java.lang.Double") {
+  public static final MockJavaResource DOUBLE = new MockJavaResource("java.lang.Double") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Double extends Number {\n");
       code.append("  private double value;\n");
@@ -144,11 +145,10 @@
       return code;
     }
   };
-  public static final MockJavaResource ENUM = new MockJavaResource(
-      "java.lang.Enum") {
+  public static final MockJavaResource ENUM = new MockJavaResource("java.lang.Enum") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("import java.io.Serializable;\n");
       code.append("public abstract class Enum<E extends Enum<E>> implements Serializable {\n");
@@ -159,33 +159,30 @@
       return code;
     }
   };
-  public static final MockJavaResource ERROR = new MockJavaResource(
-      "java.lang.Error") {
+  public static final MockJavaResource ERROR = new MockJavaResource("java.lang.Error") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Error extends Throwable {\n");
       code.append("}\n");
       return code;
     }
   };
-  public static final MockJavaResource EXCEPTION = new MockJavaResource(
-      "java.lang.Exception") {
+  public static final MockJavaResource EXCEPTION = new MockJavaResource("java.lang.Exception") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Exception extends Throwable {\n");
       code.append("}\n");
       return code;
     }
   };
-  public static final MockJavaResource FLOAT = new MockJavaResource(
-      "java.lang.Float") {
+  public static final MockJavaResource FLOAT = new MockJavaResource("java.lang.Float") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Float extends Number {\n");
       code.append("  private float value;\n");
@@ -201,7 +198,7 @@
   public static final MockJavaResource FOO = new MockJavaResource("test.Foo") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package test;\n");
       code.append("public class Foo {\n");
       code.append("  public String value() { return \"Foo\"; }\n");
@@ -209,11 +206,10 @@
       return code;
     }
   };
-  public static final MockJavaResource INTEGER = new MockJavaResource(
-      "java.lang.Integer") {
+  public static final MockJavaResource INTEGER = new MockJavaResource("java.lang.Integer") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Integer extends Number {\n");
       code.append("  private int value;\n");
@@ -230,7 +226,7 @@
       "com.google.gwt.user.client.rpc.IsSerializable") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package com.google.gwt.user.client.rpc;\n");
       code.append("public interface IsSerializable {\n");
       code.append("}\n");
@@ -241,7 +237,7 @@
       "com.google.gwt.core.client.JavaScriptObject") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package com.google.gwt.core.client;\n");
       code.append("public class JavaScriptObject {\n");
       code.append("  public static native JavaScriptObject createObject() /*-{ return {}; }-*/;\n");
@@ -251,28 +247,26 @@
       return code;
     }
   };
-  public static final MockJavaResource LONG = new MockJavaResource(
-      "java.lang.Long") {
+  public static final MockJavaResource LONG = new MockJavaResource("java.lang.Long") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Long extends Number {\n");
       code.append("  private long value;\n");
       code.append("  public Long(long value) {\n");
       code.append("    this.value = value;\n");
       code.append("  }\n");
-      code.append("  public static Long valueOf(int i) { return new Long(i); }\n");
+      code.append("  public static Long valueOf(long l) { return new Long(l); }\n");
       code.append("  public long longValue() { return value; }\n");
       code.append("}\n");
       return code;
     }
   };
-  public static final MockJavaResource MAP = new MockJavaResource(
-      "java.util.Map") {
+  public static final MockJavaResource MAP = new MockJavaResource("java.util.Map") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.util;\n");
       code.append("public interface Map<K,V> { }\n");
       return code;
@@ -282,7 +276,7 @@
       "java.lang.NoClassDefFoundError") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class NoClassDefFoundError extends Error {\n");
       code.append("  public NoClassDefFoundError() {}\n");
@@ -291,11 +285,10 @@
       return code;
     }
   };
-  public static final MockJavaResource NUMBER = new MockJavaResource(
-      "java.lang.Number") {
+  public static final MockJavaResource NUMBER = new MockJavaResource("java.lang.Number") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Number implements java.io.Serializable {\n");
       code.append("}\n");
@@ -303,13 +296,14 @@
     }
   };
 
-  public static final MockJavaResource OBJECT = new MockJavaResource(
-      "java.lang.Object") {
+  public static final MockJavaResource OBJECT = new MockJavaResource("java.lang.Object") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Object {\n");
+      code.append("  public boolean equals(Object that){return this == that;}");
+      code.append("  public int hashCode() { return 0; }\n");
       code.append("  public String toString() { return \"Object\"; }\n");
       code.append("  public Object clone() { return this; } ");
       code.append("  public Class<?> getClass() { return Object.class; } ");
@@ -317,21 +311,19 @@
       return code;
     }
   };
-  public static final MockJavaResource SERIALIZABLE = new MockJavaResource(
-      "java.io.Serializable") {
+  public static final MockJavaResource SERIALIZABLE = new MockJavaResource("java.io.Serializable") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.io;\n");
       code.append("public interface Serializable { }\n");
       return code;
     }
   };
-  public static final MockJavaResource SHORT = new MockJavaResource(
-      "java.lang.Short") {
+  public static final MockJavaResource SHORT = new MockJavaResource("java.lang.Short") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Short extends Number {\n");
       code.append("  private short value;\n");
@@ -344,26 +336,28 @@
       return code;
     }
   };
-  public static final MockJavaResource STRING = new MockJavaResource(
-      "java.lang.String") {
+  public static final MockJavaResource STRING = new MockJavaResource("java.lang.String") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("import java.io.Serializable;\n");
       code.append("public final class String implements Serializable {\n");
-      /*
-       * TODO(scottb) Can't add String constructors because they are "magic" in
-       * GWT. (They're re-vectored to static calls). Maybe we should generalize
-       * the compiler magic to work via annotations, and annotate only the real
-       * GWT string.
-       */
-      // code.append("  public String(String s) {}\n");
+      code.append("  public String() { }\n");
+      code.append("  public String(char c) { }\n");
+      code.append("  public String(String s) { }\n");
+      code.append("  public static String _String() { return \"\"; }\n");
+      code.append("  public static String _String(char c) { return \"\" + c; }\n");
+      code.append("  public static String _String(String s) { return s; }\n");
       code.append("  private static final long serialVersionUID = 0L;\n");
       code.append("  public char charAt(int index) { return 'a'; }\n");
       code.append("  public boolean equals(Object obj) { return false; }\n");
       code.append("  public boolean equalsIgnoreCase(String str) { return false; }\n");
       code.append("  public int length() { return 0; }\n");
+      code.append("  public static String valueOf(int i) { return \"\" + i; }\n");
+      code.append("  public static String valueOf(char c) { return \"\" + c; }\n");
+      code.append("  public static String valueOf(long l) { return \"\" + l; }\n");
+      code.append("  public int hashCode() { return 0; }\n");
       code.append("  public String replace(char c1, char c2) { return null; }\n");
       code.append("  public boolean startsWith(String str) { return false; }\n");
       code.append("  public String toLowerCase() { return null; }\n");
@@ -376,7 +370,7 @@
       "java.lang.StringBuilder") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public final class StringBuilder {\n");
       code.append("}\n");
@@ -387,7 +381,7 @@
       "java.lang.SuppressWarnings") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public @interface SuppressWarnings {\n");
       code.append("  String[] value();\n");
@@ -395,11 +389,10 @@
       return code;
     }
   };
-  public static final MockJavaResource THROWABLE = new MockJavaResource(
-      "java.lang.Throwable") {
+  public static final MockJavaResource THROWABLE = new MockJavaResource("java.lang.Throwable") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("public class Throwable {\n");
       code.append("  public String getMessage() { return \"\"; }\n");
@@ -411,10 +404,9 @@
 
   public static MockJavaResource[] getStandardResources() {
     return new MockJavaResource[]{
-        ANNOTATION, BYTE, BOOLEAN, CHARACTER, CLASS, CLASS_NOT_FOUND_EXCEPTION,
-        COLLECTION, DOUBLE, ENUM, EXCEPTION, ERROR, FLOAT, INTEGER,
-        IS_SERIALIZABLE, JAVASCRIPTOBJECT, LONG, MAP, NO_CLASS_DEF_FOUND_ERROR,
-        NUMBER, OBJECT, SERIALIZABLE, SHORT, STRING, STRING_BUILDER,
+        ANNOTATION, BYTE, BOOLEAN, CHARACTER, CLASS, CLASS_NOT_FOUND_EXCEPTION, COLLECTION, DOUBLE,
+        ENUM, EXCEPTION, ERROR, FLOAT, INTEGER, IS_SERIALIZABLE, JAVASCRIPTOBJECT, LONG, MAP,
+        NO_CLASS_DEF_FOUND_ERROR, NUMBER, OBJECT, SERIALIZABLE, SHORT, STRING, STRING_BUILDER,
         SUPPRESS_WARNINGS, THROWABLE};
   }
 }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
index 9e27444..3a9bbd8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
@@ -71,7 +71,7 @@
       "java.lang.CharSequence", "java.lang.Cloneable", "java.lang.Comparable", "java.lang.Enum",
       "java.lang.Iterable", "java.util.Iterator", "java.lang.AssertionError", "java.lang.Boolean",
       "java.lang.Byte", "java.lang.Character", "java.lang.Short", "java.lang.Integer",
-      "java.lang.Float", "java.lang.Double", "java.lang.Throwable",
+      "java.lang.Long", "java.lang.Float", "java.lang.Double", "java.lang.Throwable",
       "com.google.gwt.core.client.GWT", "com.google.gwt.core.client.JavaScriptObject",
       "com.google.gwt.lang.ClassLiteralHolder", "com.google.gwt.core.client.RunAsyncCallback",
       "com.google.gwt.core.client.impl.AsyncFragmentLoader",
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/AutoboxUtils.java b/dev/core/src/com/google/gwt/dev/jjs/impl/AutoboxUtils.java
index 040de32..56e8fba 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/AutoboxUtils.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/AutoboxUtils.java
@@ -15,48 +15,52 @@
  */
 package com.google.gwt.dev.jjs.impl;
 
-import com.google.gwt.dev.jjs.InternalCompilerException;
 import com.google.gwt.dev.jjs.ast.JCastOperation;
-import com.google.gwt.dev.jjs.ast.JClassType;
 import com.google.gwt.dev.jjs.ast.JDeclaredType;
 import com.google.gwt.dev.jjs.ast.JExpression;
 import com.google.gwt.dev.jjs.ast.JMethod;
 import com.google.gwt.dev.jjs.ast.JMethodCall;
-import com.google.gwt.dev.jjs.ast.JParameter;
 import com.google.gwt.dev.jjs.ast.JPrimitiveType;
 import com.google.gwt.dev.jjs.ast.JProgram;
 
+import java.util.Collection;
 import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * Utilities for managing autoboxing of Java primitive types.
  */
 public class AutoboxUtils {
-  private Set<JPrimitiveType> boxablePrimitiveTypes;
-  private Map<JClassType, JPrimitiveType> boxClassToPrimitiveMap;
-  private Set<JDeclaredType> boxTypes;
-  private final JProgram program;
-  private Set<JMethod> unboxMethods;
+  private static final JPrimitiveType[] TYPES = {
+      JPrimitiveType.BOOLEAN, JPrimitiveType.BYTE, JPrimitiveType.CHAR, JPrimitiveType.SHORT,
+      JPrimitiveType.INT, JPrimitiveType.LONG, JPrimitiveType.FLOAT, JPrimitiveType.DOUBLE};
+
+  private final Map<JPrimitiveType, JMethod> boxMethods =
+      new LinkedHashMap<JPrimitiveType, JMethod>();
+
+  private final Map<JDeclaredType, JMethod> unboxMethods =
+      new LinkedHashMap<JDeclaredType, JMethod>();
 
   public AutoboxUtils(JProgram program) {
-    this.program = program;
-    computeBoxablePrimitiveTypes();
-    computeBoxClassToPrimitiveMap();
-    computeBoxTypes();
-    computeUnboxMethods();
-  }
-
-  /**
-   * Box the expression <code>toBox</code> into an instance of
-   * <code>wrapperType</code>. If <code>toBox</code> is not already of the
-   * primitive corresponding to <code>wrapperType</code>, then a cast may be
-   * necessary.
-   */
-  public JExpression box(JExpression toBox, JClassType wrapperType) {
-    return box(toBox, primitiveTypeForBoxClass(wrapperType), wrapperType);
+    for (JPrimitiveType primType : TYPES) {
+      JDeclaredType wrapperType = program.getFromTypeMap(primType.getWrapperTypeName());
+      String boxSig =
+          "valueOf(" + primType.getJsniSignatureName() + ")" + wrapperType.getJsniSignatureName();
+      String unboxSig = primType.getName() + "Value()" + primType.getJsniSignatureName();
+      for (JMethod method : wrapperType.getMethods()) {
+        if (method.isStatic()) {
+          if (method.getSignature().equals(boxSig)) {
+            boxMethods.put(primType, method);
+          }
+        } else {
+          if (method.getSignature().equals(unboxSig)) {
+            unboxMethods.put(wrapperType, method);
+          }
+        }
+      }
+    }
+    assert boxMethods.size() == TYPES.length;
+    assert unboxMethods.size() == TYPES.length;
   }
 
   /**
@@ -65,24 +69,23 @@
    * <code>primitiveType</code>, then a cast may be necessary.
    */
   public JExpression box(JExpression toBox, JPrimitiveType primitiveType) {
-    // Find the wrapper type for this primitive type.
-    String wrapperTypeName = primitiveType.getWrapperTypeName();
-    JClassType wrapperType = (JClassType) program.getFromTypeMap(wrapperTypeName);
-    if (wrapperType == null) {
-      throw new InternalCompilerException(toBox, "Cannot find wrapper type '" + wrapperTypeName
-          + "' associated with primitive type '" + primitiveType.getName() + "'", null);
+    // Add a cast to toBox if need be
+    if (toBox.getType() != primitiveType) {
+      toBox = new JCastOperation(toBox.getSourceInfo(), primitiveType, toBox);
     }
-
-    return box(toBox, primitiveType, wrapperType);
+    JMethod method = boxMethods.get(primitiveType);
+    assert method != null;
+    JMethodCall call = new JMethodCall(toBox.getSourceInfo(), null, method);
+    call.addArg(toBox);
+    return call;
   }
 
-  /**
-   * Return the box class for a given primitive. Note that this can return
-   * <code>null</code> if the source program does not actually need the
-   * requested box type.
-   */
-  public JClassType boxClassForPrimitive(JPrimitiveType prim) {
-    return (JClassType) program.getFromTypeMap(prim.getWrapperTypeName());
+  public Collection<JMethod> getBoxMethods() {
+    return boxMethods.values();
+  }
+
+  public Collection<JMethod> getUnboxMethods() {
+    return unboxMethods.values();
   }
 
   /**
@@ -92,92 +95,9 @@
   public JExpression undoUnbox(JExpression arg) {
     if (arg instanceof JMethodCall) {
       JMethodCall argMethodCall = (JMethodCall) arg;
-      if (unboxMethods.contains(argMethodCall.getTarget())) {
-        return argMethodCall.getInstance();
-      }
+      assert unboxMethods.values().contains(argMethodCall.getTarget());
+      return argMethodCall.getInstance();
     }
     return null;
   }
-
-  private JExpression box(JExpression toBox, JPrimitiveType primitiveType, JClassType wrapperType) {
-    // Add a cast to toBox if need be
-    if (toBox.getType() != primitiveType) {
-      toBox = new JCastOperation(toBox.getSourceInfo(), primitiveType, toBox);
-    }
-
-    // Find the correct valueOf() method.
-    JMethod valueOfMethod = null;
-    for (JMethod method : wrapperType.getMethods()) {
-      if ("valueOf".equals(method.getName())) {
-        if (method.getParams().size() == 1) {
-          JParameter param = method.getParams().get(0);
-          if (param.getType() == primitiveType) {
-            // Found it.
-            valueOfMethod = method;
-            break;
-          }
-        }
-      }
-    }
-
-    if (valueOfMethod == null || !valueOfMethod.isStatic()
-        || valueOfMethod.getType() != wrapperType) {
-      throw new InternalCompilerException(toBox, "Expected to find a method on '"
-          + wrapperType.getName() + "' whose signature matches 'public static "
-          + wrapperType.getName() + " valueOf(" + primitiveType.getName() + ")'", null);
-    }
-
-    // Create the boxing call.
-    JMethodCall call = new JMethodCall(toBox.getSourceInfo(), null, valueOfMethod);
-    call.addArg(toBox);
-    return call;
-  }
-
-  private void computeBoxablePrimitiveTypes() {
-    boxablePrimitiveTypes = new LinkedHashSet<JPrimitiveType>();
-    boxablePrimitiveTypes.add(JPrimitiveType.BOOLEAN);
-    boxablePrimitiveTypes.add(JPrimitiveType.BYTE);
-    boxablePrimitiveTypes.add(JPrimitiveType.CHAR);
-    boxablePrimitiveTypes.add(JPrimitiveType.SHORT);
-    boxablePrimitiveTypes.add(JPrimitiveType.INT);
-    boxablePrimitiveTypes.add(JPrimitiveType.LONG);
-    boxablePrimitiveTypes.add(JPrimitiveType.FLOAT);
-    boxablePrimitiveTypes.add(JPrimitiveType.DOUBLE);
-  }
-
-  private void computeBoxClassToPrimitiveMap() {
-    boxClassToPrimitiveMap = new LinkedHashMap<JClassType, JPrimitiveType>();
-    for (JPrimitiveType prim : boxablePrimitiveTypes) {
-      boxClassToPrimitiveMap.put(boxClassForPrimitive(prim), prim);
-    }
-  }
-
-  private void computeBoxTypes() {
-    boxTypes = new LinkedHashSet<JDeclaredType>();
-    for (JPrimitiveType prim : boxablePrimitiveTypes) {
-      boxTypes.add(boxClassForPrimitive(prim));
-    }
-  }
-
-  private void computeUnboxMethods() {
-    unboxMethods = new LinkedHashSet<JMethod>();
-    for (JDeclaredType boxType : boxTypes) {
-      if (boxType != null) {
-        for (JMethod method : boxType.getMethods()) {
-          if (!method.isStatic() && method.getParams().isEmpty()
-              && method.getName().endsWith("Value") && (method.getType() instanceof JPrimitiveType)) {
-            unboxMethods.add(method);
-          }
-        }
-      }
-    }
-  }
-
-  private JPrimitiveType primitiveTypeForBoxClass(JClassType wrapperType) {
-    JPrimitiveType primitiveType = boxClassToPrimitiveMap.get(wrapperType);
-    if (primitiveType == null) {
-      throw new IllegalArgumentException("Not a box class: " + wrapperType);
-    }
-    return primitiveType;
-  }
 }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/FixAssignmentToUnbox.java b/dev/core/src/com/google/gwt/dev/jjs/impl/FixAssignmentToUnbox.java
index 82f7018..9d5e80d 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/FixAssignmentToUnbox.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/FixAssignmentToUnbox.java
@@ -24,6 +24,7 @@
 import com.google.gwt.dev.jjs.ast.JModVisitor;
 import com.google.gwt.dev.jjs.ast.JPostfixOperation;
 import com.google.gwt.dev.jjs.ast.JPrefixOperation;
+import com.google.gwt.dev.jjs.ast.JPrimitiveType;
 import com.google.gwt.dev.jjs.ast.JProgram;
 import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
 import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
@@ -116,9 +117,8 @@
       // Assignment-to-unbox, e.g.
       // unbox(x) = foo -> x = box(foo)
       JClassType boxedType = (JClassType) boxed.getType();
-
       ctx.replaceMe(new JBinaryOperation(x.getSourceInfo(), boxedType, JBinaryOperator.ASG, boxed,
-          autoboxUtils.box(x.getRhs(), boxedType)));
+          autoboxUtils.box(x.getRhs(), (JPrimitiveType) lhs.getType())));
       return;
     }
 
diff --git a/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java b/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java
index 98c3c23..d532ec4 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java
@@ -54,9 +54,14 @@
   public static final MockJavaResource ARRAY = new MockJavaResource("com.google.gwt.lang.Array") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package com.google.gwt.lang;\n");
+      code.append("import com.google.gwt.core.client.JavaScriptObject;\n");
       code.append("public final class Array {\n");
+      code.append("  static void setCheck(Array array, int index, Object value) { }\n");
+      code.append("  static void initDim(Class arrayClass, JavaScriptObject castableTypeMap, int queryId, int length, int seedType) { }\n");
+      code.append("  static void initDims(Class arrayClasses[], JavaScriptObject[] castableTypeMapExprs, int[] queryIdExprs, int[] dimExprs, int count, int seedType) { }\n");
+      code.append("  static void initValues(Class arrayClass, JavaScriptObject castableTypeMap, int queryId, Array array) { }\n");
       code.append("  public int length = 0;\n");
       code.append("  protected Class<?> arrayClass = null;\n");
       code.append("}\n");
@@ -66,7 +71,7 @@
   public static final MockJavaResource CAST = new MockJavaResource("com.google.gwt.lang.Cast") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package com.google.gwt.lang;\n");
       code.append("public final class Cast {\n");
       code.append("  public static Object dynamicCast(Object src, int dstId) { return src;}\n");
@@ -82,7 +87,7 @@
   public static final MockJavaResource CLASS = new MockJavaResource("java.lang.Class") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("import com.google.gwt.core.client.JavaScriptObject;\n");
       code.append("public final class Class<T> {\n");
@@ -102,7 +107,7 @@
       "com.google.gwt.lang.ClassLiteralHolder") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package com.google.gwt.lang;\n");
       code.append("final class ClassLiteralHolder {\n");
       code.append("}\n");
@@ -112,7 +117,7 @@
   public static final MockJavaResource ENUM = new MockJavaResource("java.lang.Enum") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package java.lang;\n");
       code.append("import java.io.Serializable;\n");
       code.append("import com.google.gwt.core.client.JavaScriptObject;\n");
@@ -135,12 +140,13 @@
       new MockJavaResource("com.google.gwt.core.client.GWT") {
         @Override
         public CharSequence getContent() {
-          StringBuffer code = new StringBuffer();
+          StringBuilder code = new StringBuilder();
           code.append("package com.google.gwt.core.client;\n");
           code.append("public final class GWT {\n");
-          code.append("  public boolean isClient() { return true; };\n");
-          code.append("  public boolean isProdMode() { return true; };\n");
-          code.append("  public boolean isScript() { return true; };\n");
+          code.append("  public static <T> T create(Class<?> classLiteral) { return null; }");
+          code.append("  public static boolean isClient() { return true; };\n");
+          code.append("  public static boolean isProdMode() { return true; };\n");
+          code.append("  public static boolean isScript() { return true; };\n");
           code.append("  public static void runAsync(RunAsyncCallback callback) { }\n");
           code.append("  public static void runAsync(Class<?> name, RunAsyncCallback callback) { }\n");
           code.append("}\n");
@@ -151,7 +157,7 @@
       "com.google.gwt.core.client.RunAsyncCallback") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package com.google.gwt.core.client;\n");
       code.append("public interface RunAsyncCallback { }\n");
       return code;
@@ -160,10 +166,11 @@
   public static final MockJavaResource STATS = new MockJavaResource("com.google.gwt.lang.Stats") {
     @Override
     public CharSequence getContent() {
-      StringBuffer code = new StringBuffer();
+      StringBuilder code = new StringBuilder();
       code.append("package com.google.gwt.lang;\n");
       code.append("public class Stats {\n");
-      code.append("  public boolean isStatsAvailable() { return false; };\n");
+      code.append("  static boolean isStatsAvailable() { return false; };\n");
+      code.append("  static boolean onModuleStart(String mainClassName) { return false; }\n");
       code.append("}\n");
       return code;
     }
@@ -255,7 +262,8 @@
     // Replace the basic Class and Enum with a compiler-specific one.
     result.remove(JavaResourceBase.CLASS);
     result.remove(JavaResourceBase.ENUM);
-    Collections.addAll(result, ARRAY, CAST, CLASS, CLASSLITERALHOLDER, ENUM, GWT, RUNASYNCCALLBACK);
+    Collections.addAll(result, ARRAY, CAST, CLASS, CLASSLITERALHOLDER, ENUM, GWT, RUNASYNCCALLBACK,
+        STATS);
     return result.toArray(new MockJavaResource[result.size()]);
   }
 }