@jsenv/core 36.1.1 → 36.1.3

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,3860 +0,0 @@
1
- import { createRequire} from 'node:module'
2
- import helpers_string_1 from "./helpers-string.js";
3
-
4
- const require = createRequire(import.meta.url);
5
-
6
- "use strict";
7
-
8
- const defaultConfigValues = {
9
- externalHelpers: false,
10
- hoist: false,
11
- inlineHelpers: false,
12
- minify: false,
13
- target: "es5",
14
- topLevelAwait: "disabled",
15
- asyncAwait: true,
16
- };
17
- function readConfigKey(config, key) {
18
- if (Object.hasOwnProperty.call(config, key)) {
19
- const result = config[key];
20
- if (typeof result !== "undefined") {
21
- return result;
22
- }
23
- }
24
- return defaultConfigValues[key];
25
- }
26
- function discardingIntrinsics(node) {
27
- if (node.type == "V8IntrinsicIdentifier") {
28
- throw new Error(`Expected either an expression or a statement, got a ${node.type}!`);
29
- }
30
- return node;
31
- }
32
- function clearDeclarationData(declaration) {
33
- let path = declaration;
34
- while (path) {
35
- if (path.getData("declaration:var:2") == declaration) {
36
- path.setData("declaration:var:2", null);
37
- }
38
- path = path.parentPath;
39
- }
40
- }
41
- const constantFunctionMethods = {
42
- "call": false,
43
- "apply": false,
44
- "bind": false,
45
- };
46
- const constantStaticMethods = {
47
- "Object": Object.assign({ "assign": true, "create": true, "defineProperty": true, "defineProperties": true, "entries": true, "freeze": true, "fromEntries": true, "getOwnPropertyDescriptor": true, "getOwnPropertyDescriptors": true, "getOwnPropertyNames": true, "getOwnPropertySymbols": true, "getPrototypeOf": true, "is": true, "isExtensible": true, "isFrozen": true, "isSealed": true, "keys": true, "preventExtensions": true, "seal": true, "setPrototypeOf": true, "values": true }, constantFunctionMethods),
48
- "Function": constantFunctionMethods,
49
- "Boolean": constantFunctionMethods,
50
- "Number": Object.assign({ "isNaN": true, "isFinite": true, "isInteger": true, "isSafeInteger": true, "parseFloat": true, "parseInteger": true }, constantFunctionMethods),
51
- "Array": Object.assign({ "from": true, "isArray": true, "of": true }, constantFunctionMethods),
52
- "Date": Object.assign({ "now": true, "parse": true, "UTC": true }, constantFunctionMethods),
53
- "RegExp": constantFunctionMethods,
54
- "Error": constantFunctionMethods,
55
- "TypeError": constantFunctionMethods,
56
- "Map": constantFunctionMethods,
57
- "Set": constantFunctionMethods,
58
- "WeakMap": constantFunctionMethods,
59
- "WeakSet": constantFunctionMethods,
60
- "Promise": Object.assign({ "all": true, "race": true, "resolve": true, "reject": true }, constantFunctionMethods),
61
- "Math": {
62
- "abs": true,
63
- "acos": true,
64
- "asin": true,
65
- "atan": true,
66
- "atan2": true,
67
- "ceil": true,
68
- "cos": true,
69
- "exp": true,
70
- "floor": true,
71
- "log": true,
72
- "max": true,
73
- "min": true,
74
- "pow": true,
75
- "random": true,
76
- "round": true,
77
- "sin": true,
78
- "sqrt": true,
79
- "tan": true,
80
- },
81
- "JSON": {
82
- "parse": true,
83
- "stringify": true,
84
- },
85
- "URL": Object.assign({ "createObjectURL": true, "revokeObjectURL": true }, constantFunctionMethods),
86
- "console": {
87
- "assert": true,
88
- "clear": true,
89
- "count": true,
90
- "error": true,
91
- "info": true,
92
- "log": true,
93
- "warn": true,
94
- },
95
- "document": {
96
- "createComment": true,
97
- "createElement": true,
98
- "createTextNode": true,
99
- "getElementsByClassName": true,
100
- "getElementsByTagName": true,
101
- "getElementsByName": true,
102
- "getElementById": true,
103
- "querySelector": true,
104
- "querySelectorAll": true,
105
- "write": true,
106
- "writeln": true,
107
- },
108
- "XMLHttpRequest": constantFunctionMethods,
109
- "WebSocket": constantFunctionMethods,
110
- "Image": constantFunctionMethods,
111
- "alert": constantFunctionMethods,
112
- "confirm": constantFunctionMethods,
113
- "open": constantFunctionMethods,
114
- "prompt": constantFunctionMethods,
115
- "eval": constantFunctionMethods,
116
- "isFinite": constantFunctionMethods,
117
- "isNaN": constantFunctionMethods,
118
- "parseInt": constantFunctionMethods,
119
- "parseFloat": constantFunctionMethods,
120
- "decodeURI": constantFunctionMethods,
121
- "decodeURIComponent": constantFunctionMethods,
122
- "encodeURI": constantFunctionMethods,
123
- "encodeURIComponent": constantFunctionMethods,
124
- "escape": constantFunctionMethods,
125
- "unescape": constantFunctionMethods,
126
- "$": constantFunctionMethods,
127
- };
128
- const originalNodeMap = new WeakMap();
129
- const skipNodeSet = new WeakSet();
130
- const breakIdentifierMap = new WeakMap();
131
- const isHelperDefinitionSet = new WeakSet();
132
- const helperNameMap = new WeakMap();
133
- const nodeIsAsyncSet = new WeakSet();
134
- let helpers;
135
- const alwaysTruthy = Object.keys(constantStaticMethods);
136
- const numberNames = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
137
- function default_1({ types, traverse, transformFromAst, version, }) {
138
- const isNewBabel = !/^6\./.test(version);
139
- function cloneNode(node) {
140
- const result = types.cloneDeep(node);
141
- if (types.isIdentifier(node) || types.isMemberExpression(node)) {
142
- const helperName = helperNameMap.get(node);
143
- if (helperName !== undefined) {
144
- helperNameMap.set(result, helperName);
145
- }
146
- }
147
- return result;
148
- }
149
- function wrapNodeInStatement(node) {
150
- if (types.isStatement(node)) {
151
- return types.blockStatement([node]);
152
- }
153
- if (types.isExpression(node)) {
154
- return types.expressionStatement(node);
155
- }
156
- throw new Error(`Expected either an expression or a statement, got a ${node.type}!`);
157
- }
158
- function pathForNewNode(node, parentPath) {
159
- let contextPath = parentPath;
160
- while (contextPath != null) {
161
- if (contextPath.context) {
162
- const result = contextPath.context.create(parentPath.node, [node], 0, "dummy");
163
- result.setContext(contextPath.context);
164
- return result;
165
- }
166
- contextPath = contextPath.parentPath;
167
- }
168
- throw parentPath.buildCodeFrameError(`Unable to find a context upon which to traverse!`, TypeError);
169
- }
170
- function pathsPassTest(matchingNodeTest, referenceOriginalNodes) {
171
- function visit(path, result, state) {
172
- if (referenceOriginalNodes) {
173
- const originalNode = originalNodeMap.get(path.node);
174
- if (originalNode) {
175
- traverse(wrapNodeInStatement(originalNode), visitor, path.scope, { match: result, state }, path);
176
- return false;
177
- }
178
- }
179
- const doesMatch = matchingNodeTest(path);
180
- if (doesMatch) {
181
- result.any = true;
182
- result.all = !(state.breakingLabels.length || state.unnamedBreak);
183
- }
184
- if (path.isBreakStatement()) {
185
- const label = path.node.label;
186
- if (!label) {
187
- state.unnamedBreak = true;
188
- }
189
- else if (state.breakingLabels.indexOf(label.name) === -1) {
190
- state.breakingLabels.push(label.name);
191
- }
192
- }
193
- if (path.isLabeledStatement()) {
194
- const index = state.breakingLabels.indexOf(path.node.label.name);
195
- if (index !== -1) {
196
- state.breakingLabels.splice(index, 1);
197
- }
198
- }
199
- if (path.isLoop()) {
200
- state.unnamedBreak = false;
201
- }
202
- if (doesMatch) {
203
- return false;
204
- }
205
- if (path.isConditional()) {
206
- const test = match(path.get("test"), state);
207
- const consequent = match(path.get("consequent"), state);
208
- const alternate = match(path.get("alternate"), state);
209
- result.any = result.any || test.any || consequent.any || alternate.any;
210
- return (result.all =
211
- (test.all || (consequent.all && alternate.all)) &&
212
- !(state.breakingLabels.length || state.unnamedBreak));
213
- }
214
- if (path.isSwitchStatement()) {
215
- const discriminant = match(path.get("discriminant"), state);
216
- const cases = path.get("cases");
217
- const caseMatches = cases.map((switchCase, i) => {
218
- const newState = { unnamedBreak: false, breakingLabels: state.breakingLabels };
219
- const newResult = match(switchCase, newState);
220
- for (i++; (!newResult.all || pathsBreakReturnOrThrow(switchCase).all) && i < cases.length; i++) {
221
- const tailMatch = match(cases[i], newState);
222
- newResult.all =
223
- (newResult.all || tailMatch.all) && !(state.breakingLabels.length || state.unnamedBreak);
224
- newResult.any = newResult.any || tailMatch.any;
225
- }
226
- return newResult;
227
- });
228
- result.any = result.any || discriminant.any || caseMatches.some((caseMatch) => caseMatch.any);
229
- return (result.all =
230
- (discriminant.all ||
231
- (cases.some((switchCase) => !switchCase.node.test) &&
232
- caseMatches.every((caseMatch) => caseMatch.all))) &&
233
- !(state.breakingLabels.length || state.unnamedBreak));
234
- }
235
- if (path.isDoWhileStatement()) {
236
- const body = match(path.get("body"), { unnamedBreak: false, breakingLabels: state.breakingLabels });
237
- const test = match(path.get("test"), state);
238
- result.any = result.any || body.any || test.any;
239
- return (result.all = (body.all || test.all) && !(state.breakingLabels.length || state.unnamedBreak));
240
- }
241
- if (path.isWhileStatement()) {
242
- const testPath = path.get("test");
243
- const test = match(testPath, state);
244
- const body = match(path.get("body"), { unnamedBreak: false, breakingLabels: state.breakingLabels });
245
- result.any = result.any || test.any || body.any;
246
- return (result.all =
247
- (test.all || (body.all && extractLooseBooleanValue(testPath.node) === true)) &&
248
- !(state.breakingLabels.length || state.unnamedBreak));
249
- }
250
- if (path.isForXStatement()) {
251
- const right = match(path.get("right"), state);
252
- const body = match(path.get("body"), { unnamedBreak: false, breakingLabels: state.breakingLabels });
253
- result.any = result.any || right.any || body.any;
254
- return (result.all = right.all && !(state.breakingLabels.length || state.unnamedBreak));
255
- }
256
- if (path.isForStatement()) {
257
- const init = match(path.get("init"), state);
258
- const test = match(path.get("test"), state);
259
- const body = match(path.get("body"), { unnamedBreak: false, breakingLabels: state.breakingLabels });
260
- const update = match(path.get("update"), state);
261
- result.any = result.any || init.any || test.any || body.any || update.any;
262
- return (result.all = (init.all || test.all) && !(state.breakingLabels.length || state.unnamedBreak));
263
- }
264
- if (path.isLogicalExpression()) {
265
- const left = match(path.get("left"), state);
266
- const right = match(path.get("right"), state);
267
- result.any = result.any || left.any || right.any;
268
- return (result.all = left.all && !(state.breakingLabels.length || state.unnamedBreak));
269
- }
270
- if (path.isReturnStatement()) {
271
- return true;
272
- }
273
- if (path.isBreakStatement()) {
274
- return true;
275
- }
276
- if (path.isContinueStatement()) {
277
- return true;
278
- }
279
- if (path.isThrowStatement()) {
280
- return true;
281
- }
282
- if (path.isTryStatement()) {
283
- const blockMatch = match(path.get("block"), state);
284
- const finalizer = path.get("finalizer");
285
- const finalizerMatch = match(finalizer, state);
286
- const handler = path.get("handler");
287
- const handlerMatch = match(handler, state);
288
- result.any = result.any || blockMatch.any || handlerMatch.any || finalizerMatch.any;
289
- if (finalizerMatch.all) {
290
- return (result.all = !(state.breakingLabels.length || state.unnamedBreak));
291
- }
292
- else if (!finalizer.node) {
293
- return (result.all =
294
- handlerMatch.all && blockMatch.all && !(state.breakingLabels.length || state.unnamedBreak));
295
- }
296
- return false;
297
- }
298
- if (path.isFunction()) {
299
- return false;
300
- }
301
- }
302
- const visitor = {
303
- enter(path) {
304
- switch (visit(path, this.match, this.state)) {
305
- case true:
306
- path.stop();
307
- break;
308
- case false:
309
- path.skip();
310
- break;
311
- }
312
- },
313
- };
314
- function match(path, state) {
315
- const match = { all: false, any: false };
316
- if (path && path.node) {
317
- if (typeof visit(path, match, state) === "undefined") {
318
- path.traverse(visitor, { match, state });
319
- }
320
- }
321
- return match;
322
- }
323
- return (path) => match(path, { breakingLabels: [], unnamedBreak: false });
324
- }
325
- function pathsReachNodeTypes(matchingNodeTypes, referenceOriginalNodes) {
326
- return pathsPassTest((path) => path.type !== null && path.type !== undefined && matchingNodeTypes.indexOf(path.type) !== -1, referenceOriginalNodes);
327
- }
328
- const pathsReturn = pathsReachNodeTypes(["ReturnStatement"], true);
329
- const pathsReturnOrThrow = pathsReachNodeTypes(["ReturnStatement", "ThrowStatement"], true);
330
- const pathsReturnOrThrowCurrentNodes = pathsReachNodeTypes(["ReturnStatement", "ThrowStatement"], false);
331
- const pathsBreak = pathsReachNodeTypes(["BreakStatement"], true);
332
- const pathsBreakReturnOrThrow = pathsReachNodeTypes(["ReturnStatement", "ThrowStatement", "BreakStatement"], true);
333
- function isNonEmptyStatement(statement) {
334
- return !types.isEmptyStatement(statement);
335
- }
336
- function expressionInSingleReturnStatement(target) {
337
- const body = target.body;
338
- if (types.isBlockStatement(body)) {
339
- const statements = body.body.filter(isNonEmptyStatement);
340
- if (statements.length === 0) {
341
- return voidExpression();
342
- }
343
- else {
344
- const firstStatement = statements[0];
345
- if (types.isReturnStatement(firstStatement)) {
346
- return firstStatement.argument || voidExpression();
347
- }
348
- }
349
- }
350
- else {
351
- return body;
352
- }
353
- }
354
- function propertyNameOfMemberExpression(node) {
355
- const property = node.property;
356
- if (node.computed) {
357
- if (types.isStringLiteral(property)) {
358
- return property.value;
359
- }
360
- }
361
- else {
362
- if (types.isIdentifier(property)) {
363
- return property.name;
364
- }
365
- }
366
- }
367
- function identifiersInForToLengthStatement(statement) {
368
- const init = statement.get("init");
369
- if (init.isVariableDeclaration() && init.node.declarations.length === 1) {
370
- const declaration = init.get("declarations")[0];
371
- if (types.isNumericLiteral(declaration.node.init) && declaration.node.init.value === 0) {
372
- const i = declaration.node.id;
373
- const test = statement.get("test");
374
- if (types.isIdentifier(i) &&
375
- test.isBinaryExpression() &&
376
- test.node.operator === "<" &&
377
- types.isIdentifier(test.node.left) &&
378
- test.node.left.name === i.name) {
379
- const right = test.get("right");
380
- if (right.isMemberExpression()) {
381
- const object = right.node.object;
382
- if (types.isIdentifier(object) && propertyNameOfMemberExpression(right.node) === "length") {
383
- const update = statement.get("update");
384
- if (update.isUpdateExpression() &&
385
- update.node.operator == "++" &&
386
- types.isIdentifier(update.node.argument) &&
387
- update.node.argument.name === i.name) {
388
- const binding = statement.scope.getBinding(i.name);
389
- if (binding) {
390
- const updateArgument = update.get("argument");
391
- if (!binding.constantViolations.some((cv) => cv !== updateArgument && cv !== update)) {
392
- return {
393
- i,
394
- array: object,
395
- };
396
- }
397
- }
398
- }
399
- }
400
- }
401
- }
402
- }
403
- }
404
- }
405
- function extractForOwnBodyPath(path) {
406
- let left = path.get("left");
407
- if (left.isVariableDeclaration()) {
408
- left = left.get("declarations")[0].get("id");
409
- }
410
- const right = path.get("right");
411
- if (left.isIdentifier() && right.isIdentifier()) {
412
- const rightBinding = path.scope.getBinding(right.node.name);
413
- if (rightBinding && rightBinding.constant) {
414
- let body = path.get("body");
415
- for (;;) {
416
- let statements;
417
- if (body.isBlockStatement()) {
418
- statements = body.get("body");
419
- }
420
- else if (body.isReturnStatement()) {
421
- const argument = body.get("argument");
422
- if (argument.isCallExpression() &&
423
- invokeTypeOfExpression(argument) &&
424
- argument.get("arguments").length === 1) {
425
- const firstArgument = argument.get("arguments")[0];
426
- if (firstArgument.isFunctionExpression()) {
427
- statements = firstArgument.get("body").get("body");
428
- }
429
- else {
430
- break;
431
- }
432
- }
433
- else {
434
- break;
435
- }
436
- }
437
- else {
438
- break;
439
- }
440
- if (statements.length !== 1) {
441
- return;
442
- }
443
- body = statements[0];
444
- }
445
- if (body.isIfStatement() && !body.node.alternate) {
446
- const test = body.get("test");
447
- if (test.isCallExpression() && test.node.arguments.length === 2) {
448
- const args = test.get("arguments");
449
- const firstArg = args[0];
450
- const secondArg = args[1];
451
- if (firstArg.isIdentifier() &&
452
- firstArg.node.name === right.node.name &&
453
- secondArg.isIdentifier() &&
454
- secondArg.node.name === left.node.name) {
455
- const callee = test.get("callee");
456
- if (callee.isMemberExpression() && propertyNameOfMemberExpression(callee.node) === "call") {
457
- let method = callee.get("object");
458
- if (method.isMemberExpression() &&
459
- propertyNameOfMemberExpression(method.node) === "hasOwnProperty") {
460
- let target = method.get("object");
461
- if (target.isObjectExpression() && target.node.properties.length === 0) {
462
- return body.get("consequent");
463
- }
464
- if (target.isMemberExpression() &&
465
- propertyNameOfMemberExpression(target.node) === "prototype") {
466
- target = target.get("object");
467
- }
468
- if (target.isIdentifier() && target.node.name === "Object") {
469
- return body.get("consequent");
470
- }
471
- }
472
- }
473
- }
474
- }
475
- }
476
- }
477
- }
478
- }
479
- function isContinuation(possible) {
480
- return ((types.isFunctionExpression(possible) && possible.id === null) || types.isArrowFunctionExpression(possible));
481
- }
482
- function isPassthroughContinuation(continuation) {
483
- if (continuation) {
484
- if (isContinuation(continuation) && continuation.params.length === 1) {
485
- const expression = expressionInSingleReturnStatement(continuation);
486
- if (expression) {
487
- const firstParam = continuation.params[0];
488
- if (types.isIdentifier(firstParam)) {
489
- const valueName = firstParam.name;
490
- if (types.isIdentifier(expression) && expression.name === valueName) {
491
- return true;
492
- }
493
- if (types.isConditionalExpression(expression) &&
494
- types.isIdentifier(expression.test) &&
495
- types.isIdentifier(expression.consequent) &&
496
- expression.consequent.name === valueName &&
497
- types.isIdentifier(expression.alternate) &&
498
- expression.alternate.name === valueName) {
499
- return true;
500
- }
501
- }
502
- }
503
- }
504
- }
505
- return false;
506
- }
507
- function isEmptyContinuation(continuation) {
508
- if (types.isIdentifier(continuation)) {
509
- return helperNameMap.get(continuation) === "_empty";
510
- }
511
- if (isContinuation(continuation)) {
512
- const body = continuation.body;
513
- if (types.isBlockStatement(body)) {
514
- return body.body.length === 0;
515
- }
516
- }
517
- return false;
518
- }
519
- function voidExpression(arg) {
520
- return types.unaryExpression("void", arg || types.numericLiteral(0));
521
- }
522
- function simplifyWithIdentifier(expression, identifier, truthy) {
523
- if (types.isCallExpression(expression)) {
524
- switch (promiseCallExpressionType(expression)) {
525
- case "all":
526
- case "race":
527
- case "reject":
528
- case "resolve": {
529
- const firstArgument = expression.arguments[0];
530
- if (types.isExpression(firstArgument)) {
531
- const simplified = simplifyWithIdentifier(firstArgument, identifier, truthy);
532
- return simplified === expression.arguments[0]
533
- ? expression
534
- : types.callExpression(expression.callee, [simplified]);
535
- }
536
- }
537
- case "then": {
538
- const callee = expression.callee;
539
- if (types.isMemberExpression(callee)) {
540
- const thenArgument = expression.arguments[0];
541
- const object = callee.object;
542
- if (types.isCallExpression(object)) {
543
- const valueArgument = object.arguments[0];
544
- if (types.isExpression(valueArgument) && types.isExpression(thenArgument)) {
545
- const simplified = simplifyWithIdentifier(valueArgument, identifier, truthy);
546
- return simplified === valueArgument
547
- ? expression
548
- : callThenMethod(types.callExpression(object.callee, [simplified]), thenArgument);
549
- }
550
- }
551
- }
552
- }
553
- }
554
- if ((expression.arguments.length === 1 && types.isIdentifier(expression.callee)) ||
555
- isContinuation(expression.callee)) {
556
- const firstArgument = expression.arguments[0];
557
- if (types.isExpression(firstArgument)) {
558
- const simplified = simplifyWithIdentifier(firstArgument, identifier, truthy);
559
- return simplified === expression.arguments[0]
560
- ? expression
561
- : types.callExpression(expression.callee, [simplified]);
562
- }
563
- }
564
- }
565
- if (types.isConditionalExpression(expression) &&
566
- types.isIdentifier(expression.test) &&
567
- expression.test.name === identifier.name) {
568
- return truthy ? expression.consequent : expression.alternate;
569
- }
570
- if (types.isLogicalExpression(expression) &&
571
- types.isIdentifier(expression.left) &&
572
- expression.left.name === identifier.name) {
573
- if (expression.operator === "&&") {
574
- return truthy ? expression.right : expression.left;
575
- }
576
- if (expression.operator === "||") {
577
- return truthy ? expression.left : expression.right;
578
- }
579
- }
580
- return expression;
581
- }
582
- function isIdentifierOrLiteral(expression) {
583
- return types.isIdentifier(expression) || types.isLiteral(expression);
584
- }
585
- function simpleExpressionForContinuation(continuation, value) {
586
- if (isContinuation(continuation)) {
587
- let expression = expressionInSingleReturnStatement(continuation);
588
- if (expression) {
589
- switch (continuation.params.length) {
590
- case 0:
591
- if ((types.isConditionalExpression(expression) &&
592
- isIdentifierOrLiteral(expression.test) &&
593
- isIdentifierOrLiteral(expression.consequent) &&
594
- isIdentifierOrLiteral(expression.alternate)) ||
595
- ((types.isLogicalExpression(expression) || types.isBinaryExpression(expression)) &&
596
- isIdentifierOrLiteral(expression.left) &&
597
- isIdentifierOrLiteral(expression.right)) ||
598
- (types.isUnaryExpression(expression) && isIdentifierOrLiteral(expression.argument)) ||
599
- (types.isCallExpression(expression) &&
600
- isIdentifierOrLiteral(expression.callee) &&
601
- expression.arguments.length === 0) ||
602
- isIdentifierOrLiteral(expression)) {
603
- return expression;
604
- }
605
- break;
606
- case 1: {
607
- if (!value) {
608
- return;
609
- }
610
- const firstParam = continuation.params[0];
611
- const replace = (expr) => types.isIdentifier(firstParam) && types.isIdentifier(expr) && expr.name === firstParam.name
612
- ? value
613
- : discardingIntrinsics(expr);
614
- if (isIdentifierOrLiteral(expression)) {
615
- return replace(expression);
616
- }
617
- if (types.isConditionalExpression(expression) &&
618
- isIdentifierOrLiteral(expression.test) &&
619
- isIdentifierOrLiteral(expression.consequent) &&
620
- isIdentifierOrLiteral(expression.alternate)) {
621
- return types.conditionalExpression(replace(expression.test), replace(expression.consequent), replace(expression.alternate));
622
- }
623
- if (types.isLogicalExpression(expression) &&
624
- isIdentifierOrLiteral(expression.left) &&
625
- isIdentifierOrLiteral(expression.right)) {
626
- return types.logicalExpression(expression.operator, replace(expression.left), replace(expression.right));
627
- }
628
- if (types.isBinaryExpression(expression) &&
629
- isIdentifierOrLiteral(expression.left) &&
630
- isIdentifierOrLiteral(expression.right)) {
631
- return types.binaryExpression(expression.operator, replace(expression.left), replace(expression.right));
632
- }
633
- if (types.isCallExpression(expression) &&
634
- isIdentifierOrLiteral(expression.callee) &&
635
- expression.arguments.length === 0) {
636
- return types.callExpression(replace(expression.callee), expression.arguments);
637
- }
638
- }
639
- }
640
- }
641
- }
642
- }
643
- function awaitAndContinue(state, path, value, continuation, directExpression) {
644
- const declarators = [];
645
- if (continuation) {
646
- if (isPassthroughContinuation(continuation)) {
647
- continuation = undefined;
648
- }
649
- else {
650
- continuation = unwrapReturnCallWithPassthroughArgument(continuation, path.scope);
651
- }
652
- }
653
- if (!continuation && directExpression && extractLooseBooleanValue(directExpression) === true) {
654
- return {
655
- declarators,
656
- expression: value,
657
- };
658
- }
659
- if (types.isCallExpression(value) &&
660
- value.arguments.length === 0 &&
661
- isContinuation(value.callee) &&
662
- value.callee.params.length === 0) {
663
- const newValue = expressionInSingleReturnStatement(value.callee);
664
- if (newValue) {
665
- value = newValue;
666
- }
667
- }
668
- if (continuation &&
669
- !directExpression &&
670
- types.isCallExpression(value) &&
671
- types.isMemberExpression(value.callee) &&
672
- helperNameMap.get(value.callee) === "_yield") {
673
- return {
674
- declarators,
675
- expression: callThenMethod(value, continuation),
676
- };
677
- }
678
- if (readConfigKey(state.opts, "inlineHelpers")) {
679
- if (directExpression) {
680
- const resolvedValue = types.callExpression(promiseResolve(), [value]);
681
- const direct = extractLooseBooleanValue(directExpression);
682
- if (typeof direct === "undefined") {
683
- let expression;
684
- if (continuation) {
685
- let simpleExpression;
686
- if (!types.isIdentifier(continuation) &&
687
- !(simpleExpression = simpleExpressionForContinuation(continuation, isIdentifierOrLiteral(value) ? value : undefined))) {
688
- const id = path.scope.generateUidIdentifier("temp");
689
- if (isContinuation(continuation)) {
690
- if (!path.parentPath) {
691
- throw path.buildCodeFrameError(`Expected a parent path!`, Error);
692
- }
693
- insertFunctionIntoScope(continuation, id, path.parentPath.scope);
694
- }
695
- else {
696
- declarators.push(types.variableDeclarator(id, continuation));
697
- }
698
- continuation = id;
699
- }
700
- expression = conditionalExpression(directExpression, simpleExpression || types.callExpression(continuation, [value]), callThenMethod(resolvedValue, continuation));
701
- }
702
- else {
703
- expression = conditionalExpression(directExpression, value, resolvedValue);
704
- }
705
- return {
706
- declarators,
707
- expression,
708
- };
709
- }
710
- else if (direct) {
711
- return {
712
- declarators,
713
- expression: continuation ? types.callExpression(continuation, [value]) : value,
714
- };
715
- }
716
- else {
717
- return {
718
- declarators,
719
- expression: continuation ? callThenMethod(resolvedValue, continuation) : resolvedValue,
720
- };
721
- }
722
- }
723
- else if (continuation) {
724
- if (!types.isIdentifier(value)) {
725
- if (types.isCallExpression(value) && promiseCallExpressionType(value) !== undefined) {
726
- return {
727
- declarators,
728
- expression: callThenMethod(value, continuation),
729
- };
730
- }
731
- const id = path.scope.generateUidIdentifier("temp");
732
- declarators.push(types.variableDeclarator(id, value));
733
- value = id;
734
- }
735
- const isEmpty = isEmptyContinuation(continuation);
736
- let simpleExpression;
737
- if (!isEmpty &&
738
- !types.isIdentifier(continuation) &&
739
- !(simpleExpression = simpleExpressionForContinuation(continuation, value))) {
740
- const id = path.scope.generateUidIdentifier("temp");
741
- if (isContinuation(continuation)) {
742
- if (!path.parentPath) {
743
- throw path.buildCodeFrameError(`Expected a parent path!`, Error);
744
- }
745
- insertFunctionIntoScope(continuation, id, path.parentPath.scope);
746
- }
747
- else {
748
- declarators.push(types.variableDeclarator(id, continuation));
749
- }
750
- continuation = id;
751
- }
752
- return {
753
- declarators,
754
- expression: types.conditionalExpression(types.logicalExpression("&&", value, types.memberExpression(value, types.identifier("then"))), callThenMethod(value, continuation), simpleExpression
755
- ? simpleExpression
756
- : isEmpty
757
- ? voidExpression()
758
- : types.callExpression(continuation, [value])),
759
- };
760
- }
761
- }
762
- const callTarget = types.isCallExpression(value) && value.arguments.length === 0 && !types.isMemberExpression(value.callee)
763
- ? value.callee
764
- : undefined;
765
- const args = [callTarget || value];
766
- const ignoreResult = continuation && isEmptyContinuation(continuation);
767
- if (!ignoreResult && continuation) {
768
- args.push(continuation);
769
- }
770
- if (directExpression && extractLooseBooleanValue(directExpression) !== false) {
771
- if (!ignoreResult && !continuation) {
772
- args.push(voidExpression());
773
- }
774
- args.push(directExpression);
775
- }
776
- const baseHelper = directExpression
777
- ? callTarget
778
- ? "_call"
779
- : "_await"
780
- : callTarget
781
- ? "_invoke"
782
- : "_continue";
783
- const helperName = ignoreResult ? (baseHelper + "Ignored") : baseHelper;
784
- if (args.length === 1) {
785
- switch (helperName) {
786
- case "_invoke":
787
- return {
788
- declarators,
789
- expression: types.callExpression(args[0], []),
790
- };
791
- case "_continue":
792
- return {
793
- declarators,
794
- expression: discardingIntrinsics(args[0]),
795
- };
796
- case "_continueIgnored":
797
- const firstArgument = args[0];
798
- if (types.isCallExpression(firstArgument) &&
799
- (types.isIdentifier(firstArgument.callee) || types.isMemberExpression(firstArgument.callee))) {
800
- if (helperNameMap.get(firstArgument.callee) === "_continueIgnored") {
801
- return {
802
- declarators,
803
- expression: firstArgument,
804
- };
805
- }
806
- }
807
- }
808
- }
809
- return {
810
- declarators,
811
- expression: types.callExpression(helperReference(state, path, helperName), args.map(discardingIntrinsics)),
812
- };
813
- }
814
- function borrowTail(target) {
815
- let current = target;
816
- const dest = [];
817
- while (current && current.node && current.inList && current.container) {
818
- const siblings = current.getAllNextSiblings();
819
- for (const sibling of siblings) {
820
- sibling.assertStatement();
821
- dest.push(sibling.node);
822
- }
823
- for (const sibling of siblings) {
824
- sibling.remove();
825
- }
826
- current = current.parentPath;
827
- if (!current || !current.isBlockStatement()) {
828
- break;
829
- }
830
- }
831
- return dest;
832
- }
833
- function exitsInTail(target) {
834
- let current = target;
835
- while (current && current.node && current.inList && current.container && !current.isFunction()) {
836
- for (var i = current.key + 1; i < current.container.length; i++) {
837
- if (pathsReturnOrThrow(current).any) {
838
- return true;
839
- }
840
- }
841
- current = current.parentPath;
842
- }
843
- return false;
844
- }
845
- function returnStatement(argument, originalNode) {
846
- const result = types.returnStatement(argument);
847
- skipNodeSet.add(result);
848
- if (originalNode !== undefined) {
849
- originalNodeMap.set(result, originalNode);
850
- }
851
- return result;
852
- }
853
- function removeUnnecessaryReturnStatements(blocks) {
854
- while (blocks.length) {
855
- const lastStatement = blocks[blocks.length - 1];
856
- if (types.isReturnStatement(lastStatement)) {
857
- if (lastStatement.argument === null || lastStatement.argument === undefined) {
858
- blocks = blocks.slice(0, blocks.length - 1);
859
- }
860
- else {
861
- if (types.isConditionalExpression(lastStatement.argument) &&
862
- types.isUnaryExpression(lastStatement.argument.alternate) &&
863
- lastStatement.argument.alternate.operator === "void" &&
864
- isValueLiteral(lastStatement.argument.alternate.argument)) {
865
- blocks = blocks.slice(0, blocks.length - 1);
866
- blocks.push(types.ifStatement(lastStatement.argument.test, types.returnStatement(lastStatement.argument.consequent)));
867
- }
868
- else if (blocks.length > 1) {
869
- const previousStatement = blocks[blocks.length - 2];
870
- if (types.isIfStatement(previousStatement) && !previousStatement.alternate) {
871
- let consequent = previousStatement.consequent;
872
- while (types.isBlockStatement(consequent)) {
873
- if (consequent.body.length !== 1) {
874
- return blocks;
875
- }
876
- consequent = consequent.body[0];
877
- }
878
- if (types.isReturnStatement(consequent) && consequent.argument) {
879
- blocks = blocks.slice(0, blocks.length - 2);
880
- blocks.push(types.returnStatement(conditionalExpression(previousStatement.test, consequent.argument, lastStatement.argument)));
881
- }
882
- }
883
- }
884
- break;
885
- }
886
- }
887
- else {
888
- if (types.isIfStatement(lastStatement)) {
889
- let consequent = lastStatement.consequent;
890
- if (types.isBlockStatement(consequent)) {
891
- consequent = blockStatement(removeUnnecessaryReturnStatements(consequent.body));
892
- }
893
- let alternate = lastStatement.alternate;
894
- if (alternate) {
895
- if (types.isBlockStatement(alternate)) {
896
- const removedOfUnnecessary = removeUnnecessaryReturnStatements(alternate.body);
897
- alternate = removedOfUnnecessary.length ? blockStatement(removedOfUnnecessary) : undefined;
898
- }
899
- else if (removeUnnecessaryReturnStatements([alternate]).length === 0) {
900
- alternate = undefined;
901
- }
902
- }
903
- if (consequent !== lastStatement.consequent || alternate !== lastStatement.alternate) {
904
- blocks = blocks.slice(0, blocks.length - 1);
905
- blocks.push(types.ifStatement(lastStatement.test, consequent, alternate || undefined));
906
- }
907
- }
908
- break;
909
- }
910
- }
911
- return blocks;
912
- }
913
- function rewriteAsyncNode(state, parentPath, node, additionalConstantNames, exitIdentifier, unpromisify) {
914
- const path = pathForNewNode(node, parentPath);
915
- rewriteAsyncBlock(state, path, additionalConstantNames, exitIdentifier, unpromisify);
916
- return path.node;
917
- }
918
- function allScopes(scope) {
919
- const result = [];
920
- while (scope) {
921
- result.push(scope);
922
- scope = scope.parent;
923
- }
924
- return result;
925
- }
926
- const hoistCallArgumentsInnerVisitor = {
927
- Identifier(identifierPath) {
928
- if (identifierSearchesScope(identifierPath)) {
929
- const name = identifierPath.node.name;
930
- if (this.argumentNames.indexOf(name) === -1) {
931
- if (this.additionalConstantNames.indexOf(name) !== -1) {
932
- this.scopes.push(this.path.scope.parent);
933
- }
934
- else {
935
- const binding = identifierPath.scope.getBinding(name) || this.path.scope.getBinding(name);
936
- if (binding) {
937
- const scope = binding.scope;
938
- if (scope !== null) {
939
- if (this.pathScopes.indexOf(scope) !== -1) {
940
- this.scopes.push(scope);
941
- }
942
- }
943
- }
944
- }
945
- }
946
- }
947
- },
948
- };
949
- function isValueLiteral(node) {
950
- return types.isStringLiteral(node) || types.isNumericLiteral(node) || types.isBooleanLiteral(node);
951
- }
952
- function keyFilter(key, value) {
953
- return key === "start" ||
954
- key === "end" ||
955
- key === "loc" ||
956
- key === "directives" ||
957
- key === "leadingComments" ||
958
- key === "trailingComments" ||
959
- key === "innerComments" ||
960
- key[0] === "_"
961
- ? undefined
962
- : value;
963
- }
964
- function nodesAreEquivalent(node) {
965
- let cached;
966
- return (other) => {
967
- if (typeof cached === "undefined") {
968
- cached = JSON.stringify(node, keyFilter);
969
- }
970
- return cached === JSON.stringify(other, keyFilter);
971
- };
972
- }
973
- const reregisterVariableVisitor = {
974
- VariableDeclaration(path) {
975
- path.scope.registerDeclaration(path);
976
- },
977
- FunctionDeclaration(path) {
978
- path.parentPath.scope.registerDeclaration(path);
979
- },
980
- ClassDeclaration(path) {
981
- path.scope.registerDeclaration(path);
982
- },
983
- Function(path) {
984
- path.skip();
985
- },
986
- };
987
- function insertFunctionIntoScope(func, id, scope) {
988
- scope.push({ kind: "const", id, init: func, unique: true });
989
- const binding = scope.getBinding(id.name);
990
- if (typeof binding === "undefined") {
991
- throw scope.path.buildCodeFrameError(`Could not find newly created binding for ${id.name}!`, Error);
992
- }
993
- const targetPath = binding.path.parentPath;
994
- if (!targetPath) {
995
- throw scope.path.buildCodeFrameError(`Could not find newly created binding for ${id.name}!`, Error);
996
- }
997
- targetPath.replaceWith(types.functionDeclaration(id, func.params, types.isBlockStatement(func.body)
998
- ? func.body
999
- : types.blockStatement([types.returnStatement(func.body)]), func.generator, func.async));
1000
- reregisterDeclarations(targetPath);
1001
- }
1002
- function hoistFunctionExpressionHandler(path) {
1003
- path.skip();
1004
- const bodyPath = path.get("body");
1005
- if (bodyPath.isBlockStatement() &&
1006
- bodyPath.node.body.length === 0 &&
1007
- !readConfigKey(this.state.opts, "inlineHelpers")) {
1008
- path.replaceWith(emptyFunction(this.state, path));
1009
- return;
1010
- }
1011
- const argumentNames = [];
1012
- for (const param of path.node.params) {
1013
- if (types.isIdentifier(param) || types.isPattern(param) || types.isRestElement(param)) {
1014
- addConstantNames(argumentNames, param);
1015
- }
1016
- else {
1017
- return;
1018
- }
1019
- }
1020
- const scopes = [];
1021
- const pathScopes = allScopes(path.scope.parent);
1022
- path.traverse(hoistCallArgumentsInnerVisitor, {
1023
- argumentNames,
1024
- scopes,
1025
- pathScopes,
1026
- path,
1027
- additionalConstantNames: this.additionalConstantNames,
1028
- });
1029
- let scope = path.scope.getProgramParent();
1030
- let ancestry = [scope];
1031
- for (let otherScope of scopes) {
1032
- if (ancestry.indexOf(otherScope) === -1) {
1033
- scope = otherScope;
1034
- ancestry = ancestry.concat(allScopes(otherScope));
1035
- }
1036
- }
1037
- if (ancestry.indexOf(path.scope.parent) === -1) {
1038
- const bindings = scope.bindings;
1039
- const filter = nodesAreEquivalent([...path.node.params, path.node.body]);
1040
- for (const key of Object.getOwnPropertyNames(bindings)) {
1041
- const binding = bindings[key];
1042
- const bindingPath = binding.path;
1043
- if (bindingPath.isFunctionDeclaration()) {
1044
- if (filter([...bindingPath.node.params, bindingPath.node.body])) {
1045
- path.replaceWith(binding.identifier);
1046
- return;
1047
- }
1048
- }
1049
- else if (bindingPath.isVariableDeclarator()) {
1050
- const init = bindingPath.get("init");
1051
- if (init.node && isContinuation(init.node)) {
1052
- if (filter([...init.node.params, init.node.body])) {
1053
- path.replaceWith(binding.identifier);
1054
- return;
1055
- }
1056
- }
1057
- }
1058
- }
1059
- let nameNode = path.node;
1060
- if (types.isExpression(nameNode) && isContinuation(nameNode)) {
1061
- nameNode = nameNode.body;
1062
- }
1063
- if (types.isBlockStatement(nameNode) && nameNode.body.length === 1) {
1064
- nameNode = nameNode.body[0];
1065
- }
1066
- if (types.isReturnStatement(nameNode) && nameNode.argument) {
1067
- nameNode = nameNode.argument;
1068
- }
1069
- if (types.isCallExpression(nameNode)) {
1070
- const callee = nameNode.callee;
1071
- if (types.isIdentifier(callee) && helperNameMap.has(callee)) {
1072
- nameNode = nameNode.arguments[0];
1073
- }
1074
- }
1075
- const id = isValueLiteral(nameNode)
1076
- ? scope.generateUidIdentifier(nameNode.value.toString().replace(/\d/g, (number) => numberNames[number]))
1077
- : path.scope.generateUidIdentifierBasedOnNode(nameNode, "temp");
1078
- const init = path.node;
1079
- path.replaceWith(id);
1080
- insertFunctionIntoScope(init, id, scope);
1081
- }
1082
- }
1083
- const hoistCallArgumentsVisitor = {
1084
- FunctionExpression: hoistFunctionExpressionHandler,
1085
- ArrowFunctionExpression: hoistFunctionExpressionHandler,
1086
- };
1087
- function hoistCallArguments(state, path, additionalConstantNames) {
1088
- if (path.isCallExpression()) {
1089
- const callee = path.node.callee;
1090
- if ((types.isIdentifier(callee) || types.isMemberExpression(callee)) && helperNameMap.has(callee)) {
1091
- const functionParent = path.getFunctionParent();
1092
- if (functionParent) {
1093
- const scope = functionParent.scope;
1094
- if (scope.crawl) {
1095
- scope.crawl();
1096
- }
1097
- }
1098
- path.traverse(hoistCallArgumentsVisitor, { state, additionalConstantNames });
1099
- }
1100
- }
1101
- }
1102
- function checkPathValidity(path) {
1103
- if (path.container === null) {
1104
- throw path.buildCodeFrameError(`Path was expected to have a container!`, TypeError);
1105
- }
1106
- if ("resync" in path && typeof path.resync === "function") {
1107
- path.resync();
1108
- if (path.container === null) {
1109
- throw path.buildCodeFrameError(`Path was expected to have a container, and lost its container upon resync!`, TypeError);
1110
- }
1111
- }
1112
- }
1113
- function relocateTail(generatorState, awaitExpression, statementNode, target, additionalConstantNames, temporary, exitCheck, directExpression, skipReturns) {
1114
- checkPathValidity(target);
1115
- const tail = borrowTail(target);
1116
- checkPathValidity(target);
1117
- let originalNode = types.isStatement(target.node) ? target.node : types.expressionStatement(target.node);
1118
- const rewrittenTail = statementNode || tail.length
1119
- ? rewriteAsyncNode(generatorState, target, blockStatement((statementNode ? [statementNode] : []).concat(tail)), additionalConstantNames).body
1120
- : [];
1121
- checkPathValidity(target);
1122
- let blocks = removeUnnecessaryReturnStatements(rewrittenTail.filter(isNonEmptyStatement));
1123
- checkPathValidity(target);
1124
- let replacement;
1125
- if (blocks.length) {
1126
- if (exitCheck) {
1127
- if (temporary && !types.isIdentifier(temporary)) {
1128
- const temporaryIdentifier = (temporary = target.scope.generateUidIdentifier("temp"));
1129
- const declaration = types.variableDeclaration("const", [
1130
- types.variableDeclarator(temporary, temporaryIdentifier),
1131
- ]);
1132
- blocks = [declaration].concat(blocks);
1133
- temporary = temporaryIdentifier;
1134
- }
1135
- if (temporary !== undefined) {
1136
- blocks = removeUnnecessaryReturnStatements([types.ifStatement(exitCheck, returnStatement(temporary))].concat(blocks));
1137
- }
1138
- else {
1139
- const minify = readConfigKey(generatorState.state.opts, "minify");
1140
- blocks = removeUnnecessaryReturnStatements([
1141
- types.ifStatement(logicalNot(exitCheck, minify), blocks.length === 1 ? blocks[0] : blockStatement(blocks)),
1142
- ]);
1143
- }
1144
- }
1145
- const fn = functionize(generatorState.state, temporary ? [temporary] : [], blockStatement(blocks), target);
1146
- replacement = awaitAndContinue(generatorState.state, target, awaitExpression, fn, directExpression);
1147
- originalNode = types.blockStatement([originalNode].concat(tail));
1148
- }
1149
- else if (pathsReturnOrThrow(target).any || target.parentPath.isArrowFunctionExpression()) {
1150
- replacement = awaitAndContinue(generatorState.state, target, awaitExpression, undefined, directExpression);
1151
- }
1152
- else {
1153
- replacement = awaitAndContinue(generatorState.state, target, awaitExpression, emptyFunction(generatorState.state, target), directExpression);
1154
- }
1155
- checkPathValidity(target);
1156
- if (target.isExpression() && target.parentPath.isArrowFunctionExpression()) {
1157
- target.replaceWith(replacement.expression);
1158
- }
1159
- else if (skipReturns) {
1160
- target.replaceWith(replacement.expression);
1161
- }
1162
- else if (target.isBlockStatement() && target.parentPath.isFunctionExpression()) {
1163
- target.replaceWith(types.blockStatement([returnStatement(replacement.expression, originalNode)]));
1164
- }
1165
- else {
1166
- target.replaceWith(returnStatement(replacement.expression, originalNode));
1167
- }
1168
- if (replacement.declarators.length) {
1169
- reregisterDeclarations(target.insertBefore(types.variableDeclaration("const", replacement.declarators)));
1170
- }
1171
- if (readConfigKey(generatorState.state.opts, "hoist")) {
1172
- if (target.isExpression()) {
1173
- hoistCallArguments(generatorState.state, target, additionalConstantNames);
1174
- }
1175
- else if (target.isReturnStatement()) {
1176
- const argument = target.get("argument");
1177
- if (argument.node) {
1178
- hoistCallArguments(generatorState.state, argument, additionalConstantNames);
1179
- }
1180
- }
1181
- }
1182
- }
1183
- function rewriteToNamedConstant(targetPath, callback) {
1184
- const declarators = Object.create(null);
1185
- return callback((name, path) => {
1186
- if (Object.hasOwnProperty.call(declarators, name)) {
1187
- const id = declarators[name].id;
1188
- const binding = targetPath.scope.getBinding(id.name);
1189
- if (!binding || binding.path.get("init") !== path) {
1190
- path.replaceWith(types.identifier(id.name));
1191
- }
1192
- }
1193
- else {
1194
- const id = path.scope.generateUidIdentifier(name);
1195
- const init = path.node;
1196
- path.replaceWith(id);
1197
- const declarator = (declarators[name] = {
1198
- kind: "const",
1199
- id,
1200
- init,
1201
- });
1202
- let skip = false;
1203
- if (targetPath.isClassMethod() && targetPath.node.kind === "constructor") {
1204
- targetPath.traverse({
1205
- Super(path) {
1206
- if (!skip && path.parentPath.isCallExpression() && path.parentPath.get("callee") === path) {
1207
- path.stop();
1208
- path.getStatementParent().insertAfter(types.variableDeclaration("const", [types.variableDeclarator(id, init)]));
1209
- skip = true;
1210
- }
1211
- },
1212
- });
1213
- }
1214
- if (!skip) {
1215
- targetPath.scope.push(declarator);
1216
- }
1217
- const binding = targetPath.scope.getBinding(id.name);
1218
- if (binding) {
1219
- binding.path.skip();
1220
- }
1221
- }
1222
- });
1223
- }
1224
- const rewriteThisVisitor = {
1225
- Function(path) {
1226
- if (!path.isArrowFunctionExpression()) {
1227
- path.skip();
1228
- }
1229
- },
1230
- ThisExpression(path) {
1231
- this.rewrite("this", path);
1232
- },
1233
- };
1234
- function rewriteThisExpressions(rewritePath, targetPath) {
1235
- rewriteToNamedConstant(targetPath, (rewrite) => rewritePath.traverse(rewriteThisVisitor, { rewrite }));
1236
- }
1237
- function identifiersInLVal(id, result = []) {
1238
- switch (id.type) {
1239
- case "Identifier":
1240
- result.push(id);
1241
- break;
1242
- case "AssignmentPattern":
1243
- identifiersInLVal(id.left);
1244
- break;
1245
- case "ArrayPattern":
1246
- for (const element of id.elements) {
1247
- if (types.isLVal(element)) {
1248
- identifiersInLVal(element, result);
1249
- }
1250
- }
1251
- break;
1252
- case "RestElement":
1253
- identifiersInLVal(id.argument, result);
1254
- break;
1255
- case "ObjectPattern":
1256
- for (const property of id.properties) {
1257
- if (types.isRestElement(property)) {
1258
- identifiersInLVal(property.argument, result);
1259
- }
1260
- else if (types.isPattern(property.value) || types.isIdentifier(property.value)) {
1261
- identifiersInLVal(property.value, result);
1262
- }
1263
- }
1264
- break;
1265
- default:
1266
- throw new Error(`Unexpected node is not an LVal: ${id}`);
1267
- }
1268
- return result;
1269
- }
1270
- function anyIdentifiersRequireHoisting(identifiers, path) {
1271
- const ancestry = path.getAncestry().reverse();
1272
- for (const id of identifiers) {
1273
- const binding = path.scope.getBinding(id.name);
1274
- if (!binding) {
1275
- return true;
1276
- }
1277
- const executingBeforePath = binding.referencePaths.find((referencePath) => {
1278
- if (!referencePath.willIMaybeExecuteBefore(path)) {
1279
- return false;
1280
- }
1281
- const referenceAncestry = referencePath.getAncestry().reverse();
1282
- const length = ancestry.length < referenceAncestry.length ? ancestry.length : referenceAncestry.length;
1283
- for (let i = 1; i < length; i++) {
1284
- if (ancestry[i] !== referenceAncestry[i]) {
1285
- if (typeof ancestry[i].key === "number" &&
1286
- typeof referenceAncestry[i].key === "number" &&
1287
- ancestry[i].key < referenceAncestry[i].key) {
1288
- return false;
1289
- }
1290
- if ((ancestry[i - 1].isForOfStatement() || ancestry[i - 1].isForInStatement()) &&
1291
- ancestry[i].key === "left") {
1292
- return false;
1293
- }
1294
- if (ancestry[i - 1].isForStatement() && ancestry[i].key === "init") {
1295
- return false;
1296
- }
1297
- }
1298
- }
1299
- return true;
1300
- });
1301
- if (executingBeforePath) {
1302
- return true;
1303
- }
1304
- if (binding.referencePaths.length &&
1305
- path.getDeepestCommonAncestorFrom(binding.referencePaths.concat([path])) !== path.parentPath) {
1306
- return true;
1307
- }
1308
- }
1309
- return false;
1310
- }
1311
- const rewriteThisArgumentsAndHoistVisitor = {
1312
- Function(path) {
1313
- path.skip();
1314
- if (path.isArrowFunctionExpression()) {
1315
- path.traverse(rewriteThisVisitor, this);
1316
- }
1317
- },
1318
- Super(path) {
1319
- if (this.rewriteSuper) {
1320
- const parent = path.parentPath;
1321
- if (parent.isMemberExpression() && parent.get("object") === path) {
1322
- const property = parent.get("property");
1323
- if (parent.node.computed) {
1324
- if (!property.isStringLiteral()) {
1325
- throw path.buildCodeFrameError(`Expected a staticly resolvable super expression, got a computed expression of type ${property.node.type}`, TypeError);
1326
- }
1327
- }
1328
- const grandparent = parent.parentPath;
1329
- if (property.isIdentifier() &&
1330
- grandparent.isCallExpression() &&
1331
- grandparent.get("callee") === parent) {
1332
- this.rewrite("super$" + property.node.name, parent);
1333
- const args = grandparent.node.arguments.slice(0);
1334
- args.unshift(types.thisExpression());
1335
- grandparent.replaceWith(types.callExpression(types.memberExpression(parent.node, types.identifier("call")), args));
1336
- reregisterDeclarations(grandparent);
1337
- }
1338
- }
1339
- }
1340
- },
1341
- ThisExpression(path) {
1342
- this.rewrite("this", path);
1343
- },
1344
- Identifier(path) {
1345
- if (path.node.name === "arguments" && identifierSearchesScope(path)) {
1346
- this.rewrite("arguments", path);
1347
- }
1348
- },
1349
- VariableDeclaration(path) {
1350
- if (path.node.kind === "var") {
1351
- const declarations = path.get("declarations");
1352
- const mapped = declarations.map((declaration) => ({
1353
- declaration,
1354
- identifiers: identifiersInLVal(declaration.node.id),
1355
- }));
1356
- if (mapped.some(({ identifiers }) => anyIdentifiersRequireHoisting(identifiers, path))) {
1357
- if ((path.parentPath.isForInStatement() || path.parentPath.isForOfStatement()) &&
1358
- path.parentPath.get("left") === path &&
1359
- declarations.length === 1) {
1360
- path.replaceWith(declarations[0].node.id);
1361
- }
1362
- else {
1363
- const expressions = [];
1364
- for (const { declaration } of mapped) {
1365
- if (declaration.node.init) {
1366
- expressions.push(types.assignmentExpression("=", declaration.node.id, declaration.node.init));
1367
- }
1368
- }
1369
- clearDeclarationData(path);
1370
- if (expressions.length === 0) {
1371
- path.remove();
1372
- }
1373
- else if (expressions.length === 1) {
1374
- path.replaceWith(expressions[0]);
1375
- }
1376
- else if (path.parentPath.isForStatement() && path.parentPath.get("init") === path) {
1377
- path.replaceWith(types.sequenceExpression(expressions));
1378
- }
1379
- else {
1380
- path.replaceWithMultiple(expressions.map((expression) => types.expressionStatement(expression)));
1381
- }
1382
- }
1383
- for (const { identifiers } of mapped) {
1384
- for (const id of identifiers) {
1385
- this.targetPath.scope.push({ id });
1386
- }
1387
- }
1388
- }
1389
- }
1390
- },
1391
- FunctionDeclaration(path) {
1392
- let targetPath = path;
1393
- while (targetPath.parentPath.isBlockStatement()) {
1394
- targetPath = targetPath.parentPath;
1395
- }
1396
- for (const sibling of path.getAllPrevSiblings()) {
1397
- if (!sibling.isFunctionDeclaration()) {
1398
- const node = path.node;
1399
- path.remove();
1400
- reregisterDeclarations(sibling.insertBefore(node));
1401
- return;
1402
- }
1403
- }
1404
- },
1405
- };
1406
- function rewriteThisArgumentsAndHoistFunctions(rewritePath, targetPath, rewriteSuper) {
1407
- rewriteToNamedConstant(targetPath, (rewrite) => rewritePath.traverse(rewriteThisArgumentsAndHoistVisitor, { targetPath, rewrite, rewriteSuper }));
1408
- }
1409
- function translateTSParameterProperties(array) {
1410
- return array.map((n) => (n.type === "TSParameterProperty" ? n.parameter : n));
1411
- }
1412
- function functionize(state, params, expression, target, id) {
1413
- const translatedParams = translateTSParameterProperties(params);
1414
- if (!id && readConfigKey(state.opts, "target") === "es6") {
1415
- let newExpression = expression;
1416
- if (types.isBlockStatement(newExpression) && newExpression.body.length === 1) {
1417
- newExpression = newExpression.body[0];
1418
- }
1419
- if (types.isReturnStatement(newExpression) && newExpression.argument) {
1420
- newExpression = newExpression.argument;
1421
- }
1422
- const result = types.arrowFunctionExpression(translatedParams, types.isStatement(newExpression) && !types.isBlockStatement(newExpression)
1423
- ? types.blockStatement([newExpression])
1424
- : newExpression);
1425
- let usesThisOrArguments = false;
1426
- pathForNewNode(result, target).traverse({
1427
- Function(path) {
1428
- path.skip();
1429
- },
1430
- ThisExpression(path) {
1431
- usesThisOrArguments = true;
1432
- path.stop();
1433
- },
1434
- Identifier(path) {
1435
- if (path.node.name === "arguments" && identifierSearchesScope(path)) {
1436
- usesThisOrArguments = true;
1437
- path.stop();
1438
- }
1439
- },
1440
- });
1441
- if (!usesThisOrArguments) {
1442
- return result;
1443
- }
1444
- }
1445
- if (types.isExpression(expression)) {
1446
- expression = returnStatement(expression);
1447
- }
1448
- if (!types.isBlockStatement(expression)) {
1449
- expression = blockStatement([expression]);
1450
- }
1451
- expression.body = removeUnnecessaryReturnStatements(expression.body);
1452
- return types.functionExpression(id, translatedParams, expression);
1453
- }
1454
- function blockStatement(statementOrStatements) {
1455
- if ("length" in statementOrStatements) {
1456
- return types.blockStatement(statementOrStatements.filter((statement) => !types.isEmptyStatement(statement)));
1457
- }
1458
- else if (!types.isBlockStatement(statementOrStatements)) {
1459
- return types.blockStatement([statementOrStatements]);
1460
- }
1461
- else {
1462
- return statementOrStatements;
1463
- }
1464
- }
1465
- function unwrapReturnCallWithEmptyArguments(node, scope, additionalConstantNames) {
1466
- if (isContinuation(node)) {
1467
- const expression = expressionInSingleReturnStatement(node);
1468
- if (expression && types.isCallExpression(expression)) {
1469
- let callTarget;
1470
- switch (expression.arguments.length) {
1471
- case 0:
1472
- callTarget = expression.callee;
1473
- break;
1474
- case 1: {
1475
- const callee = expression.callee;
1476
- const onlyArgument = expression.arguments[0];
1477
- if (types.isIdentifier(callee) && helperNameMap.get(callee) === "_call") {
1478
- callTarget = onlyArgument;
1479
- }
1480
- if (types.isIdentifier(callee) || types.isMemberExpression(callee)) {
1481
- switch (helperNameMap.get(callee)) {
1482
- case "_await":
1483
- case "_promiseResolve":
1484
- if (types.isCallExpression(onlyArgument) && onlyArgument.arguments.length === 0) {
1485
- callTarget = onlyArgument.callee;
1486
- }
1487
- break;
1488
- }
1489
- }
1490
- break;
1491
- }
1492
- }
1493
- if (callTarget && types.isExpression(callTarget)) {
1494
- if (types.isIdentifier(callTarget)) {
1495
- const binding = scope.getBinding(callTarget.name);
1496
- if (binding && binding.constant) {
1497
- return callTarget;
1498
- }
1499
- if (additionalConstantNames.indexOf(callTarget.name) !== -1) {
1500
- return callTarget;
1501
- }
1502
- }
1503
- else if (isContinuation(callTarget)) {
1504
- return unwrapReturnCallWithEmptyArguments(callTarget, scope, additionalConstantNames);
1505
- }
1506
- }
1507
- }
1508
- }
1509
- return node;
1510
- }
1511
- function unwrapReturnCallWithPassthroughArgument(node, scope) {
1512
- if (isContinuation(node) && node.params.length >= 1) {
1513
- const expression = expressionInSingleReturnStatement(node);
1514
- if (expression && types.isCallExpression(expression) && expression.arguments.length === 1) {
1515
- const firstArgument = expression.arguments[0];
1516
- const firstParam = node.params[0];
1517
- if (types.isIdentifier(firstArgument) &&
1518
- types.isIdentifier(firstParam) &&
1519
- firstArgument.name === firstParam.name) {
1520
- if (types.isIdentifier(expression.callee)) {
1521
- const binding = scope.getBinding(expression.callee.name);
1522
- if (binding && binding.constant) {
1523
- return expression.callee;
1524
- }
1525
- if (Object.hasOwnProperty.call(constantStaticMethods, expression.callee.name)) {
1526
- return expression.callee;
1527
- }
1528
- }
1529
- else if (types.isMemberExpression(expression.callee)) {
1530
- const propertyName = propertyNameOfMemberExpression(expression.callee);
1531
- if (propertyName !== undefined) {
1532
- const object = expression.callee.object;
1533
- if (types.isIdentifier(object) &&
1534
- Object.hasOwnProperty.call(constantStaticMethods, object.name) &&
1535
- !scope.getBinding(object.name)) {
1536
- const staticMethods = constantStaticMethods[object.name];
1537
- if (Object.hasOwnProperty.call(staticMethods, propertyName) &&
1538
- staticMethods[propertyName]) {
1539
- return expression.callee;
1540
- }
1541
- }
1542
- }
1543
- }
1544
- }
1545
- }
1546
- }
1547
- return node;
1548
- }
1549
- function isExpressionOfLiterals(path, literalNames) {
1550
- if (path.node === null || path.node === undefined) {
1551
- return true;
1552
- }
1553
- if (path.isIdentifier()) {
1554
- const name = path.node.name;
1555
- if (name === "undefined" && !path.scope.getBinding("undefined")) {
1556
- return true;
1557
- }
1558
- const binding = path.parentPath.scope.getBinding(name);
1559
- if (binding) {
1560
- return binding.constant;
1561
- }
1562
- if (literalNames.indexOf(name) !== -1) {
1563
- return true;
1564
- }
1565
- if (Object.hasOwnProperty.call(constantStaticMethods, name) && !path.scope.getBinding(name)) {
1566
- return true;
1567
- }
1568
- return false;
1569
- }
1570
- if (path.isMemberExpression()) {
1571
- const object = path.get("object");
1572
- if (object.isIdentifier()) {
1573
- const propertyName = propertyNameOfMemberExpression(path.node);
1574
- if (propertyName !== undefined &&
1575
- Object.hasOwnProperty.call(constantStaticMethods, object.node.name) &&
1576
- !path.scope.getBinding(object.node.name)) {
1577
- const staticMethods = constantStaticMethods[object.node.name];
1578
- if (Object.hasOwnProperty.call(staticMethods, propertyName) && staticMethods[propertyName]) {
1579
- return true;
1580
- }
1581
- }
1582
- }
1583
- return false;
1584
- }
1585
- if (path.isBooleanLiteral()) {
1586
- return true;
1587
- }
1588
- if (path.isNumericLiteral()) {
1589
- return true;
1590
- }
1591
- if (path.isStringLiteral()) {
1592
- return true;
1593
- }
1594
- if (path.isArrayExpression()) {
1595
- return path
1596
- .get("elements")
1597
- .every((element) => element === null || element.node === null
1598
- ? true
1599
- : isExpressionOfLiterals(element, literalNames));
1600
- }
1601
- if (path.isNullLiteral()) {
1602
- return true;
1603
- }
1604
- if (path.isObjectExpression()) {
1605
- return path.get("properties").every((property) => {
1606
- if (property.isObjectProperty()) {
1607
- if (!property.node.computed ||
1608
- isExpressionOfLiterals(property.get("key"), literalNames)) {
1609
- return isExpressionOfLiterals(property.get("value"), literalNames);
1610
- }
1611
- }
1612
- else {
1613
- return true;
1614
- }
1615
- });
1616
- }
1617
- if (path.isUnaryExpression()) {
1618
- return isExpressionOfLiterals(path.get("argument"), literalNames);
1619
- }
1620
- if (path.isLogicalExpression()) {
1621
- return (isExpressionOfLiterals(path.get("left"), literalNames) &&
1622
- isExpressionOfLiterals(path.get("right"), literalNames));
1623
- }
1624
- if (path.isBinaryExpression()) {
1625
- return (isExpressionOfLiterals(path.get("left"), literalNames) &&
1626
- isExpressionOfLiterals(path.get("right"), literalNames));
1627
- }
1628
- if (path.isConditionalExpression()) {
1629
- return (isExpressionOfLiterals(path.get("test"), literalNames) &&
1630
- isExpressionOfLiterals(path.get("consequent"), literalNames) &&
1631
- isExpressionOfLiterals(path.get("alternate"), literalNames));
1632
- }
1633
- if (path.isExpression() && isContinuation(path.node)) {
1634
- return true;
1635
- }
1636
- return false;
1637
- }
1638
- function generateIdentifierForPath(path) {
1639
- const node = path.node;
1640
- if (node) {
1641
- const result = path.scope.generateUidIdentifierBasedOnNode(node, "temp");
1642
- if (!path.isIdentifier() || path.node.name !== result.name) {
1643
- return result;
1644
- }
1645
- }
1646
- return path.scope.generateUidIdentifier("temp");
1647
- }
1648
- function booleanLiteral(value, minify) {
1649
- return minify ? types.numericLiteral(value ? 1 : 0) : types.booleanLiteral(value);
1650
- }
1651
- function conditionalExpression(test, consequent, alternate) {
1652
- const looseValue = extractLooseBooleanValue(test);
1653
- if (typeof looseValue !== "undefined") {
1654
- return looseValue ? consequent : alternate;
1655
- }
1656
- while (types.isUnaryExpression(test) && test.operator === "!") {
1657
- test = test.argument;
1658
- const temp = consequent;
1659
- consequent = alternate;
1660
- alternate = temp;
1661
- }
1662
- if ((isValueLiteral(consequent) && isValueLiteral(alternate) && consequent.value === alternate.value) ||
1663
- (types.isNullLiteral(consequent) && types.isNullLiteral(alternate)) ||
1664
- (types.isIdentifier(consequent) && types.isIdentifier(alternate) && consequent.name === alternate.name)) {
1665
- if (types.isIdentifier(test)) {
1666
- return consequent;
1667
- }
1668
- }
1669
- if (types.isIdentifier(test)) {
1670
- consequent = simplifyWithIdentifier(consequent, test, true);
1671
- alternate = simplifyWithIdentifier(alternate, test, false);
1672
- }
1673
- return types.conditionalExpression(test, consequent, alternate);
1674
- }
1675
- function extractBooleanValue(node) {
1676
- if (types.isBooleanLiteral(node)) {
1677
- return node.value;
1678
- }
1679
- if (types.isUnaryExpression(node)) {
1680
- if (node.operator === "!") {
1681
- const result = extractLooseBooleanValue(node.argument);
1682
- return typeof result === "undefined" ? undefined : !result;
1683
- }
1684
- else if (node.operator === "void") {
1685
- return typeof extractLooseBooleanValue(node.argument) !== "undefined" ? false : undefined;
1686
- }
1687
- }
1688
- }
1689
- function extractLooseBooleanValue(node) {
1690
- if (isValueLiteral(node)) {
1691
- return !!node.value;
1692
- }
1693
- if (types.isNullLiteral(node)) {
1694
- return false;
1695
- }
1696
- if (types.isIdentifier(node)) {
1697
- if (alwaysTruthy.indexOf(node.name) !== -1) {
1698
- return true;
1699
- }
1700
- if (node.name === "undefined") {
1701
- return false;
1702
- }
1703
- }
1704
- return extractBooleanValue(node);
1705
- }
1706
- function logicalOr(left, right) {
1707
- if (extractLooseBooleanValue(left) === true) {
1708
- return left;
1709
- }
1710
- else if (extractBooleanValue(left) === false) {
1711
- return right;
1712
- }
1713
- else {
1714
- return types.logicalExpression("||", left, right);
1715
- }
1716
- }
1717
- function logicalOrLoose(left, right, minify) {
1718
- switch (extractLooseBooleanValue(left)) {
1719
- case false:
1720
- return extractLooseBooleanValue(right) === false ? booleanLiteral(false, minify) : right;
1721
- case true:
1722
- return booleanLiteral(true, minify);
1723
- default:
1724
- switch (extractLooseBooleanValue(right)) {
1725
- case false:
1726
- return left;
1727
- case true:
1728
- return booleanLiteral(true, minify);
1729
- default:
1730
- return types.logicalExpression("||", left, right);
1731
- }
1732
- }
1733
- }
1734
- function logicalAnd(left, right, extract = extractBooleanValue) {
1735
- switch (extract(left)) {
1736
- case true:
1737
- return left;
1738
- case false:
1739
- return right;
1740
- default:
1741
- return types.logicalExpression("&&", left, right);
1742
- }
1743
- }
1744
- function logicalNot(node, minify) {
1745
- const literalValue = extractLooseBooleanValue(node);
1746
- if (typeof literalValue !== "undefined") {
1747
- return booleanLiteral(!literalValue, minify);
1748
- }
1749
- if (types.isUnaryExpression(node) &&
1750
- node.operator === "!" &&
1751
- types.isUnaryExpression(node.argument) &&
1752
- node.argument.operator === "!") {
1753
- return node.argument;
1754
- }
1755
- return types.unaryExpression("!", node);
1756
- }
1757
- function unwrapSpreadElement(path) {
1758
- if (path.node === null) {
1759
- return path;
1760
- }
1761
- if (path.node.type === "JSXNamespacedName") {
1762
- return path;
1763
- }
1764
- if (path.isExpression()) {
1765
- return path;
1766
- }
1767
- if (path.isSpreadElement()) {
1768
- return path.get("argument");
1769
- }
1770
- if (isArgumentPlaceholder(path)) {
1771
- return path;
1772
- }
1773
- throw path.buildCodeFrameError(`Expected either an expression or a spread element, got a ${path.type}!`, TypeError);
1774
- }
1775
- function findDeclarationToReuse(path) {
1776
- while (path) {
1777
- const parent = path.parentPath;
1778
- if (parent === null) {
1779
- break;
1780
- }
1781
- if (parent.isVariableDeclarator()) {
1782
- const id = parent.get("id");
1783
- if (id.isIdentifier() || id.isPattern()) {
1784
- return parent;
1785
- }
1786
- }
1787
- let other;
1788
- if (parent.isConditionalExpression()) {
1789
- const test = parent.get("test");
1790
- if (path === test) {
1791
- break;
1792
- }
1793
- const consequent = parent.get("consequent");
1794
- const alternate = parent.get("alternate");
1795
- other = consequent === path ? alternate : consequent;
1796
- }
1797
- else if (parent.isLogicalExpression()) {
1798
- const left = parent.get("left");
1799
- const right = parent.get("right");
1800
- other = left === path ? right : left;
1801
- }
1802
- else {
1803
- break;
1804
- }
1805
- const otherAwaitPath = findAwaitOrYieldPath(other);
1806
- if (otherAwaitPath === other || !otherAwaitPath) {
1807
- path = parent;
1808
- }
1809
- else {
1810
- break;
1811
- }
1812
- }
1813
- }
1814
- function extractDeclarations(state, originalAwaitPath, awaitExpression, additionalConstantNames) {
1815
- let awaitPath = originalAwaitPath;
1816
- const reusingExisting = findDeclarationToReuse(awaitPath);
1817
- const reusingExistingId = reusingExisting ? reusingExisting.get("id") : undefined;
1818
- const existingIdentifier = reusingExistingId && (reusingExistingId.isIdentifier() || reusingExistingId.isPattern())
1819
- ? reusingExistingId.node
1820
- : undefined;
1821
- let resultIdentifier;
1822
- if (!awaitPath.parentPath.isSequenceExpression() ||
1823
- !(awaitPath.key < awaitPath.container.length - 1)) {
1824
- const argument = originalAwaitPath.get("argument");
1825
- if (argument.isExpression()) {
1826
- resultIdentifier = existingIdentifier || generateIdentifierForPath(argument);
1827
- }
1828
- }
1829
- originalAwaitPath.replaceWith(types.isIdentifier(resultIdentifier) ? resultIdentifier : types.numericLiteral(0));
1830
- let declarations = [];
1831
- const isYield = originalAwaitPath.isYieldExpression();
1832
- let directExpression = booleanLiteral(false, readConfigKey(state.opts, "minify"));
1833
- for (;;) {
1834
- const parent = awaitPath.parentPath;
1835
- if (parent.isVariableDeclarator()) {
1836
- const beforeDeclarations = [];
1837
- let skipLiterals = true;
1838
- for (let key = parent.key - 1; key >= 0; --key) {
1839
- const sibling = parent.getSibling(key);
1840
- if (sibling.isVariableDeclarator()) {
1841
- const init = sibling.get("init");
1842
- if (!skipLiterals || (init && !isExpressionOfLiterals(init, additionalConstantNames))) {
1843
- skipLiterals = false;
1844
- beforeDeclarations.unshift(sibling.node);
1845
- sibling.remove();
1846
- }
1847
- }
1848
- else {
1849
- throw sibling.buildCodeFrameError(`Expected a variable declarator, got a ${sibling.type}!`, TypeError);
1850
- }
1851
- }
1852
- if (beforeDeclarations.length) {
1853
- declarations = declarations.concat(beforeDeclarations.concat(declarations));
1854
- }
1855
- }
1856
- else if (parent.isLogicalExpression()) {
1857
- const left = parent.get("left");
1858
- if (awaitPath !== left) {
1859
- if (!isYield && !isExpressionOfLiterals(left, additionalConstantNames)) {
1860
- const leftIdentifier = generateIdentifierForPath(left);
1861
- declarations = declarations.map((declaration) => declaration.init
1862
- ? types.variableDeclarator(declaration.id, logicalAnd(parent.node.operator === "||" ? logicalNot(leftIdentifier) : leftIdentifier, declaration.init))
1863
- : declaration);
1864
- declarations.unshift(types.variableDeclarator(leftIdentifier, left.node));
1865
- left.replaceWith(leftIdentifier);
1866
- }
1867
- const isOr = parent.node.operator === "||";
1868
- awaitExpression = (isOr ? logicalOr : logicalAnd)(left.node, awaitExpression);
1869
- if (!isYield) {
1870
- directExpression = logicalOrLoose(isOr ? left.node : logicalNot(left.node), directExpression, readConfigKey(state.opts, "minify"));
1871
- }
1872
- if (awaitPath === originalAwaitPath) {
1873
- if (resultIdentifier) {
1874
- parent.replaceWith(resultIdentifier);
1875
- }
1876
- else {
1877
- resultIdentifier =
1878
- existingIdentifier || generateIdentifierForPath(originalAwaitPath.get("argument"));
1879
- parent.replaceWith(resultIdentifier);
1880
- }
1881
- awaitPath = parent;
1882
- continue;
1883
- }
1884
- }
1885
- }
1886
- else if (parent.isBinaryExpression()) {
1887
- const left = parent.get("left");
1888
- if (awaitPath !== left) {
1889
- if (!isExpressionOfLiterals(left, additionalConstantNames) && left.node.type !== "PrivateName") {
1890
- const leftIdentifier = generateIdentifierForPath(left);
1891
- declarations.unshift(types.variableDeclarator(leftIdentifier, left.node));
1892
- left.replaceWith(leftIdentifier);
1893
- }
1894
- }
1895
- }
1896
- else if (parent.isSequenceExpression()) {
1897
- const children = parent.get("expressions");
1898
- const position = children.indexOf(awaitPath);
1899
- for (var i = 0; i < position; i++) {
1900
- const expression = children[i];
1901
- if (!isExpressionOfLiterals(expression, additionalConstantNames)) {
1902
- const sequenceIdentifier = generateIdentifierForPath(expression);
1903
- declarations.unshift(types.variableDeclarator(sequenceIdentifier, expression.node));
1904
- }
1905
- expression.remove();
1906
- }
1907
- if (position === children.length - 1) {
1908
- parent.replaceWith(children[position]);
1909
- }
1910
- }
1911
- else if (parent.isConditionalExpression()) {
1912
- const test = parent.get("test");
1913
- if (awaitPath !== test) {
1914
- let testNode = test.node;
1915
- const consequent = parent.get("consequent");
1916
- const alternate = parent.get("alternate");
1917
- const other = consequent === awaitPath ? alternate : consequent;
1918
- const otherAwaitPath = findAwaitOrYieldPath(other);
1919
- let testIdentifier;
1920
- const isBoth = consequent === awaitPath && otherAwaitPath === alternate;
1921
- if (!(isBoth && awaitPath === originalAwaitPath) &&
1922
- !isExpressionOfLiterals(test, additionalConstantNames)) {
1923
- testIdentifier = generateIdentifierForPath(test);
1924
- }
1925
- declarations = declarations.map((declaration) => declaration.init
1926
- ? types.variableDeclarator(declaration.id, (consequent === awaitPath ? logicalAnd : logicalOr)(testIdentifier || testNode, declaration.init))
1927
- : declaration);
1928
- if (testIdentifier) {
1929
- declarations.unshift(types.variableDeclarator(testIdentifier, testNode));
1930
- test.replaceWith(testIdentifier);
1931
- testNode = testIdentifier;
1932
- }
1933
- if (isBoth && otherAwaitPath) {
1934
- awaitExpression = conditionalExpression(testNode, awaitExpression, otherAwaitPath.node.argument || types.identifier("undefined"));
1935
- if (!resultIdentifier) {
1936
- resultIdentifier =
1937
- existingIdentifier || generateIdentifierForPath(originalAwaitPath.get("argument"));
1938
- }
1939
- alternate.replaceWith(resultIdentifier);
1940
- parent.replaceWith(resultIdentifier);
1941
- }
1942
- else {
1943
- if (!isYield) {
1944
- directExpression = logicalOrLoose(consequent !== awaitPath ? testNode : logicalNot(testNode), directExpression, readConfigKey(state.opts, "minify"));
1945
- }
1946
- if (otherAwaitPath) {
1947
- awaitExpression =
1948
- consequent !== awaitPath
1949
- ? conditionalExpression(testNode, types.numericLiteral(0), awaitExpression)
1950
- : conditionalExpression(testNode, awaitExpression, types.numericLiteral(0));
1951
- }
1952
- else {
1953
- awaitExpression =
1954
- consequent !== awaitPath
1955
- ? conditionalExpression(testNode, other.node, awaitExpression)
1956
- : conditionalExpression(testNode, awaitExpression, other.node);
1957
- if (!resultIdentifier) {
1958
- resultIdentifier =
1959
- existingIdentifier || generateIdentifierForPath(originalAwaitPath.get("argument"));
1960
- }
1961
- if (awaitPath === originalAwaitPath) {
1962
- parent.replaceWith(resultIdentifier);
1963
- awaitPath = parent;
1964
- continue;
1965
- }
1966
- other.replaceWith(resultIdentifier);
1967
- }
1968
- }
1969
- }
1970
- }
1971
- else if (parent.isCallExpression()) {
1972
- const callee = parent.get("callee");
1973
- if (callee !== awaitPath) {
1974
- for (const arg of parent.get("arguments")) {
1975
- const spreadArg = unwrapSpreadElement(arg);
1976
- if (spreadArg === awaitPath || arg === awaitPath) {
1977
- break;
1978
- }
1979
- if (spreadArg.isExpression() && !isExpressionOfLiterals(spreadArg, additionalConstantNames)) {
1980
- const argIdentifier = generateIdentifierForPath(spreadArg);
1981
- declarations.unshift(types.variableDeclarator(argIdentifier, spreadArg.node));
1982
- spreadArg.replaceWith(argIdentifier);
1983
- }
1984
- }
1985
- if (!isExpressionOfLiterals(callee, additionalConstantNames) &&
1986
- typeof promiseCallExpressionType(parent.node) === "undefined") {
1987
- if (callee.isMemberExpression()) {
1988
- const object = callee.get("object");
1989
- const property = callee.get("property");
1990
- let objectDeclarator;
1991
- let staticMethods = {};
1992
- let constantObject = false;
1993
- if (object.isIdentifier() &&
1994
- Object.hasOwnProperty.call(constantStaticMethods, object.node.name) &&
1995
- !callee.scope.getBinding(object.node.name)) {
1996
- constantObject = true;
1997
- staticMethods = constantStaticMethods[object.node.name];
1998
- }
1999
- else if (isExpressionOfLiterals(object, additionalConstantNames)) {
2000
- constantObject = true;
2001
- }
2002
- if (!constantObject) {
2003
- const objectIdentifier = generateIdentifierForPath(object);
2004
- objectDeclarator = types.variableDeclarator(objectIdentifier, object.node);
2005
- object.replaceWith(objectIdentifier);
2006
- }
2007
- if (!callee.node.computed &&
2008
- property.isIdentifier() &&
2009
- (property.node.name === "call" ||
2010
- Object.hasOwnProperty.call(staticMethods, property.node.name))) {
2011
- }
2012
- else {
2013
- const calleeIdentifier = generateIdentifierForPath(property);
2014
- const calleeNode = callee.node;
2015
- const newArguments = parent.node.arguments.slice();
2016
- newArguments.unshift(Object.assign({}, object.node));
2017
- parent.replaceWith(types.callExpression(types.memberExpression(calleeIdentifier, types.identifier("call")), newArguments));
2018
- declarations.unshift(types.variableDeclarator(calleeIdentifier, calleeNode));
2019
- }
2020
- if (typeof objectDeclarator !== "undefined") {
2021
- declarations.unshift(objectDeclarator);
2022
- }
2023
- }
2024
- else if (!callee.isIdentifier() ||
2025
- !(helperNameMap.has(callee.node) ||
2026
- (awaitPath.scope.getBinding(callee.node.name) || { constant: false }).constant)) {
2027
- const calleeIdentifier = generateIdentifierForPath(callee);
2028
- const calleeNode = callee.node;
2029
- callee.replaceWith(calleeIdentifier);
2030
- declarations.unshift(types.variableDeclarator(calleeIdentifier, discardingIntrinsics(calleeNode)));
2031
- }
2032
- }
2033
- }
2034
- }
2035
- else if (parent.isArrayExpression()) {
2036
- for (const element of parent.get("elements")) {
2037
- const spreadElement = unwrapSpreadElement(element);
2038
- if (element === awaitPath || spreadElement === awaitPath) {
2039
- break;
2040
- }
2041
- if (spreadElement.isExpression() &&
2042
- !isExpressionOfLiterals(spreadElement, additionalConstantNames)) {
2043
- const elementIdentifier = generateIdentifierForPath(spreadElement);
2044
- declarations.unshift(types.variableDeclarator(elementIdentifier, spreadElement.node));
2045
- spreadElement.replaceWith(elementIdentifier);
2046
- }
2047
- }
2048
- }
2049
- else if (parent.isObjectExpression()) {
2050
- for (const prop of parent.get("properties")) {
2051
- if (prop === awaitPath) {
2052
- break;
2053
- }
2054
- if (prop.isObjectProperty()) {
2055
- if (prop.node.computed) {
2056
- const propKey = prop.get("key");
2057
- if (propKey === awaitPath) {
2058
- break;
2059
- }
2060
- if (propKey.isExpression() && !isExpressionOfLiterals(propKey, additionalConstantNames)) {
2061
- const keyIdentifier = generateIdentifierForPath(propKey);
2062
- declarations.unshift(types.variableDeclarator(keyIdentifier, propKey.node));
2063
- propKey.replaceWith(keyIdentifier);
2064
- }
2065
- }
2066
- const propValue = prop.get("value");
2067
- if (propValue === awaitPath) {
2068
- break;
2069
- }
2070
- if (propValue.isExpression() && !isExpressionOfLiterals(propValue, additionalConstantNames)) {
2071
- const propIdentifier = generateIdentifierForPath(propValue);
2072
- declarations.unshift(types.variableDeclarator(propIdentifier, propValue.node));
2073
- propValue.replaceWith(propIdentifier);
2074
- }
2075
- }
2076
- }
2077
- }
2078
- if (parent.isStatement()) {
2079
- return {
2080
- declarationKind: reusingExisting ? reusingExisting.parent.kind : "const",
2081
- declarations,
2082
- awaitExpression,
2083
- directExpression,
2084
- reusingExisting,
2085
- resultIdentifier,
2086
- };
2087
- }
2088
- awaitPath = parent;
2089
- }
2090
- }
2091
- function skipNode(path) {
2092
- path.skip();
2093
- }
2094
- const awaitPathVisitor = {
2095
- Function: skipNode,
2096
- AwaitExpression(path) {
2097
- this.result = path;
2098
- path.stop();
2099
- },
2100
- YieldExpression(path) {
2101
- this.result = path;
2102
- path.stop();
2103
- },
2104
- };
2105
- function findAwaitOrYieldPath(path) {
2106
- if (path.isAwaitExpression() || path.isYieldExpression()) {
2107
- return path;
2108
- }
2109
- const state = Object.create(null);
2110
- path.traverse(awaitPathVisitor, state);
2111
- return state.result;
2112
- }
2113
- function buildBreakExitCheck(state, exitIdentifier, breakIdentifiers) {
2114
- if (breakIdentifiers !== undefined && breakIdentifiers.length > 0) {
2115
- const minify = readConfigKey(state.opts, "minify");
2116
- const first = breakIdentifiers[0].identifier;
2117
- const partial = breakIdentifiers
2118
- .slice(1)
2119
- .reduce((accumulator, { identifier }) => logicalOrLoose(accumulator, identifier, minify), first);
2120
- return exitIdentifier ? logicalOrLoose(partial, exitIdentifier, minify) : partial;
2121
- }
2122
- else {
2123
- return exitIdentifier;
2124
- }
2125
- }
2126
- function pushMissing(destination, source) {
2127
- for (var value of source) {
2128
- var index = destination.indexOf(value);
2129
- if (index < 0) {
2130
- destination.push(value);
2131
- }
2132
- }
2133
- }
2134
- function setBreakIdentifier(value, breakIdentifier) {
2135
- return types.assignmentExpression("=", breakIdentifier.identifier, value);
2136
- }
2137
- function setBreakIdentifiers(breakIdentifiers, pluginState) {
2138
- return breakIdentifiers.reduce(setBreakIdentifier, booleanLiteral(true, readConfigKey(pluginState.opts, "minify")));
2139
- }
2140
- function expressionNeverThrows(expression) {
2141
- return (isValueLiteral(expression) ||
2142
- types.isIdentifier(expression) ||
2143
- (types.isUnaryExpression(expression) && isValueLiteral(expression.argument)));
2144
- }
2145
- const replaceReturnsAndBreaksVisitor = {
2146
- Function: skipNode,
2147
- ReturnStatement(path) {
2148
- if (!skipNodeSet.has(path.node) && this.exitIdentifier) {
2149
- const minify = readConfigKey(this.pluginState.opts, "minify");
2150
- if (path.node.argument) {
2151
- if (minify && extractLooseBooleanValue(path.node.argument) === true) {
2152
- path.replaceWith(returnStatement(types.assignmentExpression("=", this.exitIdentifier, path.node.argument), path.node));
2153
- }
2154
- else if (expressionNeverThrows(path.node.argument)) {
2155
- path.replaceWithMultiple([
2156
- types.expressionStatement(types.assignmentExpression("=", this.exitIdentifier, booleanLiteral(true, minify))),
2157
- returnStatement(path.node.argument, path.node),
2158
- ]);
2159
- }
2160
- else {
2161
- const tempIdentifier = path.scope.generateUidIdentifierBasedOnNode(path.node.argument, "temp");
2162
- path.replaceWithMultiple([
2163
- types.variableDeclaration("const", [
2164
- types.variableDeclarator(tempIdentifier, path.node.argument),
2165
- ]),
2166
- types.expressionStatement(types.assignmentExpression("=", this.exitIdentifier, booleanLiteral(true, minify))),
2167
- returnStatement(tempIdentifier, path.node),
2168
- ]);
2169
- }
2170
- }
2171
- else {
2172
- path.replaceWithMultiple([
2173
- types.expressionStatement(types.assignmentExpression("=", this.exitIdentifier, booleanLiteral(true, minify))),
2174
- returnStatement(undefined, path.node),
2175
- ]);
2176
- }
2177
- }
2178
- },
2179
- SwitchStatement: {
2180
- enter() {
2181
- this.switchCount++;
2182
- },
2183
- exit() {
2184
- this.switchCount--;
2185
- },
2186
- },
2187
- Loop: {
2188
- enter(path) {
2189
- const parent = path.parentPath;
2190
- this.breakIdentifiers.unshift({
2191
- identifier: types.identifier("break"),
2192
- path,
2193
- name: parent.isLabeledStatement() ? parent.node.label.name : undefined,
2194
- isAsync: false,
2195
- });
2196
- },
2197
- exit() {
2198
- this.breakIdentifiers.shift();
2199
- },
2200
- },
2201
- BreakStatement(path) {
2202
- const label = path.node.label;
2203
- if (label || this.switchCount === 0) {
2204
- const index = label
2205
- ? this.breakIdentifiers.findIndex((breakIdentifier) => breakIdentifier.name === label.name)
2206
- : 0;
2207
- const replace = returnStatement(undefined, path.node);
2208
- if (index !== -1 && this.breakIdentifiers.length) {
2209
- if (!this.breakIdentifiers[index].isAsync) {
2210
- return;
2211
- }
2212
- const used = this.breakIdentifiers.slice(0, index + 1);
2213
- if (used.length) {
2214
- pushMissing(this.usedIdentifiers, used);
2215
- path.replaceWithMultiple([
2216
- types.expressionStatement(setBreakIdentifiers(used, this.pluginState)),
2217
- replace,
2218
- ]);
2219
- return;
2220
- }
2221
- }
2222
- path.replaceWith(replace);
2223
- }
2224
- },
2225
- ContinueStatement(path) {
2226
- const label = path.node.label;
2227
- const index = label
2228
- ? this.breakIdentifiers.findIndex((breakIdentifier) => breakIdentifier.name === label.name)
2229
- : 0;
2230
- const replace = returnStatement(undefined, path.node);
2231
- if (index !== -1 && this.breakIdentifiers.length) {
2232
- if (!this.breakIdentifiers[index].isAsync) {
2233
- return;
2234
- }
2235
- const used = this.breakIdentifiers.slice(0, index);
2236
- if (used.length) {
2237
- pushMissing(this.usedIdentifiers, used);
2238
- path.replaceWithMultiple([
2239
- types.expressionStatement(setBreakIdentifiers(used, this.pluginState)),
2240
- replace,
2241
- ]);
2242
- return;
2243
- }
2244
- }
2245
- path.replaceWith(replace);
2246
- },
2247
- };
2248
- function replaceReturnsAndBreaks(pluginState, path, exitIdentifier, existingUsedIdentifiers) {
2249
- const usedIdentifiers = [];
2250
- if (existingUsedIdentifiers !== undefined) {
2251
- for (const item of existingUsedIdentifiers) {
2252
- if (path.parentPath === null ||
2253
- path.parentPath.scope.getBinding(item.identifier.name) ===
2254
- path.scope.getBinding(item.identifier.name)) {
2255
- usedIdentifiers.push(item);
2256
- }
2257
- }
2258
- }
2259
- const state = {
2260
- pluginState,
2261
- exitIdentifier,
2262
- breakIdentifiers: breakContinueStackForPath(path),
2263
- usedIdentifiers,
2264
- switchCount: 0,
2265
- };
2266
- path.traverse(replaceReturnsAndBreaksVisitor, state);
2267
- for (const { identifier, path: identifierPath } of usedIdentifiers) {
2268
- const parentScope = identifierPath.parentPath.scope;
2269
- if (!parentScope.getBinding(identifier.name)) {
2270
- parentScope.push({
2271
- kind: "let",
2272
- id: identifier,
2273
- init: readConfigKey(pluginState.opts, "minify")
2274
- ? undefined
2275
- : booleanLiteral(false, readConfigKey(pluginState.opts, "minify")),
2276
- });
2277
- }
2278
- }
2279
- return usedIdentifiers;
2280
- }
2281
- function breakIdentifierForPath(path) {
2282
- let result = breakIdentifierMap.get(path.node);
2283
- if (!result) {
2284
- result = path.scope.generateUidIdentifier(path.parentPath !== null && path.parentPath.isLabeledStatement()
2285
- ? path.parentPath.node.label.name + "Interrupt"
2286
- : "interrupt");
2287
- breakIdentifierMap.set(path.node, result);
2288
- }
2289
- return result;
2290
- }
2291
- const simpleBreakOrContinueReferencesVisitor = {
2292
- Function: skipNode,
2293
- Loop: skipNode,
2294
- SwitchStatement: skipNode,
2295
- BreakStatement(path) {
2296
- if (!path.node.label) {
2297
- this.references.push(path);
2298
- }
2299
- },
2300
- ReturnStatement(path) {
2301
- const originalNode = originalNodeMap.get(path.node);
2302
- if (originalNode) {
2303
- traverse(wrapNodeInStatement(originalNode), simpleBreakOrContinueReferencesVisitor, path.scope, this, path);
2304
- path.skip();
2305
- }
2306
- },
2307
- };
2308
- function simpleBreakOrContinueReferences(path) {
2309
- const state = { references: [] };
2310
- path.traverse(simpleBreakOrContinueReferencesVisitor, state);
2311
- return state.references;
2312
- }
2313
- const namedLabelReferencesVisitor = {
2314
- Function: skipNode,
2315
- BreakStatement(path) {
2316
- if (path.node.label && path.node.label.name === this.name) {
2317
- this.breaks.push(path);
2318
- }
2319
- },
2320
- ContinueStatement(path) {
2321
- if (path.node.label && path.node.label.name === this.name) {
2322
- this.continues.push(path);
2323
- }
2324
- },
2325
- ReturnStatement(path) {
2326
- const originalNode = originalNodeMap.get(path.node);
2327
- if (originalNode) {
2328
- traverse(wrapNodeInStatement(originalNode), namedLabelReferencesVisitor, path.scope, this, path);
2329
- path.skip();
2330
- }
2331
- },
2332
- };
2333
- function namedLabelReferences(labelPath, targetPath) {
2334
- const state = { name: labelPath.node.label.name, breaks: [], continues: [] };
2335
- targetPath.traverse(namedLabelReferencesVisitor, state);
2336
- return state;
2337
- }
2338
- function breakContinueStackForPath(path) {
2339
- let current = path;
2340
- const result = [];
2341
- while (current && !current.isFunction()) {
2342
- if (current.isLoop() || current.isSwitchStatement()) {
2343
- const breaks = pathsBreak(current);
2344
- if (breaks.any && (!current.isSwitchStatement() || !breaks.all)) {
2345
- const simpleReferences = simpleBreakOrContinueReferences(current);
2346
- if (current.parentPath.isLabeledStatement()) {
2347
- const refs = namedLabelReferences(current.parentPath, path);
2348
- if (simpleReferences.length || refs.breaks.length || refs.continues.length) {
2349
- result.push({
2350
- identifier: breakIdentifierForPath(current),
2351
- name: current.parentPath.node.label.name,
2352
- path: current.parentPath,
2353
- isAsync: true,
2354
- });
2355
- }
2356
- current = current.parentPath;
2357
- }
2358
- else if (simpleReferences.length) {
2359
- result.push({
2360
- identifier: breakIdentifierForPath(current),
2361
- path: current,
2362
- isAsync: true,
2363
- });
2364
- }
2365
- }
2366
- }
2367
- else if (current.isLabeledStatement()) {
2368
- const refs = namedLabelReferences(current, path);
2369
- if (refs.breaks.length || refs.continues.length) {
2370
- result.push({
2371
- identifier: breakIdentifierForPath(current.get("body")),
2372
- name: current.node.label.name,
2373
- path: current,
2374
- isAsync: true,
2375
- });
2376
- }
2377
- }
2378
- current = current.parentPath;
2379
- }
2380
- return result;
2381
- }
2382
- function isForAwaitStatement(path) {
2383
- return path.isForAwaitStatement && path.node ? path.isForAwaitStatement() : false;
2384
- }
2385
- function isArgumentPlaceholder(path) {
2386
- return path.node.type === "ArgumentPlaceholder";
2387
- }
2388
- function getStatementOrArrowBodyParent(path) {
2389
- let parent = path;
2390
- while (parent) {
2391
- if (parent.isStatement()) {
2392
- return parent;
2393
- }
2394
- if (parent.isArrowFunctionExpression()) {
2395
- return parent.get("body");
2396
- }
2397
- parent = parent.parentPath;
2398
- }
2399
- throw path.buildCodeFrameError(`Expected a statement parent!`, TypeError);
2400
- }
2401
- function addConstantNames(additionalConstantNames, node) {
2402
- if (types.isIdentifier(node)) {
2403
- if (additionalConstantNames.indexOf(node.name) === -1) {
2404
- additionalConstantNames.push(node.name);
2405
- }
2406
- }
2407
- else if (types.isArrayPattern(node)) {
2408
- for (const element of node.elements) {
2409
- if (types.isIdentifier(element) || types.isPattern(element) || types.isRestElement(element)) {
2410
- addConstantNames(additionalConstantNames, element);
2411
- }
2412
- }
2413
- }
2414
- else if (types.isObjectPattern(node)) {
2415
- for (const property of node.properties) {
2416
- if (types.isObjectProperty(property)) {
2417
- addConstantNames(additionalConstantNames, property.key);
2418
- }
2419
- else if (types.isRestElement(property)) {
2420
- addConstantNames(additionalConstantNames, property.argument);
2421
- }
2422
- }
2423
- }
2424
- else if (types.isRestElement(node)) {
2425
- addConstantNames(additionalConstantNames, node.argument);
2426
- }
2427
- }
2428
- function yieldOnExpression(state, expression) {
2429
- const generatorIdentifier = state.generatorIdentifier;
2430
- if (typeof generatorIdentifier === "undefined") {
2431
- throw new Error("Encountered a yield expression outside a generator function!");
2432
- }
2433
- const callee = types.memberExpression(generatorIdentifier, types.identifier("_yield"));
2434
- helperNameMap.set(callee, "_yield");
2435
- return types.callExpression(callee, [expression]);
2436
- }
2437
- function rewriteAwaitOrYieldPath(rewritePath) {
2438
- const state = this;
2439
- const pluginState = state.generatorState.state;
2440
- const path = state.path;
2441
- const additionalConstantNames = state.additionalConstantNames;
2442
- let awaitPath;
2443
- let processExpressions;
2444
- const rewritePathCopy = rewritePath;
2445
- if (rewritePath.isAwaitExpression() || rewritePath.isYieldExpression()) {
2446
- awaitPath = rewritePath;
2447
- processExpressions = true;
2448
- }
2449
- else if (rewritePath.isForOfStatement() || isForAwaitStatement(rewritePath)) {
2450
- const left = rewritePath.get("left");
2451
- if (left.isAwaitExpression()) {
2452
- awaitPath = left.get("argument");
2453
- }
2454
- else if (left.isSpreadElement()) {
2455
- awaitPath = unwrapSpreadElement(left);
2456
- }
2457
- else {
2458
- awaitPath = left;
2459
- }
2460
- processExpressions = false;
2461
- }
2462
- else {
2463
- throw rewritePathCopy.buildCodeFrameError(`Expected either an await expression or a for await statement, got a ${rewritePathCopy.type}!`, TypeError);
2464
- }
2465
- const paths = [];
2466
- {
2467
- let targetPath = awaitPath;
2468
- let shouldPushExitIdentifier = false;
2469
- while (targetPath !== path) {
2470
- const parent = targetPath.parentPath;
2471
- if (parent == null) {
2472
- break;
2473
- }
2474
- if (!parent.isSwitchCase() && !parent.isBlockStatement()) {
2475
- let exitIdentifier;
2476
- const explicitExits = pathsReturnOrThrow(parent);
2477
- if (!explicitExits.all && explicitExits.any && (parent.isLoop() || exitsInTail(parent))) {
2478
- if (!state.exitIdentifier) {
2479
- state.exitIdentifier = targetPath.scope.generateUidIdentifier("exit");
2480
- shouldPushExitIdentifier = true;
2481
- }
2482
- exitIdentifier = state.exitIdentifier;
2483
- }
2484
- paths.push({
2485
- targetPath,
2486
- explicitExits,
2487
- parent,
2488
- exitIdentifier,
2489
- });
2490
- }
2491
- targetPath = parent;
2492
- }
2493
- if (shouldPushExitIdentifier && state.exitIdentifier) {
2494
- path.scope.push({
2495
- kind: "let",
2496
- id: state.exitIdentifier,
2497
- init: readConfigKey(pluginState.opts, "minify")
2498
- ? undefined
2499
- : booleanLiteral(false, readConfigKey(pluginState.opts, "minify")),
2500
- });
2501
- }
2502
- }
2503
- let breakIdentifiers = [];
2504
- for (const item of paths) {
2505
- const parent = item.parent;
2506
- if (parent.isForStatement() ||
2507
- parent.isWhileStatement() ||
2508
- parent.isDoWhileStatement() ||
2509
- parent.isForInStatement() ||
2510
- parent.isForOfStatement() ||
2511
- isForAwaitStatement(parent) ||
2512
- parent.isLabeledStatement()) {
2513
- breakIdentifiers = item.breakIdentifiers = replaceReturnsAndBreaks(pluginState, parent.get("body"), item.exitIdentifier, breakIdentifiers);
2514
- if (parent.isForStatement()) {
2515
- if ((item.forToIdentifiers = identifiersInForToLengthStatement(parent))) {
2516
- addConstantNames(additionalConstantNames, item.forToIdentifiers.i);
2517
- }
2518
- }
2519
- }
2520
- else if (item.parent.isSwitchStatement()) {
2521
- breakIdentifiers = breakIdentifiers.slice();
2522
- item.cases = item.parent.get("cases").map((casePath) => {
2523
- const caseExits = pathsReturnOrThrow(casePath);
2524
- const caseBreaks = pathsBreak(casePath);
2525
- const caseBreakIdentifiers = (item.breakIdentifiers = replaceReturnsAndBreaks(pluginState, casePath, item.exitIdentifier, breakIdentifiers));
2526
- for (const breakItem of caseBreakIdentifiers) {
2527
- if (!breakIdentifiers.find((existing) => existing.identifier.name === breakItem.identifier.name)) {
2528
- breakIdentifiers.push(breakItem);
2529
- }
2530
- }
2531
- return {
2532
- casePath,
2533
- caseExits,
2534
- caseBreaks,
2535
- breakIdentifiers: caseBreakIdentifiers,
2536
- test: casePath.node.test,
2537
- };
2538
- });
2539
- }
2540
- else {
2541
- breakIdentifiers = item.breakIdentifiers = replaceReturnsAndBreaks(pluginState, parent, item.exitIdentifier, breakIdentifiers);
2542
- }
2543
- }
2544
- for (const { targetPath, explicitExits, breakIdentifiers, parent, exitIdentifier, cases, forToIdentifiers, } of paths) {
2545
- if (parent.isExpressionStatement() &&
2546
- (targetPath.isAwaitExpression() || targetPath.isYieldExpression()) &&
2547
- processExpressions) {
2548
- processExpressions = false;
2549
- relocateTail(state.generatorState, targetPath.isYieldExpression()
2550
- ? yieldOnExpression(state.generatorState, targetPath.node.argument || types.identifier("undefined"))
2551
- : targetPath.node.argument, undefined, parent, additionalConstantNames, undefined, undefined, targetPath.isYieldExpression()
2552
- ? undefined
2553
- : booleanLiteral(false, readConfigKey(pluginState.opts, "minify")), state.skipReturns);
2554
- }
2555
- else if (parent.isIfStatement()) {
2556
- const test = parent.get("test");
2557
- if (targetPath !== test) {
2558
- let resultIdentifier;
2559
- if (!explicitExits.all && explicitExits.any) {
2560
- resultIdentifier = path.scope.generateUidIdentifier("result");
2561
- addConstantNames(additionalConstantNames, resultIdentifier);
2562
- }
2563
- if (!explicitExits.all) {
2564
- const consequent = parent.get("consequent");
2565
- rewriteAsyncBlock(state.generatorState, consequent, additionalConstantNames, exitIdentifier);
2566
- const alternate = parent.get("alternate");
2567
- if (alternate.isStatement()) {
2568
- rewriteAsyncBlock(state.generatorState, alternate, additionalConstantNames, exitIdentifier);
2569
- }
2570
- const fn = functionize(pluginState, [], blockStatement([parent.node]), targetPath);
2571
- relocateTail(state.generatorState, types.callExpression(fn, []), undefined, parent, additionalConstantNames, resultIdentifier, exitIdentifier, undefined, state.skipReturns);
2572
- processExpressions = false;
2573
- }
2574
- }
2575
- }
2576
- else if (parent.isTryStatement()) {
2577
- const temporary = explicitExits.any && !explicitExits.all ? path.scope.generateUidIdentifier("result") : undefined;
2578
- const exitCheck = buildBreakExitCheck(pluginState, explicitExits.any && !explicitExits.all ? exitIdentifier : undefined, breakIdentifiers);
2579
- let expression = rewriteAsyncNode(state.generatorState, parent, parent.node.block, additionalConstantNames, exitIdentifier);
2580
- const catchClause = parent.node.handler;
2581
- if (catchClause) {
2582
- const param = catchClause.param;
2583
- const paramIsUsed = param !== null &&
2584
- param !== undefined &&
2585
- (param.type !== "Identifier" ||
2586
- parent.get("handler").scope.getBinding(param.name).referencePaths.length !== 0);
2587
- const fn = catchClause.body.body.length
2588
- ? rewriteAsyncNode(state.generatorState, parent, functionize(pluginState, paramIsUsed && param != null ? [param] : [], catchClause.body, targetPath), additionalConstantNames, exitIdentifier)
2589
- : emptyFunction(pluginState, parent);
2590
- expression = types.callExpression(helperReference(pluginState, path, state.generatorState.generatorIdentifier ? "_catchInGenerator" : "_catch"), [
2591
- unwrapReturnCallWithEmptyArguments(functionize(pluginState, [], expression, targetPath), path.scope, additionalConstantNames),
2592
- fn,
2593
- ]);
2594
- }
2595
- if (parent.node.finalizer) {
2596
- let finallyName;
2597
- let finallyArgs;
2598
- let finallyBody = parent.node.finalizer.body;
2599
- if (!pathsReturnOrThrow(parent.get("finalizer")).all) {
2600
- const resultIdentifier = temporary || path.scope.generateUidIdentifier("result");
2601
- addConstantNames(additionalConstantNames, resultIdentifier);
2602
- const wasThrownIdentifier = path.scope.generateUidIdentifier("wasThrown");
2603
- addConstantNames(additionalConstantNames, wasThrownIdentifier);
2604
- finallyArgs = [wasThrownIdentifier, resultIdentifier];
2605
- if (readConfigKey(pluginState.opts, "inlineHelpers")) {
2606
- finallyBody = finallyBody.concat([
2607
- types.ifStatement(wasThrownIdentifier, types.throwStatement(resultIdentifier)),
2608
- types.returnStatement(resultIdentifier),
2609
- ]);
2610
- }
2611
- else {
2612
- finallyBody = finallyBody.concat(returnStatement(types.callExpression(helperReference(pluginState, parent, "_rethrow"), [
2613
- wasThrownIdentifier,
2614
- resultIdentifier,
2615
- ])));
2616
- }
2617
- finallyName = "_finallyRethrows";
2618
- }
2619
- else {
2620
- finallyArgs = [];
2621
- finallyName = "_finally";
2622
- }
2623
- const fn = functionize(pluginState, finallyArgs, blockStatement(finallyBody), targetPath);
2624
- const rewritten = rewriteAsyncNode(state.generatorState, parent, fn, additionalConstantNames, exitIdentifier);
2625
- expression = types.callExpression(helperReference(pluginState, parent, finallyName), [
2626
- unwrapReturnCallWithEmptyArguments(functionize(pluginState, [], expression, targetPath), path.scope, additionalConstantNames),
2627
- rewritten,
2628
- ]);
2629
- }
2630
- relocateTail(state.generatorState, types.isExpression(expression)
2631
- ? expression
2632
- : types.callExpression(functionize(pluginState, [], expression, targetPath), []), undefined, parent, additionalConstantNames, temporary, exitCheck, undefined, state.skipReturns);
2633
- processExpressions = false;
2634
- }
2635
- else if (parent.isForStatement() ||
2636
- parent.isWhileStatement() ||
2637
- parent.isDoWhileStatement() ||
2638
- parent.isForInStatement() ||
2639
- parent.isForOfStatement() ||
2640
- isForAwaitStatement(parent)) {
2641
- const label = parent.parentPath.isLabeledStatement() ? parent.parentPath.node.label.name : undefined;
2642
- if (parent.isForInStatement() || parent.isForOfStatement() || isForAwaitStatement(parent)) {
2643
- const right = parent.get("right");
2644
- if (awaitPath !== right) {
2645
- const left = parent.get("left");
2646
- const loopIdentifier = left.isVariableDeclaration()
2647
- ? left.get("declarations")[0].get("id")
2648
- : left;
2649
- if (loopIdentifier.isIdentifier() || loopIdentifier.isPattern()) {
2650
- const forOwnBodyPath = parent.isForInStatement() && extractForOwnBodyPath(parent);
2651
- const bodyBlock = blockStatement((forOwnBodyPath || parent.get("body")).node);
2652
- const params = [
2653
- right.node,
2654
- rewriteAsyncNode(state.generatorState, parent, bodyBlock.body.length
2655
- ? functionize(pluginState, [loopIdentifier.node], bodyBlock, targetPath)
2656
- : emptyFunction(pluginState, parent), additionalConstantNames, exitIdentifier),
2657
- ];
2658
- const exitCheck = buildBreakExitCheck(pluginState, exitIdentifier, breakIdentifiers);
2659
- if (exitCheck) {
2660
- params.push(functionize(pluginState, [], types.blockStatement([returnStatement(exitCheck)]), targetPath));
2661
- }
2662
- const loopCall = types.callExpression(helperReference(pluginState, parent, parent.isForInStatement()
2663
- ? forOwnBodyPath
2664
- ? "_forOwn"
2665
- : "_forIn"
2666
- : isForAwaitStatement(parent)
2667
- ? "_forAwaitOf"
2668
- : "_forOf"), params);
2669
- let resultIdentifier = undefined;
2670
- if (explicitExits.any) {
2671
- resultIdentifier = path.scope.generateUidIdentifier("result");
2672
- addConstantNames(additionalConstantNames, resultIdentifier);
2673
- }
2674
- relocateTail(state.generatorState, loopCall, undefined, label && parent.parentPath.isStatement()
2675
- ? parent.parentPath
2676
- : parent, additionalConstantNames, resultIdentifier, exitIdentifier, undefined, state.skipReturns);
2677
- processExpressions = false;
2678
- }
2679
- else {
2680
- throw loopIdentifier.buildCodeFrameError(`Expected an identifier or pattern, but got a ${loopIdentifier.type}!`, TypeError);
2681
- }
2682
- }
2683
- }
2684
- else {
2685
- let testExpression = parent.node.test;
2686
- const breakExitCheck = buildBreakExitCheck(pluginState, exitIdentifier, breakIdentifiers);
2687
- if (breakExitCheck) {
2688
- const inverted = logicalNot(breakExitCheck, readConfigKey(pluginState.opts, "minify"));
2689
- testExpression =
2690
- testExpression && (!types.isBooleanLiteral(testExpression) || !testExpression.value)
2691
- ? logicalAnd(inverted, testExpression, extractLooseBooleanValue)
2692
- : inverted;
2693
- }
2694
- if (testExpression) {
2695
- testExpression = rewriteAsyncNode(state.generatorState, parent, functionize(pluginState, [], testExpression, targetPath), additionalConstantNames, exitIdentifier, true);
2696
- }
2697
- const isDoWhile = parent.isDoWhileStatement();
2698
- let loopCall;
2699
- if (forToIdentifiers && !isDoWhile) {
2700
- const args = [
2701
- forToIdentifiers.array,
2702
- rewriteAsyncNode(state.generatorState, parent, functionize(pluginState, [forToIdentifiers.i], blockStatement(parent.node.body), targetPath), additionalConstantNames, exitIdentifier),
2703
- ];
2704
- if (breakExitCheck) {
2705
- args.push(functionize(pluginState, [], breakExitCheck, targetPath));
2706
- }
2707
- loopCall = types.callExpression(helperReference(pluginState, parent, "_forTo"), args);
2708
- }
2709
- else {
2710
- let updateExpression = null;
2711
- if (parent.isForStatement()) {
2712
- updateExpression = parent.node.update;
2713
- if (updateExpression) {
2714
- updateExpression = rewriteAsyncNode(state.generatorState, parent, functionize(pluginState, [], updateExpression, targetPath), additionalConstantNames, exitIdentifier, true);
2715
- }
2716
- const init = parent.get("init");
2717
- if (init) {
2718
- const initNode = init.node;
2719
- if (initNode !== null && initNode !== undefined) {
2720
- reregisterDeclarations(parent.insertBefore(types.isExpression(initNode)
2721
- ? types.expressionStatement(initNode)
2722
- : initNode));
2723
- }
2724
- }
2725
- }
2726
- const bodyFunction = rewriteAsyncNode(state.generatorState, parent, functionize(pluginState, [], blockStatement(parent.node.body || []), targetPath), additionalConstantNames, exitIdentifier);
2727
- const testFunction = unwrapReturnCallWithEmptyArguments(testExpression || voidExpression(), path.scope, additionalConstantNames);
2728
- const updateFunction = unwrapReturnCallWithEmptyArguments(updateExpression || voidExpression(), path.scope, additionalConstantNames);
2729
- loopCall = isDoWhile
2730
- ? types.callExpression(helperReference(pluginState, parent, "_do"), [
2731
- bodyFunction,
2732
- testFunction,
2733
- ])
2734
- : types.callExpression(helperReference(pluginState, parent, "_for"), [
2735
- testFunction,
2736
- updateFunction,
2737
- bodyFunction,
2738
- ]);
2739
- }
2740
- let resultIdentifier = undefined;
2741
- if (explicitExits.any) {
2742
- resultIdentifier = path.scope.generateUidIdentifier("result");
2743
- addConstantNames(additionalConstantNames, resultIdentifier);
2744
- }
2745
- relocateTail(state.generatorState, loopCall, undefined, parent, additionalConstantNames, resultIdentifier, exitIdentifier, undefined, state.skipReturns);
2746
- processExpressions = false;
2747
- }
2748
- }
2749
- else if (parent.isSwitchStatement()) {
2750
- const label = parent.parentPath.isLabeledStatement() ? parent.parentPath.node.label.name : undefined;
2751
- const discriminant = parent.get("discriminant");
2752
- const testPaths = parent.get("cases").map((casePath) => casePath.get("test"));
2753
- if (awaitPath !== discriminant &&
2754
- !(explicitExits.all &&
2755
- !testPaths.some((testPath) => testPath.node ? findAwaitOrYieldPath(testPath) !== undefined : false))) {
2756
- let resultIdentifier;
2757
- if (!explicitExits.all && explicitExits.any) {
2758
- resultIdentifier = path.scope.generateUidIdentifier("result");
2759
- addConstantNames(additionalConstantNames, resultIdentifier);
2760
- }
2761
- const caseNodes = types.arrayExpression(cases
2762
- ? cases.map((caseItem) => {
2763
- const args = [];
2764
- let consequent;
2765
- if (caseItem.casePath.node.consequent) {
2766
- const rewritten = rewriteAsyncNode(state.generatorState, parent, blockStatement(removeUnnecessaryReturnStatements(caseItem.casePath.node.consequent)), additionalConstantNames, exitIdentifier);
2767
- if (rewritten.body.length) {
2768
- consequent = functionize(pluginState, [], rewritten, targetPath);
2769
- }
2770
- }
2771
- if (caseItem.casePath.node.test) {
2772
- args.push(rewriteAsyncNode(state.generatorState, parent, functionize(pluginState, [], caseItem.casePath.node.test, targetPath), additionalConstantNames));
2773
- }
2774
- else if (consequent) {
2775
- args.push(voidExpression());
2776
- }
2777
- if (consequent) {
2778
- args.push(consequent);
2779
- if (!caseItem.caseExits.any && !caseItem.caseBreaks.any) {
2780
- args.push(emptyFunction(pluginState, parent));
2781
- }
2782
- else if (!(caseItem.caseExits.all || caseItem.caseBreaks.all)) {
2783
- const breakCheck = buildBreakExitCheck(pluginState, caseItem.caseExits.any ? exitIdentifier : undefined, caseItem.breakIdentifiers);
2784
- if (breakCheck) {
2785
- args.push(functionize(pluginState, [], types.blockStatement([returnStatement(breakCheck)]), targetPath));
2786
- }
2787
- }
2788
- }
2789
- return types.arrayExpression(args);
2790
- })
2791
- : []);
2792
- const switchCall = types.callExpression(helperReference(pluginState, parent, "_switch"), [
2793
- discriminant.node,
2794
- caseNodes,
2795
- ]);
2796
- relocateTail(state.generatorState, switchCall, undefined, label && parent.parentPath.isStatement() ? parent.parentPath : parent, additionalConstantNames, resultIdentifier, exitIdentifier, undefined, state.skipReturns);
2797
- processExpressions = false;
2798
- }
2799
- }
2800
- else if (parent.isLabeledStatement()) {
2801
- let resultIdentifier;
2802
- if (!explicitExits.all && explicitExits.any) {
2803
- resultIdentifier = path.scope.generateUidIdentifier("result");
2804
- addConstantNames(additionalConstantNames, resultIdentifier);
2805
- }
2806
- if (resultIdentifier || (breakIdentifiers && breakIdentifiers.length)) {
2807
- const filteredBreakIdentifiers = breakIdentifiers
2808
- ? breakIdentifiers.filter((id) => id.name !== parent.node.label.name)
2809
- : [];
2810
- const fn = functionize(pluginState, [], blockStatement(parent.node.body), targetPath);
2811
- const rewritten = rewriteAsyncNode(state.generatorState, parent, fn, additionalConstantNames, exitIdentifier);
2812
- const exitCheck = buildBreakExitCheck(pluginState, explicitExits.any ? exitIdentifier : undefined, filteredBreakIdentifiers);
2813
- relocateTail(state.generatorState, types.callExpression(rewritten, []), undefined, parent, additionalConstantNames, resultIdentifier, exitCheck, undefined, state.skipReturns);
2814
- processExpressions = false;
2815
- }
2816
- }
2817
- }
2818
- if (processExpressions) {
2819
- if (awaitPath.isAwaitExpression() || awaitPath.isYieldExpression()) {
2820
- const originalArgument = awaitPath.node.argument;
2821
- let parent = getStatementOrArrowBodyParent(awaitPath);
2822
- const { declarationKind, declarations, awaitExpression, directExpression, reusingExisting, resultIdentifier, } = extractDeclarations(pluginState, awaitPath, originalArgument || types.identifier("undefined"), additionalConstantNames);
2823
- if (resultIdentifier) {
2824
- addConstantNames(additionalConstantNames, resultIdentifier);
2825
- }
2826
- if (declarations.length) {
2827
- for (const { id } of declarations) {
2828
- addConstantNames(additionalConstantNames, id);
2829
- }
2830
- if (parent.parentPath.isBlockStatement()) {
2831
- reregisterDeclarations(parent.insertBefore(types.variableDeclaration(declarationKind, declarations)));
2832
- }
2833
- else {
2834
- parent.replaceWith(blockStatement([
2835
- types.variableDeclaration(declarationKind, declarations),
2836
- types.isStatement(parent.node) ? parent.node : returnStatement(parent.node),
2837
- ]));
2838
- const body = parent.get("body");
2839
- reregisterDeclarations(body[0]);
2840
- parent = body[1];
2841
- }
2842
- }
2843
- if (reusingExisting) {
2844
- if (types.isVariableDeclaration(reusingExisting.parent) &&
2845
- reusingExisting.parent.declarations.length === 1) {
2846
- reusingExisting.parentPath.replaceWith(types.emptyStatement());
2847
- }
2848
- else {
2849
- reusingExisting.remove();
2850
- }
2851
- }
2852
- const parentNode = parent.node;
2853
- relocateTail(state.generatorState, awaitPath.isYieldExpression()
2854
- ? yieldOnExpression(state.generatorState, awaitExpression)
2855
- : awaitExpression, types.isStatement(parentNode) ? parentNode : types.returnStatement(parentNode), parent, additionalConstantNames, resultIdentifier, undefined, awaitPath.isYieldExpression() ? undefined : directExpression, state.skipReturns);
2856
- }
2857
- }
2858
- }
2859
- const rewriteAsyncBlockVisitor = {
2860
- Function: skipNode,
2861
- AwaitExpression: rewriteAwaitOrYieldPath,
2862
- YieldExpression: rewriteAwaitOrYieldPath,
2863
- ForAwaitStatement: rewriteAwaitOrYieldPath,
2864
- ForOfStatement(path) {
2865
- if (path.node.await) {
2866
- rewriteAwaitOrYieldPath.call(this, path);
2867
- }
2868
- },
2869
- CallExpression(path) {
2870
- const callee = path.get("callee");
2871
- if (callee.isIdentifier() && callee.node.name === "eval") {
2872
- throw path.buildCodeFrameError("Calling eval from inside an async function is not supported!", TypeError);
2873
- }
2874
- },
2875
- };
2876
- const unpromisifyVisitor = {
2877
- Function: skipNode,
2878
- ReturnStatement(path) {
2879
- const argument = path.get("argument");
2880
- if (argument.node) {
2881
- unpromisify(argument, this);
2882
- }
2883
- },
2884
- };
2885
- function unpromisify(path, pluginState) {
2886
- if (path.isNumericLiteral() ||
2887
- path.isBooleanLiteral() ||
2888
- path.isStringLiteral() ||
2889
- path.isNullLiteral() ||
2890
- (path.isIdentifier() && path.node.name === "undefined") ||
2891
- path.isArrayExpression() ||
2892
- path.isObjectExpression() ||
2893
- path.isBinaryExpression() ||
2894
- path.isUnaryExpression() ||
2895
- path.isUpdateExpression()) {
2896
- return;
2897
- }
2898
- if (path.isCallExpression() &&
2899
- (types.isIdentifier(path.node.callee) || types.isMemberExpression(path.node.callee)) &&
2900
- helperNameMap.has(path.node.callee)) {
2901
- switch (helperNameMap.get(path.node.callee)) {
2902
- case "_await":
2903
- const args = path.get("arguments");
2904
- if (args.length > 0 && args[0].isExpression()) {
2905
- unpromisify(args[0], pluginState);
2906
- }
2907
- case "_call": {
2908
- const args = path.get("arguments");
2909
- if (args.length > 2) {
2910
- const secondArg = args[1];
2911
- if (types.isExpression(secondArg.node) && isContinuation(secondArg.node)) {
2912
- secondArg.traverse(unpromisifyVisitor, pluginState);
2913
- }
2914
- else if (secondArg.isIdentifier()) {
2915
- const binding = secondArg.scope.getBinding(secondArg.node.name);
2916
- if (binding && binding.path.isVariableDeclarator()) {
2917
- binding.path.get("init").traverse(unpromisifyVisitor, pluginState);
2918
- }
2919
- }
2920
- }
2921
- break;
2922
- }
2923
- case "_promiseThen": {
2924
- const args = path.get("arguments");
2925
- if (args.length > 2) {
2926
- const firstArg = args[1];
2927
- if (types.isExpression(firstArg.node) && isContinuation(firstArg.node)) {
2928
- firstArg.traverse(unpromisifyVisitor, pluginState);
2929
- }
2930
- else if (firstArg.isIdentifier()) {
2931
- const binding = firstArg.scope.getBinding(firstArg.node.name);
2932
- if (binding && binding.path.isVariableDeclarator()) {
2933
- binding.path.get("init").traverse(unpromisifyVisitor, pluginState);
2934
- }
2935
- }
2936
- }
2937
- break;
2938
- }
2939
- }
2940
- return;
2941
- }
2942
- if (path.isLogicalExpression()) {
2943
- unpromisify(path.get("left"), pluginState);
2944
- unpromisify(path.get("right"), pluginState);
2945
- return;
2946
- }
2947
- if (path.isConditionalExpression()) {
2948
- unpromisify(path.get("consequent"), pluginState);
2949
- unpromisify(path.get("alternate"), pluginState);
2950
- return;
2951
- }
2952
- if (path.isSequenceExpression()) {
2953
- const expressions = path.get("expressions");
2954
- if (expressions.length) {
2955
- unpromisify(expressions[expressions.length - 1], pluginState);
2956
- }
2957
- return;
2958
- }
2959
- const minify = readConfigKey(pluginState.opts, "minify");
2960
- path.replaceWith(logicalNot(logicalNot(path.node, minify), minify));
2961
- }
2962
- function rewriteAsyncBlock(generatorState, path, additionalConstantNames, exitIdentifier, shouldUnpromisify, skipReturns) {
2963
- path.traverse(rewriteAsyncBlockVisitor, {
2964
- generatorState,
2965
- path,
2966
- additionalConstantNames,
2967
- exitIdentifier,
2968
- skipReturns,
2969
- });
2970
- if (shouldUnpromisify) {
2971
- if (path.isArrowFunctionExpression()) {
2972
- const body = path.get("body");
2973
- if (body.isExpression()) {
2974
- unpromisify(body, generatorState.state);
2975
- }
2976
- }
2977
- else {
2978
- path.traverse(unpromisifyVisitor, generatorState.state);
2979
- }
2980
- }
2981
- }
2982
- function getFile(path) {
2983
- let hub = path.hub;
2984
- if ("file" in hub) {
2985
- return hub.file;
2986
- }
2987
- throw path.buildCodeFrameError("Expected the path's hub to contain a file!", TypeError);
2988
- }
2989
- const getHelperDependenciesVisitor = {
2990
- Identifier(path) {
2991
- if (identifierSearchesScope(path) &&
2992
- getFile(path).scope.getBinding(path.node.name) &&
2993
- this.dependencies.indexOf(path.node.name) === -1) {
2994
- this.dependencies.push(path.node.name);
2995
- }
2996
- },
2997
- };
2998
- function getHelperDependencies(path) {
2999
- const state = { dependencies: [] };
3000
- path.traverse(getHelperDependenciesVisitor, state);
3001
- return state.dependencies;
3002
- }
3003
- const usesIdentifierVisitor = {
3004
- Identifier(path) {
3005
- if (path.node.name === this.name) {
3006
- this.found = true;
3007
- path.stop();
3008
- }
3009
- },
3010
- };
3011
- function usesIdentifier(path, name) {
3012
- const state = { name, found: false };
3013
- path.traverse(usesIdentifierVisitor, state);
3014
- return state.found;
3015
- }
3016
- function insertHelper(programPath, value) {
3017
- const body = programPath.get("body");
3018
- const destinationPath = body.find((path) => !isHelperDefinitionSet.has(path.node) && !path.isImportDeclaration()) ||
3019
- body.find(() => true);
3020
- if (destinationPath.isVariableDeclaration()) {
3021
- const before = destinationPath
3022
- .get("declarations")
3023
- .filter((path) => isHelperDefinitionSet.has(path.node));
3024
- const after = destinationPath
3025
- .get("declarations")
3026
- .filter((path) => !isHelperDefinitionSet.has(path.node));
3027
- if (types.isVariableDeclaration(value)) {
3028
- const declaration = value.declarations[0];
3029
- isHelperDefinitionSet.add(declaration);
3030
- if (before.length === 0) {
3031
- const target = after[0];
3032
- reregisterDeclarations(target.insertBefore(declaration));
3033
- return getPreviousSibling(target);
3034
- }
3035
- else {
3036
- const target = before[before.length - 1];
3037
- reregisterDeclarations(target.insertAfter(declaration));
3038
- return getNextSibling(target);
3039
- }
3040
- }
3041
- else {
3042
- isHelperDefinitionSet.add(value);
3043
- if (before.length === 0) {
3044
- isHelperDefinitionSet.add(destinationPath.node);
3045
- reregisterDeclarations(destinationPath.insertBefore(value));
3046
- return getPreviousSibling(destinationPath);
3047
- }
3048
- else if (after.length === 0) {
3049
- isHelperDefinitionSet.add(destinationPath.node);
3050
- reregisterDeclarations(destinationPath.insertAfter(value));
3051
- return getNextSibling(destinationPath);
3052
- }
3053
- else {
3054
- const beforeNode = types.variableDeclaration(destinationPath.node.kind, before.map((path) => path.node));
3055
- isHelperDefinitionSet.add(beforeNode);
3056
- const afterNode = types.variableDeclaration(destinationPath.node.kind, after.map((path) => path.node));
3057
- destinationPath.replaceWith(afterNode);
3058
- reregisterDeclarations(destinationPath);
3059
- reregisterDeclarations(destinationPath.insertBefore(beforeNode));
3060
- reregisterDeclarations(destinationPath.insertBefore(value));
3061
- return getPreviousSibling(destinationPath);
3062
- }
3063
- }
3064
- }
3065
- else {
3066
- if (types.isVariableDeclaration(value)) {
3067
- isHelperDefinitionSet.add(value.declarations[0]);
3068
- }
3069
- else {
3070
- isHelperDefinitionSet.add(value);
3071
- }
3072
- const oldNode = destinationPath.node;
3073
- destinationPath.replaceWith(value);
3074
- reregisterDeclarations(destinationPath);
3075
- reregisterDeclarations(destinationPath.insertAfter(oldNode));
3076
- return destinationPath;
3077
- }
3078
- }
3079
- function helperReference(state, path, name) {
3080
- const file = getFile(path);
3081
- let result = file.declarations[name];
3082
- if (result) {
3083
- result = cloneNode(result);
3084
- }
3085
- else {
3086
- result = file.declarations[name] = usesIdentifier(file.path, name)
3087
- ? file.path.scope.generateUidIdentifier(name)
3088
- : types.identifier(name);
3089
- helperNameMap.set(result, name);
3090
- if (readConfigKey(state.opts, "externalHelpers")) {
3091
- file.path.unshiftContainer("body", types.importDeclaration([types.importSpecifier(result, types.identifier(name))], types.stringLiteral("babel-plugin-transform-async-to-promises/helpers")));
3092
- }
3093
- else {
3094
- if (!helpers) {
3095
- const newHelpers = {};
3096
- const plugins = [
3097
- {
3098
- visitor: {
3099
- ExportNamedDeclaration(path) {
3100
- const declaration = path.get("declaration");
3101
- if (declaration.isFunctionDeclaration()) {
3102
- const id = declaration.node.id;
3103
- if (!types.isIdentifier(id)) {
3104
- throw declaration.buildCodeFrameError(`Expected a named declaration!`, TypeError);
3105
- }
3106
- newHelpers[id.name] = {
3107
- value: declaration.node,
3108
- dependencies: getHelperDependencies(declaration),
3109
- };
3110
- return;
3111
- }
3112
- if (declaration.isVariableDeclaration() &&
3113
- declaration.node.declarations.length === 1) {
3114
- const declaratorId = declaration.node.declarations[0].id;
3115
- if (types.isIdentifier(declaratorId)) {
3116
- newHelpers[declaratorId.name] = {
3117
- value: declaration.node,
3118
- dependencies: getHelperDependencies(declaration),
3119
- };
3120
- return;
3121
- }
3122
- }
3123
- throw path.buildCodeFrameError("Expected a named export from built-in helper!", TypeError);
3124
- },
3125
- },
3126
- },
3127
- ];
3128
- const helperAst = require(isNewBabel ? "@babel/core" : "babylon").parse(helpers_string_1, {
3129
- sourceType: "module",
3130
- filename: "helpers.js",
3131
- });
3132
- if (isNewBabel) {
3133
- transformFromAst(helperAst, helpers_string_1, {
3134
- babelrc: false,
3135
- configFile: false,
3136
- plugins,
3137
- });
3138
- }
3139
- else {
3140
- transformFromAst(helperAst, helpers_string_1, {
3141
- babelrc: false,
3142
- plugins,
3143
- });
3144
- }
3145
- helpers = newHelpers;
3146
- }
3147
- const helper = helpers[name];
3148
- for (const dependency of helper.dependencies) {
3149
- helperReference(state, path, dependency);
3150
- }
3151
- const usedHelpers = state.usedHelpers || (state.usedHelpers = {});
3152
- usedHelpers[name] = true;
3153
- }
3154
- }
3155
- return result;
3156
- }
3157
- function emptyFunction(state, path) {
3158
- return readConfigKey(state.opts, "inlineHelpers")
3159
- ? functionize(state, [], blockStatement([]), path)
3160
- : helperReference(state, path, "_empty");
3161
- }
3162
- function promiseResolve() {
3163
- const result = types.memberExpression(types.identifier("Promise"), types.identifier("resolve"));
3164
- helperNameMap.set(result, "_promiseResolve");
3165
- return result;
3166
- }
3167
- function callThenMethod(value, continuation) {
3168
- const thenExpression = types.memberExpression(value, types.identifier("then"));
3169
- helperNameMap.set(thenExpression, "_promiseThen");
3170
- return types.callExpression(thenExpression, [continuation]);
3171
- }
3172
- function isAsyncCallExpression(path) {
3173
- if (types.isIdentifier(path.node.callee) || types.isMemberExpression(path.node.callee)) {
3174
- switch (helperNameMap.get(path.node.callee)) {
3175
- case "_await":
3176
- case "_call":
3177
- case "_promiseResolve":
3178
- case "_promiseThen":
3179
- return path.node.arguments.length < 3;
3180
- }
3181
- }
3182
- return false;
3183
- }
3184
- function invokeTypeOfExpression(path) {
3185
- if (path.isCallExpression() && types.isIdentifier(path.node.callee)) {
3186
- const helperName = helperNameMap.get(path.node.callee);
3187
- switch (helperName) {
3188
- case "_invoke":
3189
- case "_invokeIgnored":
3190
- case "_catch":
3191
- case "_catchInGenerator":
3192
- case "_finally":
3193
- case "_finallyRethrows":
3194
- return helperName;
3195
- }
3196
- }
3197
- }
3198
- function isAsyncFunctionExpression(path) {
3199
- if (path.isFunction() && (path.node.async || nodeIsAsyncSet.has(path.node))) {
3200
- return true;
3201
- }
3202
- if (path.isCallExpression() &&
3203
- types.isIdentifier(path.node.callee) &&
3204
- helperNameMap.get(path.node.callee) === "_async") {
3205
- return true;
3206
- }
3207
- return false;
3208
- }
3209
- function isAsyncFunctionIdentifier(path) {
3210
- if (path.isIdentifier()) {
3211
- const binding = path.scope.getBinding(path.node.name);
3212
- if (binding && binding.constant) {
3213
- const bindingPath = binding.path;
3214
- if (bindingPath.isVariableDeclarator()) {
3215
- const initPath = bindingPath.get("init");
3216
- if (initPath.node && isAsyncFunctionExpression(initPath)) {
3217
- return true;
3218
- }
3219
- }
3220
- else if (bindingPath.isFunctionDeclaration()) {
3221
- if (isAsyncFunctionExpression(bindingPath)) {
3222
- return true;
3223
- }
3224
- }
3225
- }
3226
- }
3227
- return false;
3228
- }
3229
- function isEvalOrArguments(path) {
3230
- return path.isIdentifier() && (path.node.name === "arguments" || path.node.name === "eval");
3231
- }
3232
- function identifierSearchesScope(path) {
3233
- if (path.node.name === "undefined") {
3234
- return false;
3235
- }
3236
- if (helperNameMap.has(path.node)) {
3237
- return false;
3238
- }
3239
- const parent = path.parentPath;
3240
- if (parent.isVariableDeclarator() && parent.get("id") === path) {
3241
- return false;
3242
- }
3243
- if (parent.isMemberExpression() && !parent.node.computed && parent.get("property") === path) {
3244
- return false;
3245
- }
3246
- if (parent.isLabeledStatement() && parent.get("label") === path) {
3247
- return false;
3248
- }
3249
- if (parent.isFunction() && parent.get("params").indexOf(path) !== -1) {
3250
- return false;
3251
- }
3252
- return true;
3253
- }
3254
- function canThrow() {
3255
- this.canThrow = true;
3256
- }
3257
- function promiseCallExpressionType(expression) {
3258
- if (types.isMemberExpression(expression.callee)) {
3259
- if (types.isIdentifier(expression.callee.object) &&
3260
- expression.callee.object.name === "Promise" &&
3261
- types.isIdentifier(expression.callee.property)) {
3262
- switch (expression.callee.property.name) {
3263
- case "all":
3264
- case "race":
3265
- case "reject":
3266
- case "resolve":
3267
- return expression.callee.property.name;
3268
- }
3269
- }
3270
- else if (types.isCallExpression(expression.callee.object) &&
3271
- types.isIdentifier(expression.callee.property)) {
3272
- switch (expression.callee.property.name) {
3273
- case "then":
3274
- case "catch":
3275
- case "finally":
3276
- if (typeof promiseCallExpressionType(expression.callee.object) !== "undefined") {
3277
- return expression.callee.property.name;
3278
- }
3279
- break;
3280
- }
3281
- }
3282
- }
3283
- return undefined;
3284
- }
3285
- const checkForErrorsAndRewriteReturnsVisitor = {
3286
- Function: skipNode,
3287
- ThrowStatement: canThrow,
3288
- ForInStatement: canThrow,
3289
- ForOfStatement: canThrow,
3290
- WithStatement: canThrow,
3291
- NewExpression: canThrow,
3292
- TryStatement(path) {
3293
- if (path.get("handler")) {
3294
- path.get("block").skip();
3295
- }
3296
- },
3297
- CallExpression(path) {
3298
- if (!isAsyncCallExpression(path)) {
3299
- const args = path.get("arguments");
3300
- switch (invokeTypeOfExpression(path)) {
3301
- default:
3302
- if (checkForErrorsAndRewriteReturns(args[0], this.plugin)) {
3303
- this.canThrow = true;
3304
- }
3305
- case "_catch":
3306
- case "_catchInGenerator":
3307
- case "_finally":
3308
- case "_finallyRethrows":
3309
- if (args[1]) {
3310
- if (checkForErrorsAndRewriteReturns(args[1], this.plugin)) {
3311
- this.canThrow = true;
3312
- }
3313
- }
3314
- break;
3315
- case undefined: {
3316
- const callee = path.get("callee");
3317
- if (!isAsyncFunctionIdentifier(callee)) {
3318
- this.canThrow = true;
3319
- }
3320
- }
3321
- }
3322
- }
3323
- },
3324
- UpdateExpression(path) {
3325
- if (isEvalOrArguments(path.get("argument"))) {
3326
- this.canThrow = true;
3327
- }
3328
- },
3329
- UnaryExpression(path) {
3330
- switch (path.node.operator) {
3331
- case "delete":
3332
- this.canThrow = true;
3333
- break;
3334
- }
3335
- },
3336
- BinaryExpression(path) {
3337
- switch (path.node.operator) {
3338
- case "instanceof":
3339
- case "in":
3340
- this.canThrow = true;
3341
- break;
3342
- }
3343
- },
3344
- Identifier(path) {
3345
- if (identifierSearchesScope(path) &&
3346
- !path.scope.getBinding(path.node.name) &&
3347
- alwaysTruthy.indexOf(path.node.name) === -1) {
3348
- this.canThrow = true;
3349
- }
3350
- },
3351
- MemberExpression(path) {
3352
- if (helperNameMap.get(path.node) !== "_await" &&
3353
- !(path.parentPath.isCallExpression() &&
3354
- promiseCallExpressionType(path.parentPath.node) !== undefined &&
3355
- path.parentPath.get("callee") === path)) {
3356
- const propertyName = propertyNameOfMemberExpression(path.node);
3357
- if (propertyName !== undefined) {
3358
- const object = path.get("object");
3359
- if (object.isIdentifier() &&
3360
- Object.hasOwnProperty.call(constantStaticMethods, object.node.name) &&
3361
- Object.hasOwnProperty.call(constantStaticMethods[object.node.name], propertyName)) {
3362
- return;
3363
- }
3364
- }
3365
- this.canThrow = true;
3366
- }
3367
- },
3368
- AssignmentExpression(path) {
3369
- if (isEvalOrArguments(path.get("left"))) {
3370
- this.canThrow = true;
3371
- }
3372
- },
3373
- ReturnStatement(path) {
3374
- if (this.rewriteReturns) {
3375
- const argument = path.get("argument");
3376
- if (argument && argument.node) {
3377
- let arg = argument.node;
3378
- if (!((argument.isCallExpression() &&
3379
- (isAsyncCallExpression(argument) ||
3380
- typeof promiseCallExpressionType(argument.node) !== "undefined")) ||
3381
- (argument.isCallExpression() && isAsyncFunctionIdentifier(argument.get("callee"))))) {
3382
- const target = readConfigKey(this.plugin.opts, "inlineHelpers")
3383
- ? promiseResolve()
3384
- : helperReference(this.plugin, path, "_await");
3385
- if (types.isConditionalExpression(arg) && types.isIdentifier(arg.test)) {
3386
- if (types.isCallExpression(arg.consequent) &&
3387
- promiseCallExpressionType(arg.consequent) === "resolve" &&
3388
- arg.consequent.arguments.length === 1 &&
3389
- nodesAreEquivalent(arg.consequent.arguments[0])(arg.alternate)) {
3390
- arg = arg.alternate;
3391
- }
3392
- else if (types.isCallExpression(arg.alternate) &&
3393
- promiseCallExpressionType(arg.alternate) === "resolve" &&
3394
- arg.alternate.arguments.length === 1 &&
3395
- nodesAreEquivalent(arg.alternate.arguments[0])(arg.consequent)) {
3396
- arg = arg.consequent;
3397
- }
3398
- }
3399
- if (types.isConditionalExpression(arg) &&
3400
- types.isCallExpression(arg.consequent) &&
3401
- promiseCallExpressionType(arg.consequent) === "resolve") {
3402
- const consequent = arg.consequent.arguments[0];
3403
- if (consequent && types.isExpression(consequent)) {
3404
- arg = conditionalExpression(arg.test, consequent, arg.alternate);
3405
- }
3406
- }
3407
- if (types.isConditionalExpression(arg) &&
3408
- types.isCallExpression(arg.alternate) &&
3409
- promiseCallExpressionType(arg.alternate) === "resolve") {
3410
- const alternate = arg.alternate.arguments[0];
3411
- if (alternate && types.isExpression(alternate)) {
3412
- arg = conditionalExpression(arg.test, arg.consequent, alternate);
3413
- }
3414
- }
3415
- if (types.isConditionalExpression(arg) && types.isIdentifier(arg.test)) {
3416
- if (types.isIdentifier(arg.consequent) && arg.test.name === arg.consequent.name) {
3417
- if (types.isIdentifier(arg.alternate) && arg.test.name === arg.alternate.name) {
3418
- arg = arg.test;
3419
- }
3420
- else {
3421
- arg = types.logicalExpression("||", arg.consequent, arg.alternate);
3422
- }
3423
- }
3424
- else if (types.isIdentifier(arg.alternate) && arg.test.name === arg.alternate.name) {
3425
- arg = types.logicalExpression("&&", arg.alternate, arg.consequent);
3426
- }
3427
- }
3428
- argument.replaceWith(types.callExpression(target, [arg]));
3429
- }
3430
- }
3431
- else {
3432
- const target = readConfigKey(this.plugin.opts, "inlineHelpers")
3433
- ? promiseResolve()
3434
- : helperReference(this.plugin, path, "_await");
3435
- argument.replaceWith(types.callExpression(target, []));
3436
- }
3437
- }
3438
- },
3439
- };
3440
- function checkForErrorsAndRewriteReturns(path, plugin, rewriteReturns = false) {
3441
- const state = { rewriteReturns, plugin, canThrow: false };
3442
- path.traverse(checkForErrorsAndRewriteReturnsVisitor, state);
3443
- return state.canThrow;
3444
- }
3445
- const rewriteTopLevelReturnsVisitor = {
3446
- Function: skipNode,
3447
- ReturnStatement(path) {
3448
- const argument = path.get("argument");
3449
- if (argument.isCallExpression()) {
3450
- const callArgs = argument.node.arguments;
3451
- switch (callArgs.length) {
3452
- case 3:
3453
- case 2: {
3454
- const secondArgument = callArgs[1];
3455
- if (!types.isUnaryExpression(secondArgument) || secondArgument.operator !== "void") {
3456
- break;
3457
- }
3458
- }
3459
- case 1:
3460
- if (types.isIdentifier(argument.node.callee) ||
3461
- types.isMemberExpression(argument.node.callee)) {
3462
- const firstArgument = callArgs[0];
3463
- if (types.isExpression(firstArgument)) {
3464
- switch (helperNameMap.get(argument.node.callee)) {
3465
- case "_promiseResolve":
3466
- case "_await":
3467
- argument.replaceWith(firstArgument);
3468
- break;
3469
- case "_call":
3470
- argument.replaceWith(types.callExpression(firstArgument, []));
3471
- break;
3472
- }
3473
- }
3474
- }
3475
- break;
3476
- }
3477
- }
3478
- },
3479
- };
3480
- function reorderPathBeforeSiblingStatements(targetPath) {
3481
- for (const sibling of targetPath.getAllPrevSiblings().reverse()) {
3482
- if (!sibling.isFunctionDeclaration() && !sibling.isImportDeclaration()) {
3483
- const newNode = targetPath.node;
3484
- targetPath.remove();
3485
- reregisterDeclarations(sibling.insertBefore(newNode));
3486
- return;
3487
- }
3488
- }
3489
- }
3490
- function reregisterDeclarations(pathOrPaths) {
3491
- if (Array.isArray(pathOrPaths)) {
3492
- for (const path of pathOrPaths) {
3493
- reregisterDeclarations(path);
3494
- }
3495
- }
3496
- else if (pathOrPaths && pathOrPaths.isLabeledStatement) {
3497
- const scope = pathOrPaths.isFunction() ? pathOrPaths.parentPath.scope : pathOrPaths.scope;
3498
- if (pathOrPaths.isVariableDeclaration() ||
3499
- pathOrPaths.isFunctionDeclaration() ||
3500
- pathOrPaths.isClassDeclaration()) {
3501
- scope.registerDeclaration(pathOrPaths);
3502
- }
3503
- pathOrPaths.traverse(reregisterVariableVisitor, { originalScope: pathOrPaths.scope });
3504
- }
3505
- }
3506
- function getPreviousSibling(targetPath) {
3507
- const siblings = targetPath.getAllPrevSiblings();
3508
- return siblings.length !== 0 ? siblings[siblings.length - 1] : undefined;
3509
- }
3510
- function getNextSibling(targetPath) {
3511
- const siblings = targetPath.getAllNextSiblings();
3512
- return siblings.length !== 0 ? siblings[0] : undefined;
3513
- }
3514
- function rewriteDefaultArguments(targetPath) {
3515
- const statements = [];
3516
- const params = targetPath.get("params");
3517
- const literals = [];
3518
- for (let i = 0; i < params.length; i++) {
3519
- const param = params[i];
3520
- if (param.isAssignmentPattern()) {
3521
- const init = param.get("right");
3522
- if (!isExpressionOfLiterals(init, literals)) {
3523
- const left = param.get("left");
3524
- let id;
3525
- let after;
3526
- if (left.isIdentifier()) {
3527
- id = left.node;
3528
- }
3529
- else {
3530
- id = left.scope.generateUidIdentifier(`arg${i}`);
3531
- after = types.variableDeclaration("let", [types.variableDeclarator(left.node, id)]);
3532
- }
3533
- const initNode = init.node;
3534
- param.replaceWith(id);
3535
- const isMissing = types.binaryExpression("===", id, types.identifier("undefined"));
3536
- const assignment = types.expressionStatement(types.assignmentExpression("=", id, initNode));
3537
- statements.push(types.ifStatement(isMissing, assignment));
3538
- if (after) {
3539
- statements.push(after);
3540
- }
3541
- }
3542
- }
3543
- else if (param.isIdentifier()) {
3544
- literals.push(param.node.name);
3545
- }
3546
- }
3547
- if (statements.length) {
3548
- targetPath.node.body.body = statements.concat(targetPath.node.body.body);
3549
- }
3550
- }
3551
- const unwrapReturnPromiseVisitor = {
3552
- ReturnStatement(path) {
3553
- const argument = path.get("argument");
3554
- if (argument.isCallExpression()) {
3555
- switch (promiseCallExpressionType(argument.node)) {
3556
- case "all":
3557
- case "race":
3558
- case "resolve":
3559
- switch (argument.node.arguments.length) {
3560
- case 0:
3561
- path.replaceWith(types.returnStatement());
3562
- break;
3563
- case 1:
3564
- const arg0 = argument.node.arguments[0];
3565
- if (types.isExpression(arg0)) {
3566
- path.replaceWith(types.returnStatement(arg0));
3567
- }
3568
- break;
3569
- }
3570
- break;
3571
- }
3572
- }
3573
- },
3574
- };
3575
- const findAwaitExpressionVisitor = {
3576
- AwaitExpression(path) {
3577
- this.awaitPath = path;
3578
- path.stop();
3579
- },
3580
- };
3581
- return {
3582
- name: "transform-async-to-promises",
3583
- manipulateOptions(_options, parserOptions) {
3584
- parserOptions.plugins.push("asyncGenerators");
3585
- },
3586
- visitor: {
3587
- AwaitExpression(path) {
3588
- if (!path.getFunctionParent() && !this.hasTopLevelAwait) {
3589
- this.hasTopLevelAwait = true;
3590
- }
3591
- },
3592
- ImportDeclaration: {
3593
- exit(path) {
3594
- if (this.hasTopLevelAwait && readConfigKey(this.opts, "topLevelAwait") === "simple") {
3595
- throw path.buildCodeFrameError(`Cannot import after a top-level await when using topLevelAwait: "simple"!`, TypeError);
3596
- }
3597
- },
3598
- },
3599
- ExportDeclaration: {
3600
- exit(path) {
3601
- if (this.hasTopLevelAwait && readConfigKey(this.opts, "topLevelAwait") === "simple") {
3602
- throw path.buildCodeFrameError(`Cannot export after a top-level await when using topLevelAwait: "simple"!`, TypeError);
3603
- }
3604
- },
3605
- },
3606
- Program: {
3607
- exit(path) {
3608
- if (this.hasTopLevelAwait) {
3609
- let rediscoverState = {};
3610
- path.traverse(findAwaitExpressionVisitor, rediscoverState);
3611
- if (rediscoverState.awaitPath !== undefined) {
3612
- const functionParent = rediscoverState.awaitPath.getFunctionParent();
3613
- const topLevelAwaitParent = functionParent ? functionParent.get("body") : path;
3614
- switch (readConfigKey(this.opts, "topLevelAwait")) {
3615
- case "simple": {
3616
- rewriteAsyncBlock({ state: this }, topLevelAwaitParent, [], undefined, false, true);
3617
- break;
3618
- }
3619
- case "return": {
3620
- helperReference(this, path, '_async')
3621
- rewriteAsyncBlock({ state: this }, topLevelAwaitParent, [], undefined, false, false);
3622
- break;
3623
- }
3624
- case "ignore":
3625
- break;
3626
- default:
3627
- throw rediscoverState.awaitPath.buildCodeFrameError(`Top level await is not supported unless experimental topLevelAwait: "simple" or topLevelAwait: "return" options are specified!`, TypeError);
3628
- }
3629
- }
3630
- }
3631
- const usedHelpers = this.usedHelpers;
3632
-
3633
-
3634
- if (usedHelpers !== undefined) {
3635
- const file = getFile(path);
3636
- for (const helperName of Object.keys(usedHelpers)) {
3637
- const helper = helpers[helperName];
3638
- const value = cloneNode(helper.value);
3639
- const newPath = insertHelper(file.path, value);
3640
- newPath.traverse({
3641
- Identifier(identifierPath) {
3642
- const name = identifierPath.node.name;
3643
- if (Object.hasOwnProperty.call(helpers, name)) {
3644
- identifierPath.replaceWith(file.declarations[name]);
3645
- }
3646
- },
3647
- });
3648
- }
3649
- }
3650
- },
3651
- },
3652
- FunctionDeclaration(path) {
3653
- if (!readConfigKey(this.opts, 'asyncAwait')) {
3654
- return
3655
- }
3656
- const node = path.node;
3657
- if (node.async) {
3658
- const expression = types.functionExpression(undefined, node.params, node.body, node.generator, node.async);
3659
- if (node.id === null || node.id === undefined) {
3660
- path.replaceWith(expression);
3661
- reregisterDeclarations(path);
3662
- return;
3663
- }
3664
- const declarators = [types.variableDeclarator(node.id, expression)];
3665
- if (path.parentPath.isExportDeclaration()) {
3666
- if (path.parentPath.isExportDefaultDeclaration()) {
3667
- const targetPath = path.parentPath;
3668
- targetPath.replaceWith(types.variableDeclaration("const", declarators));
3669
- reregisterDeclarations(targetPath);
3670
- reregisterDeclarations(targetPath.insertAfter(types.exportDefaultDeclaration(node.id)));
3671
- reorderPathBeforeSiblingStatements(targetPath);
3672
- }
3673
- else {
3674
- path.replaceWith(types.variableDeclaration("const", declarators));
3675
- reregisterDeclarations(path);
3676
- reorderPathBeforeSiblingStatements(path.parentPath);
3677
- }
3678
- }
3679
- else {
3680
- path.replaceWith(types.variableDeclaration("const", declarators));
3681
- reregisterDeclarations(path);
3682
- reorderPathBeforeSiblingStatements(path);
3683
- }
3684
- }
3685
- },
3686
- ArrowFunctionExpression(path) {
3687
- if (!readConfigKey(this.opts, 'asyncAwait')) {
3688
- return
3689
- }
3690
- const node = path.node;
3691
- if (node.async) {
3692
- rewriteThisExpressions(path, path.getFunctionParent() || path.scope.getProgramParent().path);
3693
- const body = types.isBlockStatement(path.node.body)
3694
- ? path.node.body
3695
- : blockStatement([types.returnStatement(path.node.body)]);
3696
- path.replaceWith(types.functionExpression(undefined, node.params, body, false, node.async));
3697
- reregisterDeclarations(path);
3698
- }
3699
- },
3700
- FunctionExpression(path) {
3701
- if (!readConfigKey(this.opts, 'asyncAwait')) {
3702
- return
3703
- }
3704
- if (path.node.async) {
3705
- const id = path.node.id;
3706
- if (path.parentPath.isExportDefaultDeclaration() && id !== null && id !== undefined) {
3707
- const targetPath = path.parentPath;
3708
- targetPath.replaceWith(types.variableDeclaration("const", [
3709
- types.variableDeclarator(id, types.functionExpression(undefined, path.node.params, path.node.body, path.node.generator, path.node.async)),
3710
- ]));
3711
- reregisterDeclarations(targetPath);
3712
- reregisterDeclarations(targetPath.insertAfter(types.exportDefaultDeclaration(id)));
3713
- reorderPathBeforeSiblingStatements(targetPath);
3714
- return;
3715
- }
3716
- rewriteDefaultArguments(path);
3717
- rewriteThisArgumentsAndHoistFunctions(path, path, false);
3718
- const bodyPath = path.get("body");
3719
- if (path.node.generator) {
3720
- const generatorIdentifier = path.scope.generateUidIdentifier("generator");
3721
- path.scope.push({ kind: "const", id: generatorIdentifier, unique: true });
3722
- const generatorBinding = path.scope.getBinding(generatorIdentifier.name);
3723
- if (typeof generatorBinding === "undefined") {
3724
- throw path.buildCodeFrameError(`Could not find newly created binding for ${generatorIdentifier.name}!`, Error);
3725
- }
3726
- rewriteAsyncBlock({ state: this, generatorIdentifier }, bodyPath, []);
3727
- generatorBinding.path.remove();
3728
- path.replaceWith(functionize(this, path.node.params, types.newExpression(helperReference(this, path, "_AsyncGenerator"), [
3729
- functionize(this, [generatorIdentifier], bodyPath.node, path),
3730
- ]), path, id));
3731
- }
3732
- else {
3733
- rewriteAsyncBlock({ state: this }, path, []);
3734
- const inlineHelpers = readConfigKey(this.opts, "inlineHelpers");
3735
- const canThrow = checkForErrorsAndRewriteReturns(bodyPath, this, inlineHelpers || (id !== null && id !== undefined));
3736
- const parentPath = path.parentPath;
3737
- const skipReturn = parentPath.isCallExpression() &&
3738
- parentPath.node.callee === path.node &&
3739
- parentPath.parentPath.isExpressionStatement();
3740
- if (!skipReturn && !pathsReturnOrThrowCurrentNodes(bodyPath).all) {
3741
- const awaitHelper = inlineHelpers
3742
- ? promiseResolve()
3743
- : helperReference(this, path, "_await");
3744
- path.node.body.body.push(types.returnStatement(types.callExpression(awaitHelper, [])));
3745
- }
3746
- if (skipReturn) {
3747
- path.traverse(unwrapReturnPromiseVisitor);
3748
- }
3749
- if (canThrow) {
3750
- if (inlineHelpers || id) {
3751
- if (!id &&
3752
- skipReturn &&
3753
- parentPath.isCallExpression() &&
3754
- parentPath.node.arguments.length === 0 &&
3755
- !pathsReturn(bodyPath).any) {
3756
- parentPath.parentPath.replaceWith(types.tryStatement(bodyPath.node, types.catchClause(types.identifier("e"), blockStatement([
3757
- types.expressionStatement(types.callExpression(types.memberExpression(types.identifier("Promise"), types.identifier("reject")), [types.identifier("e")])),
3758
- ]))));
3759
- }
3760
- else {
3761
- path.replaceWith(functionize(this, path.node.params, blockStatement(types.tryStatement(bodyPath.node, types.catchClause(types.identifier("e"), blockStatement([
3762
- (skipReturn
3763
- ? types.expressionStatement
3764
- : types.returnStatement)(types.callExpression(types.memberExpression(types.identifier("Promise"), types.identifier("reject")), [types.identifier("e")])),
3765
- ])))), path, id));
3766
- }
3767
- }
3768
- else {
3769
- bodyPath.traverse(rewriteTopLevelReturnsVisitor);
3770
- path.replaceWith(types.callExpression(helperReference(this, path, "_async"), [
3771
- functionize(this, path.node.params, bodyPath.node, path),
3772
- ]));
3773
- }
3774
- }
3775
- else {
3776
- if (!inlineHelpers) {
3777
- checkForErrorsAndRewriteReturns(bodyPath, this, true);
3778
- }
3779
- path.replaceWith(functionize(this, path.node.params, bodyPath.node, path, id));
3780
- }
3781
- }
3782
- nodeIsAsyncSet.add(path.node);
3783
- }
3784
- },
3785
- ClassMethod(path) {
3786
- if (!readConfigKey(this.opts, 'asyncAwait')) {
3787
- return
3788
- }
3789
- if (path.node.async) {
3790
- const body = path.get("body");
3791
- if (path.node.kind === "method") {
3792
- rewriteDefaultArguments(path);
3793
- body.replaceWith(types.blockStatement([body.node]));
3794
- const target = body.get("body")[0];
3795
- if (!target.isBlockStatement()) {
3796
- throw path.buildCodeFrameError(`Expected a BlockStatement, got a ${target.type}`, TypeError);
3797
- }
3798
- if (path.node.generator) {
3799
- const generatorIdentifier = target.scope.generateUidIdentifier("generator");
3800
- target.scope.push({
3801
- kind: "const",
3802
- id: generatorIdentifier,
3803
- init: generatorIdentifier,
3804
- unique: true,
3805
- });
3806
- const generatorBinding = target.scope.getBinding(generatorIdentifier.name);
3807
- if (typeof generatorBinding === "undefined") {
3808
- throw path.buildCodeFrameError(`Could not find newly created binding for ${generatorIdentifier.name}!`, Error);
3809
- }
3810
- rewriteAsyncBlock({ state: this, generatorIdentifier }, target, []);
3811
- generatorBinding.path.remove();
3812
- target.replaceWith(types.returnStatement(types.newExpression(helperReference(this, path, "_AsyncGenerator"), [
3813
- functionize(this, [generatorIdentifier], target.node, target),
3814
- ])));
3815
- }
3816
- else {
3817
- const inlineHelpers = readConfigKey(this.opts, "inlineHelpers");
3818
- rewriteThisArgumentsAndHoistFunctions(target, inlineHelpers ? target : body, true);
3819
- rewriteAsyncBlock({ state: this }, target, []);
3820
- const statements = target.get("body");
3821
- const lastStatement = statements[statements.length - 1];
3822
- if (!lastStatement || !lastStatement.isReturnStatement()) {
3823
- const awaitHelper = inlineHelpers
3824
- ? promiseResolve()
3825
- : helperReference(this, path, "_await");
3826
- target.node.body.push(types.returnStatement(types.callExpression(awaitHelper, [])));
3827
- }
3828
- const canThrow = checkForErrorsAndRewriteReturns(body, this, true);
3829
- if (!canThrow) {
3830
- target.replaceWithMultiple(target.node.body);
3831
- }
3832
- else if (inlineHelpers) {
3833
- target.replaceWith(types.tryStatement(target.node, types.catchClause(types.identifier("e"), blockStatement([
3834
- types.returnStatement(types.callExpression(types.memberExpression(types.identifier("Promise"), types.identifier("reject")), [types.identifier("e")])),
3835
- ]))));
3836
- }
3837
- else {
3838
- target.replaceWith(types.returnStatement(types.callExpression(helperReference(this, path, "_call"), [
3839
- functionize(this, [], target.node, path),
3840
- ])));
3841
- }
3842
- }
3843
- }
3844
- path.replaceWith(types.classMethod(path.node.kind, path.node.key, path.node.params, path.node.body, path.node.computed, path.node.static));
3845
- }
3846
- },
3847
- ObjectMethod(path) {
3848
- if (!readConfigKey(this.opts, 'asyncAwait')) {
3849
- return
3850
- }
3851
- if (path.node.async) {
3852
- if (path.node.kind === "method") {
3853
- path.replaceWith(types.objectProperty(path.node.key, types.functionExpression(undefined, path.node.params, path.node.body, path.node.generator, path.node.async), path.node.computed, false, path.node.decorators));
3854
- }
3855
- }
3856
- },
3857
- },
3858
- };
3859
- }
3860
- export default default_1;