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 bfeef2a2f6f..b72d3ad99a5 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 @@ -36,10 +36,11 @@ public class Runtime { * Otherwise it creates the prototype for the class by calling {@code createSubclassPrototype()}. * It also assigns the castable type map and sets the constructors prototype field to the * current prototype. - * Finally adds the class literal if it was created before the call to {@code defineClass}. + *
+ * Finally, adds the class literal if it was created before the call to {@code defineClass}. * Class literals might be created before the call to {@code defineClass} if they are in separate - * code-split fragments. In that case Class.createFor* methods will have created a placeholder and - * stored in {@code prototypesByTypeId} the class literal. + * code-split fragments. In that case, Class.createFor* methods will call have called + * Class.maybeSetClassLiteral to create a placeholder and stored it in {@code prototypesByTypeId}. *
* As a prerequisite if superTypeIdOrPrototype is not null, it is assumed that defineClass for the * supertype has already been called. @@ -77,23 +78,20 @@ public static native void defineClass(JavaScriptObject typeId, } }-*/; - private static native JavaScriptObject portableObjCreate(JavaScriptObject obj) /*-{ - function F() {}; - F.prototype = obj || {}; - return new F(); - }-*/; - /** * Create a subclass prototype. */ private static native JavaScriptObject createSubclassPrototype( JavaScriptObject superTypeIdOrPrototype) /*-{ - var superPrototype = superTypeIdOrPrototype && superTypeIdOrPrototype.prototype; - if (!superPrototype) { - // If it is not a prototype, then it should be a type id. - superPrototype = @Runtime::prototypesByTypeId[superTypeIdOrPrototype]; + var superPrototype = {}; + if (superTypeIdOrPrototype != null) { + superPrototype = superTypeIdOrPrototype && superTypeIdOrPrototype.prototype; + if (!superPrototype) { + // If it is not a prototype, then it should be a type id. + superPrototype = @Runtime::prototypesByTypeId[superTypeIdOrPrototype]; + } } - return @Runtime::portableObjCreate(*)(superPrototype); + return Object.create(superPrototype); }-*/; public static native void copyObjectProperties(JavaScriptObject from, JavaScriptObject to) /*-{ @@ -109,7 +107,7 @@ public static native void copyObjectProperties(JavaScriptObject from, JavaScript */ private static native JavaScriptObject maybeGetClassLiteralFromPlaceHolder( JavaScriptObject entry) /*-{ - // TODO(rluble): Relies on Class.createFor*() storing the class literal wrapped as an array + // TODO(rluble): Relies on Class.maybeSetClassLiteral() storing the class literal wrapped as an array // to distinguish it from an actual prototype. return (entry instanceof Array) ? entry[0] : null; }-*/; diff --git a/user/test/com/google/gwt/core/interop/JsTypeTest.java b/user/test/com/google/gwt/core/interop/JsTypeTest.java index 9b42fa0c28a..04b921cc6b6 100644 --- a/user/test/com/google/gwt/core/interop/JsTypeTest.java +++ b/user/test/com/google/gwt/core/interop/JsTypeTest.java @@ -374,6 +374,31 @@ public void testEnumSubclassEnumeration() { assertEquals(1, callPublicMethodFromEnumerationSubclass(MyEnumWithSubclassGen.C)); } + @JsType(isNative = true, namespace = JsPackage.GLOBAL) + public static class DoesntExist {} + + @JsType + public static class SubtypeOfDoesntExist extends DoesntExist { + public static boolean test() { + return true; + } + } + + public void testMissingClassHierarchy() { + // The class itself can be created and referenced, static members will work + assertTrue(SubtypeOfDoesntExist.test()); + + // Creating a new instance will fail, something like "Cannot call method "call" of undefined" + try { + new SubtypeOfDoesntExist(); + fail("Should not be able to create instance"); + } catch (Exception expected) { + // ignore, expected + } + + assertFalse(new Object() instanceof SubtypeOfDoesntExist); + } + private static native int callIntFunction(Object object, String functionName) /*-{ return object[functionName](); }-*/;