cincheo / jsweet Goto Github PK
View Code? Open in Web Editor NEWA Java to JavaScript transpiler.
Home Page: http://www.jsweet.org
License: Other
A Java to JavaScript transpiler.
Home Page: http://www.jsweet.org
License: Other
I am trying to use jSweet to translate DTOs (data transfer objects) from Java to Typescript so that I can easily serialize the same object on both ends (Java server and - currently - Typescript client).
I have a DTO tagged with javax.xml.bind.annotation.XmlRootElement annotation so that it can be serialized in JSON using Jackson.
I also have some methods that do not translate (equals/hashCode for instance).
It would be nice to simply ignore things that do not translate to Typescript (such as Java annotations - although now it starts existing in the latest Typescript).
And it would be nice to add a ignore annotation on methods/fields, etc... that do not need to be translated.
What do you guys think?
Create a test from the Angular example and fix it
Currently, TypeScript is used through command line processes, which is very inefficient. We can use a Nodejs server to compile with TypeScript and communicate through web services. It will most probably improve performances a lot.
Is a plugin for IntelliJ on the roadmap? Would be great!
The following code does not pass TSC:
package source.generics;
import java.util.function.Consumer;
import jsweet.lang.Interface;
public class GenericObjectStructure {
<T> void m(MyInterface<T> i, Consumer<T> c) {
}
public static void main(String[] args) {
new GenericObjectStructure().m(new MyInterface<String>() {
{
f = "test";
}
}, param -> { param.indexOf("c"); });
}
}
@Interface
abstract class MyInterface<T> {
String f;
}
That's because the new MyInterface<String>() {{ f = "test"; }}
type is erased to { f : "test" }
when transpiled... As a consequence, the T
parameter actual value cannot be inferred and param
is not considered as a String
anymore.
Objects and interfaces constructions must be correctly typed to avoid this problem.
Programmers can define their own string types as follows:
import jsweet.lang.StringType;
public class CustomStringTypes {
@Erased
public interface abc {
}
@StringType
public static final abc abc = null;
void m2(abc arg) {
}
public static void main(String[] args) {
new CustomStringTypes().m2(abc);
}
}
Correct definition checks must be added to the transpiler:
From @tdebroc on December 22, 2015 9:4
I have a maven Build Failure:
[ERROR] Plugin org.jsweet:jsweet-maven-plugin:1.0.0-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact org.jsweet:jsweet-maven-plugin:jar:1.0.0-SNAPSHOT
Copied from original issue: cincheo/jsweet-examples#12
Getters and setters are useful because:
Proposal: create a @Targetproperty("propertyName") annotation. When setters or getters are annotated with this annotation, the transpiler generates code using properties rather than invocations.
To avoid name clashes between static and non static:
We need a project template so that developers can start with JSweet very quickly through Maven... the getting started doc needs to be rewritten to reflect this change.
Users should be able to exclude some files from the transpilation
In the sandbox:
import static jsweet.util.Globals.array;
import static jsweet.dom.Globals.console;
public class C {
public static void main(String[] args) {
String[] strings = { "a", "b", "c" };
console.log(strings);
array(strings).push("d");
assert strings[3] == "d";
console.log(strings);
}
}
=> Line 12: Declaration or statement expected.
But it works if the class does not contain a main method (for instance rename main to m).
Using wildcard will eventually pose problems (I am sure there are a lot of potential non-reported bugs here), so we will just forbid them for now... they are bad practice anyway.
Potential support is not completely out of question, but we should have an interesting use case.
In version 1.0, inner classes will not be supported. It would not be that hard to support them though.
The idea (to be validated) is to create a TypeScript module with the same name as the container class and create the inner class in the module.
API improvement: jsweet.lang.Globals.JSON variable is useless because all the members of JSON are static and can thus be accessed directly.
Currently, constructors cannot be overloaded... the following code will not work (raises invalid overload):
class C {
public C(String s) {
[...]
}
public C() {
this("default value");
}
}
However, it would be easy to support this kind of overloading (similarly to method overloading).
private constructors raise an error with JSweet, I think it would be better to permit it and delete it at transpilation time, so we could enjoy the private constructor feature at least in our IDE.
@root packages and their parents are not part of the module hierarchy and should not conain any classes
Normally JSweet adds the missing "this" automatically. Not in that case it seems:
private <T> void installXMLHttpRequestListeners(XMLHttpRequest xhr,Consumer<T> resolve, Consumer<Object> reject) {
xhr.onload = (Event ev) -> {
// TODO bug
//onXMLHttpRequestComplete(xhr, resolve, reject); bug
// what we must write to avoid the bug
this.<T>onXMLHttpRequestComplete(xhr, resolve, reject);
return null;
};
}
It looks like an unusual case so we can probably fix it in the next release.
In module mode, JSweet programs cannot be debugged because they don't have source maps... It is important to have this feature because the module mode is the most comfortable mode to develop applications easily since we can generate bundles.
We need to support decorators: microsoft/TypeScript#2249
To support decorators, I propose a meta annotation @decorator.
For instance (this is still approximate code):
@Decorator
public @interface readonly {
}
@Decorator
public @interface enumerable {
boolean value();
}
public class C {
@readonly
@enumerable(false)
void method() { }
}
public static Globals {
public static <T> void readonly(Function target, String key, TypedPropertyDescriptor<T> descriptor) {
descriptor.writable = false;
}
public static <T> TypedPropertyDescriptor<T> function enumerable(value) {
return function ((Function target, String key, TypedPropertyDescriptor<T> descriptor) => {
descriptor.enumerable = value;
});
}
}
Would transpile to (approximate code also):
class C {
@readonly
@enumerable(false)
method() { }
}
function readonly(target, key, descriptor) {
descriptor.writable = false;
}
function enumerable(value) {
return function (target, key, descriptor) {
descriptor.enumerable = value;
}
}
This this just a proposal that needs to be refined. In particular, the definition of the global decoration methods could be improved and the overall pattern needs to be validated.
For loops variables should be humain-friendly when possible.
Array's forEach function shall be used when possible.
Accessing a valid method through "this" is valid in Java (warning only). JSweet should either report an error, or remove the "this".
class My {
private static Logger log; //...
void x() {
this.log.info(...);
}
}
following
package org.ssatguru.babylonjs;
import static jsweet.dom.Globals.console;
public class CodeSnippet {
public static void main(String args[]){
int i =1;
if (i==1)console.log("is true");
else console.log("is false");
}
}
gives following error during TS compile
[INFO] JSweet transpiler version 1.0.0-SNAPSHOT (build date: 2016-01-16 10:30:13)
ERROR: ';' expected. at org\ssatguru\babylonjs\CodeSnippet.ts(6)
[ERROR] transpilation failed
tools.jar is to be found in the JDK libs. When not found a sound error must request the user to insall a JDK or to configure the java home.
Lookup should be done as follows:
The Java String's length
method should be transpiled to the JS length
property.
I did mvn install
and build failed due to the absence of an executable pandoc
, node
.
Can you document the build instructions/dependencies in the README.md please.
All seemed to work for me after I did the following:
sudo apt-get install pandoc nodejs
## sort out an executable name conflict with another package by opting for nodejs
sudo ln -s /usr/bin/nodejs /usr/bin/node
Currently, JSweet prints out Java errors bud does not go through the actual error reporting API (see the bad looking TranspilationHandler.reportSilentError() method). This is bad for reporting compilation errors in a consistent way.
We need a solution for reporting or ignoring Java errors depending on if the reporting of Java errors is needed or not (for instance, in the Eclipse plugin, it is not needed because Eclipse will report the errors).
Possible solutions are:
The second solution is probably better... clearly more generic and flexible.
It'd be great to have as much support for java.lang.Math as possible.
"babylon.d.ts" has a
class Mesh
with method
clone(name: string, newParent?: Node, doNotCloneChildren?: boolean): Mesh;
JSweet coompiles this to
Clone(....)
that is clone with capital C
The TS compiler fails with this error
ERROR: Property 'Clone' does not exist on type 'Mesh'. at org\ssatguru\babylonjs\TestIt.ts(73)
Here's a small program to Test
import def.babylonjs.babylon.Mesh;
public class Test {
public static void main(String args[]){
Mesh mesh = new Mesh();
Mesh mesh2 = mesh.Clone("cloned mesh");
}
}
To be inline with other languages ("native" or "transpiled") it would be better, to change *.java
to *.jsweet
! So it should also be easier write plugins for different IDEs or editors like Sublime.
Plugin execution not covered by lifecycle configuration: org.codehaus.mojo:exec-maven-plugin:1.4.0:exec (execution: doc-markdown, phase:
generate-sources)
=> Examples and Quickstart:
Plugin execution not covered by lifecycle configuration: org.apache.maven.plugins:maven-antrun-plugin:1.8:run (execution: generate-js, phase:
generate-sources)
=> makes it look like it does not work (but it actually does)
There is currently no equivalent of "typeof myvar" in JSweet, we could have an utility method, statically imported (like union / function / ...) and call String theType = typeof(myvar); in JSweet.
It would also be possible to transpile getClass() to typeof but it doesn't feel like JSweet spirit.
Thanks.
Ran into the following issue with "candies/babylonjs--babylon/2.2.2-SNAPSHOT"
"babylon.d.ts" has a
class Mesh
with method
clone(name: string, newParent?: Node, doNotCloneChildren?: boolean): Mesh;
JSweet coompiles this to
Clone(....)
that is clone with capital C
The TS compiler fails with this error
ERROR: Property 'Clone' does not exist on type 'Mesh'. at org\ssatguru\babylonjs\TestIt.ts(73)
The transpiler should preserve Javadoc comments in the generated code. Optionally inlined comment should be also preserved.
Wildcards are not transpiled correctly. The following code fails:
public class Wildcards {
public void m(I<?> i) {
}
}
class I<T> {
}
Find a way to provide unit tests in JSweet. Jasmine / Karma are standard candies so there is no reason why we could not write unit tests using those tools. It is important to check it though.
Currently, candies are extracted from TSD definition files. The JSweet transpiler relies both on the Java definitions and on the TypeScript ones to transpile (double check). Programmers can submit to TSD new definition files and can also write @Ambiant definitions to support new APIs, however, they cannot write candies directly in Java (in theory they could, but the tsc compiler will complain because it cannot find the TypeScript definition file).
We probably need a way to support pure Java definition so that programmers can write their own candies in Java.
Troubleshooting: This feature can become a problem if people start writing definitions in parallel of the TSD (which should remain the reference). In the future, we also need to sort out this issue by proposing a full equivalence between JSweet and TypeScript definitions (maybe automatize the publication of both format at once).
Normally JSweet automatically adds a this
target when calling a method defined on the current class... however, it does not work when the method has generics and defines it own generics. For example:
public class AddThisOnGenericMethods<T> {
private <U> void m(AddThisOnGenericMethods<U> i) {
}
public <U> void m2(AddThisOnGenericMethods<U> i) {
m(i);
}
public void m3(AddThisOnGenericMethods<String> i) {
m(i);
}
}
Firstly congrats on putting together a very interesting project, nice work (and a lot of work looks like!).
I browsed the java source for jsweet
to gauge the maturity/quality of the code (to see if I should use the project) and I just thought I'd share some impressions that you may or may not choose to act on.
Now that java.util.Optional
is part of Java 8 and this is the compile level for the project then I'd suggest that null is not used anywhere and that where Optional
items are passed as arguments that guava style Preconditions.checkNotNull
checks are made on those arguments.
In companion with the Optional
suggestion there is a lot of mutabiltity floating around and it's not needed. Any non-final field is a flag for closer inspection of usage for me and almost all your fields are non-final. For creating instances of something like JSweetTranspiler
I'd suggest using a fluent builder that creates immutable instances.
I'd also avoid inheritance where possible (see composition vs inheritance discussions, e.g. in Josh Bloch's Essential Java) and default to marking classes as final so that you don't have to support inheritance yourselves. You could also move classes that have internal only function to an .internal
package so it's clear what is in the public API and what is not.
That's my fifty cents for the moment, thanks for the project!
[I report here a question from Satguru for sharing with the community]
Not sure how to use the window.setTimeout() function.
Jsweet defines it as
native public double setTimeout(Object handler, Object timeout, Object... args);
This does not allow me to pass a java function to it
For example
window.setTimout(this::aMethod,0,"abc");
gives following error
The target type of this expression must be a functional interface
The candy processor should be able to find and use the JS in the candies Jar files when available.
It should follow the Webjar conventions to package the JS code. So, programmers would be able to include the definitions and the JS code and it should work right away. Note that the JS file should probably be packaged for commonjs so that we can use the "bundle" option.
From @tdebroc on December 22, 2015 9:2
I have node js in my path in my terminal but Eclipse can't find it:
cannot find Node.js: install first and make sure that the 'node' command is in your execution path jsweet-examples Unknown JSweet Problem
Copied from original issue: cincheo/jsweet-examples#11
Good news - If the jar is packaged properly it works, I am able to successfully share the jar with another project.
And that is so great.
This makes it so easy to share JS libraries. No complicated includes, requires, references. Just add a jar to your classpath and you are good to go :)
Bad news - There seems to be some issue with the maven-plugin. It recognizes the "declaration" option but not the "dtsout" option. The ".d.ts" file is created but in default "target/js" folder.
I tried various things but wasn't successful.Ended up moving the file manually.
Attached is the pom file I was trying.
pom.zip
It should be possible in JSweet to write asm.js modules.
The good news is that Java, by supporting integers and floats, could be a good environment to generate type-checked asm code (so is C++). Of course there would be the limitations imposed by asm.js (only numbers, no strings, no objects, ...). NOTE: on contrary, TypeScript, with its sole number is not well armed to type check asm.js, as said here.
So, the idea would be to have an annotation to generate the "use asm" directive. That could be a specific annotation or a generic one. Let us imagine a generic @StringDirective
annotation. We could have something like:
@StringDirective("use asm")
class MyAsmModule {
public void static m() {
int first = 5;
int second = first;
float f = first;
}
}
Which would generate as the following TypeScript code:
class MyAsmModule {
"use asm"
m() : void {
var first = 5;
var second = first | 0;
var f = first | 0.0;
}
}
NOTE: my knowledge of asm.js being still quite recent, I may be getting some things wrong so please correct me if it is the case.
number(n/2).toFixed(0) generates n/2.toFixed(0) but it should actually generated (n/2).toFixed(0).
Calls to cast methods should always be parenthesized.
It would be great for existing implementations/libraries (even though this is not the main purpose of JSweet) which cannot be structurally changed, to have the option of mapping diffrent method overloadings to diffrent method names. I know, it is not so easily implemented. Especially if it is done with some covenience considered. But would greatly benefit migrators.
When Candies are generated, the TSD translator sets its version as the last digit of the build number.
For instance, if the TSD translator version is 12, then:
The transpiler should be able to refuse candies that will not be supported with a sound message so that users don't believe that it is an API or transpiler bug.
Todo:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.