Legend:
- Unmodified
- Added
- Removed
-
imaps-frontend/node_modules/rollup/dist/shared/rollup.js
rd565449 r0c6b92a 1 1 /* 2 2 @license 3 Rollup.js v4.2 0.04 Sat, 03 Aug 2024 04:48:21 GMT - commit df12edfea6e9c1a71bda1a01bed1ab787b7514d53 Rollup.js v4.27.4 4 Sat, 23 Nov 2024 06:59:50 GMT - commit e805b546405a4e6cfccd3fe73e9f4df770023824 5 5 6 6 https://github.com/rollup/rollup … … 13 13 const process$1 = require('node:process'); 14 14 const tty = require('tty'); 15 const path $2= require('node:path');15 const path = require('node:path'); 16 16 const require$$0 = require('path'); 17 17 const native_js = require('../native.js'); … … 32 32 const tty__namespace = /*#__PURE__*/_interopNamespaceDefault(tty); 33 33 34 var version = "4.2 0.0";34 var version = "4.27.4"; 35 35 36 36 function ensureArray$1(items) { … … 105 105 const hashPlaceholderOverhead = hashPlaceholderLeft.length + hashPlaceholderRight.length; 106 106 // This is the size of a 128-bits xxhash with base64url encoding 107 const MAX_HASH_SIZE = 2 2;107 const MAX_HASH_SIZE = 21; 108 108 const DEFAULT_HASH_SIZE = 8; 109 109 const getHashPlaceholderGenerator = () => { … … 166 166 const bundleEntries = Object.values(outputBundle); 167 167 for (const asset of bundleEntries) { 168 asset.type === 'asset' && asset.needsCodeReference && unreferencedAssets.add(asset.fileName); 168 if (asset.type === 'asset' && asset.needsCodeReference) { 169 unreferencedAssets.add(asset.fileName); 170 } 169 171 } 170 172 for (const chunk of bundleEntries) { 171 173 if (chunk.type === 'chunk') { 172 174 for (const referencedFile of chunk.referencedFiles) { 173 unreferencedAssets.has(referencedFile) && unreferencedAssets.delete(referencedFile); 175 if (unreferencedAssets.has(referencedFile)) { 176 unreferencedAssets.delete(referencedFile); 177 } 174 178 } 175 179 } … … 196 200 if (!reservedLowercaseBundleKeys.has(name.toLowerCase())) 197 201 return name; 198 const extension = path $2.extname(name);202 const extension = path.extname(name); 199 203 name = name.slice(0, Math.max(0, name.length - extension.length)); 200 204 let uniqueName, uniqueIndex = 1; … … 204 208 } 205 209 206 function generateAssetFileName(name, source, originalFileName, sourceHash, outputOptions, bundle) {210 function generateAssetFileName(name, names, source, originalFileName, originalFileNames, sourceHash, outputOptions, bundle, inputOptions) { 207 211 const emittedName = outputOptions.sanitizeFileName(name || 'asset'); 208 212 return makeUnique(renderNamePattern(typeof outputOptions.assetFileNames === 'function' 209 ? outputOptions.assetFileNames({ name, originalFileName, source, type: 'asset' }) 213 ? outputOptions.assetFileNames({ 214 // Additionally, this should be non-enumerable in the next major 215 get name() { 216 parseAst_js.warnDeprecation('Accessing the "name" property of emitted assets when generating the file name is deprecated. Use the "names" property instead.', parseAst_js.URL_GENERATEBUNDLE, false, inputOptions); 217 return name; 218 }, 219 names, 220 // Additionally, this should be non-enumerable in the next major 221 get originalFileName() { 222 parseAst_js.warnDeprecation('Accessing the "originalFileName" property of emitted assets when generating the file name is deprecated. Use the "originalFileNames" property instead.', parseAst_js.URL_GENERATEBUNDLE, false, inputOptions); 223 return originalFileName; 224 }, 225 originalFileNames, 226 source, 227 type: 'asset' 228 }) 210 229 : outputOptions.assetFileNames, 'output.assetFileNames', { 211 ext: () => path $2.extname(emittedName).slice(1),212 extname: () => path $2.extname(emittedName),230 ext: () => path.extname(emittedName).slice(1), 231 extname: () => path.extname(emittedName), 213 232 hash: size => sourceHash.slice(0, Math.max(0, size || DEFAULT_HASH_SIZE)), 214 name: () => emittedName.slice(0, Math.max(0, emittedName.length - path $2.extname(emittedName).length))233 name: () => emittedName.slice(0, Math.max(0, emittedName.length - path.extname(emittedName).length)) 215 234 }), bundle); 216 235 } … … 323 342 const output = (this.output = { 324 343 bundle, 325 fileNamesBySource : new Map(),344 fileNamesBySourceHash: new Map(), 326 345 getHash, 327 346 outputOptions … … 478 497 return referenceId; 479 498 } 480 finalizeAdditionalAsset(consumedFile, source, { bundle, fileNamesBySource , getHash, outputOptions }) {481 let { fileName, n eedsCodeReference, originalFileName, referenceId } = consumedFile;499 finalizeAdditionalAsset(consumedFile, source, { bundle, fileNamesBySourceHash, getHash, outputOptions }) { 500 let { fileName, name, needsCodeReference, originalFileName, referenceId } = consumedFile; 482 501 // Deduplicate assets if an explicit fileName is not provided 483 502 if (!fileName) { 484 503 const sourceHash = getHash(source); 485 fileName = fileNamesBySource .get(sourceHash);504 fileName = fileNamesBySourceHash.get(sourceHash); 486 505 if (!fileName) { 487 fileName = generateAssetFileName( consumedFile.name, source, originalFileName, sourceHash, outputOptions, bundle);488 fileNamesBySource .set(sourceHash, fileName);506 fileName = generateAssetFileName(name, name ? [name] : [], source, originalFileName, originalFileName ? [originalFileName] : [], sourceHash, outputOptions, bundle, this.options); 507 fileNamesBySourceHash.set(sourceHash, fileName); 489 508 } 490 509 } … … 495 514 if (existingAsset?.type === 'asset') { 496 515 existingAsset.needsCodeReference &&= needsCodeReference; 516 if (name) { 517 existingAsset.names.push(name); 518 } 519 if (originalFileName) { 520 existingAsset.originalFileNames.push(originalFileName); 521 } 497 522 } 498 523 else { 524 const { options } = this; 499 525 bundle[fileName] = { 500 526 fileName, 501 name: consumedFile.name, 527 get name() { 528 // Additionally, this should be non-enumerable in the next major 529 parseAst_js.warnDeprecation('Accessing the "name" property of emitted assets in the bundle is deprecated. Use the "names" property instead.', parseAst_js.URL_GENERATEBUNDLE, false, options); 530 return name; 531 }, 532 names: name ? [name] : [], 502 533 needsCodeReference, 503 originalFileName, 534 get originalFileName() { 535 // Additionally, this should be non-enumerable in the next major 536 parseAst_js.warnDeprecation('Accessing the "originalFileName" property of emitted assets in the bundle is deprecated. Use the "originalFileNames" property instead.', parseAst_js.URL_GENERATEBUNDLE, false, options); 537 return originalFileName; 538 }, 539 originalFileNames: originalFileName ? [originalFileName] : [], 504 540 source, 505 541 type: 'asset' … … 507 543 } 508 544 } 509 finalizeAssetsWithSameSource(consumedFiles, sourceHash, { bundle, fileNamesBySource, outputOptions }) { 545 finalizeAssetsWithSameSource(consumedFiles, sourceHash, { bundle, fileNamesBySourceHash, outputOptions }) { 546 const { names, originalFileNames } = getNamesFromAssets(consumedFiles); 510 547 let fileName = ''; 511 548 let usedConsumedFile; … … 513 550 for (const consumedFile of consumedFiles) { 514 551 needsCodeReference &&= consumedFile.needsCodeReference; 515 const assetFileName = generateAssetFileName(consumedFile.name, consumedFile.source, consumedFile.originalFileName, sourceHash, outputOptions, bundle);552 const assetFileName = generateAssetFileName(consumedFile.name, names, consumedFile.source, consumedFile.originalFileName, originalFileNames, sourceHash, outputOptions, bundle, this.options); 516 553 if (!fileName || 517 554 assetFileName.length < fileName.length || … … 521 558 } 522 559 } 523 fileNamesBySource .set(sourceHash, fileName);560 fileNamesBySourceHash.set(sourceHash, fileName); 524 561 for (const consumedFile of consumedFiles) { 525 562 // We must not modify the original assets to avoid interaction between outputs … … 527 564 this.filesByReferenceId.set(consumedFile.referenceId, assetWithFileName); 528 565 } 566 const { options } = this; 529 567 bundle[fileName] = { 530 568 fileName, 531 name: usedConsumedFile.name, 569 get name() { 570 // Additionally, this should be non-enumerable in the next major 571 parseAst_js.warnDeprecation('Accessing the "name" property of emitted assets in the bundle is deprecated. Use the "names" property instead.', parseAst_js.URL_GENERATEBUNDLE, false, options); 572 return usedConsumedFile.name; 573 }, 574 names, 532 575 needsCodeReference, 533 originalFileName: usedConsumedFile.originalFileName, 576 get originalFileName() { 577 // Additionally, this should be non-enumerable in the next major 578 parseAst_js.warnDeprecation('Accessing the "originalFileName" property of emitted assets in the bundle is deprecated. Use the "originalFileNames" property instead.', parseAst_js.URL_GENERATEBUNDLE, false, options); 579 return usedConsumedFile.originalFileName; 580 }, 581 originalFileNames, 534 582 source: usedConsumedFile.source, 535 583 type: 'asset' … … 537 585 } 538 586 } 539 540 const ANONYMOUS_PLUGIN_PREFIX = 'at position '; 541 const ANONYMOUS_OUTPUT_PLUGIN_PREFIX = 'at output position '; 542 543 function createPluginCache(cache) { 544 return { 545 delete(id) { 546 return delete cache[id]; 547 }, 548 get(id) { 549 const item = cache[id]; 550 if (!item) 551 return; 552 item[0] = 0; 553 return item[1]; 554 }, 555 has(id) { 556 const item = cache[id]; 557 if (!item) 558 return false; 559 item[0] = 0; 560 return true; 561 }, 562 set(id, value) { 563 cache[id] = [0, value]; 564 } 565 }; 566 } 567 function getTrackedPluginCache(pluginCache, onUse) { 568 return { 569 delete(id) { 570 onUse(); 571 return pluginCache.delete(id); 572 }, 573 get(id) { 574 onUse(); 575 return pluginCache.get(id); 576 }, 577 has(id) { 578 onUse(); 579 return pluginCache.has(id); 580 }, 581 set(id, value) { 582 onUse(); 583 return pluginCache.set(id, value); 584 } 585 }; 586 } 587 const NO_CACHE = { 588 delete() { 589 return false; 590 }, 591 get() { 592 return undefined; 593 }, 594 has() { 595 return false; 596 }, 597 set() { } 598 }; 599 function uncacheablePluginError(pluginName) { 600 if (pluginName.startsWith(ANONYMOUS_PLUGIN_PREFIX) || 601 pluginName.startsWith(ANONYMOUS_OUTPUT_PLUGIN_PREFIX)) { 602 return parseAst_js.error(parseAst_js.logAnonymousPluginCache()); 603 } 604 return parseAst_js.error(parseAst_js.logDuplicatePluginName(pluginName)); 605 } 606 function getCacheForUncacheablePlugin(pluginName) { 607 return { 608 delete() { 609 return uncacheablePluginError(pluginName); 610 }, 611 get() { 612 return uncacheablePluginError(pluginName); 613 }, 614 has() { 615 return uncacheablePluginError(pluginName); 616 }, 617 set() { 618 return uncacheablePluginError(pluginName); 619 } 620 }; 587 function getNamesFromAssets(consumedFiles) { 588 const names = []; 589 const originalFileNames = []; 590 for (const { name, originalFileName } of consumedFiles) { 591 if (typeof name === 'string') { 592 names.push(name); 593 } 594 if (originalFileName) { 595 originalFileNames.push(originalFileName); 596 } 597 } 598 originalFileNames.sort(); 599 // Sort by length first and then alphabetically so that the order is stable 600 // and the shortest names come first 601 names.sort((a, b) => a.length - b.length || (a > b ? 1 : a === b ? 0 : -1)); 602 return { names, originalFileNames }; 621 603 } 622 604 … … 717 699 } 718 700 }; 701 const jsxPresets = { 702 preserve: { 703 factory: null, 704 fragment: null, 705 importSource: null, 706 mode: 'preserve' 707 }, 708 'preserve-react': { 709 factory: 'React.createElement', 710 fragment: 'React.Fragment', 711 importSource: 'react', 712 mode: 'preserve' 713 }, 714 react: { 715 factory: 'React.createElement', 716 fragment: 'React.Fragment', 717 importSource: 'react', 718 mode: 'classic' 719 }, 720 'react-jsx': { 721 factory: 'React.createElement', 722 importSource: 'react', 723 jsxImportSource: 'react/jsx-runtime', 724 mode: 'automatic' 725 } 726 }; 719 727 const generatedCodePresets = { 720 728 es2015: { … … 774 782 log.plugin = pluginName; 775 783 logger(level, log); 784 }; 785 } 786 787 const ANONYMOUS_PLUGIN_PREFIX = 'at position '; 788 const ANONYMOUS_OUTPUT_PLUGIN_PREFIX = 'at output position '; 789 790 function createPluginCache(cache) { 791 return { 792 delete(id) { 793 return delete cache[id]; 794 }, 795 get(id) { 796 const item = cache[id]; 797 if (!item) 798 return; 799 item[0] = 0; 800 return item[1]; 801 }, 802 has(id) { 803 const item = cache[id]; 804 if (!item) 805 return false; 806 item[0] = 0; 807 return true; 808 }, 809 set(id, value) { 810 cache[id] = [0, value]; 811 } 812 }; 813 } 814 function getTrackedPluginCache(pluginCache, onUse) { 815 return { 816 delete(id) { 817 onUse(); 818 return pluginCache.delete(id); 819 }, 820 get(id) { 821 onUse(); 822 return pluginCache.get(id); 823 }, 824 has(id) { 825 onUse(); 826 return pluginCache.has(id); 827 }, 828 set(id, value) { 829 onUse(); 830 return pluginCache.set(id, value); 831 } 832 }; 833 } 834 const NO_CACHE = { 835 delete() { 836 return false; 837 }, 838 get() { 839 return undefined; 840 }, 841 has() { 842 return false; 843 }, 844 set() { } 845 }; 846 function uncacheablePluginError(pluginName) { 847 if (pluginName.startsWith(ANONYMOUS_PLUGIN_PREFIX) || 848 pluginName.startsWith(ANONYMOUS_OUTPUT_PLUGIN_PREFIX)) { 849 return parseAst_js.error(parseAst_js.logAnonymousPluginCache()); 850 } 851 return parseAst_js.error(parseAst_js.logDuplicatePluginName(pluginName)); 852 } 853 function getCacheForUncacheablePlugin(pluginName) { 854 return { 855 delete() { 856 return uncacheablePluginError(pluginName); 857 }, 858 get() { 859 return uncacheablePluginError(pluginName); 860 }, 861 has() { 862 return uncacheablePluginError(pluginName); 863 }, 864 set() { 865 return uncacheablePluginError(pluginName); 866 } 776 867 }; 777 868 } … … 993 1084 return handler; 994 1085 } 995 // eslint-disable-next-line @typescript-eslint/ ban-types1086 // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type 996 1087 const hookResult = handler.apply(context, parameters); 997 1088 if (!hookResult?.then) { … … 1038 1129 } 1039 1130 try { 1040 // eslint-disable-next-line @typescript-eslint/ ban-types1131 // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type 1041 1132 return handler.apply(context, parameters); 1042 1133 } … … 1196 1287 external: getExternal(config, overrides), 1197 1288 input: getOption('input') || [], 1289 jsx: getObjectOption(config, overrides, 'jsx', objectifyOptionWithPresets(jsxPresets, 'jsx', parseAst_js.URL_JSX, 'false, ')), 1198 1290 logLevel: getOption('logLevel'), 1199 1291 makeAbsoluteExternalsRelative: getOption('makeAbsoluteExternalsRelative'), … … 1288 1380 sourcemap: getOption('sourcemap'), 1289 1381 sourcemapBaseUrl: getOption('sourcemapBaseUrl'), 1382 sourcemapDebugIds: getOption('sourcemapDebugIds'), 1290 1383 sourcemapExcludeSources: getOption('sourcemapExcludeSources'), 1291 1384 sourcemapFile: getOption('sourcemapFile'), … … 1295 1388 strict: getOption('strict'), 1296 1389 systemNullSetters: getOption('systemNullSetters'), 1297 validate: getOption('validate') 1390 validate: getOption('validate'), 1391 virtualDirname: getOption('virtualDirname') 1298 1392 }; 1299 1393 warnUnknownOptions(config, Object.keys(outputOptions), 'output options', log); … … 1901 1995 this.x_google_ignoreList = properties.x_google_ignoreList; 1902 1996 } 1997 if (typeof properties.debugId !== 'undefined') { 1998 this.debugId = properties.debugId; 1999 } 1903 2000 } 1904 2001 … … 1959 2056 const toString = Object.prototype.toString; 1960 2057 1961 function isObject $1(thing) {2058 function isObject(thing) { 1962 2059 return toString.call(thing) === '[object Object]'; 1963 2060 } … … 2045 2142 2046 2143 while (originalCharIndex < chunk.end) { 2047 if (this.hires || first || sourcemapLocations.has(originalCharIndex)) {2048 const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];2049 2050 if (this.hires === 'boundary') {2051 // in hires "boundary", group segments per word boundary than per char2052 if (wordRegex.test(original[originalCharIndex])) {2053 // for first char in the boundary found, start the boundary by pushing a segment2054 if (!charInHiresBoundary) {2055 this.rawSegments.push(segment);2056 charInHiresBoundary = true;2057 }2058 } else {2059 // for non-word char, end the boundary by pushing a segment2060 this.rawSegments.push(segment);2061 charInHiresBoundary = false;2062 }2063 } else {2064 this.rawSegments.push(segment);2065 }2066 }2067 2068 2144 if (original[originalCharIndex] === '\n') { 2069 2145 loc.line += 1; … … 2074 2150 first = true; 2075 2151 } else { 2152 if (this.hires || first || sourcemapLocations.has(originalCharIndex)) { 2153 const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; 2154 2155 if (this.hires === 'boundary') { 2156 // in hires "boundary", group segments per word boundary than per char 2157 if (wordRegex.test(original[originalCharIndex])) { 2158 // for first char in the boundary found, start the boundary by pushing a segment 2159 if (!charInHiresBoundary) { 2160 this.rawSegments.push(segment); 2161 charInHiresBoundary = true; 2162 } 2163 } else { 2164 // for non-word char, end the boundary by pushing a segment 2165 this.rawSegments.push(segment); 2166 charInHiresBoundary = false; 2167 } 2168 } else { 2169 this.rawSegments.push(segment); 2170 } 2171 } 2172 2076 2173 loc.column += 1; 2077 2174 this.generatedCodeColumn += 1; … … 2280 2377 const pattern = /^[^\r\n]/gm; 2281 2378 2282 if (isObject $1(indentStr)) {2379 if (isObject(indentStr)) { 2283 2380 options = indentStr; 2284 2381 indentStr = undefined; … … 2957 3054 } 2958 3055 2959 if (!isObject $1(source) || !source.content) {3056 if (!isObject(source) || !source.content) { 2960 3057 throw new Error( 2961 3058 'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`', … … 3228 3325 }; 3229 3326 3230 const needsEscapeRegEx = /[\n\r'\\\u2028\u2029]/; 3231 const quoteNewlineRegEx = /([\n\r'\u2028\u2029])/g; 3232 const backSlashRegEx = /\\/g; 3233 function escapeId(id) { 3234 if (!needsEscapeRegEx.test(id)) 3235 return id; 3236 return id.replace(backSlashRegEx, '\\\\').replace(quoteNewlineRegEx, '\\$1'); 3237 } 3238 3239 class ExternalChunk { 3240 constructor(module, options, inputBase) { 3241 this.options = options; 3242 this.inputBase = inputBase; 3243 this.defaultVariableName = ''; 3244 this.namespaceVariableName = ''; 3245 this.variableName = ''; 3246 this.fileName = null; 3247 this.importAttributes = null; 3248 this.id = module.id; 3249 this.moduleInfo = module.info; 3250 this.renormalizeRenderPath = module.renormalizeRenderPath; 3251 this.suggestedVariableName = module.suggestedVariableName; 3252 } 3253 getFileName() { 3254 if (this.fileName) { 3255 return this.fileName; 3256 } 3257 const { paths } = this.options; 3258 return (this.fileName = 3259 (typeof paths === 'function' ? paths(this.id) : paths[this.id]) || 3260 (this.renormalizeRenderPath ? parseAst_js.normalize(path$2.relative(this.inputBase, this.id)) : this.id)); 3261 } 3262 getImportAttributes(snippets) { 3263 return (this.importAttributes ||= formatAttributes(this.options.format === 'es' && 3264 this.options.externalImportAttributes && 3265 this.moduleInfo.attributes, snippets)); 3266 } 3267 getImportPath(importer) { 3268 return escapeId(this.renormalizeRenderPath 3269 ? parseAst_js.getImportPath(importer, this.getFileName(), this.options.format === 'amd', false) 3270 : this.getFileName()); 3271 } 3272 } 3273 function formatAttributes(attributes, { getObject }) { 3274 if (!attributes) { 3275 return null; 3276 } 3277 const assertionEntries = Object.entries(attributes).map(([key, value]) => [key, `'${value}'`]); 3278 if (assertionEntries.length > 0) { 3279 return getObject(assertionEntries, { lineBreakIndent: null }); 3280 } 3281 return null; 3282 } 3327 function treeshakeNode(node, code, start, end) { 3328 code.remove(start, end); 3329 node.removeAnnotations(code); 3330 } 3331 3332 const NO_SEMICOLON = { isNoStatement: true }; 3333 // This assumes there are only white-space and comments between start and the string we are looking for 3334 function findFirstOccurrenceOutsideComment(code, searchString, start = 0) { 3335 let searchPos, charCodeAfterSlash; 3336 searchPos = code.indexOf(searchString, start); 3337 while (true) { 3338 start = code.indexOf('/', start); 3339 if (start === -1 || start >= searchPos) 3340 return searchPos; 3341 charCodeAfterSlash = code.charCodeAt(++start); 3342 ++start; 3343 // With our assumption, '/' always starts a comment. Determine comment type: 3344 start = 3345 charCodeAfterSlash === 47 /*"/"*/ 3346 ? code.indexOf('\n', start) + 1 3347 : code.indexOf('*/', start) + 2; 3348 if (start > searchPos) { 3349 searchPos = code.indexOf(searchString, start); 3350 } 3351 } 3352 } 3353 const NON_WHITESPACE = /\S/g; 3354 function findNonWhiteSpace(code, index) { 3355 NON_WHITESPACE.lastIndex = index; 3356 const result = NON_WHITESPACE.exec(code); 3357 return result.index; 3358 } 3359 const WHITESPACE = /\s/; 3360 function findLastWhiteSpaceReverse(code, start, end) { 3361 while (true) { 3362 if (start >= end) { 3363 return end; 3364 } 3365 if (WHITESPACE.test(code[end - 1])) { 3366 end--; 3367 } 3368 else { 3369 return end; 3370 } 3371 } 3372 } 3373 // This assumes "code" only contains white-space and comments 3374 // Returns position of line-comment if applicable 3375 function findFirstLineBreakOutsideComment(code) { 3376 let lineBreakPos, charCodeAfterSlash, start = 0; 3377 lineBreakPos = code.indexOf('\n', start); 3378 while (true) { 3379 start = code.indexOf('/', start); 3380 if (start === -1 || start > lineBreakPos) 3381 return [lineBreakPos, lineBreakPos + 1]; 3382 // With our assumption, '/' always starts a comment. Determine comment type: 3383 charCodeAfterSlash = code.charCodeAt(start + 1); 3384 if (charCodeAfterSlash === 47 /*"/"*/) 3385 return [start, lineBreakPos + 1]; 3386 start = code.indexOf('*/', start + 2) + 2; 3387 if (start > lineBreakPos) { 3388 lineBreakPos = code.indexOf('\n', start); 3389 } 3390 } 3391 } 3392 function renderStatementList(statements, code, start, end, options) { 3393 let currentNode, currentNodeStart, currentNodeNeedsBoundaries, nextNodeStart; 3394 let nextNode = statements[0]; 3395 let nextNodeNeedsBoundaries = !nextNode.included || nextNode.needsBoundaries; 3396 if (nextNodeNeedsBoundaries) { 3397 nextNodeStart = 3398 start + findFirstLineBreakOutsideComment(code.original.slice(start, nextNode.start))[1]; 3399 } 3400 for (let nextIndex = 1; nextIndex <= statements.length; nextIndex++) { 3401 currentNode = nextNode; 3402 currentNodeStart = nextNodeStart; 3403 currentNodeNeedsBoundaries = nextNodeNeedsBoundaries; 3404 nextNode = statements[nextIndex]; 3405 nextNodeNeedsBoundaries = 3406 nextNode === undefined ? false : !nextNode.included || nextNode.needsBoundaries; 3407 if (currentNodeNeedsBoundaries || nextNodeNeedsBoundaries) { 3408 nextNodeStart = 3409 currentNode.end + 3410 findFirstLineBreakOutsideComment(code.original.slice(currentNode.end, nextNode === undefined ? end : nextNode.start))[1]; 3411 if (currentNode.included) { 3412 if (currentNodeNeedsBoundaries) { 3413 currentNode.render(code, options, { 3414 end: nextNodeStart, 3415 start: currentNodeStart 3416 }); 3417 } 3418 else { 3419 currentNode.render(code, options); 3420 } 3421 } 3422 else { 3423 treeshakeNode(currentNode, code, currentNodeStart, nextNodeStart); 3424 } 3425 } 3426 else { 3427 currentNode.render(code, options); 3428 } 3429 } 3430 } 3431 // This assumes that the first character is not part of the first node 3432 function getCommaSeparatedNodesWithBoundaries(nodes, code, start, end) { 3433 const splitUpNodes = []; 3434 let node, nextNodeStart, contentEnd, char; 3435 let separator = start - 1; 3436 for (const nextNode of nodes) { 3437 if (node !== undefined) { 3438 separator = 3439 node.end + 3440 findFirstOccurrenceOutsideComment(code.original.slice(node.end, nextNode.start), ','); 3441 } 3442 nextNodeStart = contentEnd = 3443 separator + 3444 1 + 3445 findFirstLineBreakOutsideComment(code.original.slice(separator + 1, nextNode.start))[1]; 3446 while (((char = code.original.charCodeAt(nextNodeStart)), 3447 char === 32 /*" "*/ || char === 9 /*"\t"*/ || char === 10 /*"\n"*/ || char === 13) /*"\r"*/) 3448 nextNodeStart++; 3449 if (node !== undefined) { 3450 splitUpNodes.push({ 3451 contentEnd, 3452 end: nextNodeStart, 3453 node, 3454 separator, 3455 start 3456 }); 3457 } 3458 node = nextNode; 3459 start = nextNodeStart; 3460 } 3461 splitUpNodes.push({ 3462 contentEnd: end, 3463 end, 3464 node: node, 3465 separator: null, 3466 start 3467 }); 3468 return splitUpNodes; 3469 } 3470 // This assumes there are only white-space and comments between start and end 3471 function removeLineBreaks(code, start, end) { 3472 while (true) { 3473 const [removeStart, removeEnd] = findFirstLineBreakOutsideComment(code.original.slice(start, end)); 3474 if (removeStart === -1) { 3475 break; 3476 } 3477 code.remove(start + removeStart, (start += removeEnd)); 3478 } 3479 } 3480 3481 function getSystemExportStatement(exportedVariables, { exportNamesByVariable, snippets: { _, getObject, getPropertyAccess } }, modifier = '') { 3482 if (exportedVariables.length === 1 && 3483 exportNamesByVariable.get(exportedVariables[0]).length === 1) { 3484 const variable = exportedVariables[0]; 3485 return `exports(${JSON.stringify(exportNamesByVariable.get(variable)[0])},${_}${variable.getName(getPropertyAccess)}${modifier})`; 3486 } 3487 else { 3488 const fields = []; 3489 for (const variable of exportedVariables) { 3490 for (const exportName of exportNamesByVariable.get(variable)) { 3491 fields.push([exportName, variable.getName(getPropertyAccess) + modifier]); 3492 } 3493 } 3494 return `exports(${getObject(fields, { lineBreakIndent: null })})`; 3495 } 3496 } 3497 // This is only invoked if there is exactly one export name 3498 function renderSystemExportExpression(exportedVariable, expressionStart, expressionEnd, code, { exportNamesByVariable, snippets: { _ } }) { 3499 code.prependRight(expressionStart, `exports(${JSON.stringify(exportNamesByVariable.get(exportedVariable)[0])},${_}`); 3500 code.appendLeft(expressionEnd, ')'); 3501 } 3502 function renderSystemExportFunction(exportedVariables, expressionStart, expressionEnd, needsParens, code, options) { 3503 const { _, getDirectReturnIifeLeft } = options.snippets; 3504 code.prependRight(expressionStart, getDirectReturnIifeLeft(['v'], `${getSystemExportStatement(exportedVariables, options)},${_}v`, { needsArrowReturnParens: true, needsWrappedFunction: needsParens })); 3505 code.appendLeft(expressionEnd, ')'); 3506 } 3507 function renderSystemExportSequenceAfterExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options) { 3508 const { _, getPropertyAccess } = options.snippets; 3509 code.appendLeft(expressionEnd, `,${_}${getSystemExportStatement([exportedVariable], options)},${_}${exportedVariable.getName(getPropertyAccess)}`); 3510 if (needsParens) { 3511 code.prependRight(expressionStart, '('); 3512 code.appendLeft(expressionEnd, ')'); 3513 } 3514 } 3515 function renderSystemExportSequenceBeforeExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options, modifier) { 3516 const { _ } = options.snippets; 3517 code.prependRight(expressionStart, `${getSystemExportStatement([exportedVariable], options, modifier)},${_}`); 3518 if (needsParens) { 3519 code.prependRight(expressionStart, '('); 3520 code.appendLeft(expressionEnd, ')'); 3521 } 3522 } 3523 3524 /** @import { Node } from 'estree' */ 3525 3526 /** 3527 * @param {Node} node 3528 * @param {Node} parent 3529 * @returns {boolean} 3530 */ 3531 function is_reference(node, parent) { 3532 if (node.type === 'MemberExpression') { 3533 return !node.computed && is_reference(node.object, node); 3534 } 3535 3536 if (node.type !== 'Identifier') return false; 3537 3538 switch (parent?.type) { 3539 // disregard `bar` in `foo.bar` 3540 case 'MemberExpression': 3541 return parent.computed || node === parent.object; 3542 3543 // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}` 3544 case 'MethodDefinition': 3545 return parent.computed; 3546 3547 // disregard the `meta` in `import.meta` 3548 case 'MetaProperty': 3549 return parent.meta === node; 3550 3551 // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}` 3552 case 'PropertyDefinition': 3553 return parent.computed || node === parent.value; 3554 3555 // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }` 3556 case 'Property': 3557 return parent.computed || node === parent.value; 3558 3559 // disregard the `bar` in `export { foo as bar }` or 3560 // the foo in `import { foo as bar }` 3561 case 'ExportSpecifier': 3562 case 'ImportSpecifier': 3563 return node === parent.local; 3564 3565 // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}` 3566 case 'LabeledStatement': 3567 case 'BreakStatement': 3568 case 'ContinueStatement': 3569 return false; 3570 3571 default: 3572 return true; 3573 } 3574 } 3575 3576 const PureFunctionKey = Symbol('PureFunction'); 3577 const getPureFunctions = ({ treeshake }) => { 3578 const pureFunctions = Object.create(null); 3579 for (const functionName of treeshake ? treeshake.manualPureFunctions : []) { 3580 let currentFunctions = pureFunctions; 3581 for (const pathSegment of functionName.split('.')) { 3582 currentFunctions = currentFunctions[pathSegment] ||= Object.create(null); 3583 } 3584 currentFunctions[PureFunctionKey] = true; 3585 } 3586 return pureFunctions; 3587 }; 3283 3588 3284 3589 const UnknownKey = Symbol('Unknown Key'); … … 3440 3745 this.alwaysRendered = false; 3441 3746 this.forbiddenNames = null; 3747 this.globalName = null; 3442 3748 this.initReached = false; 3443 3749 this.isId = false; … … 3485 3791 } 3486 3792 getName(getPropertyAccess, useOriginalName) { 3793 if (this.globalName) { 3794 return this.globalName; 3795 } 3487 3796 if (useOriginalName?.(this)) { 3488 3797 return this.name; … … 3498 3807 } 3499 3808 /** 3500 * Marks this variable as being part of the bundle, which is usually the case when one of3501 * its identifiers becomes part of the bundle. Returns true if it has not been included3502 * previously.3503 * Once a variable is included, it shouldtake care all its declarations are included.3809 * Marks this variable as being part of the bundle, which is usually the case 3810 * when one of its identifiers becomes part of the bundle. Returns true if it 3811 * has not been included previously. Once a variable is included, it should 3812 * take care all its declarations are included. 3504 3813 */ 3505 3814 include() { … … 3725 4034 } 3726 4035 3727 function getDefaultExportFromCjs (x) { 3728 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; 3729 } 3730 3731 function getAugmentedNamespace(n) { 3732 if (n.__esModule) return n; 3733 var f = n.default; 3734 if (typeof f == "function") { 3735 var a = function a () { 3736 if (this instanceof a) { 3737 return Reflect.construct(f, arguments, this.constructor); 3738 } 3739 return f.apply(this, arguments); 3740 }; 3741 a.prototype = f.prototype; 3742 } else a = {}; 3743 Object.defineProperty(a, '__esModule', {value: true}); 3744 Object.keys(n).forEach(function (k) { 3745 var d = Object.getOwnPropertyDescriptor(n, k); 3746 Object.defineProperty(a, k, d.get ? d : { 3747 enumerable: true, 3748 get: function () { 3749 return n[k]; 3750 } 3751 }); 3752 }); 3753 return a; 3754 } 3755 3756 var utils$3 = {}; 3757 3758 const path$1 = require$$0; 3759 const WIN_SLASH = '\\\\/'; 3760 const WIN_NO_SLASH = `[^${WIN_SLASH}]`; 3761 3762 /** 3763 * Posix glob regex 3764 */ 3765 3766 const DOT_LITERAL = '\\.'; 3767 const PLUS_LITERAL = '\\+'; 3768 const QMARK_LITERAL = '\\?'; 3769 const SLASH_LITERAL = '\\/'; 3770 const ONE_CHAR = '(?=.)'; 3771 const QMARK = '[^/]'; 3772 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; 3773 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; 3774 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; 3775 const NO_DOT = `(?!${DOT_LITERAL})`; 3776 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; 3777 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; 3778 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; 3779 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; 3780 const STAR = `${QMARK}*?`; 3781 3782 const POSIX_CHARS = { 3783 DOT_LITERAL, 3784 PLUS_LITERAL, 3785 QMARK_LITERAL, 3786 SLASH_LITERAL, 3787 ONE_CHAR, 3788 QMARK, 3789 END_ANCHOR, 3790 DOTS_SLASH, 3791 NO_DOT, 3792 NO_DOTS, 3793 NO_DOT_SLASH, 3794 NO_DOTS_SLASH, 3795 QMARK_NO_DOT, 3796 STAR, 3797 START_ANCHOR 4036 function markModuleAndImpureDependenciesAsExecuted(baseModule) { 4037 baseModule.isExecuted = true; 4038 const modules = [baseModule]; 4039 const visitedModules = new Set(); 4040 for (const module of modules) { 4041 for (const dependency of [...module.dependencies, ...module.implicitlyLoadedBefore]) { 4042 if (!(dependency instanceof ExternalModule) && 4043 !dependency.isExecuted && 4044 (dependency.info.moduleSideEffects || module.implicitlyLoadedBefore.has(dependency)) && 4045 !visitedModules.has(dependency.id)) { 4046 dependency.isExecuted = true; 4047 visitedModules.add(dependency.id); 4048 modules.push(dependency); 4049 } 4050 } 4051 } 4052 } 4053 4054 // This file is generated by scripts/generate-child-node-keys.js. 4055 // Do not edit this file directly. 4056 const childNodeKeys = { 4057 ArrayExpression: ['elements'], 4058 ArrayPattern: ['elements'], 4059 ArrowFunctionExpression: ['params', 'body'], 4060 AssignmentExpression: ['left', 'right'], 4061 AssignmentPattern: ['left', 'right'], 4062 AwaitExpression: ['argument'], 4063 BinaryExpression: ['left', 'right'], 4064 BlockStatement: ['body'], 4065 BreakStatement: ['label'], 4066 CallExpression: ['callee', 'arguments'], 4067 CatchClause: ['param', 'body'], 4068 ChainExpression: ['expression'], 4069 ClassBody: ['body'], 4070 ClassDeclaration: ['decorators', 'id', 'superClass', 'body'], 4071 ClassExpression: ['decorators', 'id', 'superClass', 'body'], 4072 ConditionalExpression: ['test', 'consequent', 'alternate'], 4073 ContinueStatement: ['label'], 4074 DebuggerStatement: [], 4075 Decorator: ['expression'], 4076 DoWhileStatement: ['body', 'test'], 4077 EmptyStatement: [], 4078 ExportAllDeclaration: ['exported', 'source', 'attributes'], 4079 ExportDefaultDeclaration: ['declaration'], 4080 ExportNamedDeclaration: ['specifiers', 'source', 'attributes', 'declaration'], 4081 ExportSpecifier: ['local', 'exported'], 4082 ExpressionStatement: ['expression'], 4083 ForInStatement: ['left', 'right', 'body'], 4084 ForOfStatement: ['left', 'right', 'body'], 4085 ForStatement: ['init', 'test', 'update', 'body'], 4086 FunctionDeclaration: ['id', 'params', 'body'], 4087 FunctionExpression: ['id', 'params', 'body'], 4088 Identifier: [], 4089 IfStatement: ['test', 'consequent', 'alternate'], 4090 ImportAttribute: ['key', 'value'], 4091 ImportDeclaration: ['specifiers', 'source', 'attributes'], 4092 ImportDefaultSpecifier: ['local'], 4093 ImportExpression: ['source', 'options'], 4094 ImportNamespaceSpecifier: ['local'], 4095 ImportSpecifier: ['imported', 'local'], 4096 JSXAttribute: ['name', 'value'], 4097 JSXClosingElement: ['name'], 4098 JSXClosingFragment: [], 4099 JSXElement: ['openingElement', 'children', 'closingElement'], 4100 JSXEmptyExpression: [], 4101 JSXExpressionContainer: ['expression'], 4102 JSXFragment: ['openingFragment', 'children', 'closingFragment'], 4103 JSXIdentifier: [], 4104 JSXMemberExpression: ['object', 'property'], 4105 JSXNamespacedName: ['namespace', 'name'], 4106 JSXOpeningElement: ['name', 'attributes'], 4107 JSXOpeningFragment: [], 4108 JSXSpreadAttribute: ['argument'], 4109 JSXSpreadChild: ['expression'], 4110 JSXText: [], 4111 LabeledStatement: ['label', 'body'], 4112 Literal: [], 4113 LogicalExpression: ['left', 'right'], 4114 MemberExpression: ['object', 'property'], 4115 MetaProperty: ['meta', 'property'], 4116 MethodDefinition: ['decorators', 'key', 'value'], 4117 NewExpression: ['callee', 'arguments'], 4118 ObjectExpression: ['properties'], 4119 ObjectPattern: ['properties'], 4120 PanicError: [], 4121 ParseError: [], 4122 PrivateIdentifier: [], 4123 Program: ['body'], 4124 Property: ['key', 'value'], 4125 PropertyDefinition: ['decorators', 'key', 'value'], 4126 RestElement: ['argument'], 4127 ReturnStatement: ['argument'], 4128 SequenceExpression: ['expressions'], 4129 SpreadElement: ['argument'], 4130 StaticBlock: ['body'], 4131 Super: [], 4132 SwitchCase: ['test', 'consequent'], 4133 SwitchStatement: ['discriminant', 'cases'], 4134 TaggedTemplateExpression: ['tag', 'quasi'], 4135 TemplateElement: [], 4136 TemplateLiteral: ['quasis', 'expressions'], 4137 ThisExpression: [], 4138 ThrowStatement: ['argument'], 4139 TryStatement: ['block', 'handler', 'finalizer'], 4140 UnaryExpression: ['argument'], 4141 UpdateExpression: ['argument'], 4142 VariableDeclaration: ['declarations'], 4143 VariableDeclarator: ['id', 'init'], 4144 WhileStatement: ['test', 'body'], 4145 YieldExpression: ['argument'] 3798 4146 }; 3799 3800 /**3801 * Windows glob regex3802 */3803 3804 const WINDOWS_CHARS = {3805 ...POSIX_CHARS,3806 3807 SLASH_LITERAL: `[${WIN_SLASH}]`,3808 QMARK: WIN_NO_SLASH,3809 STAR: `${WIN_NO_SLASH}*?`,3810 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,3811 NO_DOT: `(?!${DOT_LITERAL})`,3812 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,3813 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,3814 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,3815 QMARK_NO_DOT: `[^.${WIN_SLASH}]`,3816 START_ANCHOR: `(?:^|[${WIN_SLASH}])`,3817 END_ANCHOR: `(?:[${WIN_SLASH}]|$)`3818 };3819 3820 /**3821 * POSIX Bracket Regex3822 */3823 3824 const POSIX_REGEX_SOURCE$1 = {3825 alnum: 'a-zA-Z0-9',3826 alpha: 'a-zA-Z',3827 ascii: '\\x00-\\x7F',3828 blank: ' \\t',3829 cntrl: '\\x00-\\x1F\\x7F',3830 digit: '0-9',3831 graph: '\\x21-\\x7E',3832 lower: 'a-z',3833 print: '\\x20-\\x7E ',3834 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',3835 space: ' \\t\\r\\n\\v\\f',3836 upper: 'A-Z',3837 word: 'A-Za-z0-9_',3838 xdigit: 'A-Fa-f0-9'3839 };3840 3841 var constants$2 = {3842 MAX_LENGTH: 1024 * 64,3843 POSIX_REGEX_SOURCE: POSIX_REGEX_SOURCE$1,3844 3845 // regular expressions3846 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,3847 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,3848 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,3849 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,3850 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,3851 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,3852 3853 // Replace globs with equivalent patterns to reduce parsing time.3854 REPLACEMENTS: {3855 '***': '*',3856 '**/**': '**',3857 '**/**/**': '**'3858 },3859 3860 // Digits3861 CHAR_0: 48, /* 0 */3862 CHAR_9: 57, /* 9 */3863 3864 // Alphabet chars.3865 CHAR_UPPERCASE_A: 65, /* A */3866 CHAR_LOWERCASE_A: 97, /* a */3867 CHAR_UPPERCASE_Z: 90, /* Z */3868 CHAR_LOWERCASE_Z: 122, /* z */3869 3870 CHAR_LEFT_PARENTHESES: 40, /* ( */3871 CHAR_RIGHT_PARENTHESES: 41, /* ) */3872 3873 CHAR_ASTERISK: 42, /* * */3874 3875 // Non-alphabetic chars.3876 CHAR_AMPERSAND: 38, /* & */3877 CHAR_AT: 64, /* @ */3878 CHAR_BACKWARD_SLASH: 92, /* \ */3879 CHAR_CARRIAGE_RETURN: 13, /* \r */3880 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */3881 CHAR_COLON: 58, /* : */3882 CHAR_COMMA: 44, /* , */3883 CHAR_DOT: 46, /* . */3884 CHAR_DOUBLE_QUOTE: 34, /* " */3885 CHAR_EQUAL: 61, /* = */3886 CHAR_EXCLAMATION_MARK: 33, /* ! */3887 CHAR_FORM_FEED: 12, /* \f */3888 CHAR_FORWARD_SLASH: 47, /* / */3889 CHAR_GRAVE_ACCENT: 96, /* ` */3890 CHAR_HASH: 35, /* # */3891 CHAR_HYPHEN_MINUS: 45, /* - */3892 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */3893 CHAR_LEFT_CURLY_BRACE: 123, /* { */3894 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */3895 CHAR_LINE_FEED: 10, /* \n */3896 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */3897 CHAR_PERCENT: 37, /* % */3898 CHAR_PLUS: 43, /* + */3899 CHAR_QUESTION_MARK: 63, /* ? */3900 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */3901 CHAR_RIGHT_CURLY_BRACE: 125, /* } */3902 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */3903 CHAR_SEMICOLON: 59, /* ; */3904 CHAR_SINGLE_QUOTE: 39, /* ' */3905 CHAR_SPACE: 32, /* */3906 CHAR_TAB: 9, /* \t */3907 CHAR_UNDERSCORE: 95, /* _ */3908 CHAR_VERTICAL_LINE: 124, /* | */3909 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */3910 3911 SEP: path$1.sep,3912 3913 /**3914 * Create EXTGLOB_CHARS3915 */3916 3917 extglobChars(chars) {3918 return {3919 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },3920 '?': { type: 'qmark', open: '(?:', close: ')?' },3921 '+': { type: 'plus', open: '(?:', close: ')+' },3922 '*': { type: 'star', open: '(?:', close: ')*' },3923 '@': { type: 'at', open: '(?:', close: ')' }3924 };3925 },3926 3927 /**3928 * Create GLOB_CHARS3929 */3930 3931 globChars(win32) {3932 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;3933 }3934 };3935 3936 (function (exports) {3937 3938 const path = require$$0;3939 const win32 = process.platform === 'win32';3940 const {3941 REGEX_BACKSLASH,3942 REGEX_REMOVE_BACKSLASH,3943 REGEX_SPECIAL_CHARS,3944 REGEX_SPECIAL_CHARS_GLOBAL3945 } = constants$2;3946 3947 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);3948 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);3949 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);3950 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');3951 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');3952 3953 exports.removeBackslashes = str => {3954 return str.replace(REGEX_REMOVE_BACKSLASH, match => {3955 return match === '\\' ? '' : match;3956 });3957 };3958 3959 exports.supportsLookbehinds = () => {3960 const segs = process.version.slice(1).split('.').map(Number);3961 if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {3962 return true;3963 }3964 return false;3965 };3966 3967 exports.isWindows = options => {3968 if (options && typeof options.windows === 'boolean') {3969 return options.windows;3970 }3971 return win32 === true || path.sep === '\\';3972 };3973 3974 exports.escapeLast = (input, char, lastIdx) => {3975 const idx = input.lastIndexOf(char, lastIdx);3976 if (idx === -1) return input;3977 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1);3978 return `${input.slice(0, idx)}\\${input.slice(idx)}`;3979 };3980 3981 exports.removePrefix = (input, state = {}) => {3982 let output = input;3983 if (output.startsWith('./')) {3984 output = output.slice(2);3985 state.prefix = './';3986 }3987 return output;3988 };3989 3990 exports.wrapOutput = (input, state = {}, options = {}) => {3991 const prepend = options.contains ? '' : '^';3992 const append = options.contains ? '' : '$';3993 3994 let output = `${prepend}(?:${input})${append}`;3995 if (state.negated === true) {3996 output = `(?:^(?!${output}).*$)`;3997 }3998 return output;3999 };4000 } (utils$3));4001 4002 const utils$2 = utils$3;4003 const {4004 CHAR_ASTERISK, /* * */4005 CHAR_AT, /* @ */4006 CHAR_BACKWARD_SLASH, /* \ */4007 CHAR_COMMA, /* , */4008 CHAR_DOT, /* . */4009 CHAR_EXCLAMATION_MARK, /* ! */4010 CHAR_FORWARD_SLASH, /* / */4011 CHAR_LEFT_CURLY_BRACE, /* { */4012 CHAR_LEFT_PARENTHESES, /* ( */4013 CHAR_LEFT_SQUARE_BRACKET, /* [ */4014 CHAR_PLUS, /* + */4015 CHAR_QUESTION_MARK, /* ? */4016 CHAR_RIGHT_CURLY_BRACE, /* } */4017 CHAR_RIGHT_PARENTHESES, /* ) */4018 CHAR_RIGHT_SQUARE_BRACKET /* ] */4019 } = constants$2;4020 4021 const isPathSeparator = code => {4022 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;4023 };4024 4025 const depth = token => {4026 if (token.isPrefix !== true) {4027 token.depth = token.isGlobstar ? Infinity : 1;4028 }4029 };4030 4031 /**4032 * Quickly scans a glob pattern and returns an object with a handful of4033 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),4034 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not4035 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).4036 *4037 * ```js4038 * const pm = require('picomatch');4039 * console.log(pm.scan('foo/bar/*.js'));4040 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }4041 * ```4042 * @param {String} `str`4043 * @param {Object} `options`4044 * @return {Object} Returns an object with tokens and regex source string.4045 * @api public4046 */4047 4048 const scan$1 = (input, options) => {4049 const opts = options || {};4050 4051 const length = input.length - 1;4052 const scanToEnd = opts.parts === true || opts.scanToEnd === true;4053 const slashes = [];4054 const tokens = [];4055 const parts = [];4056 4057 let str = input;4058 let index = -1;4059 let start = 0;4060 let lastIndex = 0;4061 let isBrace = false;4062 let isBracket = false;4063 let isGlob = false;4064 let isExtglob = false;4065 let isGlobstar = false;4066 let braceEscaped = false;4067 let backslashes = false;4068 let negated = false;4069 let negatedExtglob = false;4070 let finished = false;4071 let braces = 0;4072 let prev;4073 let code;4074 let token = { value: '', depth: 0, isGlob: false };4075 4076 const eos = () => index >= length;4077 const peek = () => str.charCodeAt(index + 1);4078 const advance = () => {4079 prev = code;4080 return str.charCodeAt(++index);4081 };4082 4083 while (index < length) {4084 code = advance();4085 let next;4086 4087 if (code === CHAR_BACKWARD_SLASH) {4088 backslashes = token.backslashes = true;4089 code = advance();4090 4091 if (code === CHAR_LEFT_CURLY_BRACE) {4092 braceEscaped = true;4093 }4094 continue;4095 }4096 4097 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {4098 braces++;4099 4100 while (eos() !== true && (code = advance())) {4101 if (code === CHAR_BACKWARD_SLASH) {4102 backslashes = token.backslashes = true;4103 advance();4104 continue;4105 }4106 4107 if (code === CHAR_LEFT_CURLY_BRACE) {4108 braces++;4109 continue;4110 }4111 4112 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {4113 isBrace = token.isBrace = true;4114 isGlob = token.isGlob = true;4115 finished = true;4116 4117 if (scanToEnd === true) {4118 continue;4119 }4120 4121 break;4122 }4123 4124 if (braceEscaped !== true && code === CHAR_COMMA) {4125 isBrace = token.isBrace = true;4126 isGlob = token.isGlob = true;4127 finished = true;4128 4129 if (scanToEnd === true) {4130 continue;4131 }4132 4133 break;4134 }4135 4136 if (code === CHAR_RIGHT_CURLY_BRACE) {4137 braces--;4138 4139 if (braces === 0) {4140 braceEscaped = false;4141 isBrace = token.isBrace = true;4142 finished = true;4143 break;4144 }4145 }4146 }4147 4148 if (scanToEnd === true) {4149 continue;4150 }4151 4152 break;4153 }4154 4155 if (code === CHAR_FORWARD_SLASH) {4156 slashes.push(index);4157 tokens.push(token);4158 token = { value: '', depth: 0, isGlob: false };4159 4160 if (finished === true) continue;4161 if (prev === CHAR_DOT && index === (start + 1)) {4162 start += 2;4163 continue;4164 }4165 4166 lastIndex = index + 1;4167 continue;4168 }4169 4170 if (opts.noext !== true) {4171 const isExtglobChar = code === CHAR_PLUS4172 || code === CHAR_AT4173 || code === CHAR_ASTERISK4174 || code === CHAR_QUESTION_MARK4175 || code === CHAR_EXCLAMATION_MARK;4176 4177 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {4178 isGlob = token.isGlob = true;4179 isExtglob = token.isExtglob = true;4180 finished = true;4181 if (code === CHAR_EXCLAMATION_MARK && index === start) {4182 negatedExtglob = true;4183 }4184 4185 if (scanToEnd === true) {4186 while (eos() !== true && (code = advance())) {4187 if (code === CHAR_BACKWARD_SLASH) {4188 backslashes = token.backslashes = true;4189 code = advance();4190 continue;4191 }4192 4193 if (code === CHAR_RIGHT_PARENTHESES) {4194 isGlob = token.isGlob = true;4195 finished = true;4196 break;4197 }4198 }4199 continue;4200 }4201 break;4202 }4203 }4204 4205 if (code === CHAR_ASTERISK) {4206 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;4207 isGlob = token.isGlob = true;4208 finished = true;4209 4210 if (scanToEnd === true) {4211 continue;4212 }4213 break;4214 }4215 4216 if (code === CHAR_QUESTION_MARK) {4217 isGlob = token.isGlob = true;4218 finished = true;4219 4220 if (scanToEnd === true) {4221 continue;4222 }4223 break;4224 }4225 4226 if (code === CHAR_LEFT_SQUARE_BRACKET) {4227 while (eos() !== true && (next = advance())) {4228 if (next === CHAR_BACKWARD_SLASH) {4229 backslashes = token.backslashes = true;4230 advance();4231 continue;4232 }4233 4234 if (next === CHAR_RIGHT_SQUARE_BRACKET) {4235 isBracket = token.isBracket = true;4236 isGlob = token.isGlob = true;4237 finished = true;4238 break;4239 }4240 }4241 4242 if (scanToEnd === true) {4243 continue;4244 }4245 4246 break;4247 }4248 4249 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {4250 negated = token.negated = true;4251 start++;4252 continue;4253 }4254 4255 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {4256 isGlob = token.isGlob = true;4257 4258 if (scanToEnd === true) {4259 while (eos() !== true && (code = advance())) {4260 if (code === CHAR_LEFT_PARENTHESES) {4261 backslashes = token.backslashes = true;4262 code = advance();4263 continue;4264 }4265 4266 if (code === CHAR_RIGHT_PARENTHESES) {4267 finished = true;4268 break;4269 }4270 }4271 continue;4272 }4273 break;4274 }4275 4276 if (isGlob === true) {4277 finished = true;4278 4279 if (scanToEnd === true) {4280 continue;4281 }4282 4283 break;4284 }4285 }4286 4287 if (opts.noext === true) {4288 isExtglob = false;4289 isGlob = false;4290 }4291 4292 let base = str;4293 let prefix = '';4294 let glob = '';4295 4296 if (start > 0) {4297 prefix = str.slice(0, start);4298 str = str.slice(start);4299 lastIndex -= start;4300 }4301 4302 if (base && isGlob === true && lastIndex > 0) {4303 base = str.slice(0, lastIndex);4304 glob = str.slice(lastIndex);4305 } else if (isGlob === true) {4306 base = '';4307 glob = str;4308 } else {4309 base = str;4310 }4311 4312 if (base && base !== '' && base !== '/' && base !== str) {4313 if (isPathSeparator(base.charCodeAt(base.length - 1))) {4314 base = base.slice(0, -1);4315 }4316 }4317 4318 if (opts.unescape === true) {4319 if (glob) glob = utils$2.removeBackslashes(glob);4320 4321 if (base && backslashes === true) {4322 base = utils$2.removeBackslashes(base);4323 }4324 }4325 4326 const state = {4327 prefix,4328 input,4329 start,4330 base,4331 glob,4332 isBrace,4333 isBracket,4334 isGlob,4335 isExtglob,4336 isGlobstar,4337 negated,4338 negatedExtglob4339 };4340 4341 if (opts.tokens === true) {4342 state.maxDepth = 0;4343 if (!isPathSeparator(code)) {4344 tokens.push(token);4345 }4346 state.tokens = tokens;4347 }4348 4349 if (opts.parts === true || opts.tokens === true) {4350 let prevIndex;4351 4352 for (let idx = 0; idx < slashes.length; idx++) {4353 const n = prevIndex ? prevIndex + 1 : start;4354 const i = slashes[idx];4355 const value = input.slice(n, i);4356 if (opts.tokens) {4357 if (idx === 0 && start !== 0) {4358 tokens[idx].isPrefix = true;4359 tokens[idx].value = prefix;4360 } else {4361 tokens[idx].value = value;4362 }4363 depth(tokens[idx]);4364 state.maxDepth += tokens[idx].depth;4365 }4366 if (idx !== 0 || value !== '') {4367 parts.push(value);4368 }4369 prevIndex = i;4370 }4371 4372 if (prevIndex && prevIndex + 1 < input.length) {4373 const value = input.slice(prevIndex + 1);4374 parts.push(value);4375 4376 if (opts.tokens) {4377 tokens[tokens.length - 1].value = value;4378 depth(tokens[tokens.length - 1]);4379 state.maxDepth += tokens[tokens.length - 1].depth;4380 }4381 }4382 4383 state.slashes = slashes;4384 state.parts = parts;4385 }4386 4387 return state;4388 };4389 4390 var scan_1 = scan$1;4391 4392 const constants$1 = constants$2;4393 const utils$1 = utils$3;4394 4395 /**4396 * Constants4397 */4398 4399 const {4400 MAX_LENGTH,4401 POSIX_REGEX_SOURCE,4402 REGEX_NON_SPECIAL_CHARS,4403 REGEX_SPECIAL_CHARS_BACKREF,4404 REPLACEMENTS4405 } = constants$1;4406 4407 /**4408 * Helpers4409 */4410 4411 const expandRange = (args, options) => {4412 if (typeof options.expandRange === 'function') {4413 return options.expandRange(...args, options);4414 }4415 4416 args.sort();4417 const value = `[${args.join('-')}]`;4418 4419 return value;4420 };4421 4422 /**4423 * Create the message for a syntax error4424 */4425 4426 const syntaxError = (type, char) => {4427 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;4428 };4429 4430 /**4431 * Parse the given input string.4432 * @param {String} input4433 * @param {Object} options4434 * @return {Object}4435 */4436 4437 const parse$1 = (input, options) => {4438 if (typeof input !== 'string') {4439 throw new TypeError('Expected a string');4440 }4441 4442 input = REPLACEMENTS[input] || input;4443 4444 const opts = { ...options };4445 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;4446 4447 let len = input.length;4448 if (len > max) {4449 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);4450 }4451 4452 const bos = { type: 'bos', value: '', output: opts.prepend || '' };4453 const tokens = [bos];4454 4455 const capture = opts.capture ? '' : '?:';4456 const win32 = utils$1.isWindows(options);4457 4458 // create constants based on platform, for windows or posix4459 const PLATFORM_CHARS = constants$1.globChars(win32);4460 const EXTGLOB_CHARS = constants$1.extglobChars(PLATFORM_CHARS);4461 4462 const {4463 DOT_LITERAL,4464 PLUS_LITERAL,4465 SLASH_LITERAL,4466 ONE_CHAR,4467 DOTS_SLASH,4468 NO_DOT,4469 NO_DOT_SLASH,4470 NO_DOTS_SLASH,4471 QMARK,4472 QMARK_NO_DOT,4473 STAR,4474 START_ANCHOR4475 } = PLATFORM_CHARS;4476 4477 const globstar = opts => {4478 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;4479 };4480 4481 const nodot = opts.dot ? '' : NO_DOT;4482 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;4483 let star = opts.bash === true ? globstar(opts) : STAR;4484 4485 if (opts.capture) {4486 star = `(${star})`;4487 }4488 4489 // minimatch options support4490 if (typeof opts.noext === 'boolean') {4491 opts.noextglob = opts.noext;4492 }4493 4494 const state = {4495 input,4496 index: -1,4497 start: 0,4498 dot: opts.dot === true,4499 consumed: '',4500 output: '',4501 prefix: '',4502 backtrack: false,4503 negated: false,4504 brackets: 0,4505 braces: 0,4506 parens: 0,4507 quotes: 0,4508 globstar: false,4509 tokens4510 };4511 4512 input = utils$1.removePrefix(input, state);4513 len = input.length;4514 4515 const extglobs = [];4516 const braces = [];4517 const stack = [];4518 let prev = bos;4519 let value;4520 4521 /**4522 * Tokenizing helpers4523 */4524 4525 const eos = () => state.index === len - 1;4526 const peek = state.peek = (n = 1) => input[state.index + n];4527 const advance = state.advance = () => input[++state.index] || '';4528 const remaining = () => input.slice(state.index + 1);4529 const consume = (value = '', num = 0) => {4530 state.consumed += value;4531 state.index += num;4532 };4533 4534 const append = token => {4535 state.output += token.output != null ? token.output : token.value;4536 consume(token.value);4537 };4538 4539 const negate = () => {4540 let count = 1;4541 4542 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) {4543 advance();4544 state.start++;4545 count++;4546 }4547 4548 if (count % 2 === 0) {4549 return false;4550 }4551 4552 state.negated = true;4553 state.start++;4554 return true;4555 };4556 4557 const increment = type => {4558 state[type]++;4559 stack.push(type);4560 };4561 4562 const decrement = type => {4563 state[type]--;4564 stack.pop();4565 };4566 4567 /**4568 * Push tokens onto the tokens array. This helper speeds up4569 * tokenizing by 1) helping us avoid backtracking as much as possible,4570 * and 2) helping us avoid creating extra tokens when consecutive4571 * characters are plain text. This improves performance and simplifies4572 * lookbehinds.4573 */4574 4575 const push = tok => {4576 if (prev.type === 'globstar') {4577 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace');4578 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'));4579 4580 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) {4581 state.output = state.output.slice(0, -prev.output.length);4582 prev.type = 'star';4583 prev.value = '*';4584 prev.output = star;4585 state.output += prev.output;4586 }4587 }4588 4589 if (extglobs.length && tok.type !== 'paren') {4590 extglobs[extglobs.length - 1].inner += tok.value;4591 }4592 4593 if (tok.value || tok.output) append(tok);4594 if (prev && prev.type === 'text' && tok.type === 'text') {4595 prev.value += tok.value;4596 prev.output = (prev.output || '') + tok.value;4597 return;4598 }4599 4600 tok.prev = prev;4601 tokens.push(tok);4602 prev = tok;4603 };4604 4605 const extglobOpen = (type, value) => {4606 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' };4607 4608 token.prev = prev;4609 token.parens = state.parens;4610 token.output = state.output;4611 const output = (opts.capture ? '(' : '') + token.open;4612 4613 increment('parens');4614 push({ type, value, output: state.output ? '' : ONE_CHAR });4615 push({ type: 'paren', extglob: true, value: advance(), output });4616 extglobs.push(token);4617 };4618 4619 const extglobClose = token => {4620 let output = token.close + (opts.capture ? ')' : '');4621 let rest;4622 4623 if (token.type === 'negate') {4624 let extglobStar = star;4625 4626 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) {4627 extglobStar = globstar(opts);4628 }4629 4630 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) {4631 output = token.close = `)$))${extglobStar}`;4632 }4633 4634 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) {4635 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis.4636 // In this case, we need to parse the string and use it in the output of the original pattern.4637 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`.4638 //4639 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`.4640 const expression = parse$1(rest, { ...options, fastpaths: false }).output;4641 4642 output = token.close = `)${expression})${extglobStar})`;4643 }4644 4645 if (token.prev.type === 'bos') {4646 state.negatedExtglob = true;4647 }4648 }4649 4650 push({ type: 'paren', extglob: true, value, output });4651 decrement('parens');4652 };4653 4654 /**4655 * Fast paths4656 */4657 4658 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) {4659 let backslashes = false;4660 4661 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {4662 if (first === '\\') {4663 backslashes = true;4664 return m;4665 }4666 4667 if (first === '?') {4668 if (esc) {4669 return esc + first + (rest ? QMARK.repeat(rest.length) : '');4670 }4671 if (index === 0) {4672 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '');4673 }4674 return QMARK.repeat(chars.length);4675 }4676 4677 if (first === '.') {4678 return DOT_LITERAL.repeat(chars.length);4679 }4680 4681 if (first === '*') {4682 if (esc) {4683 return esc + first + (rest ? star : '');4684 }4685 return star;4686 }4687 return esc ? m : `\\${m}`;4688 });4689 4690 if (backslashes === true) {4691 if (opts.unescape === true) {4692 output = output.replace(/\\/g, '');4693 } else {4694 output = output.replace(/\\+/g, m => {4695 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : '');4696 });4697 }4698 }4699 4700 if (output === input && opts.contains === true) {4701 state.output = input;4702 return state;4703 }4704 4705 state.output = utils$1.wrapOutput(output, state, options);4706 return state;4707 }4708 4709 /**4710 * Tokenize input until we reach end-of-string4711 */4712 4713 while (!eos()) {4714 value = advance();4715 4716 if (value === '\u0000') {4717 continue;4718 }4719 4720 /**4721 * Escaped characters4722 */4723 4724 if (value === '\\') {4725 const next = peek();4726 4727 if (next === '/' && opts.bash !== true) {4728 continue;4729 }4730 4731 if (next === '.' || next === ';') {4732 continue;4733 }4734 4735 if (!next) {4736 value += '\\';4737 push({ type: 'text', value });4738 continue;4739 }4740 4741 // collapse slashes to reduce potential for exploits4742 const match = /^\\+/.exec(remaining());4743 let slashes = 0;4744 4745 if (match && match[0].length > 2) {4746 slashes = match[0].length;4747 state.index += slashes;4748 if (slashes % 2 !== 0) {4749 value += '\\';4750 }4751 }4752 4753 if (opts.unescape === true) {4754 value = advance();4755 } else {4756 value += advance();4757 }4758 4759 if (state.brackets === 0) {4760 push({ type: 'text', value });4761 continue;4762 }4763 }4764 4765 /**4766 * If we're inside a regex character class, continue4767 * until we reach the closing bracket.4768 */4769 4770 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) {4771 if (opts.posix !== false && value === ':') {4772 const inner = prev.value.slice(1);4773 if (inner.includes('[')) {4774 prev.posix = true;4775 4776 if (inner.includes(':')) {4777 const idx = prev.value.lastIndexOf('[');4778 const pre = prev.value.slice(0, idx);4779 const rest = prev.value.slice(idx + 2);4780 const posix = POSIX_REGEX_SOURCE[rest];4781 if (posix) {4782 prev.value = pre + posix;4783 state.backtrack = true;4784 advance();4785 4786 if (!bos.output && tokens.indexOf(prev) === 1) {4787 bos.output = ONE_CHAR;4788 }4789 continue;4790 }4791 }4792 }4793 }4794 4795 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) {4796 value = `\\${value}`;4797 }4798 4799 if (value === ']' && (prev.value === '[' || prev.value === '[^')) {4800 value = `\\${value}`;4801 }4802 4803 if (opts.posix === true && value === '!' && prev.value === '[') {4804 value = '^';4805 }4806 4807 prev.value += value;4808 append({ value });4809 continue;4810 }4811 4812 /**4813 * If we're inside a quoted string, continue4814 * until we reach the closing double quote.4815 */4816 4817 if (state.quotes === 1 && value !== '"') {4818 value = utils$1.escapeRegex(value);4819 prev.value += value;4820 append({ value });4821 continue;4822 }4823 4824 /**4825 * Double quotes4826 */4827 4828 if (value === '"') {4829 state.quotes = state.quotes === 1 ? 0 : 1;4830 if (opts.keepQuotes === true) {4831 push({ type: 'text', value });4832 }4833 continue;4834 }4835 4836 /**4837 * Parentheses4838 */4839 4840 if (value === '(') {4841 increment('parens');4842 push({ type: 'paren', value });4843 continue;4844 }4845 4846 if (value === ')') {4847 if (state.parens === 0 && opts.strictBrackets === true) {4848 throw new SyntaxError(syntaxError('opening', '('));4849 }4850 4851 const extglob = extglobs[extglobs.length - 1];4852 if (extglob && state.parens === extglob.parens + 1) {4853 extglobClose(extglobs.pop());4854 continue;4855 }4856 4857 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' });4858 decrement('parens');4859 continue;4860 }4861 4862 /**4863 * Square brackets4864 */4865 4866 if (value === '[') {4867 if (opts.nobracket === true || !remaining().includes(']')) {4868 if (opts.nobracket !== true && opts.strictBrackets === true) {4869 throw new SyntaxError(syntaxError('closing', ']'));4870 }4871 4872 value = `\\${value}`;4873 } else {4874 increment('brackets');4875 }4876 4877 push({ type: 'bracket', value });4878 continue;4879 }4880 4881 if (value === ']') {4882 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) {4883 push({ type: 'text', value, output: `\\${value}` });4884 continue;4885 }4886 4887 if (state.brackets === 0) {4888 if (opts.strictBrackets === true) {4889 throw new SyntaxError(syntaxError('opening', '['));4890 }4891 4892 push({ type: 'text', value, output: `\\${value}` });4893 continue;4894 }4895 4896 decrement('brackets');4897 4898 const prevValue = prev.value.slice(1);4899 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) {4900 value = `/${value}`;4901 }4902 4903 prev.value += value;4904 append({ value });4905 4906 // when literal brackets are explicitly disabled4907 // assume we should match with a regex character class4908 if (opts.literalBrackets === false || utils$1.hasRegexChars(prevValue)) {4909 continue;4910 }4911 4912 const escaped = utils$1.escapeRegex(prev.value);4913 state.output = state.output.slice(0, -prev.value.length);4914 4915 // when literal brackets are explicitly enabled4916 // assume we should escape the brackets to match literal characters4917 if (opts.literalBrackets === true) {4918 state.output += escaped;4919 prev.value = escaped;4920 continue;4921 }4922 4923 // when the user specifies nothing, try to match both4924 prev.value = `(${capture}${escaped}|${prev.value})`;4925 state.output += prev.value;4926 continue;4927 }4928 4929 /**4930 * Braces4931 */4932 4933 if (value === '{' && opts.nobrace !== true) {4934 increment('braces');4935 4936 const open = {4937 type: 'brace',4938 value,4939 output: '(',4940 outputIndex: state.output.length,4941 tokensIndex: state.tokens.length4942 };4943 4944 braces.push(open);4945 push(open);4946 continue;4947 }4948 4949 if (value === '}') {4950 const brace = braces[braces.length - 1];4951 4952 if (opts.nobrace === true || !brace) {4953 push({ type: 'text', value, output: value });4954 continue;4955 }4956 4957 let output = ')';4958 4959 if (brace.dots === true) {4960 const arr = tokens.slice();4961 const range = [];4962 4963 for (let i = arr.length - 1; i >= 0; i--) {4964 tokens.pop();4965 if (arr[i].type === 'brace') {4966 break;4967 }4968 if (arr[i].type !== 'dots') {4969 range.unshift(arr[i].value);4970 }4971 }4972 4973 output = expandRange(range, opts);4974 state.backtrack = true;4975 }4976 4977 if (brace.comma !== true && brace.dots !== true) {4978 const out = state.output.slice(0, brace.outputIndex);4979 const toks = state.tokens.slice(brace.tokensIndex);4980 brace.value = brace.output = '\\{';4981 value = output = '\\}';4982 state.output = out;4983 for (const t of toks) {4984 state.output += (t.output || t.value);4985 }4986 }4987 4988 push({ type: 'brace', value, output });4989 decrement('braces');4990 braces.pop();4991 continue;4992 }4993 4994 /**4995 * Pipes4996 */4997 4998 if (value === '|') {4999 if (extglobs.length > 0) {5000 extglobs[extglobs.length - 1].conditions++;5001 }5002 push({ type: 'text', value });5003 continue;5004 }5005 5006 /**5007 * Commas5008 */5009 5010 if (value === ',') {5011 let output = value;5012 5013 const brace = braces[braces.length - 1];5014 if (brace && stack[stack.length - 1] === 'braces') {5015 brace.comma = true;5016 output = '|';5017 }5018 5019 push({ type: 'comma', value, output });5020 continue;5021 }5022 5023 /**5024 * Slashes5025 */5026 5027 if (value === '/') {5028 // if the beginning of the glob is "./", advance the start5029 // to the current index, and don't add the "./" characters5030 // to the state. This greatly simplifies lookbehinds when5031 // checking for BOS characters like "!" and "." (not "./")5032 if (prev.type === 'dot' && state.index === state.start + 1) {5033 state.start = state.index + 1;5034 state.consumed = '';5035 state.output = '';5036 tokens.pop();5037 prev = bos; // reset "prev" to the first token5038 continue;5039 }5040 5041 push({ type: 'slash', value, output: SLASH_LITERAL });5042 continue;5043 }5044 5045 /**5046 * Dots5047 */5048 5049 if (value === '.') {5050 if (state.braces > 0 && prev.type === 'dot') {5051 if (prev.value === '.') prev.output = DOT_LITERAL;5052 const brace = braces[braces.length - 1];5053 prev.type = 'dots';5054 prev.output += value;5055 prev.value += value;5056 brace.dots = true;5057 continue;5058 }5059 5060 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') {5061 push({ type: 'text', value, output: DOT_LITERAL });5062 continue;5063 }5064 5065 push({ type: 'dot', value, output: DOT_LITERAL });5066 continue;5067 }5068 5069 /**5070 * Question marks5071 */5072 5073 if (value === '?') {5074 const isGroup = prev && prev.value === '(';5075 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {5076 extglobOpen('qmark', value);5077 continue;5078 }5079 5080 if (prev && prev.type === 'paren') {5081 const next = peek();5082 let output = value;5083 5084 if (next === '<' && !utils$1.supportsLookbehinds()) {5085 throw new Error('Node.js v10 or higher is required for regex lookbehinds');5086 }5087 5088 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) {5089 output = `\\${value}`;5090 }5091 5092 push({ type: 'text', value, output });5093 continue;5094 }5095 5096 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) {5097 push({ type: 'qmark', value, output: QMARK_NO_DOT });5098 continue;5099 }5100 5101 push({ type: 'qmark', value, output: QMARK });5102 continue;5103 }5104 5105 /**5106 * Exclamation5107 */5108 5109 if (value === '!') {5110 if (opts.noextglob !== true && peek() === '(') {5111 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) {5112 extglobOpen('negate', value);5113 continue;5114 }5115 }5116 5117 if (opts.nonegate !== true && state.index === 0) {5118 negate();5119 continue;5120 }5121 }5122 5123 /**5124 * Plus5125 */5126 5127 if (value === '+') {5128 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {5129 extglobOpen('plus', value);5130 continue;5131 }5132 5133 if ((prev && prev.value === '(') || opts.regex === false) {5134 push({ type: 'plus', value, output: PLUS_LITERAL });5135 continue;5136 }5137 5138 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) {5139 push({ type: 'plus', value });5140 continue;5141 }5142 5143 push({ type: 'plus', value: PLUS_LITERAL });5144 continue;5145 }5146 5147 /**5148 * Plain text5149 */5150 5151 if (value === '@') {5152 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {5153 push({ type: 'at', extglob: true, value, output: '' });5154 continue;5155 }5156 5157 push({ type: 'text', value });5158 continue;5159 }5160 5161 /**5162 * Plain text5163 */5164 5165 if (value !== '*') {5166 if (value === '$' || value === '^') {5167 value = `\\${value}`;5168 }5169 5170 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());5171 if (match) {5172 value += match[0];5173 state.index += match[0].length;5174 }5175 5176 push({ type: 'text', value });5177 continue;5178 }5179 5180 /**5181 * Stars5182 */5183 5184 if (prev && (prev.type === 'globstar' || prev.star === true)) {5185 prev.type = 'star';5186 prev.star = true;5187 prev.value += value;5188 prev.output = star;5189 state.backtrack = true;5190 state.globstar = true;5191 consume(value);5192 continue;5193 }5194 5195 let rest = remaining();5196 if (opts.noextglob !== true && /^\([^?]/.test(rest)) {5197 extglobOpen('star', value);5198 continue;5199 }5200 5201 if (prev.type === 'star') {5202 if (opts.noglobstar === true) {5203 consume(value);5204 continue;5205 }5206 5207 const prior = prev.prev;5208 const before = prior.prev;5209 const isStart = prior.type === 'slash' || prior.type === 'bos';5210 const afterStar = before && (before.type === 'star' || before.type === 'globstar');5211 5212 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) {5213 push({ type: 'star', value, output: '' });5214 continue;5215 }5216 5217 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace');5218 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren');5219 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) {5220 push({ type: 'star', value, output: '' });5221 continue;5222 }5223 5224 // strip consecutive `/**/`5225 while (rest.slice(0, 3) === '/**') {5226 const after = input[state.index + 4];5227 if (after && after !== '/') {5228 break;5229 }5230 rest = rest.slice(3);5231 consume('/**', 3);5232 }5233 5234 if (prior.type === 'bos' && eos()) {5235 prev.type = 'globstar';5236 prev.value += value;5237 prev.output = globstar(opts);5238 state.output = prev.output;5239 state.globstar = true;5240 consume(value);5241 continue;5242 }5243 5244 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) {5245 state.output = state.output.slice(0, -(prior.output + prev.output).length);5246 prior.output = `(?:${prior.output}`;5247 5248 prev.type = 'globstar';5249 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)');5250 prev.value += value;5251 state.globstar = true;5252 state.output += prior.output + prev.output;5253 consume(value);5254 continue;5255 }5256 5257 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') {5258 const end = rest[1] !== void 0 ? '|$' : '';5259 5260 state.output = state.output.slice(0, -(prior.output + prev.output).length);5261 prior.output = `(?:${prior.output}`;5262 5263 prev.type = 'globstar';5264 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;5265 prev.value += value;5266 5267 state.output += prior.output + prev.output;5268 state.globstar = true;5269 5270 consume(value + advance());5271 5272 push({ type: 'slash', value: '/', output: '' });5273 continue;5274 }5275 5276 if (prior.type === 'bos' && rest[0] === '/') {5277 prev.type = 'globstar';5278 prev.value += value;5279 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;5280 state.output = prev.output;5281 state.globstar = true;5282 consume(value + advance());5283 push({ type: 'slash', value: '/', output: '' });5284 continue;5285 }5286 5287 // remove single star from output5288 state.output = state.output.slice(0, -prev.output.length);5289 5290 // reset previous token to globstar5291 prev.type = 'globstar';5292 prev.output = globstar(opts);5293 prev.value += value;5294 5295 // reset output with globstar5296 state.output += prev.output;5297 state.globstar = true;5298 consume(value);5299 continue;5300 }5301 5302 const token = { type: 'star', value, output: star };5303 5304 if (opts.bash === true) {5305 token.output = '.*?';5306 if (prev.type === 'bos' || prev.type === 'slash') {5307 token.output = nodot + token.output;5308 }5309 push(token);5310 continue;5311 }5312 5313 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) {5314 token.output = value;5315 push(token);5316 continue;5317 }5318 5319 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') {5320 if (prev.type === 'dot') {5321 state.output += NO_DOT_SLASH;5322 prev.output += NO_DOT_SLASH;5323 5324 } else if (opts.dot === true) {5325 state.output += NO_DOTS_SLASH;5326 prev.output += NO_DOTS_SLASH;5327 5328 } else {5329 state.output += nodot;5330 prev.output += nodot;5331 }5332 5333 if (peek() !== '*') {5334 state.output += ONE_CHAR;5335 prev.output += ONE_CHAR;5336 }5337 }5338 5339 push(token);5340 }5341 5342 while (state.brackets > 0) {5343 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']'));5344 state.output = utils$1.escapeLast(state.output, '[');5345 decrement('brackets');5346 }5347 5348 while (state.parens > 0) {5349 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')'));5350 state.output = utils$1.escapeLast(state.output, '(');5351 decrement('parens');5352 }5353 5354 while (state.braces > 0) {5355 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}'));5356 state.output = utils$1.escapeLast(state.output, '{');5357 decrement('braces');5358 }5359 5360 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) {5361 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` });5362 }5363 5364 // rebuild the output if we had to backtrack at any point5365 if (state.backtrack === true) {5366 state.output = '';5367 5368 for (const token of state.tokens) {5369 state.output += token.output != null ? token.output : token.value;5370 5371 if (token.suffix) {5372 state.output += token.suffix;5373 }5374 }5375 }5376 5377 return state;5378 };5379 5380 /**5381 * Fast paths for creating regular expressions for common glob patterns.5382 * This can significantly speed up processing and has very little downside5383 * impact when none of the fast paths match.5384 */5385 5386 parse$1.fastpaths = (input, options) => {5387 const opts = { ...options };5388 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;5389 const len = input.length;5390 if (len > max) {5391 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);5392 }5393 5394 input = REPLACEMENTS[input] || input;5395 const win32 = utils$1.isWindows(options);5396 5397 // create constants based on platform, for windows or posix5398 const {5399 DOT_LITERAL,5400 SLASH_LITERAL,5401 ONE_CHAR,5402 DOTS_SLASH,5403 NO_DOT,5404 NO_DOTS,5405 NO_DOTS_SLASH,5406 STAR,5407 START_ANCHOR5408 } = constants$1.globChars(win32);5409 5410 const nodot = opts.dot ? NO_DOTS : NO_DOT;5411 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;5412 const capture = opts.capture ? '' : '?:';5413 const state = { negated: false, prefix: '' };5414 let star = opts.bash === true ? '.*?' : STAR;5415 5416 if (opts.capture) {5417 star = `(${star})`;5418 }5419 5420 const globstar = opts => {5421 if (opts.noglobstar === true) return star;5422 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;5423 };5424 5425 const create = str => {5426 switch (str) {5427 case '*':5428 return `${nodot}${ONE_CHAR}${star}`;5429 5430 case '.*':5431 return `${DOT_LITERAL}${ONE_CHAR}${star}`;5432 5433 case '*.*':5434 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;5435 5436 case '*/*':5437 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;5438 5439 case '**':5440 return nodot + globstar(opts);5441 5442 case '**/*':5443 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;5444 5445 case '**/*.*':5446 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;5447 5448 case '**/.*':5449 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;5450 5451 default: {5452 const match = /^(.*?)\.(\w+)$/.exec(str);5453 if (!match) return;5454 5455 const source = create(match[1]);5456 if (!source) return;5457 5458 return source + DOT_LITERAL + match[2];5459 }5460 }5461 };5462 5463 const output = utils$1.removePrefix(input, state);5464 let source = create(output);5465 5466 if (source && opts.strictSlashes !== true) {5467 source += `${SLASH_LITERAL}?`;5468 }5469 5470 return source;5471 };5472 5473 var parse_1 = parse$1;5474 5475 const path = require$$0;5476 const scan = scan_1;5477 const parse = parse_1;5478 const utils = utils$3;5479 const constants = constants$2;5480 const isObject = val => val && typeof val === 'object' && !Array.isArray(val);5481 5482 /**5483 * Creates a matcher function from one or more glob patterns. The5484 * returned function takes a string to match as its first argument,5485 * and returns true if the string is a match. The returned matcher5486 * function also takes a boolean as the second argument that, when true,5487 * returns an object with additional information.5488 *5489 * ```js5490 * const picomatch = require('picomatch');5491 * // picomatch(glob[, options]);5492 *5493 * const isMatch = picomatch('*.!(*a)');5494 * console.log(isMatch('a.a')); //=> false5495 * console.log(isMatch('a.b')); //=> true5496 * ```5497 * @name picomatch5498 * @param {String|Array} `globs` One or more glob patterns.5499 * @param {Object=} `options`5500 * @return {Function=} Returns a matcher function.5501 * @api public5502 */5503 5504 const picomatch$1 = (glob, options, returnState = false) => {5505 if (Array.isArray(glob)) {5506 const fns = glob.map(input => picomatch$1(input, options, returnState));5507 const arrayMatcher = str => {5508 for (const isMatch of fns) {5509 const state = isMatch(str);5510 if (state) return state;5511 }5512 return false;5513 };5514 return arrayMatcher;5515 }5516 5517 const isState = isObject(glob) && glob.tokens && glob.input;5518 5519 if (glob === '' || (typeof glob !== 'string' && !isState)) {5520 throw new TypeError('Expected pattern to be a non-empty string');5521 }5522 5523 const opts = options || {};5524 const posix = utils.isWindows(options);5525 const regex = isState5526 ? picomatch$1.compileRe(glob, options)5527 : picomatch$1.makeRe(glob, options, false, true);5528 5529 const state = regex.state;5530 delete regex.state;5531 5532 let isIgnored = () => false;5533 if (opts.ignore) {5534 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };5535 isIgnored = picomatch$1(opts.ignore, ignoreOpts, returnState);5536 }5537 5538 const matcher = (input, returnObject = false) => {5539 const { isMatch, match, output } = picomatch$1.test(input, regex, options, { glob, posix });5540 const result = { glob, state, regex, posix, input, output, match, isMatch };5541 5542 if (typeof opts.onResult === 'function') {5543 opts.onResult(result);5544 }5545 5546 if (isMatch === false) {5547 result.isMatch = false;5548 return returnObject ? result : false;5549 }5550 5551 if (isIgnored(input)) {5552 if (typeof opts.onIgnore === 'function') {5553 opts.onIgnore(result);5554 }5555 result.isMatch = false;5556 return returnObject ? result : false;5557 }5558 5559 if (typeof opts.onMatch === 'function') {5560 opts.onMatch(result);5561 }5562 return returnObject ? result : true;5563 };5564 5565 if (returnState) {5566 matcher.state = state;5567 }5568 5569 return matcher;5570 };5571 5572 /**5573 * Test `input` with the given `regex`. This is used by the main5574 * `picomatch()` function to test the input string.5575 *5576 * ```js5577 * const picomatch = require('picomatch');5578 * // picomatch.test(input, regex[, options]);5579 *5580 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));5581 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }5582 * ```5583 * @param {String} `input` String to test.5584 * @param {RegExp} `regex`5585 * @return {Object} Returns an object with matching info.5586 * @api public5587 */5588 5589 picomatch$1.test = (input, regex, options, { glob, posix } = {}) => {5590 if (typeof input !== 'string') {5591 throw new TypeError('Expected input to be a string');5592 }5593 5594 if (input === '') {5595 return { isMatch: false, output: '' };5596 }5597 5598 const opts = options || {};5599 const format = opts.format || (posix ? utils.toPosixSlashes : null);5600 let match = input === glob;5601 let output = (match && format) ? format(input) : input;5602 5603 if (match === false) {5604 output = format ? format(input) : input;5605 match = output === glob;5606 }5607 5608 if (match === false || opts.capture === true) {5609 if (opts.matchBase === true || opts.basename === true) {5610 match = picomatch$1.matchBase(input, regex, options, posix);5611 } else {5612 match = regex.exec(output);5613 }5614 }5615 5616 return { isMatch: Boolean(match), match, output };5617 };5618 5619 /**5620 * Match the basename of a filepath.5621 *5622 * ```js5623 * const picomatch = require('picomatch');5624 * // picomatch.matchBase(input, glob[, options]);5625 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true5626 * ```5627 * @param {String} `input` String to test.5628 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).5629 * @return {Boolean}5630 * @api public5631 */5632 5633 picomatch$1.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {5634 const regex = glob instanceof RegExp ? glob : picomatch$1.makeRe(glob, options);5635 return regex.test(path.basename(input));5636 };5637 5638 /**5639 * Returns true if **any** of the given glob `patterns` match the specified `string`.5640 *5641 * ```js5642 * const picomatch = require('picomatch');5643 * // picomatch.isMatch(string, patterns[, options]);5644 *5645 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true5646 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false5647 * ```5648 * @param {String|Array} str The string to test.5649 * @param {String|Array} patterns One or more glob patterns to use for matching.5650 * @param {Object} [options] See available [options](#options).5651 * @return {Boolean} Returns true if any patterns match `str`5652 * @api public5653 */5654 5655 picomatch$1.isMatch = (str, patterns, options) => picomatch$1(patterns, options)(str);5656 5657 /**5658 * Parse a glob pattern to create the source string for a regular5659 * expression.5660 *5661 * ```js5662 * const picomatch = require('picomatch');5663 * const result = picomatch.parse(pattern[, options]);5664 * ```5665 * @param {String} `pattern`5666 * @param {Object} `options`5667 * @return {Object} Returns an object with useful properties and output to be used as a regex source string.5668 * @api public5669 */5670 5671 picomatch$1.parse = (pattern, options) => {5672 if (Array.isArray(pattern)) return pattern.map(p => picomatch$1.parse(p, options));5673 return parse(pattern, { ...options, fastpaths: false });5674 };5675 5676 /**5677 * Scan a glob pattern to separate the pattern into segments.5678 *5679 * ```js5680 * const picomatch = require('picomatch');5681 * // picomatch.scan(input[, options]);5682 *5683 * const result = picomatch.scan('!./foo/*.js');5684 * console.log(result);5685 * { prefix: '!./',5686 * input: '!./foo/*.js',5687 * start: 3,5688 * base: 'foo',5689 * glob: '*.js',5690 * isBrace: false,5691 * isBracket: false,5692 * isGlob: true,5693 * isExtglob: false,5694 * isGlobstar: false,5695 * negated: true }5696 * ```5697 * @param {String} `input` Glob pattern to scan.5698 * @param {Object} `options`5699 * @return {Object} Returns an object with5700 * @api public5701 */5702 5703 picomatch$1.scan = (input, options) => scan(input, options);5704 5705 /**5706 * Compile a regular expression from the `state` object returned by the5707 * [parse()](#parse) method.5708 *5709 * @param {Object} `state`5710 * @param {Object} `options`5711 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.5712 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.5713 * @return {RegExp}5714 * @api public5715 */5716 5717 picomatch$1.compileRe = (state, options, returnOutput = false, returnState = false) => {5718 if (returnOutput === true) {5719 return state.output;5720 }5721 5722 const opts = options || {};5723 const prepend = opts.contains ? '' : '^';5724 const append = opts.contains ? '' : '$';5725 5726 let source = `${prepend}(?:${state.output})${append}`;5727 if (state && state.negated === true) {5728 source = `^(?!${source}).*$`;5729 }5730 5731 const regex = picomatch$1.toRegex(source, options);5732 if (returnState === true) {5733 regex.state = state;5734 }5735 5736 return regex;5737 };5738 5739 /**5740 * Create a regular expression from a parsed glob pattern.5741 *5742 * ```js5743 * const picomatch = require('picomatch');5744 * const state = picomatch.parse('*.js');5745 * // picomatch.compileRe(state[, options]);5746 *5747 * console.log(picomatch.compileRe(state));5748 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/5749 * ```5750 * @param {String} `state` The object returned from the `.parse` method.5751 * @param {Object} `options`5752 * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result.5753 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.5754 * @return {RegExp} Returns a regex created from the given pattern.5755 * @api public5756 */5757 5758 picomatch$1.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {5759 if (!input || typeof input !== 'string') {5760 throw new TypeError('Expected a non-empty string');5761 }5762 5763 let parsed = { negated: false, fastpaths: true };5764 5765 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {5766 parsed.output = parse.fastpaths(input, options);5767 }5768 5769 if (!parsed.output) {5770 parsed = parse(input, options);5771 }5772 5773 return picomatch$1.compileRe(parsed, options, returnOutput, returnState);5774 };5775 5776 /**5777 * Create a regular expression from the given regex source string.5778 *5779 * ```js5780 * const picomatch = require('picomatch');5781 * // picomatch.toRegex(source[, options]);5782 *5783 * const { output } = picomatch.parse('*.js');5784 * console.log(picomatch.toRegex(output));5785 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/5786 * ```5787 * @param {String} `source` Regular expression source string.5788 * @param {Object} `options`5789 * @return {RegExp}5790 * @api public5791 */5792 5793 picomatch$1.toRegex = (source, options) => {5794 try {5795 const opts = options || {};5796 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));5797 } catch (err) {5798 if (options && options.debug === true) throw err;5799 return /$^/;5800 }5801 };5802 5803 /**5804 * Picomatch constants.5805 * @return {Object}5806 */5807 5808 picomatch$1.constants = constants;5809 5810 /**5811 * Expose "picomatch"5812 */5813 5814 var picomatch_1 = picomatch$1;5815 5816 var picomatch = picomatch_1;5817 5818 const pm = /*@__PURE__*/getDefaultExportFromCjs(picomatch);5819 5820 const extractors = {5821 ArrayPattern(names, param) {5822 for (const element of param.elements) {5823 if (element)5824 extractors[element.type](names, element);5825 }5826 },5827 AssignmentPattern(names, param) {5828 extractors[param.left.type](names, param.left);5829 },5830 Identifier(names, param) {5831 names.push(param.name);5832 },5833 MemberExpression() { },5834 ObjectPattern(names, param) {5835 for (const prop of param.properties) {5836 // @ts-ignore Typescript reports that this is not a valid type5837 if (prop.type === 'RestElement') {5838 extractors.RestElement(names, prop);5839 }5840 else {5841 extractors[prop.value.type](names, prop.value);5842 }5843 }5844 },5845 RestElement(names, param) {5846 extractors[param.argument.type](names, param.argument);5847 }5848 };5849 const extractAssignedNames = function extractAssignedNames(param) {5850 const names = [];5851 extractors[param.type](names, param);5852 return names;5853 };5854 5855 // Helper since Typescript can't detect readonly arrays with Array.isArray5856 function isArray(arg) {5857 return Array.isArray(arg);5858 }5859 function ensureArray(thing) {5860 if (isArray(thing))5861 return thing;5862 if (thing == null)5863 return [];5864 return [thing];5865 }5866 5867 const normalizePath = function normalizePath(filename) {5868 return filename.split(require$$0.win32.sep).join(require$$0.posix.sep);5869 };5870 5871 function getMatcherString(id, resolutionBase) {5872 if (resolutionBase === false || require$$0.isAbsolute(id) || id.startsWith('**')) {5873 return normalizePath(id);5874 }5875 // resolve('') is valid and will default to process.cwd()5876 const basePath = normalizePath(require$$0.resolve(resolutionBase || ''))5877 // escape all possible (posix + win) path characters that might interfere with regex5878 .replace(/[-^$*+?.()|[\]{}]/g, '\\$&');5879 // Note that we use posix.join because:5880 // 1. the basePath has been normalized to use /5881 // 2. the incoming glob (id) matcher, also uses /5882 // otherwise Node will force backslash (\) on windows5883 return require$$0.posix.join(basePath, normalizePath(id));5884 }5885 const createFilter = function createFilter(include, exclude, options) {5886 const resolutionBase = options && options.resolve;5887 const getMatcher = (id) => id instanceof RegExp5888 ? id5889 : {5890 test: (what) => {5891 // this refactor is a tad overly verbose but makes for easy debugging5892 const pattern = getMatcherString(id, resolutionBase);5893 const fn = pm(pattern, { dot: true });5894 const result = fn(what);5895 return result;5896 }5897 };5898 const includeMatchers = ensureArray(include).map(getMatcher);5899 const excludeMatchers = ensureArray(exclude).map(getMatcher);5900 return function result(id) {5901 if (typeof id !== 'string')5902 return false;5903 if (/\0/.test(id))5904 return false;5905 const pathId = normalizePath(id);5906 for (let i = 0; i < excludeMatchers.length; ++i) {5907 const matcher = excludeMatchers[i];5908 if (matcher.test(pathId))5909 return false;5910 }5911 for (let i = 0; i < includeMatchers.length; ++i) {5912 const matcher = includeMatchers[i];5913 if (matcher.test(pathId))5914 return true;5915 }5916 return !includeMatchers.length;5917 };5918 };5919 5920 const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public';5921 const builtins = 'arguments Infinity NaN undefined null true false eval uneval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Symbol Error EvalError InternalError RangeError ReferenceError SyntaxError TypeError URIError Number Math Date String RegExp Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array Map Set WeakMap WeakSet SIMD ArrayBuffer DataView JSON Promise Generator GeneratorFunction Reflect Proxy Intl';5922 const forbiddenIdentifiers = new Set(`${reservedWords} ${builtins}`.split(' '));5923 forbiddenIdentifiers.add('');5924 4147 5925 4148 function createInclusionContext() { … … 5951 4174 replacedVariableInits: new Map() 5952 4175 }; 4176 } 4177 4178 const INCLUDE_PARAMETERS = 'variables'; 4179 const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN'); 4180 class NodeBase extends ExpressionEntity { 4181 /** 4182 * Nodes can apply custom deoptimizations once they become part of the 4183 * executed code. To do this, they must initialize this as false, implement 4184 * applyDeoptimizations and call this from include and hasEffects if they have 4185 * custom handlers 4186 */ 4187 get deoptimized() { 4188 return isFlagSet(this.flags, 2 /* Flag.deoptimized */); 4189 } 4190 set deoptimized(value) { 4191 this.flags = setFlag(this.flags, 2 /* Flag.deoptimized */, value); 4192 } 4193 constructor(parent, parentScope) { 4194 super(); 4195 this.parent = parent; 4196 this.scope = parentScope; 4197 this.createScope(parentScope); 4198 } 4199 addExportedVariables(_variables, _exportNamesByVariable) { } 4200 /** 4201 * Override this to bind assignments to variables and do any initialisations 4202 * that require the scopes to be populated with variables. 4203 */ 4204 bind() { 4205 for (const key of childNodeKeys[this.type]) { 4206 const value = this[key]; 4207 if (Array.isArray(value)) { 4208 for (const child of value) { 4209 child?.bind(); 4210 } 4211 } 4212 else if (value) { 4213 value.bind(); 4214 } 4215 } 4216 } 4217 /** 4218 * Override if this node should receive a different scope than the parent 4219 * scope. 4220 */ 4221 createScope(parentScope) { 4222 this.scope = parentScope; 4223 } 4224 hasEffects(context) { 4225 if (!this.deoptimized) 4226 this.applyDeoptimizations(); 4227 for (const key of childNodeKeys[this.type]) { 4228 const value = this[key]; 4229 if (value === null) 4230 continue; 4231 if (Array.isArray(value)) { 4232 for (const child of value) { 4233 if (child?.hasEffects(context)) 4234 return true; 4235 } 4236 } 4237 else if (value.hasEffects(context)) 4238 return true; 4239 } 4240 return false; 4241 } 4242 hasEffectsAsAssignmentTarget(context, _checkAccess) { 4243 return (this.hasEffects(context) || 4244 this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context)); 4245 } 4246 include(context, includeChildrenRecursively, _options) { 4247 if (!this.deoptimized) 4248 this.applyDeoptimizations(); 4249 this.included = true; 4250 for (const key of childNodeKeys[this.type]) { 4251 const value = this[key]; 4252 if (value === null) 4253 continue; 4254 if (Array.isArray(value)) { 4255 for (const child of value) { 4256 child?.include(context, includeChildrenRecursively); 4257 } 4258 } 4259 else { 4260 value.include(context, includeChildrenRecursively); 4261 } 4262 } 4263 } 4264 includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) { 4265 this.include(context, includeChildrenRecursively); 4266 } 4267 /** 4268 * Override to perform special initialisation steps after the scope is 4269 * initialised 4270 */ 4271 initialise() { 4272 this.scope.context.magicString.addSourcemapLocation(this.start); 4273 this.scope.context.magicString.addSourcemapLocation(this.end); 4274 } 4275 parseNode(esTreeNode) { 4276 for (const [key, value] of Object.entries(esTreeNode)) { 4277 // Skip properties defined on the class already. 4278 // This way, we can override this function to add custom initialisation and then call super.parseNode 4279 // Note: this doesn't skip properties with defined getters/setters which we use to pack wrap booleans 4280 // in bitfields. Those are still assigned from the value in the esTreeNode. 4281 if (this.hasOwnProperty(key)) 4282 continue; 4283 if (key.charCodeAt(0) === 95 /* _ */) { 4284 if (key === parseAst_js.ANNOTATION_KEY) { 4285 this.annotations = value; 4286 } 4287 else if (key === parseAst_js.INVALID_ANNOTATION_KEY) { 4288 this.invalidAnnotations = value; 4289 } 4290 } 4291 else if (typeof value !== 'object' || value === null) { 4292 this[key] = value; 4293 } 4294 else if (Array.isArray(value)) { 4295 this[key] = new Array(value.length); 4296 let index = 0; 4297 for (const child of value) { 4298 this[key][index++] = 4299 child === null 4300 ? null 4301 : new (this.scope.context.getNodeConstructor(child.type))(this, this.scope).parseNode(child); 4302 } 4303 } 4304 else { 4305 this[key] = new (this.scope.context.getNodeConstructor(value.type))(this, this.scope).parseNode(value); 4306 } 4307 } 4308 // extend child keys for unknown node types 4309 childNodeKeys[esTreeNode.type] ||= createChildNodeKeysForNode(esTreeNode); 4310 this.initialise(); 4311 return this; 4312 } 4313 removeAnnotations(code) { 4314 if (this.annotations) { 4315 for (const annotation of this.annotations) { 4316 code.remove(annotation.start, annotation.end); 4317 } 4318 } 4319 } 4320 render(code, options) { 4321 for (const key of childNodeKeys[this.type]) { 4322 const value = this[key]; 4323 if (value === null) 4324 continue; 4325 if (Array.isArray(value)) { 4326 for (const child of value) { 4327 child?.render(code, options); 4328 } 4329 } 4330 else { 4331 value.render(code, options); 4332 } 4333 } 4334 } 4335 setAssignedValue(value) { 4336 this.assignmentInteraction = { args: [null, value], type: INTERACTION_ASSIGNED }; 4337 } 4338 shouldBeIncluded(context) { 4339 return this.included || (!context.brokenFlow && this.hasEffects(createHasEffectsContext())); 4340 } 4341 /** 4342 * Just deoptimize everything by default so that when e.g. we do not track 4343 * something properly, it is deoptimized. 4344 * @protected 4345 */ 4346 applyDeoptimizations() { 4347 this.deoptimized = true; 4348 for (const key of childNodeKeys[this.type]) { 4349 const value = this[key]; 4350 if (value === null) 4351 continue; 4352 if (Array.isArray(value)) { 4353 for (const child of value) { 4354 child?.deoptimizePath(UNKNOWN_PATH); 4355 } 4356 } 4357 else { 4358 value.deoptimizePath(UNKNOWN_PATH); 4359 } 4360 } 4361 this.scope.context.requestTreeshakingPass(); 4362 } 4363 } 4364 function createChildNodeKeysForNode(esTreeNode) { 4365 return Object.keys(esTreeNode).filter(key => typeof esTreeNode[key] === 'object' && key.charCodeAt(0) !== 95 /* _ */); 4366 } 4367 4368 function isObjectExpressionNode(node) { 4369 return node instanceof NodeBase && node.type === parseAst_js.ObjectExpression; 4370 } 4371 function isPropertyNode(node) { 4372 return node.type === parseAst_js.Property; 5953 4373 } 5954 4374 … … 6155 4575 } 6156 4576 6157 // This file is generated by scripts/generate-child-node-keys.js.6158 // Do not edit this file directly.6159 const childNodeKeys = {6160 ArrayExpression: ['elements'],6161 ArrayPattern: ['elements'],6162 ArrowFunctionExpression: ['params', 'body'],6163 AssignmentExpression: ['left', 'right'],6164 AssignmentPattern: ['left', 'right'],6165 AwaitExpression: ['argument'],6166 BinaryExpression: ['left', 'right'],6167 BlockStatement: ['body'],6168 BreakStatement: ['label'],6169 CallExpression: ['callee', 'arguments'],6170 CatchClause: ['param', 'body'],6171 ChainExpression: ['expression'],6172 ClassBody: ['body'],6173 ClassDeclaration: ['decorators', 'id', 'superClass', 'body'],6174 ClassExpression: ['decorators', 'id', 'superClass', 'body'],6175 ConditionalExpression: ['test', 'consequent', 'alternate'],6176 ContinueStatement: ['label'],6177 DebuggerStatement: [],6178 Decorator: ['expression'],6179 DoWhileStatement: ['body', 'test'],6180 EmptyStatement: [],6181 ExportAllDeclaration: ['exported', 'source', 'attributes'],6182 ExportDefaultDeclaration: ['declaration'],6183 ExportNamedDeclaration: ['specifiers', 'source', 'attributes', 'declaration'],6184 ExportSpecifier: ['local', 'exported'],6185 ExpressionStatement: ['expression'],6186 ForInStatement: ['left', 'right', 'body'],6187 ForOfStatement: ['left', 'right', 'body'],6188 ForStatement: ['init', 'test', 'update', 'body'],6189 FunctionDeclaration: ['id', 'params', 'body'],6190 FunctionExpression: ['id', 'params', 'body'],6191 Identifier: [],6192 IfStatement: ['test', 'consequent', 'alternate'],6193 ImportAttribute: ['key', 'value'],6194 ImportDeclaration: ['specifiers', 'source', 'attributes'],6195 ImportDefaultSpecifier: ['local'],6196 ImportExpression: ['source', 'options'],6197 ImportNamespaceSpecifier: ['local'],6198 ImportSpecifier: ['imported', 'local'],6199 LabeledStatement: ['label', 'body'],6200 Literal: [],6201 LogicalExpression: ['left', 'right'],6202 MemberExpression: ['object', 'property'],6203 MetaProperty: ['meta', 'property'],6204 MethodDefinition: ['decorators', 'key', 'value'],6205 NewExpression: ['callee', 'arguments'],6206 ObjectExpression: ['properties'],6207 ObjectPattern: ['properties'],6208 PanicError: [],6209 ParseError: [],6210 PrivateIdentifier: [],6211 Program: ['body'],6212 Property: ['key', 'value'],6213 PropertyDefinition: ['decorators', 'key', 'value'],6214 RestElement: ['argument'],6215 ReturnStatement: ['argument'],6216 SequenceExpression: ['expressions'],6217 SpreadElement: ['argument'],6218 StaticBlock: ['body'],6219 Super: [],6220 SwitchCase: ['test', 'consequent'],6221 SwitchStatement: ['discriminant', 'cases'],6222 TaggedTemplateExpression: ['tag', 'quasi'],6223 TemplateElement: [],6224 TemplateLiteral: ['quasis', 'expressions'],6225 ThisExpression: [],6226 ThrowStatement: ['argument'],6227 TryStatement: ['block', 'handler', 'finalizer'],6228 UnaryExpression: ['argument'],6229 UpdateExpression: ['argument'],6230 VariableDeclaration: ['declarations'],6231 VariableDeclarator: ['id', 'init'],6232 WhileStatement: ['test', 'body'],6233 YieldExpression: ['argument']6234 };6235 6236 const INCLUDE_PARAMETERS = 'variables';6237 const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN');6238 class NodeBase extends ExpressionEntity {6239 /**6240 * Nodes can apply custom deoptimizations once they become part of the6241 * executed code. To do this, they must initialize this as false, implement6242 * applyDeoptimizations and call this from include and hasEffects if they have6243 * custom handlers6244 */6245 get deoptimized() {6246 return isFlagSet(this.flags, 2 /* Flag.deoptimized */);6247 }6248 set deoptimized(value) {6249 this.flags = setFlag(this.flags, 2 /* Flag.deoptimized */, value);6250 }6251 constructor(parent, parentScope) {6252 super();6253 this.parent = parent;6254 this.scope = parentScope;6255 this.createScope(parentScope);6256 }6257 addExportedVariables(_variables, _exportNamesByVariable) { }6258 /**6259 * Override this to bind assignments to variables and do any initialisations6260 * that require the scopes to be populated with variables.6261 */6262 bind() {6263 for (const key of childNodeKeys[this.type]) {6264 const value = this[key];6265 if (Array.isArray(value)) {6266 for (const child of value) {6267 child?.bind();6268 }6269 }6270 else if (value) {6271 value.bind();6272 }6273 }6274 }6275 /**6276 * Override if this node should receive a different scope than the parent6277 * scope.6278 */6279 createScope(parentScope) {6280 this.scope = parentScope;6281 }6282 hasEffects(context) {6283 if (!this.deoptimized)6284 this.applyDeoptimizations();6285 for (const key of childNodeKeys[this.type]) {6286 const value = this[key];6287 if (value === null)6288 continue;6289 if (Array.isArray(value)) {6290 for (const child of value) {6291 if (child?.hasEffects(context))6292 return true;6293 }6294 }6295 else if (value.hasEffects(context))6296 return true;6297 }6298 return false;6299 }6300 hasEffectsAsAssignmentTarget(context, _checkAccess) {6301 return (this.hasEffects(context) ||6302 this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));6303 }6304 include(context, includeChildrenRecursively, _options) {6305 if (!this.deoptimized)6306 this.applyDeoptimizations();6307 this.included = true;6308 for (const key of childNodeKeys[this.type]) {6309 const value = this[key];6310 if (value === null)6311 continue;6312 if (Array.isArray(value)) {6313 for (const child of value) {6314 child?.include(context, includeChildrenRecursively);6315 }6316 }6317 else {6318 value.include(context, includeChildrenRecursively);6319 }6320 }6321 }6322 includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {6323 this.include(context, includeChildrenRecursively);6324 }6325 /**6326 * Override to perform special initialisation steps after the scope is6327 * initialised6328 */6329 initialise() {6330 this.scope.context.magicString.addSourcemapLocation(this.start);6331 this.scope.context.magicString.addSourcemapLocation(this.end);6332 }6333 parseNode(esTreeNode) {6334 for (const [key, value] of Object.entries(esTreeNode)) {6335 // Skip properties defined on the class already.6336 // This way, we can override this function to add custom initialisation and then call super.parseNode6337 // Note: this doesn't skip properties with defined getters/setters which we use to pack wrap booleans6338 // in bitfields. Those are still assigned from the value in the esTreeNode.6339 if (this.hasOwnProperty(key))6340 continue;6341 if (key.charCodeAt(0) === 95 /* _ */) {6342 if (key === parseAst_js.ANNOTATION_KEY) {6343 this.annotations = value;6344 }6345 else if (key === parseAst_js.INVALID_ANNOTATION_KEY) {6346 this.invalidAnnotations = value;6347 }6348 }6349 else if (typeof value !== 'object' || value === null) {6350 this[key] = value;6351 }6352 else if (Array.isArray(value)) {6353 this[key] = [];6354 for (const child of value) {6355 this[key].push(child === null6356 ? null6357 : new (this.scope.context.getNodeConstructor(child.type))(this, this.scope).parseNode(child));6358 }6359 }6360 else {6361 this[key] = new (this.scope.context.getNodeConstructor(value.type))(this, this.scope).parseNode(value);6362 }6363 }6364 // extend child keys for unknown node types6365 childNodeKeys[esTreeNode.type] ||= createChildNodeKeysForNode(esTreeNode);6366 this.initialise();6367 return this;6368 }6369 removeAnnotations(code) {6370 if (this.annotations) {6371 for (const annotation of this.annotations) {6372 code.remove(annotation.start, annotation.end);6373 }6374 }6375 }6376 render(code, options) {6377 for (const key of childNodeKeys[this.type]) {6378 const value = this[key];6379 if (value === null)6380 continue;6381 if (Array.isArray(value)) {6382 for (const child of value) {6383 child?.render(code, options);6384 }6385 }6386 else {6387 value.render(code, options);6388 }6389 }6390 }6391 setAssignedValue(value) {6392 this.assignmentInteraction = { args: [null, value], type: INTERACTION_ASSIGNED };6393 }6394 shouldBeIncluded(context) {6395 return this.included || (!context.brokenFlow && this.hasEffects(createHasEffectsContext()));6396 }6397 /**6398 * Just deoptimize everything by default so that when e.g. we do not track6399 * something properly, it is deoptimized.6400 * @protected6401 */6402 applyDeoptimizations() {6403 this.deoptimized = true;6404 for (const key of childNodeKeys[this.type]) {6405 const value = this[key];6406 if (value === null)6407 continue;6408 if (Array.isArray(value)) {6409 for (const child of value) {6410 child?.deoptimizePath(UNKNOWN_PATH);6411 }6412 }6413 else {6414 value.deoptimizePath(UNKNOWN_PATH);6415 }6416 }6417 this.scope.context.requestTreeshakingPass();6418 }6419 }6420 function createChildNodeKeysForNode(esTreeNode) {6421 return Object.keys(esTreeNode).filter(key => typeof esTreeNode[key] === 'object' && key.charCodeAt(0) !== 95 /* _ */);6422 }6423 6424 4577 class SpreadElement extends NodeBase { 6425 4578 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 6426 4579 if (path.length > 0) { 6427 this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, [UnknownKey, ...path], recursionTracker);4580 this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker); 6428 4581 } 6429 4582 } … … 6724 4877 property.deoptimizePath(subPath); 6725 4878 } 6726 this.prototypeExpression?.deoptimizePath(path.length === 1 ? [ ...path, UnknownKey] : path);4879 this.prototypeExpression?.deoptimizePath(path.length === 1 ? [path[0], UnknownKey] : path); 6727 4880 } 6728 4881 getLiteralValueAtPath(path, recursionTracker, origin) { … … 7137 5290 } 7138 5291 7139 class ArrayPattern extends NodeBase {7140 addExportedVariables(variables, exportNamesByVariable) {7141 for (const element of this.elements) {7142 element?.addExportedVariables(variables, exportNamesByVariable);7143 }7144 }7145 declare(kind) {7146 const variables = [];7147 for (const element of this.elements) {7148 if (element !== null) {7149 variables.push(...element.declare(kind, UNKNOWN_EXPRESSION));7150 }7151 }7152 return variables;7153 }7154 // Patterns can only be deoptimized at the empty path at the moment7155 deoptimizePath() {7156 for (const element of this.elements) {7157 element?.deoptimizePath(EMPTY_PATH);7158 }7159 }7160 // Patterns are only checked at the empty path at the moment7161 hasEffectsOnInteractionAtPath(_path, interaction, context) {7162 for (const element of this.elements) {7163 if (element?.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context))7164 return true;7165 }7166 return false;7167 }7168 markDeclarationReached() {7169 for (const element of this.elements) {7170 element?.markDeclarationReached();7171 }7172 }7173 }7174 7175 /** @typedef { import('estree').Node} Node */7176 /** @typedef {Node | {7177 * type: 'PropertyDefinition';7178 * computed: boolean;7179 * value: Node7180 * }} NodeWithPropertyDefinition */7181 7182 /**7183 *7184 * @param {NodeWithPropertyDefinition} node7185 * @param {NodeWithPropertyDefinition} parent7186 * @returns {boolean}7187 */7188 function is_reference (node, parent) {7189 if (node.type === 'MemberExpression') {7190 return !node.computed && is_reference(node.object, node);7191 }7192 7193 if (node.type === 'Identifier') {7194 if (!parent) return true;7195 7196 switch (parent.type) {7197 // disregard `bar` in `foo.bar`7198 case 'MemberExpression': return parent.computed || node === parent.object;7199 7200 // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`7201 case 'MethodDefinition': return parent.computed;7202 7203 // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`7204 case 'PropertyDefinition': return parent.computed || node === parent.value;7205 7206 // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`7207 case 'Property': return parent.computed || node === parent.value;7208 7209 // disregard the `bar` in `export { foo as bar }` or7210 // the foo in `import { foo as bar }`7211 case 'ExportSpecifier':7212 case 'ImportSpecifier': return node === parent.local;7213 7214 // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`7215 case 'LabeledStatement':7216 case 'BreakStatement':7217 case 'ContinueStatement': return false;7218 default: return true;7219 }7220 }7221 7222 return false;7223 }7224 7225 const PureFunctionKey = Symbol('PureFunction');7226 const getPureFunctions = ({ treeshake }) => {7227 const pureFunctions = Object.create(null);7228 for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {7229 let currentFunctions = pureFunctions;7230 for (const pathSegment of functionName.split('.')) {7231 currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);7232 }7233 currentFunctions[PureFunctionKey] = true;7234 }7235 return pureFunctions;7236 };7237 7238 5292 /* eslint sort-keys: "off" */ 7239 5293 const ValueProperties = Symbol('Value Properties'); … … 7349 5403 prototype: O 7350 5404 }, 5405 AggregateError: PC_WITH_ARRAY, 7351 5406 Atomics: O, 7352 5407 BigInt: C, … … 7372 5427 eval: O, 7373 5428 EvalError: PC, 5429 FinalizationRegistry: C, 7374 5430 Float32Array: ARRAY_TYPE, 7375 5431 Float64Array: ARRAY_TYPE, … … 7476 5532 }, 7477 5533 propertyIsEnumerable: O, 7478 Proxy: O, 5534 Proxy: { 5535 __proto__: null, 5536 [ValueProperties]: { 5537 deoptimizeArgumentsOnCall: ({ args: [, target, parameter] }) => { 5538 if (isObjectExpressionNode(parameter)) { 5539 const hasSpreadElement = parameter.properties.some(property => !isPropertyNode(property)); 5540 if (!hasSpreadElement) { 5541 for (const property of parameter.properties) { 5542 property.deoptimizeArgumentsOnInteractionAtPath({ 5543 args: [null, target], 5544 type: INTERACTION_CALLED, 5545 withNew: false 5546 }, EMPTY_PATH, SHARED_RECURSION_TRACKER); 5547 } 5548 return; 5549 } 5550 } 5551 target.deoptimizePath(UNKNOWN_PATH); 5552 }, 5553 getLiteralValue: getTruthyLiteralValue, 5554 hasEffectsWhenCalled: returnTrue 5555 } 5556 }, 7479 5557 RangeError: PC, 7480 5558 ReferenceError: PC, … … 7522 5600 valueOf: O, 7523 5601 WeakMap: PC_WITH_ARRAY, 5602 WeakRef: C, 7524 5603 WeakSet: PC_WITH_ARRAY, 7525 5604 // Additional globals shared by Node and Browser that are not strictly part of the language … … 8377 6456 8378 6457 const tdzVariableKinds = new Set(['class', 'const', 'let', 'var', 'using', 'await using']); 8379 class Identifier extends NodeBase {6458 class IdentifierBase extends NodeBase { 8380 6459 constructor() { 8381 6460 super(...arguments); 8382 6461 this.variable = null; 8383 this.is ReferenceVariable = false;6462 this.isVariableReference = false; 8384 6463 } 8385 6464 get isTDZAccess() { … … 8392 6471 this.flags = setFlag(this.flags, 4 /* Flag.tdzAccessDefined */, true); 8393 6472 this.flags = setFlag(this.flags, 8 /* Flag.tdzAccess */, value); 6473 } 6474 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 6475 this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 6476 } 6477 deoptimizePath(path) { 6478 if (path.length === 0 && !this.scope.contains(this.name)) { 6479 this.disallowImportReassignment(); 6480 } 6481 // We keep conditional chaining because an unknown Node could have an 6482 // Identifier as property that might be deoptimized by default 6483 this.variable?.deoptimizePath(path); 6484 } 6485 getLiteralValueAtPath(path, recursionTracker, origin) { 6486 return this.getVariableRespectingTDZ().getLiteralValueAtPath(path, recursionTracker, origin); 6487 } 6488 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 6489 const [expression, isPure] = this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 6490 return [expression, isPure || this.isPureFunction(path)]; 6491 } 6492 hasEffects(context) { 6493 if (!this.deoptimized) 6494 this.applyDeoptimizations(); 6495 if (this.isPossibleTDZ() && this.variable.kind !== 'var') { 6496 return true; 6497 } 6498 return (this.scope.context.options.treeshake 6499 .unknownGlobalSideEffects && 6500 this.variable instanceof GlobalVariable && 6501 !this.isPureFunction(EMPTY_PATH) && 6502 this.variable.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context)); 6503 } 6504 hasEffectsOnInteractionAtPath(path, interaction, context) { 6505 switch (interaction.type) { 6506 case INTERACTION_ACCESSED: { 6507 return (this.variable !== null && 6508 !this.isPureFunction(path) && 6509 this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context)); 6510 } 6511 case INTERACTION_ASSIGNED: { 6512 return (path.length > 0 ? this.getVariableRespectingTDZ() : this.variable).hasEffectsOnInteractionAtPath(path, interaction, context); 6513 } 6514 case INTERACTION_CALLED: { 6515 return (!this.isPureFunction(path) && 6516 this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context)); 6517 } 6518 } 6519 } 6520 include() { 6521 if (!this.deoptimized) 6522 this.applyDeoptimizations(); 6523 if (!this.included) { 6524 this.included = true; 6525 if (this.variable !== null) { 6526 this.scope.context.includeVariableInModule(this.variable); 6527 } 6528 } 6529 } 6530 includeCallArguments(context, parameters) { 6531 this.variable.includeCallArguments(context, parameters); 6532 } 6533 isPossibleTDZ() { 6534 // return cached value to avoid issues with the next tree-shaking pass 6535 const cachedTdzAccess = this.isTDZAccess; 6536 if (cachedTdzAccess !== null) 6537 return cachedTdzAccess; 6538 if (!(this.variable instanceof LocalVariable && 6539 this.variable.kind && 6540 tdzVariableKinds.has(this.variable.kind) && 6541 // We ignore modules that did not receive a treeshaking pass yet as that 6542 // causes many false positives due to circular dependencies or disabled 6543 // moduleSideEffects. 6544 this.variable.module.hasTreeShakingPassStarted)) { 6545 return (this.isTDZAccess = false); 6546 } 6547 let decl_id; 6548 if (this.variable.declarations && 6549 this.variable.declarations.length === 1 && 6550 (decl_id = this.variable.declarations[0]) && 6551 this.start < decl_id.start && 6552 closestParentFunctionOrProgram(this) === closestParentFunctionOrProgram(decl_id)) { 6553 // a variable accessed before its declaration 6554 // in the same function or at top level of module 6555 return (this.isTDZAccess = true); 6556 } 6557 if (!this.variable.initReached) { 6558 // Either a const/let TDZ violation or 6559 // var use before declaration was encountered. 6560 return (this.isTDZAccess = true); 6561 } 6562 return (this.isTDZAccess = false); 6563 } 6564 applyDeoptimizations() { 6565 this.deoptimized = true; 6566 if (this.variable instanceof LocalVariable) { 6567 // When accessing a variable from a module without side effects, this 6568 // means we use an export of that module and therefore need to potentially 6569 // include it in the bundle. 6570 if (!this.variable.module.isExecuted) { 6571 markModuleAndImpureDependenciesAsExecuted(this.variable.module); 6572 } 6573 this.variable.consolidateInitializers(); 6574 this.scope.context.requestTreeshakingPass(); 6575 } 6576 if (this.isVariableReference) { 6577 this.variable.addUsedPlace(this); 6578 this.scope.context.requestTreeshakingPass(); 6579 } 6580 } 6581 disallowImportReassignment() { 6582 return this.scope.context.error(parseAst_js.logIllegalImportReassignment(this.name, this.scope.context.module.id), this.start); 6583 } 6584 getVariableRespectingTDZ() { 6585 if (this.isPossibleTDZ()) { 6586 return UNKNOWN_EXPRESSION; 6587 } 6588 return this.variable; 6589 } 6590 isPureFunction(path) { 6591 let currentPureFunction = this.scope.context.manualPureFunctions[this.name]; 6592 for (const segment of path) { 6593 if (currentPureFunction) { 6594 if (currentPureFunction[PureFunctionKey]) { 6595 return true; 6596 } 6597 currentPureFunction = currentPureFunction[segment]; 6598 } 6599 else { 6600 return false; 6601 } 6602 } 6603 return currentPureFunction?.[PureFunctionKey]; 6604 } 6605 } 6606 function closestParentFunctionOrProgram(node) { 6607 while (node && !/^Program|Function/.test(node.type)) { 6608 node = node.parent; 6609 } 6610 // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program 6611 return node; 6612 } 6613 6614 class Identifier extends IdentifierBase { 6615 constructor() { 6616 super(...arguments); 6617 this.variable = null; 8394 6618 } 8395 6619 addExportedVariables(variables, exportNamesByVariable) { … … 8402 6626 this.variable = this.scope.findVariable(this.name); 8403 6627 this.variable.addReference(this); 8404 this.is ReferenceVariable = true;6628 this.isVariableReference = true; 8405 6629 } 8406 6630 } … … 8442 6666 return [(this.variable = variable)]; 8443 6667 } 8444 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {8445 this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);8446 }8447 deoptimizePath(path) {8448 if (path.length === 0 && !this.scope.contains(this.name)) {8449 this.disallowImportReassignment();8450 }8451 // We keep conditional chaining because an unknown Node could have an8452 // Identifier as property that might be deoptimized by default8453 this.variable?.deoptimizePath(path);8454 }8455 getLiteralValueAtPath(path, recursionTracker, origin) {8456 return this.getVariableRespectingTDZ().getLiteralValueAtPath(path, recursionTracker, origin);8457 }8458 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {8459 const [expression, isPure] = this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);8460 return [expression, isPure || this.isPureFunction(path)];8461 }8462 hasEffects(context) {8463 if (!this.deoptimized)8464 this.applyDeoptimizations();8465 if (this.isPossibleTDZ() && this.variable.kind !== 'var') {8466 return true;8467 }8468 return (this.scope.context.options.treeshake8469 .unknownGlobalSideEffects &&8470 this.variable instanceof GlobalVariable &&8471 !this.isPureFunction(EMPTY_PATH) &&8472 this.variable.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context));8473 }8474 hasEffectsOnInteractionAtPath(path, interaction, context) {8475 switch (interaction.type) {8476 case INTERACTION_ACCESSED: {8477 return (this.variable !== null &&8478 !this.isPureFunction(path) &&8479 this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));8480 }8481 case INTERACTION_ASSIGNED: {8482 return (path.length > 0 ? this.getVariableRespectingTDZ() : this.variable).hasEffectsOnInteractionAtPath(path, interaction, context);8483 }8484 case INTERACTION_CALLED: {8485 return (!this.isPureFunction(path) &&8486 this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));8487 }8488 }8489 }8490 include() {8491 if (!this.deoptimized)8492 this.applyDeoptimizations();8493 if (!this.included) {8494 this.included = true;8495 if (this.variable !== null) {8496 this.scope.context.includeVariableInModule(this.variable);8497 }8498 }8499 }8500 includeCallArguments(context, parameters) {8501 this.variable.includeCallArguments(context, parameters);8502 }8503 isPossibleTDZ() {8504 // return cached value to avoid issues with the next tree-shaking pass8505 const cachedTdzAccess = this.isTDZAccess;8506 if (cachedTdzAccess !== null)8507 return cachedTdzAccess;8508 if (!(this.variable instanceof LocalVariable &&8509 this.variable.kind &&8510 tdzVariableKinds.has(this.variable.kind) &&8511 // we ignore possible TDZs due to circular module dependencies as8512 // otherwise we get many false positives8513 this.variable.module === this.scope.context.module)) {8514 return (this.isTDZAccess = false);8515 }8516 let decl_id;8517 if (this.variable.declarations &&8518 this.variable.declarations.length === 1 &&8519 (decl_id = this.variable.declarations[0]) &&8520 this.start < decl_id.start &&8521 closestParentFunctionOrProgram(this) === closestParentFunctionOrProgram(decl_id)) {8522 // a variable accessed before its declaration8523 // in the same function or at top level of module8524 return (this.isTDZAccess = true);8525 }8526 // We ignore the case where the module is not yet executed because8527 // moduleSideEffects are false.8528 if (!this.variable.initReached && this.scope.context.module.isExecuted) {8529 // Either a const/let TDZ violation or8530 // var use before declaration was encountered.8531 return (this.isTDZAccess = true);8532 }8533 return (this.isTDZAccess = false);8534 }8535 6668 markDeclarationReached() { 8536 6669 this.variable.initReached = true; … … 8555 6688 } 8556 6689 } 8557 }8558 disallowImportReassignment() {8559 return this.scope.context.error(parseAst_js.logIllegalImportReassignment(this.name, this.scope.context.module.id), this.start);8560 }8561 applyDeoptimizations() {8562 this.deoptimized = true;8563 if (this.variable instanceof LocalVariable) {8564 this.variable.consolidateInitializers();8565 this.scope.context.requestTreeshakingPass();8566 }8567 if (this.isReferenceVariable) {8568 this.variable.addUsedPlace(this);8569 this.scope.context.requestTreeshakingPass();8570 }8571 }8572 getVariableRespectingTDZ() {8573 if (this.isPossibleTDZ()) {8574 return UNKNOWN_EXPRESSION;8575 }8576 return this.variable;8577 }8578 isPureFunction(path) {8579 let currentPureFunction = this.scope.context.manualPureFunctions[this.name];8580 for (const segment of path) {8581 if (currentPureFunction) {8582 if (currentPureFunction[PureFunctionKey]) {8583 return true;8584 }8585 currentPureFunction = currentPureFunction[segment];8586 }8587 else {8588 return false;8589 }8590 }8591 return currentPureFunction?.[PureFunctionKey];8592 }8593 }8594 function closestParentFunctionOrProgram(node) {8595 while (node && !/^Program|Function/.test(node.type)) {8596 node = node.parent;8597 }8598 // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program8599 return node;8600 }8601 8602 const MAX_TRACKED_INTERACTIONS = 20;8603 const NO_INTERACTIONS = parseAst_js.EMPTY_ARRAY;8604 const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);8605 const EMPTY_PATH_TRACKER = new PathTracker();8606 const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);8607 class ParameterVariable extends LocalVariable {8608 constructor(name, declarator, context) {8609 super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');8610 this.deoptimizationInteractions = [];8611 this.deoptimizations = new PathTracker();8612 this.deoptimizedFields = new Set();8613 this.entitiesToBeDeoptimized = new Set();8614 this.expressionsUseTheKnownValue = [];8615 this.knownValue = null;8616 this.knownValueLiteral = UnknownValue;8617 this.frozenValue = null;8618 }8619 addEntityToBeDeoptimized(entity) {8620 if (entity === UNKNOWN_EXPRESSION) {8621 // As unknown expressions fully deoptimize all interactions, we can clear8622 // the interaction cache at this point provided we keep this optimization8623 // in mind when adding new interactions8624 if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {8625 this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);8626 for (const { interaction } of this.deoptimizationInteractions) {8627 deoptimizeInteraction(interaction);8628 }8629 this.deoptimizationInteractions = NO_INTERACTIONS;8630 }8631 }8632 else if (this.deoptimizedFields.has(UnknownKey)) {8633 // This means that we already deoptimized all interactions and no longer8634 // track them8635 entity.deoptimizePath(UNKNOWN_PATH);8636 }8637 else if (!this.entitiesToBeDeoptimized.has(entity)) {8638 this.entitiesToBeDeoptimized.add(entity);8639 for (const field of this.deoptimizedFields) {8640 entity.deoptimizePath([field]);8641 }8642 for (const { interaction, path } of this.deoptimizationInteractions) {8643 entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);8644 }8645 }8646 }8647 markReassigned() {8648 if (this.isReassigned) {8649 return;8650 }8651 super.markReassigned();8652 for (const expression of this.expressionsUseTheKnownValue) {8653 expression.deoptimizeCache();8654 }8655 this.expressionsUseTheKnownValue = parseAst_js.EMPTY_ARRAY;8656 }8657 deoptimizeCache() {8658 this.markReassigned();8659 }8660 /**8661 * Update the known value of the parameter variable.8662 * Must be called for every function call, so it can track all the arguments,8663 * and deoptimizeCache itself to mark reassigned if the argument is changed.8664 * @param argument The argument of the function call8665 */8666 updateKnownValue(argument) {8667 if (this.isReassigned) {8668 return;8669 }8670 if (this.knownValue === null) {8671 this.knownValue = argument;8672 this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);8673 return;8674 }8675 // the same literal or identifier, do nothing8676 if (this.knownValue === argument ||8677 (this.knownValue instanceof Identifier &&8678 argument instanceof Identifier &&8679 this.knownValue.variable === argument.variable)) {8680 return;8681 }8682 const oldValue = this.knownValueLiteral;8683 if (typeof oldValue === 'symbol') {8684 this.markReassigned();8685 return;8686 }8687 // add tracking for the new argument8688 const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);8689 if (newValue !== oldValue) {8690 this.markReassigned();8691 }8692 }8693 /**8694 * This function freezes the known value of the parameter variable,8695 * so the optimization starts with a certain ExpressionEntity.8696 * The optimization can be undone by calling `markReassigned`.8697 * @returns the frozen value8698 */8699 getKnownValue() {8700 if (this.frozenValue === null) {8701 this.frozenValue = this.knownValue || UNKNOWN_EXPRESSION;8702 }8703 return this.frozenValue;8704 }8705 getLiteralValueAtPath(path, recursionTracker, origin) {8706 if (this.isReassigned) {8707 return UnknownValue;8708 }8709 const knownValue = this.getKnownValue();8710 this.expressionsUseTheKnownValue.push(origin);8711 return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);8712 }8713 hasEffectsOnInteractionAtPath(path, interaction, context) {8714 if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) {8715 return super.hasEffectsOnInteractionAtPath(path, interaction, context);8716 }8717 const knownValue = this.getKnownValue();8718 return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context);8719 }8720 deoptimizeArgumentsOnInteractionAtPath(interaction, path) {8721 // For performance reasons, we fully deoptimize all deeper interactions8722 if (path.length >= 2 ||8723 this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||8724 this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||8725 (path.length === 1 &&8726 (this.deoptimizedFields.has(UnknownKey) ||8727 (interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0]))))) {8728 deoptimizeInteraction(interaction);8729 return;8730 }8731 if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {8732 for (const entity of this.entitiesToBeDeoptimized) {8733 entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);8734 }8735 if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {8736 this.deoptimizationInteractions.push({8737 interaction,8738 path8739 });8740 }8741 }8742 }8743 deoptimizePath(path) {8744 if (path.length === 0) {8745 this.markReassigned();8746 return;8747 }8748 if (this.deoptimizedFields.has(UnknownKey)) {8749 return;8750 }8751 const key = path[0];8752 if (this.deoptimizedFields.has(key)) {8753 return;8754 }8755 this.deoptimizedFields.add(key);8756 for (const entity of this.entitiesToBeDeoptimized) {8757 // We do not need a recursion tracker here as we already track whether8758 // this field is deoptimized8759 entity.deoptimizePath([key]);8760 }8761 if (key === UnknownKey) {8762 // save some memory8763 this.deoptimizationInteractions = NO_INTERACTIONS;8764 this.deoptimizations = EMPTY_PATH_TRACKER;8765 this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;8766 this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;8767 }8768 }8769 getReturnExpressionWhenCalledAtPath(path) {8770 // We deoptimize everything that is called as that will trivially deoptimize8771 // the corresponding return expressions as well and avoid badly performing8772 // and complicated alternatives8773 if (path.length === 0) {8774 this.deoptimizePath(UNKNOWN_PATH);8775 }8776 else if (!this.deoptimizedFields.has(path[0])) {8777 this.deoptimizePath([path[0]]);8778 }8779 return UNKNOWN_RETURN_EXPRESSION;8780 6690 } 8781 6691 } … … 8864 6774 } 8865 6775 addReturnExpression(expression) { 8866 this.parent instanceof ChildScope && this.parent.addReturnExpression(expression); 6776 if (this.parent instanceof ChildScope) { 6777 this.parent.addReturnExpression(expression); 6778 } 8867 6779 } 8868 6780 addUsedOutsideNames(usedNames, format, exportNamesByVariable, accessedGlobalsByScope) { … … 8907 6819 return this.parent.findLexicalBoundary(); 8908 6820 } 6821 findGlobal(name) { 6822 const variable = this.parent.findVariable(name); 6823 this.accessedOutsideVariables.set(name, variable); 6824 return variable; 6825 } 8909 6826 findVariable(name) { 8910 6827 const knownVariable = this.variables.get(name) || this.accessedOutsideVariables.get(name); … … 8915 6832 this.accessedOutsideVariables.set(name, variable); 8916 6833 return variable; 6834 } 6835 } 6836 6837 function checkEffectForNodes(nodes, context) { 6838 for (const node of nodes) { 6839 if (node.hasEffects(context)) { 6840 return true; 6841 } 6842 } 6843 return false; 6844 } 6845 6846 class MethodBase extends NodeBase { 6847 constructor() { 6848 super(...arguments); 6849 this.accessedValue = null; 6850 } 6851 get computed() { 6852 return isFlagSet(this.flags, 1024 /* Flag.computed */); 6853 } 6854 set computed(value) { 6855 this.flags = setFlag(this.flags, 1024 /* Flag.computed */, value); 6856 } 6857 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 6858 if (interaction.type === INTERACTION_ACCESSED && this.kind === 'get' && path.length === 0) { 6859 return this.value.deoptimizeArgumentsOnInteractionAtPath({ 6860 args: interaction.args, 6861 type: INTERACTION_CALLED, 6862 withNew: false 6863 }, EMPTY_PATH, recursionTracker); 6864 } 6865 if (interaction.type === INTERACTION_ASSIGNED && this.kind === 'set' && path.length === 0) { 6866 return this.value.deoptimizeArgumentsOnInteractionAtPath({ 6867 args: interaction.args, 6868 type: INTERACTION_CALLED, 6869 withNew: false 6870 }, EMPTY_PATH, recursionTracker); 6871 } 6872 this.getAccessedValue()[0].deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 6873 } 6874 // As getter properties directly receive their values from fixed function 6875 // expressions, there is no known situation where a getter is deoptimized. 6876 deoptimizeCache() { } 6877 deoptimizePath(path) { 6878 this.getAccessedValue()[0].deoptimizePath(path); 6879 } 6880 getLiteralValueAtPath(path, recursionTracker, origin) { 6881 return this.getAccessedValue()[0].getLiteralValueAtPath(path, recursionTracker, origin); 6882 } 6883 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 6884 return this.getAccessedValue()[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 6885 } 6886 hasEffects(context) { 6887 return this.key.hasEffects(context); 6888 } 6889 hasEffectsOnInteractionAtPath(path, interaction, context) { 6890 if (this.kind === 'get' && interaction.type === INTERACTION_ACCESSED && path.length === 0) { 6891 return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, { 6892 args: interaction.args, 6893 type: INTERACTION_CALLED, 6894 withNew: false 6895 }, context); 6896 } 6897 // setters are only called for empty paths 6898 if (this.kind === 'set' && interaction.type === INTERACTION_ASSIGNED) { 6899 return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, { 6900 args: interaction.args, 6901 type: INTERACTION_CALLED, 6902 withNew: false 6903 }, context); 6904 } 6905 return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context); 6906 } 6907 applyDeoptimizations() { } 6908 getAccessedValue() { 6909 if (this.accessedValue === null) { 6910 if (this.kind === 'get') { 6911 this.accessedValue = UNKNOWN_RETURN_EXPRESSION; 6912 return (this.accessedValue = this.value.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, SHARED_RECURSION_TRACKER, this)); 6913 } 6914 else { 6915 return (this.accessedValue = [this.value, false]); 6916 } 6917 } 6918 return this.accessedValue; 6919 } 6920 } 6921 6922 class MethodDefinition extends MethodBase { 6923 hasEffects(context) { 6924 return super.hasEffects(context) || checkEffectForNodes(this.decorators, context); 6925 } 6926 applyDeoptimizations() { } 6927 } 6928 6929 class BlockScope extends ChildScope { 6930 constructor(parent) { 6931 super(parent, parent.context); 6932 } 6933 addDeclaration(identifier, context, init, kind) { 6934 if (kind === 'var') { 6935 const name = identifier.name; 6936 const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name); 6937 if (existingVariable) { 6938 if (existingVariable.kind === 'var' || 6939 (kind === 'var' && existingVariable.kind === 'parameter')) { 6940 existingVariable.addDeclaration(identifier, init); 6941 return existingVariable; 6942 } 6943 return context.error(parseAst_js.logRedeclarationError(name), identifier.start); 6944 } 6945 const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind); 6946 // Necessary to make sure the init is deoptimized for conditional declarations. 6947 // We cannot call deoptimizePath here. 6948 declaredVariable.markInitializersForDeoptimization(); 6949 // We add the variable to this and all parent scopes to reliably detect conflicts 6950 this.addHoistedVariable(name, declaredVariable); 6951 return declaredVariable; 6952 } 6953 return super.addDeclaration(identifier, context, init, kind); 6954 } 6955 } 6956 6957 class StaticBlock extends NodeBase { 6958 createScope(parentScope) { 6959 this.scope = new BlockScope(parentScope); 6960 } 6961 hasEffects(context) { 6962 for (const node of this.body) { 6963 if (node.hasEffects(context)) 6964 return true; 6965 } 6966 return false; 6967 } 6968 include(context, includeChildrenRecursively) { 6969 this.included = true; 6970 for (const node of this.body) { 6971 if (includeChildrenRecursively || node.shouldBeIncluded(context)) 6972 node.include(context, includeChildrenRecursively); 6973 } 6974 } 6975 render(code, options) { 6976 if (this.body.length > 0) { 6977 const bodyStartPos = findFirstOccurrenceOutsideComment(code.original.slice(this.start, this.end), '{') + 1; 6978 renderStatementList(this.body, code, this.start + bodyStartPos, this.end - 1, options); 6979 } 6980 else { 6981 super.render(code, options); 6982 } 6983 } 6984 } 6985 function isStaticBlock(statement) { 6986 return statement.type === parseAst_js.StaticBlock; 6987 } 6988 6989 class ObjectMember extends ExpressionEntity { 6990 constructor(object, key) { 6991 super(); 6992 this.object = object; 6993 this.key = key; 6994 } 6995 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 6996 this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker); 6997 } 6998 deoptimizePath(path) { 6999 this.object.deoptimizePath([this.key, ...path]); 7000 } 7001 getLiteralValueAtPath(path, recursionTracker, origin) { 7002 return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin); 7003 } 7004 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 7005 return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin); 7006 } 7007 hasEffectsOnInteractionAtPath(path, interaction, context) { 7008 return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context); 7009 } 7010 } 7011 7012 class ClassNode extends NodeBase { 7013 constructor() { 7014 super(...arguments); 7015 this.objectEntity = null; 7016 } 7017 createScope(parentScope) { 7018 this.scope = new ChildScope(parentScope, parentScope.context); 7019 } 7020 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 7021 this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 7022 } 7023 deoptimizeCache() { 7024 this.getObjectEntity().deoptimizeAllProperties(); 7025 } 7026 deoptimizePath(path) { 7027 this.getObjectEntity().deoptimizePath(path); 7028 } 7029 getLiteralValueAtPath(path, recursionTracker, origin) { 7030 return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin); 7031 } 7032 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 7033 return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 7034 } 7035 hasEffects(context) { 7036 if (!this.deoptimized) 7037 this.applyDeoptimizations(); 7038 const initEffect = this.superClass?.hasEffects(context) || this.body.hasEffects(context); 7039 this.id?.markDeclarationReached(); 7040 return initEffect || super.hasEffects(context) || checkEffectForNodes(this.decorators, context); 7041 } 7042 hasEffectsOnInteractionAtPath(path, interaction, context) { 7043 return interaction.type === INTERACTION_CALLED && path.length === 0 7044 ? !interaction.withNew || 7045 (this.classConstructor === null 7046 ? this.superClass?.hasEffectsOnInteractionAtPath(path, interaction, context) 7047 : this.classConstructor.hasEffectsOnInteractionAtPath(path, interaction, context)) || 7048 false 7049 : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context); 7050 } 7051 include(context, includeChildrenRecursively) { 7052 if (!this.deoptimized) 7053 this.applyDeoptimizations(); 7054 this.included = true; 7055 this.superClass?.include(context, includeChildrenRecursively); 7056 this.body.include(context, includeChildrenRecursively); 7057 for (const decorator of this.decorators) 7058 decorator.include(context, includeChildrenRecursively); 7059 if (this.id) { 7060 this.id.markDeclarationReached(); 7061 this.id.include(); 7062 } 7063 } 7064 initialise() { 7065 super.initialise(); 7066 this.id?.declare('class', this); 7067 for (const method of this.body.body) { 7068 if (method instanceof MethodDefinition && method.kind === 'constructor') { 7069 this.classConstructor = method; 7070 return; 7071 } 7072 } 7073 this.classConstructor = null; 7074 } 7075 applyDeoptimizations() { 7076 this.deoptimized = true; 7077 for (const definition of this.body.body) { 7078 if (!isStaticBlock(definition) && 7079 !(definition.static || 7080 (definition instanceof MethodDefinition && definition.kind === 'constructor'))) { 7081 // Calls to methods are not tracked, ensure that the return value is deoptimized 7082 definition.deoptimizePath(UNKNOWN_PATH); 7083 } 7084 } 7085 this.scope.context.requestTreeshakingPass(); 7086 } 7087 getObjectEntity() { 7088 if (this.objectEntity !== null) { 7089 return this.objectEntity; 7090 } 7091 const staticProperties = []; 7092 const dynamicMethods = []; 7093 for (const definition of this.body.body) { 7094 if (isStaticBlock(definition)) 7095 continue; 7096 const properties = definition.static ? staticProperties : dynamicMethods; 7097 const definitionKind = definition.kind; 7098 // Note that class fields do not end up on the prototype 7099 if (properties === dynamicMethods && !definitionKind) 7100 continue; 7101 const kind = definitionKind === 'set' || definitionKind === 'get' ? definitionKind : 'init'; 7102 let key; 7103 if (definition.computed) { 7104 const keyValue = definition.key.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 7105 if (typeof keyValue === 'symbol') { 7106 properties.push({ key: UnknownKey, kind, property: definition }); 7107 continue; 7108 } 7109 else { 7110 key = String(keyValue); 7111 } 7112 } 7113 else { 7114 key = 7115 definition.key instanceof Identifier 7116 ? definition.key.name 7117 : String(definition.key.value); 7118 } 7119 properties.push({ key, kind, property: definition }); 7120 } 7121 staticProperties.unshift({ 7122 key: 'prototype', 7123 kind: 'init', 7124 property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE) 7125 }); 7126 return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE)); 7127 } 7128 } 7129 7130 class ClassDeclaration extends ClassNode { 7131 initialise() { 7132 super.initialise(); 7133 if (this.id !== null) { 7134 this.id.variable.isId = true; 7135 } 7136 } 7137 parseNode(esTreeNode) { 7138 if (esTreeNode.id !== null) { 7139 this.id = new Identifier(this, this.scope.parent).parseNode(esTreeNode.id); 7140 } 7141 return super.parseNode(esTreeNode); 7142 } 7143 render(code, options) { 7144 const { exportNamesByVariable, format, snippets: { _, getPropertyAccess } } = options; 7145 if (this.id) { 7146 const { variable, name } = this.id; 7147 if (format === 'system' && exportNamesByVariable.has(variable)) { 7148 code.appendLeft(this.end, `${_}${getSystemExportStatement([variable], options)};`); 7149 } 7150 const renderedVariable = variable.getName(getPropertyAccess); 7151 if (renderedVariable !== name) { 7152 this.decorators.map(decorator => decorator.render(code, options)); 7153 this.superClass?.render(code, options); 7154 this.body.render(code, { 7155 ...options, 7156 useOriginalName: (_variable) => _variable === variable 7157 }); 7158 code.prependRight(this.start, `let ${renderedVariable}${_}=${_}`); 7159 code.prependLeft(this.end, ';'); 7160 return; 7161 } 7162 } 7163 super.render(code, options); 7164 } 7165 applyDeoptimizations() { 7166 super.applyDeoptimizations(); 7167 const { id, scope } = this; 7168 if (id) { 7169 const { name, variable } = id; 7170 for (const accessedVariable of scope.accessedOutsideVariables.values()) { 7171 if (accessedVariable !== variable) { 7172 accessedVariable.forbidName(name); 7173 } 7174 } 7175 } 7176 } 7177 } 7178 7179 class ArgumentsVariable extends LocalVariable { 7180 constructor(context) { 7181 super('arguments', null, UNKNOWN_EXPRESSION, context, 'other'); 7182 this.deoptimizedArguments = []; 7183 } 7184 addArgumentToBeDeoptimized(argument) { 7185 if (this.included) { 7186 argument.deoptimizePath(UNKNOWN_PATH); 7187 } 7188 else { 7189 this.deoptimizedArguments.push(argument); 7190 } 7191 } 7192 hasEffectsOnInteractionAtPath(path, { type }) { 7193 return type !== INTERACTION_ACCESSED || path.length > 1; 7194 } 7195 include() { 7196 super.include(); 7197 for (const argument of this.deoptimizedArguments) { 7198 argument.deoptimizePath(UNKNOWN_PATH); 7199 } 7200 this.deoptimizedArguments.length = 0; 7201 } 7202 } 7203 7204 const MAX_TRACKED_INTERACTIONS = 20; 7205 const NO_INTERACTIONS = parseAst_js.EMPTY_ARRAY; 7206 const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]); 7207 const EMPTY_PATH_TRACKER = new PathTracker(); 7208 const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]); 7209 class ParameterVariable extends LocalVariable { 7210 constructor(name, declarator, context) { 7211 super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter'); 7212 this.deoptimizationInteractions = []; 7213 this.deoptimizations = new PathTracker(); 7214 this.deoptimizedFields = new Set(); 7215 this.entitiesToBeDeoptimized = new Set(); 7216 this.expressionsUseTheKnownValue = []; 7217 this.knownValue = null; 7218 this.knownValueLiteral = UnknownValue; 7219 this.frozenValue = null; 7220 } 7221 addEntityToBeDeoptimized(entity) { 7222 if (entity === UNKNOWN_EXPRESSION) { 7223 // As unknown expressions fully deoptimize all interactions, we can clear 7224 // the interaction cache at this point provided we keep this optimization 7225 // in mind when adding new interactions 7226 if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) { 7227 this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION); 7228 for (const { interaction } of this.deoptimizationInteractions) { 7229 deoptimizeInteraction(interaction); 7230 } 7231 this.deoptimizationInteractions = NO_INTERACTIONS; 7232 } 7233 } 7234 else if (this.deoptimizedFields.has(UnknownKey)) { 7235 // This means that we already deoptimized all interactions and no longer 7236 // track them 7237 entity.deoptimizePath(UNKNOWN_PATH); 7238 } 7239 else if (!this.entitiesToBeDeoptimized.has(entity)) { 7240 this.entitiesToBeDeoptimized.add(entity); 7241 for (const field of this.deoptimizedFields) { 7242 entity.deoptimizePath([field]); 7243 } 7244 for (const { interaction, path } of this.deoptimizationInteractions) { 7245 entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER); 7246 } 7247 } 7248 } 7249 markReassigned() { 7250 if (this.isReassigned) { 7251 return; 7252 } 7253 super.markReassigned(); 7254 for (const expression of this.expressionsUseTheKnownValue) { 7255 expression.deoptimizeCache(); 7256 } 7257 this.expressionsUseTheKnownValue = parseAst_js.EMPTY_ARRAY; 7258 } 7259 deoptimizeCache() { 7260 this.markReassigned(); 7261 } 7262 /** 7263 * Update the known value of the parameter variable. 7264 * Must be called for every function call, so it can track all the arguments, 7265 * and deoptimizeCache itself to mark reassigned if the argument is changed. 7266 * @param argument The argument of the function call 7267 */ 7268 updateKnownValue(argument) { 7269 if (this.isReassigned) { 7270 return; 7271 } 7272 if (this.knownValue === null) { 7273 this.knownValue = argument; 7274 this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 7275 return; 7276 } 7277 // the same literal or identifier, do nothing 7278 if (this.knownValue === argument || 7279 (this.knownValue instanceof Identifier && 7280 argument instanceof Identifier && 7281 this.knownValue.variable === argument.variable)) { 7282 return; 7283 } 7284 const oldValue = this.knownValueLiteral; 7285 if (typeof oldValue === 'symbol') { 7286 this.markReassigned(); 7287 return; 7288 } 7289 // add tracking for the new argument 7290 const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 7291 if (newValue !== oldValue) { 7292 this.markReassigned(); 7293 } 7294 } 7295 /** 7296 * This function freezes the known value of the parameter variable, 7297 * so the optimization starts with a certain ExpressionEntity. 7298 * The optimization can be undone by calling `markReassigned`. 7299 * @returns the frozen value 7300 */ 7301 getKnownValue() { 7302 if (this.frozenValue === null) { 7303 this.frozenValue = this.knownValue || UNKNOWN_EXPRESSION; 7304 } 7305 return this.frozenValue; 7306 } 7307 getLiteralValueAtPath(path, recursionTracker, origin) { 7308 if (this.isReassigned) { 7309 return UnknownValue; 7310 } 7311 const knownValue = this.getKnownValue(); 7312 this.expressionsUseTheKnownValue.push(origin); 7313 return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue); 7314 } 7315 hasEffectsOnInteractionAtPath(path, interaction, context) { 7316 if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) { 7317 return super.hasEffectsOnInteractionAtPath(path, interaction, context); 7318 } 7319 const knownValue = this.getKnownValue(); 7320 return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context); 7321 } 7322 deoptimizeArgumentsOnInteractionAtPath(interaction, path) { 7323 // For performance reasons, we fully deoptimize all deeper interactions 7324 if (path.length >= 2 || 7325 this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) || 7326 this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS || 7327 (path.length === 1 && 7328 (this.deoptimizedFields.has(UnknownKey) || 7329 (interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0]))))) { 7330 deoptimizeInteraction(interaction); 7331 return; 7332 } 7333 if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) { 7334 for (const entity of this.entitiesToBeDeoptimized) { 7335 entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER); 7336 } 7337 if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) { 7338 this.deoptimizationInteractions.push({ 7339 interaction, 7340 path 7341 }); 7342 } 7343 } 7344 } 7345 deoptimizePath(path) { 7346 if (path.length === 0) { 7347 this.markReassigned(); 7348 return; 7349 } 7350 if (this.deoptimizedFields.has(UnknownKey)) { 7351 return; 7352 } 7353 const key = path[0]; 7354 if (this.deoptimizedFields.has(key)) { 7355 return; 7356 } 7357 this.deoptimizedFields.add(key); 7358 for (const entity of this.entitiesToBeDeoptimized) { 7359 // We do not need a recursion tracker here as we already track whether 7360 // this field is deoptimized 7361 entity.deoptimizePath([key]); 7362 } 7363 if (key === UnknownKey) { 7364 // save some memory 7365 this.deoptimizationInteractions = NO_INTERACTIONS; 7366 this.deoptimizations = EMPTY_PATH_TRACKER; 7367 this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD; 7368 this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY; 7369 } 7370 } 7371 getReturnExpressionWhenCalledAtPath(path) { 7372 // We deoptimize everything that is called as that will trivially deoptimize 7373 // the corresponding return expressions as well and avoid badly performing 7374 // and complicated alternatives 7375 if (path.length === 0) { 7376 this.deoptimizePath(UNKNOWN_PATH); 7377 } 7378 else if (!this.deoptimizedFields.has(path[0])) { 7379 this.deoptimizePath([path[0]]); 7380 } 7381 return UNKNOWN_RETURN_EXPRESSION; 7382 } 7383 } 7384 7385 class ThisVariable extends ParameterVariable { 7386 constructor(context) { 7387 super('this', null, context); 7388 } 7389 hasEffectsOnInteractionAtPath(path, interaction, context) { 7390 return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context); 8917 7391 } 8918 7392 } … … 9095 7569 } 9096 7570 9097 function treeshakeNode(node, code, start, end) { 9098 code.remove(start, end); 9099 node.removeAnnotations(code); 9100 } 9101 9102 const NO_SEMICOLON = { isNoStatement: true }; 9103 // This assumes there are only white-space and comments between start and the string we are looking for 9104 function findFirstOccurrenceOutsideComment(code, searchString, start = 0) { 9105 let searchPos, charCodeAfterSlash; 9106 searchPos = code.indexOf(searchString, start); 9107 while (true) { 9108 start = code.indexOf('/', start); 9109 if (start === -1 || start >= searchPos) 9110 return searchPos; 9111 charCodeAfterSlash = code.charCodeAt(++start); 9112 ++start; 9113 // With our assumption, '/' always starts a comment. Determine comment type: 9114 start = 9115 charCodeAfterSlash === 47 /*"/"*/ 9116 ? code.indexOf('\n', start) + 1 9117 : code.indexOf('*/', start) + 2; 9118 if (start > searchPos) { 9119 searchPos = code.indexOf(searchString, start); 9120 } 9121 } 9122 } 9123 const NON_WHITESPACE = /\S/g; 9124 function findNonWhiteSpace(code, index) { 9125 NON_WHITESPACE.lastIndex = index; 9126 const result = NON_WHITESPACE.exec(code); 9127 return result.index; 9128 } 9129 const WHITESPACE = /\s/; 9130 function findLastWhiteSpaceReverse(code, start, end) { 9131 while (true) { 9132 if (start >= end) { 9133 return end; 9134 } 9135 if (WHITESPACE.test(code[end - 1])) { 9136 end--; 9137 } 9138 else { 9139 return end; 9140 } 9141 } 9142 } 9143 // This assumes "code" only contains white-space and comments 9144 // Returns position of line-comment if applicable 9145 function findFirstLineBreakOutsideComment(code) { 9146 let lineBreakPos, charCodeAfterSlash, start = 0; 9147 lineBreakPos = code.indexOf('\n', start); 9148 while (true) { 9149 start = code.indexOf('/', start); 9150 if (start === -1 || start > lineBreakPos) 9151 return [lineBreakPos, lineBreakPos + 1]; 9152 // With our assumption, '/' always starts a comment. Determine comment type: 9153 charCodeAfterSlash = code.charCodeAt(start + 1); 9154 if (charCodeAfterSlash === 47 /*"/"*/) 9155 return [start, lineBreakPos + 1]; 9156 start = code.indexOf('*/', start + 2) + 2; 9157 if (start > lineBreakPos) { 9158 lineBreakPos = code.indexOf('\n', start); 9159 } 9160 } 9161 } 9162 function renderStatementList(statements, code, start, end, options) { 9163 let currentNode, currentNodeStart, currentNodeNeedsBoundaries, nextNodeStart; 9164 let nextNode = statements[0]; 9165 let nextNodeNeedsBoundaries = !nextNode.included || nextNode.needsBoundaries; 9166 if (nextNodeNeedsBoundaries) { 9167 nextNodeStart = 9168 start + findFirstLineBreakOutsideComment(code.original.slice(start, nextNode.start))[1]; 9169 } 9170 for (let nextIndex = 1; nextIndex <= statements.length; nextIndex++) { 9171 currentNode = nextNode; 9172 currentNodeStart = nextNodeStart; 9173 currentNodeNeedsBoundaries = nextNodeNeedsBoundaries; 9174 nextNode = statements[nextIndex]; 9175 nextNodeNeedsBoundaries = 9176 nextNode === undefined ? false : !nextNode.included || nextNode.needsBoundaries; 9177 if (currentNodeNeedsBoundaries || nextNodeNeedsBoundaries) { 9178 nextNodeStart = 9179 currentNode.end + 9180 findFirstLineBreakOutsideComment(code.original.slice(currentNode.end, nextNode === undefined ? end : nextNode.start))[1]; 9181 if (currentNode.included) { 9182 currentNodeNeedsBoundaries 9183 ? currentNode.render(code, options, { 9184 end: nextNodeStart, 9185 start: currentNodeStart 9186 }) 9187 : currentNode.render(code, options); 9188 } 9189 else { 9190 treeshakeNode(currentNode, code, currentNodeStart, nextNodeStart); 9191 } 9192 } 9193 else { 9194 currentNode.render(code, options); 9195 } 9196 } 9197 } 9198 // This assumes that the first character is not part of the first node 9199 function getCommaSeparatedNodesWithBoundaries(nodes, code, start, end) { 9200 const splitUpNodes = []; 9201 let node, nextNodeStart, contentEnd, char; 9202 let separator = start - 1; 9203 for (const nextNode of nodes) { 9204 if (node !== undefined) { 9205 separator = 9206 node.end + 9207 findFirstOccurrenceOutsideComment(code.original.slice(node.end, nextNode.start), ','); 9208 } 9209 nextNodeStart = contentEnd = 9210 separator + 9211 1 + 9212 findFirstLineBreakOutsideComment(code.original.slice(separator + 1, nextNode.start))[1]; 9213 while (((char = code.original.charCodeAt(nextNodeStart)), 9214 char === 32 /*" "*/ || char === 9 /*"\t"*/ || char === 10 /*"\n"*/ || char === 13) /*"\r"*/) 9215 nextNodeStart++; 9216 if (node !== undefined) { 9217 splitUpNodes.push({ 9218 contentEnd, 9219 end: nextNodeStart, 9220 node, 9221 separator, 9222 start 9223 }); 9224 } 9225 node = nextNode; 9226 start = nextNodeStart; 9227 } 9228 splitUpNodes.push({ 9229 contentEnd: end, 9230 end, 9231 node: node, 9232 separator: null, 9233 start 9234 }); 9235 return splitUpNodes; 9236 } 9237 // This assumes there are only white-space and comments between start and end 9238 function removeLineBreaks(code, start, end) { 9239 while (true) { 9240 const [removeStart, removeEnd] = findFirstLineBreakOutsideComment(code.original.slice(start, end)); 9241 if (removeStart === -1) { 9242 break; 9243 } 9244 code.remove(start + removeStart, (start += removeEnd)); 9245 } 9246 } 9247 9248 class BlockScope extends ChildScope { 7571 class FunctionScope extends ReturnValueScope { 9249 7572 constructor(parent) { 9250 super(parent, parent.context); 9251 } 9252 addDeclaration(identifier, context, init, kind) { 9253 if (kind === 'var') { 9254 const name = identifier.name; 9255 const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name); 9256 if (existingVariable) { 9257 if (existingVariable.kind === 'var' || 9258 (kind === 'var' && existingVariable.kind === 'parameter')) { 9259 existingVariable.addDeclaration(identifier, init); 9260 return existingVariable; 7573 const { context } = parent; 7574 super(parent, false); 7575 this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context))); 7576 this.variables.set('this', (this.thisVariable = new ThisVariable(context))); 7577 } 7578 findLexicalBoundary() { 7579 return this; 7580 } 7581 includeCallArguments(context, parameters) { 7582 super.includeCallArguments(context, parameters); 7583 if (this.argumentsVariable.included) { 7584 for (const argument of parameters) { 7585 if (!argument.included) { 7586 argument.include(context, false); 9261 7587 } 9262 return context.error(parseAst_js.logRedeclarationError(name), identifier.start); 9263 } 9264 const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind); 9265 // Necessary to make sure the init is deoptimized for conditional declarations. 9266 // We cannot call deoptimizePath here. 9267 declaredVariable.markInitializersForDeoptimization(); 9268 // We add the variable to this and all parent scopes to reliably detect conflicts 9269 this.addHoistedVariable(name, declaredVariable); 9270 return declaredVariable; 9271 } 9272 return super.addDeclaration(identifier, context, init, kind); 7588 } 7589 } 9273 7590 } 9274 7591 } … … 9379 7696 } 9380 7697 deoptimizePath(path) { 9381 path.length === 0 && this.argument.deoptimizePath(EMPTY_PATH); 7698 if (path.length === 0) { 7699 this.argument.deoptimizePath(EMPTY_PATH); 7700 } 9382 7701 } 9383 7702 hasEffectsOnInteractionAtPath(path, interaction, context) { … … 9587 7906 FunctionBase.prototype.preventChildBlockScope = true; 9588 7907 9589 class ArrowFunctionExpression extends FunctionBase {9590 constructor() {9591 super(...arguments);9592 this.objectEntity = null;9593 }9594 get expression() {9595 return isFlagSet(this.flags, 8388608 /* Flag.expression */);9596 }9597 set expression(value) {9598 this.flags = setFlag(this.flags, 8388608 /* Flag.expression */, value);9599 }9600 createScope(parentScope) {9601 this.scope = new ReturnValueScope(parentScope, false);9602 }9603 hasEffects() {9604 if (!this.deoptimized)9605 this.applyDeoptimizations();9606 return false;9607 }9608 hasEffectsOnInteractionAtPath(path, interaction, context) {9609 if (super.hasEffectsOnInteractionAtPath(path, interaction, context)) {9610 return true;9611 }9612 if (this.annotationNoSideEffects) {9613 return false;9614 }9615 if (interaction.type === INTERACTION_CALLED) {9616 const { ignore, brokenFlow } = context;9617 context.ignore = {9618 breaks: false,9619 continues: false,9620 labels: new Set(),9621 returnYield: true,9622 this: false9623 };9624 if (this.body.hasEffects(context))9625 return true;9626 context.ignore = ignore;9627 context.brokenFlow = brokenFlow;9628 }9629 return false;9630 }9631 onlyFunctionCallUsed() {9632 const isIIFE = this.parent.type === parseAst_js.CallExpression &&9633 this.parent.callee === this;9634 return isIIFE || super.onlyFunctionCallUsed();9635 }9636 include(context, includeChildrenRecursively) {9637 super.include(context, includeChildrenRecursively);9638 for (const parameter of this.params) {9639 if (!(parameter instanceof Identifier)) {9640 parameter.include(context, includeChildrenRecursively);9641 }9642 }9643 }9644 getObjectEntity() {9645 if (this.objectEntity !== null) {9646 return this.objectEntity;9647 }9648 return (this.objectEntity = new ObjectEntity([], OBJECT_PROTOTYPE));9649 }9650 }9651 9652 function getSystemExportStatement(exportedVariables, { exportNamesByVariable, snippets: { _, getObject, getPropertyAccess } }, modifier = '') {9653 if (exportedVariables.length === 1 &&9654 exportNamesByVariable.get(exportedVariables[0]).length === 1) {9655 const variable = exportedVariables[0];9656 return `exports(${JSON.stringify(exportNamesByVariable.get(variable)[0])},${_}${variable.getName(getPropertyAccess)}${modifier})`;9657 }9658 else {9659 const fields = [];9660 for (const variable of exportedVariables) {9661 for (const exportName of exportNamesByVariable.get(variable)) {9662 fields.push([exportName, variable.getName(getPropertyAccess) + modifier]);9663 }9664 }9665 return `exports(${getObject(fields, { lineBreakIndent: null })})`;9666 }9667 }9668 // This is only invoked if there is exactly one export name9669 function renderSystemExportExpression(exportedVariable, expressionStart, expressionEnd, code, { exportNamesByVariable, snippets: { _ } }) {9670 code.prependRight(expressionStart, `exports(${JSON.stringify(exportNamesByVariable.get(exportedVariable)[0])},${_}`);9671 code.appendLeft(expressionEnd, ')');9672 }9673 function renderSystemExportFunction(exportedVariables, expressionStart, expressionEnd, needsParens, code, options) {9674 const { _, getDirectReturnIifeLeft } = options.snippets;9675 code.prependRight(expressionStart, getDirectReturnIifeLeft(['v'], `${getSystemExportStatement(exportedVariables, options)},${_}v`, { needsArrowReturnParens: true, needsWrappedFunction: needsParens }));9676 code.appendLeft(expressionEnd, ')');9677 }9678 function renderSystemExportSequenceAfterExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options) {9679 const { _, getPropertyAccess } = options.snippets;9680 code.appendLeft(expressionEnd, `,${_}${getSystemExportStatement([exportedVariable], options)},${_}${exportedVariable.getName(getPropertyAccess)}`);9681 if (needsParens) {9682 code.prependRight(expressionStart, '(');9683 code.appendLeft(expressionEnd, ')');9684 }9685 }9686 function renderSystemExportSequenceBeforeExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options, modifier) {9687 const { _ } = options.snippets;9688 code.prependRight(expressionStart, `${getSystemExportStatement([exportedVariable], options, modifier)},${_}`);9689 if (needsParens) {9690 code.prependRight(expressionStart, '(');9691 code.appendLeft(expressionEnd, ')');9692 }9693 }9694 9695 class ObjectPattern extends NodeBase {9696 addExportedVariables(variables, exportNamesByVariable) {9697 for (const property of this.properties) {9698 if (property.type === parseAst_js.Property) {9699 property.value.addExportedVariables(variables, exportNamesByVariable);9700 }9701 else {9702 property.argument.addExportedVariables(variables, exportNamesByVariable);9703 }9704 }9705 }9706 declare(kind, init) {9707 const variables = [];9708 for (const property of this.properties) {9709 variables.push(...property.declare(kind, init));9710 }9711 return variables;9712 }9713 deoptimizePath(path) {9714 if (path.length === 0) {9715 for (const property of this.properties) {9716 property.deoptimizePath(path);9717 }9718 }9719 }9720 hasEffectsOnInteractionAtPath(9721 // At the moment, this is only triggered for assignment left-hand sides,9722 // where the path is empty9723 _path, interaction, context) {9724 for (const property of this.properties) {9725 if (property.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context))9726 return true;9727 }9728 return false;9729 }9730 markDeclarationReached() {9731 for (const property of this.properties) {9732 property.markDeclarationReached();9733 }9734 }9735 }9736 9737 class AssignmentExpression extends NodeBase {9738 hasEffects(context) {9739 const { deoptimized, left, operator, right } = this;9740 if (!deoptimized)9741 this.applyDeoptimizations();9742 // MemberExpressions do not access the property before assignments if the9743 // operator is '='.9744 return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '='));9745 }9746 hasEffectsOnInteractionAtPath(path, interaction, context) {9747 return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);9748 }9749 include(context, includeChildrenRecursively) {9750 const { deoptimized, left, right, operator } = this;9751 if (!deoptimized)9752 this.applyDeoptimizations();9753 this.included = true;9754 if (includeChildrenRecursively ||9755 operator !== '=' ||9756 left.included ||9757 left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {9758 left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');9759 }9760 right.include(context, includeChildrenRecursively);9761 }9762 initialise() {9763 super.initialise();9764 if (this.left instanceof Identifier) {9765 const variable = this.scope.variables.get(this.left.name);9766 if (variable?.kind === 'const') {9767 this.scope.context.error(parseAst_js.logConstVariableReassignError(), this.left.start);9768 }9769 }9770 this.left.setAssignedValue(this.right);9771 }9772 render(code, options, { preventASI, renderedParentType, renderedSurroundingElement } = parseAst_js.BLANK) {9773 const { left, right, start, end, parent } = this;9774 if (left.included) {9775 left.render(code, options);9776 right.render(code, options);9777 }9778 else {9779 const inclusionStart = findNonWhiteSpace(code.original, findFirstOccurrenceOutsideComment(code.original, '=', left.end) + 1);9780 code.remove(start, inclusionStart);9781 if (preventASI) {9782 removeLineBreaks(code, inclusionStart, right.start);9783 }9784 right.render(code, options, {9785 renderedParentType: renderedParentType || parent.type,9786 renderedSurroundingElement: renderedSurroundingElement || parent.type9787 });9788 }9789 if (options.format === 'system') {9790 if (left instanceof Identifier) {9791 const variable = left.variable;9792 const exportNames = options.exportNamesByVariable.get(variable);9793 if (exportNames) {9794 if (exportNames.length === 1) {9795 renderSystemExportExpression(variable, start, end, code, options);9796 }9797 else {9798 renderSystemExportSequenceAfterExpression(variable, start, end, parent.type !== parseAst_js.ExpressionStatement, code, options);9799 }9800 return;9801 }9802 }9803 else {9804 const systemPatternExports = [];9805 left.addExportedVariables(systemPatternExports, options.exportNamesByVariable);9806 if (systemPatternExports.length > 0) {9807 renderSystemExportFunction(systemPatternExports, start, end, renderedSurroundingElement === parseAst_js.ExpressionStatement, code, options);9808 return;9809 }9810 }9811 }9812 if (left.included &&9813 left instanceof ObjectPattern &&9814 (renderedSurroundingElement === parseAst_js.ExpressionStatement ||9815 renderedSurroundingElement === parseAst_js.ArrowFunctionExpression)) {9816 code.appendRight(start, '(');9817 code.prependLeft(end, ')');9818 }9819 }9820 applyDeoptimizations() {9821 this.deoptimized = true;9822 this.left.deoptimizePath(EMPTY_PATH);9823 this.right.deoptimizePath(UNKNOWN_PATH);9824 this.scope.context.requestTreeshakingPass();9825 }9826 }9827 9828 class AssignmentPattern extends NodeBase {9829 addExportedVariables(variables, exportNamesByVariable) {9830 this.left.addExportedVariables(variables, exportNamesByVariable);9831 }9832 declare(kind, init) {9833 return this.left.declare(kind, init);9834 }9835 deoptimizePath(path) {9836 path.length === 0 && this.left.deoptimizePath(path);9837 }9838 hasEffectsOnInteractionAtPath(path, interaction, context) {9839 return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));9840 }9841 markDeclarationReached() {9842 this.left.markDeclarationReached();9843 }9844 render(code, options, { isShorthandProperty } = parseAst_js.BLANK) {9845 this.left.render(code, options, { isShorthandProperty });9846 this.right.render(code, options);9847 }9848 applyDeoptimizations() {9849 this.deoptimized = true;9850 this.left.deoptimizePath(EMPTY_PATH);9851 this.right.deoptimizePath(UNKNOWN_PATH);9852 this.scope.context.requestTreeshakingPass();9853 }9854 }9855 9856 class ArgumentsVariable extends LocalVariable {9857 constructor(context) {9858 super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');9859 this.deoptimizedArguments = [];9860 }9861 addArgumentToBeDeoptimized(argument) {9862 if (this.included) {9863 argument.deoptimizePath(UNKNOWN_PATH);9864 }9865 else {9866 this.deoptimizedArguments.push(argument);9867 }9868 }9869 hasEffectsOnInteractionAtPath(path, { type }) {9870 return type !== INTERACTION_ACCESSED || path.length > 1;9871 }9872 include() {9873 super.include();9874 for (const argument of this.deoptimizedArguments) {9875 argument.deoptimizePath(UNKNOWN_PATH);9876 }9877 this.deoptimizedArguments.length = 0;9878 }9879 }9880 9881 class ThisVariable extends ParameterVariable {9882 constructor(context) {9883 super('this', null, context);9884 }9885 hasEffectsOnInteractionAtPath(path, interaction, context) {9886 return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);9887 }9888 }9889 9890 class FunctionScope extends ReturnValueScope {9891 constructor(parent) {9892 const { context } = parent;9893 super(parent, false);9894 this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));9895 this.variables.set('this', (this.thisVariable = new ThisVariable(context)));9896 }9897 findLexicalBoundary() {9898 return this;9899 }9900 includeCallArguments(context, parameters) {9901 super.includeCallArguments(context, parameters);9902 if (this.argumentsVariable.included) {9903 for (const argument of parameters) {9904 if (!argument.included) {9905 argument.include(context, false);9906 }9907 }9908 }9909 }9910 }9911 9912 7908 class FunctionNode extends FunctionBase { 9913 7909 constructor() { … … 9998 7994 } 9999 7995 10000 class AwaitExpression extends NodeBase {10001 hasEffects() {10002 if (!this.deoptimized)10003 this.applyDeoptimizations();10004 return true;10005 }10006 include(context, includeChildrenRecursively) {10007 if (!this.deoptimized)10008 this.applyDeoptimizations();10009 if (!this.included) {10010 this.included = true;10011 checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) {10012 let parent = this.parent;10013 do {10014 if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression)10015 break checkTopLevelAwait;10016 } while ((parent = parent.parent));10017 this.scope.context.usesTopLevelAwait = true;10018 }10019 }10020 this.argument.include(context, includeChildrenRecursively);10021 }10022 }10023 10024 const binaryOperators = {10025 '!=': (left, right) => left != right,10026 '!==': (left, right) => left !== right,10027 '%': (left, right) => left % right,10028 '&': (left, right) => left & right,10029 '*': (left, right) => left * right,10030 // At the moment, "**" will be transpiled to Math.pow10031 '**': (left, right) => left ** right,10032 '+': (left, right) => left + right,10033 '-': (left, right) => left - right,10034 '/': (left, right) => left / right,10035 '<': (left, right) => left < right,10036 '<<': (left, right) => left << right,10037 '<=': (left, right) => left <= right,10038 '==': (left, right) => left == right,10039 '===': (left, right) => left === right,10040 '>': (left, right) => left > right,10041 '>=': (left, right) => left >= right,10042 '>>': (left, right) => left >> right,10043 '>>>': (left, right) => left >>> right,10044 '^': (left, right) => left ^ right,10045 '|': (left, right) => left | right10046 // We use the fallback for cases where we return something unknown10047 // in: () => UnknownValue,10048 // instanceof: () => UnknownValue,10049 };10050 class BinaryExpression extends NodeBase {10051 deoptimizeCache() { }10052 getLiteralValueAtPath(path, recursionTracker, origin) {10053 if (path.length > 0)10054 return UnknownValue;10055 const leftValue = this.left.getLiteralValueAtPath(EMPTY_PATH, recursionTracker, origin);10056 if (typeof leftValue === 'symbol')10057 return UnknownValue;10058 const rightValue = this.right.getLiteralValueAtPath(EMPTY_PATH, recursionTracker, origin);10059 if (typeof rightValue === 'symbol')10060 return UnknownValue;10061 const operatorFunction = binaryOperators[this.operator];10062 if (!operatorFunction)10063 return UnknownValue;10064 return operatorFunction(leftValue, rightValue);10065 }10066 hasEffects(context) {10067 // support some implicit type coercion runtime errors10068 if (this.operator === '+' &&10069 this.parent instanceof ExpressionStatement &&10070 this.left.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) === '') {10071 return true;10072 }10073 return super.hasEffects(context);10074 }10075 hasEffectsOnInteractionAtPath(path, { type }) {10076 return type !== INTERACTION_ACCESSED || path.length > 1;10077 }10078 removeAnnotations(code) {10079 this.left.removeAnnotations(code);10080 }10081 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {10082 this.left.render(code, options, { renderedSurroundingElement });10083 this.right.render(code, options);10084 }10085 }10086 10087 class BreakStatement extends NodeBase {10088 hasEffects(context) {10089 if (this.label) {10090 if (!context.ignore.labels.has(this.label.name))10091 return true;10092 context.includedLabels.add(this.label.name);10093 }10094 else {10095 if (!context.ignore.breaks)10096 return true;10097 context.hasBreak = true;10098 }10099 context.brokenFlow = true;10100 return false;10101 }10102 include(context) {10103 this.included = true;10104 if (this.label) {10105 this.label.include();10106 context.includedLabels.add(this.label.name);10107 }10108 else {10109 context.hasBreak = true;10110 }10111 context.brokenFlow = true;10112 }10113 }10114 10115 function renderCallArguments(code, options, node) {10116 if (node.arguments.length > 0) {10117 if (node.arguments[node.arguments.length - 1].included) {10118 for (const argument of node.arguments) {10119 argument.render(code, options);10120 }10121 }10122 else {10123 let lastIncludedIndex = node.arguments.length - 2;10124 while (lastIncludedIndex >= 0 && !node.arguments[lastIncludedIndex].included) {10125 lastIncludedIndex--;10126 }10127 if (lastIncludedIndex >= 0) {10128 for (let index = 0; index <= lastIncludedIndex; index++) {10129 node.arguments[index].render(code, options);10130 }10131 code.remove(findFirstOccurrenceOutsideComment(code.original, ',', node.arguments[lastIncludedIndex].end), node.end - 1);10132 }10133 else {10134 code.remove(findFirstOccurrenceOutsideComment(code.original, '(', node.callee.end) + 1, node.end - 1);10135 }10136 }10137 }10138 }10139 10140 class Literal extends NodeBase {10141 deoptimizeArgumentsOnInteractionAtPath() { }10142 getLiteralValueAtPath(path) {10143 if (path.length > 0 ||10144 // unknown literals can also be null but do not start with an "n"10145 (this.value === null && this.scope.context.code.charCodeAt(this.start) !== 110) ||10146 typeof this.value === 'bigint' ||10147 // to support shims for regular expressions10148 this.scope.context.code.charCodeAt(this.start) === 47) {10149 return UnknownValue;10150 }10151 return this.value;10152 }10153 getReturnExpressionWhenCalledAtPath(path) {10154 if (path.length !== 1)10155 return UNKNOWN_RETURN_EXPRESSION;10156 return getMemberReturnExpressionWhenCalled(this.members, path[0]);10157 }10158 hasEffectsOnInteractionAtPath(path, interaction, context) {10159 switch (interaction.type) {10160 case INTERACTION_ACCESSED: {10161 return path.length > (this.value === null ? 0 : 1);10162 }10163 case INTERACTION_ASSIGNED: {10164 return true;10165 }10166 case INTERACTION_CALLED: {10167 if (this.included &&10168 this.value instanceof RegExp &&10169 (this.value.global || this.value.sticky)) {10170 return true;10171 }10172 return (path.length !== 1 ||10173 hasMemberEffectWhenCalled(this.members, path[0], interaction, context));10174 }10175 }10176 }10177 initialise() {10178 super.initialise();10179 this.members = getLiteralMembersForValue(this.value);10180 }10181 parseNode(esTreeNode) {10182 this.value = esTreeNode.value;10183 this.regex = esTreeNode.regex;10184 return super.parseNode(esTreeNode);10185 }10186 render(code) {10187 if (typeof this.value === 'string') {10188 code.indentExclusionRanges.push([this.start + 1, this.end - 1]);10189 }10190 }10191 }10192 10193 function getChainElementLiteralValueAtPath(element, object, path, recursionTracker, origin) {10194 if ('getLiteralValueAtPathAsChainElement' in object) {10195 const calleeValue = object.getLiteralValueAtPathAsChainElement(EMPTY_PATH, SHARED_RECURSION_TRACKER, origin);10196 if (calleeValue === IS_SKIPPED_CHAIN || (element.optional && calleeValue == null)) {10197 return IS_SKIPPED_CHAIN;10198 }10199 }10200 else if (element.optional &&10201 object.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, origin) == null) {10202 return IS_SKIPPED_CHAIN;10203 }10204 return element.getLiteralValueAtPath(path, recursionTracker, origin);10205 }10206 10207 // To avoid infinite recursions10208 const MAX_PATH_DEPTH = 7;10209 function getResolvablePropertyKey(memberExpression) {10210 return memberExpression.computed10211 ? getResolvableComputedPropertyKey(memberExpression.property)10212 : memberExpression.property.name;10213 }10214 function getResolvableComputedPropertyKey(propertyKey) {10215 if (propertyKey instanceof Literal) {10216 return String(propertyKey.value);10217 }10218 return null;10219 }10220 function getPathIfNotComputed(memberExpression) {10221 const nextPathKey = memberExpression.propertyKey;10222 const object = memberExpression.object;10223 if (typeof nextPathKey === 'string') {10224 if (object instanceof Identifier) {10225 return [10226 { key: object.name, pos: object.start },10227 { key: nextPathKey, pos: memberExpression.property.start }10228 ];10229 }10230 if (object instanceof MemberExpression) {10231 const parentPath = getPathIfNotComputed(object);10232 return (parentPath && [...parentPath, { key: nextPathKey, pos: memberExpression.property.start }]);10233 }10234 }10235 return null;10236 }10237 function getStringFromPath(path) {10238 let pathString = path[0].key;10239 for (let index = 1; index < path.length; index++) {10240 pathString += '.' + path[index].key;10241 }10242 return pathString;10243 }10244 class MemberExpression extends NodeBase {10245 constructor() {10246 super(...arguments);10247 this.variable = null;10248 this.expressionsToBeDeoptimized = [];10249 }10250 get computed() {10251 return isFlagSet(this.flags, 1024 /* Flag.computed */);10252 }10253 set computed(value) {10254 this.flags = setFlag(this.flags, 1024 /* Flag.computed */, value);10255 }10256 get optional() {10257 return isFlagSet(this.flags, 128 /* Flag.optional */);10258 }10259 set optional(value) {10260 this.flags = setFlag(this.flags, 128 /* Flag.optional */, value);10261 }10262 get assignmentDeoptimized() {10263 return isFlagSet(this.flags, 16 /* Flag.assignmentDeoptimized */);10264 }10265 set assignmentDeoptimized(value) {10266 this.flags = setFlag(this.flags, 16 /* Flag.assignmentDeoptimized */, value);10267 }10268 get bound() {10269 return isFlagSet(this.flags, 32 /* Flag.bound */);10270 }10271 set bound(value) {10272 this.flags = setFlag(this.flags, 32 /* Flag.bound */, value);10273 }10274 get isUndefined() {10275 return isFlagSet(this.flags, 64 /* Flag.isUndefined */);10276 }10277 set isUndefined(value) {10278 this.flags = setFlag(this.flags, 64 /* Flag.isUndefined */, value);10279 }10280 bind() {10281 this.bound = true;10282 const path = getPathIfNotComputed(this);10283 const baseVariable = path && this.scope.findVariable(path[0].key);10284 if (baseVariable?.isNamespace) {10285 const resolvedVariable = resolveNamespaceVariables(baseVariable, path.slice(1), this.scope.context);10286 if (!resolvedVariable) {10287 super.bind();10288 }10289 else if (resolvedVariable === 'undefined') {10290 this.isUndefined = true;10291 }10292 else {10293 this.variable = resolvedVariable;10294 this.scope.addNamespaceMemberAccess(getStringFromPath(path), resolvedVariable);10295 }10296 }10297 else {10298 super.bind();10299 }10300 }10301 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {10302 if (this.variable) {10303 this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);10304 }10305 else if (!this.isUndefined) {10306 if (path.length < MAX_PATH_DEPTH) {10307 this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.getPropertyKey(), ...path], recursionTracker);10308 }10309 else {10310 deoptimizeInteraction(interaction);10311 }10312 }10313 }10314 deoptimizeCache() {10315 const { expressionsToBeDeoptimized, object } = this;10316 this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;10317 this.propertyKey = UnknownKey;10318 object.deoptimizePath(UNKNOWN_PATH);10319 for (const expression of expressionsToBeDeoptimized) {10320 expression.deoptimizeCache();10321 }10322 }10323 deoptimizePath(path) {10324 if (path.length === 0)10325 this.disallowNamespaceReassignment();10326 if (this.variable) {10327 this.variable.deoptimizePath(path);10328 }10329 else if (!this.isUndefined && path.length < MAX_PATH_DEPTH) {10330 const propertyKey = this.getPropertyKey();10331 this.object.deoptimizePath([10332 propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey,10333 ...path10334 ]);10335 }10336 }10337 getLiteralValueAtPath(path, recursionTracker, origin) {10338 if (this.variable) {10339 return this.variable.getLiteralValueAtPath(path, recursionTracker, origin);10340 }10341 if (this.isUndefined) {10342 return undefined;10343 }10344 if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {10345 this.expressionsToBeDeoptimized.push(origin);10346 return this.object.getLiteralValueAtPath([this.getPropertyKey(), ...path], recursionTracker, origin);10347 }10348 return UnknownValue;10349 }10350 getLiteralValueAtPathAsChainElement(path, recursionTracker, origin) {10351 if (this.variable) {10352 return this.variable.getLiteralValueAtPath(path, recursionTracker, origin);10353 }10354 if (this.isUndefined) {10355 return undefined;10356 }10357 return getChainElementLiteralValueAtPath(this, this.object, path, recursionTracker, origin);10358 }10359 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {10360 if (this.variable) {10361 return this.variable.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);10362 }10363 if (this.isUndefined) {10364 return [UNDEFINED_EXPRESSION, false];10365 }10366 if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {10367 this.expressionsToBeDeoptimized.push(origin);10368 return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin);10369 }10370 return UNKNOWN_RETURN_EXPRESSION;10371 }10372 hasEffects(context) {10373 if (!this.deoptimized)10374 this.applyDeoptimizations();10375 return (this.property.hasEffects(context) ||10376 this.object.hasEffects(context) ||10377 this.hasAccessEffect(context));10378 }10379 hasEffectsAsChainElement(context) {10380 if (this.variable || this.isUndefined)10381 return this.hasEffects(context);10382 const objectHasEffects = 'hasEffectsAsChainElement' in this.object10383 ? this.object.hasEffectsAsChainElement(context)10384 : this.object.hasEffects(context);10385 if (objectHasEffects === IS_SKIPPED_CHAIN)10386 return IS_SKIPPED_CHAIN;10387 if (this.optional &&10388 this.object.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) == null) {10389 return objectHasEffects || IS_SKIPPED_CHAIN;10390 }10391 // We only apply deoptimizations lazily once we know we are not skipping10392 if (!this.deoptimized)10393 this.applyDeoptimizations();10394 return this.property.hasEffects(context) || this.hasAccessEffect(context);10395 }10396 hasEffectsAsAssignmentTarget(context, checkAccess) {10397 if (checkAccess && !this.deoptimized)10398 this.applyDeoptimizations();10399 if (!this.assignmentDeoptimized)10400 this.applyAssignmentDeoptimization();10401 return (this.property.hasEffects(context) ||10402 this.object.hasEffects(context) ||10403 (checkAccess && this.hasAccessEffect(context)) ||10404 this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));10405 }10406 hasEffectsOnInteractionAtPath(path, interaction, context) {10407 if (this.variable) {10408 return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);10409 }10410 if (this.isUndefined) {10411 return true;10412 }10413 if (path.length < MAX_PATH_DEPTH) {10414 return this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey(), ...path], interaction, context);10415 }10416 return true;10417 }10418 include(context, includeChildrenRecursively) {10419 if (!this.deoptimized)10420 this.applyDeoptimizations();10421 this.includeProperties(context, includeChildrenRecursively);10422 }10423 includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {10424 if (!this.assignmentDeoptimized)10425 this.applyAssignmentDeoptimization();10426 if (deoptimizeAccess) {10427 this.include(context, includeChildrenRecursively);10428 }10429 else {10430 this.includeProperties(context, includeChildrenRecursively);10431 }10432 }10433 includeCallArguments(context, parameters) {10434 if (this.variable) {10435 this.variable.includeCallArguments(context, parameters);10436 }10437 else {10438 super.includeCallArguments(context, parameters);10439 }10440 }10441 initialise() {10442 super.initialise();10443 this.propertyKey = getResolvablePropertyKey(this);10444 this.accessInteraction = { args: [this.object], type: INTERACTION_ACCESSED };10445 }10446 render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = parseAst_js.BLANK) {10447 if (this.variable || this.isUndefined) {10448 const { snippets: { getPropertyAccess } } = options;10449 let replacement = this.variable ? this.variable.getName(getPropertyAccess) : 'undefined';10450 if (renderedParentType && isCalleeOfRenderedParent)10451 replacement = '0, ' + replacement;10452 code.overwrite(this.start, this.end, replacement, {10453 contentOnly: true,10454 storeName: true10455 });10456 }10457 else {10458 if (renderedParentType && isCalleeOfRenderedParent) {10459 code.appendRight(this.start, '0, ');10460 }10461 this.object.render(code, options, { renderedSurroundingElement });10462 this.property.render(code, options);10463 }10464 }10465 setAssignedValue(value) {10466 this.assignmentInteraction = {10467 args: [this.object, value],10468 type: INTERACTION_ASSIGNED10469 };10470 }10471 applyDeoptimizations() {10472 this.deoptimized = true;10473 const { propertyReadSideEffects } = this.scope.context.options10474 .treeshake;10475 if (10476 // Namespaces are not bound and should not be deoptimized10477 this.bound &&10478 propertyReadSideEffects &&10479 !(this.variable || this.isUndefined)) {10480 const propertyKey = this.getPropertyKey();10481 this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER);10482 this.scope.context.requestTreeshakingPass();10483 }10484 if (this.variable) {10485 this.variable.addUsedPlace(this);10486 this.scope.context.requestTreeshakingPass();10487 }10488 }10489 applyAssignmentDeoptimization() {10490 this.assignmentDeoptimized = true;10491 const { propertyReadSideEffects } = this.scope.context.options10492 .treeshake;10493 if (10494 // Namespaces are not bound and should not be deoptimized10495 this.bound &&10496 propertyReadSideEffects &&10497 !(this.variable || this.isUndefined)) {10498 this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.getPropertyKey()], SHARED_RECURSION_TRACKER);10499 this.scope.context.requestTreeshakingPass();10500 }10501 }10502 disallowNamespaceReassignment() {10503 if (this.object instanceof Identifier) {10504 const variable = this.scope.findVariable(this.object.name);10505 if (variable.isNamespace) {10506 if (this.variable) {10507 this.scope.context.includeVariableInModule(this.variable);10508 }10509 this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);10510 }10511 }10512 }10513 getPropertyKey() {10514 if (this.propertyKey === null) {10515 this.propertyKey = UnknownKey;10516 const value = this.property.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);10517 return (this.propertyKey =10518 value === SymbolToStringTag10519 ? value10520 : typeof value === 'symbol'10521 ? UnknownKey10522 : String(value));10523 }10524 return this.propertyKey;10525 }10526 hasAccessEffect(context) {10527 const { propertyReadSideEffects } = this.scope.context.options10528 .treeshake;10529 return (!(this.variable || this.isUndefined) &&10530 propertyReadSideEffects &&10531 (propertyReadSideEffects === 'always' ||10532 this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));10533 }10534 includeProperties(context, includeChildrenRecursively) {10535 if (!this.included) {10536 this.included = true;10537 if (this.variable) {10538 this.scope.context.includeVariableInModule(this.variable);10539 }10540 }10541 this.object.include(context, includeChildrenRecursively);10542 this.property.include(context, includeChildrenRecursively);10543 }10544 }10545 function resolveNamespaceVariables(baseVariable, path, astContext) {10546 if (path.length === 0)10547 return baseVariable;10548 if (!baseVariable.isNamespace || baseVariable instanceof ExternalVariable)10549 return null;10550 const exportName = path[0].key;10551 const variable = baseVariable.context.traceExport(exportName);10552 if (!variable) {10553 if (path.length === 1) {10554 const fileName = baseVariable.context.fileName;10555 astContext.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logMissingExport(exportName, astContext.module.id, fileName), path[0].pos);10556 return 'undefined';10557 }10558 return null;10559 }10560 return resolveNamespaceVariables(variable, path.slice(1), astContext);10561 }10562 10563 class CallExpressionBase extends NodeBase {10564 constructor() {10565 super(...arguments);10566 this.returnExpression = null;10567 this.deoptimizableDependentExpressions = [];10568 this.expressionsToBeDeoptimized = new Set();10569 }10570 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {10571 const { args } = interaction;10572 const [returnExpression, isPure] = this.getReturnExpression(recursionTracker);10573 if (isPure)10574 return;10575 const deoptimizedExpressions = args.filter(expression => !!expression && expression !== UNKNOWN_EXPRESSION);10576 if (deoptimizedExpressions.length === 0)10577 return;10578 if (returnExpression === UNKNOWN_EXPRESSION) {10579 for (const expression of deoptimizedExpressions) {10580 expression.deoptimizePath(UNKNOWN_PATH);10581 }10582 }10583 else {10584 recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {10585 for (const expression of deoptimizedExpressions) {10586 this.expressionsToBeDeoptimized.add(expression);10587 }10588 returnExpression.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);10589 }, null);10590 }10591 }10592 deoptimizeCache() {10593 if (this.returnExpression?.[0] !== UNKNOWN_EXPRESSION) {10594 this.returnExpression = UNKNOWN_RETURN_EXPRESSION;10595 const { deoptimizableDependentExpressions, expressionsToBeDeoptimized } = this;10596 this.expressionsToBeDeoptimized = parseAst_js.EMPTY_SET;10597 this.deoptimizableDependentExpressions = parseAst_js.EMPTY_ARRAY;10598 for (const expression of deoptimizableDependentExpressions) {10599 expression.deoptimizeCache();10600 }10601 for (const expression of expressionsToBeDeoptimized) {10602 expression.deoptimizePath(UNKNOWN_PATH);10603 }10604 }10605 }10606 deoptimizePath(path) {10607 if (path.length === 0 ||10608 this.scope.context.deoptimizationTracker.trackEntityAtPathAndGetIfTracked(path, this)) {10609 return;10610 }10611 const [returnExpression] = this.getReturnExpression();10612 if (returnExpression !== UNKNOWN_EXPRESSION) {10613 returnExpression.deoptimizePath(path);10614 }10615 }10616 getLiteralValueAtPath(path, recursionTracker, origin) {10617 const [returnExpression] = this.getReturnExpression(recursionTracker);10618 if (returnExpression === UNKNOWN_EXPRESSION) {10619 return UnknownValue;10620 }10621 return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {10622 this.deoptimizableDependentExpressions.push(origin);10623 return returnExpression.getLiteralValueAtPath(path, recursionTracker, origin);10624 }, UnknownValue);10625 }10626 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {10627 const returnExpression = this.getReturnExpression(recursionTracker);10628 if (returnExpression[0] === UNKNOWN_EXPRESSION) {10629 return returnExpression;10630 }10631 return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {10632 this.deoptimizableDependentExpressions.push(origin);10633 const [expression, isPure] = returnExpression[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);10634 return [expression, isPure || returnExpression[1]];10635 }, UNKNOWN_RETURN_EXPRESSION);10636 }10637 hasEffectsOnInteractionAtPath(path, interaction, context) {10638 const { type } = interaction;10639 if (type === INTERACTION_CALLED) {10640 const { args, withNew } = interaction;10641 if ((withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, args, this)) {10642 return false;10643 }10644 }10645 else if ((type === INTERACTION_ASSIGNED10646 ? context.assigned10647 : context.accessed).trackEntityAtPathAndGetIfTracked(path, this)) {10648 return false;10649 }10650 const [returnExpression, isPure] = this.getReturnExpression();10651 return ((type === INTERACTION_ASSIGNED || !isPure) &&10652 returnExpression.hasEffectsOnInteractionAtPath(path, interaction, context));10653 }10654 }10655 10656 class CallExpression extends CallExpressionBase {10657 get optional() {10658 return isFlagSet(this.flags, 128 /* Flag.optional */);10659 }10660 set optional(value) {10661 this.flags = setFlag(this.flags, 128 /* Flag.optional */, value);10662 }10663 bind() {10664 super.bind();10665 if (this.callee instanceof Identifier) {10666 const variable = this.scope.findVariable(this.callee.name);10667 if (variable.isNamespace) {10668 this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logCannotCallNamespace(this.callee.name), this.start);10669 }10670 if (this.callee.name === 'eval') {10671 this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logEval(this.scope.context.module.id), this.start);10672 }10673 }10674 this.interaction = {10675 args: [10676 this.callee instanceof MemberExpression && !this.callee.variable10677 ? this.callee.object10678 : null,10679 ...this.arguments10680 ],10681 type: INTERACTION_CALLED,10682 withNew: false10683 };10684 }10685 getLiteralValueAtPathAsChainElement(path, recursionTracker, origin) {10686 return getChainElementLiteralValueAtPath(this, this.callee, path, recursionTracker, origin);10687 }10688 hasEffects(context) {10689 if (!this.deoptimized)10690 this.applyDeoptimizations();10691 for (const argument of this.arguments) {10692 if (argument.hasEffects(context))10693 return true;10694 }10695 if (this.annotationPure) {10696 return false;10697 }10698 return (this.callee.hasEffects(context) ||10699 this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));10700 }10701 hasEffectsAsChainElement(context) {10702 const calleeHasEffects = 'hasEffectsAsChainElement' in this.callee10703 ? this.callee.hasEffectsAsChainElement(context)10704 : this.callee.hasEffects(context);10705 if (calleeHasEffects === IS_SKIPPED_CHAIN)10706 return IS_SKIPPED_CHAIN;10707 if (this.optional &&10708 this.callee.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) == null) {10709 return (!this.annotationPure && calleeHasEffects) || IS_SKIPPED_CHAIN;10710 }10711 // We only apply deoptimizations lazily once we know we are not skipping10712 if (!this.deoptimized)10713 this.applyDeoptimizations();10714 for (const argument of this.arguments) {10715 if (argument.hasEffects(context))10716 return true;10717 }10718 return (!this.annotationPure &&10719 this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));10720 }10721 include(context, includeChildrenRecursively) {10722 if (!this.deoptimized)10723 this.applyDeoptimizations();10724 if (includeChildrenRecursively) {10725 super.include(context, includeChildrenRecursively);10726 if (includeChildrenRecursively === INCLUDE_PARAMETERS &&10727 this.callee instanceof Identifier &&10728 this.callee.variable) {10729 this.callee.variable.markCalledFromTryStatement();10730 }10731 }10732 else {10733 this.included = true;10734 this.callee.include(context, false);10735 }10736 this.callee.includeCallArguments(context, this.arguments);10737 }10738 initialise() {10739 super.initialise();10740 if (this.annotations &&10741 this.scope.context.options.treeshake.annotations) {10742 this.annotationPure = this.annotations.some(comment => comment.type === 'pure');10743 }10744 }10745 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {10746 this.callee.render(code, options, {10747 isCalleeOfRenderedParent: true,10748 renderedSurroundingElement10749 });10750 renderCallArguments(code, options, this);10751 }10752 applyDeoptimizations() {10753 this.deoptimized = true;10754 this.callee.deoptimizeArgumentsOnInteractionAtPath(this.interaction, EMPTY_PATH, SHARED_RECURSION_TRACKER);10755 this.scope.context.requestTreeshakingPass();10756 }10757 getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) {10758 if (this.returnExpression === null) {10759 this.returnExpression = UNKNOWN_RETURN_EXPRESSION;10760 return (this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this));10761 }10762 return this.returnExpression;10763 }10764 }10765 10766 class CatchClause extends NodeBase {10767 createScope(parentScope) {10768 this.scope = new ParameterScope(parentScope, true);10769 }10770 parseNode(esTreeNode) {10771 const { body, param, type } = esTreeNode;10772 this.type = type;10773 if (param) {10774 this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);10775 this.param.declare('parameter', UNKNOWN_EXPRESSION);10776 }10777 this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);10778 return super.parseNode(esTreeNode);10779 }10780 }10781 CatchClause.prototype.preventChildBlockScope = true;10782 10783 class ChainExpression extends NodeBase {10784 // deoptimizations are not relevant as we are not caching values10785 deoptimizeCache() { }10786 getLiteralValueAtPath(path, recursionTracker, origin) {10787 const literalValue = this.expression.getLiteralValueAtPathAsChainElement(path, recursionTracker, origin);10788 return literalValue === IS_SKIPPED_CHAIN ? undefined : literalValue;10789 }10790 hasEffects(context) {10791 return this.expression.hasEffectsAsChainElement(context) === true;10792 }10793 removeAnnotations(code) {10794 this.expression.removeAnnotations(code);10795 }10796 applyDeoptimizations() { }10797 }10798 10799 class ClassBodyScope extends ChildScope {10800 constructor(parent, classNode) {10801 const { context } = parent;10802 super(parent, context);10803 this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));10804 this.instanceScope = new ChildScope(this, context);10805 this.instanceScope.variables.set('this', new ThisVariable(context));10806 }10807 findLexicalBoundary() {10808 return this;10809 }10810 }10811 10812 class ClassBody extends NodeBase {10813 createScope(parentScope) {10814 this.scope = new ClassBodyScope(parentScope, this.parent);10815 }10816 include(context, includeChildrenRecursively) {10817 this.included = true;10818 this.scope.context.includeVariableInModule(this.scope.thisVariable);10819 for (const definition of this.body) {10820 definition.include(context, includeChildrenRecursively);10821 }10822 }10823 parseNode(esTreeNode) {10824 const body = (this.body = []);10825 for (const definition of esTreeNode.body) {10826 body.push(new (this.scope.context.getNodeConstructor(definition.type))(this, definition.static ? this.scope : this.scope.instanceScope).parseNode(definition));10827 }10828 return super.parseNode(esTreeNode);10829 }10830 applyDeoptimizations() { }10831 }10832 10833 function checkEffectForNodes(nodes, context) {10834 for (const node of nodes) {10835 if (node.hasEffects(context)) {10836 return true;10837 }10838 }10839 return false;10840 }10841 10842 class MethodBase extends NodeBase {10843 constructor() {10844 super(...arguments);10845 this.accessedValue = null;10846 }10847 get computed() {10848 return isFlagSet(this.flags, 1024 /* Flag.computed */);10849 }10850 set computed(value) {10851 this.flags = setFlag(this.flags, 1024 /* Flag.computed */, value);10852 }10853 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {10854 if (interaction.type === INTERACTION_ACCESSED && this.kind === 'get' && path.length === 0) {10855 return this.value.deoptimizeArgumentsOnInteractionAtPath({10856 args: interaction.args,10857 type: INTERACTION_CALLED,10858 withNew: false10859 }, EMPTY_PATH, recursionTracker);10860 }10861 if (interaction.type === INTERACTION_ASSIGNED && this.kind === 'set' && path.length === 0) {10862 return this.value.deoptimizeArgumentsOnInteractionAtPath({10863 args: interaction.args,10864 type: INTERACTION_CALLED,10865 withNew: false10866 }, EMPTY_PATH, recursionTracker);10867 }10868 this.getAccessedValue()[0].deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);10869 }10870 // As getter properties directly receive their values from fixed function10871 // expressions, there is no known situation where a getter is deoptimized.10872 deoptimizeCache() { }10873 deoptimizePath(path) {10874 this.getAccessedValue()[0].deoptimizePath(path);10875 }10876 getLiteralValueAtPath(path, recursionTracker, origin) {10877 return this.getAccessedValue()[0].getLiteralValueAtPath(path, recursionTracker, origin);10878 }10879 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {10880 return this.getAccessedValue()[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);10881 }10882 hasEffects(context) {10883 return this.key.hasEffects(context);10884 }10885 hasEffectsOnInteractionAtPath(path, interaction, context) {10886 if (this.kind === 'get' && interaction.type === INTERACTION_ACCESSED && path.length === 0) {10887 return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, {10888 args: interaction.args,10889 type: INTERACTION_CALLED,10890 withNew: false10891 }, context);10892 }10893 // setters are only called for empty paths10894 if (this.kind === 'set' && interaction.type === INTERACTION_ASSIGNED) {10895 return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, {10896 args: interaction.args,10897 type: INTERACTION_CALLED,10898 withNew: false10899 }, context);10900 }10901 return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context);10902 }10903 applyDeoptimizations() { }10904 getAccessedValue() {10905 if (this.accessedValue === null) {10906 if (this.kind === 'get') {10907 this.accessedValue = UNKNOWN_RETURN_EXPRESSION;10908 return (this.accessedValue = this.value.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, SHARED_RECURSION_TRACKER, this));10909 }10910 else {10911 return (this.accessedValue = [this.value, false]);10912 }10913 }10914 return this.accessedValue;10915 }10916 }10917 10918 class MethodDefinition extends MethodBase {10919 hasEffects(context) {10920 return super.hasEffects(context) || checkEffectForNodes(this.decorators, context);10921 }10922 applyDeoptimizations() { }10923 }10924 10925 class StaticBlock extends NodeBase {10926 createScope(parentScope) {10927 this.scope = new BlockScope(parentScope);10928 }10929 hasEffects(context) {10930 for (const node of this.body) {10931 if (node.hasEffects(context))10932 return true;10933 }10934 return false;10935 }10936 include(context, includeChildrenRecursively) {10937 this.included = true;10938 for (const node of this.body) {10939 if (includeChildrenRecursively || node.shouldBeIncluded(context))10940 node.include(context, includeChildrenRecursively);10941 }10942 }10943 render(code, options) {10944 if (this.body.length > 0) {10945 const bodyStartPos = findFirstOccurrenceOutsideComment(code.original.slice(this.start, this.end), '{') + 1;10946 renderStatementList(this.body, code, this.start + bodyStartPos, this.end - 1, options);10947 }10948 else {10949 super.render(code, options);10950 }10951 }10952 }10953 function isStaticBlock(statement) {10954 return statement.type === parseAst_js.StaticBlock;10955 }10956 10957 class ObjectMember extends ExpressionEntity {10958 constructor(object, key) {10959 super();10960 this.object = object;10961 this.key = key;10962 }10963 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {10964 this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker);10965 }10966 deoptimizePath(path) {10967 this.object.deoptimizePath([this.key, ...path]);10968 }10969 getLiteralValueAtPath(path, recursionTracker, origin) {10970 return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin);10971 }10972 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {10973 return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin);10974 }10975 hasEffectsOnInteractionAtPath(path, interaction, context) {10976 return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context);10977 }10978 }10979 10980 class ClassNode extends NodeBase {10981 constructor() {10982 super(...arguments);10983 this.objectEntity = null;10984 }10985 createScope(parentScope) {10986 this.scope = new ChildScope(parentScope, parentScope.context);10987 }10988 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {10989 this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);10990 }10991 deoptimizeCache() {10992 this.getObjectEntity().deoptimizeAllProperties();10993 }10994 deoptimizePath(path) {10995 this.getObjectEntity().deoptimizePath(path);10996 }10997 getLiteralValueAtPath(path, recursionTracker, origin) {10998 return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);10999 }11000 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {11001 return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);11002 }11003 hasEffects(context) {11004 if (!this.deoptimized)11005 this.applyDeoptimizations();11006 const initEffect = this.superClass?.hasEffects(context) || this.body.hasEffects(context);11007 this.id?.markDeclarationReached();11008 return initEffect || super.hasEffects(context) || checkEffectForNodes(this.decorators, context);11009 }11010 hasEffectsOnInteractionAtPath(path, interaction, context) {11011 return interaction.type === INTERACTION_CALLED && path.length === 011012 ? !interaction.withNew ||11013 (this.classConstructor === null11014 ? this.superClass?.hasEffectsOnInteractionAtPath(path, interaction, context)11015 : this.classConstructor.hasEffectsOnInteractionAtPath(path, interaction, context)) ||11016 false11017 : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);11018 }11019 include(context, includeChildrenRecursively) {11020 if (!this.deoptimized)11021 this.applyDeoptimizations();11022 this.included = true;11023 this.superClass?.include(context, includeChildrenRecursively);11024 this.body.include(context, includeChildrenRecursively);11025 for (const decorator of this.decorators)11026 decorator.include(context, includeChildrenRecursively);11027 if (this.id) {11028 this.id.markDeclarationReached();11029 this.id.include();11030 }11031 }11032 initialise() {11033 super.initialise();11034 this.id?.declare('class', this);11035 for (const method of this.body.body) {11036 if (method instanceof MethodDefinition && method.kind === 'constructor') {11037 this.classConstructor = method;11038 return;11039 }11040 }11041 this.classConstructor = null;11042 }11043 applyDeoptimizations() {11044 this.deoptimized = true;11045 for (const definition of this.body.body) {11046 if (!isStaticBlock(definition) &&11047 !(definition.static ||11048 (definition instanceof MethodDefinition && definition.kind === 'constructor'))) {11049 // Calls to methods are not tracked, ensure that the return value is deoptimized11050 definition.deoptimizePath(UNKNOWN_PATH);11051 }11052 }11053 this.scope.context.requestTreeshakingPass();11054 }11055 getObjectEntity() {11056 if (this.objectEntity !== null) {11057 return this.objectEntity;11058 }11059 const staticProperties = [];11060 const dynamicMethods = [];11061 for (const definition of this.body.body) {11062 if (isStaticBlock(definition))11063 continue;11064 const properties = definition.static ? staticProperties : dynamicMethods;11065 const definitionKind = definition.kind;11066 // Note that class fields do not end up on the prototype11067 if (properties === dynamicMethods && !definitionKind)11068 continue;11069 const kind = definitionKind === 'set' || definitionKind === 'get' ? definitionKind : 'init';11070 let key;11071 if (definition.computed) {11072 const keyValue = definition.key.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);11073 if (typeof keyValue === 'symbol') {11074 properties.push({ key: UnknownKey, kind, property: definition });11075 continue;11076 }11077 else {11078 key = String(keyValue);11079 }11080 }11081 else {11082 key =11083 definition.key instanceof Identifier11084 ? definition.key.name11085 : String(definition.key.value);11086 }11087 properties.push({ key, kind, property: definition });11088 }11089 staticProperties.unshift({11090 key: 'prototype',11091 kind: 'init',11092 property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE)11093 });11094 return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE));11095 }11096 }11097 11098 class ClassDeclaration extends ClassNode {11099 initialise() {11100 super.initialise();11101 if (this.id !== null) {11102 this.id.variable.isId = true;11103 }11104 }11105 parseNode(esTreeNode) {11106 if (esTreeNode.id !== null) {11107 this.id = new Identifier(this, this.scope.parent).parseNode(esTreeNode.id);11108 }11109 return super.parseNode(esTreeNode);11110 }11111 render(code, options) {11112 const { exportNamesByVariable, format, snippets: { _, getPropertyAccess } } = options;11113 if (this.id) {11114 const { variable, name } = this.id;11115 if (format === 'system' && exportNamesByVariable.has(variable)) {11116 code.appendLeft(this.end, `${_}${getSystemExportStatement([variable], options)};`);11117 }11118 const renderedVariable = variable.getName(getPropertyAccess);11119 if (renderedVariable !== name) {11120 this.decorators.map(decorator => decorator.render(code, options));11121 this.superClass?.render(code, options);11122 this.body.render(code, {11123 ...options,11124 useOriginalName: (_variable) => _variable === variable11125 });11126 code.prependRight(this.start, `let ${renderedVariable}${_}=${_}`);11127 code.prependLeft(this.end, ';');11128 return;11129 }11130 }11131 super.render(code, options);11132 }11133 applyDeoptimizations() {11134 super.applyDeoptimizations();11135 const { id, scope } = this;11136 if (id) {11137 const { name, variable } = id;11138 for (const accessedVariable of scope.accessedOutsideVariables.values()) {11139 if (accessedVariable !== variable) {11140 accessedVariable.forbidName(name);11141 }11142 }11143 }11144 }11145 }11146 11147 class ClassExpression extends ClassNode {11148 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {11149 super.render(code, options);11150 if (renderedSurroundingElement === parseAst_js.ExpressionStatement) {11151 code.appendRight(this.start, '(');11152 code.prependLeft(this.end, ')');11153 }11154 }11155 }11156 11157 class MultiExpression extends ExpressionEntity {11158 constructor(expressions) {11159 super();11160 this.expressions = expressions;11161 }11162 deoptimizePath(path) {11163 for (const expression of this.expressions) {11164 expression.deoptimizePath(path);11165 }11166 }11167 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {11168 return [11169 new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0])),11170 false11171 ];11172 }11173 hasEffectsOnInteractionAtPath(path, interaction, context) {11174 for (const expression of this.expressions) {11175 if (expression.hasEffectsOnInteractionAtPath(path, interaction, context))11176 return true;11177 }11178 return false;11179 }11180 }11181 11182 class ConditionalExpression extends NodeBase {11183 constructor() {11184 super(...arguments);11185 this.expressionsToBeDeoptimized = [];11186 this.usedBranch = null;11187 }11188 get isBranchResolutionAnalysed() {11189 return isFlagSet(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */);11190 }11191 set isBranchResolutionAnalysed(value) {11192 this.flags = setFlag(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */, value);11193 }11194 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {11195 this.consequent.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);11196 this.alternate.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);11197 }11198 deoptimizeCache() {11199 if (this.usedBranch !== null) {11200 const unusedBranch = this.usedBranch === this.consequent ? this.alternate : this.consequent;11201 this.usedBranch = null;11202 unusedBranch.deoptimizePath(UNKNOWN_PATH);11203 const { expressionsToBeDeoptimized } = this;11204 this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;11205 for (const expression of expressionsToBeDeoptimized) {11206 expression.deoptimizeCache();11207 }11208 }11209 }11210 deoptimizePath(path) {11211 const usedBranch = this.getUsedBranch();11212 if (usedBranch) {11213 usedBranch.deoptimizePath(path);11214 }11215 else {11216 this.consequent.deoptimizePath(path);11217 this.alternate.deoptimizePath(path);11218 }11219 }11220 getLiteralValueAtPath(path, recursionTracker, origin) {11221 const usedBranch = this.getUsedBranch();11222 if (!usedBranch)11223 return UnknownValue;11224 this.expressionsToBeDeoptimized.push(origin);11225 return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin);11226 }11227 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {11228 const usedBranch = this.getUsedBranch();11229 if (!usedBranch)11230 return [11231 new MultiExpression([11232 this.consequent.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],11233 this.alternate.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]11234 ]),11235 false11236 ];11237 this.expressionsToBeDeoptimized.push(origin);11238 return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);11239 }11240 hasEffects(context) {11241 if (this.test.hasEffects(context))11242 return true;11243 const usedBranch = this.getUsedBranch();11244 if (!usedBranch) {11245 return this.consequent.hasEffects(context) || this.alternate.hasEffects(context);11246 }11247 return usedBranch.hasEffects(context);11248 }11249 hasEffectsOnInteractionAtPath(path, interaction, context) {11250 const usedBranch = this.getUsedBranch();11251 if (!usedBranch) {11252 return (this.consequent.hasEffectsOnInteractionAtPath(path, interaction, context) ||11253 this.alternate.hasEffectsOnInteractionAtPath(path, interaction, context));11254 }11255 return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);11256 }11257 include(context, includeChildrenRecursively) {11258 this.included = true;11259 const usedBranch = this.getUsedBranch();11260 if (includeChildrenRecursively || this.test.shouldBeIncluded(context) || usedBranch === null) {11261 this.test.include(context, includeChildrenRecursively);11262 this.consequent.include(context, includeChildrenRecursively);11263 this.alternate.include(context, includeChildrenRecursively);11264 }11265 else {11266 usedBranch.include(context, includeChildrenRecursively);11267 }11268 }11269 includeCallArguments(context, parameters) {11270 const usedBranch = this.getUsedBranch();11271 if (usedBranch) {11272 usedBranch.includeCallArguments(context, parameters);11273 }11274 else {11275 this.consequent.includeCallArguments(context, parameters);11276 this.alternate.includeCallArguments(context, parameters);11277 }11278 }11279 removeAnnotations(code) {11280 this.test.removeAnnotations(code);11281 }11282 render(code, options, { isCalleeOfRenderedParent, preventASI, renderedParentType, renderedSurroundingElement } = parseAst_js.BLANK) {11283 const usedBranch = this.getUsedBranch();11284 if (this.test.included) {11285 this.test.render(code, options, { renderedSurroundingElement });11286 this.consequent.render(code, options);11287 this.alternate.render(code, options);11288 }11289 else {11290 const colonPos = findFirstOccurrenceOutsideComment(code.original, ':', this.consequent.end);11291 const inclusionStart = findNonWhiteSpace(code.original, (this.consequent.included11292 ? findFirstOccurrenceOutsideComment(code.original, '?', this.test.end)11293 : colonPos) + 1);11294 if (preventASI) {11295 removeLineBreaks(code, inclusionStart, usedBranch.start);11296 }11297 code.remove(this.start, inclusionStart);11298 if (this.consequent.included) {11299 code.remove(colonPos, this.end);11300 }11301 this.test.removeAnnotations(code);11302 usedBranch.render(code, options, {11303 isCalleeOfRenderedParent,11304 preventASI: true,11305 renderedParentType: renderedParentType || this.parent.type,11306 renderedSurroundingElement: renderedSurroundingElement || this.parent.type11307 });11308 }11309 }11310 getUsedBranch() {11311 if (this.isBranchResolutionAnalysed) {11312 return this.usedBranch;11313 }11314 this.isBranchResolutionAnalysed = true;11315 const testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);11316 return typeof testValue === 'symbol'11317 ? null11318 : (this.usedBranch = testValue ? this.consequent : this.alternate);11319 }11320 }11321 11322 class ContinueStatement extends NodeBase {11323 hasEffects(context) {11324 if (this.label) {11325 if (!context.ignore.labels.has(this.label.name))11326 return true;11327 context.includedLabels.add(this.label.name);11328 }11329 else {11330 if (!context.ignore.continues)11331 return true;11332 context.hasContinue = true;11333 }11334 context.brokenFlow = true;11335 return false;11336 }11337 include(context) {11338 this.included = true;11339 if (this.label) {11340 this.label.include();11341 context.includedLabels.add(this.label.name);11342 }11343 else {11344 context.hasContinue = true;11345 }11346 context.brokenFlow = true;11347 }11348 }11349 11350 class DebuggerStatement extends NodeBase {11351 hasEffects() {11352 return true;11353 }11354 }11355 11356 class Decorator extends NodeBase {11357 hasEffects(context) {11358 return (this.expression.hasEffects(context) ||11359 this.expression.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context));11360 }11361 }11362 11363 function hasLoopBodyEffects(context, body) {11364 const { brokenFlow, hasBreak, hasContinue, ignore } = context;11365 const { breaks, continues } = ignore;11366 ignore.breaks = true;11367 ignore.continues = true;11368 context.hasBreak = false;11369 context.hasContinue = false;11370 if (body.hasEffects(context))11371 return true;11372 ignore.breaks = breaks;11373 ignore.continues = continues;11374 context.hasBreak = hasBreak;11375 context.hasContinue = hasContinue;11376 context.brokenFlow = brokenFlow;11377 return false;11378 }11379 function includeLoopBody(context, body, includeChildrenRecursively) {11380 const { brokenFlow, hasBreak, hasContinue } = context;11381 context.hasBreak = false;11382 context.hasContinue = false;11383 body.include(context, includeChildrenRecursively, { asSingleStatement: true });11384 context.hasBreak = hasBreak;11385 context.hasContinue = hasContinue;11386 context.brokenFlow = brokenFlow;11387 }11388 11389 class DoWhileStatement extends NodeBase {11390 hasEffects(context) {11391 if (this.test.hasEffects(context))11392 return true;11393 return hasLoopBodyEffects(context, this.body);11394 }11395 include(context, includeChildrenRecursively) {11396 this.included = true;11397 this.test.include(context, includeChildrenRecursively);11398 includeLoopBody(context, this.body, includeChildrenRecursively);11399 }11400 }11401 11402 class EmptyStatement extends NodeBase {11403 hasEffects() {11404 return false;11405 }11406 }11407 11408 class ExportAllDeclaration extends NodeBase {11409 hasEffects() {11410 return false;11411 }11412 initialise() {11413 super.initialise();11414 this.scope.context.addExport(this);11415 }11416 render(code, _options, nodeRenderOptions) {11417 code.remove(nodeRenderOptions.start, nodeRenderOptions.end);11418 }11419 applyDeoptimizations() { }11420 }11421 ExportAllDeclaration.prototype.needsBoundaries = true;11422 11423 7996 class FunctionDeclaration extends FunctionNode { 11424 7997 initialise() { … … 11536 8109 ExportDefaultDeclaration.prototype.needsBoundaries = true; 11537 8110 11538 class ExportNamedDeclaration extends NodeBase { 11539 bind() { 11540 // Do not bind specifiers 11541 this.declaration?.bind(); 11542 } 11543 hasEffects(context) { 11544 return !!this.declaration?.hasEffects(context); 11545 } 11546 initialise() { 11547 super.initialise(); 11548 this.scope.context.addExport(this); 11549 } 11550 removeAnnotations(code) { 11551 this.declaration?.removeAnnotations(code); 11552 } 11553 render(code, options, nodeRenderOptions) { 11554 const { start, end } = nodeRenderOptions; 11555 if (this.declaration === null) { 11556 code.remove(start, end); 11557 } 11558 else { 11559 code.remove(this.start, this.declaration.start); 11560 this.declaration.render(code, options, { end, start }); 11561 } 11562 } 11563 applyDeoptimizations() { } 11564 } 11565 ExportNamedDeclaration.prototype.needsBoundaries = true; 11566 11567 class ExportSpecifier extends NodeBase { 11568 applyDeoptimizations() { } 11569 } 11570 11571 class ForInStatement extends NodeBase { 11572 createScope(parentScope) { 11573 this.scope = new BlockScope(parentScope); 11574 } 11575 hasEffects(context) { 11576 const { body, deoptimized, left, right } = this; 11577 if (!deoptimized) 11578 this.applyDeoptimizations(); 11579 if (left.hasEffectsAsAssignmentTarget(context, false) || right.hasEffects(context)) 11580 return true; 11581 return hasLoopBodyEffects(context, body); 11582 } 11583 include(context, includeChildrenRecursively) { 11584 const { body, deoptimized, left, right } = this; 11585 if (!deoptimized) 11586 this.applyDeoptimizations(); 11587 this.included = true; 11588 left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false); 11589 right.include(context, includeChildrenRecursively); 11590 includeLoopBody(context, body, includeChildrenRecursively); 11591 } 11592 initialise() { 11593 super.initialise(); 11594 this.left.setAssignedValue(UNKNOWN_EXPRESSION); 11595 } 11596 render(code, options) { 11597 this.left.render(code, options, NO_SEMICOLON); 11598 this.right.render(code, options, NO_SEMICOLON); 11599 // handle no space between "in" and the right side 11600 if (code.original.charCodeAt(this.right.start - 1) === 110 /* n */) { 11601 code.prependLeft(this.right.start, ' '); 11602 } 11603 this.body.render(code, options); 11604 } 11605 applyDeoptimizations() { 11606 this.deoptimized = true; 11607 this.left.deoptimizePath(EMPTY_PATH); 11608 this.scope.context.requestTreeshakingPass(); 11609 } 11610 } 11611 11612 class ForOfStatement extends NodeBase { 11613 get await() { 11614 return isFlagSet(this.flags, 131072 /* Flag.await */); 11615 } 11616 set await(value) { 11617 this.flags = setFlag(this.flags, 131072 /* Flag.await */, value); 11618 } 11619 createScope(parentScope) { 11620 this.scope = new BlockScope(parentScope); 11621 } 11622 hasEffects() { 11623 if (!this.deoptimized) 11624 this.applyDeoptimizations(); 11625 // Placeholder until proper Symbol.Iterator support 11626 return true; 11627 } 11628 include(context, includeChildrenRecursively) { 11629 const { body, deoptimized, left, right } = this; 11630 if (!deoptimized) 11631 this.applyDeoptimizations(); 11632 this.included = true; 11633 left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false); 11634 right.include(context, includeChildrenRecursively); 11635 includeLoopBody(context, body, includeChildrenRecursively); 11636 } 11637 initialise() { 11638 super.initialise(); 11639 this.left.setAssignedValue(UNKNOWN_EXPRESSION); 11640 } 11641 render(code, options) { 11642 this.left.render(code, options, NO_SEMICOLON); 11643 this.right.render(code, options, NO_SEMICOLON); 11644 // handle no space between "of" and the right side 11645 if (code.original.charCodeAt(this.right.start - 1) === 102 /* f */) { 11646 code.prependLeft(this.right.start, ' '); 11647 } 11648 this.body.render(code, options); 11649 } 11650 applyDeoptimizations() { 11651 this.deoptimized = true; 11652 this.left.deoptimizePath(EMPTY_PATH); 11653 this.right.deoptimizePath(UNKNOWN_PATH); 11654 this.scope.context.requestTreeshakingPass(); 11655 } 11656 } 11657 11658 class ForStatement extends NodeBase { 11659 createScope(parentScope) { 11660 this.scope = new BlockScope(parentScope); 11661 } 11662 hasEffects(context) { 11663 if (this.init?.hasEffects(context) || 11664 this.test?.hasEffects(context) || 11665 this.update?.hasEffects(context)) { 11666 return true; 11667 } 11668 return hasLoopBodyEffects(context, this.body); 11669 } 11670 include(context, includeChildrenRecursively) { 11671 this.included = true; 11672 this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true }); 11673 this.test?.include(context, includeChildrenRecursively); 11674 this.update?.include(context, includeChildrenRecursively); 11675 includeLoopBody(context, this.body, includeChildrenRecursively); 11676 } 11677 render(code, options) { 11678 this.init?.render(code, options, NO_SEMICOLON); 11679 this.test?.render(code, options, NO_SEMICOLON); 11680 this.update?.render(code, options, NO_SEMICOLON); 11681 this.body.render(code, options); 11682 } 11683 } 11684 11685 class FunctionExpression extends FunctionNode { 11686 createScope(parentScope) { 11687 super.createScope((this.idScope = new ChildScope(parentScope, parentScope.context))); 11688 } 11689 parseNode(esTreeNode) { 11690 if (esTreeNode.id !== null) { 11691 this.id = new Identifier(this, this.idScope).parseNode(esTreeNode.id); 11692 } 11693 return super.parseNode(esTreeNode); 11694 } 11695 onlyFunctionCallUsed() { 11696 const isIIFE = this.parent.type === parseAst_js.CallExpression && 11697 this.parent.callee === this && 11698 (this.id === null || this.id.variable.getOnlyFunctionCallUsed()); 11699 return isIIFE || super.onlyFunctionCallUsed(); 11700 } 11701 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) { 11702 super.render(code, options); 11703 if (renderedSurroundingElement === parseAst_js.ExpressionStatement) { 11704 code.appendRight(this.start, '('); 11705 code.prependLeft(this.end, ')'); 11706 } 11707 } 11708 } 11709 11710 class TrackingScope extends BlockScope { 11711 constructor() { 11712 super(...arguments); 11713 this.hoistedDeclarations = []; 11714 } 11715 addDeclaration(identifier, context, init, kind) { 11716 this.hoistedDeclarations.push(identifier); 11717 return super.addDeclaration(identifier, context, init, kind); 11718 } 11719 } 11720 11721 const unset = Symbol('unset'); 11722 class IfStatement extends NodeBase { 11723 constructor() { 11724 super(...arguments); 11725 this.testValue = unset; 11726 } 11727 deoptimizeCache() { 11728 this.testValue = UnknownValue; 11729 } 11730 hasEffects(context) { 11731 if (this.test.hasEffects(context)) { 11732 return true; 11733 } 11734 const testValue = this.getTestValue(); 11735 if (typeof testValue === 'symbol') { 11736 const { brokenFlow } = context; 11737 if (this.consequent.hasEffects(context)) 11738 return true; 11739 const consequentBrokenFlow = context.brokenFlow; 11740 context.brokenFlow = brokenFlow; 11741 if (this.alternate === null) 11742 return false; 11743 if (this.alternate.hasEffects(context)) 11744 return true; 11745 context.brokenFlow = context.brokenFlow && consequentBrokenFlow; 11746 return false; 11747 } 11748 return testValue ? this.consequent.hasEffects(context) : !!this.alternate?.hasEffects(context); 11749 } 11750 include(context, includeChildrenRecursively) { 11751 this.included = true; 11752 if (includeChildrenRecursively) { 11753 this.includeRecursively(includeChildrenRecursively, context); 11754 } 11755 else { 11756 const testValue = this.getTestValue(); 11757 if (typeof testValue === 'symbol') { 11758 this.includeUnknownTest(context); 11759 } 11760 else { 11761 this.includeKnownTest(context, testValue); 11762 } 11763 } 11764 } 11765 parseNode(esTreeNode) { 11766 this.consequent = new (this.scope.context.getNodeConstructor(esTreeNode.consequent.type))(this, (this.consequentScope = new TrackingScope(this.scope))).parseNode(esTreeNode.consequent); 11767 if (esTreeNode.alternate) { 11768 this.alternate = new (this.scope.context.getNodeConstructor(esTreeNode.alternate.type))(this, (this.alternateScope = new TrackingScope(this.scope))).parseNode(esTreeNode.alternate); 11769 } 11770 return super.parseNode(esTreeNode); 11771 } 11772 render(code, options) { 11773 const { snippets: { getPropertyAccess } } = options; 11774 // Note that unknown test values are always included 11775 const testValue = this.getTestValue(); 11776 const hoistedDeclarations = []; 11777 const includesIfElse = this.test.included; 11778 const noTreeshake = !this.scope.context.options.treeshake; 11779 if (includesIfElse) { 11780 this.test.render(code, options); 11781 } 11782 else { 11783 code.remove(this.start, this.consequent.start); 11784 } 11785 if (this.consequent.included && (noTreeshake || typeof testValue === 'symbol' || testValue)) { 11786 this.consequent.render(code, options); 11787 } 11788 else { 11789 code.overwrite(this.consequent.start, this.consequent.end, includesIfElse ? ';' : ''); 11790 hoistedDeclarations.push(...this.consequentScope.hoistedDeclarations); 11791 } 11792 if (this.alternate) { 11793 if (this.alternate.included && (noTreeshake || typeof testValue === 'symbol' || !testValue)) { 11794 if (includesIfElse) { 11795 if (code.original.charCodeAt(this.alternate.start - 1) === 101) { 11796 code.prependLeft(this.alternate.start, ' '); 11797 } 11798 } 11799 else { 11800 code.remove(this.consequent.end, this.alternate.start); 11801 } 11802 this.alternate.render(code, options); 11803 } 11804 else { 11805 if (includesIfElse && this.shouldKeepAlternateBranch()) { 11806 code.overwrite(this.alternate.start, this.end, ';'); 11807 } 11808 else { 11809 code.remove(this.consequent.end, this.end); 11810 } 11811 hoistedDeclarations.push(...this.alternateScope.hoistedDeclarations); 11812 } 11813 } 11814 this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess); 11815 } 11816 applyDeoptimizations() { } 11817 getTestValue() { 11818 if (this.testValue === unset) { 11819 return (this.testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)); 11820 } 11821 return this.testValue; 11822 } 11823 includeKnownTest(context, testValue) { 11824 if (this.test.shouldBeIncluded(context)) { 11825 this.test.include(context, false); 11826 } 11827 if (testValue && this.consequent.shouldBeIncluded(context)) { 11828 this.consequent.include(context, false, { asSingleStatement: true }); 11829 } 11830 if (!testValue && this.alternate?.shouldBeIncluded(context)) { 11831 this.alternate.include(context, false, { asSingleStatement: true }); 11832 } 11833 } 11834 includeRecursively(includeChildrenRecursively, context) { 11835 this.test.include(context, includeChildrenRecursively); 11836 this.consequent.include(context, includeChildrenRecursively); 11837 this.alternate?.include(context, includeChildrenRecursively); 11838 } 11839 includeUnknownTest(context) { 11840 this.test.include(context, false); 11841 const { brokenFlow } = context; 11842 let consequentBrokenFlow = false; 11843 if (this.consequent.shouldBeIncluded(context)) { 11844 this.consequent.include(context, false, { asSingleStatement: true }); 11845 consequentBrokenFlow = context.brokenFlow; 11846 context.brokenFlow = brokenFlow; 11847 } 11848 if (this.alternate?.shouldBeIncluded(context)) { 11849 this.alternate.include(context, false, { asSingleStatement: true }); 11850 context.brokenFlow = context.brokenFlow && consequentBrokenFlow; 11851 } 11852 } 11853 renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess) { 11854 const hoistedVariables = [ 11855 ...new Set(hoistedDeclarations.map(identifier => { 11856 const variable = identifier.variable; 11857 return variable.included ? variable.getName(getPropertyAccess) : ''; 11858 })) 11859 ] 11860 .filter(Boolean) 11861 .join(', '); 11862 if (hoistedVariables) { 11863 const parentType = this.parent.type; 11864 const needsBraces = parentType !== parseAst_js.Program && parentType !== parseAst_js.BlockStatement; 11865 code.prependRight(this.start, `${needsBraces ? '{ ' : ''}var ${hoistedVariables}; `); 11866 if (needsBraces) { 11867 code.appendLeft(this.end, ` }`); 11868 } 11869 } 11870 } 11871 shouldKeepAlternateBranch() { 11872 let currentParent = this.parent; 11873 do { 11874 if (currentParent instanceof IfStatement && currentParent.alternate) { 11875 return true; 11876 } 11877 if (currentParent instanceof BlockStatement) { 11878 return false; 11879 } 11880 currentParent = currentParent.parent; 11881 } while (currentParent); 11882 return false; 11883 } 11884 } 11885 11886 class ImportAttribute extends NodeBase { 11887 } 11888 11889 class ImportDeclaration extends NodeBase { 11890 // Do not bind specifiers or attributes 11891 bind() { } 11892 hasEffects() { 11893 return false; 11894 } 11895 initialise() { 11896 super.initialise(); 11897 this.scope.context.addImport(this); 11898 } 11899 render(code, _options, nodeRenderOptions) { 11900 code.remove(nodeRenderOptions.start, nodeRenderOptions.end); 11901 } 11902 applyDeoptimizations() { } 11903 } 11904 ImportDeclaration.prototype.needsBoundaries = true; 11905 11906 class ImportDefaultSpecifier extends NodeBase { 11907 applyDeoptimizations() { } 8111 const needsEscapeRegEx = /[\n\r'\\\u2028\u2029]/; 8112 const quoteNewlineRegEx = /([\n\r'\u2028\u2029])/g; 8113 const backSlashRegEx = /\\/g; 8114 function escapeId(id) { 8115 if (!needsEscapeRegEx.test(id)) 8116 return id; 8117 return id.replace(backSlashRegEx, '\\\\').replace(quoteNewlineRegEx, '\\$1'); 11908 8118 } 11909 8119 … … 11946 8156 const HELPER_GENERATORS = { 11947 8157 [DOCUMENT_CURRENT_SCRIPT](_t, { _, n }) { 11948 return `var ${_}${DOCUMENT_CURRENT_SCRIPT}${_}=${_}typeof${_}document${_}!==${_}'undefined'${_}?${_}document.currentScript${_}:${_}null;${n}`;8158 return `var ${DOCUMENT_CURRENT_SCRIPT}${_}=${_}typeof document${_}!==${_}'undefined'${_}?${_}document.currentScript${_}:${_}null;${n}`; 11949 8159 }, 11950 8160 [INTEROP_DEFAULT_COMPAT_VARIABLE](_t, snippets, liveBindings) { … … 12115 8325 } 12116 8326 8327 class Literal extends NodeBase { 8328 deoptimizeArgumentsOnInteractionAtPath() { } 8329 getLiteralValueAtPath(path) { 8330 if (path.length > 0 || 8331 // unknown literals can also be null but do not start with an "n" 8332 (this.value === null && this.scope.context.code.charCodeAt(this.start) !== 110) || 8333 typeof this.value === 'bigint' || 8334 // to support shims for regular expressions 8335 this.scope.context.code.charCodeAt(this.start) === 47) { 8336 return UnknownValue; 8337 } 8338 return this.value; 8339 } 8340 getReturnExpressionWhenCalledAtPath(path) { 8341 if (path.length !== 1) 8342 return UNKNOWN_RETURN_EXPRESSION; 8343 return getMemberReturnExpressionWhenCalled(this.members, path[0]); 8344 } 8345 hasEffectsOnInteractionAtPath(path, interaction, context) { 8346 switch (interaction.type) { 8347 case INTERACTION_ACCESSED: { 8348 return path.length > (this.value === null ? 0 : 1); 8349 } 8350 case INTERACTION_ASSIGNED: { 8351 return true; 8352 } 8353 case INTERACTION_CALLED: { 8354 if (this.included && 8355 this.value instanceof RegExp && 8356 (this.value.global || this.value.sticky)) { 8357 return true; 8358 } 8359 return (path.length !== 1 || 8360 hasMemberEffectWhenCalled(this.members, path[0], interaction, context)); 8361 } 8362 } 8363 } 8364 initialise() { 8365 super.initialise(); 8366 this.members = getLiteralMembersForValue(this.value); 8367 } 8368 parseNode(esTreeNode) { 8369 this.value = esTreeNode.value; 8370 this.regex = esTreeNode.regex; 8371 return super.parseNode(esTreeNode); 8372 } 8373 render(code) { 8374 if (typeof this.value === 'string') { 8375 code.indentExclusionRanges.push([this.start + 1, this.end - 1]); 8376 } 8377 } 8378 } 8379 8380 function getChainElementLiteralValueAtPath(element, object, path, recursionTracker, origin) { 8381 if ('getLiteralValueAtPathAsChainElement' in object) { 8382 const calleeValue = object.getLiteralValueAtPathAsChainElement(EMPTY_PATH, SHARED_RECURSION_TRACKER, origin); 8383 if (calleeValue === IS_SKIPPED_CHAIN || (element.optional && calleeValue == null)) { 8384 return IS_SKIPPED_CHAIN; 8385 } 8386 } 8387 else if (element.optional && 8388 object.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, origin) == null) { 8389 return IS_SKIPPED_CHAIN; 8390 } 8391 return element.getLiteralValueAtPath(path, recursionTracker, origin); 8392 } 8393 8394 // To avoid infinite recursions 8395 const MAX_PATH_DEPTH = 7; 8396 function getResolvablePropertyKey(memberExpression) { 8397 return memberExpression.computed 8398 ? getResolvableComputedPropertyKey(memberExpression.property) 8399 : memberExpression.property.name; 8400 } 8401 function getResolvableComputedPropertyKey(propertyKey) { 8402 if (propertyKey instanceof Literal) { 8403 return String(propertyKey.value); 8404 } 8405 return null; 8406 } 8407 function getPathIfNotComputed(memberExpression) { 8408 const nextPathKey = memberExpression.propertyKey; 8409 const object = memberExpression.object; 8410 if (typeof nextPathKey === 'string') { 8411 if (object instanceof Identifier) { 8412 return [ 8413 { key: object.name, pos: object.start }, 8414 { key: nextPathKey, pos: memberExpression.property.start } 8415 ]; 8416 } 8417 if (object instanceof MemberExpression) { 8418 const parentPath = getPathIfNotComputed(object); 8419 return (parentPath && [...parentPath, { key: nextPathKey, pos: memberExpression.property.start }]); 8420 } 8421 } 8422 return null; 8423 } 8424 function getStringFromPath(path) { 8425 let pathString = path[0].key; 8426 for (let index = 1; index < path.length; index++) { 8427 pathString += '.' + path[index].key; 8428 } 8429 return pathString; 8430 } 8431 class MemberExpression extends NodeBase { 8432 constructor() { 8433 super(...arguments); 8434 this.variable = null; 8435 this.expressionsToBeDeoptimized = []; 8436 } 8437 get computed() { 8438 return isFlagSet(this.flags, 1024 /* Flag.computed */); 8439 } 8440 set computed(value) { 8441 this.flags = setFlag(this.flags, 1024 /* Flag.computed */, value); 8442 } 8443 get optional() { 8444 return isFlagSet(this.flags, 128 /* Flag.optional */); 8445 } 8446 set optional(value) { 8447 this.flags = setFlag(this.flags, 128 /* Flag.optional */, value); 8448 } 8449 get assignmentDeoptimized() { 8450 return isFlagSet(this.flags, 16 /* Flag.assignmentDeoptimized */); 8451 } 8452 set assignmentDeoptimized(value) { 8453 this.flags = setFlag(this.flags, 16 /* Flag.assignmentDeoptimized */, value); 8454 } 8455 get bound() { 8456 return isFlagSet(this.flags, 32 /* Flag.bound */); 8457 } 8458 set bound(value) { 8459 this.flags = setFlag(this.flags, 32 /* Flag.bound */, value); 8460 } 8461 get isUndefined() { 8462 return isFlagSet(this.flags, 64 /* Flag.isUndefined */); 8463 } 8464 set isUndefined(value) { 8465 this.flags = setFlag(this.flags, 64 /* Flag.isUndefined */, value); 8466 } 8467 bind() { 8468 this.bound = true; 8469 const path = getPathIfNotComputed(this); 8470 const baseVariable = path && this.scope.findVariable(path[0].key); 8471 if (baseVariable?.isNamespace) { 8472 const resolvedVariable = resolveNamespaceVariables(baseVariable, path.slice(1), this.scope.context); 8473 if (!resolvedVariable) { 8474 super.bind(); 8475 } 8476 else if (resolvedVariable === 'undefined') { 8477 this.isUndefined = true; 8478 } 8479 else { 8480 this.variable = resolvedVariable; 8481 this.scope.addNamespaceMemberAccess(getStringFromPath(path), resolvedVariable); 8482 } 8483 } 8484 else { 8485 super.bind(); 8486 } 8487 } 8488 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 8489 if (this.variable) { 8490 this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 8491 } 8492 else if (!this.isUndefined) { 8493 if (path.length < MAX_PATH_DEPTH) { 8494 this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.getPropertyKey(), ...path], recursionTracker); 8495 } 8496 else { 8497 deoptimizeInteraction(interaction); 8498 } 8499 } 8500 } 8501 deoptimizeCache() { 8502 const { expressionsToBeDeoptimized, object } = this; 8503 this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY; 8504 this.propertyKey = UnknownKey; 8505 object.deoptimizePath(UNKNOWN_PATH); 8506 for (const expression of expressionsToBeDeoptimized) { 8507 expression.deoptimizeCache(); 8508 } 8509 } 8510 deoptimizePath(path) { 8511 if (path.length === 0) 8512 this.disallowNamespaceReassignment(); 8513 if (this.variable) { 8514 this.variable.deoptimizePath(path); 8515 } 8516 else if (!this.isUndefined && path.length < MAX_PATH_DEPTH) { 8517 const propertyKey = this.getPropertyKey(); 8518 this.object.deoptimizePath([ 8519 propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey, 8520 ...path 8521 ]); 8522 } 8523 } 8524 getLiteralValueAtPath(path, recursionTracker, origin) { 8525 if (this.variable) { 8526 return this.variable.getLiteralValueAtPath(path, recursionTracker, origin); 8527 } 8528 if (this.isUndefined) { 8529 return undefined; 8530 } 8531 if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) { 8532 this.expressionsToBeDeoptimized.push(origin); 8533 return this.object.getLiteralValueAtPath([this.getPropertyKey(), ...path], recursionTracker, origin); 8534 } 8535 return UnknownValue; 8536 } 8537 getLiteralValueAtPathAsChainElement(path, recursionTracker, origin) { 8538 if (this.variable) { 8539 return this.variable.getLiteralValueAtPath(path, recursionTracker, origin); 8540 } 8541 if (this.isUndefined) { 8542 return undefined; 8543 } 8544 return getChainElementLiteralValueAtPath(this, this.object, path, recursionTracker, origin); 8545 } 8546 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 8547 if (this.variable) { 8548 return this.variable.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 8549 } 8550 if (this.isUndefined) { 8551 return [UNDEFINED_EXPRESSION, false]; 8552 } 8553 if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) { 8554 this.expressionsToBeDeoptimized.push(origin); 8555 return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin); 8556 } 8557 return UNKNOWN_RETURN_EXPRESSION; 8558 } 8559 hasEffects(context) { 8560 if (!this.deoptimized) 8561 this.applyDeoptimizations(); 8562 return (this.property.hasEffects(context) || 8563 this.object.hasEffects(context) || 8564 this.hasAccessEffect(context)); 8565 } 8566 hasEffectsAsChainElement(context) { 8567 if (this.variable || this.isUndefined) 8568 return this.hasEffects(context); 8569 const objectHasEffects = 'hasEffectsAsChainElement' in this.object 8570 ? this.object.hasEffectsAsChainElement(context) 8571 : this.object.hasEffects(context); 8572 if (objectHasEffects === IS_SKIPPED_CHAIN) 8573 return IS_SKIPPED_CHAIN; 8574 if (this.optional && 8575 this.object.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) == null) { 8576 return objectHasEffects || IS_SKIPPED_CHAIN; 8577 } 8578 // We only apply deoptimizations lazily once we know we are not skipping 8579 if (!this.deoptimized) 8580 this.applyDeoptimizations(); 8581 return objectHasEffects || this.property.hasEffects(context) || this.hasAccessEffect(context); 8582 } 8583 hasEffectsAsAssignmentTarget(context, checkAccess) { 8584 if (checkAccess && !this.deoptimized) 8585 this.applyDeoptimizations(); 8586 if (!this.assignmentDeoptimized) 8587 this.applyAssignmentDeoptimization(); 8588 return (this.property.hasEffects(context) || 8589 this.object.hasEffects(context) || 8590 (checkAccess && this.hasAccessEffect(context)) || 8591 this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context)); 8592 } 8593 hasEffectsOnInteractionAtPath(path, interaction, context) { 8594 if (this.variable) { 8595 return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context); 8596 } 8597 if (this.isUndefined) { 8598 return true; 8599 } 8600 if (path.length < MAX_PATH_DEPTH) { 8601 return this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey(), ...path], interaction, context); 8602 } 8603 return true; 8604 } 8605 include(context, includeChildrenRecursively) { 8606 if (!this.deoptimized) 8607 this.applyDeoptimizations(); 8608 this.includeProperties(context, includeChildrenRecursively); 8609 } 8610 includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) { 8611 if (!this.assignmentDeoptimized) 8612 this.applyAssignmentDeoptimization(); 8613 if (deoptimizeAccess) { 8614 this.include(context, includeChildrenRecursively); 8615 } 8616 else { 8617 this.includeProperties(context, includeChildrenRecursively); 8618 } 8619 } 8620 includeCallArguments(context, parameters) { 8621 if (this.variable) { 8622 this.variable.includeCallArguments(context, parameters); 8623 } 8624 else { 8625 super.includeCallArguments(context, parameters); 8626 } 8627 } 8628 initialise() { 8629 super.initialise(); 8630 this.propertyKey = getResolvablePropertyKey(this); 8631 this.accessInteraction = { args: [this.object], type: INTERACTION_ACCESSED }; 8632 } 8633 render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = parseAst_js.BLANK) { 8634 if (this.variable || this.isUndefined) { 8635 const { snippets: { getPropertyAccess } } = options; 8636 let replacement = this.variable ? this.variable.getName(getPropertyAccess) : 'undefined'; 8637 if (renderedParentType && isCalleeOfRenderedParent) 8638 replacement = '0, ' + replacement; 8639 code.overwrite(this.start, this.end, replacement, { 8640 contentOnly: true, 8641 storeName: true 8642 }); 8643 } 8644 else { 8645 if (renderedParentType && isCalleeOfRenderedParent) { 8646 code.appendRight(this.start, '0, '); 8647 } 8648 this.object.render(code, options, { renderedSurroundingElement }); 8649 this.property.render(code, options); 8650 } 8651 } 8652 setAssignedValue(value) { 8653 this.assignmentInteraction = { 8654 args: [this.object, value], 8655 type: INTERACTION_ASSIGNED 8656 }; 8657 } 8658 applyDeoptimizations() { 8659 this.deoptimized = true; 8660 const { propertyReadSideEffects } = this.scope.context.options 8661 .treeshake; 8662 if ( 8663 // Namespaces are not bound and should not be deoptimized 8664 this.bound && 8665 propertyReadSideEffects && 8666 !(this.variable || this.isUndefined)) { 8667 const propertyKey = this.getPropertyKey(); 8668 this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER); 8669 this.scope.context.requestTreeshakingPass(); 8670 } 8671 if (this.variable) { 8672 this.variable.addUsedPlace(this); 8673 this.scope.context.requestTreeshakingPass(); 8674 } 8675 } 8676 applyAssignmentDeoptimization() { 8677 this.assignmentDeoptimized = true; 8678 const { propertyReadSideEffects } = this.scope.context.options 8679 .treeshake; 8680 if ( 8681 // Namespaces are not bound and should not be deoptimized 8682 this.bound && 8683 propertyReadSideEffects && 8684 !(this.variable || this.isUndefined)) { 8685 this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.getPropertyKey()], SHARED_RECURSION_TRACKER); 8686 this.scope.context.requestTreeshakingPass(); 8687 } 8688 } 8689 disallowNamespaceReassignment() { 8690 if (this.object instanceof Identifier) { 8691 const variable = this.scope.findVariable(this.object.name); 8692 if (variable.isNamespace) { 8693 if (this.variable) { 8694 this.scope.context.includeVariableInModule(this.variable); 8695 } 8696 this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start); 8697 } 8698 } 8699 } 8700 getPropertyKey() { 8701 if (this.propertyKey === null) { 8702 this.propertyKey = UnknownKey; 8703 const value = this.property.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 8704 return (this.propertyKey = 8705 value === SymbolToStringTag 8706 ? value 8707 : typeof value === 'symbol' 8708 ? UnknownKey 8709 : String(value)); 8710 } 8711 return this.propertyKey; 8712 } 8713 hasAccessEffect(context) { 8714 const { propertyReadSideEffects } = this.scope.context.options 8715 .treeshake; 8716 return (!(this.variable || this.isUndefined) && 8717 propertyReadSideEffects && 8718 (propertyReadSideEffects === 'always' || 8719 this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context))); 8720 } 8721 includeProperties(context, includeChildrenRecursively) { 8722 if (!this.included) { 8723 this.included = true; 8724 if (this.variable) { 8725 this.scope.context.includeVariableInModule(this.variable); 8726 } 8727 } 8728 this.object.include(context, includeChildrenRecursively); 8729 this.property.include(context, includeChildrenRecursively); 8730 } 8731 } 8732 function resolveNamespaceVariables(baseVariable, path, astContext) { 8733 if (path.length === 0) 8734 return baseVariable; 8735 if (!baseVariable.isNamespace || baseVariable instanceof ExternalVariable) 8736 return null; 8737 const exportName = path[0].key; 8738 const variable = baseVariable.context.traceExport(exportName); 8739 if (!variable) { 8740 if (path.length === 1) { 8741 const fileName = baseVariable.context.fileName; 8742 astContext.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logMissingExport(exportName, astContext.module.id, fileName), path[0].pos); 8743 return 'undefined'; 8744 } 8745 return null; 8746 } 8747 return resolveNamespaceVariables(variable, path.slice(1), astContext); 8748 } 8749 8750 const FILE_PREFIX = 'ROLLUP_FILE_URL_'; 8751 const IMPORT = 'import'; 8752 class MetaProperty extends NodeBase { 8753 constructor() { 8754 super(...arguments); 8755 this.metaProperty = null; 8756 this.preliminaryChunkId = null; 8757 this.referenceId = null; 8758 } 8759 getReferencedFileName(outputPluginDriver) { 8760 const { meta: { name }, metaProperty } = this; 8761 if (name === IMPORT && metaProperty?.startsWith(FILE_PREFIX)) { 8762 return outputPluginDriver.getFileName(metaProperty.slice(FILE_PREFIX.length)); 8763 } 8764 return null; 8765 } 8766 hasEffects() { 8767 return false; 8768 } 8769 hasEffectsOnInteractionAtPath(path, { type }) { 8770 return path.length > 1 || type !== INTERACTION_ACCESSED; 8771 } 8772 include() { 8773 if (!this.included) { 8774 this.included = true; 8775 if (this.meta.name === IMPORT) { 8776 this.scope.context.addImportMeta(this); 8777 const parent = this.parent; 8778 const metaProperty = (this.metaProperty = 8779 parent instanceof MemberExpression && typeof parent.propertyKey === 'string' 8780 ? parent.propertyKey 8781 : null); 8782 if (metaProperty?.startsWith(FILE_PREFIX)) { 8783 this.referenceId = metaProperty.slice(FILE_PREFIX.length); 8784 } 8785 } 8786 } 8787 } 8788 render(code, renderOptions) { 8789 const { format, pluginDriver, snippets } = renderOptions; 8790 const { scope: { context: { module } }, meta: { name }, metaProperty, parent, preliminaryChunkId, referenceId, start, end } = this; 8791 const { id: moduleId } = module; 8792 if (name !== IMPORT) 8793 return; 8794 const chunkId = preliminaryChunkId; 8795 if (referenceId) { 8796 const fileName = pluginDriver.getFileName(referenceId); 8797 const relativePath = parseAst_js.normalize(path.relative(path.dirname(chunkId), fileName)); 8798 const replacement = pluginDriver.hookFirstSync('resolveFileUrl', [ 8799 { chunkId, fileName, format, moduleId, referenceId, relativePath } 8800 ]) || relativeUrlMechanisms[format](relativePath); 8801 code.overwrite(parent.start, parent.end, replacement, { contentOnly: true }); 8802 return; 8803 } 8804 let replacement = pluginDriver.hookFirstSync('resolveImportMeta', [ 8805 metaProperty, 8806 { chunkId, format, moduleId } 8807 ]); 8808 if (!replacement) { 8809 replacement = importMetaMechanisms[format]?.(metaProperty, { chunkId, snippets }); 8810 renderOptions.accessedDocumentCurrentScript ||= 8811 formatsMaybeAccessDocumentCurrentScript.includes(format) && replacement !== 'undefined'; 8812 } 8813 if (typeof replacement === 'string') { 8814 if (parent instanceof MemberExpression) { 8815 code.overwrite(parent.start, parent.end, replacement, { contentOnly: true }); 8816 } 8817 else { 8818 code.overwrite(start, end, replacement, { contentOnly: true }); 8819 } 8820 } 8821 } 8822 setResolution(format, accessedGlobalsByScope, preliminaryChunkId) { 8823 this.preliminaryChunkId = preliminaryChunkId; 8824 const accessedGlobals = (this.metaProperty?.startsWith(FILE_PREFIX) ? accessedFileUrlGlobals : accessedMetaUrlGlobals)[format]; 8825 if (accessedGlobals.length > 0) { 8826 this.scope.addAccessedGlobals(accessedGlobals, accessedGlobalsByScope); 8827 } 8828 } 8829 } 8830 const formatsMaybeAccessDocumentCurrentScript = ['cjs', 'iife', 'umd']; 8831 const accessedMetaUrlGlobals = { 8832 amd: ['document', 'module', 'URL'], 8833 cjs: ['document', 'require', 'URL', DOCUMENT_CURRENT_SCRIPT], 8834 es: [], 8835 iife: ['document', 'URL', DOCUMENT_CURRENT_SCRIPT], 8836 system: ['module'], 8837 umd: ['document', 'require', 'URL', DOCUMENT_CURRENT_SCRIPT] 8838 }; 8839 const accessedFileUrlGlobals = { 8840 amd: ['document', 'require', 'URL'], 8841 cjs: ['document', 'require', 'URL'], 8842 es: [], 8843 iife: ['document', 'URL'], 8844 system: ['module', 'URL'], 8845 umd: ['document', 'require', 'URL'] 8846 }; 8847 const getResolveUrl = (path, URL = 'URL') => `new ${URL}(${path}).href`; 8848 const getRelativeUrlFromDocument = (relativePath, umd = false) => getResolveUrl(`'${escapeId(relativePath)}', ${umd ? `typeof document === 'undefined' ? location.href : ` : ''}document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT' && document.currentScript.src || document.baseURI`); 8849 const getGenericImportMetaMechanism = (getUrl) => (property, { chunkId }) => { 8850 const urlMechanism = getUrl(chunkId); 8851 return property === null 8852 ? `({ url: ${urlMechanism} })` 8853 : property === 'url' 8854 ? urlMechanism 8855 : 'undefined'; 8856 }; 8857 const getFileUrlFromFullPath = (path) => `require('u' + 'rl').pathToFileURL(${path}).href`; 8858 const getFileUrlFromRelativePath = (path) => getFileUrlFromFullPath(`__dirname + '/${escapeId(path)}'`); 8859 const getUrlFromDocument = (chunkId, umd = false) => `${umd ? `typeof document === 'undefined' ? location.href : ` : ''}(${DOCUMENT_CURRENT_SCRIPT} && ${DOCUMENT_CURRENT_SCRIPT}.tagName.toUpperCase() === 'SCRIPT' && ${DOCUMENT_CURRENT_SCRIPT}.src || new URL('${escapeId(chunkId)}', document.baseURI).href)`; 8860 const relativeUrlMechanisms = { 8861 amd: relativePath => { 8862 if (relativePath[0] !== '.') 8863 relativePath = './' + relativePath; 8864 return getResolveUrl(`require.toUrl('${escapeId(relativePath)}'), document.baseURI`); 8865 }, 8866 cjs: relativePath => `(typeof document === 'undefined' ? ${getFileUrlFromRelativePath(relativePath)} : ${getRelativeUrlFromDocument(relativePath)})`, 8867 es: relativePath => getResolveUrl(`'${escapeId(relativePath)}', import.meta.url`), 8868 iife: relativePath => getRelativeUrlFromDocument(relativePath), 8869 system: relativePath => getResolveUrl(`'${escapeId(relativePath)}', module.meta.url`), 8870 umd: relativePath => `(typeof document === 'undefined' && typeof location === 'undefined' ? ${getFileUrlFromRelativePath(relativePath)} : ${getRelativeUrlFromDocument(relativePath, true)})` 8871 }; 8872 const importMetaMechanisms = { 8873 amd: getGenericImportMetaMechanism(() => getResolveUrl(`module.uri, document.baseURI`)), 8874 cjs: getGenericImportMetaMechanism(chunkId => `(typeof document === 'undefined' ? ${getFileUrlFromFullPath('__filename')} : ${getUrlFromDocument(chunkId)})`), 8875 iife: getGenericImportMetaMechanism(chunkId => getUrlFromDocument(chunkId)), 8876 system: (property, { snippets: { getPropertyAccess } }) => property === null ? `module.meta` : `module.meta${getPropertyAccess(property)}`, 8877 umd: getGenericImportMetaMechanism(chunkId => `(typeof document === 'undefined' && typeof location === 'undefined' ? ${getFileUrlFromFullPath('__filename')} : ${getUrlFromDocument(chunkId, true)})`) 8878 }; 8879 8880 class UndefinedVariable extends Variable { 8881 constructor() { 8882 super('undefined'); 8883 } 8884 getLiteralValueAtPath() { 8885 return undefined; 8886 } 8887 } 8888 8889 class ExportDefaultVariable extends LocalVariable { 8890 constructor(name, exportDefaultDeclaration, context) { 8891 super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other'); 8892 this.hasId = false; 8893 this.originalId = null; 8894 this.originalVariable = null; 8895 const declaration = exportDefaultDeclaration.declaration; 8896 if ((declaration instanceof FunctionDeclaration || declaration instanceof ClassDeclaration) && 8897 declaration.id) { 8898 this.hasId = true; 8899 this.originalId = declaration.id; 8900 } 8901 else if (declaration instanceof Identifier) { 8902 this.originalId = declaration; 8903 } 8904 } 8905 addReference(identifier) { 8906 if (!this.hasId) { 8907 this.name = identifier.name; 8908 } 8909 } 8910 addUsedPlace(usedPlace) { 8911 const original = this.getOriginalVariable(); 8912 if (original === this) { 8913 super.addUsedPlace(usedPlace); 8914 } 8915 else { 8916 original.addUsedPlace(usedPlace); 8917 } 8918 } 8919 forbidName(name) { 8920 const original = this.getOriginalVariable(); 8921 if (original === this) { 8922 super.forbidName(name); 8923 } 8924 else { 8925 original.forbidName(name); 8926 } 8927 } 8928 getAssignedVariableName() { 8929 return (this.originalId && this.originalId.name) || null; 8930 } 8931 getBaseVariableName() { 8932 const original = this.getOriginalVariable(); 8933 return original === this ? super.getBaseVariableName() : original.getBaseVariableName(); 8934 } 8935 getDirectOriginalVariable() { 8936 return this.originalId && 8937 (this.hasId || 8938 !(this.originalId.isPossibleTDZ() || 8939 this.originalId.variable.isReassigned || 8940 this.originalId.variable instanceof UndefinedVariable || 8941 // this avoids a circular dependency 8942 'syntheticNamespace' in this.originalId.variable)) 8943 ? this.originalId.variable 8944 : null; 8945 } 8946 getName(getPropertyAccess) { 8947 const original = this.getOriginalVariable(); 8948 return original === this 8949 ? super.getName(getPropertyAccess) 8950 : original.getName(getPropertyAccess); 8951 } 8952 getOriginalVariable() { 8953 if (this.originalVariable) 8954 return this.originalVariable; 8955 // eslint-disable-next-line @typescript-eslint/no-this-alias 8956 let original = this; 8957 let currentVariable; 8958 const checkedVariables = new Set(); 8959 do { 8960 checkedVariables.add(original); 8961 currentVariable = original; 8962 original = currentVariable.getDirectOriginalVariable(); 8963 } while (original instanceof ExportDefaultVariable && !checkedVariables.has(original)); 8964 return (this.originalVariable = original || currentVariable); 8965 } 8966 } 8967 8968 class NamespaceVariable extends Variable { 8969 constructor(context) { 8970 super(context.getModuleName()); 8971 this.memberVariables = null; 8972 this.mergedNamespaces = []; 8973 this.referencedEarly = false; 8974 this.references = []; 8975 this.context = context; 8976 this.module = context.module; 8977 } 8978 addReference(identifier) { 8979 this.references.push(identifier); 8980 this.name = identifier.name; 8981 } 8982 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 8983 if (path.length > 1 || (path.length === 1 && interaction.type === INTERACTION_CALLED)) { 8984 const key = path[0]; 8985 if (typeof key === 'string') { 8986 this.getMemberVariables()[key]?.deoptimizeArgumentsOnInteractionAtPath(interaction, path.slice(1), recursionTracker); 8987 } 8988 else { 8989 deoptimizeInteraction(interaction); 8990 } 8991 } 8992 } 8993 deoptimizePath(path) { 8994 if (path.length > 1) { 8995 const key = path[0]; 8996 if (typeof key === 'string') { 8997 this.getMemberVariables()[key]?.deoptimizePath(path.slice(1)); 8998 } 8999 } 9000 } 9001 getLiteralValueAtPath(path) { 9002 if (path[0] === SymbolToStringTag) { 9003 return 'Module'; 9004 } 9005 return UnknownValue; 9006 } 9007 getMemberVariables() { 9008 if (this.memberVariables) { 9009 return this.memberVariables; 9010 } 9011 const memberVariables = Object.create(null); 9012 const sortedExports = [...this.context.getExports(), ...this.context.getReexports()].sort(); 9013 for (const name of sortedExports) { 9014 if (name[0] !== '*' && name !== this.module.info.syntheticNamedExports) { 9015 const exportedVariable = this.context.traceExport(name); 9016 if (exportedVariable) { 9017 memberVariables[name] = exportedVariable; 9018 } 9019 } 9020 } 9021 return (this.memberVariables = memberVariables); 9022 } 9023 hasEffectsOnInteractionAtPath(path, interaction, context) { 9024 const { type } = interaction; 9025 if (path.length === 0) { 9026 // This can only be a call anyway 9027 return true; 9028 } 9029 if (path.length === 1 && type !== INTERACTION_CALLED) { 9030 return type === INTERACTION_ASSIGNED; 9031 } 9032 const key = path[0]; 9033 if (typeof key !== 'string') { 9034 return true; 9035 } 9036 const memberVariable = this.getMemberVariables()[key]; 9037 return (!memberVariable || 9038 memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context)); 9039 } 9040 include() { 9041 super.include(); 9042 this.context.includeAllExports(); 9043 } 9044 prepare(accessedGlobalsByScope) { 9045 if (this.mergedNamespaces.length > 0) { 9046 this.module.scope.addAccessedGlobals([MERGE_NAMESPACES_VARIABLE], accessedGlobalsByScope); 9047 } 9048 } 9049 renderBlock(options) { 9050 const { exportNamesByVariable, format, freeze, indent: t, symbols, snippets: { _, cnst, getObject, getPropertyAccess, n, s } } = options; 9051 const memberVariables = this.getMemberVariables(); 9052 const members = Object.entries(memberVariables) 9053 .filter(([_, variable]) => variable.included) 9054 .map(([name, variable]) => { 9055 if (this.referencedEarly || variable.isReassigned || variable === this) { 9056 return [ 9057 null, 9058 `get ${stringifyObjectKeyIfNeeded(name)}${_}()${_}{${_}return ${variable.getName(getPropertyAccess)}${s}${_}}` 9059 ]; 9060 } 9061 return [name, variable.getName(getPropertyAccess)]; 9062 }); 9063 members.unshift([null, `__proto__:${_}null`]); 9064 let output = getObject(members, { lineBreakIndent: { base: '', t } }); 9065 if (this.mergedNamespaces.length > 0) { 9066 const assignmentArguments = this.mergedNamespaces.map(variable => variable.getName(getPropertyAccess)); 9067 output = `/*#__PURE__*/${MERGE_NAMESPACES_VARIABLE}(${output},${_}[${assignmentArguments.join(`,${_}`)}])`; 9068 } 9069 else { 9070 // The helper to merge namespaces will also take care of freezing and toStringTag 9071 if (symbols) { 9072 output = `/*#__PURE__*/Object.defineProperty(${output},${_}Symbol.toStringTag,${_}${getToStringTagValue(getObject)})`; 9073 } 9074 if (freeze) { 9075 output = `/*#__PURE__*/Object.freeze(${output})`; 9076 } 9077 } 9078 const name = this.getName(getPropertyAccess); 9079 output = `${cnst} ${name}${_}=${_}${output};`; 9080 if (format === 'system' && exportNamesByVariable.has(this)) { 9081 output += `${n}${getSystemExportStatement([this], options)};`; 9082 } 9083 return output; 9084 } 9085 renderFirst() { 9086 return this.referencedEarly; 9087 } 9088 setMergedNamespaces(mergedNamespaces) { 9089 this.mergedNamespaces = mergedNamespaces; 9090 const moduleExecIndex = this.context.getModuleExecIndex(); 9091 for (const identifier of this.references) { 9092 const { context } = identifier.scope; 9093 if (context.getModuleExecIndex() <= moduleExecIndex) { 9094 this.referencedEarly = true; 9095 break; 9096 } 9097 } 9098 } 9099 } 9100 NamespaceVariable.prototype.isNamespace = true; 9101 9102 class SyntheticNamedExportVariable extends Variable { 9103 constructor(context, name, syntheticNamespace) { 9104 super(name); 9105 this.baseVariable = null; 9106 this.context = context; 9107 this.module = context.module; 9108 this.syntheticNamespace = syntheticNamespace; 9109 } 9110 getBaseVariable() { 9111 if (this.baseVariable) 9112 return this.baseVariable; 9113 let baseVariable = this.syntheticNamespace; 9114 while (baseVariable instanceof ExportDefaultVariable || 9115 baseVariable instanceof SyntheticNamedExportVariable) { 9116 if (baseVariable instanceof ExportDefaultVariable) { 9117 const original = baseVariable.getOriginalVariable(); 9118 if (original === baseVariable) 9119 break; 9120 baseVariable = original; 9121 } 9122 if (baseVariable instanceof SyntheticNamedExportVariable) { 9123 baseVariable = baseVariable.syntheticNamespace; 9124 } 9125 } 9126 return (this.baseVariable = baseVariable); 9127 } 9128 getBaseVariableName() { 9129 return this.syntheticNamespace.getBaseVariableName(); 9130 } 9131 getName(getPropertyAccess) { 9132 return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`; 9133 } 9134 include() { 9135 super.include(); 9136 this.context.includeVariableInModule(this.syntheticNamespace); 9137 } 9138 setRenderNames(baseName, name) { 9139 super.setRenderNames(baseName, name); 9140 } 9141 } 9142 9143 class ExternalChunk { 9144 constructor(module, options, inputBase) { 9145 this.options = options; 9146 this.inputBase = inputBase; 9147 this.defaultVariableName = ''; 9148 this.namespaceVariableName = ''; 9149 this.variableName = ''; 9150 this.fileName = null; 9151 this.importAttributes = null; 9152 this.id = module.id; 9153 this.moduleInfo = module.info; 9154 this.renormalizeRenderPath = module.renormalizeRenderPath; 9155 this.suggestedVariableName = module.suggestedVariableName; 9156 } 9157 getFileName() { 9158 if (this.fileName) { 9159 return this.fileName; 9160 } 9161 const { paths } = this.options; 9162 return (this.fileName = 9163 (typeof paths === 'function' ? paths(this.id) : paths[this.id]) || 9164 (this.renormalizeRenderPath ? parseAst_js.normalize(path.relative(this.inputBase, this.id)) : this.id)); 9165 } 9166 getImportAttributes(snippets) { 9167 return (this.importAttributes ||= formatAttributes(this.options.format === 'es' && 9168 this.options.externalImportAttributes && 9169 this.moduleInfo.attributes, snippets)); 9170 } 9171 getImportPath(importer) { 9172 return escapeId(this.renormalizeRenderPath 9173 ? parseAst_js.getImportPath(importer, this.getFileName(), this.options.format === 'amd', false) 9174 : this.getFileName()); 9175 } 9176 } 9177 function formatAttributes(attributes, { getObject }) { 9178 if (!attributes) { 9179 return null; 9180 } 9181 const assertionEntries = Object.entries(attributes).map(([key, value]) => [key, `'${value}'`]); 9182 if (assertionEntries.length > 0) { 9183 return getObject(assertionEntries, { lineBreakIndent: null }); 9184 } 9185 return null; 9186 } 9187 9188 function removeJsExtension(name) { 9189 return name.endsWith('.js') ? name.slice(0, -3) : name; 9190 } 9191 9192 function getCompleteAmdId(options, chunkId) { 9193 if (options.autoId) { 9194 return `${options.basePath ? options.basePath + '/' : ''}${removeJsExtension(chunkId)}`; 9195 } 9196 return options.id ?? ''; 9197 } 9198 9199 function getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal, mechanism = 'return ') { 9200 const { _, getDirectReturnFunction, getFunctionIntro, getPropertyAccess, n, s } = snippets; 9201 if (!namedExportsMode) { 9202 return `${n}${n}${mechanism}${getSingleDefaultExport(exports, dependencies, interop, externalLiveBindings, getPropertyAccess)};`; 9203 } 9204 let exportBlock = ''; 9205 if (namedExportsMode) { 9206 for (const { defaultVariableName, importPath, isChunk, name, namedExportsMode: depNamedExportsMode, namespaceVariableName, reexports } of dependencies) { 9207 if (!reexports) { 9208 continue; 9209 } 9210 for (const specifier of reexports) { 9211 if (specifier.reexported !== '*') { 9212 const importName = getReexportedImportName(name, specifier.imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, importPath, externalLiveBindings, getPropertyAccess); 9213 if (exportBlock) 9214 exportBlock += n; 9215 if (specifier.imported !== '*' && specifier.needsLiveBinding) { 9216 const [left, right] = getDirectReturnFunction([], { 9217 functionReturn: true, 9218 lineBreakIndent: null, 9219 name: null 9220 }); 9221 exportBlock += 9222 `Object.defineProperty(exports,${_}${JSON.stringify(specifier.reexported)},${_}{${n}` + 9223 `${t}enumerable:${_}true,${n}` + 9224 `${t}get:${_}${left}${importName}${right}${n}});`; 9225 } 9226 else if (specifier.reexported === '__proto__') { 9227 exportBlock += 9228 `Object.defineProperty(exports,${_}"__proto__",${_}{${n}` + 9229 `${t}enumerable:${_}true,${n}` + 9230 `${t}value:${_}${importName}${n}});`; 9231 } 9232 else { 9233 exportBlock += `exports${getPropertyAccess(specifier.reexported)}${_}=${_}${importName};`; 9234 } 9235 } 9236 } 9237 } 9238 } 9239 for (const { exported, local } of exports) { 9240 const lhs = `exports${getPropertyAccess(exported)}`; 9241 const rhs = local; 9242 if (lhs !== rhs) { 9243 if (exportBlock) 9244 exportBlock += n; 9245 exportBlock += 9246 exported === '__proto__' 9247 ? `Object.defineProperty(exports,${_}"__proto__",${_}{${n}` + 9248 `${t}enumerable:${_}true,${n}` + 9249 `${t}value:${_}${rhs}${n}});` 9250 : `${lhs}${_}=${_}${rhs};`; 9251 } 9252 } 9253 if (namedExportsMode) { 9254 for (const { name, reexports } of dependencies) { 9255 if (!reexports) { 9256 continue; 9257 } 9258 for (const specifier of reexports) { 9259 if (specifier.reexported === '*') { 9260 if (exportBlock) 9261 exportBlock += n; 9262 if (!specifier.needsLiveBinding && reexportProtoFromExternal) { 9263 const protoString = "'__proto__'"; 9264 exportBlock += 9265 `Object.prototype.hasOwnProperty.call(${name},${_}${protoString})${_}&&${n}` + 9266 `${t}!Object.prototype.hasOwnProperty.call(exports,${_}${protoString})${_}&&${n}` + 9267 `${t}Object.defineProperty(exports,${_}${protoString},${_}{${n}` + 9268 `${t}${t}enumerable:${_}true,${n}` + 9269 `${t}${t}value:${_}${name}[${protoString}]${n}` + 9270 `${t}});${n}${n}`; 9271 } 9272 const copyPropertyIfNecessary = `{${n}${t}if${_}(k${_}!==${_}'default'${_}&&${_}!Object.prototype.hasOwnProperty.call(exports,${_}k))${_}${getDefineProperty(name, specifier.needsLiveBinding, t, snippets)}${s}${n}}`; 9273 exportBlock += `Object.keys(${name}).forEach(${getFunctionIntro(['k'], { 9274 isAsync: false, 9275 name: null 9276 })}${copyPropertyIfNecessary});`; 9277 } 9278 } 9279 } 9280 } 9281 if (exportBlock) { 9282 return `${n}${n}${exportBlock}`; 9283 } 9284 return ''; 9285 } 9286 function getSingleDefaultExport(exports, dependencies, interop, externalLiveBindings, getPropertyAccess) { 9287 if (exports.length > 0) { 9288 return exports[0].local; 9289 } 9290 else { 9291 for (const { defaultVariableName, importPath, isChunk, name, namedExportsMode: depNamedExportsMode, namespaceVariableName, reexports } of dependencies) { 9292 if (reexports) { 9293 return getReexportedImportName(name, reexports[0].imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, importPath, externalLiveBindings, getPropertyAccess); 9294 } 9295 } 9296 } 9297 } 9298 function getReexportedImportName(moduleVariableName, imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, moduleId, externalLiveBindings, getPropertyAccess) { 9299 if (imported === 'default') { 9300 if (!isChunk) { 9301 const moduleInterop = interop(moduleId); 9302 const variableName = defaultInteropHelpersByInteropType[moduleInterop] 9303 ? defaultVariableName 9304 : moduleVariableName; 9305 return isDefaultAProperty(moduleInterop, externalLiveBindings) 9306 ? `${variableName}${getPropertyAccess('default')}` 9307 : variableName; 9308 } 9309 return depNamedExportsMode 9310 ? `${moduleVariableName}${getPropertyAccess('default')}` 9311 : moduleVariableName; 9312 } 9313 if (imported === '*') { 9314 return (isChunk ? !depNamedExportsMode : namespaceInteropHelpersByInteropType[interop(moduleId)]) 9315 ? namespaceVariableName 9316 : moduleVariableName; 9317 } 9318 return `${moduleVariableName}${getPropertyAccess(imported)}`; 9319 } 9320 function getEsModuleValue(getObject) { 9321 return getObject([['value', 'true']], { 9322 lineBreakIndent: null 9323 }); 9324 } 9325 function getNamespaceMarkers(hasNamedExports, addEsModule, addNamespaceToStringTag, { _, getObject }) { 9326 if (hasNamedExports) { 9327 if (addEsModule) { 9328 if (addNamespaceToStringTag) { 9329 return `Object.defineProperties(exports,${_}${getObject([ 9330 ['__esModule', getEsModuleValue(getObject)], 9331 [null, `[Symbol.toStringTag]:${_}${getToStringTagValue(getObject)}`] 9332 ], { 9333 lineBreakIndent: null 9334 })});`; 9335 } 9336 return `Object.defineProperty(exports,${_}'__esModule',${_}${getEsModuleValue(getObject)});`; 9337 } 9338 if (addNamespaceToStringTag) { 9339 return `Object.defineProperty(exports,${_}Symbol.toStringTag,${_}${getToStringTagValue(getObject)});`; 9340 } 9341 } 9342 return ''; 9343 } 9344 const getDefineProperty = (name, needsLiveBinding, t, { _, getDirectReturnFunction, n }) => { 9345 if (needsLiveBinding) { 9346 const [left, right] = getDirectReturnFunction([], { 9347 functionReturn: true, 9348 lineBreakIndent: null, 9349 name: null 9350 }); 9351 return (`Object.defineProperty(exports,${_}k,${_}{${n}` + 9352 `${t}${t}enumerable:${_}true,${n}` + 9353 `${t}${t}get:${_}${left}${name}[k]${right}${n}${t}})`); 9354 } 9355 return `exports[k]${_}=${_}${name}[k]`; 9356 }; 9357 9358 function getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, indent, snippets) { 9359 const { _, cnst, n } = snippets; 9360 const neededInteropHelpers = new Set(); 9361 const interopStatements = []; 9362 const addInteropStatement = (helperVariableName, helper, dependencyVariableName) => { 9363 neededInteropHelpers.add(helper); 9364 interopStatements.push(`${cnst} ${helperVariableName}${_}=${_}/*#__PURE__*/${helper}(${dependencyVariableName});`); 9365 }; 9366 for (const { defaultVariableName, imports, importPath, isChunk, name, namedExportsMode, namespaceVariableName, reexports } of dependencies) { 9367 if (isChunk) { 9368 for (const { imported, reexported } of [ 9369 ...(imports || []), 9370 ...(reexports || []) 9371 ]) { 9372 if (imported === '*' && reexported !== '*') { 9373 if (!namedExportsMode) { 9374 addInteropStatement(namespaceVariableName, INTEROP_NAMESPACE_DEFAULT_ONLY_VARIABLE, name); 9375 } 9376 break; 9377 } 9378 } 9379 } 9380 else { 9381 const moduleInterop = interop(importPath); 9382 let hasDefault = false; 9383 let hasNamespace = false; 9384 for (const { imported, reexported } of [ 9385 ...(imports || []), 9386 ...(reexports || []) 9387 ]) { 9388 let helper; 9389 let variableName; 9390 if (imported === 'default') { 9391 if (!hasDefault) { 9392 hasDefault = true; 9393 if (defaultVariableName !== namespaceVariableName) { 9394 variableName = defaultVariableName; 9395 helper = defaultInteropHelpersByInteropType[moduleInterop]; 9396 } 9397 } 9398 } 9399 else if (imported === '*' && reexported !== '*' && !hasNamespace) { 9400 hasNamespace = true; 9401 helper = namespaceInteropHelpersByInteropType[moduleInterop]; 9402 variableName = namespaceVariableName; 9403 } 9404 if (helper) { 9405 addInteropStatement(variableName, helper, name); 9406 } 9407 } 9408 } 9409 } 9410 return `${getHelpersBlock(neededInteropHelpers, accessedGlobals, indent, snippets, externalLiveBindings, freeze, symbols)}${interopStatements.length > 0 ? `${interopStatements.join(n)}${n}${n}` : ''}`; 9411 } 9412 9413 function addJsExtension(name) { 9414 return name.endsWith('.js') ? name : name + '.js'; 9415 } 9416 9417 // AMD resolution will only respect the AMD baseUrl if the .js extension is omitted. 9418 // The assumption is that this makes sense for all relative ids: 9419 // https://requirejs.org/docs/api.html#jsfiles 9420 function updateExtensionForRelativeAmdId(id, forceJsExtensionForImports) { 9421 if (id[0] !== '.') { 9422 return id; 9423 } 9424 return forceJsExtensionForImports ? addJsExtension(id) : removeJsExtension(id); 9425 } 9426 9427 const builtinModules = [ 9428 "assert", 9429 "assert/strict", 9430 "async_hooks", 9431 "buffer", 9432 "child_process", 9433 "cluster", 9434 "console", 9435 "constants", 9436 "crypto", 9437 "dgram", 9438 "diagnostics_channel", 9439 "dns", 9440 "dns/promises", 9441 "domain", 9442 "events", 9443 "fs", 9444 "fs/promises", 9445 "http", 9446 "http2", 9447 "https", 9448 "inspector", 9449 "inspector/promises", 9450 "module", 9451 "net", 9452 "os", 9453 "path", 9454 "path/posix", 9455 "path/win32", 9456 "perf_hooks", 9457 "process", 9458 "punycode", 9459 "querystring", 9460 "readline", 9461 "readline/promises", 9462 "repl", 9463 "stream", 9464 "stream/consumers", 9465 "stream/promises", 9466 "stream/web", 9467 "string_decoder", 9468 "timers", 9469 "timers/promises", 9470 "tls", 9471 "trace_events", 9472 "tty", 9473 "url", 9474 "util", 9475 "util/types", 9476 "v8", 9477 "vm", 9478 "wasi", 9479 "worker_threads", 9480 "zlib" 9481 ]; 9482 9483 const nodeBuiltins = new Set(builtinModules); 9484 function warnOnBuiltins(log, dependencies) { 9485 const externalBuiltins = dependencies 9486 .map(({ importPath }) => importPath) 9487 .filter(importPath => nodeBuiltins.has(importPath) || importPath.startsWith('node:')); 9488 if (externalBuiltins.length === 0) 9489 return; 9490 log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logMissingNodeBuiltins(externalBuiltins)); 9491 } 9492 9493 function amd(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, id, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, log, outro, snippets }, { amd, esModule, externalLiveBindings, freeze, generatedCode: { symbols }, interop, reexportProtoFromExternal, strict }) { 9494 warnOnBuiltins(log, dependencies); 9495 const deps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`); 9496 const parameters = dependencies.map(m => m.name); 9497 const { n, getNonArrowFunctionIntro, _ } = snippets; 9498 if (namedExportsMode && hasExports) { 9499 parameters.unshift(`exports`); 9500 deps.unshift(`'exports'`); 9501 } 9502 if (accessedGlobals.has('require')) { 9503 parameters.unshift('require'); 9504 deps.unshift(`'require'`); 9505 } 9506 if (accessedGlobals.has('module')) { 9507 parameters.unshift('module'); 9508 deps.unshift(`'module'`); 9509 } 9510 const completeAmdId = getCompleteAmdId(amd, id); 9511 const defineParameters = (completeAmdId ? `'${completeAmdId}',${_}` : ``) + 9512 (deps.length > 0 ? `[${deps.join(`,${_}`)}],${_}` : ``); 9513 const useStrict = strict ? `${_}'use strict';` : ''; 9514 magicString.prepend(`${intro}${getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets)}`); 9515 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal); 9516 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets); 9517 if (namespaceMarkers) { 9518 namespaceMarkers = n + n + namespaceMarkers; 9519 } 9520 magicString 9521 .append(`${exportBlock}${namespaceMarkers}${outro}`) 9522 .indent(t) 9523 // factory function should be wrapped by parentheses to avoid lazy parsing, 9524 // cf. https://v8.dev/blog/preparser#pife 9525 .prepend(`${amd.define}(${defineParameters}(${getNonArrowFunctionIntro(parameters, { 9526 isAsync: false, 9527 name: null 9528 })}{${useStrict}${n}${n}`) 9529 .append(`${n}${n}}));`); 9530 } 9531 9532 function cjs(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, outro, snippets }, { compact, esModule, externalLiveBindings, freeze, interop, generatedCode: { symbols }, reexportProtoFromExternal, strict }) { 9533 const { _, n } = snippets; 9534 const useStrict = strict ? `'use strict';${n}${n}` : ''; 9535 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets); 9536 if (namespaceMarkers) { 9537 namespaceMarkers += n + n; 9538 } 9539 const importBlock = getImportBlock$1(dependencies, snippets, compact); 9540 const interopBlock = getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets); 9541 magicString.prepend(`${useStrict}${intro}${namespaceMarkers}${importBlock}${interopBlock}`); 9542 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal, `module.exports${_}=${_}`); 9543 magicString.append(`${exportBlock}${outro}`); 9544 } 9545 function getImportBlock$1(dependencies, { _, cnst, n }, compact) { 9546 let importBlock = ''; 9547 let definingVariable = false; 9548 for (const { importPath, name, reexports, imports } of dependencies) { 9549 if (!reexports && !imports) { 9550 if (importBlock) { 9551 importBlock += compact && !definingVariable ? ',' : `;${n}`; 9552 } 9553 definingVariable = false; 9554 importBlock += `require('${importPath}')`; 9555 } 9556 else { 9557 importBlock += compact && definingVariable ? ',' : `${importBlock ? `;${n}` : ''}${cnst} `; 9558 definingVariable = true; 9559 importBlock += `${name}${_}=${_}require('${importPath}')`; 9560 } 9561 } 9562 if (importBlock) { 9563 return `${importBlock};${n}${n}`; 9564 } 9565 return ''; 9566 } 9567 9568 function es(magicString, { accessedGlobals, indent: t, intro, outro, dependencies, exports, snippets }, { externalLiveBindings, freeze, generatedCode: { symbols }, importAttributesKey }) { 9569 const { n } = snippets; 9570 const importBlock = getImportBlock(dependencies, importAttributesKey, snippets); 9571 if (importBlock.length > 0) 9572 intro += importBlock.join(n) + n + n; 9573 intro += getHelpersBlock(null, accessedGlobals, t, snippets, externalLiveBindings, freeze, symbols); 9574 if (intro) 9575 magicString.prepend(intro); 9576 const exportBlock = getExportBlock(exports, snippets); 9577 if (exportBlock.length > 0) 9578 magicString.append(n + n + exportBlock.join(n).trim()); 9579 if (outro) 9580 magicString.append(outro); 9581 magicString.trim(); 9582 } 9583 function getImportBlock(dependencies, importAttributesKey, { _ }) { 9584 const importBlock = []; 9585 for (const { importPath, reexports, imports, name, attributes } of dependencies) { 9586 const assertion = attributes ? `${_}${importAttributesKey}${_}${attributes}` : ''; 9587 const pathWithAssertion = `'${importPath}'${assertion};`; 9588 if (!reexports && !imports) { 9589 importBlock.push(`import${_}${pathWithAssertion}`); 9590 continue; 9591 } 9592 if (imports) { 9593 let defaultImport = null; 9594 let starImport = null; 9595 const importedNames = []; 9596 for (const specifier of imports) { 9597 if (specifier.imported === 'default') { 9598 defaultImport = specifier; 9599 } 9600 else if (specifier.imported === '*') { 9601 starImport = specifier; 9602 } 9603 else { 9604 importedNames.push(specifier); 9605 } 9606 } 9607 if (starImport) { 9608 importBlock.push(`import${_}*${_}as ${starImport.local} from${_}${pathWithAssertion}`); 9609 } 9610 if (defaultImport && importedNames.length === 0) { 9611 importBlock.push(`import ${defaultImport.local} from${_}${pathWithAssertion}`); 9612 } 9613 else if (importedNames.length > 0) { 9614 importBlock.push(`import ${defaultImport ? `${defaultImport.local},${_}` : ''}{${_}${importedNames 9615 .map(specifier => specifier.imported === specifier.local 9616 ? specifier.imported 9617 : `${stringifyIdentifierIfNeeded(specifier.imported)} as ${specifier.local}`) 9618 .join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`); 9619 } 9620 } 9621 if (reexports) { 9622 let starExport = null; 9623 const namespaceReexports = []; 9624 const namedReexports = []; 9625 for (const specifier of reexports) { 9626 if (specifier.reexported === '*') { 9627 starExport = specifier; 9628 } 9629 else if (specifier.imported === '*') { 9630 namespaceReexports.push(specifier); 9631 } 9632 else { 9633 namedReexports.push(specifier); 9634 } 9635 } 9636 if (starExport) { 9637 importBlock.push(`export${_}*${_}from${_}${pathWithAssertion}`); 9638 } 9639 if (namespaceReexports.length > 0) { 9640 if (!imports || 9641 !imports.some(specifier => specifier.imported === '*' && specifier.local === name)) { 9642 importBlock.push(`import${_}*${_}as ${name} from${_}${pathWithAssertion}`); 9643 } 9644 for (const specifier of namespaceReexports) { 9645 importBlock.push(`export${_}{${_}${name === specifier.reexported 9646 ? name 9647 : `${name} as ${stringifyIdentifierIfNeeded(specifier.reexported)}`} };`); 9648 } 9649 } 9650 if (namedReexports.length > 0) { 9651 importBlock.push(`export${_}{${_}${namedReexports 9652 .map(specifier => specifier.imported === specifier.reexported 9653 ? stringifyIdentifierIfNeeded(specifier.imported) 9654 : `${stringifyIdentifierIfNeeded(specifier.imported)} as ${stringifyIdentifierIfNeeded(specifier.reexported)}`) 9655 .join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`); 9656 } 9657 } 9658 } 9659 return importBlock; 9660 } 9661 function getExportBlock(exports, { _, cnst }) { 9662 const exportBlock = []; 9663 const exportDeclaration = new Array(exports.length); 9664 let index = 0; 9665 for (const specifier of exports) { 9666 if (specifier.expression) { 9667 exportBlock.push(`${cnst} ${specifier.local}${_}=${_}${specifier.expression};`); 9668 } 9669 exportDeclaration[index++] = 9670 specifier.exported === specifier.local 9671 ? specifier.local 9672 : `${specifier.local} as ${stringifyIdentifierIfNeeded(specifier.exported)}`; 9673 } 9674 if (exportDeclaration.length > 0) { 9675 exportBlock.push(`export${_}{${_}${exportDeclaration.join(`,${_}`)}${_}};`); 9676 } 9677 return exportBlock; 9678 } 9679 9680 const keypath = (keypath, getPropertyAccess) => keypath.split('.').map(getPropertyAccess).join(''); 9681 9682 function setupNamespace(name, root, globals, { _, getPropertyAccess, s }, compact, log) { 9683 const parts = name.split('.'); 9684 // Check if the key exists in the object's prototype. 9685 const isReserved = parts[0] in Object.prototype; 9686 if (log && isReserved) { 9687 log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logReservedNamespace(parts[0])); 9688 } 9689 parts[0] = 9690 (typeof globals === 'function' 9691 ? globals(parts[0]) 9692 : isReserved 9693 ? parts[0] 9694 : globals[parts[0]]) || parts[0]; 9695 parts.pop(); 9696 let propertyPath = root; 9697 return (parts 9698 .map(part => { 9699 propertyPath += getPropertyAccess(part); 9700 return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}${s}`; 9701 }) 9702 .join(compact ? ',' : '\n') + (compact && parts.length > 0 ? ';' : '\n')); 9703 } 9704 function assignToDeepVariable(deepName, root, globals, assignment, { _, getPropertyAccess }, log) { 9705 const parts = deepName.split('.'); 9706 // Check if the key exists in the object's prototype. 9707 const isReserved = parts[0] in Object.prototype; 9708 if (log && isReserved) { 9709 log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logReservedNamespace(parts[0])); 9710 } 9711 parts[0] = 9712 (typeof globals === 'function' 9713 ? globals(parts[0]) 9714 : isReserved 9715 ? parts[0] 9716 : globals[parts[0]]) || parts[0]; 9717 const last = parts.pop(); 9718 let propertyPath = root; 9719 let deepAssignment = [ 9720 ...parts.map(part => { 9721 propertyPath += getPropertyAccess(part); 9722 return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}`; 9723 }), 9724 `${propertyPath}${getPropertyAccess(last)}` 9725 ].join(`,${_}`) + `${_}=${_}${assignment}`; 9726 if (parts.length > 0) { 9727 deepAssignment = `(${deepAssignment})`; 9728 } 9729 return deepAssignment; 9730 } 9731 9732 function trimEmptyImports(dependencies) { 9733 let index = dependencies.length; 9734 while (index--) { 9735 const { imports, reexports } = dependencies[index]; 9736 if (imports || reexports) { 9737 return dependencies.slice(0, index + 1); 9738 } 9739 } 9740 return []; 9741 } 9742 9743 function iife(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, indent: t, intro, namedExportsMode, log, outro, snippets }, { compact, esModule, extend, freeze, externalLiveBindings, reexportProtoFromExternal, globals, interop, name, generatedCode: { symbols }, strict }) { 9744 const { _, getNonArrowFunctionIntro, getPropertyAccess, n } = snippets; 9745 const isNamespaced = name && name.includes('.'); 9746 const useVariableAssignment = !extend && !isNamespaced; 9747 if (name && useVariableAssignment && !isLegal(name)) { 9748 return parseAst_js.error(parseAst_js.logIllegalIdentifierAsName(name)); 9749 } 9750 warnOnBuiltins(log, dependencies); 9751 const external = trimEmptyImports(dependencies); 9752 const deps = external.map(dep => dep.globalName || 'null'); 9753 const parameters = external.map(m => m.name); 9754 if (hasExports && !name) { 9755 log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logMissingNameOptionForIifeExport()); 9756 } 9757 if (namedExportsMode && hasExports) { 9758 if (extend) { 9759 deps.unshift(`this${keypath(name, getPropertyAccess)}${_}=${_}this${keypath(name, getPropertyAccess)}${_}||${_}{}`); 9760 parameters.unshift('exports'); 9761 } 9762 else { 9763 deps.unshift('{}'); 9764 parameters.unshift('exports'); 9765 } 9766 } 9767 const useStrict = strict ? `${t}'use strict';${n}` : ''; 9768 const interopBlock = getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets); 9769 magicString.prepend(`${intro}${interopBlock}`); 9770 let wrapperIntro = `(${getNonArrowFunctionIntro(parameters, { 9771 isAsync: false, 9772 name: null 9773 })}{${n}${useStrict}${n}`; 9774 if (hasExports) { 9775 if (name && !(extend && namedExportsMode)) { 9776 wrapperIntro = 9777 (useVariableAssignment ? `var ${name}` : `this${keypath(name, getPropertyAccess)}`) + 9778 `${_}=${_}${wrapperIntro}`; 9779 } 9780 if (isNamespaced) { 9781 wrapperIntro = setupNamespace(name, 'this', globals, snippets, compact, log) + wrapperIntro; 9782 } 9783 } 9784 let wrapperOutro = `${n}${n}})(${deps.join(`,${_}`)});`; 9785 if (hasExports && !extend && namedExportsMode) { 9786 wrapperOutro = `${n}${n}${t}return exports;${wrapperOutro}`; 9787 } 9788 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal); 9789 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, esModule === true || (esModule === 'if-default-prop' && hasDefaultExport), symbols, snippets); 9790 if (namespaceMarkers) { 9791 namespaceMarkers = n + n + namespaceMarkers; 9792 } 9793 magicString 9794 .append(`${exportBlock}${namespaceMarkers}${outro}`) 9795 .indent(t) 9796 .prepend(wrapperIntro) 9797 .append(wrapperOutro); 9798 } 9799 9800 const MISSING_EXPORT_SHIM_VARIABLE = '_missingExportShim'; 9801 9802 function system(magicString, { accessedGlobals, dependencies, exports, hasExports, indent: t, intro, snippets, outro, usesTopLevelAwait }, { externalLiveBindings, freeze, name, generatedCode: { symbols }, strict, systemNullSetters }) { 9803 const { _, getFunctionIntro, getNonArrowFunctionIntro, n, s } = snippets; 9804 const { importBindings, setters, starExcludes } = analyzeDependencies(dependencies, exports, t, snippets); 9805 const registeredName = name ? `'${name}',${_}` : ''; 9806 const wrapperParameters = accessedGlobals.has('module') 9807 ? ['exports', 'module'] 9808 : hasExports 9809 ? ['exports'] 9810 : []; 9811 // factory function should be wrapped by parentheses to avoid lazy parsing, 9812 // cf. https://v8.dev/blog/preparser#pife 9813 let wrapperStart = `System.register(${registeredName}[` + 9814 dependencies.map(({ importPath }) => `'${importPath}'`).join(`,${_}`) + 9815 `],${_}(${getNonArrowFunctionIntro(wrapperParameters, { 9816 isAsync: false, 9817 name: null 9818 })}{${n}${t}${strict ? "'use strict';" : ''}` + 9819 getStarExcludesBlock(starExcludes, t, snippets) + 9820 getImportBindingsBlock(importBindings, t, snippets) + 9821 `${n}${t}return${_}{${setters.length > 0 9822 ? `${n}${t}${t}setters:${_}[${setters 9823 .map(setter => setter 9824 ? `${getFunctionIntro(['module'], { 9825 isAsync: false, 9826 name: null 9827 })}{${n}${t}${t}${t}${setter}${n}${t}${t}}` 9828 : systemNullSetters 9829 ? `null` 9830 : `${getFunctionIntro([], { isAsync: false, name: null })}{}`) 9831 .join(`,${_}`)}],` 9832 : ''}${n}`; 9833 wrapperStart += `${t}${t}execute:${_}(${getNonArrowFunctionIntro([], { 9834 isAsync: usesTopLevelAwait, 9835 name: null 9836 })}{${n}${n}`; 9837 const wrapperEnd = `${t}${t}})${n}${t}}${s}${n}}));`; 9838 magicString 9839 .prepend(intro + 9840 getHelpersBlock(null, accessedGlobals, t, snippets, externalLiveBindings, freeze, symbols) + 9841 getHoistedExportsBlock(exports, t, snippets)) 9842 .append(`${outro}${n}${n}` + 9843 getSyntheticExportsBlock(exports, t, snippets) + 9844 getMissingExportsBlock(exports, t, snippets)) 9845 .indent(`${t}${t}${t}`) 9846 .append(wrapperEnd) 9847 .prepend(wrapperStart); 9848 } 9849 function analyzeDependencies(dependencies, exports, t, { _, cnst, getObject, getPropertyAccess, n }) { 9850 const importBindings = []; 9851 const setters = []; 9852 let starExcludes = null; 9853 for (const { imports, reexports } of dependencies) { 9854 const setter = []; 9855 if (imports) { 9856 for (const specifier of imports) { 9857 importBindings.push(specifier.local); 9858 if (specifier.imported === '*') { 9859 setter.push(`${specifier.local}${_}=${_}module;`); 9860 } 9861 else { 9862 setter.push(`${specifier.local}${_}=${_}module${getPropertyAccess(specifier.imported)};`); 9863 } 9864 } 9865 } 9866 if (reexports) { 9867 const reexportedNames = []; 9868 let hasStarReexport = false; 9869 for (const { imported, reexported } of reexports) { 9870 if (reexported === '*') { 9871 hasStarReexport = true; 9872 } 9873 else { 9874 reexportedNames.push([ 9875 reexported, 9876 imported === '*' ? 'module' : `module${getPropertyAccess(imported)}` 9877 ]); 9878 } 9879 } 9880 if (reexportedNames.length > 1 || hasStarReexport) { 9881 if (hasStarReexport) { 9882 if (!starExcludes) { 9883 starExcludes = getStarExcludes({ dependencies, exports }); 9884 } 9885 reexportedNames.unshift([null, `__proto__:${_}null`]); 9886 const exportMapping = getObject(reexportedNames, { lineBreakIndent: null }); 9887 setter.push(`${cnst} setter${_}=${_}${exportMapping};`, `for${_}(${cnst} name in module)${_}{`, `${t}if${_}(!_starExcludes[name])${_}setter[name]${_}=${_}module[name];`, '}', 'exports(setter);'); 9888 } 9889 else { 9890 const exportMapping = getObject(reexportedNames, { lineBreakIndent: null }); 9891 setter.push(`exports(${exportMapping});`); 9892 } 9893 } 9894 else { 9895 const [key, value] = reexportedNames[0]; 9896 setter.push(`exports(${JSON.stringify(key)},${_}${value});`); 9897 } 9898 } 9899 setters.push(setter.join(`${n}${t}${t}${t}`)); 9900 } 9901 return { importBindings, setters, starExcludes }; 9902 } 9903 const getStarExcludes = ({ dependencies, exports }) => { 9904 const starExcludes = new Set(exports.map(expt => expt.exported)); 9905 starExcludes.add('default'); 9906 for (const { reexports } of dependencies) { 9907 if (reexports) { 9908 for (const reexport of reexports) { 9909 if (reexport.reexported !== '*') 9910 starExcludes.add(reexport.reexported); 9911 } 9912 } 9913 } 9914 return starExcludes; 9915 }; 9916 const getStarExcludesBlock = (starExcludes, t, { _, cnst, getObject, n }) => { 9917 if (starExcludes) { 9918 const fields = [...starExcludes].map(property => [ 9919 property, 9920 '1' 9921 ]); 9922 fields.unshift([null, `__proto__:${_}null`]); 9923 return `${n}${t}${cnst} _starExcludes${_}=${_}${getObject(fields, { 9924 lineBreakIndent: { base: t, t } 9925 })};`; 9926 } 9927 return ''; 9928 }; 9929 const getImportBindingsBlock = (importBindings, t, { _, n }) => (importBindings.length > 0 ? `${n}${t}var ${importBindings.join(`,${_}`)};` : ''); 9930 const getHoistedExportsBlock = (exports, t, snippets) => getExportsBlock(exports.filter(expt => expt.hoisted).map(expt => ({ name: expt.exported, value: expt.local })), t, snippets); 9931 function getExportsBlock(exports, t, { _, n }) { 9932 if (exports.length === 0) { 9933 return ''; 9934 } 9935 if (exports.length === 1) { 9936 return `exports(${JSON.stringify(exports[0].name)},${_}${exports[0].value});${n}${n}`; 9937 } 9938 return (`exports({${n}` + 9939 exports 9940 .map(({ name, value }) => `${t}${stringifyObjectKeyIfNeeded(name)}:${_}${value}`) 9941 .join(`,${n}`) + 9942 `${n}});${n}${n}`); 9943 } 9944 const getSyntheticExportsBlock = (exports, t, snippets) => getExportsBlock(exports 9945 .filter(expt => expt.expression) 9946 .map(expt => ({ name: expt.exported, value: expt.local })), t, snippets); 9947 const getMissingExportsBlock = (exports, t, snippets) => getExportsBlock(exports 9948 .filter(expt => expt.local === MISSING_EXPORT_SHIM_VARIABLE) 9949 .map(expt => ({ name: expt.exported, value: MISSING_EXPORT_SHIM_VARIABLE })), t, snippets); 9950 9951 function globalProperty(name, globalVariable, getPropertyAccess) { 9952 if (!name) 9953 return 'null'; 9954 return `${globalVariable}${keypath(name, getPropertyAccess)}`; 9955 } 9956 function safeAccess(name, globalVariable, { _, getPropertyAccess }) { 9957 let propertyPath = globalVariable; 9958 return name 9959 .split('.') 9960 .map(part => (propertyPath += getPropertyAccess(part))) 9961 .join(`${_}&&${_}`); 9962 } 9963 function umd(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, id, indent: t, intro, namedExportsMode, log, outro, snippets }, { amd, compact, esModule, extend, externalLiveBindings, freeze, interop, name, generatedCode: { symbols }, globals, noConflict, reexportProtoFromExternal, strict }) { 9964 const { _, cnst, getFunctionIntro, getNonArrowFunctionIntro, getPropertyAccess, n, s } = snippets; 9965 const factoryVariable = compact ? 'f' : 'factory'; 9966 const globalVariable = compact ? 'g' : 'global'; 9967 if (hasExports && !name) { 9968 return parseAst_js.error(parseAst_js.logMissingNameOptionForUmdExport()); 9969 } 9970 warnOnBuiltins(log, dependencies); 9971 const amdDeps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`); 9972 const cjsDeps = dependencies.map(m => `require('${m.importPath}')`); 9973 const trimmedImports = trimEmptyImports(dependencies); 9974 const globalDeps = trimmedImports.map(module => globalProperty(module.globalName, globalVariable, getPropertyAccess)); 9975 const factoryParameters = trimmedImports.map(m => m.name); 9976 if (namedExportsMode && (hasExports || noConflict)) { 9977 amdDeps.unshift(`'exports'`); 9978 cjsDeps.unshift(`exports`); 9979 globalDeps.unshift(assignToDeepVariable(name, globalVariable, globals, `${extend ? `${globalProperty(name, globalVariable, getPropertyAccess)}${_}||${_}` : ''}{}`, snippets, log)); 9980 factoryParameters.unshift('exports'); 9981 } 9982 const completeAmdId = getCompleteAmdId(amd, id); 9983 const amdParameters = (completeAmdId ? `'${completeAmdId}',${_}` : ``) + 9984 (amdDeps.length > 0 ? `[${amdDeps.join(`,${_}`)}],${_}` : ``); 9985 const define = amd.define; 9986 const cjsExport = !namedExportsMode && hasExports ? `module.exports${_}=${_}` : ``; 9987 const useStrict = strict ? `${_}'use strict';${n}` : ``; 9988 let iifeExport; 9989 if (noConflict) { 9990 const noConflictExportsVariable = compact ? 'e' : 'exports'; 9991 let factory; 9992 if (!namedExportsMode && hasExports) { 9993 factory = `${cnst} ${noConflictExportsVariable}${_}=${_}${assignToDeepVariable(name, globalVariable, globals, `${factoryVariable}(${globalDeps.join(`,${_}`)})`, snippets, log)};`; 9994 } 9995 else { 9996 const module = globalDeps.shift(); 9997 factory = 9998 `${cnst} ${noConflictExportsVariable}${_}=${_}${module};${n}` + 9999 `${t}${t}${factoryVariable}(${[noConflictExportsVariable, ...globalDeps].join(`,${_}`)});`; 10000 } 10001 iifeExport = 10002 `(${getFunctionIntro([], { isAsync: false, name: null })}{${n}` + 10003 `${t}${t}${cnst} current${_}=${_}${safeAccess(name, globalVariable, snippets)};${n}` + 10004 `${t}${t}${factory}${n}` + 10005 `${t}${t}${noConflictExportsVariable}.noConflict${_}=${_}${getFunctionIntro([], { 10006 isAsync: false, 10007 name: null 10008 })}{${_}` + 10009 `${globalProperty(name, globalVariable, getPropertyAccess)}${_}=${_}current;${_}return ${noConflictExportsVariable}${s}${_}};${n}` + 10010 `${t}})()`; 10011 } 10012 else { 10013 iifeExport = `${factoryVariable}(${globalDeps.join(`,${_}`)})`; 10014 if (!namedExportsMode && hasExports) { 10015 iifeExport = assignToDeepVariable(name, globalVariable, globals, iifeExport, snippets, log); 10016 } 10017 } 10018 const iifeNeedsGlobal = hasExports || (noConflict && namedExportsMode) || globalDeps.length > 0; 10019 const wrapperParameters = [factoryVariable]; 10020 if (iifeNeedsGlobal) { 10021 wrapperParameters.unshift(globalVariable); 10022 } 10023 const globalArgument = iifeNeedsGlobal ? `this,${_}` : ''; 10024 const iifeStart = iifeNeedsGlobal 10025 ? `(${globalVariable}${_}=${_}typeof globalThis${_}!==${_}'undefined'${_}?${_}globalThis${_}:${_}${globalVariable}${_}||${_}self,${_}` 10026 : ''; 10027 const iifeEnd = iifeNeedsGlobal ? ')' : ''; 10028 const cjsIntro = iifeNeedsGlobal 10029 ? `${t}typeof exports${_}===${_}'object'${_}&&${_}typeof module${_}!==${_}'undefined'${_}?` + 10030 `${_}${cjsExport}${factoryVariable}(${cjsDeps.join(`,${_}`)})${_}:${n}` 10031 : ''; 10032 const wrapperIntro = `(${getNonArrowFunctionIntro(wrapperParameters, { isAsync: false, name: null })}{${n}` + 10033 cjsIntro + 10034 `${t}typeof ${define}${_}===${_}'function'${_}&&${_}${define}.amd${_}?${_}${define}(${amdParameters}${factoryVariable})${_}:${n}` + 10035 `${t}${iifeStart}${iifeExport}${iifeEnd};${n}` + 10036 // factory function should be wrapped by parentheses to avoid lazy parsing, 10037 // cf. https://v8.dev/blog/preparser#pife 10038 `})(${globalArgument}(${getNonArrowFunctionIntro(factoryParameters, { 10039 isAsync: false, 10040 name: null 10041 })}{${useStrict}${n}`; 10042 const wrapperOutro = n + n + '}));'; 10043 magicString.prepend(`${intro}${getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets)}`); 10044 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal); 10045 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, esModule === true || (esModule === 'if-default-prop' && hasDefaultExport), symbols, snippets); 10046 if (namespaceMarkers) { 10047 namespaceMarkers = n + n + namespaceMarkers; 10048 } 10049 magicString 10050 .append(`${exportBlock}${namespaceMarkers}${outro}`) 10051 .trim() 10052 .indent(t) 10053 .append(wrapperOutro) 10054 .prepend(wrapperIntro); 10055 } 10056 10057 const finalisers = { amd, cjs, es, iife, system, umd }; 10058 10059 function getDefaultExportFromCjs (x) { 10060 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; 10061 } 10062 10063 function getAugmentedNamespace(n) { 10064 if (n.__esModule) return n; 10065 var f = n.default; 10066 if (typeof f == "function") { 10067 var a = function a () { 10068 if (this instanceof a) { 10069 return Reflect.construct(f, arguments, this.constructor); 10070 } 10071 return f.apply(this, arguments); 10072 }; 10073 a.prototype = f.prototype; 10074 } else a = {}; 10075 Object.defineProperty(a, '__esModule', {value: true}); 10076 Object.keys(n).forEach(function (k) { 10077 var d = Object.getOwnPropertyDescriptor(n, k); 10078 Object.defineProperty(a, k, d.get ? d : { 10079 enumerable: true, 10080 get: function () { 10081 return n[k]; 10082 } 10083 }); 10084 }); 10085 return a; 10086 } 10087 10088 var utils = {}; 10089 10090 var constants; 10091 var hasRequiredConstants; 10092 10093 function requireConstants () { 10094 if (hasRequiredConstants) return constants; 10095 hasRequiredConstants = 1; 10096 10097 const WIN_SLASH = '\\\\/'; 10098 const WIN_NO_SLASH = `[^${WIN_SLASH}]`; 10099 10100 /** 10101 * Posix glob regex 10102 */ 10103 10104 const DOT_LITERAL = '\\.'; 10105 const PLUS_LITERAL = '\\+'; 10106 const QMARK_LITERAL = '\\?'; 10107 const SLASH_LITERAL = '\\/'; 10108 const ONE_CHAR = '(?=.)'; 10109 const QMARK = '[^/]'; 10110 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; 10111 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; 10112 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; 10113 const NO_DOT = `(?!${DOT_LITERAL})`; 10114 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; 10115 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; 10116 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; 10117 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; 10118 const STAR = `${QMARK}*?`; 10119 const SEP = '/'; 10120 10121 const POSIX_CHARS = { 10122 DOT_LITERAL, 10123 PLUS_LITERAL, 10124 QMARK_LITERAL, 10125 SLASH_LITERAL, 10126 ONE_CHAR, 10127 QMARK, 10128 END_ANCHOR, 10129 DOTS_SLASH, 10130 NO_DOT, 10131 NO_DOTS, 10132 NO_DOT_SLASH, 10133 NO_DOTS_SLASH, 10134 QMARK_NO_DOT, 10135 STAR, 10136 START_ANCHOR, 10137 SEP 10138 }; 10139 10140 /** 10141 * Windows glob regex 10142 */ 10143 10144 const WINDOWS_CHARS = { 10145 ...POSIX_CHARS, 10146 10147 SLASH_LITERAL: `[${WIN_SLASH}]`, 10148 QMARK: WIN_NO_SLASH, 10149 STAR: `${WIN_NO_SLASH}*?`, 10150 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, 10151 NO_DOT: `(?!${DOT_LITERAL})`, 10152 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 10153 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, 10154 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 10155 QMARK_NO_DOT: `[^.${WIN_SLASH}]`, 10156 START_ANCHOR: `(?:^|[${WIN_SLASH}])`, 10157 END_ANCHOR: `(?:[${WIN_SLASH}]|$)`, 10158 SEP: '\\' 10159 }; 10160 10161 /** 10162 * POSIX Bracket Regex 10163 */ 10164 10165 const POSIX_REGEX_SOURCE = { 10166 alnum: 'a-zA-Z0-9', 10167 alpha: 'a-zA-Z', 10168 ascii: '\\x00-\\x7F', 10169 blank: ' \\t', 10170 cntrl: '\\x00-\\x1F\\x7F', 10171 digit: '0-9', 10172 graph: '\\x21-\\x7E', 10173 lower: 'a-z', 10174 print: '\\x20-\\x7E ', 10175 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', 10176 space: ' \\t\\r\\n\\v\\f', 10177 upper: 'A-Z', 10178 word: 'A-Za-z0-9_', 10179 xdigit: 'A-Fa-f0-9' 10180 }; 10181 10182 constants = { 10183 MAX_LENGTH: 1024 * 64, 10184 POSIX_REGEX_SOURCE, 10185 10186 // regular expressions 10187 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, 10188 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, 10189 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, 10190 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, 10191 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, 10192 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, 10193 10194 // Replace globs with equivalent patterns to reduce parsing time. 10195 REPLACEMENTS: { 10196 '***': '*', 10197 '**/**': '**', 10198 '**/**/**': '**' 10199 }, 10200 10201 // Digits 10202 CHAR_0: 48, /* 0 */ 10203 CHAR_9: 57, /* 9 */ 10204 10205 // Alphabet chars. 10206 CHAR_UPPERCASE_A: 65, /* A */ 10207 CHAR_LOWERCASE_A: 97, /* a */ 10208 CHAR_UPPERCASE_Z: 90, /* Z */ 10209 CHAR_LOWERCASE_Z: 122, /* z */ 10210 10211 CHAR_LEFT_PARENTHESES: 40, /* ( */ 10212 CHAR_RIGHT_PARENTHESES: 41, /* ) */ 10213 10214 CHAR_ASTERISK: 42, /* * */ 10215 10216 // Non-alphabetic chars. 10217 CHAR_AMPERSAND: 38, /* & */ 10218 CHAR_AT: 64, /* @ */ 10219 CHAR_BACKWARD_SLASH: 92, /* \ */ 10220 CHAR_CARRIAGE_RETURN: 13, /* \r */ 10221 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ 10222 CHAR_COLON: 58, /* : */ 10223 CHAR_COMMA: 44, /* , */ 10224 CHAR_DOT: 46, /* . */ 10225 CHAR_DOUBLE_QUOTE: 34, /* " */ 10226 CHAR_EQUAL: 61, /* = */ 10227 CHAR_EXCLAMATION_MARK: 33, /* ! */ 10228 CHAR_FORM_FEED: 12, /* \f */ 10229 CHAR_FORWARD_SLASH: 47, /* / */ 10230 CHAR_GRAVE_ACCENT: 96, /* ` */ 10231 CHAR_HASH: 35, /* # */ 10232 CHAR_HYPHEN_MINUS: 45, /* - */ 10233 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ 10234 CHAR_LEFT_CURLY_BRACE: 123, /* { */ 10235 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ 10236 CHAR_LINE_FEED: 10, /* \n */ 10237 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ 10238 CHAR_PERCENT: 37, /* % */ 10239 CHAR_PLUS: 43, /* + */ 10240 CHAR_QUESTION_MARK: 63, /* ? */ 10241 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ 10242 CHAR_RIGHT_CURLY_BRACE: 125, /* } */ 10243 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ 10244 CHAR_SEMICOLON: 59, /* ; */ 10245 CHAR_SINGLE_QUOTE: 39, /* ' */ 10246 CHAR_SPACE: 32, /* */ 10247 CHAR_TAB: 9, /* \t */ 10248 CHAR_UNDERSCORE: 95, /* _ */ 10249 CHAR_VERTICAL_LINE: 124, /* | */ 10250 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ 10251 10252 /** 10253 * Create EXTGLOB_CHARS 10254 */ 10255 10256 extglobChars(chars) { 10257 return { 10258 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, 10259 '?': { type: 'qmark', open: '(?:', close: ')?' }, 10260 '+': { type: 'plus', open: '(?:', close: ')+' }, 10261 '*': { type: 'star', open: '(?:', close: ')*' }, 10262 '@': { type: 'at', open: '(?:', close: ')' } 10263 }; 10264 }, 10265 10266 /** 10267 * Create GLOB_CHARS 10268 */ 10269 10270 globChars(win32) { 10271 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; 10272 } 10273 }; 10274 return constants; 10275 } 10276 10277 /*global navigator*/ 10278 10279 var hasRequiredUtils; 10280 10281 function requireUtils () { 10282 if (hasRequiredUtils) return utils; 10283 hasRequiredUtils = 1; 10284 (function (exports) { 10285 10286 const { 10287 REGEX_BACKSLASH, 10288 REGEX_REMOVE_BACKSLASH, 10289 REGEX_SPECIAL_CHARS, 10290 REGEX_SPECIAL_CHARS_GLOBAL 10291 } = /*@__PURE__*/ requireConstants(); 10292 10293 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); 10294 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); 10295 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); 10296 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); 10297 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); 10298 10299 exports.isWindows = () => { 10300 if (typeof navigator !== 'undefined' && navigator.platform) { 10301 const platform = navigator.platform.toLowerCase(); 10302 return platform === 'win32' || platform === 'windows'; 10303 } 10304 10305 if (typeof process !== 'undefined' && process.platform) { 10306 return process.platform === 'win32'; 10307 } 10308 10309 return false; 10310 }; 10311 10312 exports.removeBackslashes = str => { 10313 return str.replace(REGEX_REMOVE_BACKSLASH, match => { 10314 return match === '\\' ? '' : match; 10315 }); 10316 }; 10317 10318 exports.escapeLast = (input, char, lastIdx) => { 10319 const idx = input.lastIndexOf(char, lastIdx); 10320 if (idx === -1) return input; 10321 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); 10322 return `${input.slice(0, idx)}\\${input.slice(idx)}`; 10323 }; 10324 10325 exports.removePrefix = (input, state = {}) => { 10326 let output = input; 10327 if (output.startsWith('./')) { 10328 output = output.slice(2); 10329 state.prefix = './'; 10330 } 10331 return output; 10332 }; 10333 10334 exports.wrapOutput = (input, state = {}, options = {}) => { 10335 const prepend = options.contains ? '' : '^'; 10336 const append = options.contains ? '' : '$'; 10337 10338 let output = `${prepend}(?:${input})${append}`; 10339 if (state.negated === true) { 10340 output = `(?:^(?!${output}).*$)`; 10341 } 10342 return output; 10343 }; 10344 10345 exports.basename = (path, { windows } = {}) => { 10346 const segs = path.split(windows ? /[\\/]/ : '/'); 10347 const last = segs[segs.length - 1]; 10348 10349 if (last === '') { 10350 return segs[segs.length - 2]; 10351 } 10352 10353 return last; 10354 }; 10355 } (utils)); 10356 return utils; 10357 } 10358 10359 var scan_1; 10360 var hasRequiredScan; 10361 10362 function requireScan () { 10363 if (hasRequiredScan) return scan_1; 10364 hasRequiredScan = 1; 10365 10366 const utils = /*@__PURE__*/ requireUtils(); 10367 const { 10368 CHAR_ASTERISK, /* * */ 10369 CHAR_AT, /* @ */ 10370 CHAR_BACKWARD_SLASH, /* \ */ 10371 CHAR_COMMA, /* , */ 10372 CHAR_DOT, /* . */ 10373 CHAR_EXCLAMATION_MARK, /* ! */ 10374 CHAR_FORWARD_SLASH, /* / */ 10375 CHAR_LEFT_CURLY_BRACE, /* { */ 10376 CHAR_LEFT_PARENTHESES, /* ( */ 10377 CHAR_LEFT_SQUARE_BRACKET, /* [ */ 10378 CHAR_PLUS, /* + */ 10379 CHAR_QUESTION_MARK, /* ? */ 10380 CHAR_RIGHT_CURLY_BRACE, /* } */ 10381 CHAR_RIGHT_PARENTHESES, /* ) */ 10382 CHAR_RIGHT_SQUARE_BRACKET /* ] */ 10383 } = /*@__PURE__*/ requireConstants(); 10384 10385 const isPathSeparator = code => { 10386 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; 10387 }; 10388 10389 const depth = token => { 10390 if (token.isPrefix !== true) { 10391 token.depth = token.isGlobstar ? Infinity : 1; 10392 } 10393 }; 10394 10395 /** 10396 * Quickly scans a glob pattern and returns an object with a handful of 10397 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), 10398 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not 10399 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). 10400 * 10401 * ```js 10402 * const pm = require('picomatch'); 10403 * console.log(pm.scan('foo/bar/*.js')); 10404 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } 10405 * ``` 10406 * @param {String} `str` 10407 * @param {Object} `options` 10408 * @return {Object} Returns an object with tokens and regex source string. 10409 * @api public 10410 */ 10411 10412 const scan = (input, options) => { 10413 const opts = options || {}; 10414 10415 const length = input.length - 1; 10416 const scanToEnd = opts.parts === true || opts.scanToEnd === true; 10417 const slashes = []; 10418 const tokens = []; 10419 const parts = []; 10420 10421 let str = input; 10422 let index = -1; 10423 let start = 0; 10424 let lastIndex = 0; 10425 let isBrace = false; 10426 let isBracket = false; 10427 let isGlob = false; 10428 let isExtglob = false; 10429 let isGlobstar = false; 10430 let braceEscaped = false; 10431 let backslashes = false; 10432 let negated = false; 10433 let negatedExtglob = false; 10434 let finished = false; 10435 let braces = 0; 10436 let prev; 10437 let code; 10438 let token = { value: '', depth: 0, isGlob: false }; 10439 10440 const eos = () => index >= length; 10441 const peek = () => str.charCodeAt(index + 1); 10442 const advance = () => { 10443 prev = code; 10444 return str.charCodeAt(++index); 10445 }; 10446 10447 while (index < length) { 10448 code = advance(); 10449 let next; 10450 10451 if (code === CHAR_BACKWARD_SLASH) { 10452 backslashes = token.backslashes = true; 10453 code = advance(); 10454 10455 if (code === CHAR_LEFT_CURLY_BRACE) { 10456 braceEscaped = true; 10457 } 10458 continue; 10459 } 10460 10461 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { 10462 braces++; 10463 10464 while (eos() !== true && (code = advance())) { 10465 if (code === CHAR_BACKWARD_SLASH) { 10466 backslashes = token.backslashes = true; 10467 advance(); 10468 continue; 10469 } 10470 10471 if (code === CHAR_LEFT_CURLY_BRACE) { 10472 braces++; 10473 continue; 10474 } 10475 10476 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { 10477 isBrace = token.isBrace = true; 10478 isGlob = token.isGlob = true; 10479 finished = true; 10480 10481 if (scanToEnd === true) { 10482 continue; 10483 } 10484 10485 break; 10486 } 10487 10488 if (braceEscaped !== true && code === CHAR_COMMA) { 10489 isBrace = token.isBrace = true; 10490 isGlob = token.isGlob = true; 10491 finished = true; 10492 10493 if (scanToEnd === true) { 10494 continue; 10495 } 10496 10497 break; 10498 } 10499 10500 if (code === CHAR_RIGHT_CURLY_BRACE) { 10501 braces--; 10502 10503 if (braces === 0) { 10504 braceEscaped = false; 10505 isBrace = token.isBrace = true; 10506 finished = true; 10507 break; 10508 } 10509 } 10510 } 10511 10512 if (scanToEnd === true) { 10513 continue; 10514 } 10515 10516 break; 10517 } 10518 10519 if (code === CHAR_FORWARD_SLASH) { 10520 slashes.push(index); 10521 tokens.push(token); 10522 token = { value: '', depth: 0, isGlob: false }; 10523 10524 if (finished === true) continue; 10525 if (prev === CHAR_DOT && index === (start + 1)) { 10526 start += 2; 10527 continue; 10528 } 10529 10530 lastIndex = index + 1; 10531 continue; 10532 } 10533 10534 if (opts.noext !== true) { 10535 const isExtglobChar = code === CHAR_PLUS 10536 || code === CHAR_AT 10537 || code === CHAR_ASTERISK 10538 || code === CHAR_QUESTION_MARK 10539 || code === CHAR_EXCLAMATION_MARK; 10540 10541 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { 10542 isGlob = token.isGlob = true; 10543 isExtglob = token.isExtglob = true; 10544 finished = true; 10545 if (code === CHAR_EXCLAMATION_MARK && index === start) { 10546 negatedExtglob = true; 10547 } 10548 10549 if (scanToEnd === true) { 10550 while (eos() !== true && (code = advance())) { 10551 if (code === CHAR_BACKWARD_SLASH) { 10552 backslashes = token.backslashes = true; 10553 code = advance(); 10554 continue; 10555 } 10556 10557 if (code === CHAR_RIGHT_PARENTHESES) { 10558 isGlob = token.isGlob = true; 10559 finished = true; 10560 break; 10561 } 10562 } 10563 continue; 10564 } 10565 break; 10566 } 10567 } 10568 10569 if (code === CHAR_ASTERISK) { 10570 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; 10571 isGlob = token.isGlob = true; 10572 finished = true; 10573 10574 if (scanToEnd === true) { 10575 continue; 10576 } 10577 break; 10578 } 10579 10580 if (code === CHAR_QUESTION_MARK) { 10581 isGlob = token.isGlob = true; 10582 finished = true; 10583 10584 if (scanToEnd === true) { 10585 continue; 10586 } 10587 break; 10588 } 10589 10590 if (code === CHAR_LEFT_SQUARE_BRACKET) { 10591 while (eos() !== true && (next = advance())) { 10592 if (next === CHAR_BACKWARD_SLASH) { 10593 backslashes = token.backslashes = true; 10594 advance(); 10595 continue; 10596 } 10597 10598 if (next === CHAR_RIGHT_SQUARE_BRACKET) { 10599 isBracket = token.isBracket = true; 10600 isGlob = token.isGlob = true; 10601 finished = true; 10602 break; 10603 } 10604 } 10605 10606 if (scanToEnd === true) { 10607 continue; 10608 } 10609 10610 break; 10611 } 10612 10613 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { 10614 negated = token.negated = true; 10615 start++; 10616 continue; 10617 } 10618 10619 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { 10620 isGlob = token.isGlob = true; 10621 10622 if (scanToEnd === true) { 10623 while (eos() !== true && (code = advance())) { 10624 if (code === CHAR_LEFT_PARENTHESES) { 10625 backslashes = token.backslashes = true; 10626 code = advance(); 10627 continue; 10628 } 10629 10630 if (code === CHAR_RIGHT_PARENTHESES) { 10631 finished = true; 10632 break; 10633 } 10634 } 10635 continue; 10636 } 10637 break; 10638 } 10639 10640 if (isGlob === true) { 10641 finished = true; 10642 10643 if (scanToEnd === true) { 10644 continue; 10645 } 10646 10647 break; 10648 } 10649 } 10650 10651 if (opts.noext === true) { 10652 isExtglob = false; 10653 isGlob = false; 10654 } 10655 10656 let base = str; 10657 let prefix = ''; 10658 let glob = ''; 10659 10660 if (start > 0) { 10661 prefix = str.slice(0, start); 10662 str = str.slice(start); 10663 lastIndex -= start; 10664 } 10665 10666 if (base && isGlob === true && lastIndex > 0) { 10667 base = str.slice(0, lastIndex); 10668 glob = str.slice(lastIndex); 10669 } else if (isGlob === true) { 10670 base = ''; 10671 glob = str; 10672 } else { 10673 base = str; 10674 } 10675 10676 if (base && base !== '' && base !== '/' && base !== str) { 10677 if (isPathSeparator(base.charCodeAt(base.length - 1))) { 10678 base = base.slice(0, -1); 10679 } 10680 } 10681 10682 if (opts.unescape === true) { 10683 if (glob) glob = utils.removeBackslashes(glob); 10684 10685 if (base && backslashes === true) { 10686 base = utils.removeBackslashes(base); 10687 } 10688 } 10689 10690 const state = { 10691 prefix, 10692 input, 10693 start, 10694 base, 10695 glob, 10696 isBrace, 10697 isBracket, 10698 isGlob, 10699 isExtglob, 10700 isGlobstar, 10701 negated, 10702 negatedExtglob 10703 }; 10704 10705 if (opts.tokens === true) { 10706 state.maxDepth = 0; 10707 if (!isPathSeparator(code)) { 10708 tokens.push(token); 10709 } 10710 state.tokens = tokens; 10711 } 10712 10713 if (opts.parts === true || opts.tokens === true) { 10714 let prevIndex; 10715 10716 for (let idx = 0; idx < slashes.length; idx++) { 10717 const n = prevIndex ? prevIndex + 1 : start; 10718 const i = slashes[idx]; 10719 const value = input.slice(n, i); 10720 if (opts.tokens) { 10721 if (idx === 0 && start !== 0) { 10722 tokens[idx].isPrefix = true; 10723 tokens[idx].value = prefix; 10724 } else { 10725 tokens[idx].value = value; 10726 } 10727 depth(tokens[idx]); 10728 state.maxDepth += tokens[idx].depth; 10729 } 10730 if (idx !== 0 || value !== '') { 10731 parts.push(value); 10732 } 10733 prevIndex = i; 10734 } 10735 10736 if (prevIndex && prevIndex + 1 < input.length) { 10737 const value = input.slice(prevIndex + 1); 10738 parts.push(value); 10739 10740 if (opts.tokens) { 10741 tokens[tokens.length - 1].value = value; 10742 depth(tokens[tokens.length - 1]); 10743 state.maxDepth += tokens[tokens.length - 1].depth; 10744 } 10745 } 10746 10747 state.slashes = slashes; 10748 state.parts = parts; 10749 } 10750 10751 return state; 10752 }; 10753 10754 scan_1 = scan; 10755 return scan_1; 10756 } 10757 10758 var parse_1; 10759 var hasRequiredParse; 10760 10761 function requireParse () { 10762 if (hasRequiredParse) return parse_1; 10763 hasRequiredParse = 1; 10764 10765 const constants = /*@__PURE__*/ requireConstants(); 10766 const utils = /*@__PURE__*/ requireUtils(); 10767 10768 /** 10769 * Constants 10770 */ 10771 10772 const { 10773 MAX_LENGTH, 10774 POSIX_REGEX_SOURCE, 10775 REGEX_NON_SPECIAL_CHARS, 10776 REGEX_SPECIAL_CHARS_BACKREF, 10777 REPLACEMENTS 10778 } = constants; 10779 10780 /** 10781 * Helpers 10782 */ 10783 10784 const expandRange = (args, options) => { 10785 if (typeof options.expandRange === 'function') { 10786 return options.expandRange(...args, options); 10787 } 10788 10789 args.sort(); 10790 const value = `[${args.join('-')}]`; 10791 10792 return value; 10793 }; 10794 10795 /** 10796 * Create the message for a syntax error 10797 */ 10798 10799 const syntaxError = (type, char) => { 10800 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; 10801 }; 10802 10803 /** 10804 * Parse the given input string. 10805 * @param {String} input 10806 * @param {Object} options 10807 * @return {Object} 10808 */ 10809 10810 const parse = (input, options) => { 10811 if (typeof input !== 'string') { 10812 throw new TypeError('Expected a string'); 10813 } 10814 10815 input = REPLACEMENTS[input] || input; 10816 10817 const opts = { ...options }; 10818 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 10819 10820 let len = input.length; 10821 if (len > max) { 10822 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 10823 } 10824 10825 const bos = { type: 'bos', value: '', output: opts.prepend || '' }; 10826 const tokens = [bos]; 10827 10828 const capture = opts.capture ? '' : '?:'; 10829 10830 // create constants based on platform, for windows or posix 10831 const PLATFORM_CHARS = constants.globChars(opts.windows); 10832 const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); 10833 10834 const { 10835 DOT_LITERAL, 10836 PLUS_LITERAL, 10837 SLASH_LITERAL, 10838 ONE_CHAR, 10839 DOTS_SLASH, 10840 NO_DOT, 10841 NO_DOT_SLASH, 10842 NO_DOTS_SLASH, 10843 QMARK, 10844 QMARK_NO_DOT, 10845 STAR, 10846 START_ANCHOR 10847 } = PLATFORM_CHARS; 10848 10849 const globstar = opts => { 10850 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 10851 }; 10852 10853 const nodot = opts.dot ? '' : NO_DOT; 10854 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; 10855 let star = opts.bash === true ? globstar(opts) : STAR; 10856 10857 if (opts.capture) { 10858 star = `(${star})`; 10859 } 10860 10861 // minimatch options support 10862 if (typeof opts.noext === 'boolean') { 10863 opts.noextglob = opts.noext; 10864 } 10865 10866 const state = { 10867 input, 10868 index: -1, 10869 start: 0, 10870 dot: opts.dot === true, 10871 consumed: '', 10872 output: '', 10873 prefix: '', 10874 backtrack: false, 10875 negated: false, 10876 brackets: 0, 10877 braces: 0, 10878 parens: 0, 10879 quotes: 0, 10880 globstar: false, 10881 tokens 10882 }; 10883 10884 input = utils.removePrefix(input, state); 10885 len = input.length; 10886 10887 const extglobs = []; 10888 const braces = []; 10889 const stack = []; 10890 let prev = bos; 10891 let value; 10892 10893 /** 10894 * Tokenizing helpers 10895 */ 10896 10897 const eos = () => state.index === len - 1; 10898 const peek = state.peek = (n = 1) => input[state.index + n]; 10899 const advance = state.advance = () => input[++state.index] || ''; 10900 const remaining = () => input.slice(state.index + 1); 10901 const consume = (value = '', num = 0) => { 10902 state.consumed += value; 10903 state.index += num; 10904 }; 10905 10906 const append = token => { 10907 state.output += token.output != null ? token.output : token.value; 10908 consume(token.value); 10909 }; 10910 10911 const negate = () => { 10912 let count = 1; 10913 10914 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { 10915 advance(); 10916 state.start++; 10917 count++; 10918 } 10919 10920 if (count % 2 === 0) { 10921 return false; 10922 } 10923 10924 state.negated = true; 10925 state.start++; 10926 return true; 10927 }; 10928 10929 const increment = type => { 10930 state[type]++; 10931 stack.push(type); 10932 }; 10933 10934 const decrement = type => { 10935 state[type]--; 10936 stack.pop(); 10937 }; 10938 10939 /** 10940 * Push tokens onto the tokens array. This helper speeds up 10941 * tokenizing by 1) helping us avoid backtracking as much as possible, 10942 * and 2) helping us avoid creating extra tokens when consecutive 10943 * characters are plain text. This improves performance and simplifies 10944 * lookbehinds. 10945 */ 10946 10947 const push = tok => { 10948 if (prev.type === 'globstar') { 10949 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); 10950 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); 10951 10952 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { 10953 state.output = state.output.slice(0, -prev.output.length); 10954 prev.type = 'star'; 10955 prev.value = '*'; 10956 prev.output = star; 10957 state.output += prev.output; 10958 } 10959 } 10960 10961 if (extglobs.length && tok.type !== 'paren') { 10962 extglobs[extglobs.length - 1].inner += tok.value; 10963 } 10964 10965 if (tok.value || tok.output) append(tok); 10966 if (prev && prev.type === 'text' && tok.type === 'text') { 10967 prev.output = (prev.output || prev.value) + tok.value; 10968 prev.value += tok.value; 10969 return; 10970 } 10971 10972 tok.prev = prev; 10973 tokens.push(tok); 10974 prev = tok; 10975 }; 10976 10977 const extglobOpen = (type, value) => { 10978 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; 10979 10980 token.prev = prev; 10981 token.parens = state.parens; 10982 token.output = state.output; 10983 const output = (opts.capture ? '(' : '') + token.open; 10984 10985 increment('parens'); 10986 push({ type, value, output: state.output ? '' : ONE_CHAR }); 10987 push({ type: 'paren', extglob: true, value: advance(), output }); 10988 extglobs.push(token); 10989 }; 10990 10991 const extglobClose = token => { 10992 let output = token.close + (opts.capture ? ')' : ''); 10993 let rest; 10994 10995 if (token.type === 'negate') { 10996 let extglobStar = star; 10997 10998 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { 10999 extglobStar = globstar(opts); 11000 } 11001 11002 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { 11003 output = token.close = `)$))${extglobStar}`; 11004 } 11005 11006 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { 11007 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis. 11008 // In this case, we need to parse the string and use it in the output of the original pattern. 11009 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`. 11010 // 11011 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`. 11012 const expression = parse(rest, { ...options, fastpaths: false }).output; 11013 11014 output = token.close = `)${expression})${extglobStar})`; 11015 } 11016 11017 if (token.prev.type === 'bos') { 11018 state.negatedExtglob = true; 11019 } 11020 } 11021 11022 push({ type: 'paren', extglob: true, value, output }); 11023 decrement('parens'); 11024 }; 11025 11026 /** 11027 * Fast paths 11028 */ 11029 11030 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { 11031 let backslashes = false; 11032 11033 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { 11034 if (first === '\\') { 11035 backslashes = true; 11036 return m; 11037 } 11038 11039 if (first === '?') { 11040 if (esc) { 11041 return esc + first + (rest ? QMARK.repeat(rest.length) : ''); 11042 } 11043 if (index === 0) { 11044 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); 11045 } 11046 return QMARK.repeat(chars.length); 11047 } 11048 11049 if (first === '.') { 11050 return DOT_LITERAL.repeat(chars.length); 11051 } 11052 11053 if (first === '*') { 11054 if (esc) { 11055 return esc + first + (rest ? star : ''); 11056 } 11057 return star; 11058 } 11059 return esc ? m : `\\${m}`; 11060 }); 11061 11062 if (backslashes === true) { 11063 if (opts.unescape === true) { 11064 output = output.replace(/\\/g, ''); 11065 } else { 11066 output = output.replace(/\\+/g, m => { 11067 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); 11068 }); 11069 } 11070 } 11071 11072 if (output === input && opts.contains === true) { 11073 state.output = input; 11074 return state; 11075 } 11076 11077 state.output = utils.wrapOutput(output, state, options); 11078 return state; 11079 } 11080 11081 /** 11082 * Tokenize input until we reach end-of-string 11083 */ 11084 11085 while (!eos()) { 11086 value = advance(); 11087 11088 if (value === '\u0000') { 11089 continue; 11090 } 11091 11092 /** 11093 * Escaped characters 11094 */ 11095 11096 if (value === '\\') { 11097 const next = peek(); 11098 11099 if (next === '/' && opts.bash !== true) { 11100 continue; 11101 } 11102 11103 if (next === '.' || next === ';') { 11104 continue; 11105 } 11106 11107 if (!next) { 11108 value += '\\'; 11109 push({ type: 'text', value }); 11110 continue; 11111 } 11112 11113 // collapse slashes to reduce potential for exploits 11114 const match = /^\\+/.exec(remaining()); 11115 let slashes = 0; 11116 11117 if (match && match[0].length > 2) { 11118 slashes = match[0].length; 11119 state.index += slashes; 11120 if (slashes % 2 !== 0) { 11121 value += '\\'; 11122 } 11123 } 11124 11125 if (opts.unescape === true) { 11126 value = advance(); 11127 } else { 11128 value += advance(); 11129 } 11130 11131 if (state.brackets === 0) { 11132 push({ type: 'text', value }); 11133 continue; 11134 } 11135 } 11136 11137 /** 11138 * If we're inside a regex character class, continue 11139 * until we reach the closing bracket. 11140 */ 11141 11142 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { 11143 if (opts.posix !== false && value === ':') { 11144 const inner = prev.value.slice(1); 11145 if (inner.includes('[')) { 11146 prev.posix = true; 11147 11148 if (inner.includes(':')) { 11149 const idx = prev.value.lastIndexOf('['); 11150 const pre = prev.value.slice(0, idx); 11151 const rest = prev.value.slice(idx + 2); 11152 const posix = POSIX_REGEX_SOURCE[rest]; 11153 if (posix) { 11154 prev.value = pre + posix; 11155 state.backtrack = true; 11156 advance(); 11157 11158 if (!bos.output && tokens.indexOf(prev) === 1) { 11159 bos.output = ONE_CHAR; 11160 } 11161 continue; 11162 } 11163 } 11164 } 11165 } 11166 11167 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { 11168 value = `\\${value}`; 11169 } 11170 11171 if (value === ']' && (prev.value === '[' || prev.value === '[^')) { 11172 value = `\\${value}`; 11173 } 11174 11175 if (opts.posix === true && value === '!' && prev.value === '[') { 11176 value = '^'; 11177 } 11178 11179 prev.value += value; 11180 append({ value }); 11181 continue; 11182 } 11183 11184 /** 11185 * If we're inside a quoted string, continue 11186 * until we reach the closing double quote. 11187 */ 11188 11189 if (state.quotes === 1 && value !== '"') { 11190 value = utils.escapeRegex(value); 11191 prev.value += value; 11192 append({ value }); 11193 continue; 11194 } 11195 11196 /** 11197 * Double quotes 11198 */ 11199 11200 if (value === '"') { 11201 state.quotes = state.quotes === 1 ? 0 : 1; 11202 if (opts.keepQuotes === true) { 11203 push({ type: 'text', value }); 11204 } 11205 continue; 11206 } 11207 11208 /** 11209 * Parentheses 11210 */ 11211 11212 if (value === '(') { 11213 increment('parens'); 11214 push({ type: 'paren', value }); 11215 continue; 11216 } 11217 11218 if (value === ')') { 11219 if (state.parens === 0 && opts.strictBrackets === true) { 11220 throw new SyntaxError(syntaxError('opening', '(')); 11221 } 11222 11223 const extglob = extglobs[extglobs.length - 1]; 11224 if (extglob && state.parens === extglob.parens + 1) { 11225 extglobClose(extglobs.pop()); 11226 continue; 11227 } 11228 11229 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); 11230 decrement('parens'); 11231 continue; 11232 } 11233 11234 /** 11235 * Square brackets 11236 */ 11237 11238 if (value === '[') { 11239 if (opts.nobracket === true || !remaining().includes(']')) { 11240 if (opts.nobracket !== true && opts.strictBrackets === true) { 11241 throw new SyntaxError(syntaxError('closing', ']')); 11242 } 11243 11244 value = `\\${value}`; 11245 } else { 11246 increment('brackets'); 11247 } 11248 11249 push({ type: 'bracket', value }); 11250 continue; 11251 } 11252 11253 if (value === ']') { 11254 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { 11255 push({ type: 'text', value, output: `\\${value}` }); 11256 continue; 11257 } 11258 11259 if (state.brackets === 0) { 11260 if (opts.strictBrackets === true) { 11261 throw new SyntaxError(syntaxError('opening', '[')); 11262 } 11263 11264 push({ type: 'text', value, output: `\\${value}` }); 11265 continue; 11266 } 11267 11268 decrement('brackets'); 11269 11270 const prevValue = prev.value.slice(1); 11271 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { 11272 value = `/${value}`; 11273 } 11274 11275 prev.value += value; 11276 append({ value }); 11277 11278 // when literal brackets are explicitly disabled 11279 // assume we should match with a regex character class 11280 if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { 11281 continue; 11282 } 11283 11284 const escaped = utils.escapeRegex(prev.value); 11285 state.output = state.output.slice(0, -prev.value.length); 11286 11287 // when literal brackets are explicitly enabled 11288 // assume we should escape the brackets to match literal characters 11289 if (opts.literalBrackets === true) { 11290 state.output += escaped; 11291 prev.value = escaped; 11292 continue; 11293 } 11294 11295 // when the user specifies nothing, try to match both 11296 prev.value = `(${capture}${escaped}|${prev.value})`; 11297 state.output += prev.value; 11298 continue; 11299 } 11300 11301 /** 11302 * Braces 11303 */ 11304 11305 if (value === '{' && opts.nobrace !== true) { 11306 increment('braces'); 11307 11308 const open = { 11309 type: 'brace', 11310 value, 11311 output: '(', 11312 outputIndex: state.output.length, 11313 tokensIndex: state.tokens.length 11314 }; 11315 11316 braces.push(open); 11317 push(open); 11318 continue; 11319 } 11320 11321 if (value === '}') { 11322 const brace = braces[braces.length - 1]; 11323 11324 if (opts.nobrace === true || !brace) { 11325 push({ type: 'text', value, output: value }); 11326 continue; 11327 } 11328 11329 let output = ')'; 11330 11331 if (brace.dots === true) { 11332 const arr = tokens.slice(); 11333 const range = []; 11334 11335 for (let i = arr.length - 1; i >= 0; i--) { 11336 tokens.pop(); 11337 if (arr[i].type === 'brace') { 11338 break; 11339 } 11340 if (arr[i].type !== 'dots') { 11341 range.unshift(arr[i].value); 11342 } 11343 } 11344 11345 output = expandRange(range, opts); 11346 state.backtrack = true; 11347 } 11348 11349 if (brace.comma !== true && brace.dots !== true) { 11350 const out = state.output.slice(0, brace.outputIndex); 11351 const toks = state.tokens.slice(brace.tokensIndex); 11352 brace.value = brace.output = '\\{'; 11353 value = output = '\\}'; 11354 state.output = out; 11355 for (const t of toks) { 11356 state.output += (t.output || t.value); 11357 } 11358 } 11359 11360 push({ type: 'brace', value, output }); 11361 decrement('braces'); 11362 braces.pop(); 11363 continue; 11364 } 11365 11366 /** 11367 * Pipes 11368 */ 11369 11370 if (value === '|') { 11371 if (extglobs.length > 0) { 11372 extglobs[extglobs.length - 1].conditions++; 11373 } 11374 push({ type: 'text', value }); 11375 continue; 11376 } 11377 11378 /** 11379 * Commas 11380 */ 11381 11382 if (value === ',') { 11383 let output = value; 11384 11385 const brace = braces[braces.length - 1]; 11386 if (brace && stack[stack.length - 1] === 'braces') { 11387 brace.comma = true; 11388 output = '|'; 11389 } 11390 11391 push({ type: 'comma', value, output }); 11392 continue; 11393 } 11394 11395 /** 11396 * Slashes 11397 */ 11398 11399 if (value === '/') { 11400 // if the beginning of the glob is "./", advance the start 11401 // to the current index, and don't add the "./" characters 11402 // to the state. This greatly simplifies lookbehinds when 11403 // checking for BOS characters like "!" and "." (not "./") 11404 if (prev.type === 'dot' && state.index === state.start + 1) { 11405 state.start = state.index + 1; 11406 state.consumed = ''; 11407 state.output = ''; 11408 tokens.pop(); 11409 prev = bos; // reset "prev" to the first token 11410 continue; 11411 } 11412 11413 push({ type: 'slash', value, output: SLASH_LITERAL }); 11414 continue; 11415 } 11416 11417 /** 11418 * Dots 11419 */ 11420 11421 if (value === '.') { 11422 if (state.braces > 0 && prev.type === 'dot') { 11423 if (prev.value === '.') prev.output = DOT_LITERAL; 11424 const brace = braces[braces.length - 1]; 11425 prev.type = 'dots'; 11426 prev.output += value; 11427 prev.value += value; 11428 brace.dots = true; 11429 continue; 11430 } 11431 11432 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { 11433 push({ type: 'text', value, output: DOT_LITERAL }); 11434 continue; 11435 } 11436 11437 push({ type: 'dot', value, output: DOT_LITERAL }); 11438 continue; 11439 } 11440 11441 /** 11442 * Question marks 11443 */ 11444 11445 if (value === '?') { 11446 const isGroup = prev && prev.value === '('; 11447 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 11448 extglobOpen('qmark', value); 11449 continue; 11450 } 11451 11452 if (prev && prev.type === 'paren') { 11453 const next = peek(); 11454 let output = value; 11455 11456 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { 11457 output = `\\${value}`; 11458 } 11459 11460 push({ type: 'text', value, output }); 11461 continue; 11462 } 11463 11464 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { 11465 push({ type: 'qmark', value, output: QMARK_NO_DOT }); 11466 continue; 11467 } 11468 11469 push({ type: 'qmark', value, output: QMARK }); 11470 continue; 11471 } 11472 11473 /** 11474 * Exclamation 11475 */ 11476 11477 if (value === '!') { 11478 if (opts.noextglob !== true && peek() === '(') { 11479 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { 11480 extglobOpen('negate', value); 11481 continue; 11482 } 11483 } 11484 11485 if (opts.nonegate !== true && state.index === 0) { 11486 negate(); 11487 continue; 11488 } 11489 } 11490 11491 /** 11492 * Plus 11493 */ 11494 11495 if (value === '+') { 11496 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 11497 extglobOpen('plus', value); 11498 continue; 11499 } 11500 11501 if ((prev && prev.value === '(') || opts.regex === false) { 11502 push({ type: 'plus', value, output: PLUS_LITERAL }); 11503 continue; 11504 } 11505 11506 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { 11507 push({ type: 'plus', value }); 11508 continue; 11509 } 11510 11511 push({ type: 'plus', value: PLUS_LITERAL }); 11512 continue; 11513 } 11514 11515 /** 11516 * Plain text 11517 */ 11518 11519 if (value === '@') { 11520 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 11521 push({ type: 'at', extglob: true, value, output: '' }); 11522 continue; 11523 } 11524 11525 push({ type: 'text', value }); 11526 continue; 11527 } 11528 11529 /** 11530 * Plain text 11531 */ 11532 11533 if (value !== '*') { 11534 if (value === '$' || value === '^') { 11535 value = `\\${value}`; 11536 } 11537 11538 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); 11539 if (match) { 11540 value += match[0]; 11541 state.index += match[0].length; 11542 } 11543 11544 push({ type: 'text', value }); 11545 continue; 11546 } 11547 11548 /** 11549 * Stars 11550 */ 11551 11552 if (prev && (prev.type === 'globstar' || prev.star === true)) { 11553 prev.type = 'star'; 11554 prev.star = true; 11555 prev.value += value; 11556 prev.output = star; 11557 state.backtrack = true; 11558 state.globstar = true; 11559 consume(value); 11560 continue; 11561 } 11562 11563 let rest = remaining(); 11564 if (opts.noextglob !== true && /^\([^?]/.test(rest)) { 11565 extglobOpen('star', value); 11566 continue; 11567 } 11568 11569 if (prev.type === 'star') { 11570 if (opts.noglobstar === true) { 11571 consume(value); 11572 continue; 11573 } 11574 11575 const prior = prev.prev; 11576 const before = prior.prev; 11577 const isStart = prior.type === 'slash' || prior.type === 'bos'; 11578 const afterStar = before && (before.type === 'star' || before.type === 'globstar'); 11579 11580 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { 11581 push({ type: 'star', value, output: '' }); 11582 continue; 11583 } 11584 11585 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); 11586 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); 11587 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { 11588 push({ type: 'star', value, output: '' }); 11589 continue; 11590 } 11591 11592 // strip consecutive `/**/` 11593 while (rest.slice(0, 3) === '/**') { 11594 const after = input[state.index + 4]; 11595 if (after && after !== '/') { 11596 break; 11597 } 11598 rest = rest.slice(3); 11599 consume('/**', 3); 11600 } 11601 11602 if (prior.type === 'bos' && eos()) { 11603 prev.type = 'globstar'; 11604 prev.value += value; 11605 prev.output = globstar(opts); 11606 state.output = prev.output; 11607 state.globstar = true; 11608 consume(value); 11609 continue; 11610 } 11611 11612 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { 11613 state.output = state.output.slice(0, -(prior.output + prev.output).length); 11614 prior.output = `(?:${prior.output}`; 11615 11616 prev.type = 'globstar'; 11617 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); 11618 prev.value += value; 11619 state.globstar = true; 11620 state.output += prior.output + prev.output; 11621 consume(value); 11622 continue; 11623 } 11624 11625 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { 11626 const end = rest[1] !== void 0 ? '|$' : ''; 11627 11628 state.output = state.output.slice(0, -(prior.output + prev.output).length); 11629 prior.output = `(?:${prior.output}`; 11630 11631 prev.type = 'globstar'; 11632 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; 11633 prev.value += value; 11634 11635 state.output += prior.output + prev.output; 11636 state.globstar = true; 11637 11638 consume(value + advance()); 11639 11640 push({ type: 'slash', value: '/', output: '' }); 11641 continue; 11642 } 11643 11644 if (prior.type === 'bos' && rest[0] === '/') { 11645 prev.type = 'globstar'; 11646 prev.value += value; 11647 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; 11648 state.output = prev.output; 11649 state.globstar = true; 11650 consume(value + advance()); 11651 push({ type: 'slash', value: '/', output: '' }); 11652 continue; 11653 } 11654 11655 // remove single star from output 11656 state.output = state.output.slice(0, -prev.output.length); 11657 11658 // reset previous token to globstar 11659 prev.type = 'globstar'; 11660 prev.output = globstar(opts); 11661 prev.value += value; 11662 11663 // reset output with globstar 11664 state.output += prev.output; 11665 state.globstar = true; 11666 consume(value); 11667 continue; 11668 } 11669 11670 const token = { type: 'star', value, output: star }; 11671 11672 if (opts.bash === true) { 11673 token.output = '.*?'; 11674 if (prev.type === 'bos' || prev.type === 'slash') { 11675 token.output = nodot + token.output; 11676 } 11677 push(token); 11678 continue; 11679 } 11680 11681 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { 11682 token.output = value; 11683 push(token); 11684 continue; 11685 } 11686 11687 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { 11688 if (prev.type === 'dot') { 11689 state.output += NO_DOT_SLASH; 11690 prev.output += NO_DOT_SLASH; 11691 11692 } else if (opts.dot === true) { 11693 state.output += NO_DOTS_SLASH; 11694 prev.output += NO_DOTS_SLASH; 11695 11696 } else { 11697 state.output += nodot; 11698 prev.output += nodot; 11699 } 11700 11701 if (peek() !== '*') { 11702 state.output += ONE_CHAR; 11703 prev.output += ONE_CHAR; 11704 } 11705 } 11706 11707 push(token); 11708 } 11709 11710 while (state.brackets > 0) { 11711 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); 11712 state.output = utils.escapeLast(state.output, '['); 11713 decrement('brackets'); 11714 } 11715 11716 while (state.parens > 0) { 11717 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); 11718 state.output = utils.escapeLast(state.output, '('); 11719 decrement('parens'); 11720 } 11721 11722 while (state.braces > 0) { 11723 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); 11724 state.output = utils.escapeLast(state.output, '{'); 11725 decrement('braces'); 11726 } 11727 11728 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { 11729 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); 11730 } 11731 11732 // rebuild the output if we had to backtrack at any point 11733 if (state.backtrack === true) { 11734 state.output = ''; 11735 11736 for (const token of state.tokens) { 11737 state.output += token.output != null ? token.output : token.value; 11738 11739 if (token.suffix) { 11740 state.output += token.suffix; 11741 } 11742 } 11743 } 11744 11745 return state; 11746 }; 11747 11748 /** 11749 * Fast paths for creating regular expressions for common glob patterns. 11750 * This can significantly speed up processing and has very little downside 11751 * impact when none of the fast paths match. 11752 */ 11753 11754 parse.fastpaths = (input, options) => { 11755 const opts = { ...options }; 11756 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 11757 const len = input.length; 11758 if (len > max) { 11759 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 11760 } 11761 11762 input = REPLACEMENTS[input] || input; 11763 11764 // create constants based on platform, for windows or posix 11765 const { 11766 DOT_LITERAL, 11767 SLASH_LITERAL, 11768 ONE_CHAR, 11769 DOTS_SLASH, 11770 NO_DOT, 11771 NO_DOTS, 11772 NO_DOTS_SLASH, 11773 STAR, 11774 START_ANCHOR 11775 } = constants.globChars(opts.windows); 11776 11777 const nodot = opts.dot ? NO_DOTS : NO_DOT; 11778 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; 11779 const capture = opts.capture ? '' : '?:'; 11780 const state = { negated: false, prefix: '' }; 11781 let star = opts.bash === true ? '.*?' : STAR; 11782 11783 if (opts.capture) { 11784 star = `(${star})`; 11785 } 11786 11787 const globstar = opts => { 11788 if (opts.noglobstar === true) return star; 11789 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 11790 }; 11791 11792 const create = str => { 11793 switch (str) { 11794 case '*': 11795 return `${nodot}${ONE_CHAR}${star}`; 11796 11797 case '.*': 11798 return `${DOT_LITERAL}${ONE_CHAR}${star}`; 11799 11800 case '*.*': 11801 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 11802 11803 case '*/*': 11804 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; 11805 11806 case '**': 11807 return nodot + globstar(opts); 11808 11809 case '**/*': 11810 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; 11811 11812 case '**/*.*': 11813 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 11814 11815 case '**/.*': 11816 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; 11817 11818 default: { 11819 const match = /^(.*?)\.(\w+)$/.exec(str); 11820 if (!match) return; 11821 11822 const source = create(match[1]); 11823 if (!source) return; 11824 11825 return source + DOT_LITERAL + match[2]; 11826 } 11827 } 11828 }; 11829 11830 const output = utils.removePrefix(input, state); 11831 let source = create(output); 11832 11833 if (source && opts.strictSlashes !== true) { 11834 source += `${SLASH_LITERAL}?`; 11835 } 11836 11837 return source; 11838 }; 11839 11840 parse_1 = parse; 11841 return parse_1; 11842 } 11843 11844 var picomatch_1$1; 11845 var hasRequiredPicomatch$1; 11846 11847 function requirePicomatch$1 () { 11848 if (hasRequiredPicomatch$1) return picomatch_1$1; 11849 hasRequiredPicomatch$1 = 1; 11850 11851 const scan = /*@__PURE__*/ requireScan(); 11852 const parse = /*@__PURE__*/ requireParse(); 11853 const utils = /*@__PURE__*/ requireUtils(); 11854 const constants = /*@__PURE__*/ requireConstants(); 11855 const isObject = val => val && typeof val === 'object' && !Array.isArray(val); 11856 11857 /** 11858 * Creates a matcher function from one or more glob patterns. The 11859 * returned function takes a string to match as its first argument, 11860 * and returns true if the string is a match. The returned matcher 11861 * function also takes a boolean as the second argument that, when true, 11862 * returns an object with additional information. 11863 * 11864 * ```js 11865 * const picomatch = require('picomatch'); 11866 * // picomatch(glob[, options]); 11867 * 11868 * const isMatch = picomatch('*.!(*a)'); 11869 * console.log(isMatch('a.a')); //=> false 11870 * console.log(isMatch('a.b')); //=> true 11871 * ``` 11872 * @name picomatch 11873 * @param {String|Array} `globs` One or more glob patterns. 11874 * @param {Object=} `options` 11875 * @return {Function=} Returns a matcher function. 11876 * @api public 11877 */ 11878 11879 const picomatch = (glob, options, returnState = false) => { 11880 if (Array.isArray(glob)) { 11881 const fns = glob.map(input => picomatch(input, options, returnState)); 11882 const arrayMatcher = str => { 11883 for (const isMatch of fns) { 11884 const state = isMatch(str); 11885 if (state) return state; 11886 } 11887 return false; 11888 }; 11889 return arrayMatcher; 11890 } 11891 11892 const isState = isObject(glob) && glob.tokens && glob.input; 11893 11894 if (glob === '' || (typeof glob !== 'string' && !isState)) { 11895 throw new TypeError('Expected pattern to be a non-empty string'); 11896 } 11897 11898 const opts = options || {}; 11899 const posix = opts.windows; 11900 const regex = isState 11901 ? picomatch.compileRe(glob, options) 11902 : picomatch.makeRe(glob, options, false, true); 11903 11904 const state = regex.state; 11905 delete regex.state; 11906 11907 let isIgnored = () => false; 11908 if (opts.ignore) { 11909 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; 11910 isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); 11911 } 11912 11913 const matcher = (input, returnObject = false) => { 11914 const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); 11915 const result = { glob, state, regex, posix, input, output, match, isMatch }; 11916 11917 if (typeof opts.onResult === 'function') { 11918 opts.onResult(result); 11919 } 11920 11921 if (isMatch === false) { 11922 result.isMatch = false; 11923 return returnObject ? result : false; 11924 } 11925 11926 if (isIgnored(input)) { 11927 if (typeof opts.onIgnore === 'function') { 11928 opts.onIgnore(result); 11929 } 11930 result.isMatch = false; 11931 return returnObject ? result : false; 11932 } 11933 11934 if (typeof opts.onMatch === 'function') { 11935 opts.onMatch(result); 11936 } 11937 return returnObject ? result : true; 11938 }; 11939 11940 if (returnState) { 11941 matcher.state = state; 11942 } 11943 11944 return matcher; 11945 }; 11946 11947 /** 11948 * Test `input` with the given `regex`. This is used by the main 11949 * `picomatch()` function to test the input string. 11950 * 11951 * ```js 11952 * const picomatch = require('picomatch'); 11953 * // picomatch.test(input, regex[, options]); 11954 * 11955 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); 11956 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } 11957 * ``` 11958 * @param {String} `input` String to test. 11959 * @param {RegExp} `regex` 11960 * @return {Object} Returns an object with matching info. 11961 * @api public 11962 */ 11963 11964 picomatch.test = (input, regex, options, { glob, posix } = {}) => { 11965 if (typeof input !== 'string') { 11966 throw new TypeError('Expected input to be a string'); 11967 } 11968 11969 if (input === '') { 11970 return { isMatch: false, output: '' }; 11971 } 11972 11973 const opts = options || {}; 11974 const format = opts.format || (posix ? utils.toPosixSlashes : null); 11975 let match = input === glob; 11976 let output = (match && format) ? format(input) : input; 11977 11978 if (match === false) { 11979 output = format ? format(input) : input; 11980 match = output === glob; 11981 } 11982 11983 if (match === false || opts.capture === true) { 11984 if (opts.matchBase === true || opts.basename === true) { 11985 match = picomatch.matchBase(input, regex, options, posix); 11986 } else { 11987 match = regex.exec(output); 11988 } 11989 } 11990 11991 return { isMatch: Boolean(match), match, output }; 11992 }; 11993 11994 /** 11995 * Match the basename of a filepath. 11996 * 11997 * ```js 11998 * const picomatch = require('picomatch'); 11999 * // picomatch.matchBase(input, glob[, options]); 12000 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true 12001 * ``` 12002 * @param {String} `input` String to test. 12003 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). 12004 * @return {Boolean} 12005 * @api public 12006 */ 12007 12008 picomatch.matchBase = (input, glob, options) => { 12009 const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); 12010 return regex.test(utils.basename(input)); 12011 }; 12012 12013 /** 12014 * Returns true if **any** of the given glob `patterns` match the specified `string`. 12015 * 12016 * ```js 12017 * const picomatch = require('picomatch'); 12018 * // picomatch.isMatch(string, patterns[, options]); 12019 * 12020 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true 12021 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false 12022 * ``` 12023 * @param {String|Array} str The string to test. 12024 * @param {String|Array} patterns One or more glob patterns to use for matching. 12025 * @param {Object} [options] See available [options](#options). 12026 * @return {Boolean} Returns true if any patterns match `str` 12027 * @api public 12028 */ 12029 12030 picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); 12031 12032 /** 12033 * Parse a glob pattern to create the source string for a regular 12034 * expression. 12035 * 12036 * ```js 12037 * const picomatch = require('picomatch'); 12038 * const result = picomatch.parse(pattern[, options]); 12039 * ``` 12040 * @param {String} `pattern` 12041 * @param {Object} `options` 12042 * @return {Object} Returns an object with useful properties and output to be used as a regex source string. 12043 * @api public 12044 */ 12045 12046 picomatch.parse = (pattern, options) => { 12047 if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); 12048 return parse(pattern, { ...options, fastpaths: false }); 12049 }; 12050 12051 /** 12052 * Scan a glob pattern to separate the pattern into segments. 12053 * 12054 * ```js 12055 * const picomatch = require('picomatch'); 12056 * // picomatch.scan(input[, options]); 12057 * 12058 * const result = picomatch.scan('!./foo/*.js'); 12059 * console.log(result); 12060 * { prefix: '!./', 12061 * input: '!./foo/*.js', 12062 * start: 3, 12063 * base: 'foo', 12064 * glob: '*.js', 12065 * isBrace: false, 12066 * isBracket: false, 12067 * isGlob: true, 12068 * isExtglob: false, 12069 * isGlobstar: false, 12070 * negated: true } 12071 * ``` 12072 * @param {String} `input` Glob pattern to scan. 12073 * @param {Object} `options` 12074 * @return {Object} Returns an object with 12075 * @api public 12076 */ 12077 12078 picomatch.scan = (input, options) => scan(input, options); 12079 12080 /** 12081 * Compile a regular expression from the `state` object returned by the 12082 * [parse()](#parse) method. 12083 * 12084 * @param {Object} `state` 12085 * @param {Object} `options` 12086 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. 12087 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. 12088 * @return {RegExp} 12089 * @api public 12090 */ 12091 12092 picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => { 12093 if (returnOutput === true) { 12094 return state.output; 12095 } 12096 12097 const opts = options || {}; 12098 const prepend = opts.contains ? '' : '^'; 12099 const append = opts.contains ? '' : '$'; 12100 12101 let source = `${prepend}(?:${state.output})${append}`; 12102 if (state && state.negated === true) { 12103 source = `^(?!${source}).*$`; 12104 } 12105 12106 const regex = picomatch.toRegex(source, options); 12107 if (returnState === true) { 12108 regex.state = state; 12109 } 12110 12111 return regex; 12112 }; 12113 12114 /** 12115 * Create a regular expression from a parsed glob pattern. 12116 * 12117 * ```js 12118 * const picomatch = require('picomatch'); 12119 * const state = picomatch.parse('*.js'); 12120 * // picomatch.compileRe(state[, options]); 12121 * 12122 * console.log(picomatch.compileRe(state)); 12123 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 12124 * ``` 12125 * @param {String} `state` The object returned from the `.parse` method. 12126 * @param {Object} `options` 12127 * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. 12128 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. 12129 * @return {RegExp} Returns a regex created from the given pattern. 12130 * @api public 12131 */ 12132 12133 picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { 12134 if (!input || typeof input !== 'string') { 12135 throw new TypeError('Expected a non-empty string'); 12136 } 12137 12138 let parsed = { negated: false, fastpaths: true }; 12139 12140 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { 12141 parsed.output = parse.fastpaths(input, options); 12142 } 12143 12144 if (!parsed.output) { 12145 parsed = parse(input, options); 12146 } 12147 12148 return picomatch.compileRe(parsed, options, returnOutput, returnState); 12149 }; 12150 12151 /** 12152 * Create a regular expression from the given regex source string. 12153 * 12154 * ```js 12155 * const picomatch = require('picomatch'); 12156 * // picomatch.toRegex(source[, options]); 12157 * 12158 * const { output } = picomatch.parse('*.js'); 12159 * console.log(picomatch.toRegex(output)); 12160 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 12161 * ``` 12162 * @param {String} `source` Regular expression source string. 12163 * @param {Object} `options` 12164 * @return {RegExp} 12165 * @api public 12166 */ 12167 12168 picomatch.toRegex = (source, options) => { 12169 try { 12170 const opts = options || {}; 12171 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); 12172 } catch (err) { 12173 if (options && options.debug === true) throw err; 12174 return /$^/; 12175 } 12176 }; 12177 12178 /** 12179 * Picomatch constants. 12180 * @return {Object} 12181 */ 12182 12183 picomatch.constants = constants; 12184 12185 /** 12186 * Expose "picomatch" 12187 */ 12188 12189 picomatch_1$1 = picomatch; 12190 return picomatch_1$1; 12191 } 12192 12193 var picomatch_1; 12194 var hasRequiredPicomatch; 12195 12196 function requirePicomatch () { 12197 if (hasRequiredPicomatch) return picomatch_1; 12198 hasRequiredPicomatch = 1; 12199 12200 const pico = /*@__PURE__*/ requirePicomatch$1(); 12201 const utils = /*@__PURE__*/ requireUtils(); 12202 12203 function picomatch(glob, options, returnState = false) { 12204 // default to os.platform() 12205 if (options && (options.windows === null || options.windows === undefined)) { 12206 // don't mutate the original options object 12207 options = { ...options, windows: utils.isWindows() }; 12208 } 12209 12210 return pico(glob, options, returnState); 12211 } 12212 12213 Object.assign(picomatch, pico); 12214 picomatch_1 = picomatch; 12215 return picomatch_1; 12216 } 12217 12218 var picomatchExports = /*@__PURE__*/ requirePicomatch(); 12219 const pm = /*@__PURE__*/getDefaultExportFromCjs(picomatchExports); 12220 12221 const extractors = { 12222 ArrayPattern(names, param) { 12223 for (const element of param.elements) { 12224 if (element) 12225 extractors[element.type](names, element); 12226 } 12227 }, 12228 AssignmentPattern(names, param) { 12229 extractors[param.left.type](names, param.left); 12230 }, 12231 Identifier(names, param) { 12232 names.push(param.name); 12233 }, 12234 MemberExpression() { }, 12235 ObjectPattern(names, param) { 12236 for (const prop of param.properties) { 12237 // @ts-ignore Typescript reports that this is not a valid type 12238 if (prop.type === 'RestElement') { 12239 extractors.RestElement(names, prop); 12240 } 12241 else { 12242 extractors[prop.value.type](names, prop.value); 12243 } 12244 } 12245 }, 12246 RestElement(names, param) { 12247 extractors[param.argument.type](names, param.argument); 12248 } 12249 }; 12250 const extractAssignedNames = function extractAssignedNames(param) { 12251 const names = []; 12252 extractors[param.type](names, param); 12253 return names; 12254 }; 12255 12256 // Helper since Typescript can't detect readonly arrays with Array.isArray 12257 function isArray(arg) { 12258 return Array.isArray(arg); 12259 } 12260 function ensureArray(thing) { 12261 if (isArray(thing)) 12262 return thing; 12263 if (thing == null) 12264 return []; 12265 return [thing]; 12266 } 12267 12268 const normalizePathRegExp = new RegExp(`\\${require$$0.win32.sep}`, 'g'); 12269 const normalizePath = function normalizePath(filename) { 12270 return filename.replace(normalizePathRegExp, require$$0.posix.sep); 12271 }; 12272 12273 function getMatcherString(id, resolutionBase) { 12274 if (resolutionBase === false || require$$0.isAbsolute(id) || id.startsWith('**')) { 12275 return normalizePath(id); 12276 } 12277 // resolve('') is valid and will default to process.cwd() 12278 const basePath = normalizePath(require$$0.resolve(resolutionBase || '')) 12279 // escape all possible (posix + win) path characters that might interfere with regex 12280 .replace(/[-^$*+?.()|[\]{}]/g, '\\$&'); 12281 // Note that we use posix.join because: 12282 // 1. the basePath has been normalized to use / 12283 // 2. the incoming glob (id) matcher, also uses / 12284 // otherwise Node will force backslash (\) on windows 12285 return require$$0.posix.join(basePath, normalizePath(id)); 12286 } 12287 const createFilter = function createFilter(include, exclude, options) { 12288 const resolutionBase = options && options.resolve; 12289 const getMatcher = (id) => id instanceof RegExp 12290 ? id 12291 : { 12292 test: (what) => { 12293 // this refactor is a tad overly verbose but makes for easy debugging 12294 const pattern = getMatcherString(id, resolutionBase); 12295 const fn = pm(pattern, { dot: true }); 12296 const result = fn(what); 12297 return result; 12298 } 12299 }; 12300 const includeMatchers = ensureArray(include).map(getMatcher); 12301 const excludeMatchers = ensureArray(exclude).map(getMatcher); 12302 if (!includeMatchers.length && !excludeMatchers.length) 12303 return (id) => typeof id === 'string' && !id.includes('\0'); 12304 return function result(id) { 12305 if (typeof id !== 'string') 12306 return false; 12307 if (id.includes('\0')) 12308 return false; 12309 const pathId = normalizePath(id); 12310 for (let i = 0; i < excludeMatchers.length; ++i) { 12311 const matcher = excludeMatchers[i]; 12312 if (matcher.test(pathId)) 12313 return false; 12314 } 12315 for (let i = 0; i < includeMatchers.length; ++i) { 12316 const matcher = includeMatchers[i]; 12317 if (matcher.test(pathId)) 12318 return true; 12319 } 12320 return !includeMatchers.length; 12321 }; 12322 }; 12323 12324 const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public'; 12325 const builtins = 'arguments Infinity NaN undefined null true false eval uneval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Symbol Error EvalError InternalError RangeError ReferenceError SyntaxError TypeError URIError Number Math Date String RegExp Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array Map Set WeakMap WeakSet SIMD ArrayBuffer DataView JSON Promise Generator GeneratorFunction Reflect Proxy Intl'; 12326 const forbiddenIdentifiers = new Set(`${reservedWords} ${builtins}`.split(' ')); 12327 forbiddenIdentifiers.add(''); 12328 12329 class ArrayPattern extends NodeBase { 12330 addExportedVariables(variables, exportNamesByVariable) { 12331 for (const element of this.elements) { 12332 element?.addExportedVariables(variables, exportNamesByVariable); 12333 } 12334 } 12335 declare(kind) { 12336 const variables = []; 12337 for (const element of this.elements) { 12338 if (element !== null) { 12339 variables.push(...element.declare(kind, UNKNOWN_EXPRESSION)); 12340 } 12341 } 12342 return variables; 12343 } 12344 // Patterns can only be deoptimized at the empty path at the moment 12345 deoptimizePath() { 12346 for (const element of this.elements) { 12347 element?.deoptimizePath(EMPTY_PATH); 12348 } 12349 } 12350 // Patterns are only checked at the empty path at the moment 12351 hasEffectsOnInteractionAtPath(_path, interaction, context) { 12352 for (const element of this.elements) { 12353 if (element?.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context)) 12354 return true; 12355 } 12356 return false; 12357 } 12358 markDeclarationReached() { 12359 for (const element of this.elements) { 12360 element?.markDeclarationReached(); 12361 } 12362 } 12363 } 12364 12365 class ArrowFunctionExpression extends FunctionBase { 12366 constructor() { 12367 super(...arguments); 12368 this.objectEntity = null; 12369 } 12370 get expression() { 12371 return isFlagSet(this.flags, 8388608 /* Flag.expression */); 12372 } 12373 set expression(value) { 12374 this.flags = setFlag(this.flags, 8388608 /* Flag.expression */, value); 12375 } 12376 createScope(parentScope) { 12377 this.scope = new ReturnValueScope(parentScope, false); 12378 } 12379 hasEffects() { 12380 if (!this.deoptimized) 12381 this.applyDeoptimizations(); 12382 return false; 12383 } 12384 hasEffectsOnInteractionAtPath(path, interaction, context) { 12385 if (super.hasEffectsOnInteractionAtPath(path, interaction, context)) { 12386 return true; 12387 } 12388 if (this.annotationNoSideEffects) { 12389 return false; 12390 } 12391 if (interaction.type === INTERACTION_CALLED) { 12392 const { ignore, brokenFlow } = context; 12393 context.ignore = { 12394 breaks: false, 12395 continues: false, 12396 labels: new Set(), 12397 returnYield: true, 12398 this: false 12399 }; 12400 if (this.body.hasEffects(context)) 12401 return true; 12402 context.ignore = ignore; 12403 context.brokenFlow = brokenFlow; 12404 } 12405 return false; 12406 } 12407 onlyFunctionCallUsed() { 12408 const isIIFE = this.parent.type === parseAst_js.CallExpression && 12409 this.parent.callee === this; 12410 return isIIFE || super.onlyFunctionCallUsed(); 12411 } 12412 include(context, includeChildrenRecursively) { 12413 super.include(context, includeChildrenRecursively); 12414 for (const parameter of this.params) { 12415 if (!(parameter instanceof Identifier)) { 12416 parameter.include(context, includeChildrenRecursively); 12417 } 12418 } 12419 } 12420 getObjectEntity() { 12421 if (this.objectEntity !== null) { 12422 return this.objectEntity; 12423 } 12424 return (this.objectEntity = new ObjectEntity([], OBJECT_PROTOTYPE)); 12425 } 12426 } 12427 12428 class ObjectPattern extends NodeBase { 12429 addExportedVariables(variables, exportNamesByVariable) { 12430 for (const property of this.properties) { 12431 if (property.type === parseAst_js.Property) { 12432 property.value.addExportedVariables(variables, exportNamesByVariable); 12433 } 12434 else { 12435 property.argument.addExportedVariables(variables, exportNamesByVariable); 12436 } 12437 } 12438 } 12439 declare(kind, init) { 12440 const variables = []; 12441 for (const property of this.properties) { 12442 variables.push(...property.declare(kind, init)); 12443 } 12444 return variables; 12445 } 12446 deoptimizePath(path) { 12447 if (path.length === 0) { 12448 for (const property of this.properties) { 12449 property.deoptimizePath(path); 12450 } 12451 } 12452 } 12453 hasEffectsOnInteractionAtPath( 12454 // At the moment, this is only triggered for assignment left-hand sides, 12455 // where the path is empty 12456 _path, interaction, context) { 12457 for (const property of this.properties) { 12458 if (property.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context)) 12459 return true; 12460 } 12461 return false; 12462 } 12463 markDeclarationReached() { 12464 for (const property of this.properties) { 12465 property.markDeclarationReached(); 12466 } 12467 } 12468 } 12469 12470 class AssignmentExpression extends NodeBase { 12471 hasEffects(context) { 12472 const { deoptimized, left, operator, right } = this; 12473 if (!deoptimized) 12474 this.applyDeoptimizations(); 12475 // MemberExpressions do not access the property before assignments if the 12476 // operator is '='. 12477 return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '=')); 12478 } 12479 hasEffectsOnInteractionAtPath(path, interaction, context) { 12480 return this.right.hasEffectsOnInteractionAtPath(path, interaction, context); 12481 } 12482 include(context, includeChildrenRecursively) { 12483 const { deoptimized, left, right, operator } = this; 12484 if (!deoptimized) 12485 this.applyDeoptimizations(); 12486 this.included = true; 12487 if (includeChildrenRecursively || 12488 operator !== '=' || 12489 left.included || 12490 left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) { 12491 left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '='); 12492 } 12493 right.include(context, includeChildrenRecursively); 12494 } 12495 initialise() { 12496 super.initialise(); 12497 if (this.left instanceof Identifier) { 12498 const variable = this.scope.variables.get(this.left.name); 12499 if (variable?.kind === 'const') { 12500 this.scope.context.error(parseAst_js.logConstVariableReassignError(), this.left.start); 12501 } 12502 } 12503 this.left.setAssignedValue(this.right); 12504 } 12505 render(code, options, { preventASI, renderedParentType, renderedSurroundingElement } = parseAst_js.BLANK) { 12506 const { left, right, start, end, parent } = this; 12507 if (left.included) { 12508 left.render(code, options); 12509 right.render(code, options); 12510 } 12511 else { 12512 const inclusionStart = findNonWhiteSpace(code.original, findFirstOccurrenceOutsideComment(code.original, '=', left.end) + 1); 12513 code.remove(start, inclusionStart); 12514 if (preventASI) { 12515 removeLineBreaks(code, inclusionStart, right.start); 12516 } 12517 right.render(code, options, { 12518 renderedParentType: renderedParentType || parent.type, 12519 renderedSurroundingElement: renderedSurroundingElement || parent.type 12520 }); 12521 } 12522 if (options.format === 'system') { 12523 if (left instanceof Identifier) { 12524 const variable = left.variable; 12525 const exportNames = options.exportNamesByVariable.get(variable); 12526 if (exportNames) { 12527 if (exportNames.length === 1) { 12528 renderSystemExportExpression(variable, start, end, code, options); 12529 } 12530 else { 12531 renderSystemExportSequenceAfterExpression(variable, start, end, parent.type !== parseAst_js.ExpressionStatement, code, options); 12532 } 12533 return; 12534 } 12535 } 12536 else { 12537 const systemPatternExports = []; 12538 left.addExportedVariables(systemPatternExports, options.exportNamesByVariable); 12539 if (systemPatternExports.length > 0) { 12540 renderSystemExportFunction(systemPatternExports, start, end, renderedSurroundingElement === parseAst_js.ExpressionStatement, code, options); 12541 return; 12542 } 12543 } 12544 } 12545 if (left.included && 12546 left instanceof ObjectPattern && 12547 (renderedSurroundingElement === parseAst_js.ExpressionStatement || 12548 renderedSurroundingElement === parseAst_js.ArrowFunctionExpression)) { 12549 code.appendRight(start, '('); 12550 code.prependLeft(end, ')'); 12551 } 12552 } 12553 applyDeoptimizations() { 12554 this.deoptimized = true; 12555 this.left.deoptimizePath(EMPTY_PATH); 12556 this.right.deoptimizePath(UNKNOWN_PATH); 12557 this.scope.context.requestTreeshakingPass(); 12558 } 12559 } 12560 12561 class AssignmentPattern extends NodeBase { 12562 addExportedVariables(variables, exportNamesByVariable) { 12563 this.left.addExportedVariables(variables, exportNamesByVariable); 12564 } 12565 declare(kind, init) { 12566 return this.left.declare(kind, init); 12567 } 12568 deoptimizePath(path) { 12569 if (path.length === 0) { 12570 this.left.deoptimizePath(path); 12571 } 12572 } 12573 hasEffectsOnInteractionAtPath(path, interaction, context) { 12574 return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context)); 12575 } 12576 markDeclarationReached() { 12577 this.left.markDeclarationReached(); 12578 } 12579 render(code, options, { isShorthandProperty } = parseAst_js.BLANK) { 12580 this.left.render(code, options, { isShorthandProperty }); 12581 this.right.render(code, options); 12582 } 12583 applyDeoptimizations() { 12584 this.deoptimized = true; 12585 this.left.deoptimizePath(EMPTY_PATH); 12586 this.right.deoptimizePath(UNKNOWN_PATH); 12587 this.scope.context.requestTreeshakingPass(); 12588 } 12589 } 12590 12591 class AwaitExpression extends NodeBase { 12592 hasEffects() { 12593 if (!this.deoptimized) 12594 this.applyDeoptimizations(); 12595 return true; 12596 } 12597 include(context, includeChildrenRecursively) { 12598 if (!this.deoptimized) 12599 this.applyDeoptimizations(); 12600 if (!this.included) { 12601 this.included = true; 12602 checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) { 12603 let parent = this.parent; 12604 do { 12605 if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression) 12606 break checkTopLevelAwait; 12607 } while ((parent = parent.parent)); 12608 this.scope.context.usesTopLevelAwait = true; 12609 } 12610 } 12611 this.argument.include(context, includeChildrenRecursively); 12612 } 12613 } 12614 12615 const binaryOperators = { 12616 '!=': (left, right) => left != right, 12617 '!==': (left, right) => left !== right, 12618 '%': (left, right) => left % right, 12619 '&': (left, right) => left & right, 12620 '*': (left, right) => left * right, 12621 // At the moment, "**" will be transpiled to Math.pow 12622 '**': (left, right) => left ** right, 12623 '+': (left, right) => left + right, 12624 '-': (left, right) => left - right, 12625 '/': (left, right) => left / right, 12626 '<': (left, right) => left < right, 12627 '<<': (left, right) => left << right, 12628 '<=': (left, right) => left <= right, 12629 '==': (left, right) => left == right, 12630 '===': (left, right) => left === right, 12631 '>': (left, right) => left > right, 12632 '>=': (left, right) => left >= right, 12633 '>>': (left, right) => left >> right, 12634 '>>>': (left, right) => left >>> right, 12635 '^': (left, right) => left ^ right, 12636 '|': (left, right) => left | right 12637 // We use the fallback for cases where we return something unknown 12638 // in: () => UnknownValue, 12639 // instanceof: () => UnknownValue, 12640 }; 12641 class BinaryExpression extends NodeBase { 12642 deoptimizeCache() { } 12643 getLiteralValueAtPath(path, recursionTracker, origin) { 12644 if (path.length > 0) 12645 return UnknownValue; 12646 const leftValue = this.left.getLiteralValueAtPath(EMPTY_PATH, recursionTracker, origin); 12647 if (typeof leftValue === 'symbol') 12648 return UnknownValue; 12649 const rightValue = this.right.getLiteralValueAtPath(EMPTY_PATH, recursionTracker, origin); 12650 if (typeof rightValue === 'symbol') 12651 return UnknownValue; 12652 const operatorFunction = binaryOperators[this.operator]; 12653 if (!operatorFunction) 12654 return UnknownValue; 12655 return operatorFunction(leftValue, rightValue); 12656 } 12657 hasEffects(context) { 12658 // support some implicit type coercion runtime errors 12659 if (this.operator === '+' && 12660 this.parent instanceof ExpressionStatement && 12661 this.left.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) === '') { 12662 return true; 12663 } 12664 return super.hasEffects(context); 12665 } 12666 hasEffectsOnInteractionAtPath(path, { type }) { 12667 return type !== INTERACTION_ACCESSED || path.length > 1; 12668 } 12669 removeAnnotations(code) { 12670 this.left.removeAnnotations(code); 12671 } 12672 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) { 12673 this.left.render(code, options, { renderedSurroundingElement }); 12674 this.right.render(code, options); 12675 } 12676 } 12677 12678 class BreakStatement extends NodeBase { 12679 hasEffects(context) { 12680 if (this.label) { 12681 if (!context.ignore.labels.has(this.label.name)) 12682 return true; 12683 context.includedLabels.add(this.label.name); 12684 } 12685 else { 12686 if (!context.ignore.breaks) 12687 return true; 12688 context.hasBreak = true; 12689 } 12690 context.brokenFlow = true; 12691 return false; 12692 } 12693 include(context) { 12694 this.included = true; 12695 if (this.label) { 12696 this.label.include(); 12697 context.includedLabels.add(this.label.name); 12698 } 12699 else { 12700 context.hasBreak = true; 12701 } 12702 context.brokenFlow = true; 12703 } 12704 } 12705 12706 function renderCallArguments(code, options, node) { 12707 if (node.arguments.length > 0) { 12708 if (node.arguments[node.arguments.length - 1].included) { 12709 for (const argument of node.arguments) { 12710 argument.render(code, options); 12711 } 12712 } 12713 else { 12714 let lastIncludedIndex = node.arguments.length - 2; 12715 while (lastIncludedIndex >= 0 && !node.arguments[lastIncludedIndex].included) { 12716 lastIncludedIndex--; 12717 } 12718 if (lastIncludedIndex >= 0) { 12719 for (let index = 0; index <= lastIncludedIndex; index++) { 12720 node.arguments[index].render(code, options); 12721 } 12722 code.remove(findFirstOccurrenceOutsideComment(code.original, ',', node.arguments[lastIncludedIndex].end), node.end - 1); 12723 } 12724 else { 12725 code.remove(findFirstOccurrenceOutsideComment(code.original, '(', node.callee.end) + 1, node.end - 1); 12726 } 12727 } 12728 } 12729 } 12730 12731 class CallExpressionBase extends NodeBase { 12732 constructor() { 12733 super(...arguments); 12734 this.returnExpression = null; 12735 this.deoptimizableDependentExpressions = []; 12736 this.expressionsToBeDeoptimized = new Set(); 12737 } 12738 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 12739 const { args } = interaction; 12740 const [returnExpression, isPure] = this.getReturnExpression(recursionTracker); 12741 if (isPure) 12742 return; 12743 const deoptimizedExpressions = args.filter(expression => !!expression && expression !== UNKNOWN_EXPRESSION); 12744 if (deoptimizedExpressions.length === 0) 12745 return; 12746 if (returnExpression === UNKNOWN_EXPRESSION) { 12747 for (const expression of deoptimizedExpressions) { 12748 expression.deoptimizePath(UNKNOWN_PATH); 12749 } 12750 } 12751 else { 12752 recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => { 12753 for (const expression of deoptimizedExpressions) { 12754 this.expressionsToBeDeoptimized.add(expression); 12755 } 12756 returnExpression.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 12757 }, null); 12758 } 12759 } 12760 deoptimizeCache() { 12761 if (this.returnExpression?.[0] !== UNKNOWN_EXPRESSION) { 12762 this.returnExpression = UNKNOWN_RETURN_EXPRESSION; 12763 const { deoptimizableDependentExpressions, expressionsToBeDeoptimized } = this; 12764 this.expressionsToBeDeoptimized = parseAst_js.EMPTY_SET; 12765 this.deoptimizableDependentExpressions = parseAst_js.EMPTY_ARRAY; 12766 for (const expression of deoptimizableDependentExpressions) { 12767 expression.deoptimizeCache(); 12768 } 12769 for (const expression of expressionsToBeDeoptimized) { 12770 expression.deoptimizePath(UNKNOWN_PATH); 12771 } 12772 } 12773 } 12774 deoptimizePath(path) { 12775 if (path.length === 0 || 12776 this.scope.context.deoptimizationTracker.trackEntityAtPathAndGetIfTracked(path, this)) { 12777 return; 12778 } 12779 const [returnExpression] = this.getReturnExpression(); 12780 if (returnExpression !== UNKNOWN_EXPRESSION) { 12781 returnExpression.deoptimizePath(path); 12782 } 12783 } 12784 getLiteralValueAtPath(path, recursionTracker, origin) { 12785 const [returnExpression] = this.getReturnExpression(recursionTracker); 12786 if (returnExpression === UNKNOWN_EXPRESSION) { 12787 return UnknownValue; 12788 } 12789 return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => { 12790 this.deoptimizableDependentExpressions.push(origin); 12791 return returnExpression.getLiteralValueAtPath(path, recursionTracker, origin); 12792 }, UnknownValue); 12793 } 12794 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 12795 const returnExpression = this.getReturnExpression(recursionTracker); 12796 if (returnExpression[0] === UNKNOWN_EXPRESSION) { 12797 return returnExpression; 12798 } 12799 return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => { 12800 this.deoptimizableDependentExpressions.push(origin); 12801 const [expression, isPure] = returnExpression[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 12802 return [expression, isPure || returnExpression[1]]; 12803 }, UNKNOWN_RETURN_EXPRESSION); 12804 } 12805 hasEffectsOnInteractionAtPath(path, interaction, context) { 12806 const { type } = interaction; 12807 if (type === INTERACTION_CALLED) { 12808 const { args, withNew } = interaction; 12809 if ((withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, args, this)) { 12810 return false; 12811 } 12812 } 12813 else if ((type === INTERACTION_ASSIGNED 12814 ? context.assigned 12815 : context.accessed).trackEntityAtPathAndGetIfTracked(path, this)) { 12816 return false; 12817 } 12818 const [returnExpression, isPure] = this.getReturnExpression(); 12819 return ((type === INTERACTION_ASSIGNED || !isPure) && 12820 returnExpression.hasEffectsOnInteractionAtPath(path, interaction, context)); 12821 } 12822 } 12823 12824 class CallExpression extends CallExpressionBase { 12825 get optional() { 12826 return isFlagSet(this.flags, 128 /* Flag.optional */); 12827 } 12828 set optional(value) { 12829 this.flags = setFlag(this.flags, 128 /* Flag.optional */, value); 12830 } 12831 bind() { 12832 super.bind(); 12833 if (this.callee instanceof Identifier) { 12834 const variable = this.scope.findVariable(this.callee.name); 12835 if (variable.isNamespace) { 12836 this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logCannotCallNamespace(this.callee.name), this.start); 12837 } 12838 if (this.callee.name === 'eval') { 12839 this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logEval(this.scope.context.module.id), this.start); 12840 } 12841 } 12842 this.interaction = { 12843 args: [ 12844 this.callee instanceof MemberExpression && !this.callee.variable 12845 ? this.callee.object 12846 : null, 12847 ...this.arguments 12848 ], 12849 type: INTERACTION_CALLED, 12850 withNew: false 12851 }; 12852 } 12853 getLiteralValueAtPathAsChainElement(path, recursionTracker, origin) { 12854 return getChainElementLiteralValueAtPath(this, this.callee, path, recursionTracker, origin); 12855 } 12856 hasEffects(context) { 12857 if (!this.deoptimized) 12858 this.applyDeoptimizations(); 12859 for (const argument of this.arguments) { 12860 if (argument.hasEffects(context)) 12861 return true; 12862 } 12863 if (this.annotationPure) { 12864 return false; 12865 } 12866 return (this.callee.hasEffects(context) || 12867 this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)); 12868 } 12869 hasEffectsAsChainElement(context) { 12870 const calleeHasEffects = 'hasEffectsAsChainElement' in this.callee 12871 ? this.callee.hasEffectsAsChainElement(context) 12872 : this.callee.hasEffects(context); 12873 if (calleeHasEffects === IS_SKIPPED_CHAIN) 12874 return IS_SKIPPED_CHAIN; 12875 if (this.optional && 12876 this.callee.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) == null) { 12877 return (!this.annotationPure && calleeHasEffects) || IS_SKIPPED_CHAIN; 12878 } 12879 // We only apply deoptimizations lazily once we know we are not skipping 12880 if (!this.deoptimized) 12881 this.applyDeoptimizations(); 12882 for (const argument of this.arguments) { 12883 if (argument.hasEffects(context)) 12884 return true; 12885 } 12886 return (!this.annotationPure && 12887 (calleeHasEffects || 12888 this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context))); 12889 } 12890 include(context, includeChildrenRecursively) { 12891 if (!this.deoptimized) 12892 this.applyDeoptimizations(); 12893 if (includeChildrenRecursively) { 12894 super.include(context, includeChildrenRecursively); 12895 if (includeChildrenRecursively === INCLUDE_PARAMETERS && 12896 this.callee instanceof Identifier && 12897 this.callee.variable) { 12898 this.callee.variable.markCalledFromTryStatement(); 12899 } 12900 } 12901 else { 12902 this.included = true; 12903 this.callee.include(context, false); 12904 } 12905 this.callee.includeCallArguments(context, this.arguments); 12906 } 12907 initialise() { 12908 super.initialise(); 12909 if (this.annotations && 12910 this.scope.context.options.treeshake.annotations) { 12911 this.annotationPure = this.annotations.some(comment => comment.type === 'pure'); 12912 } 12913 } 12914 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) { 12915 this.callee.render(code, options, { 12916 isCalleeOfRenderedParent: true, 12917 renderedSurroundingElement 12918 }); 12919 renderCallArguments(code, options, this); 12920 } 12921 applyDeoptimizations() { 12922 this.deoptimized = true; 12923 this.callee.deoptimizeArgumentsOnInteractionAtPath(this.interaction, EMPTY_PATH, SHARED_RECURSION_TRACKER); 12924 this.scope.context.requestTreeshakingPass(); 12925 } 12926 getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) { 12927 if (this.returnExpression === null) { 12928 this.returnExpression = UNKNOWN_RETURN_EXPRESSION; 12929 return (this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this)); 12930 } 12931 return this.returnExpression; 12932 } 12933 } 12934 12935 class CatchClause extends NodeBase { 12936 createScope(parentScope) { 12937 this.scope = new ParameterScope(parentScope, true); 12938 } 12939 parseNode(esTreeNode) { 12940 const { body, param, type } = esTreeNode; 12941 this.type = type; 12942 if (param) { 12943 this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param); 12944 this.param.declare('parameter', UNKNOWN_EXPRESSION); 12945 } 12946 this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body); 12947 return super.parseNode(esTreeNode); 12948 } 12949 } 12950 CatchClause.prototype.preventChildBlockScope = true; 12951 12952 class ChainExpression extends NodeBase { 12953 // deoptimizations are not relevant as we are not caching values 12954 deoptimizeCache() { } 12955 getLiteralValueAtPath(path, recursionTracker, origin) { 12956 const literalValue = this.expression.getLiteralValueAtPathAsChainElement(path, recursionTracker, origin); 12957 return literalValue === IS_SKIPPED_CHAIN ? undefined : literalValue; 12958 } 12959 hasEffects(context) { 12960 return this.expression.hasEffectsAsChainElement(context) === true; 12961 } 12962 removeAnnotations(code) { 12963 this.expression.removeAnnotations(code); 12964 } 12965 applyDeoptimizations() { } 12966 } 12967 12968 class ClassBodyScope extends ChildScope { 12969 constructor(parent, classNode) { 12970 const { context } = parent; 12971 super(parent, context); 12972 this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other'))); 12973 this.instanceScope = new ChildScope(this, context); 12974 this.instanceScope.variables.set('this', new ThisVariable(context)); 12975 } 12976 findLexicalBoundary() { 12977 return this; 12978 } 12979 } 12980 12981 class ClassBody extends NodeBase { 12982 createScope(parentScope) { 12983 this.scope = new ClassBodyScope(parentScope, this.parent); 12984 } 12985 include(context, includeChildrenRecursively) { 12986 this.included = true; 12987 this.scope.context.includeVariableInModule(this.scope.thisVariable); 12988 for (const definition of this.body) { 12989 definition.include(context, includeChildrenRecursively); 12990 } 12991 } 12992 parseNode(esTreeNode) { 12993 const body = (this.body = new Array(esTreeNode.body.length)); 12994 let index = 0; 12995 for (const definition of esTreeNode.body) { 12996 body[index++] = new (this.scope.context.getNodeConstructor(definition.type))(this, definition.static ? this.scope : this.scope.instanceScope).parseNode(definition); 12997 } 12998 return super.parseNode(esTreeNode); 12999 } 13000 applyDeoptimizations() { } 13001 } 13002 13003 class ClassExpression extends ClassNode { 13004 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) { 13005 super.render(code, options); 13006 if (renderedSurroundingElement === parseAst_js.ExpressionStatement) { 13007 code.appendRight(this.start, '('); 13008 code.prependLeft(this.end, ')'); 13009 } 13010 } 13011 } 13012 13013 class MultiExpression extends ExpressionEntity { 13014 constructor(expressions) { 13015 super(); 13016 this.expressions = expressions; 13017 } 13018 deoptimizePath(path) { 13019 for (const expression of this.expressions) { 13020 expression.deoptimizePath(path); 13021 } 13022 } 13023 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 13024 return [ 13025 new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0])), 13026 false 13027 ]; 13028 } 13029 hasEffectsOnInteractionAtPath(path, interaction, context) { 13030 for (const expression of this.expressions) { 13031 if (expression.hasEffectsOnInteractionAtPath(path, interaction, context)) 13032 return true; 13033 } 13034 return false; 13035 } 13036 } 13037 13038 class ConditionalExpression extends NodeBase { 13039 constructor() { 13040 super(...arguments); 13041 this.expressionsToBeDeoptimized = []; 13042 this.usedBranch = null; 13043 } 13044 get isBranchResolutionAnalysed() { 13045 return isFlagSet(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */); 13046 } 13047 set isBranchResolutionAnalysed(value) { 13048 this.flags = setFlag(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */, value); 13049 } 13050 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 13051 this.consequent.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 13052 this.alternate.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 13053 } 13054 deoptimizeCache() { 13055 if (this.usedBranch !== null) { 13056 const unusedBranch = this.usedBranch === this.consequent ? this.alternate : this.consequent; 13057 this.usedBranch = null; 13058 unusedBranch.deoptimizePath(UNKNOWN_PATH); 13059 const { expressionsToBeDeoptimized } = this; 13060 this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY; 13061 for (const expression of expressionsToBeDeoptimized) { 13062 expression.deoptimizeCache(); 13063 } 13064 } 13065 } 13066 deoptimizePath(path) { 13067 const usedBranch = this.getUsedBranch(); 13068 if (usedBranch) { 13069 usedBranch.deoptimizePath(path); 13070 } 13071 else { 13072 this.consequent.deoptimizePath(path); 13073 this.alternate.deoptimizePath(path); 13074 } 13075 } 13076 getLiteralValueAtPath(path, recursionTracker, origin) { 13077 const usedBranch = this.getUsedBranch(); 13078 if (!usedBranch) 13079 return UnknownValue; 13080 this.expressionsToBeDeoptimized.push(origin); 13081 return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin); 13082 } 13083 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 13084 const usedBranch = this.getUsedBranch(); 13085 if (!usedBranch) 13086 return [ 13087 new MultiExpression([ 13088 this.consequent.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0], 13089 this.alternate.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0] 13090 ]), 13091 false 13092 ]; 13093 this.expressionsToBeDeoptimized.push(origin); 13094 return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 13095 } 13096 hasEffects(context) { 13097 if (this.test.hasEffects(context)) 13098 return true; 13099 const usedBranch = this.getUsedBranch(); 13100 if (!usedBranch) { 13101 return this.consequent.hasEffects(context) || this.alternate.hasEffects(context); 13102 } 13103 return usedBranch.hasEffects(context); 13104 } 13105 hasEffectsOnInteractionAtPath(path, interaction, context) { 13106 const usedBranch = this.getUsedBranch(); 13107 if (!usedBranch) { 13108 return (this.consequent.hasEffectsOnInteractionAtPath(path, interaction, context) || 13109 this.alternate.hasEffectsOnInteractionAtPath(path, interaction, context)); 13110 } 13111 return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context); 13112 } 13113 include(context, includeChildrenRecursively) { 13114 this.included = true; 13115 const usedBranch = this.getUsedBranch(); 13116 if (includeChildrenRecursively || this.test.shouldBeIncluded(context) || usedBranch === null) { 13117 this.test.include(context, includeChildrenRecursively); 13118 this.consequent.include(context, includeChildrenRecursively); 13119 this.alternate.include(context, includeChildrenRecursively); 13120 } 13121 else { 13122 usedBranch.include(context, includeChildrenRecursively); 13123 } 13124 } 13125 includeCallArguments(context, parameters) { 13126 const usedBranch = this.getUsedBranch(); 13127 if (usedBranch) { 13128 usedBranch.includeCallArguments(context, parameters); 13129 } 13130 else { 13131 this.consequent.includeCallArguments(context, parameters); 13132 this.alternate.includeCallArguments(context, parameters); 13133 } 13134 } 13135 removeAnnotations(code) { 13136 this.test.removeAnnotations(code); 13137 } 13138 render(code, options, { isCalleeOfRenderedParent, preventASI, renderedParentType, renderedSurroundingElement } = parseAst_js.BLANK) { 13139 const usedBranch = this.getUsedBranch(); 13140 if (this.test.included) { 13141 this.test.render(code, options, { renderedSurroundingElement }); 13142 this.consequent.render(code, options); 13143 this.alternate.render(code, options); 13144 } 13145 else { 13146 const colonPos = findFirstOccurrenceOutsideComment(code.original, ':', this.consequent.end); 13147 const inclusionStart = findNonWhiteSpace(code.original, (this.consequent.included 13148 ? findFirstOccurrenceOutsideComment(code.original, '?', this.test.end) 13149 : colonPos) + 1); 13150 if (preventASI) { 13151 removeLineBreaks(code, inclusionStart, usedBranch.start); 13152 } 13153 code.remove(this.start, inclusionStart); 13154 if (this.consequent.included) { 13155 code.remove(colonPos, this.end); 13156 } 13157 this.test.removeAnnotations(code); 13158 usedBranch.render(code, options, { 13159 isCalleeOfRenderedParent, 13160 preventASI: true, 13161 renderedParentType: renderedParentType || this.parent.type, 13162 renderedSurroundingElement: renderedSurroundingElement || this.parent.type 13163 }); 13164 } 13165 } 13166 getUsedBranch() { 13167 if (this.isBranchResolutionAnalysed) { 13168 return this.usedBranch; 13169 } 13170 this.isBranchResolutionAnalysed = true; 13171 const testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 13172 return typeof testValue === 'symbol' 13173 ? null 13174 : (this.usedBranch = testValue ? this.consequent : this.alternate); 13175 } 13176 } 13177 13178 class ContinueStatement extends NodeBase { 13179 hasEffects(context) { 13180 if (this.label) { 13181 if (!context.ignore.labels.has(this.label.name)) 13182 return true; 13183 context.includedLabels.add(this.label.name); 13184 } 13185 else { 13186 if (!context.ignore.continues) 13187 return true; 13188 context.hasContinue = true; 13189 } 13190 context.brokenFlow = true; 13191 return false; 13192 } 13193 include(context) { 13194 this.included = true; 13195 if (this.label) { 13196 this.label.include(); 13197 context.includedLabels.add(this.label.name); 13198 } 13199 else { 13200 context.hasContinue = true; 13201 } 13202 context.brokenFlow = true; 13203 } 13204 } 13205 13206 class DebuggerStatement extends NodeBase { 13207 hasEffects() { 13208 return true; 13209 } 13210 } 13211 13212 class Decorator extends NodeBase { 13213 hasEffects(context) { 13214 return (this.expression.hasEffects(context) || 13215 this.expression.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context)); 13216 } 13217 } 13218 13219 function hasLoopBodyEffects(context, body) { 13220 const { brokenFlow, hasBreak, hasContinue, ignore } = context; 13221 const { breaks, continues } = ignore; 13222 ignore.breaks = true; 13223 ignore.continues = true; 13224 context.hasBreak = false; 13225 context.hasContinue = false; 13226 if (body.hasEffects(context)) 13227 return true; 13228 ignore.breaks = breaks; 13229 ignore.continues = continues; 13230 context.hasBreak = hasBreak; 13231 context.hasContinue = hasContinue; 13232 context.brokenFlow = brokenFlow; 13233 return false; 13234 } 13235 function includeLoopBody(context, body, includeChildrenRecursively) { 13236 const { brokenFlow, hasBreak, hasContinue } = context; 13237 context.hasBreak = false; 13238 context.hasContinue = false; 13239 body.include(context, includeChildrenRecursively, { asSingleStatement: true }); 13240 context.hasBreak = hasBreak; 13241 context.hasContinue = hasContinue; 13242 context.brokenFlow = brokenFlow; 13243 } 13244 13245 class DoWhileStatement extends NodeBase { 13246 hasEffects(context) { 13247 if (this.test.hasEffects(context)) 13248 return true; 13249 return hasLoopBodyEffects(context, this.body); 13250 } 13251 include(context, includeChildrenRecursively) { 13252 this.included = true; 13253 this.test.include(context, includeChildrenRecursively); 13254 includeLoopBody(context, this.body, includeChildrenRecursively); 13255 } 13256 } 13257 13258 class EmptyStatement extends NodeBase { 13259 hasEffects() { 13260 return false; 13261 } 13262 } 13263 13264 class ExportAllDeclaration extends NodeBase { 13265 hasEffects() { 13266 return false; 13267 } 13268 initialise() { 13269 super.initialise(); 13270 this.scope.context.addExport(this); 13271 } 13272 render(code, _options, nodeRenderOptions) { 13273 code.remove(nodeRenderOptions.start, nodeRenderOptions.end); 13274 } 13275 applyDeoptimizations() { } 13276 } 13277 ExportAllDeclaration.prototype.needsBoundaries = true; 13278 13279 class ExportNamedDeclaration extends NodeBase { 13280 bind() { 13281 // Do not bind specifiers 13282 this.declaration?.bind(); 13283 } 13284 hasEffects(context) { 13285 return !!this.declaration?.hasEffects(context); 13286 } 13287 initialise() { 13288 super.initialise(); 13289 this.scope.context.addExport(this); 13290 } 13291 removeAnnotations(code) { 13292 this.declaration?.removeAnnotations(code); 13293 } 13294 render(code, options, nodeRenderOptions) { 13295 const { start, end } = nodeRenderOptions; 13296 if (this.declaration === null) { 13297 code.remove(start, end); 13298 } 13299 else { 13300 code.remove(this.start, this.declaration.start); 13301 this.declaration.render(code, options, { end, start }); 13302 } 13303 } 13304 applyDeoptimizations() { } 13305 } 13306 ExportNamedDeclaration.prototype.needsBoundaries = true; 13307 13308 class ExportSpecifier extends NodeBase { 13309 applyDeoptimizations() { } 13310 } 13311 13312 class ForInStatement extends NodeBase { 13313 createScope(parentScope) { 13314 this.scope = new BlockScope(parentScope); 13315 } 13316 hasEffects(context) { 13317 const { body, deoptimized, left, right } = this; 13318 if (!deoptimized) 13319 this.applyDeoptimizations(); 13320 if (left.hasEffectsAsAssignmentTarget(context, false) || right.hasEffects(context)) 13321 return true; 13322 return hasLoopBodyEffects(context, body); 13323 } 13324 include(context, includeChildrenRecursively) { 13325 const { body, deoptimized, left, right } = this; 13326 if (!deoptimized) 13327 this.applyDeoptimizations(); 13328 this.included = true; 13329 left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false); 13330 right.include(context, includeChildrenRecursively); 13331 includeLoopBody(context, body, includeChildrenRecursively); 13332 } 13333 initialise() { 13334 super.initialise(); 13335 this.left.setAssignedValue(UNKNOWN_EXPRESSION); 13336 } 13337 render(code, options) { 13338 this.left.render(code, options, NO_SEMICOLON); 13339 this.right.render(code, options, NO_SEMICOLON); 13340 // handle no space between "in" and the right side 13341 if (code.original.charCodeAt(this.right.start - 1) === 110 /* n */) { 13342 code.prependLeft(this.right.start, ' '); 13343 } 13344 this.body.render(code, options); 13345 } 13346 applyDeoptimizations() { 13347 this.deoptimized = true; 13348 this.left.deoptimizePath(EMPTY_PATH); 13349 this.scope.context.requestTreeshakingPass(); 13350 } 13351 } 13352 13353 class ForOfStatement extends NodeBase { 13354 get await() { 13355 return isFlagSet(this.flags, 131072 /* Flag.await */); 13356 } 13357 set await(value) { 13358 this.flags = setFlag(this.flags, 131072 /* Flag.await */, value); 13359 } 13360 createScope(parentScope) { 13361 this.scope = new BlockScope(parentScope); 13362 } 13363 hasEffects() { 13364 if (!this.deoptimized) 13365 this.applyDeoptimizations(); 13366 // Placeholder until proper Symbol.Iterator support 13367 return true; 13368 } 13369 include(context, includeChildrenRecursively) { 13370 const { body, deoptimized, left, right } = this; 13371 if (!deoptimized) 13372 this.applyDeoptimizations(); 13373 this.included = true; 13374 left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false); 13375 right.include(context, includeChildrenRecursively); 13376 includeLoopBody(context, body, includeChildrenRecursively); 13377 } 13378 initialise() { 13379 super.initialise(); 13380 this.left.setAssignedValue(UNKNOWN_EXPRESSION); 13381 } 13382 render(code, options) { 13383 this.left.render(code, options, NO_SEMICOLON); 13384 this.right.render(code, options, NO_SEMICOLON); 13385 // handle no space between "of" and the right side 13386 if (code.original.charCodeAt(this.right.start - 1) === 102 /* f */) { 13387 code.prependLeft(this.right.start, ' '); 13388 } 13389 this.body.render(code, options); 13390 } 13391 applyDeoptimizations() { 13392 this.deoptimized = true; 13393 this.left.deoptimizePath(EMPTY_PATH); 13394 this.right.deoptimizePath(UNKNOWN_PATH); 13395 this.scope.context.requestTreeshakingPass(); 13396 } 13397 } 13398 13399 class ForStatement extends NodeBase { 13400 createScope(parentScope) { 13401 this.scope = new BlockScope(parentScope); 13402 } 13403 hasEffects(context) { 13404 if (this.init?.hasEffects(context) || 13405 this.test?.hasEffects(context) || 13406 this.update?.hasEffects(context)) { 13407 return true; 13408 } 13409 return hasLoopBodyEffects(context, this.body); 13410 } 13411 include(context, includeChildrenRecursively) { 13412 this.included = true; 13413 this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true }); 13414 this.test?.include(context, includeChildrenRecursively); 13415 this.update?.include(context, includeChildrenRecursively); 13416 includeLoopBody(context, this.body, includeChildrenRecursively); 13417 } 13418 render(code, options) { 13419 this.init?.render(code, options, NO_SEMICOLON); 13420 this.test?.render(code, options, NO_SEMICOLON); 13421 this.update?.render(code, options, NO_SEMICOLON); 13422 this.body.render(code, options); 13423 } 13424 } 13425 13426 class FunctionExpression extends FunctionNode { 13427 createScope(parentScope) { 13428 super.createScope((this.idScope = new ChildScope(parentScope, parentScope.context))); 13429 } 13430 parseNode(esTreeNode) { 13431 if (esTreeNode.id !== null) { 13432 this.id = new Identifier(this, this.idScope).parseNode(esTreeNode.id); 13433 } 13434 return super.parseNode(esTreeNode); 13435 } 13436 onlyFunctionCallUsed() { 13437 const isIIFE = this.parent.type === parseAst_js.CallExpression && 13438 this.parent.callee === this && 13439 (this.id === null || this.id.variable.getOnlyFunctionCallUsed()); 13440 return isIIFE || super.onlyFunctionCallUsed(); 13441 } 13442 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) { 13443 super.render(code, options); 13444 if (renderedSurroundingElement === parseAst_js.ExpressionStatement) { 13445 code.appendRight(this.start, '('); 13446 code.prependLeft(this.end, ')'); 13447 } 13448 } 13449 } 13450 13451 class TrackingScope extends BlockScope { 13452 constructor() { 13453 super(...arguments); 13454 this.hoistedDeclarations = []; 13455 } 13456 addDeclaration(identifier, context, init, kind) { 13457 this.hoistedDeclarations.push(identifier); 13458 return super.addDeclaration(identifier, context, init, kind); 13459 } 13460 } 13461 13462 const unset = Symbol('unset'); 13463 class IfStatement extends NodeBase { 13464 constructor() { 13465 super(...arguments); 13466 this.testValue = unset; 13467 } 13468 deoptimizeCache() { 13469 this.testValue = UnknownValue; 13470 } 13471 hasEffects(context) { 13472 if (this.test.hasEffects(context)) { 13473 return true; 13474 } 13475 const testValue = this.getTestValue(); 13476 if (typeof testValue === 'symbol') { 13477 const { brokenFlow } = context; 13478 if (this.consequent.hasEffects(context)) 13479 return true; 13480 const consequentBrokenFlow = context.brokenFlow; 13481 context.brokenFlow = brokenFlow; 13482 if (this.alternate === null) 13483 return false; 13484 if (this.alternate.hasEffects(context)) 13485 return true; 13486 context.brokenFlow = context.brokenFlow && consequentBrokenFlow; 13487 return false; 13488 } 13489 return testValue ? this.consequent.hasEffects(context) : !!this.alternate?.hasEffects(context); 13490 } 13491 include(context, includeChildrenRecursively) { 13492 this.included = true; 13493 if (includeChildrenRecursively) { 13494 this.includeRecursively(includeChildrenRecursively, context); 13495 } 13496 else { 13497 const testValue = this.getTestValue(); 13498 if (typeof testValue === 'symbol') { 13499 this.includeUnknownTest(context); 13500 } 13501 else { 13502 this.includeKnownTest(context, testValue); 13503 } 13504 } 13505 } 13506 parseNode(esTreeNode) { 13507 this.consequent = new (this.scope.context.getNodeConstructor(esTreeNode.consequent.type))(this, (this.consequentScope = new TrackingScope(this.scope))).parseNode(esTreeNode.consequent); 13508 if (esTreeNode.alternate) { 13509 this.alternate = new (this.scope.context.getNodeConstructor(esTreeNode.alternate.type))(this, (this.alternateScope = new TrackingScope(this.scope))).parseNode(esTreeNode.alternate); 13510 } 13511 return super.parseNode(esTreeNode); 13512 } 13513 render(code, options) { 13514 const { snippets: { getPropertyAccess } } = options; 13515 // Note that unknown test values are always included 13516 const testValue = this.getTestValue(); 13517 const hoistedDeclarations = []; 13518 const includesIfElse = this.test.included; 13519 const noTreeshake = !this.scope.context.options.treeshake; 13520 if (includesIfElse) { 13521 this.test.render(code, options); 13522 } 13523 else { 13524 code.remove(this.start, this.consequent.start); 13525 } 13526 if (this.consequent.included && (noTreeshake || typeof testValue === 'symbol' || testValue)) { 13527 this.consequent.render(code, options); 13528 } 13529 else { 13530 code.overwrite(this.consequent.start, this.consequent.end, includesIfElse ? ';' : ''); 13531 hoistedDeclarations.push(...this.consequentScope.hoistedDeclarations); 13532 } 13533 if (this.alternate) { 13534 if (this.alternate.included && (noTreeshake || typeof testValue === 'symbol' || !testValue)) { 13535 if (includesIfElse) { 13536 if (code.original.charCodeAt(this.alternate.start - 1) === 101) { 13537 code.prependLeft(this.alternate.start, ' '); 13538 } 13539 } 13540 else { 13541 code.remove(this.consequent.end, this.alternate.start); 13542 } 13543 this.alternate.render(code, options); 13544 } 13545 else { 13546 if (includesIfElse && this.shouldKeepAlternateBranch()) { 13547 code.overwrite(this.alternate.start, this.end, ';'); 13548 } 13549 else { 13550 code.remove(this.consequent.end, this.end); 13551 } 13552 hoistedDeclarations.push(...this.alternateScope.hoistedDeclarations); 13553 } 13554 } 13555 this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess); 13556 } 13557 applyDeoptimizations() { } 13558 getTestValue() { 13559 if (this.testValue === unset) { 13560 return (this.testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)); 13561 } 13562 return this.testValue; 13563 } 13564 includeKnownTest(context, testValue) { 13565 if (this.test.shouldBeIncluded(context)) { 13566 this.test.include(context, false); 13567 } 13568 if (testValue && this.consequent.shouldBeIncluded(context)) { 13569 this.consequent.include(context, false, { asSingleStatement: true }); 13570 } 13571 if (!testValue && this.alternate?.shouldBeIncluded(context)) { 13572 this.alternate.include(context, false, { asSingleStatement: true }); 13573 } 13574 } 13575 includeRecursively(includeChildrenRecursively, context) { 13576 this.test.include(context, includeChildrenRecursively); 13577 this.consequent.include(context, includeChildrenRecursively); 13578 this.alternate?.include(context, includeChildrenRecursively); 13579 } 13580 includeUnknownTest(context) { 13581 this.test.include(context, false); 13582 const { brokenFlow } = context; 13583 let consequentBrokenFlow = false; 13584 if (this.consequent.shouldBeIncluded(context)) { 13585 this.consequent.include(context, false, { asSingleStatement: true }); 13586 consequentBrokenFlow = context.brokenFlow; 13587 context.brokenFlow = brokenFlow; 13588 } 13589 if (this.alternate?.shouldBeIncluded(context)) { 13590 this.alternate.include(context, false, { asSingleStatement: true }); 13591 context.brokenFlow = context.brokenFlow && consequentBrokenFlow; 13592 } 13593 } 13594 renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess) { 13595 const hoistedVariables = [ 13596 ...new Set(hoistedDeclarations.map(identifier => { 13597 const variable = identifier.variable; 13598 return variable.included ? variable.getName(getPropertyAccess) : ''; 13599 })) 13600 ] 13601 .filter(Boolean) 13602 .join(', '); 13603 if (hoistedVariables) { 13604 const parentType = this.parent.type; 13605 const needsBraces = parentType !== parseAst_js.Program && parentType !== parseAst_js.BlockStatement; 13606 code.prependRight(this.start, `${needsBraces ? '{ ' : ''}var ${hoistedVariables}; `); 13607 if (needsBraces) { 13608 code.appendLeft(this.end, ` }`); 13609 } 13610 } 13611 } 13612 shouldKeepAlternateBranch() { 13613 let currentParent = this.parent; 13614 do { 13615 if (currentParent instanceof IfStatement && currentParent.alternate) { 13616 return true; 13617 } 13618 if (currentParent instanceof BlockStatement) { 13619 return false; 13620 } 13621 currentParent = currentParent.parent; 13622 } while (currentParent); 13623 return false; 13624 } 13625 } 13626 13627 class ImportAttribute extends NodeBase { 13628 } 13629 13630 class ImportDeclaration extends NodeBase { 13631 // Do not bind specifiers or attributes 13632 bind() { } 13633 hasEffects() { 13634 return false; 13635 } 13636 initialise() { 13637 super.initialise(); 13638 this.scope.context.addImport(this); 13639 } 13640 render(code, _options, nodeRenderOptions) { 13641 code.remove(nodeRenderOptions.start, nodeRenderOptions.end); 13642 } 13643 applyDeoptimizations() { } 13644 } 13645 ImportDeclaration.prototype.needsBoundaries = true; 13646 13647 class ImportDefaultSpecifier extends NodeBase { 13648 applyDeoptimizations() { } 13649 } 13650 12117 13651 function isReassignedExportsMember(variable, exportNamesByVariable) { 12118 13652 return (variable.renderBaseName !== null && exportNamesByVariable.has(variable) && variable.isReassigned); … … 12473 14007 } 12474 14008 14009 class JSXIdentifier extends IdentifierBase { 14010 constructor() { 14011 super(...arguments); 14012 this.isNativeElement = false; 14013 } 14014 bind() { 14015 const type = this.getType(); 14016 if (type === 0 /* IdentifierType.Reference */) { 14017 this.variable = this.scope.findVariable(this.name); 14018 this.variable.addReference(this); 14019 } 14020 else if (type === 1 /* IdentifierType.NativeElementName */) { 14021 this.isNativeElement = true; 14022 } 14023 } 14024 render(code, { snippets: { getPropertyAccess }, useOriginalName }) { 14025 if (this.variable) { 14026 const name = this.variable.getName(getPropertyAccess, useOriginalName); 14027 if (name !== this.name) { 14028 code.overwrite(this.start, this.end, name, { 14029 contentOnly: true, 14030 storeName: true 14031 }); 14032 } 14033 } 14034 else if (this.isNativeElement && 14035 this.scope.context.options.jsx.mode !== 'preserve') { 14036 code.update(this.start, this.end, JSON.stringify(this.name)); 14037 } 14038 } 14039 getType() { 14040 switch (this.parent.type) { 14041 case 'JSXOpeningElement': 14042 case 'JSXClosingElement': { 14043 return this.name.startsWith(this.name.charAt(0).toUpperCase()) 14044 ? 0 /* IdentifierType.Reference */ 14045 : 1 /* IdentifierType.NativeElementName */; 14046 } 14047 case 'JSXMemberExpression': { 14048 return this.parent.object === this 14049 ? 0 /* IdentifierType.Reference */ 14050 : 2 /* IdentifierType.Other */; 14051 } 14052 case 'JSXAttribute': 14053 case 'JSXNamespacedName': { 14054 return 2 /* IdentifierType.Other */; 14055 } 14056 default: { 14057 /* istanbul ignore next */ 14058 throw new Error(`Unexpected parent node type for JSXIdentifier: ${this.parent.type}`); 14059 } 14060 } 14061 } 14062 } 14063 14064 class JSXAttribute extends NodeBase { 14065 render(code, options, { jsxMode } = parseAst_js.BLANK) { 14066 super.render(code, options); 14067 if (['classic', 'automatic'].includes(jsxMode)) { 14068 const { name, value } = this; 14069 const key = name instanceof JSXIdentifier ? name.name : `${name.namespace.name}:${name.name.name}`; 14070 if (!(jsxMode === 'automatic' && key === 'key')) { 14071 const safeKey = stringifyObjectKeyIfNeeded(key); 14072 if (key !== safeKey) { 14073 code.overwrite(name.start, name.end, safeKey, { contentOnly: true }); 14074 } 14075 if (value) { 14076 code.overwrite(name.end, value.start, ': ', { contentOnly: true }); 14077 } 14078 else { 14079 code.appendLeft(name.end, ': true'); 14080 } 14081 } 14082 } 14083 } 14084 } 14085 14086 class JSXClosingBase extends NodeBase { 14087 render(code, options) { 14088 const { mode } = this.scope.context.options.jsx; 14089 if (mode !== 'preserve') { 14090 code.overwrite(this.start, this.end, ')', { contentOnly: true }); 14091 } 14092 else { 14093 super.render(code, options); 14094 } 14095 } 14096 } 14097 14098 class JSXClosingElement extends JSXClosingBase { 14099 } 14100 14101 class JSXClosingFragment extends JSXClosingBase { 14102 } 14103 14104 class JSXSpreadAttribute extends NodeBase { 14105 render(code, options) { 14106 this.argument.render(code, options); 14107 const { mode } = this.scope.context.options.jsx; 14108 if (mode !== 'preserve') { 14109 code.overwrite(this.start, this.argument.start, '', { contentOnly: true }); 14110 code.overwrite(this.argument.end, this.end, '', { contentOnly: true }); 14111 } 14112 } 14113 } 14114 14115 class JSXEmptyExpression extends NodeBase { 14116 } 14117 14118 class JSXExpressionContainer extends NodeBase { 14119 render(code, options) { 14120 const { mode } = this.scope.context.options.jsx; 14121 if (mode !== 'preserve') { 14122 code.remove(this.start, this.expression.start); 14123 code.remove(this.expression.end, this.end); 14124 } 14125 this.expression.render(code, options); 14126 } 14127 } 14128 14129 function getRenderedJsxChildren(children) { 14130 let renderedChildren = 0; 14131 for (const child of children) { 14132 if (!(child instanceof JSXExpressionContainer && child.expression instanceof JSXEmptyExpression)) { 14133 renderedChildren++; 14134 } 14135 } 14136 return renderedChildren; 14137 } 14138 14139 function getAndIncludeFactoryVariable(factory, preserve, importSource, node) { 14140 const [baseName, nestedName] = factory.split('.'); 14141 let factoryVariable; 14142 if (importSource) { 14143 factoryVariable = node.scope.context.getImportedJsxFactoryVariable(nestedName ? 'default' : baseName, node.start, importSource); 14144 if (preserve) { 14145 // This pretends we are accessing an included global variable of the same name 14146 const globalVariable = node.scope.findGlobal(baseName); 14147 globalVariable.include(); 14148 // This excludes this variable from renaming 14149 factoryVariable.globalName = baseName; 14150 } 14151 } 14152 else { 14153 factoryVariable = node.scope.findGlobal(baseName); 14154 } 14155 node.scope.context.includeVariableInModule(factoryVariable); 14156 if (factoryVariable instanceof LocalVariable) { 14157 factoryVariable.consolidateInitializers(); 14158 factoryVariable.addUsedPlace(node); 14159 node.scope.context.requestTreeshakingPass(); 14160 } 14161 return factoryVariable; 14162 } 14163 14164 class JSXElementBase extends NodeBase { 14165 constructor() { 14166 super(...arguments); 14167 this.factoryVariable = null; 14168 this.factory = null; 14169 } 14170 initialise() { 14171 super.initialise(); 14172 const { importSource } = (this.jsxMode = this.getRenderingMode()); 14173 if (importSource) { 14174 this.scope.context.addImportSource(importSource); 14175 } 14176 } 14177 include(context, includeChildrenRecursively) { 14178 if (!this.included) { 14179 const { factory, importSource, mode } = this.jsxMode; 14180 if (factory) { 14181 this.factory = factory; 14182 this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this); 14183 } 14184 } 14185 super.include(context, includeChildrenRecursively); 14186 } 14187 applyDeoptimizations() { } 14188 getRenderingMode() { 14189 const jsx = this.scope.context.options.jsx; 14190 const { mode, factory, importSource } = jsx; 14191 if (mode === 'automatic') { 14192 return { 14193 factory: getRenderedJsxChildren(this.children) > 1 ? 'jsxs' : 'jsx', 14194 importSource: jsx.jsxImportSource, 14195 mode 14196 }; 14197 } 14198 return { factory, importSource, mode }; 14199 } 14200 renderChildren(code, options, openingEnd) { 14201 const { children } = this; 14202 let hasMultipleChildren = false; 14203 let childrenEnd = openingEnd; 14204 let firstChild = null; 14205 for (const child of children) { 14206 if (child instanceof JSXExpressionContainer && 14207 child.expression instanceof JSXEmptyExpression) { 14208 code.remove(childrenEnd, child.end); 14209 } 14210 else { 14211 code.appendLeft(childrenEnd, ', '); 14212 child.render(code, options); 14213 if (firstChild) { 14214 hasMultipleChildren = true; 14215 } 14216 else { 14217 firstChild = child; 14218 } 14219 } 14220 childrenEnd = child.end; 14221 } 14222 return { childrenEnd, firstChild, hasMultipleChildren }; 14223 } 14224 } 14225 14226 class JSXElement extends JSXElementBase { 14227 render(code, options) { 14228 switch (this.jsxMode.mode) { 14229 case 'classic': { 14230 this.renderClassicMode(code, options); 14231 break; 14232 } 14233 case 'automatic': { 14234 this.renderAutomaticMode(code, options); 14235 break; 14236 } 14237 default: { 14238 super.render(code, options); 14239 } 14240 } 14241 } 14242 getRenderingMode() { 14243 const jsx = this.scope.context.options.jsx; 14244 const { mode, factory, importSource } = jsx; 14245 if (mode === 'automatic') { 14246 // In the case there is a key after a spread attribute, we fall back to 14247 // classic mode, see https://github.com/facebook/react/issues/20031#issuecomment-710346866 14248 // for reasoning. 14249 let hasSpread = false; 14250 for (const attribute of this.openingElement.attributes) { 14251 if (attribute instanceof JSXSpreadAttribute) { 14252 hasSpread = true; 14253 } 14254 else if (hasSpread && attribute.name.name === 'key') { 14255 return { factory, importSource, mode: 'classic' }; 14256 } 14257 } 14258 } 14259 return super.getRenderingMode(); 14260 } 14261 renderClassicMode(code, options) { 14262 const { snippets: { getPropertyAccess }, useOriginalName } = options; 14263 const { closingElement, end, factory, factoryVariable, openingElement: { end: openingEnd, selfClosing } } = this; 14264 const [, ...nestedName] = factory.split('.'); 14265 const { firstAttribute, hasAttributes, hasSpread, inObject, previousEnd } = this.renderAttributes(code, options, [factoryVariable.getName(getPropertyAccess, useOriginalName), ...nestedName].join('.'), false); 14266 this.wrapAttributes(code, inObject, hasAttributes, hasSpread, firstAttribute, 'null', previousEnd); 14267 this.renderChildren(code, options, openingEnd); 14268 if (selfClosing) { 14269 code.appendLeft(end, ')'); 14270 } 14271 else { 14272 closingElement.render(code, options); 14273 } 14274 } 14275 renderAutomaticMode(code, options) { 14276 const { snippets: { getPropertyAccess }, useOriginalName } = options; 14277 const { closingElement, end, factoryVariable, openingElement: { end: openindEnd, selfClosing } } = this; 14278 let { firstAttribute, hasAttributes, hasSpread, inObject, keyAttribute, previousEnd } = this.renderAttributes(code, options, factoryVariable.getName(getPropertyAccess, useOriginalName), true); 14279 const { firstChild, hasMultipleChildren, childrenEnd } = this.renderChildren(code, options, openindEnd); 14280 if (firstChild) { 14281 code.prependRight(firstChild.start, `children: ${hasMultipleChildren ? '[' : ''}`); 14282 if (!inObject) { 14283 code.prependRight(firstChild.start, '{ '); 14284 inObject = true; 14285 } 14286 previousEnd = closingElement.start; 14287 if (hasMultipleChildren) { 14288 code.appendLeft(previousEnd, ']'); 14289 } 14290 } 14291 this.wrapAttributes(code, inObject, hasAttributes || !!firstChild, hasSpread, firstAttribute || firstChild, '{}', childrenEnd); 14292 if (keyAttribute) { 14293 const { value } = keyAttribute; 14294 // This will appear to the left of the moved code... 14295 code.appendLeft(childrenEnd, ', '); 14296 if (value) { 14297 code.move(value.start, value.end, childrenEnd); 14298 } 14299 else { 14300 code.appendLeft(childrenEnd, 'true'); 14301 } 14302 } 14303 if (selfClosing) { 14304 // Moving the key attribute will also move the parenthesis to the right position 14305 code.appendLeft(keyAttribute?.value?.end || end, ')'); 14306 } 14307 else { 14308 closingElement.render(code, options); 14309 } 14310 } 14311 renderAttributes(code, options, factoryName, extractKeyAttribute) { 14312 const { jsxMode: { mode }, openingElement } = this; 14313 const { attributes, end: openingEnd, start: openingStart, name: { start: nameStart, end: nameEnd } } = openingElement; 14314 code.update(openingStart, nameStart, `/*#__PURE__*/${factoryName}(`); 14315 openingElement.render(code, options, { jsxMode: mode }); 14316 let keyAttribute = null; 14317 let hasSpread = false; 14318 let inObject = false; 14319 let previousEnd = nameEnd; 14320 let hasAttributes = false; 14321 let firstAttribute = null; 14322 for (const attribute of attributes) { 14323 if (attribute instanceof JSXAttribute) { 14324 if (extractKeyAttribute && attribute.name.name === 'key') { 14325 keyAttribute = attribute; 14326 code.remove(previousEnd, attribute.value?.start || attribute.end); 14327 continue; 14328 } 14329 code.appendLeft(previousEnd, ','); 14330 if (!inObject) { 14331 code.prependRight(attribute.start, '{ '); 14332 inObject = true; 14333 } 14334 hasAttributes = true; 14335 } 14336 else { 14337 if (inObject) { 14338 if (hasAttributes) { 14339 code.appendLeft(previousEnd, ' '); 14340 } 14341 code.appendLeft(previousEnd, '},'); 14342 inObject = false; 14343 } 14344 else { 14345 code.appendLeft(previousEnd, ','); 14346 } 14347 hasSpread = true; 14348 } 14349 previousEnd = attribute.end; 14350 if (!firstAttribute) { 14351 firstAttribute = attribute; 14352 } 14353 } 14354 code.remove(attributes.at(-1)?.end || previousEnd, openingEnd); 14355 return { firstAttribute, hasAttributes, hasSpread, inObject, keyAttribute, previousEnd }; 14356 } 14357 wrapAttributes(code, inObject, hasAttributes, hasSpread, firstAttribute, missingAttributesFallback, attributesEnd) { 14358 if (inObject) { 14359 code.appendLeft(attributesEnd, ' }'); 14360 } 14361 if (hasSpread) { 14362 if (hasAttributes) { 14363 const { start } = firstAttribute; 14364 if (firstAttribute instanceof JSXSpreadAttribute) { 14365 code.prependRight(start, '{}, '); 14366 } 14367 code.prependRight(start, 'Object.assign('); 14368 code.appendLeft(attributesEnd, ')'); 14369 } 14370 } 14371 else if (!hasAttributes) { 14372 code.appendLeft(attributesEnd, `, ${missingAttributesFallback}`); 14373 } 14374 } 14375 } 14376 14377 class JSXFragment extends JSXElementBase { 14378 render(code, options) { 14379 switch (this.jsxMode.mode) { 14380 case 'classic': { 14381 this.renderClassicMode(code, options); 14382 break; 14383 } 14384 case 'automatic': { 14385 this.renderAutomaticMode(code, options); 14386 break; 14387 } 14388 default: { 14389 super.render(code, options); 14390 } 14391 } 14392 } 14393 renderClassicMode(code, options) { 14394 const { snippets: { getPropertyAccess }, useOriginalName } = options; 14395 const { closingFragment, factory, factoryVariable, openingFragment, start } = this; 14396 const [, ...nestedName] = factory.split('.'); 14397 openingFragment.render(code, options); 14398 code.prependRight(start, `/*#__PURE__*/${[ 14399 factoryVariable.getName(getPropertyAccess, useOriginalName), 14400 ...nestedName 14401 ].join('.')}(`); 14402 code.appendLeft(openingFragment.end, ', null'); 14403 this.renderChildren(code, options, openingFragment.end); 14404 closingFragment.render(code, options); 14405 } 14406 renderAutomaticMode(code, options) { 14407 const { snippets: { getPropertyAccess }, useOriginalName } = options; 14408 const { closingFragment, factoryVariable, openingFragment, start } = this; 14409 openingFragment.render(code, options); 14410 code.prependRight(start, `/*#__PURE__*/${factoryVariable.getName(getPropertyAccess, useOriginalName)}(`); 14411 const { firstChild, hasMultipleChildren, childrenEnd } = this.renderChildren(code, options, openingFragment.end); 14412 if (firstChild) { 14413 code.prependRight(firstChild.start, `{ children: ${hasMultipleChildren ? '[' : ''}`); 14414 if (hasMultipleChildren) { 14415 code.appendLeft(closingFragment.start, ']'); 14416 } 14417 code.appendLeft(childrenEnd, ' }'); 14418 } 14419 else { 14420 code.appendLeft(openingFragment.end, ', {}'); 14421 } 14422 closingFragment.render(code, options); 14423 } 14424 } 14425 14426 class JSXMemberExpression extends NodeBase { 14427 } 14428 14429 class JSXNamespacedName extends NodeBase { 14430 } 14431 14432 class JSXOpeningElement extends NodeBase { 14433 render(code, options, { jsxMode = this.scope.context.options.jsx.mode } = {}) { 14434 this.name.render(code, options); 14435 for (const attribute of this.attributes) { 14436 attribute.render(code, options, { jsxMode }); 14437 } 14438 } 14439 } 14440 14441 class JSXOpeningFragment extends NodeBase { 14442 constructor() { 14443 super(...arguments); 14444 this.fragment = null; 14445 this.fragmentVariable = null; 14446 } 14447 include(context, includeChildrenRecursively) { 14448 if (!this.included) { 14449 const jsx = this.scope.context.options.jsx; 14450 if (jsx.mode === 'automatic') { 14451 this.fragment = 'Fragment'; 14452 this.fragmentVariable = getAndIncludeFactoryVariable('Fragment', false, jsx.jsxImportSource, this); 14453 } 14454 else { 14455 const { fragment, importSource, mode } = jsx; 14456 if (fragment != null) { 14457 this.fragment = fragment; 14458 this.fragmentVariable = getAndIncludeFactoryVariable(fragment, mode === 'preserve', importSource, this); 14459 } 14460 } 14461 } 14462 super.include(context, includeChildrenRecursively); 14463 } 14464 render(code, options) { 14465 const { mode } = this.scope.context.options.jsx; 14466 if (mode !== 'preserve') { 14467 const { snippets: { getPropertyAccess }, useOriginalName } = options; 14468 const [, ...nestedFragment] = this.fragment.split('.'); 14469 const fragment = [ 14470 this.fragmentVariable.getName(getPropertyAccess, useOriginalName), 14471 ...nestedFragment 14472 ].join('.'); 14473 code.update(this.start, this.end, fragment); 14474 } 14475 } 14476 } 14477 14478 class JSXSpreadChild extends NodeBase { 14479 render(code, options) { 14480 super.render(code, options); 14481 const { mode } = this.scope.context.options.jsx; 14482 if (mode !== 'preserve') { 14483 code.overwrite(this.start, this.expression.start, '...', { contentOnly: true }); 14484 code.overwrite(this.expression.end, this.end, '', { contentOnly: true }); 14485 } 14486 } 14487 } 14488 14489 class JSXText extends NodeBase { 14490 render(code) { 14491 const { mode } = this.scope.context.options.jsx; 14492 if (mode !== 'preserve') { 14493 code.overwrite(this.start, this.end, JSON.stringify(this.value), { 14494 contentOnly: true 14495 }); 14496 } 14497 } 14498 } 14499 12475 14500 class LabeledStatement extends NodeBase { 12476 14501 hasEffects(context) { … … 12660 14685 } 12661 14686 12662 const FILE_PREFIX = 'ROLLUP_FILE_URL_';12663 const IMPORT = 'import';12664 class MetaProperty extends NodeBase {12665 constructor() {12666 super(...arguments);12667 this.metaProperty = null;12668 this.preliminaryChunkId = null;12669 this.referenceId = null;12670 }12671 getReferencedFileName(outputPluginDriver) {12672 const { meta: { name }, metaProperty } = this;12673 if (name === IMPORT && metaProperty?.startsWith(FILE_PREFIX)) {12674 return outputPluginDriver.getFileName(metaProperty.slice(FILE_PREFIX.length));12675 }12676 return null;12677 }12678 hasEffects() {12679 return false;12680 }12681 hasEffectsOnInteractionAtPath(path, { type }) {12682 return path.length > 1 || type !== INTERACTION_ACCESSED;12683 }12684 include() {12685 if (!this.included) {12686 this.included = true;12687 if (this.meta.name === IMPORT) {12688 this.scope.context.addImportMeta(this);12689 const parent = this.parent;12690 const metaProperty = (this.metaProperty =12691 parent instanceof MemberExpression && typeof parent.propertyKey === 'string'12692 ? parent.propertyKey12693 : null);12694 if (metaProperty?.startsWith(FILE_PREFIX)) {12695 this.referenceId = metaProperty.slice(FILE_PREFIX.length);12696 }12697 }12698 }12699 }12700 render(code, renderOptions) {12701 const { format, pluginDriver, snippets } = renderOptions;12702 const { scope: { context: { module } }, meta: { name }, metaProperty, parent, preliminaryChunkId, referenceId, start, end } = this;12703 const { id: moduleId } = module;12704 if (name !== IMPORT)12705 return;12706 const chunkId = preliminaryChunkId;12707 if (referenceId) {12708 const fileName = pluginDriver.getFileName(referenceId);12709 const relativePath = parseAst_js.normalize(path$2.relative(path$2.dirname(chunkId), fileName));12710 const replacement = pluginDriver.hookFirstSync('resolveFileUrl', [12711 { chunkId, fileName, format, moduleId, referenceId, relativePath }12712 ]) || relativeUrlMechanisms[format](relativePath);12713 code.overwrite(parent.start, parent.end, replacement, { contentOnly: true });12714 return;12715 }12716 let replacement = pluginDriver.hookFirstSync('resolveImportMeta', [12717 metaProperty,12718 { chunkId, format, moduleId }12719 ]);12720 if (!replacement) {12721 replacement = importMetaMechanisms[format]?.(metaProperty, { chunkId, snippets });12722 renderOptions.accessedDocumentCurrentScript ||=12723 formatsMaybeAccessDocumentCurrentScript.includes(format) && replacement !== 'undefined';12724 }12725 if (typeof replacement === 'string') {12726 if (parent instanceof MemberExpression) {12727 code.overwrite(parent.start, parent.end, replacement, { contentOnly: true });12728 }12729 else {12730 code.overwrite(start, end, replacement, { contentOnly: true });12731 }12732 }12733 }12734 setResolution(format, accessedGlobalsByScope, preliminaryChunkId) {12735 this.preliminaryChunkId = preliminaryChunkId;12736 const accessedGlobals = (this.metaProperty?.startsWith(FILE_PREFIX) ? accessedFileUrlGlobals : accessedMetaUrlGlobals)[format];12737 if (accessedGlobals.length > 0) {12738 this.scope.addAccessedGlobals(accessedGlobals, accessedGlobalsByScope);12739 }12740 }12741 }12742 const formatsMaybeAccessDocumentCurrentScript = ['cjs', 'iife', 'umd'];12743 const accessedMetaUrlGlobals = {12744 amd: ['document', 'module', 'URL'],12745 cjs: ['document', 'require', 'URL', DOCUMENT_CURRENT_SCRIPT],12746 es: [],12747 iife: ['document', 'URL', DOCUMENT_CURRENT_SCRIPT],12748 system: ['module'],12749 umd: ['document', 'require', 'URL', DOCUMENT_CURRENT_SCRIPT]12750 };12751 const accessedFileUrlGlobals = {12752 amd: ['document', 'require', 'URL'],12753 cjs: ['document', 'require', 'URL'],12754 es: [],12755 iife: ['document', 'URL'],12756 system: ['module', 'URL'],12757 umd: ['document', 'require', 'URL']12758 };12759 const getResolveUrl = (path, URL = 'URL') => `new ${URL}(${path}).href`;12760 const getRelativeUrlFromDocument = (relativePath, umd = false) => getResolveUrl(`'${escapeId(relativePath)}', ${umd ? `typeof document === 'undefined' ? location.href : ` : ''}document.currentScript && document.currentScript.src || document.baseURI`);12761 const getGenericImportMetaMechanism = (getUrl) => (property, { chunkId }) => {12762 const urlMechanism = getUrl(chunkId);12763 return property === null12764 ? `({ url: ${urlMechanism} })`12765 : property === 'url'12766 ? urlMechanism12767 : 'undefined';12768 };12769 const getFileUrlFromFullPath = (path) => `require('u' + 'rl').pathToFileURL(${path}).href`;12770 const getFileUrlFromRelativePath = (path) => getFileUrlFromFullPath(`__dirname + '/${escapeId(path)}'`);12771 const getUrlFromDocument = (chunkId, umd = false) => `${umd ? `typeof document === 'undefined' ? location.href : ` : ''}(${DOCUMENT_CURRENT_SCRIPT} && ${DOCUMENT_CURRENT_SCRIPT}.src || new URL('${escapeId(chunkId)}', document.baseURI).href)`;12772 const relativeUrlMechanisms = {12773 amd: relativePath => {12774 if (relativePath[0] !== '.')12775 relativePath = './' + relativePath;12776 return getResolveUrl(`require.toUrl('${escapeId(relativePath)}'), document.baseURI`);12777 },12778 cjs: relativePath => `(typeof document === 'undefined' ? ${getFileUrlFromRelativePath(relativePath)} : ${getRelativeUrlFromDocument(relativePath)})`,12779 es: relativePath => getResolveUrl(`'${escapeId(relativePath)}', import.meta.url`),12780 iife: relativePath => getRelativeUrlFromDocument(relativePath),12781 system: relativePath => getResolveUrl(`'${escapeId(relativePath)}', module.meta.url`),12782 umd: relativePath => `(typeof document === 'undefined' && typeof location === 'undefined' ? ${getFileUrlFromRelativePath(relativePath)} : ${getRelativeUrlFromDocument(relativePath, true)})`12783 };12784 const importMetaMechanisms = {12785 amd: getGenericImportMetaMechanism(() => getResolveUrl(`module.uri, document.baseURI`)),12786 cjs: getGenericImportMetaMechanism(chunkId => `(typeof document === 'undefined' ? ${getFileUrlFromFullPath('__filename')} : ${getUrlFromDocument(chunkId)})`),12787 iife: getGenericImportMetaMechanism(chunkId => getUrlFromDocument(chunkId)),12788 system: (property, { snippets: { getPropertyAccess } }) => property === null ? `module.meta` : `module.meta${getPropertyAccess(property)}`,12789 umd: getGenericImportMetaMechanism(chunkId => `(typeof document === 'undefined' && typeof location === 'undefined' ? ${getFileUrlFromFullPath('__filename')} : ${getUrlFromDocument(chunkId, true)})`)12790 };12791 12792 14687 class NewExpression extends NodeBase { 12793 14688 hasEffects(context) { … … 13224 15119 render(code, options, nodeRenderOptions) { 13225 15120 if (this.consequent.length > 0) { 13226 this.test && this.test.render(code, options); 15121 if (this.test) { 15122 this.test.render(code, options); 15123 } 13227 15124 const testEnd = this.test 13228 15125 ? this.test.end … … 13436 15333 code.indentExclusionRanges.push([this.start, this.end]); 13437 15334 super.render(code, options); 13438 }13439 }13440 13441 class UndefinedVariable extends Variable {13442 constructor() {13443 super('undefined');13444 }13445 getLiteralValueAtPath() {13446 return undefined;13447 }13448 }13449 13450 class ExportDefaultVariable extends LocalVariable {13451 constructor(name, exportDefaultDeclaration, context) {13452 super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');13453 this.hasId = false;13454 this.originalId = null;13455 this.originalVariable = null;13456 const declaration = exportDefaultDeclaration.declaration;13457 if ((declaration instanceof FunctionDeclaration || declaration instanceof ClassDeclaration) &&13458 declaration.id) {13459 this.hasId = true;13460 this.originalId = declaration.id;13461 }13462 else if (declaration instanceof Identifier) {13463 this.originalId = declaration;13464 }13465 }13466 addReference(identifier) {13467 if (!this.hasId) {13468 this.name = identifier.name;13469 }13470 }13471 addUsedPlace(usedPlace) {13472 const original = this.getOriginalVariable();13473 if (original === this) {13474 super.addUsedPlace(usedPlace);13475 }13476 else {13477 original.addUsedPlace(usedPlace);13478 }13479 }13480 forbidName(name) {13481 const original = this.getOriginalVariable();13482 if (original === this) {13483 super.forbidName(name);13484 }13485 else {13486 original.forbidName(name);13487 }13488 }13489 getAssignedVariableName() {13490 return (this.originalId && this.originalId.name) || null;13491 }13492 getBaseVariableName() {13493 const original = this.getOriginalVariable();13494 return original === this ? super.getBaseVariableName() : original.getBaseVariableName();13495 }13496 getDirectOriginalVariable() {13497 return this.originalId &&13498 (this.hasId ||13499 !(this.originalId.isPossibleTDZ() ||13500 this.originalId.variable.isReassigned ||13501 this.originalId.variable instanceof UndefinedVariable ||13502 // this avoids a circular dependency13503 'syntheticNamespace' in this.originalId.variable))13504 ? this.originalId.variable13505 : null;13506 }13507 getName(getPropertyAccess) {13508 const original = this.getOriginalVariable();13509 return original === this13510 ? super.getName(getPropertyAccess)13511 : original.getName(getPropertyAccess);13512 }13513 getOriginalVariable() {13514 if (this.originalVariable)13515 return this.originalVariable;13516 // eslint-disable-next-line @typescript-eslint/no-this-alias13517 let original = this;13518 let currentVariable;13519 const checkedVariables = new Set();13520 do {13521 checkedVariables.add(original);13522 currentVariable = original;13523 original = currentVariable.getDirectOriginalVariable();13524 } while (original instanceof ExportDefaultVariable && !checkedVariables.has(original));13525 return (this.originalVariable = original || currentVariable);13526 15335 } 13527 15336 } … … 14017 15826 'ImportNamespaceSpecifier', 14018 15827 'ImportSpecifier', 15828 'JSXAttribute', 15829 'JSXClosingElement', 15830 'JSXClosingFragment', 15831 'JSXElement', 15832 'JSXEmptyExpression', 15833 'JSXExpressionContainer', 15834 'JSXFragment', 15835 'JSXIdentifier', 15836 'JSXMemberExpression', 15837 'JSXNamespacedName', 15838 'JSXOpeningElement', 15839 'JSXOpeningFragment', 15840 'JSXSpreadAttribute', 15841 'JSXSpreadChild', 15842 'JSXText', 14019 15843 'LabeledStatement', 14020 15844 'Literal', … … 14099 15923 ImportNamespaceSpecifier, 14100 15924 ImportSpecifier, 15925 JSXAttribute, 15926 JSXClosingElement, 15927 JSXClosingFragment, 15928 JSXElement, 15929 JSXEmptyExpression, 15930 JSXExpressionContainer, 15931 JSXFragment, 15932 JSXIdentifier, 15933 JSXMemberExpression, 15934 JSXNamespacedName, 15935 JSXOpeningElement, 15936 JSXOpeningFragment, 15937 JSXSpreadAttribute, 15938 JSXSpreadChild, 15939 JSXText, 14101 15940 LabeledStatement, 14102 15941 Literal, … … 14218 16057 const { scope } = node; 14219 16058 const bodyPosition = buffer[position]; 14220 const body = (node.body = []);14221 16059 if (bodyPosition) { 14222 16060 const length = buffer[bodyPosition]; 16061 const body = (node.body = new Array(length)); 14223 16062 for (let index = 0; index < length; index++) { 14224 16063 const nodePosition = buffer[bodyPosition + 1 + index]; 14225 body.push(convertNode(node, (buffer[nodePosition + 3] & 1) === 0 ? scope.instanceScope : scope, nodePosition, buffer)); 14226 } 16064 body[index] = convertNode(node, (buffer[nodePosition + 3] & 1) === 0 ? scope.instanceScope : scope, nodePosition, buffer); 16065 } 16066 } 16067 else { 16068 node.body = []; 14227 16069 } 14228 16070 }, … … 14404 16246 node.imported = 14405 16247 importedPosition === 0 ? node.local : convertNode(node, scope, importedPosition, buffer); 16248 }, 16249 function jsxAttribute(node, position, buffer) { 16250 const { scope } = node; 16251 node.name = convertNode(node, scope, buffer[position], buffer); 16252 const valuePosition = buffer[position + 1]; 16253 node.value = valuePosition === 0 ? null : convertNode(node, scope, valuePosition, buffer); 16254 }, 16255 function jsxClosingElement(node, position, buffer) { 16256 const { scope } = node; 16257 node.name = convertNode(node, scope, buffer[position], buffer); 16258 }, 16259 function jsxClosingFragment() { }, 16260 function jsxElement(node, position, buffer) { 16261 const { scope } = node; 16262 node.openingElement = convertNode(node, scope, buffer[position], buffer); 16263 node.children = convertNodeList(node, scope, buffer[position + 1], buffer); 16264 const closingElementPosition = buffer[position + 2]; 16265 node.closingElement = 16266 closingElementPosition === 0 16267 ? null 16268 : convertNode(node, scope, closingElementPosition, buffer); 16269 }, 16270 function jsxEmptyExpression() { }, 16271 function jsxExpressionContainer(node, position, buffer) { 16272 const { scope } = node; 16273 node.expression = convertNode(node, scope, buffer[position], buffer); 16274 }, 16275 function jsxFragment(node, position, buffer) { 16276 const { scope } = node; 16277 node.openingFragment = convertNode(node, scope, buffer[position], buffer); 16278 node.children = convertNodeList(node, scope, buffer[position + 1], buffer); 16279 node.closingFragment = convertNode(node, scope, buffer[position + 2], buffer); 16280 }, 16281 function jsxIdentifier(node, position, buffer) { 16282 node.name = buffer.convertString(buffer[position]); 16283 }, 16284 function jsxMemberExpression(node, position, buffer) { 16285 const { scope } = node; 16286 node.object = convertNode(node, scope, buffer[position], buffer); 16287 node.property = convertNode(node, scope, buffer[position + 1], buffer); 16288 }, 16289 function jsxNamespacedName(node, position, buffer) { 16290 const { scope } = node; 16291 node.namespace = convertNode(node, scope, buffer[position], buffer); 16292 node.name = convertNode(node, scope, buffer[position + 1], buffer); 16293 }, 16294 function jsxOpeningElement(node, position, buffer) { 16295 const { scope } = node; 16296 const flags = buffer[position]; 16297 node.selfClosing = (flags & 1) === 1; 16298 node.name = convertNode(node, scope, buffer[position + 1], buffer); 16299 node.attributes = convertNodeList(node, scope, buffer[position + 2], buffer); 16300 }, 16301 function jsxOpeningFragment(node) { 16302 node.attributes = []; 16303 node.selfClosing = false; 16304 }, 16305 function jsxSpreadAttribute(node, position, buffer) { 16306 const { scope } = node; 16307 node.argument = convertNode(node, scope, buffer[position], buffer); 16308 }, 16309 function jsxSpreadChild(node, position, buffer) { 16310 const { scope } = node; 16311 node.expression = convertNode(node, scope, buffer[position], buffer); 16312 }, 16313 function jsxText(node, position, buffer) { 16314 node.value = buffer.convertString(buffer[position]); 16315 node.raw = buffer.convertString(buffer[position + 1]); 14406 16316 }, 14407 16317 function labeledStatement(node, position, buffer) { … … 14635 16545 return parseAst_js.EMPTY_ARRAY; 14636 16546 const length = buffer[position++]; 14637 const list = [];16547 const list = new Array(length); 14638 16548 for (let index = 0; index < length; index++) { 14639 16549 const nodePosition = buffer[position++]; 14640 list .push(nodePosition ? convertNode(parent, parentScope, nodePosition, buffer) : null);16550 list[index] = nodePosition ? convertNode(parent, parentScope, nodePosition, buffer) : null; 14641 16551 } 14642 16552 return list; … … 14694 16604 ImportNamespaceSpecifier, 14695 16605 ImportSpecifier, 16606 JSXAttribute, 16607 JSXClosingElement, 16608 JSXClosingFragment, 16609 JSXElement, 16610 JSXEmptyExpression, 16611 JSXExpressionContainer, 16612 JSXFragment, 16613 JSXIdentifier, 16614 JSXMemberExpression, 16615 JSXNamespacedName, 16616 JSXOpeningElement, 16617 JSXOpeningFragment, 16618 JSXSpreadAttribute, 16619 JSXSpreadChild, 16620 JSXText, 14696 16621 LabeledStatement, 14697 16622 Literal, … … 14732 16657 }; 14733 16658 14734 const MISSING_EXPORT_SHIM_VARIABLE = '_missingExportShim';14735 14736 16659 class ExportShimVariable extends Variable { 14737 16660 constructor(module) { … … 14742 16665 super.include(); 14743 16666 this.module.needsExportShim = true; 14744 }14745 }14746 14747 class NamespaceVariable extends Variable {14748 constructor(context) {14749 super(context.getModuleName());14750 this.memberVariables = null;14751 this.mergedNamespaces = [];14752 this.referencedEarly = false;14753 this.references = [];14754 this.context = context;14755 this.module = context.module;14756 }14757 addReference(identifier) {14758 this.references.push(identifier);14759 this.name = identifier.name;14760 }14761 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {14762 if (path.length > 1 || (path.length === 1 && interaction.type === INTERACTION_CALLED)) {14763 const key = path[0];14764 if (typeof key === 'string') {14765 this.getMemberVariables()[key]?.deoptimizeArgumentsOnInteractionAtPath(interaction, path.slice(1), recursionTracker);14766 }14767 else {14768 deoptimizeInteraction(interaction);14769 }14770 }14771 }14772 deoptimizePath(path) {14773 if (path.length > 1) {14774 const key = path[0];14775 if (typeof key === 'string') {14776 this.getMemberVariables()[key]?.deoptimizePath(path.slice(1));14777 }14778 }14779 }14780 getLiteralValueAtPath(path) {14781 if (path[0] === SymbolToStringTag) {14782 return 'Module';14783 }14784 return UnknownValue;14785 }14786 getMemberVariables() {14787 if (this.memberVariables) {14788 return this.memberVariables;14789 }14790 const memberVariables = Object.create(null);14791 const sortedExports = [...this.context.getExports(), ...this.context.getReexports()].sort();14792 for (const name of sortedExports) {14793 if (name[0] !== '*' && name !== this.module.info.syntheticNamedExports) {14794 const exportedVariable = this.context.traceExport(name);14795 if (exportedVariable) {14796 memberVariables[name] = exportedVariable;14797 }14798 }14799 }14800 return (this.memberVariables = memberVariables);14801 }14802 hasEffectsOnInteractionAtPath(path, interaction, context) {14803 const { type } = interaction;14804 if (path.length === 0) {14805 // This can only be a call anyway14806 return true;14807 }14808 if (path.length === 1 && type !== INTERACTION_CALLED) {14809 return type === INTERACTION_ASSIGNED;14810 }14811 const key = path[0];14812 if (typeof key !== 'string') {14813 return true;14814 }14815 const memberVariable = this.getMemberVariables()[key];14816 return (!memberVariable ||14817 memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));14818 }14819 include() {14820 super.include();14821 this.context.includeAllExports();14822 }14823 prepare(accessedGlobalsByScope) {14824 if (this.mergedNamespaces.length > 0) {14825 this.module.scope.addAccessedGlobals([MERGE_NAMESPACES_VARIABLE], accessedGlobalsByScope);14826 }14827 }14828 renderBlock(options) {14829 const { exportNamesByVariable, format, freeze, indent: t, symbols, snippets: { _, cnst, getObject, getPropertyAccess, n, s } } = options;14830 const memberVariables = this.getMemberVariables();14831 const members = Object.entries(memberVariables)14832 .filter(([_, variable]) => variable.included)14833 .map(([name, variable]) => {14834 if (this.referencedEarly || variable.isReassigned || variable === this) {14835 return [14836 null,14837 `get ${stringifyObjectKeyIfNeeded(name)}${_}()${_}{${_}return ${variable.getName(getPropertyAccess)}${s}${_}}`14838 ];14839 }14840 return [name, variable.getName(getPropertyAccess)];14841 });14842 members.unshift([null, `__proto__:${_}null`]);14843 let output = getObject(members, { lineBreakIndent: { base: '', t } });14844 if (this.mergedNamespaces.length > 0) {14845 const assignmentArguments = this.mergedNamespaces.map(variable => variable.getName(getPropertyAccess));14846 output = `/*#__PURE__*/${MERGE_NAMESPACES_VARIABLE}(${output},${_}[${assignmentArguments.join(`,${_}`)}])`;14847 }14848 else {14849 // The helper to merge namespaces will also take care of freezing and toStringTag14850 if (symbols) {14851 output = `/*#__PURE__*/Object.defineProperty(${output},${_}Symbol.toStringTag,${_}${getToStringTagValue(getObject)})`;14852 }14853 if (freeze) {14854 output = `/*#__PURE__*/Object.freeze(${output})`;14855 }14856 }14857 const name = this.getName(getPropertyAccess);14858 output = `${cnst} ${name}${_}=${_}${output};`;14859 if (format === 'system' && exportNamesByVariable.has(this)) {14860 output += `${n}${getSystemExportStatement([this], options)};`;14861 }14862 return output;14863 }14864 renderFirst() {14865 return this.referencedEarly;14866 }14867 setMergedNamespaces(mergedNamespaces) {14868 this.mergedNamespaces = mergedNamespaces;14869 const moduleExecIndex = this.context.getModuleExecIndex();14870 for (const identifier of this.references) {14871 const { context } = identifier.scope;14872 if (context.getModuleExecIndex() <= moduleExecIndex) {14873 this.referencedEarly = true;14874 break;14875 }14876 }14877 }14878 }14879 NamespaceVariable.prototype.isNamespace = true;14880 14881 class SyntheticNamedExportVariable extends Variable {14882 constructor(context, name, syntheticNamespace) {14883 super(name);14884 this.baseVariable = null;14885 this.context = context;14886 this.module = context.module;14887 this.syntheticNamespace = syntheticNamespace;14888 }14889 getBaseVariable() {14890 if (this.baseVariable)14891 return this.baseVariable;14892 let baseVariable = this.syntheticNamespace;14893 while (baseVariable instanceof ExportDefaultVariable ||14894 baseVariable instanceof SyntheticNamedExportVariable) {14895 if (baseVariable instanceof ExportDefaultVariable) {14896 const original = baseVariable.getOriginalVariable();14897 if (original === baseVariable)14898 break;14899 baseVariable = original;14900 }14901 if (baseVariable instanceof SyntheticNamedExportVariable) {14902 baseVariable = baseVariable.syntheticNamespace;14903 }14904 }14905 return (this.baseVariable = baseVariable);14906 }14907 getBaseVariableName() {14908 return this.syntheticNamespace.getBaseVariableName();14909 }14910 getName(getPropertyAccess) {14911 return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;14912 }14913 include() {14914 super.include();14915 this.context.includeVariableInModule(this.syntheticNamespace);14916 }14917 setRenderNames(baseName, name) {14918 super.setRenderNames(baseName, name);14919 16667 } 14920 16668 } … … 15185 16933 } 15186 16934 15187 function markModuleAndImpureDependenciesAsExecuted(baseModule) {15188 baseModule.isExecuted = true;15189 const modules = [baseModule];15190 const visitedModules = new Set();15191 for (const module of modules) {15192 for (const dependency of [...module.dependencies, ...module.implicitlyLoadedBefore]) {15193 if (!(dependency instanceof ExternalModule) &&15194 !dependency.isExecuted &&15195 (dependency.info.moduleSideEffects || module.implicitlyLoadedBefore.has(dependency)) &&15196 !visitedModules.has(dependency.id)) {15197 dependency.isExecuted = true;15198 visitedModules.add(dependency.id);15199 modules.push(dependency);15200 }15201 }15202 }15203 }15204 15205 16935 const MISSING_EXPORT_SHIM_DESCRIPTION = { 15206 16936 identifier: null, … … 15264 16994 this.dynamicImports = []; 15265 16995 this.execIndex = Infinity; 16996 this.hasTreeShakingPassStarted = false; 15266 16997 this.implicitlyLoadedAfter = new Set(); 15267 16998 this.implicitlyLoadedBefore = new Set(); … … 15340 17071 id, 15341 17072 get implicitlyLoadedAfterOneOf() { 15342 // eslint-disable-next-line unicorn/prefer-spread15343 17073 return Array.from(implicitlyLoadedAfter, getId).sort(); 15344 17074 }, 15345 17075 get implicitlyLoadedBefore() { 15346 // eslint-disable-next-line unicorn/prefer-spread15347 17076 return Array.from(implicitlyLoadedBefore, getId).sort(); 15348 17077 }, 15349 17078 get importedIdResolutions() { 15350 // eslint-disable-next-line unicorn/prefer-spread15351 17079 return Array.from(sourcesWithAttributes.keys(), source => module.resolvedIds[source]).filter(Boolean); 15352 17080 }, … … 15354 17082 // We cannot use this.dependencies because this is needed before 15355 17083 // dependencies are populated 15356 // eslint-disable-next-line unicorn/prefer-spread15357 17084 return Array.from(sourcesWithAttributes.keys(), source => module.resolvedIds[source]?.id).filter(Boolean); 15358 17085 }, … … 15374 17101 } 15375 17102 basename() { 15376 const base = path $2.basename(this.id);15377 const extension = path $2.extname(this.id);17103 const base = path.basename(this.id); 17104 const extension = path.extname(this.id); 15378 17105 return makeLegal(extension ? base.slice(0, -extension.length) : base); 15379 17106 } … … 15397 17124 } 15398 17125 error(properties, pos) { 15399 pos !== undefined && this.addLocationToLogProps(properties, pos); 17126 if (pos !== undefined) { 17127 this.addLocationToLogProps(properties, pos); 17128 } 15400 17129 return parseAst_js.error(properties); 15401 17130 } … … 15750 17479 addImport: this.addImport.bind(this), 15751 17480 addImportMeta: this.addImportMeta.bind(this), 17481 addImportSource: this.addImportSource.bind(this), 15752 17482 code, // Only needed for debugging 15753 17483 deoptimizationTracker: this.graph.deoptimizationTracker, … … 15755 17485 fileName, // Needed for warnings 15756 17486 getExports: this.getExports.bind(this), 17487 getImportedJsxFactoryVariable: this.getImportedJsxFactoryVariable.bind(this), 15757 17488 getModuleExecIndex: () => this.execIndex, 15758 17489 getModuleName: this.basename.bind(this), … … 15784 17515 // Measuring asynchronous code does not provide reasonable results 15785 17516 timeEnd('generate ast', 3); 15786 const astBuffer = await native_js.parseAsync(code, false );17517 const astBuffer = await native_js.parseAsync(code, false, this.options.jsx !== false); 15787 17518 timeStart('generate ast', 3); 15788 17519 this.ast = convertProgram(astBuffer, programParent, this.scope); … … 15819 17550 code: this.info.code, 15820 17551 customTransformCache: this.customTransformCache, 15821 // eslint-disable-next-line unicorn/prefer-spread15822 17552 dependencies: Array.from(this.dependencies, getId), 15823 17553 id: this.id, … … 15976 17706 start: specifier.start 15977 17707 }); 17708 } 17709 } 17710 addImportSource(importSource) { 17711 if (importSource && !this.sourcesWithAttributes.has(importSource)) { 17712 this.sourcesWithAttributes.set(importSource, parseAst_js.EMPTY_OBJECT); 15978 17713 } 15979 17714 } … … 16041 17776 } 16042 17777 } 17778 getImportedJsxFactoryVariable(baseName, nodeStart, importSource) { 17779 const { id } = this.resolvedIds[importSource]; 17780 const module = this.graph.modulesById.get(id); 17781 const [variable] = module.getVariableForExportName(baseName); 17782 if (!variable) { 17783 return this.error(parseAst_js.logMissingJsxExport(baseName, id, this.id), nodeStart); 17784 } 17785 return variable; 17786 } 16043 17787 getVariableFromNamespaceReexports(name, importerForSideEffects, searchedNamesAndModules) { 16044 17788 let foundSyntheticDeclaration = null; … … 16161 17905 tryParse() { 16162 17906 try { 16163 return parseAst_js.parseAst(this.info.code );17907 return parseAst_js.parseAst(this.info.code, { jsx: this.options.jsx !== false }); 16164 17908 } 16165 17909 catch (error_) { … … 16186 17930 } 16187 17931 const copyNameToModulesMap = (searchedNamesAndModules) => searchedNamesAndModules && 16188 // eslint-disable-next-line unicorn/prefer-spread16189 17932 new Map(Array.from(searchedNamesAndModules, ([name, modules]) => [name, new Set(modules)])); 16190 16191 function removeJsExtension(name) {16192 return name.endsWith('.js') ? name.slice(0, -3) : name;16193 }16194 16195 function getCompleteAmdId(options, chunkId) {16196 if (options.autoId) {16197 return `${options.basePath ? options.basePath + '/' : ''}${removeJsExtension(chunkId)}`;16198 }16199 return options.id ?? '';16200 }16201 16202 function getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal, mechanism = 'return ') {16203 const { _, getDirectReturnFunction, getFunctionIntro, getPropertyAccess, n, s } = snippets;16204 if (!namedExportsMode) {16205 return `${n}${n}${mechanism}${getSingleDefaultExport(exports, dependencies, interop, externalLiveBindings, getPropertyAccess)};`;16206 }16207 let exportBlock = '';16208 if (namedExportsMode) {16209 for (const { defaultVariableName, importPath, isChunk, name, namedExportsMode: depNamedExportsMode, namespaceVariableName, reexports } of dependencies) {16210 if (!reexports) {16211 continue;16212 }16213 for (const specifier of reexports) {16214 if (specifier.reexported !== '*') {16215 const importName = getReexportedImportName(name, specifier.imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, importPath, externalLiveBindings, getPropertyAccess);16216 if (exportBlock)16217 exportBlock += n;16218 if (specifier.imported !== '*' && specifier.needsLiveBinding) {16219 const [left, right] = getDirectReturnFunction([], {16220 functionReturn: true,16221 lineBreakIndent: null,16222 name: null16223 });16224 exportBlock +=16225 `Object.defineProperty(exports,${_}${JSON.stringify(specifier.reexported)},${_}{${n}` +16226 `${t}enumerable:${_}true,${n}` +16227 `${t}get:${_}${left}${importName}${right}${n}});`;16228 }16229 else if (specifier.reexported === '__proto__') {16230 exportBlock +=16231 `Object.defineProperty(exports,${_}"__proto__",${_}{${n}` +16232 `${t}enumerable:${_}true,${n}` +16233 `${t}value:${_}${importName}${n}});`;16234 }16235 else {16236 exportBlock += `exports${getPropertyAccess(specifier.reexported)}${_}=${_}${importName};`;16237 }16238 }16239 }16240 }16241 }16242 for (const { exported, local } of exports) {16243 const lhs = `exports${getPropertyAccess(exported)}`;16244 const rhs = local;16245 if (lhs !== rhs) {16246 if (exportBlock)16247 exportBlock += n;16248 exportBlock +=16249 exported === '__proto__'16250 ? `Object.defineProperty(exports,${_}"__proto__",${_}{${n}` +16251 `${t}enumerable:${_}true,${n}` +16252 `${t}value:${_}${rhs}${n}});`16253 : `${lhs}${_}=${_}${rhs};`;16254 }16255 }16256 if (namedExportsMode) {16257 for (const { name, reexports } of dependencies) {16258 if (!reexports) {16259 continue;16260 }16261 for (const specifier of reexports) {16262 if (specifier.reexported === '*') {16263 if (exportBlock)16264 exportBlock += n;16265 if (!specifier.needsLiveBinding && reexportProtoFromExternal) {16266 const protoString = "'__proto__'";16267 exportBlock +=16268 `Object.prototype.hasOwnProperty.call(${name},${_}${protoString})${_}&&${n}` +16269 `${t}!Object.prototype.hasOwnProperty.call(exports,${_}${protoString})${_}&&${n}` +16270 `${t}Object.defineProperty(exports,${_}${protoString},${_}{${n}` +16271 `${t}${t}enumerable:${_}true,${n}` +16272 `${t}${t}value:${_}${name}[${protoString}]${n}` +16273 `${t}});${n}${n}`;16274 }16275 const copyPropertyIfNecessary = `{${n}${t}if${_}(k${_}!==${_}'default'${_}&&${_}!Object.prototype.hasOwnProperty.call(exports,${_}k))${_}${getDefineProperty(name, specifier.needsLiveBinding, t, snippets)}${s}${n}}`;16276 exportBlock += `Object.keys(${name}).forEach(${getFunctionIntro(['k'], {16277 isAsync: false,16278 name: null16279 })}${copyPropertyIfNecessary});`;16280 }16281 }16282 }16283 }16284 if (exportBlock) {16285 return `${n}${n}${exportBlock}`;16286 }16287 return '';16288 }16289 function getSingleDefaultExport(exports, dependencies, interop, externalLiveBindings, getPropertyAccess) {16290 if (exports.length > 0) {16291 return exports[0].local;16292 }16293 else {16294 for (const { defaultVariableName, importPath, isChunk, name, namedExportsMode: depNamedExportsMode, namespaceVariableName, reexports } of dependencies) {16295 if (reexports) {16296 return getReexportedImportName(name, reexports[0].imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, importPath, externalLiveBindings, getPropertyAccess);16297 }16298 }16299 }16300 }16301 function getReexportedImportName(moduleVariableName, imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, moduleId, externalLiveBindings, getPropertyAccess) {16302 if (imported === 'default') {16303 if (!isChunk) {16304 const moduleInterop = interop(moduleId);16305 const variableName = defaultInteropHelpersByInteropType[moduleInterop]16306 ? defaultVariableName16307 : moduleVariableName;16308 return isDefaultAProperty(moduleInterop, externalLiveBindings)16309 ? `${variableName}${getPropertyAccess('default')}`16310 : variableName;16311 }16312 return depNamedExportsMode16313 ? `${moduleVariableName}${getPropertyAccess('default')}`16314 : moduleVariableName;16315 }16316 if (imported === '*') {16317 return (isChunk ? !depNamedExportsMode : namespaceInteropHelpersByInteropType[interop(moduleId)])16318 ? namespaceVariableName16319 : moduleVariableName;16320 }16321 return `${moduleVariableName}${getPropertyAccess(imported)}`;16322 }16323 function getEsModuleValue(getObject) {16324 return getObject([['value', 'true']], {16325 lineBreakIndent: null16326 });16327 }16328 function getNamespaceMarkers(hasNamedExports, addEsModule, addNamespaceToStringTag, { _, getObject }) {16329 if (hasNamedExports) {16330 if (addEsModule) {16331 if (addNamespaceToStringTag) {16332 return `Object.defineProperties(exports,${_}${getObject([16333 ['__esModule', getEsModuleValue(getObject)],16334 [null, `[Symbol.toStringTag]:${_}${getToStringTagValue(getObject)}`]16335 ], {16336 lineBreakIndent: null16337 })});`;16338 }16339 return `Object.defineProperty(exports,${_}'__esModule',${_}${getEsModuleValue(getObject)});`;16340 }16341 if (addNamespaceToStringTag) {16342 return `Object.defineProperty(exports,${_}Symbol.toStringTag,${_}${getToStringTagValue(getObject)});`;16343 }16344 }16345 return '';16346 }16347 const getDefineProperty = (name, needsLiveBinding, t, { _, getDirectReturnFunction, n }) => {16348 if (needsLiveBinding) {16349 const [left, right] = getDirectReturnFunction([], {16350 functionReturn: true,16351 lineBreakIndent: null,16352 name: null16353 });16354 return (`Object.defineProperty(exports,${_}k,${_}{${n}` +16355 `${t}${t}enumerable:${_}true,${n}` +16356 `${t}${t}get:${_}${left}${name}[k]${right}${n}${t}})`);16357 }16358 return `exports[k]${_}=${_}${name}[k]`;16359 };16360 16361 function getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, indent, snippets) {16362 const { _, cnst, n } = snippets;16363 const neededInteropHelpers = new Set();16364 const interopStatements = [];16365 const addInteropStatement = (helperVariableName, helper, dependencyVariableName) => {16366 neededInteropHelpers.add(helper);16367 interopStatements.push(`${cnst} ${helperVariableName}${_}=${_}/*#__PURE__*/${helper}(${dependencyVariableName});`);16368 };16369 for (const { defaultVariableName, imports, importPath, isChunk, name, namedExportsMode, namespaceVariableName, reexports } of dependencies) {16370 if (isChunk) {16371 for (const { imported, reexported } of [16372 ...(imports || []),16373 ...(reexports || [])16374 ]) {16375 if (imported === '*' && reexported !== '*') {16376 if (!namedExportsMode) {16377 addInteropStatement(namespaceVariableName, INTEROP_NAMESPACE_DEFAULT_ONLY_VARIABLE, name);16378 }16379 break;16380 }16381 }16382 }16383 else {16384 const moduleInterop = interop(importPath);16385 let hasDefault = false;16386 let hasNamespace = false;16387 for (const { imported, reexported } of [16388 ...(imports || []),16389 ...(reexports || [])16390 ]) {16391 let helper;16392 let variableName;16393 if (imported === 'default') {16394 if (!hasDefault) {16395 hasDefault = true;16396 if (defaultVariableName !== namespaceVariableName) {16397 variableName = defaultVariableName;16398 helper = defaultInteropHelpersByInteropType[moduleInterop];16399 }16400 }16401 }16402 else if (imported === '*' && reexported !== '*' && !hasNamespace) {16403 hasNamespace = true;16404 helper = namespaceInteropHelpersByInteropType[moduleInterop];16405 variableName = namespaceVariableName;16406 }16407 if (helper) {16408 addInteropStatement(variableName, helper, name);16409 }16410 }16411 }16412 }16413 return `${getHelpersBlock(neededInteropHelpers, accessedGlobals, indent, snippets, externalLiveBindings, freeze, symbols)}${interopStatements.length > 0 ? `${interopStatements.join(n)}${n}${n}` : ''}`;16414 }16415 16416 function addJsExtension(name) {16417 return name.endsWith('.js') ? name : name + '.js';16418 }16419 16420 // AMD resolution will only respect the AMD baseUrl if the .js extension is omitted.16421 // The assumption is that this makes sense for all relative ids:16422 // https://requirejs.org/docs/api.html#jsfiles16423 function updateExtensionForRelativeAmdId(id, forceJsExtensionForImports) {16424 if (id[0] !== '.') {16425 return id;16426 }16427 return forceJsExtensionForImports ? addJsExtension(id) : removeJsExtension(id);16428 }16429 16430 const builtinModules = [16431 "assert",16432 "assert/strict",16433 "async_hooks",16434 "buffer",16435 "child_process",16436 "cluster",16437 "console",16438 "constants",16439 "crypto",16440 "dgram",16441 "diagnostics_channel",16442 "dns",16443 "dns/promises",16444 "domain",16445 "events",16446 "fs",16447 "fs/promises",16448 "http",16449 "http2",16450 "https",16451 "inspector",16452 "inspector/promises",16453 "module",16454 "net",16455 "os",16456 "path",16457 "path/posix",16458 "path/win32",16459 "perf_hooks",16460 "process",16461 "punycode",16462 "querystring",16463 "readline",16464 "readline/promises",16465 "repl",16466 "stream",16467 "stream/consumers",16468 "stream/promises",16469 "stream/web",16470 "string_decoder",16471 "timers",16472 "timers/promises",16473 "tls",16474 "trace_events",16475 "tty",16476 "url",16477 "util",16478 "util/types",16479 "v8",16480 "vm",16481 "wasi",16482 "worker_threads",16483 "zlib"16484 ];16485 16486 const nodeBuiltins = new Set(builtinModules);16487 function warnOnBuiltins(log, dependencies) {16488 const externalBuiltins = dependencies16489 .map(({ importPath }) => importPath)16490 .filter(importPath => nodeBuiltins.has(importPath) || importPath.startsWith('node:'));16491 if (externalBuiltins.length === 0)16492 return;16493 log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logMissingNodeBuiltins(externalBuiltins));16494 }16495 16496 function amd(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, id, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, log, outro, snippets }, { amd, esModule, externalLiveBindings, freeze, generatedCode: { symbols }, interop, reexportProtoFromExternal, strict }) {16497 warnOnBuiltins(log, dependencies);16498 const deps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`);16499 const parameters = dependencies.map(m => m.name);16500 const { n, getNonArrowFunctionIntro, _ } = snippets;16501 if (namedExportsMode && hasExports) {16502 parameters.unshift(`exports`);16503 deps.unshift(`'exports'`);16504 }16505 if (accessedGlobals.has('require')) {16506 parameters.unshift('require');16507 deps.unshift(`'require'`);16508 }16509 if (accessedGlobals.has('module')) {16510 parameters.unshift('module');16511 deps.unshift(`'module'`);16512 }16513 const completeAmdId = getCompleteAmdId(amd, id);16514 const defineParameters = (completeAmdId ? `'${completeAmdId}',${_}` : ``) +16515 (deps.length > 0 ? `[${deps.join(`,${_}`)}],${_}` : ``);16516 const useStrict = strict ? `${_}'use strict';` : '';16517 magicString.prepend(`${intro}${getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets)}`);16518 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal);16519 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets);16520 if (namespaceMarkers) {16521 namespaceMarkers = n + n + namespaceMarkers;16522 }16523 magicString16524 .append(`${exportBlock}${namespaceMarkers}${outro}`)16525 .indent(t)16526 // factory function should be wrapped by parentheses to avoid lazy parsing,16527 // cf. https://v8.dev/blog/preparser#pife16528 .prepend(`${amd.define}(${defineParameters}(${getNonArrowFunctionIntro(parameters, {16529 isAsync: false,16530 name: null16531 })}{${useStrict}${n}${n}`)16532 .append(`${n}${n}}));`);16533 }16534 16535 function cjs(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, outro, snippets }, { compact, esModule, externalLiveBindings, freeze, interop, generatedCode: { symbols }, reexportProtoFromExternal, strict }) {16536 const { _, n } = snippets;16537 const useStrict = strict ? `'use strict';${n}${n}` : '';16538 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets);16539 if (namespaceMarkers) {16540 namespaceMarkers += n + n;16541 }16542 const importBlock = getImportBlock$1(dependencies, snippets, compact);16543 const interopBlock = getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets);16544 magicString.prepend(`${useStrict}${intro}${namespaceMarkers}${importBlock}${interopBlock}`);16545 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal, `module.exports${_}=${_}`);16546 magicString.append(`${exportBlock}${outro}`);16547 }16548 function getImportBlock$1(dependencies, { _, cnst, n }, compact) {16549 let importBlock = '';16550 let definingVariable = false;16551 for (const { importPath, name, reexports, imports } of dependencies) {16552 if (!reexports && !imports) {16553 if (importBlock) {16554 importBlock += compact && !definingVariable ? ',' : `;${n}`;16555 }16556 definingVariable = false;16557 importBlock += `require('${importPath}')`;16558 }16559 else {16560 importBlock += compact && definingVariable ? ',' : `${importBlock ? `;${n}` : ''}${cnst} `;16561 definingVariable = true;16562 importBlock += `${name}${_}=${_}require('${importPath}')`;16563 }16564 }16565 if (importBlock) {16566 return `${importBlock};${n}${n}`;16567 }16568 return '';16569 }16570 16571 function es(magicString, { accessedGlobals, indent: t, intro, outro, dependencies, exports, snippets }, { externalLiveBindings, freeze, generatedCode: { symbols }, importAttributesKey }) {16572 const { n } = snippets;16573 const importBlock = getImportBlock(dependencies, importAttributesKey, snippets);16574 if (importBlock.length > 0)16575 intro += importBlock.join(n) + n + n;16576 intro += getHelpersBlock(null, accessedGlobals, t, snippets, externalLiveBindings, freeze, symbols);16577 if (intro)16578 magicString.prepend(intro);16579 const exportBlock = getExportBlock(exports, snippets);16580 if (exportBlock.length > 0)16581 magicString.append(n + n + exportBlock.join(n).trim());16582 if (outro)16583 magicString.append(outro);16584 magicString.trim();16585 }16586 function getImportBlock(dependencies, importAttributesKey, { _ }) {16587 const importBlock = [];16588 for (const { importPath, reexports, imports, name, attributes } of dependencies) {16589 const assertion = attributes ? `${_}${importAttributesKey}${_}${attributes}` : '';16590 const pathWithAssertion = `'${importPath}'${assertion};`;16591 if (!reexports && !imports) {16592 importBlock.push(`import${_}${pathWithAssertion}`);16593 continue;16594 }16595 if (imports) {16596 let defaultImport = null;16597 let starImport = null;16598 const importedNames = [];16599 for (const specifier of imports) {16600 if (specifier.imported === 'default') {16601 defaultImport = specifier;16602 }16603 else if (specifier.imported === '*') {16604 starImport = specifier;16605 }16606 else {16607 importedNames.push(specifier);16608 }16609 }16610 if (starImport) {16611 importBlock.push(`import${_}*${_}as ${starImport.local} from${_}${pathWithAssertion}`);16612 }16613 if (defaultImport && importedNames.length === 0) {16614 importBlock.push(`import ${defaultImport.local} from${_}${pathWithAssertion}`);16615 }16616 else if (importedNames.length > 0) {16617 importBlock.push(`import ${defaultImport ? `${defaultImport.local},${_}` : ''}{${_}${importedNames16618 .map(specifier => specifier.imported === specifier.local16619 ? specifier.imported16620 : `${stringifyIdentifierIfNeeded(specifier.imported)} as ${specifier.local}`)16621 .join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`);16622 }16623 }16624 if (reexports) {16625 let starExport = null;16626 const namespaceReexports = [];16627 const namedReexports = [];16628 for (const specifier of reexports) {16629 if (specifier.reexported === '*') {16630 starExport = specifier;16631 }16632 else if (specifier.imported === '*') {16633 namespaceReexports.push(specifier);16634 }16635 else {16636 namedReexports.push(specifier);16637 }16638 }16639 if (starExport) {16640 importBlock.push(`export${_}*${_}from${_}${pathWithAssertion}`);16641 }16642 if (namespaceReexports.length > 0) {16643 if (!imports ||16644 !imports.some(specifier => specifier.imported === '*' && specifier.local === name)) {16645 importBlock.push(`import${_}*${_}as ${name} from${_}${pathWithAssertion}`);16646 }16647 for (const specifier of namespaceReexports) {16648 importBlock.push(`export${_}{${_}${name === specifier.reexported16649 ? name16650 : `${name} as ${stringifyIdentifierIfNeeded(specifier.reexported)}`} };`);16651 }16652 }16653 if (namedReexports.length > 0) {16654 importBlock.push(`export${_}{${_}${namedReexports16655 .map(specifier => specifier.imported === specifier.reexported16656 ? stringifyIdentifierIfNeeded(specifier.imported)16657 : `${stringifyIdentifierIfNeeded(specifier.imported)} as ${stringifyIdentifierIfNeeded(specifier.reexported)}`)16658 .join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`);16659 }16660 }16661 }16662 return importBlock;16663 }16664 function getExportBlock(exports, { _, cnst }) {16665 const exportBlock = [];16666 const exportDeclaration = [];16667 for (const specifier of exports) {16668 if (specifier.expression) {16669 exportBlock.push(`${cnst} ${specifier.local}${_}=${_}${specifier.expression};`);16670 }16671 exportDeclaration.push(specifier.exported === specifier.local16672 ? specifier.local16673 : `${specifier.local} as ${stringifyIdentifierIfNeeded(specifier.exported)}`);16674 }16675 if (exportDeclaration.length > 0) {16676 exportBlock.push(`export${_}{${_}${exportDeclaration.join(`,${_}`)}${_}};`);16677 }16678 return exportBlock;16679 }16680 16681 const keypath = (keypath, getPropertyAccess) => keypath.split('.').map(getPropertyAccess).join('');16682 16683 function setupNamespace(name, root, globals, { _, getPropertyAccess, s }, compact) {16684 const parts = name.split('.');16685 parts[0] = (typeof globals === 'function' ? globals(parts[0]) : globals[parts[0]]) || parts[0];16686 parts.pop();16687 let propertyPath = root;16688 return (parts16689 .map(part => {16690 propertyPath += getPropertyAccess(part);16691 return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}${s}`;16692 })16693 .join(compact ? ',' : '\n') + (compact && parts.length > 0 ? ';' : '\n'));16694 }16695 function assignToDeepVariable(deepName, root, globals, assignment, { _, getPropertyAccess }) {16696 const parts = deepName.split('.');16697 parts[0] = (typeof globals === 'function' ? globals(parts[0]) : globals[parts[0]]) || parts[0];16698 const last = parts.pop();16699 let propertyPath = root;16700 let deepAssignment = [16701 ...parts.map(part => {16702 propertyPath += getPropertyAccess(part);16703 return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}`;16704 }),16705 `${propertyPath}${getPropertyAccess(last)}`16706 ].join(`,${_}`) + `${_}=${_}${assignment}`;16707 if (parts.length > 0) {16708 deepAssignment = `(${deepAssignment})`;16709 }16710 return deepAssignment;16711 }16712 16713 function trimEmptyImports(dependencies) {16714 let index = dependencies.length;16715 while (index--) {16716 const { imports, reexports } = dependencies[index];16717 if (imports || reexports) {16718 return dependencies.slice(0, index + 1);16719 }16720 }16721 return [];16722 }16723 16724 function iife(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, indent: t, intro, namedExportsMode, log, outro, snippets }, { compact, esModule, extend, freeze, externalLiveBindings, reexportProtoFromExternal, globals, interop, name, generatedCode: { symbols }, strict }) {16725 const { _, getNonArrowFunctionIntro, getPropertyAccess, n } = snippets;16726 const isNamespaced = name && name.includes('.');16727 const useVariableAssignment = !extend && !isNamespaced;16728 if (name && useVariableAssignment && !isLegal(name)) {16729 return parseAst_js.error(parseAst_js.logIllegalIdentifierAsName(name));16730 }16731 warnOnBuiltins(log, dependencies);16732 const external = trimEmptyImports(dependencies);16733 const deps = external.map(dep => dep.globalName || 'null');16734 const parameters = external.map(m => m.name);16735 if (hasExports && !name) {16736 log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logMissingNameOptionForIifeExport());16737 }16738 if (namedExportsMode && hasExports) {16739 if (extend) {16740 deps.unshift(`this${keypath(name, getPropertyAccess)}${_}=${_}this${keypath(name, getPropertyAccess)}${_}||${_}{}`);16741 parameters.unshift('exports');16742 }16743 else {16744 deps.unshift('{}');16745 parameters.unshift('exports');16746 }16747 }16748 const useStrict = strict ? `${t}'use strict';${n}` : '';16749 const interopBlock = getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets);16750 magicString.prepend(`${intro}${interopBlock}`);16751 let wrapperIntro = `(${getNonArrowFunctionIntro(parameters, {16752 isAsync: false,16753 name: null16754 })}{${n}${useStrict}${n}`;16755 if (hasExports) {16756 if (name && !(extend && namedExportsMode)) {16757 wrapperIntro =16758 (useVariableAssignment ? `var ${name}` : `this${keypath(name, getPropertyAccess)}`) +16759 `${_}=${_}${wrapperIntro}`;16760 }16761 if (isNamespaced) {16762 wrapperIntro = setupNamespace(name, 'this', globals, snippets, compact) + wrapperIntro;16763 }16764 }16765 let wrapperOutro = `${n}${n}})(${deps.join(`,${_}`)});`;16766 if (hasExports && !extend && namedExportsMode) {16767 wrapperOutro = `${n}${n}${t}return exports;${wrapperOutro}`;16768 }16769 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal);16770 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, esModule === true || (esModule === 'if-default-prop' && hasDefaultExport), symbols, snippets);16771 if (namespaceMarkers) {16772 namespaceMarkers = n + n + namespaceMarkers;16773 }16774 magicString16775 .append(`${exportBlock}${namespaceMarkers}${outro}`)16776 .indent(t)16777 .prepend(wrapperIntro)16778 .append(wrapperOutro);16779 }16780 16781 function system(magicString, { accessedGlobals, dependencies, exports, hasExports, indent: t, intro, snippets, outro, usesTopLevelAwait }, { externalLiveBindings, freeze, name, generatedCode: { symbols }, strict, systemNullSetters }) {16782 const { _, getFunctionIntro, getNonArrowFunctionIntro, n, s } = snippets;16783 const { importBindings, setters, starExcludes } = analyzeDependencies(dependencies, exports, t, snippets);16784 const registeredName = name ? `'${name}',${_}` : '';16785 const wrapperParameters = accessedGlobals.has('module')16786 ? ['exports', 'module']16787 : hasExports16788 ? ['exports']16789 : [];16790 // factory function should be wrapped by parentheses to avoid lazy parsing,16791 // cf. https://v8.dev/blog/preparser#pife16792 let wrapperStart = `System.register(${registeredName}[` +16793 dependencies.map(({ importPath }) => `'${importPath}'`).join(`,${_}`) +16794 `],${_}(${getNonArrowFunctionIntro(wrapperParameters, {16795 isAsync: false,16796 name: null16797 })}{${n}${t}${strict ? "'use strict';" : ''}` +16798 getStarExcludesBlock(starExcludes, t, snippets) +16799 getImportBindingsBlock(importBindings, t, snippets) +16800 `${n}${t}return${_}{${setters.length > 016801 ? `${n}${t}${t}setters:${_}[${setters16802 .map(setter => setter16803 ? `${getFunctionIntro(['module'], {16804 isAsync: false,16805 name: null16806 })}{${n}${t}${t}${t}${setter}${n}${t}${t}}`16807 : systemNullSetters16808 ? `null`16809 : `${getFunctionIntro([], { isAsync: false, name: null })}{}`)16810 .join(`,${_}`)}],`16811 : ''}${n}`;16812 wrapperStart += `${t}${t}execute:${_}(${getNonArrowFunctionIntro([], {16813 isAsync: usesTopLevelAwait,16814 name: null16815 })}{${n}${n}`;16816 const wrapperEnd = `${t}${t}})${n}${t}}${s}${n}}));`;16817 magicString16818 .prepend(intro +16819 getHelpersBlock(null, accessedGlobals, t, snippets, externalLiveBindings, freeze, symbols) +16820 getHoistedExportsBlock(exports, t, snippets))16821 .append(`${outro}${n}${n}` +16822 getSyntheticExportsBlock(exports, t, snippets) +16823 getMissingExportsBlock(exports, t, snippets))16824 .indent(`${t}${t}${t}`)16825 .append(wrapperEnd)16826 .prepend(wrapperStart);16827 }16828 function analyzeDependencies(dependencies, exports, t, { _, cnst, getObject, getPropertyAccess, n }) {16829 const importBindings = [];16830 const setters = [];16831 let starExcludes = null;16832 for (const { imports, reexports } of dependencies) {16833 const setter = [];16834 if (imports) {16835 for (const specifier of imports) {16836 importBindings.push(specifier.local);16837 if (specifier.imported === '*') {16838 setter.push(`${specifier.local}${_}=${_}module;`);16839 }16840 else {16841 setter.push(`${specifier.local}${_}=${_}module${getPropertyAccess(specifier.imported)};`);16842 }16843 }16844 }16845 if (reexports) {16846 const reexportedNames = [];16847 let hasStarReexport = false;16848 for (const { imported, reexported } of reexports) {16849 if (reexported === '*') {16850 hasStarReexport = true;16851 }16852 else {16853 reexportedNames.push([16854 reexported,16855 imported === '*' ? 'module' : `module${getPropertyAccess(imported)}`16856 ]);16857 }16858 }16859 if (reexportedNames.length > 1 || hasStarReexport) {16860 if (hasStarReexport) {16861 if (!starExcludes) {16862 starExcludes = getStarExcludes({ dependencies, exports });16863 }16864 reexportedNames.unshift([null, `__proto__:${_}null`]);16865 const exportMapping = getObject(reexportedNames, { lineBreakIndent: null });16866 setter.push(`${cnst} setter${_}=${_}${exportMapping};`, `for${_}(${cnst} name in module)${_}{`, `${t}if${_}(!_starExcludes[name])${_}setter[name]${_}=${_}module[name];`, '}', 'exports(setter);');16867 }16868 else {16869 const exportMapping = getObject(reexportedNames, { lineBreakIndent: null });16870 setter.push(`exports(${exportMapping});`);16871 }16872 }16873 else {16874 const [key, value] = reexportedNames[0];16875 setter.push(`exports(${JSON.stringify(key)},${_}${value});`);16876 }16877 }16878 setters.push(setter.join(`${n}${t}${t}${t}`));16879 }16880 return { importBindings, setters, starExcludes };16881 }16882 const getStarExcludes = ({ dependencies, exports }) => {16883 const starExcludes = new Set(exports.map(expt => expt.exported));16884 starExcludes.add('default');16885 for (const { reexports } of dependencies) {16886 if (reexports) {16887 for (const reexport of reexports) {16888 if (reexport.reexported !== '*')16889 starExcludes.add(reexport.reexported);16890 }16891 }16892 }16893 return starExcludes;16894 };16895 const getStarExcludesBlock = (starExcludes, t, { _, cnst, getObject, n }) => {16896 if (starExcludes) {16897 const fields = [...starExcludes].map(property => [16898 property,16899 '1'16900 ]);16901 fields.unshift([null, `__proto__:${_}null`]);16902 return `${n}${t}${cnst} _starExcludes${_}=${_}${getObject(fields, {16903 lineBreakIndent: { base: t, t }16904 })};`;16905 }16906 return '';16907 };16908 const getImportBindingsBlock = (importBindings, t, { _, n }) => (importBindings.length > 0 ? `${n}${t}var ${importBindings.join(`,${_}`)};` : '');16909 const getHoistedExportsBlock = (exports, t, snippets) => getExportsBlock(exports.filter(expt => expt.hoisted).map(expt => ({ name: expt.exported, value: expt.local })), t, snippets);16910 function getExportsBlock(exports, t, { _, n }) {16911 if (exports.length === 0) {16912 return '';16913 }16914 if (exports.length === 1) {16915 return `exports(${JSON.stringify(exports[0].name)},${_}${exports[0].value});${n}${n}`;16916 }16917 return (`exports({${n}` +16918 exports16919 .map(({ name, value }) => `${t}${stringifyObjectKeyIfNeeded(name)}:${_}${value}`)16920 .join(`,${n}`) +16921 `${n}});${n}${n}`);16922 }16923 const getSyntheticExportsBlock = (exports, t, snippets) => getExportsBlock(exports16924 .filter(expt => expt.expression)16925 .map(expt => ({ name: expt.exported, value: expt.local })), t, snippets);16926 const getMissingExportsBlock = (exports, t, snippets) => getExportsBlock(exports16927 .filter(expt => expt.local === MISSING_EXPORT_SHIM_VARIABLE)16928 .map(expt => ({ name: expt.exported, value: MISSING_EXPORT_SHIM_VARIABLE })), t, snippets);16929 16930 function globalProperty(name, globalVariable, getPropertyAccess) {16931 if (!name)16932 return 'null';16933 return `${globalVariable}${keypath(name, getPropertyAccess)}`;16934 }16935 function safeAccess(name, globalVariable, { _, getPropertyAccess }) {16936 let propertyPath = globalVariable;16937 return name16938 .split('.')16939 .map(part => (propertyPath += getPropertyAccess(part)))16940 .join(`${_}&&${_}`);16941 }16942 function umd(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, id, indent: t, intro, namedExportsMode, log, outro, snippets }, { amd, compact, esModule, extend, externalLiveBindings, freeze, interop, name, generatedCode: { symbols }, globals, noConflict, reexportProtoFromExternal, strict }) {16943 const { _, cnst, getFunctionIntro, getNonArrowFunctionIntro, getPropertyAccess, n, s } = snippets;16944 const factoryVariable = compact ? 'f' : 'factory';16945 const globalVariable = compact ? 'g' : 'global';16946 if (hasExports && !name) {16947 return parseAst_js.error(parseAst_js.logMissingNameOptionForUmdExport());16948 }16949 warnOnBuiltins(log, dependencies);16950 const amdDeps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`);16951 const cjsDeps = dependencies.map(m => `require('${m.importPath}')`);16952 const trimmedImports = trimEmptyImports(dependencies);16953 const globalDeps = trimmedImports.map(module => globalProperty(module.globalName, globalVariable, getPropertyAccess));16954 const factoryParameters = trimmedImports.map(m => m.name);16955 if (namedExportsMode && (hasExports || noConflict)) {16956 amdDeps.unshift(`'exports'`);16957 cjsDeps.unshift(`exports`);16958 globalDeps.unshift(assignToDeepVariable(name, globalVariable, globals, `${extend ? `${globalProperty(name, globalVariable, getPropertyAccess)}${_}||${_}` : ''}{}`, snippets));16959 factoryParameters.unshift('exports');16960 }16961 const completeAmdId = getCompleteAmdId(amd, id);16962 const amdParameters = (completeAmdId ? `'${completeAmdId}',${_}` : ``) +16963 (amdDeps.length > 0 ? `[${amdDeps.join(`,${_}`)}],${_}` : ``);16964 const define = amd.define;16965 const cjsExport = !namedExportsMode && hasExports ? `module.exports${_}=${_}` : ``;16966 const useStrict = strict ? `${_}'use strict';${n}` : ``;16967 let iifeExport;16968 if (noConflict) {16969 const noConflictExportsVariable = compact ? 'e' : 'exports';16970 let factory;16971 if (!namedExportsMode && hasExports) {16972 factory = `${cnst} ${noConflictExportsVariable}${_}=${_}${assignToDeepVariable(name, globalVariable, globals, `${factoryVariable}(${globalDeps.join(`,${_}`)})`, snippets)};`;16973 }16974 else {16975 const module = globalDeps.shift();16976 factory =16977 `${cnst} ${noConflictExportsVariable}${_}=${_}${module};${n}` +16978 `${t}${t}${factoryVariable}(${[noConflictExportsVariable, ...globalDeps].join(`,${_}`)});`;16979 }16980 iifeExport =16981 `(${getFunctionIntro([], { isAsync: false, name: null })}{${n}` +16982 `${t}${t}${cnst} current${_}=${_}${safeAccess(name, globalVariable, snippets)};${n}` +16983 `${t}${t}${factory}${n}` +16984 `${t}${t}${noConflictExportsVariable}.noConflict${_}=${_}${getFunctionIntro([], {16985 isAsync: false,16986 name: null16987 })}{${_}` +16988 `${globalProperty(name, globalVariable, getPropertyAccess)}${_}=${_}current;${_}return ${noConflictExportsVariable}${s}${_}};${n}` +16989 `${t}})()`;16990 }16991 else {16992 iifeExport = `${factoryVariable}(${globalDeps.join(`,${_}`)})`;16993 if (!namedExportsMode && hasExports) {16994 iifeExport = assignToDeepVariable(name, globalVariable, globals, iifeExport, snippets);16995 }16996 }16997 const iifeNeedsGlobal = hasExports || (noConflict && namedExportsMode) || globalDeps.length > 0;16998 const wrapperParameters = [factoryVariable];16999 if (iifeNeedsGlobal) {17000 wrapperParameters.unshift(globalVariable);17001 }17002 const globalArgument = iifeNeedsGlobal ? `this,${_}` : '';17003 const iifeStart = iifeNeedsGlobal17004 ? `(${globalVariable}${_}=${_}typeof globalThis${_}!==${_}'undefined'${_}?${_}globalThis${_}:${_}${globalVariable}${_}||${_}self,${_}`17005 : '';17006 const iifeEnd = iifeNeedsGlobal ? ')' : '';17007 const cjsIntro = iifeNeedsGlobal17008 ? `${t}typeof exports${_}===${_}'object'${_}&&${_}typeof module${_}!==${_}'undefined'${_}?` +17009 `${_}${cjsExport}${factoryVariable}(${cjsDeps.join(`,${_}`)})${_}:${n}`17010 : '';17011 const wrapperIntro = `(${getNonArrowFunctionIntro(wrapperParameters, { isAsync: false, name: null })}{${n}` +17012 cjsIntro +17013 `${t}typeof ${define}${_}===${_}'function'${_}&&${_}${define}.amd${_}?${_}${define}(${amdParameters}${factoryVariable})${_}:${n}` +17014 `${t}${iifeStart}${iifeExport}${iifeEnd};${n}` +17015 // factory function should be wrapped by parentheses to avoid lazy parsing,17016 // cf. https://v8.dev/blog/preparser#pife17017 `})(${globalArgument}(${getNonArrowFunctionIntro(factoryParameters, {17018 isAsync: false,17019 name: null17020 })}{${useStrict}${n}`;17021 const wrapperOutro = n + n + '}));';17022 magicString.prepend(`${intro}${getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets)}`);17023 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal);17024 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, esModule === true || (esModule === 'if-default-prop' && hasDefaultExport), symbols, snippets);17025 if (namespaceMarkers) {17026 namespaceMarkers = n + n + namespaceMarkers;17027 }17028 magicString17029 .append(`${exportBlock}${namespaceMarkers}${outro}`)17030 .trim()17031 .indent(t)17032 .append(wrapperOutro)17033 .prepend(wrapperIntro);17034 }17035 17036 const finalisers = { amd, cjs, es, iife, system, umd };17037 17933 17038 17934 const concatSeparator = (out, next) => (next ? `${out}\n${next}` : out); … … 17502 18398 } 17503 18399 for (const module of entryModules) { 17504 // eslint-disable-next-line unicorn/prefer-spread17505 18400 const requiredFacades = Array.from(new Set(module.chunkNames.filter(({ isUserDefined }) => isUserDefined).map(({ name }) => name)), 17506 18401 // mapping must run after Set 'name' dedupe … … 17511 18406 requiredFacades.push({}); 17512 18407 } 17513 // eslint-disable-next-line unicorn/prefer-spread17514 18408 requiredFacades.push(...Array.from(module.chunkFileNames, fileName => ({ fileName }))); 17515 18409 if (requiredFacades.length === 0) { … … 17578 18472 const { chunkFileNames, entryFileNames, file, format, preserveModules } = this.outputOptions; 17579 18473 if (file) { 17580 fileName = path $2.basename(file);18474 fileName = path.basename(file); 17581 18475 } 17582 18476 else if (this.fileName === null) { … … 17636 18530 dynamicImports: this.getDynamicDependencies().map(resolveFileName), 17637 18531 fileName: this.getFileName(), 17638 // eslint-disable-next-line unicorn/prefer-spread17639 18532 implicitlyLoadedBefore: Array.from(this.implicitlyLoadedBefore, resolveFileName), 17640 18533 importedBindings: getImportedBindingsPerDependency(this.getRenderedDependencies(), resolveFileName), 17641 // eslint-disable-next-line unicorn/prefer-spread17642 18534 imports: Array.from(this.dependencies, resolveFileName), 17643 18535 modules: this.renderedModules, … … 17684 18576 } 17685 18577 if (format === 'es') { 17686 renderedDependency.reexports = reexports.filter( 17687 // eslint-disable-next-line unicorn/prefer-array-some 17688 ({ reexported }) => !renderedExports.find(({ exported }) => exported === reexported)); 18578 renderedDependency.reexports = reexports.filter(({ reexported }) => !renderedExports.find(({ exported }) => exported === reexported)); 17689 18579 } 17690 18580 } … … 17720 18610 if (format === 'es' || format === 'cjs') { 17721 18611 const shebang = facadeModule !== null && facadeModule.info.isEntry && facadeModule.shebang; 17722 shebang && magicString.prepend(`#!${shebang}\n`); 18612 if (shebang) { 18613 magicString.prepend(`#!${shebang}\n`); 18614 } 17723 18615 } 17724 18616 if (footer) … … 18031 18923 const { preserveModulesRoot, sanitizeFileName } = this.outputOptions; 18032 18924 const sanitizedId = sanitizeFileName(parseAst_js.normalize(module.id.split(QUERY_HASH_REGEX, 1)[0])); 18033 const extensionName = path $2.extname(sanitizedId);18925 const extensionName = path.extname(sanitizedId); 18034 18926 const idWithoutExtension = NON_ASSET_EXTENSIONS.has(extensionName) 18035 18927 ? sanitizedId.slice(0, -extensionName.length) 18036 18928 : sanitizedId; 18037 18929 if (parseAst_js.isAbsolute(idWithoutExtension)) { 18038 return preserveModulesRoot && path$2.resolve(idWithoutExtension).startsWith(preserveModulesRoot) 18039 ? idWithoutExtension.slice(preserveModulesRoot.length).replace(/^[/\\]/, '') 18040 : parseAst_js.relative(this.inputBase, idWithoutExtension); 18930 if (preserveModulesRoot && path.resolve(idWithoutExtension).startsWith(preserveModulesRoot)) { 18931 return idWithoutExtension.slice(preserveModulesRoot.length).replace(/^[/\\]/, ''); 18932 } 18933 else { 18934 // handle edge case in Windows 18935 if (this.inputBase === '/' && !idWithoutExtension.startsWith('/')) { 18936 return parseAst_js.relative(this.inputBase, idWithoutExtension.replace(/^[a-zA-Z]:[/\\]/, '/')); 18937 } 18938 return parseAst_js.relative(this.inputBase, idWithoutExtension); 18939 } 18041 18940 } 18042 18941 else { 18043 return `_virtual/${path$2.basename(idWithoutExtension)}`;18942 return (this.outputOptions.virtualDirname.replace(/\/$/, '') + '/' + path.basename(idWithoutExtension)); 18044 18943 } 18045 18944 } … … 18178 19077 if (!renderOptions.accessedDocumentCurrentScript && 18179 19078 formatsMaybeAccessDocumentCurrentScript.includes(format)) { 18180 // eslint-disable-next-line unicorn/consistent-destructuring18181 19079 this.accessedGlobalsByScope.get(module.scope)?.delete(DOCUMENT_CURRENT_SCRIPT); 18182 19080 } … … 18220 19118 if (hoistedSource) 18221 19119 magicString.prepend(hoistedSource + n + n); 18222 // eslint-disable-next-line unicorn/consistent-destructuring18223 19120 if (this.needsExportsShim) { 18224 19121 magicString.prepend(`${n}${cnst} ${MISSING_EXPORT_SHIM_VARIABLE}${_}=${_}void 0;${n}${n}`); … … 18528 19425 } 18529 19426 function getChunkDefinitionsFromManualChunks(manualChunkAliasByEntry) { 18530 const chunkDefinitions = [];18531 19427 const modulesInManualChunks = new Set(manualChunkAliasByEntry.keys()); 18532 19428 const manualChunkModulesByAlias = Object.create(null); … … 18534 19430 addStaticDependenciesToManualChunk(entry, (manualChunkModulesByAlias[alias] ||= []), modulesInManualChunks); 18535 19431 } 18536 for (const [alias, modules] of Object.entries(manualChunkModulesByAlias)) { 18537 chunkDefinitions.push({ alias, modules }); 19432 const manualChunks = Object.entries(manualChunkModulesByAlias); 19433 const chunkDefinitions = new Array(manualChunks.length); 19434 let index = 0; 19435 for (const [alias, modules] of manualChunks) { 19436 chunkDefinitions[index++] = { alias, modules }; 18538 19437 } 18539 19438 return { chunkDefinitions, modulesInManualChunks }; … … 18554 19453 const dynamicEntryModules = new Set(); 18555 19454 const dependentEntriesByModule = new Map(); 18556 const dynamicImportModulesByEntry = [];18557 19455 const allEntriesSet = new Set(entries); 19456 const dynamicImportModulesByEntry = new Array(allEntriesSet.size); 18558 19457 let entryIndex = 0; 18559 19458 for (const currentEntry of allEntriesSet) { 18560 19459 const dynamicImportsForCurrentEntry = new Set(); 18561 dynamicImportModulesByEntry .push(dynamicImportsForCurrentEntry);19460 dynamicImportModulesByEntry[entryIndex] = dynamicImportsForCurrentEntry; 18562 19461 const modulesToHandle = new Set([currentEntry]); 18563 19462 for (const module of modulesToHandle) { … … 18604 19503 } 18605 19504 } 18606 const dynamicImportsByEntry = []; 19505 const dynamicImportsByEntry = new Array(dynamicImportModulesByEntry.length); 19506 let index = 0; 18607 19507 for (const dynamicImportModules of dynamicImportModulesByEntry) { 18608 19508 const dynamicImports = new Set(); … … 18610 19510 dynamicImports.add(entryIndexByModule.get(dynamicEntry)); 18611 19511 } 18612 dynamicImportsByEntry .push(dynamicImports);19512 dynamicImportsByEntry[index++] = dynamicImports; 18613 19513 } 18614 19514 return { dynamicEntries, dynamicImportsByEntry }; … … 18715 19615 const chunksBySignature = Object.create(null); 18716 19616 const chunkByModule = new Map(); 18717 const sizeByAtom = [];19617 const sizeByAtom = new Array(chunkAtoms.length); 18718 19618 let sideEffectAtoms = 0n; 18719 19619 let atomMask = 1n; 19620 let index = 0; 18720 19621 for (const { dependentEntries, modules } of chunkAtoms) { 18721 19622 let chunkSignature = 0n; … … 18755 19656 sideEffectAtoms |= atomMask; 18756 19657 } 18757 sizeByAtom .push(atomSize);19658 sizeByAtom[index++] = atomSize; 18758 19659 chunk.containedAtoms |= atomMask; 18759 19660 chunk.modules.push(...modules); … … 18880 19781 return chunks; // the actual modules 18881 19782 } 18882 minChunkSize > 1 &&19783 if (minChunkSize > 1) { 18883 19784 log('info', parseAst_js.logOptimizeChunkStatus(chunks.length, chunkPartition.small.size, 'Initially')); 19785 } 18884 19786 mergeChunks(chunkPartition, minChunkSize, sideEffectAtoms, sizeByAtom); 18885 minChunkSize > 1 &&19787 if (minChunkSize > 1) { 18886 19788 log('info', parseAst_js.logOptimizeChunkStatus(chunkPartition.small.size + chunkPartition.big.size, chunkPartition.small.size, 'After merging chunks')); 19789 } 18887 19790 timeEnd('optimize chunks', 3); 18888 19791 return [...chunkPartition.small, ...chunkPartition.big]; … … 19024 19927 return '/'; 19025 19928 if (files.length === 1) 19026 return path $2.dirname(files[0]);19929 return path.dirname(files[0]); 19027 19930 const commonSegments = files.slice(1).reduce((commonSegments, file) => { 19028 19931 const pathSegments = file.split(/\/+|\\+/); … … 19282 20185 const sources = originalSourcemap.sources; 19283 20186 const sourcesContent = originalSourcemap.sourcesContent || []; 19284 const directory = path $2.dirname(id) || '.';20187 const directory = path.dirname(id) || '.'; 19285 20188 const sourceRoot = originalSourcemap.sourceRoot || '.'; 19286 const baseSources = sources.map((source, index) => new Source(path $2.resolve(directory, sourceRoot, source), sourcesContent[index]));20189 const baseSources = sources.map((source, index) => new Source(path.resolve(directory, sourceRoot, source), sourcesContent[index])); 19287 20190 source = new Link(originalSourcemap, baseSources); 19288 20191 } … … 19301 20204 let { sources, sourcesContent, names, mappings } = source.traceMappings(); 19302 20205 if (file) { 19303 const directory = path $2.dirname(file);19304 sources = sources.map((source) => path $2.relative(directory, source));19305 file = path $2.basename(file);20206 const directory = path.dirname(file); 20207 sources = sources.map((source) => path.relative(directory, source)); 20208 file = path.basename(file); 19306 20209 } 19307 20210 sourcesContent = (excludeContent ? null : sourcesContent); … … 19333 20236 const getHash = hasherByType[outputOptions.hashCharacters]; 19334 20237 const chunkGraph = getChunkGraph(chunks); 19335 const { initialHashesByPlaceholder, nonHashedChunksWithPlaceholders, renderedChunksByPlaceholder, hashDependenciesByPlaceholder } = await transformChunksAndGenerateContentHashes(renderedChunks, chunkGraph, outputOptions, pluginDriver, getHash, log);19336 const hashesByPlaceholder = generateFinalHashes(renderedChunksByPlaceholder, hashDependenciesByPlaceholder, initialHashesByPlaceholder, bundle, getHash);20238 const { hashDependenciesByPlaceholder, initialHashesByPlaceholder, nonHashedChunksWithPlaceholders, placeholders, renderedChunksByPlaceholder } = await transformChunksAndGenerateContentHashes(renderedChunks, chunkGraph, outputOptions, pluginDriver, getHash, log); 20239 const hashesByPlaceholder = generateFinalHashes(renderedChunksByPlaceholder, hashDependenciesByPlaceholder, initialHashesByPlaceholder, placeholders, bundle, getHash); 19337 20240 addChunksToBundle(renderedChunksByPlaceholder, hashesByPlaceholder, bundle, nonHashedChunksWithPlaceholders, pluginDriver, outputOptions); 19338 20241 timeEnd('transform chunks', 2); … … 19377 20280 let resultingFile; 19378 20281 if (file) 19379 resultingFile = path $2.resolve(sourcemapFile || file);20282 resultingFile = path.resolve(sourcemapFile || file); 19380 20283 else if (dir) 19381 resultingFile = path $2.resolve(dir, fileName);20284 resultingFile = path.resolve(dir, fileName); 19382 20285 else 19383 resultingFile = path $2.resolve(fileName);20286 resultingFile = path.resolve(fileName); 19384 20287 const decodedMap = magicString.generateDecodedMap({}); 19385 20288 map = collapseSourcemaps(resultingFile, decodedMap, usedModules, sourcemapChain, sourcemapExcludeSources, log); … … 19464 20367 initialHashesByPlaceholder, 19465 20368 nonHashedChunksWithPlaceholders, 20369 placeholders, 19466 20370 renderedChunksByPlaceholder 19467 20371 }; 19468 20372 } 19469 function generateFinalHashes(renderedChunksByPlaceholder, hashDependenciesByPlaceholder, initialHashesByPlaceholder, bundle, getHash) {20373 function generateFinalHashes(renderedChunksByPlaceholder, hashDependenciesByPlaceholder, initialHashesByPlaceholder, placeholders, bundle, getHash) { 19470 20374 const hashesByPlaceholder = new Map(initialHashesByPlaceholder); 19471 for (const [placeholder, { fileName }] of renderedChunksByPlaceholder) { 20375 for (const placeholder of placeholders) { 20376 const { fileName } = renderedChunksByPlaceholder.get(placeholder); 19472 20377 let contentToHash = ''; 19473 20378 const hashDependencyPlaceholders = new Set([placeholder]); … … 19501 20406 let finalSourcemapFileName = null; 19502 20407 if (map) { 20408 if (options.sourcemapDebugIds) { 20409 updatedCode += calculateDebugIdAndGetComment(updatedCode, map); 20410 } 19503 20411 finalSourcemapFileName = sourcemapFileName 19504 20412 ? replacePlaceholders(sourcemapFileName, hashesByPlaceholder) … … 19513 20421 let finalSourcemapFileName = null; 19514 20422 if (map) { 20423 if (options.sourcemapDebugIds) { 20424 updatedCode += calculateDebugIdAndGetComment(updatedCode, map); 20425 } 19515 20426 finalSourcemapFileName = sourcemapFileName 19516 20427 ? replacePlaceholders(sourcemapFileName, hashesByPlaceholder) … … 19527 20438 } 19528 20439 else { 19529 const sourcemapFileName = path $2.basename(fileName);20440 const sourcemapFileName = path.basename(fileName); 19530 20441 url = sourcemapBaseUrl 19531 20442 ? new URL(sourcemapFileName, sourcemapBaseUrl).toString() … … 19539 20450 } 19540 20451 return sourcemap === 'hidden' ? '' : `//# ${SOURCEMAPPING_URL}=${url}\n`; 20452 } 20453 function calculateDebugIdAndGetComment(code, map) { 20454 const hash = hasherByType.hex(code); 20455 const debugId = [ 20456 hash.slice(0, 8), 20457 hash.slice(8, 12), 20458 '4' + hash.slice(12, 15), 20459 ((parseInt(hash.slice(15, 16), 16) & 3) | 8).toString(16) + hash.slice(17, 20), 20460 hash.slice(20, 32) 20461 ].join('-'); 20462 map.debugId = debugId; 20463 return '//# debugId=' + debugId + '\n'; 19541 20464 } 19542 20465 … … 19603 20526 } 19604 20527 assignManualChunks(getManualChunk) { 19605 // eslint-disable-next-line unicorn/prefer-module19606 20528 const manualChunkAliasesWithEntry = []; 19607 20529 const manualChunksApi = { … … 19629 20551 if ('code' in file) { 19630 20552 try { 19631 parseAst_js.parseAst(file.code );20553 parseAst_js.parseAst(file.code, { jsx: this.inputOptions.jsx !== false }); 19632 20554 } 19633 20555 catch (error_) { … … 19648 20570 const inputBase = commondir(getAbsoluteEntryModulePaths(includedModules, preserveModules)); 19649 20571 const externalChunkByModule = getExternalChunkByModule(this.graph.modulesById, this.outputOptions, inputBase); 19650 const chunks = []; 19651 const chunkByModule = new Map(); 19652 for (const { alias, modules } of inlineDynamicImports 20572 const executableModule = inlineDynamicImports 19653 20573 ? [{ alias: null, modules: includedModules }] 19654 20574 : preserveModules 19655 20575 ? includedModules.map(module => ({ alias: null, modules: [module] })) 19656 : getChunkAssignments(this.graph.entryModules, manualChunkAliasByEntry, experimentalMinChunkSize, this.inputOptions.onLog)) { 20576 : getChunkAssignments(this.graph.entryModules, manualChunkAliasByEntry, experimentalMinChunkSize, this.inputOptions.onLog); 20577 const chunks = new Array(executableModule.length); 20578 const chunkByModule = new Map(); 20579 let index = 0; 20580 for (const { alias, modules } of executableModule) { 19657 20581 sortByExecutionOrder(modules); 19658 20582 const chunk = new Chunk(modules, this.inputOptions, this.outputOptions, this.unsetOptions, this.pluginDriver, this.graph.modulesById, chunkByModule, externalChunkByModule, this.facadeChunkByModule, this.includedNamespaces, alias, getHashPlaceholder, bundle, inputBase, snippets); 19659 chunks .push(chunk);20583 chunks[index++] = chunk; 19660 20584 } 19661 20585 for (const chunk of chunks) { … … 19759 20683 } 19760 20684 20685 class GlobalScope extends Scope { 20686 constructor() { 20687 super(); 20688 this.parent = null; 20689 this.variables.set('undefined', new UndefinedVariable()); 20690 } 20691 findVariable(name) { 20692 let variable = this.variables.get(name); 20693 if (!variable) { 20694 variable = new GlobalVariable(name); 20695 this.variables.set(name, variable); 20696 } 20697 return variable; 20698 } 20699 } 20700 19761 20701 function resolveIdViaPlugins(source, importer, pluginDriver, moduleLoaderResolveId, skip, customOptions, isEntry, attributes) { 19762 20702 let skipped = null; … … 19806 20746 // resolve call and require no special handing on our part. 19807 20747 // See https://nodejs.org/api/path.html#path_path_resolve_paths 19808 return addJsExtensionIfNecessary(importer ? path $2.resolve(path$2.dirname(importer), source) : path$2.resolve(source), preserveSymlinks);20748 return addJsExtensionIfNecessary(importer ? path.resolve(path.dirname(importer), source) : path.resolve(source), preserveSymlinks); 19809 20749 } 19810 20750 async function addJsExtensionIfNecessary(file, preserveSymlinks) { … … 19820 20760 if ((preserveSymlinks && stats.isSymbolicLink()) || stats.isFile()) { 19821 20761 // check case 19822 const name = path $2.basename(file);19823 const files = await promises.readdir(path $2.dirname(file));20762 const name = path.basename(file); 20763 const files = await promises.readdir(path.dirname(file)); 19824 20764 if (files.includes(name)) 19825 20765 return file; … … 20264 21204 } 20265 21205 getResolveStaticDependencyPromises(module) { 20266 // eslint-disable-next-line unicorn/prefer-spread20267 21206 return Array.from(module.sourcesWithAttributes, async ([source, attributes]) => [ 20268 21207 source, … … 20377 21316 return parseAst_js.isRelative(source) 20378 21317 ? importer 20379 ? path $2.resolve(importer, '..', source)20380 : path $2.resolve(source)21318 ? path.resolve(importer, '..', source) 21319 : path.resolve(source) 20381 21320 : source; 20382 21321 } … … 20401 21340 const [resolveStaticDependencyPromises, resolveDynamicImportPromises] = await loadPromise; 20402 21341 return Promise.all([...resolveStaticDependencyPromises, ...resolveDynamicImportPromises]); 20403 }20404 20405 class GlobalScope extends Scope {20406 constructor() {20407 super();20408 this.parent = null;20409 this.variables.set('undefined', new UndefinedVariable());20410 }20411 findVariable(name) {20412 let variable = this.variables.get(name);20413 if (!variable) {20414 variable = new GlobalVariable(name);20415 this.variables.set(name, variable);20416 }20417 return variable;20418 }20419 21342 } 20420 21343 … … 20575 21498 for (const module of this.modules) { 20576 21499 if (module.isExecuted) { 21500 module.hasTreeShakingPassStarted = true; 20577 21501 if (module.info.moduleSideEffects === 'no-treeshake') { 20578 21502 module.includeAllInBundle(); … … 20704 21628 external: getIdMatcher(config.external), 20705 21629 input: getInput(config), 21630 jsx: getJsx(config), 20706 21631 logLevel, 20707 21632 makeAbsoluteExternalsRelative: config.makeAbsoluteExternalsRelative ?? 'ifRelativeSource', … … 20749 21674 return configInput == null ? [] : typeof configInput === 'string' ? [configInput] : configInput; 20750 21675 }; 21676 const getJsx = (config) => { 21677 const configJsx = config.jsx; 21678 if (!configJsx) 21679 return false; 21680 const configWithPreset = getOptionWithPreset(configJsx, jsxPresets, 'jsx', parseAst_js.URL_JSX, 'false, '); 21681 const { factory, importSource, mode } = configWithPreset; 21682 switch (mode) { 21683 case 'automatic': { 21684 return { 21685 factory: factory || 'React.createElement', 21686 importSource: importSource || 'react', 21687 jsxImportSource: configWithPreset.jsxImportSource || 'react/jsx-runtime', 21688 mode: 'automatic' 21689 }; 21690 } 21691 case 'preserve': { 21692 if (importSource && !(factory || configWithPreset.fragment)) { 21693 parseAst_js.error(parseAst_js.logInvalidOption('jsx', parseAst_js.URL_JSX, 'when preserving JSX and specifying an importSource, you also need to specify a factory or fragment')); 21694 } 21695 return { 21696 factory: factory || null, 21697 fragment: configWithPreset.fragment || null, 21698 importSource: importSource || null, 21699 mode: 'preserve' 21700 }; 21701 } 21702 // case 'classic': 21703 default: { 21704 if (mode && mode !== 'classic') { 21705 parseAst_js.error(parseAst_js.logInvalidOption('jsx.mode', parseAst_js.URL_JSX, 'mode must be "automatic", "classic" or "preserve"', mode)); 21706 } 21707 return { 21708 factory: factory || 'React.createElement', 21709 fragment: configWithPreset.fragment || 'React.Fragment', 21710 importSource: importSource || null, 21711 mode: 'classic' 21712 }; 21713 } 21714 } 21715 }; 20751 21716 const getMaxParallelFileOps = (config) => { 20752 21717 const maxParallelFileOps = config.maxParallelFileOps; … … 20766 21731 const contextByModuleId = Object.create(null); 20767 21732 for (const [key, moduleContext] of Object.entries(configModuleContext)) { 20768 contextByModuleId[path $2.resolve(key)] = moduleContext;21733 contextByModuleId[path.resolve(key)] = moduleContext; 20769 21734 } 20770 21735 return id => contextByModuleId[id] ?? context; … … 20879 21844 sourcemap: config.sourcemap || false, 20880 21845 sourcemapBaseUrl: getSourcemapBaseUrl(config), 21846 sourcemapDebugIds: config.sourcemapDebugIds || false, 20881 21847 sourcemapExcludeSources: config.sourcemapExcludeSources || false, 20882 21848 sourcemapFile: config.sourcemapFile, … … 20890 21856 strict: config.strict ?? true, 20891 21857 systemNullSetters: config.systemNullSetters ?? true, 20892 validate: config.validate || false 21858 validate: config.validate || false, 21859 virtualDirname: config.virtualDirname || '_virtual' 20893 21860 }; 20894 21861 warnUnknownOptions(config, Object.keys(outputOptions), 'output options', inputOptions.onLog); … … 20958 21925 return undefined; 20959 21926 } 20960 return path $2.resolve(preserveModulesRoot);21927 return path.resolve(preserveModulesRoot); 20961 21928 }; 20962 21929 const getAmd = (config) => { … … 20995 21962 return () => configAddon || ''; 20996 21963 }; 20997 // eslint-disable-next-line unicorn/prevent-abbreviations20998 21964 const getDir = (config, file) => { 20999 21965 const { dir } = config; … … 21065 22031 const validateInterop = (interop) => { 21066 22032 if (!ALLOWED_INTEROP_TYPES.has(interop)) { 21067 return parseAst_js.error(parseAst_js.logInvalidOption('output.interop', parseAst_js.URL_OUTPUT_INTEROP, 21068 // eslint-disable-next-line unicorn/prefer-spread 21069 `use one of ${Array.from(ALLOWED_INTEROP_TYPES, value => JSON.stringify(value)).join(', ')}`, interop)); 22033 return parseAst_js.error(parseAst_js.logInvalidOption('output.interop', parseAst_js.URL_OUTPUT_INTEROP, `use one of ${Array.from(ALLOWED_INTEROP_TYPES, value => JSON.stringify(value)).join(', ')}`, interop)); 21070 22034 } 21071 22035 return interop; … … 21101 22065 }; 21102 22066 22067 // @ts-expect-error TS2540: the polyfill of `asyncDispose`. 22068 Symbol.asyncDispose ??= Symbol('Symbol.asyncDispose'); 21103 22069 function rollup(rawInputOptions) { 21104 22070 return rollupInternal(rawInputOptions, null); … … 21144 22110 }, 21145 22111 closed: false, 22112 async [Symbol.asyncDispose]() { 22113 await this.close(); 22114 }, 21146 22115 async generate(rawOutputOptions) { 21147 22116 if (result.closed) … … 21258 22227 } 21259 22228 async function writeOutputFile(outputFile, outputOptions) { 21260 const fileName = path $2.resolve(outputOptions.dir || path$2.dirname(outputOptions.file), outputFile.fileName);22229 const fileName = path.resolve(outputOptions.dir || path.dirname(outputOptions.file), outputFile.fileName); 21261 22230 // 'recursive: true' does not throw if the folder structure, or parts of it, already exist 21262 await promises.mkdir(path $2.dirname(fileName), { recursive: true });22231 await promises.mkdir(path.dirname(fileName), { recursive: true }); 21263 22232 return promises.writeFile(fileName, outputFile.type === 'asset' ? outputFile.source : outputFile.code); 21264 22233 } … … 21282 22251 exports.ensureArray = ensureArray$1; 21283 22252 exports.getAugmentedNamespace = getAugmentedNamespace; 22253 exports.getDefaultExportFromCjs = getDefaultExportFromCjs; 21284 22254 exports.getNewArray = getNewArray; 21285 22255 exports.getOrCreate = getOrCreate; … … 21290 22260 exports.mergeOptions = mergeOptions; 21291 22261 exports.normalizePluginOption = normalizePluginOption; 21292 exports.picomatch = picomatch;21293 22262 exports.rollup = rollup; 21294 22263 exports.rollupInternal = rollupInternal;
Note:
See TracChangeset
for help on using the changeset viewer.