The attached patch, relative to trunk r5191, adds a new tests which fails
only in web mode and only for the JsniSuper case. It appears the problem
isn't directly related to super, but rather with making calls to private
methods polymorphic rather than virtual dispatch. This is the bug I ran
into with the CurrencyListGenerator changes I committed and then had to roll
back.
Ie:
public class A {
public void foo() {}
}
public class B extends A {
public void foo() { callSuper(); }
private void callSuper() { super.foo(); }
}
public class C extends B {
public void foo() { callSuper(); }
private void callSuper() { super.foo(); }
}
B's foo will always call B's callSuper, even when this is actually a C. We
handle this properly for Java code, but not when foo is a JSNI method.
--
John A. Tamplin
Software Engineer (GWT), Google
--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---
Index: user/test/com/google/gwt/dev/jjs/test/CompilerTest.java
===================================================================
--- user/test/com/google/gwt/dev/jjs/test/CompilerTest.java (revision 5191)
+++ user/test/com/google/gwt/dev/jjs/test/CompilerTest.java (working copy)
@@ -28,6 +28,62 @@
@SuppressWarnings("unused")
public class CompilerTest extends GWTTestCase {
+ public static class JsniSuperChild extends JsniSuperParent {
+ @Override
+ public native int foo() /*-{
+ return [email protected]$jsnisuperchild::callSuper()();
+ }-*/;
+
+ private int callSuper() {
+ return super.foo();
+ }
+ }
+
+ public static class JsniSuperGrandparent {
+ public int foo() {
+ return 0;
+ }
+ }
+
+ public static class JsniSuperParent extends JsniSuperGrandparent {
+ @Override
+ public native int foo() /*-{
+ return [email protected]$jsnisuperparent::callSuper()();
+ }-*/;
+
+ private int callSuper() {
+ return super.foo();
+ }
+ }
+
+ public static class SuperChild extends SuperParent {
+ @Override
+ public int foo() {
+ return callSuper();
+ }
+
+ private int callSuper() {
+ return super.foo();
+ }
+ }
+
+ public static class SuperGrandparent {
+ public int foo() {
+ return 0;
+ }
+ }
+
+ public static class SuperParent extends SuperGrandparent {
+ @Override
+ public int foo() {
+ return callSuper();
+ }
+
+ private int callSuper() {
+ return super.foo();
+ }
+ }
+
interface MyMap {
Object get(String key);
}
@@ -952,6 +1008,15 @@
new CheckSubclassStaticInnerAndClinitOrdering();
}
+ /**
+ * Test that super calls work properly, including private bridge methods
+ * needed since JSNI can't call super methods.
+ */
+ public void testSuper() {
+ assertEquals(0, new SuperChild().foo());
+ assertEquals(0, new JsniSuperChild().foo());
+ }
+
public void testSwitchStatement() {
switch (0) {
case 0: