cincheo / jsweet-candy-js-quickstart

A sample project to build a JSweet candy from an existing JavaScript library
0 stars 3 forks source link

Online TypeScript to Java API translator file structure #3

Open kito99 opened 8 years ago

kito99 commented 8 years ago

So, I'm trying out the tool (http://www.jsweet.org/online-typescript-to-java-api-translator/), and I'm having trouble getting it to work with PrimeNG. PrimeNG is a little different, since it includes quite a few components (rather than a single file like jquery.d.ts). So the structure is like this:

primeng.d.ts components -> accordion -> accordion.d.t.s autocomplete -> autocomplete.d.t.s breadcrumb -> breadcrumb.d.t.s button -> button.d.t.s ...

(See https://github.com/primefaces/primeng/)

First, it seems like the translator can'd handle any extra files, which I find a bit odd. If I upload the repository as-is, it ignores everything and tells me there are no errors.

If I remove everything except for d.t.s files, it'll process only primeng.d.ts. So, in order to ensure the components were processed, I flattened the directory structure so it's like this:

primeng.d.ts accordion -> accordion.d.t.s autocomplete -> autocomplete.d.t.s breadcrumb -> breadcrumb.d.t.s button -> button.d.t.s ...

When I upload this, the translator ignores everything and tells me there are no errors. Any idea why? (sample file attached).

primeng 2.zip

renaudpawlak commented 8 years ago

The translator was tested mostly with DefinititlyTyped examples (i.e. only one d.ts file per library)... so that's not surprising that some adjustments are required. I will check and fix ASAP.

renaudpawlak commented 8 years ago

Ok. I spent a while on it. It's not straightforward because of the quite important difference between what has been done so far and the Angular 2 way of organizing the modules.

So I have made some fixes to the translator and I have run it on the zip you sent. Here is the output:

tmpout.zip

I have not deployed the online translator yet because I would first like to make sure with you that it looks like the output you are expecting....

Note that the generated file heavily depends on Angular (of course). So you will eventually have to implement more Angular definitions in your project.

kito99 commented 8 years ago

Thanks so much! Looking at the output, it looks like there's an extra folder level. For example:

datascroller 
   datascroller
         DataScroller.java
         ...

DataScroller.java has the package name def.primeng.datascroller.datascroller.

And primeng (the main module) has this structure:

primeng primeng package-info.java

The package name is def.primeng.primeng.primeng.

I wonder if it'd be better to leave the original directory structure intact for the input zip file like this:

primeng primeng.d.t.s components component1 component1.d.ts component2 component2.d.t.s ...

I have attached a new zip file in case this simplifies things. primeng.zip

kito99 commented 8 years ago

Two more things:

(1) One of the compilation errors is related to being unable to find the Function class. As this is a standard JavaScript class, shouldn't this be defined? Or should I import the Java Function class?

(2) I see what you mean about the Angular dependencies. I didn't realize the basic Angular classes in the quickstart didn't include most of the framework. I'm not sure I have time to manually implement them all. Now that you have modified the generator for PrimeNG, do you think it could parse Angular2?

renaudpawlak commented 8 years ago

I am still quite puzzled on how to deal with Angular modules and d.ts files...

But, from what I can see from primeng examples, it looks that all you need to do is to import the components from the primeng/primeng module. Like it is done here: https://github.com/primefaces/primeng-quickstart/blob/master/app/app.module.ts#L8

Looking closer, that's normal actually. That's because the primeng.d.ts module just exports all the components.

Here is a snippet of primeng.d.ts:

export * from './components/common/api';
export * from './components/common/shared';
export * from './components/accordion/accordion';
export * from './components/autocomplete/autocomplete';
export * from './components/breadcrumb/breadcrumb';
export * from './components/button/button';
export * from './components/calendar/calendar';
export * from './components/carousel/carousel';
export * from './components/codehighlighter/codehighlighter';
export * from './components/contextmenu/contextmenu';
export * from './components/chart/chart';
[...]

So, unless I misunderstand something, what it means actually is that all the classes should probably be located in the in the def.primeng.primeng module. The reason it does not work (yet) is that the JSweet API translator does not support the export * from ... construct...

So, what I will do is that I will try to support the export * from ... construct. If too complicated for the short delay, I will probably add some hacky parameter to the generation engine in order to generate what I need.

(1) One of the compilation errors is related to being unable to find the Function class. As this is a standard JavaScript class, shouldn't this be defined? Or should I import the Java Function class?

Sure, if it is a JavaScript Function instance, you should import jsweet.lang.Function. Do not confuse with a functional type (p:Type1) => Type2, where you need to use a Java functional type (java.util.function.Function<Type1, Type2>).

(2) I see what you mean about the Angular dependencies. I didn't realize the basic Angular classes in the quickstart didn't include most of the framework. I'm not sure I have time to manually implement them all. Now that you have modified the generator for PrimeNG, do you think it could parse Angular2?

Yes, it should be able to do it because it is a similar structure. But I guess I will also have to fix the same kind of issues as with the export * from ... construct. I hope I'll be able to find a hack that will allow me to have something working soon. I'll tell you ASAP.

Thank you for your patience.

kito99 commented 8 years ago

Thanks for taking another stab at this, @renaudpawlak!

renaudpawlak commented 8 years ago

Ok, here is the state of progress.

I have supported partially the export * from construct and it works better for primeng. However, for Angular itself, I would need to support much more things for automated translation.

So, what I did so far, is that I have manually added all the Angular 2 APIs needed by primeng to compile.

That compiles fine and I have pushed the primeng definitions in the https://github.com/cincheo/jsweet-angular2-quickstart project. You can now update and try them out.

That said, when I looked at a more complex project (tour-of-heroes tutorial), I noticed that some other constructs/APIs were missing. So, I am pretty sure that you will hit missing features when you will want to go further.

It seems very hard to have a complete API soon enough. However, a possible way to go would be to have a sample (TypeScript) project of what you would want to talk about in your presentation. Having that project, I could probably provide the needed JSweet support on time.

kito99 commented 8 years ago

Thanks!

I forked jsweet-angualr2-qickstart: https://github.com/kito99/angular-primeng-jsweet-todo-client. I made a few minor changes to try and add a PrimeNG button to the main component, and I hit a wall. After running npm start, I'm getting this error:

app/app/module.ts(7,22): error TS2307: Cannot find module '../def/module'.

I added a single line to Globals.java:

import def.primeng.primeng.Button;

This is the generated TypeScript:

/* Generated from Java with JSweet 1.2.0-SNAPSHOT - http://www.jsweet.org */
export import component = require('./component/module');
export import module = require('./module/module');
import platform_browser_dynamic = require("@angular/platform-browser-dynamic"); 
import primeng = require("primeng/primeng"); 
import app = require("./module"); 
import def = require("../def/module"); 
import platformBrowserDynamic = platform_browser_dynamic.platformBrowserDynamic;

import AppModule = app.module.AppModule;

import Button = def.primeng.primeng.Button;

var foo : string = "";
platformBrowserDynamic().bootstrapModule(AppModule);

Indeed def/module does not exist.

Any ideas?

renaudpawlak commented 8 years ago

Well, my fault, but I did not have time to test that primeng actually works :( Maybe the API is still wrong.

There is clearly a @Root annotation missing on the def.primeng package (I have commited it on jsweet-angualr2-qickstart). Also, to use primeng with TypeScript, I guess it needs to be added to the package.json (commited too). Maybe the @Root annotation is misplaced or some @Module annotation needs to be added, but I have hard time understanding how to use primeng.

I see that maybe I need to follow the configuration steps there: http://www.primefaces.org/primeng/#/setup

Right?

I will try this setup in order to enable primeng on the quickstart project and see what happens... but according to the setup link, It looks like components should have been located in a component package (the idea is to refactor the API until it fits the expected TypeScript API)...

renaudpawlak commented 8 years ago

Ok. After a small test, I am pretty sure that it will work just by adding the @Root annotation like I did on the jsweet-angular2-quickstart project. I will now try a more in-depth test by adapting the primeng-quickstart project and see what happens...

kito99 commented 8 years ago

Cool. I'll take a look at this now.

You may want to use primeng-quickstart-webpack;. I was unable to get primeng-quickstart to run (even before adding jsweet).

kito99 commented 8 years ago

Actually, it looks like someone pointed out the issue with the regular quickstart: https://github.com/primefaces/primeng-quickstart/issues/18 (see the last comment).