ESTree AST Descriptor Syntax - gregswindle/eslint-plugin-crc GitHub Wiki
This document specifies the extensions to the core ESTree AST types to support the ES5, ES6 (ES2015), ES7 (ES2016), and ES8 (2017) grammars.
๐ Estree/estree. (2017, October 05). Retrieved December 01, 2017,
from https://github.com/estree/estree
-
ES5 / ES2009 AST node types
- Node objects
- Identifier
- Literal
- Programs
- Functions
- Statements
- Declarations
- Expressions
- Patterns
- ES6 / ES2015 AST node types
- ES7 / ES2016 node types
- ES8 / ES2017 AST node types
ESTree AST nodes are represented as Node objects, which may have any prototype inheritance but which implement the following interface:
interface Node {
type: string;
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 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 <: Expression, Pattern {
type: "Identifier";
name: string;
}An identifier. Note that an identifier may be an expression or a destructuring pattern.
interface Literal <: 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: [ Directive | Statement ];
}A complete program source tree.
interface Function <: Node {
id: Identifier | null;
params: [ Pattern ];
body: FunctionBody;
}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 Directive <: Node {
type: "ExpressionStatement";
expression: Literal;
directive: string;
}A directive from the directive prologue of a script or function.
The directive property is the raw string source of the directive without quotes.
interface BlockStatement <: Statement {
type: "BlockStatement";
body: [ Statement ];
}A block statement, i.e., a sequence of statements surrounded by braces.
interface FunctionBody <: BlockStatement {
body: [ Directive | Statement ];
}The body of a function, which is a block statement that may begin with directives.
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 | Pattern;
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 <: Expression {
type: "NewExpression";
callee: Expression;
arguments: [ Expression ];
}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 ES5, but all binding positions accept Pattern to allow for destructuring in ES6. Nevertheless, for ES5, the only Pattern subtype is Identifier.
interface Pattern <: Node { }extend interface Program {
sourceType: "script" | "module";
body: [ Statement | ModuleDeclaration ];
}Parsers must specify sourceType as "module" if the source has been parsed as an ES6 module. Otherwise, sourceType must be "script".
extend interface Function {
generator: boolean;
}interface ForOfStatement <: ForInStatement {
type: "ForOfStatement";
}extend interface VariableDeclaration {
kind: "var" | "let" | "const";
}interface Super <: Node {
type: "Super";
}
extend interface CallExpression {
callee: Expression | Super;
}
extend interface MemberExpression {
object: Expression | Super;
}A super pseudo-expression.
interface SpreadElement <: Node {
type: "SpreadElement";
argument: Expression;
}
extend interface ArrayExpression {
elements: [ Expression | SpreadElement | null ];
}
extend interface CallExpression {
arguments: [ Expression | SpreadElement ];
}Spread expression, e.g., [head, ...iter, tail], f(head, ...iter, ...tail).
FIXME: This describes the Esprima and Acorn behaviors, which is not currently aligned with the SpiderMonkey behavior.
extend interface AssignmentExpression {
left: Pattern;
}Note that pre-ES6 code was allowed to pass references around and so left was much more liberal; an implementation might choose to continue using old definition if it needs to support such legacy code.
extend interface Property {
key: Expression;
method: boolean;
shorthand: boolean;
computed: boolean;
}interface ArrowFunctionExpression <: Function, Expression {
type: "ArrowFunctionExpression";
body: FunctionBody | Expression;
expression: boolean;
}A fat arrow function expression, e.g., let foo = (bar) => { /* body */ }.
interface YieldExpression <: Expression {
type: "YieldExpression";
argument: Expression | null;
delegate: boolean;
}A yield expression.
interface TemplateLiteral <: Expression {
type: "TemplateLiteral";
quasis: [ TemplateElement ];
expressions: [ Expression ];
}interface TaggedTemplateExpression <: Expression {
type: "TaggedTemplateExpression";
tag: Expression;
quasi: TemplateLiteral;
}interface TemplateElement <: Node {
type: "TemplateElement";
tail: boolean;
value: {
cooked: string;
raw: string;
};
}interface AssignmentProperty <: Property {
type: "Property"; // inherited
value: Pattern;
kind: "init";
method: false;
}
interface ObjectPattern <: Pattern {
type: "ObjectPattern";
properties: [ AssignmentProperty ];
}interface ArrayPattern <: Pattern {
type: "ArrayPattern";
elements: [ Pattern | null ];
}interface RestElement <: Pattern {
type: "RestElement";
argument: Pattern;
}interface AssignmentPattern <: Pattern {
type: "AssignmentPattern";
left: Pattern;
right: Expression;
}interface Class <: Node {
id: Identifier | null;
superClass: Expression | null;
body: ClassBody;
}interface ClassBody <: Node {
type: "ClassBody";
body: [ MethodDefinition ];
}interface MethodDefinition <: Node {
type: "MethodDefinition";
key: Expression;
value: FunctionExpression;
kind: "constructor" | "method" | "get" | "set";
computed: boolean;
static: boolean;
}interface ClassDeclaration <: Class, Declaration {
type: "ClassDeclaration";
id: Identifier;
}interface ClassExpression <: Class, Expression {
type: "ClassExpression";
}interface MetaProperty <: Expression {
type: "MetaProperty";
meta: Identifier;
property: Identifier;
}interface ModuleDeclaration <: Node { }A module import or export declaration.
interface ModuleSpecifier <: Node {
local: Identifier;
}A specifier in an import or export declaration.
interface ImportDeclaration <: ModuleDeclaration {
type: "ImportDeclaration";
specifiers: [ ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier ];
source: Literal;
}An import declaration, e.g., import foo from "mod";.
interface ImportSpecifier <: ModuleSpecifier {
type: "ImportSpecifier";
imported: Identifier;
}An imported variable binding, e.g., {foo} in import {foo} from "mod" or {foo as bar} in import {foo as bar} from "mod". The imported field refers to the name of the export imported from the module. The local field refers to the binding imported into the local module scope. If it is a basic named import, such as in import {foo} from "mod", both imported and local are equivalent Identifier nodes; in this case an Identifier node representing foo. If it is an aliased import, such as in import {foo as bar} from "mod", the imported field is an Identifier node representing foo, and the local field is an Identifier node representing bar.
interface ImportDefaultSpecifier <: ModuleSpecifier {
type: "ImportDefaultSpecifier";
}A default import specifier, e.g., foo in import foo from "mod.js".
interface ImportNamespaceSpecifier <: ModuleSpecifier {
type: "ImportNamespaceSpecifier";
}A namespace import specifier, e.g., * as foo in import * as foo from "mod.js".
interface ExportNamedDeclaration <: ModuleDeclaration {
type: "ExportNamedDeclaration";
declaration: Declaration | null;
specifiers: [ ExportSpecifier ];
source: Literal | null;
}An export named declaration, e.g., export {foo, bar};, export {foo} from "mod"; or export var foo = 1;.
Note: Having declaration populated with non-empty specifiers or non-null source results in an invalid state.
interface ExportSpecifier <: ModuleSpecifier {
type: "ExportSpecifier";
exported: Identifier;
}An exported variable binding, e.g., {foo} in export {foo} or {bar as foo} in export {bar as foo}. The exported field refers to the name exported in the module. The local field refers to the binding into the local module scope. If it is a basic named export, such as in export {foo}, both exported and local are equivalent Identifier nodes; in this case an Identifier node representing foo. If it is an aliased export, such as in export {bar as foo}, the exported field is an Identifier node representing foo, and the local field is an Identifier node representing bar.
interface ExportDefaultDeclaration <: ModuleDeclaration {
type: "ExportDefaultDeclaration";
declaration: Declaration | Expression;
}An export default declaration, e.g., export default function () {}; or export default 1;.
interface ExportAllDeclaration <: ModuleDeclaration {
type: "ExportAllDeclaration";
source: Literal;
}An export batch declaration, e.g., export * from "mod";.
extend enum BinaryOperator {
"**"
}extend enum AssignmentOperator {
"**="
}extend interface Function {
async: boolean;
}interface AwaitExpression <: Expression {
type: "AwaitExpression";
argument: Expression;
}