Revert "Cleanup array usage of class literals."

This cleanup breaks assumptions made by EnumOrdinalizer.

This reverts commit a1e72ddbf96b45f58874f721925d67151b180369.

Change-Id: Ib0d51ed5b0fae85ed08fd371f5c1668e32412b24
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java
index 8ed0104..1bc3877 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java
@@ -28,27 +28,36 @@
       SourceInfo info, JArrayType arrayType, List<JExpression> dimensionExpressions) {
     // Produce all class literals that will eventually get generated.
     assert dimensionExpressions != null;
-    return new JNewArray(info, arrayType, dimensionExpressions, null);
+    return new JNewArray(info, arrayType, dimensionExpressions, null,
+        new JClassLiteral(info.makeChild(), arrayType.getLeafType()));
   }
 
   public static JNewArray createArrayWithInitializers(SourceInfo info, JArrayType arrayType,
       List<JExpression> initializers) {
     assert initializers != null;
-    return new JNewArray(info, arrayType, null, initializers);
+    return new JNewArray(info, arrayType, null, initializers,
+        new JClassLiteral(info.makeChild(), arrayType.getLeafType()));
   }
 
   private final List<JExpression> dimensionExpressions;
 
   private final List<JExpression> initializers;
 
+  /**
+   * The list of class literals that will be needed to support this expression.
+   */
+  private JClassLiteral leafTypeClassLiteral;
+
   private JArrayType type;
 
   public JNewArray(SourceInfo info, JArrayType type, List<JExpression> dimensionExpressions,
-      List<JExpression> initializers) {
+      List<JExpression> initializers, JClassLiteral leafTypeClassLiteral) {
     super(info);
     this.type = type;
     this.dimensionExpressions = dimensionExpressions;
     this.initializers = initializers;
+    this.leafTypeClassLiteral = leafTypeClassLiteral;
+    assert !(leafTypeClassLiteral.getRefType().isArrayType());
   }
 
   public JArrayType getArrayType() {
@@ -63,6 +72,13 @@
     return initializers;
   }
 
+  /**
+   * Return a class literal for the leaf type of the array.
+   */
+  public JClassLiteral getLeafTypeClassLiteral() {
+    return leafTypeClassLiteral;
+  }
+
   @Override
   public JReferenceType getType() {
     return type.strengthenToNonNull().strengthenToExact();
@@ -91,6 +107,8 @@
       assert ((dimensionExpressions != null) ^ (initializers != null));
 
       visitor.accept(initializers != null ? initializers : dimensionExpressions);
+
+      leafTypeClassLiteral = (JClassLiteral) visitor.accept(leafTypeClassLiteral);
     }
     visitor.endVisit(this, ctx);
   }
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ArrayNormalizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ArrayNormalizer.java
index 498d227..226bfb8 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ArrayNormalizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ArrayNormalizer.java
@@ -22,7 +22,6 @@
 import com.google.gwt.dev.jjs.ast.JBinaryOperation;
 import com.google.gwt.dev.jjs.ast.JBinaryOperator;
 import com.google.gwt.dev.jjs.ast.JCastMap;
-import com.google.gwt.dev.jjs.ast.JClassLiteral;
 import com.google.gwt.dev.jjs.ast.JExpression;
 import com.google.gwt.dev.jjs.ast.JIntLiteral;
 import com.google.gwt.dev.jjs.ast.JLiteral;
@@ -131,7 +130,7 @@
     private JExpression initializeUnidimensionalArray(JNewArray x, JArrayType arrayType) {
       // override the type of the called method with the array's type
       SourceInfo sourceInfo = x.getSourceInfo();
-      JLiteral classLiteral = getLeafTypeClassLiteral(x);
+      JLiteral classLit = x.getLeafTypeClassLiteral();
       JExpression castableTypeMap = getOrCreateCastMap(sourceInfo, arrayType);
       JRuntimeTypeReference arrayElementRuntimeTypeReference =
           getElementRuntimeTypeReference(sourceInfo, arrayType);
@@ -141,7 +140,7 @@
       JMethodCall call =
           new JMethodCall(sourceInfo, null, initializeUnidimensionalArrayMethod);
       call.overrideReturnType(arrayType);
-      call.addArgs(classLiteral, castableTypeMap, arrayElementRuntimeTypeReference, dim,
+      call.addArgs(classLit, castableTypeMap, arrayElementRuntimeTypeReference, dim,
           elementTypeCategory, program.getLiteralInt(arrayType.getDims()));
       return call;
     }
@@ -153,7 +152,7 @@
       JsonArray elementTypeReferences = new JsonArray(sourceInfo, program.getJavaScriptObject());
       JsonArray dimList = new JsonArray(sourceInfo, program.getJavaScriptObject());
       JType currentElementType = arrayType;
-      JLiteral classLit = getLeafTypeClassLiteral(x);
+      JLiteral classLit = x.getLeafTypeClassLiteral();
       for (int i = 0; i < x.getDimensionExpressions().size(); ++i) {
         // Walk down each type from most dims to least.
         JArrayType curArrayType = (JArrayType) currentElementType;
@@ -182,7 +181,7 @@
       // override the type of the called method with the array's type
       SourceInfo sourceInfo = x.getSourceInfo();
       JExpression classLitExpression = program.createArrayClassLiteralExpression(x.getSourceInfo(),
-          getLeafTypeClassLiteral(x), arrayType.getDims());
+          x.getLeafTypeClassLiteral(), arrayType.getDims());
       JExpression castableTypeMap = getOrCreateCastMap(sourceInfo, arrayType);
       JRuntimeTypeReference elementTypeIds = getElementRuntimeTypeReference(sourceInfo, arrayType);
       JsonArray initializers =
@@ -203,13 +202,6 @@
     }
   }
 
-  private JClassLiteral getLeafTypeClassLiteral(JNewArray newArray) {
-    JType leafType = newArray.getArrayType().getLeafType();
-    JClassLiteral leafClassLiteral =  new JClassLiteral(newArray.getSourceInfo(), leafType);
-    leafClassLiteral.setField(program.getClassLiteralField(leafType));
-    return leafClassLiteral;
-  }
-
   private JArrayRef needsSetCheck(JBinaryOperation x) {
     if (x.getOp() != JBinaryOperator.ASG || !(x.getLhs() instanceof JArrayRef)) {
       return null;
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/CloneExpressionVisitor.java b/dev/core/src/com/google/gwt/dev/jjs/impl/CloneExpressionVisitor.java
index 5699666..a453256 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/CloneExpressionVisitor.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/CloneExpressionVisitor.java
@@ -217,7 +217,8 @@
   @Override
   public boolean visit(JNewArray x, Context ctx) {
     expression = new JNewArray(x.getSourceInfo(), x.getArrayType(),
-        cloneExpressions(x.getDimensionExpressions()), cloneExpressions(x.getInitializers()));
+        cloneExpressions(x.getDimensionExpressions()), cloneExpressions(x.getInitializers()),
+        cloneExpression(x.getLeafTypeClassLiteral()));
     return false;
   }
 
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
index 1014218..1b97a34 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
@@ -577,11 +577,6 @@
     }
 
     private void maybeRescueClassLiteral(JReferenceType type) {
-      if (type.isArrayType()) {
-        JArrayType arrayType = (JArrayType) type.getUnderlyingType();
-        // Always rescue the leaf type class literal as it is needed for creating arrays.
-        rescue(program.getClassLiteralField(arrayType.getLeafType()));
-      }
       if (liveFieldsAndMethods.contains(getClassMethod) ||
           liveFieldsAndMethods.contains(getClassField)) {
         // getClass() already live so rescue class literal immediately
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowRecorder.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowRecorder.java
index 6d1ddf2..d13ed82 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowRecorder.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowRecorder.java
@@ -15,7 +15,6 @@
 
 import com.google.gwt.dev.StringAnalyzableTypeEnvironment;
 import com.google.gwt.dev.jjs.ast.Context;
-import com.google.gwt.dev.jjs.ast.JArrayType;
 import com.google.gwt.dev.jjs.ast.JClassLiteral;
 import com.google.gwt.dev.jjs.ast.JClassType;
 import com.google.gwt.dev.jjs.ast.JDeclaredType;
@@ -24,8 +23,6 @@
 import com.google.gwt.dev.jjs.ast.JInterfaceType;
 import com.google.gwt.dev.jjs.ast.JMethod;
 import com.google.gwt.dev.jjs.ast.JMethodCall;
-import com.google.gwt.dev.jjs.ast.JNewArray;
-import com.google.gwt.dev.jjs.ast.JParameter;
 import com.google.gwt.dev.jjs.ast.JProgram;
 import com.google.gwt.dev.jjs.ast.JType;
 import com.google.gwt.dev.jjs.ast.JVisitor;
@@ -70,13 +67,22 @@
 
   @Override
   public void endVisit(JClassLiteral x, Context ctx) {
-    recordClassLiteralReferenced(x.getRefType());
-  }
-
-  @Override
-  public void endVisit(JNewArray x, Context ctx) {
-    JType type = x.getArrayType().getLeafType();
-    recordClassLiteralReferenced(type);
+    JType type = x.getRefType();
+    if (type instanceof JDeclaredType) {
+      String typeName = type.getName();
+      stringAnalyzableTypeEnvironment.recordStaticReferenceInMethod(typeName, currentMethodName);
+      maybeRecordClinitCall(typeName);
+    }
+    // Any Enum subtype whose class literal is referenced might have its enumValueOfFunc
+    // reflectively called at runtime (see Enum.valueOf()). So to be safe the enumValueOfFunc
+    // must be assumed to be called.
+    if (type.isEnumOrSubclass() != null && !type.getName().equals("java.lang.Enum")) {
+      JMethod valueOfMethod = getValueOfMethod((JDeclaredType) type);
+      if (valueOfMethod != null) {
+        stringAnalyzableTypeEnvironment.recordMethodCallsMethod(currentMethodName,
+            computeName(valueOfMethod));
+      }
+    }
   }
 
   @Override
@@ -106,6 +112,7 @@
   @Override
   public boolean visit(JField x, Context ctx) {
     String typeName = x.getEnclosingType().getName();
+
     if (x.isJsInteropEntryPoint()) {
       stringAnalyzableTypeEnvironment.recordExportedStaticReferenceInType(typeName);
     }
@@ -143,12 +150,6 @@
       recordCurrentMethodInstantiatesType(x.getEnclosingType());
     }
 
-    for (JParameter parameter : x.getParams()) {
-      if (x.isJsMethodVarargs() && parameter.isVarargs()) {
-        recordClassLiteralReferenced(
-            ((JArrayType) parameter.getType().getUnderlyingType()).getLeafType());
-      }
-    }
     return true;
   }
 
@@ -178,24 +179,6 @@
     }
   }
 
-  private void recordClassLiteralReferenced(JType type) {
-    if (type instanceof JDeclaredType) {
-      String typeName = type.getName();
-      stringAnalyzableTypeEnvironment.recordStaticReferenceInMethod(typeName, currentMethodName);
-      maybeRecordClinitCall(typeName);
-    }
-    // Any Enum subtype whose class literal is referenced might have its enumValueOfFunc
-    // reflectively called at runtime (see Enum.valueOf()). So to be safe the enumValueOfFunc
-    // must be assumed to be called.
-    if (type.isEnumOrSubclass() != null && !type.getName().equals("java.lang.Enum")) {
-      JMethod valueOfMethod = getValueOfMethod((JDeclaredType) type);
-      if (valueOfMethod != null) {
-        stringAnalyzableTypeEnvironment.recordMethodCallsMethod(currentMethodName,
-            computeName(valueOfMethod));
-      }
-    }
-  }
-
   private void processJFieldRef(JFieldRef x) {
     if (x.getTarget() instanceof JField) {
       JField field = (JField) x.getTarget();
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java
index 0eaae52..11d373a 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java
@@ -396,11 +396,6 @@
         resolveClassLiteralField(type);
       }
     }
-    // Class literals for array types are implicitly used in array creation, so they must be
-    // considered reachable.
-    for (JArrayType arrayType : program.getAllArrayTypes()) {
-      resolveClassLiteralField(arrayType.getLeafType());
-    }
     NormalizeVisitor visitor = new NormalizeVisitor();
     visitor.accept(program);
     program.recordClassLiteralFields(classLiteralFields);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementJsVarargs.java b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementJsVarargs.java
index a0bd259..0938544 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementJsVarargs.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementJsVarargs.java
@@ -374,6 +374,8 @@
               new JIntLiteral(sourceInfo, varargsIndex));
       JNewArray arrayVariable = JNewArray.createArrayWithDimensionExpressions(sourceInfo,
           varargsArrayType, Collections.singletonList(lengthMinusVarargsIndex));
+      arrayVariable.getLeafTypeClassLiteral().setField(
+          program.getClassLiteralField(varargsArrayType.getLeafType()));
       preamble.addStmt(new JDeclarationStatement(
           sourceInfo, argumentsCopyVariable.createRef(sourceInfo), arrayVariable));
 
diff --git a/dev/core/test/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzerTest.java b/dev/core/test/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzerTest.java
index a435dfd..deaa8f5 100644
--- a/dev/core/test/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzerTest.java
+++ b/dev/core/test/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzerTest.java
@@ -252,15 +252,11 @@
 
     // Returning a JSO from a JSNI method rescues.
     analyzeSnippet("Foo.create_array();").assertOnlyInstantiatedTypes(
-        "int[]", "Object",
-        // Classes rescued due to rescueing classliterals for instantiated arrays.
-        "Class", "String", "Serializable", "Comparable", "CharSequence");
+        "int[]", "Object");
 
     // Returning a JSO from a JSNI method rescues.
     analyzeSnippet("Foo.create_2d_array();").assertOnlyInstantiatedTypes(
-        "int[][]", "Object[]", "Object",
-        // Classes rescued due to rescueing classliterals for instantiated arrays.
-        "Class", "String", "Serializable", "Comparable", "CharSequence");
+        "int[][]", "Object[]", "Object");
   }
 
   private Result analyzeSnippet(String codeSnippet)
diff --git a/user/test/com/google/gwt/core/interop/JsTypeVarargsTest.java b/user/test/com/google/gwt/core/interop/JsTypeVarargsTest.java
index 68322a7..9ab1c19 100644
--- a/user/test/com/google/gwt/core/interop/JsTypeVarargsTest.java
+++ b/user/test/com/google/gwt/core/interop/JsTypeVarargsTest.java
@@ -287,7 +287,6 @@
     sideEffectCount++;
     return obj;
   }
-
   public void testVarargsCall_sideEffectingInstance() {
     SubclassNativeWithVarargsConstructor object =
         new SubclassNativeWithVarargsConstructor(0, new Object[0]);
@@ -296,16 +295,4 @@
     assertSame(object, doSideEffect(object).varargsMethod(0, params));
     assertSame(1, sideEffectCount);
   }
-
-  static class UninstantiatedClass {
-  }
-
-  @JsMethod(namespace = JsPackage.GLOBAL)
-  public static UninstantiatedClass[] varargJsMethodUninstantiatedVararg(UninstantiatedClass... varargs) {
-    return varargs;
-  }
-
-  public native void testVarargsCall_uninstantiatedVararg() /*-{
-    @GWTTestCase::assertEquals(II)(0, $global.varargJsMethodUninstantiatedVararg().length);
-  }-*/;
 }