Skip to content

Latest commit

 

History

History
742 lines (559 loc) · 16 KB

spec.md

File metadata and controls

742 lines (559 loc) · 16 KB

This document specifies the core ESTree AST and CST node types that support the ES5 grammar.

Node objects

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
}

Identifier

interface Identifier <: Node, Expression, Pattern {
    type: "Identifier";
    name: string;
}

An identifier. Note that an identifier may be an expression or a destructuring pattern.

Literal

interface Literal <: Node, Expression {
    type: "Literal";
    value: string | boolean | null | number | RegExp;
}

A literal token. Note that a literal can be an expression.

RegExpLiteral

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.

Programs

interface Program <: Node {
    type: "Program";
    body: [ Statement ];
}

A complete program source tree.

Functions

interface Function <: Node {
    id: Identifier | null;
    params: [ Pattern ];
    body: BlockStatement;
}

A function declaration or expression.

Statements

interface Statement <: Node { }

Any statement.

ExpressionStatement

interface ExpressionStatement <: Statement {
    type: "ExpressionStatement";
    expression: Expression;
}

An expression statement, i.e., a statement consisting of a single expression.

BlockStatement

interface BlockStatement <: Statement {
    type: "BlockStatement";
    body: [ Statement ];
}

A block statement, i.e., a sequence of statements surrounded by braces.

EmptyStatement

interface EmptyStatement <: Statement {
    type: "EmptyStatement";
}

An empty statement, i.e., a solitary semicolon.

DebuggerStatement

interface DebuggerStatement <: Statement {
    type: "DebuggerStatement";
}

A debugger statement.

WithStatement

interface WithStatement <: Statement {
    type: "WithStatement";
    object: Expression;
    body: Statement;
}

A with statement.

Control flow

ReturnStatement

interface ReturnStatement <: Statement {
    type: "ReturnStatement";
    argument: Expression | null;
}

A return statement.

LabeledStatement

interface LabeledStatement <: Statement {
    type: "LabeledStatement";
    label: Identifier;
    body: Statement;
}

A labeled statement, i.e., a statement prefixed by a break/continue label.

BreakStatement

interface BreakStatement <: Statement {
    type: "BreakStatement";
    label: Identifier | null;
}

A break statement.

ContinueStatement

interface ContinueStatement <: Statement {
    type: "ContinueStatement";
    label: Identifier | null;
}

A continue statement.

Choice

IfStatement

interface IfStatement <: Statement {
    type: "IfStatement";
    test: Expression;
    consequent: Statement;
    alternate: Statement | null;
}

An if statement.

SwitchStatement

interface SwitchStatement <: Statement {
    type: "SwitchStatement";
    discriminant: Expression;
    cases: [ SwitchCase ];
}

A switch statement.

SwitchCase

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.

Exceptions

ThrowStatement

interface ThrowStatement <: Statement {
    type: "ThrowStatement";
    argument: Expression;
}

A throw statement.

TryStatement

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.

CatchClause

interface CatchClause <: Node {
    type: "CatchClause";
    param: Pattern;
    body: BlockStatement;
}

A catch clause following a try block.

Loops

WhileStatement

interface WhileStatement <: Statement {
    type: "WhileStatement";
    test: Expression;
    body: Statement;
}

A while statement.

DoWhileStatement

interface DoWhileStatement <: Statement {
    type: "DoWhileStatement";
    body: Statement;
    test: Expression;
}

A do/while statement.

ForStatement

interface ForStatement <: Statement {
    type: "ForStatement";
    init: VariableDeclaration | Expression | null;
    test: Expression | null;
    update: Expression | null;
    body: Statement;
}

A for statement.

ForInStatement

interface ForInStatement <: Statement {
    type: "ForInStatement";
    left: VariableDeclaration |  Expression;
    right: Expression;
    body: Statement;
}

A for/in statement.

Declarations

interface Declaration <: Statement { }

Any declaration node. Note that declarations are considered statements; this is because declarations can appear in any statement context.

FunctionDeclaration

interface FunctionDeclaration <: Function, Declaration {
    type: "FunctionDeclaration";
    id: Identifier;
}

A function declaration. Note that unlike in the parent interface Function, the id cannot be null.

VariableDeclaration

interface VariableDeclaration <: Declaration {
    type: "VariableDeclaration";
    declarations: [ VariableDeclarator ];
    kind: "var";
}

A variable declaration.

VariableDeclarator

interface VariableDeclarator <: Node {
    type: "VariableDeclarator";
    id: Pattern;
    init: Expression | null;
}

A variable declarator.

Expressions

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.

ThisExpression

interface ThisExpression <: Expression {
    type: "ThisExpression";
}

A this expression.

ArrayExpression

interface ArrayExpression <: Expression {
    type: "ArrayExpression";
    elements: [ Expression | null ];
}

An array expression.

ObjectExpression

interface ObjectExpression <: Expression {
    type: "ObjectExpression";
    properties: [ Property ];
}

An object expression.

Property

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.

FunctionExpression

interface FunctionExpression <: Function, Expression {
    type: "FunctionExpression";
}

A function expression.

Unary operations

UnaryExpression

interface UnaryExpression <: Expression {
    type: "UnaryExpression";
    operator: UnaryOperator;
    prefix: boolean;
    argument: Expression;
}

A unary operator expression.

UnaryOperator

enum UnaryOperator {
    "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"
}

A unary operator token.

UpdateExpression

interface UpdateExpression <: Expression {
    type: "UpdateExpression";
    operator: UpdateOperator;
    argument: Expression;
    prefix: boolean;
}

An update (increment or decrement) operator expression.

UpdateOperator

enum UpdateOperator {
    "++" | "--"
}

An update (increment or decrement) operator token.

Binary operations

BinaryExpression

interface BinaryExpression <: Expression {
    type: "BinaryExpression";
    operator: BinaryOperator;
    left: Expression;
    right: Expression;
}

A binary operator expression.

BinaryOperator

enum BinaryOperator {
    "==" | "!=" | "===" | "!=="
         | "<" | "<=" | ">" | ">="
         | "<<" | ">>" | ">>>"
         | "+" | "-" | "*" | "/" | "%"
         | "|" | "^" | "&" | "in"
         | "instanceof"
}

A binary operator token.

AssignmentExpression

interface AssignmentExpression <: Expression {
    type: "AssignmentExpression";
    operator: AssignmentOperator;
    left: Pattern | Expression;
    right: Expression;
}

An assignment operator expression.

AssignmentOperator

enum AssignmentOperator {
    "=" | "+=" | "-=" | "*=" | "/=" | "%="
        | "<<=" | ">>=" | ">>>="
        | "|=" | "^=" | "&="
}

An assignment operator token.

LogicalExpression

interface LogicalExpression <: Expression {
    type: "LogicalExpression";
    operator: LogicalOperator;
    left: Expression;
    right: Expression;
}

A logical operator expression.

LogicalOperator

enum LogicalOperator {
    "||" | "&&"
}

A logical operator token.

MemberExpression

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.

ConditionalExpression

interface ConditionalExpression <: Expression {
    type: "ConditionalExpression";
    test: Expression;
    alternate: Expression;
    consequent: Expression;
}

A conditional expression, i.e., a ternary ?/: expression.

CallExpression

interface CallExpression <: Expression {
    type: "CallExpression";
    callee: Expression;
    arguments: [ Expression ];
}

A function or method call expression.

NewExpression

interface NewExpression <: CallExpression {
    type: "NewExpression";
}

A new expression.

SequenceExpression

interface SequenceExpression <: Expression {
    type: "SequenceExpression";
    expressions: [ Expression ];
}

A sequence expression, i.e., a comma-separated sequence of expressions.

Patterns

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 { }

Concrete syntax

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.

Child-node reference

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).

Token

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).

Nontoken

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.