-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Architecture: Modify the AST directly #44
Comments
This may take awhile, development will occur in the |
One major issue here is that the TypeScript AST is not the same as the Esprima AST. Hence, we still would have to have generator.js around and maintain two very different code paths. I think this is out of scope for 2.0. |
What does the TS AST have to do with the Esprima JS AST? just to make sure I get this right. |
There was a lot of frustration that occurred in the hours leading up to that comment :) None of this is infeasible from an implementation standpoint, it's an architectural question of "what's the simplest thing to do that accomplishes our goals" and "how much work should ojc do, how much can we leverage existing ES tools". I'm hesitant on the long term plan of having two very different paths (one AST based for ES5/6 generation, one string based for type-checking). Right now, generator.js is used by both paths. Although, over time, the number of There's nothing wrong with the current method of generation. It just results in string output, and that string output needs to be reparsed by Babel/Uglify/ESLint/JSHint/etc. My original comment of: "More importantly, we can expose the AST to clients and allow them to write custom modifiers before passing into escodegen." is still true, but it's also possible to accomplish the same by sending the string output of ojc into Babel and writing a Babel transformer. |
I see what you are getting at. In fact, many people and modules seem to use a similar technique. For instance, WebPack 2 knows that Babel emits ES6 and does some more reading to do dead-code stripping - but it doesn't really pick up the AST. So, the concept is similar. So you used TypeScript for the Type Checker? |
Yep, |
Another issue with the AST approach: JSHint integration relies on its input being a string, as JSHint uses it's own JS parser. |
Modified strategy:
|
Sounds solid to me. But have you taken ES6 into account, as in, how big will the efford be to change the ES5 handling to be ES6 capable? Otherwise there doesn't seem to be any problem. |
The beauty of this (combined with procrastination) is that TypeScript/escodegen/ESTree/estraverse all handle ES6 now :) |
Okay, that super-long name-chain convinced me ;) |
Sadly, escodegen with source maps enabled is incredibly slow (~2 seconds to generate our source bases, compared to ~200ms with 1.1's generator/modifier). That's going to be a deal-breaker for us (at least for now). The problem may be with source-map rather than escodegen (or specifically, escodegen's approach of wrapping the Array IR with source-map's SourceNode and then having source-map generate the string). I should recheck this once escodegen implements their Dumper (estools/escodegen#214). |
(Note: this shouldn't prevent you from using ES6 with OJ. Using the AST vs. using the modifier/compiler has always been about avoiding additional parse/generate steps. Right now you can still use ES6 in the 2.0-wip branch, and you can also pass the result to Babel to transpile back to ES5). |
Without this, I can't think of any reason why I would need to bump semver major. So the next release will probably be 1.2 (with Esprima 2.7 et al.) |
That works for me. :) Ill I wish is to just make sure that when I update my modules with the new support, that I don't run into too many bugs :) |
I've been pondering this issue again recently. There have been speed improvements to the However, one glaring issue is that oj has to output Typescript in addition to JS. The current string-based solution of Modifier.js allows us to easily do this. |
The oj compiler currently modifies lines of code directly (via the Modifier class), rather than operating on the AST. This is due to historical reasons: before source maps became widely supported, I relied on preserving line numbers between oj source and the generated js source to aid debugging.
Now that source maps are common, and escodegen supports them, the compiler should modify the oj AST directly: converting the oj AST into an ECMAScript 5 AST. We can then pass that AST into escodegen to generate the resulting js source.
We can also pass that AST into ESLint (see #40) or 6to5 (http://6to5.org) without having to go through a codegen/reparse pass. More importantly, we can expose the AST to clients and allow them to write custom modifiers before passing into escodegen.
The oj->TypeScript code generator will still be string-based, as the TypeScript compiler doesn't allow AST input, and there is no real specification for a TypeScript AST.
The long term plan:
modifier.js
andgenerator.js
are only used by the typechecker.replacer.js
(ortransformer.js
?) is responsible for replacing/transforming the oj AST to a js AST.Strategy:
modifier.js
andgenerator.js
generator.js
toreplacer.js
. Add debug option to use the replacer rather than the generatorThe text was updated successfully, but these errors were encountered: