1// Type definitions for ESTree AST specification
2// Project: https://github.com/estree/estree
3// Definitions by: RReverser <https://github.com/RReverser>
4// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
5
6// This definition file follows a somewhat unusual format. ESTree allows
7// runtime type checks based on the `type` parameter. In order to explain this
8// to typescript we want to use discriminated union types:
9// https://github.com/Microsoft/TypeScript/pull/9163
10//
11// For ESTree this is a bit tricky because the high level interfaces like
12// Node or Function are pulling double duty. We want to pass common fields down
13// to the interfaces that extend them (like Identifier or
14// ArrowFunctionExpression), but you can't extend a type union or enforce
15// common fields on them. So we've split the high level interfaces into two
16// types, a base type which passes down inhereted fields, and a type union of
17// all types which extend the base type. Only the type union is exported, and
18// the union is how other types refer to the collection of inheriting types.
19//
20// This makes the definitions file here somewhat more difficult to maintain,
21// but it has the notable advantage of making ESTree much easier to use as
22// an end user.
23
24interface BaseNodeWithoutComments {
25  // Every leaf interface that extends BaseNode must specify a type property.
26  // The type property should be a string literal. For example, Identifier
27  // has: `type: "Identifier"`
28  type: string;
29  loc?: SourceLocation | null;
30  range?: [number, number];
31}
32
33interface BaseNode extends BaseNodeWithoutComments {
34  leadingComments?: Array<Comment>;
35  trailingComments?: Array<Comment>;
36}
37
38export type Node =
39    Identifier | Literal | Program | Function | SwitchCase | CatchClause |
40    VariableDeclarator | Statement | Expression | Property |
41    AssignmentProperty | Super | TemplateElement | SpreadElement | Pattern |
42    ClassBody | Class | MethodDefinition | ModuleDeclaration | ModuleSpecifier;
43
44export interface Comment extends BaseNodeWithoutComments {
45  type: "Line" | "Block";
46  value: string;
47}
48
49interface SourceLocation {
50  source?: string | null;
51  start: Position;
52  end: Position;
53}
54
55export interface Position {
56  /** >= 1 */
57  line: number;
58  /** >= 0 */
59  column: number;
60}
61
62export interface Program extends BaseNode {
63  type: "Program";
64  sourceType: "script" | "module";
65  body: Array<Statement | ModuleDeclaration>;
66  comments?: Array<Comment>;
67}
68
69interface BaseFunction extends BaseNode {
70  params: Array<Pattern>;
71  generator?: boolean;
72  async?: boolean;
73  // The body is either BlockStatement or Expression because arrow functions
74  // can have a body that's either. FunctionDeclarations and
75  // FunctionExpressions have only BlockStatement bodies.
76  body: BlockStatement | Expression;
77}
78
79export type Function =
80    FunctionDeclaration | FunctionExpression | ArrowFunctionExpression;
81
82export type Statement =
83    ExpressionStatement | BlockStatement | EmptyStatement |
84    DebuggerStatement | WithStatement | ReturnStatement | LabeledStatement |
85    BreakStatement | ContinueStatement | IfStatement | SwitchStatement |
86    ThrowStatement | TryStatement | WhileStatement | DoWhileStatement |
87    ForStatement | ForInStatement | ForOfStatement | Declaration;
88
89interface BaseStatement extends BaseNode { }
90
91export interface EmptyStatement extends BaseStatement {
92  type: "EmptyStatement";
93}
94
95export interface BlockStatement extends BaseStatement {
96  type: "BlockStatement";
97  body: Array<Statement>;
98  innerComments?: Array<Comment>;
99}
100
101export interface ExpressionStatement extends BaseStatement {
102  type: "ExpressionStatement";
103  expression: Expression;
104}
105
106export interface IfStatement extends BaseStatement {
107  type: "IfStatement";
108  test: Expression;
109  consequent: Statement;
110  alternate?: Statement | null;
111}
112
113export interface LabeledStatement extends BaseStatement {
114  type: "LabeledStatement";
115  label: Identifier;
116  body: Statement;
117}
118
119export interface BreakStatement extends BaseStatement {
120  type: "BreakStatement";
121  label?: Identifier | null;
122}
123
124export interface ContinueStatement extends BaseStatement {
125  type: "ContinueStatement";
126  label?: Identifier | null;
127}
128
129export interface WithStatement extends BaseStatement {
130  type: "WithStatement";
131  object: Expression;
132  body: Statement;
133}
134
135export interface SwitchStatement extends BaseStatement {
136  type: "SwitchStatement";
137  discriminant: Expression;
138  cases: Array<SwitchCase>;
139}
140
141export interface ReturnStatement extends BaseStatement {
142  type: "ReturnStatement";
143  argument?: Expression | null;
144}
145
146export interface ThrowStatement extends BaseStatement {
147  type: "ThrowStatement";
148  argument: Expression;
149}
150
151export interface TryStatement extends BaseStatement {
152  type: "TryStatement";
153  block: BlockStatement;
154  handler?: CatchClause | null;
155  finalizer?: BlockStatement | null;
156}
157
158export interface WhileStatement extends BaseStatement {
159  type: "WhileStatement";
160  test: Expression;
161  body: Statement;
162}
163
164export interface DoWhileStatement extends BaseStatement {
165  type: "DoWhileStatement";
166  body: Statement;
167  test: Expression;
168}
169
170export interface ForStatement extends BaseStatement {
171  type: "ForStatement";
172  init?: VariableDeclaration | Expression | null;
173  test?: Expression | null;
174  update?: Expression | null;
175  body: Statement;
176}
177
178interface BaseForXStatement extends BaseStatement {
179  left: VariableDeclaration | Pattern;
180  right: Expression;
181  body: Statement;
182}
183
184export interface ForInStatement extends BaseForXStatement {
185  type: "ForInStatement";
186}
187
188export interface DebuggerStatement extends BaseStatement {
189  type: "DebuggerStatement";
190}
191
192export type Declaration =
193      FunctionDeclaration | VariableDeclaration | ClassDeclaration;
194
195interface BaseDeclaration extends BaseStatement { }
196
197export interface FunctionDeclaration extends BaseFunction, BaseDeclaration {
198  type: "FunctionDeclaration";
199  /** It is null when a function declaration is a part of the `export default function` statement */
200  id: Identifier | null;
201  body: BlockStatement;
202}
203
204export interface VariableDeclaration extends BaseDeclaration {
205  type: "VariableDeclaration";
206  declarations: Array<VariableDeclarator>;
207  kind: "var" | "let" | "const";
208}
209
210export interface VariableDeclarator extends BaseNode {
211  type: "VariableDeclarator";
212  id: Pattern;
213  init?: Expression | null;
214}
215
216type Expression =
217    ThisExpression | ArrayExpression | ObjectExpression | FunctionExpression |
218    ArrowFunctionExpression | YieldExpression | Literal | UnaryExpression |
219    UpdateExpression | BinaryExpression | AssignmentExpression |
220    LogicalExpression | MemberExpression | ConditionalExpression |
221    CallExpression | NewExpression | SequenceExpression | TemplateLiteral |
222    TaggedTemplateExpression | ClassExpression | MetaProperty | Identifier |
223    AwaitExpression;
224
225export interface BaseExpression extends BaseNode { }
226
227export interface ThisExpression extends BaseExpression {
228  type: "ThisExpression";
229}
230
231export interface ArrayExpression extends BaseExpression {
232  type: "ArrayExpression";
233  elements: Array<Expression | SpreadElement>;
234}
235
236export interface ObjectExpression extends BaseExpression {
237  type: "ObjectExpression";
238  properties: Array<Property>;
239}
240
241export interface Property extends BaseNode {
242  type: "Property";
243  key: Expression;
244  value: Expression | Pattern; // Could be an AssignmentProperty
245  kind: "init" | "get" | "set";
246  method: boolean;
247  shorthand: boolean;
248  computed: boolean;
249}
250
251export interface FunctionExpression extends BaseFunction, BaseExpression {
252  id?: Identifier | null;
253  type: "FunctionExpression";
254  body: BlockStatement;
255}
256
257export interface SequenceExpression extends BaseExpression {
258  type: "SequenceExpression";
259  expressions: Array<Expression>;
260}
261
262export interface UnaryExpression extends BaseExpression {
263  type: "UnaryExpression";
264  operator: UnaryOperator;
265  prefix: true;
266  argument: Expression;
267}
268
269export interface BinaryExpression extends BaseExpression {
270  type: "BinaryExpression";
271  operator: BinaryOperator;
272  left: Expression;
273  right: Expression;
274}
275
276export interface AssignmentExpression extends BaseExpression {
277  type: "AssignmentExpression";
278  operator: AssignmentOperator;
279  left: Pattern | MemberExpression;
280  right: Expression;
281}
282
283export interface UpdateExpression extends BaseExpression {
284  type: "UpdateExpression";
285  operator: UpdateOperator;
286  argument: Expression;
287  prefix: boolean;
288}
289
290export interface LogicalExpression extends BaseExpression {
291  type: "LogicalExpression";
292  operator: LogicalOperator;
293  left: Expression;
294  right: Expression;
295}
296
297export interface ConditionalExpression extends BaseExpression {
298  type: "ConditionalExpression";
299  test: Expression;
300  alternate: Expression;
301  consequent: Expression;
302}
303
304interface BaseCallExpression extends BaseExpression {
305  callee: Expression | Super;
306  arguments: Array<Expression | SpreadElement>;
307}
308export type CallExpression = SimpleCallExpression | NewExpression;
309
310export interface SimpleCallExpression extends BaseCallExpression {
311  type: "CallExpression";
312}
313
314export interface NewExpression extends BaseCallExpression {
315  type: "NewExpression";
316}
317
318export interface MemberExpression extends BaseExpression, BasePattern {
319  type: "MemberExpression";
320  object: Expression | Super;
321  property: Expression;
322  computed: boolean;
323}
324
325export type Pattern =
326    Identifier | ObjectPattern | ArrayPattern | RestElement |
327    AssignmentPattern | MemberExpression;
328
329interface BasePattern extends BaseNode { }
330
331export interface SwitchCase extends BaseNode {
332  type: "SwitchCase";
333  test?: Expression | null;
334  consequent: Array<Statement>;
335}
336
337export interface CatchClause extends BaseNode {
338  type: "CatchClause";
339  param: Pattern;
340  body: BlockStatement;
341}
342
343export interface Identifier extends BaseNode, BaseExpression, BasePattern {
344  type: "Identifier";
345  name: string;
346}
347
348export type Literal = SimpleLiteral | RegExpLiteral;
349
350export interface SimpleLiteral extends BaseNode, BaseExpression {
351  type: "Literal";
352  value: string | boolean | number | null;
353  raw?: string;
354}
355
356export interface RegExpLiteral extends BaseNode, BaseExpression {
357  type: "Literal";
358  value?: RegExp | null;
359  regex: {
360    pattern: string;
361    flags: string;
362  };
363  raw?: string;
364}
365
366export type UnaryOperator =
367    "-" | "+" | "!" | "~" | "typeof" | "void" | "delete";
368
369export type BinaryOperator =
370    "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" |
371    ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "**" | "|" | "^" | "&" | "in" |
372    "instanceof";
373
374export type LogicalOperator = "||" | "&&";
375
376export type AssignmentOperator =
377    "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "**=" | "<<=" | ">>=" | ">>>=" |
378    "|=" | "^=" | "&=";
379
380export type UpdateOperator = "++" | "--";
381
382export interface ForOfStatement extends BaseForXStatement {
383  type: "ForOfStatement";
384}
385
386export interface Super extends BaseNode {
387  type: "Super";
388}
389
390export interface SpreadElement extends BaseNode {
391  type: "SpreadElement";
392  argument: Expression;
393}
394
395export interface ArrowFunctionExpression extends BaseExpression, BaseFunction {
396  type: "ArrowFunctionExpression";
397  expression: boolean;
398  body: BlockStatement | Expression;
399}
400
401export interface YieldExpression extends BaseExpression {
402  type: "YieldExpression";
403  argument?: Expression | null;
404  delegate: boolean;
405}
406
407export interface TemplateLiteral extends BaseExpression {
408  type: "TemplateLiteral";
409  quasis: Array<TemplateElement>;
410  expressions: Array<Expression>;
411}
412
413export interface TaggedTemplateExpression extends BaseExpression {
414  type: "TaggedTemplateExpression";
415  tag: Expression;
416  quasi: TemplateLiteral;
417}
418
419export interface TemplateElement extends BaseNode {
420  type: "TemplateElement";
421  tail: boolean;
422  value: {
423    cooked: string;
424    raw: string;
425  };
426}
427
428export interface AssignmentProperty extends Property {
429  value: Pattern;
430  kind: "init";
431  method: boolean; // false
432}
433
434export interface ObjectPattern extends BasePattern {
435  type: "ObjectPattern";
436  properties: Array<AssignmentProperty>;
437}
438
439export interface ArrayPattern extends BasePattern {
440  type: "ArrayPattern";
441  elements: Array<Pattern>;
442}
443
444export interface RestElement extends BasePattern {
445  type: "RestElement";
446  argument: Pattern;
447}
448
449export interface AssignmentPattern extends BasePattern {
450  type: "AssignmentPattern";
451  left: Pattern;
452  right: Expression;
453}
454
455export type Class = ClassDeclaration | ClassExpression;
456interface BaseClass extends BaseNode {
457  superClass?: Expression | null;
458  body: ClassBody;
459}
460
461export interface ClassBody extends BaseNode {
462  type: "ClassBody";
463  body: Array<MethodDefinition>;
464}
465
466export interface MethodDefinition extends BaseNode {
467  type: "MethodDefinition";
468  key: Expression;
469  value: FunctionExpression;
470  kind: "constructor" | "method" | "get" | "set";
471  computed: boolean;
472  static: boolean;
473}
474
475export interface ClassDeclaration extends BaseClass, BaseDeclaration {
476  type: "ClassDeclaration";
477  /** It is null when a class declaration is a part of the `export default class` statement */
478  id: Identifier | null;
479}
480
481export interface ClassExpression extends BaseClass, BaseExpression {
482  type: "ClassExpression";
483  id?: Identifier | null;
484}
485
486export interface MetaProperty extends BaseExpression {
487  type: "MetaProperty";
488  meta: Identifier;
489  property: Identifier;
490}
491
492export type ModuleDeclaration =
493    ImportDeclaration | ExportNamedDeclaration | ExportDefaultDeclaration |
494    ExportAllDeclaration;
495interface BaseModuleDeclaration extends BaseNode { }
496
497export type ModuleSpecifier =
498    ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier |
499    ExportSpecifier;
500interface BaseModuleSpecifier extends BaseNode {
501  local: Identifier;
502}
503
504export interface ImportDeclaration extends BaseModuleDeclaration {
505  type: "ImportDeclaration";
506  specifiers: Array<ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier>;
507  source: Literal;
508}
509
510export interface ImportSpecifier extends BaseModuleSpecifier {
511  type: "ImportSpecifier";
512  imported: Identifier;
513}
514
515export interface ImportDefaultSpecifier extends BaseModuleSpecifier {
516  type: "ImportDefaultSpecifier";
517}
518
519export interface ImportNamespaceSpecifier extends BaseModuleSpecifier {
520  type: "ImportNamespaceSpecifier";
521}
522
523export interface ExportNamedDeclaration extends BaseModuleDeclaration {
524  type: "ExportNamedDeclaration";
525  declaration?: Declaration | null;
526  specifiers: Array<ExportSpecifier>;
527  source?: Literal | null;
528}
529
530export interface ExportSpecifier extends BaseModuleSpecifier {
531  type: "ExportSpecifier";
532  exported: Identifier;
533}
534
535export interface ExportDefaultDeclaration extends BaseModuleDeclaration {
536  type: "ExportDefaultDeclaration";
537  declaration: Declaration | Expression;
538}
539
540export interface ExportAllDeclaration extends BaseModuleDeclaration {
541  type: "ExportAllDeclaration";
542  source: Literal;
543}
544
545export interface AwaitExpression extends BaseExpression {
546  type: "AwaitExpression";
547  argument: Expression;
548}
549