Fix incorrect property copying for native JsType subclasses.
Bug: #9430
Bug-Link: https://github.com/gwtproject/gwt/issues/9430
Change-Id: Idb9c47cb5d7d9969dc379b23f6ab4d1ea4c589dd
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
index 4071518..f70a96b 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JMethod.java
@@ -199,7 +199,7 @@
* an existing non-JsMember inside a class.
*/
public boolean exposesNonJsMember() {
- if (isInterfaceMethod() || !JjsUtils.exposesJsName(this)) {
+ if (isInterfaceMethod() || enclosingType.isJsNative() || !JjsUtils.exposesJsName(this)) {
return false;
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index 6a47400..f78edbb 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -2012,20 +2012,22 @@
RuntimeConstants.RUNTIME_DEFINE_CLASS, defineClassArguments).makeStmt();
addTypeDefinitionStatement(type, defineClassStatement);
- maybeCopyObjProperties(
+ maybeCopyJavaLangObjectProperties(
type,
getPrototypeQualifierViaLookup(program.getTypeJavaLangObject(), type.getSourceInfo()),
globalTemp.makeRef(type.getSourceInfo()));
}
- private void maybeCopyObjProperties(
- JDeclaredType type, JsExpression toPrototype, JsExpression fromPrototype) {
+ private void maybeCopyJavaLangObjectProperties(
+ JDeclaredType type, JsExpression javaLangObjectPrototype, JsExpression toPrototype) {
if (getSuperPrototype(type) != null && !type.isJsFunctionImplementation()) {
- JsStatement statement = constructInvocation(type.getSourceInfo(),
- RuntimeConstants.RUNTIME_COPY_OBJECT_PROPERTIES,
- fromPrototype,
- toPrototype)
- .makeStmt();
+ JsStatement statement =
+ constructInvocation(
+ type.getSourceInfo(),
+ RuntimeConstants.RUNTIME_COPY_OBJECT_PROPERTIES,
+ javaLangObjectPrototype,
+ toPrototype
+ ).makeStmt();
addTypeDefinitionStatement(type, statement);
}
}
@@ -2152,7 +2154,7 @@
// inline assignment of castableTypeMap field instead of using defineClass()
setupCastMapOnPrototype(type);
- maybeCopyObjProperties(
+ maybeCopyJavaLangObjectProperties(
type,
getPrototypeQualifierOf(program.getTypeJavaLangObject(), info),
getPrototypeQualifierOf(type, info));
diff --git a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Runtime.java b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Runtime.java
index 45bd626..e48652b 100644
--- a/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Runtime.java
+++ b/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Runtime.java
@@ -97,8 +97,7 @@
return @Runtime::portableObjCreate(*)(superPrototype);
}-*/;
- public static native void copyObjectProperties(JavaScriptObject from,
- JavaScriptObject to) /*-{
+ public static native void copyObjectProperties(JavaScriptObject from, JavaScriptObject to) /*-{
for (var property in from) {
if (to[property] === undefined) {
to[property] = from[property];
diff --git a/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java b/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java
index 8dc10c7..b222732 100644
--- a/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java
+++ b/user/test/com/google/gwt/core/interop/NativeJsTypeTest.java
@@ -468,4 +468,22 @@
assertNotSame(IFrameWindow.window, MainWindow.window);
assertSame(MainWindow.window, AlsoMainWindow.window);
}
+
+ @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Error")
+ private static class NativeError {
+ }
+
+ private static class NativeErrorSubclass extends NativeError {
+ }
+
+ public void testObjectPropertiesAreCopied() {
+ Object error = new NativeErrorSubclass();
+ assertTrue(error instanceof NativeError);
+ // Make sure the subclass is a proper Java object (the typeMarker should be one of the
+ // properties copied from java.lang.Object).
+ assertFalse(error instanceof JavaScriptObject);
+ // TODO(rluble): NativeErrorSubclass should have inherited Error toString behavior not
+ // j.l.Object.toString behavior.
+ // assertTrue(error.toString().matches("[0-9a-zA-Z$_.]+@[0-9a-fA-F]+"));
+ }
}