Hello,
I totally agree on your first two points. I would add a third which is that since this SAM functionnality will be very essential to javascript interoperability, it will be used a lot (already in some projects i am eagerly waiting for this to be implemented, instead of writing my own wrappers). And since it will be used a lot, it needs to be non-invasive (as much as it can).
Your solution is really clean, regarding that point. More, it is expressive, so the developper knows what happens. And since it uses the already defined jsconvert mechanism, it is much simpler.
So i would definitely vote for that to happen !
Thanks
Arnaud
Le Wed Nov 19 2014 at 11:54:29, <
google-web-tool...@googlegroups.com> a écrit :
Goktug Gokdogan <gok...@google.com>: Nov 18 02:45PM -0800
We originally started with the idea that when we encounter a non-JsType
that is a Single-Abstract-Method class (SAM), we will automatically threat
it as a javascript function for interoperability purposes.
For that to work well, we need to make it work in a predictable way. Which
means;
1. Behavior shouldn't be broken with runtime type information.
i.e. if the method accepts interface 'Consumer' it should accept any
implementation of Consumer, not some of them (e.g. object that implements
both Consumer and Runnable).
2. Referential equality should be preserved at least per SAM definition.
i.e. element.addEventListener(e) and element.removeEventListener(e)
should result in same function given that both methods uses the same SAM
interface.
I don't think we can diverge from these two in our final solution. However,
this forces us to generate bridge methods that is more complex to
implement, results in extra code bloat and also it can be surprising (e.g.
an object that happens to be a SAM but meant to be an opaque object).
Anyway, after long discussions we converged into an alternative.
We are planning to introduce javascript functions to our type system and
explicitly mark them by @JsFunction that has its own restrictions similar
to JsTypes. We will forbid concrete classes to implement/extend multiple
@JsFunction types. With this, they can handled efficiently and will be more
explicit and will behave predictable.
This option basically prevents simple consumption of java functional
interfaces that appear on JsTypes but we can later handle this (if
necessary) via @JsConvert. This will make 'function <=> SAM' conversion
more explicit. As an additional benefit, it will follow the same code path
as the rest of the @JsConvert while generating the bridge methods. E.g.
@JsConvert(SamToFunctionConverter.class)
public @Interface ToJsFunction {}
void forEach(@ToJsFunction Consumer c);
I'll update the doc soon. Let us know what you think.
Cheers.
|