Provide API to access JsConstructor from Class
This is an undocumented API and might change in any
GWT version. jsinterop.base will provide a supported
utility to access JsConstructor from Class instance.
Change-Id: Ib8bbb6bf7754bc59fa91f7d025d91721f2dfab40
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 c7c7606..5118b40 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
@@ -61,7 +61,6 @@
} else {
_ = @Runtime::createSubclassPrototype(*)(superTypeIdOrPrototype);
_.@Object::castableTypeMap = castableTypeMap;
- _.constructor = _;
if (!superTypeIdOrPrototype) {
// Set the typeMarker on java.lang.Object's prototype, implicitly setting it for all
// Java subclasses (String and Arrays have special handling in Cast and Array respectively).
@@ -138,6 +137,11 @@
cur.execScript('var ' + parts[0]);
}
+ if(optCtor) {
+ var clazz = optCtor.prototype.@Object::___clazz;
+ clazz.@Class::jsConstructor = optCtor;
+ }
+
// Certain browsers cannot parse code in the form for((a in b); c;);
// This pattern is produced by the JSCompiler when it collapses the
// statement above into the conditional loop below. To prevent this from
diff --git a/user/super/com/google/gwt/emul/java/lang/Class.java b/user/super/com/google/gwt/emul/java/lang/Class.java
index fca599a..fbca4e7 100644
--- a/user/super/com/google/gwt/emul/java/lang/Class.java
+++ b/user/super/com/google/gwt/emul/java/lang/Class.java
@@ -124,15 +124,14 @@
/**
* Used by {@link WebModePayloadSink} to create uninitialized instances.
*/
- @DoNotInline
- static native JavaScriptObject getPrototypeForClass(Class<?> clazz) /*-{
- if (clazz.@Class::isPrimitive()()) {
- return null;
- }
- var typeId = clazz.@Class::typeId;
- var prototype = @com.google.gwt.lang.Runtime::prototypesByTypeId[typeId];
- return prototype;
- }-*/;
+ @DoNotInline
+ static native JavaScriptObject getPrototypeForClass(Class<?> clazz) /*-{
+ if (clazz.@Class::isPrimitive()()) {
+ return null;
+ }
+ var typeId = clazz.@Class::typeId;
+ return @com.google.gwt.lang.Runtime::prototypesByTypeId[typeId];
+ }-*/;
public static boolean isClassMetadataEnabled() {
// This body may be replaced by the compiler
@@ -302,6 +301,8 @@
private JavaScriptObject arrayLiterals;
+ private JavaScriptObject jsConstructor;
+
// Assign a sequential id to each class literal to avoid calling hashCode which bring Impl as
// a dependency.
private int sequentialId = nextSequentialId++;
diff --git a/user/test/com/google/gwt/core/interop/JsExportTest.java b/user/test/com/google/gwt/core/interop/JsExportTest.java
index df58627..3c3c2b3 100644
--- a/user/test/com/google/gwt/core/interop/JsExportTest.java
+++ b/user/test/com/google/gwt/core/interop/JsExportTest.java
@@ -45,6 +45,10 @@
$wnd.$global = $global;
}-*/;
+ private native boolean isClosureFormattedOutputEnabled() /*-{
+ return !!(window.goog && window.goog.global);
+ }-*/;
+
public void testMethodExport() {
myClassExportsMethodCallMe1();
assertTrue(MyClassExportsMethod.calledFromCallMe1);
@@ -207,6 +211,29 @@
public NativeMyClassExportsConstructor(@SuppressWarnings("unused") int a) { }
}
+ public void testGetJsConstructor() {
+ if (isClosureFormattedOutputEnabled()) {
+ return; // Closure formatted output doesn't support jsConstructor.
+ }
+ Object constructorFn = getJsConstructor(MyClassExportsConstructor.class);
+ assertSame(getMyClassExportsConstructor(), constructorFn);
+ assertSame(MyClassExportsConstructor.class, getClass(constructorFn));
+
+ assertNull(getJsConstructor(Object.class));
+ assertNull(getJsConstructor(String.class));
+ }
+
+ @JsProperty(namespace = "$global.woo", name = "MyClassExportsConstructor")
+ private static native Object getMyClassExportsConstructor();
+
+ private static native Object getJsConstructor(Class<?> clazz) /*-{
+ return clazz.@Class::jsConstructor;
+ }-*/;
+
+ private static native Class<?> getClass(Object ctor) /*-{
+ return ctor.prototype.@Object::___clazz;
+ }-*/;
+
public void testExportedField() {
assertEquals(100, MyExportedClass.EXPORTED_1);
assertEquals(100, getExportedField());