Revision: 9808
Author: gwt.mirror...@gmail.com
Date: Thu Mar  3 17:42:23 2011
Log: Decentralize JClassLiterals.

This change allows JClassLiterals to be created apart from a JProgram. A new normalization pass runs before optimizations and creates all the ClassLiteralHolder implementation fields.

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

http://code.google.com/p/google-web-toolkit/source/detail?r=9808

Added:
/trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java
Modified:
 /trunk/dev/core/src/com/google/gwt/dev/jjs/ArtificialRescueRecorder.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/js/JsniMethodBody.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/CodeSplitter.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
/trunk/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java
 /trunk/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java
 /trunk/dev/core/test/com/google/gwt/dev/jjs/impl/JsniRefLookupTest.java

=======================================
--- /dev/null
+++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ImplementClassLiteralsAsFields.java Thu Mar 3 17:42:23 2011
@@ -0,0 +1,309 @@
+/*
+ * 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
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.jjs.impl;
+
+import com.google.gwt.dev.jjs.Correlation.Literal;
+import com.google.gwt.dev.jjs.InternalCompilerException;
+import com.google.gwt.dev.jjs.SourceInfo;
+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.JDeclarationStatement;
+import com.google.gwt.dev.jjs.ast.JDeclaredType;
+import com.google.gwt.dev.jjs.ast.JEnumType;
+import com.google.gwt.dev.jjs.ast.JField;
+import com.google.gwt.dev.jjs.ast.JFieldRef;
+import com.google.gwt.dev.jjs.ast.JInterfaceType;
+import com.google.gwt.dev.jjs.ast.JLiteral;
+import com.google.gwt.dev.jjs.ast.JMethod;
+import com.google.gwt.dev.jjs.ast.JMethodBody;
+import com.google.gwt.dev.jjs.ast.JMethodCall;
+import com.google.gwt.dev.jjs.ast.JModVisitor;
+import com.google.gwt.dev.jjs.ast.JNameOf;
+import com.google.gwt.dev.jjs.ast.JNullLiteral;
+import com.google.gwt.dev.jjs.ast.JPrimitiveType;
+import com.google.gwt.dev.jjs.ast.JProgram;
+import com.google.gwt.dev.jjs.ast.JStringLiteral;
+import com.google.gwt.dev.jjs.ast.JType;
+import com.google.gwt.dev.jjs.ast.JField.Disposition;
+import com.google.gwt.dev.jjs.ast.js.JsniMethodRef;
+import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
+import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+/**
+ * Create fields to represent the mechanical implementation of class literals. + * Must be done after all class literals are created, but before optimizations
+ * begin. {@link ControlFlowAnalyzer} depends on this.
+ * <p>
+ * Class literals are implemented as static field references. The static fields + * are all put into the special com.google.gwt.lang.ClassLiteralHolder class. + * Ordinarily, accessing one of these fields would trigger a clinit to run, but + * we've special-cased class literal fields to evaluate as top-level code before
+ * the application starts running to avoid the clinit.
+ * <p>
+ * TODO(cromwellian): consider lazy-initialization to improve startup time.
+ */
+public class ImplementClassLiteralsAsFields {
+
+  private class NormalizeVisitor extends JModVisitor {
+    @Override
+    public void endVisit(JClassLiteral x, Context ctx) {
+      JField field = resolveClassLiteralField(x);
+      x.setField(field);
+    }
+  }
+
+  public static void exec(JProgram program) {
+ Event normalizerEvent = SpeedTracerLogger.start(CompilerEventType.NORMALIZER);
+    new ImplementClassLiteralsAsFields(program).execImpl();
+    normalizerEvent.end();
+  }
+
+  private static String getClassName(String fullName) {
+    int pos = fullName.lastIndexOf(".");
+    return fullName.substring(pos + 1);
+  }
+
+  private static String getPackageName(String fullName) {
+    int pos = fullName.lastIndexOf(".");
+    return fullName.substring(0, pos + 1);
+  }
+
+ private final Map<JType, JField> classLiteralFields = new IdentityHashMap<JType, JField>();
+  private final JMethodBody classLiteralHolderClinitBody;
+  private final JProgram program;
+  private final JClassType typeClassLiteralHolder;
+
+  private ImplementClassLiteralsAsFields(JProgram program) {
+    this.program = program;
+    this.typeClassLiteralHolder = program.getTypeClassLiteralHolder();
+    this.classLiteralHolderClinitBody =
+        (JMethodBody) typeClassLiteralHolder.getMethods().get(0).getBody();
+  }
+
+  /**
+ * 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", /JNameOf/"java.lang.Object", null) + * Class.createForClass("java.lang.", "Exception", /JNameOf/"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", /JNameOf/"com.google.gwt.lang.Array", int.class) + * Class.createForArray("[Lcom.example.", "Foo;", /JNameOf/"com.google.gwt.lang.Array", Foo.class)
+   * </pre>
+   *
+   * Enum:
+   *
+   * <pre>
+ * Class.createForEnum("com.example.", "MyEnum", /JNameOf/"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", /JNameOf/"com.example.MyEnum$1", MyEnum.class,
+   *     null, null))
+   * </pre>
+   */
+ private JMethodCall computeClassObjectAllocation(SourceInfo info, JType type) {
+    String typeName = getTypeName(type);
+
+ JMethod method = program.getIndexedMethod(type.getClassLiteralFactoryMethod());
+
+    /*
+     * Use the classForEnum() constructor even for enum subtypes to aid in
+     * pruning supertype data.
+     */
+    boolean isEnumOrSubclass = false;
+    if (type instanceof JClassType) {
+      JEnumType maybeEnum = ((JClassType) type).isEnumOrSubclass();
+      if (maybeEnum != null) {
+        isEnumOrSubclass = true;
+ method = program.getIndexedMethod(maybeEnum.getClassLiteralFactoryMethod());
+      }
+    }
+
+    assert method != null;
+
+    JMethodCall call = new JMethodCall(info, null, method);
+ JStringLiteral packageName = program.getLiteralString(info, getPackageName(typeName)); + JStringLiteral className = program.getLiteralString(info, getClassName(typeName));
+    call.addArgs(packageName, className);
+
+    if (type instanceof JArrayType) {
+      // There's only one seed function for all arrays
+      JDeclaredType arrayType = program.getIndexedType("Array");
+      call.addArg(new JNameOf(info, className.getType(), arrayType));
+
+    } else if (type instanceof JClassType) {
+      // Add the name of the seed function for concrete types
+      call.addArg(new JNameOf(info, className.getType(), type));
+
+    } else if (type instanceof JPrimitiveType) {
+      // And give primitive types an illegal, though meaningful, value
+ call.addArg(program.getLiteralString(info, " " + type.getJavahSignatureName()));
+    }
+
+    if (type instanceof JClassType) {
+      /*
+ * For non-array classes and enums, determine the class literal of the + * supertype, if there is one. Arrays are excluded because they always
+       * have Object as their superclass.
+       */
+      JClassType classType = (JClassType) type;
+
+      JLiteral superclassLiteral;
+      if (classType.getSuperClass() != null) {
+ superclassLiteral = createDependentClassLiteral(info, classType.getSuperClass());
+      } else {
+        superclassLiteral = JNullLiteral.INSTANCE;
+      }
+
+      call.addArg(superclassLiteral);
+
+      if (classType instanceof JEnumType) {
+        JEnumType enumType = (JEnumType) classType;
+        JMethod valuesMethod = null;
+        JMethod valueOfMethod = null;
+        for (JMethod methodIt : enumType.getMethods()) {
+          if ("values".equals(methodIt.getName())) {
+            if (methodIt.getParams().size() != 0) {
+              continue;
+            }
+            valuesMethod = methodIt;
+          } else if ("valueOf".equals(methodIt.getName())) {
+            if (methodIt.getParams().size() != 1
+ || methodIt.getParams().get(0).getType() != program.getTypeJavaLangString()) {
+              continue;
+            }
+            valueOfMethod = methodIt;
+          }
+        }
+        if (valuesMethod == null) {
+ throw new InternalCompilerException("Could not find enum values() method");
+        }
+        if (valueOfMethod == null) {
+ throw new InternalCompilerException("Could not find enum valueOf() method");
+        }
+ call.addArg(new JsniMethodRef(info, null, valuesMethod, program.getJavaScriptObject())); + call.addArg(new JsniMethodRef(info, null, valueOfMethod, program.getJavaScriptObject()));
+      } else if (isEnumOrSubclass) {
+        // A subclass of an enum class
+        call.addArg(JNullLiteral.INSTANCE);
+        call.addArg(JNullLiteral.INSTANCE);
+      }
+    } else if (type instanceof JArrayType) {
+      JArrayType arrayType = (JArrayType) type;
+      JClassLiteral componentLiteral =
+          createDependentClassLiteral(info, arrayType.getElementType());
+      call.addArg(componentLiteral);
+    } else {
+ assert (type instanceof JInterfaceType || type instanceof JPrimitiveType);
+    }
+ assert call.getArgs().size() == method.getParams().size() : "Argument / param mismatch "
+        + call.toString() + " versus " + method.toString();
+    return call;
+  }
+
+ private JClassLiteral createDependentClassLiteral(SourceInfo info, JType type) {
+    JClassLiteral classLiteral = new JClassLiteral(info.makeChild(), type);
+    JField field = resolveClassLiteralField(classLiteral);
+    classLiteral.setField(field);
+    return classLiteral;
+  }
+
+  private void execImpl() {
+    NormalizeVisitor visitor = new NormalizeVisitor();
+    visitor.accept(program);
+  }
+
+  private String getTypeName(JType type) {
+    String typeName;
+    if (type instanceof JArrayType) {
+      typeName = type.getJsniSignatureName().replace('/', '.');
+      // Mangle the class name to match hosted mode.
+      if (program.isJavaScriptObject(((JArrayType) type).getLeafType())) {
+        typeName = typeName.replace(";", "$;");
+      }
+    } else {
+      typeName = type.getName();
+      // Mangle the class name to match hosted mode.
+      if (program.isJavaScriptObject(type)) {
+        typeName += '$';
+      }
+    }
+    return typeName;
+  }
+
+  /**
+   * Takes the form:
+   *
+   * <pre>
+   * class ClassLiteralHolder {
+   *   Class Ljava_lang_Object_2_classLit =
+ * Class.createForClass("java.lang.", "Object", /JNameOf/"java.lang.Object", null)
+   * }
+   * </pre>
+   */
+  private JField resolveClassLiteralField(JClassLiteral classLiteral) {
+    JType type = classLiteral.getRefType();
+    JField field = classLiteralFields.get(type);
+    if (field == null) {
+ // Create the allocation expression FIRST since this may be recursive on + // super type (this forces the super type classLit to be created first).
+      SourceInfo info = typeClassLiteralHolder.getSourceInfo().makeChild();
+      JMethodCall alloc = computeClassObjectAllocation(info, type);
+      // Create a field in the class literal holder to hold the object.
+      field =
+ new JField(info, program.getClassLiteralName(type), typeClassLiteralHolder, program
+              .getTypeJavaLangClass(), true, Disposition.FINAL);
+      typeClassLiteralHolder.addField(field);
+      info.addCorrelation(info.getCorrelator().by(Literal.CLASS));
+
+      // Initialize the field.
+ JFieldRef fieldRef = new JFieldRef(info, null, field, typeClassLiteralHolder); + JDeclarationStatement decl = new JDeclarationStatement(info, fieldRef, alloc);
+      classLiteralHolderClinitBody.getBlock().addStmt(decl);
+      classLiteralFields.put(type, field);
+    }
+    return field;
+  }
+}
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/ArtificialRescueRecorder.java Wed Mar 2 12:43:16 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/ArtificialRescueRecorder.java Thu Mar 3 17:42:23 2011
@@ -18,7 +18,6 @@
 import com.google.gwt.core.client.impl.ArtificialRescue;
 import com.google.gwt.core.client.impl.ArtificialRescue.Rescue;
 import com.google.gwt.dev.jjs.ast.Context;
-import com.google.gwt.dev.jjs.ast.HasEnclosingType;
 import com.google.gwt.dev.jjs.ast.JAnnotation;
 import com.google.gwt.dev.jjs.ast.JDeclaredType;
 import com.google.gwt.dev.jjs.ast.JField;
@@ -26,6 +25,7 @@
 import com.google.gwt.dev.jjs.ast.JNode;
 import com.google.gwt.dev.jjs.ast.JProgram;
 import com.google.gwt.dev.jjs.ast.JReferenceType;
+import com.google.gwt.dev.jjs.ast.JType;
 import com.google.gwt.dev.jjs.ast.JVisitor;
 import com.google.gwt.dev.jjs.impl.JsniRefLookup;
 import com.google.gwt.dev.util.JsniRef;
@@ -97,7 +97,7 @@
         for (String name : toRescue) {
JsniRef ref = JsniRef.parse("@" + classType.getName() + "::" + name);
           final String[] errors = {null};
- HasEnclosingType node = JsniRefLookup.findJsniRefTarget(ref, program,
+          JNode node = JsniRefLookup.findJsniRefTarget(ref, program,
               new JsniRefLookup.ErrorReporter() {
                 public void reportError(String error) {
                   errors[0] = error;
@@ -109,7 +109,11 @@
"Unable to artificially rescue " + name + ": " + errors[0]);
           }

-          currentClass.addArtificialRescue((JNode) node);
+          if (node instanceof JType) {
+            // Already added the type above.
+          } else {
+            currentClass.addArtificialRescue(node);
+          }
           if (node instanceof JField) {
             JField field = (JField) node;
             if (!field.isFinal()) {
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java Wed Feb 9 11:52:03 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java Thu Mar 3 14:34:14 2011
@@ -81,6 +81,7 @@
 import com.google.gwt.dev.jjs.impl.GenerateJavaAST;
 import com.google.gwt.dev.jjs.impl.GenerateJavaScriptAST;
 import com.google.gwt.dev.jjs.impl.HandleCrossFragmentReferences;
+import com.google.gwt.dev.jjs.impl.ImplementClassLiteralsAsFields;
 import com.google.gwt.dev.jjs.impl.JavaScriptObjectNormalizer;
 import com.google.gwt.dev.jjs.impl.JavaToJavaScriptMap;
 import com.google.gwt.dev.jjs.impl.JsFunctionClusterer;
@@ -622,6 +623,8 @@
       // Replace references to JSO subtypes with JSO itself.
       JavaScriptObjectNormalizer.exec(jprogram);

+      ImplementClassLiteralsAsFields.exec(jprogram);
+
       /*
        * 4) Possibly optimize some.
        *
@@ -675,12 +678,6 @@
    */
   protected static void draftOptimize(JProgram jprogram) {
Event draftOptimizeEvent = SpeedTracerLogger.start(CompilerEventType.DRAFT_OPTIMIZE);
-    /*
- * Record the beginning of optimizations; this turns on certain checks that
-     * guard against problematic late construction of things like class
-     * literals.
-     */
-    jprogram.beginOptimizations();
     Finalizer.exec(jprogram);
     MakeCallsStatic.exec(jprogram);
     jprogram.typeOracle.recomputeAfterOptimizations();
@@ -692,13 +689,6 @@
       throws InterruptedException {
Event optimizeEvent = SpeedTracerLogger.start(CompilerEventType.OPTIMIZE);

-    /*
- * Record the beginning of optimizations; this turns on certain checks that
-     * guard against problematic late construction of things like class
-     * literals.
-     */
-    jprogram.beginOptimizations();
-
List<OptimizerStats> allOptimizerStats = new ArrayList<OptimizerStats>();
     int counter = 0;
     int optimizationLevel = options.getOptimizationLevel();
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java Wed Jan 26 16:52:13 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JClassLiteral.java Thu Mar 3 14:34:14 2011
@@ -15,9 +15,8 @@
  */
 package com.google.gwt.dev.jjs.ast;

-import com.google.gwt.dev.jjs.InternalCompilerException;
+import com.google.gwt.dev.jjs.Correlation.Literal;
 import com.google.gwt.dev.jjs.SourceInfo;
-import com.google.gwt.dev.jjs.ast.js.JsniMethodRef;

 /**
  * Java class literal expression.
@@ -27,152 +26,19 @@
  * initializer.
  */
public class JClassLiteral extends JLiteral implements JAnnotationArgument {
-  /**
- * Create an expression that will evaluate, at run time, to the class literal.
-   * Cannot be called after optimizations begin.
-   */
-  static JMethodCall computeClassObjectAllocation(JProgram program,
-      SourceInfo info, JType type) {
-    String typeName = getTypeName(program, type);
-
- JMethod method = program.getIndexedMethod(type.getClassLiteralFactoryMethod());
-
-    /*
-     * Use the classForEnum() constructor even for enum subtypes to aid in
-     * pruning supertype data.
-     */
-    boolean isEnumOrSubclass = false;
-    if (type instanceof JClassType) {
-      JEnumType maybeEnum = ((JClassType) type).isEnumOrSubclass();
-      if (maybeEnum != null) {
-        isEnumOrSubclass = true;
- method = program.getIndexedMethod(maybeEnum.getClassLiteralFactoryMethod());
-      }
-    }
-
-    assert method != null;
-
-    JMethodCall call = new JMethodCall(info, null, method);
-    JStringLiteral packageName = program.getLiteralString(info,
-        getPackageName(typeName));
-    JStringLiteral className = program.getLiteralString(info,
-        getClassName(typeName));
-    call.addArgs(packageName, className);
-
-    if (type instanceof JArrayType) {
-      // There's only one seed function for all arrays
-      JDeclaredType arrayType = program.getIndexedType("Array");
-      call.addArg(new JNameOf(info, className.getType(), arrayType));
-
-    } else if (type instanceof JClassType) {
-      // Add the name of the seed function for concrete types
-      call.addArg(new JNameOf(info, className.getType(), type));
-
-    } else if (type instanceof JPrimitiveType) {
-      // And give primitive types an illegal, though meaningful, value
-      call.addArg(program.getLiteralString(info, " "
-          + type.getJavahSignatureName()));
-    }
-
-    if (type instanceof JClassType) {
-      /*
- * For non-array classes and enums, determine the class literal of the - * supertype, if there is one. Arrays are excluded because they always
-       * have Object as their superclass.
-       */
-      JClassType classType = (JClassType) type;
-
-      JLiteral superclassLiteral;
-      if (classType.getSuperClass() != null) {
- superclassLiteral = program.getLiteralClass(classType.getSuperClass());
-      } else {
-        superclassLiteral = program.getLiteralNull();
-      }
-
-      call.addArg(superclassLiteral);
-
-      if (classType instanceof JEnumType) {
-        JEnumType enumType = (JEnumType) classType;
-        JMethod valuesMethod = null;
-        JMethod valueOfMethod = null;
-        for (JMethod methodIt : enumType.getMethods()) {
-          if ("values".equals(methodIt.getName())) {
-            if (methodIt.getParams().size() != 0) {
-              continue;
-            }
-            valuesMethod = methodIt;
-          } else if ("valueOf".equals(methodIt.getName())) {
-            if (methodIt.getParams().size() != 1 ||
- methodIt.getParams().get(0).getType() != program.getTypeJavaLangString()) {
-              continue;
-            }
-            valueOfMethod = methodIt;
-          }
-        }
-        if (valuesMethod == null) {
-          throw new InternalCompilerException(
-              "Could not find enum values() method");
-        }
-        if (valueOfMethod == null) {
-          throw new InternalCompilerException(
-              "Could not find enum valueOf() method");
-        }
-        call.addArg(new JsniMethodRef(info, null, valuesMethod,
-            program.getJavaScriptObject()));
-        call.addArg(new JsniMethodRef(info, null, valueOfMethod,
-            program.getJavaScriptObject()));
-      } else if (isEnumOrSubclass) {
-        // A subclass of an enum class
-        call.addArg(program.getLiteralNull());
-        call.addArg(program.getLiteralNull());
-      }
-    } else if (type instanceof JArrayType) {
-      JArrayType arrayType = (JArrayType) type;
- JClassLiteral componentLiteral = program.getLiteralClass(arrayType.getElementType());
-      call.addArg(componentLiteral);
-    } else {
- assert (type instanceof JInterfaceType || type instanceof JPrimitiveType);
-    }
- assert call.getArgs().size() == method.getParams().size() : "Argument / param mismatch "
-        + call.toString() + " versus " + method.toString();
-    return call;
+
+  private static SourceInfo addCorrelation(SourceInfo info) {
+    info.addCorrelation(info.getCorrelator().by(Literal.CLASS));
+    return info;
   }

-  private static String getClassName(String fullName) {
-    int pos = fullName.lastIndexOf(".");
-    return fullName.substring(pos + 1);
-  }
-
-  private static String getPackageName(String fullName) {
-    int pos = fullName.lastIndexOf(".");
-    return fullName.substring(0, pos + 1);
-  }
-
-  private static String getTypeName(JProgram program, JType type) {
-    String typeName;
-    if (type instanceof JArrayType) {
-      typeName = type.getJsniSignatureName().replace('/', '.');
-      // Mangle the class name to match hosted mode.
-      if (program.isJavaScriptObject(((JArrayType) type).getLeafType())) {
-        typeName = typeName.replace(";", "$;");
-      }
-    } else {
-      typeName = type.getName();
-      // Mangle the class name to match hosted mode.
-      if (program.isJavaScriptObject(type)) {
-        typeName += '$';
-      }
-    }
-    return typeName;
-  }
-
-  private final JField field;
+  private JField field;
+
   private final JType refType;

-  public JClassLiteral(SourceInfo sourceInfo, JType type, JField field) {
-    super(sourceInfo);
+  public JClassLiteral(SourceInfo sourceInfo, JType type) {
+    super(addCorrelation(sourceInfo));
     refType = type;
-    this.field = field;
   }

   public JNode annotationNode() {
@@ -193,6 +59,14 @@
   public JType getType() {
     return field.getType();
   }
+
+  /**
+   * @param field the field to set
+   */
+  public void setField(JField field) {
+    assert field != null;
+    this.field = field;
+  }

   public void traverse(JVisitor visitor, Context ctx) {
     if (visitor.visit(this, ctx)) {
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java Fri Jan 21 12:22:33 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java Thu Mar 3 14:34:14 2011
@@ -25,8 +25,8 @@
  */
 public class JNewArray extends JExpression {

-  public static JNewArray createDims(JProgram program, SourceInfo info,
-      JArrayType arrayType, List<JExpression> dims) {
+  public static JNewArray createDims(SourceInfo info, JArrayType arrayType,
+      List<JExpression> dims) {
     List<JClassLiteral> classLiterals = new ArrayList<JClassLiteral>();

     // Produce all class literals that will eventually get generated.
@@ -41,7 +41,7 @@
     JType cur = arrayType;
     for (int i = 0; i < realDims; ++i) {
       // Walk down each type from most dims to least.
-      JClassLiteral classLit = program.getLiteralClass(cur);
+      JClassLiteral classLit = new JClassLiteral(info.makeChild(), cur);
       classLiterals.add(classLit);
       cur = ((JArrayType) cur).getElementType();
     }
@@ -49,10 +49,10 @@
         classLiterals);
   }

- public static JNewArray createInitializers(JProgram program, SourceInfo info,
+  public static JNewArray createInitializers(SourceInfo info,
       JArrayType arrayType, List<JExpression> initializers) {
     List<JClassLiteral> classLiterals = new ArrayList<JClassLiteral>();
-    classLiterals.add(program.getLiteralClass(arrayType));
+    classLiterals.add(new JClassLiteral(info.makeChild(), arrayType));
     return new JNewArray(info, arrayType.getNonNull(), null, initializers,
         classLiterals);
   }
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java Wed Feb 16 14:26:49 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/JProgram.java Thu Mar 3 14:34:14 2011
@@ -311,7 +311,7 @@
    */
public final List<List<JMethod>> entryMethods = new ArrayList<List<JMethod>>();

- public final Map<String, HasEnclosingType> jsniMap = new HashMap<String, HasEnclosingType>();
+  public final Map<String, JNode> jsniMap = new HashMap<String, JNode>();

   public final JTypeOracle typeOracle = new JTypeOracle(this);

@@ -322,8 +322,6 @@

private final HashMap<JType, JArrayType> arrayTypes = new HashMap<JType, JArrayType>();

- private final Map<JType, JClassLiteral> classLiterals = new IdentityHashMap<JType, JClassLiteral>();
-
   /**
    * A factory to create correlations.
    */
@@ -343,11 +341,6 @@

   private JMethod nullMethod;

-  /**
-   * Turned on once optimizations begin.
-   */
-  private boolean optimizationsStarted = false;
-
   private Map<JReferenceType, Integer> queryIds;

   /**
@@ -410,15 +403,6 @@
       methods.add(entryPoint);
     }
   }
-
-  /**
-   * Record the start of optimizations, which disables certain problematic
- * constructions. In particular, new class literals cannot be created once
-   * optimization starts.
-   */
-  public void beginOptimizations() {
-    optimizationsStarted = true;
-  }

   public JClassType createClass(SourceInfo info, String name,
       boolean isAbstract, boolean isFinal) {
@@ -859,61 +843,6 @@
   public JCharLiteral getLiteralChar(char value) {
     return JCharLiteral.get(value);
   }
-
-  /**
- * May not be called once optimizations begin; all possible class literals
-   * must be created up front.
-   */
-  public JClassLiteral getLiteralClass(JType type) {
-    JClassLiteral classLiteral = classLiterals.get(type);
-    if (classLiteral == null) {
-      if (optimizationsStarted) {
-        throw new InternalCompilerException(
- "New class literals cannot be created once optimizations have started; type '"
-                + type + "'");
-      }
-
-      SourceInfo info = typeSpecialClassLiteralHolder.getSourceInfo();
-
- // Create the allocation expression FIRST since this may be recursive on - // super type (this forces the super type classLit to be created first).
-      boolean isObjectExternal = getTypeJavaLangObject().isExternal();
-      JExpression alloc = isObjectExternal ? null :
-          JClassLiteral.computeClassObjectAllocation(this,info, type);
-
-      // Create a field in the class literal holder to hold the object.
-      JField field = new JField(info, getClassLiteralName(type),
-          typeSpecialClassLiteralHolder, getTypeJavaLangClass(),
-          true, Disposition.FINAL);
-      typeSpecialClassLiteralHolder.addField(field);
-
-      // Initialize the field.
-      if (alloc != null) {
-        JFieldRef fieldRef = new JFieldRef(info, null, field,
-            typeSpecialClassLiteralHolder);
- JDeclarationStatement decl = new JDeclarationStatement(info, fieldRef,
-            alloc);
-        JMethodBody clinitBody = (JMethodBody)
-            typeSpecialClassLiteralHolder.getMethods().get(0).getBody();
-        clinitBody.getBlock().addStmt(decl);
-      }
-
-      SourceInfo literalInfo = createSourceInfoSynthetic(JProgram.class);
-      literalInfo.addCorrelation(correlator.by(Literal.CLASS));
-      classLiteral = new JClassLiteral(literalInfo, type, field);
-      classLiterals.put(type, classLiteral);
-    } else {
-      // Make sure the field hasn't been pruned.
-      JField field = classLiteral.getField();
-      if (optimizationsStarted
-          && !field.getEnclosingType().getFields().contains(field)) {
-        throw new InternalCompilerException(
- "Getting a class literal whose field holder has already been pruned; type '"
-                + type + " '");
-      }
-    }
-    return classLiteral;
-  }

   public JDoubleLiteral getLiteralDouble(double d) {
     return JDoubleLiteral.get(d);
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/js/JsniMethodBody.java Wed Feb 2 13:13:58 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/ast/js/JsniMethodBody.java Thu Mar 3 14:34:14 2011
@@ -18,6 +18,7 @@
 import com.google.gwt.dev.jjs.SourceInfo;
 import com.google.gwt.dev.jjs.ast.Context;
 import com.google.gwt.dev.jjs.ast.JAbstractMethodBody;
+import com.google.gwt.dev.jjs.ast.JClassLiteral;
 import com.google.gwt.dev.jjs.ast.JVisitor;
 import com.google.gwt.dev.js.ast.JsContext;
 import com.google.gwt.dev.js.ast.JsFunction;
@@ -36,6 +37,7 @@
  */
 public class JsniMethodBody extends JAbstractMethodBody {

+  private List<JClassLiteral> classRefs = Collections.emptyList();
   private JsFunction jsFunction = null;
   private List<JsniFieldRef> jsniFieldRefs = Collections.emptyList();
   private List<JsniMethodRef> jsniMethodRefs = Collections.emptyList();
@@ -45,6 +47,13 @@
   public JsniMethodBody(SourceInfo info) {
     super(info);
   }
+
+  /**
+   * Adds a reference from this method to a Java class literal.
+   */
+  public void addClassRef(JClassLiteral ref) {
+    classRefs = Lists.add(classRefs, ref);
+  }

   /**
    * Adds a reference from this method to a Java field.
@@ -59,6 +68,13 @@
   public void addJsniRef(JsniMethodRef ref) {
     jsniMethodRefs = Lists.add(jsniMethodRefs, ref);
   }
+
+  /**
+   * Return this method's references to Java class literals.
+   */
+  public List<JClassLiteral> getClassRefs() {
+    return classRefs;
+  }

   public JsFunction getFunc() {
     assert (this.jsFunction != null);
@@ -104,6 +120,7 @@

   public void traverse(JVisitor visitor, Context ctx) {
     if (visitor.visit(this, ctx)) {
+      classRefs = visitor.acceptImmutable(classRefs);
       jsniFieldRefs = visitor.acceptImmutable(jsniFieldRefs);
       jsniMethodRefs = visitor.acceptImmutable(jsniMethodRefs);
     }
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/CodeSplitter.java Wed Feb 9 13:07:01 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/CodeSplitter.java Thu Mar 3 14:34:14 2011
@@ -21,14 +21,12 @@
 import com.google.gwt.dev.cfg.Properties;
 import com.google.gwt.dev.cfg.Property;
 import com.google.gwt.dev.jjs.InternalCompilerException;
-import com.google.gwt.dev.jjs.SourceInfo;
 import com.google.gwt.dev.jjs.ast.Context;
-import com.google.gwt.dev.jjs.ast.HasEnclosingType;
-import com.google.gwt.dev.jjs.ast.JArrayType;
 import com.google.gwt.dev.jjs.ast.JClassLiteral;
 import com.google.gwt.dev.jjs.ast.JDeclaredType;
 import com.google.gwt.dev.jjs.ast.JExpression;
 import com.google.gwt.dev.jjs.ast.JField;
+import com.google.gwt.dev.jjs.ast.JIntLiteral;
 import com.google.gwt.dev.jjs.ast.JMethod;
 import com.google.gwt.dev.jjs.ast.JMethodCall;
 import com.google.gwt.dev.jjs.ast.JNewArray;
@@ -282,8 +280,8 @@
         throw new UnableToCompleteException();
       }
       final String lookupErrorHolder[] = new String[1];
-      HasEnclosingType referent = JsniRefLookup.findJsniRefTarget(jsniRef,
-          program, new JsniRefLookup.ErrorReporter() {
+      JNode referent = JsniRefLookup.findJsniRefTarget(jsniRef, program,
+          new JsniRefLookup.ErrorReporter() {
             public void reportError(String error) {
               lookupErrorHolder[0] = error;
             }
@@ -512,21 +510,15 @@
    */
   private static void installInitialLoadSequenceField(JProgram program,
       LinkedHashSet<Integer> initialLoadSequence) {
+     // Arg 1 is initialized in the source as  "new int[]{}".
JMethodCall constructorCall = ReplaceRunAsyncs.getBrowserLoaderConstructor(program); - assert ((JReferenceType) constructorCall.getArgs().get(1).getType()).getUnderlyingType() instanceof JArrayType; - assert ((JArrayType) ((JReferenceType) constructorCall.getArgs().get(1).getType()).getUnderlyingType()).getElementType() == JPrimitiveType.INT;
-
- SourceInfo info = program.createSourceInfoSynthetic(ReplaceRunAsyncs.class);
-    List<JExpression> intExprs = new ArrayList<JExpression>();
+    JNewArray newArray = (JNewArray) constructorCall.getArgs().get(1);
+    assert newArray.getArrayType().getElementType() == JPrimitiveType.INT;
+    assert newArray.initializers.size() == 0;
+
     for (int sp : initialLoadSequence) {
-      intExprs.add(program.getLiteralInt(sp));
-    }
-    /*
-     * Note: the following field is known to have a manually installed
-     * initializer, of new int[0].
-     */
-    constructorCall.setArg(1, JNewArray.createInitializers(program, info,
-        program.getTypeArray(JPrimitiveType.INT), intExprs));
+      newArray.initializers.add(JIntLiteral.get(sp));
+    }
   }

   private static <T> T last(T[] array) {
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java Wed Mar 2 12:43:16 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ControlFlowAnalyzer.java Thu Mar 3 14:34:14 2011
@@ -192,6 +192,7 @@
     @Override
     public boolean visit(JClassLiteral x, Context ctx) {
       JField field = x.getField();
+      assert field != null;
       rescue(field);
       return true;
     }
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java Wed Feb 16 14:26:49 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java Thu Mar 3 14:34:14 2011
@@ -23,7 +23,6 @@
 import com.google.gwt.dev.jjs.SourceOrigin;
 import com.google.gwt.dev.jjs.ast.Context;
 import com.google.gwt.dev.jjs.ast.HasAnnotations;
-import com.google.gwt.dev.jjs.ast.HasEnclosingType;
 import com.google.gwt.dev.jjs.ast.JAnnotation;
 import com.google.gwt.dev.jjs.ast.JAnnotation.Property;
 import com.google.gwt.dev.jjs.ast.JAnnotationArgument;
@@ -39,6 +38,7 @@
 import com.google.gwt.dev.jjs.ast.JCaseStatement;
 import com.google.gwt.dev.jjs.ast.JCastOperation;
 import com.google.gwt.dev.jjs.ast.JCharLiteral;
+import com.google.gwt.dev.jjs.ast.JClassLiteral;
 import com.google.gwt.dev.jjs.ast.JClassType;
 import com.google.gwt.dev.jjs.ast.JConditional;
 import com.google.gwt.dev.jjs.ast.JConstructor;
@@ -524,17 +524,18 @@
             currentClass.getMethods().remove(2);
           } else {
             tryFindUpRefs(method);
+            SourceInfo info = method.getSourceInfo();
             if (isScript(program)
                 && currentClass == program.getIndexedType("Array")) {
               // Special implementation: return this.arrayClass
-              SourceInfo info = method.getSourceInfo();
               implementMethod(
                   method,
                   new JFieldRef(info, new JThisRef(info,
                       (JClassType) currentClass),
program.getIndexedField("Array.arrayClass"), currentClass));
             } else {
- implementMethod(method, program.getLiteralClass(currentClass));
+              implementMethod(method, new JClassLiteral(info.makeChild(),
+                  currentClass));
             }
           }
         }
@@ -919,7 +920,7 @@
             initializers.add(dispProcessExpression(expression));
           }
         }
- return JNewArray.createInitializers(program, info, type, initializers);
+        return JNewArray.createInitializers(info, type, initializers);
       } else {
         List<JExpression> dims = new ArrayList<JExpression>();
         for (Expression dimension : x.dimensions) {
@@ -930,7 +931,7 @@
             dims.add(dispProcessExpression(dimension));
           }
         }
-        return JNewArray.createDims(program, info, type, dims);
+        return JNewArray.createDims(info, type, dims);
       }
     }

@@ -944,7 +945,7 @@
           initializers.add(dispProcessExpression(expression));
         }
       }
- return JNewArray.createInitializers(program, info, type, initializers);
+      return JNewArray.createInitializers(info, type, initializers);
     }

     JExpression processExpression(ArrayReference x) {
@@ -1034,8 +1035,9 @@
     }

     JExpression processExpression(ClassLiteralAccess x) {
+      SourceInfo info = makeSourceInfo(x);
       JType type = (JType) typeMap.get(x.targetType);
-      return program.getLiteralClass(type);
+      return new JClassLiteral(info, type);
     }

     JExpression processExpression(CombinedBinaryExpression x) {
@@ -1699,7 +1701,7 @@
       } else {
         /**
          * <pre>
- * for (Iterator<T> i$iterator = collection.iterator(); i$iterator.hasNext(); ) { + * for (Iterator<T> i$iterator = collection.iterator(); i$iterator.hasNext();) {
          *   T elementVar = i$iterator.next();
          *   // user action
          * }
@@ -2086,8 +2088,8 @@
         initializers.add(args[i]);
       }
       JArrayType lastParamType = (JArrayType) typeMap.get(params[varArg]);
-      JNewArray newArray = JNewArray.createInitializers(program,
-          SourceOrigin.UNKNOWN, lastParamType, initializers);
+ JNewArray newArray = JNewArray.createInitializers(SourceOrigin.UNKNOWN,
+          lastParamType, initializers);
       call.addArg(newArray);
     }

@@ -2571,7 +2573,8 @@
           type = getOrCreateExternalType(info,
               ((ReferenceBinding) value).compoundName);
         }
- return Lists.<JAnnotationArgument> create(program.getLiteralClass(type));
+        return Lists.<JAnnotationArgument> create(new JClassLiteral(
+            info.makeChild(), type));

       } else if (value instanceof Constant) {
return Lists.create((JAnnotationArgument) dispatch("processConstant",
@@ -2910,7 +2913,7 @@
           JFieldRef fieldRef = new JFieldRef(fieldInfo, null, field, type);
           initializers.add(fieldRef);
         }
- JNewArray newExpr = JNewArray.createInitializers(program, fieldInfo,
+        JNewArray newExpr = JNewArray.createInitializers(fieldInfo,
             enumArrayType, initializers);
JFieldRef valuesRef = new JFieldRef(fieldInfo, null, valuesField, type); JDeclarationStatement declStmt = new JDeclarationStatement(fieldInfo,
@@ -2962,8 +2965,7 @@
         }
       }

-      private HasEnclosingType findJsniRefTarget(final SourceInfo info,
-          String ident) {
+ private JNode findJsniRefTarget(final SourceInfo info, String ident) {
         JsniRef parsed = JsniRef.parse(ident);
         if (parsed == null) {
           JsniCollector.reportJsniError(info, methodDecl,
@@ -2980,6 +2982,11 @@
               }
             });
       }
+
+ private void processClassLiteral(JClassLiteral classLiteral, JsContext ctx) {
+        assert !ctx.isLvalue();
+        nativeMethodBody.addClassRef(classLiteral);
+      }

       private void processField(JsNameRef nameRef, SourceInfo info,
           JField field, JsContext ctx) {
@@ -3020,12 +3027,15 @@
         // TODO: make this tighter when we have real source info
         // JSourceInfo info = translateInfo(nameRef.getInfo());
         String ident = nameRef.getIdent();
-        HasEnclosingType node = program.jsniMap.get(ident);
+        JNode node = program.jsniMap.get(ident);
         if (node == null) {
           node = findJsniRefTarget(info, ident);
           if (node == null) {
             return; // already reported error
           }
+          if (node instanceof JType) {
+            node = new JClassLiteral(info.makeChild(), (JType) node);
+          }
           program.jsniMap.put(ident, node);
         }

@@ -3033,9 +3043,11 @@
           processField(nameRef, info, (JField) node, ctx);
         } else if (node instanceof JMethod) {
           processMethod(nameRef, info, (JMethod) node, ctx);
+        } else if (node instanceof JClassLiteral) {
+          processClassLiteral((JClassLiteral) node, ctx);
         } else {
-          throw new InternalCompilerException((HasSourceInfo) node,
- "JSNI reference to something other than a field or method?", null);
+          throw new InternalCompilerException(node,
+ "JSNI reference to something other than a class, field, or method?", null);
         }
       }
     }
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java Wed Feb 9 13:07:01 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java Thu Mar 3 14:34:14 2011
@@ -1340,7 +1340,7 @@
             JsNameRef ref = (JsNameRef) x.getQualifier();
             String ident = ref.getIdent();
             if (isJsniIdent(ident)) {
-              HasEnclosingType node = program.jsniMap.get(ident);
+              JNode node = program.jsniMap.get(ident);
               assert node instanceof JConstructor;
               assert ref.getQualifier() == null;
               JsName jsName = names.get(node);
@@ -1357,8 +1357,12 @@
         public void endVisit(JsNameRef x, JsContext ctx) {
           String ident = x.getIdent();
           if (isJsniIdent(ident)) {
-            HasEnclosingType node = program.jsniMap.get(ident);
+            JNode node = program.jsniMap.get(ident);
             assert (node != null);
+            if (node instanceof JClassLiteral) {
+              node = ((JClassLiteral) node).getField();
+              assert node != null;
+            }
             if (node instanceof JField) {
               JField field = (JField) node;
               JsName jsName = names.get(field);
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java Wed Feb 9 11:52:03 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java Thu Mar 3 14:34:14 2011
@@ -69,7 +69,7 @@
     public void endVisit(JClassLiteral x, Context ctx) {
       JType newType = translate(x.getRefType());
       if (newType != x.getRefType()) {
-        ctx.replaceMe(program.getLiteralClass(newType));
+        ctx.replaceMe(new JClassLiteral(x.getSourceInfo(), newType));
       }
     }

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java Thu Jul 8 08:08:57 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/JsniRefLookup.java Thu Mar 3 14:34:14 2011
@@ -15,14 +15,13 @@
  */
 package com.google.gwt.dev.jjs.impl;

-import com.google.gwt.dev.jjs.ast.HasEnclosingType;
 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.JConstructor;
 import com.google.gwt.dev.jjs.ast.JDeclaredType;
 import com.google.gwt.dev.jjs.ast.JField;
 import com.google.gwt.dev.jjs.ast.JMethod;
+import com.google.gwt.dev.jjs.ast.JNode;
 import com.google.gwt.dev.jjs.ast.JParameter;
 import com.google.gwt.dev.jjs.ast.JPrimitiveType;
 import com.google.gwt.dev.jjs.ast.JProgram;
@@ -56,8 +55,8 @@
    *         found. If the return value is <code>null</code>,
    *         <code>errorReporter</code> will have been invoked.
    */
-  public static HasEnclosingType findJsniRefTarget(JsniRef ref,
-      JProgram program, JsniRefLookup.ErrorReporter errorReporter) {
+  public static JNode findJsniRefTarget(JsniRef ref, JProgram program,
+      JsniRefLookup.ErrorReporter errorReporter) {
     String className = ref.className();
     JType type = null;
     if (!className.equals("null")) {
@@ -78,8 +77,7 @@
         }

       } else if (fieldName.equals(JsniRef.CLASS)) {
-        JClassLiteral lit = program.getLiteralClass(type);
-        return lit.getField();
+        return type;

       } else if (type instanceof JPrimitiveType) {
errorReporter.reportError("May not refer to fields on primitive types");
=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java Fri Aug 6 12:01:02 2010 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/ReplaceRebinds.java Thu Mar 3 14:34:14 2011
@@ -20,7 +20,6 @@
 import com.google.gwt.dev.jdt.RebindPermutationOracle;
 import com.google.gwt.dev.jjs.InternalCompilerException;
 import com.google.gwt.dev.jjs.ast.Context;
-import com.google.gwt.dev.jjs.ast.HasEnclosingType;
 import com.google.gwt.dev.jjs.ast.HasName;
 import com.google.gwt.dev.jjs.ast.JClassLiteral;
 import com.google.gwt.dev.jjs.ast.JClassType;
@@ -31,6 +30,7 @@
 import com.google.gwt.dev.jjs.ast.JMethodCall;
 import com.google.gwt.dev.jjs.ast.JModVisitor;
 import com.google.gwt.dev.jjs.ast.JNameOf;
+import com.google.gwt.dev.jjs.ast.JNode;
 import com.google.gwt.dev.jjs.ast.JNullLiteral;
 import com.google.gwt.dev.jjs.ast.JProgram;
 import com.google.gwt.dev.jjs.ast.JReferenceType;
@@ -106,7 +106,7 @@

       if (ref != null) {
         final List<String> errors = new ArrayList<String>();
- HasEnclosingType node = JsniRefLookup.findJsniRefTarget(ref, program,
+        JNode node = JsniRefLookup.findJsniRefTarget(ref, program,
             new JsniRefLookup.ErrorReporter() {
               public void reportError(String error) {
                 errors.add(error);
=======================================
--- /trunk/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java Wed Feb 9 11:52:03 2011 +++ /trunk/dev/core/test/com/google/gwt/dev/jjs/JavaAstConstructor.java Thu Mar 3 14:34:14 2011
@@ -29,6 +29,7 @@
 import com.google.gwt.dev.jjs.ast.JProgram;
 import com.google.gwt.dev.jjs.impl.AssertionNormalizer;
 import com.google.gwt.dev.jjs.impl.BuildTypeMap;
+import com.google.gwt.dev.jjs.impl.ImplementClassLiteralsAsFields;
 import com.google.gwt.dev.jjs.impl.TypeLinker;
 import com.google.gwt.dev.jjs.impl.FixAssignmentToUnbox;
 import com.google.gwt.dev.jjs.impl.GenerateJavaAST;
@@ -275,6 +276,8 @@
     // Replace references to JSO subtypes with JSO itself.
     JavaScriptObjectNormalizer.exec(jprogram);

+    ImplementClassLiteralsAsFields.exec(jprogram);
+
     // Tree is now ready to optimize.
     return jprogram;
   }
=======================================
--- /trunk/dev/core/test/com/google/gwt/dev/jjs/impl/JsniRefLookupTest.java Thu Jul 8 08:08:57 2010 +++ /trunk/dev/core/test/com/google/gwt/dev/jjs/impl/JsniRefLookupTest.java Thu Mar 3 14:34:14 2011
@@ -17,9 +17,9 @@

 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.dev.javac.impl.MockJavaResource;
-import com.google.gwt.dev.jjs.ast.HasEnclosingType;
 import com.google.gwt.dev.jjs.ast.JField;
 import com.google.gwt.dev.jjs.ast.JMethod;
+import com.google.gwt.dev.jjs.ast.JNode;
 import com.google.gwt.dev.jjs.ast.JPrimitiveType;
 import com.google.gwt.dev.jjs.ast.JProgram;
 import com.google.gwt.dev.jjs.impl.JsniRefLookup.ErrorReporter;
@@ -238,17 +238,17 @@

     {
       MockErrorReporter errors = new MockErrorReporter();
-      HasEnclosingType res = lookup("test.Foo::bogoField", errors);
+      lookup("test.Foo::bogoField", errors);
       errors.assertHasError();
     }
     {
       MockErrorReporter errors = new MockErrorReporter();
-      HasEnclosingType res = lookup("test.Foo::bogoMethod()", errors);
+      lookup("test.Foo::bogoMethod()", errors);
       errors.assertHasError();
     }
     {
       MockErrorReporter errors = new MockErrorReporter();
-      HasEnclosingType res = lookup("test.Foo::new(J)", errors);
+      lookup("test.Foo::new(J)", errors);
       errors.assertHasError();
     }
   }
@@ -367,7 +367,7 @@
     }
     {
       MockErrorReporter errors = new MockErrorReporter();
- HasEnclosingType res = lookup("test.Bar::addTwoOverloaded(*)", errors);
+      lookup("test.Bar::addTwoOverloaded(*)", errors);
       errors.assertHasError();
     }

@@ -398,7 +398,7 @@
     }
     {
       MockErrorReporter errors = new MockErrorReporter();
-      HasEnclosingType res = lookup("test.Bar::foo(*)", errors);
+      lookup("test.Bar::foo(*)", errors);
       errors.assertHasError();
     }

@@ -463,7 +463,7 @@
     }
     {
       MockErrorReporter errors = new MockErrorReporter();
-      JMethod res = (JMethod) lookup("test.Intf::foo(*)", errors);
+      lookup("test.Intf::foo(*)", errors);
       errors.assertHasError();
     }
   }
@@ -488,12 +488,12 @@
     // test private entries in the superclass
     {
       MockErrorReporter errors = new MockErrorReporter();
- JMethod res = (JMethod) lookup("test.PrivateSub::methodSup()", errors);
+      lookup("test.PrivateSub::methodSup()", errors);
       errors.assertHasError();
     }
     {
       MockErrorReporter errors = new MockErrorReporter();
-      JField res = (JField) lookup("test.PrivateSub::fieldSup", errors);
+      lookup("test.PrivateSub::fieldSup", errors);
       errors.assertHasError();
     }
   }
@@ -508,17 +508,17 @@
     }
     {
       MockErrorReporter errors = new MockErrorReporter();
- HasEnclosingType res = lookup("test.Foo::addTwoOverloaded(*)", errors);
+      lookup("test.Foo::addTwoOverloaded(*)", errors);
       errors.assertHasError();
     }
     {
       MockErrorReporter errors = new MockErrorReporter();
-      HasEnclosingType res = lookup("test.Foo::bogoMethod(*)", errors);
+      lookup("test.Foo::bogoMethod(*)", errors);
       errors.assertHasError();
     }
   }

- private HasEnclosingType lookup(String refString, MockErrorReporter errors) {
+  private JNode lookup(String refString, MockErrorReporter errors) {
return JsniRefLookup.findJsniRefTarget(JsniRef.parse(refString), program,
         errors);
   }

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to