If you have followed some jsinterop discussions earlier [1], we decided to
drop Prototype class generation in favor of concrete classes with native
methods:
@JsType(prototype="Object")
public class JsObject {
public static native String[] keys(JsObject obj);
public native boolean hasOwnProperty(String prop);
}
I'm implementing this and it works well but the prototype attribute is
serving a very similar purpose to name and namespace attribute. The
attribute is simple there because we cannot differentiate if the type
represents a type that is already available in native code or if the type
is introduced by java.
Similarly, we hit such ambiguity for interfaces. If you have a JsType
interface, it is not clear that if such type is introduced by the app or if
it is just a stub for existing type that is already available natively.
These affects several stuff like how instanceof works (which is quite
problematic) or if we should generate any code for the interface or not
(which is more problematic in j2cl).
So the solution we came up with is to remove the prototype attribute and
instead introduce isNative attribute. When the attribute is set to true, it
basically tells the compiler to assume that the type already exists in
native code (similar to the native keyword available for methods).
The prototype will be equivalent to the fully qualified javascript name
(which is calculated based on JsType name/namespace, JsPackage etc). So
above code becomes:
@JsType(namepace=GLOBAL, name="Object", isNative=true)
public class JsObject {
public static native String[] keys(JsObject obj);
public native boolean hasOwnProperty(String prop);
}
or if the package-info.java already has @JsPackage(name=GLOBAL), it could
be re-written as
@JsType(isNative=true)
public class Object {
public static native String[] keys(Object obj);
public native boolean hasOwnProperty(String prop);
}
Based on this change, we also redefining how the instanceof works for
native JsTypes.
If the native type is concrete, the instanceof will be generated in
JavaScript as
obj instanceof <fully_qualified_js_name>
If the native type is an interface, the instanceof operation will always
return true as it simply represents a loose javascript contract. [2]
For all non-native JsTypes, regular java instanceof semantic will apply.
That means, for example, if you do (jso instanceof SomeJsTypeInterface), it
will return false (earlier it would have returned true).
That's all for now. As always, feel free to send any comments and let me
know what you think.
Cheers,
Goktug.
PS: Note that due this change, when the new annotations introduced, you
will need to add isNative=true for all interfaces that is abstracting some
javascript API. If you were using it for just generating unobfuscated names
for java APIs then you can keep it as it is.
[1]
https://groups.google.com/d/topic/google-web-toolkit-contributors/L6uh96NcZtE/discussion
[2] We may later provide a way for developers to customize this behavior,
like providing their own method to be called for instanceof.
--
You received this message because you are subscribed to the Google Groups "GWT
Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/google-web-toolkit-contributors/CAN%3DyUA3UHpXB8%2BgmtRHM5Of4nV6V4-25U82t%2BuhGjmjS_EaD3w%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.