UNPKG

typescript-estree

Version:

A parser that converts TypeScript source code into an ESTree compatible form

849 lines (848 loc) 21.5 kB
/** * This document specifies the core ESTree AST node types based on: * - ES5: https://github.com/estree/estree/blob/master/es5.md * - ES2015: https://github.com/estree/estree/blob/master/es2015.md * - ES2016: https://github.com/estree/estree/blob/master/es2016.md * - ES2017: https://github.com/estree/estree/blob/master/es2017.md * - ES2018: https://github.com/estree/estree/blob/master/es2018.md */ /** * Node objects * * ESTree AST nodes are represented as `Node` objects, which may have any prototype inheritance but which implement the following interface: */ export 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): */ export 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): */ export interface Position { line: number; column: number; } /** * Identifier * * An identifier. Note that an identifier may be an expression or a destructuring pattern. */ export interface Identifier extends Expression, Pattern { type: 'Identifier'; name: string; } /** * Literal * * A literal token. Note that a literal can be an expression. */ export interface Literal extends Expression { type: 'Literal'; value: string | boolean | null | number | RegExp; } /** * RegExpLiteral * * 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. */ export interface RegExpLiteral extends Literal { regex: { pattern: string; flags: string; }; } /** * Programs * * A complete program source tree. * * ES2015+ Parsers must specify sourceType as "module" if the source has been parsed as an ES6 module. Otherwise, sourceType must be "script". */ export interface Program extends Node { type: 'Program'; body: Array<Directive | Statement | ModuleDeclaration>; sourceType: 'script' | 'module'; } /** * Functions * * A function declaration or expression. */ export interface Function extends Node { id: Identifier | null; params: Pattern[]; body: FunctionBody; generator: boolean; async: boolean; } /** * Statements * * Any statement. */ export interface Statement extends Node { } /** * ExpressionStatement * * An expression statement, i.e., a statement consisting of a single expression. */ export interface ExpressionStatement extends Statement { type: 'ExpressionStatement'; expression: Expression; } /** * Directive * * A directive from the directive prologue of a script or function. * The `directive` property is the raw string source of the directive without quotes. */ export interface Directive extends Node { type: 'ExpressionStatement'; expression: Literal; directive: string; } /** * BlockStatement * * A block statement, i.e., a sequence of statements surrounded by braces. */ export interface BlockStatement extends Statement { type: 'BlockStatement'; body: Statement[]; } /** * FunctionBody * * The body of a function, which is a block statement that may begin with directives. */ export interface FunctionBody extends BlockStatement { body: Array<Directive | Statement>; } /** * EmptyStatement * * An empty statement, i.e., a solitary semicolon. */ export interface EmptyStatement extends Statement { type: 'EmptyStatement'; } /** * DebuggerStatement * * A `debugger` statement. */ export interface DebuggerStatement extends Statement { type: 'DebuggerStatement'; } /** * WithStatement * * A `with` statement. */ export interface WithStatement extends Statement { type: 'WithStatement'; object: Expression; body: Statement; } /** * Control flow */ /** * ReturnStatement * * A `return` statement. */ export interface ReturnStatement extends Statement { type: 'ReturnStatement'; argument: Expression | null; } /** * LabeledStatement * * A labeled statement, i.e., a statement prefixed by a `break`/`continue` label. */ export interface LabeledStatement extends Statement { type: 'LabeledStatement'; label: Identifier; body: Statement; } /** * BreakStatement * * A `break` statement. */ export interface BreakStatement extends Statement { type: 'BreakStatement'; label: Identifier | null; } /** * ContinueStatement * * A `continue` statement. */ export interface ContinueStatement extends Statement { type: 'ContinueStatement'; label: Identifier | null; } /** * Choice */ /** * IfStatement * * An `if` statement. */ export interface IfStatement extends Statement { type: 'IfStatement'; test: Expression; consequent: Statement; alternate: Statement | null; } /** * SwitchStatement * * A `switch` statement. */ export interface SwitchStatement extends Statement { type: 'SwitchStatement'; discriminant: Expression; cases: SwitchCase[]; } /** * SwitchCase * * A `case` (if `test` is an `Expression`) or `default` (if `test === null`) clause in the body of a `switch` statement. */ export interface SwitchCase extends Node { type: 'SwitchCase'; test: Expression | null; consequent: Statement[]; } /** * Exceptions */ /** * ThrowStatement * * A `throw` statement. */ export interface ThrowStatement extends Statement { type: 'ThrowStatement'; argument: Expression; } /** * TryStatement * * A `try` statement. If `handler` is `null` then `finalizer` must be a `BlockStatement`. */ export interface TryStatement extends Statement { type: 'TryStatement'; block: BlockStatement; handler: CatchClause | null; finalizer: BlockStatement | null; } /** * CatchClause * * A `catch` clause following a `try` block. * * The param is null if the catch binding is omitted. E.g., try { foo() } catch { bar() } */ export interface CatchClause extends Node { type: 'CatchClause'; param: Pattern | null; body: BlockStatement; } /** * Loops */ /** * WhileStatement * * A `while` statement. */ export interface WhileStatement extends Statement { type: 'WhileStatement'; test: Expression; body: Statement; } /** * DoWhileStatement * * A `do`/`while` statement. */ export interface DoWhileStatement extends Statement { type: 'DoWhileStatement'; body: Statement; test: Expression; } /** * ForStatement * * A `for` statement. */ export interface ForStatement extends Statement { type: 'ForStatement'; init: VariableDeclaration | Expression | null; test: Expression | null; update: Expression | null; body: Statement; } /** * ForInStatement * * A `for`/`in` statement. */ export interface ForInStatement extends Statement { type: 'ForInStatement'; left: VariableDeclaration | Pattern; right: Expression; body: Statement; } /** * ForOfStatement * * A `for`/`of` statement and for-await-of statements, e.g., for await (const x of xs) { */ export interface ForOfStatement { type: 'ForOfStatement'; left: VariableDeclaration | Pattern; right: Expression; body: Statement; await: boolean; } /** * Declarations * * Any declaration node. Note that declarations are considered statements; this is because declarations can appear in any statement context. */ export interface Declaration extends Statement { } /** * FunctionDeclaration * * A function declaration. Note that unlike in the parent interface `Function`, the `id` cannot be `null`. */ export interface FunctionDeclaration extends Function, Declaration { type: 'FunctionDeclaration'; id: Identifier; } /** * VariableDeclaration * * A variable declaration. */ export interface VariableDeclaration extends Declaration { type: 'VariableDeclaration'; declarations: VariableDeclarator[]; kind: 'var' | 'let' | 'const'; } /** * VariableDeclarator * * A variable declarator. */ export interface VariableDeclarator extends Node { type: 'VariableDeclarator'; id: Pattern; init: Expression | null; } /** * Expressions * * Any expression node. Since the left-hand side of an assignment may be any expression in general, an expression can also be a pattern. */ export interface Expression extends Node { } /** * Super * * A super pseudo-expression. */ export interface Super extends Node { type: 'Super'; } /** * ThisExpression * * A `this` expression. */ export interface ThisExpression extends Expression { type: 'ThisExpression'; } /** * SpreadElement * * Spread expression, e.g., [head, ...iter, tail], f(head, ...iter, ...tail). */ export interface SpreadElement extends Node { type: 'SpreadElement'; argument: Expression; } /** * ArrayExpression * * An array expression. */ export interface ArrayExpression extends Expression { type: 'ArrayExpression'; elements: Array<Expression | SpreadElement | null>; } /** * ObjectExpression * * An object expression. * * Spread properties, e.g., {a: 1, ...obj, b: 2}. */ export interface ObjectExpression extends Expression { type: 'ObjectExpression'; properties: Array<Property | SpreadElement>; } /** * Property * * 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. */ export interface Property extends Node { type: 'Property'; key: Literal | Identifier | Expression; value: Expression; kind: 'init' | 'get' | 'set'; method: boolean; shorthand: boolean; computed: boolean; } /** * FunctionExpression * * A `function` expression. */ export interface FunctionExpression extends Function, Expression { type: 'FunctionExpression'; } /** * ArrowFunctionExpression * * A fat arrow function expression, e.g., let foo = (bar) => { / body / }. */ export interface ArrowFunctionExpression extends Expression { id: Identifier | null; params: Pattern[]; type: 'ArrowFunctionExpression'; body: FunctionBody | Expression; generator: boolean; expression: boolean; } /** * Unary operations */ /** * UnaryExpression * * A unary operator expression. */ export interface UnaryExpression extends Expression { type: 'UnaryExpression'; operator: UnaryOperator; prefix: boolean; argument: Expression; } /** * UnaryOperator * * A unary operator token. */ export declare type UnaryOperator = '-' | '+' | '!' | '~' | 'typeof' | 'void' | 'delete'; /** * UpdateExpression * * An update (increment or decrement) operator expression. */ export interface UpdateExpression extends Expression { type: 'UpdateExpression'; operator: UpdateOperator; argument: Expression; prefix: boolean; } /** * UpdateOperator * * An update (increment or decrement) operator token. */ export declare type UpdateOperator = '++' | '--'; /** * Binary operations */ /** * BinaryExpression * * A binary operator expression. */ export interface BinaryExpression extends Expression { type: 'BinaryExpression'; operator: BinaryOperator; left: Expression; right: Expression; } /** * BinaryOperator * * A binary operator token. */ export declare type BinaryOperator = '==' | '!=' | '===' | '!==' | '<' | '<=' | '>' | '>=' | '<<' | '>>' | '>>>' | '+' | '-' | '*' | '/' | '%' | '|' | '^' | '&' | 'in' | 'instanceof' | '**'; /** * AssignmentExpression * * An assignment operator expression. * * FROM ESTREE DOCS: * * ``` * 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. * ``` */ export interface AssignmentExpression extends Expression { type: 'AssignmentExpression'; operator: AssignmentOperator; left: Pattern | Expression; right: Expression; } /** * AssignmentOperator * * An assignment operator token. */ export declare type AssignmentOperator = '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '<<=' | '>>=' | '>>>=' | '|=' | '^=' | '&=' | '**='; /** * LogicalExpression * * A logical operator expression. */ export interface LogicalExpression extends Expression { type: 'LogicalExpression'; operator: LogicalOperator; left: Expression; right: Expression; } /** * LogicalOperator * * A logical operator token. */ export declare type LogicalOperator = '||' | '&&'; /** * MemberExpression * * 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`. */ export interface MemberExpression extends Expression, Pattern { type: 'MemberExpression'; object: Expression | Super; property: Expression; computed: boolean; } /** * ConditionalExpression * * A conditional expression, i.e., a ternary `?`/`:` expression. */ export interface ConditionalExpression extends Expression { type: 'ConditionalExpression'; test: Expression; alternate: Expression; consequent: Expression; } /** * CallExpression * * A function or method call expression. */ export interface CallExpression extends Expression { type: 'CallExpression'; callee: Expression | Super; arguments: Array<Expression | SpreadElement>; } /** * NewExpression * * A `new` expression. */ export interface NewExpression extends Expression { type: 'NewExpression'; callee: Expression; arguments: Array<Expression | SpreadElement>; } /** * SequenceExpression * * A sequence expression, i.e., a comma-separated sequence of expressions. */ export interface SequenceExpression extends Expression { type: 'SequenceExpression'; expressions: Expression[]; } /** * YieldExpression * * A yield expression. */ export interface YieldExpression extends Expression { type: 'YieldExpression'; argument: Expression | null; delegate: boolean; } /** * AwaitExpression */ export interface AwaitExpression extends Expression { type: 'AwaitExpression'; argument: Expression; } /** * Template Literals */ /** * TemplateLiteral */ export interface TemplateLiteral extends Expression { type: 'TemplateLiteral'; quasis: TemplateElement[]; expressions: Expression[]; } /** * TaggedTemplateExpression */ export interface TaggedTemplateExpression extends Expression { type: 'TaggedTemplateExpression'; tag: Expression; quasi: TemplateLiteral; } /** * TemplateElement * * If the template literal is tagged and the text has an invalid escape, cooked will be null, e.g., tag`\unicode and \u{55}` */ export interface TemplateElement extends Node { type: 'TemplateElement'; tail: boolean; value: { cooked: string | null; raw: string; }; } /** * Patterns * * 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. */ export interface Pattern extends Node { } /** * AssignmentProperty */ export interface AssignmentProperty extends Property { type: 'Property'; value: Pattern; kind: 'init'; method: false; } /** * ObjectPattern * * Rest properties, e.g., {a, ...rest} = obj. */ export interface ObjectPattern extends Pattern { type: 'ObjectPattern'; properties: Array<AssignmentProperty | RestElement>; } /** * ArrayPattern */ export interface ArrayPattern extends Pattern { type: 'ArrayPattern'; elements: Array<Pattern | null>; } /** * RestElement */ export interface RestElement extends Pattern { type: 'RestElement'; argument: Pattern; } /** * AssignmentPattern */ export interface AssignmentPattern extends Pattern { type: 'AssignmentPattern'; left: Pattern; right: Expression; } /** * Classes */ /** * Class */ export interface Class extends Node { id: Identifier | null; superClass: Expression | null; body: ClassBody; } /** * ClassBody */ export interface ClassBody extends Node { type: 'ClassBody'; body: MethodDefinition[]; } /** * MethodDefinition */ export interface MethodDefinition extends Node { type: 'MethodDefinition'; key: Expression; value: FunctionExpression; kind: 'constructor' | 'method' | 'get' | 'set'; computed: boolean; static: boolean; } /** * ClassDeclaration */ export interface ClassDeclaration extends Class, Declaration { type: 'ClassDeclaration'; id: Identifier; } /** * ClassExpression */ export interface ClassExpression extends Class, Expression { type: 'ClassExpression'; } /** * MetaProperty */ export interface MetaProperty extends Expression { type: 'MetaProperty'; meta: Identifier; property: Identifier; } /** * Modules */ /** * ModuleDeclaration * * A module `import` or `export` declaration. */ export interface ModuleDeclaration extends Node { } /** * ModuleSpecifier * * A specifier in an import or export declaration. */ export interface ModuleSpecifier extends Node { local: Identifier; } /** * Imports */ /** * ImportDeclaration * * An import declaration, e.g., `import foo from "mod";`. */ export interface ImportDeclaration extends ModuleDeclaration { type: 'ImportDeclaration'; specifiers: Array<ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier>; source: Literal; } /** * ImportSpecifier * * 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`. */ export interface ImportSpecifier extends ModuleSpecifier { type: 'ImportSpecifier'; imported: Identifier; } /** * ImportDefaultSpecifier * * A default import specifier, e.g., `foo` in `import foo from "mod.js"`. */ export interface ImportDefaultSpecifier extends ModuleSpecifier { type: 'ImportDefaultSpecifier'; } /** * ImportNamespaceSpecifier * * A namespace import specifier, e.g., `* as foo` in `import * as foo from "mod.js"`. */ export interface ImportNamespaceSpecifier extends ModuleSpecifier { type: 'ImportNamespaceSpecifier'; } /** * Exports */ /** * ExportNamedDeclaration * * 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._ */ export interface ExportNamedDeclaration extends ModuleDeclaration { type: 'ExportNamedDeclaration'; declaration: Declaration | null; specifiers: [ExportSpecifier]; source: Literal | null; } /** * ExportSpecifier * * 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`. */ export interface ExportSpecifier extends ModuleSpecifier { type: 'ExportSpecifier'; exported: Identifier; } /** * ExportDefaultDeclaration * * An export default declaration, e.g., `export default function () {};` or `export default 1;`. */ export interface ExportDefaultDeclaration extends ModuleDeclaration { type: 'ExportDefaultDeclaration'; declaration: Declaration | Expression; } /** * ExportAllDeclaration * * An export batch declaration, e.g., `export * from "mod";`. */ export interface ExportAllDeclaration extends ModuleDeclaration { type: 'ExportAllDeclaration'; source: Literal; }