@jsenv/core 36.1.1 → 36.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import { pathToFileURL, fileURLToPath } from "node:url";
2
- import { chmod, stat, lstat, readdir, promises, unlink, openSync, closeSync, rmdir, readFileSync as readFileSync$1, watch, readdirSync, statSync, writeFileSync as writeFileSync$1, mkdirSync, createReadStream, readFile, existsSync, realpathSync } from "node:fs";
2
+ import { chmod, stat, lstat, readdir, promises, unlink, openSync, closeSync, rmdir, watch, readdirSync, statSync, writeFileSync as writeFileSync$1, mkdirSync, createReadStream, readFile, existsSync, readFileSync, realpathSync } from "node:fs";
3
3
  import crypto, { createHash } from "node:crypto";
4
4
  import { extname } from "node:path";
5
5
  import process$1 from "node:process";
@@ -14,10 +14,10 @@ import { Readable, Stream, Writable } from "node:stream";
14
14
  import { Http2ServerResponse } from "node:http2";
15
15
  import { lookup } from "node:dns";
16
16
  import { SOURCEMAP, generateSourcemapFileUrl, composeTwoSourcemaps, generateSourcemapDataUrl, createMagicSource } from "@jsenv/sourcemap";
17
- import { parseHtmlString, visitHtmlNodes, getHtmlNodeAttribute, analyzeScriptNode, stringifyHtmlAst, parseSrcSet, getHtmlNodeText, setHtmlNodeAttributes, getHtmlNodePosition, getHtmlNodeAttributePosition, removeHtmlNodeText, setHtmlNodeText, parseCssUrls, parseJsUrls, applyBabelPlugins, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, findHtmlNode, removeHtmlNode, injectJsImport, analyzeLinkNode, injectHtmlNode, insertHtmlNodeAfter } from "@jsenv/ast";
18
- import { createRequire } from "node:module";
19
- import babelParser from "@babel/parser";
17
+ import { parseHtmlString, visitHtmlNodes, getHtmlNodeAttribute, analyzeScriptNode, stringifyHtmlAst, parseSrcSet, getHtmlNodeText, setHtmlNodeAttributes, getHtmlNodePosition, getHtmlNodeAttributePosition, removeHtmlNodeText, setHtmlNodeText, parseCssUrls, parseJsUrls, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, findHtmlNode, removeHtmlNode, applyBabelPlugins, injectJsImport, analyzeLinkNode, injectHtmlNode, insertHtmlNodeAfter } from "@jsenv/ast";
18
+ import { convertJsModuleToJsClassic, systemJsClientFileUrlDefault } from "@jsenv/js-module-fallback";
20
19
  import { jsenvPluginSupervisor } from "@jsenv/plugin-supervisor";
20
+ import { createRequire } from "node:module";
21
21
 
22
22
  /*
23
23
  * data:[<mediatype>][;base64],<data>
@@ -2214,23 +2214,6 @@ const extractDriveLetter = resource => {
2214
2214
 
2215
2215
  process.platform === "win32";
2216
2216
 
2217
- const readFileSync = (value, {
2218
- as = "buffer"
2219
- } = {}) => {
2220
- const fileUrl = assertAndNormalizeFileUrl(value);
2221
- const buffer = readFileSync$1(new URL(fileUrl));
2222
- if (as === "buffer") {
2223
- return buffer;
2224
- }
2225
- if (as === "string") {
2226
- return buffer.toString();
2227
- }
2228
- if (as === "json") {
2229
- return JSON.parse(buffer.toString());
2230
- }
2231
- throw new Error(`"as" must be one of "buffer","string","json" received "${as}"`);
2232
- };
2233
-
2234
2217
  const guardTooFastSecondCallPerFile = (callback, cooldownBetweenFileEvents = 40) => {
2235
2218
  const previousCallMsMap = new Map();
2236
2219
  return fileEvent => {
@@ -8787,10 +8770,16 @@ const createFetchUrlContentError = ({
8787
8770
  });
8788
8771
  }
8789
8772
  if (error.code === "ENOENT") {
8790
- return createFailedToFetchUrlContentError({
8791
- code: "NOT_FOUND",
8792
- reason: "no entry on filesystem"
8793
- });
8773
+ const urlTried = pathToFileURL(error.path).href;
8774
+ // ensure ENOENT is caused by trying to read the urlInfo.url
8775
+ // any ENOENT trying to read an other file should display the error.stack
8776
+ // because it means some side logic has failed
8777
+ if (urlInfo.url.startsWith(urlTried)) {
8778
+ return createFailedToFetchUrlContentError({
8779
+ code: "NOT_FOUND",
8780
+ reason: "no entry on filesystem"
8781
+ });
8782
+ }
8794
8783
  }
8795
8784
  if (error.code === "PARSE_ERROR") {
8796
8785
  return createFailedToFetchUrlContentError({
@@ -11395,3899 +11384,166 @@ const jsenvPluginInlining = () => {
11395
11384
  }, jsenvPluginInliningAsDataUrl(), jsenvPluginInliningIntoHtml()];
11396
11385
  };
11397
11386
 
11398
- const requireFromJsenv = createRequire(import.meta.url);
11399
-
11400
- const babelPluginPackagePath = requireFromJsenv.resolve("@jsenv/babel-plugins");
11401
- const babelPluginPackageUrl = pathToFileURL(babelPluginPackagePath);
11402
- const requireBabelPlugin = createRequire(babelPluginPackageUrl);
11387
+ /*
11388
+ * - propagate "?js_module_fallback" query string param on urls
11389
+ * - perform conversion from js module to js classic when url uses "?js_module_fallback"
11390
+ */
11403
11391
 
11404
- const babelPluginTransformImportMetaUrl = babel => {
11405
- return {
11406
- name: "transform-import-meta-url",
11407
- visitor: {
11408
- Program: programPath => {
11409
- const currentUrlIdentifier = programPath.scope.generateUidIdentifier("currentUrl");
11410
- let used = false;
11411
- programPath.traverse({
11412
- MemberExpression: path => {
11413
- const node = path.node;
11414
- if (node.object.type === "MetaProperty" && node.object.property.name === "meta" && node.property.name === "url") {
11415
- // const node = babel.types.valueToNode(10)
11416
- const identifier = babel.types.identifier(currentUrlIdentifier.name);
11417
- const expressionStatement = babel.types.expressionStatement(identifier);
11418
- path.replaceWith(expressionStatement);
11419
- used = true;
11420
- }
11421
- }
11422
- });
11423
- if (used) {
11424
- const ast = generateExpressionAst(`document.currentScript.src`);
11425
- programPath.scope.push({
11426
- id: currentUrlIdentifier,
11427
- init: ast
11428
- });
11429
- }
11392
+ const jsenvPluginJsModuleConversion = ({
11393
+ systemJsInjection,
11394
+ systemJsClientFileUrl,
11395
+ generateJsClassicFilename
11396
+ }) => {
11397
+ const isReferencingJsModule = reference => {
11398
+ if (reference.type === "js_import" || reference.subtype === "system_register_arg" || reference.subtype === "system_import_arg") {
11399
+ return true;
11400
+ }
11401
+ if (reference.type === "js_url" && reference.expectedType === "js_module") {
11402
+ return true;
11403
+ }
11404
+ return false;
11405
+ };
11406
+ const shouldPropagateJsModuleConversion = (reference, context) => {
11407
+ if (isReferencingJsModule(reference)) {
11408
+ const parentUrlInfo = context.urlGraph.getUrlInfo(reference.parentUrl);
11409
+ if (!parentUrlInfo) {
11410
+ return false;
11430
11411
  }
11412
+ const parentGotAsJsClassic = new URL(parentUrlInfo.url).searchParams.has("js_module_fallback");
11413
+ return parentGotAsJsClassic;
11431
11414
  }
11415
+ return false;
11416
+ };
11417
+ const markAsJsClassicProxy = reference => {
11418
+ reference.expectedType = "js_classic";
11419
+ reference.filename = generateJsClassicFilename(reference.url);
11420
+ };
11421
+ const turnIntoJsClassicProxy = reference => {
11422
+ const urlTransformed = injectQueryParams(reference.url, {
11423
+ js_module_fallback: ""
11424
+ });
11425
+ markAsJsClassicProxy(reference);
11426
+ return urlTransformed;
11432
11427
  };
11433
- };
11434
- const generateExpressionAst = (expression, options) => {
11435
- const {
11436
- parseExpression
11437
- } = babelParser;
11438
- const ast = parseExpression(expression, options);
11439
- return ast;
11440
- };
11441
-
11442
- const babelPluginTransformImportMetaResolve = () => {
11443
11428
  return {
11444
- name: "transform-import-meta-resolve",
11445
- visitor: {
11446
- Program: programPath => {
11447
- programPath.traverse({
11448
- MemberExpression: path => {
11449
- const node = path.node;
11450
- if (node.object.type === "MetaProperty" && node.object.property.name === "meta" && node.property.name === "resolve") {
11451
- const firstArg = node.arguments[0];
11452
- if (firstArg && firstArg.type === "StringLiteral") {
11453
- path.replaceWithSourceString(`new URL(${firstArg.value}, document.currentScript.src).href`);
11454
- }
11455
- }
11456
- }
11429
+ name: "jsenv:js_module_conversion",
11430
+ appliesDuring: "*",
11431
+ redirectReference: (reference, context) => {
11432
+ if (reference.searchParams.has("js_module_fallback")) {
11433
+ markAsJsClassicProxy(reference);
11434
+ return null;
11435
+ }
11436
+ // We want to propagate transformation of js module to js classic to:
11437
+ // - import specifier (static/dynamic import + re-export)
11438
+ // - url specifier when inside System.register/_context.import()
11439
+ // (because it's the transpiled equivalent of static and dynamic imports)
11440
+ // And not other references otherwise we could try to transform inline resources
11441
+ // or specifiers inside new URL()...
11442
+ if (shouldPropagateJsModuleConversion(reference, context)) {
11443
+ return turnIntoJsClassicProxy(reference);
11444
+ }
11445
+ return null;
11446
+ },
11447
+ fetchUrlContent: async (urlInfo, context) => {
11448
+ const [jsModuleReference, jsModuleUrlInfo] = context.getWithoutSearchParam({
11449
+ urlInfo,
11450
+ context,
11451
+ searchParam: "js_module_fallback",
11452
+ // override the expectedType to "js_module"
11453
+ // because when there is ?js_module_fallback it means the underlying resource
11454
+ // is a js_module
11455
+ expectedType: "js_module"
11456
+ });
11457
+ if (!jsModuleReference) {
11458
+ return null;
11459
+ }
11460
+ await context.fetchUrlContent(jsModuleUrlInfo, {
11461
+ reference: jsModuleReference
11462
+ });
11463
+ if (context.dev) {
11464
+ context.referenceUtils.found({
11465
+ type: "js_import",
11466
+ subtype: jsModuleReference.subtype,
11467
+ specifier: jsModuleReference.url,
11468
+ expectedType: "js_module"
11457
11469
  });
11470
+ } else if (context.build && jsModuleUrlInfo.dependents.size === 0) {
11471
+ context.urlGraph.deleteUrlInfo(jsModuleUrlInfo.url);
11458
11472
  }
11473
+ const {
11474
+ content,
11475
+ sourcemap
11476
+ } = await convertJsModuleToJsClassic({
11477
+ rootDirectoryUrl: context.rootDirectoryUrl,
11478
+ systemJsInjection,
11479
+ systemJsClientFileUrl,
11480
+ urlInfo,
11481
+ jsModuleUrlInfo
11482
+ });
11483
+ return {
11484
+ content,
11485
+ contentType: "text/javascript",
11486
+ type: "js_classic",
11487
+ originalUrl: jsModuleUrlInfo.originalUrl,
11488
+ originalContent: jsModuleUrlInfo.originalContent,
11489
+ sourcemap,
11490
+ data: jsModuleUrlInfo.data
11491
+ };
11459
11492
  }
11460
11493
  };
11461
11494
  };
11462
11495
 
11463
- // eslint-disable-next-line import/no-default-export
11464
- const helpers_string_1 = '// A type of promise-like that resolves synchronously and supports only one observer\nexport const _Pact = /*#__PURE__*/(function() {\n\tfunction _Pact() {}\n\t_Pact.prototype.then = function(onFulfilled, onRejected) {\n\t\tconst result = new _Pact();\n\t\tconst state = this.s;\n\t\tif (state) {\n\t\t\tconst callback = state & 1 ? onFulfilled : onRejected;\n\t\t\tif (callback) {\n\t\t\t\ttry {\n\t\t\t\t\t_settle(result, 1, callback(this.v));\n\t\t\t\t} catch (e) {\n\t\t\t\t\t_settle(result, 2, e);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t} else {\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}\n\t\tthis.o = function(_this) {\n\t\t\ttry {\n\t\t\t\tconst value = _this.v;\n\t\t\t\tif (_this.s & 1) {\n\t\t\t\t\t_settle(result, 1, onFulfilled ? onFulfilled(value) : value);\n\t\t\t\t} else if (onRejected) {\n\t\t\t\t\t_settle(result, 1, onRejected(value));\n\t\t\t\t} else {\n\t\t\t\t\t_settle(result, 2, value);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\t_settle(result, 2, e);\n\t\t\t}\n\t\t};\n\t\treturn result;\n\t}\n\treturn _Pact;\n})();\n\n// Settles a pact synchronously\nexport function _settle(pact, state, value) {\n\tif (!pact.s) {\n\t\tif (value instanceof _Pact) {\n\t\t\tif (value.s) {\n\t\t\t\tif (state & 1) {\n\t\t\t\t\tstate = value.s;\n\t\t\t\t}\n\t\t\t\tvalue = value.v;\n\t\t\t} else {\n\t\t\t\tvalue.o = _settle.bind(null, pact, state);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tif (value && value.then) {\n\t\t\tvalue.then(_settle.bind(null, pact, state), _settle.bind(null, pact, 2));\n\t\t\treturn;\n\t\t}\n\t\tpact.s = state;\n\t\tpact.v = value;\n\t\tconst observer = pact.o;\n\t\tif (observer) {\n\t\t\tobserver(pact);\n\t\t}\n\t}\n}\n\nexport function _isSettledPact(thenable) {\n\treturn thenable instanceof _Pact && thenable.s & 1;\n}\n\n// Converts argument to a function that always returns a Promise\nexport function _async(f) {\n\treturn function() {\n\t\tfor (var args = [], i = 0; i < arguments.length; i++) {\n\t\t\targs[i] = arguments[i];\n\t\t}\n\t\ttry {\n\t\t\treturn Promise.resolve(f.apply(this, args));\n\t\t} catch(e) {\n\t\t\treturn Promise.reject(e);\n\t\t}\n\t}\n}\n\n// Awaits on a value that may or may not be a Promise (equivalent to the await keyword in ES2015, with continuations passed explicitly)\nexport function _await(value, then, direct) {\n\tif (direct) {\n\t\treturn then ? then(value) : value;\n\t}\n\tif (!value || !value.then) {\n\t\tvalue = Promise.resolve(value);\n\t}\n\treturn then ? value.then(then) : value;\n}\n\n// Awaits on a value that may or may not be a Promise, then ignores it\nexport function _awaitIgnored(value, direct) {\n\tif (!direct) {\n\t\treturn value && value.then ? value.then(_empty) : Promise.resolve();\n\t}\n}\n\n// Proceeds after a value has resolved, or proceeds immediately if the value is not thenable\nexport function _continue(value, then) {\n\treturn value && value.then ? value.then(then) : then(value);\n}\n\n// Proceeds after a value has resolved, or proceeds immediately if the value is not thenable\nexport function _continueIgnored(value) {\n\tif (value && value.then) {\n\t\treturn value.then(_empty);\n\t}\n}\n\n// Asynchronously iterate through an object that has a length property, passing the index as the first argument to the callback (even as the length property changes)\nexport function _forTo(array, body, check) {\n\tvar i = -1, pact, reject;\n\tfunction _cycle(result) {\n\t\ttry {\n\t\t\twhile (++i < array.length && (!check || !check())) {\n\t\t\t\tresult = body(i);\n\t\t\t\tif (result && result.then) {\n\t\t\t\t\tif (_isSettledPact(result)) {\n\t\t\t\t\t\tresult = result.v;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult.then(_cycle, reject || (reject = _settle.bind(null, pact = new _Pact(), 2)));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (pact) {\n\t\t\t\t_settle(pact, 1, result);\n\t\t\t} else {\n\t\t\t\tpact = result;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\t_settle(pact || (pact = new _Pact()), 2, e);\n\t\t}\n\t}\n\t_cycle();\n\treturn pact;\n}\n\n// Asynchronously iterate through an object\'s properties (including properties inherited from the prototype)\n// Uses a snapshot of the object\'s properties\nexport function _forIn(target, body, check) {\n\tvar keys = [];\n\tfor (var key in target) {\n\t\tkeys.push(key);\n\t}\n\treturn _forTo(keys, function(i) { return body(keys[i]); }, check);\n}\n\n// Asynchronously iterate through an object\'s own properties (excluding properties inherited from the prototype)\n// Uses a snapshot of the object\'s properties\nexport function _forOwn(target, body, check) {\n\tvar keys = [];\n\tfor (var key in target) {\n\t\tif (Object.prototype.hasOwnProperty.call(target, key)) {\n\t\t\tkeys.push(key);\n\t\t}\n\t}\n\treturn _forTo(keys, function(i) { return body(keys[i]); }, check);\n}\n\nexport const _iteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator"))) : "@@iterator";\n\n// Asynchronously iterate through an object\'s values\n// Uses for...of if the runtime supports it, otherwise iterates until length on a copy\nexport function _forOf(target, body, check) {\n\tif (typeof target[_iteratorSymbol] === "function") {\n\t\tvar iterator = target[_iteratorSymbol](), step, pact, reject;\n\t\tfunction _cycle(result) {\n\t\t\ttry {\n\t\t\t\twhile (!(step = iterator.next()).done && (!check || !check())) {\n\t\t\t\t\tresult = body(step.value);\n\t\t\t\t\tif (result && result.then) {\n\t\t\t\t\t\tif (_isSettledPact(result)) {\n\t\t\t\t\t\t\tresult = result.v;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tresult.then(_cycle, reject || (reject = _settle.bind(null, pact = new _Pact(), 2)));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (pact) {\n\t\t\t\t\t_settle(pact, 1, result);\n\t\t\t\t} else {\n\t\t\t\t\tpact = result;\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\t_settle(pact || (pact = new _Pact()), 2, e);\n\t\t\t}\n\t\t}\n\t\t_cycle();\n\t\tif (iterator.return) {\n\t\t\tvar _fixup = function(value) {\n\t\t\t\ttry {\n\t\t\t\t\tif (!step.done) {\n\t\t\t\t\t\titerator.return();\n\t\t\t\t\t}\n\t\t\t\t} catch(e) {\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t}\n\t\t\tif (pact && pact.then) {\n\t\t\t\treturn pact.then(_fixup, function(e) {\n\t\t\t\t\tthrow _fixup(e);\n\t\t\t\t});\n\t\t\t}\n\t\t\t_fixup();\n\t\t}\n\t\treturn pact;\n\t}\n\t// No support for Symbol.iterator\n\tif (!("length" in target)) {\n\t\tthrow new TypeError("Object is not iterable");\n\t}\n\t// Handle live collections properly\n\tvar values = [];\n\tfor (var i = 0; i < target.length; i++) {\n\t\tvalues.push(target[i]);\n\t}\n\treturn _forTo(values, function(i) { return body(values[i]); }, check);\n}\n\nexport const _asyncIteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.asyncIterator || (Symbol.asyncIterator = Symbol("Symbol.asyncIterator"))) : "@@asyncIterator";\n\n// Asynchronously iterate on a value using it\'s async iterator if present, or its synchronous iterator if missing\nexport function _forAwaitOf(target, body, check) {\n\tif (typeof target[_asyncIteratorSymbol] === "function") {\n\t\tvar pact = new _Pact();\n\t\tvar iterator = target[_asyncIteratorSymbol]();\n\t\titerator.next().then(_resumeAfterNext).then(void 0, _reject);\n\t\treturn pact;\n\t\tfunction _resumeAfterBody(result) {\n\t\t\tif (check && check()) {\n\t\t\t\treturn _settle(pact, 1, iterator.return ? iterator.return().then(function() { return result; }) : result);\n\t\t\t}\n\t\t\titerator.next().then(_resumeAfterNext).then(void 0, _reject);\n\t\t}\n\t\tfunction _resumeAfterNext(step) {\n\t\t\tif (step.done) {\n\t\t\t\t_settle(pact, 1);\n\t\t\t} else {\n\t\t\t\tPromise.resolve(body(step.value)).then(_resumeAfterBody).then(void 0, _reject);\n\t\t\t}\n\t\t}\n\t\tfunction _reject(error) {\n\t\t\t_settle(pact, 2, iterator.return ? iterator.return().then(function() { return error; }) : error);\n\t\t}\n\t}\n\treturn Promise.resolve(_forOf(target, function(value) { return Promise.resolve(value).then(body); }, check));\n}\n\n// Asynchronously implement a generic for loop\nexport function _for(test, update, body) {\n\tvar stage;\n\tfor (;;) {\n\t\tvar shouldContinue = test();\n\t\tif (_isSettledPact(shouldContinue)) {\n\t\t\tshouldContinue = shouldContinue.v;\n\t\t}\n\t\tif (!shouldContinue) {\n\t\t\treturn result;\n\t\t}\n\t\tif (shouldContinue.then) {\n\t\t\tstage = 0;\n\t\t\tbreak;\n\t\t}\n\t\tvar result = body();\n\t\tif (result && result.then) {\n\t\t\tif (_isSettledPact(result)) {\n\t\t\t\tresult = result.s;\n\t\t\t} else {\n\t\t\t\tstage = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (update) {\n\t\t\tvar updateValue = update();\n\t\t\tif (updateValue && updateValue.then && !_isSettledPact(updateValue)) {\n\t\t\t\tstage = 2;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tvar pact = new _Pact();\n\tvar reject = _settle.bind(null, pact, 2);\n\t(stage === 0 ? shouldContinue.then(_resumeAfterTest) : stage === 1 ? result.then(_resumeAfterBody) : updateValue.then(_resumeAfterUpdate)).then(void 0, reject);\n\treturn pact;\n\tfunction _resumeAfterBody(value) {\n\t\tresult = value;\n\t\tdo {\n\t\t\tif (update) {\n\t\t\t\tupdateValue = update();\n\t\t\t\tif (updateValue && updateValue.then && !_isSettledPact(updateValue)) {\n\t\t\t\t\tupdateValue.then(_resumeAfterUpdate).then(void 0, reject);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tshouldContinue = test();\n\t\t\tif (!shouldContinue || (_isSettledPact(shouldContinue) && !shouldContinue.v)) {\n\t\t\t\t_settle(pact, 1, result);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (shouldContinue.then) {\n\t\t\t\tshouldContinue.then(_resumeAfterTest).then(void 0, reject);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresult = body();\n\t\t\tif (_isSettledPact(result)) {\n\t\t\t\tresult = result.v;\n\t\t\t}\n\t\t} while (!result || !result.then);\n\t\tresult.then(_resumeAfterBody).then(void 0, reject);\n\t}\n\tfunction _resumeAfterTest(shouldContinue) {\n\t\tif (shouldContinue) {\n\t\t\tresult = body();\n\t\t\tif (result && result.then) {\n\t\t\t\tresult.then(_resumeAfterBody).then(void 0, reject);\n\t\t\t} else {\n\t\t\t\t_resumeAfterBody(result);\n\t\t\t}\n\t\t} else {\n\t\t\t_settle(pact, 1, result);\n\t\t}\n\t}\n\tfunction _resumeAfterUpdate() {\n\t\tif (shouldContinue = test()) {\n\t\t\tif (shouldContinue.then) {\n\t\t\t\tshouldContinue.then(_resumeAfterTest).then(void 0, reject);\n\t\t\t} else {\n\t\t\t\t_resumeAfterTest(shouldContinue);\n\t\t\t}\n\t\t} else {\n\t\t\t_settle(pact, 1, result);\n\t\t}\n\t}\n}\n\n// Asynchronously implement a do ... while loop\nexport function _do(body, test) {\n\tvar awaitBody;\n\tdo {\n\t\tvar result = body();\n\t\tif (result && result.then) {\n\t\t\tif (_isSettledPact(result)) {\n\t\t\t\tresult = result.v;\n\t\t\t} else {\n\t\t\t\tawaitBody = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tvar shouldContinue = test();\n\t\tif (_isSettledPact(shouldContinue)) {\n\t\t\tshouldContinue = shouldContinue.v;\n\t\t}\n\t\tif (!shouldContinue) {\n\t\t\treturn result;\n\t\t}\n\t} while (!shouldContinue.then);\n\tconst pact = new _Pact();\n\tconst reject = _settle.bind(null, pact, 2);\n\t(awaitBody ? result.then(_resumeAfterBody) : shouldContinue.then(_resumeAfterTest)).then(void 0, reject);\n\treturn pact;\n\tfunction _resumeAfterBody(value) {\n\t\tresult = value;\n\t\tfor (;;) {\n\t\t\tshouldContinue = test();\n\t\t\tif (_isSettledPact(shouldContinue)) {\n\t\t\t\tshouldContinue = shouldContinue.v;\n\t\t\t}\n\t\t\tif (!shouldContinue) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (shouldContinue.then) {\n\t\t\t\tshouldContinue.then(_resumeAfterTest).then(void 0, reject);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresult = body();\n\t\t\tif (result && result.then) {\n\t\t\t\tif (_isSettledPact(result)) {\n\t\t\t\t\tresult = result.v;\n\t\t\t\t} else {\n\t\t\t\t\tresult.then(_resumeAfterBody).then(void 0, reject);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t_settle(pact, 1, result);\n\t}\n\tfunction _resumeAfterTest(shouldContinue) {\n\t\tif (shouldContinue) {\n\t\t\tdo {\n\t\t\t\tresult = body();\n\t\t\t\tif (result && result.then) {\n\t\t\t\t\tif (_isSettledPact(result)) {\n\t\t\t\t\t\tresult = result.v;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult.then(_resumeAfterBody).then(void 0, reject);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tshouldContinue = test();\n\t\t\t\tif (_isSettledPact(shouldContinue)) {\n\t\t\t\t\tshouldContinue = shouldContinue.v;\n\t\t\t\t}\n\t\t\t\tif (!shouldContinue) {\n\t\t\t\t\t_settle(pact, 1, result);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} while (!shouldContinue.then);\n\t\t\tshouldContinue.then(_resumeAfterTest).then(void 0, reject);\n\t\t} else {\n\t\t\t_settle(pact, 1, result);\n\t\t}\n\t}\n}\n\n// Asynchronously implement a switch statement\nexport function _switch(discriminant, cases) {\n\tvar dispatchIndex = -1;\n\tvar awaitBody;\n\touter: {\n\t\tfor (var i = 0; i < cases.length; i++) {\n\t\t\tvar test = cases[i][0];\n\t\t\tif (test) {\n\t\t\t\tvar testValue = test();\n\t\t\t\tif (testValue && testValue.then) {\n\t\t\t\t\tbreak outer;\n\t\t\t\t}\n\t\t\t\tif (testValue === discriminant) {\n\t\t\t\t\tdispatchIndex = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Found the default case, set it as the pending dispatch case\n\t\t\t\tdispatchIndex = i;\n\t\t\t}\n\t\t}\n\t\tif (dispatchIndex !== -1) {\n\t\t\tdo {\n\t\t\t\tvar body = cases[dispatchIndex][1];\n\t\t\t\twhile (!body) {\n\t\t\t\t\tdispatchIndex++;\n\t\t\t\t\tbody = cases[dispatchIndex][1];\n\t\t\t\t}\n\t\t\t\tvar result = body();\n\t\t\t\tif (result && result.then) {\n\t\t\t\t\tawaitBody = true;\n\t\t\t\t\tbreak outer;\n\t\t\t\t}\n\t\t\t\tvar fallthroughCheck = cases[dispatchIndex][2];\n\t\t\t\tdispatchIndex++;\n\t\t\t} while (fallthroughCheck && !fallthroughCheck());\n\t\t\treturn result;\n\t\t}\n\t}\n\tconst pact = new _Pact();\n\tconst reject = _settle.bind(null, pact, 2);\n\t(awaitBody ? result.then(_resumeAfterBody) : testValue.then(_resumeAfterTest)).then(void 0, reject);\n\treturn pact;\n\tfunction _resumeAfterTest(value) {\n\t\tfor (;;) {\n\t\t\tif (value === discriminant) {\n\t\t\t\tdispatchIndex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (++i === cases.length) {\n\t\t\t\tif (dispatchIndex !== -1) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\t_settle(pact, 1, result);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttest = cases[i][0];\n\t\t\tif (test) {\n\t\t\t\tvalue = test();\n\t\t\t\tif (value && value.then) {\n\t\t\t\t\tvalue.then(_resumeAfterTest).then(void 0, reject);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdispatchIndex = i;\n\t\t\t}\n\t\t}\n\t\tdo {\n\t\t\tvar body = cases[dispatchIndex][1];\n\t\t\twhile (!body) {\n\t\t\t\tdispatchIndex++;\n\t\t\t\tbody = cases[dispatchIndex][1];\n\t\t\t}\n\t\t\tvar result = body();\n\t\t\tif (result && result.then) {\n\t\t\t\tresult.then(_resumeAfterBody).then(void 0, reject);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar fallthroughCheck = cases[dispatchIndex][2];\n\t\t\tdispatchIndex++;\n\t\t} while (fallthroughCheck && !fallthroughCheck());\n\t\t_settle(pact, 1, result);\n\t}\n\tfunction _resumeAfterBody(result) {\n\t\tfor (;;) {\n\t\t\tvar fallthroughCheck = cases[dispatchIndex][2];\n\t\t\tif (!fallthroughCheck || fallthroughCheck()) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdispatchIndex++;\n\t\t\tvar body = cases[dispatchIndex][1];\n\t\t\twhile (!body) {\n\t\t\t\tdispatchIndex++;\n\t\t\t\tbody = cases[dispatchIndex][1];\n\t\t\t}\n\t\t\tresult = body();\n\t\t\tif (result && result.then) {\n\t\t\t\tresult.then(_resumeAfterBody).then(void 0, reject);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t_settle(pact, 1, result);\n\t}\n}\n\n// Asynchronously call a function and pass the result to explicitly passed continuations\nexport function _call(body, then, direct) {\n\tif (direct) {\n\t\treturn then ? then(body()) : body();\n\t}\n\ttry {\n\t\tvar result = Promise.resolve(body());\n\t\treturn then ? result.then(then) : result;\n\t} catch (e) {\n\t\treturn Promise.reject(e);\n\t}\n}\n\n// Asynchronously call a function and swallow the result\nexport function _callIgnored(body, direct) {\n\treturn _call(body, _empty, direct);\n}\n\n// Asynchronously call a function and pass the result to explicitly passed continuations\nexport function _invoke(body, then) {\n\tvar result = body();\n\tif (result && result.then) {\n\t\treturn result.then(then);\n\t}\n\treturn then(result);\n}\n\n// Asynchronously call a function and swallow the result\nexport function _invokeIgnored(body) {\n\tvar result = body();\n\tif (result && result.then) {\n\t\treturn result.then(_empty);\n\t}\n}\n\n// Asynchronously call a function and send errors to recovery continuation\nexport function _catch(body, recover) {\n\ttry {\n\t\tvar result = body();\n\t} catch(e) {\n\t\treturn recover(e);\n\t}\n\tif (result && result.then) {\n\t\treturn result.then(void 0, recover);\n\t}\n\treturn result;\n}\n\n// Asynchronously await a promise and pass the result to a finally continuation\nexport function _finallyRethrows(body, finalizer) {\n\ttry {\n\t\tvar result = body();\n\t} catch (e) {\n\t\treturn finalizer(true, e);\n\t}\n\tif (result && result.then) {\n\t\treturn result.then(finalizer.bind(null, false), finalizer.bind(null, true));\n\t}\n\treturn finalizer(false, result);\n}\n\n// Asynchronously await a promise and invoke a finally continuation that always overrides the result\nexport function _finally(body, finalizer) {\n\ttry {\n\t\tvar result = body();\n\t} catch (e) {\n\t\treturn finalizer();\n\t}\n\tif (result && result.then) {\n\t\treturn result.then(finalizer, finalizer);\n\t}\n\treturn finalizer();\n}\n\n// Rethrow or return a value from a finally continuation\nexport function _rethrow(thrown, value) {\n\tif (thrown)\n\t\tthrow value;\n\treturn value;\n}\n\n// Empty function to implement break and other control flow that ignores asynchronous results\nexport function _empty() {\n}\n\n// Sentinel value for early returns in generators \nexport const _earlyReturn = /*#__PURE__*/ {};\n\n// Asynchronously call a function and send errors to recovery continuation, skipping early returns\nexport function _catchInGenerator(body, recover) {\n\treturn _catch(body, function(e) {\n\t\tif (e === _earlyReturn) {\n\t\t\tthrow e;\n\t\t}\n\t\treturn recover(e);\n\t});\n}\n\n// Asynchronous generator class; accepts the entrypoint of the generator, to which it passes itself when the generator should start\nexport const _AsyncGenerator = /*#__PURE__*/(function() {\n\tfunction _AsyncGenerator(entry) {\n\t\tthis._entry = entry;\n\t\tthis._pact = null;\n\t\tthis._resolve = null;\n\t\tthis._return = null;\n\t\tthis._promise = null;\n\t}\n\n\tfunction _wrapReturnedValue(value) {\n\t\treturn { value: value, done: true };\n\t}\n\tfunction _wrapYieldedValue(value) {\n\t\treturn { value: value, done: false };\n\t}\n\n\t_AsyncGenerator.prototype._yield = function(value) {\n\t\t// Yield the value to the pending next call\n\t\tthis._resolve(value && value.then ? value.then(_wrapYieldedValue) : _wrapYieldedValue(value));\n\t\t// Return a pact for an upcoming next/return/throw call\n\t\treturn this._pact = new _Pact();\n\t};\n\t_AsyncGenerator.prototype.next = function(value) {\n\t\t// Advance the generator, starting it if it has yet to be started\n\t\tconst _this = this;\n\t\treturn _this._promise = new Promise(function (resolve) {\n\t\t\tconst _pact = _this._pact;\n\t\t\tif (_pact === null) {\n\t\t\t\tconst _entry = _this._entry;\n\t\t\t\tif (_entry === null) {\n\t\t\t\t\t// Generator is started, but not awaiting a yield expression\n\t\t\t\t\t// Abandon the next call!\n\t\t\t\t\treturn resolve(_this._promise);\n\t\t\t\t}\n\t\t\t\t// Start the generator\n\t\t\t\t_this._entry = null;\n\t\t\t\t_this._resolve = resolve;\n\t\t\t\tfunction returnValue(value) {\n\t\t\t\t\t_this._resolve(value && value.then ? value.then(_wrapReturnedValue) : _wrapReturnedValue(value));\n\t\t\t\t\t_this._pact = null;\n\t\t\t\t\t_this._resolve = null;\n\t\t\t\t}\n\t\t\t\tvar result = _entry(_this);\n\t\t\t\tif (result && result.then) {\n\t\t\t\t\tresult.then(returnValue, function(error) {\n\t\t\t\t\t\tif (error === _earlyReturn) {\n\t\t\t\t\t\t\treturnValue(_this._return);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst pact = new _Pact();\n\t\t\t\t\t\t\t_this._resolve(pact);\n\t\t\t\t\t\t\t_this._pact = null;\n\t\t\t\t\t\t\t_this._resolve = null;\n\t\t\t\t\t\t\t_resolve(pact, 2, error);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\treturnValue(result);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Generator is started and a yield expression is pending, settle it\n\t\t\t\t_this._pact = null;\n\t\t\t\t_this._resolve = resolve;\n\t\t\t\t_settle(_pact, 1, value);\n\t\t\t}\n\t\t});\n\t};\n\t_AsyncGenerator.prototype.return = function(value) {\n\t\t// Early return from the generator if started, otherwise abandons the generator\n\t\tconst _this = this;\n\t\treturn _this._promise = new Promise(function (resolve) {\n\t\t\tconst _pact = _this._pact;\n\t\t\tif (_pact === null) {\n\t\t\t\tif (_this._entry === null) {\n\t\t\t\t\t// Generator is started, but not awaiting a yield expression\n\t\t\t\t\t// Abandon the return call!\n\t\t\t\t\treturn resolve(_this._promise);\n\t\t\t\t}\n\t\t\t\t// Generator is not started, abandon it and return the specified value\n\t\t\t\t_this._entry = null;\n\t\t\t\treturn resolve(value && value.then ? value.then(_wrapReturnedValue) : _wrapReturnedValue(value));\n\t\t\t}\n\t\t\t// Settle the yield expression with a rejected "early return" value\n\t\t\t_this._return = value;\n\t\t\t_this._resolve = resolve;\n\t\t\t_this._pact = null;\n\t\t\t_settle(_pact, 2, _earlyReturn);\n\t\t});\n\t};\n\t_AsyncGenerator.prototype.throw = function(error) {\n\t\t// Inject an exception into the pending yield expression\n\t\tconst _this = this;\n\t\treturn _this._promise = new Promise(function (resolve, reject) {\n\t\t\tconst _pact = _this._pact;\n\t\t\tif (_pact === null) {\n\t\t\t\tif (_this._entry === null) {\n\t\t\t\t\t// Generator is started, but not awaiting a yield expression\n\t\t\t\t\t// Abandon the throw call!\n\t\t\t\t\treturn resolve(_this._promise);\n\t\t\t\t}\n\t\t\t\t// Generator is not started, abandon it and return a rejected Promise containing the error\n\t\t\t\t_this._entry = null;\n\t\t\t\treturn reject(error);\n\t\t\t}\n\t\t\t// Settle the yield expression with the value as a rejection\n\t\t\t_this._resolve = resolve;\n\t\t\t_this._pact = null;\n\t\t\t_settle(_pact, 2, error);\n\t\t});\n\t};\n\n\t_AsyncGenerator.prototype[_asyncIteratorSymbol] = function() {\n\t\treturn this;\n\t};\n\t\n\treturn _AsyncGenerator;\n})();\n';
11496
+ /*
11497
+ * when <script type="module"> cannot be used:
11498
+ * - ?js_module_fallback is injected into the src of <script type="module">
11499
+ * - js inside <script type="module"> is transformed into classic js
11500
+ * - <link rel="modulepreload"> are converted to <link rel="preload">
11501
+ */
11465
11502
 
11466
- const require = createRequire(import.meta.url);
11467
- const defaultConfigValues = {
11468
- externalHelpers: false,
11469
- hoist: false,
11470
- inlineHelpers: false,
11471
- minify: false,
11472
- target: "es5",
11473
- topLevelAwait: "disabled",
11474
- asyncAwait: true
11475
- };
11476
- function readConfigKey(config, key) {
11477
- if (Object.hasOwnProperty.call(config, key)) {
11478
- const result = config[key];
11479
- if (typeof result !== "undefined") {
11480
- return result;
11481
- }
11482
- }
11483
- return defaultConfigValues[key];
11484
- }
11485
- function discardingIntrinsics(node) {
11486
- if (node.type == "V8IntrinsicIdentifier") {
11487
- throw new Error(`Expected either an expression or a statement, got a ${node.type}!`);
11488
- }
11489
- return node;
11490
- }
11491
- function clearDeclarationData(declaration) {
11492
- let path = declaration;
11493
- while (path) {
11494
- if (path.getData("declaration:var:2") == declaration) {
11495
- path.setData("declaration:var:2", null);
11496
- }
11497
- path = path.parentPath;
11498
- }
11499
- }
11500
- const constantFunctionMethods = {
11501
- "call": false,
11502
- "apply": false,
11503
- "bind": false
11504
- };
11505
- const constantStaticMethods = {
11506
- "Object": Object.assign({
11507
- "assign": true,
11508
- "create": true,
11509
- "defineProperty": true,
11510
- "defineProperties": true,
11511
- "entries": true,
11512
- "freeze": true,
11513
- "fromEntries": true,
11514
- "getOwnPropertyDescriptor": true,
11515
- "getOwnPropertyDescriptors": true,
11516
- "getOwnPropertyNames": true,
11517
- "getOwnPropertySymbols": true,
11518
- "getPrototypeOf": true,
11519
- "is": true,
11520
- "isExtensible": true,
11521
- "isFrozen": true,
11522
- "isSealed": true,
11523
- "keys": true,
11524
- "preventExtensions": true,
11525
- "seal": true,
11526
- "setPrototypeOf": true,
11527
- "values": true
11528
- }, constantFunctionMethods),
11529
- "Function": constantFunctionMethods,
11530
- "Boolean": constantFunctionMethods,
11531
- "Number": Object.assign({
11532
- "isNaN": true,
11533
- "isFinite": true,
11534
- "isInteger": true,
11535
- "isSafeInteger": true,
11536
- "parseFloat": true,
11537
- "parseInteger": true
11538
- }, constantFunctionMethods),
11539
- "Array": Object.assign({
11540
- "from": true,
11541
- "isArray": true,
11542
- "of": true
11543
- }, constantFunctionMethods),
11544
- "Date": Object.assign({
11545
- "now": true,
11546
- "parse": true,
11547
- "UTC": true
11548
- }, constantFunctionMethods),
11549
- "RegExp": constantFunctionMethods,
11550
- "Error": constantFunctionMethods,
11551
- "TypeError": constantFunctionMethods,
11552
- "Map": constantFunctionMethods,
11553
- "Set": constantFunctionMethods,
11554
- "WeakMap": constantFunctionMethods,
11555
- "WeakSet": constantFunctionMethods,
11556
- "Promise": Object.assign({
11557
- "all": true,
11558
- "race": true,
11559
- "resolve": true,
11560
- "reject": true
11561
- }, constantFunctionMethods),
11562
- "Math": {
11563
- "abs": true,
11564
- "acos": true,
11565
- "asin": true,
11566
- "atan": true,
11567
- "atan2": true,
11568
- "ceil": true,
11569
- "cos": true,
11570
- "exp": true,
11571
- "floor": true,
11572
- "log": true,
11573
- "max": true,
11574
- "min": true,
11575
- "pow": true,
11576
- "random": true,
11577
- "round": true,
11578
- "sin": true,
11579
- "sqrt": true,
11580
- "tan": true
11581
- },
11582
- "JSON": {
11583
- "parse": true,
11584
- "stringify": true
11585
- },
11586
- "URL": Object.assign({
11587
- "createObjectURL": true,
11588
- "revokeObjectURL": true
11589
- }, constantFunctionMethods),
11590
- "console": {
11591
- "assert": true,
11592
- "clear": true,
11593
- "count": true,
11594
- "error": true,
11595
- "info": true,
11596
- "log": true,
11597
- "warn": true
11598
- },
11599
- "document": {
11600
- "createComment": true,
11601
- "createElement": true,
11602
- "createTextNode": true,
11603
- "getElementsByClassName": true,
11604
- "getElementsByTagName": true,
11605
- "getElementsByName": true,
11606
- "getElementById": true,
11607
- "querySelector": true,
11608
- "querySelectorAll": true,
11609
- "write": true,
11610
- "writeln": true
11611
- },
11612
- "XMLHttpRequest": constantFunctionMethods,
11613
- "WebSocket": constantFunctionMethods,
11614
- "Image": constantFunctionMethods,
11615
- "alert": constantFunctionMethods,
11616
- "confirm": constantFunctionMethods,
11617
- "open": constantFunctionMethods,
11618
- "prompt": constantFunctionMethods,
11619
- "eval": constantFunctionMethods,
11620
- "isFinite": constantFunctionMethods,
11621
- "isNaN": constantFunctionMethods,
11622
- "parseInt": constantFunctionMethods,
11623
- "parseFloat": constantFunctionMethods,
11624
- "decodeURI": constantFunctionMethods,
11625
- "decodeURIComponent": constantFunctionMethods,
11626
- "encodeURI": constantFunctionMethods,
11627
- "encodeURIComponent": constantFunctionMethods,
11628
- "escape": constantFunctionMethods,
11629
- "unescape": constantFunctionMethods,
11630
- "$": constantFunctionMethods
11631
- };
11632
- const originalNodeMap = new WeakMap();
11633
- const skipNodeSet = new WeakSet();
11634
- const breakIdentifierMap = new WeakMap();
11635
- const isHelperDefinitionSet = new WeakSet();
11636
- const helperNameMap = new WeakMap();
11637
- const nodeIsAsyncSet = new WeakSet();
11638
- let helpers;
11639
- const alwaysTruthy = Object.keys(constantStaticMethods);
11640
- const numberNames = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"];
11641
- function default_1({
11642
- types,
11643
- traverse,
11644
- transformFromAst,
11645
- version
11646
- }) {
11647
- const isNewBabel = !/^6\./.test(version);
11648
- function cloneNode(node) {
11649
- const result = types.cloneDeep(node);
11650
- if (types.isIdentifier(node) || types.isMemberExpression(node)) {
11651
- const helperName = helperNameMap.get(node);
11652
- if (helperName !== undefined) {
11653
- helperNameMap.set(result, helperName);
11654
- }
11655
- }
11656
- return result;
11657
- }
11658
- function wrapNodeInStatement(node) {
11659
- if (types.isStatement(node)) {
11660
- return types.blockStatement([node]);
11661
- }
11662
- if (types.isExpression(node)) {
11663
- return types.expressionStatement(node);
11664
- }
11665
- throw new Error(`Expected either an expression or a statement, got a ${node.type}!`);
11666
- }
11667
- function pathForNewNode(node, parentPath) {
11668
- let contextPath = parentPath;
11669
- while (contextPath != null) {
11670
- if (contextPath.context) {
11671
- const result = contextPath.context.create(parentPath.node, [node], 0, "dummy");
11672
- result.setContext(contextPath.context);
11673
- return result;
11674
- }
11675
- contextPath = contextPath.parentPath;
11676
- }
11677
- throw parentPath.buildCodeFrameError(`Unable to find a context upon which to traverse!`, TypeError);
11678
- }
11679
- function pathsPassTest(matchingNodeTest, referenceOriginalNodes) {
11680
- function visit(path, result, state) {
11681
- if (referenceOriginalNodes) {
11682
- const originalNode = originalNodeMap.get(path.node);
11683
- if (originalNode) {
11684
- traverse(wrapNodeInStatement(originalNode), visitor, path.scope, {
11685
- match: result,
11686
- state
11687
- }, path);
11688
- return false;
11689
- }
11690
- }
11691
- const doesMatch = matchingNodeTest(path);
11692
- if (doesMatch) {
11693
- result.any = true;
11694
- result.all = !(state.breakingLabels.length || state.unnamedBreak);
11695
- }
11696
- if (path.isBreakStatement()) {
11697
- const label = path.node.label;
11698
- if (!label) {
11699
- state.unnamedBreak = true;
11700
- } else if (state.breakingLabels.indexOf(label.name) === -1) {
11701
- state.breakingLabels.push(label.name);
11702
- }
11703
- }
11704
- if (path.isLabeledStatement()) {
11705
- const index = state.breakingLabels.indexOf(path.node.label.name);
11706
- if (index !== -1) {
11707
- state.breakingLabels.splice(index, 1);
11708
- }
11709
- }
11710
- if (path.isLoop()) {
11711
- state.unnamedBreak = false;
11712
- }
11713
- if (doesMatch) {
11714
- return false;
11715
- }
11716
- if (path.isConditional()) {
11717
- const test = match(path.get("test"), state);
11718
- const consequent = match(path.get("consequent"), state);
11719
- const alternate = match(path.get("alternate"), state);
11720
- result.any = result.any || test.any || consequent.any || alternate.any;
11721
- return result.all = (test.all || consequent.all && alternate.all) && !(state.breakingLabels.length || state.unnamedBreak);
11722
- }
11723
- if (path.isSwitchStatement()) {
11724
- const discriminant = match(path.get("discriminant"), state);
11725
- const cases = path.get("cases");
11726
- const caseMatches = cases.map((switchCase, i) => {
11727
- const newState = {
11728
- unnamedBreak: false,
11729
- breakingLabels: state.breakingLabels
11730
- };
11731
- const newResult = match(switchCase, newState);
11732
- for (i++; (!newResult.all || pathsBreakReturnOrThrow(switchCase).all) && i < cases.length; i++) {
11733
- const tailMatch = match(cases[i], newState);
11734
- newResult.all = (newResult.all || tailMatch.all) && !(state.breakingLabels.length || state.unnamedBreak);
11735
- newResult.any = newResult.any || tailMatch.any;
11736
- }
11737
- return newResult;
11738
- });
11739
- result.any = result.any || discriminant.any || caseMatches.some(caseMatch => caseMatch.any);
11740
- return result.all = (discriminant.all || cases.some(switchCase => !switchCase.node.test) && caseMatches.every(caseMatch => caseMatch.all)) && !(state.breakingLabels.length || state.unnamedBreak);
11741
- }
11742
- if (path.isDoWhileStatement()) {
11743
- const body = match(path.get("body"), {
11744
- unnamedBreak: false,
11745
- breakingLabels: state.breakingLabels
11746
- });
11747
- const test = match(path.get("test"), state);
11748
- result.any = result.any || body.any || test.any;
11749
- return result.all = (body.all || test.all) && !(state.breakingLabels.length || state.unnamedBreak);
11750
- }
11751
- if (path.isWhileStatement()) {
11752
- const testPath = path.get("test");
11753
- const test = match(testPath, state);
11754
- const body = match(path.get("body"), {
11755
- unnamedBreak: false,
11756
- breakingLabels: state.breakingLabels
11757
- });
11758
- result.any = result.any || test.any || body.any;
11759
- return result.all = (test.all || body.all && extractLooseBooleanValue(testPath.node) === true) && !(state.breakingLabels.length || state.unnamedBreak);
11760
- }
11761
- if (path.isForXStatement()) {
11762
- const right = match(path.get("right"), state);
11763
- const body = match(path.get("body"), {
11764
- unnamedBreak: false,
11765
- breakingLabels: state.breakingLabels
11766
- });
11767
- result.any = result.any || right.any || body.any;
11768
- return result.all = right.all && !(state.breakingLabels.length || state.unnamedBreak);
11769
- }
11770
- if (path.isForStatement()) {
11771
- const init = match(path.get("init"), state);
11772
- const test = match(path.get("test"), state);
11773
- const body = match(path.get("body"), {
11774
- unnamedBreak: false,
11775
- breakingLabels: state.breakingLabels
11776
- });
11777
- const update = match(path.get("update"), state);
11778
- result.any = result.any || init.any || test.any || body.any || update.any;
11779
- return result.all = (init.all || test.all) && !(state.breakingLabels.length || state.unnamedBreak);
11780
- }
11781
- if (path.isLogicalExpression()) {
11782
- const left = match(path.get("left"), state);
11783
- const right = match(path.get("right"), state);
11784
- result.any = result.any || left.any || right.any;
11785
- return result.all = left.all && !(state.breakingLabels.length || state.unnamedBreak);
11786
- }
11787
- if (path.isReturnStatement()) {
11788
- return true;
11789
- }
11790
- if (path.isBreakStatement()) {
11791
- return true;
11792
- }
11793
- if (path.isContinueStatement()) {
11794
- return true;
11795
- }
11796
- if (path.isThrowStatement()) {
11797
- return true;
11798
- }
11799
- if (path.isTryStatement()) {
11800
- const blockMatch = match(path.get("block"), state);
11801
- const finalizer = path.get("finalizer");
11802
- const finalizerMatch = match(finalizer, state);
11803
- const handler = path.get("handler");
11804
- const handlerMatch = match(handler, state);
11805
- result.any = result.any || blockMatch.any || handlerMatch.any || finalizerMatch.any;
11806
- if (finalizerMatch.all) {
11807
- return result.all = !(state.breakingLabels.length || state.unnamedBreak);
11808
- } else if (!finalizer.node) {
11809
- return result.all = handlerMatch.all && blockMatch.all && !(state.breakingLabels.length || state.unnamedBreak);
11503
+ const jsenvPluginJsModuleFallbackInsideHtml = ({
11504
+ systemJsInjection,
11505
+ systemJsClientFileUrl
11506
+ }) => {
11507
+ const turnIntoJsClassicProxy = reference => {
11508
+ return injectQueryParams(reference.url, {
11509
+ js_module_fallback: ""
11510
+ });
11511
+ };
11512
+ return {
11513
+ name: "jsenv:js_module_fallback_inside_html",
11514
+ appliesDuring: "*",
11515
+ redirectReference: {
11516
+ link_href: (reference, context) => {
11517
+ if (context.systemJsTranspilation && reference.subtype === "modulepreload") {
11518
+ return turnIntoJsClassicProxy(reference);
11810
11519
  }
11811
- return false;
11812
- }
11813
- if (path.isFunction()) {
11814
- return false;
11815
- }
11816
- }
11817
- const visitor = {
11818
- enter(path) {
11819
- switch (visit(path, this.match, this.state)) {
11820
- case true:
11821
- path.stop();
11822
- break;
11823
- case false:
11824
- path.skip();
11825
- break;
11520
+ if (context.systemJsTranspilation && reference.subtype === "preload" && reference.expectedType === "js_module") {
11521
+ return turnIntoJsClassicProxy(reference);
11826
11522
  }
11827
- }
11828
- };
11829
- function match(path, state) {
11830
- const match = {
11831
- all: false,
11832
- any: false
11833
- };
11834
- if (path && path.node) {
11835
- if (typeof visit(path, match, state) === "undefined") {
11836
- path.traverse(visitor, {
11837
- match,
11838
- state
11839
- });
11523
+ return null;
11524
+ },
11525
+ script: (reference, context) => {
11526
+ if (context.systemJsTranspilation && reference.expectedType === "js_module") {
11527
+ return turnIntoJsClassicProxy(reference);
11840
11528
  }
11841
- }
11842
- return match;
11843
- }
11844
- return path => match(path, {
11845
- breakingLabels: [],
11846
- unnamedBreak: false
11847
- });
11848
- }
11849
- function pathsReachNodeTypes(matchingNodeTypes, referenceOriginalNodes) {
11850
- return pathsPassTest(path => path.type !== null && path.type !== undefined && matchingNodeTypes.indexOf(path.type) !== -1, referenceOriginalNodes);
11851
- }
11852
- const pathsReturn = pathsReachNodeTypes(["ReturnStatement"], true);
11853
- const pathsReturnOrThrow = pathsReachNodeTypes(["ReturnStatement", "ThrowStatement"], true);
11854
- const pathsReturnOrThrowCurrentNodes = pathsReachNodeTypes(["ReturnStatement", "ThrowStatement"], false);
11855
- const pathsBreak = pathsReachNodeTypes(["BreakStatement"], true);
11856
- const pathsBreakReturnOrThrow = pathsReachNodeTypes(["ReturnStatement", "ThrowStatement", "BreakStatement"], true);
11857
- function isNonEmptyStatement(statement) {
11858
- return !types.isEmptyStatement(statement);
11859
- }
11860
- function expressionInSingleReturnStatement(target) {
11861
- const body = target.body;
11862
- if (types.isBlockStatement(body)) {
11863
- const statements = body.body.filter(isNonEmptyStatement);
11864
- if (statements.length === 0) {
11865
- return voidExpression();
11866
- } else {
11867
- const firstStatement = statements[0];
11868
- if (types.isReturnStatement(firstStatement)) {
11869
- return firstStatement.argument || voidExpression();
11529
+ return null;
11530
+ },
11531
+ js_url: (reference, context) => {
11532
+ if (context.systemJsTranspilation && reference.expectedType === "js_module") {
11533
+ return turnIntoJsClassicProxy(reference);
11870
11534
  }
11535
+ return null;
11871
11536
  }
11872
- } else {
11873
- return body;
11874
- }
11875
- }
11876
- function propertyNameOfMemberExpression(node) {
11877
- const property = node.property;
11878
- if (node.computed) {
11879
- if (types.isStringLiteral(property)) {
11880
- return property.value;
11881
- }
11882
- } else {
11883
- if (types.isIdentifier(property)) {
11884
- return property.name;
11885
- }
11886
- }
11887
- }
11888
- function identifiersInForToLengthStatement(statement) {
11889
- const init = statement.get("init");
11890
- if (init.isVariableDeclaration() && init.node.declarations.length === 1) {
11891
- const declaration = init.get("declarations")[0];
11892
- if (types.isNumericLiteral(declaration.node.init) && declaration.node.init.value === 0) {
11893
- const i = declaration.node.id;
11894
- const test = statement.get("test");
11895
- if (types.isIdentifier(i) && test.isBinaryExpression() && test.node.operator === "<" && types.isIdentifier(test.node.left) && test.node.left.name === i.name) {
11896
- const right = test.get("right");
11897
- if (right.isMemberExpression()) {
11898
- const object = right.node.object;
11899
- if (types.isIdentifier(object) && propertyNameOfMemberExpression(right.node) === "length") {
11900
- const update = statement.get("update");
11901
- if (update.isUpdateExpression() && update.node.operator == "++" && types.isIdentifier(update.node.argument) && update.node.argument.name === i.name) {
11902
- const binding = statement.scope.getBinding(i.name);
11903
- if (binding) {
11904
- const updateArgument = update.get("argument");
11905
- if (!binding.constantViolations.some(cv => cv !== updateArgument && cv !== update)) {
11906
- return {
11907
- i,
11908
- array: object
11909
- };
11910
- }
11911
- }
11912
- }
11913
- }
11914
- }
11915
- }
11916
- }
11917
- }
11918
- }
11919
- function extractForOwnBodyPath(path) {
11920
- let left = path.get("left");
11921
- if (left.isVariableDeclaration()) {
11922
- left = left.get("declarations")[0].get("id");
11923
- }
11924
- const right = path.get("right");
11925
- if (left.isIdentifier() && right.isIdentifier()) {
11926
- const rightBinding = path.scope.getBinding(right.node.name);
11927
- if (rightBinding && rightBinding.constant) {
11928
- let body = path.get("body");
11929
- for (;;) {
11930
- let statements;
11931
- if (body.isBlockStatement()) {
11932
- statements = body.get("body");
11933
- } else if (body.isReturnStatement()) {
11934
- const argument = body.get("argument");
11935
- if (argument.isCallExpression() && invokeTypeOfExpression(argument) && argument.get("arguments").length === 1) {
11936
- const firstArgument = argument.get("arguments")[0];
11937
- if (firstArgument.isFunctionExpression()) {
11938
- statements = firstArgument.get("body").get("body");
11939
- } else {
11940
- break;
11941
- }
11942
- } else {
11943
- break;
11944
- }
11945
- } else {
11946
- break;
11947
- }
11948
- if (statements.length !== 1) {
11949
- return;
11950
- }
11951
- body = statements[0];
11952
- }
11953
- if (body.isIfStatement() && !body.node.alternate) {
11954
- const test = body.get("test");
11955
- if (test.isCallExpression() && test.node.arguments.length === 2) {
11956
- const args = test.get("arguments");
11957
- const firstArg = args[0];
11958
- const secondArg = args[1];
11959
- if (firstArg.isIdentifier() && firstArg.node.name === right.node.name && secondArg.isIdentifier() && secondArg.node.name === left.node.name) {
11960
- const callee = test.get("callee");
11961
- if (callee.isMemberExpression() && propertyNameOfMemberExpression(callee.node) === "call") {
11962
- let method = callee.get("object");
11963
- if (method.isMemberExpression() && propertyNameOfMemberExpression(method.node) === "hasOwnProperty") {
11964
- let target = method.get("object");
11965
- if (target.isObjectExpression() && target.node.properties.length === 0) {
11966
- return body.get("consequent");
11967
- }
11968
- if (target.isMemberExpression() && propertyNameOfMemberExpression(target.node) === "prototype") {
11969
- target = target.get("object");
11970
- }
11971
- if (target.isIdentifier() && target.node.name === "Object") {
11972
- return body.get("consequent");
11973
- }
11974
- }
11975
- }
11976
- }
11977
- }
11978
- }
11979
- }
11980
- }
11981
- }
11982
- function isContinuation(possible) {
11983
- return types.isFunctionExpression(possible) && possible.id === null || types.isArrowFunctionExpression(possible);
11984
- }
11985
- function isPassthroughContinuation(continuation) {
11986
- if (continuation) {
11987
- if (isContinuation(continuation) && continuation.params.length === 1) {
11988
- const expression = expressionInSingleReturnStatement(continuation);
11989
- if (expression) {
11990
- const firstParam = continuation.params[0];
11991
- if (types.isIdentifier(firstParam)) {
11992
- const valueName = firstParam.name;
11993
- if (types.isIdentifier(expression) && expression.name === valueName) {
11994
- return true;
11995
- }
11996
- if (types.isConditionalExpression(expression) && types.isIdentifier(expression.test) && types.isIdentifier(expression.consequent) && expression.consequent.name === valueName && types.isIdentifier(expression.alternate) && expression.alternate.name === valueName) {
11997
- return true;
11998
- }
11999
- }
12000
- }
12001
- }
12002
- }
12003
- return false;
12004
- }
12005
- function isEmptyContinuation(continuation) {
12006
- if (types.isIdentifier(continuation)) {
12007
- return helperNameMap.get(continuation) === "_empty";
12008
- }
12009
- if (isContinuation(continuation)) {
12010
- const body = continuation.body;
12011
- if (types.isBlockStatement(body)) {
12012
- return body.body.length === 0;
12013
- }
12014
- }
12015
- return false;
12016
- }
12017
- function voidExpression(arg) {
12018
- return types.unaryExpression("void", arg || types.numericLiteral(0));
12019
- }
12020
- function simplifyWithIdentifier(expression, identifier, truthy) {
12021
- if (types.isCallExpression(expression)) {
12022
- switch (promiseCallExpressionType(expression)) {
12023
- case "all":
12024
- case "race":
12025
- case "reject":
12026
- case "resolve":
12027
- {
12028
- const firstArgument = expression.arguments[0];
12029
- if (types.isExpression(firstArgument)) {
12030
- const simplified = simplifyWithIdentifier(firstArgument, identifier, truthy);
12031
- return simplified === expression.arguments[0] ? expression : types.callExpression(expression.callee, [simplified]);
12032
- }
12033
- }
12034
- case "then":
12035
- {
12036
- const callee = expression.callee;
12037
- if (types.isMemberExpression(callee)) {
12038
- const thenArgument = expression.arguments[0];
12039
- const object = callee.object;
12040
- if (types.isCallExpression(object)) {
12041
- const valueArgument = object.arguments[0];
12042
- if (types.isExpression(valueArgument) && types.isExpression(thenArgument)) {
12043
- const simplified = simplifyWithIdentifier(valueArgument, identifier, truthy);
12044
- return simplified === valueArgument ? expression : callThenMethod(types.callExpression(object.callee, [simplified]), thenArgument);
12045
- }
12046
- }
12047
- }
12048
- }
12049
- }
12050
- if (expression.arguments.length === 1 && types.isIdentifier(expression.callee) || isContinuation(expression.callee)) {
12051
- const firstArgument = expression.arguments[0];
12052
- if (types.isExpression(firstArgument)) {
12053
- const simplified = simplifyWithIdentifier(firstArgument, identifier, truthy);
12054
- return simplified === expression.arguments[0] ? expression : types.callExpression(expression.callee, [simplified]);
12055
- }
12056
- }
12057
- }
12058
- if (types.isConditionalExpression(expression) && types.isIdentifier(expression.test) && expression.test.name === identifier.name) {
12059
- return truthy ? expression.consequent : expression.alternate;
12060
- }
12061
- if (types.isLogicalExpression(expression) && types.isIdentifier(expression.left) && expression.left.name === identifier.name) {
12062
- if (expression.operator === "&&") {
12063
- return truthy ? expression.right : expression.left;
12064
- }
12065
- if (expression.operator === "||") {
12066
- return truthy ? expression.left : expression.right;
12067
- }
12068
- }
12069
- return expression;
12070
- }
12071
- function isIdentifierOrLiteral(expression) {
12072
- return types.isIdentifier(expression) || types.isLiteral(expression);
12073
- }
12074
- function simpleExpressionForContinuation(continuation, value) {
12075
- if (isContinuation(continuation)) {
12076
- let expression = expressionInSingleReturnStatement(continuation);
12077
- if (expression) {
12078
- switch (continuation.params.length) {
12079
- case 0:
12080
- if (types.isConditionalExpression(expression) && isIdentifierOrLiteral(expression.test) && isIdentifierOrLiteral(expression.consequent) && isIdentifierOrLiteral(expression.alternate) || (types.isLogicalExpression(expression) || types.isBinaryExpression(expression)) && isIdentifierOrLiteral(expression.left) && isIdentifierOrLiteral(expression.right) || types.isUnaryExpression(expression) && isIdentifierOrLiteral(expression.argument) || types.isCallExpression(expression) && isIdentifierOrLiteral(expression.callee) && expression.arguments.length === 0 || isIdentifierOrLiteral(expression)) {
12081
- return expression;
12082
- }
12083
- break;
12084
- case 1:
12085
- {
12086
- if (!value) {
12087
- return;
12088
- }
12089
- const firstParam = continuation.params[0];
12090
- const replace = expr => types.isIdentifier(firstParam) && types.isIdentifier(expr) && expr.name === firstParam.name ? value : discardingIntrinsics(expr);
12091
- if (isIdentifierOrLiteral(expression)) {
12092
- return replace(expression);
12093
- }
12094
- if (types.isConditionalExpression(expression) && isIdentifierOrLiteral(expression.test) && isIdentifierOrLiteral(expression.consequent) && isIdentifierOrLiteral(expression.alternate)) {
12095
- return types.conditionalExpression(replace(expression.test), replace(expression.consequent), replace(expression.alternate));
12096
- }
12097
- if (types.isLogicalExpression(expression) && isIdentifierOrLiteral(expression.left) && isIdentifierOrLiteral(expression.right)) {
12098
- return types.logicalExpression(expression.operator, replace(expression.left), replace(expression.right));
12099
- }
12100
- if (types.isBinaryExpression(expression) && isIdentifierOrLiteral(expression.left) && isIdentifierOrLiteral(expression.right)) {
12101
- return types.binaryExpression(expression.operator, replace(expression.left), replace(expression.right));
12102
- }
12103
- if (types.isCallExpression(expression) && isIdentifierOrLiteral(expression.callee) && expression.arguments.length === 0) {
12104
- return types.callExpression(replace(expression.callee), expression.arguments);
12105
- }
12106
- }
12107
- }
12108
- }
12109
- }
12110
- }
12111
- function awaitAndContinue(state, path, value, continuation, directExpression) {
12112
- const declarators = [];
12113
- if (continuation) {
12114
- if (isPassthroughContinuation(continuation)) {
12115
- continuation = undefined;
12116
- } else {
12117
- continuation = unwrapReturnCallWithPassthroughArgument(continuation, path.scope);
12118
- }
12119
- }
12120
- if (!continuation && directExpression && extractLooseBooleanValue(directExpression) === true) {
12121
- return {
12122
- declarators,
12123
- expression: value
12124
- };
12125
- }
12126
- if (types.isCallExpression(value) && value.arguments.length === 0 && isContinuation(value.callee) && value.callee.params.length === 0) {
12127
- const newValue = expressionInSingleReturnStatement(value.callee);
12128
- if (newValue) {
12129
- value = newValue;
12130
- }
12131
- }
12132
- if (continuation && !directExpression && types.isCallExpression(value) && types.isMemberExpression(value.callee) && helperNameMap.get(value.callee) === "_yield") {
12133
- return {
12134
- declarators,
12135
- expression: callThenMethod(value, continuation)
12136
- };
12137
- }
12138
- if (readConfigKey(state.opts, "inlineHelpers")) {
12139
- if (directExpression) {
12140
- const resolvedValue = types.callExpression(promiseResolve(), [value]);
12141
- const direct = extractLooseBooleanValue(directExpression);
12142
- if (typeof direct === "undefined") {
12143
- let expression;
12144
- if (continuation) {
12145
- let simpleExpression;
12146
- if (!types.isIdentifier(continuation) && !(simpleExpression = simpleExpressionForContinuation(continuation, isIdentifierOrLiteral(value) ? value : undefined))) {
12147
- const id = path.scope.generateUidIdentifier("temp");
12148
- if (isContinuation(continuation)) {
12149
- if (!path.parentPath) {
12150
- throw path.buildCodeFrameError(`Expected a parent path!`, Error);
12151
- }
12152
- insertFunctionIntoScope(continuation, id, path.parentPath.scope);
12153
- } else {
12154
- declarators.push(types.variableDeclarator(id, continuation));
12155
- }
12156
- continuation = id;
12157
- }
12158
- expression = conditionalExpression(directExpression, simpleExpression || types.callExpression(continuation, [value]), callThenMethod(resolvedValue, continuation));
12159
- } else {
12160
- expression = conditionalExpression(directExpression, value, resolvedValue);
12161
- }
12162
- return {
12163
- declarators,
12164
- expression
12165
- };
12166
- } else if (direct) {
12167
- return {
12168
- declarators,
12169
- expression: continuation ? types.callExpression(continuation, [value]) : value
12170
- };
12171
- } else {
12172
- return {
12173
- declarators,
12174
- expression: continuation ? callThenMethod(resolvedValue, continuation) : resolvedValue
12175
- };
12176
- }
12177
- } else if (continuation) {
12178
- if (!types.isIdentifier(value)) {
12179
- if (types.isCallExpression(value) && promiseCallExpressionType(value) !== undefined) {
12180
- return {
12181
- declarators,
12182
- expression: callThenMethod(value, continuation)
12183
- };
12184
- }
12185
- const id = path.scope.generateUidIdentifier("temp");
12186
- declarators.push(types.variableDeclarator(id, value));
12187
- value = id;
12188
- }
12189
- const isEmpty = isEmptyContinuation(continuation);
12190
- let simpleExpression;
12191
- if (!isEmpty && !types.isIdentifier(continuation) && !(simpleExpression = simpleExpressionForContinuation(continuation, value))) {
12192
- const id = path.scope.generateUidIdentifier("temp");
12193
- if (isContinuation(continuation)) {
12194
- if (!path.parentPath) {
12195
- throw path.buildCodeFrameError(`Expected a parent path!`, Error);
12196
- }
12197
- insertFunctionIntoScope(continuation, id, path.parentPath.scope);
12198
- } else {
12199
- declarators.push(types.variableDeclarator(id, continuation));
12200
- }
12201
- continuation = id;
12202
- }
12203
- return {
12204
- declarators,
12205
- expression: types.conditionalExpression(types.logicalExpression("&&", value, types.memberExpression(value, types.identifier("then"))), callThenMethod(value, continuation), simpleExpression ? simpleExpression : isEmpty ? voidExpression() : types.callExpression(continuation, [value]))
12206
- };
12207
- }
12208
- }
12209
- const callTarget = types.isCallExpression(value) && value.arguments.length === 0 && !types.isMemberExpression(value.callee) ? value.callee : undefined;
12210
- const args = [callTarget || value];
12211
- const ignoreResult = continuation && isEmptyContinuation(continuation);
12212
- if (!ignoreResult && continuation) {
12213
- args.push(continuation);
12214
- }
12215
- if (directExpression && extractLooseBooleanValue(directExpression) !== false) {
12216
- if (!ignoreResult && !continuation) {
12217
- args.push(voidExpression());
12218
- }
12219
- args.push(directExpression);
12220
- }
12221
- const baseHelper = directExpression ? callTarget ? "_call" : "_await" : callTarget ? "_invoke" : "_continue";
12222
- const helperName = ignoreResult ? baseHelper + "Ignored" : baseHelper;
12223
- if (args.length === 1) {
12224
- switch (helperName) {
12225
- case "_invoke":
12226
- return {
12227
- declarators,
12228
- expression: types.callExpression(args[0], [])
12229
- };
12230
- case "_continue":
12231
- return {
12232
- declarators,
12233
- expression: discardingIntrinsics(args[0])
12234
- };
12235
- case "_continueIgnored":
12236
- const firstArgument = args[0];
12237
- if (types.isCallExpression(firstArgument) && (types.isIdentifier(firstArgument.callee) || types.isMemberExpression(firstArgument.callee))) {
12238
- if (helperNameMap.get(firstArgument.callee) === "_continueIgnored") {
12239
- return {
12240
- declarators,
12241
- expression: firstArgument
12242
- };
12243
- }
12244
- }
12245
- }
12246
- }
12247
- return {
12248
- declarators,
12249
- expression: types.callExpression(helperReference(state, path, helperName), args.map(discardingIntrinsics))
12250
- };
12251
- }
12252
- function borrowTail(target) {
12253
- let current = target;
12254
- const dest = [];
12255
- while (current && current.node && current.inList && current.container) {
12256
- const siblings = current.getAllNextSiblings();
12257
- for (const sibling of siblings) {
12258
- sibling.assertStatement();
12259
- dest.push(sibling.node);
12260
- }
12261
- for (const sibling of siblings) {
12262
- sibling.remove();
12263
- }
12264
- current = current.parentPath;
12265
- if (!current || !current.isBlockStatement()) {
12266
- break;
12267
- }
12268
- }
12269
- return dest;
12270
- }
12271
- function exitsInTail(target) {
12272
- let current = target;
12273
- while (current && current.node && current.inList && current.container && !current.isFunction()) {
12274
- for (var i = current.key + 1; i < current.container.length; i++) {
12275
- if (pathsReturnOrThrow(current).any) {
12276
- return true;
12277
- }
12278
- }
12279
- current = current.parentPath;
12280
- }
12281
- return false;
12282
- }
12283
- function returnStatement(argument, originalNode) {
12284
- const result = types.returnStatement(argument);
12285
- skipNodeSet.add(result);
12286
- if (originalNode !== undefined) {
12287
- originalNodeMap.set(result, originalNode);
12288
- }
12289
- return result;
12290
- }
12291
- function removeUnnecessaryReturnStatements(blocks) {
12292
- while (blocks.length) {
12293
- const lastStatement = blocks[blocks.length - 1];
12294
- if (types.isReturnStatement(lastStatement)) {
12295
- if (lastStatement.argument === null || lastStatement.argument === undefined) {
12296
- blocks = blocks.slice(0, blocks.length - 1);
12297
- } else {
12298
- if (types.isConditionalExpression(lastStatement.argument) && types.isUnaryExpression(lastStatement.argument.alternate) && lastStatement.argument.alternate.operator === "void" && isValueLiteral(lastStatement.argument.alternate.argument)) {
12299
- blocks = blocks.slice(0, blocks.length - 1);
12300
- blocks.push(types.ifStatement(lastStatement.argument.test, types.returnStatement(lastStatement.argument.consequent)));
12301
- } else if (blocks.length > 1) {
12302
- const previousStatement = blocks[blocks.length - 2];
12303
- if (types.isIfStatement(previousStatement) && !previousStatement.alternate) {
12304
- let consequent = previousStatement.consequent;
12305
- while (types.isBlockStatement(consequent)) {
12306
- if (consequent.body.length !== 1) {
12307
- return blocks;
12308
- }
12309
- consequent = consequent.body[0];
12310
- }
12311
- if (types.isReturnStatement(consequent) && consequent.argument) {
12312
- blocks = blocks.slice(0, blocks.length - 2);
12313
- blocks.push(types.returnStatement(conditionalExpression(previousStatement.test, consequent.argument, lastStatement.argument)));
12314
- }
12315
- }
12316
- }
12317
- break;
12318
- }
12319
- } else {
12320
- if (types.isIfStatement(lastStatement)) {
12321
- let consequent = lastStatement.consequent;
12322
- if (types.isBlockStatement(consequent)) {
12323
- consequent = blockStatement(removeUnnecessaryReturnStatements(consequent.body));
12324
- }
12325
- let alternate = lastStatement.alternate;
12326
- if (alternate) {
12327
- if (types.isBlockStatement(alternate)) {
12328
- const removedOfUnnecessary = removeUnnecessaryReturnStatements(alternate.body);
12329
- alternate = removedOfUnnecessary.length ? blockStatement(removedOfUnnecessary) : undefined;
12330
- } else if (removeUnnecessaryReturnStatements([alternate]).length === 0) {
12331
- alternate = undefined;
12332
- }
12333
- }
12334
- if (consequent !== lastStatement.consequent || alternate !== lastStatement.alternate) {
12335
- blocks = blocks.slice(0, blocks.length - 1);
12336
- blocks.push(types.ifStatement(lastStatement.test, consequent, alternate || undefined));
12337
- }
12338
- }
12339
- break;
12340
- }
12341
- }
12342
- return blocks;
12343
- }
12344
- function rewriteAsyncNode(state, parentPath, node, additionalConstantNames, exitIdentifier, unpromisify) {
12345
- const path = pathForNewNode(node, parentPath);
12346
- rewriteAsyncBlock(state, path, additionalConstantNames, exitIdentifier, unpromisify);
12347
- return path.node;
12348
- }
12349
- function allScopes(scope) {
12350
- const result = [];
12351
- while (scope) {
12352
- result.push(scope);
12353
- scope = scope.parent;
12354
- }
12355
- return result;
12356
- }
12357
- const hoistCallArgumentsInnerVisitor = {
12358
- Identifier(identifierPath) {
12359
- if (identifierSearchesScope(identifierPath)) {
12360
- const name = identifierPath.node.name;
12361
- if (this.argumentNames.indexOf(name) === -1) {
12362
- if (this.additionalConstantNames.indexOf(name) !== -1) {
12363
- this.scopes.push(this.path.scope.parent);
12364
- } else {
12365
- const binding = identifierPath.scope.getBinding(name) || this.path.scope.getBinding(name);
12366
- if (binding) {
12367
- const scope = binding.scope;
12368
- if (scope !== null) {
12369
- if (this.pathScopes.indexOf(scope) !== -1) {
12370
- this.scopes.push(scope);
12371
- }
12372
- }
12373
- }
12374
- }
12375
- }
12376
- }
12377
- }
12378
- };
12379
- function isValueLiteral(node) {
12380
- return types.isStringLiteral(node) || types.isNumericLiteral(node) || types.isBooleanLiteral(node);
12381
- }
12382
- function keyFilter(key, value) {
12383
- return key === "start" || key === "end" || key === "loc" || key === "directives" || key === "leadingComments" || key === "trailingComments" || key === "innerComments" || key[0] === "_" ? undefined : value;
12384
- }
12385
- function nodesAreEquivalent(node) {
12386
- let cached;
12387
- return other => {
12388
- if (typeof cached === "undefined") {
12389
- cached = JSON.stringify(node, keyFilter);
12390
- }
12391
- return cached === JSON.stringify(other, keyFilter);
12392
- };
12393
- }
12394
- const reregisterVariableVisitor = {
12395
- VariableDeclaration(path) {
12396
- path.scope.registerDeclaration(path);
12397
- },
12398
- FunctionDeclaration(path) {
12399
- path.parentPath.scope.registerDeclaration(path);
12400
- },
12401
- ClassDeclaration(path) {
12402
- path.scope.registerDeclaration(path);
12403
- },
12404
- Function(path) {
12405
- path.skip();
12406
- }
12407
- };
12408
- function insertFunctionIntoScope(func, id, scope) {
12409
- scope.push({
12410
- kind: "const",
12411
- id,
12412
- init: func,
12413
- unique: true
12414
- });
12415
- const binding = scope.getBinding(id.name);
12416
- if (typeof binding === "undefined") {
12417
- throw scope.path.buildCodeFrameError(`Could not find newly created binding for ${id.name}!`, Error);
12418
- }
12419
- const targetPath = binding.path.parentPath;
12420
- if (!targetPath) {
12421
- throw scope.path.buildCodeFrameError(`Could not find newly created binding for ${id.name}!`, Error);
12422
- }
12423
- targetPath.replaceWith(types.functionDeclaration(id, func.params, types.isBlockStatement(func.body) ? func.body : types.blockStatement([types.returnStatement(func.body)]), func.generator, func.async));
12424
- reregisterDeclarations(targetPath);
12425
- }
12426
- function hoistFunctionExpressionHandler(path) {
12427
- path.skip();
12428
- const bodyPath = path.get("body");
12429
- if (bodyPath.isBlockStatement() && bodyPath.node.body.length === 0 && !readConfigKey(this.state.opts, "inlineHelpers")) {
12430
- path.replaceWith(emptyFunction(this.state, path));
12431
- return;
12432
- }
12433
- const argumentNames = [];
12434
- for (const param of path.node.params) {
12435
- if (types.isIdentifier(param) || types.isPattern(param) || types.isRestElement(param)) {
12436
- addConstantNames(argumentNames, param);
12437
- } else {
12438
- return;
12439
- }
12440
- }
12441
- const scopes = [];
12442
- const pathScopes = allScopes(path.scope.parent);
12443
- path.traverse(hoistCallArgumentsInnerVisitor, {
12444
- argumentNames,
12445
- scopes,
12446
- pathScopes,
12447
- path,
12448
- additionalConstantNames: this.additionalConstantNames
12449
- });
12450
- let scope = path.scope.getProgramParent();
12451
- let ancestry = [scope];
12452
- for (let otherScope of scopes) {
12453
- if (ancestry.indexOf(otherScope) === -1) {
12454
- scope = otherScope;
12455
- ancestry = ancestry.concat(allScopes(otherScope));
12456
- }
12457
- }
12458
- if (ancestry.indexOf(path.scope.parent) === -1) {
12459
- const bindings = scope.bindings;
12460
- const filter = nodesAreEquivalent([...path.node.params, path.node.body]);
12461
- for (const key of Object.getOwnPropertyNames(bindings)) {
12462
- const binding = bindings[key];
12463
- const bindingPath = binding.path;
12464
- if (bindingPath.isFunctionDeclaration()) {
12465
- if (filter([...bindingPath.node.params, bindingPath.node.body])) {
12466
- path.replaceWith(binding.identifier);
12467
- return;
12468
- }
12469
- } else if (bindingPath.isVariableDeclarator()) {
12470
- const init = bindingPath.get("init");
12471
- if (init.node && isContinuation(init.node)) {
12472
- if (filter([...init.node.params, init.node.body])) {
12473
- path.replaceWith(binding.identifier);
12474
- return;
12475
- }
12476
- }
12477
- }
12478
- }
12479
- let nameNode = path.node;
12480
- if (types.isExpression(nameNode) && isContinuation(nameNode)) {
12481
- nameNode = nameNode.body;
12482
- }
12483
- if (types.isBlockStatement(nameNode) && nameNode.body.length === 1) {
12484
- nameNode = nameNode.body[0];
12485
- }
12486
- if (types.isReturnStatement(nameNode) && nameNode.argument) {
12487
- nameNode = nameNode.argument;
12488
- }
12489
- if (types.isCallExpression(nameNode)) {
12490
- const callee = nameNode.callee;
12491
- if (types.isIdentifier(callee) && helperNameMap.has(callee)) {
12492
- nameNode = nameNode.arguments[0];
12493
- }
12494
- }
12495
- const id = isValueLiteral(nameNode) ? scope.generateUidIdentifier(nameNode.value.toString().replace(/\d/g, number => numberNames[number])) : path.scope.generateUidIdentifierBasedOnNode(nameNode, "temp");
12496
- const init = path.node;
12497
- path.replaceWith(id);
12498
- insertFunctionIntoScope(init, id, scope);
12499
- }
12500
- }
12501
- const hoistCallArgumentsVisitor = {
12502
- FunctionExpression: hoistFunctionExpressionHandler,
12503
- ArrowFunctionExpression: hoistFunctionExpressionHandler
12504
- };
12505
- function hoistCallArguments(state, path, additionalConstantNames) {
12506
- if (path.isCallExpression()) {
12507
- const callee = path.node.callee;
12508
- if ((types.isIdentifier(callee) || types.isMemberExpression(callee)) && helperNameMap.has(callee)) {
12509
- const functionParent = path.getFunctionParent();
12510
- if (functionParent) {
12511
- const scope = functionParent.scope;
12512
- if (scope.crawl) {
12513
- scope.crawl();
12514
- }
12515
- }
12516
- path.traverse(hoistCallArgumentsVisitor, {
12517
- state,
12518
- additionalConstantNames
12519
- });
12520
- }
12521
- }
12522
- }
12523
- function checkPathValidity(path) {
12524
- if (path.container === null) {
12525
- throw path.buildCodeFrameError(`Path was expected to have a container!`, TypeError);
12526
- }
12527
- if ("resync" in path && typeof path.resync === "function") {
12528
- path.resync();
12529
- if (path.container === null) {
12530
- throw path.buildCodeFrameError(`Path was expected to have a container, and lost its container upon resync!`, TypeError);
12531
- }
12532
- }
12533
- }
12534
- function relocateTail(generatorState, awaitExpression, statementNode, target, additionalConstantNames, temporary, exitCheck, directExpression, skipReturns) {
12535
- checkPathValidity(target);
12536
- const tail = borrowTail(target);
12537
- checkPathValidity(target);
12538
- let originalNode = types.isStatement(target.node) ? target.node : types.expressionStatement(target.node);
12539
- const rewrittenTail = statementNode || tail.length ? rewriteAsyncNode(generatorState, target, blockStatement((statementNode ? [statementNode] : []).concat(tail)), additionalConstantNames).body : [];
12540
- checkPathValidity(target);
12541
- let blocks = removeUnnecessaryReturnStatements(rewrittenTail.filter(isNonEmptyStatement));
12542
- checkPathValidity(target);
12543
- let replacement;
12544
- if (blocks.length) {
12545
- if (exitCheck) {
12546
- if (temporary && !types.isIdentifier(temporary)) {
12547
- const temporaryIdentifier = temporary = target.scope.generateUidIdentifier("temp");
12548
- const declaration = types.variableDeclaration("const", [types.variableDeclarator(temporary, temporaryIdentifier)]);
12549
- blocks = [declaration].concat(blocks);
12550
- temporary = temporaryIdentifier;
12551
- }
12552
- if (temporary !== undefined) {
12553
- blocks = removeUnnecessaryReturnStatements([types.ifStatement(exitCheck, returnStatement(temporary))].concat(blocks));
12554
- } else {
12555
- const minify = readConfigKey(generatorState.state.opts, "minify");
12556
- blocks = removeUnnecessaryReturnStatements([types.ifStatement(logicalNot(exitCheck, minify), blocks.length === 1 ? blocks[0] : blockStatement(blocks))]);
12557
- }
12558
- }
12559
- const fn = functionize(generatorState.state, temporary ? [temporary] : [], blockStatement(blocks), target);
12560
- replacement = awaitAndContinue(generatorState.state, target, awaitExpression, fn, directExpression);
12561
- originalNode = types.blockStatement([originalNode].concat(tail));
12562
- } else if (pathsReturnOrThrow(target).any || target.parentPath.isArrowFunctionExpression()) {
12563
- replacement = awaitAndContinue(generatorState.state, target, awaitExpression, undefined, directExpression);
12564
- } else {
12565
- replacement = awaitAndContinue(generatorState.state, target, awaitExpression, emptyFunction(generatorState.state, target), directExpression);
12566
- }
12567
- checkPathValidity(target);
12568
- if (target.isExpression() && target.parentPath.isArrowFunctionExpression()) {
12569
- target.replaceWith(replacement.expression);
12570
- } else if (skipReturns) {
12571
- target.replaceWith(replacement.expression);
12572
- } else if (target.isBlockStatement() && target.parentPath.isFunctionExpression()) {
12573
- target.replaceWith(types.blockStatement([returnStatement(replacement.expression, originalNode)]));
12574
- } else {
12575
- target.replaceWith(returnStatement(replacement.expression, originalNode));
12576
- }
12577
- if (replacement.declarators.length) {
12578
- reregisterDeclarations(target.insertBefore(types.variableDeclaration("const", replacement.declarators)));
12579
- }
12580
- if (readConfigKey(generatorState.state.opts, "hoist")) {
12581
- if (target.isExpression()) {
12582
- hoistCallArguments(generatorState.state, target, additionalConstantNames);
12583
- } else if (target.isReturnStatement()) {
12584
- const argument = target.get("argument");
12585
- if (argument.node) {
12586
- hoistCallArguments(generatorState.state, argument, additionalConstantNames);
12587
- }
12588
- }
12589
- }
12590
- }
12591
- function rewriteToNamedConstant(targetPath, callback) {
12592
- const declarators = Object.create(null);
12593
- return callback((name, path) => {
12594
- if (Object.hasOwnProperty.call(declarators, name)) {
12595
- const id = declarators[name].id;
12596
- const binding = targetPath.scope.getBinding(id.name);
12597
- if (!binding || binding.path.get("init") !== path) {
12598
- path.replaceWith(types.identifier(id.name));
12599
- }
12600
- } else {
12601
- const id = path.scope.generateUidIdentifier(name);
12602
- const init = path.node;
12603
- path.replaceWith(id);
12604
- const declarator = declarators[name] = {
12605
- kind: "const",
12606
- id,
12607
- init
12608
- };
12609
- let skip = false;
12610
- if (targetPath.isClassMethod() && targetPath.node.kind === "constructor") {
12611
- targetPath.traverse({
12612
- Super(path) {
12613
- if (!skip && path.parentPath.isCallExpression() && path.parentPath.get("callee") === path) {
12614
- path.stop();
12615
- path.getStatementParent().insertAfter(types.variableDeclaration("const", [types.variableDeclarator(id, init)]));
12616
- skip = true;
12617
- }
12618
- }
12619
- });
12620
- }
12621
- if (!skip) {
12622
- targetPath.scope.push(declarator);
12623
- }
12624
- const binding = targetPath.scope.getBinding(id.name);
12625
- if (binding) {
12626
- binding.path.skip();
12627
- }
12628
- }
12629
- });
12630
- }
12631
- const rewriteThisVisitor = {
12632
- Function(path) {
12633
- if (!path.isArrowFunctionExpression()) {
12634
- path.skip();
12635
- }
12636
- },
12637
- ThisExpression(path) {
12638
- this.rewrite("this", path);
12639
- }
12640
- };
12641
- function rewriteThisExpressions(rewritePath, targetPath) {
12642
- rewriteToNamedConstant(targetPath, rewrite => rewritePath.traverse(rewriteThisVisitor, {
12643
- rewrite
12644
- }));
12645
- }
12646
- function identifiersInLVal(id, result = []) {
12647
- switch (id.type) {
12648
- case "Identifier":
12649
- result.push(id);
12650
- break;
12651
- case "AssignmentPattern":
12652
- identifiersInLVal(id.left);
12653
- break;
12654
- case "ArrayPattern":
12655
- for (const element of id.elements) {
12656
- if (types.isLVal(element)) {
12657
- identifiersInLVal(element, result);
12658
- }
12659
- }
12660
- break;
12661
- case "RestElement":
12662
- identifiersInLVal(id.argument, result);
12663
- break;
12664
- case "ObjectPattern":
12665
- for (const property of id.properties) {
12666
- if (types.isRestElement(property)) {
12667
- identifiersInLVal(property.argument, result);
12668
- } else if (types.isPattern(property.value) || types.isIdentifier(property.value)) {
12669
- identifiersInLVal(property.value, result);
12670
- }
12671
- }
12672
- break;
12673
- default:
12674
- throw new Error(`Unexpected node is not an LVal: ${id}`);
12675
- }
12676
- return result;
12677
- }
12678
- function anyIdentifiersRequireHoisting(identifiers, path) {
12679
- const ancestry = path.getAncestry().reverse();
12680
- for (const id of identifiers) {
12681
- const binding = path.scope.getBinding(id.name);
12682
- if (!binding) {
12683
- return true;
12684
- }
12685
- const executingBeforePath = binding.referencePaths.find(referencePath => {
12686
- if (!referencePath.willIMaybeExecuteBefore(path)) {
12687
- return false;
12688
- }
12689
- const referenceAncestry = referencePath.getAncestry().reverse();
12690
- const length = ancestry.length < referenceAncestry.length ? ancestry.length : referenceAncestry.length;
12691
- for (let i = 1; i < length; i++) {
12692
- if (ancestry[i] !== referenceAncestry[i]) {
12693
- if (typeof ancestry[i].key === "number" && typeof referenceAncestry[i].key === "number" && ancestry[i].key < referenceAncestry[i].key) {
12694
- return false;
12695
- }
12696
- if ((ancestry[i - 1].isForOfStatement() || ancestry[i - 1].isForInStatement()) && ancestry[i].key === "left") {
12697
- return false;
12698
- }
12699
- if (ancestry[i - 1].isForStatement() && ancestry[i].key === "init") {
12700
- return false;
12701
- }
12702
- }
12703
- }
12704
- return true;
12705
- });
12706
- if (executingBeforePath) {
12707
- return true;
12708
- }
12709
- if (binding.referencePaths.length && path.getDeepestCommonAncestorFrom(binding.referencePaths.concat([path])) !== path.parentPath) {
12710
- return true;
12711
- }
12712
- }
12713
- return false;
12714
- }
12715
- const rewriteThisArgumentsAndHoistVisitor = {
12716
- Function(path) {
12717
- path.skip();
12718
- if (path.isArrowFunctionExpression()) {
12719
- path.traverse(rewriteThisVisitor, this);
12720
- }
12721
- },
12722
- Super(path) {
12723
- if (this.rewriteSuper) {
12724
- const parent = path.parentPath;
12725
- if (parent.isMemberExpression() && parent.get("object") === path) {
12726
- const property = parent.get("property");
12727
- if (parent.node.computed) {
12728
- if (!property.isStringLiteral()) {
12729
- throw path.buildCodeFrameError(`Expected a staticly resolvable super expression, got a computed expression of type ${property.node.type}`, TypeError);
12730
- }
12731
- }
12732
- const grandparent = parent.parentPath;
12733
- if (property.isIdentifier() && grandparent.isCallExpression() && grandparent.get("callee") === parent) {
12734
- this.rewrite("super$" + property.node.name, parent);
12735
- const args = grandparent.node.arguments.slice(0);
12736
- args.unshift(types.thisExpression());
12737
- grandparent.replaceWith(types.callExpression(types.memberExpression(parent.node, types.identifier("call")), args));
12738
- reregisterDeclarations(grandparent);
12739
- }
12740
- }
12741
- }
12742
- },
12743
- ThisExpression(path) {
12744
- this.rewrite("this", path);
12745
- },
12746
- Identifier(path) {
12747
- if (path.node.name === "arguments" && identifierSearchesScope(path)) {
12748
- this.rewrite("arguments", path);
12749
- }
12750
- },
12751
- VariableDeclaration(path) {
12752
- if (path.node.kind === "var") {
12753
- const declarations = path.get("declarations");
12754
- const mapped = declarations.map(declaration => ({
12755
- declaration,
12756
- identifiers: identifiersInLVal(declaration.node.id)
12757
- }));
12758
- if (mapped.some(({
12759
- identifiers
12760
- }) => anyIdentifiersRequireHoisting(identifiers, path))) {
12761
- if ((path.parentPath.isForInStatement() || path.parentPath.isForOfStatement()) && path.parentPath.get("left") === path && declarations.length === 1) {
12762
- path.replaceWith(declarations[0].node.id);
12763
- } else {
12764
- const expressions = [];
12765
- for (const {
12766
- declaration
12767
- } of mapped) {
12768
- if (declaration.node.init) {
12769
- expressions.push(types.assignmentExpression("=", declaration.node.id, declaration.node.init));
12770
- }
12771
- }
12772
- clearDeclarationData(path);
12773
- if (expressions.length === 0) {
12774
- path.remove();
12775
- } else if (expressions.length === 1) {
12776
- path.replaceWith(expressions[0]);
12777
- } else if (path.parentPath.isForStatement() && path.parentPath.get("init") === path) {
12778
- path.replaceWith(types.sequenceExpression(expressions));
12779
- } else {
12780
- path.replaceWithMultiple(expressions.map(expression => types.expressionStatement(expression)));
12781
- }
12782
- }
12783
- for (const {
12784
- identifiers
12785
- } of mapped) {
12786
- for (const id of identifiers) {
12787
- this.targetPath.scope.push({
12788
- id
12789
- });
12790
- }
12791
- }
12792
- }
12793
- }
12794
- },
12795
- FunctionDeclaration(path) {
12796
- let targetPath = path;
12797
- while (targetPath.parentPath.isBlockStatement()) {
12798
- targetPath = targetPath.parentPath;
12799
- }
12800
- for (const sibling of path.getAllPrevSiblings()) {
12801
- if (!sibling.isFunctionDeclaration()) {
12802
- const node = path.node;
12803
- path.remove();
12804
- reregisterDeclarations(sibling.insertBefore(node));
12805
- return;
12806
- }
12807
- }
12808
- }
12809
- };
12810
- function rewriteThisArgumentsAndHoistFunctions(rewritePath, targetPath, rewriteSuper) {
12811
- rewriteToNamedConstant(targetPath, rewrite => rewritePath.traverse(rewriteThisArgumentsAndHoistVisitor, {
12812
- targetPath,
12813
- rewrite,
12814
- rewriteSuper
12815
- }));
12816
- }
12817
- function translateTSParameterProperties(array) {
12818
- return array.map(n => n.type === "TSParameterProperty" ? n.parameter : n);
12819
- }
12820
- function functionize(state, params, expression, target, id) {
12821
- const translatedParams = translateTSParameterProperties(params);
12822
- if (!id && readConfigKey(state.opts, "target") === "es6") {
12823
- let newExpression = expression;
12824
- if (types.isBlockStatement(newExpression) && newExpression.body.length === 1) {
12825
- newExpression = newExpression.body[0];
12826
- }
12827
- if (types.isReturnStatement(newExpression) && newExpression.argument) {
12828
- newExpression = newExpression.argument;
12829
- }
12830
- const result = types.arrowFunctionExpression(translatedParams, types.isStatement(newExpression) && !types.isBlockStatement(newExpression) ? types.blockStatement([newExpression]) : newExpression);
12831
- let usesThisOrArguments = false;
12832
- pathForNewNode(result, target).traverse({
12833
- Function(path) {
12834
- path.skip();
12835
- },
12836
- ThisExpression(path) {
12837
- usesThisOrArguments = true;
12838
- path.stop();
12839
- },
12840
- Identifier(path) {
12841
- if (path.node.name === "arguments" && identifierSearchesScope(path)) {
12842
- usesThisOrArguments = true;
12843
- path.stop();
12844
- }
12845
- }
12846
- });
12847
- if (!usesThisOrArguments) {
12848
- return result;
12849
- }
12850
- }
12851
- if (types.isExpression(expression)) {
12852
- expression = returnStatement(expression);
12853
- }
12854
- if (!types.isBlockStatement(expression)) {
12855
- expression = blockStatement([expression]);
12856
- }
12857
- expression.body = removeUnnecessaryReturnStatements(expression.body);
12858
- return types.functionExpression(id, translatedParams, expression);
12859
- }
12860
- function blockStatement(statementOrStatements) {
12861
- if ("length" in statementOrStatements) {
12862
- return types.blockStatement(statementOrStatements.filter(statement => !types.isEmptyStatement(statement)));
12863
- } else if (!types.isBlockStatement(statementOrStatements)) {
12864
- return types.blockStatement([statementOrStatements]);
12865
- } else {
12866
- return statementOrStatements;
12867
- }
12868
- }
12869
- function unwrapReturnCallWithEmptyArguments(node, scope, additionalConstantNames) {
12870
- if (isContinuation(node)) {
12871
- const expression = expressionInSingleReturnStatement(node);
12872
- if (expression && types.isCallExpression(expression)) {
12873
- let callTarget;
12874
- switch (expression.arguments.length) {
12875
- case 0:
12876
- callTarget = expression.callee;
12877
- break;
12878
- case 1:
12879
- {
12880
- const callee = expression.callee;
12881
- const onlyArgument = expression.arguments[0];
12882
- if (types.isIdentifier(callee) && helperNameMap.get(callee) === "_call") {
12883
- callTarget = onlyArgument;
12884
- }
12885
- if (types.isIdentifier(callee) || types.isMemberExpression(callee)) {
12886
- switch (helperNameMap.get(callee)) {
12887
- case "_await":
12888
- case "_promiseResolve":
12889
- if (types.isCallExpression(onlyArgument) && onlyArgument.arguments.length === 0) {
12890
- callTarget = onlyArgument.callee;
12891
- }
12892
- break;
12893
- }
12894
- }
12895
- break;
12896
- }
12897
- }
12898
- if (callTarget && types.isExpression(callTarget)) {
12899
- if (types.isIdentifier(callTarget)) {
12900
- const binding = scope.getBinding(callTarget.name);
12901
- if (binding && binding.constant) {
12902
- return callTarget;
12903
- }
12904
- if (additionalConstantNames.indexOf(callTarget.name) !== -1) {
12905
- return callTarget;
12906
- }
12907
- } else if (isContinuation(callTarget)) {
12908
- return unwrapReturnCallWithEmptyArguments(callTarget, scope, additionalConstantNames);
12909
- }
12910
- }
12911
- }
12912
- }
12913
- return node;
12914
- }
12915
- function unwrapReturnCallWithPassthroughArgument(node, scope) {
12916
- if (isContinuation(node) && node.params.length >= 1) {
12917
- const expression = expressionInSingleReturnStatement(node);
12918
- if (expression && types.isCallExpression(expression) && expression.arguments.length === 1) {
12919
- const firstArgument = expression.arguments[0];
12920
- const firstParam = node.params[0];
12921
- if (types.isIdentifier(firstArgument) && types.isIdentifier(firstParam) && firstArgument.name === firstParam.name) {
12922
- if (types.isIdentifier(expression.callee)) {
12923
- const binding = scope.getBinding(expression.callee.name);
12924
- if (binding && binding.constant) {
12925
- return expression.callee;
12926
- }
12927
- if (Object.hasOwnProperty.call(constantStaticMethods, expression.callee.name)) {
12928
- return expression.callee;
12929
- }
12930
- } else if (types.isMemberExpression(expression.callee)) {
12931
- const propertyName = propertyNameOfMemberExpression(expression.callee);
12932
- if (propertyName !== undefined) {
12933
- const object = expression.callee.object;
12934
- if (types.isIdentifier(object) && Object.hasOwnProperty.call(constantStaticMethods, object.name) && !scope.getBinding(object.name)) {
12935
- const staticMethods = constantStaticMethods[object.name];
12936
- if (Object.hasOwnProperty.call(staticMethods, propertyName) && staticMethods[propertyName]) {
12937
- return expression.callee;
12938
- }
12939
- }
12940
- }
12941
- }
12942
- }
12943
- }
12944
- }
12945
- return node;
12946
- }
12947
- function isExpressionOfLiterals(path, literalNames) {
12948
- if (path.node === null || path.node === undefined) {
12949
- return true;
12950
- }
12951
- if (path.isIdentifier()) {
12952
- const name = path.node.name;
12953
- if (name === "undefined" && !path.scope.getBinding("undefined")) {
12954
- return true;
12955
- }
12956
- const binding = path.parentPath.scope.getBinding(name);
12957
- if (binding) {
12958
- return binding.constant;
12959
- }
12960
- if (literalNames.indexOf(name) !== -1) {
12961
- return true;
12962
- }
12963
- if (Object.hasOwnProperty.call(constantStaticMethods, name) && !path.scope.getBinding(name)) {
12964
- return true;
12965
- }
12966
- return false;
12967
- }
12968
- if (path.isMemberExpression()) {
12969
- const object = path.get("object");
12970
- if (object.isIdentifier()) {
12971
- const propertyName = propertyNameOfMemberExpression(path.node);
12972
- if (propertyName !== undefined && Object.hasOwnProperty.call(constantStaticMethods, object.node.name) && !path.scope.getBinding(object.node.name)) {
12973
- const staticMethods = constantStaticMethods[object.node.name];
12974
- if (Object.hasOwnProperty.call(staticMethods, propertyName) && staticMethods[propertyName]) {
12975
- return true;
12976
- }
12977
- }
12978
- }
12979
- return false;
12980
- }
12981
- if (path.isBooleanLiteral()) {
12982
- return true;
12983
- }
12984
- if (path.isNumericLiteral()) {
12985
- return true;
12986
- }
12987
- if (path.isStringLiteral()) {
12988
- return true;
12989
- }
12990
- if (path.isArrayExpression()) {
12991
- return path.get("elements").every(element => element === null || element.node === null ? true : isExpressionOfLiterals(element, literalNames));
12992
- }
12993
- if (path.isNullLiteral()) {
12994
- return true;
12995
- }
12996
- if (path.isObjectExpression()) {
12997
- return path.get("properties").every(property => {
12998
- if (property.isObjectProperty()) {
12999
- if (!property.node.computed || isExpressionOfLiterals(property.get("key"), literalNames)) {
13000
- return isExpressionOfLiterals(property.get("value"), literalNames);
13001
- }
13002
- } else {
13003
- return true;
13004
- }
13005
- });
13006
- }
13007
- if (path.isUnaryExpression()) {
13008
- return isExpressionOfLiterals(path.get("argument"), literalNames);
13009
- }
13010
- if (path.isLogicalExpression()) {
13011
- return isExpressionOfLiterals(path.get("left"), literalNames) && isExpressionOfLiterals(path.get("right"), literalNames);
13012
- }
13013
- if (path.isBinaryExpression()) {
13014
- return isExpressionOfLiterals(path.get("left"), literalNames) && isExpressionOfLiterals(path.get("right"), literalNames);
13015
- }
13016
- if (path.isConditionalExpression()) {
13017
- return isExpressionOfLiterals(path.get("test"), literalNames) && isExpressionOfLiterals(path.get("consequent"), literalNames) && isExpressionOfLiterals(path.get("alternate"), literalNames);
13018
- }
13019
- if (path.isExpression() && isContinuation(path.node)) {
13020
- return true;
13021
- }
13022
- return false;
13023
- }
13024
- function generateIdentifierForPath(path) {
13025
- const node = path.node;
13026
- if (node) {
13027
- const result = path.scope.generateUidIdentifierBasedOnNode(node, "temp");
13028
- if (!path.isIdentifier() || path.node.name !== result.name) {
13029
- return result;
13030
- }
13031
- }
13032
- return path.scope.generateUidIdentifier("temp");
13033
- }
13034
- function booleanLiteral(value, minify) {
13035
- return minify ? types.numericLiteral(value ? 1 : 0) : types.booleanLiteral(value);
13036
- }
13037
- function conditionalExpression(test, consequent, alternate) {
13038
- const looseValue = extractLooseBooleanValue(test);
13039
- if (typeof looseValue !== "undefined") {
13040
- return looseValue ? consequent : alternate;
13041
- }
13042
- while (types.isUnaryExpression(test) && test.operator === "!") {
13043
- test = test.argument;
13044
- const temp = consequent;
13045
- consequent = alternate;
13046
- alternate = temp;
13047
- }
13048
- if (isValueLiteral(consequent) && isValueLiteral(alternate) && consequent.value === alternate.value || types.isNullLiteral(consequent) && types.isNullLiteral(alternate) || types.isIdentifier(consequent) && types.isIdentifier(alternate) && consequent.name === alternate.name) {
13049
- if (types.isIdentifier(test)) {
13050
- return consequent;
13051
- }
13052
- }
13053
- if (types.isIdentifier(test)) {
13054
- consequent = simplifyWithIdentifier(consequent, test, true);
13055
- alternate = simplifyWithIdentifier(alternate, test, false);
13056
- }
13057
- return types.conditionalExpression(test, consequent, alternate);
13058
- }
13059
- function extractBooleanValue(node) {
13060
- if (types.isBooleanLiteral(node)) {
13061
- return node.value;
13062
- }
13063
- if (types.isUnaryExpression(node)) {
13064
- if (node.operator === "!") {
13065
- const result = extractLooseBooleanValue(node.argument);
13066
- return typeof result === "undefined" ? undefined : !result;
13067
- } else if (node.operator === "void") {
13068
- return typeof extractLooseBooleanValue(node.argument) !== "undefined" ? false : undefined;
13069
- }
13070
- }
13071
- }
13072
- function extractLooseBooleanValue(node) {
13073
- if (isValueLiteral(node)) {
13074
- return !!node.value;
13075
- }
13076
- if (types.isNullLiteral(node)) {
13077
- return false;
13078
- }
13079
- if (types.isIdentifier(node)) {
13080
- if (alwaysTruthy.indexOf(node.name) !== -1) {
13081
- return true;
13082
- }
13083
- if (node.name === "undefined") {
13084
- return false;
13085
- }
13086
- }
13087
- return extractBooleanValue(node);
13088
- }
13089
- function logicalOr(left, right) {
13090
- if (extractLooseBooleanValue(left) === true) {
13091
- return left;
13092
- } else if (extractBooleanValue(left) === false) {
13093
- return right;
13094
- } else {
13095
- return types.logicalExpression("||", left, right);
13096
- }
13097
- }
13098
- function logicalOrLoose(left, right, minify) {
13099
- switch (extractLooseBooleanValue(left)) {
13100
- case false:
13101
- return extractLooseBooleanValue(right) === false ? booleanLiteral(false, minify) : right;
13102
- case true:
13103
- return booleanLiteral(true, minify);
13104
- default:
13105
- switch (extractLooseBooleanValue(right)) {
13106
- case false:
13107
- return left;
13108
- case true:
13109
- return booleanLiteral(true, minify);
13110
- default:
13111
- return types.logicalExpression("||", left, right);
13112
- }
13113
- }
13114
- }
13115
- function logicalAnd(left, right, extract = extractBooleanValue) {
13116
- switch (extract(left)) {
13117
- case true:
13118
- return left;
13119
- case false:
13120
- return right;
13121
- default:
13122
- return types.logicalExpression("&&", left, right);
13123
- }
13124
- }
13125
- function logicalNot(node, minify) {
13126
- const literalValue = extractLooseBooleanValue(node);
13127
- if (typeof literalValue !== "undefined") {
13128
- return booleanLiteral(!literalValue, minify);
13129
- }
13130
- if (types.isUnaryExpression(node) && node.operator === "!" && types.isUnaryExpression(node.argument) && node.argument.operator === "!") {
13131
- return node.argument;
13132
- }
13133
- return types.unaryExpression("!", node);
13134
- }
13135
- function unwrapSpreadElement(path) {
13136
- if (path.node === null) {
13137
- return path;
13138
- }
13139
- if (path.node.type === "JSXNamespacedName") {
13140
- return path;
13141
- }
13142
- if (path.isExpression()) {
13143
- return path;
13144
- }
13145
- if (path.isSpreadElement()) {
13146
- return path.get("argument");
13147
- }
13148
- if (isArgumentPlaceholder(path)) {
13149
- return path;
13150
- }
13151
- throw path.buildCodeFrameError(`Expected either an expression or a spread element, got a ${path.type}!`, TypeError);
13152
- }
13153
- function findDeclarationToReuse(path) {
13154
- while (path) {
13155
- const parent = path.parentPath;
13156
- if (parent === null) {
13157
- break;
13158
- }
13159
- if (parent.isVariableDeclarator()) {
13160
- const id = parent.get("id");
13161
- if (id.isIdentifier() || id.isPattern()) {
13162
- return parent;
13163
- }
13164
- }
13165
- let other;
13166
- if (parent.isConditionalExpression()) {
13167
- const test = parent.get("test");
13168
- if (path === test) {
13169
- break;
13170
- }
13171
- const consequent = parent.get("consequent");
13172
- const alternate = parent.get("alternate");
13173
- other = consequent === path ? alternate : consequent;
13174
- } else if (parent.isLogicalExpression()) {
13175
- const left = parent.get("left");
13176
- const right = parent.get("right");
13177
- other = left === path ? right : left;
13178
- } else {
13179
- break;
13180
- }
13181
- const otherAwaitPath = findAwaitOrYieldPath(other);
13182
- if (otherAwaitPath === other || !otherAwaitPath) {
13183
- path = parent;
13184
- } else {
13185
- break;
13186
- }
13187
- }
13188
- }
13189
- function extractDeclarations(state, originalAwaitPath, awaitExpression, additionalConstantNames) {
13190
- let awaitPath = originalAwaitPath;
13191
- const reusingExisting = findDeclarationToReuse(awaitPath);
13192
- const reusingExistingId = reusingExisting ? reusingExisting.get("id") : undefined;
13193
- const existingIdentifier = reusingExistingId && (reusingExistingId.isIdentifier() || reusingExistingId.isPattern()) ? reusingExistingId.node : undefined;
13194
- let resultIdentifier;
13195
- if (!awaitPath.parentPath.isSequenceExpression() || !(awaitPath.key < awaitPath.container.length - 1)) {
13196
- const argument = originalAwaitPath.get("argument");
13197
- if (argument.isExpression()) {
13198
- resultIdentifier = existingIdentifier || generateIdentifierForPath(argument);
13199
- }
13200
- }
13201
- originalAwaitPath.replaceWith(types.isIdentifier(resultIdentifier) ? resultIdentifier : types.numericLiteral(0));
13202
- let declarations = [];
13203
- const isYield = originalAwaitPath.isYieldExpression();
13204
- let directExpression = booleanLiteral(false, readConfigKey(state.opts, "minify"));
13205
- for (;;) {
13206
- const parent = awaitPath.parentPath;
13207
- if (parent.isVariableDeclarator()) {
13208
- const beforeDeclarations = [];
13209
- let skipLiterals = true;
13210
- for (let key = parent.key - 1; key >= 0; --key) {
13211
- const sibling = parent.getSibling(key);
13212
- if (sibling.isVariableDeclarator()) {
13213
- const init = sibling.get("init");
13214
- if (!skipLiterals || init && !isExpressionOfLiterals(init, additionalConstantNames)) {
13215
- skipLiterals = false;
13216
- beforeDeclarations.unshift(sibling.node);
13217
- sibling.remove();
13218
- }
13219
- } else {
13220
- throw sibling.buildCodeFrameError(`Expected a variable declarator, got a ${sibling.type}!`, TypeError);
13221
- }
13222
- }
13223
- if (beforeDeclarations.length) {
13224
- declarations = declarations.concat(beforeDeclarations.concat(declarations));
13225
- }
13226
- } else if (parent.isLogicalExpression()) {
13227
- const left = parent.get("left");
13228
- if (awaitPath !== left) {
13229
- if (!isYield && !isExpressionOfLiterals(left, additionalConstantNames)) {
13230
- const leftIdentifier = generateIdentifierForPath(left);
13231
- declarations = declarations.map(declaration => declaration.init ? types.variableDeclarator(declaration.id, logicalAnd(parent.node.operator === "||" ? logicalNot(leftIdentifier) : leftIdentifier, declaration.init)) : declaration);
13232
- declarations.unshift(types.variableDeclarator(leftIdentifier, left.node));
13233
- left.replaceWith(leftIdentifier);
13234
- }
13235
- const isOr = parent.node.operator === "||";
13236
- awaitExpression = (isOr ? logicalOr : logicalAnd)(left.node, awaitExpression);
13237
- if (!isYield) {
13238
- directExpression = logicalOrLoose(isOr ? left.node : logicalNot(left.node), directExpression, readConfigKey(state.opts, "minify"));
13239
- }
13240
- if (awaitPath === originalAwaitPath) {
13241
- if (resultIdentifier) {
13242
- parent.replaceWith(resultIdentifier);
13243
- } else {
13244
- resultIdentifier = existingIdentifier || generateIdentifierForPath(originalAwaitPath.get("argument"));
13245
- parent.replaceWith(resultIdentifier);
13246
- }
13247
- awaitPath = parent;
13248
- continue;
13249
- }
13250
- }
13251
- } else if (parent.isBinaryExpression()) {
13252
- const left = parent.get("left");
13253
- if (awaitPath !== left) {
13254
- if (!isExpressionOfLiterals(left, additionalConstantNames) && left.node.type !== "PrivateName") {
13255
- const leftIdentifier = generateIdentifierForPath(left);
13256
- declarations.unshift(types.variableDeclarator(leftIdentifier, left.node));
13257
- left.replaceWith(leftIdentifier);
13258
- }
13259
- }
13260
- } else if (parent.isSequenceExpression()) {
13261
- const children = parent.get("expressions");
13262
- const position = children.indexOf(awaitPath);
13263
- for (var i = 0; i < position; i++) {
13264
- const expression = children[i];
13265
- if (!isExpressionOfLiterals(expression, additionalConstantNames)) {
13266
- const sequenceIdentifier = generateIdentifierForPath(expression);
13267
- declarations.unshift(types.variableDeclarator(sequenceIdentifier, expression.node));
13268
- }
13269
- expression.remove();
13270
- }
13271
- if (position === children.length - 1) {
13272
- parent.replaceWith(children[position]);
13273
- }
13274
- } else if (parent.isConditionalExpression()) {
13275
- const test = parent.get("test");
13276
- if (awaitPath !== test) {
13277
- let testNode = test.node;
13278
- const consequent = parent.get("consequent");
13279
- const alternate = parent.get("alternate");
13280
- const other = consequent === awaitPath ? alternate : consequent;
13281
- const otherAwaitPath = findAwaitOrYieldPath(other);
13282
- let testIdentifier;
13283
- const isBoth = consequent === awaitPath && otherAwaitPath === alternate;
13284
- if (!(isBoth && awaitPath === originalAwaitPath) && !isExpressionOfLiterals(test, additionalConstantNames)) {
13285
- testIdentifier = generateIdentifierForPath(test);
13286
- }
13287
- declarations = declarations.map(declaration => declaration.init ? types.variableDeclarator(declaration.id, (consequent === awaitPath ? logicalAnd : logicalOr)(testIdentifier || testNode, declaration.init)) : declaration);
13288
- if (testIdentifier) {
13289
- declarations.unshift(types.variableDeclarator(testIdentifier, testNode));
13290
- test.replaceWith(testIdentifier);
13291
- testNode = testIdentifier;
13292
- }
13293
- if (isBoth && otherAwaitPath) {
13294
- awaitExpression = conditionalExpression(testNode, awaitExpression, otherAwaitPath.node.argument || types.identifier("undefined"));
13295
- if (!resultIdentifier) {
13296
- resultIdentifier = existingIdentifier || generateIdentifierForPath(originalAwaitPath.get("argument"));
13297
- }
13298
- alternate.replaceWith(resultIdentifier);
13299
- parent.replaceWith(resultIdentifier);
13300
- } else {
13301
- if (!isYield) {
13302
- directExpression = logicalOrLoose(consequent !== awaitPath ? testNode : logicalNot(testNode), directExpression, readConfigKey(state.opts, "minify"));
13303
- }
13304
- if (otherAwaitPath) {
13305
- awaitExpression = consequent !== awaitPath ? conditionalExpression(testNode, types.numericLiteral(0), awaitExpression) : conditionalExpression(testNode, awaitExpression, types.numericLiteral(0));
13306
- } else {
13307
- awaitExpression = consequent !== awaitPath ? conditionalExpression(testNode, other.node, awaitExpression) : conditionalExpression(testNode, awaitExpression, other.node);
13308
- if (!resultIdentifier) {
13309
- resultIdentifier = existingIdentifier || generateIdentifierForPath(originalAwaitPath.get("argument"));
13310
- }
13311
- if (awaitPath === originalAwaitPath) {
13312
- parent.replaceWith(resultIdentifier);
13313
- awaitPath = parent;
13314
- continue;
13315
- }
13316
- other.replaceWith(resultIdentifier);
13317
- }
13318
- }
13319
- }
13320
- } else if (parent.isCallExpression()) {
13321
- const callee = parent.get("callee");
13322
- if (callee !== awaitPath) {
13323
- for (const arg of parent.get("arguments")) {
13324
- const spreadArg = unwrapSpreadElement(arg);
13325
- if (spreadArg === awaitPath || arg === awaitPath) {
13326
- break;
13327
- }
13328
- if (spreadArg.isExpression() && !isExpressionOfLiterals(spreadArg, additionalConstantNames)) {
13329
- const argIdentifier = generateIdentifierForPath(spreadArg);
13330
- declarations.unshift(types.variableDeclarator(argIdentifier, spreadArg.node));
13331
- spreadArg.replaceWith(argIdentifier);
13332
- }
13333
- }
13334
- if (!isExpressionOfLiterals(callee, additionalConstantNames) && typeof promiseCallExpressionType(parent.node) === "undefined") {
13335
- if (callee.isMemberExpression()) {
13336
- const object = callee.get("object");
13337
- const property = callee.get("property");
13338
- let objectDeclarator;
13339
- let staticMethods = {};
13340
- let constantObject = false;
13341
- if (object.isIdentifier() && Object.hasOwnProperty.call(constantStaticMethods, object.node.name) && !callee.scope.getBinding(object.node.name)) {
13342
- constantObject = true;
13343
- staticMethods = constantStaticMethods[object.node.name];
13344
- } else if (isExpressionOfLiterals(object, additionalConstantNames)) {
13345
- constantObject = true;
13346
- }
13347
- if (!constantObject) {
13348
- const objectIdentifier = generateIdentifierForPath(object);
13349
- objectDeclarator = types.variableDeclarator(objectIdentifier, object.node);
13350
- object.replaceWith(objectIdentifier);
13351
- }
13352
- if (!callee.node.computed && property.isIdentifier() && (property.node.name === "call" || Object.hasOwnProperty.call(staticMethods, property.node.name))) ; else {
13353
- const calleeIdentifier = generateIdentifierForPath(property);
13354
- const calleeNode = callee.node;
13355
- const newArguments = parent.node.arguments.slice();
13356
- newArguments.unshift(Object.assign({}, object.node));
13357
- parent.replaceWith(types.callExpression(types.memberExpression(calleeIdentifier, types.identifier("call")), newArguments));
13358
- declarations.unshift(types.variableDeclarator(calleeIdentifier, calleeNode));
13359
- }
13360
- if (typeof objectDeclarator !== "undefined") {
13361
- declarations.unshift(objectDeclarator);
13362
- }
13363
- } else if (!callee.isIdentifier() || !(helperNameMap.has(callee.node) || (awaitPath.scope.getBinding(callee.node.name) || {
13364
- constant: false
13365
- }).constant)) {
13366
- const calleeIdentifier = generateIdentifierForPath(callee);
13367
- const calleeNode = callee.node;
13368
- callee.replaceWith(calleeIdentifier);
13369
- declarations.unshift(types.variableDeclarator(calleeIdentifier, discardingIntrinsics(calleeNode)));
13370
- }
13371
- }
13372
- }
13373
- } else if (parent.isArrayExpression()) {
13374
- for (const element of parent.get("elements")) {
13375
- const spreadElement = unwrapSpreadElement(element);
13376
- if (element === awaitPath || spreadElement === awaitPath) {
13377
- break;
13378
- }
13379
- if (spreadElement.isExpression() && !isExpressionOfLiterals(spreadElement, additionalConstantNames)) {
13380
- const elementIdentifier = generateIdentifierForPath(spreadElement);
13381
- declarations.unshift(types.variableDeclarator(elementIdentifier, spreadElement.node));
13382
- spreadElement.replaceWith(elementIdentifier);
13383
- }
13384
- }
13385
- } else if (parent.isObjectExpression()) {
13386
- for (const prop of parent.get("properties")) {
13387
- if (prop === awaitPath) {
13388
- break;
13389
- }
13390
- if (prop.isObjectProperty()) {
13391
- if (prop.node.computed) {
13392
- const propKey = prop.get("key");
13393
- if (propKey === awaitPath) {
13394
- break;
13395
- }
13396
- if (propKey.isExpression() && !isExpressionOfLiterals(propKey, additionalConstantNames)) {
13397
- const keyIdentifier = generateIdentifierForPath(propKey);
13398
- declarations.unshift(types.variableDeclarator(keyIdentifier, propKey.node));
13399
- propKey.replaceWith(keyIdentifier);
13400
- }
13401
- }
13402
- const propValue = prop.get("value");
13403
- if (propValue === awaitPath) {
13404
- break;
13405
- }
13406
- if (propValue.isExpression() && !isExpressionOfLiterals(propValue, additionalConstantNames)) {
13407
- const propIdentifier = generateIdentifierForPath(propValue);
13408
- declarations.unshift(types.variableDeclarator(propIdentifier, propValue.node));
13409
- propValue.replaceWith(propIdentifier);
13410
- }
13411
- }
13412
- }
13413
- }
13414
- if (parent.isStatement()) {
13415
- return {
13416
- declarationKind: reusingExisting ? reusingExisting.parent.kind : "const",
13417
- declarations,
13418
- awaitExpression,
13419
- directExpression,
13420
- reusingExisting,
13421
- resultIdentifier
13422
- };
13423
- }
13424
- awaitPath = parent;
13425
- }
13426
- }
13427
- function skipNode(path) {
13428
- path.skip();
13429
- }
13430
- const awaitPathVisitor = {
13431
- Function: skipNode,
13432
- AwaitExpression(path) {
13433
- this.result = path;
13434
- path.stop();
13435
- },
13436
- YieldExpression(path) {
13437
- this.result = path;
13438
- path.stop();
13439
- }
13440
- };
13441
- function findAwaitOrYieldPath(path) {
13442
- if (path.isAwaitExpression() || path.isYieldExpression()) {
13443
- return path;
13444
- }
13445
- const state = Object.create(null);
13446
- path.traverse(awaitPathVisitor, state);
13447
- return state.result;
13448
- }
13449
- function buildBreakExitCheck(state, exitIdentifier, breakIdentifiers) {
13450
- if (breakIdentifiers !== undefined && breakIdentifiers.length > 0) {
13451
- const minify = readConfigKey(state.opts, "minify");
13452
- const first = breakIdentifiers[0].identifier;
13453
- const partial = breakIdentifiers.slice(1).reduce((accumulator, {
13454
- identifier
13455
- }) => logicalOrLoose(accumulator, identifier, minify), first);
13456
- return exitIdentifier ? logicalOrLoose(partial, exitIdentifier, minify) : partial;
13457
- } else {
13458
- return exitIdentifier;
13459
- }
13460
- }
13461
- function pushMissing(destination, source) {
13462
- for (var value of source) {
13463
- var index = destination.indexOf(value);
13464
- if (index < 0) {
13465
- destination.push(value);
13466
- }
13467
- }
13468
- }
13469
- function setBreakIdentifier(value, breakIdentifier) {
13470
- return types.assignmentExpression("=", breakIdentifier.identifier, value);
13471
- }
13472
- function setBreakIdentifiers(breakIdentifiers, pluginState) {
13473
- return breakIdentifiers.reduce(setBreakIdentifier, booleanLiteral(true, readConfigKey(pluginState.opts, "minify")));
13474
- }
13475
- function expressionNeverThrows(expression) {
13476
- return isValueLiteral(expression) || types.isIdentifier(expression) || types.isUnaryExpression(expression) && isValueLiteral(expression.argument);
13477
- }
13478
- const replaceReturnsAndBreaksVisitor = {
13479
- Function: skipNode,
13480
- ReturnStatement(path) {
13481
- if (!skipNodeSet.has(path.node) && this.exitIdentifier) {
13482
- const minify = readConfigKey(this.pluginState.opts, "minify");
13483
- if (path.node.argument) {
13484
- if (minify && extractLooseBooleanValue(path.node.argument) === true) {
13485
- path.replaceWith(returnStatement(types.assignmentExpression("=", this.exitIdentifier, path.node.argument), path.node));
13486
- } else if (expressionNeverThrows(path.node.argument)) {
13487
- path.replaceWithMultiple([types.expressionStatement(types.assignmentExpression("=", this.exitIdentifier, booleanLiteral(true, minify))), returnStatement(path.node.argument, path.node)]);
13488
- } else {
13489
- const tempIdentifier = path.scope.generateUidIdentifierBasedOnNode(path.node.argument, "temp");
13490
- path.replaceWithMultiple([types.variableDeclaration("const", [types.variableDeclarator(tempIdentifier, path.node.argument)]), types.expressionStatement(types.assignmentExpression("=", this.exitIdentifier, booleanLiteral(true, minify))), returnStatement(tempIdentifier, path.node)]);
13491
- }
13492
- } else {
13493
- path.replaceWithMultiple([types.expressionStatement(types.assignmentExpression("=", this.exitIdentifier, booleanLiteral(true, minify))), returnStatement(undefined, path.node)]);
13494
- }
13495
- }
13496
- },
13497
- SwitchStatement: {
13498
- enter() {
13499
- this.switchCount++;
13500
- },
13501
- exit() {
13502
- this.switchCount--;
13503
- }
13504
- },
13505
- Loop: {
13506
- enter(path) {
13507
- const parent = path.parentPath;
13508
- this.breakIdentifiers.unshift({
13509
- identifier: types.identifier("break"),
13510
- path,
13511
- name: parent.isLabeledStatement() ? parent.node.label.name : undefined,
13512
- isAsync: false
13513
- });
13514
- },
13515
- exit() {
13516
- this.breakIdentifiers.shift();
13517
- }
13518
- },
13519
- BreakStatement(path) {
13520
- const label = path.node.label;
13521
- if (label || this.switchCount === 0) {
13522
- const index = label ? this.breakIdentifiers.findIndex(breakIdentifier => breakIdentifier.name === label.name) : 0;
13523
- const replace = returnStatement(undefined, path.node);
13524
- if (index !== -1 && this.breakIdentifiers.length) {
13525
- if (!this.breakIdentifiers[index].isAsync) {
13526
- return;
13527
- }
13528
- const used = this.breakIdentifiers.slice(0, index + 1);
13529
- if (used.length) {
13530
- pushMissing(this.usedIdentifiers, used);
13531
- path.replaceWithMultiple([types.expressionStatement(setBreakIdentifiers(used, this.pluginState)), replace]);
13532
- return;
13533
- }
13534
- }
13535
- path.replaceWith(replace);
13536
- }
13537
- },
13538
- ContinueStatement(path) {
13539
- const label = path.node.label;
13540
- const index = label ? this.breakIdentifiers.findIndex(breakIdentifier => breakIdentifier.name === label.name) : 0;
13541
- const replace = returnStatement(undefined, path.node);
13542
- if (index !== -1 && this.breakIdentifiers.length) {
13543
- if (!this.breakIdentifiers[index].isAsync) {
13544
- return;
13545
- }
13546
- const used = this.breakIdentifiers.slice(0, index);
13547
- if (used.length) {
13548
- pushMissing(this.usedIdentifiers, used);
13549
- path.replaceWithMultiple([types.expressionStatement(setBreakIdentifiers(used, this.pluginState)), replace]);
13550
- return;
13551
- }
13552
- }
13553
- path.replaceWith(replace);
13554
- }
13555
- };
13556
- function replaceReturnsAndBreaks(pluginState, path, exitIdentifier, existingUsedIdentifiers) {
13557
- const usedIdentifiers = [];
13558
- if (existingUsedIdentifiers !== undefined) {
13559
- for (const item of existingUsedIdentifiers) {
13560
- if (path.parentPath === null || path.parentPath.scope.getBinding(item.identifier.name) === path.scope.getBinding(item.identifier.name)) {
13561
- usedIdentifiers.push(item);
13562
- }
13563
- }
13564
- }
13565
- const state = {
13566
- pluginState,
13567
- exitIdentifier,
13568
- breakIdentifiers: breakContinueStackForPath(path),
13569
- usedIdentifiers,
13570
- switchCount: 0
13571
- };
13572
- path.traverse(replaceReturnsAndBreaksVisitor, state);
13573
- for (const {
13574
- identifier,
13575
- path: identifierPath
13576
- } of usedIdentifiers) {
13577
- const parentScope = identifierPath.parentPath.scope;
13578
- if (!parentScope.getBinding(identifier.name)) {
13579
- parentScope.push({
13580
- kind: "let",
13581
- id: identifier,
13582
- init: readConfigKey(pluginState.opts, "minify") ? undefined : booleanLiteral(false, readConfigKey(pluginState.opts, "minify"))
13583
- });
13584
- }
13585
- }
13586
- return usedIdentifiers;
13587
- }
13588
- function breakIdentifierForPath(path) {
13589
- let result = breakIdentifierMap.get(path.node);
13590
- if (!result) {
13591
- result = path.scope.generateUidIdentifier(path.parentPath !== null && path.parentPath.isLabeledStatement() ? path.parentPath.node.label.name + "Interrupt" : "interrupt");
13592
- breakIdentifierMap.set(path.node, result);
13593
- }
13594
- return result;
13595
- }
13596
- const simpleBreakOrContinueReferencesVisitor = {
13597
- Function: skipNode,
13598
- Loop: skipNode,
13599
- SwitchStatement: skipNode,
13600
- BreakStatement(path) {
13601
- if (!path.node.label) {
13602
- this.references.push(path);
13603
- }
13604
- },
13605
- ReturnStatement(path) {
13606
- const originalNode = originalNodeMap.get(path.node);
13607
- if (originalNode) {
13608
- traverse(wrapNodeInStatement(originalNode), simpleBreakOrContinueReferencesVisitor, path.scope, this, path);
13609
- path.skip();
13610
- }
13611
- }
13612
- };
13613
- function simpleBreakOrContinueReferences(path) {
13614
- const state = {
13615
- references: []
13616
- };
13617
- path.traverse(simpleBreakOrContinueReferencesVisitor, state);
13618
- return state.references;
13619
- }
13620
- const namedLabelReferencesVisitor = {
13621
- Function: skipNode,
13622
- BreakStatement(path) {
13623
- if (path.node.label && path.node.label.name === this.name) {
13624
- this.breaks.push(path);
13625
- }
13626
- },
13627
- ContinueStatement(path) {
13628
- if (path.node.label && path.node.label.name === this.name) {
13629
- this.continues.push(path);
13630
- }
13631
- },
13632
- ReturnStatement(path) {
13633
- const originalNode = originalNodeMap.get(path.node);
13634
- if (originalNode) {
13635
- traverse(wrapNodeInStatement(originalNode), namedLabelReferencesVisitor, path.scope, this, path);
13636
- path.skip();
13637
- }
13638
- }
13639
- };
13640
- function namedLabelReferences(labelPath, targetPath) {
13641
- const state = {
13642
- name: labelPath.node.label.name,
13643
- breaks: [],
13644
- continues: []
13645
- };
13646
- targetPath.traverse(namedLabelReferencesVisitor, state);
13647
- return state;
13648
- }
13649
- function breakContinueStackForPath(path) {
13650
- let current = path;
13651
- const result = [];
13652
- while (current && !current.isFunction()) {
13653
- if (current.isLoop() || current.isSwitchStatement()) {
13654
- const breaks = pathsBreak(current);
13655
- if (breaks.any && (!current.isSwitchStatement() || !breaks.all)) {
13656
- const simpleReferences = simpleBreakOrContinueReferences(current);
13657
- if (current.parentPath.isLabeledStatement()) {
13658
- const refs = namedLabelReferences(current.parentPath, path);
13659
- if (simpleReferences.length || refs.breaks.length || refs.continues.length) {
13660
- result.push({
13661
- identifier: breakIdentifierForPath(current),
13662
- name: current.parentPath.node.label.name,
13663
- path: current.parentPath,
13664
- isAsync: true
13665
- });
13666
- }
13667
- current = current.parentPath;
13668
- } else if (simpleReferences.length) {
13669
- result.push({
13670
- identifier: breakIdentifierForPath(current),
13671
- path: current,
13672
- isAsync: true
13673
- });
13674
- }
13675
- }
13676
- } else if (current.isLabeledStatement()) {
13677
- const refs = namedLabelReferences(current, path);
13678
- if (refs.breaks.length || refs.continues.length) {
13679
- result.push({
13680
- identifier: breakIdentifierForPath(current.get("body")),
13681
- name: current.node.label.name,
13682
- path: current,
13683
- isAsync: true
13684
- });
13685
- }
13686
- }
13687
- current = current.parentPath;
13688
- }
13689
- return result;
13690
- }
13691
- function isForAwaitStatement(path) {
13692
- return path.isForAwaitStatement && path.node ? path.isForAwaitStatement() : false;
13693
- }
13694
- function isArgumentPlaceholder(path) {
13695
- return path.node.type === "ArgumentPlaceholder";
13696
- }
13697
- function getStatementOrArrowBodyParent(path) {
13698
- let parent = path;
13699
- while (parent) {
13700
- if (parent.isStatement()) {
13701
- return parent;
13702
- }
13703
- if (parent.isArrowFunctionExpression()) {
13704
- return parent.get("body");
13705
- }
13706
- parent = parent.parentPath;
13707
- }
13708
- throw path.buildCodeFrameError(`Expected a statement parent!`, TypeError);
13709
- }
13710
- function addConstantNames(additionalConstantNames, node) {
13711
- if (types.isIdentifier(node)) {
13712
- if (additionalConstantNames.indexOf(node.name) === -1) {
13713
- additionalConstantNames.push(node.name);
13714
- }
13715
- } else if (types.isArrayPattern(node)) {
13716
- for (const element of node.elements) {
13717
- if (types.isIdentifier(element) || types.isPattern(element) || types.isRestElement(element)) {
13718
- addConstantNames(additionalConstantNames, element);
13719
- }
13720
- }
13721
- } else if (types.isObjectPattern(node)) {
13722
- for (const property of node.properties) {
13723
- if (types.isObjectProperty(property)) {
13724
- addConstantNames(additionalConstantNames, property.key);
13725
- } else if (types.isRestElement(property)) {
13726
- addConstantNames(additionalConstantNames, property.argument);
13727
- }
13728
- }
13729
- } else if (types.isRestElement(node)) {
13730
- addConstantNames(additionalConstantNames, node.argument);
13731
- }
13732
- }
13733
- function yieldOnExpression(state, expression) {
13734
- const generatorIdentifier = state.generatorIdentifier;
13735
- if (typeof generatorIdentifier === "undefined") {
13736
- throw new Error("Encountered a yield expression outside a generator function!");
13737
- }
13738
- const callee = types.memberExpression(generatorIdentifier, types.identifier("_yield"));
13739
- helperNameMap.set(callee, "_yield");
13740
- return types.callExpression(callee, [expression]);
13741
- }
13742
- function rewriteAwaitOrYieldPath(rewritePath) {
13743
- const state = this;
13744
- const pluginState = state.generatorState.state;
13745
- const path = state.path;
13746
- const additionalConstantNames = state.additionalConstantNames;
13747
- let awaitPath;
13748
- let processExpressions;
13749
- const rewritePathCopy = rewritePath;
13750
- if (rewritePath.isAwaitExpression() || rewritePath.isYieldExpression()) {
13751
- awaitPath = rewritePath;
13752
- processExpressions = true;
13753
- } else if (rewritePath.isForOfStatement() || isForAwaitStatement(rewritePath)) {
13754
- const left = rewritePath.get("left");
13755
- if (left.isAwaitExpression()) {
13756
- awaitPath = left.get("argument");
13757
- } else if (left.isSpreadElement()) {
13758
- awaitPath = unwrapSpreadElement(left);
13759
- } else {
13760
- awaitPath = left;
13761
- }
13762
- processExpressions = false;
13763
- } else {
13764
- throw rewritePathCopy.buildCodeFrameError(`Expected either an await expression or a for await statement, got a ${rewritePathCopy.type}!`, TypeError);
13765
- }
13766
- const paths = [];
13767
- {
13768
- let targetPath = awaitPath;
13769
- let shouldPushExitIdentifier = false;
13770
- while (targetPath !== path) {
13771
- const parent = targetPath.parentPath;
13772
- if (parent == null) {
13773
- break;
13774
- }
13775
- if (!parent.isSwitchCase() && !parent.isBlockStatement()) {
13776
- let exitIdentifier;
13777
- const explicitExits = pathsReturnOrThrow(parent);
13778
- if (!explicitExits.all && explicitExits.any && (parent.isLoop() || exitsInTail(parent))) {
13779
- if (!state.exitIdentifier) {
13780
- state.exitIdentifier = targetPath.scope.generateUidIdentifier("exit");
13781
- shouldPushExitIdentifier = true;
13782
- }
13783
- exitIdentifier = state.exitIdentifier;
13784
- }
13785
- paths.push({
13786
- targetPath,
13787
- explicitExits,
13788
- parent,
13789
- exitIdentifier
13790
- });
13791
- }
13792
- targetPath = parent;
13793
- }
13794
- if (shouldPushExitIdentifier && state.exitIdentifier) {
13795
- path.scope.push({
13796
- kind: "let",
13797
- id: state.exitIdentifier,
13798
- init: readConfigKey(pluginState.opts, "minify") ? undefined : booleanLiteral(false, readConfigKey(pluginState.opts, "minify"))
13799
- });
13800
- }
13801
- }
13802
- let breakIdentifiers = [];
13803
- for (const item of paths) {
13804
- const parent = item.parent;
13805
- if (parent.isForStatement() || parent.isWhileStatement() || parent.isDoWhileStatement() || parent.isForInStatement() || parent.isForOfStatement() || isForAwaitStatement(parent) || parent.isLabeledStatement()) {
13806
- breakIdentifiers = item.breakIdentifiers = replaceReturnsAndBreaks(pluginState, parent.get("body"), item.exitIdentifier, breakIdentifiers);
13807
- if (parent.isForStatement()) {
13808
- if (item.forToIdentifiers = identifiersInForToLengthStatement(parent)) {
13809
- addConstantNames(additionalConstantNames, item.forToIdentifiers.i);
13810
- }
13811
- }
13812
- } else if (item.parent.isSwitchStatement()) {
13813
- breakIdentifiers = breakIdentifiers.slice();
13814
- item.cases = item.parent.get("cases").map(casePath => {
13815
- const caseExits = pathsReturnOrThrow(casePath);
13816
- const caseBreaks = pathsBreak(casePath);
13817
- const caseBreakIdentifiers = item.breakIdentifiers = replaceReturnsAndBreaks(pluginState, casePath, item.exitIdentifier, breakIdentifiers);
13818
- for (const breakItem of caseBreakIdentifiers) {
13819
- if (!breakIdentifiers.find(existing => existing.identifier.name === breakItem.identifier.name)) {
13820
- breakIdentifiers.push(breakItem);
13821
- }
13822
- }
13823
- return {
13824
- casePath,
13825
- caseExits,
13826
- caseBreaks,
13827
- breakIdentifiers: caseBreakIdentifiers,
13828
- test: casePath.node.test
13829
- };
13830
- });
13831
- } else {
13832
- breakIdentifiers = item.breakIdentifiers = replaceReturnsAndBreaks(pluginState, parent, item.exitIdentifier, breakIdentifiers);
13833
- }
13834
- }
13835
- for (const {
13836
- targetPath,
13837
- explicitExits,
13838
- breakIdentifiers,
13839
- parent,
13840
- exitIdentifier,
13841
- cases,
13842
- forToIdentifiers
13843
- } of paths) {
13844
- if (parent.isExpressionStatement() && (targetPath.isAwaitExpression() || targetPath.isYieldExpression()) && processExpressions) {
13845
- processExpressions = false;
13846
- relocateTail(state.generatorState, targetPath.isYieldExpression() ? yieldOnExpression(state.generatorState, targetPath.node.argument || types.identifier("undefined")) : targetPath.node.argument, undefined, parent, additionalConstantNames, undefined, undefined, targetPath.isYieldExpression() ? undefined : booleanLiteral(false, readConfigKey(pluginState.opts, "minify")), state.skipReturns);
13847
- } else if (parent.isIfStatement()) {
13848
- const test = parent.get("test");
13849
- if (targetPath !== test) {
13850
- let resultIdentifier;
13851
- if (!explicitExits.all && explicitExits.any) {
13852
- resultIdentifier = path.scope.generateUidIdentifier("result");
13853
- addConstantNames(additionalConstantNames, resultIdentifier);
13854
- }
13855
- if (!explicitExits.all) {
13856
- const consequent = parent.get("consequent");
13857
- rewriteAsyncBlock(state.generatorState, consequent, additionalConstantNames, exitIdentifier);
13858
- const alternate = parent.get("alternate");
13859
- if (alternate.isStatement()) {
13860
- rewriteAsyncBlock(state.generatorState, alternate, additionalConstantNames, exitIdentifier);
13861
- }
13862
- const fn = functionize(pluginState, [], blockStatement([parent.node]), targetPath);
13863
- relocateTail(state.generatorState, types.callExpression(fn, []), undefined, parent, additionalConstantNames, resultIdentifier, exitIdentifier, undefined, state.skipReturns);
13864
- processExpressions = false;
13865
- }
13866
- }
13867
- } else if (parent.isTryStatement()) {
13868
- const temporary = explicitExits.any && !explicitExits.all ? path.scope.generateUidIdentifier("result") : undefined;
13869
- const exitCheck = buildBreakExitCheck(pluginState, explicitExits.any && !explicitExits.all ? exitIdentifier : undefined, breakIdentifiers);
13870
- let expression = rewriteAsyncNode(state.generatorState, parent, parent.node.block, additionalConstantNames, exitIdentifier);
13871
- const catchClause = parent.node.handler;
13872
- if (catchClause) {
13873
- const param = catchClause.param;
13874
- const paramIsUsed = param !== null && param !== undefined && (param.type !== "Identifier" || parent.get("handler").scope.getBinding(param.name).referencePaths.length !== 0);
13875
- const fn = catchClause.body.body.length ? rewriteAsyncNode(state.generatorState, parent, functionize(pluginState, paramIsUsed && param != null ? [param] : [], catchClause.body, targetPath), additionalConstantNames, exitIdentifier) : emptyFunction(pluginState, parent);
13876
- expression = types.callExpression(helperReference(pluginState, path, state.generatorState.generatorIdentifier ? "_catchInGenerator" : "_catch"), [unwrapReturnCallWithEmptyArguments(functionize(pluginState, [], expression, targetPath), path.scope, additionalConstantNames), fn]);
13877
- }
13878
- if (parent.node.finalizer) {
13879
- let finallyName;
13880
- let finallyArgs;
13881
- let finallyBody = parent.node.finalizer.body;
13882
- if (!pathsReturnOrThrow(parent.get("finalizer")).all) {
13883
- const resultIdentifier = temporary || path.scope.generateUidIdentifier("result");
13884
- addConstantNames(additionalConstantNames, resultIdentifier);
13885
- const wasThrownIdentifier = path.scope.generateUidIdentifier("wasThrown");
13886
- addConstantNames(additionalConstantNames, wasThrownIdentifier);
13887
- finallyArgs = [wasThrownIdentifier, resultIdentifier];
13888
- if (readConfigKey(pluginState.opts, "inlineHelpers")) {
13889
- finallyBody = finallyBody.concat([types.ifStatement(wasThrownIdentifier, types.throwStatement(resultIdentifier)), types.returnStatement(resultIdentifier)]);
13890
- } else {
13891
- finallyBody = finallyBody.concat(returnStatement(types.callExpression(helperReference(pluginState, parent, "_rethrow"), [wasThrownIdentifier, resultIdentifier])));
13892
- }
13893
- finallyName = "_finallyRethrows";
13894
- } else {
13895
- finallyArgs = [];
13896
- finallyName = "_finally";
13897
- }
13898
- const fn = functionize(pluginState, finallyArgs, blockStatement(finallyBody), targetPath);
13899
- const rewritten = rewriteAsyncNode(state.generatorState, parent, fn, additionalConstantNames, exitIdentifier);
13900
- expression = types.callExpression(helperReference(pluginState, parent, finallyName), [unwrapReturnCallWithEmptyArguments(functionize(pluginState, [], expression, targetPath), path.scope, additionalConstantNames), rewritten]);
13901
- }
13902
- relocateTail(state.generatorState, types.isExpression(expression) ? expression : types.callExpression(functionize(pluginState, [], expression, targetPath), []), undefined, parent, additionalConstantNames, temporary, exitCheck, undefined, state.skipReturns);
13903
- processExpressions = false;
13904
- } else if (parent.isForStatement() || parent.isWhileStatement() || parent.isDoWhileStatement() || parent.isForInStatement() || parent.isForOfStatement() || isForAwaitStatement(parent)) {
13905
- const label = parent.parentPath.isLabeledStatement() ? parent.parentPath.node.label.name : undefined;
13906
- if (parent.isForInStatement() || parent.isForOfStatement() || isForAwaitStatement(parent)) {
13907
- const right = parent.get("right");
13908
- if (awaitPath !== right) {
13909
- const left = parent.get("left");
13910
- const loopIdentifier = left.isVariableDeclaration() ? left.get("declarations")[0].get("id") : left;
13911
- if (loopIdentifier.isIdentifier() || loopIdentifier.isPattern()) {
13912
- const forOwnBodyPath = parent.isForInStatement() && extractForOwnBodyPath(parent);
13913
- const bodyBlock = blockStatement((forOwnBodyPath || parent.get("body")).node);
13914
- const params = [right.node, rewriteAsyncNode(state.generatorState, parent, bodyBlock.body.length ? functionize(pluginState, [loopIdentifier.node], bodyBlock, targetPath) : emptyFunction(pluginState, parent), additionalConstantNames, exitIdentifier)];
13915
- const exitCheck = buildBreakExitCheck(pluginState, exitIdentifier, breakIdentifiers);
13916
- if (exitCheck) {
13917
- params.push(functionize(pluginState, [], types.blockStatement([returnStatement(exitCheck)]), targetPath));
13918
- }
13919
- const loopCall = types.callExpression(helperReference(pluginState, parent, parent.isForInStatement() ? forOwnBodyPath ? "_forOwn" : "_forIn" : isForAwaitStatement(parent) ? "_forAwaitOf" : "_forOf"), params);
13920
- let resultIdentifier = undefined;
13921
- if (explicitExits.any) {
13922
- resultIdentifier = path.scope.generateUidIdentifier("result");
13923
- addConstantNames(additionalConstantNames, resultIdentifier);
13924
- }
13925
- relocateTail(state.generatorState, loopCall, undefined, label && parent.parentPath.isStatement() ? parent.parentPath : parent, additionalConstantNames, resultIdentifier, exitIdentifier, undefined, state.skipReturns);
13926
- processExpressions = false;
13927
- } else {
13928
- throw loopIdentifier.buildCodeFrameError(`Expected an identifier or pattern, but got a ${loopIdentifier.type}!`, TypeError);
13929
- }
13930
- }
13931
- } else {
13932
- let testExpression = parent.node.test;
13933
- const breakExitCheck = buildBreakExitCheck(pluginState, exitIdentifier, breakIdentifiers);
13934
- if (breakExitCheck) {
13935
- const inverted = logicalNot(breakExitCheck, readConfigKey(pluginState.opts, "minify"));
13936
- testExpression = testExpression && (!types.isBooleanLiteral(testExpression) || !testExpression.value) ? logicalAnd(inverted, testExpression, extractLooseBooleanValue) : inverted;
13937
- }
13938
- if (testExpression) {
13939
- testExpression = rewriteAsyncNode(state.generatorState, parent, functionize(pluginState, [], testExpression, targetPath), additionalConstantNames, exitIdentifier, true);
13940
- }
13941
- const isDoWhile = parent.isDoWhileStatement();
13942
- let loopCall;
13943
- if (forToIdentifiers && !isDoWhile) {
13944
- const args = [forToIdentifiers.array, rewriteAsyncNode(state.generatorState, parent, functionize(pluginState, [forToIdentifiers.i], blockStatement(parent.node.body), targetPath), additionalConstantNames, exitIdentifier)];
13945
- if (breakExitCheck) {
13946
- args.push(functionize(pluginState, [], breakExitCheck, targetPath));
13947
- }
13948
- loopCall = types.callExpression(helperReference(pluginState, parent, "_forTo"), args);
13949
- } else {
13950
- let updateExpression = null;
13951
- if (parent.isForStatement()) {
13952
- updateExpression = parent.node.update;
13953
- if (updateExpression) {
13954
- updateExpression = rewriteAsyncNode(state.generatorState, parent, functionize(pluginState, [], updateExpression, targetPath), additionalConstantNames, exitIdentifier, true);
13955
- }
13956
- const init = parent.get("init");
13957
- if (init) {
13958
- const initNode = init.node;
13959
- if (initNode !== null && initNode !== undefined) {
13960
- reregisterDeclarations(parent.insertBefore(types.isExpression(initNode) ? types.expressionStatement(initNode) : initNode));
13961
- }
13962
- }
13963
- }
13964
- const bodyFunction = rewriteAsyncNode(state.generatorState, parent, functionize(pluginState, [], blockStatement(parent.node.body || []), targetPath), additionalConstantNames, exitIdentifier);
13965
- const testFunction = unwrapReturnCallWithEmptyArguments(testExpression || voidExpression(), path.scope, additionalConstantNames);
13966
- const updateFunction = unwrapReturnCallWithEmptyArguments(updateExpression || voidExpression(), path.scope, additionalConstantNames);
13967
- loopCall = isDoWhile ? types.callExpression(helperReference(pluginState, parent, "_do"), [bodyFunction, testFunction]) : types.callExpression(helperReference(pluginState, parent, "_for"), [testFunction, updateFunction, bodyFunction]);
13968
- }
13969
- let resultIdentifier = undefined;
13970
- if (explicitExits.any) {
13971
- resultIdentifier = path.scope.generateUidIdentifier("result");
13972
- addConstantNames(additionalConstantNames, resultIdentifier);
13973
- }
13974
- relocateTail(state.generatorState, loopCall, undefined, parent, additionalConstantNames, resultIdentifier, exitIdentifier, undefined, state.skipReturns);
13975
- processExpressions = false;
13976
- }
13977
- } else if (parent.isSwitchStatement()) {
13978
- const label = parent.parentPath.isLabeledStatement() ? parent.parentPath.node.label.name : undefined;
13979
- const discriminant = parent.get("discriminant");
13980
- const testPaths = parent.get("cases").map(casePath => casePath.get("test"));
13981
- if (awaitPath !== discriminant && !(explicitExits.all && !testPaths.some(testPath => testPath.node ? findAwaitOrYieldPath(testPath) !== undefined : false))) {
13982
- let resultIdentifier;
13983
- if (!explicitExits.all && explicitExits.any) {
13984
- resultIdentifier = path.scope.generateUidIdentifier("result");
13985
- addConstantNames(additionalConstantNames, resultIdentifier);
13986
- }
13987
- const caseNodes = types.arrayExpression(cases ? cases.map(caseItem => {
13988
- const args = [];
13989
- let consequent;
13990
- if (caseItem.casePath.node.consequent) {
13991
- const rewritten = rewriteAsyncNode(state.generatorState, parent, blockStatement(removeUnnecessaryReturnStatements(caseItem.casePath.node.consequent)), additionalConstantNames, exitIdentifier);
13992
- if (rewritten.body.length) {
13993
- consequent = functionize(pluginState, [], rewritten, targetPath);
13994
- }
13995
- }
13996
- if (caseItem.casePath.node.test) {
13997
- args.push(rewriteAsyncNode(state.generatorState, parent, functionize(pluginState, [], caseItem.casePath.node.test, targetPath), additionalConstantNames));
13998
- } else if (consequent) {
13999
- args.push(voidExpression());
14000
- }
14001
- if (consequent) {
14002
- args.push(consequent);
14003
- if (!caseItem.caseExits.any && !caseItem.caseBreaks.any) {
14004
- args.push(emptyFunction(pluginState, parent));
14005
- } else if (!(caseItem.caseExits.all || caseItem.caseBreaks.all)) {
14006
- const breakCheck = buildBreakExitCheck(pluginState, caseItem.caseExits.any ? exitIdentifier : undefined, caseItem.breakIdentifiers);
14007
- if (breakCheck) {
14008
- args.push(functionize(pluginState, [], types.blockStatement([returnStatement(breakCheck)]), targetPath));
14009
- }
14010
- }
14011
- }
14012
- return types.arrayExpression(args);
14013
- }) : []);
14014
- const switchCall = types.callExpression(helperReference(pluginState, parent, "_switch"), [discriminant.node, caseNodes]);
14015
- relocateTail(state.generatorState, switchCall, undefined, label && parent.parentPath.isStatement() ? parent.parentPath : parent, additionalConstantNames, resultIdentifier, exitIdentifier, undefined, state.skipReturns);
14016
- processExpressions = false;
14017
- }
14018
- } else if (parent.isLabeledStatement()) {
14019
- let resultIdentifier;
14020
- if (!explicitExits.all && explicitExits.any) {
14021
- resultIdentifier = path.scope.generateUidIdentifier("result");
14022
- addConstantNames(additionalConstantNames, resultIdentifier);
14023
- }
14024
- if (resultIdentifier || breakIdentifiers && breakIdentifiers.length) {
14025
- const filteredBreakIdentifiers = breakIdentifiers ? breakIdentifiers.filter(id => id.name !== parent.node.label.name) : [];
14026
- const fn = functionize(pluginState, [], blockStatement(parent.node.body), targetPath);
14027
- const rewritten = rewriteAsyncNode(state.generatorState, parent, fn, additionalConstantNames, exitIdentifier);
14028
- const exitCheck = buildBreakExitCheck(pluginState, explicitExits.any ? exitIdentifier : undefined, filteredBreakIdentifiers);
14029
- relocateTail(state.generatorState, types.callExpression(rewritten, []), undefined, parent, additionalConstantNames, resultIdentifier, exitCheck, undefined, state.skipReturns);
14030
- processExpressions = false;
14031
- }
14032
- }
14033
- }
14034
- if (processExpressions) {
14035
- if (awaitPath.isAwaitExpression() || awaitPath.isYieldExpression()) {
14036
- const originalArgument = awaitPath.node.argument;
14037
- let parent = getStatementOrArrowBodyParent(awaitPath);
14038
- const {
14039
- declarationKind,
14040
- declarations,
14041
- awaitExpression,
14042
- directExpression,
14043
- reusingExisting,
14044
- resultIdentifier
14045
- } = extractDeclarations(pluginState, awaitPath, originalArgument || types.identifier("undefined"), additionalConstantNames);
14046
- if (resultIdentifier) {
14047
- addConstantNames(additionalConstantNames, resultIdentifier);
14048
- }
14049
- if (declarations.length) {
14050
- for (const {
14051
- id
14052
- } of declarations) {
14053
- addConstantNames(additionalConstantNames, id);
14054
- }
14055
- if (parent.parentPath.isBlockStatement()) {
14056
- reregisterDeclarations(parent.insertBefore(types.variableDeclaration(declarationKind, declarations)));
14057
- } else {
14058
- parent.replaceWith(blockStatement([types.variableDeclaration(declarationKind, declarations), types.isStatement(parent.node) ? parent.node : returnStatement(parent.node)]));
14059
- const body = parent.get("body");
14060
- reregisterDeclarations(body[0]);
14061
- parent = body[1];
14062
- }
14063
- }
14064
- if (reusingExisting) {
14065
- if (types.isVariableDeclaration(reusingExisting.parent) && reusingExisting.parent.declarations.length === 1) {
14066
- reusingExisting.parentPath.replaceWith(types.emptyStatement());
14067
- } else {
14068
- reusingExisting.remove();
14069
- }
14070
- }
14071
- const parentNode = parent.node;
14072
- relocateTail(state.generatorState, awaitPath.isYieldExpression() ? yieldOnExpression(state.generatorState, awaitExpression) : awaitExpression, types.isStatement(parentNode) ? parentNode : types.returnStatement(parentNode), parent, additionalConstantNames, resultIdentifier, undefined, awaitPath.isYieldExpression() ? undefined : directExpression, state.skipReturns);
14073
- }
14074
- }
14075
- }
14076
- const rewriteAsyncBlockVisitor = {
14077
- Function: skipNode,
14078
- AwaitExpression: rewriteAwaitOrYieldPath,
14079
- YieldExpression: rewriteAwaitOrYieldPath,
14080
- ForAwaitStatement: rewriteAwaitOrYieldPath,
14081
- ForOfStatement(path) {
14082
- if (path.node.await) {
14083
- rewriteAwaitOrYieldPath.call(this, path);
14084
- }
14085
- },
14086
- CallExpression(path) {
14087
- const callee = path.get("callee");
14088
- if (callee.isIdentifier() && callee.node.name === "eval") {
14089
- throw path.buildCodeFrameError("Calling eval from inside an async function is not supported!", TypeError);
14090
- }
14091
- }
14092
- };
14093
- const unpromisifyVisitor = {
14094
- Function: skipNode,
14095
- ReturnStatement(path) {
14096
- const argument = path.get("argument");
14097
- if (argument.node) {
14098
- unpromisify(argument, this);
14099
- }
14100
- }
14101
- };
14102
- function unpromisify(path, pluginState) {
14103
- if (path.isNumericLiteral() || path.isBooleanLiteral() || path.isStringLiteral() || path.isNullLiteral() || path.isIdentifier() && path.node.name === "undefined" || path.isArrayExpression() || path.isObjectExpression() || path.isBinaryExpression() || path.isUnaryExpression() || path.isUpdateExpression()) {
14104
- return;
14105
- }
14106
- if (path.isCallExpression() && (types.isIdentifier(path.node.callee) || types.isMemberExpression(path.node.callee)) && helperNameMap.has(path.node.callee)) {
14107
- switch (helperNameMap.get(path.node.callee)) {
14108
- case "_await":
14109
- const args = path.get("arguments");
14110
- if (args.length > 0 && args[0].isExpression()) {
14111
- unpromisify(args[0], pluginState);
14112
- }
14113
- case "_call":
14114
- {
14115
- const args = path.get("arguments");
14116
- if (args.length > 2) {
14117
- const secondArg = args[1];
14118
- if (types.isExpression(secondArg.node) && isContinuation(secondArg.node)) {
14119
- secondArg.traverse(unpromisifyVisitor, pluginState);
14120
- } else if (secondArg.isIdentifier()) {
14121
- const binding = secondArg.scope.getBinding(secondArg.node.name);
14122
- if (binding && binding.path.isVariableDeclarator()) {
14123
- binding.path.get("init").traverse(unpromisifyVisitor, pluginState);
14124
- }
14125
- }
14126
- }
14127
- break;
14128
- }
14129
- case "_promiseThen":
14130
- {
14131
- const args = path.get("arguments");
14132
- if (args.length > 2) {
14133
- const firstArg = args[1];
14134
- if (types.isExpression(firstArg.node) && isContinuation(firstArg.node)) {
14135
- firstArg.traverse(unpromisifyVisitor, pluginState);
14136
- } else if (firstArg.isIdentifier()) {
14137
- const binding = firstArg.scope.getBinding(firstArg.node.name);
14138
- if (binding && binding.path.isVariableDeclarator()) {
14139
- binding.path.get("init").traverse(unpromisifyVisitor, pluginState);
14140
- }
14141
- }
14142
- }
14143
- break;
14144
- }
14145
- }
14146
- return;
14147
- }
14148
- if (path.isLogicalExpression()) {
14149
- unpromisify(path.get("left"), pluginState);
14150
- unpromisify(path.get("right"), pluginState);
14151
- return;
14152
- }
14153
- if (path.isConditionalExpression()) {
14154
- unpromisify(path.get("consequent"), pluginState);
14155
- unpromisify(path.get("alternate"), pluginState);
14156
- return;
14157
- }
14158
- if (path.isSequenceExpression()) {
14159
- const expressions = path.get("expressions");
14160
- if (expressions.length) {
14161
- unpromisify(expressions[expressions.length - 1], pluginState);
14162
- }
14163
- return;
14164
- }
14165
- const minify = readConfigKey(pluginState.opts, "minify");
14166
- path.replaceWith(logicalNot(logicalNot(path.node, minify), minify));
14167
- }
14168
- function rewriteAsyncBlock(generatorState, path, additionalConstantNames, exitIdentifier, shouldUnpromisify, skipReturns) {
14169
- path.traverse(rewriteAsyncBlockVisitor, {
14170
- generatorState,
14171
- path,
14172
- additionalConstantNames,
14173
- exitIdentifier,
14174
- skipReturns
14175
- });
14176
- if (shouldUnpromisify) {
14177
- if (path.isArrowFunctionExpression()) {
14178
- const body = path.get("body");
14179
- if (body.isExpression()) {
14180
- unpromisify(body, generatorState.state);
14181
- }
14182
- } else {
14183
- path.traverse(unpromisifyVisitor, generatorState.state);
14184
- }
14185
- }
14186
- }
14187
- function getFile(path) {
14188
- let hub = path.hub;
14189
- if ("file" in hub) {
14190
- return hub.file;
14191
- }
14192
- throw path.buildCodeFrameError("Expected the path's hub to contain a file!", TypeError);
14193
- }
14194
- const getHelperDependenciesVisitor = {
14195
- Identifier(path) {
14196
- if (identifierSearchesScope(path) && getFile(path).scope.getBinding(path.node.name) && this.dependencies.indexOf(path.node.name) === -1) {
14197
- this.dependencies.push(path.node.name);
14198
- }
14199
- }
14200
- };
14201
- function getHelperDependencies(path) {
14202
- const state = {
14203
- dependencies: []
14204
- };
14205
- path.traverse(getHelperDependenciesVisitor, state);
14206
- return state.dependencies;
14207
- }
14208
- const usesIdentifierVisitor = {
14209
- Identifier(path) {
14210
- if (path.node.name === this.name) {
14211
- this.found = true;
14212
- path.stop();
14213
- }
14214
- }
14215
- };
14216
- function usesIdentifier(path, name) {
14217
- const state = {
14218
- name,
14219
- found: false
14220
- };
14221
- path.traverse(usesIdentifierVisitor, state);
14222
- return state.found;
14223
- }
14224
- function insertHelper(programPath, value) {
14225
- const body = programPath.get("body");
14226
- const destinationPath = body.find(path => !isHelperDefinitionSet.has(path.node) && !path.isImportDeclaration()) || body.find(() => true);
14227
- if (destinationPath.isVariableDeclaration()) {
14228
- const before = destinationPath.get("declarations").filter(path => isHelperDefinitionSet.has(path.node));
14229
- const after = destinationPath.get("declarations").filter(path => !isHelperDefinitionSet.has(path.node));
14230
- if (types.isVariableDeclaration(value)) {
14231
- const declaration = value.declarations[0];
14232
- isHelperDefinitionSet.add(declaration);
14233
- if (before.length === 0) {
14234
- const target = after[0];
14235
- reregisterDeclarations(target.insertBefore(declaration));
14236
- return getPreviousSibling(target);
14237
- } else {
14238
- const target = before[before.length - 1];
14239
- reregisterDeclarations(target.insertAfter(declaration));
14240
- return getNextSibling(target);
14241
- }
14242
- } else {
14243
- isHelperDefinitionSet.add(value);
14244
- if (before.length === 0) {
14245
- isHelperDefinitionSet.add(destinationPath.node);
14246
- reregisterDeclarations(destinationPath.insertBefore(value));
14247
- return getPreviousSibling(destinationPath);
14248
- } else if (after.length === 0) {
14249
- isHelperDefinitionSet.add(destinationPath.node);
14250
- reregisterDeclarations(destinationPath.insertAfter(value));
14251
- return getNextSibling(destinationPath);
14252
- } else {
14253
- const beforeNode = types.variableDeclaration(destinationPath.node.kind, before.map(path => path.node));
14254
- isHelperDefinitionSet.add(beforeNode);
14255
- const afterNode = types.variableDeclaration(destinationPath.node.kind, after.map(path => path.node));
14256
- destinationPath.replaceWith(afterNode);
14257
- reregisterDeclarations(destinationPath);
14258
- reregisterDeclarations(destinationPath.insertBefore(beforeNode));
14259
- reregisterDeclarations(destinationPath.insertBefore(value));
14260
- return getPreviousSibling(destinationPath);
14261
- }
14262
- }
14263
- } else {
14264
- if (types.isVariableDeclaration(value)) {
14265
- isHelperDefinitionSet.add(value.declarations[0]);
14266
- } else {
14267
- isHelperDefinitionSet.add(value);
14268
- }
14269
- const oldNode = destinationPath.node;
14270
- destinationPath.replaceWith(value);
14271
- reregisterDeclarations(destinationPath);
14272
- reregisterDeclarations(destinationPath.insertAfter(oldNode));
14273
- return destinationPath;
14274
- }
14275
- }
14276
- function helperReference(state, path, name) {
14277
- const file = getFile(path);
14278
- let result = file.declarations[name];
14279
- if (result) {
14280
- result = cloneNode(result);
14281
- } else {
14282
- result = file.declarations[name] = usesIdentifier(file.path, name) ? file.path.scope.generateUidIdentifier(name) : types.identifier(name);
14283
- helperNameMap.set(result, name);
14284
- if (readConfigKey(state.opts, "externalHelpers")) {
14285
- file.path.unshiftContainer("body", types.importDeclaration([types.importSpecifier(result, types.identifier(name))], types.stringLiteral("babel-plugin-transform-async-to-promises/helpers")));
14286
- } else {
14287
- if (!helpers) {
14288
- const newHelpers = {};
14289
- const plugins = [{
14290
- visitor: {
14291
- ExportNamedDeclaration(path) {
14292
- const declaration = path.get("declaration");
14293
- if (declaration.isFunctionDeclaration()) {
14294
- const id = declaration.node.id;
14295
- if (!types.isIdentifier(id)) {
14296
- throw declaration.buildCodeFrameError(`Expected a named declaration!`, TypeError);
14297
- }
14298
- newHelpers[id.name] = {
14299
- value: declaration.node,
14300
- dependencies: getHelperDependencies(declaration)
14301
- };
14302
- return;
14303
- }
14304
- if (declaration.isVariableDeclaration() && declaration.node.declarations.length === 1) {
14305
- const declaratorId = declaration.node.declarations[0].id;
14306
- if (types.isIdentifier(declaratorId)) {
14307
- newHelpers[declaratorId.name] = {
14308
- value: declaration.node,
14309
- dependencies: getHelperDependencies(declaration)
14310
- };
14311
- return;
14312
- }
14313
- }
14314
- throw path.buildCodeFrameError("Expected a named export from built-in helper!", TypeError);
14315
- }
14316
- }
14317
- }];
14318
- const helperAst = require(isNewBabel ? "@babel/core" : "babylon").parse(helpers_string_1, {
14319
- sourceType: "module",
14320
- filename: "helpers.js"
14321
- });
14322
- if (isNewBabel) {
14323
- transformFromAst(helperAst, helpers_string_1, {
14324
- babelrc: false,
14325
- configFile: false,
14326
- plugins
14327
- });
14328
- } else {
14329
- transformFromAst(helperAst, helpers_string_1, {
14330
- babelrc: false,
14331
- plugins
14332
- });
14333
- }
14334
- helpers = newHelpers;
14335
- }
14336
- const helper = helpers[name];
14337
- for (const dependency of helper.dependencies) {
14338
- helperReference(state, path, dependency);
14339
- }
14340
- const usedHelpers = state.usedHelpers || (state.usedHelpers = {});
14341
- usedHelpers[name] = true;
14342
- }
14343
- }
14344
- return result;
14345
- }
14346
- function emptyFunction(state, path) {
14347
- return readConfigKey(state.opts, "inlineHelpers") ? functionize(state, [], blockStatement([]), path) : helperReference(state, path, "_empty");
14348
- }
14349
- function promiseResolve() {
14350
- const result = types.memberExpression(types.identifier("Promise"), types.identifier("resolve"));
14351
- helperNameMap.set(result, "_promiseResolve");
14352
- return result;
14353
- }
14354
- function callThenMethod(value, continuation) {
14355
- const thenExpression = types.memberExpression(value, types.identifier("then"));
14356
- helperNameMap.set(thenExpression, "_promiseThen");
14357
- return types.callExpression(thenExpression, [continuation]);
14358
- }
14359
- function isAsyncCallExpression(path) {
14360
- if (types.isIdentifier(path.node.callee) || types.isMemberExpression(path.node.callee)) {
14361
- switch (helperNameMap.get(path.node.callee)) {
14362
- case "_await":
14363
- case "_call":
14364
- case "_promiseResolve":
14365
- case "_promiseThen":
14366
- return path.node.arguments.length < 3;
14367
- }
14368
- }
14369
- return false;
14370
- }
14371
- function invokeTypeOfExpression(path) {
14372
- if (path.isCallExpression() && types.isIdentifier(path.node.callee)) {
14373
- const helperName = helperNameMap.get(path.node.callee);
14374
- switch (helperName) {
14375
- case "_invoke":
14376
- case "_invokeIgnored":
14377
- case "_catch":
14378
- case "_catchInGenerator":
14379
- case "_finally":
14380
- case "_finallyRethrows":
14381
- return helperName;
14382
- }
14383
- }
14384
- }
14385
- function isAsyncFunctionExpression(path) {
14386
- if (path.isFunction() && (path.node.async || nodeIsAsyncSet.has(path.node))) {
14387
- return true;
14388
- }
14389
- if (path.isCallExpression() && types.isIdentifier(path.node.callee) && helperNameMap.get(path.node.callee) === "_async") {
14390
- return true;
14391
- }
14392
- return false;
14393
- }
14394
- function isAsyncFunctionIdentifier(path) {
14395
- if (path.isIdentifier()) {
14396
- const binding = path.scope.getBinding(path.node.name);
14397
- if (binding && binding.constant) {
14398
- const bindingPath = binding.path;
14399
- if (bindingPath.isVariableDeclarator()) {
14400
- const initPath = bindingPath.get("init");
14401
- if (initPath.node && isAsyncFunctionExpression(initPath)) {
14402
- return true;
14403
- }
14404
- } else if (bindingPath.isFunctionDeclaration()) {
14405
- if (isAsyncFunctionExpression(bindingPath)) {
14406
- return true;
14407
- }
14408
- }
14409
- }
14410
- }
14411
- return false;
14412
- }
14413
- function isEvalOrArguments(path) {
14414
- return path.isIdentifier() && (path.node.name === "arguments" || path.node.name === "eval");
14415
- }
14416
- function identifierSearchesScope(path) {
14417
- if (path.node.name === "undefined") {
14418
- return false;
14419
- }
14420
- if (helperNameMap.has(path.node)) {
14421
- return false;
14422
- }
14423
- const parent = path.parentPath;
14424
- if (parent.isVariableDeclarator() && parent.get("id") === path) {
14425
- return false;
14426
- }
14427
- if (parent.isMemberExpression() && !parent.node.computed && parent.get("property") === path) {
14428
- return false;
14429
- }
14430
- if (parent.isLabeledStatement() && parent.get("label") === path) {
14431
- return false;
14432
- }
14433
- if (parent.isFunction() && parent.get("params").indexOf(path) !== -1) {
14434
- return false;
14435
- }
14436
- return true;
14437
- }
14438
- function canThrow() {
14439
- this.canThrow = true;
14440
- }
14441
- function promiseCallExpressionType(expression) {
14442
- if (types.isMemberExpression(expression.callee)) {
14443
- if (types.isIdentifier(expression.callee.object) && expression.callee.object.name === "Promise" && types.isIdentifier(expression.callee.property)) {
14444
- switch (expression.callee.property.name) {
14445
- case "all":
14446
- case "race":
14447
- case "reject":
14448
- case "resolve":
14449
- return expression.callee.property.name;
14450
- }
14451
- } else if (types.isCallExpression(expression.callee.object) && types.isIdentifier(expression.callee.property)) {
14452
- switch (expression.callee.property.name) {
14453
- case "then":
14454
- case "catch":
14455
- case "finally":
14456
- if (typeof promiseCallExpressionType(expression.callee.object) !== "undefined") {
14457
- return expression.callee.property.name;
14458
- }
14459
- break;
14460
- }
14461
- }
14462
- }
14463
- return undefined;
14464
- }
14465
- const checkForErrorsAndRewriteReturnsVisitor = {
14466
- Function: skipNode,
14467
- ThrowStatement: canThrow,
14468
- ForInStatement: canThrow,
14469
- ForOfStatement: canThrow,
14470
- WithStatement: canThrow,
14471
- NewExpression: canThrow,
14472
- TryStatement(path) {
14473
- if (path.get("handler")) {
14474
- path.get("block").skip();
14475
- }
14476
- },
14477
- CallExpression(path) {
14478
- if (!isAsyncCallExpression(path)) {
14479
- const args = path.get("arguments");
14480
- switch (invokeTypeOfExpression(path)) {
14481
- default:
14482
- if (checkForErrorsAndRewriteReturns(args[0], this.plugin)) {
14483
- this.canThrow = true;
14484
- }
14485
- case "_catch":
14486
- case "_catchInGenerator":
14487
- case "_finally":
14488
- case "_finallyRethrows":
14489
- if (args[1]) {
14490
- if (checkForErrorsAndRewriteReturns(args[1], this.plugin)) {
14491
- this.canThrow = true;
14492
- }
14493
- }
14494
- break;
14495
- case undefined:
14496
- {
14497
- const callee = path.get("callee");
14498
- if (!isAsyncFunctionIdentifier(callee)) {
14499
- this.canThrow = true;
14500
- }
14501
- }
14502
- }
14503
- }
14504
- },
14505
- UpdateExpression(path) {
14506
- if (isEvalOrArguments(path.get("argument"))) {
14507
- this.canThrow = true;
14508
- }
14509
- },
14510
- UnaryExpression(path) {
14511
- switch (path.node.operator) {
14512
- case "delete":
14513
- this.canThrow = true;
14514
- break;
14515
- }
14516
- },
14517
- BinaryExpression(path) {
14518
- switch (path.node.operator) {
14519
- case "instanceof":
14520
- case "in":
14521
- this.canThrow = true;
14522
- break;
14523
- }
14524
- },
14525
- Identifier(path) {
14526
- if (identifierSearchesScope(path) && !path.scope.getBinding(path.node.name) && alwaysTruthy.indexOf(path.node.name) === -1) {
14527
- this.canThrow = true;
14528
- }
14529
- },
14530
- MemberExpression(path) {
14531
- if (helperNameMap.get(path.node) !== "_await" && !(path.parentPath.isCallExpression() && promiseCallExpressionType(path.parentPath.node) !== undefined && path.parentPath.get("callee") === path)) {
14532
- const propertyName = propertyNameOfMemberExpression(path.node);
14533
- if (propertyName !== undefined) {
14534
- const object = path.get("object");
14535
- if (object.isIdentifier() && Object.hasOwnProperty.call(constantStaticMethods, object.node.name) && Object.hasOwnProperty.call(constantStaticMethods[object.node.name], propertyName)) {
14536
- return;
14537
- }
14538
- }
14539
- this.canThrow = true;
14540
- }
14541
- },
14542
- AssignmentExpression(path) {
14543
- if (isEvalOrArguments(path.get("left"))) {
14544
- this.canThrow = true;
14545
- }
14546
- },
14547
- ReturnStatement(path) {
14548
- if (this.rewriteReturns) {
14549
- const argument = path.get("argument");
14550
- if (argument && argument.node) {
14551
- let arg = argument.node;
14552
- if (!(argument.isCallExpression() && (isAsyncCallExpression(argument) || typeof promiseCallExpressionType(argument.node) !== "undefined") || argument.isCallExpression() && isAsyncFunctionIdentifier(argument.get("callee")))) {
14553
- const target = readConfigKey(this.plugin.opts, "inlineHelpers") ? promiseResolve() : helperReference(this.plugin, path, "_await");
14554
- if (types.isConditionalExpression(arg) && types.isIdentifier(arg.test)) {
14555
- if (types.isCallExpression(arg.consequent) && promiseCallExpressionType(arg.consequent) === "resolve" && arg.consequent.arguments.length === 1 && nodesAreEquivalent(arg.consequent.arguments[0])(arg.alternate)) {
14556
- arg = arg.alternate;
14557
- } else if (types.isCallExpression(arg.alternate) && promiseCallExpressionType(arg.alternate) === "resolve" && arg.alternate.arguments.length === 1 && nodesAreEquivalent(arg.alternate.arguments[0])(arg.consequent)) {
14558
- arg = arg.consequent;
14559
- }
14560
- }
14561
- if (types.isConditionalExpression(arg) && types.isCallExpression(arg.consequent) && promiseCallExpressionType(arg.consequent) === "resolve") {
14562
- const consequent = arg.consequent.arguments[0];
14563
- if (consequent && types.isExpression(consequent)) {
14564
- arg = conditionalExpression(arg.test, consequent, arg.alternate);
14565
- }
14566
- }
14567
- if (types.isConditionalExpression(arg) && types.isCallExpression(arg.alternate) && promiseCallExpressionType(arg.alternate) === "resolve") {
14568
- const alternate = arg.alternate.arguments[0];
14569
- if (alternate && types.isExpression(alternate)) {
14570
- arg = conditionalExpression(arg.test, arg.consequent, alternate);
14571
- }
14572
- }
14573
- if (types.isConditionalExpression(arg) && types.isIdentifier(arg.test)) {
14574
- if (types.isIdentifier(arg.consequent) && arg.test.name === arg.consequent.name) {
14575
- if (types.isIdentifier(arg.alternate) && arg.test.name === arg.alternate.name) {
14576
- arg = arg.test;
14577
- } else {
14578
- arg = types.logicalExpression("||", arg.consequent, arg.alternate);
14579
- }
14580
- } else if (types.isIdentifier(arg.alternate) && arg.test.name === arg.alternate.name) {
14581
- arg = types.logicalExpression("&&", arg.alternate, arg.consequent);
14582
- }
14583
- }
14584
- argument.replaceWith(types.callExpression(target, [arg]));
14585
- }
14586
- } else {
14587
- const target = readConfigKey(this.plugin.opts, "inlineHelpers") ? promiseResolve() : helperReference(this.plugin, path, "_await");
14588
- argument.replaceWith(types.callExpression(target, []));
14589
- }
14590
- }
14591
- }
14592
- };
14593
- function checkForErrorsAndRewriteReturns(path, plugin, rewriteReturns = false) {
14594
- const state = {
14595
- rewriteReturns,
14596
- plugin,
14597
- canThrow: false
14598
- };
14599
- path.traverse(checkForErrorsAndRewriteReturnsVisitor, state);
14600
- return state.canThrow;
14601
- }
14602
- const rewriteTopLevelReturnsVisitor = {
14603
- Function: skipNode,
14604
- ReturnStatement(path) {
14605
- const argument = path.get("argument");
14606
- if (argument.isCallExpression()) {
14607
- const callArgs = argument.node.arguments;
14608
- switch (callArgs.length) {
14609
- case 3:
14610
- case 2:
14611
- {
14612
- const secondArgument = callArgs[1];
14613
- if (!types.isUnaryExpression(secondArgument) || secondArgument.operator !== "void") {
14614
- break;
14615
- }
14616
- }
14617
- case 1:
14618
- if (types.isIdentifier(argument.node.callee) || types.isMemberExpression(argument.node.callee)) {
14619
- const firstArgument = callArgs[0];
14620
- if (types.isExpression(firstArgument)) {
14621
- switch (helperNameMap.get(argument.node.callee)) {
14622
- case "_promiseResolve":
14623
- case "_await":
14624
- argument.replaceWith(firstArgument);
14625
- break;
14626
- case "_call":
14627
- argument.replaceWith(types.callExpression(firstArgument, []));
14628
- break;
14629
- }
14630
- }
14631
- }
14632
- break;
14633
- }
14634
- }
14635
- }
14636
- };
14637
- function reorderPathBeforeSiblingStatements(targetPath) {
14638
- for (const sibling of targetPath.getAllPrevSiblings().reverse()) {
14639
- if (!sibling.isFunctionDeclaration() && !sibling.isImportDeclaration()) {
14640
- const newNode = targetPath.node;
14641
- targetPath.remove();
14642
- reregisterDeclarations(sibling.insertBefore(newNode));
14643
- return;
14644
- }
14645
- }
14646
- }
14647
- function reregisterDeclarations(pathOrPaths) {
14648
- if (Array.isArray(pathOrPaths)) {
14649
- for (const path of pathOrPaths) {
14650
- reregisterDeclarations(path);
14651
- }
14652
- } else if (pathOrPaths && pathOrPaths.isLabeledStatement) {
14653
- const scope = pathOrPaths.isFunction() ? pathOrPaths.parentPath.scope : pathOrPaths.scope;
14654
- if (pathOrPaths.isVariableDeclaration() || pathOrPaths.isFunctionDeclaration() || pathOrPaths.isClassDeclaration()) {
14655
- scope.registerDeclaration(pathOrPaths);
14656
- }
14657
- pathOrPaths.traverse(reregisterVariableVisitor, {
14658
- originalScope: pathOrPaths.scope
14659
- });
14660
- }
14661
- }
14662
- function getPreviousSibling(targetPath) {
14663
- const siblings = targetPath.getAllPrevSiblings();
14664
- return siblings.length !== 0 ? siblings[siblings.length - 1] : undefined;
14665
- }
14666
- function getNextSibling(targetPath) {
14667
- const siblings = targetPath.getAllNextSiblings();
14668
- return siblings.length !== 0 ? siblings[0] : undefined;
14669
- }
14670
- function rewriteDefaultArguments(targetPath) {
14671
- const statements = [];
14672
- const params = targetPath.get("params");
14673
- const literals = [];
14674
- for (let i = 0; i < params.length; i++) {
14675
- const param = params[i];
14676
- if (param.isAssignmentPattern()) {
14677
- const init = param.get("right");
14678
- if (!isExpressionOfLiterals(init, literals)) {
14679
- const left = param.get("left");
14680
- let id;
14681
- let after;
14682
- if (left.isIdentifier()) {
14683
- id = left.node;
14684
- } else {
14685
- id = left.scope.generateUidIdentifier(`arg${i}`);
14686
- after = types.variableDeclaration("let", [types.variableDeclarator(left.node, id)]);
14687
- }
14688
- const initNode = init.node;
14689
- param.replaceWith(id);
14690
- const isMissing = types.binaryExpression("===", id, types.identifier("undefined"));
14691
- const assignment = types.expressionStatement(types.assignmentExpression("=", id, initNode));
14692
- statements.push(types.ifStatement(isMissing, assignment));
14693
- if (after) {
14694
- statements.push(after);
14695
- }
14696
- }
14697
- } else if (param.isIdentifier()) {
14698
- literals.push(param.node.name);
14699
- }
14700
- }
14701
- if (statements.length) {
14702
- targetPath.node.body.body = statements.concat(targetPath.node.body.body);
14703
- }
14704
- }
14705
- const unwrapReturnPromiseVisitor = {
14706
- ReturnStatement(path) {
14707
- const argument = path.get("argument");
14708
- if (argument.isCallExpression()) {
14709
- switch (promiseCallExpressionType(argument.node)) {
14710
- case "all":
14711
- case "race":
14712
- case "resolve":
14713
- switch (argument.node.arguments.length) {
14714
- case 0:
14715
- path.replaceWith(types.returnStatement());
14716
- break;
14717
- case 1:
14718
- const arg0 = argument.node.arguments[0];
14719
- if (types.isExpression(arg0)) {
14720
- path.replaceWith(types.returnStatement(arg0));
14721
- }
14722
- break;
14723
- }
14724
- break;
14725
- }
14726
- }
14727
- }
14728
- };
14729
- const findAwaitExpressionVisitor = {
14730
- AwaitExpression(path) {
14731
- this.awaitPath = path;
14732
- path.stop();
14733
- }
14734
- };
14735
- return {
14736
- name: "transform-async-to-promises",
14737
- manipulateOptions(_options, parserOptions) {
14738
- parserOptions.plugins.push("asyncGenerators");
14739
- },
14740
- visitor: {
14741
- AwaitExpression(path) {
14742
- if (!path.getFunctionParent() && !this.hasTopLevelAwait) {
14743
- this.hasTopLevelAwait = true;
14744
- }
14745
- },
14746
- ImportDeclaration: {
14747
- exit(path) {
14748
- if (this.hasTopLevelAwait && readConfigKey(this.opts, "topLevelAwait") === "simple") {
14749
- throw path.buildCodeFrameError(`Cannot import after a top-level await when using topLevelAwait: "simple"!`, TypeError);
14750
- }
14751
- }
14752
- },
14753
- ExportDeclaration: {
14754
- exit(path) {
14755
- if (this.hasTopLevelAwait && readConfigKey(this.opts, "topLevelAwait") === "simple") {
14756
- throw path.buildCodeFrameError(`Cannot export after a top-level await when using topLevelAwait: "simple"!`, TypeError);
14757
- }
14758
- }
14759
- },
14760
- Program: {
14761
- exit(path) {
14762
- if (this.hasTopLevelAwait) {
14763
- let rediscoverState = {};
14764
- path.traverse(findAwaitExpressionVisitor, rediscoverState);
14765
- if (rediscoverState.awaitPath !== undefined) {
14766
- const functionParent = rediscoverState.awaitPath.getFunctionParent();
14767
- const topLevelAwaitParent = functionParent ? functionParent.get("body") : path;
14768
- switch (readConfigKey(this.opts, "topLevelAwait")) {
14769
- case "simple":
14770
- {
14771
- rewriteAsyncBlock({
14772
- state: this
14773
- }, topLevelAwaitParent, [], undefined, false, true);
14774
- break;
14775
- }
14776
- case "return":
14777
- {
14778
- helperReference(this, path, '_async');
14779
- rewriteAsyncBlock({
14780
- state: this
14781
- }, topLevelAwaitParent, [], undefined, false, false);
14782
- break;
14783
- }
14784
- case "ignore":
14785
- break;
14786
- default:
14787
- throw rediscoverState.awaitPath.buildCodeFrameError(`Top level await is not supported unless experimental topLevelAwait: "simple" or topLevelAwait: "return" options are specified!`, TypeError);
14788
- }
14789
- }
14790
- }
14791
- const usedHelpers = this.usedHelpers;
14792
- if (usedHelpers !== undefined) {
14793
- const file = getFile(path);
14794
- for (const helperName of Object.keys(usedHelpers)) {
14795
- const helper = helpers[helperName];
14796
- const value = cloneNode(helper.value);
14797
- const newPath = insertHelper(file.path, value);
14798
- newPath.traverse({
14799
- Identifier(identifierPath) {
14800
- const name = identifierPath.node.name;
14801
- if (Object.hasOwnProperty.call(helpers, name)) {
14802
- identifierPath.replaceWith(file.declarations[name]);
14803
- }
14804
- }
14805
- });
14806
- }
14807
- }
14808
- }
14809
- },
14810
- FunctionDeclaration(path) {
14811
- if (!readConfigKey(this.opts, 'asyncAwait')) {
14812
- return;
14813
- }
14814
- const node = path.node;
14815
- if (node.async) {
14816
- const expression = types.functionExpression(undefined, node.params, node.body, node.generator, node.async);
14817
- if (node.id === null || node.id === undefined) {
14818
- path.replaceWith(expression);
14819
- reregisterDeclarations(path);
14820
- return;
14821
- }
14822
- const declarators = [types.variableDeclarator(node.id, expression)];
14823
- if (path.parentPath.isExportDeclaration()) {
14824
- if (path.parentPath.isExportDefaultDeclaration()) {
14825
- const targetPath = path.parentPath;
14826
- targetPath.replaceWith(types.variableDeclaration("const", declarators));
14827
- reregisterDeclarations(targetPath);
14828
- reregisterDeclarations(targetPath.insertAfter(types.exportDefaultDeclaration(node.id)));
14829
- reorderPathBeforeSiblingStatements(targetPath);
14830
- } else {
14831
- path.replaceWith(types.variableDeclaration("const", declarators));
14832
- reregisterDeclarations(path);
14833
- reorderPathBeforeSiblingStatements(path.parentPath);
14834
- }
14835
- } else {
14836
- path.replaceWith(types.variableDeclaration("const", declarators));
14837
- reregisterDeclarations(path);
14838
- reorderPathBeforeSiblingStatements(path);
14839
- }
14840
- }
14841
- },
14842
- ArrowFunctionExpression(path) {
14843
- if (!readConfigKey(this.opts, 'asyncAwait')) {
14844
- return;
14845
- }
14846
- const node = path.node;
14847
- if (node.async) {
14848
- rewriteThisExpressions(path, path.getFunctionParent() || path.scope.getProgramParent().path);
14849
- const body = types.isBlockStatement(path.node.body) ? path.node.body : blockStatement([types.returnStatement(path.node.body)]);
14850
- path.replaceWith(types.functionExpression(undefined, node.params, body, false, node.async));
14851
- reregisterDeclarations(path);
14852
- }
14853
- },
14854
- FunctionExpression(path) {
14855
- if (!readConfigKey(this.opts, 'asyncAwait')) {
14856
- return;
14857
- }
14858
- if (path.node.async) {
14859
- const id = path.node.id;
14860
- if (path.parentPath.isExportDefaultDeclaration() && id !== null && id !== undefined) {
14861
- const targetPath = path.parentPath;
14862
- targetPath.replaceWith(types.variableDeclaration("const", [types.variableDeclarator(id, types.functionExpression(undefined, path.node.params, path.node.body, path.node.generator, path.node.async))]));
14863
- reregisterDeclarations(targetPath);
14864
- reregisterDeclarations(targetPath.insertAfter(types.exportDefaultDeclaration(id)));
14865
- reorderPathBeforeSiblingStatements(targetPath);
14866
- return;
14867
- }
14868
- rewriteDefaultArguments(path);
14869
- rewriteThisArgumentsAndHoistFunctions(path, path, false);
14870
- const bodyPath = path.get("body");
14871
- if (path.node.generator) {
14872
- const generatorIdentifier = path.scope.generateUidIdentifier("generator");
14873
- path.scope.push({
14874
- kind: "const",
14875
- id: generatorIdentifier,
14876
- unique: true
14877
- });
14878
- const generatorBinding = path.scope.getBinding(generatorIdentifier.name);
14879
- if (typeof generatorBinding === "undefined") {
14880
- throw path.buildCodeFrameError(`Could not find newly created binding for ${generatorIdentifier.name}!`, Error);
14881
- }
14882
- rewriteAsyncBlock({
14883
- state: this,
14884
- generatorIdentifier
14885
- }, bodyPath, []);
14886
- generatorBinding.path.remove();
14887
- path.replaceWith(functionize(this, path.node.params, types.newExpression(helperReference(this, path, "_AsyncGenerator"), [functionize(this, [generatorIdentifier], bodyPath.node, path)]), path, id));
14888
- } else {
14889
- rewriteAsyncBlock({
14890
- state: this
14891
- }, path, []);
14892
- const inlineHelpers = readConfigKey(this.opts, "inlineHelpers");
14893
- const canThrow = checkForErrorsAndRewriteReturns(bodyPath, this, inlineHelpers || id !== null && id !== undefined);
14894
- const parentPath = path.parentPath;
14895
- const skipReturn = parentPath.isCallExpression() && parentPath.node.callee === path.node && parentPath.parentPath.isExpressionStatement();
14896
- if (!skipReturn && !pathsReturnOrThrowCurrentNodes(bodyPath).all) {
14897
- const awaitHelper = inlineHelpers ? promiseResolve() : helperReference(this, path, "_await");
14898
- path.node.body.body.push(types.returnStatement(types.callExpression(awaitHelper, [])));
14899
- }
14900
- if (skipReturn) {
14901
- path.traverse(unwrapReturnPromiseVisitor);
14902
- }
14903
- if (canThrow) {
14904
- if (inlineHelpers || id) {
14905
- if (!id && skipReturn && parentPath.isCallExpression() && parentPath.node.arguments.length === 0 && !pathsReturn(bodyPath).any) {
14906
- parentPath.parentPath.replaceWith(types.tryStatement(bodyPath.node, types.catchClause(types.identifier("e"), blockStatement([types.expressionStatement(types.callExpression(types.memberExpression(types.identifier("Promise"), types.identifier("reject")), [types.identifier("e")]))]))));
14907
- } else {
14908
- path.replaceWith(functionize(this, path.node.params, blockStatement(types.tryStatement(bodyPath.node, types.catchClause(types.identifier("e"), blockStatement([(skipReturn ? types.expressionStatement : types.returnStatement)(types.callExpression(types.memberExpression(types.identifier("Promise"), types.identifier("reject")), [types.identifier("e")]))])))), path, id));
14909
- }
14910
- } else {
14911
- bodyPath.traverse(rewriteTopLevelReturnsVisitor);
14912
- path.replaceWith(types.callExpression(helperReference(this, path, "_async"), [functionize(this, path.node.params, bodyPath.node, path)]));
14913
- }
14914
- } else {
14915
- if (!inlineHelpers) {
14916
- checkForErrorsAndRewriteReturns(bodyPath, this, true);
14917
- }
14918
- path.replaceWith(functionize(this, path.node.params, bodyPath.node, path, id));
14919
- }
14920
- }
14921
- nodeIsAsyncSet.add(path.node);
14922
- }
14923
- },
14924
- ClassMethod(path) {
14925
- if (!readConfigKey(this.opts, 'asyncAwait')) {
14926
- return;
14927
- }
14928
- if (path.node.async) {
14929
- const body = path.get("body");
14930
- if (path.node.kind === "method") {
14931
- rewriteDefaultArguments(path);
14932
- body.replaceWith(types.blockStatement([body.node]));
14933
- const target = body.get("body")[0];
14934
- if (!target.isBlockStatement()) {
14935
- throw path.buildCodeFrameError(`Expected a BlockStatement, got a ${target.type}`, TypeError);
14936
- }
14937
- if (path.node.generator) {
14938
- const generatorIdentifier = target.scope.generateUidIdentifier("generator");
14939
- target.scope.push({
14940
- kind: "const",
14941
- id: generatorIdentifier,
14942
- init: generatorIdentifier,
14943
- unique: true
14944
- });
14945
- const generatorBinding = target.scope.getBinding(generatorIdentifier.name);
14946
- if (typeof generatorBinding === "undefined") {
14947
- throw path.buildCodeFrameError(`Could not find newly created binding for ${generatorIdentifier.name}!`, Error);
14948
- }
14949
- rewriteAsyncBlock({
14950
- state: this,
14951
- generatorIdentifier
14952
- }, target, []);
14953
- generatorBinding.path.remove();
14954
- target.replaceWith(types.returnStatement(types.newExpression(helperReference(this, path, "_AsyncGenerator"), [functionize(this, [generatorIdentifier], target.node, target)])));
14955
- } else {
14956
- const inlineHelpers = readConfigKey(this.opts, "inlineHelpers");
14957
- rewriteThisArgumentsAndHoistFunctions(target, inlineHelpers ? target : body, true);
14958
- rewriteAsyncBlock({
14959
- state: this
14960
- }, target, []);
14961
- const statements = target.get("body");
14962
- const lastStatement = statements[statements.length - 1];
14963
- if (!lastStatement || !lastStatement.isReturnStatement()) {
14964
- const awaitHelper = inlineHelpers ? promiseResolve() : helperReference(this, path, "_await");
14965
- target.node.body.push(types.returnStatement(types.callExpression(awaitHelper, [])));
14966
- }
14967
- const canThrow = checkForErrorsAndRewriteReturns(body, this, true);
14968
- if (!canThrow) {
14969
- target.replaceWithMultiple(target.node.body);
14970
- } else if (inlineHelpers) {
14971
- target.replaceWith(types.tryStatement(target.node, types.catchClause(types.identifier("e"), blockStatement([types.returnStatement(types.callExpression(types.memberExpression(types.identifier("Promise"), types.identifier("reject")), [types.identifier("e")]))]))));
14972
- } else {
14973
- target.replaceWith(types.returnStatement(types.callExpression(helperReference(this, path, "_call"), [functionize(this, [], target.node, path)])));
14974
- }
14975
- }
14976
- }
14977
- path.replaceWith(types.classMethod(path.node.kind, path.node.key, path.node.params, path.node.body, path.node.computed, path.node.static));
14978
- }
14979
- },
14980
- ObjectMethod(path) {
14981
- if (!readConfigKey(this.opts, 'asyncAwait')) {
14982
- return;
14983
- }
14984
- if (path.node.async) {
14985
- if (path.node.kind === "method") {
14986
- 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));
14987
- }
14988
- }
14989
- }
14990
- }
14991
- };
14992
- }
14993
-
14994
- const systemJsClientFileUrlDefault = new URL("./js/s.js", import.meta.url).href;
14995
- const convertJsModuleToJsClassic = async ({
14996
- systemJsInjection,
14997
- systemJsClientFileUrl = systemJsClientFileUrlDefault,
14998
- urlInfo,
14999
- jsModuleUrlInfo
15000
- }) => {
15001
- let jsClassicFormat;
15002
- if (urlInfo.isEntryPoint && !jsModuleUrlInfo.data.usesImport) {
15003
- // if it's an entry point without dependency (it does not use import)
15004
- // then we can use UMD
15005
- jsClassicFormat = "umd";
15006
- } else {
15007
- // otherwise we have to use system in case it's imported
15008
- // by an other file (for entry points)
15009
- // or to be able to import when it uses import
15010
- jsClassicFormat = "system";
15011
- }
15012
- urlInfo.data.jsClassicFormat = jsClassicFormat;
15013
- const {
15014
- code,
15015
- map
15016
- } = await applyBabelPlugins({
15017
- babelPlugins: [...(jsClassicFormat === "system" ? [
15018
- // proposal-dynamic-import required with systemjs for babel8:
15019
- // https://github.com/babel/babel/issues/10746
15020
- requireFromJsenv("@babel/plugin-proposal-dynamic-import"), requireFromJsenv("@babel/plugin-transform-modules-systemjs"), [babelPluginRelativeImports, {
15021
- rootUrl: jsModuleUrlInfo.url
15022
- }], [default_1, {
15023
- asyncAwait: false,
15024
- // already handled + we might not needs it at all
15025
- topLevelAwait: "return"
15026
- }]] : [[requireBabelPlugin("babel-plugin-transform-async-to-promises"), {
15027
- asyncAwait: false,
15028
- // already handled + we might not needs it at all
15029
- topLevelAwait: "simple"
15030
- }], babelPluginTransformImportMetaUrl, babelPluginTransformImportMetaResolve, requireFromJsenv("@babel/plugin-transform-modules-umd"), [babelPluginRelativeImports, {
15031
- rootUrl: jsModuleUrlInfo.url
15032
- }]])],
15033
- urlInfo: jsModuleUrlInfo
15034
- });
15035
- let sourcemap = jsModuleUrlInfo.sourcemap;
15036
- sourcemap = await composeTwoSourcemaps(sourcemap, map);
15037
- if (systemJsInjection && jsClassicFormat === "system" && urlInfo.isEntryPoint) {
15038
- const magicSource = createMagicSource(code);
15039
- let systemJsFileContent = readFileSync(systemJsClientFileUrl, {
15040
- as: "string"
15041
- });
15042
- const sourcemapFound = SOURCEMAP.readComment({
15043
- contentType: "text/javascript",
15044
- content: systemJsFileContent
15045
- });
15046
- if (sourcemapFound) {
15047
- // for now let's remove s.js sourcemap
15048
- // because it would likely mess the sourcemap of the entry point itself
15049
- systemJsFileContent = SOURCEMAP.writeComment({
15050
- contentType: "text/javascript",
15051
- content: systemJsFileContent,
15052
- specifier: ""
15053
- });
15054
- }
15055
- magicSource.prepend(`${systemJsFileContent}\n\n`);
15056
- const magicResult = magicSource.toContentAndSourcemap();
15057
- sourcemap = await composeTwoSourcemaps(sourcemap, magicResult.sourcemap);
15058
- return {
15059
- content: magicResult.content,
15060
- sourcemap
15061
- };
15062
- }
15063
- return {
15064
- content: code,
15065
- sourcemap
15066
- };
15067
- };
15068
-
15069
- /*
15070
- * When systemjs or umd format is used by babel, it will generated UID based on
15071
- * the import specifier:
15072
- * https://github.com/babel/babel/blob/97d1967826077f15e766778c0d64711399e9a72a/packages/babel-plugin-transform-modules-systemjs/src/index.ts#L498
15073
- * But at this stage import specifier are absolute file urls
15074
- * This can be mitigated by minification that will rename them.
15075
- * But to fix this issue once and for all there is babelPluginRelativeImports below
15076
- */
15077
- const babelPluginRelativeImports = babel => {
15078
- const t = babel.types;
15079
- const replaceSpecifierAtPath = (path, state) => {
15080
- const specifier = path.node.value;
15081
- if (specifier.startsWith("file://")) {
15082
- const specifierRelative = urlToRelativeUrl(specifier, state.opts.rootUrl);
15083
- path.replaceWith(t.stringLiteral(specifierRelative));
15084
- }
15085
- };
15086
- return {
15087
- name: "relative-imports",
15088
- visitor: {
15089
- CallExpression: (path, state) => {
15090
- if (path.node.callee.type !== "Import") {
15091
- // Some other function call, not import();
15092
- return;
15093
- }
15094
- if (path.node.arguments[0].type !== "StringLiteral") {
15095
- // Non-string argument, probably a variable or expression, e.g.
15096
- // import(moduleId)
15097
- // import('./' + moduleName)
15098
- return;
15099
- }
15100
- const sourcePath = path.get("arguments")[0];
15101
- if (sourcePath.node.type === "StringLiteral") {
15102
- replaceSpecifierAtPath(sourcePath, state);
15103
- }
15104
- },
15105
- ImportDeclaration: (path, state) => {
15106
- const sourcePath = path.get("source");
15107
- replaceSpecifierAtPath(sourcePath, state);
15108
- },
15109
- ExportAllDeclaration: (path, state) => {
15110
- const sourcePath = path.get("source");
15111
- replaceSpecifierAtPath(sourcePath, state);
15112
- },
15113
- ExportNamedDeclaration: (path, state) => {
15114
- if (!path.node.source) {
15115
- // This export has no "source", so it's probably
15116
- // a local variable or function, e.g.
15117
- // export { varName }
15118
- // export const constName = ...
15119
- // export function funcName() {}
15120
- return;
15121
- }
15122
- const sourcePath = path.get("source");
15123
- if (sourcePath.node.type === "StringLiteral") {
15124
- replaceSpecifierAtPath(sourcePath, state);
15125
- }
15126
- }
15127
- }
15128
- };
15129
- };
15130
-
15131
- /*
15132
- * - propagate "?js_module_fallback" query string param on urls
15133
- * - perform conversion from js module to js classic when url uses "?js_module_fallback"
15134
- */
15135
-
15136
- const jsenvPluginJsModuleConversion = ({
15137
- systemJsInjection,
15138
- systemJsClientFileUrl,
15139
- generateJsClassicFilename
15140
- }) => {
15141
- const isReferencingJsModule = reference => {
15142
- if (reference.type === "js_import" || reference.subtype === "system_register_arg" || reference.subtype === "system_import_arg") {
15143
- return true;
15144
- }
15145
- if (reference.type === "js_url" && reference.expectedType === "js_module") {
15146
- return true;
15147
- }
15148
- return false;
15149
- };
15150
- const shouldPropagateJsModuleConversion = (reference, context) => {
15151
- if (isReferencingJsModule(reference)) {
15152
- const parentUrlInfo = context.urlGraph.getUrlInfo(reference.parentUrl);
15153
- if (!parentUrlInfo) {
15154
- return false;
15155
- }
15156
- const parentGotAsJsClassic = new URL(parentUrlInfo.url).searchParams.has("js_module_fallback");
15157
- return parentGotAsJsClassic;
15158
- }
15159
- return false;
15160
- };
15161
- const markAsJsClassicProxy = reference => {
15162
- reference.expectedType = "js_classic";
15163
- reference.filename = generateJsClassicFilename(reference.url);
15164
- };
15165
- const turnIntoJsClassicProxy = reference => {
15166
- const urlTransformed = injectQueryParams(reference.url, {
15167
- js_module_fallback: ""
15168
- });
15169
- markAsJsClassicProxy(reference);
15170
- return urlTransformed;
15171
- };
15172
- return {
15173
- name: "jsenv:js_module_conversion",
15174
- appliesDuring: "*",
15175
- redirectReference: (reference, context) => {
15176
- if (reference.searchParams.has("js_module_fallback")) {
15177
- markAsJsClassicProxy(reference);
15178
- return null;
15179
- }
15180
- // We want to propagate transformation of js module to js classic to:
15181
- // - import specifier (static/dynamic import + re-export)
15182
- // - url specifier when inside System.register/_context.import()
15183
- // (because it's the transpiled equivalent of static and dynamic imports)
15184
- // And not other references otherwise we could try to transform inline resources
15185
- // or specifiers inside new URL()...
15186
- if (shouldPropagateJsModuleConversion(reference, context)) {
15187
- return turnIntoJsClassicProxy(reference);
15188
- }
15189
- return null;
15190
- },
15191
- fetchUrlContent: async (urlInfo, context) => {
15192
- const [jsModuleReference, jsModuleUrlInfo] = context.getWithoutSearchParam({
15193
- urlInfo,
15194
- context,
15195
- searchParam: "js_module_fallback",
15196
- // override the expectedType to "js_module"
15197
- // because when there is ?js_module_fallback it means the underlying resource
15198
- // is a js_module
15199
- expectedType: "js_module"
15200
- });
15201
- if (!jsModuleReference) {
15202
- return null;
15203
- }
15204
- await context.fetchUrlContent(jsModuleUrlInfo, {
15205
- reference: jsModuleReference
15206
- });
15207
- if (context.dev) {
15208
- context.referenceUtils.found({
15209
- type: "js_import",
15210
- subtype: jsModuleReference.subtype,
15211
- specifier: jsModuleReference.url,
15212
- expectedType: "js_module"
15213
- });
15214
- } else if (context.build && jsModuleUrlInfo.dependents.size === 0) {
15215
- context.urlGraph.deleteUrlInfo(jsModuleUrlInfo.url);
15216
- }
15217
- const {
15218
- content,
15219
- sourcemap
15220
- } = await convertJsModuleToJsClassic({
15221
- rootDirectoryUrl: context.rootDirectoryUrl,
15222
- systemJsInjection,
15223
- systemJsClientFileUrl,
15224
- urlInfo,
15225
- jsModuleUrlInfo
15226
- });
15227
- return {
15228
- content,
15229
- contentType: "text/javascript",
15230
- type: "js_classic",
15231
- originalUrl: jsModuleUrlInfo.originalUrl,
15232
- originalContent: jsModuleUrlInfo.originalContent,
15233
- sourcemap,
15234
- data: jsModuleUrlInfo.data
15235
- };
15236
- }
15237
- };
15238
- };
15239
-
15240
- /*
15241
- * when <script type="module"> cannot be used:
15242
- * - ?js_module_fallback is injected into the src of <script type="module">
15243
- * - js inside <script type="module"> is transformed into classic js
15244
- * - <link rel="modulepreload"> are converted to <link rel="preload">
15245
- */
15246
-
15247
- const jsenvPluginJsModuleFallbackInsideHtml = ({
15248
- systemJsInjection,
15249
- systemJsClientFileUrl
15250
- }) => {
15251
- const turnIntoJsClassicProxy = reference => {
15252
- return injectQueryParams(reference.url, {
15253
- js_module_fallback: ""
15254
- });
15255
- };
15256
- return {
15257
- name: "jsenv:js_module_fallback_inside_html",
15258
- appliesDuring: "*",
15259
- redirectReference: {
15260
- link_href: (reference, context) => {
15261
- if (context.systemJsTranspilation && reference.subtype === "modulepreload") {
15262
- return turnIntoJsClassicProxy(reference);
15263
- }
15264
- if (context.systemJsTranspilation && reference.subtype === "preload" && reference.expectedType === "js_module") {
15265
- return turnIntoJsClassicProxy(reference);
15266
- }
15267
- return null;
15268
- },
15269
- script: (reference, context) => {
15270
- if (context.systemJsTranspilation && reference.expectedType === "js_module") {
15271
- return turnIntoJsClassicProxy(reference);
15272
- }
15273
- return null;
15274
- },
15275
- js_url: (reference, context) => {
15276
- if (context.systemJsTranspilation && reference.expectedType === "js_module") {
15277
- return turnIntoJsClassicProxy(reference);
15278
- }
15279
- return null;
15280
- }
15281
- },
15282
- finalizeUrlContent: {
15283
- html: async (urlInfo, context) => {
15284
- const htmlAst = parseHtmlString(urlInfo.content);
15285
- const mutations = [];
15286
- visitHtmlNodes(htmlAst, {
15287
- link: node => {
15288
- const rel = getHtmlNodeAttribute(node, "rel");
15289
- if (rel !== "modulepreload" && rel !== "preload") {
15290
- return;
11537
+ },
11538
+ finalizeUrlContent: {
11539
+ html: async (urlInfo, context) => {
11540
+ const htmlAst = parseHtmlString(urlInfo.content);
11541
+ const mutations = [];
11542
+ visitHtmlNodes(htmlAst, {
11543
+ link: node => {
11544
+ const rel = getHtmlNodeAttribute(node, "rel");
11545
+ if (rel !== "modulepreload" && rel !== "preload") {
11546
+ return;
15291
11547
  }
15292
11548
  const href = getHtmlNodeAttribute(node, "href");
15293
11549
  if (!href) {
@@ -15378,7 +11634,7 @@ const jsenvPluginJsModuleFallbackInsideHtml = ({
15378
11634
  }
15379
11635
  if (needsSystemJs) {
15380
11636
  mutations.push(async () => {
15381
- let systemJsFileContent = readFileSync$1(new URL(systemJsClientFileUrl), {
11637
+ let systemJsFileContent = readFileSync(new URL(systemJsClientFileUrl), {
15382
11638
  encoding: "utf8"
15383
11639
  });
15384
11640
  const sourcemapFound = SOURCEMAP.readComment({
@@ -16407,7 +12663,7 @@ const defaultLookupPackageScope = url => {
16407
12663
 
16408
12664
  const defaultReadPackageJson = packageUrl => {
16409
12665
  const packageJsonUrl = new URL("package.json", packageUrl);
16410
- const buffer = readFileSync$1(packageJsonUrl);
12666
+ const buffer = readFileSync(packageJsonUrl);
16411
12667
  const string = String(buffer);
16412
12668
  try {
16413
12669
  return JSON.parse(string);
@@ -17123,7 +13379,7 @@ const mainLegacyResolvers = {
17123
13379
  };
17124
13380
  }
17125
13381
  const browserMainUrlObject = new URL(browserMain, packageDirectoryUrl);
17126
- const content = readFileSync$1(browserMainUrlObject, "utf-8");
13382
+ const content = readFileSync(browserMainUrlObject, "utf-8");
17127
13383
  if (/typeof exports\s*==/.test(content) && /typeof module\s*==/.test(content) || /module\.exports\s*=/.test(content)) {
17128
13384
  return {
17129
13385
  type: "field:module",
@@ -17375,7 +13631,7 @@ const addRelationshipWithPackageJson = ({
17375
13631
  hasVersioningEffect
17376
13632
  });
17377
13633
  if (packageJsonUrlInfo.type === undefined) {
17378
- const packageJsonContentAsBuffer = readFileSync$1(new URL(packageJsonUrl));
13634
+ const packageJsonContentAsBuffer = readFileSync(new URL(packageJsonUrl));
17379
13635
  packageJsonUrlInfo.type = "json";
17380
13636
  packageJsonUrlInfo.content = String(packageJsonContentAsBuffer);
17381
13637
  packageJsonUrlInfo.originalContentEtag = packageJsonUrlInfo.contentEtag = bufferToEtag$1(packageJsonContentAsBuffer);
@@ -17659,7 +13915,7 @@ const jsenvPluginProtocolFile = ({
17659
13915
  filename
17660
13916
  };
17661
13917
  }
17662
- const fileBuffer = readFileSync$1(urlObject);
13918
+ const fileBuffer = readFileSync(urlObject);
17663
13919
  const contentType = CONTENT_TYPE.fromUrlExtension(urlInfo.url);
17664
13920
  return {
17665
13921
  content: CONTENT_TYPE.isTextual(contentType) ? String(fileBuffer) : fileBuffer,
@@ -18428,6 +14684,12 @@ const babelHelperNameFromUrl = url => {
18428
14684
  return babelHelperName;
18429
14685
  };
18430
14686
 
14687
+ const requireFromJsenv = createRequire(import.meta.url);
14688
+
14689
+ const babelPluginPackagePath = requireFromJsenv.resolve("@jsenv/babel-plugins");
14690
+ const babelPluginPackageUrl = pathToFileURL(babelPluginPackagePath);
14691
+ const requireBabelPlugin = createRequire(babelPluginPackageUrl);
14692
+
18431
14693
  /* eslint-disable camelcase */
18432
14694
  // copied from
18433
14695
  // https://github.com/babel/babel/blob/e498bee10f0123bb208baa228ce6417542a2c3c4/packages/babel-compat-data/data/plugins.json#L1
@@ -20819,7 +17081,7 @@ ${ANSI.color(buildUrl, ANSI.MAGENTA)}
20819
17081
  }), ...(lineBreakNormalization ? [jsenvPluginLineBreakNormalization()] : []), jsenvPluginJsModuleFallback({
20820
17082
  systemJsInjection: true
20821
17083
  }), jsenvPluginInlining(), {
20822
- name: "jsenv:build",
17084
+ name: "jsenv:build_shape",
20823
17085
  appliesDuring: "build",
20824
17086
  resolveReference: reference => {
20825
17087
  const getUrl = () => {
@@ -22247,7 +18509,7 @@ const createFileService = ({
22247
18509
  // file is not watched, check the filesystem
22248
18510
  let fileContentAsBuffer;
22249
18511
  try {
22250
- fileContentAsBuffer = readFileSync$1(new URL(urlInfo.url));
18512
+ fileContentAsBuffer = readFileSync(new URL(urlInfo.url));
22251
18513
  } catch (e) {
22252
18514
  if (e.code === "ENOENT") {
22253
18515
  // we should consider calling urlGraph.deleteUrlInfo(urlInfo)
@@ -22502,12 +18764,7 @@ const inferParentFromRequest = (request, sourceDirectoryUrl, sourceMainFilePath)
22502
18764
  return null;
22503
18765
  }
22504
18766
  const refererUrlObject = new URL(referer);
22505
- refererUrlObject.searchParams.delete("hmr");
22506
- refererUrlObject.searchParams.delete("v");
22507
- let refererUrl = refererUrlObject.href;
22508
- if (refererUrl === `${request.origin}/`) {
22509
- refererUrl = new URL(sourceMainFilePath, request.origin).href;
22510
- }
18767
+ const refererUrl = refererUrlObject.pathname === `/` ? new URL(sourceMainFilePath, request.origin).href : referer;
22511
18768
  return WEB_URL_CONVERTER.asFileUrl(refererUrl, {
22512
18769
  origin: request.origin,
22513
18770
  rootDirectoryUrl: sourceDirectoryUrl