This document specifies the core ESTree AST and CST node types that support the ES5 grammar.
- Node objects
- Identifier
- Literal
- Programs
- Functions
- Statements
- Declarations
- Expressions
- Patterns
- Concrete syntax
ESTree AST nodes are represented as Node
objects, which may have any prototype inheritance but which implement the following interface:
interface Node {
type: string;
sourceElements: [ ChildReference | Token | Nontoken ] | null;
loc: SourceLocation | null;
}
The type
field is a string representing the AST variant type. Each subtype of Node
is documented below with the specific string of its type
field. You can use this field to determine which interface a node implements.
The sourceElements
field represents the "concrete syntax" of the node. If the node contains no information about the source, the field is null
; otherwise it is a list of source input elements and references to child nodes. Any (sub)tree in which sourceElements
is complete on every node (i.e., there are no unreferenced child nodes and all necessary whitespace and punctuation is included) can be rendered by depth-first concatenation (with respect to references).
The loc
field represents the source location information of the node. If the node contains no information about the source location, the field is null
; otherwise it is an object consisting of a start position (the position of the first character of the parsed source region) and an end position (the position of the first character after the parsed source region):
interface SourceLocation {
source: string | null;
start: Position;
end: Position;
}
Each Position
object consists of a line
number (1-indexed) and a column
number (0-indexed):
interface Position {
line: number; // >= 1
column: number; // >= 0
}
interface Identifier <: Node, Expression, Pattern {
type: "Identifier";
name: string;
}
An identifier. Note that an identifier may be an expression or a destructuring pattern.
interface Literal <: Node, Expression {
type: "Literal";
value: string | boolean | null | number | RegExp;
}
A literal token. Note that a literal can be an expression.
interface RegExpLiteral <: Literal {
regex: {
pattern: string;
flags: string;
};
}
The regex
property allows regexes to be represented in environments that don’t
support certain flags such as y
or u
. In environments that don't support
these flags value
will be null
as the regex can't be represented natively.
interface Program <: Node {
type: "Program";
body: [ Statement ];
}
A complete program source tree.
interface Function <: Node {
id: Identifier | null;
params: [ Pattern ];
body: BlockStatement;
}
A function declaration or expression.
interface Statement <: Node { }
Any statement.
interface ExpressionStatement <: Statement {
type: "ExpressionStatement";
expression: Expression;
}
An expression statement, i.e., a statement consisting of a single expression.
interface BlockStatement <: Statement {
type: "BlockStatement";
body: [ Statement ];
}
A block statement, i.e., a sequence of statements surrounded by braces.
interface EmptyStatement <: Statement {
type: "EmptyStatement";
}
An empty statement, i.e., a solitary semicolon.
interface DebuggerStatement <: Statement {
type: "DebuggerStatement";
}
A debugger
statement.
interface WithStatement <: Statement {
type: "WithStatement";
object: Expression;
body: Statement;
}
A with
statement.
interface ReturnStatement <: Statement {
type: "ReturnStatement";
argument: Expression | null;
}
A return
statement.
interface LabeledStatement <: Statement {
type: "LabeledStatement";
label: Identifier;
body: Statement;
}
A labeled statement, i.e., a statement prefixed by a break
/continue
label.
interface BreakStatement <: Statement {
type: "BreakStatement";
label: Identifier | null;
}
A break
statement.
interface ContinueStatement <: Statement {
type: "ContinueStatement";
label: Identifier | null;
}
A continue
statement.
interface IfStatement <: Statement {
type: "IfStatement";
test: Expression;
consequent: Statement;
alternate: Statement | null;
}
An if
statement.
interface SwitchStatement <: Statement {
type: "SwitchStatement";
discriminant: Expression;
cases: [ SwitchCase ];
}
A switch
statement.
interface SwitchCase <: Node {
type: "SwitchCase";
test: Expression | null;
consequent: [ Statement ];
}
A case
(if test
is an Expression
) or default
(if test === null
) clause in the body of a switch
statement.
interface ThrowStatement <: Statement {
type: "ThrowStatement";
argument: Expression;
}
A throw
statement.
interface TryStatement <: Statement {
type: "TryStatement";
block: BlockStatement;
handler: CatchClause | null;
finalizer: BlockStatement | null;
}
A try
statement. If handler
is null
then finalizer
must be a BlockStatement
.
interface CatchClause <: Node {
type: "CatchClause";
param: Pattern;
body: BlockStatement;
}
A catch
clause following a try
block.
interface WhileStatement <: Statement {
type: "WhileStatement";
test: Expression;
body: Statement;
}
A while
statement.
interface DoWhileStatement <: Statement {
type: "DoWhileStatement";
body: Statement;
test: Expression;
}
A do
/while
statement.
interface ForStatement <: Statement {
type: "ForStatement";
init: VariableDeclaration | Expression | null;
test: Expression | null;
update: Expression | null;
body: Statement;
}
A for
statement.
interface ForInStatement <: Statement {
type: "ForInStatement";
left: VariableDeclaration | Expression;
right: Expression;
body: Statement;
}
A for
/in
statement.
interface Declaration <: Statement { }
Any declaration node. Note that declarations are considered statements; this is because declarations can appear in any statement context.
interface FunctionDeclaration <: Function, Declaration {
type: "FunctionDeclaration";
id: Identifier;
}
A function declaration. Note that unlike in the parent interface Function
, the id
cannot be null
.
interface VariableDeclaration <: Declaration {
type: "VariableDeclaration";
declarations: [ VariableDeclarator ];
kind: "var";
}
A variable declaration.
interface VariableDeclarator <: Node {
type: "VariableDeclarator";
id: Pattern;
init: Expression | null;
}
A variable declarator.
interface Expression <: Node { }
Any expression node. Since the left-hand side of an assignment may be any expression in general, an expression can also be a pattern.
interface ThisExpression <: Expression {
type: "ThisExpression";
}
A this
expression.
interface ArrayExpression <: Expression {
type: "ArrayExpression";
elements: [ Expression | null ];
}
An array expression.
interface ObjectExpression <: Expression {
type: "ObjectExpression";
properties: [ Property ];
}
An object expression.
interface Property <: Node {
type: "Property";
key: Literal | Identifier;
value: Expression;
kind: "init" | "get" | "set";
}
A literal property in an object expression can have either a string or number as its value
. Ordinary property initializers have a kind
value "init"
; getters and setters have the kind values "get"
and "set"
, respectively.
interface FunctionExpression <: Function, Expression {
type: "FunctionExpression";
}
A function
expression.
interface UnaryExpression <: Expression {
type: "UnaryExpression";
operator: UnaryOperator;
prefix: boolean;
argument: Expression;
}
A unary operator expression.
enum UnaryOperator {
"-" | "+" | "!" | "~" | "typeof" | "void" | "delete"
}
A unary operator token.
interface UpdateExpression <: Expression {
type: "UpdateExpression";
operator: UpdateOperator;
argument: Expression;
prefix: boolean;
}
An update (increment or decrement) operator expression.
enum UpdateOperator {
"++" | "--"
}
An update (increment or decrement) operator token.
interface BinaryExpression <: Expression {
type: "BinaryExpression";
operator: BinaryOperator;
left: Expression;
right: Expression;
}
A binary operator expression.
enum BinaryOperator {
"==" | "!=" | "===" | "!=="
| "<" | "<=" | ">" | ">="
| "<<" | ">>" | ">>>"
| "+" | "-" | "*" | "/" | "%"
| "|" | "^" | "&" | "in"
| "instanceof"
}
A binary operator token.
interface AssignmentExpression <: Expression {
type: "AssignmentExpression";
operator: AssignmentOperator;
left: Pattern | Expression;
right: Expression;
}
An assignment operator expression.
enum AssignmentOperator {
"=" | "+=" | "-=" | "*=" | "/=" | "%="
| "<<=" | ">>=" | ">>>="
| "|=" | "^=" | "&="
}
An assignment operator token.
interface LogicalExpression <: Expression {
type: "LogicalExpression";
operator: LogicalOperator;
left: Expression;
right: Expression;
}
A logical operator expression.
enum LogicalOperator {
"||" | "&&"
}
A logical operator token.
interface MemberExpression <: Expression, Pattern {
type: "MemberExpression";
object: Expression;
property: Expression;
computed: boolean;
}
A member expression. If computed
is true
, the node corresponds to a computed (a[b]
) member expression and property
is an Expression
. If computed
is false
, the node corresponds to a static (a.b
) member expression and property
is an Identifier
.
interface ConditionalExpression <: Expression {
type: "ConditionalExpression";
test: Expression;
alternate: Expression;
consequent: Expression;
}
A conditional expression, i.e., a ternary ?
/:
expression.
interface CallExpression <: Expression {
type: "CallExpression";
callee: Expression;
arguments: [ Expression ];
}
A function or method call expression.
interface NewExpression <: CallExpression {
type: "NewExpression";
}
A new
expression.
interface SequenceExpression <: Expression {
type: "SequenceExpression";
expressions: [ Expression ];
}
A sequence expression, i.e., a comma-separated sequence of expressions.
Destructuring binding and assignment are not part of ES6, but all binding positions accept Pattern
to allow for destructuring in ES6. Nevertheless, for ES5, the only Pattern
subtype is Identifier
.
interface Pattern <: Node { }
Whitespace, comments, and the exact character sequences comprising Literal nodes are part of the lexical grammar, but not part of the abstract syntax. Their representation is completely optional.
interface ChildReference {
reference: string;
}
reference
names the property identifying a referenced child (e.g., expression
for ChildReferences on ExpressionStatement nodes), optionally followed by #next
when identifying the next unreferenced member of a list-valued property (e.g., body#next
for ChildReferences on BlockStatement nodes).
interface Token <: ChildReference {
element: string;
reference: string | null;
value: string | null;
}
Tokens are relevant to abstract syntax. The element
field is a string identifying input element type ("Keyword", "Identifier", "Punctuator", "StringLiteral", etc.).
The reference
field is optional (being useful only when there is already a field matching the input token, e.g. operator
on BinaryExpression nodes), and if absent must be replaced by a value
of the exact character(s) corresponding to the token (e.g., function
, (
, 0xCAFE
).
interface Nontoken {
element: string;
value: string;
}
Nontokens are not relevant to abstract syntax. The element
field is a string identifying type (one of "WhiteSpace", "LineTerminator", "CommentHead", "CommentBody", "CommentTail").
The value
field is identical to the same field on Nontoken elements—a string of the exact character(s) corresponding to it.