JsInterop Advance

379 views
Skip to first unread message

Cristian Rinaldi

unread,
Aug 20, 2014, 9:17:53 AM8/20/14
to google-web-tool...@googlegroups.com
Community: 
     I'm playing with JsInterop , and I have two questions: 

     1) Are you planning to try the static methods of JS objects, such as Object, Promise, etc.? 
     2) How do when an instance is mapped to an existing Object, eg Promise, has a constructor with parameters? 
  
    Currently to resolve this 1) I created the following class Factory: JS

    But the interfaces define a contract at the level instance of a class or object, this way of doing things, I do not know if it is semantically correct. 

   To solve 2) there are not many options: 

     Create a Factory that returns an instance of the object, because it has no meaning, only to make the new, implement the interface, because the compiler already does. 
     There is some progress in this? 

     I saw in one of the post a proposal to do something like this: 
 
     Promise Promise.Prototype p = new (new Function ....., new Function ....);

    Where Promise, is the interface defined with prototype = "Promise". 

    @JsType(isNative = true, prototype = "Promise")
    
public interface Promise {
   
      
void then(Function f);
    
      
void cath(Function f);
  
}

    Here 'access to jsCore project: 
  

I hope the answers ... 

greetings

Goktug Gokdogan

unread,
Aug 20, 2014, 3:38:31 PM8/20/14
to google-web-toolkit-contributors
On Wed, Aug 20, 2014 at 6:17 AM, Cristian Rinaldi <csri...@gmail.com> wrote:
Community: 
     I'm playing with JsInterop , and I have two questions: 

     1) Are you planning to try the static methods of JS objects, such as Object, Promise, etc.? 


There will be some static helpers provided from the SDK. I originally started the JSNI 2.0 document but it is basically waiting for me to start on Elemental 2.0 and accumulate more experience to turn it into something more concrete.

 
     2) How do when an instance is mapped to an existing Object, eg Promise, has a constructor with parameters? 
  

Actually I have new ideas on this derived from how some other APTs work.

I need to update the JsInterop doc but these are the options that I'm thinking right now:

Option 1 (works better for extending):
@JsType(prototype = "Promise")
public interface Promise {
  /* Protoype_Promise is an autogenerated package visible class */
  public static class Prototype extends Protoype_Promise {
    public Prototype(Function... functions) {
       super(functions);
    }
  }

  
void then(Function f);

  void cath(Function f);
}

Option 2 (works better for general use):
@JsType(prototype = "Promise")
public interface Promise {
  /* Protoype_Promise is an autogenerated package visible class */
  public static Promise create(Function... functions) {
     return new Protoype_Promise(functions);
  }

  
void then(Function f);

  void cath(Function f);
}

Of course one can do both:

@JsType(prototype = "Promise")
public interface Promise {

  public static class Prototype extends Protoype_Promise {
    public Prototype(Function... functions) {
       super(functions);
    }
  }

  public static Promise create(Function... functions) {
     return new Prototype(functions);
  }

  
void then(Function f);

  void cath(Function f);
}
 
    Currently to resolve this 1) I created the following class Factory: JS

    But the interfaces define a contract at the level instance of a class or object, this way of doing things, I do not know if it is semantically correct. 

   To solve 2) there are not many options: 

     Create a Factory that returns an instance of the object, because it has no meaning, only to make the new, implement the interface, because the compiler already does. 
     There is some progress in this? 

     I saw in one of the post a proposal to do something like this: 
 
     Promise Promise.Prototype p = new (new Function ....., new Function ....);

    Where Promise, is the interface defined with prototype = "Promise". 

    @JsType(isNative = true, prototype = "Promise")
    
public interface Promise {
   
      
void then(Function f);
    
      
void cath(Function f);
  
}

    Here 'access to jsCore project: 
  


Great work. This kind of stuff is also very valuable as a feedback.
 
I hope the answers ... 

greetings

--
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 google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/3268ccc7-9953-49c9-9079-574096f0d5d3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ray Cromwell

unread,
Aug 20, 2014, 4:21:35 PM8/20/14
to google-web-toolkit-contributors
Static methods on interfaces is a Java8 only feature, but I prefer it. Since you can use Java8 with GWT even if you are running Java7 or below as a JVM, and since these features are not for shared code, but for Web code, I'm kinda leaning towards the idea of JSNI 2.0 requiring Java8. We should have a debate about this in the community. We get several benefits:

1. Static methods on interfaces
2. Defender methods to implement JSNI fragments on JsTypes
3. APIs designed for Lambdas everywhere.


Here's a motivating usecase right now:

@JsType
interface SomeJsType {
  void someMethod();
  default void anotherMethod(int arg) {
    js("this.doIt($0, "must be present", arg);
  }
}

That is, there are some cases in Js interfaces where default prototype dispatch is not what you want, and you need wrapper code.


Another use case

@JsType
@IterateAsArray(getter = "item", length="length")
interface NodeList<T extends Element> extends Iterable<T> {
    T item(int x);
    int length();

   default Iterator<T> iterator() {
      return NodeListIterator(this);
   }
}


for (T x : nodeList) { ... }

Are we ballsy enough to say GWT 3.0 = Java8 source level enforced for client side code?




Goktug Gokdogan

unread,
Aug 20, 2014, 5:00:00 PM8/20/14
to google-web-toolkit-contributors
It is not like a library forces Java8; as we are supplying our own java8 compatible compiler, I think we are flexible to force Java8.
If there is shared code and they want to keep java7 compatibility, then they should avoid using java8 specific features.


Jens

unread,
Aug 20, 2014, 5:44:04 PM8/20/14
to google-web-tool...@googlegroups.com
Are we ballsy enough to say GWT 3.0 = Java8 source level enforced for client side code?

I hope so. 

I am pretty sure everyone who has given Java8 a try so far, even if it was just an example project, feels the pain when coming back to a GWT project. If Java8 gives more freedom and a cleaner API design for Elemental 2.0 then GWT 3.0 should require it. Thats why it will be called 3.0...going forward. 

But when doing so, SDM in GWT 2.7 must work well on any project size because people might not migrate that fast to GWT 3.0 (depending on how many breaking changes it will contain)

-- J.

Cristian Rinaldi

unread,
Aug 21, 2014, 8:29:59 AM8/21/14
to google-web-tool...@googlegroups.com
Thanks +Goktug Gokdogan for response.

APT is very good option and java 8 support for GWT 3.0 would be a amazing thing.
You have a planning for Elemental 2.0 or initial documentation to share, to how you plan address the desing?
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.

Goktug Gokdogan

unread,
Aug 21, 2014, 12:33:38 PM8/21/14
to google-web-toolkit-contributors
On Thu, Aug 21, 2014 at 5:29 AM, Cristian Rinaldi <csri...@gmail.com> wrote:
Thanks +Goktug Gokdogan for response.

APT is very good option and java 8 support for GWT 3.0 would be a amazing thing.
You have a planning for Elemental 2.0 or initial documentation to share, to how you plan address the desing?


Nothing planned yet other than the plan to work on it :) My anticipation is. initially we will auto generate JsTyped DOM, deal with problems and incrementally improve it.
 
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/44fbf2d1-d791-4e7b-8078-5e804c3da99e%40googlegroups.com.

Ray Cromwell

unread,
Aug 21, 2014, 12:41:28 PM8/21/14
to google-web-toolkit-contributors
I think the IDL->DOM generation stuff will be the easy part since the API is driven by the IDL. The more tricky (likely to bikeshed) stuff I think is modeling all of the ES5 APIs that back everything.  e.g. JsObject, JsArray, etc.

I somewhat like the old Elemental interfaces (ArrayOf, MapFromStringTo...) at a high level for allowing shared code to continue to work, but at a lower level, we need basic interfaces that let you write anything you could write in JS, like

JsObject.hasOwnProperty(), JsObject.keys(), JsObject.defineProperty(), etc

My goal would be to minimize the need to drop to JS snippets to as small as possible. But we won't be able to do it perfectly (e.g. dealing with statics and overloads), and so the workarounds will be where the debate is. :)




Brian Slesinsky

unread,
Aug 21, 2014, 1:41:18 PM8/21/14
to GWTcontrib
I'm eager to start using Java 8 too, but I think we should wait until we have Java 8 committed (behind a flag) before having the discussion about whether to require it for anything. As we've found with incremental compile, sometimes we end up changing direction a bit to reach our goal, so there's not much point in having policy discussions before the mechanism is there.



Cristian Rinaldi

unread,
Aug 22, 2014, 1:00:40 PM8/22/14
to google-web-tool...@googlegroups.com
I followed with JsInterop and implement a basic version of Promise (not full implemented). 
The code is here: 

I found some things, for example: 

Promise has the "catch" method, and this is a reserved word in Java. 
Then, on the interface that represents Promise, can not be put this method. Perhaps, there could be a JsAlias ​​for functions:

@JsType(isNative = true, prototype = "Promise")
public interface Promise {

   
   
Promise then(PromiseThenFn f, PromiseThenFn error);

   
@JsAlias(value="catch")
   
Promise catchError(PromiseThenFn error);
}


Another annoying thing is the management function as a parameter, for example: 

In JS: 

var p = new Promise (function (resolved, rejected) {...});

In Java I emulated it this way, and if not the best:

@JsType
public interface PromiseFn {
   
void f(Resolve resolve, Rejected rejected);
}

// In JS Class Factory
public static native PromiseFn Function(PromiseFn fn) /*-{
    return function(resolve, rejected){
        fn.f(resolve, rejected);
     }
}-*/
;

And use this:

final Promise p3 = Browser.newPromise(JS.Function(new PromiseFn() {
     
@Override
     
public void f(Resolve resolve, Rejected rejected) {
            resolve
.resolve("Resolve Promise P3");
     
}
}));

I do not know if they are working in a cleaner way to work with functions to JS style.

Example Usage of Promise:

Promise p1 = Browser.newPromise(JS.Function(new PromiseFn() {
     
@Override
     
public void f(Resolve resolve, Rejected rejected) {
           resolve
.resolve("Resolve Promise P1");
     
}
}));

p1.then(
    JS.Function(
        new PromiseThenFn() {
            @Override
            public Promise f(final Object changed) {
                Browser.getWindow().getConsole().log("Promise Complete: " + changed);
                return Browser.newPromise(JS.Function(new PromiseFn() {
                    @Override
                     public void f(Resolve resolve, Rejected rejected) {
                        resolve.resolve(changed + " > Other Promise");
                     }
                }));
            }
        }), JS.Function(
           new PromiseThenFn() {
              @Override
              public Promise f(final Object changed) {
                Browser.getWindow().getConsole().log("Promise with Error: " + changed);
                return Browser.newPromise(JS.Function(new PromiseFn() {
                    @Override
                    public void f(Resolve resolve, Rejected rejected) {
                         rejected.rejected(changed + " > Other With Error Promise");
                    }
                }));
            }
        })
    ).then(
       JS.Function(
          new PromiseThenFn() {
              @Override
              public Promise f(final Object changed) {
                   Browser.getWindow().getConsole().log("Promise Complete: " + changed);
                   return null;
              }
          }),
       JS.Function(
          new PromiseThenFn() {
              @Override
              public Promise f(Object changed) {
                 Browser.getWindow().getConsole().log("Promise with Error: " + changed);
                 return null;
              }
           })
       );

The Result:

["Promise Complete: Resolve Promise P1"cZphcMObjecttMfunction__elementTypeId$1__elementTypeCategory$3]
["Promise Complete: Resolve Promise P1 > Other Promise"cZphcMObjecttMfunction__elementTypeId$1__elementTypeCategory$3]

Thanks and hope to suggestions.

Goktug Gokdogan

unread,
Aug 22, 2014, 8:28:45 PM8/22/14
to google-web-toolkit-contributors
On Fri, Aug 22, 2014 at 10:00 AM, Cristian Rinaldi <csri...@gmail.com> wrote:
I followed with JsInterop and implement a basic version of Promise (not full implemented). 
The code is here: 

I found some things, for example: 

Promise has the "catch" method, and this is a reserved word in Java. 
Then, on the interface that represents Promise, can not be put this method. Perhaps, there could be a JsAlias ​​for functions:

@JsType(isNative = true, prototype = "Promise")
public interface Promise {

   
   
Promise then(PromiseThenFn f, PromiseThenFn error);

   
@JsAlias(value="catch")
   
Promise catchError(PromiseThenFn error);
}


Hmm, we probably going to need something like that.
 

Another annoying thing is the management function as a parameter, for example: 

In JS: 

var p = new Promise (function (resolved, rejected) {...});

In Java I emulated it this way, and if not the best:

@JsType
public interface PromiseFn {
   
void f(Resolve resolve, Rejected rejected);
}

// In JS Class Factory
public static native PromiseFn Function(PromiseFn fn) /*-{
    return function(resolve, rejected){
        fn.f(resolve, rejected);
     }
}-*/
;


For single-abstract-method classes (SAM) without @JsType (or perhaps only the SAMs marked with Java8 @Functional), we are planning to do an auto conversion into real javascript function so that you can directly do this:


@Functional

public interface PromiseFn {
    void f(Resolve resolve, Rejected rejected);
}

final Promise p3 = Browser.newPromise(new PromiseFn() {
   
@Override
   public void f(Resolve resolve, Rejected rejected) {
      resolve.resolve("Resolve Promise P3"
);
   }
});

 
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/b4c4bfb4-9470-49a0-9ab2-67e855ed1a0c%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages