Fixes issue #2158.  We had missed a few erasure cases while processing calls to constructors in parameterized types, causing internal compiler errors.

Found by: jat
Review by: spoon (TBR)


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2288 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
index cd0b507..c34a807 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
@@ -607,7 +607,7 @@
         if (!hasExplicitThis) {
           ReferenceBinding declaringClass = x.binding.declaringClass;
           if (declaringClass instanceof NestedTypeBinding) {
-            Iterator<JParameter> paramIt = getSyntheticsIterator(ctor);
+            Iterator<JParameter> paramIt = getSyntheticsIterator();
             NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
             if (nestedBinding.enclosingInstances != null) {
               for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) {
@@ -1166,7 +1166,7 @@
       // Synthetic args for inner classes
       ReferenceBinding targetBinding = b.declaringClass;
       if (targetBinding.isNestedType() && !targetBinding.isStatic()) {
-        NestedTypeBinding nestedBinding = (NestedTypeBinding) targetBinding;
+        NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(targetBinding);
         // Synthetic this args for inner classes
         if (nestedBinding.enclosingInstances != null) {
           for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) {
@@ -1789,7 +1789,7 @@
                * check each one to see if any will make a suitable this ref.
                */
               List<JExpression> workList = new ArrayList<JExpression>();
-              Iterator<JParameter> paramIt = getSyntheticsIterator(currentMethod);
+              Iterator<JParameter> paramIt = getSyntheticsIterator();
               for (ReferenceBinding b : myBinding.syntheticEnclosingInstanceTypes()) {
                 workList.add(createVariableRef(info, paramIt.next()));
               }
@@ -1838,9 +1838,9 @@
 
       // All synthetics must be passed through to the target ctor
       ReferenceBinding declaringClass = x.binding.declaringClass;
-      if (declaringClass instanceof NestedTypeBinding) {
-        Iterator<JParameter> paramIt = getSyntheticsIterator(currentMethod);
-        NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
+      if (declaringClass.isNestedType() && !declaringClass.isStatic()) {
+        Iterator<JParameter> paramIt = getSyntheticsIterator();
+        NestedTypeBinding nestedBinding = (NestedTypeBinding) erasure(declaringClass);
         if (nestedBinding.enclosingInstances != null) {
           for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) {
             call.getArgs().add(createVariableRef(info, paramIt.next()));
@@ -2183,6 +2183,18 @@
       }
     }
 
+    /**
+     * Gets a JParameter iterator for a constructor method over its synthetic
+     * parameters.
+     */
+    private Iterator<JParameter> getSyntheticsIterator() {
+      Iterator<JParameter> it = currentMethod.params.iterator();
+      for (int i = 0, c = currentMethod.getOriginalParamTypes().size(); i < c; ++i) {
+        it.next();
+      }
+      return it;
+    }
+
     private void implementMethod(JMethod method, JExpression returnValue) {
       assert method != null;
       JMethodBody body = (JMethodBody) method.getBody();
@@ -2739,18 +2751,6 @@
   }
 
   /**
-   * Gets a JParameter iterator for a constructor method over its synthetic
-   * parameters.
-   */
-  private static Iterator<JParameter> getSyntheticsIterator(JMethod method) {
-    Iterator<JParameter> it = method.params.iterator();
-    for (int i = 0, c = method.getOriginalParamTypes().size(); i < c; ++i) {
-      it.next();
-    }
-    return it;
-  }
-
-  /**
    * Returns <code>true</code> if JDT optimized the condition to
    * <code>false</code>.
    */
diff --git a/user/test/com/google/gwt/dev/jjs/test/InnerClassTest.java b/user/test/com/google/gwt/dev/jjs/test/InnerClassTest.java
index 753c6f2..918b2c2 100644
--- a/user/test/com/google/gwt/dev/jjs/test/InnerClassTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/InnerClassTest.java
@@ -18,7 +18,6 @@
 import com.google.gwt.junit.client.GWTTestCase;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 /**
@@ -26,49 +25,93 @@
  */
 public class InnerClassTest extends GWTTestCase {
 
-  /**
-   * TODO: document me.
-   */
-  public class InnerClass {
+  class InnerClass {
+    {
+      callInner();
+    }
+
     void callInner() {
       testAppend.append("a");
       class ReallyInnerClass {
-        void callReallyInner() {
-          testAppend.append("b");
-        }
-
         {
           callReallyInner();
         }
+
+        void callReallyInner() {
+          testAppend.append("b");
+        }
       }
       new ReallyInnerClass();
     }
+  }
 
-    {
-      callInner();
+  static class P1<T1> {
+    class P2<T2> extends P1<T1> {
+      class P3<T3> extends P2<T2> {
+        P3() {
+          this(1);
+        }
+
+        P3(int i) {
+          P2.this.super(i);
+        }
+      }
+
+      P2() {
+        this(1);
+      }
+
+      P2(int i) {
+        super(i);
+      }
+    }
+
+    final int value;
+
+    P1() {
+      this(1);
+    }
+
+    P1(int i) {
+      value = i;
     }
   }
 
+  private StringBuffer testAppend;
+
   public String getModuleName() {
     return "com.google.gwt.dev.jjs.CompilerSuite";
   }
 
+  public void testInnerClassCtors() {
+    P1<?> p1 = new P1<Object>();
+    assertEquals(1, p1.value);
+    assertEquals(2, new P1<Object>(2).value);
+    P1<?>.P2<?> p2 = p1.new P2<Object>();
+    assertEquals(1, p2.value);
+    assertEquals(2, p1.new P2<Object>(2).value);
+    assertEquals(1, p2.new P3<Object>().value);
+    assertEquals(2, p2.new P3<Object>(2).value);
+  }
+
   public void testInnerClassInitialization() {
+    testAppend = new StringBuffer();
+    new InnerClass();
     assertEquals("ab", testAppend.toString());
   }
 
   public void testInnerClassLoop() {
     final StringBuffer b = new StringBuffer();
-    List results = new ArrayList();
     abstract class AppendToStringBuffer {
+      int num;
+
       public AppendToStringBuffer(int i) {
         this.num = i;
       }
 
       public abstract void act();
-
-      int num;
     }
+    List<AppendToStringBuffer> results = new ArrayList<AppendToStringBuffer>();
     for (int i = 0; i < 10; i++) {
       AppendToStringBuffer ap = new AppendToStringBuffer(i) {
         public void act() {
@@ -77,18 +120,10 @@
       };
       results.add(ap);
     }
-    for (Iterator it = results.iterator(); it.hasNext();) {
-      AppendToStringBuffer theAp = (AppendToStringBuffer) it.next();
+    for (AppendToStringBuffer theAp : results) {
       theAp.act();
     }
     assertEquals("0123456789", b.toString());
   }
 
-  protected void setUp() throws Exception {
-    testAppend = new StringBuffer();
-    new InnerClass();
-  }
-
-  private StringBuffer testAppend;
-
 }