Implement all class literals when compiling separately.

In monolithic compiles (where whole world information is available)
only class literals that are determined to be potentially accessed are
created in ImplementClassLiteralsAsFields normalizing pass.

This patch makes the normalizing pass create ALL class literals only in
the case of separate compilation.

In the future this normalizing pass should always create all class
literals and let the optimizer prune unneeded ones.

Change-Id: Ib6c63f6ef9c8dcf79ae2159bd18f45804b824033
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
index 2d19d90..7613ff7 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
@@ -297,11 +297,6 @@
   private final Map<JClassType, Map<String, JMethod>> polyClassMethodMap =
       new IdentityHashMap<JClassType, Map<String, JMethod>>();
 
-  /**
-   * Whether this type oracle has whole world knowledge or not. Monolithic compiles have whole
-   * world knowledge but separate compiles know only about their immediate source and the
-   * immediately referenced types
-   */
   private final boolean hasWholeWorldKnowledge;
 
   /**
@@ -598,6 +593,15 @@
   }
 
   /**
+   * Whether this type oracle has whole world knowledge or not. Monolithic compiles have whole
+   * world knowledge but separate compiles know only about their immediate source and the
+   * immediately referenced types.
+   */
+  public boolean hasWholeWorldKnowledge() {
+    return hasWholeWorldKnowledge;
+  }
+
+  /**
    * True if either a JSO, or is an interface that is ONLY implemented by a JSO.
    */
   public boolean isEffectivelyJavaScriptObject(JType type) {
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 868cd93..d12c402 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
@@ -1,12 +1,12 @@
 /*
  * Copyright 2011 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
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -120,42 +120,42 @@
   /**
    * Create an expression that will evaluate, at run time, to the class literal.
    * Causes recursive literal create (super type, array element type). Examples:
-   * 
+   *
    * Class:
-   * 
+   *
    * <pre>
    * Class.createForClass("java.lang.", "Object", /JSeedIdOf/"java.lang.Object", null)
    * Class.createForClass("java.lang.", "Exception", /JSeedIdOf/"java.lang.Exception", Throwable.class)
    * </pre>
-   * 
+   *
    * Interface:
-   * 
+   *
    * <pre>
    * Class.createForInterface(&quot;java.lang.&quot;, &quot;Comparable&quot;)
    * </pre>
-   * 
+   *
    * Primitive:
-   * 
+   *
    * <pre>
    * Class.createForPrimitive(&quot;&quot;, &quot;int&quot;, &quot; I&quot;)
    * </pre>
-   * 
+   *
    * Array:
-   * 
+   *
    * <pre>
    * Class.createForArray("", "[I", /JSeedIdOf/"com.google.gwt.lang.Array", int.class)
    * Class.createForArray("[Lcom.example.", "Foo;", /JSeedIdOf/"com.google.gwt.lang.Array", Foo.class)
    * </pre>
-   * 
+   *
    * Enum:
-   * 
+   *
    * <pre>
    * Class.createForEnum("com.example.", "MyEnum", /JSeedIdOf/"com.example.MyEnum", Enum.class,
    *     public static MyEnum[] values(), public static MyEnum valueOf(String name))
    * </pre>
-   * 
+   *
    * Enum subclass:
-   * 
+   *
    * <pre>
    * Class.createForEnum("com.example.", "MyEnum$1", /JSeedIdOf/"com.example.MyEnum$1", MyEnum.class,
    *     null, null))
@@ -262,6 +262,14 @@
   private void execImpl() {
     NormalizeVisitor visitor = new NormalizeVisitor();
     visitor.accept(program);
+    // TODO(rluble): This is kind of hacky. It would be more general purpose to create a class
+    // literal implementation for every class and let unused ones be pruned by optimization.
+    // Instead we're prematurely optimizing.
+    if (!program.typeOracle.hasWholeWorldKnowledge()) {
+      for (JType type : program.getDeclaredTypes()) {
+        resolveClassLiteralField(type);
+      }
+    }
     program.recordClassLiteralFields(classLiteralFields);
   }
 
@@ -300,7 +308,7 @@
 
   /**
    * Resolve a class literal field. Takes the form:
-   * 
+   *
    * <pre>
    * class ClassLiteralHolder {
    *   Class Ljava_lang_Object_2_classLit =