cincheo / jsweet

A Java to JavaScript transpiler.
http://www.jsweet.org
Other
1.46k stars 158 forks source link

JSNI feature #495

Closed WhiteTrashLord closed 6 years ago

WhiteTrashLord commented 6 years ago

I miss something like JSNI in GWT. Sometimes I have Javascript code and don't want to think how it would look like in Java. Is there already a possibility to do this?

GWT JSNI: public static native void alert(String msg) /-{ $wnd.alert(msg); }-/;

In TeaVM you can do it like this:

@JSBody(params = { "a", "b" }, script = "return a + b;") static native int add(int a, int b);

In my opinion this is even better than the GWT approach.

TDesjardins commented 6 years ago

@WhiteTrashLord JSNI ist the old way of GWT to handle this. Since GWT version 2.8 you can use JsInterop which provides and easy and lightweight way to use JS from Java and vice versa:

http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJsInterop.html

lgrignon commented 6 years ago

@TDesjardins : this is JSweet's GitHub, question was of course related to this project, not GWT...

@WhiteTrashLord do you know $insert util in Lang. Wouldn't it be just what you are looking for? https://github.com/cincheo/jsweet/blob/master/core-lib/es6/src/main/java/jsweet/util/Lang.java

TDesjardins commented 6 years ago

@lgrignon What's your problem? Please read the origin post carefully! My answer refers to the origin question which refers to a GWT approach which could maybe adopt for jsweet. My intention was not to advertise GWT but make mention of the better approach of JsInterop which could maybe adapt.

lgrignon commented 6 years ago

@TDesjardins I apologize I didn't mean to be rude. I just thought you were answering on how to do with GWT

That being said, I do not find anything with JsInterop which allows to write TS / JS code like the JSweet's Lang.$insert or JSNI's native void foo() /-{

On the other hand, if the question is just about how to bridge to existing js code / libraries. It is fully covered in the documentation: https://github.com/cincheo/jsweet/blob/master/doc/jsweet-language-specifications.md#bridging-to-external-javascript-elements

@WhiteTrashLord do you now have all the information you needed? :)

WhiteTrashLord commented 6 years ago

@lgrignon

I didn't know $insert. I just tested it. It's almost what I want. I tried to define a Javascript function in the $insert. But I failed to start this function from Java. It won't work with functions?

@TDesjardins

I think I don't need a feature like JsInterop. But I would really like to have something like this from TeaVM also in JSweet:

@JSBody(params = { "a", "b" }, script = "return a + b;") static native int add(int a, int b);

lgrignon commented 6 years ago

Right. I thought something like this would be ok for you:

static int add(int a, int b) {
  return $insert("a + b");
}
lgrignon commented 6 years ago

And if you want to spice it up a little bit, you could try doing something like that:


static int add(int a, int b) 
  return $insert(
    " let result = a;"
+ " result += b"
+ " return result"); 
}

I

renaudpawlak commented 6 years ago

We have a quite powerful @Replace annotation. With this annotation, you can not only replace the body of any method, but also generate new code that will use the body of the original method and other variables.

The code given to the @Replace annotation needs to be TypeScript compatible... (use the any type to avoid typing issues). It should normally cover all you needs (and more), so don't hesitate to tell me if it does not work for you.

WhiteTrashLord commented 6 years ago

@renaudpawlak

Thank you! That's exactly what I was looking for! It seems to work fine. But I don't understand when I would need the supported variables like {{className}} or {{methodName}}

renaudpawlak commented 6 years ago

That's a long story but it is inspired from my background in Aspect Oriented Programming... JSweet annotations can be centralized in the JSweet configuration file so that you don't need to annotate your program with inline annotations. Typically, you can replace the bodies of several methods at once using a pattern matching expression in the configuration file. That could be useful to inject a logging feature or any other globally impacting feature. In that case where the annotation definition is centralized, it can be useful to have access to the annotated class and method in order to switch on it at runtime.

You will find an example here (read the whole section if you are not familiar with this part...): https://github.com/cincheo/jsweet/blob/master/doc/jsweet-language-specifications.md#centralizing-annotations-in-jsweetconfigjson