On Fri, Nov 9, 2012 at 2:33 AM, Brandon Bloom <
snpr...@gmail.com> wrote:
> I'm curious if it's possible (or sane) to target the Closure Compiler's AST
> directly. In particular, I'm interested in building a Node tree with JSType
> information for use with both TypedCodeGenerator-based printing and all the
> wonderful optimization and compression features offered by Compiler.
>
> Here's the background:
>
> The ClojureScript compiler currently emits Google Closure compatible
> JavaScript source code. I am experimenting with migrating towards emitting a
> JavaScript AST, instead of source code strings. See
>
https://github.com/brandonbloom/clojurescript/blob/js-ast/src/clj/cljs/compiler.clj
> and
>
https://github.com/brandonbloom/clojurescript/blob/js-ast/src/clj/cljs/js.clj
>
> I have a few goals with this:
>
> 1) Eliminate the printing side effect, so that the ClojureScript compiler
> can be simplified by rearranging the order of various things without
> worrying about the impact on printing.
> 2) Speed up CLJS compilation by bypassing writing a file to disk and then
> immediately reading it back in and re-parsing it.
> 3) Learn a whole lot of stuff about compilers :-)
>
> In order to get this up and running quickly, I used reflection to hack
> together that to-source function which takes a Node and turns it to
> JavaScript source. I've got all of the key ClojureScript libraries to
> compile using my modified compiler. The missing bit, however, are the type
> annotations. It looks like a pretty complex beast to set up a
> JSTypeRegistry, construct JSTypeExpressions, JSType objects, etc, and attach
> them to the AST. I don't see an obvious way to get the Compiler class and
> the various CompilerInput bits to work directly against an AST instead of a
> source code string of some sort.
>
> Here's some specific questions:
>
> 1) What's the quickest way to get some minimum JSType objects onto my AST?
> At minimum, I need @constructor annotations on a few functions in the output
> of TypedCodeGenerator.
is the goal to write your own coffeescript type inference engine and
attach a type to every node, or to tell closure-compiler about type
contracts, or to just add a few @constructor tags?
If you're tending towards the later, it might be a lot easier just to
use JSDocInfoBuilder and attach JSDocInfo.
> 2) Is the Compiler class up to the task of working with completely synthetic
> ASTs in the absence of source files? What issues will I run into? Has some
> one tried this before?
A year or two ago, there was a proposal to define a common interchange
format for Javascript syntax trees.
http://code.google.com/p/es-lab/wiki/JsonMLASTFormat
http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/jscomp/jsonml/
We abandoned it due to lack of interest, but the ecmascript committee
people might still be pursuing it.
> 3) How stable is the interface I'll need to code against? Are the Rhino or
> JSTypeExpression ASTs changing much? In what ways?
They change often enough that we softly discourage people writing code
directly against the AST, but we understand that there are sometimes
reasonable engineering reasons to do so. Most of the recent changes
can be seen here:
http://code.google.com/p/closure-compiler/source/list?path=/trunk/src/com/google/javascript/jscomp/parsing/IRFactory.java&start=2295
> 4) Is this a use case the Closure Compiler team is interested in supporting?
We tend to be pretty results-oriented, i.e., if that's the best
solution, then it's a solution worth supporting.
So I'd be interested in hearing more about how effective your solution
is. The SourceFile/SourceAst API is pretty rich, and we have existing
clients that use it to read the source code directly from memory
(bypassing file I/O), or to duplicate/cache the AST during incremental
builds, so that you can use the cached AST if the file hasn't changed.
I'm not sure what kind of savings you get from generating the AST
directly.
Nick