ventojs 0.12.1 → 0.12.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.
@@ -1,1159 +0,0 @@
1
- // Astring is a tiny and fast JavaScript code generator from an ESTree-compliant AST.
2
- //
3
- // Astring was written by David Bonnet and released under an MIT license.
4
- //
5
- // The Git repository for Astring is available at:
6
- // https://github.com/davidbonnet/astring.git
7
- //
8
- // Please use the GitHub bug tracker to report issues:
9
- // https://github.com/davidbonnet/astring/issues
10
- const { stringify } = JSON;
11
- /* c8 ignore if */
12
- if (!String.prototype.repeat) {
13
- /* c8 ignore next */
14
- throw new Error('String.prototype.repeat is undefined, see https://github.com/davidbonnet/astring#installation');
15
- }
16
- /* c8 ignore if */
17
- if (!String.prototype.endsWith) {
18
- /* c8 ignore next */
19
- throw new Error('String.prototype.endsWith is undefined, see https://github.com/davidbonnet/astring#installation');
20
- }
21
- const OPERATOR_PRECEDENCE = {
22
- '||': 2,
23
- '??': 3,
24
- '&&': 4,
25
- '|': 5,
26
- '^': 6,
27
- '&': 7,
28
- '==': 8,
29
- '!=': 8,
30
- '===': 8,
31
- '!==': 8,
32
- '<': 9,
33
- '>': 9,
34
- '<=': 9,
35
- '>=': 9,
36
- in: 9,
37
- instanceof: 9,
38
- '<<': 10,
39
- '>>': 10,
40
- '>>>': 10,
41
- '+': 11,
42
- '-': 11,
43
- '*': 12,
44
- '%': 12,
45
- '/': 12,
46
- '**': 13,
47
- };
48
- // Enables parenthesis regardless of precedence
49
- export const NEEDS_PARENTHESES = 17;
50
- export const EXPRESSIONS_PRECEDENCE = {
51
- // Definitions
52
- ArrayExpression: 20,
53
- TaggedTemplateExpression: 20,
54
- ThisExpression: 20,
55
- Identifier: 20,
56
- PrivateIdentifier: 20,
57
- Literal: 18,
58
- TemplateLiteral: 20,
59
- Super: 20,
60
- SequenceExpression: 20,
61
- // Operations
62
- MemberExpression: 19,
63
- ChainExpression: 19,
64
- CallExpression: 19,
65
- NewExpression: 19,
66
- // Other definitions
67
- ArrowFunctionExpression: NEEDS_PARENTHESES,
68
- ClassExpression: NEEDS_PARENTHESES,
69
- FunctionExpression: NEEDS_PARENTHESES,
70
- ObjectExpression: NEEDS_PARENTHESES,
71
- // Other operations
72
- UpdateExpression: 16,
73
- UnaryExpression: 15,
74
- AwaitExpression: 15,
75
- BinaryExpression: 14,
76
- LogicalExpression: 13,
77
- ConditionalExpression: 4,
78
- AssignmentExpression: 3,
79
- YieldExpression: 2,
80
- RestElement: 1,
81
- };
82
- function formatSequence(state, nodes) {
83
- /*
84
- Writes into `state` a sequence of `nodes`.
85
- */
86
- const { generator } = state;
87
- state.write('(');
88
- if (nodes != null && nodes.length > 0) {
89
- generator[nodes[0].type](nodes[0], state);
90
- const { length } = nodes;
91
- for (let i = 1; i < length; i++) {
92
- const param = nodes[i];
93
- state.write(', ');
94
- generator[param.type](param, state);
95
- }
96
- }
97
- state.write(')');
98
- }
99
- function expressionNeedsParenthesis(state, node, parentNode, isRightHand) {
100
- const nodePrecedence = state.expressionsPrecedence[node.type];
101
- if (nodePrecedence === NEEDS_PARENTHESES) {
102
- return true;
103
- }
104
- const parentNodePrecedence = state.expressionsPrecedence[parentNode.type];
105
- if (nodePrecedence !== parentNodePrecedence) {
106
- // Different node types
107
- return ((!isRightHand &&
108
- nodePrecedence === 15 &&
109
- parentNodePrecedence === 14 &&
110
- parentNode.operator === '**') ||
111
- nodePrecedence < parentNodePrecedence);
112
- }
113
- if (nodePrecedence !== 13 && nodePrecedence !== 14) {
114
- // Not a `LogicalExpression` or `BinaryExpression`
115
- return false;
116
- }
117
- if (node.operator === '**' && parentNode.operator === '**') {
118
- // Exponentiation operator has right-to-left associativity
119
- return !isRightHand;
120
- }
121
- if (nodePrecedence === 13 &&
122
- parentNodePrecedence === 13 &&
123
- (node.operator === '??' || parentNode.operator === '??')) {
124
- // Nullish coalescing and boolean operators cannot be combined
125
- return true;
126
- }
127
- if (isRightHand) {
128
- // Parenthesis are used if both operators have the same precedence
129
- return (OPERATOR_PRECEDENCE[node.operator] <=
130
- OPERATOR_PRECEDENCE[parentNode.operator]);
131
- }
132
- return (OPERATOR_PRECEDENCE[node.operator] <
133
- OPERATOR_PRECEDENCE[parentNode.operator]);
134
- }
135
- function formatExpression(state, node, parentNode, isRightHand) {
136
- /*
137
- Writes into `state` the provided `node`, adding parenthesis around if the provided `parentNode` needs it. If `node` is a right-hand argument, the provided `isRightHand` parameter should be `true`.
138
- */
139
- const { generator } = state;
140
- if (expressionNeedsParenthesis(state, node, parentNode, isRightHand)) {
141
- state.write('(');
142
- generator[node.type](node, state);
143
- state.write(')');
144
- }
145
- else {
146
- generator[node.type](node, state);
147
- }
148
- }
149
- function reindent(state, text, indent, lineEnd) {
150
- /*
151
- Writes into `state` the `text` string reindented with the provided `indent`.
152
- */
153
- const lines = text.split('\n');
154
- const end = lines.length - 1;
155
- state.write(lines[0].trim());
156
- if (end > 0) {
157
- state.write(lineEnd);
158
- for (let i = 1; i < end; i++) {
159
- state.write(indent + lines[i].trim() + lineEnd);
160
- }
161
- state.write(indent + lines[end].trim());
162
- }
163
- }
164
- function formatComments(state, comments, indent, lineEnd) {
165
- /*
166
- Writes into `state` the provided list of `comments`, with the given `indent` and `lineEnd` strings.
167
- Line comments will end with `"\n"` regardless of the value of `lineEnd`.
168
- Expects to start on a new unindented line.
169
- */
170
- const { length } = comments;
171
- for (let i = 0; i < length; i++) {
172
- const comment = comments[i];
173
- state.write(indent);
174
- if (comment.type[0] === 'L') {
175
- // Line comment
176
- state.write('// ' + comment.value.trim() + '\n', comment);
177
- }
178
- else {
179
- // Block comment
180
- state.write('/*');
181
- reindent(state, comment.value, indent, lineEnd);
182
- state.write('*/' + lineEnd);
183
- }
184
- }
185
- }
186
- function hasCallExpression(node) {
187
- /*
188
- Returns `true` if the provided `node` contains a call expression and `false` otherwise.
189
- */
190
- let currentNode = node;
191
- while (currentNode != null) {
192
- const { type } = currentNode;
193
- if (type[0] === 'C' && type[1] === 'a') {
194
- // Is CallExpression
195
- return true;
196
- }
197
- else if (type[0] === 'M' && type[1] === 'e' && type[2] === 'm') {
198
- // Is MemberExpression
199
- currentNode = currentNode.object;
200
- }
201
- else {
202
- return false;
203
- }
204
- }
205
- }
206
- function formatVariableDeclaration(state, node) {
207
- /*
208
- Writes into `state` a variable declaration.
209
- */
210
- const { generator } = state;
211
- const { declarations } = node;
212
- state.write(node.kind + ' ');
213
- const { length } = declarations;
214
- if (length > 0) {
215
- generator.VariableDeclarator(declarations[0], state);
216
- for (let i = 1; i < length; i++) {
217
- state.write(', ');
218
- generator.VariableDeclarator(declarations[i], state);
219
- }
220
- }
221
- }
222
- let ForInStatement, FunctionDeclaration, RestElement, BinaryExpression, ArrayExpression, BlockStatement;
223
- export const GENERATOR = {
224
- /*
225
- Default generator.
226
- */
227
- Program(node, state) {
228
- const indent = state.indent.repeat(state.indentLevel);
229
- const { lineEnd, writeComments } = state;
230
- if (writeComments && node.comments != null) {
231
- formatComments(state, node.comments, indent, lineEnd);
232
- }
233
- const statements = node.body;
234
- const { length } = statements;
235
- for (let i = 0; i < length; i++) {
236
- const statement = statements[i];
237
- if (writeComments && statement.comments != null) {
238
- formatComments(state, statement.comments, indent, lineEnd);
239
- }
240
- state.write(indent);
241
- this[statement.type](statement, state);
242
- state.write(lineEnd);
243
- }
244
- if (writeComments && node.trailingComments != null) {
245
- formatComments(state, node.trailingComments, indent, lineEnd);
246
- }
247
- },
248
- BlockStatement: (BlockStatement = function (node, state) {
249
- const indent = state.indent.repeat(state.indentLevel++);
250
- const { lineEnd, writeComments } = state;
251
- const statementIndent = indent + state.indent;
252
- state.write('{');
253
- const statements = node.body;
254
- if (statements != null && statements.length > 0) {
255
- state.write(lineEnd);
256
- if (writeComments && node.comments != null) {
257
- formatComments(state, node.comments, statementIndent, lineEnd);
258
- }
259
- const { length } = statements;
260
- for (let i = 0; i < length; i++) {
261
- const statement = statements[i];
262
- if (writeComments && statement.comments != null) {
263
- formatComments(state, statement.comments, statementIndent, lineEnd);
264
- }
265
- state.write(statementIndent);
266
- this[statement.type](statement, state);
267
- state.write(lineEnd);
268
- }
269
- state.write(indent);
270
- }
271
- else {
272
- if (writeComments && node.comments != null) {
273
- state.write(lineEnd);
274
- formatComments(state, node.comments, statementIndent, lineEnd);
275
- state.write(indent);
276
- }
277
- }
278
- if (writeComments && node.trailingComments != null) {
279
- formatComments(state, node.trailingComments, statementIndent, lineEnd);
280
- }
281
- state.write('}');
282
- state.indentLevel--;
283
- }),
284
- ClassBody: BlockStatement,
285
- StaticBlock(node, state) {
286
- state.write('static ');
287
- this.BlockStatement(node, state);
288
- },
289
- EmptyStatement(node, state) {
290
- state.write(';');
291
- },
292
- ExpressionStatement(node, state) {
293
- const precedence = state.expressionsPrecedence[node.expression.type];
294
- if (precedence === NEEDS_PARENTHESES ||
295
- (precedence === 3 && node.expression.left.type[0] === 'O')) {
296
- // Should always have parentheses or is an AssignmentExpression to an ObjectPattern
297
- state.write('(');
298
- this[node.expression.type](node.expression, state);
299
- state.write(')');
300
- }
301
- else {
302
- this[node.expression.type](node.expression, state);
303
- }
304
- state.write(';');
305
- },
306
- IfStatement(node, state) {
307
- state.write('if (');
308
- this[node.test.type](node.test, state);
309
- state.write(') ');
310
- this[node.consequent.type](node.consequent, state);
311
- if (node.alternate != null) {
312
- state.write(' else ');
313
- this[node.alternate.type](node.alternate, state);
314
- }
315
- },
316
- LabeledStatement(node, state) {
317
- this[node.label.type](node.label, state);
318
- state.write(': ');
319
- this[node.body.type](node.body, state);
320
- },
321
- BreakStatement(node, state) {
322
- state.write('break');
323
- if (node.label != null) {
324
- state.write(' ');
325
- this[node.label.type](node.label, state);
326
- }
327
- state.write(';');
328
- },
329
- ContinueStatement(node, state) {
330
- state.write('continue');
331
- if (node.label != null) {
332
- state.write(' ');
333
- this[node.label.type](node.label, state);
334
- }
335
- state.write(';');
336
- },
337
- WithStatement(node, state) {
338
- state.write('with (');
339
- this[node.object.type](node.object, state);
340
- state.write(') ');
341
- this[node.body.type](node.body, state);
342
- },
343
- SwitchStatement(node, state) {
344
- const indent = state.indent.repeat(state.indentLevel++);
345
- const { lineEnd, writeComments } = state;
346
- state.indentLevel++;
347
- const caseIndent = indent + state.indent;
348
- const statementIndent = caseIndent + state.indent;
349
- state.write('switch (');
350
- this[node.discriminant.type](node.discriminant, state);
351
- state.write(') {' + lineEnd);
352
- const { cases: occurences } = node;
353
- const { length: occurencesCount } = occurences;
354
- for (let i = 0; i < occurencesCount; i++) {
355
- const occurence = occurences[i];
356
- if (writeComments && occurence.comments != null) {
357
- formatComments(state, occurence.comments, caseIndent, lineEnd);
358
- }
359
- if (occurence.test) {
360
- state.write(caseIndent + 'case ');
361
- this[occurence.test.type](occurence.test, state);
362
- state.write(':' + lineEnd);
363
- }
364
- else {
365
- state.write(caseIndent + 'default:' + lineEnd);
366
- }
367
- const { consequent } = occurence;
368
- const { length: consequentCount } = consequent;
369
- for (let i = 0; i < consequentCount; i++) {
370
- const statement = consequent[i];
371
- if (writeComments && statement.comments != null) {
372
- formatComments(state, statement.comments, statementIndent, lineEnd);
373
- }
374
- state.write(statementIndent);
375
- this[statement.type](statement, state);
376
- state.write(lineEnd);
377
- }
378
- }
379
- state.indentLevel -= 2;
380
- state.write(indent + '}');
381
- },
382
- ReturnStatement(node, state) {
383
- state.write('return');
384
- if (node.argument) {
385
- state.write(' ');
386
- this[node.argument.type](node.argument, state);
387
- }
388
- state.write(';');
389
- },
390
- ThrowStatement(node, state) {
391
- state.write('throw ');
392
- this[node.argument.type](node.argument, state);
393
- state.write(';');
394
- },
395
- TryStatement(node, state) {
396
- state.write('try ');
397
- this[node.block.type](node.block, state);
398
- if (node.handler) {
399
- const { handler } = node;
400
- if (handler.param == null) {
401
- state.write(' catch ');
402
- }
403
- else {
404
- state.write(' catch (');
405
- this[handler.param.type](handler.param, state);
406
- state.write(') ');
407
- }
408
- this[handler.body.type](handler.body, state);
409
- }
410
- if (node.finalizer) {
411
- state.write(' finally ');
412
- this[node.finalizer.type](node.finalizer, state);
413
- }
414
- },
415
- WhileStatement(node, state) {
416
- state.write('while (');
417
- this[node.test.type](node.test, state);
418
- state.write(') ');
419
- this[node.body.type](node.body, state);
420
- },
421
- DoWhileStatement(node, state) {
422
- state.write('do ');
423
- this[node.body.type](node.body, state);
424
- state.write(' while (');
425
- this[node.test.type](node.test, state);
426
- state.write(');');
427
- },
428
- ForStatement(node, state) {
429
- state.write('for (');
430
- if (node.init != null) {
431
- const { init } = node;
432
- if (init.type[0] === 'V') {
433
- formatVariableDeclaration(state, init);
434
- }
435
- else {
436
- this[init.type](init, state);
437
- }
438
- }
439
- state.write('; ');
440
- if (node.test) {
441
- this[node.test.type](node.test, state);
442
- }
443
- state.write('; ');
444
- if (node.update) {
445
- this[node.update.type](node.update, state);
446
- }
447
- state.write(') ');
448
- this[node.body.type](node.body, state);
449
- },
450
- ForInStatement: (ForInStatement = function (node, state) {
451
- state.write(`for ${node.await ? 'await ' : ''}(`);
452
- const { left } = node;
453
- if (left.type[0] === 'V') {
454
- formatVariableDeclaration(state, left);
455
- }
456
- else {
457
- this[left.type](left, state);
458
- }
459
- // Identifying whether node.type is `ForInStatement` or `ForOfStatement`
460
- state.write(node.type[3] === 'I' ? ' in ' : ' of ');
461
- this[node.right.type](node.right, state);
462
- state.write(') ');
463
- this[node.body.type](node.body, state);
464
- }),
465
- ForOfStatement: ForInStatement,
466
- DebuggerStatement(node, state) {
467
- state.write('debugger;', node);
468
- },
469
- FunctionDeclaration: (FunctionDeclaration = function (node, state) {
470
- state.write((node.async ? 'async ' : '') +
471
- (node.generator ? 'function* ' : 'function ') +
472
- (node.id ? node.id.name : ''), node);
473
- formatSequence(state, node.params);
474
- state.write(' ');
475
- this[node.body.type](node.body, state);
476
- }),
477
- FunctionExpression: FunctionDeclaration,
478
- VariableDeclaration(node, state) {
479
- formatVariableDeclaration(state, node);
480
- state.write(';');
481
- },
482
- VariableDeclarator(node, state) {
483
- this[node.id.type](node.id, state);
484
- if (node.init != null) {
485
- state.write(' = ');
486
- this[node.init.type](node.init, state);
487
- }
488
- },
489
- ClassDeclaration(node, state) {
490
- state.write('class ' + (node.id ? `${node.id.name} ` : ''), node);
491
- if (node.superClass) {
492
- state.write('extends ');
493
- const { superClass } = node;
494
- const { type } = superClass;
495
- const precedence = state.expressionsPrecedence[type];
496
- if ((type[0] !== 'C' || type[1] !== 'l' || type[5] !== 'E') &&
497
- (precedence === NEEDS_PARENTHESES ||
498
- precedence < state.expressionsPrecedence.ClassExpression)) {
499
- // Not a ClassExpression that needs parentheses
500
- state.write('(');
501
- this[node.superClass.type](superClass, state);
502
- state.write(')');
503
- }
504
- else {
505
- this[superClass.type](superClass, state);
506
- }
507
- state.write(' ');
508
- }
509
- this.ClassBody(node.body, state);
510
- },
511
- ImportDeclaration(node, state) {
512
- state.write('import ');
513
- const { specifiers } = node;
514
- const { length } = specifiers;
515
- // TODO: Once babili is fixed, put this after condition
516
- // https://github.com/babel/babili/issues/430
517
- let i = 0;
518
- if (length > 0) {
519
- for (; i < length;) {
520
- if (i > 0) {
521
- state.write(', ');
522
- }
523
- const specifier = specifiers[i];
524
- const type = specifier.type[6];
525
- if (type === 'D') {
526
- // ImportDefaultSpecifier
527
- state.write(specifier.local.name, specifier);
528
- i++;
529
- }
530
- else if (type === 'N') {
531
- // ImportNamespaceSpecifier
532
- state.write('* as ' + specifier.local.name, specifier);
533
- i++;
534
- }
535
- else {
536
- // ImportSpecifier
537
- break;
538
- }
539
- }
540
- if (i < length) {
541
- state.write('{');
542
- for (;;) {
543
- const specifier = specifiers[i];
544
- const { name } = specifier.imported;
545
- state.write(name, specifier);
546
- if (name !== specifier.local.name) {
547
- state.write(' as ' + specifier.local.name);
548
- }
549
- if (++i < length) {
550
- state.write(', ');
551
- }
552
- else {
553
- break;
554
- }
555
- }
556
- state.write('}');
557
- }
558
- state.write(' from ');
559
- }
560
- this.Literal(node.source, state);
561
- state.write(';');
562
- },
563
- ImportExpression(node, state) {
564
- state.write('import(');
565
- this[node.source.type](node.source, state);
566
- state.write(')');
567
- },
568
- ExportDefaultDeclaration(node, state) {
569
- state.write('export default ');
570
- this[node.declaration.type](node.declaration, state);
571
- if (state.expressionsPrecedence[node.declaration.type] != null &&
572
- node.declaration.type[0] !== 'F') {
573
- // All expression nodes except `FunctionExpression`
574
- state.write(';');
575
- }
576
- },
577
- ExportNamedDeclaration(node, state) {
578
- state.write('export ');
579
- if (node.declaration) {
580
- this[node.declaration.type](node.declaration, state);
581
- }
582
- else {
583
- state.write('{');
584
- const { specifiers } = node, { length } = specifiers;
585
- if (length > 0) {
586
- for (let i = 0;;) {
587
- const specifier = specifiers[i];
588
- const { name } = specifier.local;
589
- state.write(name, specifier);
590
- if (name !== specifier.exported.name) {
591
- state.write(' as ' + specifier.exported.name);
592
- }
593
- if (++i < length) {
594
- state.write(', ');
595
- }
596
- else {
597
- break;
598
- }
599
- }
600
- }
601
- state.write('}');
602
- if (node.source) {
603
- state.write(' from ');
604
- this.Literal(node.source, state);
605
- }
606
- state.write(';');
607
- }
608
- },
609
- ExportAllDeclaration(node, state) {
610
- if (node.exported != null) {
611
- state.write('export * as ' + node.exported.name + ' from ');
612
- }
613
- else {
614
- state.write('export * from ');
615
- }
616
- this.Literal(node.source, state);
617
- state.write(';');
618
- },
619
- MethodDefinition(node, state) {
620
- if (node.static) {
621
- state.write('static ');
622
- }
623
- const kind = node.kind[0];
624
- if (kind === 'g' || kind === 's') {
625
- // Getter or setter
626
- state.write(node.kind + ' ');
627
- }
628
- if (node.value.async) {
629
- state.write('async ');
630
- }
631
- if (node.value.generator) {
632
- state.write('*');
633
- }
634
- if (node.computed) {
635
- state.write('[');
636
- this[node.key.type](node.key, state);
637
- state.write(']');
638
- }
639
- else {
640
- this[node.key.type](node.key, state);
641
- }
642
- formatSequence(state, node.value.params);
643
- state.write(' ');
644
- this[node.value.body.type](node.value.body, state);
645
- },
646
- ClassExpression(node, state) {
647
- this.ClassDeclaration(node, state);
648
- },
649
- ArrowFunctionExpression(node, state) {
650
- state.write(node.async ? 'async ' : '', node);
651
- const { params } = node;
652
- if (params != null) {
653
- // Omit parenthesis if only one named parameter
654
- if (params.length === 1 && params[0].type[0] === 'I') {
655
- // If params[0].type[0] starts with 'I', it can't be `ImportDeclaration` nor `IfStatement` and thus is `Identifier`
656
- state.write(params[0].name, params[0]);
657
- }
658
- else {
659
- formatSequence(state, node.params);
660
- }
661
- }
662
- state.write(' => ');
663
- if (node.body.type[0] === 'O') {
664
- // Body is an object expression
665
- state.write('(');
666
- this.ObjectExpression(node.body, state);
667
- state.write(')');
668
- }
669
- else {
670
- this[node.body.type](node.body, state);
671
- }
672
- },
673
- ThisExpression(node, state) {
674
- state.write('this', node);
675
- },
676
- Super(node, state) {
677
- state.write('super', node);
678
- },
679
- RestElement: (RestElement = function (node, state) {
680
- state.write('...');
681
- this[node.argument.type](node.argument, state);
682
- }),
683
- SpreadElement: RestElement,
684
- YieldExpression(node, state) {
685
- state.write(node.delegate ? 'yield*' : 'yield');
686
- if (node.argument) {
687
- state.write(' ');
688
- this[node.argument.type](node.argument, state);
689
- }
690
- },
691
- AwaitExpression(node, state) {
692
- state.write('await ', node);
693
- formatExpression(state, node.argument, node);
694
- },
695
- TemplateLiteral(node, state) {
696
- const { quasis, expressions } = node;
697
- state.write('`');
698
- const { length } = expressions;
699
- for (let i = 0; i < length; i++) {
700
- const expression = expressions[i];
701
- const quasi = quasis[i];
702
- state.write(quasi.value.raw, quasi);
703
- state.write('${');
704
- this[expression.type](expression, state);
705
- state.write('}');
706
- }
707
- const quasi = quasis[quasis.length - 1];
708
- state.write(quasi.value.raw, quasi);
709
- state.write('`');
710
- },
711
- TemplateElement(node, state) {
712
- state.write(node.value.raw, node);
713
- },
714
- TaggedTemplateExpression(node, state) {
715
- formatExpression(state, node.tag, node);
716
- this[node.quasi.type](node.quasi, state);
717
- },
718
- ArrayExpression: (ArrayExpression = function (node, state) {
719
- state.write('[');
720
- if (node.elements.length > 0) {
721
- const { elements } = node, { length } = elements;
722
- for (let i = 0;;) {
723
- const element = elements[i];
724
- if (element != null) {
725
- this[element.type](element, state);
726
- }
727
- if (++i < length) {
728
- state.write(', ');
729
- }
730
- else {
731
- if (element == null) {
732
- state.write(', ');
733
- }
734
- break;
735
- }
736
- }
737
- }
738
- state.write(']');
739
- }),
740
- ArrayPattern: ArrayExpression,
741
- ObjectExpression(node, state) {
742
- const indent = state.indent.repeat(state.indentLevel++);
743
- const { lineEnd, writeComments } = state;
744
- const propertyIndent = indent + state.indent;
745
- state.write('{');
746
- if (node.properties.length > 0) {
747
- state.write(lineEnd);
748
- if (writeComments && node.comments != null) {
749
- formatComments(state, node.comments, propertyIndent, lineEnd);
750
- }
751
- const comma = ',' + lineEnd;
752
- const { properties } = node, { length } = properties;
753
- for (let i = 0;;) {
754
- const property = properties[i];
755
- if (writeComments && property.comments != null) {
756
- formatComments(state, property.comments, propertyIndent, lineEnd);
757
- }
758
- state.write(propertyIndent);
759
- this[property.type](property, state);
760
- if (++i < length) {
761
- state.write(comma);
762
- }
763
- else {
764
- break;
765
- }
766
- }
767
- state.write(lineEnd);
768
- if (writeComments && node.trailingComments != null) {
769
- formatComments(state, node.trailingComments, propertyIndent, lineEnd);
770
- }
771
- state.write(indent + '}');
772
- }
773
- else if (writeComments) {
774
- if (node.comments != null) {
775
- state.write(lineEnd);
776
- formatComments(state, node.comments, propertyIndent, lineEnd);
777
- if (node.trailingComments != null) {
778
- formatComments(state, node.trailingComments, propertyIndent, lineEnd);
779
- }
780
- state.write(indent + '}');
781
- }
782
- else if (node.trailingComments != null) {
783
- state.write(lineEnd);
784
- formatComments(state, node.trailingComments, propertyIndent, lineEnd);
785
- state.write(indent + '}');
786
- }
787
- else {
788
- state.write('}');
789
- }
790
- }
791
- else {
792
- state.write('}');
793
- }
794
- state.indentLevel--;
795
- },
796
- Property(node, state) {
797
- if (node.method || node.kind[0] !== 'i') {
798
- // Either a method or of kind `set` or `get` (not `init`)
799
- this.MethodDefinition(node, state);
800
- }
801
- else {
802
- if (!node.shorthand) {
803
- if (node.computed) {
804
- state.write('[');
805
- this[node.key.type](node.key, state);
806
- state.write(']');
807
- }
808
- else {
809
- this[node.key.type](node.key, state);
810
- }
811
- state.write(': ');
812
- }
813
- this[node.value.type](node.value, state);
814
- }
815
- },
816
- PropertyDefinition(node, state) {
817
- if (node.static) {
818
- state.write('static ');
819
- }
820
- if (node.computed) {
821
- state.write('[');
822
- }
823
- this[node.key.type](node.key, state);
824
- if (node.computed) {
825
- state.write(']');
826
- }
827
- if (node.value == null) {
828
- if (node.key.type[0] !== 'F') {
829
- state.write(';');
830
- }
831
- return;
832
- }
833
- state.write(' = ');
834
- this[node.value.type](node.value, state);
835
- state.write(';');
836
- },
837
- ObjectPattern(node, state) {
838
- state.write('{');
839
- if (node.properties.length > 0) {
840
- const { properties } = node, { length } = properties;
841
- for (let i = 0;;) {
842
- this[properties[i].type](properties[i], state);
843
- if (++i < length) {
844
- state.write(', ');
845
- }
846
- else {
847
- break;
848
- }
849
- }
850
- }
851
- state.write('}');
852
- },
853
- SequenceExpression(node, state) {
854
- formatSequence(state, node.expressions);
855
- },
856
- UnaryExpression(node, state) {
857
- if (node.prefix) {
858
- const { operator, argument, argument: { type }, } = node;
859
- state.write(operator);
860
- const needsParentheses = expressionNeedsParenthesis(state, argument, node);
861
- if (!needsParentheses &&
862
- (operator.length > 1 ||
863
- (type[0] === 'U' &&
864
- (type[1] === 'n' || type[1] === 'p') &&
865
- argument.prefix &&
866
- argument.operator[0] === operator &&
867
- (operator === '+' || operator === '-')))) {
868
- // Large operator or argument is UnaryExpression or UpdateExpression node
869
- state.write(' ');
870
- }
871
- if (needsParentheses) {
872
- state.write(operator.length > 1 ? ' (' : '(');
873
- this[type](argument, state);
874
- state.write(')');
875
- }
876
- else {
877
- this[type](argument, state);
878
- }
879
- }
880
- else {
881
- // FIXME: This case never occurs
882
- this[node.argument.type](node.argument, state);
883
- state.write(node.operator);
884
- }
885
- },
886
- UpdateExpression(node, state) {
887
- // Always applied to identifiers or members, no parenthesis check needed
888
- if (node.prefix) {
889
- state.write(node.operator);
890
- this[node.argument.type](node.argument, state);
891
- }
892
- else {
893
- this[node.argument.type](node.argument, state);
894
- state.write(node.operator);
895
- }
896
- },
897
- AssignmentExpression(node, state) {
898
- this[node.left.type](node.left, state);
899
- state.write(' ' + node.operator + ' ');
900
- this[node.right.type](node.right, state);
901
- },
902
- AssignmentPattern(node, state) {
903
- this[node.left.type](node.left, state);
904
- state.write(' = ');
905
- this[node.right.type](node.right, state);
906
- },
907
- BinaryExpression: (BinaryExpression = function (node, state) {
908
- const isIn = node.operator === 'in';
909
- if (isIn) {
910
- // Avoids confusion in `for` loops initializers
911
- state.write('(');
912
- }
913
- formatExpression(state, node.left, node, false);
914
- state.write(' ' + node.operator + ' ');
915
- formatExpression(state, node.right, node, true);
916
- if (isIn) {
917
- state.write(')');
918
- }
919
- }),
920
- LogicalExpression: BinaryExpression,
921
- ConditionalExpression(node, state) {
922
- const { test } = node;
923
- const precedence = state.expressionsPrecedence[test.type];
924
- if (precedence === NEEDS_PARENTHESES ||
925
- precedence <= state.expressionsPrecedence.ConditionalExpression) {
926
- state.write('(');
927
- this[test.type](test, state);
928
- state.write(')');
929
- }
930
- else {
931
- this[test.type](test, state);
932
- }
933
- state.write(' ? ');
934
- this[node.consequent.type](node.consequent, state);
935
- state.write(' : ');
936
- this[node.alternate.type](node.alternate, state);
937
- },
938
- NewExpression(node, state) {
939
- state.write('new ');
940
- const precedence = state.expressionsPrecedence[node.callee.type];
941
- if (precedence === NEEDS_PARENTHESES ||
942
- precedence < state.expressionsPrecedence.CallExpression ||
943
- hasCallExpression(node.callee)) {
944
- state.write('(');
945
- this[node.callee.type](node.callee, state);
946
- state.write(')');
947
- }
948
- else {
949
- this[node.callee.type](node.callee, state);
950
- }
951
- formatSequence(state, node['arguments']);
952
- },
953
- CallExpression(node, state) {
954
- const precedence = state.expressionsPrecedence[node.callee.type];
955
- if (precedence === NEEDS_PARENTHESES ||
956
- precedence < state.expressionsPrecedence.CallExpression) {
957
- state.write('(');
958
- this[node.callee.type](node.callee, state);
959
- state.write(')');
960
- }
961
- else {
962
- this[node.callee.type](node.callee, state);
963
- }
964
- if (node.optional) {
965
- state.write('?.');
966
- }
967
- formatSequence(state, node['arguments']);
968
- },
969
- ChainExpression(node, state) {
970
- this[node.expression.type](node.expression, state);
971
- },
972
- MemberExpression(node, state) {
973
- const precedence = state.expressionsPrecedence[node.object.type];
974
- if (precedence === NEEDS_PARENTHESES ||
975
- precedence < state.expressionsPrecedence.MemberExpression) {
976
- state.write('(');
977
- this[node.object.type](node.object, state);
978
- state.write(')');
979
- }
980
- else {
981
- this[node.object.type](node.object, state);
982
- }
983
- if (node.computed) {
984
- if (node.optional) {
985
- state.write('?.');
986
- }
987
- state.write('[');
988
- this[node.property.type](node.property, state);
989
- state.write(']');
990
- }
991
- else {
992
- if (node.optional) {
993
- state.write('?.');
994
- }
995
- else {
996
- state.write('.');
997
- }
998
- this[node.property.type](node.property, state);
999
- }
1000
- },
1001
- MetaProperty(node, state) {
1002
- state.write(node.meta.name + '.' + node.property.name, node);
1003
- },
1004
- Identifier(node, state) {
1005
- state.write(node.name, node);
1006
- },
1007
- PrivateIdentifier(node, state) {
1008
- state.write(`#${node.name}`, node);
1009
- },
1010
- Literal(node, state) {
1011
- if (node.raw != null) {
1012
- // Non-standard property
1013
- state.write(node.raw, node);
1014
- }
1015
- else if (node.regex != null) {
1016
- this.RegExpLiteral(node, state);
1017
- }
1018
- else if (node.bigint != null) {
1019
- state.write(node.bigint + 'n', node);
1020
- }
1021
- else {
1022
- state.write(stringify(node.value), node);
1023
- }
1024
- },
1025
- RegExpLiteral(node, state) {
1026
- const { regex } = node;
1027
- state.write(`/${regex.pattern}/${regex.flags}`, node);
1028
- },
1029
- };
1030
- const EMPTY_OBJECT = {};
1031
- /*
1032
- DEPRECATED: Alternate export of `GENERATOR`.
1033
- */
1034
- export const baseGenerator = GENERATOR;
1035
- class State {
1036
- constructor(options) {
1037
- const setup = options == null ? EMPTY_OBJECT : options;
1038
- this.output = '';
1039
- // Functional options
1040
- if (setup.output != null) {
1041
- this.output = setup.output;
1042
- this.write = this.writeToStream;
1043
- }
1044
- else {
1045
- this.output = '';
1046
- }
1047
- this.generator = setup.generator != null ? setup.generator : GENERATOR;
1048
- this.expressionsPrecedence =
1049
- setup.expressionsPrecedence != null
1050
- ? setup.expressionsPrecedence
1051
- : EXPRESSIONS_PRECEDENCE;
1052
- // Formating setup
1053
- this.indent = setup.indent != null ? setup.indent : ' ';
1054
- this.lineEnd = setup.lineEnd != null ? setup.lineEnd : '\n';
1055
- this.indentLevel =
1056
- setup.startingIndentLevel != null ? setup.startingIndentLevel : 0;
1057
- this.writeComments = setup.comments ? setup.comments : false;
1058
- // Source map
1059
- if (setup.sourceMap != null) {
1060
- this.write =
1061
- setup.output == null ? this.writeAndMap : this.writeToStreamAndMap;
1062
- this.sourceMap = setup.sourceMap;
1063
- this.line = 1;
1064
- this.column = 0;
1065
- this.lineEndSize = this.lineEnd.split('\n').length - 1;
1066
- this.mapping = {
1067
- original: null,
1068
- // Uses the entire state to avoid generating ephemeral objects
1069
- generated: this,
1070
- name: undefined,
1071
- source: setup.sourceMap.file || setup.sourceMap._file,
1072
- };
1073
- }
1074
- }
1075
- write(code) {
1076
- this.output += code;
1077
- }
1078
- writeToStream(code) {
1079
- this.output.write(code);
1080
- }
1081
- writeAndMap(code, node) {
1082
- this.output += code;
1083
- this.map(code, node);
1084
- }
1085
- writeToStreamAndMap(code, node) {
1086
- this.output.write(code);
1087
- this.map(code, node);
1088
- }
1089
- map(code, node) {
1090
- if (node != null) {
1091
- const { type } = node;
1092
- if (type[0] === 'L' && type[2] === 'n') {
1093
- // LineComment
1094
- this.column = 0;
1095
- this.line++;
1096
- return;
1097
- }
1098
- if (node.loc != null) {
1099
- const { mapping } = this;
1100
- mapping.original = node.loc.start;
1101
- mapping.name = node.name;
1102
- this.sourceMap.addMapping(mapping);
1103
- }
1104
- if ((type[0] === 'T' && type[8] === 'E') ||
1105
- (type[0] === 'L' && type[1] === 'i' && typeof node.value === 'string')) {
1106
- // TemplateElement or Literal string node
1107
- const { length } = code;
1108
- let { column, line } = this;
1109
- for (let i = 0; i < length; i++) {
1110
- if (code[i] === '\n') {
1111
- column = 0;
1112
- line++;
1113
- }
1114
- else {
1115
- column++;
1116
- }
1117
- }
1118
- this.column = column;
1119
- this.line = line;
1120
- return;
1121
- }
1122
- }
1123
- const { length } = code;
1124
- const { lineEnd } = this;
1125
- if (length > 0) {
1126
- if (this.lineEndSize > 0 &&
1127
- (lineEnd.length === 1
1128
- ? code[length - 1] === lineEnd
1129
- : code.endsWith(lineEnd))) {
1130
- this.line += this.lineEndSize;
1131
- this.column = 0;
1132
- }
1133
- else {
1134
- this.column += length;
1135
- }
1136
- }
1137
- }
1138
- toString() {
1139
- return this.output;
1140
- }
1141
- }
1142
- export function generate(node, options) {
1143
- /*
1144
- Returns a string representing the rendered code of the provided AST `node`.
1145
- The `options` are:
1146
-
1147
- - `indent`: string to use for indentation (defaults to `␣␣`)
1148
- - `lineEnd`: string to use for line endings (defaults to `\n`)
1149
- - `startingIndentLevel`: indent level to start from (defaults to `0`)
1150
- - `comments`: generate comments if `true` (defaults to `false`)
1151
- - `output`: output stream to write the rendered code to (defaults to `null`)
1152
- - `generator`: custom code generator (defaults to `GENERATOR`)
1153
- - `expressionsPrecedence`: custom map of node types and their precedence level (defaults to `EXPRESSIONS_PRECEDENCE`)
1154
- */
1155
- const state = new State(options);
1156
- // Travel through the AST node and generate the code
1157
- state.generator[node.type](node, state);
1158
- return state.output;
1159
- }