json-as 0.9.28 → 1.0.0-alpha.1

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