Merges defineClass and defineClassWithPrototype

Change-Id: Ibb362c62caa371c19bb933f846ad17d501b055ab
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index c645462..f3a2671 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -2572,9 +2572,7 @@
       // choose appropriate setup function
       // JavaClassHierarchySetupUtil.defineClass(typeId, superTypeId, castableMap, constructors)
       JsStatement defineClassStatement = constructInvocation(x.getSourceInfo(),
-          jsPrototype == null ? "JavaClassHierarchySetupUtil.defineClass" :
-              "JavaClassHierarchySetupUtil.defineClassWithPrototype",
-          defineClassArguments).makeStmt();
+          "JavaClassHierarchySetupUtil.defineClass", defineClassArguments).makeStmt();
       globalStmts.add(defineClassStatement);
       typeForStatMap.put(defineClassStatement, x);
     }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/codesplitter/FragmentExtractor.java b/dev/core/src/com/google/gwt/dev/jjs/impl/codesplitter/FragmentExtractor.java
index feb0538..ff2108f 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/codesplitter/FragmentExtractor.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/codesplitter/FragmentExtractor.java
@@ -442,11 +442,7 @@
       JsNameRef func = (JsNameRef) call.getQualifier();
       JsFunction defineClassJsFunc =
           jsprogram.getIndexedFunction("JavaClassHierarchySetupUtil.defineClass");
-      JsFunction defineClassJsProtoFunc =
-          jsprogram.getIndexedFunction(
-              "JavaClassHierarchySetupUtil.defineClassWithPrototype");
-      if (func.getName() != defineClassJsFunc.getName() && func.getName() !=
-          defineClassJsProtoFunc.getName()) {
+      if (func.getName() != defineClassJsFunc.getName()) {
         return null;
       }
       return map.typeForStatement(stat);
diff --git a/dev/core/src/com/google/gwt/dev/js/JsInliner.java b/dev/core/src/com/google/gwt/dev/js/JsInliner.java
index 3de81bf..8d49fd4 100644
--- a/dev/core/src/com/google/gwt/dev/js/JsInliner.java
+++ b/dev/core/src/com/google/gwt/dev/js/JsInliner.java
@@ -644,11 +644,9 @@
       this.whitelist = whitelist;
       invocationCountingVisitor.accept(program);
       JsName defineClass = getFunctionName(program, "JavaClassHierarchySetupUtil.defineClass");
-      JsName defineClassProto = getFunctionName(program,
-          "JavaClassHierarchySetupUtil.defineClassWithPrototype");
       // JsInlinerTest doesn't have these functions, but doesn't need them
-      safeToInlineAtTopLevel = defineClass != null ? ImmutableSet.of(
-          defineClass, defineClassProto) : ImmutableSet.<JsName>of();
+      safeToInlineAtTopLevel = defineClass != null ? ImmutableSet.of(defineClass)
+          : ImmutableSet.<JsName>of();
     }
 
     private static JsName getFunctionName(JsProgram program, String name) {
diff --git a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/JavaClassHierarchySetupUtil.java b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/JavaClassHierarchySetupUtil.java
index 5c70098..1c149ed 100644
--- a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/JavaClassHierarchySetupUtil.java
+++ b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/JavaClassHierarchySetupUtil.java
@@ -29,8 +29,8 @@
 
   /**
    * If not already created it creates the prototype for the class and stores it in
-   * {@code prototypesByTypeId}. If superTypeId is null, it means that the class being defined
-   * is the topmost class (i.e. java.lang.Object) and creates an empty prototype for it.
+   * {@code prototypesByTypeId}. If superTypeIdOrPrototype is null, it means that the class being
+   * defined is the topmost class (i.e. java.lang.Object) and creates an empty prototype for it.
    * Otherwise it creates the prototype for the class by calling {@code createSubclassPrototype()}.
    * It also assigns the castable type map and sets the constructors prototype field to the
    * current prototype.
@@ -39,80 +39,43 @@
    * code-split fragments. In that case Class.createFor* methods will have created a placeholder and
    * stored in {@code prototypesByTypeId} the class literal.
    * <p>
-   * As a prerequisite if superTypeId is not null, it is assumed that defineClass for the supertype
-   * has already been called.
+   * As a prerequisite if superTypeIdOrPrototype is not null, it is assumed that defineClass for the
+   * supertype has already been called.
    * <p>
    * This method has the effect of assigning the newly created prototype to the global temp variable
    * '_'.
    */
   public static native void defineClass(JavaScriptObject typeId,
-      JavaScriptObject superTypeId, JavaScriptObject castableTypeMap) /*-{
+      JavaScriptObject superTypeIdOrPrototype, JavaScriptObject castableTypeMap) /*-{
     // Setup aliases for (horribly long) JSNI references.
-    var prototypesByTypeId = @com.google.gwt.lang.JavaClassHierarchySetupUtil::prototypesByTypeId;
-    var createSubclassPrototype =
-        @com.google.gwt.lang.JavaClassHierarchySetupUtil::createSubclassPrototype(*)
-    var maybeGetClassLiteralFromPlaceHolder =  @com.google.gwt.lang.JavaClassHierarchySetupUtil::
-        maybeGetClassLiteralFromPlaceHolder(*);
+    var prototypesByTypeId = @JavaClassHierarchySetupUtil::prototypesByTypeId;
     // end of alias definitions.
 
     var prototype = prototypesByTypeId[typeId];
-    var clazz = maybeGetClassLiteralFromPlaceHolder(prototype);
+    var clazz = @JavaClassHierarchySetupUtil::maybeGetClassLiteralFromPlaceHolder(*)(prototype);
     if (prototype && !clazz) {
       // not a placeholder entry setup by Class.setClassLiteral
       _ = prototype;
     } else {
-      _ = prototypesByTypeId[typeId]  = (!superTypeId) ? {} : createSubclassPrototype(superTypeId);
-      _.@java.lang.Object::castableTypeMap = castableTypeMap;
+      _ = @JavaClassHierarchySetupUtil::createSubclassPrototype(*)(superTypeIdOrPrototype);
+      _.@Object::castableTypeMap = castableTypeMap;
       _.constructor = _;
-      if (!superTypeId) {
+      if (!superTypeIdOrPrototype) {
         // Set the typeMarker on java.lang.Object's prototype, implicitly setting it for all
         // Java subclasses (String and Arrays have special handling in Cast and Array respectively).
-        _.@java.lang.Object::typeMarker =
-            @JavaClassHierarchySetupUtil::typeMarkerFn(*);
+        _.@Object::typeMarker = @JavaClassHierarchySetupUtil::typeMarkerFn(*);
       }
+      prototypesByTypeId[typeId] = _;
     }
     for (var i = 3; i < arguments.length; ++i) {
       // Assign the type prototype to each constructor.
       arguments[i].prototype = _;
     }
     if (clazz) {
-      _.@java.lang.Object::___clazz = clazz;
+      _.@Object::___clazz = clazz;
     }
   }-*/;
 
-  /**
-   * Like defineClass() but second parameter is a native JS prototype reference.
-   */
-  public static native void defineClassWithPrototype(int typeId,
-      JavaScriptObject jsSuperClass, JavaScriptObject castableTypeMap) /*-{
-      // Setup aliases for (horribly long) JSNI references.
-      var prototypesByTypeId = @com.google.gwt.lang.JavaClassHierarchySetupUtil::prototypesByTypeId;
-
-      var maybeGetClassLiteralFromPlaceHolder =  @com.google.gwt.lang.JavaClassHierarchySetupUtil::
-          maybeGetClassLiteralFromPlaceHolder(Lcom/google/gwt/core/client/JavaScriptObject;);
-      // end of alias definitions.
-
-      var prototype = prototypesByTypeId[typeId];
-      var clazz = maybeGetClassLiteralFromPlaceHolder(prototype);
-
-      if (prototype && !clazz) {
-          // not a placeholder entry setup by Class.setClassLiteral
-          _ = prototype;
-      } else {
-          var superPrototype = jsSuperClass && jsSuperClass.prototype || {};
-          _ = prototypesByTypeId[typeId] =  @com.google.gwt.lang.JavaClassHierarchySetupUtil::
-              portableObjCreate(Lcom/google/gwt/core/client/JavaScriptObject;)(superPrototype);
-          _.@java.lang.Object::castableTypeMap = castableTypeMap;
-      }
-      for (var i = 3; i < arguments.length; ++i) {
-          // Assign the type prototype to each constructor.
-          arguments[i].prototype = _;
-      }
-      if (clazz) {
-          _.@java.lang.Object::___clazz = clazz;
-      }
-  }-*/;
-
   private static native JavaScriptObject portableObjCreate(JavaScriptObject obj) /*-{
     function F() {};
     F.prototype = obj || {};
@@ -122,12 +85,17 @@
   /**
    * Create a subclass prototype.
    */
-  public static native JavaScriptObject createSubclassPrototype(JavaScriptObject superTypeId) /*-{
-    // Setup aliases for (horribly long) JSNI references.
-    var prototypesByTypeId = @com.google.gwt.lang.JavaClassHierarchySetupUtil::prototypesByTypeId;
-    // end of alias definitions.
-    return @com.google.gwt.lang.JavaClassHierarchySetupUtil::
-        portableObjCreate(Lcom/google/gwt/core/client/JavaScriptObject;)(prototypesByTypeId[superTypeId]);
+  private static native JavaScriptObject createSubclassPrototype(
+      JavaScriptObject superTypeIdOrPrototype) /*-{
+    var superPrototype;
+    if (typeof superTypeIdOrPrototype != 'number') {
+      // Either it is null or the prototype of the super type.
+      superPrototype = (superTypeIdOrPrototype && superTypeIdOrPrototype.prototype) || {};
+    } else {
+      superPrototype = @JavaClassHierarchySetupUtil::prototypesByTypeId[superTypeIdOrPrototype];
+    }
+
+    return @JavaClassHierarchySetupUtil::portableObjCreate(*)(superPrototype);
   }-*/;
 
   /**
@@ -220,9 +188,7 @@
    * Retrieves the prototype for a type if it exists, null otherwise.
    */
   public static native JavaScriptObject getClassPrototype(JavaScriptObject typeId) /*-{
-    var prototypeForTypeId =
-        @com.google.gwt.lang.JavaClassHierarchySetupUtil::prototypesByTypeId[typeId];
-    return prototypeForTypeId;
+    return @JavaClassHierarchySetupUtil::prototypesByTypeId[typeId];
   }-*/;
 
   /**
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 7b265b0..cdd6c99 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java
@@ -262,11 +262,6 @@
               "  public static Object defineClass(int typeId, int superTypeId, Object map) {",
               "    return null;",
               "  }",
-              " public static Object defineClassWithPrototype(int typeId, "
-                  + "int superTypeId, ",
-              " Object map) {",
-              "    return null;",
-              "  }",
               "  public static void modernizeBrowser() {}",
               "  public static void emptyMethod() {}",
               "}"