Fix compiler crash due to accidental override in native JsType.
Bug: #9379
Bug-Link: https://github.com/gwtproject/gwt/issues/9379
Change-Id: I56319552d6a5cc58b3af93fe2d78c5093a226e34
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/JjsUtils.java b/dev/core/src/com/google/gwt/dev/jjs/impl/JjsUtils.java
index 59dc479..425d876 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/JjsUtils.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/JjsUtils.java
@@ -154,15 +154,22 @@
/**
* Creates a synthetic forwarding stub in {@code type} with the same signature as
- * {@code superTypeMethod} that dispatchs to that method..
+ * {@code superTypeMethod} that dispatchs to that method.
*/
public static JMethod createForwardingMethod(JDeclaredType type,
JMethod methodToDelegateTo) {
JMethod forwardingMethod = createEmptyMethodFromExample(type, methodToDelegateTo, false);
forwardingMethod.setForwarding();
- if (methodToDelegateTo.isJsOverlay() && type.isJsNative()) {
- forwardingMethod.isJsOverlay();
+ if (type.isJsNative()) {
+ if (methodToDelegateTo.isJsNative()) {
+ // Accidental override of native methods on native JsTypes are done by just redeclaring the
+ // native method.
+ return forwardingMethod;
+ }
+ // Otherwise the forwarding method is an overlay method with a proper body.
+ forwardingMethod.setJsOverlay();
+ forwardingMethod.setBody(new JMethodBody(methodToDelegateTo.getSourceInfo()));
}
// Create the forwarding body.
diff --git a/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java b/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java
index 2dc6762..2529d6e 100644
--- a/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java
+++ b/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java
@@ -382,4 +382,42 @@
public void testUnreferencedNativeArrayInstanceOf() {
assertTrue(createArray() instanceof UnreferencedNativeType[]);
}
+
+ @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
+ interface NativeInterface {
+ void add(String element);
+ }
+
+ @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
+ static class NativeSuperClass {
+ public native void add(String element);
+ public native boolean remove(String element);
+ }
+
+ @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
+ static class NativeSubClassAccidentalOverride
+ extends NativeSuperClass implements NativeInterface {
+ }
+
+ public native NativeSubClassAccidentalOverride createNativeSubclass() /*-{
+ return {
+ add:
+ function(e) {
+ this[0] = e;
+ },
+ remove:
+ function(e) {
+ var ret = this[0] == e;
+ this[0] = undefined;
+ return ret;
+ }
+ };
+ }-*/;
+
+ public void testForwaringMethodsOnNativeClasses() {
+ NativeSubClassAccidentalOverride subClass = createNativeSubclass();
+ subClass.add("Hi");
+ assertTrue(subClass.remove("Hi"));
+ assertFalse(subClass.remove("Hi"));
+ }
}