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:
_prefixinThisExpression. -
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 --astProgramatically, 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:expressionsin an ArrayExpression) -
Optional properties are denoted with
*, meaning they can benullin some cases. (eg:argumentof 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 (trueif 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