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.
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9659 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
index 82dd29a..42bc89c 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
@@ -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);
}
}
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 38a03fd..1557dc4 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
@@ -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;
}
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 e38a869..072974a 100644
--- a/user/test/com/google/gwt/dev/jjs/test/InnerClassTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/InnerClassTest.java
@@ -25,6 +25,12 @@
*/
public class InnerClassTest extends GWTTestCase {
+ static class OuterRefFromSuperCtorBase {
+ OuterRefFromSuperCtorBase(Object o) {
+ o.toString();
+ }
+ }
+
class InnerClass {
{
callInner();
@@ -45,12 +51,6 @@
}
}
- class OuterRefFromSuperCtorBase {
- OuterRefFromSuperCtorBase(Object o) {
- o.toString();
- }
- }
-
class OuterRefFromSuperCtorCall extends OuterRefFromSuperCtorBase {
OuterRefFromSuperCtorCall() {
super(new Object() {
@@ -63,6 +63,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> {
class P3<T3> extends P2<T2> {
@@ -150,4 +166,8 @@
assertEquals("OuterRefFromSuperCtorCall", testAppend.toString());
}
+ public void testOuterThisFromThisCall() {
+ new OuterRefFromThisCtorCall();
+ assertEquals("OuterRefFromThisCtorCall", testAppend.toString());
+ }
}