UNPKG

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