@rollup/wasm-node 4.16.4 → 4.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,13 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v4.16.4
4
- Tue, 23 Apr 2024 13:14:37 GMT - commit 1c404fa352b70007066e94ff4c1981f8046f8cef
3
+ Rollup.js v4.17.1
4
+ Mon, 29 Apr 2024 04:57:19 GMT - commit dbf0a2e5d3c3eae09ac4d502646d0ecab63f40fd
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
8
8
  Released under the MIT License.
9
9
  */
10
- import { normalize, getImportPath, EMPTY_ARRAY, LOGLEVEL_WARN, logUnusedExternalImports, ANNOTATION_KEY, INVALID_ANNOTATION_KEY, Program as Program$1, logRedeclarationError, CatchClause as CatchClause$1, logDuplicateArgumentNameError, CallExpression as CallExpression$1, BLANK, logIllegalImportReassignment, logModuleLevelDirective, ReturnStatement as ReturnStatement$1, Property as Property$1, logConstVariableReassignError, ExpressionStatement as ExpressionStatement$1, ArrowFunctionExpression as ArrowFunctionExpression$1, logMissingExport, EMPTY_SET, logCannotCallNamespace, logEval, BlockStatement as BlockStatement$1, getRollupError, logParseError, logModuleParseError, error, LOGLEVEL_INFO, logFirstSideEffect, locate, logInvalidAnnotation, Identifier as Identifier$1, logThisIsUndefined, getReadStringFunction, convertString, convertAnnotations, FIXED_STRINGS, convertNode as convertNode$1, EMPTY_OBJECT, logImportAttributeIsInvalid, logImportOptionsAreInvalid, logSyntheticNamedExportsNeedNamespaceExport, logMissingEntryExport, logInvalidFormatForTopLevelAwait, logDuplicateExportError, logInvalidSourcemapForError, augmentCodeLocation, logInconsistentImportAttributes, logNamespaceConflict, logAmbiguousExternalNamespaces, logShimmedExport, parseAst, logCircularReexport, TemplateLiteral as TemplateLiteral$1, Literal as Literal$1, logMissingNodeBuiltins, logIllegalIdentifierAsName, logMissingNameOptionForIifeExport, logMissingNameOptionForUmdExport, logAddonNotGenerated, logIncompatibleExportOptionValue, logMixedExport, logFailedValidation, isPathFragment, logCyclicCrossChunkReexport, getAliasName, logUnexpectedNamedImport, isAbsolute as isAbsolute$1, relative as relative$1, logUnexpectedNamespaceReexport, logEmptyChunk, logMissingGlobalName, logOptimizeChunkStatus, logSourcemapBroken, logConflictingSourcemapSources, logChunkInvalid, logInvalidOption, URL_OUTPUT_FORMAT, URL_OUTPUT_DIR, URL_OUTPUT_SOURCEMAPFILE, URL_OUTPUT_AMD_ID, logCannotAssignModuleToChunk, logAnonymousPluginCache, logDuplicatePluginName, LOGLEVEL_ERROR, logLevelPriority, LOGLEVEL_DEBUG, logUnknownOption, printQuotedStringList, logInvalidSetAssetSourceCall, logPluginError, logNoTransformMapOrAstWithoutCode, relativeId, logBadLoader, logExternalModulesCannotBeTransformedToModules, logInternalIdCannotBeExternal, isRelative, logUnresolvedImport, logUnresolvedImportTreatedAsExternal, logExternalSyntheticExports, logUnresolvedEntry, logUnresolvedImplicitDependant, logExternalModulesCannotBeIncludedInManualChunks, logEntryCannotBeExternal, logImplicitDependantCannotBeExternal, logNoAssetSourceSet, logFileReferenceIdNotFoundForFilename, logAssetReferenceIdNotFoundForSetSource, logAssetSourceAlreadySet, logInvalidRollupPhaseForChunkEmission, logFileNameConflict, logAssetNotFinalisedForFileName, logChunkNotGeneratedForFileName, logInvalidLogPosition, logInputHookInOutputPlugin, logInvalidFunctionPluginHook, logInvalidAddonPluginHook, logImplicitDependantIsNotIncluded, logCircularDependency, augmentLogMessage, URL_TREESHAKE_MODULESIDEEFFECTS, URL_TREESHAKE, URL_OUTPUT_INLINEDYNAMICIMPORTS, URL_PRESERVEENTRYSIGNATURES, URL_OUTPUT_AMD_BASEPATH, logInvalidExportOptionValue, warnDeprecation, URL_OUTPUT_INTEROP, URL_OUTPUT_MANUALCHUNKS, isValidUrl, addTrailingSlashIfMissed, URL_OUTPUT_SOURCEMAPBASEURL, URL_OUTPUT_GENERATEDCODE, URL_OUTPUT_EXTERNALIMPORTATTRIBUTES, logAlreadyClosed, logMissingFileOrDirOption, logCannotEmitFromOptionsHook, URL_WATCH } from './parseAst.js';
10
+ import { normalize, getImportPath, ExportDefaultDeclaration as ExportDefaultDeclaration$1, CallExpression as CallExpression$1, EMPTY_ARRAY, LOGLEVEL_WARN, logUnusedExternalImports, ANNOTATION_KEY, INVALID_ANNOTATION_KEY, Program as Program$1, BLANK, logIllegalImportReassignment, logRedeclarationError, CatchClause as CatchClause$1, logDuplicateArgumentNameError, logModuleLevelDirective, ReturnStatement as ReturnStatement$1, VariableDeclarator as VariableDeclarator$1, Property as Property$1, logConstVariableReassignError, ExpressionStatement as ExpressionStatement$1, ArrowFunctionExpression as ArrowFunctionExpression$1, logMissingExport, EMPTY_SET, logCannotCallNamespace, logEval, BlockStatement as BlockStatement$1, getRollupError, logParseError, logModuleParseError, error, LOGLEVEL_INFO, logFirstSideEffect, locate, logInvalidAnnotation, Identifier as Identifier$1, logThisIsUndefined, getReadStringFunction, convertString, convertAnnotations, FIXED_STRINGS, convertNode as convertNode$1, EMPTY_OBJECT, logImportAttributeIsInvalid, logImportOptionsAreInvalid, logSyntheticNamedExportsNeedNamespaceExport, logMissingEntryExport, logInvalidFormatForTopLevelAwait, logDuplicateExportError, logInvalidSourcemapForError, augmentCodeLocation, logInconsistentImportAttributes, logNamespaceConflict, logAmbiguousExternalNamespaces, logShimmedExport, parseAst, logCircularReexport, TemplateLiteral as TemplateLiteral$1, Literal as Literal$1, logMissingNodeBuiltins, logIllegalIdentifierAsName, logMissingNameOptionForIifeExport, logMissingNameOptionForUmdExport, logAddonNotGenerated, logIncompatibleExportOptionValue, logMixedExport, logFailedValidation, isPathFragment, logCyclicCrossChunkReexport, getAliasName, logUnexpectedNamedImport, isAbsolute as isAbsolute$1, relative as relative$1, logUnexpectedNamespaceReexport, logEmptyChunk, logMissingGlobalName, logOptimizeChunkStatus, logSourcemapBroken, logConflictingSourcemapSources, logChunkInvalid, logInvalidOption, URL_OUTPUT_FORMAT, URL_OUTPUT_DIR, URL_OUTPUT_SOURCEMAPFILE, URL_OUTPUT_AMD_ID, logCannotAssignModuleToChunk, logAnonymousPluginCache, logDuplicatePluginName, LOGLEVEL_ERROR, logLevelPriority, LOGLEVEL_DEBUG, logUnknownOption, printQuotedStringList, logInvalidSetAssetSourceCall, logPluginError, logNoTransformMapOrAstWithoutCode, relativeId, logBadLoader, logExternalModulesCannotBeTransformedToModules, logInternalIdCannotBeExternal, isRelative, logUnresolvedImport, logUnresolvedImportTreatedAsExternal, logExternalSyntheticExports, logUnresolvedEntry, logUnresolvedImplicitDependant, logExternalModulesCannotBeIncludedInManualChunks, logEntryCannotBeExternal, logImplicitDependantCannotBeExternal, logNoAssetSourceSet, logFileReferenceIdNotFoundForFilename, logAssetReferenceIdNotFoundForSetSource, logAssetSourceAlreadySet, logInvalidRollupPhaseForChunkEmission, logFileNameConflict, logAssetNotFinalisedForFileName, logChunkNotGeneratedForFileName, logInvalidLogPosition, logInputHookInOutputPlugin, logInvalidFunctionPluginHook, logInvalidAddonPluginHook, logImplicitDependantIsNotIncluded, logCircularDependency, augmentLogMessage, URL_TREESHAKE_MODULESIDEEFFECTS, URL_TREESHAKE, URL_OUTPUT_INLINEDYNAMICIMPORTS, URL_PRESERVEENTRYSIGNATURES, URL_OUTPUT_AMD_BASEPATH, logInvalidExportOptionValue, warnDeprecation, URL_OUTPUT_INTEROP, URL_OUTPUT_MANUALCHUNKS, isValidUrl, addTrailingSlashIfMissed, URL_OUTPUT_SOURCEMAPBASEURL, URL_OUTPUT_GENERATEDCODE, URL_OUTPUT_EXTERNALIMPORTATTRIBUTES, logAlreadyClosed, logMissingFileOrDirOption, logCannotEmitFromOptionsHook, URL_WATCH } from './parseAst.js';
11
11
  import { relative, dirname, basename, extname, resolve as resolve$1 } from 'node:path';
12
12
  import require$$0$1, { win32, posix, isAbsolute, resolve } from 'path';
13
13
  import { parseAsync, xxhashBase64Url, xxhashBase36, xxhashBase16 } from '../../native.js';
@@ -16,7 +16,7 @@ import { performance } from 'node:perf_hooks';
16
16
  import { lstat, realpath, readdir, readFile, mkdir, writeFile } from 'node:fs/promises';
17
17
  import * as tty from 'tty';
18
18
 
19
- var version = "4.16.4";
19
+ var version = "4.17.1";
20
20
 
21
21
  const comma = ','.charCodeAt(0);
22
22
  const semicolon = ';'.charCodeAt(0);
@@ -1937,6 +1937,9 @@ const NODE_INTERACTION_UNKNOWN_CALL = {
1937
1937
  };
1938
1938
 
1939
1939
  class Variable extends ExpressionEntity {
1940
+ markReassigned() {
1941
+ this.isReassigned = true;
1942
+ }
1940
1943
  constructor(name) {
1941
1944
  super();
1942
1945
  this.name = name;
@@ -1944,16 +1947,35 @@ class Variable extends ExpressionEntity {
1944
1947
  this.forbiddenNames = null;
1945
1948
  this.initReached = false;
1946
1949
  this.isId = false;
1947
- this.isReassigned = false;
1948
1950
  this.kind = null;
1949
1951
  this.renderBaseName = null;
1950
1952
  this.renderName = null;
1953
+ this.isReassigned = false;
1954
+ this.onlyFunctionCallUsed = true;
1951
1955
  }
1952
1956
  /**
1953
1957
  * Binds identifiers that reference this variable to this variable.
1954
1958
  * Necessary to be able to change variable names.
1955
1959
  */
1956
1960
  addReference(_identifier) { }
1961
+ /**
1962
+ * Check if the identifier variable is only used as function call
1963
+ * @returns true if the variable is only used as function call
1964
+ */
1965
+ getOnlyFunctionCallUsed() {
1966
+ return this.onlyFunctionCallUsed;
1967
+ }
1968
+ /**
1969
+ * Collect the places where the identifier variable is used
1970
+ * @param usedPlace Where the variable is used
1971
+ */
1972
+ addUsedPlace(usedPlace) {
1973
+ const isFunctionCall = usedPlace.parent.type === CallExpression$1 &&
1974
+ usedPlace.parent.callee === usedPlace;
1975
+ if (!isFunctionCall && usedPlace.parent.type !== ExportDefaultDeclaration$1) {
1976
+ this.onlyFunctionCallUsed = false;
1977
+ }
1978
+ }
1957
1979
  /**
1958
1980
  * Prevent this variable from being renamed to this name to avoid name
1959
1981
  * collisions
@@ -5654,692 +5676,129 @@ class ArrayPattern extends NodeBase {
5654
5676
  }
5655
5677
  }
5656
5678
 
5657
- class LocalVariable extends Variable {
5658
- constructor(name, declarator, init, context, kind) {
5659
- super(name);
5660
- this.init = init;
5661
- this.calledFromTryStatement = false;
5662
- this.additionalInitializers = null;
5663
- this.expressionsToBeDeoptimized = [];
5664
- this.declarations = declarator ? [declarator] : [];
5665
- this.deoptimizationTracker = context.deoptimizationTracker;
5666
- this.module = context.module;
5667
- this.kind = kind;
5668
- }
5669
- addDeclaration(identifier, init) {
5670
- this.declarations.push(identifier);
5671
- this.markInitializersForDeoptimization().push(init);
5672
- }
5673
- consolidateInitializers() {
5674
- if (this.additionalInitializers) {
5675
- for (const initializer of this.additionalInitializers) {
5676
- initializer.deoptimizePath(UNKNOWN_PATH);
5677
- }
5678
- this.additionalInitializers = null;
5679
- }
5680
- }
5681
- deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
5682
- if (this.isReassigned) {
5683
- deoptimizeInteraction(interaction);
5684
- return;
5685
- }
5686
- recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker), undefined);
5687
- }
5688
- deoptimizePath(path) {
5689
- if (this.isReassigned ||
5690
- this.deoptimizationTracker.trackEntityAtPathAndGetIfTracked(path, this)) {
5691
- return;
5692
- }
5693
- if (path.length === 0) {
5694
- this.isReassigned = true;
5695
- const expressionsToBeDeoptimized = this.expressionsToBeDeoptimized;
5696
- this.expressionsToBeDeoptimized = EMPTY_ARRAY;
5697
- for (const expression of expressionsToBeDeoptimized) {
5698
- expression.deoptimizeCache();
5699
- }
5700
- this.init.deoptimizePath(UNKNOWN_PATH);
5701
- }
5702
- else {
5703
- this.init.deoptimizePath(path);
5704
- }
5705
- }
5706
- getLiteralValueAtPath(path, recursionTracker, origin) {
5707
- if (this.isReassigned) {
5708
- return UnknownValue;
5709
- }
5710
- return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
5711
- this.expressionsToBeDeoptimized.push(origin);
5712
- return this.init.getLiteralValueAtPath(path, recursionTracker, origin);
5713
- }, UnknownValue);
5714
- }
5715
- getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
5716
- if (this.isReassigned) {
5717
- return UNKNOWN_RETURN_EXPRESSION;
5679
+ /** @typedef { import('estree').Node} Node */
5680
+ /** @typedef {Node | {
5681
+ * type: 'PropertyDefinition';
5682
+ * computed: boolean;
5683
+ * value: Node
5684
+ * }} NodeWithPropertyDefinition */
5685
+
5686
+ /**
5687
+ *
5688
+ * @param {NodeWithPropertyDefinition} node
5689
+ * @param {NodeWithPropertyDefinition} parent
5690
+ * @returns {boolean}
5691
+ */
5692
+ function is_reference (node, parent) {
5693
+ if (node.type === 'MemberExpression') {
5694
+ return !node.computed && is_reference(node.object, node);
5695
+ }
5696
+
5697
+ if (node.type === 'Identifier') {
5698
+ if (!parent) return true;
5699
+
5700
+ switch (parent.type) {
5701
+ // disregard `bar` in `foo.bar`
5702
+ case 'MemberExpression': return parent.computed || node === parent.object;
5703
+
5704
+ // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
5705
+ case 'MethodDefinition': return parent.computed;
5706
+
5707
+ // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
5708
+ case 'PropertyDefinition': return parent.computed || node === parent.value;
5709
+
5710
+ // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
5711
+ case 'Property': return parent.computed || node === parent.value;
5712
+
5713
+ // disregard the `bar` in `export { foo as bar }` or
5714
+ // the foo in `import { foo as bar }`
5715
+ case 'ExportSpecifier':
5716
+ case 'ImportSpecifier': return node === parent.local;
5717
+
5718
+ // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
5719
+ case 'LabeledStatement':
5720
+ case 'BreakStatement':
5721
+ case 'ContinueStatement': return false;
5722
+ default: return true;
5723
+ }
5724
+ }
5725
+
5726
+ return false;
5727
+ }
5728
+
5729
+ const PureFunctionKey = Symbol('PureFunction');
5730
+ const getPureFunctions = ({ treeshake }) => {
5731
+ const pureFunctions = Object.create(null);
5732
+ for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
5733
+ let currentFunctions = pureFunctions;
5734
+ for (const pathSegment of functionName.split('.')) {
5735
+ currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
5718
5736
  }
5719
- return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
5720
- this.expressionsToBeDeoptimized.push(origin);
5721
- return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
5722
- }, UNKNOWN_RETURN_EXPRESSION);
5737
+ currentFunctions[PureFunctionKey] = true;
5723
5738
  }
5724
- hasEffectsOnInteractionAtPath(path, interaction, context) {
5725
- switch (interaction.type) {
5726
- case INTERACTION_ACCESSED: {
5727
- if (this.isReassigned)
5728
- return true;
5729
- return (!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
5730
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
5731
- }
5732
- case INTERACTION_ASSIGNED: {
5733
- if (this.included)
5734
- return true;
5735
- if (path.length === 0)
5736
- return false;
5737
- if (this.isReassigned)
5738
- return true;
5739
- return (!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
5740
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
5741
- }
5742
- case INTERACTION_CALLED: {
5743
- if (this.isReassigned)
5744
- return true;
5745
- return (!(interaction.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this) &&
5746
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
5747
- }
5748
- }
5739
+ return pureFunctions;
5740
+ };
5741
+
5742
+ const doNothing = () => { };
5743
+
5744
+ /* eslint sort-keys: "off" */
5745
+ const ValueProperties = Symbol('Value Properties');
5746
+ const getTruthyLiteralValue = () => UnknownTruthyValue;
5747
+ const returnFalse = () => false;
5748
+ const returnTrue = () => true;
5749
+ const PURE = {
5750
+ deoptimizeArgumentsOnCall: doNothing,
5751
+ getLiteralValue: getTruthyLiteralValue,
5752
+ hasEffectsWhenCalled: returnFalse
5753
+ };
5754
+ const IMPURE = {
5755
+ deoptimizeArgumentsOnCall: doNothing,
5756
+ getLiteralValue: getTruthyLiteralValue,
5757
+ hasEffectsWhenCalled: returnTrue
5758
+ };
5759
+ const PURE_WITH_ARRAY = {
5760
+ deoptimizeArgumentsOnCall: doNothing,
5761
+ getLiteralValue: getTruthyLiteralValue,
5762
+ hasEffectsWhenCalled({ args }) {
5763
+ return args.length > 1 && !(args[1] instanceof ArrayExpression);
5749
5764
  }
5750
- include() {
5751
- if (!this.included) {
5752
- super.include();
5753
- for (const declaration of this.declarations) {
5754
- // If node is a default export, it can save a tree-shaking run to include the full declaration now
5755
- if (!declaration.included)
5756
- declaration.include(createInclusionContext(), false);
5757
- let node = declaration.parent;
5758
- while (!node.included) {
5759
- // We do not want to properly include parents in case they are part of a dead branch
5760
- // in which case .include() might pull in more dead code
5761
- node.included = true;
5762
- if (node.type === Program$1)
5763
- break;
5764
- node = node.parent;
5765
- }
5766
- }
5767
- }
5765
+ };
5766
+ const GETTER_ACCESS = {
5767
+ deoptimizeArgumentsOnCall: doNothing,
5768
+ getLiteralValue: getTruthyLiteralValue,
5769
+ hasEffectsWhenCalled({ args }, context) {
5770
+ const [_thisArgument, firstArgument] = args;
5771
+ return (!(firstArgument instanceof ExpressionEntity) ||
5772
+ firstArgument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context));
5768
5773
  }
5769
- includeCallArguments(context, parameters) {
5770
- if (this.isReassigned || context.includedCallArguments.has(this.init)) {
5771
- for (const argument of parameters) {
5772
- argument.include(context, false);
5773
- }
5774
- }
5775
- else {
5776
- context.includedCallArguments.add(this.init);
5777
- this.init.includeCallArguments(context, parameters);
5778
- context.includedCallArguments.delete(this.init);
5779
- }
5780
- }
5781
- markCalledFromTryStatement() {
5782
- this.calledFromTryStatement = true;
5783
- }
5784
- markInitializersForDeoptimization() {
5785
- if (this.additionalInitializers === null) {
5786
- this.additionalInitializers = [this.init];
5787
- this.init = UNKNOWN_EXPRESSION;
5788
- this.isReassigned = true;
5789
- }
5790
- return this.additionalInitializers;
5791
- }
5792
- }
5793
-
5794
- const MAX_TRACKED_INTERACTIONS = 20;
5795
- const NO_INTERACTIONS = EMPTY_ARRAY;
5796
- const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);
5797
- const EMPTY_PATH_TRACKER = new PathTracker();
5798
- const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);
5799
- class ParameterVariable extends LocalVariable {
5800
- constructor(name, declarator, context) {
5801
- super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');
5802
- this.deoptimizationInteractions = [];
5803
- this.deoptimizations = new PathTracker();
5804
- this.deoptimizedFields = new Set();
5805
- this.entitiesToBeDeoptimized = new Set();
5806
- }
5807
- addEntityToBeDeoptimized(entity) {
5808
- if (entity === UNKNOWN_EXPRESSION) {
5809
- // As unknown expressions fully deoptimize all interactions, we can clear
5810
- // the interaction cache at this point provided we keep this optimization
5811
- // in mind when adding new interactions
5812
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5813
- this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);
5814
- for (const { interaction } of this.deoptimizationInteractions) {
5815
- deoptimizeInteraction(interaction);
5816
- }
5817
- this.deoptimizationInteractions = NO_INTERACTIONS;
5818
- }
5819
- }
5820
- else if (this.deoptimizedFields.has(UnknownKey)) {
5821
- // This means that we already deoptimized all interactions and no longer
5822
- // track them
5823
- entity.deoptimizePath(UNKNOWN_PATH);
5824
- }
5825
- else if (!this.entitiesToBeDeoptimized.has(entity)) {
5826
- this.entitiesToBeDeoptimized.add(entity);
5827
- for (const field of this.deoptimizedFields) {
5828
- entity.deoptimizePath([field]);
5829
- }
5830
- for (const { interaction, path } of this.deoptimizationInteractions) {
5831
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
5832
- }
5833
- }
5834
- }
5835
- deoptimizeArgumentsOnInteractionAtPath(interaction, path) {
5836
- // For performance reasons, we fully deoptimize all deeper interactions
5837
- if (path.length >= 2 ||
5838
- this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
5839
- this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||
5840
- (path.length === 1 &&
5841
- (this.deoptimizedFields.has(UnknownKey) ||
5842
- (interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0]))))) {
5843
- deoptimizeInteraction(interaction);
5844
- return;
5845
- }
5846
- if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {
5847
- for (const entity of this.entitiesToBeDeoptimized) {
5848
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
5849
- }
5850
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5851
- this.deoptimizationInteractions.push({
5852
- interaction,
5853
- path
5854
- });
5855
- }
5856
- }
5857
- }
5858
- deoptimizePath(path) {
5859
- if (path.length === 0 || this.deoptimizedFields.has(UnknownKey)) {
5860
- return;
5861
- }
5862
- const key = path[0];
5863
- if (this.deoptimizedFields.has(key)) {
5864
- return;
5865
- }
5866
- this.deoptimizedFields.add(key);
5867
- for (const entity of this.entitiesToBeDeoptimized) {
5868
- // We do not need a recursion tracker here as we already track whether
5869
- // this field is deoptimized
5870
- entity.deoptimizePath([key]);
5871
- }
5872
- if (key === UnknownKey) {
5873
- // save some memory
5874
- this.deoptimizationInteractions = NO_INTERACTIONS;
5875
- this.deoptimizations = EMPTY_PATH_TRACKER;
5876
- this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;
5877
- this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
5878
- }
5879
- }
5880
- getReturnExpressionWhenCalledAtPath(path) {
5881
- // We deoptimize everything that is called as that will trivially deoptimize
5882
- // the corresponding return expressions as well and avoid badly performing
5883
- // and complicated alternatives
5884
- if (path.length === 0) {
5885
- this.deoptimizePath(UNKNOWN_PATH);
5886
- }
5887
- else if (!this.deoptimizedFields.has(path[0])) {
5888
- this.deoptimizePath([path[0]]);
5889
- }
5890
- return UNKNOWN_RETURN_EXPRESSION;
5891
- }
5892
- }
5893
-
5894
- const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$';
5895
- const base = 64;
5896
- function toBase64(value) {
5897
- let outString = '';
5898
- do {
5899
- const currentDigit = value % base;
5900
- value = (value / base) | 0;
5901
- outString = chars[currentDigit] + outString;
5902
- } while (value !== 0);
5903
- return outString;
5904
- }
5905
-
5906
- function getSafeName(baseName, usedNames, forbiddenNames) {
5907
- let safeName = baseName;
5908
- let count = 1;
5909
- while (usedNames.has(safeName) || RESERVED_NAMES.has(safeName) || forbiddenNames?.has(safeName)) {
5910
- safeName = `${baseName}$${toBase64(count++)}`;
5911
- }
5912
- usedNames.add(safeName);
5913
- return safeName;
5914
- }
5915
-
5916
- class Scope {
5917
- constructor() {
5918
- this.children = [];
5919
- this.variables = new Map();
5920
- }
5921
- /*
5922
- Redeclaration rules:
5923
- - var can redeclare var
5924
- - in function scopes, function and var can redeclare function and var
5925
- - var is hoisted across scopes, function remains in the scope it is declared
5926
- - var and function can redeclare function parameters, but parameters cannot redeclare parameters
5927
- - function cannot redeclare catch scope parameters
5928
- - var can redeclare catch scope parameters in a way
5929
- - if the parameter is an identifier and not a pattern
5930
- - then the variable is still declared in the hoisted outer scope, but the initializer is assigned to the parameter
5931
- - const, let, class, and function except in the cases above cannot redeclare anything
5932
- */
5933
- addDeclaration(identifier, context, init, kind) {
5934
- const name = identifier.name;
5935
- const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
5936
- if (existingVariable) {
5937
- const existingKind = existingVariable.kind;
5938
- if (kind === 'var' && existingKind === 'var') {
5939
- existingVariable.addDeclaration(identifier, init);
5940
- return existingVariable;
5941
- }
5942
- context.error(logRedeclarationError(name), identifier.start);
5943
- }
5944
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
5945
- this.variables.set(name, newVariable);
5946
- return newVariable;
5947
- }
5948
- addHoistedVariable(name, variable) {
5949
- (this.hoistedVariables ||= new Map()).set(name, variable);
5950
- }
5951
- contains(name) {
5952
- return this.variables.has(name);
5953
- }
5954
- findVariable(_name) {
5955
- /* istanbul ignore next */
5956
- throw new Error('Internal Error: findVariable needs to be implemented by a subclass');
5957
- }
5958
- }
5959
-
5960
- class ChildScope extends Scope {
5961
- constructor(parent, context) {
5962
- super();
5963
- this.parent = parent;
5964
- this.context = context;
5965
- this.accessedOutsideVariables = new Map();
5966
- parent.children.push(this);
5967
- }
5968
- addAccessedDynamicImport(importExpression) {
5969
- (this.accessedDynamicImports || (this.accessedDynamicImports = new Set())).add(importExpression);
5970
- if (this.parent instanceof ChildScope) {
5971
- this.parent.addAccessedDynamicImport(importExpression);
5972
- }
5973
- }
5974
- addAccessedGlobals(globals, accessedGlobalsByScope) {
5975
- const accessedGlobals = accessedGlobalsByScope.get(this) || new Set();
5976
- for (const name of globals) {
5977
- accessedGlobals.add(name);
5978
- }
5979
- accessedGlobalsByScope.set(this, accessedGlobals);
5980
- if (this.parent instanceof ChildScope) {
5981
- this.parent.addAccessedGlobals(globals, accessedGlobalsByScope);
5982
- }
5983
- }
5984
- addNamespaceMemberAccess(name, variable) {
5985
- this.accessedOutsideVariables.set(name, variable);
5986
- this.parent.addNamespaceMemberAccess(name, variable);
5987
- }
5988
- addReturnExpression(expression) {
5989
- this.parent instanceof ChildScope && this.parent.addReturnExpression(expression);
5990
- }
5991
- addUsedOutsideNames(usedNames, format, exportNamesByVariable, accessedGlobalsByScope) {
5992
- for (const variable of this.accessedOutsideVariables.values()) {
5993
- if (variable.included) {
5994
- usedNames.add(variable.getBaseVariableName());
5995
- if (format === 'system' && exportNamesByVariable.has(variable)) {
5996
- usedNames.add('exports');
5997
- }
5998
- }
5999
- }
6000
- const accessedGlobals = accessedGlobalsByScope.get(this);
6001
- if (accessedGlobals) {
6002
- for (const name of accessedGlobals) {
6003
- usedNames.add(name);
6004
- }
6005
- }
6006
- }
6007
- contains(name) {
6008
- return this.variables.has(name) || this.parent.contains(name);
6009
- }
6010
- deconflict(format, exportNamesByVariable, accessedGlobalsByScope) {
6011
- const usedNames = new Set();
6012
- this.addUsedOutsideNames(usedNames, format, exportNamesByVariable, accessedGlobalsByScope);
6013
- if (this.accessedDynamicImports) {
6014
- for (const importExpression of this.accessedDynamicImports) {
6015
- if (importExpression.inlineNamespace) {
6016
- usedNames.add(importExpression.inlineNamespace.getBaseVariableName());
6017
- }
6018
- }
6019
- }
6020
- for (const [name, variable] of this.variables) {
6021
- if (variable.included || variable.alwaysRendered) {
6022
- variable.setRenderNames(null, getSafeName(name, usedNames, variable.forbiddenNames));
6023
- }
6024
- }
6025
- for (const scope of this.children) {
6026
- scope.deconflict(format, exportNamesByVariable, accessedGlobalsByScope);
6027
- }
6028
- }
6029
- findLexicalBoundary() {
6030
- return this.parent.findLexicalBoundary();
6031
- }
6032
- findVariable(name) {
6033
- const knownVariable = this.variables.get(name) || this.accessedOutsideVariables.get(name);
6034
- if (knownVariable) {
6035
- return knownVariable;
6036
- }
6037
- const variable = this.parent.findVariable(name);
6038
- this.accessedOutsideVariables.set(name, variable);
6039
- return variable;
6040
- }
6041
- }
6042
-
6043
- class CatchBodyScope extends ChildScope {
6044
- constructor(parent) {
6045
- super(parent, parent.context);
6046
- this.parent = parent;
6047
- }
6048
- addDeclaration(identifier, context, init, kind) {
6049
- if (kind === 'var') {
6050
- const name = identifier.name;
6051
- const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
6052
- if (existingVariable) {
6053
- const existingKind = existingVariable.kind;
6054
- if (existingKind === 'parameter' &&
6055
- // If this is a destructured parameter, it is forbidden to redeclare
6056
- existingVariable.declarations[0].parent.type === CatchClause$1) {
6057
- // If this is a var with the same name as the catch scope parameter,
6058
- // the assignment actually goes to the parameter and the var is
6059
- // hoisted without assignment. Locally, it is shadowed by the
6060
- // parameter
6061
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, kind);
6062
- // To avoid the need to rewrite the declaration, we link the variable
6063
- // names. If we ever implement a logic that splits initialization and
6064
- // assignment for hoisted vars, the "renderLikeHoisted" logic can be
6065
- // removed again.
6066
- // We do not need to check whether there already is a linked
6067
- // variable because then declaredVariable would be that linked
6068
- // variable.
6069
- existingVariable.renderLikeHoisted(declaredVariable);
6070
- this.addHoistedVariable(name, declaredVariable);
6071
- return declaredVariable;
6072
- }
6073
- if (existingKind === 'var') {
6074
- existingVariable.addDeclaration(identifier, init);
6075
- return existingVariable;
6076
- }
6077
- return context.error(logRedeclarationError(name), identifier.start);
6078
- }
6079
- // We only add parameters to parameter scopes
6080
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, kind);
6081
- // Necessary to make sure the init is deoptimized for conditional declarations.
6082
- // We cannot call deoptimizePath here.
6083
- declaredVariable.markInitializersForDeoptimization();
6084
- // We add the variable to this and all parent scopes to reliably detect conflicts
6085
- this.addHoistedVariable(name, declaredVariable);
6086
- return declaredVariable;
6087
- }
6088
- return super.addDeclaration(identifier, context, init, kind);
6089
- }
6090
- }
6091
-
6092
- class FunctionBodyScope extends ChildScope {
6093
- constructor(parent) {
6094
- super(parent, parent.context);
6095
- }
6096
- // There is stuff that is only allowed in function scopes, i.e. functions can
6097
- // be redeclared, functions and var can redeclare each other
6098
- addDeclaration(identifier, context, init, kind) {
6099
- const name = identifier.name;
6100
- const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
6101
- if (existingVariable) {
6102
- const existingKind = existingVariable.kind;
6103
- if ((kind === 'var' || kind === 'function') &&
6104
- (existingKind === 'var' || existingKind === 'function' || existingKind === 'parameter')) {
6105
- existingVariable.addDeclaration(identifier, init);
6106
- return existingVariable;
6107
- }
6108
- context.error(logRedeclarationError(name), identifier.start);
6109
- }
6110
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
6111
- this.variables.set(name, newVariable);
6112
- return newVariable;
6113
- }
6114
- }
6115
-
6116
- class ParameterScope extends ChildScope {
6117
- constructor(parent, isCatchScope) {
6118
- super(parent, parent.context);
6119
- this.parameters = [];
6120
- this.hasRest = false;
6121
- this.bodyScope = isCatchScope ? new CatchBodyScope(this) : new FunctionBodyScope(this);
6122
- }
6123
- /**
6124
- * Adds a parameter to this scope. Parameters must be added in the correct
6125
- * order, i.e. from left to right.
6126
- */
6127
- addParameterDeclaration(identifier) {
6128
- const { name, start } = identifier;
6129
- const existingParameter = this.variables.get(name);
6130
- if (existingParameter) {
6131
- return this.context.error(logDuplicateArgumentNameError(name), start);
6132
- }
6133
- const variable = new ParameterVariable(name, identifier, this.context);
6134
- this.variables.set(name, variable);
6135
- // We also add it to the body scope to detect name conflicts with local
6136
- // variables. We still need the intermediate scope, though, as parameter
6137
- // defaults are NOT taken from the body scope but from the parameters or
6138
- // outside scope.
6139
- this.bodyScope.addHoistedVariable(name, variable);
6140
- return variable;
6141
- }
6142
- addParameterVariables(parameters, hasRest) {
6143
- this.parameters = parameters;
6144
- for (const parameterList of parameters) {
6145
- for (const parameter of parameterList) {
6146
- parameter.alwaysRendered = true;
6147
- }
6148
- }
6149
- this.hasRest = hasRest;
6150
- }
6151
- includeCallArguments(context, parameters) {
6152
- let calledFromTryStatement = false;
6153
- let argumentIncluded = false;
6154
- const restParameter = this.hasRest && this.parameters[this.parameters.length - 1];
6155
- for (const checkedArgument of parameters) {
6156
- if (checkedArgument instanceof SpreadElement) {
6157
- for (const argument of parameters) {
6158
- argument.include(context, false);
6159
- }
6160
- break;
6161
- }
6162
- }
6163
- for (let index = parameters.length - 1; index >= 0; index--) {
6164
- const parameterVariables = this.parameters[index] || restParameter;
6165
- const argument = parameters[index];
6166
- if (parameterVariables) {
6167
- calledFromTryStatement = false;
6168
- if (parameterVariables.length === 0) {
6169
- // handle empty destructuring
6170
- argumentIncluded = true;
6171
- }
6172
- else {
6173
- for (const variable of parameterVariables) {
6174
- if (variable.included) {
6175
- argumentIncluded = true;
6176
- }
6177
- if (variable.calledFromTryStatement) {
6178
- calledFromTryStatement = true;
6179
- }
6180
- }
6181
- }
6182
- }
6183
- if (!argumentIncluded && argument.shouldBeIncluded(context)) {
6184
- argumentIncluded = true;
6185
- }
6186
- if (argumentIncluded) {
6187
- argument.include(context, calledFromTryStatement);
6188
- }
6189
- }
6190
- }
6191
- }
6192
-
6193
- class ReturnValueScope extends ParameterScope {
6194
- constructor() {
6195
- super(...arguments);
6196
- this.returnExpression = null;
6197
- this.returnExpressions = [];
6198
- }
6199
- addReturnExpression(expression) {
6200
- this.returnExpressions.push(expression);
6201
- }
6202
- getReturnExpression() {
6203
- if (this.returnExpression === null)
6204
- this.updateReturnExpression();
6205
- return this.returnExpression;
6206
- }
6207
- updateReturnExpression() {
6208
- if (this.returnExpressions.length === 1) {
6209
- this.returnExpression = this.returnExpressions[0];
6210
- }
6211
- else {
6212
- this.returnExpression = UNKNOWN_EXPRESSION;
6213
- for (const expression of this.returnExpressions) {
6214
- expression.deoptimizePath(UNKNOWN_PATH);
6215
- }
6216
- }
6217
- }
6218
- }
6219
-
6220
- /** @typedef { import('estree').Node} Node */
6221
- /** @typedef {Node | {
6222
- * type: 'PropertyDefinition';
6223
- * computed: boolean;
6224
- * value: Node
6225
- * }} NodeWithPropertyDefinition */
6226
-
6227
- /**
6228
- *
6229
- * @param {NodeWithPropertyDefinition} node
6230
- * @param {NodeWithPropertyDefinition} parent
6231
- * @returns {boolean}
6232
- */
6233
- function is_reference (node, parent) {
6234
- if (node.type === 'MemberExpression') {
6235
- return !node.computed && is_reference(node.object, node);
6236
- }
6237
-
6238
- if (node.type === 'Identifier') {
6239
- if (!parent) return true;
6240
-
6241
- switch (parent.type) {
6242
- // disregard `bar` in `foo.bar`
6243
- case 'MemberExpression': return parent.computed || node === parent.object;
6244
-
6245
- // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
6246
- case 'MethodDefinition': return parent.computed;
6247
-
6248
- // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
6249
- case 'PropertyDefinition': return parent.computed || node === parent.value;
6250
-
6251
- // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
6252
- case 'Property': return parent.computed || node === parent.value;
6253
-
6254
- // disregard the `bar` in `export { foo as bar }` or
6255
- // the foo in `import { foo as bar }`
6256
- case 'ExportSpecifier':
6257
- case 'ImportSpecifier': return node === parent.local;
6258
-
6259
- // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
6260
- case 'LabeledStatement':
6261
- case 'BreakStatement':
6262
- case 'ContinueStatement': return false;
6263
- default: return true;
6264
- }
6265
- }
6266
-
6267
- return false;
6268
- }
6269
-
6270
- const PureFunctionKey = Symbol('PureFunction');
6271
- const getPureFunctions = ({ treeshake }) => {
6272
- const pureFunctions = Object.create(null);
6273
- for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
6274
- let currentFunctions = pureFunctions;
6275
- for (const pathSegment of functionName.split('.')) {
6276
- currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
6277
- }
6278
- currentFunctions[PureFunctionKey] = true;
6279
- }
6280
- return pureFunctions;
6281
- };
6282
-
6283
- const doNothing = () => { };
6284
-
6285
- /* eslint sort-keys: "off" */
6286
- const ValueProperties = Symbol('Value Properties');
6287
- const getTruthyLiteralValue = () => UnknownTruthyValue;
6288
- const returnFalse = () => false;
6289
- const returnTrue = () => true;
6290
- const PURE = {
6291
- deoptimizeArgumentsOnCall: doNothing,
6292
- getLiteralValue: getTruthyLiteralValue,
6293
- hasEffectsWhenCalled: returnFalse
6294
- };
6295
- const IMPURE = {
6296
- deoptimizeArgumentsOnCall: doNothing,
6297
- getLiteralValue: getTruthyLiteralValue,
6298
- hasEffectsWhenCalled: returnTrue
6299
- };
6300
- const PURE_WITH_ARRAY = {
6301
- deoptimizeArgumentsOnCall: doNothing,
6302
- getLiteralValue: getTruthyLiteralValue,
6303
- hasEffectsWhenCalled({ args }) {
6304
- return args.length > 1 && !(args[1] instanceof ArrayExpression);
6305
- }
6306
- };
6307
- const GETTER_ACCESS = {
6308
- deoptimizeArgumentsOnCall: doNothing,
6309
- getLiteralValue: getTruthyLiteralValue,
6310
- hasEffectsWhenCalled({ args }, context) {
6311
- const [_thisArgument, firstArgument] = args;
6312
- return (!(firstArgument instanceof ExpressionEntity) ||
6313
- firstArgument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context));
6314
- }
6315
- };
6316
- // We use shortened variables to reduce file size here
6317
- /* OBJECT */
6318
- const O = {
6319
- __proto__: null,
6320
- [ValueProperties]: IMPURE
6321
- };
6322
- /* PURE FUNCTION */
6323
- const PF = {
6324
- __proto__: null,
6325
- [ValueProperties]: PURE
6326
- };
6327
- /* PURE FUNCTION IF FIRST ARG DOES NOT CONTAIN A GETTER */
6328
- const PF_NO_GETTER = {
6329
- __proto__: null,
6330
- [ValueProperties]: GETTER_ACCESS
6331
- };
6332
- /* FUNCTION THAT MUTATES FIRST ARG WITHOUT TRIGGERING ACCESSORS */
6333
- const MUTATES_ARG_WITHOUT_ACCESSOR = {
6334
- __proto__: null,
6335
- [ValueProperties]: {
6336
- deoptimizeArgumentsOnCall({ args: [, firstArgument] }) {
6337
- firstArgument?.deoptimizePath(UNKNOWN_PATH);
6338
- },
6339
- getLiteralValue: getTruthyLiteralValue,
6340
- hasEffectsWhenCalled({ args }, context) {
6341
- return (args.length <= 1 ||
6342
- args[1].hasEffectsOnInteractionAtPath(UNKNOWN_NON_ACCESSOR_PATH, NODE_INTERACTION_UNKNOWN_ASSIGNMENT, context));
5774
+ };
5775
+ // We use shortened variables to reduce file size here
5776
+ /* OBJECT */
5777
+ const O = {
5778
+ __proto__: null,
5779
+ [ValueProperties]: IMPURE
5780
+ };
5781
+ /* PURE FUNCTION */
5782
+ const PF = {
5783
+ __proto__: null,
5784
+ [ValueProperties]: PURE
5785
+ };
5786
+ /* PURE FUNCTION IF FIRST ARG DOES NOT CONTAIN A GETTER */
5787
+ const PF_NO_GETTER = {
5788
+ __proto__: null,
5789
+ [ValueProperties]: GETTER_ACCESS
5790
+ };
5791
+ /* FUNCTION THAT MUTATES FIRST ARG WITHOUT TRIGGERING ACCESSORS */
5792
+ const MUTATES_ARG_WITHOUT_ACCESSOR = {
5793
+ __proto__: null,
5794
+ [ValueProperties]: {
5795
+ deoptimizeArgumentsOnCall({ args: [, firstArgument] }) {
5796
+ firstArgument?.deoptimizePath(UNKNOWN_PATH);
5797
+ },
5798
+ getLiteralValue: getTruthyLiteralValue,
5799
+ hasEffectsWhenCalled({ args }, context) {
5800
+ return (args.length <= 1 ||
5801
+ args[1].hasEffectsOnInteractionAtPath(UNKNOWN_NON_ACCESSOR_PATH, NODE_INTERACTION_UNKNOWN_ASSIGNMENT, context));
6343
5802
  }
6344
5803
  }
6345
5804
  };
@@ -7217,290 +6676,940 @@ const knownGlobals = {
7217
6676
  for (const global of ['window', 'global', 'self', 'globalThis']) {
7218
6677
  knownGlobals[global] = knownGlobals;
7219
6678
  }
7220
- function getGlobalAtPath(path) {
7221
- let currentGlobal = knownGlobals;
7222
- for (const pathSegment of path) {
7223
- if (typeof pathSegment !== 'string') {
6679
+ function getGlobalAtPath(path) {
6680
+ let currentGlobal = knownGlobals;
6681
+ for (const pathSegment of path) {
6682
+ if (typeof pathSegment !== 'string') {
6683
+ return null;
6684
+ }
6685
+ currentGlobal = currentGlobal[pathSegment];
6686
+ if (!currentGlobal) {
6687
+ return null;
6688
+ }
6689
+ }
6690
+ return currentGlobal[ValueProperties];
6691
+ }
6692
+
6693
+ class GlobalVariable extends Variable {
6694
+ constructor(name) {
6695
+ super(name);
6696
+ // Ensure we use live-bindings for globals as we do not know if they have
6697
+ // been reassigned
6698
+ this.markReassigned();
6699
+ }
6700
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6701
+ switch (interaction.type) {
6702
+ // While there is no point in testing these cases as at the moment, they
6703
+ // are also covered via other means, we keep them for completeness
6704
+ case INTERACTION_ACCESSED:
6705
+ case INTERACTION_ASSIGNED: {
6706
+ if (!getGlobalAtPath([this.name, ...path].slice(0, -1))) {
6707
+ super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
6708
+ }
6709
+ return;
6710
+ }
6711
+ case INTERACTION_CALLED: {
6712
+ const globalAtPath = getGlobalAtPath([this.name, ...path]);
6713
+ if (globalAtPath) {
6714
+ globalAtPath.deoptimizeArgumentsOnCall(interaction);
6715
+ }
6716
+ else {
6717
+ super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
6718
+ }
6719
+ return;
6720
+ }
6721
+ }
6722
+ }
6723
+ getLiteralValueAtPath(path, _recursionTracker, _origin) {
6724
+ const globalAtPath = getGlobalAtPath([this.name, ...path]);
6725
+ return globalAtPath ? globalAtPath.getLiteralValue() : UnknownValue;
6726
+ }
6727
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
6728
+ switch (interaction.type) {
6729
+ case INTERACTION_ACCESSED: {
6730
+ if (path.length === 0) {
6731
+ // Technically, "undefined" is a global variable of sorts
6732
+ return this.name !== 'undefined' && !getGlobalAtPath([this.name]);
6733
+ }
6734
+ return !getGlobalAtPath([this.name, ...path].slice(0, -1));
6735
+ }
6736
+ case INTERACTION_ASSIGNED: {
6737
+ return true;
6738
+ }
6739
+ case INTERACTION_CALLED: {
6740
+ const globalAtPath = getGlobalAtPath([this.name, ...path]);
6741
+ return !globalAtPath || globalAtPath.hasEffectsWhenCalled(interaction, context);
6742
+ }
6743
+ }
6744
+ }
6745
+ }
6746
+
6747
+ class LocalVariable extends Variable {
6748
+ constructor(name, declarator, init, context, kind) {
6749
+ super(name);
6750
+ this.init = init;
6751
+ this.calledFromTryStatement = false;
6752
+ this.additionalInitializers = null;
6753
+ this.expressionsToBeDeoptimized = [];
6754
+ this.declarations = declarator ? [declarator] : [];
6755
+ this.deoptimizationTracker = context.deoptimizationTracker;
6756
+ this.module = context.module;
6757
+ this.kind = kind;
6758
+ }
6759
+ addDeclaration(identifier, init) {
6760
+ this.declarations.push(identifier);
6761
+ this.markInitializersForDeoptimization().push(init);
6762
+ }
6763
+ consolidateInitializers() {
6764
+ if (this.additionalInitializers) {
6765
+ for (const initializer of this.additionalInitializers) {
6766
+ initializer.deoptimizePath(UNKNOWN_PATH);
6767
+ }
6768
+ this.additionalInitializers = null;
6769
+ }
6770
+ }
6771
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6772
+ if (this.isReassigned) {
6773
+ deoptimizeInteraction(interaction);
6774
+ return;
6775
+ }
6776
+ recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker), undefined);
6777
+ }
6778
+ deoptimizePath(path) {
6779
+ if (this.isReassigned ||
6780
+ this.deoptimizationTracker.trackEntityAtPathAndGetIfTracked(path, this)) {
6781
+ return;
6782
+ }
6783
+ if (path.length === 0) {
6784
+ this.markReassigned();
6785
+ const expressionsToBeDeoptimized = this.expressionsToBeDeoptimized;
6786
+ this.expressionsToBeDeoptimized = EMPTY_ARRAY;
6787
+ for (const expression of expressionsToBeDeoptimized) {
6788
+ expression.deoptimizeCache();
6789
+ }
6790
+ this.init.deoptimizePath(UNKNOWN_PATH);
6791
+ }
6792
+ else {
6793
+ this.init.deoptimizePath(path);
6794
+ }
6795
+ }
6796
+ getLiteralValueAtPath(path, recursionTracker, origin) {
6797
+ if (this.isReassigned) {
6798
+ return UnknownValue;
6799
+ }
6800
+ return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
6801
+ this.expressionsToBeDeoptimized.push(origin);
6802
+ return this.init.getLiteralValueAtPath(path, recursionTracker, origin);
6803
+ }, UnknownValue);
6804
+ }
6805
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
6806
+ if (this.isReassigned) {
6807
+ return UNKNOWN_RETURN_EXPRESSION;
6808
+ }
6809
+ return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
6810
+ this.expressionsToBeDeoptimized.push(origin);
6811
+ return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
6812
+ }, UNKNOWN_RETURN_EXPRESSION);
6813
+ }
6814
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
6815
+ switch (interaction.type) {
6816
+ case INTERACTION_ACCESSED: {
6817
+ if (this.isReassigned)
6818
+ return true;
6819
+ return (!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
6820
+ this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
6821
+ }
6822
+ case INTERACTION_ASSIGNED: {
6823
+ if (this.included)
6824
+ return true;
6825
+ if (path.length === 0)
6826
+ return false;
6827
+ if (this.isReassigned)
6828
+ return true;
6829
+ return (!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
6830
+ this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
6831
+ }
6832
+ case INTERACTION_CALLED: {
6833
+ if (this.isReassigned)
6834
+ return true;
6835
+ return (!(interaction.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this) &&
6836
+ this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
6837
+ }
6838
+ }
6839
+ }
6840
+ include() {
6841
+ if (!this.included) {
6842
+ super.include();
6843
+ for (const declaration of this.declarations) {
6844
+ // If node is a default export, it can save a tree-shaking run to include the full declaration now
6845
+ if (!declaration.included)
6846
+ declaration.include(createInclusionContext(), false);
6847
+ let node = declaration.parent;
6848
+ while (!node.included) {
6849
+ // We do not want to properly include parents in case they are part of a dead branch
6850
+ // in which case .include() might pull in more dead code
6851
+ node.included = true;
6852
+ if (node.type === Program$1)
6853
+ break;
6854
+ node = node.parent;
6855
+ }
6856
+ }
6857
+ }
6858
+ }
6859
+ includeCallArguments(context, parameters) {
6860
+ if (this.isReassigned || context.includedCallArguments.has(this.init)) {
6861
+ for (const argument of parameters) {
6862
+ argument.include(context, false);
6863
+ }
6864
+ }
6865
+ else {
6866
+ context.includedCallArguments.add(this.init);
6867
+ this.init.includeCallArguments(context, parameters);
6868
+ context.includedCallArguments.delete(this.init);
6869
+ }
6870
+ }
6871
+ markCalledFromTryStatement() {
6872
+ this.calledFromTryStatement = true;
6873
+ }
6874
+ markInitializersForDeoptimization() {
6875
+ if (this.additionalInitializers === null) {
6876
+ this.additionalInitializers = [this.init];
6877
+ this.init = UNKNOWN_EXPRESSION;
6878
+ this.markReassigned();
6879
+ }
6880
+ return this.additionalInitializers;
6881
+ }
6882
+ }
6883
+
6884
+ const tdzVariableKinds = new Set(['class', 'const', 'let', 'var', 'using', 'await using']);
6885
+ class Identifier extends NodeBase {
6886
+ constructor() {
6887
+ super(...arguments);
6888
+ this.variable = null;
6889
+ this.isReferenceVariable = false;
6890
+ }
6891
+ get isTDZAccess() {
6892
+ if (!isFlagSet(this.flags, 4 /* Flag.tdzAccessDefined */)) {
7224
6893
  return null;
7225
6894
  }
7226
- currentGlobal = currentGlobal[pathSegment];
7227
- if (!currentGlobal) {
7228
- return null;
6895
+ return isFlagSet(this.flags, 8 /* Flag.tdzAccess */);
6896
+ }
6897
+ set isTDZAccess(value) {
6898
+ this.flags = setFlag(this.flags, 4 /* Flag.tdzAccessDefined */, true);
6899
+ this.flags = setFlag(this.flags, 8 /* Flag.tdzAccess */, value);
6900
+ }
6901
+ addExportedVariables(variables, exportNamesByVariable) {
6902
+ if (exportNamesByVariable.has(this.variable)) {
6903
+ variables.push(this.variable);
6904
+ }
6905
+ }
6906
+ bind() {
6907
+ if (!this.variable && is_reference(this, this.parent)) {
6908
+ this.variable = this.scope.findVariable(this.name);
6909
+ this.variable.addReference(this);
6910
+ this.isReferenceVariable = true;
6911
+ }
6912
+ }
6913
+ declare(kind, init) {
6914
+ let variable;
6915
+ const { treeshake } = this.scope.context.options;
6916
+ switch (kind) {
6917
+ case 'var': {
6918
+ variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
6919
+ if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
6920
+ // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
6921
+ variable.markInitializersForDeoptimization();
6922
+ }
6923
+ break;
6924
+ }
6925
+ case 'function': {
6926
+ // in strict mode, functions are only hoisted within a scope but not across block scopes
6927
+ variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
6928
+ break;
6929
+ }
6930
+ case 'let':
6931
+ case 'const':
6932
+ case 'using':
6933
+ case 'await using':
6934
+ case 'class': {
6935
+ variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
6936
+ break;
6937
+ }
6938
+ case 'parameter': {
6939
+ variable = this.scope.addParameterDeclaration(this);
6940
+ break;
6941
+ }
6942
+ /* istanbul ignore next */
6943
+ default: {
6944
+ /* istanbul ignore next */
6945
+ throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
6946
+ }
6947
+ }
6948
+ return [(this.variable = variable)];
6949
+ }
6950
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6951
+ this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
6952
+ }
6953
+ deoptimizePath(path) {
6954
+ if (path.length === 0 && !this.scope.contains(this.name)) {
6955
+ this.disallowImportReassignment();
6956
+ }
6957
+ // We keep conditional chaining because an unknown Node could have an
6958
+ // Identifier as property that might be deoptimized by default
6959
+ this.variable?.deoptimizePath(path);
6960
+ }
6961
+ getLiteralValueAtPath(path, recursionTracker, origin) {
6962
+ return this.getVariableRespectingTDZ().getLiteralValueAtPath(path, recursionTracker, origin);
6963
+ }
6964
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
6965
+ const [expression, isPure] = this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
6966
+ return [expression, isPure || this.isPureFunction(path)];
6967
+ }
6968
+ hasEffects(context) {
6969
+ if (!this.deoptimized)
6970
+ this.applyDeoptimizations();
6971
+ if (this.isPossibleTDZ() && this.variable.kind !== 'var') {
6972
+ return true;
6973
+ }
6974
+ return (this.scope.context.options.treeshake
6975
+ .unknownGlobalSideEffects &&
6976
+ this.variable instanceof GlobalVariable &&
6977
+ !this.isPureFunction(EMPTY_PATH) &&
6978
+ this.variable.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context));
6979
+ }
6980
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
6981
+ switch (interaction.type) {
6982
+ case INTERACTION_ACCESSED: {
6983
+ return (this.variable !== null &&
6984
+ !this.isPureFunction(path) &&
6985
+ this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));
6986
+ }
6987
+ case INTERACTION_ASSIGNED: {
6988
+ return (path.length > 0 ? this.getVariableRespectingTDZ() : this.variable).hasEffectsOnInteractionAtPath(path, interaction, context);
6989
+ }
6990
+ case INTERACTION_CALLED: {
6991
+ return (!this.isPureFunction(path) &&
6992
+ this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));
6993
+ }
6994
+ }
6995
+ }
6996
+ include() {
6997
+ if (!this.deoptimized)
6998
+ this.applyDeoptimizations();
6999
+ if (!this.included) {
7000
+ this.included = true;
7001
+ if (this.variable !== null) {
7002
+ this.scope.context.includeVariableInModule(this.variable);
7003
+ }
7004
+ }
7005
+ }
7006
+ includeCallArguments(context, parameters) {
7007
+ this.variable.includeCallArguments(context, parameters);
7008
+ }
7009
+ isPossibleTDZ() {
7010
+ // return cached value to avoid issues with the next tree-shaking pass
7011
+ const cachedTdzAccess = this.isTDZAccess;
7012
+ if (cachedTdzAccess !== null)
7013
+ return cachedTdzAccess;
7014
+ if (!(this.variable instanceof LocalVariable &&
7015
+ this.variable.kind &&
7016
+ tdzVariableKinds.has(this.variable.kind) &&
7017
+ // we ignore possible TDZs due to circular module dependencies as
7018
+ // otherwise we get many false positives
7019
+ this.variable.module === this.scope.context.module)) {
7020
+ return (this.isTDZAccess = false);
7021
+ }
7022
+ let decl_id;
7023
+ if (this.variable.declarations &&
7024
+ this.variable.declarations.length === 1 &&
7025
+ (decl_id = this.variable.declarations[0]) &&
7026
+ this.start < decl_id.start &&
7027
+ closestParentFunctionOrProgram(this) === closestParentFunctionOrProgram(decl_id)) {
7028
+ // a variable accessed before its declaration
7029
+ // in the same function or at top level of module
7030
+ return (this.isTDZAccess = true);
7031
+ }
7032
+ // We ignore the case where the module is not yet executed because
7033
+ // moduleSideEffects are false.
7034
+ if (!this.variable.initReached && this.scope.context.module.isExecuted) {
7035
+ // Either a const/let TDZ violation or
7036
+ // var use before declaration was encountered.
7037
+ return (this.isTDZAccess = true);
7229
7038
  }
7039
+ return (this.isTDZAccess = false);
7230
7040
  }
7231
- return currentGlobal[ValueProperties];
7232
- }
7233
-
7234
- class GlobalVariable extends Variable {
7235
- constructor() {
7236
- super(...arguments);
7237
- // Ensure we use live-bindings for globals as we do not know if they have
7238
- // been reassigned
7239
- this.isReassigned = true;
7041
+ markDeclarationReached() {
7042
+ this.variable.initReached = true;
7240
7043
  }
7241
- deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
7242
- switch (interaction.type) {
7243
- // While there is no point in testing these cases as at the moment, they
7244
- // are also covered via other means, we keep them for completeness
7245
- case INTERACTION_ACCESSED:
7246
- case INTERACTION_ASSIGNED: {
7247
- if (!getGlobalAtPath([this.name, ...path].slice(0, -1))) {
7248
- super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
7044
+ render(code, { snippets: { getPropertyAccess }, useOriginalName }, { renderedParentType, isCalleeOfRenderedParent, isShorthandProperty } = BLANK) {
7045
+ if (this.variable) {
7046
+ const name = this.variable.getName(getPropertyAccess, useOriginalName);
7047
+ if (name !== this.name) {
7048
+ code.overwrite(this.start, this.end, name, {
7049
+ contentOnly: true,
7050
+ storeName: true
7051
+ });
7052
+ if (isShorthandProperty) {
7053
+ code.prependRight(this.start, `${this.name}: `);
7249
7054
  }
7250
- return;
7251
7055
  }
7252
- case INTERACTION_CALLED: {
7253
- const globalAtPath = getGlobalAtPath([this.name, ...path]);
7254
- if (globalAtPath) {
7255
- globalAtPath.deoptimizeArgumentsOnCall(interaction);
7256
- }
7257
- else {
7258
- super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
7056
+ // In strict mode, any variable named "eval" must be the actual "eval" function
7057
+ if (name === 'eval' &&
7058
+ renderedParentType === CallExpression$1 &&
7059
+ isCalleeOfRenderedParent) {
7060
+ code.appendRight(this.start, '0, ');
7061
+ }
7062
+ }
7063
+ }
7064
+ disallowImportReassignment() {
7065
+ return this.scope.context.error(logIllegalImportReassignment(this.name, this.scope.context.module.id), this.start);
7066
+ }
7067
+ applyDeoptimizations() {
7068
+ this.deoptimized = true;
7069
+ if (this.variable instanceof LocalVariable) {
7070
+ this.variable.consolidateInitializers();
7071
+ this.scope.context.requestTreeshakingPass();
7072
+ }
7073
+ if (this.isReferenceVariable) {
7074
+ this.variable.addUsedPlace(this);
7075
+ this.scope.context.requestTreeshakingPass();
7076
+ }
7077
+ }
7078
+ getVariableRespectingTDZ() {
7079
+ if (this.isPossibleTDZ()) {
7080
+ return UNKNOWN_EXPRESSION;
7081
+ }
7082
+ return this.variable;
7083
+ }
7084
+ isPureFunction(path) {
7085
+ let currentPureFunction = this.scope.context.manualPureFunctions[this.name];
7086
+ for (const segment of path) {
7087
+ if (currentPureFunction) {
7088
+ if (currentPureFunction[PureFunctionKey]) {
7089
+ return true;
7259
7090
  }
7260
- return;
7091
+ currentPureFunction = currentPureFunction[segment];
7092
+ }
7093
+ else {
7094
+ return false;
7261
7095
  }
7262
7096
  }
7097
+ return currentPureFunction?.[PureFunctionKey];
7263
7098
  }
7264
- getLiteralValueAtPath(path, _recursionTracker, _origin) {
7265
- const globalAtPath = getGlobalAtPath([this.name, ...path]);
7266
- return globalAtPath ? globalAtPath.getLiteralValue() : UnknownValue;
7099
+ }
7100
+ function closestParentFunctionOrProgram(node) {
7101
+ while (node && !/^Program|Function/.test(node.type)) {
7102
+ node = node.parent;
7267
7103
  }
7268
- hasEffectsOnInteractionAtPath(path, interaction, context) {
7269
- switch (interaction.type) {
7270
- case INTERACTION_ACCESSED: {
7271
- if (path.length === 0) {
7272
- // Technically, "undefined" is a global variable of sorts
7273
- return this.name !== 'undefined' && !getGlobalAtPath([this.name]);
7104
+ // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program
7105
+ return node;
7106
+ }
7107
+
7108
+ const MAX_TRACKED_INTERACTIONS = 20;
7109
+ const NO_INTERACTIONS = EMPTY_ARRAY;
7110
+ const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);
7111
+ const EMPTY_PATH_TRACKER = new PathTracker();
7112
+ const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);
7113
+ class ParameterVariable extends LocalVariable {
7114
+ constructor(name, declarator, context) {
7115
+ super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');
7116
+ this.deoptimizationInteractions = [];
7117
+ this.deoptimizations = new PathTracker();
7118
+ this.deoptimizedFields = new Set();
7119
+ this.entitiesToBeDeoptimized = new Set();
7120
+ this.expressionsUseTheKnownValue = [];
7121
+ this.knownValue = null;
7122
+ this.knownValueLiteral = UnknownValue;
7123
+ this.frozenValue = null;
7124
+ }
7125
+ addEntityToBeDeoptimized(entity) {
7126
+ if (entity === UNKNOWN_EXPRESSION) {
7127
+ // As unknown expressions fully deoptimize all interactions, we can clear
7128
+ // the interaction cache at this point provided we keep this optimization
7129
+ // in mind when adding new interactions
7130
+ if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7131
+ this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);
7132
+ for (const { interaction } of this.deoptimizationInteractions) {
7133
+ deoptimizeInteraction(interaction);
7274
7134
  }
7275
- return !getGlobalAtPath([this.name, ...path].slice(0, -1));
7135
+ this.deoptimizationInteractions = NO_INTERACTIONS;
7276
7136
  }
7277
- case INTERACTION_ASSIGNED: {
7278
- return true;
7137
+ }
7138
+ else if (this.deoptimizedFields.has(UnknownKey)) {
7139
+ // This means that we already deoptimized all interactions and no longer
7140
+ // track them
7141
+ entity.deoptimizePath(UNKNOWN_PATH);
7142
+ }
7143
+ else if (!this.entitiesToBeDeoptimized.has(entity)) {
7144
+ this.entitiesToBeDeoptimized.add(entity);
7145
+ for (const field of this.deoptimizedFields) {
7146
+ entity.deoptimizePath([field]);
7279
7147
  }
7280
- case INTERACTION_CALLED: {
7281
- const globalAtPath = getGlobalAtPath([this.name, ...path]);
7282
- return !globalAtPath || globalAtPath.hasEffectsWhenCalled(interaction, context);
7148
+ for (const { interaction, path } of this.deoptimizationInteractions) {
7149
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
7150
+ }
7151
+ }
7152
+ }
7153
+ markReassigned() {
7154
+ if (this.isReassigned) {
7155
+ return;
7156
+ }
7157
+ super.markReassigned();
7158
+ for (const expression of this.expressionsUseTheKnownValue) {
7159
+ expression.deoptimizeCache();
7160
+ }
7161
+ this.expressionsUseTheKnownValue = EMPTY_ARRAY;
7162
+ }
7163
+ deoptimizeCache() {
7164
+ this.markReassigned();
7165
+ }
7166
+ /**
7167
+ * Update the known value of the parameter variable.
7168
+ * Must be called for every function call, so it can track all the arguments,
7169
+ * and deoptimizeCache itself to mark reassigned if the argument is changed.
7170
+ * @param argument The argument of the function call
7171
+ */
7172
+ updateKnownValue(argument) {
7173
+ if (this.isReassigned) {
7174
+ return;
7175
+ }
7176
+ if (this.knownValue === null) {
7177
+ this.knownValue = argument;
7178
+ this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
7179
+ return;
7180
+ }
7181
+ // the same literal or identifier, do nothing
7182
+ if (this.knownValue === argument ||
7183
+ (this.knownValue instanceof Identifier &&
7184
+ argument instanceof Identifier &&
7185
+ this.knownValue.variable === argument.variable)) {
7186
+ return;
7187
+ }
7188
+ const oldValue = this.knownValueLiteral;
7189
+ if (typeof oldValue === 'symbol') {
7190
+ this.markReassigned();
7191
+ return;
7192
+ }
7193
+ // add tracking for the new argument
7194
+ const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
7195
+ if (newValue !== oldValue) {
7196
+ this.markReassigned();
7197
+ }
7198
+ }
7199
+ /**
7200
+ * This function freezes the known value of the parameter variable,
7201
+ * so the optimization starts with a certain ExpressionEntity.
7202
+ * The optimization can be undone by calling `markReassigned`.
7203
+ * @returns the frozen value
7204
+ */
7205
+ getKnownValue() {
7206
+ if (this.frozenValue === null) {
7207
+ this.frozenValue = this.knownValue || UNKNOWN_EXPRESSION;
7208
+ }
7209
+ return this.frozenValue;
7210
+ }
7211
+ getLiteralValueAtPath(path, recursionTracker, origin) {
7212
+ if (this.isReassigned) {
7213
+ return UnknownValue;
7214
+ }
7215
+ const knownValue = this.getKnownValue();
7216
+ this.expressionsUseTheKnownValue.push(origin);
7217
+ return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);
7218
+ }
7219
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
7220
+ if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) {
7221
+ return super.hasEffectsOnInteractionAtPath(path, interaction, context);
7222
+ }
7223
+ const knownValue = this.getKnownValue();
7224
+ return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context);
7225
+ }
7226
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path) {
7227
+ // For performance reasons, we fully deoptimize all deeper interactions
7228
+ if (path.length >= 2 ||
7229
+ this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
7230
+ this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||
7231
+ (path.length === 1 &&
7232
+ (this.deoptimizedFields.has(UnknownKey) ||
7233
+ (interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0]))))) {
7234
+ deoptimizeInteraction(interaction);
7235
+ return;
7236
+ }
7237
+ if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {
7238
+ for (const entity of this.entitiesToBeDeoptimized) {
7239
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
7283
7240
  }
7241
+ if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7242
+ this.deoptimizationInteractions.push({
7243
+ interaction,
7244
+ path
7245
+ });
7246
+ }
7247
+ }
7248
+ }
7249
+ deoptimizePath(path) {
7250
+ if (path.length === 0) {
7251
+ this.markReassigned();
7252
+ return;
7253
+ }
7254
+ if (this.deoptimizedFields.has(UnknownKey)) {
7255
+ return;
7256
+ }
7257
+ const key = path[0];
7258
+ if (this.deoptimizedFields.has(key)) {
7259
+ return;
7260
+ }
7261
+ this.deoptimizedFields.add(key);
7262
+ for (const entity of this.entitiesToBeDeoptimized) {
7263
+ // We do not need a recursion tracker here as we already track whether
7264
+ // this field is deoptimized
7265
+ entity.deoptimizePath([key]);
7266
+ }
7267
+ if (key === UnknownKey) {
7268
+ // save some memory
7269
+ this.deoptimizationInteractions = NO_INTERACTIONS;
7270
+ this.deoptimizations = EMPTY_PATH_TRACKER;
7271
+ this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;
7272
+ this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
7273
+ }
7274
+ }
7275
+ getReturnExpressionWhenCalledAtPath(path) {
7276
+ // We deoptimize everything that is called as that will trivially deoptimize
7277
+ // the corresponding return expressions as well and avoid badly performing
7278
+ // and complicated alternatives
7279
+ if (path.length === 0) {
7280
+ this.deoptimizePath(UNKNOWN_PATH);
7281
+ }
7282
+ else if (!this.deoptimizedFields.has(path[0])) {
7283
+ this.deoptimizePath([path[0]]);
7284
7284
  }
7285
+ return UNKNOWN_RETURN_EXPRESSION;
7285
7286
  }
7286
7287
  }
7287
7288
 
7288
- const tdzVariableKinds = new Set(['class', 'const', 'let', 'var', 'using', 'await using']);
7289
- class Identifier extends NodeBase {
7289
+ const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$';
7290
+ const base = 64;
7291
+ function toBase64(value) {
7292
+ let outString = '';
7293
+ do {
7294
+ const currentDigit = value % base;
7295
+ value = (value / base) | 0;
7296
+ outString = chars[currentDigit] + outString;
7297
+ } while (value !== 0);
7298
+ return outString;
7299
+ }
7300
+
7301
+ function getSafeName(baseName, usedNames, forbiddenNames) {
7302
+ let safeName = baseName;
7303
+ let count = 1;
7304
+ while (usedNames.has(safeName) || RESERVED_NAMES.has(safeName) || forbiddenNames?.has(safeName)) {
7305
+ safeName = `${baseName}$${toBase64(count++)}`;
7306
+ }
7307
+ usedNames.add(safeName);
7308
+ return safeName;
7309
+ }
7310
+
7311
+ class Scope {
7290
7312
  constructor() {
7291
- super(...arguments);
7292
- this.variable = null;
7313
+ this.children = [];
7314
+ this.variables = new Map();
7293
7315
  }
7294
- get isTDZAccess() {
7295
- if (!isFlagSet(this.flags, 4 /* Flag.tdzAccessDefined */)) {
7296
- return null;
7316
+ /*
7317
+ Redeclaration rules:
7318
+ - var can redeclare var
7319
+ - in function scopes, function and var can redeclare function and var
7320
+ - var is hoisted across scopes, function remains in the scope it is declared
7321
+ - var and function can redeclare function parameters, but parameters cannot redeclare parameters
7322
+ - function cannot redeclare catch scope parameters
7323
+ - var can redeclare catch scope parameters in a way
7324
+ - if the parameter is an identifier and not a pattern
7325
+ - then the variable is still declared in the hoisted outer scope, but the initializer is assigned to the parameter
7326
+ - const, let, class, and function except in the cases above cannot redeclare anything
7327
+ */
7328
+ addDeclaration(identifier, context, init, kind) {
7329
+ const name = identifier.name;
7330
+ const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
7331
+ if (existingVariable) {
7332
+ const existingKind = existingVariable.kind;
7333
+ if (kind === 'var' && existingKind === 'var') {
7334
+ existingVariable.addDeclaration(identifier, init);
7335
+ return existingVariable;
7336
+ }
7337
+ context.error(logRedeclarationError(name), identifier.start);
7297
7338
  }
7298
- return isFlagSet(this.flags, 8 /* Flag.tdzAccess */);
7339
+ const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
7340
+ this.variables.set(name, newVariable);
7341
+ return newVariable;
7299
7342
  }
7300
- set isTDZAccess(value) {
7301
- this.flags = setFlag(this.flags, 4 /* Flag.tdzAccessDefined */, true);
7302
- this.flags = setFlag(this.flags, 8 /* Flag.tdzAccess */, value);
7343
+ addHoistedVariable(name, variable) {
7344
+ (this.hoistedVariables ||= new Map()).set(name, variable);
7303
7345
  }
7304
- addExportedVariables(variables, exportNamesByVariable) {
7305
- if (exportNamesByVariable.has(this.variable)) {
7306
- variables.push(this.variable);
7346
+ contains(name) {
7347
+ return this.variables.has(name);
7348
+ }
7349
+ findVariable(_name) {
7350
+ /* istanbul ignore next */
7351
+ throw new Error('Internal Error: findVariable needs to be implemented by a subclass');
7352
+ }
7353
+ }
7354
+
7355
+ class ChildScope extends Scope {
7356
+ constructor(parent, context) {
7357
+ super();
7358
+ this.parent = parent;
7359
+ this.context = context;
7360
+ this.accessedOutsideVariables = new Map();
7361
+ parent.children.push(this);
7362
+ }
7363
+ addAccessedDynamicImport(importExpression) {
7364
+ (this.accessedDynamicImports || (this.accessedDynamicImports = new Set())).add(importExpression);
7365
+ if (this.parent instanceof ChildScope) {
7366
+ this.parent.addAccessedDynamicImport(importExpression);
7307
7367
  }
7308
7368
  }
7309
- bind() {
7310
- if (!this.variable && is_reference(this, this.parent)) {
7311
- this.variable = this.scope.findVariable(this.name);
7312
- this.variable.addReference(this);
7369
+ addAccessedGlobals(globals, accessedGlobalsByScope) {
7370
+ const accessedGlobals = accessedGlobalsByScope.get(this) || new Set();
7371
+ for (const name of globals) {
7372
+ accessedGlobals.add(name);
7373
+ }
7374
+ accessedGlobalsByScope.set(this, accessedGlobals);
7375
+ if (this.parent instanceof ChildScope) {
7376
+ this.parent.addAccessedGlobals(globals, accessedGlobalsByScope);
7313
7377
  }
7314
7378
  }
7315
- declare(kind, init) {
7316
- let variable;
7317
- const { treeshake } = this.scope.context.options;
7318
- switch (kind) {
7319
- case 'var': {
7320
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
7321
- if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
7322
- // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
7323
- variable.markInitializersForDeoptimization();
7379
+ addNamespaceMemberAccess(name, variable) {
7380
+ this.accessedOutsideVariables.set(name, variable);
7381
+ this.parent.addNamespaceMemberAccess(name, variable);
7382
+ }
7383
+ addReturnExpression(expression) {
7384
+ this.parent instanceof ChildScope && this.parent.addReturnExpression(expression);
7385
+ }
7386
+ addUsedOutsideNames(usedNames, format, exportNamesByVariable, accessedGlobalsByScope) {
7387
+ for (const variable of this.accessedOutsideVariables.values()) {
7388
+ if (variable.included) {
7389
+ usedNames.add(variable.getBaseVariableName());
7390
+ if (format === 'system' && exportNamesByVariable.has(variable)) {
7391
+ usedNames.add('exports');
7324
7392
  }
7325
- break;
7326
- }
7327
- case 'function': {
7328
- // in strict mode, functions are only hoisted within a scope but not across block scopes
7329
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
7330
- break;
7331
- }
7332
- case 'let':
7333
- case 'const':
7334
- case 'using':
7335
- case 'await using':
7336
- case 'class': {
7337
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
7338
- break;
7339
- }
7340
- case 'parameter': {
7341
- variable = this.scope.addParameterDeclaration(this);
7342
- break;
7343
7393
  }
7344
- /* istanbul ignore next */
7345
- default: {
7346
- /* istanbul ignore next */
7347
- throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
7394
+ }
7395
+ const accessedGlobals = accessedGlobalsByScope.get(this);
7396
+ if (accessedGlobals) {
7397
+ for (const name of accessedGlobals) {
7398
+ usedNames.add(name);
7348
7399
  }
7349
7400
  }
7350
- return [(this.variable = variable)];
7351
7401
  }
7352
- deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
7353
- this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
7402
+ contains(name) {
7403
+ return this.variables.has(name) || this.parent.contains(name);
7354
7404
  }
7355
- deoptimizePath(path) {
7356
- if (path.length === 0 && !this.scope.contains(this.name)) {
7357
- this.disallowImportReassignment();
7405
+ deconflict(format, exportNamesByVariable, accessedGlobalsByScope) {
7406
+ const usedNames = new Set();
7407
+ this.addUsedOutsideNames(usedNames, format, exportNamesByVariable, accessedGlobalsByScope);
7408
+ if (this.accessedDynamicImports) {
7409
+ for (const importExpression of this.accessedDynamicImports) {
7410
+ if (importExpression.inlineNamespace) {
7411
+ usedNames.add(importExpression.inlineNamespace.getBaseVariableName());
7412
+ }
7413
+ }
7414
+ }
7415
+ for (const [name, variable] of this.variables) {
7416
+ if (variable.included || variable.alwaysRendered) {
7417
+ variable.setRenderNames(null, getSafeName(name, usedNames, variable.forbiddenNames));
7418
+ }
7419
+ }
7420
+ for (const scope of this.children) {
7421
+ scope.deconflict(format, exportNamesByVariable, accessedGlobalsByScope);
7358
7422
  }
7359
- // We keep conditional chaining because an unknown Node could have an
7360
- // Identifier as property that might be deoptimized by default
7361
- this.variable?.deoptimizePath(path);
7362
- }
7363
- getLiteralValueAtPath(path, recursionTracker, origin) {
7364
- return this.getVariableRespectingTDZ().getLiteralValueAtPath(path, recursionTracker, origin);
7365
7423
  }
7366
- getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
7367
- const [expression, isPure] = this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
7368
- return [expression, isPure || this.isPureFunction(path)];
7424
+ findLexicalBoundary() {
7425
+ return this.parent.findLexicalBoundary();
7369
7426
  }
7370
- hasEffects(context) {
7371
- if (!this.deoptimized)
7372
- this.applyDeoptimizations();
7373
- if (this.isPossibleTDZ() && this.variable.kind !== 'var') {
7374
- return true;
7427
+ findVariable(name) {
7428
+ const knownVariable = this.variables.get(name) || this.accessedOutsideVariables.get(name);
7429
+ if (knownVariable) {
7430
+ return knownVariable;
7375
7431
  }
7376
- return (this.scope.context.options.treeshake
7377
- .unknownGlobalSideEffects &&
7378
- this.variable instanceof GlobalVariable &&
7379
- !this.isPureFunction(EMPTY_PATH) &&
7380
- this.variable.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context));
7432
+ const variable = this.parent.findVariable(name);
7433
+ this.accessedOutsideVariables.set(name, variable);
7434
+ return variable;
7381
7435
  }
7382
- hasEffectsOnInteractionAtPath(path, interaction, context) {
7383
- switch (interaction.type) {
7384
- case INTERACTION_ACCESSED: {
7385
- return (this.variable !== null &&
7386
- !this.isPureFunction(path) &&
7387
- this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));
7388
- }
7389
- case INTERACTION_ASSIGNED: {
7390
- return (path.length > 0 ? this.getVariableRespectingTDZ() : this.variable).hasEffectsOnInteractionAtPath(path, interaction, context);
7391
- }
7392
- case INTERACTION_CALLED: {
7393
- return (!this.isPureFunction(path) &&
7394
- this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));
7436
+ }
7437
+
7438
+ class CatchBodyScope extends ChildScope {
7439
+ constructor(parent) {
7440
+ super(parent, parent.context);
7441
+ this.parent = parent;
7442
+ }
7443
+ addDeclaration(identifier, context, init, kind) {
7444
+ if (kind === 'var') {
7445
+ const name = identifier.name;
7446
+ const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
7447
+ if (existingVariable) {
7448
+ const existingKind = existingVariable.kind;
7449
+ if (existingKind === 'parameter' &&
7450
+ // If this is a destructured parameter, it is forbidden to redeclare
7451
+ existingVariable.declarations[0].parent.type === CatchClause$1) {
7452
+ // If this is a var with the same name as the catch scope parameter,
7453
+ // the assignment actually goes to the parameter and the var is
7454
+ // hoisted without assignment. Locally, it is shadowed by the
7455
+ // parameter
7456
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, kind);
7457
+ // To avoid the need to rewrite the declaration, we link the variable
7458
+ // names. If we ever implement a logic that splits initialization and
7459
+ // assignment for hoisted vars, the "renderLikeHoisted" logic can be
7460
+ // removed again.
7461
+ // We do not need to check whether there already is a linked
7462
+ // variable because then declaredVariable would be that linked
7463
+ // variable.
7464
+ existingVariable.renderLikeHoisted(declaredVariable);
7465
+ this.addHoistedVariable(name, declaredVariable);
7466
+ return declaredVariable;
7467
+ }
7468
+ if (existingKind === 'var') {
7469
+ existingVariable.addDeclaration(identifier, init);
7470
+ return existingVariable;
7471
+ }
7472
+ return context.error(logRedeclarationError(name), identifier.start);
7395
7473
  }
7474
+ // We only add parameters to parameter scopes
7475
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, kind);
7476
+ // Necessary to make sure the init is deoptimized for conditional declarations.
7477
+ // We cannot call deoptimizePath here.
7478
+ declaredVariable.markInitializersForDeoptimization();
7479
+ // We add the variable to this and all parent scopes to reliably detect conflicts
7480
+ this.addHoistedVariable(name, declaredVariable);
7481
+ return declaredVariable;
7396
7482
  }
7483
+ return super.addDeclaration(identifier, context, init, kind);
7397
7484
  }
7398
- include() {
7399
- if (!this.deoptimized)
7400
- this.applyDeoptimizations();
7401
- if (!this.included) {
7402
- this.included = true;
7403
- if (this.variable !== null) {
7404
- this.scope.context.includeVariableInModule(this.variable);
7485
+ }
7486
+
7487
+ class FunctionBodyScope extends ChildScope {
7488
+ constructor(parent) {
7489
+ super(parent, parent.context);
7490
+ }
7491
+ // There is stuff that is only allowed in function scopes, i.e. functions can
7492
+ // be redeclared, functions and var can redeclare each other
7493
+ addDeclaration(identifier, context, init, kind) {
7494
+ const name = identifier.name;
7495
+ const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
7496
+ if (existingVariable) {
7497
+ const existingKind = existingVariable.kind;
7498
+ if ((kind === 'var' || kind === 'function') &&
7499
+ (existingKind === 'var' || existingKind === 'function' || existingKind === 'parameter')) {
7500
+ existingVariable.addDeclaration(identifier, init);
7501
+ return existingVariable;
7405
7502
  }
7503
+ context.error(logRedeclarationError(name), identifier.start);
7406
7504
  }
7505
+ const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
7506
+ this.variables.set(name, newVariable);
7507
+ return newVariable;
7407
7508
  }
7408
- includeCallArguments(context, parameters) {
7409
- this.variable.includeCallArguments(context, parameters);
7509
+ }
7510
+
7511
+ class ParameterScope extends ChildScope {
7512
+ constructor(parent, isCatchScope) {
7513
+ super(parent, parent.context);
7514
+ this.parameters = [];
7515
+ this.hasRest = false;
7516
+ this.bodyScope = isCatchScope ? new CatchBodyScope(this) : new FunctionBodyScope(this);
7410
7517
  }
7411
- isPossibleTDZ() {
7412
- // return cached value to avoid issues with the next tree-shaking pass
7413
- const cachedTdzAccess = this.isTDZAccess;
7414
- if (cachedTdzAccess !== null)
7415
- return cachedTdzAccess;
7416
- if (!(this.variable instanceof LocalVariable &&
7417
- this.variable.kind &&
7418
- tdzVariableKinds.has(this.variable.kind) &&
7419
- // we ignore possible TDZs due to circular module dependencies as
7420
- // otherwise we get many false positives
7421
- this.variable.module === this.scope.context.module)) {
7422
- return (this.isTDZAccess = false);
7423
- }
7424
- let decl_id;
7425
- if (this.variable.declarations &&
7426
- this.variable.declarations.length === 1 &&
7427
- (decl_id = this.variable.declarations[0]) &&
7428
- this.start < decl_id.start &&
7429
- closestParentFunctionOrProgram(this) === closestParentFunctionOrProgram(decl_id)) {
7430
- // a variable accessed before its declaration
7431
- // in the same function or at top level of module
7432
- return (this.isTDZAccess = true);
7433
- }
7434
- // We ignore the case where the module is not yet executed because
7435
- // moduleSideEffects are false.
7436
- if (!this.variable.initReached && this.scope.context.module.isExecuted) {
7437
- // Either a const/let TDZ violation or
7438
- // var use before declaration was encountered.
7439
- return (this.isTDZAccess = true);
7518
+ /**
7519
+ * Adds a parameter to this scope. Parameters must be added in the correct
7520
+ * order, i.e. from left to right.
7521
+ */
7522
+ addParameterDeclaration(identifier) {
7523
+ const { name, start } = identifier;
7524
+ const existingParameter = this.variables.get(name);
7525
+ if (existingParameter) {
7526
+ return this.context.error(logDuplicateArgumentNameError(name), start);
7440
7527
  }
7441
- return (this.isTDZAccess = false);
7528
+ const variable = new ParameterVariable(name, identifier, this.context);
7529
+ this.variables.set(name, variable);
7530
+ // We also add it to the body scope to detect name conflicts with local
7531
+ // variables. We still need the intermediate scope, though, as parameter
7532
+ // defaults are NOT taken from the body scope but from the parameters or
7533
+ // outside scope.
7534
+ this.bodyScope.addHoistedVariable(name, variable);
7535
+ return variable;
7442
7536
  }
7443
- markDeclarationReached() {
7444
- this.variable.initReached = true;
7537
+ addParameterVariables(parameters, hasRest) {
7538
+ this.parameters = parameters;
7539
+ for (const parameterList of parameters) {
7540
+ for (const parameter of parameterList) {
7541
+ parameter.alwaysRendered = true;
7542
+ }
7543
+ }
7544
+ this.hasRest = hasRest;
7445
7545
  }
7446
- render(code, { snippets: { getPropertyAccess }, useOriginalName }, { renderedParentType, isCalleeOfRenderedParent, isShorthandProperty } = BLANK) {
7447
- if (this.variable) {
7448
- const name = this.variable.getName(getPropertyAccess, useOriginalName);
7449
- if (name !== this.name) {
7450
- code.overwrite(this.start, this.end, name, {
7451
- contentOnly: true,
7452
- storeName: true
7453
- });
7454
- if (isShorthandProperty) {
7455
- code.prependRight(this.start, `${this.name}: `);
7546
+ includeCallArguments(context, parameters) {
7547
+ let calledFromTryStatement = false;
7548
+ let argumentIncluded = false;
7549
+ const restParameter = this.hasRest && this.parameters[this.parameters.length - 1];
7550
+ for (const checkedArgument of parameters) {
7551
+ if (checkedArgument instanceof SpreadElement) {
7552
+ for (const argument of parameters) {
7553
+ argument.include(context, false);
7456
7554
  }
7555
+ break;
7457
7556
  }
7458
- // In strict mode, any variable named "eval" must be the actual "eval" function
7459
- if (name === 'eval' &&
7460
- renderedParentType === CallExpression$1 &&
7461
- isCalleeOfRenderedParent) {
7462
- code.appendRight(this.start, '0, ');
7557
+ }
7558
+ for (let index = parameters.length - 1; index >= 0; index--) {
7559
+ const parameterVariables = this.parameters[index] || restParameter;
7560
+ const argument = parameters[index];
7561
+ if (parameterVariables) {
7562
+ calledFromTryStatement = false;
7563
+ if (parameterVariables.length === 0) {
7564
+ // handle empty destructuring
7565
+ argumentIncluded = true;
7566
+ }
7567
+ else {
7568
+ for (const variable of parameterVariables) {
7569
+ if (variable.included) {
7570
+ argumentIncluded = true;
7571
+ }
7572
+ if (variable.calledFromTryStatement) {
7573
+ calledFromTryStatement = true;
7574
+ }
7575
+ }
7576
+ }
7577
+ }
7578
+ if (!argumentIncluded && argument.shouldBeIncluded(context)) {
7579
+ argumentIncluded = true;
7580
+ }
7581
+ if (argumentIncluded) {
7582
+ argument.include(context, calledFromTryStatement);
7463
7583
  }
7464
7584
  }
7465
7585
  }
7466
- disallowImportReassignment() {
7467
- return this.scope.context.error(logIllegalImportReassignment(this.name, this.scope.context.module.id), this.start);
7586
+ }
7587
+
7588
+ class ReturnValueScope extends ParameterScope {
7589
+ constructor() {
7590
+ super(...arguments);
7591
+ this.returnExpression = null;
7592
+ this.returnExpressions = [];
7468
7593
  }
7469
- applyDeoptimizations() {
7470
- this.deoptimized = true;
7471
- if (this.variable instanceof LocalVariable) {
7472
- this.variable.consolidateInitializers();
7473
- this.scope.context.requestTreeshakingPass();
7474
- }
7594
+ addReturnExpression(expression) {
7595
+ this.returnExpressions.push(expression);
7475
7596
  }
7476
- getVariableRespectingTDZ() {
7477
- if (this.isPossibleTDZ()) {
7478
- return UNKNOWN_EXPRESSION;
7479
- }
7480
- return this.variable;
7597
+ getReturnExpression() {
7598
+ if (this.returnExpression === null)
7599
+ this.updateReturnExpression();
7600
+ return this.returnExpression;
7481
7601
  }
7482
- isPureFunction(path) {
7483
- let currentPureFunction = this.scope.context.manualPureFunctions[this.name];
7484
- for (const segment of path) {
7485
- if (currentPureFunction) {
7486
- if (currentPureFunction[PureFunctionKey]) {
7487
- return true;
7488
- }
7489
- currentPureFunction = currentPureFunction[segment];
7490
- }
7491
- else {
7492
- return false;
7602
+ updateReturnExpression() {
7603
+ if (this.returnExpressions.length === 1) {
7604
+ this.returnExpression = this.returnExpressions[0];
7605
+ }
7606
+ else {
7607
+ this.returnExpression = UNKNOWN_EXPRESSION;
7608
+ for (const expression of this.returnExpressions) {
7609
+ expression.deoptimizePath(UNKNOWN_PATH);
7493
7610
  }
7494
7611
  }
7495
- return currentPureFunction?.[PureFunctionKey];
7496
- }
7497
- }
7498
- function closestParentFunctionOrProgram(node) {
7499
- while (node && !/^Program|Function/.test(node.type)) {
7500
- node = node.parent;
7501
7612
  }
7502
- // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program
7503
- return node;
7504
7613
  }
7505
7614
 
7506
7615
  function treeshakeNode(node, code, start, end) {
@@ -7795,6 +7904,7 @@ class FunctionBase extends NodeBase {
7795
7904
  constructor() {
7796
7905
  super(...arguments);
7797
7906
  this.objectEntity = null;
7907
+ this.parameterVariableValuesDeoptimized = false;
7798
7908
  }
7799
7909
  get async() {
7800
7910
  return isFlagSet(this.flags, 256 /* Flag.async */);
@@ -7814,6 +7924,25 @@ class FunctionBase extends NodeBase {
7814
7924
  set generator(value) {
7815
7925
  this.flags = setFlag(this.flags, 4194304 /* Flag.generator */, value);
7816
7926
  }
7927
+ updateParameterVariableValues(_arguments) {
7928
+ for (let position = 0; position < this.params.length; position++) {
7929
+ const parameter = this.params[position];
7930
+ if (!(parameter instanceof Identifier)) {
7931
+ continue;
7932
+ }
7933
+ const parameterVariable = parameter.variable;
7934
+ const argument = _arguments[position + 1] ?? UNDEFINED_EXPRESSION;
7935
+ parameterVariable.updateKnownValue(argument);
7936
+ }
7937
+ }
7938
+ deoptimizeParameterVariableValues() {
7939
+ for (const parameter of this.params) {
7940
+ if (parameter instanceof Identifier) {
7941
+ const parameterVariable = parameter.variable;
7942
+ parameterVariable.markReassigned();
7943
+ }
7944
+ }
7945
+ }
7817
7946
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
7818
7947
  if (interaction.type === INTERACTION_CALLED) {
7819
7948
  const { parameters } = this.scope;
@@ -7838,6 +7967,7 @@ class FunctionBase extends NodeBase {
7838
7967
  this.addArgumentToBeDeoptimized(argument);
7839
7968
  }
7840
7969
  }
7970
+ this.updateParameterVariableValues(args);
7841
7971
  }
7842
7972
  else {
7843
7973
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -7852,6 +7982,7 @@ class FunctionBase extends NodeBase {
7852
7982
  for (const parameterList of this.scope.parameters) {
7853
7983
  for (const parameter of parameterList) {
7854
7984
  parameter.deoptimizePath(UNKNOWN_PATH);
7985
+ parameter.markReassigned();
7855
7986
  }
7856
7987
  }
7857
7988
  }
@@ -7897,7 +8028,24 @@ class FunctionBase extends NodeBase {
7897
8028
  }
7898
8029
  return false;
7899
8030
  }
8031
+ /**
8032
+ * If the function (expression or declaration) is only used as function calls
8033
+ */
8034
+ onlyFunctionCallUsed() {
8035
+ let variable = null;
8036
+ if (this.parent.type === VariableDeclarator$1) {
8037
+ variable = this.parent.id.variable ?? null;
8038
+ }
8039
+ if (this.parent.type === ExportDefaultDeclaration$1) {
8040
+ variable = this.parent.variable;
8041
+ }
8042
+ return variable?.getOnlyFunctionCallUsed() ?? false;
8043
+ }
7900
8044
  include(context, includeChildrenRecursively) {
8045
+ if (!this.parameterVariableValuesDeoptimized && !this.onlyFunctionCallUsed()) {
8046
+ this.parameterVariableValuesDeoptimized = true;
8047
+ this.deoptimizeParameterVariableValues();
8048
+ }
7901
8049
  if (!this.deoptimized)
7902
8050
  this.applyDeoptimizations();
7903
8051
  this.included = true;
@@ -7981,6 +8129,11 @@ class ArrowFunctionExpression extends FunctionBase {
7981
8129
  }
7982
8130
  return false;
7983
8131
  }
8132
+ onlyFunctionCallUsed() {
8133
+ const isIIFE = this.parent.type === CallExpression$1 &&
8134
+ this.parent.callee === this;
8135
+ return isIIFE || super.onlyFunctionCallUsed();
8136
+ }
7984
8137
  include(context, includeChildrenRecursively) {
7985
8138
  super.include(context, includeChildrenRecursively);
7986
8139
  for (const parameter of this.params) {
@@ -8796,6 +8949,10 @@ class MemberExpression extends NodeBase {
8796
8949
  this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER);
8797
8950
  this.scope.context.requestTreeshakingPass();
8798
8951
  }
8952
+ if (this.variable) {
8953
+ this.variable.addUsedPlace(this);
8954
+ this.scope.context.requestTreeshakingPass();
8955
+ }
8799
8956
  }
8800
8957
  applyAssignmentDeoptimization() {
8801
8958
  this.assignmentDeoptimized = true;
@@ -8994,21 +9151,17 @@ class CallExpression extends CallExpressionBase {
8994
9151
  };
8995
9152
  }
8996
9153
  hasEffects(context) {
8997
- try {
8998
- for (const argument of this.arguments) {
8999
- if (argument.hasEffects(context))
9000
- return true;
9001
- }
9002
- if (this.annotationPure) {
9003
- return false;
9004
- }
9005
- return (this.callee.hasEffects(context) ||
9006
- this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
9154
+ if (!this.deoptimized)
9155
+ this.applyDeoptimizations();
9156
+ for (const argument of this.arguments) {
9157
+ if (argument.hasEffects(context))
9158
+ return true;
9007
9159
  }
9008
- finally {
9009
- if (!this.deoptimized)
9010
- this.applyDeoptimizations();
9160
+ if (this.annotationPure) {
9161
+ return false;
9011
9162
  }
9163
+ return (this.callee.hasEffects(context) ||
9164
+ this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
9012
9165
  }
9013
9166
  include(context, includeChildrenRecursively) {
9014
9167
  if (!this.deoptimized)
@@ -9669,6 +9822,10 @@ class FunctionDeclaration extends FunctionNode {
9669
9822
  this.id.variable.isId = true;
9670
9823
  }
9671
9824
  }
9825
+ onlyFunctionCallUsed() {
9826
+ // call super.onlyFunctionCallUsed for export default anonymous function
9827
+ return this.id?.variable.getOnlyFunctionCallUsed() ?? super.onlyFunctionCallUsed();
9828
+ }
9672
9829
  parseNode(esTreeNode) {
9673
9830
  if (esTreeNode.id !== null) {
9674
9831
  this.id = new Identifier(this, this.scope.parent).parseNode(esTreeNode.id);
@@ -9930,6 +10087,12 @@ class FunctionExpression extends FunctionNode {
9930
10087
  }
9931
10088
  return super.parseNode(esTreeNode);
9932
10089
  }
10090
+ onlyFunctionCallUsed() {
10091
+ const isIIFE = this.parent.type === CallExpression$1 &&
10092
+ this.parent.callee === this &&
10093
+ (this.id === null || this.id.variable.getOnlyFunctionCallUsed());
10094
+ return isIIFE || super.onlyFunctionCallUsed();
10095
+ }
9933
10096
  render(code, options, { renderedSurroundingElement } = BLANK) {
9934
10097
  super.render(code, options);
9935
10098
  if (renderedSurroundingElement === ExpressionStatement$1) {
@@ -11023,21 +11186,17 @@ const importMetaMechanisms = {
11023
11186
 
11024
11187
  class NewExpression extends NodeBase {
11025
11188
  hasEffects(context) {
11026
- try {
11027
- for (const argument of this.arguments) {
11028
- if (argument.hasEffects(context))
11029
- return true;
11030
- }
11031
- if (this.annotationPure) {
11032
- return false;
11033
- }
11034
- return (this.callee.hasEffects(context) ||
11035
- this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
11189
+ if (!this.deoptimized)
11190
+ this.applyDeoptimizations();
11191
+ for (const argument of this.arguments) {
11192
+ if (argument.hasEffects(context))
11193
+ return true;
11036
11194
  }
11037
- finally {
11038
- if (!this.deoptimized)
11039
- this.applyDeoptimizations();
11195
+ if (this.annotationPure) {
11196
+ return false;
11040
11197
  }
11198
+ return (this.callee.hasEffects(context) ||
11199
+ this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
11041
11200
  }
11042
11201
  hasEffectsOnInteractionAtPath(path, { type }) {
11043
11202
  return path.length > 0 || type !== INTERACTION_ACCESSED;
@@ -11594,18 +11753,14 @@ class TaggedTemplateExpression extends CallExpressionBase {
11594
11753
  }
11595
11754
  }
11596
11755
  hasEffects(context) {
11597
- try {
11598
- for (const argument of this.quasi.expressions) {
11599
- if (argument.hasEffects(context))
11600
- return true;
11601
- }
11602
- return (this.tag.hasEffects(context) ||
11603
- this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
11604
- }
11605
- finally {
11606
- if (!this.deoptimized)
11607
- this.applyDeoptimizations();
11756
+ if (!this.deoptimized)
11757
+ this.applyDeoptimizations();
11758
+ for (const argument of this.quasi.expressions) {
11759
+ if (argument.hasEffects(context))
11760
+ return true;
11608
11761
  }
11762
+ return (this.tag.hasEffects(context) ||
11763
+ this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
11609
11764
  }
11610
11765
  include(context, includeChildrenRecursively) {
11611
11766
  if (!this.deoptimized)
@@ -11735,6 +11890,15 @@ class ExportDefaultVariable extends LocalVariable {
11735
11890
  this.name = identifier.name;
11736
11891
  }
11737
11892
  }
11893
+ addUsedPlace(usedPlace) {
11894
+ const original = this.getOriginalVariable();
11895
+ if (original === this) {
11896
+ super.addUsedPlace(usedPlace);
11897
+ }
11898
+ else {
11899
+ original.addUsedPlace(usedPlace);
11900
+ }
11901
+ }
11738
11902
  forbidName(name) {
11739
11903
  const original = this.getOriginalVariable();
11740
11904
  if (original === this) {
@@ -12008,7 +12172,7 @@ class UpdateExpression extends NodeBase {
12008
12172
  this.argument.deoptimizePath(EMPTY_PATH);
12009
12173
  if (this.argument instanceof Identifier) {
12010
12174
  const variable = this.scope.findVariable(this.argument.name);
12011
- variable.isReassigned = true;
12175
+ variable.markReassigned();
12012
12176
  }
12013
12177
  this.scope.context.requestTreeshakingPass();
12014
12178
  }
@@ -18125,7 +18289,7 @@ function addModuleToManualChunk(alias, module, manualChunkAliasByEntry) {
18125
18289
 
18126
18290
  function flru (max) {
18127
18291
  var num, curr, prev;
18128
- var limit = max || 1;
18292
+ var limit = max ;
18129
18293
 
18130
18294
  function keep(key, value) {
18131
18295
  if (++num > limit) {