Revision: 9659
Author: [email protected]
Date: Mon Jan 31 11:16:33 2011
Log: Fix latent bug in this() calls needing synthetic ctor args.

When processing a this() constructor invocation, the GWT compiler currently has a bug where it tries to reference a field that hasn't yet been assigned.

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

Modified:
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
 /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java
 /trunk/user/test/com/google/gwt/dev/jjs/test/InnerClassTest.java

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java Sat Jan 22 17:19:44 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java Mon Jan 31 11:16:33 2011
@@ -841,9 +841,7 @@
         if (nestedBinding.enclosingInstances != null) {
for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) { SyntheticArgumentBinding arg = nestedBinding.enclosingInstances[i];
-            if (arg.matchingField != null) {
-              createField(arg, type, Disposition.THIS_REF);
-            }
+            createField(arg, type, Disposition.THIS_REF);
           }
         }

=======================================
--- /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java Fri Jan 28 10:48:44 2011 +++ /trunk/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaAST.java Mon Jan 31 11:16:33 2011
@@ -752,25 +752,25 @@
* this constructor call, in which case the callee will assign them for
          * us.
          */
-        if (!hasExplicitThis) {
-          ReferenceBinding declaringClass = x.binding.declaringClass;
-          if (declaringClass instanceof NestedTypeBinding) {
- Iterator<JParameter> paramIt = currentMethod.getParams().iterator(); - NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
-            if (nestedBinding.enclosingInstances != null) {
- for (SyntheticArgumentBinding arg : nestedBinding.enclosingInstances) {
-                JParameter param = paramIt.next();
-                if (arg.matchingField != null) {
-                  JField field = (JField) typeMap.get(arg);
-                  block.addStmt(JProgram.createAssignmentStmt(info,
-                      createVariableRef(info, field),
-                      createVariableRef(info, param)));
-                  currentOuterThisRefParams = Maps.put(
-                      currentOuterThisRefParams, field, param);
-                }
-              }
-            }
-
+        ReferenceBinding declaringClass = x.binding.declaringClass;
+        if (declaringClass instanceof NestedTypeBinding) {
+ Iterator<JParameter> paramIt = currentMethod.getParams().iterator(); + NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
+          if (nestedBinding.enclosingInstances != null) {
+ for (SyntheticArgumentBinding arg : nestedBinding.enclosingInstances) {
+              JParameter param = paramIt.next();
+              JField field = (JField) typeMap.get(arg);
+              if (!hasExplicitThis) {
+                block.addStmt(JProgram.createAssignmentStmt(info,
+                    createVariableRef(info, field),
+                    createVariableRef(info, param)));
+              }
+ currentOuterThisRefParams = Maps.put(currentOuterThisRefParams,
+                  field, param);
+            }
+          }
+
+          if (!hasExplicitThis) {
             paramIt = getSyntheticLocalsIterator();
             if (nestedBinding.outerLocalVariables != null) {
for (SyntheticArgumentBinding arg : nestedBinding.outerLocalVariables) {
@@ -2550,6 +2550,15 @@

// now we have an updated variable that we can create our ref from
         }
+      } else {
+        assert variable instanceof JField;
+        // In a constructor, prefer the ctor arg rather than the field.
+        if (currentOuterThisRefParams != null) {
+          JParameter ctorArg = currentOuterThisRefParams.get(variable);
+          if (ctorArg != null) {
+            variable = ctorArg;
+          }
+        }
       }
       return variable;
     }
=======================================
--- /trunk/user/test/com/google/gwt/dev/jjs/test/InnerClassTest.java Mon Aug 16 15:00:16 2010 +++ /trunk/user/test/com/google/gwt/dev/jjs/test/InnerClassTest.java Mon Jan 31 11:16:33 2011
@@ -25,6 +25,12 @@
  */
 public class InnerClassTest extends GWTTestCase {

+  static class OuterRefFromSuperCtorBase {
+    OuterRefFromSuperCtorBase(Object o) {
+      o.toString();
+    }
+  }
+
   class InnerClass {
     {
       callInner();
@@ -44,12 +50,6 @@
       new ReallyInnerClass();
     }
   }
-
-  class OuterRefFromSuperCtorBase {
-    OuterRefFromSuperCtorBase(Object o) {
-      o.toString();
-    }
-  }

   class OuterRefFromSuperCtorCall extends OuterRefFromSuperCtorBase {
     OuterRefFromSuperCtorCall() {
@@ -62,6 +62,22 @@
       });
     }
   }
+
+  class OuterRefFromThisCtorCall extends OuterRefFromSuperCtorBase {
+    public OuterRefFromThisCtorCall(Object object) {
+      super(object);
+    }
+
+    public OuterRefFromThisCtorCall() {
+      this(new Object() {
+        @Override
+        public String toString() {
+          testAppend.append("OuterRefFromThisCtorCall");
+          return "";
+        }
+      });
+    }
+  }

   static class P1<T1> {
     class P2<T2> extends P1<T1> {
@@ -150,4 +166,8 @@
     assertEquals("OuterRefFromSuperCtorCall", testAppend.toString());
   }

-}
+  public void testOuterThisFromThisCall() {
+    new OuterRefFromThisCtorCall();
+    assertEquals("OuterRefFromThisCtorCall", testAppend.toString());
+  }
+}

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

Reply via email to