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