1import { Syntax } from './syntax';
2
3export type ArgumentListElement = Expression | SpreadElement;
4export type ArrayExpressionElement = Expression | SpreadElement | null;
5export type ArrayPatternElement = AssignmentPattern | BindingIdentifier | BindingPattern | RestElement | null;
6export type BindingPattern = ArrayPattern | ObjectPattern;
7export type BindingIdentifier = Identifier;
8export type Declaration = AsyncFunctionDeclaration | ClassDeclaration | ExportDeclaration | FunctionDeclaration | ImportDeclaration | VariableDeclaration;
9export type ExportableDefaultDeclaration = BindingIdentifier | BindingPattern | ClassDeclaration | Expression | FunctionDeclaration;
10export type ExportableNamedDeclaration = AsyncFunctionDeclaration | ClassDeclaration | FunctionDeclaration | VariableDeclaration;
11export type ExportDeclaration = ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration;
12export type Expression = ArrayExpression | ArrowFunctionExpression | AssignmentExpression | AsyncArrowFunctionExpression | AsyncFunctionExpression |
13    AwaitExpression | BinaryExpression | CallExpression | ClassExpression | ComputedMemberExpression |
14    ConditionalExpression | Identifier | FunctionExpression | Literal | NewExpression | ObjectExpression |
15    RegexLiteral | SequenceExpression | StaticMemberExpression | TaggedTemplateExpression |
16    ThisExpression | UnaryExpression | UpdateExpression | YieldExpression;
17export type FunctionParameter = AssignmentPattern | BindingIdentifier | BindingPattern;
18export type ImportDeclarationSpecifier = ImportDefaultSpecifier | ImportNamespaceSpecifier | ImportSpecifier;
19export type ObjectExpressionProperty = Property | SpreadElement;
20export type ObjectPatternProperty = Property | RestElement;
21export type Statement = AsyncFunctionDeclaration | BreakStatement | ContinueStatement | DebuggerStatement | DoWhileStatement |
22    EmptyStatement | ExpressionStatement | Directive | ForStatement | ForInStatement | ForOfStatement |
23    FunctionDeclaration | IfStatement | ReturnStatement | SwitchStatement | ThrowStatement |
24    TryStatement | VariableDeclaration | WhileStatement | WithStatement;
25export type PropertyKey = Identifier | Literal;
26export type PropertyValue = AssignmentPattern | AsyncFunctionExpression | BindingIdentifier | BindingPattern | FunctionExpression;
27export type StatementListItem = Declaration | Statement;
28
29/* tslint:disable:max-classes-per-file */
30
31export class ArrayExpression {
32    readonly type: string;
33    readonly elements: ArrayExpressionElement[];
34    constructor(elements: ArrayExpressionElement[]) {
35        this.type = Syntax.ArrayExpression;
36        this.elements = elements;
37    }
38}
39
40export class ArrayPattern {
41    readonly type: string;
42    readonly elements: ArrayPatternElement[];
43    constructor(elements: ArrayPatternElement[]) {
44        this.type = Syntax.ArrayPattern;
45        this.elements = elements;
46    }
47}
48
49export class ArrowFunctionExpression {
50    readonly type: string;
51    readonly id: Identifier | null;
52    readonly params: FunctionParameter[];
53    readonly body: BlockStatement | Expression;
54    readonly generator: boolean;
55    readonly expression: boolean;
56    readonly async: boolean;
57    constructor(params: FunctionParameter[], body: BlockStatement | Expression, expression: boolean) {
58        this.type = Syntax.ArrowFunctionExpression;
59        this.id = null;
60        this.params = params;
61        this.body = body;
62        this.generator = false;
63        this.expression = expression;
64        this.async = false;
65    }
66}
67
68export class AssignmentExpression {
69    readonly type: string;
70    readonly operator: string;
71    readonly left: Expression;
72    readonly right: Expression;
73    constructor(operator: string, left: Expression, right: Expression) {
74        this.type = Syntax.AssignmentExpression;
75        this.operator = operator;
76        this.left = left;
77        this.right = right;
78    }
79}
80
81export class AssignmentPattern {
82    readonly type: string;
83    readonly left: BindingIdentifier | BindingPattern;
84    readonly right: Expression;
85    constructor(left: BindingIdentifier | BindingPattern, right: Expression) {
86        this.type = Syntax.AssignmentPattern;
87        this.left = left;
88        this.right = right;
89    }
90}
91
92export class AsyncArrowFunctionExpression {
93    readonly type: string;
94    readonly id: Identifier | null;
95    readonly params: FunctionParameter[];
96    readonly body: BlockStatement | Expression;
97    readonly generator: boolean;
98    readonly expression: boolean;
99    readonly async: boolean;
100    constructor(params: FunctionParameter[], body: BlockStatement | Expression, expression: boolean) {
101        this.type = Syntax.ArrowFunctionExpression;
102        this.id = null;
103        this.params = params;
104        this.body = body;
105        this.generator = false;
106        this.expression = expression;
107        this.async = true;
108    }
109}
110
111export class AsyncFunctionDeclaration {
112    readonly type: string;
113    readonly id: Identifier | null;
114    readonly params: FunctionParameter[];
115    readonly body: BlockStatement;
116    readonly generator: boolean;
117    readonly expression: boolean;
118    readonly async: boolean;
119    constructor(id: Identifier | null, params: FunctionParameter[], body: BlockStatement) {
120        this.type = Syntax.FunctionDeclaration;
121        this.id = id;
122        this.params = params;
123        this.body = body;
124        this.generator = false;
125        this.expression = false;
126        this.async = true;
127    }
128}
129
130export class AsyncFunctionExpression {
131    readonly type: string;
132    readonly id: Identifier | null;
133    readonly params: FunctionParameter[];
134    readonly body: BlockStatement;
135    readonly generator: boolean;
136    readonly expression: boolean;
137    readonly async: boolean;
138    constructor(id: Identifier | null, params: FunctionParameter[], body: BlockStatement) {
139        this.type = Syntax.FunctionExpression;
140        this.id = id;
141        this.params = params;
142        this.body = body;
143        this.generator = false;
144        this.expression = false;
145        this.async = true;
146    }
147}
148
149export class AwaitExpression {
150    readonly type: string;
151    readonly argument: Expression;
152    constructor(argument: Expression) {
153        this.type = Syntax.AwaitExpression;
154        this.argument = argument;
155    }
156}
157
158export class BinaryExpression {
159    readonly type: string;
160    readonly operator: string;
161    readonly left: Expression;
162    readonly right: Expression;
163    constructor(operator: string, left: Expression, right: Expression) {
164        const logical = (operator === '||' || operator === '&&');
165        this.type = logical ? Syntax.LogicalExpression : Syntax.BinaryExpression;
166        this.operator = operator;
167        this.left = left;
168        this.right = right;
169    }
170}
171
172export class BlockStatement {
173    readonly type: string;
174    readonly body: Statement[];
175    constructor(body) {
176        this.type = Syntax.BlockStatement;
177        this.body = body;
178    }
179}
180
181export class BreakStatement {
182    readonly type: string;
183    readonly label: Identifier | null;
184    constructor(label: Identifier | null) {
185        this.type = Syntax.BreakStatement;
186        this.label = label;
187    }
188}
189
190export class CallExpression {
191    readonly type: string;
192    readonly callee: Expression | Import;
193    readonly arguments: ArgumentListElement[];
194    constructor(callee: Expression | Import, args: ArgumentListElement[]) {
195        this.type = Syntax.CallExpression;
196        this.callee = callee;
197        this.arguments = args;
198    }
199}
200
201export class CatchClause {
202    readonly type: string;
203    readonly param: BindingIdentifier | BindingPattern;
204    readonly body: BlockStatement;
205    constructor(param: BindingIdentifier | BindingPattern, body: BlockStatement) {
206        this.type = Syntax.CatchClause;
207        this.param = param;
208        this.body = body;
209    }
210}
211
212export class ClassBody {
213    readonly type: string;
214    readonly body: Property[];
215    constructor(body: Property[]) {
216        this.type = Syntax.ClassBody;
217        this.body = body;
218    }
219}
220
221export class ClassDeclaration {
222    readonly type: string;
223    readonly id: Identifier | null;
224    readonly superClass: Identifier | null;
225    readonly body: ClassBody;
226    constructor(id: Identifier | null, superClass: Identifier | null, body: ClassBody) {
227        this.type = Syntax.ClassDeclaration;
228        this.id = id;
229        this.superClass = superClass;
230        this.body = body;
231    }
232}
233
234export class ClassExpression {
235    readonly type: string;
236    readonly id: Identifier | null;
237    readonly superClass: Identifier | null;
238    readonly body: ClassBody;
239    constructor(id: Identifier | null, superClass: Identifier | null, body: ClassBody) {
240        this.type = Syntax.ClassExpression;
241        this.id = id;
242        this.superClass = superClass;
243        this.body = body;
244    }
245}
246
247export class ComputedMemberExpression {
248    readonly type: string;
249    readonly computed: boolean;
250    readonly object: Expression;
251    readonly property: Expression;
252    constructor(object: Expression, property: Expression) {
253        this.type = Syntax.MemberExpression;
254        this.computed = true;
255        this.object = object;
256        this.property = property;
257    }
258}
259
260export class ConditionalExpression {
261    readonly type: string;
262    readonly test: Expression;
263    readonly consequent: Expression;
264    readonly alternate: Expression;
265    constructor(test: Expression, consequent: Expression, alternate: Expression) {
266        this.type = Syntax.ConditionalExpression;
267        this.test = test;
268        this.consequent = consequent;
269        this.alternate = alternate;
270    }
271}
272
273export class ContinueStatement {
274    readonly type: string;
275    readonly label: Identifier | null;
276    constructor(label: Identifier | null) {
277        this.type = Syntax.ContinueStatement;
278        this.label = label;
279    }
280}
281
282export class DebuggerStatement {
283    readonly type: string;
284    constructor() {
285        this.type = Syntax.DebuggerStatement;
286    }
287}
288
289export class Directive {
290    readonly type: string;
291    readonly expression: Expression;
292    readonly directive: string;
293    constructor(expression: Expression, directive: string) {
294        this.type = Syntax.ExpressionStatement;
295        this.expression = expression;
296        this.directive = directive;
297    }
298}
299
300export class DoWhileStatement {
301    readonly type: string;
302    readonly body: Statement;
303    readonly test: Expression;
304    constructor(body: Statement, test: Expression) {
305        this.type = Syntax.DoWhileStatement;
306        this.body = body;
307        this.test = test;
308    }
309}
310
311export class EmptyStatement {
312    readonly type: string;
313    constructor() {
314        this.type = Syntax.EmptyStatement;
315    }
316}
317
318export class ExportAllDeclaration {
319    readonly type: string;
320    readonly source: Literal;
321    constructor(source: Literal) {
322        this.type = Syntax.ExportAllDeclaration;
323        this.source = source;
324    }
325}
326
327export class ExportDefaultDeclaration {
328    readonly type: string;
329    readonly declaration: ExportableDefaultDeclaration;
330    constructor(declaration: ExportableDefaultDeclaration) {
331        this.type = Syntax.ExportDefaultDeclaration;
332        this.declaration = declaration;
333    }
334}
335
336export class ExportNamedDeclaration {
337    readonly type: string;
338    readonly declaration: ExportableNamedDeclaration | null;
339    readonly specifiers: ExportSpecifier[];
340    readonly source: Literal | null;
341    constructor(declaration: ExportableNamedDeclaration | null, specifiers: ExportSpecifier[], source: Literal | null) {
342        this.type = Syntax.ExportNamedDeclaration;
343        this.declaration = declaration;
344        this.specifiers = specifiers;
345        this.source = source;
346    }
347}
348
349export class ExportSpecifier {
350    readonly type: string;
351    readonly exported: Identifier;
352    readonly local: Identifier;
353    constructor(local: Identifier, exported: Identifier) {
354        this.type = Syntax.ExportSpecifier;
355        this.exported = exported;
356        this.local = local;
357    }
358}
359
360export class ExpressionStatement {
361    readonly type: string;
362    readonly expression: Expression;
363    constructor(expression: Expression) {
364        this.type = Syntax.ExpressionStatement;
365        this.expression = expression;
366    }
367}
368
369export class ForInStatement {
370    readonly type: string;
371    readonly left: Expression;
372    readonly right: Expression;
373    readonly body: Statement;
374    readonly each: boolean;
375    constructor(left: Expression, right: Expression, body: Statement) {
376        this.type = Syntax.ForInStatement;
377        this.left = left;
378        this.right = right;
379        this.body = body;
380        this.each = false;
381    }
382}
383
384export class ForOfStatement {
385    readonly type: string;
386    readonly left: Expression;
387    readonly right: Expression;
388    readonly body: Statement;
389    constructor(left: Expression, right: Expression, body: Statement) {
390        this.type = Syntax.ForOfStatement;
391        this.left = left;
392        this.right = right;
393        this.body = body;
394    }
395}
396
397export class ForStatement {
398    readonly type: string;
399    readonly init: Expression | null;
400    readonly test: Expression | null;
401    readonly update: Expression | null;
402    body: Statement;
403    constructor(init: Expression | null, test: Expression | null, update: Expression | null, body: Statement) {
404        this.type = Syntax.ForStatement;
405        this.init = init;
406        this.test = test;
407        this.update = update;
408        this.body = body;
409    }
410}
411
412export class FunctionDeclaration {
413    readonly type: string;
414    readonly id: Identifier | null;
415    readonly params: FunctionParameter[];
416    readonly body: BlockStatement;
417    readonly generator: boolean;
418    readonly expression: boolean;
419    readonly async: boolean;
420    constructor(id: Identifier | null, params: FunctionParameter[], body: BlockStatement, generator: boolean) {
421        this.type = Syntax.FunctionDeclaration;
422        this.id = id;
423        this.params = params;
424        this.body = body;
425        this.generator = generator;
426        this.expression = false;
427        this.async = false;
428    }
429}
430
431export class FunctionExpression {
432    readonly type: string;
433    readonly id: Identifier | null;
434    readonly params: FunctionParameter[];
435    readonly body: BlockStatement;
436    readonly generator: boolean;
437    readonly expression: boolean;
438    readonly async: boolean;
439    constructor(id: Identifier | null, params: FunctionParameter[], body: BlockStatement, generator: boolean) {
440        this.type = Syntax.FunctionExpression;
441        this.id = id;
442        this.params = params;
443        this.body = body;
444        this.generator = generator;
445        this.expression = false;
446        this.async = false;
447    }
448}
449
450export class Identifier {
451    readonly type: string;
452    readonly name: string;
453    constructor(name) {
454        this.type = Syntax.Identifier;
455        this.name = name;
456    }
457}
458
459export class IfStatement {
460    readonly type: string;
461    readonly test: Expression;
462    readonly consequent: Statement;
463    readonly alternate: Statement | null;
464    constructor(test: Expression, consequent: Statement, alternate: Statement | null) {
465        this.type = Syntax.IfStatement;
466        this.test = test;
467        this.consequent = consequent;
468        this.alternate = alternate;
469    }
470}
471
472export class Import {
473    readonly type: string;
474    constructor() {
475        this.type = Syntax.Import;
476    }
477}
478
479export class ImportDeclaration {
480    readonly type: string;
481    readonly specifiers: ImportDeclarationSpecifier[];
482    readonly source: Literal;
483    constructor(specifiers, source) {
484        this.type = Syntax.ImportDeclaration;
485        this.specifiers = specifiers;
486        this.source = source;
487    }
488}
489
490export class ImportDefaultSpecifier {
491    readonly type: string;
492    readonly local: Identifier;
493    constructor(local: Identifier) {
494        this.type = Syntax.ImportDefaultSpecifier;
495        this.local = local;
496    }
497}
498
499export class ImportNamespaceSpecifier {
500    readonly type: string;
501    readonly local: Identifier;
502    constructor(local: Identifier) {
503        this.type = Syntax.ImportNamespaceSpecifier;
504        this.local = local;
505    }
506}
507
508export class ImportSpecifier {
509    readonly type: string;
510    readonly local: Identifier;
511    readonly imported: Identifier;
512    constructor(local: Identifier, imported: Identifier) {
513        this.type = Syntax.ImportSpecifier;
514        this.local = local;
515        this.imported = imported;
516    }
517}
518
519export class LabeledStatement {
520    readonly type: string;
521    readonly label: Identifier;
522    readonly body: Statement;
523    constructor(label: Identifier, body: Statement) {
524        this.type = Syntax.LabeledStatement;
525        this.label = label;
526        this.body = body;
527    }
528}
529
530export class Literal {
531    readonly type: string;
532    readonly value: boolean | number | string | null;
533    readonly raw: string;
534    constructor(value: boolean | number | string | null, raw: string) {
535        this.type = Syntax.Literal;
536        this.value = value;
537        this.raw = raw;
538    }
539}
540
541export class MetaProperty {
542    readonly type: string;
543    readonly meta: Identifier;
544    readonly property: Identifier;
545    constructor(meta: Identifier, property: Identifier) {
546        this.type = Syntax.MetaProperty;
547        this.meta = meta;
548        this.property = property;
549    }
550}
551
552export class MethodDefinition {
553    readonly type: string;
554    readonly key: Expression | null;
555    readonly computed: boolean;
556    readonly value: AsyncFunctionExpression | FunctionExpression | null;
557    readonly kind: string;
558    readonly static: boolean;
559    constructor(key: Expression | null, computed: boolean, value: AsyncFunctionExpression | FunctionExpression | null, kind: string, isStatic: boolean) {
560        this.type = Syntax.MethodDefinition;
561        this.key = key;
562        this.computed = computed;
563        this.value = value;
564        this.kind = kind;
565        this.static = isStatic;
566    }
567}
568
569export class Module {
570    readonly type: string;
571    readonly body: StatementListItem[];
572    readonly sourceType: string;
573    constructor(body: StatementListItem[]) {
574        this.type = Syntax.Program;
575        this.body = body;
576        this.sourceType = 'module';
577    }
578}
579
580export class NewExpression {
581    readonly type: string;
582    readonly callee: Expression;
583    readonly arguments: ArgumentListElement[];
584    constructor(callee: Expression, args: ArgumentListElement[]) {
585        this.type = Syntax.NewExpression;
586        this.callee = callee;
587        this.arguments = args;
588    }
589}
590
591export class ObjectExpression {
592    readonly type: string;
593    readonly properties: ObjectExpressionProperty[];
594    constructor(properties: ObjectExpressionProperty[]) {
595        this.type = Syntax.ObjectExpression;
596        this.properties = properties;
597    }
598}
599
600export class ObjectPattern {
601    readonly type: string;
602    readonly properties: ObjectPatternProperty[];
603    constructor(properties: ObjectPatternProperty[]) {
604        this.type = Syntax.ObjectPattern;
605        this.properties = properties;
606    }
607}
608
609export class Property {
610    readonly type: string;
611    readonly key: PropertyKey;
612    readonly computed: boolean;
613    readonly value: PropertyValue | null;
614    readonly kind: string;
615    readonly method: boolean;
616    readonly shorthand: boolean;
617    constructor(kind: string, key: PropertyKey, computed: boolean, value: PropertyValue | null, method: boolean, shorthand: boolean) {
618        this.type = Syntax.Property;
619        this.key = key;
620        this.computed = computed;
621        this.value = value;
622        this.kind = kind;
623        this.method = method;
624        this.shorthand = shorthand;
625    }
626}
627
628export class RegexLiteral {
629    readonly type: string;
630    readonly value: RegExp;
631    readonly raw: string;
632    readonly regex: { pattern: string, flags: string };
633    constructor(value: RegExp, raw: string, pattern: string, flags: string) {
634        this.type = Syntax.Literal;
635        this.value = value;
636        this.raw = raw;
637        this.regex = { pattern, flags };
638    }
639}
640
641export class RestElement {
642    readonly type: string;
643    readonly argument: BindingIdentifier | BindingPattern;
644    constructor(argument: BindingIdentifier | BindingPattern) {
645        this.type = Syntax.RestElement;
646        this.argument = argument;
647    }
648}
649
650export class ReturnStatement {
651    readonly type: string;
652    readonly argument: Expression | null;
653    constructor(argument: Expression | null) {
654        this.type = Syntax.ReturnStatement;
655        this.argument = argument;
656    }
657}
658
659export class Script {
660    readonly type: string;
661    readonly body: StatementListItem[];
662    readonly sourceType: string;
663    constructor(body: StatementListItem[]) {
664        this.type = Syntax.Program;
665        this.body = body;
666        this.sourceType = 'script';
667    }
668}
669
670export class SequenceExpression {
671    readonly type: string;
672    readonly expressions: Expression[];
673    constructor(expressions: Expression[]) {
674        this.type = Syntax.SequenceExpression;
675        this.expressions = expressions;
676    }
677}
678
679export class SpreadElement {
680    readonly type: string;
681    readonly argument: Expression;
682    constructor(argument: Expression) {
683        this.type = Syntax.SpreadElement;
684        this.argument = argument;
685    }
686}
687
688export class StaticMemberExpression {
689    readonly type: string;
690    readonly computed: boolean;
691    readonly object: Expression;
692    readonly property: Expression;
693    constructor(object: Expression, property: Expression) {
694        this.type = Syntax.MemberExpression;
695        this.computed = false;
696        this.object = object;
697        this.property = property;
698    }
699}
700
701export class Super {
702    readonly type: string;
703    constructor() {
704        this.type = Syntax.Super;
705    }
706}
707
708export class SwitchCase {
709    readonly type: string;
710    readonly test: Expression | null;
711    readonly consequent: Statement[];
712    constructor(test: Expression, consequent: Statement[]) {
713        this.type = Syntax.SwitchCase;
714        this.test = test;
715        this.consequent = consequent;
716    }
717}
718
719export class SwitchStatement {
720    readonly type: string;
721    readonly discriminant: Expression;
722    readonly cases: SwitchCase[];
723    constructor(discriminant: Expression, cases: SwitchCase[]) {
724        this.type = Syntax.SwitchStatement;
725        this.discriminant = discriminant;
726        this.cases = cases;
727    }
728}
729
730export class TaggedTemplateExpression {
731    readonly type: string;
732    readonly tag: Expression;
733    readonly quasi: TemplateLiteral;
734    constructor(tag: Expression, quasi: TemplateLiteral) {
735        this.type = Syntax.TaggedTemplateExpression;
736        this.tag = tag;
737        this.quasi = quasi;
738    }
739}
740
741interface TemplateElementValue {
742    cooked: string;
743    raw: string;
744}
745
746export class TemplateElement {
747    readonly type: string;
748    readonly value: TemplateElementValue;
749    readonly tail: boolean;
750    constructor(value: TemplateElementValue, tail: boolean) {
751        this.type = Syntax.TemplateElement;
752        this.value = value;
753        this.tail = tail;
754    }
755}
756
757export class TemplateLiteral {
758    readonly type: string;
759    readonly quasis: TemplateElement[];
760    readonly expressions: Expression[];
761    constructor(quasis: TemplateElement[], expressions: Expression[]) {
762        this.type = Syntax.TemplateLiteral;
763        this.quasis = quasis;
764        this.expressions = expressions;
765    }
766}
767
768export class ThisExpression {
769    readonly type: string;
770    constructor() {
771        this.type = Syntax.ThisExpression;
772    }
773}
774
775export class ThrowStatement {
776    readonly type: string;
777    readonly argument: Expression;
778    constructor(argument: Expression) {
779        this.type = Syntax.ThrowStatement;
780        this.argument = argument;
781    }
782}
783
784export class TryStatement {
785    readonly type: string;
786    readonly block: BlockStatement;
787    readonly handler: CatchClause | null;
788    readonly finalizer: BlockStatement | null;
789    constructor(block: BlockStatement, handler: CatchClause | null, finalizer: BlockStatement | null) {
790        this.type = Syntax.TryStatement;
791        this.block = block;
792        this.handler = handler;
793        this.finalizer = finalizer;
794    }
795}
796
797export class UnaryExpression {
798    readonly type: string;
799    readonly operator: string;
800    readonly argument: Expression;
801    readonly prefix: boolean;
802    constructor(operator, argument) {
803        this.type = Syntax.UnaryExpression;
804        this.operator = operator;
805        this.argument = argument;
806        this.prefix = true;
807    }
808}
809
810export class UpdateExpression {
811    readonly type: string;
812    readonly operator: string;
813    readonly argument: Expression;
814    readonly prefix: boolean;
815    constructor(operator, argument, prefix) {
816        this.type = Syntax.UpdateExpression;
817        this.operator = operator;
818        this.argument = argument;
819        this.prefix = prefix;
820    }
821}
822
823export class VariableDeclaration {
824    readonly type: string;
825    readonly declarations: VariableDeclarator[];
826    readonly kind: string;
827    constructor(declarations: VariableDeclarator[], kind: string) {
828        this.type = Syntax.VariableDeclaration;
829        this.declarations = declarations;
830        this.kind = kind;
831    }
832}
833
834export class VariableDeclarator {
835    readonly type: string;
836    readonly id: BindingIdentifier | BindingPattern;
837    readonly init: Expression | null;
838    constructor(id: BindingIdentifier | BindingPattern, init: Expression | null) {
839        this.type = Syntax.VariableDeclarator;
840        this.id = id;
841        this.init = init;
842    }
843}
844
845export class WhileStatement {
846    readonly type: string;
847    readonly test: Expression;
848    readonly body: Statement;
849    constructor(test: Expression, body: Statement) {
850        this.type = Syntax.WhileStatement;
851        this.test = test;
852        this.body = body;
853    }
854}
855
856export class WithStatement {
857    readonly type: string;
858    readonly object: Expression;
859    readonly body: Statement;
860    constructor(object: Expression, body: Statement) {
861        this.type = Syntax.WithStatement;
862        this.object = object;
863        this.body = body;
864    }
865}
866
867export class YieldExpression {
868    readonly type: string;
869    readonly argument: Expression | null;
870    readonly delegate: boolean;
871    constructor(argument: Expression | null, delegate: boolean) {
872        this.type = Syntax.YieldExpression;
873        this.argument = argument;
874        this.delegate = delegate;
875    }
876}
877