The CoffeeScript AST format is much pretty much exactly like JavaScript's. Only: it has a few new node types, a few new properties in existing types, and some unsupported ones are removed.
-
New node types are always prefixed with Coffee, eg:
CoffeeLoopStatement
. -
New properties are always prefixed with underscore, eg:
_prefix
inThisExpression
. -
Types supported in JS but not Coffee are removed, eg:
WithStatement
.
Refer to the Mozilla's Parser API spec for the JavaScript version.
In the command line, you can use the --ast
option:
js2c file.coffee --ast
Programatically, just check the result's ast
property:
result = js2coffee.build(source);
console.log(result.ast);
An example of an AST:
/* echo "alert()" | js2c --ast */
{ type: 'Program',
body:
[ { type: 'ExpressionStatement',
expression:
{ type: 'CallExpression',
callee: { type: 'Identifier', name: 'alert' },
arguments: [],
_isStatement: true } } ],
comments: [] }
A few pointers on notation:
-
Array properties are denoted with
[ ... ]
. (eg:expressions
in an ArrayExpression) -
Optional properties are denoted with
*
, meaning they can benull
in some cases. (eg:argument
of a ReturnStatement)
A block contains many statements. (eg, IfStatement, ExpressionStatement).
Fragments of a statement (eg, ObjectExpression, Identifier).
These are nodes available in both CoffeeScript and JavaScript.
The root node.
body
: [ Statement, ... ]
A sequence of statements. Usually belongs to a loop like WhileStatement, or an IfStatement, or some other.
body
: [ Statement, ... ]_negative
: Boolean (true
if it'sunless
)
A statement with one expression in it.
expression
: Expression
Just an identifier.
name
: String
A conditional. This encompasses both the if
and else
parts.
test
: Expressionconsequent
: BlockStatementalternate
: BlockStatement *
Just break
, for breaking out of loops. No properties.
Just continue
, for breaking out of loops. No properties.
Can have its argument missing (eg: return
).
argument
: Expression *
argument
: Expression
A try block. Encompasses all try
, catch
, and finally
.
block
: BlockStatement (the try)handler
: CatchClause * (the catch)finalizer
: BlockStatement * (the finally)
A handler in a TryStatement. (eg: catch err
)
param
: Identifierbody
: BlockStatement
Invokes a debugger. No properties.
Just this
.
_prefix
: Boolean (true if rendered as@
)
elements
: [ Expression, ... ] *
properties
: [ Property, ... ] *_braced
: Boolean (true if braced, eg{ a: 1 }
)_last
: Boolean (true if it's the last expression in the scope)
The _last
property is set to true
when the expression is the last in the
scope, such as in this example. In these cases, js2coffee will omit the braces
and won't indent the object.
/* assume there's nothing else in the file */
({a:2, c:3});
Inside ObjectExpression.
kind
: "init" (not sure what this is)key
: Expression (usually Identifier or Literal)value
: Expression
(note: id
is removed from function expressions.)
params
: [ Identifier, ... ]defaults
: [ Identifier, ... ] ]body
: BlockStatement_parenthesized
: Boolean (true if parenthesized, eg(-> ...)
)
A prefix expression. Note that this operator also be not
, which is not
available in JS.
operator
: String (eg: "void", "!")argument
: Expression
left
: Expressionoperator
: String (eg:+
)right
: Expression
An assignment. Also covers shorthand like +=
.
left
: Identifieroperator
: String (eg:+=
)right
: Expression
An increment or decrement. (a++
)
prefix
: Booleanoperator
: String (eg:++
)argument
: Identifier (eg:a
)
The ternary operator. (if a then b else c
)
test
: Expression (the if)consequent
: Expression (the then)alternate
: Expression (the else)
Instanciation (eg: new X()
).
callee
: Expression (usually an Identifier)arguments
: [ Expression, ... ]
A function call.
callee
: Expression (usually an Identifier)arguments
: [ Expression, ... ]_isStatement
: Boolean (true if it has no parentheses)
Scope resolution (eg: this.foo
).
computed
: Boolean (true ifa[b]
, false ifa.b
)object
: Expression (left side)property
: Expression (right side)
discriminant
: Expressioncases
: [ SwitchCase, ... ]
A case inside a SwitchStatement. Then test
is not present, it's the else
.
type
: ??test
: Expression *consquent
: BlockStatement
name
: String
raw
: raw code as a string (eg:"\"hello\""
)value
: whatever the value is (eg:hello
)
These are CoffeeScript-specific AST types:
a comma-separated list (eg: when a, b
).
expressions
: [ Expression, ... ]
Prototype resolution operator. Similar to MemberExpression.
object
: BlockStatementproperty
: Expression (usually Identifier)computed
: Boolean (true ifa::[b]
)
Examples:
a::b
# { type: 'CoffeePrototypeExpression',
# object: { type: 'Identifier', name: 'a' },
# property: { type: 'Identifier', name: 'b' } }
A forever loop. Compiles to loop
.
body
: BlockStatement
Examples:
loop
a()
# { type: 'CoffeeLoopExpression',
# body: {
# type: 'BlockStatement',
# body: { ... } }
A backtick-wrapped JS expression.
value
: the raw value
Example:
`undefined`
# { type: 'CoffeeEscapedExpression',
# value: 'undefined' }
Represents do -> ...
.
function
: FunctionExpression
Example:
do -> ...
# { type: 'CoffeeDoExpression'
# function: {
# type: 'FunctionExpression'
# body: { ... } } }
A ### ... ###
comment.
value
: String
A # ...
comment.
value
: String
These node types are not present in CoffeeScript ASTs, but are present in JavaScript ASTs.
turned into a sequence of ExpressionStatements.
removed from the tree.
converted into a = ->
(AssignmentExpression).
converted into a = ->
(AssignmentExpression).
converted into a = ->
(AssignmentExpression).
throws an error; unsupported in CoffeeScript.
throws an error; unsupported in CoffeeScript.
Converted to WhileStatement loops.
Converted to WhileStatement loops.
Converted to CoffeeLoopStatement loops.
For destructuring
For destructuring