@rollup/wasm-node 4.24.2 → 4.25.0-0

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,22 +1,22 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v4.24.2
4
- Sun, 27 Oct 2024 15:39:37 GMT - commit 32d0e7dae85121ac0850ec28576a10a6302f84a9
3
+ Rollup.js v4.25.0-0
4
+ Tue, 29 Oct 2024 06:14:37 GMT - commit b7fcaba12e863db516f39de74c1eacfe5329a5c3
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
8
8
  Released under the MIT License.
9
9
  */
10
- import { ExportDefaultDeclaration as ExportDefaultDeclaration$1, CallExpression as CallExpression$1, EMPTY_ARRAY, LOGLEVEL_WARN, logUnusedExternalImports, ANNOTATION_KEY, INVALID_ANNOTATION_KEY, Program as Program$1, logIllegalImportReassignment, BLANK, logRedeclarationError, StaticBlock as StaticBlock$1, CatchClause as CatchClause$1, logDuplicateArgumentNameError, logModuleLevelDirective, ReturnStatement as ReturnStatement$1, VariableDeclarator as VariableDeclarator$1, ExpressionStatement as ExpressionStatement$1, logMissingExport, normalize, getImportPath, logMissingNodeBuiltins, logReservedNamespace, error, logIllegalIdentifierAsName, logMissingNameOptionForIifeExport, logMissingNameOptionForUmdExport, Property as Property$1, logConstVariableReassignError, ArrowFunctionExpression as ArrowFunctionExpression$1, EMPTY_SET, logCannotCallNamespace, logEval, BlockStatement as BlockStatement$1, getRollupError, logParseError, logModuleParseError, LOGLEVEL_INFO, logFirstSideEffect, locate, logInvalidAnnotation, Identifier as Identifier$1, logThisIsUndefined, getAstBuffer, convertAnnotations, FIXED_STRINGS, convertNode as convertNode$1, EMPTY_OBJECT, logImportAttributeIsInvalid, logImportOptionsAreInvalid, logSyntheticNamedExportsNeedNamespaceExport, logMissingEntryExport, logDuplicateExportError, logInvalidSourcemapForError, augmentCodeLocation, logInconsistentImportAttributes, logMissingJsxExport, logNamespaceConflict, logAmbiguousExternalNamespaces, logShimmedExport, parseAst, logCircularReexport, logInvalidFormatForTopLevelAwait, TemplateLiteral as TemplateLiteral$1, Literal as Literal$1, 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, logUnknownOption, printQuotedStringList, LOGLEVEL_ERROR, logLevelPriority, LOGLEVEL_DEBUG, logInvalidSetAssetSourceCall, logPluginError, logNoTransformMapOrAstWithoutCode, relativeId, logBadLoader, logExternalModulesCannotBeTransformedToModules, logInternalIdCannotBeExternal, isRelative, logUnresolvedImport, logUnresolvedImportTreatedAsExternal, logExternalSyntheticExports, logUnresolvedEntry, logUnresolvedImplicitDependant, logExternalModulesCannotBeIncludedInManualChunks, logEntryCannotBeExternal, logImplicitDependantCannotBeExternal, logNoAssetSourceSet, logFileReferenceIdNotFoundForFilename, logAssetReferenceIdNotFoundForSetSource, logAssetSourceAlreadySet, logInvalidRollupPhaseForChunkEmission, warnDeprecation, URL_GENERATEBUNDLE, logFileNameConflict, logAssetNotFinalisedForFileName, logChunkNotGeneratedForFileName, logInvalidLogPosition, logInputHookInOutputPlugin, logInvalidFunctionPluginHook, logInvalidAddonPluginHook, logImplicitDependantIsNotIncluded, logCircularDependency, augmentLogMessage, URL_JSX, URL_TREESHAKE, URL_TREESHAKE_MODULESIDEEFFECTS, logInvalidExportOptionValue, URL_OUTPUT_INTEROP, isValidUrl, addTrailingSlashIfMissed, URL_OUTPUT_SOURCEMAPBASEURL, URL_OUTPUT_INLINEDYNAMICIMPORTS, URL_PRESERVEENTRYSIGNATURES, URL_OUTPUT_AMD_BASEPATH, URL_OUTPUT_GENERATEDCODE, URL_OUTPUT_MANUALCHUNKS, URL_OUTPUT_EXTERNALIMPORTATTRIBUTES, logAlreadyClosed, logMissingFileOrDirOption, logCannotEmitFromOptionsHook, URL_WATCH } from './parseAst.js';
10
+ import { EMPTY_OBJECT, CallExpression as CallExpression$1, ExportDefaultDeclaration as ExportDefaultDeclaration$1, EMPTY_ARRAY, LOGLEVEL_WARN, logUnusedExternalImports, ANNOTATION_KEY, INVALID_ANNOTATION_KEY, Program as Program$1, logIllegalImportReassignment, BLANK, logRedeclarationError, StaticBlock as StaticBlock$1, CatchClause as CatchClause$1, logDuplicateArgumentNameError, logModuleLevelDirective, ReturnStatement as ReturnStatement$1, VariableDeclarator as VariableDeclarator$1, ExpressionStatement as ExpressionStatement$1, logMissingExport, normalize, getImportPath, logMissingNodeBuiltins, logReservedNamespace, error, logIllegalIdentifierAsName, logMissingNameOptionForIifeExport, logMissingNameOptionForUmdExport, Property as Property$1, logConstVariableReassignError, ArrowFunctionExpression as ArrowFunctionExpression$1, EMPTY_SET, logCannotCallNamespace, logEval, BlockStatement as BlockStatement$1, getRollupError, logParseError, logModuleParseError, LOGLEVEL_INFO, logFirstSideEffect, locate, logInvalidAnnotation, Identifier as Identifier$1, logThisIsUndefined, convertAnnotations, FIXED_STRINGS, convertNode as convertNode$1, getAstBuffer, logImportAttributeIsInvalid, logImportOptionsAreInvalid, logSyntheticNamedExportsNeedNamespaceExport, logCircularReexport, logMissingEntryExport, logInvalidFormatForTopLevelAwait, logDuplicateExportError, logInvalidSourcemapForError, augmentCodeLocation, logInconsistentImportAttributes, logMissingJsxExport, logNamespaceConflict, logAmbiguousExternalNamespaces, logShimmedExport, parseAst, TemplateLiteral as TemplateLiteral$1, Literal as Literal$1, logAddonNotGenerated, logIncompatibleExportOptionValue, logMixedExport, logFailedValidation, isPathFragment, getAliasName, logCyclicCrossChunkReexport, logUnexpectedNamedImport, isAbsolute as isAbsolute$1, relative as relative$1, logUnexpectedNamespaceReexport, logMissingGlobalName, logEmptyChunk, logOptimizeChunkStatus, logConflictingSourcemapSources, logSourcemapBroken, logInvalidOption, URL_OUTPUT_FORMAT, URL_OUTPUT_DIR, URL_OUTPUT_SOURCEMAPFILE, URL_OUTPUT_AMD_ID, logCannotAssignModuleToChunk, logChunkInvalid, logAnonymousPluginCache, logDuplicatePluginName, LOGLEVEL_ERROR, logLevelPriority, LOGLEVEL_DEBUG, printQuotedStringList, logUnknownOption, logNoTransformMapOrAstWithoutCode, logInvalidSetAssetSourceCall, logPluginError, relativeId, logBadLoader, logExternalModulesCannotBeTransformedToModules, logInternalIdCannotBeExternal, isRelative, logUnresolvedImport, logUnresolvedImportTreatedAsExternal, logExternalSyntheticExports, logUnresolvedEntry, logUnresolvedImplicitDependant, logExternalModulesCannotBeIncludedInManualChunks, logEntryCannotBeExternal, logImplicitDependantCannotBeExternal, logNoAssetSourceSet, logFileReferenceIdNotFoundForFilename, logChunkNotGeneratedForFileName, logAssetNotFinalisedForFileName, logAssetReferenceIdNotFoundForSetSource, logAssetSourceAlreadySet, logFileNameConflict, logInvalidRollupPhaseForChunkEmission, warnDeprecation, URL_GENERATEBUNDLE, logInvalidLogPosition, logInvalidFunctionPluginHook, logInputHookInOutputPlugin, logInvalidAddonPluginHook, logImplicitDependantIsNotIncluded, logCircularDependency, augmentLogMessage, URL_TREESHAKE, URL_TREESHAKE_MODULESIDEEFFECTS, URL_JSX, URL_OUTPUT_INLINEDYNAMICIMPORTS, URL_PRESERVEENTRYSIGNATURES, URL_OUTPUT_GENERATEDCODE, URL_OUTPUT_EXTERNALIMPORTATTRIBUTES, isValidUrl, addTrailingSlashIfMissed, URL_OUTPUT_SOURCEMAPBASEURL, URL_OUTPUT_MANUALCHUNKS, logInvalidExportOptionValue, URL_OUTPUT_AMD_BASEPATH, URL_OUTPUT_INTEROP, logAlreadyClosed, logCannotEmitFromOptionsHook, logMissingFileOrDirOption, URL_WATCH } from './parseAst.js';
11
11
  import { relative, dirname, basename, extname, resolve as resolve$1 } from 'node:path';
12
- import { posix, win32, isAbsolute, resolve } from 'path';
13
- import { parseAsync, xxhashBase64Url, xxhashBase36, xxhashBase16 } from '../../native.js';
12
+ import { isAbsolute, win32, posix, resolve } from 'path';
13
+ import { parseAsync, xxhashBase16, xxhashBase64Url, xxhashBase36 } from '../../native.js';
14
14
  import process$1, { env as env$1 } from 'node:process';
15
15
  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.24.2";
19
+ var version = "4.25.0-0";
20
20
 
21
21
  const comma = ','.charCodeAt(0);
22
22
  const semicolon = ';'.charCodeAt(0);
@@ -2038,7 +2038,7 @@ const UNKNOWN_PATH = [UnknownKey];
2038
2038
  const UNKNOWN_NON_ACCESSOR_PATH = [UnknownNonAccessorKey];
2039
2039
  const UNKNOWN_INTEGER_PATH = [UnknownInteger];
2040
2040
  const EntitiesKey = Symbol('Entities');
2041
- class PathTracker {
2041
+ class EntityPathTracker {
2042
2042
  constructor() {
2043
2043
  this.entityPaths = Object.create(null, {
2044
2044
  [EntitiesKey]: { value: new Set() }
@@ -2063,14 +2063,14 @@ class PathTracker {
2063
2063
  getEntities(path) {
2064
2064
  let currentPaths = this.entityPaths;
2065
2065
  for (const pathSegment of path) {
2066
- currentPaths = currentPaths[pathSegment] =
2067
- currentPaths[pathSegment] ||
2068
- Object.create(null, { [EntitiesKey]: { value: new Set() } });
2066
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
2067
+ [EntitiesKey]: { value: new Set() }
2068
+ });
2069
2069
  }
2070
2070
  return currentPaths[EntitiesKey];
2071
2071
  }
2072
2072
  }
2073
- const SHARED_RECURSION_TRACKER = new PathTracker();
2073
+ const SHARED_RECURSION_TRACKER = new EntityPathTracker();
2074
2074
  class DiscriminatedPathTracker {
2075
2075
  constructor() {
2076
2076
  this.entityPaths = Object.create(null, {
@@ -2080,9 +2080,9 @@ class DiscriminatedPathTracker {
2080
2080
  trackEntityAtPathAndGetIfTracked(path, discriminator, entity) {
2081
2081
  let currentPaths = this.entityPaths;
2082
2082
  for (const pathSegment of path) {
2083
- currentPaths = currentPaths[pathSegment] =
2084
- currentPaths[pathSegment] ||
2085
- Object.create(null, { [EntitiesKey]: { value: new Map() } });
2083
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
2084
+ [EntitiesKey]: { value: new Map() }
2085
+ });
2086
2086
  }
2087
2087
  const trackedEntities = getOrCreate(currentPaths[EntitiesKey], discriminator, (getNewSet));
2088
2088
  if (trackedEntities.has(entity))
@@ -2091,6 +2091,55 @@ class DiscriminatedPathTracker {
2091
2091
  return false;
2092
2092
  }
2093
2093
  }
2094
+ const UNKNOWN_INCLUDED_PATH = Object.freeze({ [UnknownKey]: EMPTY_OBJECT });
2095
+ class IncludedPathTracker {
2096
+ constructor() {
2097
+ this.includedPaths = null;
2098
+ }
2099
+ includePathAndGetIfIncluded(path) {
2100
+ let included = true;
2101
+ let parent = this;
2102
+ let parentSegment = 'includedPaths';
2103
+ let currentPaths = (this.includedPaths ||=
2104
+ ((included = false), Object.create(null)));
2105
+ for (const pathSegment of path) {
2106
+ // This means from here, all paths are included
2107
+ if (currentPaths[UnknownKey]) {
2108
+ return true;
2109
+ }
2110
+ // Including UnknownKey automatically includes all nested paths.
2111
+ // From above, we know that UnknownKey is not included yet.
2112
+ if (typeof pathSegment === 'symbol') {
2113
+ // Hopefully, this saves some memory over just setting
2114
+ // currentPaths[UnknownKey] = EMPTY_OBJECT
2115
+ parent[parentSegment] = UNKNOWN_INCLUDED_PATH;
2116
+ return false;
2117
+ }
2118
+ parent = currentPaths;
2119
+ parentSegment = pathSegment;
2120
+ currentPaths = currentPaths[pathSegment] ||= ((included = false), Object.create(null));
2121
+ }
2122
+ return included;
2123
+ }
2124
+ includeAllPaths(entity, context, basePath) {
2125
+ const { includedPaths } = this;
2126
+ if (includedPaths) {
2127
+ includeAllPaths(entity, context, basePath, includedPaths);
2128
+ }
2129
+ }
2130
+ }
2131
+ function includeAllPaths(entity, context, basePath, currentPaths) {
2132
+ if (currentPaths[UnknownKey]) {
2133
+ return entity.includePath([...basePath, UnknownKey], context, false);
2134
+ }
2135
+ const keys = Object.keys(currentPaths);
2136
+ if (keys.length === 0) {
2137
+ return entity.includePath(basePath, context, false);
2138
+ }
2139
+ for (const key of keys) {
2140
+ includeAllPaths(entity, context, [...basePath, key], currentPaths[key]);
2141
+ }
2142
+ }
2094
2143
 
2095
2144
  function isFlagSet(flags, flag) {
2096
2145
  return (flags & flag) !== 0;
@@ -2129,12 +2178,12 @@ class ExpressionEntity {
2129
2178
  hasEffectsOnInteractionAtPath(_path, _interaction, _context) {
2130
2179
  return true;
2131
2180
  }
2132
- include(_context, _includeChildrenRecursively, _options) {
2181
+ includePath(_path, _context, _includeChildrenRecursively, _options) {
2133
2182
  this.included = true;
2134
2183
  }
2135
- includeCallArguments(context, parameters) {
2136
- for (const argument of parameters) {
2137
- argument.include(context, false);
2184
+ includeCallArguments(context, interaction) {
2185
+ for (const argument of interaction.args) {
2186
+ argument?.includePath(UNKNOWN_PATH, context, false);
2138
2187
  }
2139
2188
  }
2140
2189
  shouldBeIncluded(_context) {
@@ -2249,9 +2298,9 @@ class Variable extends ExpressionEntity {
2249
2298
  * has not been included previously. Once a variable is included, it should
2250
2299
  * take care all its declarations are included.
2251
2300
  */
2252
- include() {
2301
+ includePath(path, context) {
2253
2302
  this.included = true;
2254
- this.renderedLikeHoisted?.include();
2303
+ this.renderedLikeHoisted?.includePath(path, context);
2255
2304
  }
2256
2305
  /**
2257
2306
  * Links the rendered name of this variable to another variable and includes
@@ -2283,8 +2332,8 @@ class ExternalVariable extends Variable {
2283
2332
  hasEffectsOnInteractionAtPath(path, { type }) {
2284
2333
  return type !== INTERACTION_ACCESSED || path.length > (this.isNamespace ? 1 : 0);
2285
2334
  }
2286
- include() {
2287
- super.include();
2335
+ includePath(path, context) {
2336
+ super.includePath(path, context);
2288
2337
  this.module.used = true;
2289
2338
  }
2290
2339
  }
@@ -2798,8 +2847,8 @@ function createInclusionContext() {
2798
2847
  }
2799
2848
  function createHasEffectsContext() {
2800
2849
  return {
2801
- accessed: new PathTracker(),
2802
- assigned: new PathTracker(),
2850
+ accessed: new EntityPathTracker(),
2851
+ assigned: new EntityPathTracker(),
2803
2852
  brokenFlow: false,
2804
2853
  called: new DiscriminatedPathTracker(),
2805
2854
  hasBreak: false,
@@ -2885,7 +2934,7 @@ class NodeBase extends ExpressionEntity {
2885
2934
  return (this.hasEffects(context) ||
2886
2935
  this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));
2887
2936
  }
2888
- include(context, includeChildrenRecursively, _options) {
2937
+ includePath(_path, context, includeChildrenRecursively, _options) {
2889
2938
  if (!this.deoptimized)
2890
2939
  this.applyDeoptimizations();
2891
2940
  this.included = true;
@@ -2895,16 +2944,16 @@ class NodeBase extends ExpressionEntity {
2895
2944
  continue;
2896
2945
  if (Array.isArray(value)) {
2897
2946
  for (const child of value) {
2898
- child?.include(context, includeChildrenRecursively);
2947
+ child?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
2899
2948
  }
2900
2949
  }
2901
2950
  else {
2902
- value.include(context, includeChildrenRecursively);
2951
+ value.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
2903
2952
  }
2904
2953
  }
2905
2954
  }
2906
2955
  includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {
2907
- this.include(context, includeChildrenRecursively);
2956
+ this.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
2908
2957
  }
2909
2958
  /**
2910
2959
  * Override to perform special initialisation steps after the scope is
@@ -3155,6 +3204,7 @@ class ObjectEntity extends ExpressionEntity {
3155
3204
  this.unknownIntegerProps = [];
3156
3205
  this.unmatchableGetters = [];
3157
3206
  this.unmatchablePropertiesAndGetters = [];
3207
+ this.unmatchablePropertiesAndSetters = [];
3158
3208
  this.unmatchableSetters = [];
3159
3209
  if (Array.isArray(properties)) {
3160
3210
  this.buildPropertyMaps(properties);
@@ -3389,9 +3439,37 @@ class ObjectEntity extends ExpressionEntity {
3389
3439
  }
3390
3440
  return false;
3391
3441
  }
3442
+ includePath(path, context, includeChildrenRecursively) {
3443
+ this.included = true;
3444
+ const [key, ...subPath] = path;
3445
+ if (key == null || includeChildrenRecursively) {
3446
+ for (const property of this.allProperties) {
3447
+ if (includeChildrenRecursively || property.shouldBeIncluded(context)) {
3448
+ property.includePath(EMPTY_PATH, context, includeChildrenRecursively);
3449
+ }
3450
+ }
3451
+ this.prototypeExpression?.includePath(EMPTY_PATH, context, includeChildrenRecursively);
3452
+ }
3453
+ else {
3454
+ const [includedMembers, includedPath] = typeof key === 'string'
3455
+ ? [
3456
+ [
3457
+ ...new Set([
3458
+ ...(this.propertiesAndGettersByKey[key] || this.unmatchablePropertiesAndGetters),
3459
+ ...(this.propertiesAndSettersByKey[key] || this.unmatchablePropertiesAndSetters)
3460
+ ])
3461
+ ],
3462
+ subPath
3463
+ ]
3464
+ : [this.allProperties, UNKNOWN_PATH];
3465
+ for (const property of includedMembers) {
3466
+ property.includePath(includedPath, context, includeChildrenRecursively);
3467
+ }
3468
+ this.prototypeExpression?.includePath(path, context, includeChildrenRecursively);
3469
+ }
3470
+ }
3392
3471
  buildPropertyMaps(properties) {
3393
- const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchableGetters, unmatchableSetters } = this;
3394
- const unmatchablePropertiesAndSetters = [];
3472
+ const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchablePropertiesAndSetters, unmatchableGetters, unmatchableSetters } = this;
3395
3473
  for (let index = properties.length - 1; index >= 0; index--) {
3396
3474
  const { key, kind, property } = properties[index];
3397
3475
  allProperties.push(property);
@@ -4727,16 +4805,20 @@ class GlobalVariable extends Variable {
4727
4805
  }
4728
4806
 
4729
4807
  class LocalVariable extends Variable {
4730
- constructor(name, declarator, init, context, kind) {
4808
+ constructor(name, declarator, init,
4809
+ /** if this is non-empty, the actual init is this path of this.init */
4810
+ initPath, context, kind) {
4731
4811
  super(name);
4732
4812
  this.init = init;
4813
+ this.initPath = initPath;
4814
+ this.kind = kind;
4733
4815
  this.calledFromTryStatement = false;
4734
4816
  this.additionalInitializers = null;
4817
+ this.includedPathTracker = new IncludedPathTracker();
4735
4818
  this.expressionsToBeDeoptimized = [];
4736
4819
  this.declarations = declarator ? [declarator] : [];
4737
4820
  this.deoptimizationTracker = context.deoptimizationTracker;
4738
4821
  this.module = context.module;
4739
- this.kind = kind;
4740
4822
  }
4741
4823
  addDeclaration(identifier, init) {
4742
4824
  this.declarations.push(identifier);
@@ -4747,7 +4829,6 @@ class LocalVariable extends Variable {
4747
4829
  for (const initializer of this.additionalInitializers) {
4748
4830
  initializer.deoptimizePath(UNKNOWN_PATH);
4749
4831
  }
4750
- this.additionalInitializers = null;
4751
4832
  }
4752
4833
  }
4753
4834
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
@@ -4755,7 +4836,7 @@ class LocalVariable extends Variable {
4755
4836
  deoptimizeInteraction(interaction);
4756
4837
  return;
4757
4838
  }
4758
- recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker), undefined);
4839
+ recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], recursionTracker), undefined);
4759
4840
  }
4760
4841
  deoptimizePath(path) {
4761
4842
  if (this.isReassigned ||
@@ -4769,10 +4850,10 @@ class LocalVariable extends Variable {
4769
4850
  for (const expression of expressionsToBeDeoptimized) {
4770
4851
  expression.deoptimizeCache();
4771
4852
  }
4772
- this.init.deoptimizePath(UNKNOWN_PATH);
4853
+ this.init.deoptimizePath([...this.initPath, UnknownKey]);
4773
4854
  }
4774
4855
  else {
4775
- this.init.deoptimizePath(path);
4856
+ this.init.deoptimizePath([...this.initPath, ...path]);
4776
4857
  }
4777
4858
  }
4778
4859
  getLiteralValueAtPath(path, recursionTracker, origin) {
@@ -4781,7 +4862,7 @@ class LocalVariable extends Variable {
4781
4862
  }
4782
4863
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
4783
4864
  this.expressionsToBeDeoptimized.push(origin);
4784
- return this.init.getLiteralValueAtPath(path, recursionTracker, origin);
4865
+ return this.init.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin);
4785
4866
  }, UnknownValue);
4786
4867
  }
4787
4868
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
@@ -4790,7 +4871,7 @@ class LocalVariable extends Variable {
4790
4871
  }
4791
4872
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
4792
4873
  this.expressionsToBeDeoptimized.push(origin);
4793
- return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
4874
+ return this.init.getReturnExpressionWhenCalledAtPath([...this.initPath, ...path], interaction, recursionTracker, origin);
4794
4875
  }, UNKNOWN_RETURN_EXPRESSION);
4795
4876
  }
4796
4877
  hasEffectsOnInteractionAtPath(path, interaction, context) {
@@ -4799,7 +4880,7 @@ class LocalVariable extends Variable {
4799
4880
  if (this.isReassigned)
4800
4881
  return true;
4801
4882
  return (!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
4802
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
4883
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4803
4884
  }
4804
4885
  case INTERACTION_ASSIGNED: {
4805
4886
  if (this.included)
@@ -4809,23 +4890,23 @@ class LocalVariable extends Variable {
4809
4890
  if (this.isReassigned)
4810
4891
  return true;
4811
4892
  return (!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
4812
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
4893
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4813
4894
  }
4814
4895
  case INTERACTION_CALLED: {
4815
4896
  if (this.isReassigned)
4816
4897
  return true;
4817
4898
  return (!(interaction.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this) &&
4818
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
4899
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4819
4900
  }
4820
4901
  }
4821
4902
  }
4822
- include() {
4823
- if (!this.included) {
4824
- super.include();
4903
+ includePath(path, context) {
4904
+ if (!this.includedPathTracker.includePathAndGetIfIncluded(path)) {
4905
+ super.includePath(path, context);
4825
4906
  for (const declaration of this.declarations) {
4826
4907
  // If node is a default export, it can save a tree-shaking run to include the full declaration now
4827
4908
  if (!declaration.included)
4828
- declaration.include(createInclusionContext(), false);
4909
+ declaration.includePath(EMPTY_PATH, context, false);
4829
4910
  let node = declaration.parent;
4830
4911
  while (!node.included) {
4831
4912
  // We do not want to properly include parents in case they are part of a dead branch
@@ -4836,17 +4917,26 @@ class LocalVariable extends Variable {
4836
4917
  node = node.parent;
4837
4918
  }
4838
4919
  }
4920
+ // We need to make sure we include the correct path of the init
4921
+ if (path.length > 0) {
4922
+ this.init.includePath([...this.initPath, ...path], context, false);
4923
+ this.additionalInitializers?.forEach(initializer => initializer.includePath(UNKNOWN_PATH, context, false));
4924
+ }
4839
4925
  }
4840
4926
  }
4841
- includeCallArguments(context, parameters) {
4842
- if (this.isReassigned || context.includedCallArguments.has(this.init)) {
4843
- for (const argument of parameters) {
4844
- argument.include(context, false);
4927
+ includeCallArguments(context, interaction) {
4928
+ if (this.isReassigned ||
4929
+ context.includedCallArguments.has(this.init) ||
4930
+ // This can be removed again once we can include arguments when called at
4931
+ // a specific path
4932
+ this.initPath.length > 0) {
4933
+ for (const argument of interaction.args) {
4934
+ argument?.includePath(UNKNOWN_PATH, context, false);
4845
4935
  }
4846
4936
  }
4847
4937
  else {
4848
4938
  context.includedCallArguments.add(this.init);
4849
- this.init.includeCallArguments(context, parameters);
4939
+ this.init.includeCallArguments(context, interaction);
4850
4940
  context.includedCallArguments.delete(this.init);
4851
4941
  }
4852
4942
  }
@@ -4926,18 +5016,21 @@ class IdentifierBase extends NodeBase {
4926
5016
  }
4927
5017
  }
4928
5018
  }
4929
- include() {
5019
+ includePath(path, context) {
4930
5020
  if (!this.deoptimized)
4931
5021
  this.applyDeoptimizations();
4932
5022
  if (!this.included) {
4933
5023
  this.included = true;
4934
5024
  if (this.variable !== null) {
4935
- this.scope.context.includeVariableInModule(this.variable);
5025
+ this.scope.context.includeVariableInModule(this.variable, path);
4936
5026
  }
4937
5027
  }
5028
+ else if (path.length > 0) {
5029
+ this.variable?.includePath(path, context);
5030
+ }
4938
5031
  }
4939
- includeCallArguments(context, parameters) {
4940
- this.variable.includeCallArguments(context, parameters);
5032
+ includeCallArguments(context, interaction) {
5033
+ this.variable.includeCallArguments(context, interaction);
4941
5034
  }
4942
5035
  isPossibleTDZ() {
4943
5036
  // return cached value to avoid issues with the next tree-shaking pass
@@ -5037,39 +5130,17 @@ class Identifier extends IdentifierBase {
5037
5130
  this.isVariableReference = true;
5038
5131
  }
5039
5132
  }
5040
- declare(kind, init) {
5133
+ declare(kind, includedInitPath, init) {
5041
5134
  let variable;
5042
5135
  const { treeshake } = this.scope.context.options;
5043
- switch (kind) {
5044
- case 'var': {
5045
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5046
- if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
5047
- // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
5048
- variable.markInitializersForDeoptimization();
5049
- }
5050
- break;
5051
- }
5052
- case 'function': {
5053
- // in strict mode, functions are only hoisted within a scope but not across block scopes
5054
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5055
- break;
5056
- }
5057
- case 'let':
5058
- case 'const':
5059
- case 'using':
5060
- case 'await using':
5061
- case 'class': {
5062
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5063
- break;
5064
- }
5065
- case 'parameter': {
5066
- variable = this.scope.addParameterDeclaration(this);
5067
- break;
5068
- }
5069
- /* istanbul ignore next */
5070
- default: {
5071
- /* istanbul ignore next */
5072
- throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
5136
+ if (kind === 'parameter') {
5137
+ variable = this.scope.addParameterDeclaration(this, includedInitPath);
5138
+ }
5139
+ else {
5140
+ variable = this.scope.addDeclaration(this, this.scope.context, init, includedInitPath, kind);
5141
+ if (kind === 'var' && treeshake && treeshake.correctVarValueBeforeDeclaration) {
5142
+ // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
5143
+ variable.markInitializersForDeoptimization();
5073
5144
  }
5074
5145
  }
5075
5146
  return [(this.variable = variable)];
@@ -5138,18 +5209,17 @@ class Scope {
5138
5209
  - then the variable is still declared in the hoisted outer scope, but the initializer is assigned to the parameter
5139
5210
  - const, let, class, and function except in the cases above cannot redeclare anything
5140
5211
  */
5141
- addDeclaration(identifier, context, init, kind) {
5212
+ addDeclaration(identifier, context, init, includedInitPath, kind) {
5142
5213
  const name = identifier.name;
5143
5214
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
5144
5215
  if (existingVariable) {
5145
- const existingKind = existingVariable.kind;
5146
- if (kind === 'var' && existingKind === 'var') {
5216
+ if (kind === 'var' && existingVariable.kind === 'var') {
5147
5217
  existingVariable.addDeclaration(identifier, init);
5148
5218
  return existingVariable;
5149
5219
  }
5150
5220
  context.error(logRedeclarationError(name), identifier.start);
5151
5221
  }
5152
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
5222
+ const newVariable = new LocalVariable(identifier.name, identifier, init, includedInitPath, context, kind);
5153
5223
  this.variables.set(name, newVariable);
5154
5224
  return newVariable;
5155
5225
  }
@@ -5351,7 +5421,7 @@ class BlockScope extends ChildScope {
5351
5421
  constructor(parent) {
5352
5422
  super(parent, parent.context);
5353
5423
  }
5354
- addDeclaration(identifier, context, init, kind) {
5424
+ addDeclaration(identifier, context, init, includedInitPath, kind) {
5355
5425
  if (kind === 'var') {
5356
5426
  const name = identifier.name;
5357
5427
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -5363,7 +5433,7 @@ class BlockScope extends ChildScope {
5363
5433
  }
5364
5434
  return context.error(logRedeclarationError(name), identifier.start);
5365
5435
  }
5366
- const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind);
5436
+ const declaredVariable = this.parent.addDeclaration(identifier, context, init, includedInitPath, kind);
5367
5437
  // Necessary to make sure the init is deoptimized for conditional declarations.
5368
5438
  // We cannot call deoptimizePath here.
5369
5439
  declaredVariable.markInitializersForDeoptimization();
@@ -5371,7 +5441,7 @@ class BlockScope extends ChildScope {
5371
5441
  this.addHoistedVariable(name, declaredVariable);
5372
5442
  return declaredVariable;
5373
5443
  }
5374
- return super.addDeclaration(identifier, context, init, kind);
5444
+ return super.addDeclaration(identifier, context, init, includedInitPath, kind);
5375
5445
  }
5376
5446
  }
5377
5447
 
@@ -5386,11 +5456,11 @@ class StaticBlock extends NodeBase {
5386
5456
  }
5387
5457
  return false;
5388
5458
  }
5389
- include(context, includeChildrenRecursively) {
5459
+ includePath(_path, context, includeChildrenRecursively) {
5390
5460
  this.included = true;
5391
5461
  for (const node of this.body) {
5392
5462
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
5393
- node.include(context, includeChildrenRecursively);
5463
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
5394
5464
  }
5395
5465
  }
5396
5466
  render(code, options) {
@@ -5469,22 +5539,22 @@ class ClassNode extends NodeBase {
5469
5539
  false
5470
5540
  : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
5471
5541
  }
5472
- include(context, includeChildrenRecursively) {
5542
+ includePath(_path, context, includeChildrenRecursively) {
5473
5543
  if (!this.deoptimized)
5474
5544
  this.applyDeoptimizations();
5475
5545
  this.included = true;
5476
- this.superClass?.include(context, includeChildrenRecursively);
5477
- this.body.include(context, includeChildrenRecursively);
5546
+ this.superClass?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
5547
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
5478
5548
  for (const decorator of this.decorators)
5479
- decorator.include(context, includeChildrenRecursively);
5549
+ decorator.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
5480
5550
  if (this.id) {
5481
5551
  this.id.markDeclarationReached();
5482
- this.id.include();
5552
+ this.id.includePath(UNKNOWN_PATH, createInclusionContext());
5483
5553
  }
5484
5554
  }
5485
5555
  initialise() {
5486
5556
  super.initialise();
5487
- this.id?.declare('class', this);
5557
+ this.id?.declare('class', EMPTY_PATH, this);
5488
5558
  for (const method of this.body.body) {
5489
5559
  if (method instanceof MethodDefinition && method.kind === 'constructor') {
5490
5560
  this.classConstructor = method;
@@ -5599,7 +5669,7 @@ class ClassDeclaration extends ClassNode {
5599
5669
 
5600
5670
  class ArgumentsVariable extends LocalVariable {
5601
5671
  constructor(context) {
5602
- super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');
5672
+ super('arguments', null, UNKNOWN_EXPRESSION, EMPTY_PATH, context, 'other');
5603
5673
  this.deoptimizedArguments = [];
5604
5674
  }
5605
5675
  addArgumentToBeDeoptimized(argument) {
@@ -5613,8 +5683,8 @@ class ArgumentsVariable extends LocalVariable {
5613
5683
  hasEffectsOnInteractionAtPath(path, { type }) {
5614
5684
  return type !== INTERACTION_ACCESSED || path.length > 1;
5615
5685
  }
5616
- include() {
5617
- super.include();
5686
+ includePath(path, context) {
5687
+ super.includePath(path, context);
5618
5688
  for (const argument of this.deoptimizedArguments) {
5619
5689
  argument.deoptimizePath(UNKNOWN_PATH);
5620
5690
  }
@@ -5625,27 +5695,28 @@ class ArgumentsVariable extends LocalVariable {
5625
5695
  const MAX_TRACKED_INTERACTIONS = 20;
5626
5696
  const NO_INTERACTIONS = EMPTY_ARRAY;
5627
5697
  const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);
5628
- const EMPTY_PATH_TRACKER = new PathTracker();
5698
+ const EMPTY_PATH_TRACKER = new EntityPathTracker();
5629
5699
  const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);
5630
5700
  class ParameterVariable extends LocalVariable {
5631
- constructor(name, declarator, context) {
5632
- super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');
5701
+ constructor(name, declarator, argumentPath, context) {
5702
+ super(name, declarator, UNKNOWN_EXPRESSION, argumentPath, context, 'parameter');
5633
5703
  this.deoptimizationInteractions = [];
5634
- this.deoptimizations = new PathTracker();
5704
+ this.deoptimizations = new EntityPathTracker();
5635
5705
  this.deoptimizedFields = new Set();
5636
- this.entitiesToBeDeoptimized = new Set();
5637
- this.expressionsUseTheKnownValue = [];
5706
+ this.argumentsToBeDeoptimized = new Set();
5707
+ this.expressionsDependingOnKnownValue = [];
5638
5708
  this.knownValue = null;
5639
5709
  this.knownValueLiteral = UnknownValue;
5640
5710
  this.frozenValue = null;
5641
5711
  }
5642
- addEntityToBeDeoptimized(entity) {
5712
+ addArgumentValue(entity) {
5713
+ this.updateKnownValue(entity);
5643
5714
  if (entity === UNKNOWN_EXPRESSION) {
5644
5715
  // As unknown expressions fully deoptimize all interactions, we can clear
5645
5716
  // the interaction cache at this point provided we keep this optimization
5646
5717
  // in mind when adding new interactions
5647
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5648
- this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);
5718
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5719
+ this.argumentsToBeDeoptimized.add(UNKNOWN_EXPRESSION);
5649
5720
  for (const { interaction } of this.deoptimizationInteractions) {
5650
5721
  deoptimizeInteraction(interaction);
5651
5722
  }
@@ -5655,27 +5726,30 @@ class ParameterVariable extends LocalVariable {
5655
5726
  else if (this.deoptimizedFields.has(UnknownKey)) {
5656
5727
  // This means that we already deoptimized all interactions and no longer
5657
5728
  // track them
5658
- entity.deoptimizePath(UNKNOWN_PATH);
5729
+ entity.deoptimizePath([...this.initPath, UnknownKey]);
5659
5730
  }
5660
- else if (!this.entitiesToBeDeoptimized.has(entity)) {
5661
- this.entitiesToBeDeoptimized.add(entity);
5731
+ else if (!this.argumentsToBeDeoptimized.has(entity)) {
5732
+ this.argumentsToBeDeoptimized.add(entity);
5662
5733
  for (const field of this.deoptimizedFields) {
5663
- entity.deoptimizePath([field]);
5734
+ entity.deoptimizePath([...this.initPath, field]);
5664
5735
  }
5665
5736
  for (const { interaction, path } of this.deoptimizationInteractions) {
5666
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
5737
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
5667
5738
  }
5668
5739
  }
5669
5740
  }
5741
+ /** This says we should not make assumptions about the value of the parameter.
5742
+ * This is different from deoptimization that will also cause argument values
5743
+ * to be deoptimized. */
5670
5744
  markReassigned() {
5671
5745
  if (this.isReassigned) {
5672
5746
  return;
5673
5747
  }
5674
5748
  super.markReassigned();
5675
- for (const expression of this.expressionsUseTheKnownValue) {
5749
+ for (const expression of this.expressionsDependingOnKnownValue) {
5676
5750
  expression.deoptimizeCache();
5677
5751
  }
5678
- this.expressionsUseTheKnownValue = EMPTY_ARRAY;
5752
+ this.expressionsDependingOnKnownValue = EMPTY_ARRAY;
5679
5753
  }
5680
5754
  deoptimizeCache() {
5681
5755
  this.markReassigned();
@@ -5692,7 +5766,7 @@ class ParameterVariable extends LocalVariable {
5692
5766
  }
5693
5767
  if (this.knownValue === null) {
5694
5768
  this.knownValue = argument;
5695
- this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
5769
+ this.knownValueLiteral = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
5696
5770
  return;
5697
5771
  }
5698
5772
  // the same literal or identifier, do nothing
@@ -5708,7 +5782,7 @@ class ParameterVariable extends LocalVariable {
5708
5782
  return;
5709
5783
  }
5710
5784
  // add tracking for the new argument
5711
- const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
5785
+ const newValue = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
5712
5786
  if (newValue !== oldValue) {
5713
5787
  this.markReassigned();
5714
5788
  }
@@ -5730,20 +5804,25 @@ class ParameterVariable extends LocalVariable {
5730
5804
  return UnknownValue;
5731
5805
  }
5732
5806
  const knownValue = this.getKnownValue();
5733
- this.expressionsUseTheKnownValue.push(origin);
5734
- return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);
5807
+ this.expressionsDependingOnKnownValue.push(origin);
5808
+ return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin), UnknownValue);
5735
5809
  }
5736
5810
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5737
- if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) {
5811
+ const { type } = interaction;
5812
+ if (this.isReassigned || type === INTERACTION_ASSIGNED) {
5738
5813
  return super.hasEffectsOnInteractionAtPath(path, interaction, context);
5739
5814
  }
5740
- const knownValue = this.getKnownValue();
5741
- return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context);
5815
+ return (!(type === INTERACTION_CALLED
5816
+ ? (interaction.withNew
5817
+ ? context.instantiated
5818
+ : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)
5819
+ : context.accessed.trackEntityAtPathAndGetIfTracked(path, this)) &&
5820
+ this.getKnownValue().hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
5742
5821
  }
5743
5822
  deoptimizeArgumentsOnInteractionAtPath(interaction, path) {
5744
5823
  // For performance reasons, we fully deoptimize all deeper interactions
5745
5824
  if (path.length >= 2 ||
5746
- this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
5825
+ this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
5747
5826
  this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||
5748
5827
  (path.length === 1 &&
5749
5828
  (this.deoptimizedFields.has(UnknownKey) ||
@@ -5752,10 +5831,10 @@ class ParameterVariable extends LocalVariable {
5752
5831
  return;
5753
5832
  }
5754
5833
  if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {
5755
- for (const entity of this.entitiesToBeDeoptimized) {
5756
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
5834
+ for (const entity of this.argumentsToBeDeoptimized) {
5835
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
5757
5836
  }
5758
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5837
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5759
5838
  this.deoptimizationInteractions.push({
5760
5839
  interaction,
5761
5840
  path
@@ -5776,17 +5855,17 @@ class ParameterVariable extends LocalVariable {
5776
5855
  return;
5777
5856
  }
5778
5857
  this.deoptimizedFields.add(key);
5779
- for (const entity of this.entitiesToBeDeoptimized) {
5858
+ for (const entity of this.argumentsToBeDeoptimized) {
5780
5859
  // We do not need a recursion tracker here as we already track whether
5781
5860
  // this field is deoptimized
5782
- entity.deoptimizePath([key]);
5861
+ entity.deoptimizePath([...this.initPath, key]);
5783
5862
  }
5784
5863
  if (key === UnknownKey) {
5785
5864
  // save some memory
5786
5865
  this.deoptimizationInteractions = NO_INTERACTIONS;
5787
5866
  this.deoptimizations = EMPTY_PATH_TRACKER;
5788
5867
  this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;
5789
- this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
5868
+ this.argumentsToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
5790
5869
  }
5791
5870
  }
5792
5871
  getReturnExpressionWhenCalledAtPath(path) {
@@ -5801,11 +5880,14 @@ class ParameterVariable extends LocalVariable {
5801
5880
  }
5802
5881
  return UNKNOWN_RETURN_EXPRESSION;
5803
5882
  }
5883
+ includeArgumentPaths(entity, context) {
5884
+ this.includedPathTracker.includeAllPaths(entity, context, this.initPath);
5885
+ }
5804
5886
  }
5805
5887
 
5806
5888
  class ThisVariable extends ParameterVariable {
5807
5889
  constructor(context) {
5808
- super('this', null, context);
5890
+ super('this', null, EMPTY_PATH, context);
5809
5891
  }
5810
5892
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5811
5893
  return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);
@@ -5817,7 +5899,7 @@ class CatchBodyScope extends ChildScope {
5817
5899
  super(parent, parent.context);
5818
5900
  this.parent = parent;
5819
5901
  }
5820
- addDeclaration(identifier, context, init, kind) {
5902
+ addDeclaration(identifier, context, init, includedInitPath, kind) {
5821
5903
  if (kind === 'var') {
5822
5904
  const name = identifier.name;
5823
5905
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -5830,7 +5912,7 @@ class CatchBodyScope extends ChildScope {
5830
5912
  // the assignment actually goes to the parameter and the var is
5831
5913
  // hoisted without assignment. Locally, it is shadowed by the
5832
5914
  // parameter
5833
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, kind);
5915
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, includedInitPath, kind);
5834
5916
  // To avoid the need to rewrite the declaration, we link the variable
5835
5917
  // names. If we ever implement a logic that splits initialization and
5836
5918
  // assignment for hoisted vars, the "renderLikeHoisted" logic can be
@@ -5849,7 +5931,7 @@ class CatchBodyScope extends ChildScope {
5849
5931
  return context.error(logRedeclarationError(name), identifier.start);
5850
5932
  }
5851
5933
  // We only add parameters to parameter scopes
5852
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, kind);
5934
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, includedInitPath, kind);
5853
5935
  // Necessary to make sure the init is deoptimized for conditional declarations.
5854
5936
  // We cannot call deoptimizePath here.
5855
5937
  declaredVariable.markInitializersForDeoptimization();
@@ -5857,7 +5939,7 @@ class CatchBodyScope extends ChildScope {
5857
5939
  this.addHoistedVariable(name, declaredVariable);
5858
5940
  return declaredVariable;
5859
5941
  }
5860
- return super.addDeclaration(identifier, context, init, kind);
5942
+ return super.addDeclaration(identifier, context, init, includedInitPath, kind);
5861
5943
  }
5862
5944
  }
5863
5945
 
@@ -5867,7 +5949,7 @@ class FunctionBodyScope extends ChildScope {
5867
5949
  }
5868
5950
  // There is stuff that is only allowed in function scopes, i.e. functions can
5869
5951
  // be redeclared, functions and var can redeclare each other
5870
- addDeclaration(identifier, context, init, kind) {
5952
+ addDeclaration(identifier, context, init, includedInitPath, kind) {
5871
5953
  const name = identifier.name;
5872
5954
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
5873
5955
  if (existingVariable) {
@@ -5879,7 +5961,7 @@ class FunctionBodyScope extends ChildScope {
5879
5961
  }
5880
5962
  context.error(logRedeclarationError(name), identifier.start);
5881
5963
  }
5882
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
5964
+ const newVariable = new LocalVariable(identifier.name, identifier, init, includedInitPath, context, kind);
5883
5965
  this.variables.set(name, newVariable);
5884
5966
  return newVariable;
5885
5967
  }
@@ -5888,21 +5970,21 @@ class FunctionBodyScope extends ChildScope {
5888
5970
  class ParameterScope extends ChildScope {
5889
5971
  constructor(parent, isCatchScope) {
5890
5972
  super(parent, parent.context);
5891
- this.parameters = [];
5892
5973
  this.hasRest = false;
5974
+ this.parameters = [];
5893
5975
  this.bodyScope = isCatchScope ? new CatchBodyScope(this) : new FunctionBodyScope(this);
5894
5976
  }
5895
5977
  /**
5896
5978
  * Adds a parameter to this scope. Parameters must be added in the correct
5897
5979
  * order, i.e. from left to right.
5898
5980
  */
5899
- addParameterDeclaration(identifier) {
5981
+ addParameterDeclaration(identifier, argumentPath) {
5900
5982
  const { name, start } = identifier;
5901
5983
  const existingParameter = this.variables.get(name);
5902
5984
  if (existingParameter) {
5903
5985
  return this.context.error(logDuplicateArgumentNameError(name), start);
5904
5986
  }
5905
- const variable = new ParameterVariable(name, identifier, this.context);
5987
+ const variable = new ParameterVariable(name, identifier, argumentPath, this.context);
5906
5988
  this.variables.set(name, variable);
5907
5989
  // We also add it to the body scope to detect name conflicts with local
5908
5990
  // variables. We still need the intermediate scope, though, as parameter
@@ -5920,43 +6002,54 @@ class ParameterScope extends ChildScope {
5920
6002
  }
5921
6003
  this.hasRest = hasRest;
5922
6004
  }
5923
- includeCallArguments(context, parameters) {
6005
+ includeCallArguments(context, interaction) {
5924
6006
  let calledFromTryStatement = false;
5925
6007
  let argumentIncluded = false;
5926
6008
  const restParameter = this.hasRest && this.parameters[this.parameters.length - 1];
5927
- for (const checkedArgument of parameters) {
5928
- if (checkedArgument instanceof SpreadElement) {
5929
- for (const argument of parameters) {
5930
- argument.include(context, false);
5931
- }
5932
- break;
6009
+ const { args } = interaction;
6010
+ let lastExplicitlyIncludedIndex = args.length - 1;
6011
+ // If there is a SpreadElement, we need to include all arguments after it
6012
+ // because we no longer know which argument corresponds to which parameter.
6013
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
6014
+ if (args[argumentIndex] instanceof SpreadElement && !argumentIncluded) {
6015
+ argumentIncluded = true;
6016
+ lastExplicitlyIncludedIndex = argumentIndex - 1;
6017
+ }
6018
+ if (argumentIncluded) {
6019
+ args[argumentIndex].includePath(UNKNOWN_PATH, context, false);
5933
6020
  }
5934
6021
  }
5935
- for (let index = parameters.length - 1; index >= 0; index--) {
5936
- const parameterVariables = this.parameters[index] || restParameter;
5937
- const argument = parameters[index];
6022
+ // Now we go backwards either starting from the last argument or before the
6023
+ // first SpreadElement to ensure all arguments before are included as needed
6024
+ for (let index = lastExplicitlyIncludedIndex; index >= 1; index--) {
6025
+ const parameterVariables = this.parameters[index - 1] || restParameter;
6026
+ const argument = args[index];
5938
6027
  if (parameterVariables) {
5939
6028
  calledFromTryStatement = false;
5940
6029
  if (parameterVariables.length === 0) {
5941
- // handle empty destructuring
6030
+ // handle empty destructuring to avoid destructuring undefined
5942
6031
  argumentIncluded = true;
5943
6032
  }
5944
6033
  else {
5945
6034
  for (const variable of parameterVariables) {
5946
- if (variable.included) {
5947
- argumentIncluded = true;
5948
- }
5949
6035
  if (variable.calledFromTryStatement) {
5950
6036
  calledFromTryStatement = true;
5951
6037
  }
6038
+ if (variable.included) {
6039
+ argumentIncluded = true;
6040
+ if (calledFromTryStatement) {
6041
+ argument.includePath(UNKNOWN_PATH, context, true);
6042
+ }
6043
+ else {
6044
+ variable.includeArgumentPaths(argument, context);
6045
+ }
6046
+ }
5952
6047
  }
5953
6048
  }
5954
6049
  }
5955
- if (!argumentIncluded && argument.shouldBeIncluded(context)) {
6050
+ if (!argument.included && (argumentIncluded || argument.shouldBeIncluded(context))) {
5956
6051
  argumentIncluded = true;
5957
- }
5958
- if (argumentIncluded) {
5959
- argument.include(context, calledFromTryStatement);
6052
+ argument.includePath(EMPTY_PATH, context, calledFromTryStatement);
5960
6053
  }
5961
6054
  }
5962
6055
  }
@@ -5971,11 +6064,61 @@ class ReturnValueScope extends ParameterScope {
5971
6064
  addReturnExpression(expression) {
5972
6065
  this.returnExpressions.push(expression);
5973
6066
  }
6067
+ deoptimizeArgumentsOnCall(interaction) {
6068
+ const { parameters } = this;
6069
+ const { args } = interaction;
6070
+ let position = 0;
6071
+ for (; position < args.length - 1; position++) {
6072
+ // Only the "this" argument arg[0] can be null
6073
+ const argument = args[position + 1];
6074
+ if (argument instanceof SpreadElement) {
6075
+ // This deoptimizes the current and remaining parameters and arguments
6076
+ for (; position < parameters.length; position++) {
6077
+ args[position + 1]?.deoptimizePath(UNKNOWN_PATH);
6078
+ parameters[position].forEach(variable => variable.markReassigned());
6079
+ }
6080
+ break;
6081
+ }
6082
+ if (this.hasRest && position >= parameters.length - 1) {
6083
+ argument.deoptimizePath(UNKNOWN_PATH);
6084
+ }
6085
+ else {
6086
+ const variables = parameters[position];
6087
+ if (variables) {
6088
+ for (const variable of variables) {
6089
+ variable.addArgumentValue(argument);
6090
+ }
6091
+ }
6092
+ this.addArgumentToBeDeoptimized(argument);
6093
+ }
6094
+ }
6095
+ for (; position < parameters.length; position++) {
6096
+ for (const variable of parameters[position]) {
6097
+ variable.addArgumentValue(UNDEFINED_EXPRESSION);
6098
+ }
6099
+ }
6100
+ }
5974
6101
  getReturnExpression() {
5975
6102
  if (this.returnExpression === null)
5976
6103
  this.updateReturnExpression();
5977
6104
  return this.returnExpression;
5978
6105
  }
6106
+ deoptimizeAllParameters() {
6107
+ for (const parameter of this.parameters) {
6108
+ for (const variable of parameter) {
6109
+ variable.deoptimizePath(UNKNOWN_PATH);
6110
+ variable.markReassigned();
6111
+ }
6112
+ }
6113
+ }
6114
+ reassignAllParameters() {
6115
+ for (const parameter of this.parameters) {
6116
+ for (const variable of parameter) {
6117
+ variable.markReassigned();
6118
+ }
6119
+ }
6120
+ }
6121
+ addArgumentToBeDeoptimized(_argument) { }
5979
6122
  updateReturnExpression() {
5980
6123
  if (this.returnExpressions.length === 1) {
5981
6124
  this.returnExpression = this.returnExpressions[0];
@@ -5991,24 +6134,26 @@ class ReturnValueScope extends ParameterScope {
5991
6134
 
5992
6135
  class FunctionScope extends ReturnValueScope {
5993
6136
  constructor(parent) {
5994
- const { context } = parent;
5995
6137
  super(parent, false);
6138
+ const { context } = parent;
5996
6139
  this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));
5997
6140
  this.variables.set('this', (this.thisVariable = new ThisVariable(context)));
5998
6141
  }
5999
6142
  findLexicalBoundary() {
6000
6143
  return this;
6001
6144
  }
6002
- includeCallArguments(context, parameters) {
6003
- super.includeCallArguments(context, parameters);
6145
+ includeCallArguments(context, interaction) {
6146
+ super.includeCallArguments(context, interaction);
6004
6147
  if (this.argumentsVariable.included) {
6005
- for (const argument of parameters) {
6006
- if (!argument.included) {
6007
- argument.include(context, false);
6008
- }
6148
+ const { args } = interaction;
6149
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
6150
+ args[argumentIndex]?.includePath(UNKNOWN_PATH, context, false);
6009
6151
  }
6010
6152
  }
6011
6153
  }
6154
+ addArgumentToBeDeoptimized(argument) {
6155
+ this.argumentsVariable.addArgumentToBeDeoptimized(argument);
6156
+ }
6012
6157
  }
6013
6158
 
6014
6159
  class ExpressionStatement extends NodeBase {
@@ -6074,7 +6219,7 @@ class BlockStatement extends NodeBase {
6074
6219
  }
6075
6220
  return false;
6076
6221
  }
6077
- include(context, includeChildrenRecursively) {
6222
+ includePath(_path, context, includeChildrenRecursively) {
6078
6223
  if (!(this.deoptimizeBody && this.directlyIncluded)) {
6079
6224
  this.included = true;
6080
6225
  this.directlyIncluded = true;
@@ -6082,7 +6227,7 @@ class BlockStatement extends NodeBase {
6082
6227
  includeChildrenRecursively = true;
6083
6228
  for (const node of this.body) {
6084
6229
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
6085
- node.include(context, includeChildrenRecursively);
6230
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
6086
6231
  }
6087
6232
  }
6088
6233
  }
@@ -6111,9 +6256,9 @@ class RestElement extends NodeBase {
6111
6256
  addExportedVariables(variables, exportNamesByVariable) {
6112
6257
  this.argument.addExportedVariables(variables, exportNamesByVariable);
6113
6258
  }
6114
- declare(kind, init) {
6259
+ declare(kind, includedInitPath, init) {
6115
6260
  this.declarationInit = init;
6116
- return this.argument.declare(kind, UNKNOWN_EXPRESSION);
6261
+ return this.argument.declare(kind, includedInitPath.at(-1) === UnknownKey ? includedInitPath : [...includedInitPath, UnknownKey], init);
6117
6262
  }
6118
6263
  deoptimizePath(path) {
6119
6264
  if (path.length === 0) {
@@ -6124,6 +6269,12 @@ class RestElement extends NodeBase {
6124
6269
  return (path.length > 0 ||
6125
6270
  this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
6126
6271
  }
6272
+ includePath(_path, context, includeChildrenRecursively) {
6273
+ this.included = true;
6274
+ // This should just include the identifier, its properties should be
6275
+ // included where the variable is used.
6276
+ this.argument.includePath(EMPTY_PATH, context, includeChildrenRecursively);
6277
+ }
6127
6278
  markDeclarationReached() {
6128
6279
  this.argument.markDeclarationReached();
6129
6280
  }
@@ -6139,8 +6290,8 @@ class RestElement extends NodeBase {
6139
6290
  class FunctionBase extends NodeBase {
6140
6291
  constructor() {
6141
6292
  super(...arguments);
6142
- this.objectEntity = null;
6143
6293
  this.parameterVariableValuesDeoptimized = false;
6294
+ this.includeCallArguments = this.scope.includeCallArguments.bind(this.scope);
6144
6295
  }
6145
6296
  get async() {
6146
6297
  return isFlagSet(this.flags, 256 /* Flag.async */);
@@ -6160,53 +6311,9 @@ class FunctionBase extends NodeBase {
6160
6311
  set generator(value) {
6161
6312
  this.flags = setFlag(this.flags, 4194304 /* Flag.generator */, value);
6162
6313
  }
6163
- updateParameterVariableValues(_arguments) {
6164
- for (let position = 0; position < this.params.length; position++) {
6165
- const parameter = this.params[position];
6166
- if (!(parameter instanceof Identifier)) {
6167
- continue;
6168
- }
6169
- const parameterVariable = parameter.variable;
6170
- const argument = _arguments[position + 1] ?? UNDEFINED_EXPRESSION;
6171
- parameterVariable.updateKnownValue(argument);
6172
- }
6173
- }
6174
- deoptimizeParameterVariableValues() {
6175
- for (const parameter of this.params) {
6176
- if (parameter instanceof Identifier) {
6177
- const parameterVariable = parameter.variable;
6178
- parameterVariable.markReassigned();
6179
- }
6180
- }
6181
- }
6182
6314
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6183
- if (interaction.type === INTERACTION_CALLED) {
6184
- const { parameters } = this.scope;
6185
- const { args } = interaction;
6186
- let hasRest = false;
6187
- for (let position = 0; position < args.length - 1; position++) {
6188
- const parameter = this.params[position];
6189
- // Only the "this" argument arg[0] can be null
6190
- const argument = args[position + 1];
6191
- if (argument instanceof SpreadElement) {
6192
- this.deoptimizeParameterVariableValues();
6193
- }
6194
- if (hasRest || parameter instanceof RestElement) {
6195
- hasRest = true;
6196
- argument.deoptimizePath(UNKNOWN_PATH);
6197
- }
6198
- else if (parameter instanceof Identifier) {
6199
- parameters[position][0].addEntityToBeDeoptimized(argument);
6200
- this.addArgumentToBeDeoptimized(argument);
6201
- }
6202
- else if (parameter) {
6203
- argument.deoptimizePath(UNKNOWN_PATH);
6204
- }
6205
- else {
6206
- this.addArgumentToBeDeoptimized(argument);
6207
- }
6208
- }
6209
- this.updateParameterVariableValues(args);
6315
+ if (interaction.type === INTERACTION_CALLED && path.length === 0) {
6316
+ this.scope.deoptimizeArgumentsOnCall(interaction);
6210
6317
  }
6211
6318
  else {
6212
6319
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -6218,12 +6325,7 @@ class FunctionBase extends NodeBase {
6218
6325
  // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
6219
6326
  // which means the return expression and parameters need to be reassigned
6220
6327
  this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
6221
- for (const parameterList of this.scope.parameters) {
6222
- for (const parameter of parameterList) {
6223
- parameter.deoptimizePath(UNKNOWN_PATH);
6224
- parameter.markReassigned();
6225
- }
6226
- }
6328
+ this.scope.deoptimizeAllParameters();
6227
6329
  }
6228
6330
  }
6229
6331
  getLiteralValueAtPath(path, recursionTracker, origin) {
@@ -6280,22 +6382,19 @@ class FunctionBase extends NodeBase {
6280
6382
  }
6281
6383
  return variable?.getOnlyFunctionCallUsed() ?? false;
6282
6384
  }
6283
- include(context, includeChildrenRecursively) {
6284
- if (!this.parameterVariableValuesDeoptimized && !this.onlyFunctionCallUsed()) {
6385
+ includePath(_path, context, includeChildrenRecursively) {
6386
+ if (!(this.parameterVariableValuesDeoptimized || this.onlyFunctionCallUsed())) {
6285
6387
  this.parameterVariableValuesDeoptimized = true;
6286
- this.deoptimizeParameterVariableValues();
6388
+ this.scope.reassignAllParameters();
6287
6389
  }
6288
6390
  if (!this.deoptimized)
6289
6391
  this.applyDeoptimizations();
6290
6392
  this.included = true;
6291
6393
  const { brokenFlow } = context;
6292
6394
  context.brokenFlow = false;
6293
- this.body.include(context, includeChildrenRecursively);
6395
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
6294
6396
  context.brokenFlow = brokenFlow;
6295
6397
  }
6296
- includeCallArguments(context, parameters) {
6297
- this.scope.includeCallArguments(context, parameters);
6298
- }
6299
6398
  initialise() {
6300
6399
  super.initialise();
6301
6400
  if (this.body instanceof BlockStatement) {
@@ -6317,11 +6416,10 @@ class FunctionBase extends NodeBase {
6317
6416
  // so that the scope already knows all parameters and can detect conflicts
6318
6417
  // when parsing the body.
6319
6418
  const parameters = (this.params = params.map((parameter) => new (context.getNodeConstructor(parameter.type))(this, scope).parseNode(parameter)));
6320
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
6419
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
6321
6420
  this.body = new (context.getNodeConstructor(body.type))(this, bodyScope).parseNode(body);
6322
6421
  return super.parseNode(esTreeNode);
6323
6422
  }
6324
- addArgumentToBeDeoptimized(_argument) { }
6325
6423
  applyDeoptimizations() { }
6326
6424
  }
6327
6425
  FunctionBase.prototype.preventChildBlockScope = true;
@@ -6336,13 +6434,13 @@ class FunctionNode extends FunctionBase {
6336
6434
  this.constructedEntity = new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE);
6337
6435
  // This makes sure that all deoptimizations of "this" are applied to the
6338
6436
  // constructed entity.
6339
- this.scope.thisVariable.addEntityToBeDeoptimized(this.constructedEntity);
6437
+ this.scope.thisVariable.addArgumentValue(this.constructedEntity);
6340
6438
  }
6341
6439
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6342
6440
  super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
6343
6441
  if (interaction.type === INTERACTION_CALLED && path.length === 0 && interaction.args[0]) {
6344
6442
  // args[0] is the "this" argument
6345
- this.scope.thisVariable.addEntityToBeDeoptimized(interaction.args[0]);
6443
+ this.scope.thisVariable.addArgumentValue(interaction.args[0]);
6346
6444
  }
6347
6445
  }
6348
6446
  hasEffects(context) {
@@ -6383,22 +6481,19 @@ class FunctionNode extends FunctionBase {
6383
6481
  }
6384
6482
  return false;
6385
6483
  }
6386
- include(context, includeChildrenRecursively) {
6387
- super.include(context, includeChildrenRecursively);
6388
- this.id?.include();
6484
+ includePath(path, context, includeChildrenRecursively) {
6485
+ super.includePath(path, context, includeChildrenRecursively);
6486
+ this.id?.includePath(UNKNOWN_PATH, createInclusionContext());
6389
6487
  const hasArguments = this.scope.argumentsVariable.included;
6390
6488
  for (const parameter of this.params) {
6391
6489
  if (!(parameter instanceof Identifier) || hasArguments) {
6392
- parameter.include(context, includeChildrenRecursively);
6490
+ parameter.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
6393
6491
  }
6394
6492
  }
6395
6493
  }
6396
6494
  initialise() {
6397
6495
  super.initialise();
6398
- this.id?.declare('function', this);
6399
- }
6400
- addArgumentToBeDeoptimized(argument) {
6401
- this.scope.argumentsVariable.addArgumentToBeDeoptimized(argument);
6496
+ this.id?.declare('function', EMPTY_PATH, this);
6402
6497
  }
6403
6498
  getObjectEntity() {
6404
6499
  if (this.objectEntity !== null) {
@@ -6447,10 +6542,11 @@ function getFunctionIdInsertPosition(code, start) {
6447
6542
  return declarationEnd + generatorStarPos + 1;
6448
6543
  }
6449
6544
  class ExportDefaultDeclaration extends NodeBase {
6450
- include(context, includeChildrenRecursively) {
6451
- super.include(context, includeChildrenRecursively);
6545
+ includePath(path, context, includeChildrenRecursively) {
6546
+ this.included = true;
6547
+ this.declaration.includePath(path, context, includeChildrenRecursively);
6452
6548
  if (includeChildrenRecursively) {
6453
- this.scope.context.includeVariableInModule(this.variable);
6549
+ this.scope.context.includeVariableInModule(this.variable, path);
6454
6550
  }
6455
6551
  }
6456
6552
  initialise() {
@@ -7023,27 +7119,27 @@ class MemberExpression extends NodeBase {
7023
7119
  }
7024
7120
  return true;
7025
7121
  }
7026
- include(context, includeChildrenRecursively) {
7122
+ includePath(path, context, includeChildrenRecursively) {
7027
7123
  if (!this.deoptimized)
7028
7124
  this.applyDeoptimizations();
7029
- this.includeProperties(context, includeChildrenRecursively);
7125
+ this.includeProperties(path, [this.getPropertyKey(), ...path], context, includeChildrenRecursively);
7030
7126
  }
7031
7127
  includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {
7032
7128
  if (!this.assignmentDeoptimized)
7033
7129
  this.applyAssignmentDeoptimization();
7034
7130
  if (deoptimizeAccess) {
7035
- this.include(context, includeChildrenRecursively);
7131
+ this.includePath([this.getPropertyKey()], context, includeChildrenRecursively);
7036
7132
  }
7037
7133
  else {
7038
- this.includeProperties(context, includeChildrenRecursively);
7134
+ this.includeProperties(EMPTY_PATH, [this.getPropertyKey()], context, includeChildrenRecursively);
7039
7135
  }
7040
7136
  }
7041
- includeCallArguments(context, parameters) {
7137
+ includeCallArguments(context, interaction) {
7042
7138
  if (this.variable) {
7043
- this.variable.includeCallArguments(context, parameters);
7139
+ this.variable.includeCallArguments(context, interaction);
7044
7140
  }
7045
7141
  else {
7046
- super.includeCallArguments(context, parameters);
7142
+ super.includeCallArguments(context, interaction);
7047
7143
  }
7048
7144
  }
7049
7145
  initialise() {
@@ -7112,7 +7208,7 @@ class MemberExpression extends NodeBase {
7112
7208
  const variable = this.scope.findVariable(this.object.name);
7113
7209
  if (variable.isNamespace) {
7114
7210
  if (this.variable) {
7115
- this.scope.context.includeVariableInModule(this.variable);
7211
+ this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH);
7116
7212
  }
7117
7213
  this.scope.context.log(LOGLEVEL_WARN, logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);
7118
7214
  }
@@ -7139,15 +7235,18 @@ class MemberExpression extends NodeBase {
7139
7235
  (propertyReadSideEffects === 'always' ||
7140
7236
  this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));
7141
7237
  }
7142
- includeProperties(context, includeChildrenRecursively) {
7238
+ includeProperties(includedPath, objectPath, context, includeChildrenRecursively) {
7143
7239
  if (!this.included) {
7144
7240
  this.included = true;
7145
7241
  if (this.variable) {
7146
- this.scope.context.includeVariableInModule(this.variable);
7242
+ this.scope.context.includeVariableInModule(this.variable, includedPath);
7147
7243
  }
7148
7244
  }
7149
- this.object.include(context, includeChildrenRecursively);
7150
- this.property.include(context, includeChildrenRecursively);
7245
+ else if (includedPath.length > 0) {
7246
+ this.variable?.includePath(includedPath, context);
7247
+ }
7248
+ this.object.includePath(objectPath, context, includeChildrenRecursively);
7249
+ this.property.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7151
7250
  }
7152
7251
  }
7153
7252
  function resolveNamespaceVariables(baseVariable, path, astContext) {
@@ -7190,7 +7289,7 @@ class MetaProperty extends NodeBase {
7190
7289
  hasEffectsOnInteractionAtPath(path, { type }) {
7191
7290
  return path.length > 1 || type !== INTERACTION_ACCESSED;
7192
7291
  }
7193
- include() {
7292
+ includePath() {
7194
7293
  if (!this.included) {
7195
7294
  this.included = true;
7196
7295
  if (this.meta.name === IMPORT) {
@@ -7309,7 +7408,7 @@ class UndefinedVariable extends Variable {
7309
7408
 
7310
7409
  class ExportDefaultVariable extends LocalVariable {
7311
7410
  constructor(name, exportDefaultDeclaration, context) {
7312
- super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');
7411
+ super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, EMPTY_PATH, context, 'other');
7313
7412
  this.hasId = false;
7314
7413
  this.originalId = null;
7315
7414
  this.originalVariable = null;
@@ -7458,8 +7557,8 @@ class NamespaceVariable extends Variable {
7458
7557
  return (!memberVariable ||
7459
7558
  memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));
7460
7559
  }
7461
- include() {
7462
- super.include();
7560
+ includePath(path, context) {
7561
+ super.includePath(path, context);
7463
7562
  this.context.includeAllExports();
7464
7563
  }
7465
7564
  prepare(accessedGlobalsByScope) {
@@ -7552,9 +7651,9 @@ class SyntheticNamedExportVariable extends Variable {
7552
7651
  getName(getPropertyAccess) {
7553
7652
  return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;
7554
7653
  }
7555
- include() {
7556
- super.include();
7557
- this.context.includeVariableInModule(this.syntheticNamespace);
7654
+ includePath(path, context) {
7655
+ super.includePath(path, context);
7656
+ this.context.includeVariableInModule(this.syntheticNamespace, path);
7558
7657
  }
7559
7658
  setRenderNames(baseName, name) {
7560
7659
  super.setRenderNames(baseName, name);
@@ -10751,11 +10850,14 @@ class ArrayPattern extends NodeBase {
10751
10850
  element?.addExportedVariables(variables, exportNamesByVariable);
10752
10851
  }
10753
10852
  }
10754
- declare(kind) {
10853
+ declare(kind, includedInitPath, init) {
10755
10854
  const variables = [];
10855
+ const includedPatternPath = includedInitPath.at(-1) === UnknownKey
10856
+ ? includedInitPath
10857
+ : [...includedInitPath, UnknownInteger];
10756
10858
  for (const element of this.elements) {
10757
10859
  if (element !== null) {
10758
- variables.push(...element.declare(kind, UNKNOWN_EXPRESSION));
10860
+ variables.push(...element.declare(kind, includedPatternPath, init));
10759
10861
  }
10760
10862
  }
10761
10863
  return variables;
@@ -10828,11 +10930,11 @@ class ArrowFunctionExpression extends FunctionBase {
10828
10930
  this.parent.callee === this;
10829
10931
  return isIIFE || super.onlyFunctionCallUsed();
10830
10932
  }
10831
- include(context, includeChildrenRecursively) {
10832
- super.include(context, includeChildrenRecursively);
10933
+ includePath(_path, context, includeChildrenRecursively) {
10934
+ super.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
10833
10935
  for (const parameter of this.params) {
10834
10936
  if (!(parameter instanceof Identifier)) {
10835
- parameter.include(context, includeChildrenRecursively);
10937
+ parameter.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
10836
10938
  }
10837
10939
  }
10838
10940
  }
@@ -10855,10 +10957,10 @@ class ObjectPattern extends NodeBase {
10855
10957
  }
10856
10958
  }
10857
10959
  }
10858
- declare(kind, init) {
10960
+ declare(kind, includedInitPath, init) {
10859
10961
  const variables = [];
10860
10962
  for (const property of this.properties) {
10861
- variables.push(...property.declare(kind, init));
10963
+ variables.push(...property.declare(kind, includedInitPath, init));
10862
10964
  }
10863
10965
  return variables;
10864
10966
  }
@@ -10879,11 +10981,22 @@ class ObjectPattern extends NodeBase {
10879
10981
  }
10880
10982
  return false;
10881
10983
  }
10984
+ includePath(_path, context, includeChildrenRecursively) {
10985
+ this.included = true;
10986
+ for (const property of this.properties) {
10987
+ // Including a pattern should not deeply include its children as that
10988
+ // would include all children of nested variable references. Their paths
10989
+ // will be included via their usages instead, and we store the path in
10990
+ // the pattern when declaring the variables.
10991
+ property.includePath(EMPTY_PATH, context, includeChildrenRecursively);
10992
+ }
10993
+ }
10882
10994
  markDeclarationReached() {
10883
10995
  for (const property of this.properties) {
10884
10996
  property.markDeclarationReached();
10885
10997
  }
10886
10998
  }
10999
+ applyDeoptimizations() { }
10887
11000
  }
10888
11001
 
10889
11002
  class AssignmentExpression extends NodeBase {
@@ -10898,7 +11011,7 @@ class AssignmentExpression extends NodeBase {
10898
11011
  hasEffectsOnInteractionAtPath(path, interaction, context) {
10899
11012
  return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);
10900
11013
  }
10901
- include(context, includeChildrenRecursively) {
11014
+ includePath(_path, context, includeChildrenRecursively) {
10902
11015
  const { deoptimized, left, right, operator } = this;
10903
11016
  if (!deoptimized)
10904
11017
  this.applyDeoptimizations();
@@ -10909,7 +11022,7 @@ class AssignmentExpression extends NodeBase {
10909
11022
  left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {
10910
11023
  left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');
10911
11024
  }
10912
- right.include(context, includeChildrenRecursively);
11025
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
10913
11026
  }
10914
11027
  initialise() {
10915
11028
  super.initialise();
@@ -10981,8 +11094,8 @@ class AssignmentPattern extends NodeBase {
10981
11094
  addExportedVariables(variables, exportNamesByVariable) {
10982
11095
  this.left.addExportedVariables(variables, exportNamesByVariable);
10983
11096
  }
10984
- declare(kind, init) {
10985
- return this.left.declare(kind, init);
11097
+ declare(kind, includedInitPath, init) {
11098
+ return this.left.declare(kind, includedInitPath, init);
10986
11099
  }
10987
11100
  deoptimizePath(path) {
10988
11101
  if (path.length === 0) {
@@ -11013,7 +11126,7 @@ class AwaitExpression extends NodeBase {
11013
11126
  this.applyDeoptimizations();
11014
11127
  return true;
11015
11128
  }
11016
- include(context, includeChildrenRecursively) {
11129
+ includePath(path, context, includeChildrenRecursively) {
11017
11130
  if (!this.deoptimized)
11018
11131
  this.applyDeoptimizations();
11019
11132
  if (!this.included) {
@@ -11027,7 +11140,7 @@ class AwaitExpression extends NodeBase {
11027
11140
  this.scope.context.usesTopLevelAwait = true;
11028
11141
  }
11029
11142
  }
11030
- this.argument.include(context, includeChildrenRecursively);
11143
+ this.argument.includePath(path, context, includeChildrenRecursively);
11031
11144
  }
11032
11145
  }
11033
11146
 
@@ -11109,10 +11222,10 @@ class BreakStatement extends NodeBase {
11109
11222
  context.brokenFlow = true;
11110
11223
  return false;
11111
11224
  }
11112
- include(context) {
11225
+ includePath(_, context) {
11113
11226
  this.included = true;
11114
11227
  if (this.label) {
11115
- this.label.include();
11228
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
11116
11229
  context.includedLabels.add(this.label.name);
11117
11230
  }
11118
11231
  else {
@@ -11306,11 +11419,11 @@ class CallExpression extends CallExpressionBase {
11306
11419
  (calleeHasEffects ||
11307
11420
  this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)));
11308
11421
  }
11309
- include(context, includeChildrenRecursively) {
11422
+ includePath(path, context, includeChildrenRecursively) {
11310
11423
  if (!this.deoptimized)
11311
11424
  this.applyDeoptimizations();
11312
11425
  if (includeChildrenRecursively) {
11313
- super.include(context, includeChildrenRecursively);
11426
+ super.includePath(path, context, includeChildrenRecursively);
11314
11427
  if (includeChildrenRecursively === INCLUDE_PARAMETERS &&
11315
11428
  this.callee instanceof Identifier &&
11316
11429
  this.callee.variable) {
@@ -11319,9 +11432,18 @@ class CallExpression extends CallExpressionBase {
11319
11432
  }
11320
11433
  else {
11321
11434
  this.included = true;
11322
- this.callee.include(context, false);
11435
+ // If the callee is a member expression and does not have a variable, its
11436
+ // object will already be included via the first argument of the
11437
+ // interaction in includeCallArguments. Including it again can lead to
11438
+ // severe performance problems.
11439
+ if (this.callee instanceof MemberExpression && !this.callee.variable) {
11440
+ this.callee.property.includePath(UNKNOWN_PATH, context, false);
11441
+ }
11442
+ else {
11443
+ this.callee.includePath(UNKNOWN_PATH, context, false);
11444
+ }
11445
+ this.callee.includeCallArguments(context, this.interaction);
11323
11446
  }
11324
- this.callee.includeCallArguments(context, this.arguments);
11325
11447
  }
11326
11448
  initialise() {
11327
11449
  super.initialise();
@@ -11360,7 +11482,7 @@ class CatchClause extends NodeBase {
11360
11482
  this.type = type;
11361
11483
  if (param) {
11362
11484
  this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);
11363
- this.param.declare('parameter', UNKNOWN_EXPRESSION);
11485
+ this.param.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
11364
11486
  }
11365
11487
  this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);
11366
11488
  return super.parseNode(esTreeNode);
@@ -11388,7 +11510,7 @@ class ClassBodyScope extends ChildScope {
11388
11510
  constructor(parent, classNode) {
11389
11511
  const { context } = parent;
11390
11512
  super(parent, context);
11391
- this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));
11513
+ this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, EMPTY_PATH, context, 'other')));
11392
11514
  this.instanceScope = new ChildScope(this, context);
11393
11515
  this.instanceScope.variables.set('this', new ThisVariable(context));
11394
11516
  }
@@ -11401,11 +11523,11 @@ class ClassBody extends NodeBase {
11401
11523
  createScope(parentScope) {
11402
11524
  this.scope = new ClassBodyScope(parentScope, this.parent);
11403
11525
  }
11404
- include(context, includeChildrenRecursively) {
11526
+ includePath(_path, context, includeChildrenRecursively) {
11405
11527
  this.included = true;
11406
- this.scope.context.includeVariableInModule(this.scope.thisVariable);
11528
+ this.scope.context.includeVariableInModule(this.scope.thisVariable, UNKNOWN_PATH);
11407
11529
  for (const definition of this.body) {
11408
- definition.include(context, includeChildrenRecursively);
11530
+ definition.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11409
11531
  }
11410
11532
  }
11411
11533
  parseNode(esTreeNode) {
@@ -11528,26 +11650,26 @@ class ConditionalExpression extends NodeBase {
11528
11650
  }
11529
11651
  return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
11530
11652
  }
11531
- include(context, includeChildrenRecursively) {
11653
+ includePath(path, context, includeChildrenRecursively) {
11532
11654
  this.included = true;
11533
11655
  const usedBranch = this.getUsedBranch();
11534
11656
  if (includeChildrenRecursively || this.test.shouldBeIncluded(context) || usedBranch === null) {
11535
- this.test.include(context, includeChildrenRecursively);
11536
- this.consequent.include(context, includeChildrenRecursively);
11537
- this.alternate.include(context, includeChildrenRecursively);
11657
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11658
+ this.consequent.includePath(path, context, includeChildrenRecursively);
11659
+ this.alternate.includePath(path, context, includeChildrenRecursively);
11538
11660
  }
11539
11661
  else {
11540
- usedBranch.include(context, includeChildrenRecursively);
11662
+ usedBranch.includePath(path, context, includeChildrenRecursively);
11541
11663
  }
11542
11664
  }
11543
- includeCallArguments(context, parameters) {
11665
+ includeCallArguments(context, interaction) {
11544
11666
  const usedBranch = this.getUsedBranch();
11545
11667
  if (usedBranch) {
11546
- usedBranch.includeCallArguments(context, parameters);
11668
+ usedBranch.includeCallArguments(context, interaction);
11547
11669
  }
11548
11670
  else {
11549
- this.consequent.includeCallArguments(context, parameters);
11550
- this.alternate.includeCallArguments(context, parameters);
11671
+ this.consequent.includeCallArguments(context, interaction);
11672
+ this.alternate.includeCallArguments(context, interaction);
11551
11673
  }
11552
11674
  }
11553
11675
  removeAnnotations(code) {
@@ -11608,10 +11730,10 @@ class ContinueStatement extends NodeBase {
11608
11730
  context.brokenFlow = true;
11609
11731
  return false;
11610
11732
  }
11611
- include(context) {
11733
+ includePath(_, context) {
11612
11734
  this.included = true;
11613
11735
  if (this.label) {
11614
- this.label.include();
11736
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
11615
11737
  context.includedLabels.add(this.label.name);
11616
11738
  }
11617
11739
  else {
@@ -11654,7 +11776,7 @@ function includeLoopBody(context, body, includeChildrenRecursively) {
11654
11776
  const { brokenFlow, hasBreak, hasContinue } = context;
11655
11777
  context.hasBreak = false;
11656
11778
  context.hasContinue = false;
11657
- body.include(context, includeChildrenRecursively, { asSingleStatement: true });
11779
+ body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively, { asSingleStatement: true });
11658
11780
  context.hasBreak = hasBreak;
11659
11781
  context.hasContinue = hasContinue;
11660
11782
  context.brokenFlow = brokenFlow;
@@ -11666,9 +11788,9 @@ class DoWhileStatement extends NodeBase {
11666
11788
  return true;
11667
11789
  return hasLoopBodyEffects(context, this.body);
11668
11790
  }
11669
- include(context, includeChildrenRecursively) {
11791
+ includePath(_path, context, includeChildrenRecursively) {
11670
11792
  this.included = true;
11671
- this.test.include(context, includeChildrenRecursively);
11793
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11672
11794
  includeLoopBody(context, this.body, includeChildrenRecursively);
11673
11795
  }
11674
11796
  }
@@ -11739,13 +11861,13 @@ class ForInStatement extends NodeBase {
11739
11861
  return true;
11740
11862
  return hasLoopBodyEffects(context, body);
11741
11863
  }
11742
- include(context, includeChildrenRecursively) {
11864
+ includePath(_path, context, includeChildrenRecursively) {
11743
11865
  const { body, deoptimized, left, right } = this;
11744
11866
  if (!deoptimized)
11745
11867
  this.applyDeoptimizations();
11746
11868
  this.included = true;
11747
11869
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
11748
- right.include(context, includeChildrenRecursively);
11870
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11749
11871
  includeLoopBody(context, body, includeChildrenRecursively);
11750
11872
  }
11751
11873
  initialise() {
@@ -11784,13 +11906,13 @@ class ForOfStatement extends NodeBase {
11784
11906
  // Placeholder until proper Symbol.Iterator support
11785
11907
  return true;
11786
11908
  }
11787
- include(context, includeChildrenRecursively) {
11909
+ includePath(_path, context, includeChildrenRecursively) {
11788
11910
  const { body, deoptimized, left, right } = this;
11789
11911
  if (!deoptimized)
11790
11912
  this.applyDeoptimizations();
11791
11913
  this.included = true;
11792
11914
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
11793
- right.include(context, includeChildrenRecursively);
11915
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11794
11916
  includeLoopBody(context, body, includeChildrenRecursively);
11795
11917
  }
11796
11918
  initialise() {
@@ -11826,11 +11948,13 @@ class ForStatement extends NodeBase {
11826
11948
  }
11827
11949
  return hasLoopBodyEffects(context, this.body);
11828
11950
  }
11829
- include(context, includeChildrenRecursively) {
11951
+ includePath(_path, context, includeChildrenRecursively) {
11830
11952
  this.included = true;
11831
- this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true });
11832
- this.test?.include(context, includeChildrenRecursively);
11833
- this.update?.include(context, includeChildrenRecursively);
11953
+ this.init?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively, {
11954
+ asSingleStatement: true
11955
+ });
11956
+ this.test?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11957
+ this.update?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11834
11958
  includeLoopBody(context, this.body, includeChildrenRecursively);
11835
11959
  }
11836
11960
  render(code, options) {
@@ -11871,9 +11995,9 @@ class TrackingScope extends BlockScope {
11871
11995
  super(...arguments);
11872
11996
  this.hoistedDeclarations = [];
11873
11997
  }
11874
- addDeclaration(identifier, context, init, kind) {
11998
+ addDeclaration(identifier, context, init, includedInitPath, kind) {
11875
11999
  this.hoistedDeclarations.push(identifier);
11876
- return super.addDeclaration(identifier, context, init, kind);
12000
+ return super.addDeclaration(identifier, context, init, includedInitPath, kind);
11877
12001
  }
11878
12002
  }
11879
12003
 
@@ -11906,7 +12030,7 @@ class IfStatement extends NodeBase {
11906
12030
  }
11907
12031
  return testValue ? this.consequent.hasEffects(context) : !!this.alternate?.hasEffects(context);
11908
12032
  }
11909
- include(context, includeChildrenRecursively) {
12033
+ includePath(_, context, includeChildrenRecursively) {
11910
12034
  this.included = true;
11911
12035
  if (includeChildrenRecursively) {
11912
12036
  this.includeRecursively(includeChildrenRecursively, context);
@@ -11981,31 +12105,31 @@ class IfStatement extends NodeBase {
11981
12105
  }
11982
12106
  includeKnownTest(context, testValue) {
11983
12107
  if (this.test.shouldBeIncluded(context)) {
11984
- this.test.include(context, false);
12108
+ this.test.includePath(UNKNOWN_PATH, context, false);
11985
12109
  }
11986
12110
  if (testValue && this.consequent.shouldBeIncluded(context)) {
11987
- this.consequent.include(context, false, { asSingleStatement: true });
12111
+ this.consequent.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
11988
12112
  }
11989
12113
  if (!testValue && this.alternate?.shouldBeIncluded(context)) {
11990
- this.alternate.include(context, false, { asSingleStatement: true });
12114
+ this.alternate.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
11991
12115
  }
11992
12116
  }
11993
12117
  includeRecursively(includeChildrenRecursively, context) {
11994
- this.test.include(context, includeChildrenRecursively);
11995
- this.consequent.include(context, includeChildrenRecursively);
11996
- this.alternate?.include(context, includeChildrenRecursively);
12118
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12119
+ this.consequent.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12120
+ this.alternate?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11997
12121
  }
11998
12122
  includeUnknownTest(context) {
11999
- this.test.include(context, false);
12123
+ this.test.includePath(UNKNOWN_PATH, context, false);
12000
12124
  const { brokenFlow } = context;
12001
12125
  let consequentBrokenFlow = false;
12002
12126
  if (this.consequent.shouldBeIncluded(context)) {
12003
- this.consequent.include(context, false, { asSingleStatement: true });
12127
+ this.consequent.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
12004
12128
  consequentBrokenFlow = context.brokenFlow;
12005
12129
  context.brokenFlow = brokenFlow;
12006
12130
  }
12007
12131
  if (this.alternate?.shouldBeIncluded(context)) {
12008
- this.alternate.include(context, false, { asSingleStatement: true });
12132
+ this.alternate.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
12009
12133
  context.brokenFlow = context.brokenFlow && consequentBrokenFlow;
12010
12134
  }
12011
12135
  }
@@ -12073,7 +12197,7 @@ function isReassignedExportsMember(variable, exportNamesByVariable) {
12073
12197
  class VariableDeclarator extends NodeBase {
12074
12198
  declareDeclarator(kind, isUsingDeclaration) {
12075
12199
  this.isUsingDeclaration = isUsingDeclaration;
12076
- this.id.declare(kind, this.init || UNDEFINED_EXPRESSION);
12200
+ this.id.declare(kind, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION);
12077
12201
  }
12078
12202
  deoptimizePath(path) {
12079
12203
  this.id.deoptimizePath(path);
@@ -12085,15 +12209,15 @@ class VariableDeclarator extends NodeBase {
12085
12209
  this.id.markDeclarationReached();
12086
12210
  return initEffect || this.id.hasEffects(context) || this.isUsingDeclaration;
12087
12211
  }
12088
- include(context, includeChildrenRecursively) {
12212
+ includePath(_path, context, includeChildrenRecursively) {
12089
12213
  const { deoptimized, id, init } = this;
12090
12214
  if (!deoptimized)
12091
12215
  this.applyDeoptimizations();
12092
12216
  this.included = true;
12093
- init?.include(context, includeChildrenRecursively);
12217
+ init?.includePath(EMPTY_PATH, context, includeChildrenRecursively);
12094
12218
  id.markDeclarationReached();
12095
12219
  if (includeChildrenRecursively || id.shouldBeIncluded(context)) {
12096
- id.include(context, includeChildrenRecursively);
12220
+ id.includePath(EMPTY_PATH, context, includeChildrenRecursively);
12097
12221
  }
12098
12222
  }
12099
12223
  removeAnnotations(code) {
@@ -12142,6 +12266,8 @@ class ImportExpression extends NodeBase {
12142
12266
  constructor() {
12143
12267
  super(...arguments);
12144
12268
  this.inlineNamespace = null;
12269
+ this.hasUnknownAccessedKey = false;
12270
+ this.accessedPropKey = new Set();
12145
12271
  this.attributes = null;
12146
12272
  this.mechanism = null;
12147
12273
  this.namespaceExportName = undefined;
@@ -12174,12 +12300,15 @@ class ImportExpression extends NodeBase {
12174
12300
  if (parent2 instanceof ExpressionStatement) {
12175
12301
  return EMPTY_ARRAY;
12176
12302
  }
12177
- // Case 1: const { foo } = await import('bar')
12303
+ // Case 1: const { foo } / module = await import('bar')
12178
12304
  if (parent2 instanceof VariableDeclarator) {
12179
12305
  const declaration = parent2.id;
12180
- return declaration instanceof ObjectPattern
12181
- ? getDeterministicObjectDestructure(declaration)
12182
- : undefined;
12306
+ if (declaration instanceof Identifier) {
12307
+ return this.hasUnknownAccessedKey ? undefined : [...this.accessedPropKey];
12308
+ }
12309
+ if (declaration instanceof ObjectPattern) {
12310
+ return getDeterministicObjectDestructure(declaration);
12311
+ }
12183
12312
  }
12184
12313
  // Case 2: (await import('bar')).foo
12185
12314
  if (parent2 instanceof MemberExpression) {
@@ -12228,13 +12357,23 @@ class ImportExpression extends NodeBase {
12228
12357
  hasEffects() {
12229
12358
  return true;
12230
12359
  }
12231
- include(context, includeChildrenRecursively) {
12360
+ includePath(path, context, includeChildrenRecursively) {
12232
12361
  if (!this.included) {
12233
12362
  this.included = true;
12234
12363
  this.scope.context.includeDynamicImport(this);
12235
12364
  this.scope.addAccessedDynamicImport(this);
12365
+ this.source.includePath(path, context, includeChildrenRecursively);
12366
+ }
12367
+ if (this.hasUnknownAccessedKey)
12368
+ return;
12369
+ if (path[0] === UnknownKey) {
12370
+ this.hasUnknownAccessedKey = true;
12371
+ this.scope.context.includeDynamicImport(this);
12372
+ }
12373
+ else if (typeof path[0] === 'string') {
12374
+ this.accessedPropKey.add(path[0]);
12375
+ this.scope.context.includeDynamicImport(this);
12236
12376
  }
12237
- this.source.include(context, includeChildrenRecursively);
12238
12377
  }
12239
12378
  initialise() {
12240
12379
  super.initialise();
@@ -12562,7 +12701,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
12562
12701
  if (preserve) {
12563
12702
  // This pretends we are accessing an included global variable of the same name
12564
12703
  const globalVariable = node.scope.findGlobal(baseName);
12565
- globalVariable.include();
12704
+ globalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
12566
12705
  // This excludes this variable from renaming
12567
12706
  factoryVariable.globalName = baseName;
12568
12707
  }
@@ -12570,7 +12709,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
12570
12709
  else {
12571
12710
  factoryVariable = node.scope.findGlobal(baseName);
12572
12711
  }
12573
- node.scope.context.includeVariableInModule(factoryVariable);
12712
+ node.scope.context.includeVariableInModule(factoryVariable, UNKNOWN_PATH);
12574
12713
  if (factoryVariable instanceof LocalVariable) {
12575
12714
  factoryVariable.consolidateInitializers();
12576
12715
  factoryVariable.addUsedPlace(node);
@@ -12592,7 +12731,7 @@ class JSXElementBase extends NodeBase {
12592
12731
  this.scope.context.addImportSource(importSource);
12593
12732
  }
12594
12733
  }
12595
- include(context, includeChildrenRecursively) {
12734
+ includePath(path, context, includeChildrenRecursively) {
12596
12735
  if (!this.included) {
12597
12736
  const { factory, importSource, mode } = this.jsxMode;
12598
12737
  if (factory) {
@@ -12600,7 +12739,7 @@ class JSXElementBase extends NodeBase {
12600
12739
  this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this);
12601
12740
  }
12602
12741
  }
12603
- super.include(context, includeChildrenRecursively);
12742
+ super.includePath(path, context, includeChildrenRecursively);
12604
12743
  }
12605
12744
  applyDeoptimizations() { }
12606
12745
  getRenderingMode() {
@@ -12862,7 +13001,7 @@ class JSXOpeningFragment extends NodeBase {
12862
13001
  this.fragment = null;
12863
13002
  this.fragmentVariable = null;
12864
13003
  }
12865
- include(context, includeChildrenRecursively) {
13004
+ includePath(path, context, includeChildrenRecursively) {
12866
13005
  if (!this.included) {
12867
13006
  const jsx = this.scope.context.options.jsx;
12868
13007
  if (jsx.mode === 'automatic') {
@@ -12877,7 +13016,7 @@ class JSXOpeningFragment extends NodeBase {
12877
13016
  }
12878
13017
  }
12879
13018
  }
12880
- super.include(context, includeChildrenRecursively);
13019
+ super.includePath(path, context, includeChildrenRecursively);
12881
13020
  }
12882
13021
  render(code, options) {
12883
13022
  const { mode } = this.scope.context.options.jsx;
@@ -12934,13 +13073,13 @@ class LabeledStatement extends NodeBase {
12934
13073
  context.includedLabels = new Set([...includedLabels, ...context.includedLabels]);
12935
13074
  return bodyHasEffects;
12936
13075
  }
12937
- include(context, includeChildrenRecursively) {
13076
+ includePath(_path, context, includeChildrenRecursively) {
12938
13077
  this.included = true;
12939
13078
  const { brokenFlow, includedLabels } = context;
12940
13079
  context.includedLabels = new Set();
12941
- this.body.include(context, includeChildrenRecursively);
13080
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12942
13081
  if (includeChildrenRecursively || context.includedLabels.has(this.label.name)) {
12943
- this.label.include();
13082
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
12944
13083
  context.includedLabels.delete(this.label.name);
12945
13084
  context.brokenFlow = brokenFlow;
12946
13085
  }
@@ -13037,17 +13176,17 @@ class LogicalExpression extends NodeBase {
13037
13176
  }
13038
13177
  return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
13039
13178
  }
13040
- include(context, includeChildrenRecursively) {
13179
+ includePath(path, context, includeChildrenRecursively) {
13041
13180
  this.included = true;
13042
13181
  const usedBranch = this.getUsedBranch();
13043
13182
  if (includeChildrenRecursively ||
13044
13183
  (usedBranch === this.right && this.left.shouldBeIncluded(context)) ||
13045
13184
  !usedBranch) {
13046
- this.left.include(context, includeChildrenRecursively);
13047
- this.right.include(context, includeChildrenRecursively);
13185
+ this.left.includePath(path, context, includeChildrenRecursively);
13186
+ this.right.includePath(path, context, includeChildrenRecursively);
13048
13187
  }
13049
13188
  else {
13050
- usedBranch.include(context, includeChildrenRecursively);
13189
+ usedBranch.includePath(path, context, includeChildrenRecursively);
13051
13190
  }
13052
13191
  }
13053
13192
  removeAnnotations(code) {
@@ -13119,17 +13258,17 @@ class NewExpression extends NodeBase {
13119
13258
  hasEffectsOnInteractionAtPath(path, { type }) {
13120
13259
  return path.length > 0 || type !== INTERACTION_ACCESSED;
13121
13260
  }
13122
- include(context, includeChildrenRecursively) {
13261
+ includePath(path, context, includeChildrenRecursively) {
13123
13262
  if (!this.deoptimized)
13124
13263
  this.applyDeoptimizations();
13125
13264
  if (includeChildrenRecursively) {
13126
- super.include(context, includeChildrenRecursively);
13265
+ super.includePath(path, context, includeChildrenRecursively);
13127
13266
  }
13128
13267
  else {
13129
13268
  this.included = true;
13130
- this.callee.include(context, false);
13269
+ this.callee.includePath(UNKNOWN_PATH, context, false);
13131
13270
  }
13132
- this.callee.includeCallArguments(context, this.arguments);
13271
+ this.callee.includeCallArguments(context, this.interaction);
13133
13272
  }
13134
13273
  initialise() {
13135
13274
  super.initialise();
@@ -13158,6 +13297,7 @@ class ObjectExpression extends NodeBase {
13158
13297
  constructor() {
13159
13298
  super(...arguments);
13160
13299
  this.objectEntity = null;
13300
+ this.protoProp = null;
13161
13301
  }
13162
13302
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
13163
13303
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -13177,13 +13317,32 @@ class ObjectExpression extends NodeBase {
13177
13317
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13178
13318
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
13179
13319
  }
13320
+ includePath(path, context, includeChildrenRecursively) {
13321
+ this.included = true;
13322
+ this.getObjectEntity().includePath(path, context, includeChildrenRecursively);
13323
+ this.protoProp?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13324
+ }
13180
13325
  render(code, options, { renderedSurroundingElement } = BLANK) {
13181
- super.render(code, options);
13182
13326
  if (renderedSurroundingElement === ExpressionStatement$1 ||
13183
13327
  renderedSurroundingElement === ArrowFunctionExpression$1) {
13184
13328
  code.appendRight(this.start, '(');
13185
13329
  code.prependLeft(this.end, ')');
13186
13330
  }
13331
+ if (this.properties.length > 0) {
13332
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
13333
+ let lastSeparatorPos = null;
13334
+ for (const { node, separator, start, end } of separatedNodes) {
13335
+ if (!node.included) {
13336
+ treeshakeNode(node, code, start, end);
13337
+ continue;
13338
+ }
13339
+ lastSeparatorPos = separator;
13340
+ node.render(code, options);
13341
+ }
13342
+ if (lastSeparatorPos) {
13343
+ code.remove(lastSeparatorPos, this.end - 1);
13344
+ }
13345
+ }
13187
13346
  }
13188
13347
  applyDeoptimizations() { }
13189
13348
  getObjectEntity() {
@@ -13214,6 +13373,7 @@ class ObjectExpression extends NodeBase {
13214
13373
  ? property.key.name
13215
13374
  : String(property.key.value);
13216
13375
  if (key === '__proto__' && property.kind === 'init') {
13376
+ this.protoProp = property;
13217
13377
  prototype =
13218
13378
  property.value instanceof Literal && property.value.value === null
13219
13379
  ? null
@@ -13280,11 +13440,11 @@ class Program extends NodeBase {
13280
13440
  }
13281
13441
  return false;
13282
13442
  }
13283
- include(context, includeChildrenRecursively) {
13443
+ includePath(_path, context, includeChildrenRecursively) {
13284
13444
  this.included = true;
13285
13445
  for (const node of this.body) {
13286
13446
  if (includeChildrenRecursively || node.shouldBeIncluded(context)) {
13287
- node.include(context, includeChildrenRecursively);
13447
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13288
13448
  }
13289
13449
  }
13290
13450
  }
@@ -13323,10 +13483,6 @@ class Program extends NodeBase {
13323
13483
  }
13324
13484
 
13325
13485
  class Property extends MethodBase {
13326
- constructor() {
13327
- super(...arguments);
13328
- this.declarationInit = null;
13329
- }
13330
13486
  //declare method: boolean;
13331
13487
  get method() {
13332
13488
  return isFlagSet(this.flags, 262144 /* Flag.method */);
@@ -13341,9 +13497,17 @@ class Property extends MethodBase {
13341
13497
  set shorthand(value) {
13342
13498
  this.flags = setFlag(this.flags, 524288 /* Flag.shorthand */, value);
13343
13499
  }
13344
- declare(kind, init) {
13345
- this.declarationInit = init;
13346
- return this.value.declare(kind, UNKNOWN_EXPRESSION);
13500
+ declare(kind, includedInitPath, init) {
13501
+ const pathInProperty = includedInitPath.at(-1) === UnknownKey
13502
+ ? includedInitPath
13503
+ : // For now, we only consider static path as we do not know how to
13504
+ // deoptimize the path in the dynamic case.
13505
+ this.computed
13506
+ ? [...includedInitPath, UnknownKey]
13507
+ : this.key instanceof Identifier
13508
+ ? [...includedInitPath, this.key.name]
13509
+ : [...includedInitPath, String(this.key.value)];
13510
+ return this.value.declare(kind, pathInProperty, init);
13347
13511
  }
13348
13512
  hasEffects(context) {
13349
13513
  if (!this.deoptimized)
@@ -13353,6 +13517,11 @@ class Property extends MethodBase {
13353
13517
  this.key.hasEffects(context) ||
13354
13518
  this.value.hasEffects(context));
13355
13519
  }
13520
+ includePath(path, context, includeChildrenRecursively) {
13521
+ this.included = true;
13522
+ this.key.includePath(EMPTY_PATH, context, includeChildrenRecursively);
13523
+ this.value.includePath(path, context, includeChildrenRecursively);
13524
+ }
13356
13525
  markDeclarationReached() {
13357
13526
  this.value.markDeclarationReached();
13358
13527
  }
@@ -13362,13 +13531,7 @@ class Property extends MethodBase {
13362
13531
  }
13363
13532
  this.value.render(code, options, { isShorthandProperty: this.shorthand });
13364
13533
  }
13365
- applyDeoptimizations() {
13366
- this.deoptimized = true;
13367
- if (this.declarationInit !== null) {
13368
- this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
13369
- this.scope.context.requestTreeshakingPass();
13370
- }
13371
- }
13534
+ applyDeoptimizations() { }
13372
13535
  }
13373
13536
 
13374
13537
  class PropertyDefinition extends NodeBase {
@@ -13412,9 +13575,9 @@ class ReturnStatement extends NodeBase {
13412
13575
  context.brokenFlow = true;
13413
13576
  return false;
13414
13577
  }
13415
- include(context, includeChildrenRecursively) {
13578
+ includePath(_path, context, includeChildrenRecursively) {
13416
13579
  this.included = true;
13417
- this.argument?.include(context, includeChildrenRecursively);
13580
+ this.argument?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13418
13581
  context.brokenFlow = true;
13419
13582
  }
13420
13583
  initialise() {
@@ -13451,14 +13614,14 @@ class SequenceExpression extends NodeBase {
13451
13614
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13452
13615
  return this.expressions[this.expressions.length - 1].hasEffectsOnInteractionAtPath(path, interaction, context);
13453
13616
  }
13454
- include(context, includeChildrenRecursively) {
13617
+ includePath(path, context, includeChildrenRecursively) {
13455
13618
  this.included = true;
13456
13619
  const lastExpression = this.expressions[this.expressions.length - 1];
13457
13620
  for (const expression of this.expressions) {
13458
13621
  if (includeChildrenRecursively ||
13459
13622
  (expression === lastExpression && !(this.parent instanceof ExpressionStatement)) ||
13460
13623
  expression.shouldBeIncluded(context))
13461
- expression.include(context, includeChildrenRecursively);
13624
+ expression.includePath(path, context, includeChildrenRecursively);
13462
13625
  }
13463
13626
  }
13464
13627
  removeAnnotations(code) {
@@ -13506,10 +13669,13 @@ class Super extends NodeBase {
13506
13669
  deoptimizePath(path) {
13507
13670
  this.variable.deoptimizePath(path);
13508
13671
  }
13509
- include() {
13672
+ includePath(path, context) {
13510
13673
  if (!this.included) {
13511
13674
  this.included = true;
13512
- this.scope.context.includeVariableInModule(this.variable);
13675
+ this.scope.context.includeVariableInModule(this.variable, path);
13676
+ }
13677
+ else if (path.length > 0) {
13678
+ this.variable.includePath(path, context);
13513
13679
  }
13514
13680
  }
13515
13681
  }
@@ -13526,12 +13692,12 @@ class SwitchCase extends NodeBase {
13526
13692
  }
13527
13693
  return false;
13528
13694
  }
13529
- include(context, includeChildrenRecursively) {
13695
+ includePath(_path, context, includeChildrenRecursively) {
13530
13696
  this.included = true;
13531
- this.test?.include(context, includeChildrenRecursively);
13697
+ this.test?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13532
13698
  for (const node of this.consequent) {
13533
13699
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
13534
- node.include(context, includeChildrenRecursively);
13700
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13535
13701
  }
13536
13702
  }
13537
13703
  render(code, options, nodeRenderOptions) {
@@ -13579,9 +13745,9 @@ class SwitchStatement extends NodeBase {
13579
13745
  context.hasBreak = hasBreak;
13580
13746
  return false;
13581
13747
  }
13582
- include(context, includeChildrenRecursively) {
13748
+ includePath(_path, context, includeChildrenRecursively) {
13583
13749
  this.included = true;
13584
- this.discriminant.include(context, includeChildrenRecursively);
13750
+ this.discriminant.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13585
13751
  const { brokenFlow, hasBreak } = context;
13586
13752
  context.hasBreak = false;
13587
13753
  let onlyHasBrokenFlow = true;
@@ -13598,7 +13764,7 @@ class SwitchStatement extends NodeBase {
13598
13764
  isCaseIncluded = switchCase.hasEffects(hasEffectsContext);
13599
13765
  }
13600
13766
  if (isCaseIncluded) {
13601
- switchCase.include(context, includeChildrenRecursively);
13767
+ switchCase.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13602
13768
  onlyHasBrokenFlow &&= context.brokenFlow && !context.hasBreak;
13603
13769
  context.hasBreak = false;
13604
13770
  context.brokenFlow = brokenFlow;
@@ -13655,21 +13821,21 @@ class TaggedTemplateExpression extends CallExpressionBase {
13655
13821
  return (this.tag.hasEffects(context) ||
13656
13822
  this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
13657
13823
  }
13658
- include(context, includeChildrenRecursively) {
13824
+ includePath(path, context, includeChildrenRecursively) {
13659
13825
  if (!this.deoptimized)
13660
13826
  this.applyDeoptimizations();
13661
13827
  if (includeChildrenRecursively) {
13662
- super.include(context, includeChildrenRecursively);
13828
+ super.includePath(path, context, includeChildrenRecursively);
13663
13829
  }
13664
13830
  else {
13665
13831
  this.included = true;
13666
- this.tag.include(context, includeChildrenRecursively);
13667
- this.quasi.include(context, includeChildrenRecursively);
13832
+ this.tag.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13833
+ this.quasi.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13668
13834
  }
13669
- this.tag.includeCallArguments(context, this.args);
13835
+ this.tag.includeCallArguments(context, this.interaction);
13670
13836
  const [returnExpression] = this.getReturnExpression();
13671
13837
  if (!returnExpression.included) {
13672
- returnExpression.include(context, false);
13838
+ returnExpression.includePath(UNKNOWN_PATH, context, false);
13673
13839
  }
13674
13840
  }
13675
13841
  initialise() {
@@ -13714,7 +13880,7 @@ class TemplateElement extends NodeBase {
13714
13880
  hasEffects() {
13715
13881
  return false;
13716
13882
  }
13717
- include() {
13883
+ includePath() {
13718
13884
  this.included = true;
13719
13885
  }
13720
13886
  parseNode(esTreeNode) {
@@ -13756,13 +13922,13 @@ class TemplateLiteral extends NodeBase {
13756
13922
  class ModuleScope extends ChildScope {
13757
13923
  constructor(parent, context) {
13758
13924
  super(parent, context);
13759
- this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, context, 'other'));
13925
+ this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, EMPTY_PATH, context, 'other'));
13760
13926
  }
13761
- addDeclaration(identifier, context, init, kind) {
13927
+ addDeclaration(identifier, context, init, includedInitPath, kind) {
13762
13928
  if (this.context.module.importDescriptions.has(identifier.name)) {
13763
13929
  context.error(logRedeclarationError(identifier.name), identifier.start);
13764
13930
  }
13765
- return super.addDeclaration(identifier, context, init, kind);
13931
+ return super.addDeclaration(identifier, context, init, includedInitPath, kind);
13766
13932
  }
13767
13933
  addExportDefaultDeclaration(name, exportDefaultDeclaration, context) {
13768
13934
  const variable = new ExportDefaultVariable(name, exportDefaultDeclaration, context);
@@ -13807,10 +13973,13 @@ class ThisExpression extends NodeBase {
13807
13973
  }
13808
13974
  return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
13809
13975
  }
13810
- include() {
13976
+ includePath(path, context) {
13811
13977
  if (!this.included) {
13812
13978
  this.included = true;
13813
- this.scope.context.includeVariableInModule(this.variable);
13979
+ this.scope.context.includeVariableInModule(this.variable, path);
13980
+ }
13981
+ else if (path.length > 0) {
13982
+ this.variable.includePath(path, context);
13814
13983
  }
13815
13984
  }
13816
13985
  initialise() {
@@ -13837,9 +14006,9 @@ class ThrowStatement extends NodeBase {
13837
14006
  hasEffects() {
13838
14007
  return true;
13839
14008
  }
13840
- include(context, includeChildrenRecursively) {
14009
+ includePath(_path, context, includeChildrenRecursively) {
13841
14010
  this.included = true;
13842
- this.argument.include(context, includeChildrenRecursively);
14011
+ this.argument.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13843
14012
  context.brokenFlow = true;
13844
14013
  }
13845
14014
  render(code, options) {
@@ -13861,13 +14030,13 @@ class TryStatement extends NodeBase {
13861
14030
  ? this.block.body.length > 0
13862
14031
  : this.block.hasEffects(context)) || !!this.finalizer?.hasEffects(context));
13863
14032
  }
13864
- include(context, includeChildrenRecursively) {
14033
+ includePath(_path, context, includeChildrenRecursively) {
13865
14034
  const tryCatchDeoptimization = this.scope.context.options.treeshake?.tryCatchDeoptimization;
13866
14035
  const { brokenFlow, includedLabels } = context;
13867
14036
  if (!this.directlyIncluded || !tryCatchDeoptimization) {
13868
14037
  this.included = true;
13869
14038
  this.directlyIncluded = true;
13870
- this.block.include(context, tryCatchDeoptimization ? INCLUDE_PARAMETERS : includeChildrenRecursively);
14039
+ this.block.includePath(UNKNOWN_PATH, context, tryCatchDeoptimization ? INCLUDE_PARAMETERS : includeChildrenRecursively);
13871
14040
  if (includedLabels.size > 0) {
13872
14041
  this.includedLabelsAfterBlock = [...includedLabels];
13873
14042
  }
@@ -13879,10 +14048,10 @@ class TryStatement extends NodeBase {
13879
14048
  }
13880
14049
  }
13881
14050
  if (this.handler !== null) {
13882
- this.handler.include(context, includeChildrenRecursively);
14051
+ this.handler.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13883
14052
  context.brokenFlow = brokenFlow;
13884
14053
  }
13885
- this.finalizer?.include(context, includeChildrenRecursively);
14054
+ this.finalizer?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13886
14055
  }
13887
14056
  }
13888
14057
 
@@ -13940,7 +14109,7 @@ class UpdateExpression extends NodeBase {
13940
14109
  hasEffectsOnInteractionAtPath(path, { type }) {
13941
14110
  return path.length > 1 || type !== INTERACTION_ACCESSED;
13942
14111
  }
13943
- include(context, includeChildrenRecursively) {
14112
+ includePath(_, context, includeChildrenRecursively) {
13944
14113
  if (!this.deoptimized)
13945
14114
  this.applyDeoptimizations();
13946
14115
  this.included = true;
@@ -14009,20 +14178,20 @@ class VariableDeclaration extends NodeBase {
14009
14178
  hasEffectsOnInteractionAtPath() {
14010
14179
  return false;
14011
14180
  }
14012
- include(context, includeChildrenRecursively, { asSingleStatement } = BLANK) {
14181
+ includePath(_path, context, includeChildrenRecursively, { asSingleStatement } = BLANK) {
14013
14182
  this.included = true;
14014
14183
  for (const declarator of this.declarations) {
14015
14184
  if (includeChildrenRecursively || declarator.shouldBeIncluded(context))
14016
- declarator.include(context, includeChildrenRecursively);
14185
+ declarator.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14017
14186
  const { id, init } = declarator;
14018
14187
  if (asSingleStatement) {
14019
- id.include(context, includeChildrenRecursively);
14188
+ id.includePath(EMPTY_PATH, context, includeChildrenRecursively);
14020
14189
  }
14021
14190
  if (init &&
14022
14191
  id.included &&
14023
14192
  !init.included &&
14024
14193
  (id instanceof ObjectPattern || id instanceof ArrayPattern)) {
14025
- init.include(context, includeChildrenRecursively);
14194
+ init.includePath(EMPTY_PATH, context, includeChildrenRecursively);
14026
14195
  }
14027
14196
  }
14028
14197
  }
@@ -14094,8 +14263,7 @@ class VariableDeclaration extends NodeBase {
14094
14263
  const singleSystemExport = gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregatedSystemExports);
14095
14264
  for (const { node, start, separator, contentEnd, end } of separatedNodes) {
14096
14265
  if (!node.included) {
14097
- code.remove(start, end);
14098
- node.removeAnnotations(code);
14266
+ treeshakeNode(node, code, start, end);
14099
14267
  continue;
14100
14268
  }
14101
14269
  node.render(code, options);
@@ -14172,9 +14340,9 @@ class WhileStatement extends NodeBase {
14172
14340
  return true;
14173
14341
  return hasLoopBodyEffects(context, this.body);
14174
14342
  }
14175
- include(context, includeChildrenRecursively) {
14343
+ includePath(_path, context, includeChildrenRecursively) {
14176
14344
  this.included = true;
14177
- this.test.include(context, includeChildrenRecursively);
14345
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14178
14346
  includeLoopBody(context, this.body, includeChildrenRecursively);
14179
14347
  }
14180
14348
  }
@@ -14418,7 +14586,7 @@ const bufferParsers = [
14418
14586
  const annotations = (node.annotations = convertAnnotations(buffer[position + 1], buffer));
14419
14587
  node.annotationNoSideEffects = annotations.some(comment => comment.type === 'noSideEffects');
14420
14588
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 2], buffer));
14421
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14589
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14422
14590
  node.body = convertNode(node, scope.bodyScope, buffer[position + 3], buffer);
14423
14591
  },
14424
14592
  function assignmentExpression(node, position, buffer) {
@@ -14464,7 +14632,7 @@ const bufferParsers = [
14464
14632
  const parameterPosition = buffer[position];
14465
14633
  const parameter = (node.param =
14466
14634
  parameterPosition === 0 ? null : convertNode(node, scope, parameterPosition, buffer));
14467
- parameter?.declare('parameter', UNKNOWN_EXPRESSION);
14635
+ parameter?.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
14468
14636
  node.body = convertNode(node, scope.bodyScope, buffer[position + 1], buffer);
14469
14637
  },
14470
14638
  function chainExpression(node, position, buffer) {
@@ -14599,7 +14767,7 @@ const bufferParsers = [
14599
14767
  node.id =
14600
14768
  idPosition === 0 ? null : convertNode(node, scope.parent, idPosition, buffer);
14601
14769
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
14602
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14770
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14603
14771
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
14604
14772
  },
14605
14773
  function functionExpression(node, position, buffer) {
@@ -14612,7 +14780,7 @@ const bufferParsers = [
14612
14780
  const idPosition = buffer[position + 2];
14613
14781
  node.id = idPosition === 0 ? null : convertNode(node, node.idScope, idPosition, buffer);
14614
14782
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
14615
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14783
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14616
14784
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
14617
14785
  },
14618
14786
  function identifier(node, position, buffer) {
@@ -14971,8 +15139,8 @@ class UnknownNode extends NodeBase {
14971
15139
  hasEffects() {
14972
15140
  return true;
14973
15141
  }
14974
- include(context) {
14975
- super.include(context, true);
15142
+ includePath(path, context) {
15143
+ super.includePath(path, context, true);
14976
15144
  }
14977
15145
  }
14978
15146
 
@@ -15076,8 +15244,8 @@ class ExportShimVariable extends Variable {
15076
15244
  super(MISSING_EXPORT_SHIM_VARIABLE);
15077
15245
  this.module = module;
15078
15246
  }
15079
- include() {
15080
- super.include();
15247
+ includePath(path, context) {
15248
+ super.includePath(path, context);
15081
15249
  this.module.needsExportShim = true;
15082
15250
  }
15083
15251
  }
@@ -15768,7 +15936,7 @@ class Module {
15768
15936
  include() {
15769
15937
  const context = createInclusionContext();
15770
15938
  if (this.ast.shouldBeIncluded(context))
15771
- this.ast.include(context, false);
15939
+ this.ast.includePath(EMPTY_PATH, context, false);
15772
15940
  }
15773
15941
  includeAllExports(includeNamespaceMembers) {
15774
15942
  if (!this.isExecuted) {
@@ -15782,9 +15950,7 @@ class Module {
15782
15950
  return error(logMissingEntryExport(exportName, this.id));
15783
15951
  }
15784
15952
  variable.deoptimizePath(UNKNOWN_PATH);
15785
- if (!variable.included) {
15786
- this.includeVariable(variable);
15787
- }
15953
+ this.includeVariable(variable, UNKNOWN_PATH);
15788
15954
  }
15789
15955
  }
15790
15956
  for (const name of this.getReexports()) {
@@ -15792,7 +15958,7 @@ class Module {
15792
15958
  if (variable) {
15793
15959
  variable.deoptimizePath(UNKNOWN_PATH);
15794
15960
  if (!variable.included) {
15795
- this.includeVariable(variable);
15961
+ this.includeVariable(variable, UNKNOWN_PATH);
15796
15962
  }
15797
15963
  if (variable instanceof ExternalVariable) {
15798
15964
  variable.module.reexported = true;
@@ -15804,7 +15970,7 @@ class Module {
15804
15970
  }
15805
15971
  }
15806
15972
  includeAllInBundle() {
15807
- this.ast.include(createInclusionContext(), true);
15973
+ this.ast.includePath(UNKNOWN_PATH, createInclusionContext(), true);
15808
15974
  this.includeAllExports(false);
15809
15975
  }
15810
15976
  includeExportsByNames(names) {
@@ -15818,7 +15984,7 @@ class Module {
15818
15984
  if (variable) {
15819
15985
  variable.deoptimizePath(UNKNOWN_PATH);
15820
15986
  if (!variable.included) {
15821
- this.includeVariable(variable);
15987
+ this.includeVariable(variable, EMPTY_PATH);
15822
15988
  }
15823
15989
  }
15824
15990
  if (!this.exports.has(name) && !this.reexportDescriptions.has(name)) {
@@ -16260,13 +16426,13 @@ class Module {
16260
16426
  for (const module of [this, ...this.exportAllModules]) {
16261
16427
  if (module instanceof ExternalModule) {
16262
16428
  const [externalVariable] = module.getVariableForExportName('*');
16263
- externalVariable.include();
16429
+ externalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
16264
16430
  this.includedImports.add(externalVariable);
16265
16431
  externalNamespaces.add(externalVariable);
16266
16432
  }
16267
16433
  else if (module.info.syntheticNamedExports) {
16268
16434
  const syntheticNamespace = module.getSyntheticNamespace();
16269
- syntheticNamespace.include();
16435
+ syntheticNamespace.includePath(UNKNOWN_PATH, createInclusionContext());
16270
16436
  this.includedImports.add(syntheticNamespace);
16271
16437
  syntheticNamespaces.add(syntheticNamespace);
16272
16438
  }
@@ -16276,7 +16442,9 @@ class Module {
16276
16442
  includeDynamicImport(node) {
16277
16443
  const resolution = this.dynamicImports.find(dynamicImport => dynamicImport.node === node).resolution;
16278
16444
  if (resolution instanceof Module) {
16279
- resolution.includedDynamicImporters.push(this);
16445
+ if (!resolution.includedDynamicImporters.includes(this)) {
16446
+ resolution.includedDynamicImporters.push(this);
16447
+ }
16280
16448
  const importedNames = this.options.treeshake
16281
16449
  ? node.getDeterministicImportedNames()
16282
16450
  : undefined;
@@ -16288,7 +16456,7 @@ class Module {
16288
16456
  }
16289
16457
  }
16290
16458
  }
16291
- includeVariable(variable) {
16459
+ includeVariable(variable, path) {
16292
16460
  const variableModule = variable.module;
16293
16461
  if (variable.included) {
16294
16462
  if (variableModule instanceof Module && variableModule !== this) {
@@ -16296,7 +16464,6 @@ class Module {
16296
16464
  }
16297
16465
  }
16298
16466
  else {
16299
- variable.include();
16300
16467
  this.graph.needsTreeshakingPass = true;
16301
16468
  if (variableModule instanceof Module) {
16302
16469
  if (!variableModule.isExecuted) {
@@ -16312,9 +16479,10 @@ class Module {
16312
16479
  }
16313
16480
  }
16314
16481
  }
16482
+ variable.includePath(path, createInclusionContext());
16315
16483
  }
16316
- includeVariableInModule(variable) {
16317
- this.includeVariable(variable);
16484
+ includeVariableInModule(variable, path) {
16485
+ this.includeVariable(variable, path);
16318
16486
  const variableModule = variable.module;
16319
16487
  if (variableModule && variableModule !== this) {
16320
16488
  this.includedImports.add(variable);
@@ -20887,7 +21055,7 @@ class Graph {
20887
21055
  this.options = options;
20888
21056
  this.astLru = flru(5);
20889
21057
  this.cachedModules = new Map();
20890
- this.deoptimizationTracker = new PathTracker();
21058
+ this.deoptimizationTracker = new EntityPathTracker();
20891
21059
  this.entryModules = [];
20892
21060
  this.modulesById = new Map();
20893
21061
  this.needsTreeshakingPass = false;