question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Proposal: code generation for dictionary types

See original GitHub issue

There are many dictionaries that are used as arguments to methods. This is problematic because as currently generated, any type defined in a spec as a dictionary cannot be constructed in elemental . Of course, there are workarounds, but they are ugly and not type-safe. Take for example the following example of Element::animate (which is not in Elemental2 yet):

JsPropertyMapOfAny keyframeAnimationOptions = JsPropertyMap.of();
keyframeAnimationOptions.set("duration",10_000);
keyframeAnimationOptions.set("iterations", Infinity);     
document.querySelector("div.clouds").animate(transitions,  Js.uncheckedCast(keyframeAnimationOptions));

The second parameter is a KeyframeAnimationOptions, but since I cannot construct it, I have to create it as a property map, hope I spell the property names correctly and uncheckedCast it. It is basically back to raw JavaScript. What I would like to write instead is:

KeyframeAnimationOptions options=new KeyframeAnimationOptions();
options.setDuration(10_000);
options.setIterations(Infinity);
document.querySelector("div.clouds").animate(transitions,options);

The root problem is the @JsType annotation added to Dict types. Any class that does not have an equivalent class in JavaScript should instead be descended from JsObject (with the changes in Issue #5 ), with getters and setters for the properties that call JsObject::set and JsObject::get, for example:

public class AnimationEffectTimingProperties extends JsObject {

    public void setDuration(double duration){
        set("duration", duration);
    }

    public void setDuration(String duration){
        set("duration", duration);
    }

    public AnimationEffectTimingReadOnly.DurationUnionType getDuration(){
        return get("duration");
    }

    public void setIterations(double iterations){
        set("iterations", iterations);
    }

    public double getIterations(){
        return get("iterations");
    }
// ... more properties here
}

This then allows me to write type safe code, with code completion.

For an example that is applicable to Elemental2, see GeoLocation::getCurrentPosition or GeoLocation:watchPosition, which take a Dictionary (per the spec) of type PositionOptions (GeoLocationPostionOptions in elemental), but which you will not be able to construct as currently defined.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:12 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
tbenbrahimcommented, Jul 25, 2017

@tbroyer

I am working on my own JsInterop generator, that generates from IDL, this is what a dictionary looks like (as of a few minutes ago):, and it works quite well:

@JsType(name = "Object", namespace = JsPackage.GLOBAL, isNative = true)
public class AnimationEffectTimingProperties  {

    @JsConstructor
    public AnimationEffectTimingProperties(){
    }

    @JsOverlay
    public final void setDuration(double duration){
        Js.<Any>cast(this).asPropertyMap().set("duration", duration);
    }

    @JsOverlay
    public final void setDuration(String duration){
        Js.<Any>cast(this).asPropertyMap().set("duration", duration);
    }

    @JsOverlay
    public final AnimationEffectTimingReadOnly.DoubleOrStringUnionType getDuration(){
        return (AnimationEffectTimingReadOnly.DoubleOrStringUnionType) Js.<Any>cast(this).asPropertyMap().get("duration");
    }
    @JsOverlay
    public final void setIterations(double iterations){
        Js.<Any>cast(this).asPropertyMap().set("iterations", iterations);
    }

    @JsOverlay
    public final double getIterations(){
        return (double) Js.<Any>cast(this).asPropertyMap().get("iterations");
    }

    @JsOverlay
    public final void setDirection(String direction){
        Js.<Any>cast(this).asPropertyMap().set("direction", direction);
    }
}

The main points are:

  • EVery dictionary is @JsType(name=“Object” …, because it really is an Object, it is not a question of whether I like or not.
  • getters and setters for every property (now does not require any changes to JsObject)
  • a constructor
  • no surprises in the API, works like a Java object:
        KeyframeAnimationOptions logoAnimationOptions = new KeyframeAnimationOptions();
        logoAnimationOptions.setDuration(4_000);
        logoAnimationOptions.setIterations(Infinity);
        logoAnimationOptions.setDirection("alternate");
        logo.animate(logoTransitions, logoAnimationOptions);

demo: https://gwt-jelement.github.io/demo/index.html#element-animate

0reactions
jDramaixcommented, Nov 12, 2017

We now provide staticfactory for dictionary types

Read more comments on GitHub >

github_iconTop Results From Across the Web

proposal/generics-implementation-dictionaries.md at master
This document describes a method to implement the Go generics proposal using compile-time instantiated dictionaries. Dictionaries will be stenciled per ...
Read more >
Generics implementation - GC Shape Stenciling
This document describes a method to implement the Go generics proposal by stenciling the code for each different GC shape of the instantiated...
Read more >
Python's list, generator, and dictionary comprehensions ...
Proposal : Python's list, generator, and dictionary comprehensions ... g = (x*x for x in range(10)) // generator comprehension.
Read more >
Deploy Code Generation Definitions - MATLAB & Simulink
Make code generation definitions, such as storage classes and function templates, ... Simulink ® provides version handling for Embedded Coder ® Dictionaries.
Read more >
PEP 589 – TypedDict: Type Hints for Dictionaries with a Fixed ...
A TypedDict type represents dictionary objects with a specific set of string keys, and with specific value types for each valid key. Each...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found