Better cloning support for JGwtCreate expressions; does not try to create new instantiation expressions late in the game.

Review by: spoon (postmortem)

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@3361 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JGwtCreate.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JGwtCreate.java
index 9a44731..7587c19 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JGwtCreate.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JGwtCreate.java
@@ -50,26 +50,48 @@
     return new JMethodCall(program, info, newInstance, noArgCtor);
   }
 
-  private final ArrayList<JExpression> instantiationExpressions = new ArrayList<JExpression>();
+  private static ArrayList<JExpression> createInstantiationExpressions(
+      JProgram program, SourceInfo info, List<JClassType> classTypes) {
+    ArrayList<JExpression> exprs = new ArrayList<JExpression>();
+    for (JClassType classType : classTypes) {
+      JExpression expr = createInstantiationExpression(program, info, classType);
+      assert expr != null;
+      exprs.add(expr);
+    }
+    return exprs;
+  }
+
+  private final ArrayList<JExpression> instantiationExpressions;
   private final List<JClassType> resultTypes;
+
   private final JReferenceType sourceType;
 
+  /*
+   * Initially object; will be updated by type tightening.
+   */
   private JType type;
 
+  /**
+   * Public constructor used during AST creation.
+   */
   public JGwtCreate(JProgram program, SourceInfo info,
       JReferenceType sourceType, List<JClassType> resultTypes) {
+    this(program, info, sourceType, resultTypes,
+        program.getTypeJavaLangObject(), createInstantiationExpressions(
+            program, info, resultTypes));
+  }
+
+  /**
+   * Constructor used for cloning an existing node.
+   */
+  public JGwtCreate(JProgram program, SourceInfo info,
+      JReferenceType sourceType, List<JClassType> resultTypes, JType type,
+      ArrayList<JExpression> instantiationExpressions) {
     super(program, info);
     this.sourceType = sourceType;
     this.resultTypes = resultTypes;
-
-    // Initially object; will be updated by type tightening.
-    this.type = program.getTypeJavaLangObject();
-
-    for (JClassType classType : resultTypes) {
-      JExpression expr = createInstantiationExpression(program, info, classType);
-      assert expr != null;
-      instantiationExpressions.add(expr);
-    }
+    this.type = type;
+    this.instantiationExpressions = instantiationExpressions;
   }
 
   public ArrayList<JExpression> getInstantiationExpressions() {
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 3ddbf42..eb70ed3 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
@@ -84,11 +84,11 @@
     return originalClass.cast(expression);
   }
 
-  public List<JExpression> cloneExpressions(List<JExpression> exprs) {
+  public ArrayList<JExpression> cloneExpressions(List<JExpression> exprs) {
     if (exprs == null) {
       return null;
     }
-    List<JExpression> result = new ArrayList<JExpression>();
+    ArrayList<JExpression> result = new ArrayList<JExpression>();
     for (JExpression expr : exprs) {
       result.add(cloneExpression(expr));
     }
@@ -174,6 +174,23 @@
   }
 
   @Override
+  public boolean visit(JGwtCreate x, Context ctx) {
+    // Clone the internal instantiation expressions directly.
+    ArrayList<JExpression> clonedExprs = new ArrayList<JExpression>();
+    for (JExpression expr : x.getInstantiationExpressions()) {
+      clonedExprs.add(cloneExpression(expr));
+    }
+
+    // Use the clone constructor.
+    JGwtCreate gwtCreate = new JGwtCreate(program, x.getSourceInfo(),
+        x.getSourceType(), x.getResultTypes(), x.getType(),
+        cloneExpressions(x.getInstantiationExpressions()));
+
+    expression = gwtCreate;
+    return false;
+  }
+
+  @Override
   public boolean visit(JInstanceOf x, Context ctx) {
     expression = new JInstanceOf(program, x.getSourceInfo(), x.getTestType(),
         cloneExpression(x.getExpr()));
@@ -235,21 +252,6 @@
   }
 
   @Override
-  public boolean visit(JGwtCreate x, Context ctx) {
-    JGwtCreate gwtCreate = new JGwtCreate(program, x.getSourceInfo(),
-        x.getSourceType(), x.getResultTypes());
-
-    // Clone the internal instantiation expressions directly.
-    ArrayList<JExpression> exprs = x.getInstantiationExpressions();
-    ArrayList<JExpression> cloneExprs = gwtCreate.getInstantiationExpressions();
-    for (int i = 0; i < exprs.size(); ++i) {
-      cloneExprs.set(i, cloneExpression(exprs.get(i)));
-    }
-    expression = gwtCreate;
-    return false;
-  }
-
-  @Override
   public boolean visit(JNullLiteral x, Context ctx) {
     expression = x;
     return false;