as-test 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +10 -1
  2. package/README.md +12 -12
  3. package/as-test.config.json +1 -1
  4. package/assembly/__tests__/array.spec.ts +3 -3
  5. package/assembly/src/expectation.ts +29 -16
  6. package/assembly/src/suite.ts +2 -0
  7. package/assembly/src/tests.ts +1 -0
  8. package/bin/build.js +65 -77
  9. package/bin/index.js +130 -160
  10. package/bin/init.js +96 -109
  11. package/bin/reporter.js +1 -1
  12. package/bin/run.js +210 -236
  13. package/bin/types.js +25 -25
  14. package/bin/util.js +35 -42
  15. package/cli/run.ts +13 -15
  16. package/cli/tsconfig.json +2 -1
  17. package/package.json +12 -9
  18. package/transform/lib/builder.js +1361 -0
  19. package/transform/lib/builder.js.map +1 -0
  20. package/transform/lib/coverage.js +6 -6
  21. package/transform/lib/coverage.js.map +1 -1
  22. package/transform/lib/index.js +1 -1
  23. package/transform/lib/index.js.map +1 -1
  24. package/transform/lib/linker.js +19 -0
  25. package/transform/lib/linker.js.map +1 -0
  26. package/transform/lib/mock.js +9 -9
  27. package/transform/lib/mock.js.map +1 -1
  28. package/transform/lib/range.js +13 -0
  29. package/transform/lib/range.js.map +1 -0
  30. package/transform/lib/types.js +26 -0
  31. package/transform/lib/types.js.map +1 -0
  32. package/transform/lib/util.js +47 -0
  33. package/transform/lib/util.js.map +1 -0
  34. package/transform/lib/visitor.js +532 -0
  35. package/transform/lib/visitor.js.map +1 -0
  36. package/transform/src/builder.ts +1474 -0
  37. package/transform/src/coverage.ts +6 -7
  38. package/transform/src/index.ts +1 -2
  39. package/transform/src/linker.ts +41 -0
  40. package/transform/src/mock.ts +9 -10
  41. package/transform/src/range.ts +12 -0
  42. package/transform/src/types.ts +35 -0
  43. package/transform/src/util.ts +81 -0
  44. package/transform/src/visitor.ts +744 -0
  45. package/.trunk/configs/.markdownlint.yaml +0 -2
  46. package/.trunk/configs/.yamllint.yaml +0 -7
  47. package/.trunk/trunk.yaml +0 -34
  48. package/bin/about.js +0 -135
  49. package/bin/package.json +0 -3
@@ -0,0 +1,1474 @@
1
+ // Taken from https://github.com/as-pect/visitor-as/blob/master/src/astBuilder.ts
2
+ // tslint:disable: as-internal-case
3
+
4
+ import {
5
+ CommonFlags,
6
+ TypeNode,
7
+ Node,
8
+ NodeKind,
9
+ Source,
10
+ NamedTypeNode,
11
+ FunctionTypeNode,
12
+ TypeParameterNode,
13
+ IdentifierExpression,
14
+ CallExpression,
15
+ ClassExpression,
16
+ ElementAccessExpression,
17
+ FunctionExpression,
18
+ InstanceOfExpression,
19
+ LiteralExpression,
20
+ NewExpression,
21
+ ParenthesizedExpression,
22
+ PropertyAccessExpression,
23
+ TernaryExpression,
24
+ UnaryPostfixExpression,
25
+ UnaryPrefixExpression,
26
+ BlockStatement,
27
+ BreakStatement,
28
+ ContinueStatement,
29
+ DoStatement,
30
+ EmptyStatement,
31
+ ExportStatement,
32
+ ExportDefaultStatement,
33
+ ExportImportStatement,
34
+ ExpressionStatement,
35
+ ForStatement,
36
+ IfStatement,
37
+ ImportStatement,
38
+ ReturnStatement,
39
+ SwitchStatement,
40
+ ThrowStatement,
41
+ TryStatement,
42
+ VariableStatement,
43
+ WhileStatement,
44
+ ClassDeclaration,
45
+ EnumDeclaration,
46
+ EnumValueDeclaration,
47
+ FieldDeclaration,
48
+ FunctionDeclaration,
49
+ ImportDeclaration,
50
+ InterfaceDeclaration,
51
+ MethodDeclaration,
52
+ NamespaceDeclaration,
53
+ TypeDeclaration,
54
+ VariableDeclaration,
55
+ DecoratorNode,
56
+ ExportMember,
57
+ ParameterNode,
58
+ SwitchCase,
59
+ TypeName,
60
+ ArrayLiteralExpression,
61
+ Expression,
62
+ ObjectLiteralExpression,
63
+ AssertionKind,
64
+ LiteralKind,
65
+ FloatLiteralExpression,
66
+ StringLiteralExpression,
67
+ RegexpLiteralExpression,
68
+ UnaryExpression,
69
+ ArrowKind,
70
+ ParameterKind,
71
+ DeclarationStatement,
72
+ AssertionExpression,
73
+ BinaryExpression,
74
+ CommaExpression,
75
+ IntegerLiteralExpression,
76
+ isTypeOmitted,
77
+ operatorTokenToString,
78
+ ForOfStatement,
79
+ IndexSignatureNode,
80
+ TemplateLiteralExpression,
81
+ util,
82
+ FalseExpression,
83
+ NullExpression,
84
+ TrueExpression,
85
+ } from "assemblyscript/dist/assemblyscript.js";
86
+ import { Visitor } from "./visitor.js";
87
+
88
+ function assert<T>(isTruish: T, message: string = "assertion error"): T {
89
+ if (!isTruish) throw new Error(message);
90
+ return isTruish;
91
+ }
92
+
93
+ /** An AST builder. */
94
+ export class ASTBuilder extends Visitor {
95
+ /** Rebuilds the textual source from the specified AST, as far as possible. */
96
+ static build(node: Node): string {
97
+ var builder = new ASTBuilder();
98
+ builder.visitNode(node);
99
+ return builder.finish();
100
+ }
101
+
102
+ private sb: string[] = [];
103
+ private indentLevel: number = 0;
104
+ visitNode(node: Node) {
105
+ return this.visit(node);
106
+ }
107
+
108
+ visitSource(source: Source): void {
109
+ var statements = source.statements;
110
+ for (let i = 0, k = statements.length; i < k; ++i) {
111
+ this.visitNodeAndTerminate(statements[i]);
112
+ }
113
+ }
114
+
115
+ // types
116
+
117
+ visitTypeNode(node: TypeNode): void {
118
+ switch (node.kind) {
119
+ case NodeKind.NamedType: {
120
+ this.visitNamedTypeNode(<NamedTypeNode>node);
121
+ break;
122
+ }
123
+ case NodeKind.FunctionType: {
124
+ this.visitFunctionTypeNode(<FunctionTypeNode>node);
125
+ break;
126
+ }
127
+ default:
128
+ assert(false);
129
+ }
130
+ }
131
+
132
+ visitTypeName(node: TypeName): void {
133
+ this.visitIdentifierExpression(node.identifier);
134
+ var sb = this.sb;
135
+ var current = node.next;
136
+ while (current) {
137
+ sb.push(".");
138
+ this.visitIdentifierExpression(current.identifier);
139
+ current = current.next;
140
+ }
141
+ }
142
+
143
+ visitNamedTypeNode(node: NamedTypeNode): void {
144
+ this.visitTypeName(node.name);
145
+ var typeArguments = node.typeArguments;
146
+ if (typeArguments) {
147
+ let numTypeArguments = typeArguments.length;
148
+ let sb = this.sb;
149
+ if (numTypeArguments) {
150
+ sb.push("<");
151
+ this.visitTypeNode(typeArguments[0]);
152
+ for (let i = 1; i < numTypeArguments; ++i) {
153
+ sb.push(", ");
154
+ this.visitTypeNode(typeArguments[i]);
155
+ }
156
+ sb.push(">");
157
+ }
158
+ if (node.isNullable) sb.push(" | null");
159
+ }
160
+ }
161
+
162
+ visitFunctionTypeNode(node: FunctionTypeNode): void {
163
+ var isNullable = node.isNullable;
164
+ var sb = this.sb;
165
+ sb.push(isNullable ? "((" : "(");
166
+ var explicitThisType = node.explicitThisType;
167
+ if (explicitThisType) {
168
+ sb.push("this: ");
169
+ this.visitTypeNode(explicitThisType);
170
+ }
171
+ var parameters = node.parameters;
172
+ var numParameters = parameters.length;
173
+ if (numParameters) {
174
+ if (explicitThisType) sb.push(", ");
175
+ this.serializeParameter(parameters[0]);
176
+ for (let i = 1; i < numParameters; ++i) {
177
+ sb.push(", ");
178
+ this.serializeParameter(parameters[i]);
179
+ }
180
+ }
181
+ var returnType = node.returnType;
182
+ if (returnType) {
183
+ sb.push(") => ");
184
+ this.visitTypeNode(returnType);
185
+ } else {
186
+ sb.push(") => void");
187
+ }
188
+ if (isNullable) sb.push(") | null");
189
+ }
190
+
191
+ visitTypeParameter(node: TypeParameterNode): void {
192
+ this.visitIdentifierExpression(node.name);
193
+ var extendsType = node.extendsType;
194
+ if (extendsType) {
195
+ this.sb.push(" extends ");
196
+ this.visitTypeNode(extendsType);
197
+ }
198
+ var defaultType = node.defaultType;
199
+ if (defaultType) {
200
+ this.sb.push("=");
201
+ this.visitTypeNode(defaultType);
202
+ }
203
+ }
204
+
205
+ // expressions
206
+
207
+ visitIdentifierExpression(node: IdentifierExpression): void {
208
+ if (node.isQuoted) this.visitStringLiteral(node.text);
209
+ else this.sb.push(node.text);
210
+ }
211
+
212
+ visitArrayLiteralExpression(node: ArrayLiteralExpression): void {
213
+ var sb = this.sb;
214
+ sb.push("[");
215
+ var elements = node.elementExpressions;
216
+ var numElements = elements.length;
217
+ if (numElements) {
218
+ let element = elements[0];
219
+ if (element) this.visitNode(element);
220
+ for (let i = 1; i < numElements; ++i) {
221
+ element = elements[i];
222
+ sb.push(", ");
223
+ if (element) this.visitNode(element);
224
+ }
225
+ }
226
+ sb.push("]");
227
+ }
228
+
229
+ visitObjectLiteralExpression(node: ObjectLiteralExpression): void {
230
+ var sb = this.sb;
231
+ var names = node.names;
232
+ var values = node.values;
233
+ var numElements = names.length;
234
+ assert(numElements == values.length);
235
+ if (numElements) {
236
+ sb.push("{\n");
237
+ util.indent(sb, ++this.indentLevel);
238
+ this.visitNode(names[0]);
239
+ sb.push(": ");
240
+ this.visitNode(values[0]);
241
+ for (let i = 1; i < numElements; ++i) {
242
+ sb.push(",\n");
243
+ util.indent(sb, this.indentLevel);
244
+ let name = names[i];
245
+ let value = values[i];
246
+ if (name == value) {
247
+ this.visitNode(name);
248
+ } else {
249
+ this.visitNode(name);
250
+ sb.push(": ");
251
+ this.visitNode(value);
252
+ }
253
+ }
254
+ sb.push("\n");
255
+ util.indent(sb, --this.indentLevel);
256
+ sb.push("}");
257
+ } else {
258
+ sb.push("{}");
259
+ }
260
+ }
261
+
262
+ visitAssertionExpression(node: AssertionExpression): void {
263
+ var sb = this.sb;
264
+ switch (node.assertionKind) {
265
+ case AssertionKind.Prefix: {
266
+ sb.push("<");
267
+ if (node.toType) this.visitTypeNode(node.toType);
268
+ sb.push(">");
269
+ this.visitNode(node.expression);
270
+ break;
271
+ }
272
+ case AssertionKind.As: {
273
+ this.visitNode(node.expression);
274
+ sb.push(" as ");
275
+ if (node.toType) this.visitTypeNode(node.toType);
276
+ break;
277
+ }
278
+ case AssertionKind.NonNull: {
279
+ this.visitNode(node.expression);
280
+ sb.push("!");
281
+ break;
282
+ }
283
+ case AssertionKind.Const: {
284
+ this.visitNode(node.expression);
285
+ sb.push(" as const");
286
+ break;
287
+ }
288
+ default:
289
+ assert(false);
290
+ }
291
+ }
292
+
293
+ visitBinaryExpression(node: BinaryExpression): void {
294
+ var sb = this.sb;
295
+ this.visitNode(node.left);
296
+ sb.push(" ");
297
+ sb.push(operatorTokenToString(node.operator));
298
+ sb.push(" ");
299
+ this.visitNode(node.right);
300
+ }
301
+
302
+ visitCallExpression(node: CallExpression): void {
303
+ this.visitNode(node.expression);
304
+ this.visitArguments(node.typeArguments, node.args);
305
+ }
306
+
307
+ visitArguments(typeArguments: TypeNode[] | null, args: Expression[]): void {
308
+ var sb = this.sb;
309
+ if (typeArguments) {
310
+ let numTypeArguments = typeArguments.length;
311
+ if (numTypeArguments) {
312
+ sb.push("<");
313
+ this.visitTypeNode(typeArguments[0]);
314
+ for (let i = 1; i < numTypeArguments; ++i) {
315
+ sb.push(", ");
316
+ this.visitTypeNode(typeArguments[i]);
317
+ }
318
+ sb.push(">(");
319
+ }
320
+ } else {
321
+ sb.push("(");
322
+ }
323
+ var numArgs = args.length;
324
+ if (numArgs) {
325
+ this.visitNode(args[0]);
326
+ for (let i = 1; i < numArgs; ++i) {
327
+ sb.push(", ");
328
+ this.visitNode(args[i]);
329
+ }
330
+ }
331
+ sb.push(")");
332
+ }
333
+
334
+ visitClassExpression(node: ClassExpression): void {
335
+ var declaration = node.declaration;
336
+ this.visitClassDeclaration(declaration);
337
+ }
338
+
339
+ visitCommaExpression(node: CommaExpression): void {
340
+ var expressions = node.expressions;
341
+ var numExpressions = expressions.length;
342
+ this.visitNode(expressions[0]);
343
+ var sb = this.sb;
344
+ for (let i = 1; i < numExpressions; ++i) {
345
+ sb.push(",");
346
+ this.visitNode(expressions[i]);
347
+ }
348
+ }
349
+
350
+ visitElementAccessExpression(node: ElementAccessExpression): void {
351
+ var sb = this.sb;
352
+ this.visitNode(node.expression);
353
+ sb.push("[");
354
+ this.visitNode(node.elementExpression);
355
+ sb.push("]");
356
+ }
357
+
358
+ visitFunctionExpression(node: FunctionExpression): void {
359
+ var declaration = node.declaration;
360
+ if (!declaration.arrowKind) {
361
+ if (declaration.name.text.length) {
362
+ this.sb.push("function ");
363
+ } else {
364
+ this.sb.push("function");
365
+ }
366
+ } else {
367
+ assert(declaration.name.text.length == 0);
368
+ }
369
+ this.visitFunctionCommon(declaration);
370
+ }
371
+
372
+ visitLiteralExpression(node: LiteralExpression): void {
373
+ switch (node.literalKind) {
374
+ case LiteralKind.Float: {
375
+ this.visitFloatLiteralExpression(<FloatLiteralExpression>node);
376
+ break;
377
+ }
378
+ case LiteralKind.Integer: {
379
+ this.visitIntegerLiteralExpression(<IntegerLiteralExpression>node);
380
+ break;
381
+ }
382
+ case LiteralKind.String: {
383
+ this.visitStringLiteralExpression(<StringLiteralExpression>node);
384
+ break;
385
+ }
386
+ case LiteralKind.Template: {
387
+ this.visitTemplateLiteralExpression(<TemplateLiteralExpression>node);
388
+ break;
389
+ }
390
+ case LiteralKind.RegExp: {
391
+ this.visitRegexpLiteralExpression(<RegexpLiteralExpression>node);
392
+ break;
393
+ }
394
+ case LiteralKind.Array: {
395
+ this.visitArrayLiteralExpression(<ArrayLiteralExpression>node);
396
+ break;
397
+ }
398
+ case LiteralKind.Object: {
399
+ this.visitObjectLiteralExpression(<ObjectLiteralExpression>node);
400
+ break;
401
+ }
402
+ default: {
403
+ assert(false);
404
+ break;
405
+ }
406
+ }
407
+ }
408
+
409
+ visitFloatLiteralExpression(node: FloatLiteralExpression): void {
410
+ this.sb.push(node.value.toString());
411
+ }
412
+
413
+ visitInstanceOfExpression(node: InstanceOfExpression): void {
414
+ this.visitNode(node.expression);
415
+ this.sb.push(" instanceof ");
416
+ this.visitTypeNode(node.isType);
417
+ }
418
+
419
+ visitIntegerLiteralExpression(node: IntegerLiteralExpression): void {
420
+ this.sb.push(i64_to_string(node.value));
421
+ }
422
+
423
+ visitStringLiteral(str: string): void {
424
+ var sb = this.sb;
425
+ sb.push('"');
426
+ this.visitRawString(str, util.CharCode.DoubleQuote);
427
+ sb.push('"');
428
+ }
429
+
430
+ private visitRawString(str: string, quote: util.CharCode): void {
431
+ var sb = this.sb;
432
+ var off = 0;
433
+ var i = 0;
434
+ for (let k = str.length; i < k; ) {
435
+ switch (str.charCodeAt(i)) {
436
+ case util.CharCode.Null: {
437
+ if (i > off) sb.push(str.substring(off, (off = i + 1)));
438
+ sb.push("\\0");
439
+ off = ++i;
440
+ break;
441
+ }
442
+ case util.CharCode.Backslash: {
443
+ if (i > off) sb.push(str.substring(off, i));
444
+ off = ++i;
445
+ sb.push("\\b");
446
+ break;
447
+ }
448
+ case util.CharCode.Tab: {
449
+ if (i > off) sb.push(str.substring(off, i));
450
+ off = ++i;
451
+ sb.push("\\t");
452
+ break;
453
+ }
454
+ case util.CharCode.LineFeed: {
455
+ if (i > off) sb.push(str.substring(off, i));
456
+ off = ++i;
457
+ sb.push("\\n");
458
+ break;
459
+ }
460
+ case util.CharCode.VerticalTab: {
461
+ if (i > off) sb.push(str.substring(off, i));
462
+ off = ++i;
463
+ sb.push("\\v");
464
+ break;
465
+ }
466
+ case util.CharCode.FormFeed: {
467
+ if (i > off) sb.push(str.substring(off, i));
468
+ off = ++i;
469
+ sb.push("\\f");
470
+ break;
471
+ }
472
+ case util.CharCode.CarriageReturn: {
473
+ if (i > off) sb.push(str.substring(off, i));
474
+ sb.push("\\r");
475
+ off = ++i;
476
+ break;
477
+ }
478
+ case util.CharCode.DoubleQuote: {
479
+ if (quote == util.CharCode.DoubleQuote) {
480
+ if (i > off) sb.push(str.substring(off, i));
481
+ sb.push('\\"');
482
+ off = ++i;
483
+ } else {
484
+ ++i;
485
+ }
486
+ break;
487
+ }
488
+ case util.CharCode.SingleQuote: {
489
+ if (quote == util.CharCode.SingleQuote) {
490
+ if (i > off) sb.push(str.substring(off, i));
491
+ sb.push("\\'");
492
+ off = ++i;
493
+ } else {
494
+ ++i;
495
+ }
496
+ break;
497
+ }
498
+ case util.CharCode.Backslash: {
499
+ if (i > off) sb.push(str.substring(off, i));
500
+ sb.push("\\\\");
501
+ off = ++i;
502
+ break;
503
+ }
504
+ case util.CharCode.Backtick: {
505
+ if (quote == util.CharCode.Backtick) {
506
+ if (i > off) sb.push(str.substring(off, i));
507
+ sb.push("\\`");
508
+ off = ++i;
509
+ } else {
510
+ ++i;
511
+ }
512
+ break;
513
+ }
514
+ default: {
515
+ ++i;
516
+ break;
517
+ }
518
+ }
519
+ }
520
+ if (i > off) sb.push(str.substring(off, i));
521
+ }
522
+
523
+ visitStringLiteralExpression(node: StringLiteralExpression): void {
524
+ this.visitStringLiteral(node.value);
525
+ }
526
+
527
+ visitTemplateLiteralExpression(node: TemplateLiteralExpression): void {
528
+ var sb = this.sb;
529
+ var tag = node.tag;
530
+ var parts = node.parts;
531
+ var expressions = node.expressions;
532
+ if (tag) this.visitNode(tag);
533
+ sb.push("`");
534
+ this.visitRawString(parts[0], util.CharCode.Backtick);
535
+ assert(parts.length == expressions.length + 1);
536
+ for (let i = 0, k = expressions.length; i < k; ++i) {
537
+ sb.push("${");
538
+ this.visitNode(expressions[i]);
539
+ sb.push("}");
540
+ this.visitRawString(parts[i + 1], util.CharCode.Backtick);
541
+ }
542
+ sb.push("`");
543
+ }
544
+
545
+ visitRegexpLiteralExpression(node: RegexpLiteralExpression): void {
546
+ var sb = this.sb;
547
+ sb.push("/");
548
+ sb.push(node.pattern);
549
+ sb.push("/");
550
+ sb.push(node.patternFlags);
551
+ }
552
+
553
+ visitNewExpression(node: NewExpression): void {
554
+ this.sb.push("new ");
555
+ this.visitTypeName(node.typeName);
556
+ this.visitArguments(node.typeArguments, node.args);
557
+ }
558
+
559
+ visitParenthesizedExpression(node: ParenthesizedExpression): void {
560
+ var sb = this.sb;
561
+ sb.push("(");
562
+ this.visitNode(node.expression);
563
+ sb.push(")");
564
+ }
565
+
566
+ visitPropertyAccessExpression(node: PropertyAccessExpression): void {
567
+ this.visitNode(node.expression);
568
+ this.sb.push(".");
569
+ this.visitIdentifierExpression(node.property);
570
+ }
571
+
572
+ visitTernaryExpression(node: TernaryExpression): void {
573
+ var sb = this.sb;
574
+ this.visitNode(node.condition);
575
+ sb.push(" ? ");
576
+ this.visitNode(node.ifThen);
577
+ sb.push(" : ");
578
+ this.visitNode(node.ifElse);
579
+ }
580
+
581
+ visitUnaryExpression(node: UnaryExpression): void {
582
+ switch (node.kind) {
583
+ case NodeKind.UnaryPostfix: {
584
+ this.visitUnaryPostfixExpression(<UnaryPostfixExpression>node);
585
+ break;
586
+ }
587
+ case NodeKind.UnaryPrefix: {
588
+ this.visitUnaryPrefixExpression(<UnaryPrefixExpression>node);
589
+ break;
590
+ }
591
+ default:
592
+ assert(false);
593
+ }
594
+ }
595
+
596
+ visitUnaryPostfixExpression(node: UnaryPostfixExpression): void {
597
+ this.visitNode(node.operand);
598
+ this.sb.push(operatorTokenToString(node.operator));
599
+ }
600
+
601
+ visitUnaryPrefixExpression(node: UnaryPrefixExpression): void {
602
+ this.sb.push(operatorTokenToString(node.operator));
603
+ this.visitNode(node.operand);
604
+ }
605
+
606
+ // statements
607
+
608
+ visitNodeAndTerminate(node: Node): void {
609
+ this.visitNode(node);
610
+ var sb = this.sb;
611
+ if (
612
+ !sb.length || // leading EmptyStatement
613
+ node.kind == NodeKind.Variable || // potentially assigns a FunctionExpression
614
+ node.kind == NodeKind.Expression // potentially assigns a FunctionExpression
615
+ ) {
616
+ sb.push(";\n");
617
+ } else {
618
+ let last = sb[sb.length - 1];
619
+ let lastCharPos = last.length - 1;
620
+ if (
621
+ lastCharPos >= 0 &&
622
+ (last.charCodeAt(lastCharPos) == util.CharCode.CloseBrace ||
623
+ last.charCodeAt(lastCharPos) == util.CharCode.Semicolon)
624
+ ) {
625
+ sb.push("\n");
626
+ } else {
627
+ sb.push(";\n");
628
+ }
629
+ }
630
+ }
631
+
632
+ visitBlockStatement(node: BlockStatement): void {
633
+ var sb = this.sb;
634
+ var statements = node.statements;
635
+ var numStatements = statements.length;
636
+ if (numStatements) {
637
+ sb.push("{\n");
638
+ let indentLevel = ++this.indentLevel;
639
+ for (let i = 0; i < numStatements; ++i) {
640
+ util.indent(sb, indentLevel);
641
+ this.visitNodeAndTerminate(statements[i]);
642
+ }
643
+ util.indent(sb, --this.indentLevel);
644
+ sb.push("}");
645
+ } else {
646
+ sb.push("{}");
647
+ }
648
+ }
649
+
650
+ visitBreakStatement(node: BreakStatement): void {
651
+ var label = node.label;
652
+ if (label) {
653
+ this.sb.push("break ");
654
+ this.visitIdentifierExpression(label);
655
+ } else {
656
+ this.sb.push("break");
657
+ }
658
+ }
659
+
660
+ visitContinueStatement(node: ContinueStatement): void {
661
+ var label = node.label;
662
+ if (label) {
663
+ this.sb.push("continue ");
664
+ this.visitIdentifierExpression(label);
665
+ } else {
666
+ this.sb.push("continue");
667
+ }
668
+ }
669
+
670
+ visitClassDeclaration(node: ClassDeclaration, isDefault = false): void {
671
+ var decorators = node.decorators;
672
+ if (decorators) {
673
+ for (let i = 0, k = decorators.length; i < k; ++i) {
674
+ this.serializeDecorator(decorators[i]);
675
+ }
676
+ }
677
+ var sb = this.sb;
678
+ if (isDefault) {
679
+ sb.push("export default ");
680
+ } else {
681
+ this.serializeExternalModifiers(node);
682
+ }
683
+ if (node.is(CommonFlags.Abstract)) sb.push("abstract ");
684
+ if (node.name.text.length) {
685
+ sb.push("class ");
686
+ this.visitIdentifierExpression(node.name);
687
+ } else {
688
+ sb.push("class");
689
+ }
690
+ var typeParameters = node.typeParameters;
691
+ if (typeParameters != null && typeParameters.length > 0) {
692
+ sb.push("<");
693
+ this.visitTypeParameter(typeParameters[0]);
694
+ for (let i = 1, k = typeParameters.length; i < k; ++i) {
695
+ sb.push(", ");
696
+ this.visitTypeParameter(typeParameters[i]);
697
+ }
698
+ sb.push(">");
699
+ }
700
+ var extendsType = node.extendsType;
701
+ if (extendsType) {
702
+ sb.push(" extends ");
703
+ this.visitTypeNode(extendsType);
704
+ }
705
+ var implementsTypes = node.implementsTypes;
706
+ if (implementsTypes) {
707
+ let numImplementsTypes = implementsTypes.length;
708
+ if (numImplementsTypes) {
709
+ sb.push(" implements ");
710
+ this.visitTypeNode(implementsTypes[0]);
711
+ for (let i = 1; i < numImplementsTypes; ++i) {
712
+ sb.push(", ");
713
+ this.visitTypeNode(implementsTypes[i]);
714
+ }
715
+ }
716
+ }
717
+ var indexSignature = node.indexSignature;
718
+ var members = node.members;
719
+ var numMembers = members.length;
720
+ if (indexSignature !== null || numMembers) {
721
+ sb.push(" {\n");
722
+ let indentLevel = ++this.indentLevel;
723
+ if (indexSignature) {
724
+ util.indent(sb, indentLevel);
725
+ this.visitNodeAndTerminate(indexSignature);
726
+ }
727
+ for (let i = 0, k = members.length; i < k; ++i) {
728
+ let member = members[i];
729
+ if (
730
+ member.kind != NodeKind.FieldDeclaration ||
731
+ (<FieldDeclaration>member).parameterIndex < 0
732
+ ) {
733
+ util.indent(sb, indentLevel);
734
+ this.visitNodeAndTerminate(member);
735
+ }
736
+ }
737
+ util.indent(sb, --this.indentLevel);
738
+ sb.push("}");
739
+ } else {
740
+ sb.push(" {}");
741
+ }
742
+ }
743
+
744
+ visitDoStatement(node: DoStatement): void {
745
+ var sb = this.sb;
746
+ sb.push("do ");
747
+ this.visitNode(node.body);
748
+ if (node.body.kind == NodeKind.Block) {
749
+ sb.push(" while (");
750
+ } else {
751
+ util.indent(sb, this.indentLevel);
752
+ sb.push("while (");
753
+ }
754
+ this.visitNode(node.condition);
755
+ sb.push(")");
756
+ }
757
+
758
+ visitEmptyStatement(node: EmptyStatement): void {
759
+ /* nop */
760
+ }
761
+
762
+ visitEnumDeclaration(node: EnumDeclaration, isDefault = false): void {
763
+ var sb = this.sb;
764
+ if (isDefault) {
765
+ sb.push("export default ");
766
+ } else {
767
+ this.serializeExternalModifiers(node);
768
+ }
769
+ if (node.is(CommonFlags.Const)) sb.push("const ");
770
+ sb.push("enum ");
771
+ this.visitIdentifierExpression(node.name);
772
+ var values = node.values;
773
+ var numValues = values.length;
774
+ if (numValues) {
775
+ sb.push(" {\n");
776
+ let indentLevel = ++this.indentLevel;
777
+ util.indent(sb, indentLevel);
778
+ this.visitEnumValueDeclaration(node.values[0]);
779
+ for (let i = 1; i < numValues; ++i) {
780
+ sb.push(",\n");
781
+ util.indent(sb, indentLevel);
782
+ this.visitEnumValueDeclaration(node.values[i]);
783
+ }
784
+ sb.push("\n");
785
+ util.indent(sb, --this.indentLevel);
786
+ sb.push("}");
787
+ } else {
788
+ sb.push(" {}");
789
+ }
790
+ }
791
+
792
+ visitEnumValueDeclaration(node: EnumValueDeclaration): void {
793
+ this.visitIdentifierExpression(node.name);
794
+ var initializer = node.initializer;
795
+ if (initializer) {
796
+ this.sb.push(" = ");
797
+ this.visitNode(initializer);
798
+ }
799
+ }
800
+
801
+ visitExportImportStatement(node: ExportImportStatement): void {
802
+ var sb = this.sb;
803
+ sb.push("export import ");
804
+ this.visitIdentifierExpression(node.externalName);
805
+ sb.push(" = ");
806
+ this.visitIdentifierExpression(node.name);
807
+ }
808
+
809
+ visitExportMember(node: ExportMember): void {
810
+ this.visitIdentifierExpression(node.localName);
811
+ if (node.exportedName.text != node.localName.text) {
812
+ this.sb.push(" as ");
813
+ this.visitIdentifierExpression(node.exportedName);
814
+ }
815
+ }
816
+
817
+ visitExportStatement(node: ExportStatement): void {
818
+ var sb = this.sb;
819
+ if (node.isDeclare) {
820
+ sb.push("declare ");
821
+ }
822
+ var members = node.members;
823
+ if (members == null) {
824
+ sb.push("export *");
825
+ } else if (members.length > 0) {
826
+ let numMembers = members.length;
827
+ sb.push("export {\n");
828
+ let indentLevel = ++this.indentLevel;
829
+ util.indent(sb, indentLevel);
830
+ this.visitExportMember(members[0]);
831
+ for (let i = 1; i < numMembers; ++i) {
832
+ sb.push(",\n");
833
+ util.indent(sb, indentLevel);
834
+ this.visitExportMember(members[i]);
835
+ }
836
+ --this.indentLevel;
837
+ sb.push("\n}");
838
+ } else {
839
+ sb.push("export {}");
840
+ }
841
+ var path = node.path;
842
+ if (path) {
843
+ sb.push(" from ");
844
+ this.visitStringLiteralExpression(path);
845
+ }
846
+ sb.push(";");
847
+ }
848
+
849
+ visitExportDefaultStatement(node: ExportDefaultStatement): void {
850
+ var declaration = node.declaration;
851
+ switch (declaration.kind) {
852
+ case NodeKind.EnumDeclaration: {
853
+ this.visitEnumDeclaration(<EnumDeclaration>declaration, true);
854
+ break;
855
+ }
856
+ case NodeKind.FunctionDeclaration: {
857
+ this.visitFunctionDeclaration(<FunctionDeclaration>declaration, true);
858
+ break;
859
+ }
860
+ case NodeKind.ClassDeclaration: {
861
+ this.visitClassDeclaration(<ClassDeclaration>declaration, true);
862
+ break;
863
+ }
864
+ case NodeKind.InterfaceDeclaration: {
865
+ this.visitInterfaceDeclaration(<InterfaceDeclaration>declaration, true);
866
+ break;
867
+ }
868
+ case NodeKind.NamespaceDeclaration: {
869
+ this.visitNamespaceDeclaration(<NamespaceDeclaration>declaration, true);
870
+ break;
871
+ }
872
+ default:
873
+ assert(false);
874
+ }
875
+ }
876
+
877
+ visitExpressionStatement(node: ExpressionStatement): void {
878
+ this.visitNode(node.expression);
879
+ }
880
+
881
+ visitFieldDeclaration(node: FieldDeclaration): void {
882
+ var decorators = node.decorators;
883
+ if (decorators) {
884
+ for (let i = 0, k = decorators.length; i < k; ++i) {
885
+ this.serializeDecorator(decorators[i]);
886
+ }
887
+ }
888
+ this.serializeAccessModifiers(node);
889
+ this.visitIdentifierExpression(node.name);
890
+ var sb = this.sb;
891
+ if (node.flags & CommonFlags.DefinitelyAssigned) {
892
+ sb.push("!");
893
+ }
894
+ var type = node.type;
895
+ if (type) {
896
+ sb.push(": ");
897
+ this.visitTypeNode(type);
898
+ }
899
+ var initializer = node.initializer;
900
+ if (initializer) {
901
+ sb.push(" = ");
902
+ this.visitNode(initializer);
903
+ }
904
+ }
905
+
906
+ visitForStatement(node: ForStatement): void {
907
+ var sb = this.sb;
908
+ sb.push("for (");
909
+ var initializer = node.initializer;
910
+ if (initializer) {
911
+ this.visitNode(initializer);
912
+ }
913
+ var condition = node.condition;
914
+ if (condition) {
915
+ sb.push("; ");
916
+ this.visitNode(condition);
917
+ } else {
918
+ sb.push(";");
919
+ }
920
+ var incrementor = node.incrementor;
921
+ if (incrementor) {
922
+ sb.push("; ");
923
+ this.visitNode(incrementor);
924
+ } else {
925
+ sb.push(";");
926
+ }
927
+ sb.push(") ");
928
+ this.visitNode(node.body);
929
+ }
930
+
931
+ visitForOfStatement(node: ForOfStatement): void {
932
+ var sb = this.sb;
933
+ sb.push("for (");
934
+ this.visitNode(node.variable);
935
+ sb.push(" of ");
936
+ this.visitNode(node.iterable);
937
+ sb.push(") ");
938
+ this.visitNode(node.body);
939
+ }
940
+
941
+ visitFunctionDeclaration(node: FunctionDeclaration, isDefault = false): void {
942
+ var sb = this.sb;
943
+ var decorators = node.decorators;
944
+ if (decorators) {
945
+ for (let i = 0, k = decorators.length; i < k; ++i) {
946
+ this.serializeDecorator(decorators[i]);
947
+ }
948
+ }
949
+ if (isDefault) {
950
+ sb.push("export default ");
951
+ } else {
952
+ this.serializeExternalModifiers(node);
953
+ this.serializeAccessModifiers(node);
954
+ }
955
+ if (node.name.text.length) {
956
+ sb.push("function ");
957
+ } else {
958
+ sb.push("function");
959
+ }
960
+ this.visitFunctionCommon(node);
961
+ }
962
+
963
+ visitFunctionCommon(node: FunctionDeclaration): void {
964
+ var sb = this.sb;
965
+ this.visitIdentifierExpression(node.name);
966
+ var signature = node.signature;
967
+ var typeParameters = node.typeParameters;
968
+ if (typeParameters) {
969
+ let numTypeParameters = typeParameters.length;
970
+ if (numTypeParameters) {
971
+ sb.push("<");
972
+ this.visitTypeParameter(typeParameters[0]);
973
+ for (let i = 1; i < numTypeParameters; ++i) {
974
+ sb.push(", ");
975
+ this.visitTypeParameter(typeParameters[i]);
976
+ }
977
+ sb.push(">");
978
+ }
979
+ }
980
+ if (node.arrowKind == ArrowKind.Single) {
981
+ let parameters = signature.parameters;
982
+ assert(parameters.length == 1);
983
+ assert(!signature.explicitThisType);
984
+ this.serializeParameter(parameters[0]);
985
+ } else {
986
+ sb.push("(");
987
+ let parameters = signature.parameters;
988
+ let numParameters = parameters.length;
989
+ let explicitThisType = signature.explicitThisType;
990
+ if (explicitThisType) {
991
+ sb.push("this: ");
992
+ this.visitTypeNode(explicitThisType);
993
+ }
994
+ if (numParameters) {
995
+ if (explicitThisType) sb.push(", ");
996
+ this.serializeParameter(parameters[0]);
997
+ for (let i = 1; i < numParameters; ++i) {
998
+ sb.push(", ");
999
+ this.serializeParameter(parameters[i]);
1000
+ }
1001
+ }
1002
+ }
1003
+ var body = node.body;
1004
+ var returnType = signature.returnType;
1005
+ if (node.arrowKind) {
1006
+ if (body) {
1007
+ if (node.arrowKind == ArrowKind.Single) {
1008
+ assert(isTypeOmitted(returnType));
1009
+ } else {
1010
+ if (isTypeOmitted(returnType)) {
1011
+ sb.push(")");
1012
+ } else {
1013
+ sb.push("): ");
1014
+ this.visitTypeNode(returnType);
1015
+ }
1016
+ }
1017
+ sb.push(" => ");
1018
+ this.visitNode(body);
1019
+ } else {
1020
+ assert(!isTypeOmitted(returnType));
1021
+ sb.push(" => ");
1022
+ this.visitTypeNode(returnType);
1023
+ }
1024
+ } else {
1025
+ if (
1026
+ !isTypeOmitted(returnType) &&
1027
+ !node.isAny(CommonFlags.Constructor | CommonFlags.Set)
1028
+ ) {
1029
+ sb.push("): ");
1030
+ this.visitTypeNode(returnType);
1031
+ } else {
1032
+ sb.push(")");
1033
+ }
1034
+ if (body) {
1035
+ sb.push(" ");
1036
+ this.visitNode(body);
1037
+ }
1038
+ }
1039
+ }
1040
+
1041
+ visitIfStatement(node: IfStatement): void {
1042
+ var sb = this.sb;
1043
+ sb.push("if (");
1044
+ this.visitNode(node.condition);
1045
+ sb.push(") ");
1046
+ var ifTrue = node.ifTrue;
1047
+ this.visitNode(ifTrue);
1048
+ if (ifTrue.kind != NodeKind.Block) {
1049
+ sb.push(";\n");
1050
+ }
1051
+ var ifFalse = node.ifFalse;
1052
+ if (ifFalse) {
1053
+ if (ifTrue.kind == NodeKind.Block) {
1054
+ sb.push(" else ");
1055
+ } else {
1056
+ sb.push("else ");
1057
+ }
1058
+ this.visitNode(ifFalse);
1059
+ }
1060
+ }
1061
+
1062
+ visitImportDeclaration(node: ImportDeclaration): void {
1063
+ var externalName = node.foreignName;
1064
+ var name = node.name;
1065
+ this.visitIdentifierExpression(externalName);
1066
+ if (externalName.text != name.text) {
1067
+ this.sb.push(" as ");
1068
+ this.visitIdentifierExpression(name);
1069
+ }
1070
+ }
1071
+
1072
+ visitImportStatement(node: ImportStatement): void {
1073
+ var sb = this.sb;
1074
+ sb.push("import ");
1075
+ var declarations = node.declarations;
1076
+ var namespaceName = node.namespaceName;
1077
+ if (declarations) {
1078
+ let numDeclarations = declarations.length;
1079
+ if (numDeclarations) {
1080
+ sb.push("{\n");
1081
+ let indentLevel = ++this.indentLevel;
1082
+ util.indent(sb, indentLevel);
1083
+ this.visitImportDeclaration(declarations[0]);
1084
+ for (let i = 1; i < numDeclarations; ++i) {
1085
+ sb.push(",\n");
1086
+ util.indent(sb, indentLevel);
1087
+ this.visitImportDeclaration(declarations[i]);
1088
+ }
1089
+ --this.indentLevel;
1090
+ sb.push("\n} from ");
1091
+ } else {
1092
+ sb.push("{} from ");
1093
+ }
1094
+ } else if (namespaceName) {
1095
+ sb.push("* as ");
1096
+ this.visitIdentifierExpression(namespaceName);
1097
+ sb.push(" from ");
1098
+ }
1099
+ this.visitStringLiteralExpression(node.path);
1100
+ }
1101
+
1102
+ visitIndexSignature(node: IndexSignatureNode): void {
1103
+ var sb = this.sb;
1104
+ sb.push("[key: ");
1105
+ this.visitTypeNode(node.keyType);
1106
+ sb.push("]: ");
1107
+ this.visitTypeNode(node.valueType);
1108
+ }
1109
+
1110
+ visitInterfaceDeclaration(
1111
+ node: InterfaceDeclaration,
1112
+ isDefault = false,
1113
+ ): void {
1114
+ var decorators = node.decorators;
1115
+ if (decorators) {
1116
+ for (let i = 0, k = decorators.length; i < k; ++i) {
1117
+ this.serializeDecorator(decorators[i]);
1118
+ }
1119
+ }
1120
+ var sb = this.sb;
1121
+ if (isDefault) {
1122
+ sb.push("export default ");
1123
+ } else {
1124
+ this.serializeExternalModifiers(node);
1125
+ }
1126
+ sb.push("interface ");
1127
+ this.visitIdentifierExpression(node.name);
1128
+ var typeParameters = node.typeParameters;
1129
+ if (typeParameters != null && typeParameters.length > 0) {
1130
+ sb.push("<");
1131
+ this.visitTypeParameter(typeParameters[0]);
1132
+ for (let i = 1, k = typeParameters.length; i < k; ++i) {
1133
+ sb.push(", ");
1134
+ this.visitTypeParameter(typeParameters[i]);
1135
+ }
1136
+ sb.push(">");
1137
+ }
1138
+ var extendsType = node.extendsType;
1139
+ if (extendsType) {
1140
+ sb.push(" extends ");
1141
+ this.visitTypeNode(extendsType);
1142
+ }
1143
+ // must not have implementsTypes
1144
+ sb.push(" {\n");
1145
+ var indentLevel = ++this.indentLevel;
1146
+ var members = node.members;
1147
+ for (let i = 0, k = members.length; i < k; ++i) {
1148
+ util.indent(sb, indentLevel);
1149
+ this.visitNodeAndTerminate(members[i]);
1150
+ }
1151
+ --this.indentLevel;
1152
+ sb.push("}");
1153
+ }
1154
+
1155
+ visitMethodDeclaration(node: MethodDeclaration): void {
1156
+ var decorators = node.decorators;
1157
+ if (decorators) {
1158
+ for (let i = 0, k = decorators.length; i < k; ++i) {
1159
+ this.serializeDecorator(decorators[i]);
1160
+ }
1161
+ }
1162
+ this.serializeAccessModifiers(node);
1163
+ if (node.is(CommonFlags.Get)) {
1164
+ this.sb.push("get ");
1165
+ } else if (node.is(CommonFlags.Set)) {
1166
+ this.sb.push("set ");
1167
+ }
1168
+ this.visitFunctionCommon(node);
1169
+ }
1170
+
1171
+ visitNamespaceDeclaration(
1172
+ node: NamespaceDeclaration,
1173
+ isDefault = false,
1174
+ ): void {
1175
+ var decorators = node.decorators;
1176
+ if (decorators) {
1177
+ for (let i = 0, k = decorators.length; i < k; ++i) {
1178
+ this.serializeDecorator(decorators[i]);
1179
+ }
1180
+ }
1181
+ var sb = this.sb;
1182
+ if (isDefault) {
1183
+ sb.push("export default ");
1184
+ } else {
1185
+ this.serializeExternalModifiers(node);
1186
+ }
1187
+ sb.push("namespace ");
1188
+ this.visitIdentifierExpression(node.name);
1189
+ var members = node.members;
1190
+ var numMembers = members.length;
1191
+ if (numMembers) {
1192
+ sb.push(" {\n");
1193
+ let indentLevel = ++this.indentLevel;
1194
+ for (let i = 0, k = members.length; i < k; ++i) {
1195
+ util.indent(sb, indentLevel);
1196
+ this.visitNodeAndTerminate(members[i]);
1197
+ }
1198
+ util.indent(sb, --this.indentLevel);
1199
+ sb.push("}");
1200
+ } else {
1201
+ sb.push(" {}");
1202
+ }
1203
+ }
1204
+
1205
+ visitReturnStatement(node: ReturnStatement): void {
1206
+ var value = node.value;
1207
+ if (value) {
1208
+ this.sb.push("return ");
1209
+ this.visitNode(value);
1210
+ } else {
1211
+ this.sb.push("return");
1212
+ }
1213
+ }
1214
+
1215
+ visitTrueExpression(node: TrueExpression): void {
1216
+ this.sb.push("true");
1217
+ }
1218
+
1219
+ visitFalseExpression(node: FalseExpression): void {
1220
+ this.sb.push("false");
1221
+ }
1222
+ visitNullExpression(node: NullExpression): void {
1223
+ this.sb.push("null");
1224
+ }
1225
+ visitSwitchCase(node: SwitchCase): void {
1226
+ var sb = this.sb;
1227
+ var label = node.label;
1228
+ if (label) {
1229
+ sb.push("case ");
1230
+ this.visitNode(label);
1231
+ sb.push(":\n");
1232
+ } else {
1233
+ sb.push("default:\n");
1234
+ }
1235
+ var statements = node.statements;
1236
+ var numStatements = statements.length;
1237
+ if (numStatements) {
1238
+ let indentLevel = ++this.indentLevel;
1239
+ util.indent(sb, indentLevel);
1240
+ this.visitNodeAndTerminate(statements[0]);
1241
+ for (let i = 1; i < numStatements; ++i) {
1242
+ util.indent(sb, indentLevel);
1243
+ this.visitNodeAndTerminate(statements[i]);
1244
+ }
1245
+ --this.indentLevel;
1246
+ }
1247
+ }
1248
+
1249
+ visitSwitchStatement(node: SwitchStatement): void {
1250
+ var sb = this.sb;
1251
+ sb.push("switch (");
1252
+ this.visitNode(node.condition);
1253
+ sb.push(") {\n");
1254
+ var indentLevel = ++this.indentLevel;
1255
+ var cases = node.cases;
1256
+ for (let i = 0, k = cases.length; i < k; ++i) {
1257
+ util.indent(sb, indentLevel);
1258
+ this.visitSwitchCase(cases[i]);
1259
+ sb.push("\n");
1260
+ }
1261
+ --this.indentLevel;
1262
+ sb.push("}");
1263
+ }
1264
+
1265
+ visitThrowStatement(node: ThrowStatement): void {
1266
+ this.sb.push("throw ");
1267
+ this.visitNode(node.value);
1268
+ }
1269
+
1270
+ visitTryStatement(node: TryStatement): void {
1271
+ var sb = this.sb;
1272
+ sb.push("try {\n");
1273
+ var indentLevel = ++this.indentLevel;
1274
+ var statements = node.bodyStatements;
1275
+ for (let i = 0, k = statements.length; i < k; ++i) {
1276
+ util.indent(sb, indentLevel);
1277
+ this.visitNodeAndTerminate(statements[i]);
1278
+ }
1279
+ var catchVariable = node.catchVariable;
1280
+ if (catchVariable) {
1281
+ util.indent(sb, indentLevel - 1);
1282
+ sb.push("} catch (");
1283
+ this.visitIdentifierExpression(catchVariable);
1284
+ sb.push(") {\n");
1285
+ let catchStatements = node.catchStatements;
1286
+ if (catchStatements) {
1287
+ for (let i = 0, k = catchStatements.length; i < k; ++i) {
1288
+ util.indent(sb, indentLevel);
1289
+ this.visitNodeAndTerminate(catchStatements[i]);
1290
+ }
1291
+ }
1292
+ }
1293
+ var finallyStatements = node.finallyStatements;
1294
+ if (finallyStatements) {
1295
+ util.indent(sb, indentLevel - 1);
1296
+ sb.push("} finally {\n");
1297
+ for (let i = 0, k = finallyStatements.length; i < k; ++i) {
1298
+ util.indent(sb, indentLevel);
1299
+ this.visitNodeAndTerminate(finallyStatements[i]);
1300
+ }
1301
+ }
1302
+ util.indent(sb, indentLevel - 1);
1303
+ sb.push("}");
1304
+ }
1305
+
1306
+ visitTypeDeclaration(node: TypeDeclaration): void {
1307
+ var decorators = node.decorators;
1308
+ if (decorators) {
1309
+ for (let i = 0, k = decorators.length; i < k; ++i) {
1310
+ this.serializeDecorator(decorators[i]);
1311
+ }
1312
+ }
1313
+ var sb = this.sb;
1314
+ this.serializeExternalModifiers(node);
1315
+ sb.push("type ");
1316
+ this.visitIdentifierExpression(node.name);
1317
+ var typeParameters = node.typeParameters;
1318
+ if (typeParameters) {
1319
+ let numTypeParameters = typeParameters.length;
1320
+ if (numTypeParameters) {
1321
+ sb.push("<");
1322
+ for (let i = 0; i < numTypeParameters; ++i) {
1323
+ this.visitTypeParameter(typeParameters[i]);
1324
+ }
1325
+ sb.push(">");
1326
+ }
1327
+ }
1328
+ sb.push(" = ");
1329
+ this.visitTypeNode(node.type);
1330
+ }
1331
+
1332
+ visitVariableDeclaration(node: VariableDeclaration): void {
1333
+ this.visitIdentifierExpression(node.name);
1334
+ var type = node.type;
1335
+ var sb = this.sb;
1336
+ if (node.flags & CommonFlags.DefinitelyAssigned) {
1337
+ sb.push("!");
1338
+ }
1339
+ if (type) {
1340
+ sb.push(": ");
1341
+ this.visitTypeNode(type);
1342
+ }
1343
+ var initializer = node.initializer;
1344
+ if (initializer) {
1345
+ sb.push(" = ");
1346
+ this.visitNode(initializer);
1347
+ }
1348
+ }
1349
+
1350
+ visitVariableStatement(node: VariableStatement): void {
1351
+ var decorators = node.decorators;
1352
+ if (decorators) {
1353
+ for (let i = 0, k = decorators.length; i < k; ++i) {
1354
+ this.serializeDecorator(decorators[i]);
1355
+ }
1356
+ }
1357
+ var sb = this.sb;
1358
+ var declarations = node.declarations;
1359
+ var numDeclarations = declarations.length;
1360
+ var firstDeclaration = declarations[0];
1361
+ this.serializeExternalModifiers(firstDeclaration);
1362
+ sb.push(
1363
+ firstDeclaration.is(CommonFlags.Const)
1364
+ ? "const "
1365
+ : firstDeclaration.is(CommonFlags.Let)
1366
+ ? "let "
1367
+ : "var ",
1368
+ );
1369
+ this.visitVariableDeclaration(node.declarations[0]);
1370
+ for (let i = 1; i < numDeclarations; ++i) {
1371
+ sb.push(", ");
1372
+ this.visitVariableDeclaration(node.declarations[i]);
1373
+ }
1374
+ }
1375
+
1376
+ visitWhileStatement(node: WhileStatement): void {
1377
+ var sb = this.sb;
1378
+ sb.push("while (");
1379
+ this.visitNode(node.condition);
1380
+ var statement = node.body;
1381
+ if (statement.kind == NodeKind.Empty) {
1382
+ sb.push(")");
1383
+ } else {
1384
+ sb.push(") ");
1385
+ this.visitNode(node.body);
1386
+ }
1387
+ }
1388
+
1389
+ // other
1390
+
1391
+ serializeDecorator(node: DecoratorNode): void {
1392
+ var sb = this.sb;
1393
+ sb.push("@");
1394
+ this.visitNode(node.name);
1395
+ var args = node.args;
1396
+ if (args) {
1397
+ sb.push("(");
1398
+ let numArgs = args.length;
1399
+ if (numArgs) {
1400
+ this.visitNode(args[0]);
1401
+ for (let i = 1; i < numArgs; ++i) {
1402
+ sb.push(", ");
1403
+ this.visitNode(args[i]);
1404
+ }
1405
+ }
1406
+ sb.push(")\n");
1407
+ } else {
1408
+ sb.push("\n");
1409
+ }
1410
+ util.indent(sb, this.indentLevel);
1411
+ }
1412
+
1413
+ serializeParameter(node: ParameterNode): void {
1414
+ var sb = this.sb;
1415
+ var kind = node.parameterKind;
1416
+ var implicitFieldDeclaration = node.implicitFieldDeclaration;
1417
+ if (implicitFieldDeclaration) {
1418
+ this.serializeAccessModifiers(implicitFieldDeclaration);
1419
+ }
1420
+ if (kind == ParameterKind.Rest) {
1421
+ sb.push("...");
1422
+ }
1423
+ this.visitIdentifierExpression(node.name);
1424
+ var type = node.type;
1425
+ var initializer = node.initializer;
1426
+ if (type) {
1427
+ if (kind == ParameterKind.Optional && !initializer) sb.push("?");
1428
+ if (!isTypeOmitted(type)) {
1429
+ sb.push(": ");
1430
+ this.visitTypeNode(type);
1431
+ }
1432
+ }
1433
+ if (initializer) {
1434
+ sb.push(" = ");
1435
+ this.visitNode(initializer);
1436
+ }
1437
+ }
1438
+
1439
+ serializeExternalModifiers(node: DeclarationStatement): void {
1440
+ var sb = this.sb;
1441
+ if (node.is(CommonFlags.Export)) {
1442
+ sb.push("export ");
1443
+ } else if (node.is(CommonFlags.Import)) {
1444
+ sb.push("import ");
1445
+ } else if (node.is(CommonFlags.Declare)) {
1446
+ sb.push("declare ");
1447
+ }
1448
+ }
1449
+
1450
+ serializeAccessModifiers(node: DeclarationStatement): void {
1451
+ var sb = this.sb;
1452
+ if (node.is(CommonFlags.Public)) {
1453
+ sb.push("public ");
1454
+ } else if (node.is(CommonFlags.Private)) {
1455
+ sb.push("private ");
1456
+ } else if (node.is(CommonFlags.Protected)) {
1457
+ sb.push("protected ");
1458
+ }
1459
+ if (node.is(CommonFlags.Static)) {
1460
+ sb.push("static ");
1461
+ } else if (node.is(CommonFlags.Abstract)) {
1462
+ sb.push("abstract ");
1463
+ }
1464
+ if (node.is(CommonFlags.Readonly)) {
1465
+ sb.push("readonly ");
1466
+ }
1467
+ }
1468
+
1469
+ finish(): string {
1470
+ var ret = this.sb.join("");
1471
+ this.sb = [];
1472
+ return ret;
1473
+ }
1474
+ }