Fixes compiler error for class extending an inner class.
Fixes an internal compiler error when a class extends an inner class whose enclosing class is of
generic type.
fixes ISSUE 7789
Change-Id: I0d1c5ababe332efad7b58b98b85a150b83d659f2
Review-Link: https://gwt-review.googlesource.com/#/c/1690/
Review by: mdempsky@google.com
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@11463 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
index 3ecdefb..9423eeb 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
@@ -2373,16 +2373,25 @@
}
}
+ // Only called on nested instances constructors (explicitConstructorCalls) that are of the
+ // form: outer.super(...) or super(...)
+ //
+ // Will set outer (in the first case) or the implicit enclosing object reference to
+ // be the first parameter of super(...)
private void processSuperCallThisArgs(ReferenceBinding superClass, JMethodCall call,
JExpression qualifier, Expression qualification) {
+ // Explicit super calls can only happend inside constructors
+ assert curMethod.scope.isInsideConstructor();
if (superClass.syntheticEnclosingInstanceTypes() != null) {
- for (ReferenceBinding targetType : superClass.syntheticEnclosingInstanceTypes()) {
- if (qualification != null && superClass.enclosingType() == targetType) {
- assert qualification.resolvedType.erasure().isCompatibleWith(targetType);
- call.addArg(qualifier);
- } else {
- call.addArg(makeThisReference(call.getSourceInfo(), targetType, false, curMethod.scope));
- }
+ // there can only be ONE immediate enclosing instance.
+ assert superClass.syntheticEnclosingInstanceTypes().length == 1;
+ ReferenceBinding targetType = superClass.syntheticEnclosingInstanceTypes()[0];
+ if (qualification != null) {
+ // Outer object is the qualifier.
+ call.addArg(qualifier);
+ } else {
+ // Get implicit outer object.
+ call.addArg(makeThisReference(call.getSourceInfo(), targetType, false, curMethod.scope));
}
}
}
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 072974a..9b8e651 100644
--- a/user/test/com/google/gwt/dev/jjs/test/InnerClassTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/InnerClassTest.java
@@ -111,12 +111,90 @@
}
}
+
+ /**
+ * Used in test {@link #testExtendsNested()}
+ */
+ private static class ESOuter {
+ class ESInner {
+ public int value;
+ public ESInner() {
+ value = 1;
+ }
+ public ESInner(int value) {
+ this.value = value;
+ }
+ }
+
+ public ESInner newESInner() {
+ return new ESInner();
+ }
+ }
+
+ private static class ESInnerSubclass extends ESOuter.ESInner {
+ ESInnerSubclass(ESOuter outer) {
+ outer.super();
+ }
+
+ ESInnerSubclass(int value, ESOuter outer) {
+ outer.super(value);
+ }
+ }
+
+ /**
+ * Used in test {@link #testExtendsNestedWithGenerics()}
+ */
+ private static class ESWGOuter<T> {
+ class ESWGInner {
+ public int value;
+ public ESWGInner() {
+ value = 1;
+ }
+ public ESWGInner(int value) {
+ this.value = value;
+ }
+ }
+
+ public ESWGInner newESWGInner() {
+ return new ESWGInner();
+ }
+ }
+
+ private static class ESWGInnerSubclass extends ESWGOuter<String>.ESWGInner {
+ ESWGInnerSubclass(ESWGOuter<String> outer) {
+ outer.super();
+ }
+
+ ESWGInnerSubclass(int value, ESWGOuter<String> outer) {
+ outer.super(value);
+ }
+ }
+
private StringBuffer testAppend = new StringBuffer();
public String getModuleName() {
return "com.google.gwt.dev.jjs.CompilerSuite";
}
+ public void testExtendsNested() {
+ ESOuter o = new ESOuter();
+ assertEquals(1, o.new ESInner().value);
+ assertEquals(2, o.new ESInner(2).value);
+ assertEquals(1, new ESInnerSubclass(o).value);
+ assertEquals(2, new ESInnerSubclass(2, o).value);
+ }
+
+ /**
+ * Test for Issue 7789
+ */
+ public void testExtendsNestedWithGenerics() {
+ ESWGOuter<String> o = new ESWGOuter<String>();
+ assertEquals(1, o.new ESWGInner().value);
+ assertEquals(2, o.new ESWGInner(2).value);
+ assertEquals(1, new ESWGInnerSubclass(o).value);
+ assertEquals(2, new ESWGInnerSubclass(2, o).value);
+ }
+
public void testInnerClassCtors() {
P1<?> p1 = new P1<Object>();
assertEquals(1, p1.value);