Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gwtbootstrap3 0.9.2, doubleValue() is not a function error. #9242

Closed
michael-newsrx opened this issue Dec 9, 2015 · 6 comments
Closed

gwtbootstrap3 0.9.2, doubleValue() is not a function error. #9242

michael-newsrx opened this issue Dec 9, 2015 · 6 comments

Comments

@michael-newsrx
Copy link

When using the pre-packaged gwtbootstrap3-extras 0.9.2 with gwt 2.8.0 beta the following function throws an error about "doubleValue()" not being a function:

package org.gwtbootstrap3.extras.slider.client.ui;
...
public class Slider extends SliderBase<Double> {
...
@Override
    protected native void setValue(Element e, Double value) /*-{
        var doubleValue = value.@java.lang.Double::doubleValue()();
        $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::SET_VALUE, doubleValue);
    }-*/;
...
}

This is a boxed value in the function declaration, why would the JSNI not support a boxed object function? Especially for values like 'Long' that can't be represented in native js?

We've worked around it here by creating a local function:

protected native void setValue(Element e, Double value) /*-{
        $wnd.jQuery(e).slider(@org.gwtbootstrap3.extras.slider.client.ui.base.SliderCommand::SET_VALUE, value);
    }-*/;

which seems to work by treating the boxed Double as a literal value in the JSNI.

@tbroyer
Copy link
Member

tbroyer commented Dec 9, 2015

/cc @rluble @dankurka

@rluble
Copy link
Contributor

rluble commented Dec 9, 2015

Double and Boolean are devirtualized, and that means that when you have an instance of Double (Boolean) the object is an actual JavaScript number (boolean). The side effect is that the restrictions are the same as those for JSOs you can not call their methods through JSNI. (We need to update the compiler to produce an error message for this case).

In the scenario presented you can use value directly in JSNI (without the need to call doubleValue())

@Legioth
Copy link

Legioth commented Jun 6, 2016

Why can't those be called from JSNI when it's completely valid to to the same things through regular Java?

I see that it might be slightly problematic to support @Double::doubleValue(), but couldn't value.@Double::doubleValue()() still be rewritten to just value?

@rluble
Copy link
Contributor

rluble commented Jun 6, 2016

GWT does not really understand JS inside JSNI. These calls are devirtualized and is some cases there is trampoline dispatch (think more like in Number.doubleValue() where a trampoline is needed because only Double is devirtualized but not Integer, Long, etc). So the same argument that applies to restrictring those type of dispatches for JSOs apply to Double, Boolean, Number,String, CharSequence and Comparable.

Under the hood method references resolve into names and if you change your example you can do things like

var a = value.@double::doubleValue().bind(value);

not that they are common but they are supported but that simple handling would not work here.

@rluble
Copy link
Contributor

rluble commented Jun 6, 2016

Duplicate of issue #9356.

@rluble rluble closed this as completed Jun 6, 2016
@rluble
Copy link
Contributor

rluble commented Jun 10, 2016

I see that it might be slightly problematic to support @double::doubleValue(), but couldn't
value.@double::doubleValue()() still be rewritten to just value?

So there are different methods in the different devirtualized classes (Double, String, Boolean and supers) not just doubleValue(). The devirtualization process is more general, transforms the methods defined in the respective classes into static methods either synthesized from the bodies of the devirtualized methods (to implement the functionality) or artificial trampolines to route to the appropriate implementation (sort of mimicking dynamic dispatch, as in for example Comparable.compare).

Devirtualizer currently does this for the Java AST, so when there is a method call such as "o.compare(o1)" it gets replaced by comparable_compare_trampoline(o, o1) if it was Comparable::compare or just string_compare_devirtual(o, o1) if the target was known statically to be String.

So the best solution is to make Devirtualizer do the same to the JSNI JavaScript AST (JSNI methods are just methods with JS ast in the bodies), so they basically pass through the Jva AST pipeline untouched.

Then the JS optimization phase would inline, e.g. doubleValue_devirtual(d) into d.

The patch https://gwt-review.googlesource.com/#/c/15121/ implements the devirtualization for the JS AST.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants