@rollup/wasm-node 4.26.0 → 4.27.0-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,22 +1,22 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v4.26.0
4
- Wed, 13 Nov 2024 06:44:29 GMT - commit ae1d14b7855ff6568a6697d37271a5eb4d8e2d3e
3
+ Rollup.js v4.27.0-1
4
+ Thu, 14 Nov 2024 06:32:38 GMT - commit 81f5021d7d7e2a488639dc036f2334995b3761fc
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, ObjectExpression as ObjectExpression$1, Property as Property$1, 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, 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, ObjectExpression as ObjectExpression$1, Property as Property$1, 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, 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.26.0";
19
+ var version = "4.27.0-1";
20
20
 
21
21
  const comma = ','.charCodeAt(0);
22
22
  const semicolon = ';'.charCodeAt(0);
@@ -1995,19 +1995,6 @@ function is_reference (node, parent) {
1995
1995
  return false;
1996
1996
  }
1997
1997
 
1998
- const PureFunctionKey = Symbol('PureFunction');
1999
- const getPureFunctions = ({ treeshake }) => {
2000
- const pureFunctions = Object.create(null);
2001
- for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
2002
- let currentFunctions = pureFunctions;
2003
- for (const pathSegment of functionName.split('.')) {
2004
- currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
2005
- }
2006
- currentFunctions[PureFunctionKey] = true;
2007
- }
2008
- return pureFunctions;
2009
- };
2010
-
2011
1998
  function getOrCreate(map, key, init) {
2012
1999
  const existing = map.get(key);
2013
2000
  if (existing !== undefined) {
@@ -2038,7 +2025,7 @@ const UNKNOWN_PATH = [UnknownKey];
2038
2025
  const UNKNOWN_NON_ACCESSOR_PATH = [UnknownNonAccessorKey];
2039
2026
  const UNKNOWN_INTEGER_PATH = [UnknownInteger];
2040
2027
  const EntitiesKey = Symbol('Entities');
2041
- class PathTracker {
2028
+ class EntityPathTracker {
2042
2029
  constructor() {
2043
2030
  this.entityPaths = Object.create(null, {
2044
2031
  [EntitiesKey]: { value: new Set() }
@@ -2063,14 +2050,14 @@ class PathTracker {
2063
2050
  getEntities(path) {
2064
2051
  let currentPaths = this.entityPaths;
2065
2052
  for (const pathSegment of path) {
2066
- currentPaths = currentPaths[pathSegment] =
2067
- currentPaths[pathSegment] ||
2068
- Object.create(null, { [EntitiesKey]: { value: new Set() } });
2053
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
2054
+ [EntitiesKey]: { value: new Set() }
2055
+ });
2069
2056
  }
2070
2057
  return currentPaths[EntitiesKey];
2071
2058
  }
2072
2059
  }
2073
- const SHARED_RECURSION_TRACKER = new PathTracker();
2060
+ const SHARED_RECURSION_TRACKER = new EntityPathTracker();
2074
2061
  class DiscriminatedPathTracker {
2075
2062
  constructor() {
2076
2063
  this.entityPaths = Object.create(null, {
@@ -2080,9 +2067,9 @@ class DiscriminatedPathTracker {
2080
2067
  trackEntityAtPathAndGetIfTracked(path, discriminator, entity) {
2081
2068
  let currentPaths = this.entityPaths;
2082
2069
  for (const pathSegment of path) {
2083
- currentPaths = currentPaths[pathSegment] =
2084
- currentPaths[pathSegment] ||
2085
- Object.create(null, { [EntitiesKey]: { value: new Map() } });
2070
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
2071
+ [EntitiesKey]: { value: new Map() }
2072
+ });
2086
2073
  }
2087
2074
  const trackedEntities = getOrCreate(currentPaths[EntitiesKey], discriminator, (getNewSet));
2088
2075
  if (trackedEntities.has(entity))
@@ -2091,6 +2078,85 @@ class DiscriminatedPathTracker {
2091
2078
  return false;
2092
2079
  }
2093
2080
  }
2081
+ const UNKNOWN_INCLUDED_PATH = Object.freeze({ [UnknownKey]: EMPTY_OBJECT });
2082
+ class IncludedPathTracker {
2083
+ constructor() {
2084
+ this.includedPaths = null;
2085
+ }
2086
+ includePathAndGetIfIncluded(path) {
2087
+ let included = true;
2088
+ let parent = this;
2089
+ let parentSegment = 'includedPaths';
2090
+ let currentPaths = (this.includedPaths ||=
2091
+ ((included = false), Object.create(null)));
2092
+ for (const pathSegment of path) {
2093
+ // This means from here, all paths are included
2094
+ if (currentPaths[UnknownKey]) {
2095
+ return true;
2096
+ }
2097
+ // Including UnknownKey automatically includes all nested paths.
2098
+ // From above, we know that UnknownKey is not included yet.
2099
+ if (typeof pathSegment === 'symbol') {
2100
+ // Hopefully, this saves some memory over just setting
2101
+ // currentPaths[UnknownKey] = EMPTY_OBJECT
2102
+ parent[parentSegment] = UNKNOWN_INCLUDED_PATH;
2103
+ return false;
2104
+ }
2105
+ parent = currentPaths;
2106
+ parentSegment = pathSegment;
2107
+ currentPaths = currentPaths[pathSegment] ||= ((included = false), Object.create(null));
2108
+ }
2109
+ return included;
2110
+ }
2111
+ includeAllPaths(entity, context, basePath) {
2112
+ const { includedPaths } = this;
2113
+ if (includedPaths) {
2114
+ includeAllPaths(entity, context, basePath, includedPaths);
2115
+ }
2116
+ }
2117
+ }
2118
+ function includeAllPaths(entity, context, basePath, currentPaths) {
2119
+ if (currentPaths[UnknownKey]) {
2120
+ return entity.includePath([...basePath, UnknownKey], context, false);
2121
+ }
2122
+ const keys = Object.keys(currentPaths);
2123
+ if (keys.length === 0) {
2124
+ return entity.includePath(basePath, context, false);
2125
+ }
2126
+ for (const key of keys) {
2127
+ includeAllPaths(entity, context, [...basePath, key], currentPaths[key]);
2128
+ }
2129
+ }
2130
+
2131
+ function createInclusionContext() {
2132
+ return {
2133
+ brokenFlow: false,
2134
+ hasBreak: false,
2135
+ hasContinue: false,
2136
+ includedCallArguments: new Set(),
2137
+ includedLabels: new Set()
2138
+ };
2139
+ }
2140
+ function createHasEffectsContext() {
2141
+ return {
2142
+ accessed: new EntityPathTracker(),
2143
+ assigned: new EntityPathTracker(),
2144
+ brokenFlow: false,
2145
+ called: new DiscriminatedPathTracker(),
2146
+ hasBreak: false,
2147
+ hasContinue: false,
2148
+ ignore: {
2149
+ breaks: false,
2150
+ continues: false,
2151
+ labels: new Set(),
2152
+ returnYield: false,
2153
+ this: false
2154
+ },
2155
+ includedLabels: new Set(),
2156
+ instantiated: new DiscriminatedPathTracker(),
2157
+ replacedVariableInits: new Map()
2158
+ };
2159
+ }
2094
2160
 
2095
2161
  function isFlagSet(flags, flag) {
2096
2162
  return (flags & flag) !== 0;
@@ -2129,12 +2195,12 @@ class ExpressionEntity {
2129
2195
  hasEffectsOnInteractionAtPath(_path, _interaction, _context) {
2130
2196
  return true;
2131
2197
  }
2132
- include(_context, _includeChildrenRecursively, _options) {
2198
+ includePath(_path, _context, _includeChildrenRecursively, _options) {
2133
2199
  this.included = true;
2134
2200
  }
2135
- includeCallArguments(context, parameters) {
2136
- for (const argument of parameters) {
2137
- argument.include(context, false);
2201
+ includeCallArguments(context, interaction) {
2202
+ for (const argument of interaction.args) {
2203
+ argument?.includePath(UNKNOWN_PATH, context, false);
2138
2204
  }
2139
2205
  }
2140
2206
  shouldBeIncluded(_context) {
@@ -2173,6 +2239,19 @@ const NODE_INTERACTION_UNKNOWN_CALL = {
2173
2239
  withNew: false
2174
2240
  };
2175
2241
 
2242
+ const PureFunctionKey = Symbol('PureFunction');
2243
+ const getPureFunctions = ({ treeshake }) => {
2244
+ const pureFunctions = Object.create(null);
2245
+ for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
2246
+ let currentFunctions = pureFunctions;
2247
+ for (const pathSegment of functionName.split('.')) {
2248
+ currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
2249
+ }
2250
+ currentFunctions[PureFunctionKey] = true;
2251
+ }
2252
+ return pureFunctions;
2253
+ };
2254
+
2176
2255
  class Variable extends ExpressionEntity {
2177
2256
  markReassigned() {
2178
2257
  this.isReassigned = true;
@@ -2249,9 +2328,9 @@ class Variable extends ExpressionEntity {
2249
2328
  * has not been included previously. Once a variable is included, it should
2250
2329
  * take care all its declarations are included.
2251
2330
  */
2252
- include() {
2331
+ includePath(path, context) {
2253
2332
  this.included = true;
2254
- this.renderedLikeHoisted?.include();
2333
+ this.renderedLikeHoisted?.includePath(path, context);
2255
2334
  }
2256
2335
  /**
2257
2336
  * Links the rendered name of this variable to another variable and includes
@@ -2283,8 +2362,8 @@ class ExternalVariable extends Variable {
2283
2362
  hasEffectsOnInteractionAtPath(path, { type }) {
2284
2363
  return type !== INTERACTION_ACCESSED || path.length > (this.isNamespace ? 1 : 0);
2285
2364
  }
2286
- include() {
2287
- super.include();
2365
+ includePath(path, context) {
2366
+ super.includePath(path, context);
2288
2367
  this.module.used = true;
2289
2368
  }
2290
2369
  }
@@ -2585,36 +2664,6 @@ const childNodeKeys = {
2585
2664
  YieldExpression: ['argument']
2586
2665
  };
2587
2666
 
2588
- function createInclusionContext() {
2589
- return {
2590
- brokenFlow: false,
2591
- hasBreak: false,
2592
- hasContinue: false,
2593
- includedCallArguments: new Set(),
2594
- includedLabels: new Set()
2595
- };
2596
- }
2597
- function createHasEffectsContext() {
2598
- return {
2599
- accessed: new PathTracker(),
2600
- assigned: new PathTracker(),
2601
- brokenFlow: false,
2602
- called: new DiscriminatedPathTracker(),
2603
- hasBreak: false,
2604
- hasContinue: false,
2605
- ignore: {
2606
- breaks: false,
2607
- continues: false,
2608
- labels: new Set(),
2609
- returnYield: false,
2610
- this: false
2611
- },
2612
- includedLabels: new Set(),
2613
- instantiated: new DiscriminatedPathTracker(),
2614
- replacedVariableInits: new Map()
2615
- };
2616
- }
2617
-
2618
2667
  const INCLUDE_PARAMETERS = 'variables';
2619
2668
  const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN');
2620
2669
  class NodeBase extends ExpressionEntity {
@@ -2683,7 +2732,7 @@ class NodeBase extends ExpressionEntity {
2683
2732
  return (this.hasEffects(context) ||
2684
2733
  this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));
2685
2734
  }
2686
- include(context, includeChildrenRecursively, _options) {
2735
+ includePath(_path, context, includeChildrenRecursively, _options) {
2687
2736
  if (!this.deoptimized)
2688
2737
  this.applyDeoptimizations();
2689
2738
  this.included = true;
@@ -2693,16 +2742,16 @@ class NodeBase extends ExpressionEntity {
2693
2742
  continue;
2694
2743
  if (Array.isArray(value)) {
2695
2744
  for (const child of value) {
2696
- child?.include(context, includeChildrenRecursively);
2745
+ child?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
2697
2746
  }
2698
2747
  }
2699
2748
  else {
2700
- value.include(context, includeChildrenRecursively);
2749
+ value.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
2701
2750
  }
2702
2751
  }
2703
2752
  }
2704
2753
  includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {
2705
- this.include(context, includeChildrenRecursively);
2754
+ this.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
2706
2755
  }
2707
2756
  /**
2708
2757
  * Override to perform special initialisation steps after the scope is
@@ -3164,6 +3213,7 @@ class ObjectEntity extends ExpressionEntity {
3164
3213
  this.unknownIntegerProps = [];
3165
3214
  this.unmatchableGetters = [];
3166
3215
  this.unmatchablePropertiesAndGetters = [];
3216
+ this.unmatchablePropertiesAndSetters = [];
3167
3217
  this.unmatchableSetters = [];
3168
3218
  if (Array.isArray(properties)) {
3169
3219
  this.buildPropertyMaps(properties);
@@ -3398,9 +3448,37 @@ class ObjectEntity extends ExpressionEntity {
3398
3448
  }
3399
3449
  return false;
3400
3450
  }
3451
+ includePath(path, context, includeChildrenRecursively) {
3452
+ this.included = true;
3453
+ const [key, ...subPath] = path;
3454
+ if (key == null || includeChildrenRecursively) {
3455
+ for (const property of this.allProperties) {
3456
+ if (includeChildrenRecursively || property.shouldBeIncluded(context)) {
3457
+ property.includePath(EMPTY_PATH, context, includeChildrenRecursively);
3458
+ }
3459
+ }
3460
+ this.prototypeExpression?.includePath(EMPTY_PATH, context, includeChildrenRecursively);
3461
+ }
3462
+ else {
3463
+ const [includedMembers, includedPath] = typeof key === 'string'
3464
+ ? [
3465
+ [
3466
+ ...new Set([
3467
+ ...(this.propertiesAndGettersByKey[key] || this.unmatchablePropertiesAndGetters),
3468
+ ...(this.propertiesAndSettersByKey[key] || this.unmatchablePropertiesAndSetters)
3469
+ ])
3470
+ ],
3471
+ subPath
3472
+ ]
3473
+ : [this.allProperties, UNKNOWN_PATH];
3474
+ for (const property of includedMembers) {
3475
+ property.includePath(includedPath, context, includeChildrenRecursively);
3476
+ }
3477
+ this.prototypeExpression?.includePath(path, context, includeChildrenRecursively);
3478
+ }
3479
+ }
3401
3480
  buildPropertyMaps(properties) {
3402
- const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchableGetters, unmatchableSetters } = this;
3403
- const unmatchablePropertiesAndSetters = [];
3481
+ const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchablePropertiesAndSetters, unmatchableGetters, unmatchableSetters } = this;
3404
3482
  for (let index = properties.length - 1; index >= 0; index--) {
3405
3483
  const { key, kind, property } = properties[index];
3406
3484
  allProperties.push(property);
@@ -4758,16 +4836,20 @@ class GlobalVariable extends Variable {
4758
4836
  }
4759
4837
 
4760
4838
  class LocalVariable extends Variable {
4761
- constructor(name, declarator, init, context, kind) {
4839
+ constructor(name, declarator, init,
4840
+ /** if this is non-empty, the actual init is this path of this.init */
4841
+ initPath, context, kind) {
4762
4842
  super(name);
4763
4843
  this.init = init;
4844
+ this.initPath = initPath;
4845
+ this.kind = kind;
4764
4846
  this.calledFromTryStatement = false;
4765
4847
  this.additionalInitializers = null;
4848
+ this.includedPathTracker = new IncludedPathTracker();
4766
4849
  this.expressionsToBeDeoptimized = [];
4767
4850
  this.declarations = declarator ? [declarator] : [];
4768
4851
  this.deoptimizationTracker = context.deoptimizationTracker;
4769
4852
  this.module = context.module;
4770
- this.kind = kind;
4771
4853
  }
4772
4854
  addDeclaration(identifier, init) {
4773
4855
  this.declarations.push(identifier);
@@ -4778,7 +4860,6 @@ class LocalVariable extends Variable {
4778
4860
  for (const initializer of this.additionalInitializers) {
4779
4861
  initializer.deoptimizePath(UNKNOWN_PATH);
4780
4862
  }
4781
- this.additionalInitializers = null;
4782
4863
  }
4783
4864
  }
4784
4865
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
@@ -4786,7 +4867,7 @@ class LocalVariable extends Variable {
4786
4867
  deoptimizeInteraction(interaction);
4787
4868
  return;
4788
4869
  }
4789
- recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker), undefined);
4870
+ recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], recursionTracker), undefined);
4790
4871
  }
4791
4872
  deoptimizePath(path) {
4792
4873
  if (this.isReassigned ||
@@ -4800,10 +4881,10 @@ class LocalVariable extends Variable {
4800
4881
  for (const expression of expressionsToBeDeoptimized) {
4801
4882
  expression.deoptimizeCache();
4802
4883
  }
4803
- this.init.deoptimizePath(UNKNOWN_PATH);
4884
+ this.init.deoptimizePath([...this.initPath, UnknownKey]);
4804
4885
  }
4805
4886
  else {
4806
- this.init.deoptimizePath(path);
4887
+ this.init.deoptimizePath([...this.initPath, ...path]);
4807
4888
  }
4808
4889
  }
4809
4890
  getLiteralValueAtPath(path, recursionTracker, origin) {
@@ -4812,7 +4893,7 @@ class LocalVariable extends Variable {
4812
4893
  }
4813
4894
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
4814
4895
  this.expressionsToBeDeoptimized.push(origin);
4815
- return this.init.getLiteralValueAtPath(path, recursionTracker, origin);
4896
+ return this.init.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin);
4816
4897
  }, UnknownValue);
4817
4898
  }
4818
4899
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
@@ -4821,7 +4902,7 @@ class LocalVariable extends Variable {
4821
4902
  }
4822
4903
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
4823
4904
  this.expressionsToBeDeoptimized.push(origin);
4824
- return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
4905
+ return this.init.getReturnExpressionWhenCalledAtPath([...this.initPath, ...path], interaction, recursionTracker, origin);
4825
4906
  }, UNKNOWN_RETURN_EXPRESSION);
4826
4907
  }
4827
4908
  hasEffectsOnInteractionAtPath(path, interaction, context) {
@@ -4830,7 +4911,7 @@ class LocalVariable extends Variable {
4830
4911
  if (this.isReassigned)
4831
4912
  return true;
4832
4913
  return (!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
4833
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
4914
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4834
4915
  }
4835
4916
  case INTERACTION_ASSIGNED: {
4836
4917
  if (this.included)
@@ -4840,23 +4921,23 @@ class LocalVariable extends Variable {
4840
4921
  if (this.isReassigned)
4841
4922
  return true;
4842
4923
  return (!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
4843
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
4924
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4844
4925
  }
4845
4926
  case INTERACTION_CALLED: {
4846
4927
  if (this.isReassigned)
4847
4928
  return true;
4848
4929
  return (!(interaction.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this) &&
4849
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
4930
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4850
4931
  }
4851
4932
  }
4852
4933
  }
4853
- include() {
4854
- if (!this.included) {
4855
- super.include();
4934
+ includePath(path, context) {
4935
+ if (!this.includedPathTracker.includePathAndGetIfIncluded(path)) {
4936
+ super.includePath(path, context);
4856
4937
  for (const declaration of this.declarations) {
4857
4938
  // If node is a default export, it can save a tree-shaking run to include the full declaration now
4858
4939
  if (!declaration.included)
4859
- declaration.include(createInclusionContext(), false);
4940
+ declaration.includePath(EMPTY_PATH, context, false);
4860
4941
  let node = declaration.parent;
4861
4942
  while (!node.included) {
4862
4943
  // We do not want to properly include parents in case they are part of a dead branch
@@ -4867,17 +4948,26 @@ class LocalVariable extends Variable {
4867
4948
  node = node.parent;
4868
4949
  }
4869
4950
  }
4951
+ // We need to make sure we include the correct path of the init
4952
+ if (path.length > 0) {
4953
+ this.init.includePath([...this.initPath, ...path], context, false);
4954
+ this.additionalInitializers?.forEach(initializer => initializer.includePath(UNKNOWN_PATH, context, false));
4955
+ }
4870
4956
  }
4871
4957
  }
4872
- includeCallArguments(context, parameters) {
4873
- if (this.isReassigned || context.includedCallArguments.has(this.init)) {
4874
- for (const argument of parameters) {
4875
- argument.include(context, false);
4958
+ includeCallArguments(context, interaction) {
4959
+ if (this.isReassigned ||
4960
+ context.includedCallArguments.has(this.init) ||
4961
+ // This can be removed again once we can include arguments when called at
4962
+ // a specific path
4963
+ this.initPath.length > 0) {
4964
+ for (const argument of interaction.args) {
4965
+ argument?.includePath(UNKNOWN_PATH, context, false);
4876
4966
  }
4877
4967
  }
4878
4968
  else {
4879
4969
  context.includedCallArguments.add(this.init);
4880
- this.init.includeCallArguments(context, parameters);
4970
+ this.init.includeCallArguments(context, interaction);
4881
4971
  context.includedCallArguments.delete(this.init);
4882
4972
  }
4883
4973
  }
@@ -4957,18 +5047,21 @@ class IdentifierBase extends NodeBase {
4957
5047
  }
4958
5048
  }
4959
5049
  }
4960
- include() {
5050
+ includePath(path, context) {
4961
5051
  if (!this.deoptimized)
4962
5052
  this.applyDeoptimizations();
4963
5053
  if (!this.included) {
4964
5054
  this.included = true;
4965
5055
  if (this.variable !== null) {
4966
- this.scope.context.includeVariableInModule(this.variable);
5056
+ this.scope.context.includeVariableInModule(this.variable, path);
4967
5057
  }
4968
5058
  }
5059
+ else if (path.length > 0) {
5060
+ this.variable?.includePath(path, context);
5061
+ }
4969
5062
  }
4970
- includeCallArguments(context, parameters) {
4971
- this.variable.includeCallArguments(context, parameters);
5063
+ includeCallArguments(context, interaction) {
5064
+ this.variable.includeCallArguments(context, interaction);
4972
5065
  }
4973
5066
  isPossibleTDZ() {
4974
5067
  // return cached value to avoid issues with the next tree-shaking pass
@@ -5051,11 +5144,40 @@ function closestParentFunctionOrProgram(node) {
5051
5144
  return node;
5052
5145
  }
5053
5146
 
5147
+ class ObjectMember extends ExpressionEntity {
5148
+ constructor(object, path) {
5149
+ super();
5150
+ this.object = object;
5151
+ this.path = path;
5152
+ }
5153
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
5154
+ this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.path, ...path], recursionTracker);
5155
+ }
5156
+ deoptimizePath(path) {
5157
+ this.object.deoptimizePath([...this.path, ...path]);
5158
+ }
5159
+ getLiteralValueAtPath(path, recursionTracker, origin) {
5160
+ return this.object.getLiteralValueAtPath([...this.path, ...path], recursionTracker, origin);
5161
+ }
5162
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
5163
+ return this.object.getReturnExpressionWhenCalledAtPath([...this.path, ...path], interaction, recursionTracker, origin);
5164
+ }
5165
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
5166
+ return this.object.hasEffectsOnInteractionAtPath([...this.path, ...path], interaction, context);
5167
+ }
5168
+ }
5169
+
5054
5170
  class Identifier extends IdentifierBase {
5055
5171
  constructor() {
5056
5172
  super(...arguments);
5057
5173
  this.variable = null;
5058
5174
  }
5175
+ get isDestructuringDeoptimized() {
5176
+ return isFlagSet(this.flags, 8388608 /* Flag.destructuringDeoptimized */);
5177
+ }
5178
+ set isDestructuringDeoptimized(value) {
5179
+ this.flags = setFlag(this.flags, 8388608 /* Flag.destructuringDeoptimized */, value);
5180
+ }
5059
5181
  addExportedVariables(variables, exportNamesByVariable) {
5060
5182
  if (exportNamesByVariable.has(this.variable)) {
5061
5183
  variables.push(this.variable);
@@ -5068,43 +5190,53 @@ class Identifier extends IdentifierBase {
5068
5190
  this.isVariableReference = true;
5069
5191
  }
5070
5192
  }
5071
- declare(kind, init) {
5193
+ declare(kind, destructuredInitPath, init) {
5072
5194
  let variable;
5073
5195
  const { treeshake } = this.scope.context.options;
5074
- switch (kind) {
5075
- case 'var': {
5076
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5077
- if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
5078
- // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
5079
- variable.markInitializersForDeoptimization();
5080
- }
5081
- break;
5082
- }
5083
- case 'function': {
5084
- // in strict mode, functions are only hoisted within a scope but not across block scopes
5085
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5086
- break;
5087
- }
5088
- case 'let':
5089
- case 'const':
5090
- case 'using':
5091
- case 'await using':
5092
- case 'class': {
5093
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5094
- break;
5095
- }
5096
- case 'parameter': {
5097
- variable = this.scope.addParameterDeclaration(this);
5098
- break;
5099
- }
5100
- /* istanbul ignore next */
5101
- default: {
5102
- /* istanbul ignore next */
5103
- throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
5196
+ if (kind === 'parameter') {
5197
+ variable = this.scope.addParameterDeclaration(this, destructuredInitPath);
5198
+ }
5199
+ else {
5200
+ variable = this.scope.addDeclaration(this, this.scope.context, init, destructuredInitPath, kind);
5201
+ if (kind === 'var' && treeshake && treeshake.correctVarValueBeforeDeclaration) {
5202
+ // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
5203
+ variable.markInitializersForDeoptimization();
5104
5204
  }
5105
5205
  }
5106
5206
  return [(this.variable = variable)];
5107
5207
  }
5208
+ deoptimizeAssignment(destructuredInitPath, init) {
5209
+ this.deoptimizePath(EMPTY_PATH);
5210
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
5211
+ }
5212
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
5213
+ return (destructuredInitPath.length > 0 &&
5214
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
5215
+ }
5216
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
5217
+ if (destructuredInitPath.length > 0 && !this.isDestructuringDeoptimized) {
5218
+ this.isDestructuringDeoptimized = true;
5219
+ init.deoptimizeArgumentsOnInteractionAtPath({
5220
+ args: [new ObjectMember(init, destructuredInitPath.slice(0, -1))],
5221
+ type: INTERACTION_ACCESSED
5222
+ }, destructuredInitPath, SHARED_RECURSION_TRACKER);
5223
+ }
5224
+ const { propertyReadSideEffects } = this.scope.context.options
5225
+ .treeshake;
5226
+ if ((this.included ||=
5227
+ destructuredInitPath.length > 0 &&
5228
+ !context.brokenFlow &&
5229
+ propertyReadSideEffects &&
5230
+ (propertyReadSideEffects === 'always' ||
5231
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext())))) {
5232
+ if (this.variable && !this.variable.included) {
5233
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH);
5234
+ }
5235
+ init.includePath(destructuredInitPath, context, false);
5236
+ return true;
5237
+ }
5238
+ return false;
5239
+ }
5108
5240
  markDeclarationReached() {
5109
5241
  this.variable.initReached = true;
5110
5242
  }
@@ -5169,18 +5301,17 @@ class Scope {
5169
5301
  - then the variable is still declared in the hoisted outer scope, but the initializer is assigned to the parameter
5170
5302
  - const, let, class, and function except in the cases above cannot redeclare anything
5171
5303
  */
5172
- addDeclaration(identifier, context, init, kind) {
5304
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5173
5305
  const name = identifier.name;
5174
5306
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
5175
5307
  if (existingVariable) {
5176
- const existingKind = existingVariable.kind;
5177
- if (kind === 'var' && existingKind === 'var') {
5308
+ if (kind === 'var' && existingVariable.kind === 'var') {
5178
5309
  existingVariable.addDeclaration(identifier, init);
5179
5310
  return existingVariable;
5180
5311
  }
5181
5312
  context.error(logRedeclarationError(name), identifier.start);
5182
5313
  }
5183
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
5314
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
5184
5315
  this.variables.set(name, newVariable);
5185
5316
  return newVariable;
5186
5317
  }
@@ -5382,7 +5513,7 @@ class BlockScope extends ChildScope {
5382
5513
  constructor(parent) {
5383
5514
  super(parent, parent.context);
5384
5515
  }
5385
- addDeclaration(identifier, context, init, kind) {
5516
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5386
5517
  if (kind === 'var') {
5387
5518
  const name = identifier.name;
5388
5519
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -5394,7 +5525,7 @@ class BlockScope extends ChildScope {
5394
5525
  }
5395
5526
  return context.error(logRedeclarationError(name), identifier.start);
5396
5527
  }
5397
- const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind);
5528
+ const declaredVariable = this.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5398
5529
  // Necessary to make sure the init is deoptimized for conditional declarations.
5399
5530
  // We cannot call deoptimizePath here.
5400
5531
  declaredVariable.markInitializersForDeoptimization();
@@ -5402,7 +5533,7 @@ class BlockScope extends ChildScope {
5402
5533
  this.addHoistedVariable(name, declaredVariable);
5403
5534
  return declaredVariable;
5404
5535
  }
5405
- return super.addDeclaration(identifier, context, init, kind);
5536
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5406
5537
  }
5407
5538
  }
5408
5539
 
@@ -5417,11 +5548,11 @@ class StaticBlock extends NodeBase {
5417
5548
  }
5418
5549
  return false;
5419
5550
  }
5420
- include(context, includeChildrenRecursively) {
5551
+ includePath(_path, context, includeChildrenRecursively) {
5421
5552
  this.included = true;
5422
5553
  for (const node of this.body) {
5423
5554
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
5424
- node.include(context, includeChildrenRecursively);
5555
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
5425
5556
  }
5426
5557
  }
5427
5558
  render(code, options) {
@@ -5438,29 +5569,6 @@ function isStaticBlock(statement) {
5438
5569
  return statement.type === StaticBlock$1;
5439
5570
  }
5440
5571
 
5441
- class ObjectMember extends ExpressionEntity {
5442
- constructor(object, key) {
5443
- super();
5444
- this.object = object;
5445
- this.key = key;
5446
- }
5447
- deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
5448
- this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker);
5449
- }
5450
- deoptimizePath(path) {
5451
- this.object.deoptimizePath([this.key, ...path]);
5452
- }
5453
- getLiteralValueAtPath(path, recursionTracker, origin) {
5454
- return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin);
5455
- }
5456
- getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
5457
- return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin);
5458
- }
5459
- hasEffectsOnInteractionAtPath(path, interaction, context) {
5460
- return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context);
5461
- }
5462
- }
5463
-
5464
5572
  class ClassNode extends NodeBase {
5465
5573
  constructor() {
5466
5574
  super(...arguments);
@@ -5500,22 +5608,22 @@ class ClassNode extends NodeBase {
5500
5608
  false
5501
5609
  : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
5502
5610
  }
5503
- include(context, includeChildrenRecursively) {
5611
+ includePath(_path, context, includeChildrenRecursively) {
5504
5612
  if (!this.deoptimized)
5505
5613
  this.applyDeoptimizations();
5506
5614
  this.included = true;
5507
- this.superClass?.include(context, includeChildrenRecursively);
5508
- this.body.include(context, includeChildrenRecursively);
5615
+ this.superClass?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
5616
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
5509
5617
  for (const decorator of this.decorators)
5510
- decorator.include(context, includeChildrenRecursively);
5618
+ decorator.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
5511
5619
  if (this.id) {
5512
5620
  this.id.markDeclarationReached();
5513
- this.id.include();
5621
+ this.id.includePath(UNKNOWN_PATH, createInclusionContext());
5514
5622
  }
5515
5623
  }
5516
5624
  initialise() {
5517
5625
  super.initialise();
5518
- this.id?.declare('class', this);
5626
+ this.id?.declare('class', EMPTY_PATH, this);
5519
5627
  for (const method of this.body.body) {
5520
5628
  if (method instanceof MethodDefinition && method.kind === 'constructor') {
5521
5629
  this.classConstructor = method;
@@ -5573,7 +5681,7 @@ class ClassNode extends NodeBase {
5573
5681
  staticProperties.unshift({
5574
5682
  key: 'prototype',
5575
5683
  kind: 'init',
5576
- property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE)
5684
+ property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, ['prototype']) : OBJECT_PROTOTYPE)
5577
5685
  });
5578
5686
  return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE));
5579
5687
  }
@@ -5630,7 +5738,7 @@ class ClassDeclaration extends ClassNode {
5630
5738
 
5631
5739
  class ArgumentsVariable extends LocalVariable {
5632
5740
  constructor(context) {
5633
- super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');
5741
+ super('arguments', null, UNKNOWN_EXPRESSION, EMPTY_PATH, context, 'other');
5634
5742
  this.deoptimizedArguments = [];
5635
5743
  }
5636
5744
  addArgumentToBeDeoptimized(argument) {
@@ -5644,8 +5752,8 @@ class ArgumentsVariable extends LocalVariable {
5644
5752
  hasEffectsOnInteractionAtPath(path, { type }) {
5645
5753
  return type !== INTERACTION_ACCESSED || path.length > 1;
5646
5754
  }
5647
- include() {
5648
- super.include();
5755
+ includePath(path, context) {
5756
+ super.includePath(path, context);
5649
5757
  for (const argument of this.deoptimizedArguments) {
5650
5758
  argument.deoptimizePath(UNKNOWN_PATH);
5651
5759
  }
@@ -5656,27 +5764,28 @@ class ArgumentsVariable extends LocalVariable {
5656
5764
  const MAX_TRACKED_INTERACTIONS = 20;
5657
5765
  const NO_INTERACTIONS = EMPTY_ARRAY;
5658
5766
  const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);
5659
- const EMPTY_PATH_TRACKER = new PathTracker();
5767
+ const EMPTY_PATH_TRACKER = new EntityPathTracker();
5660
5768
  const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);
5661
5769
  class ParameterVariable extends LocalVariable {
5662
- constructor(name, declarator, context) {
5663
- super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');
5770
+ constructor(name, declarator, argumentPath, context) {
5771
+ super(name, declarator, UNKNOWN_EXPRESSION, argumentPath, context, 'parameter');
5664
5772
  this.deoptimizationInteractions = [];
5665
- this.deoptimizations = new PathTracker();
5773
+ this.deoptimizations = new EntityPathTracker();
5666
5774
  this.deoptimizedFields = new Set();
5667
- this.entitiesToBeDeoptimized = new Set();
5668
- this.expressionsUseTheKnownValue = [];
5775
+ this.argumentsToBeDeoptimized = new Set();
5776
+ this.expressionsDependingOnKnownValue = [];
5669
5777
  this.knownValue = null;
5670
5778
  this.knownValueLiteral = UnknownValue;
5671
5779
  this.frozenValue = null;
5672
5780
  }
5673
- addEntityToBeDeoptimized(entity) {
5781
+ addArgumentValue(entity) {
5782
+ this.updateKnownValue(entity);
5674
5783
  if (entity === UNKNOWN_EXPRESSION) {
5675
5784
  // As unknown expressions fully deoptimize all interactions, we can clear
5676
5785
  // the interaction cache at this point provided we keep this optimization
5677
5786
  // in mind when adding new interactions
5678
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5679
- this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);
5787
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5788
+ this.argumentsToBeDeoptimized.add(UNKNOWN_EXPRESSION);
5680
5789
  for (const { interaction } of this.deoptimizationInteractions) {
5681
5790
  deoptimizeInteraction(interaction);
5682
5791
  }
@@ -5686,27 +5795,30 @@ class ParameterVariable extends LocalVariable {
5686
5795
  else if (this.deoptimizedFields.has(UnknownKey)) {
5687
5796
  // This means that we already deoptimized all interactions and no longer
5688
5797
  // track them
5689
- entity.deoptimizePath(UNKNOWN_PATH);
5798
+ entity.deoptimizePath([...this.initPath, UnknownKey]);
5690
5799
  }
5691
- else if (!this.entitiesToBeDeoptimized.has(entity)) {
5692
- this.entitiesToBeDeoptimized.add(entity);
5800
+ else if (!this.argumentsToBeDeoptimized.has(entity)) {
5801
+ this.argumentsToBeDeoptimized.add(entity);
5693
5802
  for (const field of this.deoptimizedFields) {
5694
- entity.deoptimizePath([field]);
5803
+ entity.deoptimizePath([...this.initPath, field]);
5695
5804
  }
5696
5805
  for (const { interaction, path } of this.deoptimizationInteractions) {
5697
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
5806
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
5698
5807
  }
5699
5808
  }
5700
5809
  }
5810
+ /** This says we should not make assumptions about the value of the parameter.
5811
+ * This is different from deoptimization that will also cause argument values
5812
+ * to be deoptimized. */
5701
5813
  markReassigned() {
5702
5814
  if (this.isReassigned) {
5703
5815
  return;
5704
5816
  }
5705
5817
  super.markReassigned();
5706
- for (const expression of this.expressionsUseTheKnownValue) {
5818
+ for (const expression of this.expressionsDependingOnKnownValue) {
5707
5819
  expression.deoptimizeCache();
5708
5820
  }
5709
- this.expressionsUseTheKnownValue = EMPTY_ARRAY;
5821
+ this.expressionsDependingOnKnownValue = EMPTY_ARRAY;
5710
5822
  }
5711
5823
  deoptimizeCache() {
5712
5824
  this.markReassigned();
@@ -5723,7 +5835,7 @@ class ParameterVariable extends LocalVariable {
5723
5835
  }
5724
5836
  if (this.knownValue === null) {
5725
5837
  this.knownValue = argument;
5726
- this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
5838
+ this.knownValueLiteral = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
5727
5839
  return;
5728
5840
  }
5729
5841
  // the same literal or identifier, do nothing
@@ -5739,7 +5851,7 @@ class ParameterVariable extends LocalVariable {
5739
5851
  return;
5740
5852
  }
5741
5853
  // add tracking for the new argument
5742
- const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
5854
+ const newValue = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
5743
5855
  if (newValue !== oldValue) {
5744
5856
  this.markReassigned();
5745
5857
  }
@@ -5761,20 +5873,25 @@ class ParameterVariable extends LocalVariable {
5761
5873
  return UnknownValue;
5762
5874
  }
5763
5875
  const knownValue = this.getKnownValue();
5764
- this.expressionsUseTheKnownValue.push(origin);
5765
- return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);
5876
+ this.expressionsDependingOnKnownValue.push(origin);
5877
+ return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin), UnknownValue);
5766
5878
  }
5767
5879
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5768
- if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) {
5880
+ const { type } = interaction;
5881
+ if (this.isReassigned || type === INTERACTION_ASSIGNED) {
5769
5882
  return super.hasEffectsOnInteractionAtPath(path, interaction, context);
5770
5883
  }
5771
- const knownValue = this.getKnownValue();
5772
- return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context);
5884
+ return (!(type === INTERACTION_CALLED
5885
+ ? (interaction.withNew
5886
+ ? context.instantiated
5887
+ : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)
5888
+ : context.accessed.trackEntityAtPathAndGetIfTracked(path, this)) &&
5889
+ this.getKnownValue().hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
5773
5890
  }
5774
5891
  deoptimizeArgumentsOnInteractionAtPath(interaction, path) {
5775
5892
  // For performance reasons, we fully deoptimize all deeper interactions
5776
5893
  if (path.length >= 2 ||
5777
- this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
5894
+ this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
5778
5895
  this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||
5779
5896
  (path.length === 1 &&
5780
5897
  (this.deoptimizedFields.has(UnknownKey) ||
@@ -5783,10 +5900,10 @@ class ParameterVariable extends LocalVariable {
5783
5900
  return;
5784
5901
  }
5785
5902
  if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {
5786
- for (const entity of this.entitiesToBeDeoptimized) {
5787
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
5903
+ for (const entity of this.argumentsToBeDeoptimized) {
5904
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
5788
5905
  }
5789
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5906
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5790
5907
  this.deoptimizationInteractions.push({
5791
5908
  interaction,
5792
5909
  path
@@ -5807,17 +5924,17 @@ class ParameterVariable extends LocalVariable {
5807
5924
  return;
5808
5925
  }
5809
5926
  this.deoptimizedFields.add(key);
5810
- for (const entity of this.entitiesToBeDeoptimized) {
5927
+ for (const entity of this.argumentsToBeDeoptimized) {
5811
5928
  // We do not need a recursion tracker here as we already track whether
5812
5929
  // this field is deoptimized
5813
- entity.deoptimizePath([key]);
5930
+ entity.deoptimizePath([...this.initPath, key]);
5814
5931
  }
5815
5932
  if (key === UnknownKey) {
5816
5933
  // save some memory
5817
5934
  this.deoptimizationInteractions = NO_INTERACTIONS;
5818
5935
  this.deoptimizations = EMPTY_PATH_TRACKER;
5819
5936
  this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;
5820
- this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
5937
+ this.argumentsToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
5821
5938
  }
5822
5939
  }
5823
5940
  getReturnExpressionWhenCalledAtPath(path) {
@@ -5832,11 +5949,14 @@ class ParameterVariable extends LocalVariable {
5832
5949
  }
5833
5950
  return UNKNOWN_RETURN_EXPRESSION;
5834
5951
  }
5952
+ includeArgumentPaths(entity, context) {
5953
+ this.includedPathTracker.includeAllPaths(entity, context, this.initPath);
5954
+ }
5835
5955
  }
5836
5956
 
5837
5957
  class ThisVariable extends ParameterVariable {
5838
5958
  constructor(context) {
5839
- super('this', null, context);
5959
+ super('this', null, EMPTY_PATH, context);
5840
5960
  }
5841
5961
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5842
5962
  return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);
@@ -5848,7 +5968,7 @@ class CatchBodyScope extends ChildScope {
5848
5968
  super(parent, parent.context);
5849
5969
  this.parent = parent;
5850
5970
  }
5851
- addDeclaration(identifier, context, init, kind) {
5971
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5852
5972
  if (kind === 'var') {
5853
5973
  const name = identifier.name;
5854
5974
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -5861,7 +5981,7 @@ class CatchBodyScope extends ChildScope {
5861
5981
  // the assignment actually goes to the parameter and the var is
5862
5982
  // hoisted without assignment. Locally, it is shadowed by the
5863
5983
  // parameter
5864
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, kind);
5984
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, destructuredInitPath, kind);
5865
5985
  // To avoid the need to rewrite the declaration, we link the variable
5866
5986
  // names. If we ever implement a logic that splits initialization and
5867
5987
  // assignment for hoisted vars, the "renderLikeHoisted" logic can be
@@ -5880,7 +6000,7 @@ class CatchBodyScope extends ChildScope {
5880
6000
  return context.error(logRedeclarationError(name), identifier.start);
5881
6001
  }
5882
6002
  // We only add parameters to parameter scopes
5883
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, kind);
6003
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5884
6004
  // Necessary to make sure the init is deoptimized for conditional declarations.
5885
6005
  // We cannot call deoptimizePath here.
5886
6006
  declaredVariable.markInitializersForDeoptimization();
@@ -5888,7 +6008,7 @@ class CatchBodyScope extends ChildScope {
5888
6008
  this.addHoistedVariable(name, declaredVariable);
5889
6009
  return declaredVariable;
5890
6010
  }
5891
- return super.addDeclaration(identifier, context, init, kind);
6011
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5892
6012
  }
5893
6013
  }
5894
6014
 
@@ -5898,7 +6018,7 @@ class FunctionBodyScope extends ChildScope {
5898
6018
  }
5899
6019
  // There is stuff that is only allowed in function scopes, i.e. functions can
5900
6020
  // be redeclared, functions and var can redeclare each other
5901
- addDeclaration(identifier, context, init, kind) {
6021
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5902
6022
  const name = identifier.name;
5903
6023
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
5904
6024
  if (existingVariable) {
@@ -5910,7 +6030,7 @@ class FunctionBodyScope extends ChildScope {
5910
6030
  }
5911
6031
  context.error(logRedeclarationError(name), identifier.start);
5912
6032
  }
5913
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
6033
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
5914
6034
  this.variables.set(name, newVariable);
5915
6035
  return newVariable;
5916
6036
  }
@@ -5919,21 +6039,21 @@ class FunctionBodyScope extends ChildScope {
5919
6039
  class ParameterScope extends ChildScope {
5920
6040
  constructor(parent, isCatchScope) {
5921
6041
  super(parent, parent.context);
5922
- this.parameters = [];
5923
6042
  this.hasRest = false;
6043
+ this.parameters = [];
5924
6044
  this.bodyScope = isCatchScope ? new CatchBodyScope(this) : new FunctionBodyScope(this);
5925
6045
  }
5926
6046
  /**
5927
6047
  * Adds a parameter to this scope. Parameters must be added in the correct
5928
6048
  * order, i.e. from left to right.
5929
6049
  */
5930
- addParameterDeclaration(identifier) {
6050
+ addParameterDeclaration(identifier, argumentPath) {
5931
6051
  const { name, start } = identifier;
5932
6052
  const existingParameter = this.variables.get(name);
5933
6053
  if (existingParameter) {
5934
6054
  return this.context.error(logDuplicateArgumentNameError(name), start);
5935
6055
  }
5936
- const variable = new ParameterVariable(name, identifier, this.context);
6056
+ const variable = new ParameterVariable(name, identifier, argumentPath, this.context);
5937
6057
  this.variables.set(name, variable);
5938
6058
  // We also add it to the body scope to detect name conflicts with local
5939
6059
  // variables. We still need the intermediate scope, though, as parameter
@@ -5951,43 +6071,54 @@ class ParameterScope extends ChildScope {
5951
6071
  }
5952
6072
  this.hasRest = hasRest;
5953
6073
  }
5954
- includeCallArguments(context, parameters) {
6074
+ includeCallArguments(context, interaction) {
5955
6075
  let calledFromTryStatement = false;
5956
6076
  let argumentIncluded = false;
5957
6077
  const restParameter = this.hasRest && this.parameters[this.parameters.length - 1];
5958
- for (const checkedArgument of parameters) {
5959
- if (checkedArgument instanceof SpreadElement) {
5960
- for (const argument of parameters) {
5961
- argument.include(context, false);
5962
- }
5963
- break;
6078
+ const { args } = interaction;
6079
+ let lastExplicitlyIncludedIndex = args.length - 1;
6080
+ // If there is a SpreadElement, we need to include all arguments after it
6081
+ // because we no longer know which argument corresponds to which parameter.
6082
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
6083
+ if (args[argumentIndex] instanceof SpreadElement && !argumentIncluded) {
6084
+ argumentIncluded = true;
6085
+ lastExplicitlyIncludedIndex = argumentIndex - 1;
6086
+ }
6087
+ if (argumentIncluded) {
6088
+ args[argumentIndex].includePath(UNKNOWN_PATH, context, false);
5964
6089
  }
5965
6090
  }
5966
- for (let index = parameters.length - 1; index >= 0; index--) {
5967
- const parameterVariables = this.parameters[index] || restParameter;
5968
- const argument = parameters[index];
6091
+ // Now we go backwards either starting from the last argument or before the
6092
+ // first SpreadElement to ensure all arguments before are included as needed
6093
+ for (let index = lastExplicitlyIncludedIndex; index >= 1; index--) {
6094
+ const parameterVariables = this.parameters[index - 1] || restParameter;
6095
+ const argument = args[index];
5969
6096
  if (parameterVariables) {
5970
6097
  calledFromTryStatement = false;
5971
6098
  if (parameterVariables.length === 0) {
5972
- // handle empty destructuring
6099
+ // handle empty destructuring to avoid destructuring undefined
5973
6100
  argumentIncluded = true;
5974
6101
  }
5975
6102
  else {
5976
6103
  for (const variable of parameterVariables) {
5977
- if (variable.included) {
5978
- argumentIncluded = true;
5979
- }
5980
6104
  if (variable.calledFromTryStatement) {
5981
6105
  calledFromTryStatement = true;
5982
6106
  }
6107
+ if (variable.included) {
6108
+ argumentIncluded = true;
6109
+ if (calledFromTryStatement) {
6110
+ argument.includePath(UNKNOWN_PATH, context, true);
6111
+ }
6112
+ else {
6113
+ variable.includeArgumentPaths(argument, context);
6114
+ }
6115
+ }
5983
6116
  }
5984
6117
  }
5985
6118
  }
5986
- if (!argumentIncluded && argument.shouldBeIncluded(context)) {
6119
+ if (!argument.included && (argumentIncluded || argument.shouldBeIncluded(context))) {
5987
6120
  argumentIncluded = true;
5988
- }
5989
- if (argumentIncluded) {
5990
- argument.include(context, calledFromTryStatement);
6121
+ argument.includePath(EMPTY_PATH, context, calledFromTryStatement);
5991
6122
  }
5992
6123
  }
5993
6124
  }
@@ -6002,11 +6133,61 @@ class ReturnValueScope extends ParameterScope {
6002
6133
  addReturnExpression(expression) {
6003
6134
  this.returnExpressions.push(expression);
6004
6135
  }
6136
+ deoptimizeArgumentsOnCall(interaction) {
6137
+ const { parameters } = this;
6138
+ const { args } = interaction;
6139
+ let position = 0;
6140
+ for (; position < args.length - 1; position++) {
6141
+ // Only the "this" argument arg[0] can be null
6142
+ const argument = args[position + 1];
6143
+ if (argument instanceof SpreadElement) {
6144
+ // This deoptimizes the current and remaining parameters and arguments
6145
+ for (; position < parameters.length; position++) {
6146
+ args[position + 1]?.deoptimizePath(UNKNOWN_PATH);
6147
+ parameters[position].forEach(variable => variable.markReassigned());
6148
+ }
6149
+ break;
6150
+ }
6151
+ if (this.hasRest && position >= parameters.length - 1) {
6152
+ argument.deoptimizePath(UNKNOWN_PATH);
6153
+ }
6154
+ else {
6155
+ const variables = parameters[position];
6156
+ if (variables) {
6157
+ for (const variable of variables) {
6158
+ variable.addArgumentValue(argument);
6159
+ }
6160
+ }
6161
+ this.addArgumentToBeDeoptimized(argument);
6162
+ }
6163
+ }
6164
+ for (; position < parameters.length; position++) {
6165
+ for (const variable of parameters[position]) {
6166
+ variable.addArgumentValue(UNDEFINED_EXPRESSION);
6167
+ }
6168
+ }
6169
+ }
6005
6170
  getReturnExpression() {
6006
6171
  if (this.returnExpression === null)
6007
6172
  this.updateReturnExpression();
6008
6173
  return this.returnExpression;
6009
6174
  }
6175
+ deoptimizeAllParameters() {
6176
+ for (const parameter of this.parameters) {
6177
+ for (const variable of parameter) {
6178
+ variable.deoptimizePath(UNKNOWN_PATH);
6179
+ variable.markReassigned();
6180
+ }
6181
+ }
6182
+ }
6183
+ reassignAllParameters() {
6184
+ for (const parameter of this.parameters) {
6185
+ for (const variable of parameter) {
6186
+ variable.markReassigned();
6187
+ }
6188
+ }
6189
+ }
6190
+ addArgumentToBeDeoptimized(_argument) { }
6010
6191
  updateReturnExpression() {
6011
6192
  if (this.returnExpressions.length === 1) {
6012
6193
  this.returnExpression = this.returnExpressions[0];
@@ -6022,24 +6203,26 @@ class ReturnValueScope extends ParameterScope {
6022
6203
 
6023
6204
  class FunctionScope extends ReturnValueScope {
6024
6205
  constructor(parent) {
6025
- const { context } = parent;
6026
6206
  super(parent, false);
6207
+ const { context } = parent;
6027
6208
  this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));
6028
6209
  this.variables.set('this', (this.thisVariable = new ThisVariable(context)));
6029
6210
  }
6030
6211
  findLexicalBoundary() {
6031
6212
  return this;
6032
6213
  }
6033
- includeCallArguments(context, parameters) {
6034
- super.includeCallArguments(context, parameters);
6214
+ includeCallArguments(context, interaction) {
6215
+ super.includeCallArguments(context, interaction);
6035
6216
  if (this.argumentsVariable.included) {
6036
- for (const argument of parameters) {
6037
- if (!argument.included) {
6038
- argument.include(context, false);
6039
- }
6217
+ const { args } = interaction;
6218
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
6219
+ args[argumentIndex]?.includePath(UNKNOWN_PATH, context, false);
6040
6220
  }
6041
6221
  }
6042
6222
  }
6223
+ addArgumentToBeDeoptimized(argument) {
6224
+ this.argumentsVariable.addArgumentToBeDeoptimized(argument);
6225
+ }
6043
6226
  }
6044
6227
 
6045
6228
  class ExpressionStatement extends NodeBase {
@@ -6105,7 +6288,7 @@ class BlockStatement extends NodeBase {
6105
6288
  }
6106
6289
  return false;
6107
6290
  }
6108
- include(context, includeChildrenRecursively) {
6291
+ includePath(_path, context, includeChildrenRecursively) {
6109
6292
  if (!(this.deoptimizeBody && this.directlyIncluded)) {
6110
6293
  this.included = true;
6111
6294
  this.directlyIncluded = true;
@@ -6113,7 +6296,7 @@ class BlockStatement extends NodeBase {
6113
6296
  includeChildrenRecursively = true;
6114
6297
  for (const node of this.body) {
6115
6298
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
6116
- node.include(context, includeChildrenRecursively);
6299
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
6117
6300
  }
6118
6301
  }
6119
6302
  }
@@ -6142,9 +6325,12 @@ class RestElement extends NodeBase {
6142
6325
  addExportedVariables(variables, exportNamesByVariable) {
6143
6326
  this.argument.addExportedVariables(variables, exportNamesByVariable);
6144
6327
  }
6145
- declare(kind, init) {
6328
+ declare(kind, destructuredInitPath, init) {
6146
6329
  this.declarationInit = init;
6147
- return this.argument.declare(kind, UNKNOWN_EXPRESSION);
6330
+ return this.argument.declare(kind, getIncludedPatternPath$1(destructuredInitPath), init);
6331
+ }
6332
+ deoptimizeAssignment(destructuredInitPath, init) {
6333
+ this.argument.deoptimizeAssignment(getIncludedPatternPath$1(destructuredInitPath), init);
6148
6334
  }
6149
6335
  deoptimizePath(path) {
6150
6336
  if (path.length === 0) {
@@ -6155,6 +6341,19 @@ class RestElement extends NodeBase {
6155
6341
  return (path.length > 0 ||
6156
6342
  this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
6157
6343
  }
6344
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
6345
+ return this.argument.hasEffectsWhenDestructuring(context, getIncludedPatternPath$1(destructuredInitPath), init);
6346
+ }
6347
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
6348
+ return (this.included =
6349
+ this.argument.includeDestructuredIfNecessary(context, getIncludedPatternPath$1(destructuredInitPath), init) || this.included);
6350
+ }
6351
+ includePath(_path, context, includeChildrenRecursively) {
6352
+ this.included = true;
6353
+ // This should just include the identifier, its properties should be
6354
+ // included where the variable is used.
6355
+ this.argument.includePath(EMPTY_PATH, context, includeChildrenRecursively);
6356
+ }
6158
6357
  markDeclarationReached() {
6159
6358
  this.argument.markDeclarationReached();
6160
6359
  }
@@ -6166,12 +6365,15 @@ class RestElement extends NodeBase {
6166
6365
  }
6167
6366
  }
6168
6367
  }
6368
+ const getIncludedPatternPath$1 = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
6369
+ ? destructuredInitPath
6370
+ : [...destructuredInitPath, UnknownKey];
6169
6371
 
6170
6372
  class FunctionBase extends NodeBase {
6171
6373
  constructor() {
6172
6374
  super(...arguments);
6173
- this.objectEntity = null;
6174
6375
  this.parameterVariableValuesDeoptimized = false;
6376
+ this.includeCallArguments = this.scope.includeCallArguments.bind(this.scope);
6175
6377
  }
6176
6378
  get async() {
6177
6379
  return isFlagSet(this.flags, 256 /* Flag.async */);
@@ -6191,53 +6393,9 @@ class FunctionBase extends NodeBase {
6191
6393
  set generator(value) {
6192
6394
  this.flags = setFlag(this.flags, 4194304 /* Flag.generator */, value);
6193
6395
  }
6194
- updateParameterVariableValues(_arguments) {
6195
- for (let position = 0; position < this.params.length; position++) {
6196
- const parameter = this.params[position];
6197
- if (!(parameter instanceof Identifier)) {
6198
- continue;
6199
- }
6200
- const parameterVariable = parameter.variable;
6201
- const argument = _arguments[position + 1] ?? UNDEFINED_EXPRESSION;
6202
- parameterVariable.updateKnownValue(argument);
6203
- }
6204
- }
6205
- deoptimizeParameterVariableValues() {
6206
- for (const parameter of this.params) {
6207
- if (parameter instanceof Identifier) {
6208
- const parameterVariable = parameter.variable;
6209
- parameterVariable.markReassigned();
6210
- }
6211
- }
6212
- }
6213
6396
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6214
- if (interaction.type === INTERACTION_CALLED) {
6215
- const { parameters } = this.scope;
6216
- const { args } = interaction;
6217
- let hasRest = false;
6218
- for (let position = 0; position < args.length - 1; position++) {
6219
- const parameter = this.params[position];
6220
- // Only the "this" argument arg[0] can be null
6221
- const argument = args[position + 1];
6222
- if (argument instanceof SpreadElement) {
6223
- this.deoptimizeParameterVariableValues();
6224
- }
6225
- if (hasRest || parameter instanceof RestElement) {
6226
- hasRest = true;
6227
- argument.deoptimizePath(UNKNOWN_PATH);
6228
- }
6229
- else if (parameter instanceof Identifier) {
6230
- parameters[position][0].addEntityToBeDeoptimized(argument);
6231
- this.addArgumentToBeDeoptimized(argument);
6232
- }
6233
- else if (parameter) {
6234
- argument.deoptimizePath(UNKNOWN_PATH);
6235
- }
6236
- else {
6237
- this.addArgumentToBeDeoptimized(argument);
6238
- }
6239
- }
6240
- this.updateParameterVariableValues(args);
6397
+ if (interaction.type === INTERACTION_CALLED && path.length === 0) {
6398
+ this.scope.deoptimizeArgumentsOnCall(interaction);
6241
6399
  }
6242
6400
  else {
6243
6401
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -6249,12 +6407,7 @@ class FunctionBase extends NodeBase {
6249
6407
  // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
6250
6408
  // which means the return expression and parameters need to be reassigned
6251
6409
  this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
6252
- for (const parameterList of this.scope.parameters) {
6253
- for (const parameter of parameterList) {
6254
- parameter.deoptimizePath(UNKNOWN_PATH);
6255
- parameter.markReassigned();
6256
- }
6257
- }
6410
+ this.scope.deoptimizeAllParameters();
6258
6411
  }
6259
6412
  }
6260
6413
  getLiteralValueAtPath(path, recursionTracker, origin) {
@@ -6292,8 +6445,13 @@ class FunctionBase extends NodeBase {
6292
6445
  return true;
6293
6446
  }
6294
6447
  }
6295
- for (const parameter of this.params) {
6296
- if (parameter.hasEffects(context))
6448
+ const { propertyReadSideEffects } = this.scope.context.options
6449
+ .treeshake;
6450
+ for (let index = 0; index < this.params.length; index++) {
6451
+ const parameter = this.params[index];
6452
+ if (parameter.hasEffects(context) ||
6453
+ (propertyReadSideEffects &&
6454
+ parameter.hasEffectsWhenDestructuring(context, EMPTY_PATH, interaction.args[index + 1] || UNDEFINED_EXPRESSION)))
6297
6455
  return true;
6298
6456
  }
6299
6457
  return false;
@@ -6311,22 +6469,19 @@ class FunctionBase extends NodeBase {
6311
6469
  }
6312
6470
  return variable?.getOnlyFunctionCallUsed() ?? false;
6313
6471
  }
6314
- include(context, includeChildrenRecursively) {
6315
- if (!this.parameterVariableValuesDeoptimized && !this.onlyFunctionCallUsed()) {
6472
+ includePath(_path, context, includeChildrenRecursively) {
6473
+ if (!(this.parameterVariableValuesDeoptimized || this.onlyFunctionCallUsed())) {
6316
6474
  this.parameterVariableValuesDeoptimized = true;
6317
- this.deoptimizeParameterVariableValues();
6475
+ this.scope.reassignAllParameters();
6318
6476
  }
6319
6477
  if (!this.deoptimized)
6320
6478
  this.applyDeoptimizations();
6321
6479
  this.included = true;
6322
6480
  const { brokenFlow } = context;
6323
6481
  context.brokenFlow = false;
6324
- this.body.include(context, includeChildrenRecursively);
6482
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
6325
6483
  context.brokenFlow = brokenFlow;
6326
6484
  }
6327
- includeCallArguments(context, parameters) {
6328
- this.scope.includeCallArguments(context, parameters);
6329
- }
6330
6485
  initialise() {
6331
6486
  super.initialise();
6332
6487
  if (this.body instanceof BlockStatement) {
@@ -6348,11 +6503,10 @@ class FunctionBase extends NodeBase {
6348
6503
  // so that the scope already knows all parameters and can detect conflicts
6349
6504
  // when parsing the body.
6350
6505
  const parameters = (this.params = params.map((parameter) => new (context.getNodeConstructor(parameter.type))(this, scope).parseNode(parameter)));
6351
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
6506
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
6352
6507
  this.body = new (context.getNodeConstructor(body.type))(this, bodyScope).parseNode(body);
6353
6508
  return super.parseNode(esTreeNode);
6354
6509
  }
6355
- addArgumentToBeDeoptimized(_argument) { }
6356
6510
  applyDeoptimizations() { }
6357
6511
  }
6358
6512
  FunctionBase.prototype.preventChildBlockScope = true;
@@ -6367,13 +6521,13 @@ class FunctionNode extends FunctionBase {
6367
6521
  this.constructedEntity = new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE);
6368
6522
  // This makes sure that all deoptimizations of "this" are applied to the
6369
6523
  // constructed entity.
6370
- this.scope.thisVariable.addEntityToBeDeoptimized(this.constructedEntity);
6524
+ this.scope.thisVariable.addArgumentValue(this.constructedEntity);
6371
6525
  }
6372
6526
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6373
6527
  super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
6374
6528
  if (interaction.type === INTERACTION_CALLED && path.length === 0 && interaction.args[0]) {
6375
6529
  // args[0] is the "this" argument
6376
- this.scope.thisVariable.addEntityToBeDeoptimized(interaction.args[0]);
6530
+ this.scope.thisVariable.addArgumentValue(interaction.args[0]);
6377
6531
  }
6378
6532
  }
6379
6533
  hasEffects(context) {
@@ -6414,22 +6568,19 @@ class FunctionNode extends FunctionBase {
6414
6568
  }
6415
6569
  return false;
6416
6570
  }
6417
- include(context, includeChildrenRecursively) {
6418
- super.include(context, includeChildrenRecursively);
6419
- this.id?.include();
6571
+ includePath(path, context, includeChildrenRecursively) {
6572
+ super.includePath(path, context, includeChildrenRecursively);
6573
+ this.id?.includePath(UNKNOWN_PATH, createInclusionContext());
6420
6574
  const hasArguments = this.scope.argumentsVariable.included;
6421
6575
  for (const parameter of this.params) {
6422
6576
  if (!(parameter instanceof Identifier) || hasArguments) {
6423
- parameter.include(context, includeChildrenRecursively);
6577
+ parameter.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
6424
6578
  }
6425
6579
  }
6426
6580
  }
6427
6581
  initialise() {
6428
6582
  super.initialise();
6429
- this.id?.declare('function', this);
6430
- }
6431
- addArgumentToBeDeoptimized(argument) {
6432
- this.scope.argumentsVariable.addArgumentToBeDeoptimized(argument);
6583
+ this.id?.declare('function', EMPTY_PATH, this);
6433
6584
  }
6434
6585
  getObjectEntity() {
6435
6586
  if (this.objectEntity !== null) {
@@ -6478,10 +6629,11 @@ function getFunctionIdInsertPosition(code, start) {
6478
6629
  return declarationEnd + generatorStarPos + 1;
6479
6630
  }
6480
6631
  class ExportDefaultDeclaration extends NodeBase {
6481
- include(context, includeChildrenRecursively) {
6482
- super.include(context, includeChildrenRecursively);
6632
+ includePath(path, context, includeChildrenRecursively) {
6633
+ this.included = true;
6634
+ this.declaration.includePath(path, context, includeChildrenRecursively);
6483
6635
  if (includeChildrenRecursively) {
6484
- this.scope.context.includeVariableInModule(this.variable);
6636
+ this.scope.context.includeVariableInModule(this.variable, path);
6485
6637
  }
6486
6638
  }
6487
6639
  initialise() {
@@ -6950,6 +7102,10 @@ class MemberExpression extends NodeBase {
6950
7102
  }
6951
7103
  }
6952
7104
  }
7105
+ deoptimizeAssignment(destructuredInitPath, init) {
7106
+ this.deoptimizePath(EMPTY_PATH);
7107
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
7108
+ }
6953
7109
  deoptimizeCache() {
6954
7110
  const { expressionsToBeDeoptimized, object } = this;
6955
7111
  this.expressionsToBeDeoptimized = EMPTY_ARRAY;
@@ -7054,28 +7210,42 @@ class MemberExpression extends NodeBase {
7054
7210
  }
7055
7211
  return true;
7056
7212
  }
7057
- include(context, includeChildrenRecursively) {
7213
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
7214
+ return (destructuredInitPath.length > 0 &&
7215
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
7216
+ }
7217
+ includePath(path, context, includeChildrenRecursively) {
7058
7218
  if (!this.deoptimized)
7059
7219
  this.applyDeoptimizations();
7060
- this.includeProperties(context, includeChildrenRecursively);
7220
+ this.includeProperties(path, [this.getPropertyKey(), ...path], context, includeChildrenRecursively);
7061
7221
  }
7062
7222
  includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {
7063
7223
  if (!this.assignmentDeoptimized)
7064
7224
  this.applyAssignmentDeoptimization();
7065
7225
  if (deoptimizeAccess) {
7066
- this.include(context, includeChildrenRecursively);
7226
+ this.includePath([this.getPropertyKey()], context, includeChildrenRecursively);
7067
7227
  }
7068
7228
  else {
7069
- this.includeProperties(context, includeChildrenRecursively);
7229
+ this.includeProperties(EMPTY_PATH, [this.getPropertyKey()], context, includeChildrenRecursively);
7070
7230
  }
7071
7231
  }
7072
- includeCallArguments(context, parameters) {
7232
+ includeCallArguments(context, interaction) {
7073
7233
  if (this.variable) {
7074
- this.variable.includeCallArguments(context, parameters);
7234
+ this.variable.includeCallArguments(context, interaction);
7075
7235
  }
7076
7236
  else {
7077
- super.includeCallArguments(context, parameters);
7237
+ super.includeCallArguments(context, interaction);
7238
+ }
7239
+ }
7240
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
7241
+ if ((this.included ||=
7242
+ destructuredInitPath.length > 0 &&
7243
+ !context.brokenFlow &&
7244
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext()))) {
7245
+ init.includePath(destructuredInitPath, context, false);
7246
+ return true;
7078
7247
  }
7248
+ return false;
7079
7249
  }
7080
7250
  initialise() {
7081
7251
  super.initialise();
@@ -7143,7 +7313,7 @@ class MemberExpression extends NodeBase {
7143
7313
  const variable = this.scope.findVariable(this.object.name);
7144
7314
  if (variable.isNamespace) {
7145
7315
  if (this.variable) {
7146
- this.scope.context.includeVariableInModule(this.variable);
7316
+ this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH);
7147
7317
  }
7148
7318
  this.scope.context.log(LOGLEVEL_WARN, logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);
7149
7319
  }
@@ -7170,15 +7340,18 @@ class MemberExpression extends NodeBase {
7170
7340
  (propertyReadSideEffects === 'always' ||
7171
7341
  this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));
7172
7342
  }
7173
- includeProperties(context, includeChildrenRecursively) {
7343
+ includeProperties(includedPath, objectPath, context, includeChildrenRecursively) {
7174
7344
  if (!this.included) {
7175
7345
  this.included = true;
7176
7346
  if (this.variable) {
7177
- this.scope.context.includeVariableInModule(this.variable);
7347
+ this.scope.context.includeVariableInModule(this.variable, includedPath);
7178
7348
  }
7179
7349
  }
7180
- this.object.include(context, includeChildrenRecursively);
7181
- this.property.include(context, includeChildrenRecursively);
7350
+ else if (includedPath.length > 0) {
7351
+ this.variable?.includePath(includedPath, context);
7352
+ }
7353
+ this.object.includePath(objectPath, context, includeChildrenRecursively);
7354
+ this.property.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7182
7355
  }
7183
7356
  }
7184
7357
  function resolveNamespaceVariables(baseVariable, path, astContext) {
@@ -7221,7 +7394,7 @@ class MetaProperty extends NodeBase {
7221
7394
  hasEffectsOnInteractionAtPath(path, { type }) {
7222
7395
  return path.length > 1 || type !== INTERACTION_ACCESSED;
7223
7396
  }
7224
- include() {
7397
+ includePath() {
7225
7398
  if (!this.included) {
7226
7399
  this.included = true;
7227
7400
  if (this.meta.name === IMPORT) {
@@ -7340,7 +7513,7 @@ class UndefinedVariable extends Variable {
7340
7513
 
7341
7514
  class ExportDefaultVariable extends LocalVariable {
7342
7515
  constructor(name, exportDefaultDeclaration, context) {
7343
- super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');
7516
+ super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, EMPTY_PATH, context, 'other');
7344
7517
  this.hasId = false;
7345
7518
  this.originalId = null;
7346
7519
  this.originalVariable = null;
@@ -7489,8 +7662,8 @@ class NamespaceVariable extends Variable {
7489
7662
  return (!memberVariable ||
7490
7663
  memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));
7491
7664
  }
7492
- include() {
7493
- super.include();
7665
+ includePath(path, context) {
7666
+ super.includePath(path, context);
7494
7667
  this.context.includeAllExports();
7495
7668
  }
7496
7669
  prepare(accessedGlobalsByScope) {
@@ -7583,9 +7756,9 @@ class SyntheticNamedExportVariable extends Variable {
7583
7756
  getName(getPropertyAccess) {
7584
7757
  return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;
7585
7758
  }
7586
- include() {
7587
- super.include();
7588
- this.context.includeVariableInModule(this.syntheticNamespace);
7759
+ includePath(path, context) {
7760
+ super.includePath(path, context);
7761
+ this.context.includeVariableInModule(this.syntheticNamespace, path);
7589
7762
  }
7590
7763
  setRenderNames(baseName, name) {
7591
7764
  super.setRenderNames(baseName, name);
@@ -10784,21 +10957,37 @@ class ArrayPattern extends NodeBase {
10784
10957
  element?.addExportedVariables(variables, exportNamesByVariable);
10785
10958
  }
10786
10959
  }
10787
- declare(kind) {
10960
+ declare(kind, destructuredInitPath, init) {
10788
10961
  const variables = [];
10962
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
10789
10963
  for (const element of this.elements) {
10790
10964
  if (element !== null) {
10791
- variables.push(...element.declare(kind, UNKNOWN_EXPRESSION));
10965
+ variables.push(...element.declare(kind, includedPatternPath, init));
10792
10966
  }
10793
10967
  }
10794
10968
  return variables;
10795
10969
  }
10970
+ deoptimizeAssignment(destructuredInitPath, init) {
10971
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
10972
+ for (const element of this.elements) {
10973
+ element?.deoptimizeAssignment(includedPatternPath, init);
10974
+ }
10975
+ }
10796
10976
  // Patterns can only be deoptimized at the empty path at the moment
10797
10977
  deoptimizePath() {
10798
10978
  for (const element of this.elements) {
10799
10979
  element?.deoptimizePath(EMPTY_PATH);
10800
10980
  }
10801
10981
  }
10982
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
10983
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
10984
+ for (const element of this.elements) {
10985
+ if (element?.hasEffectsWhenDestructuring(context, includedPatternPath, init)) {
10986
+ return true;
10987
+ }
10988
+ }
10989
+ return false;
10990
+ }
10802
10991
  // Patterns are only checked at the empty path at the moment
10803
10992
  hasEffectsOnInteractionAtPath(_path, interaction, context) {
10804
10993
  for (const element of this.elements) {
@@ -10807,12 +10996,24 @@ class ArrayPattern extends NodeBase {
10807
10996
  }
10808
10997
  return false;
10809
10998
  }
10999
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11000
+ let included = false;
11001
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
11002
+ for (const element of this.elements) {
11003
+ included =
11004
+ element?.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
11005
+ }
11006
+ return (this.included ||= included);
11007
+ }
10810
11008
  markDeclarationReached() {
10811
11009
  for (const element of this.elements) {
10812
11010
  element?.markDeclarationReached();
10813
11011
  }
10814
11012
  }
10815
11013
  }
11014
+ const getIncludedPatternPath = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
11015
+ ? destructuredInitPath
11016
+ : [...destructuredInitPath, UnknownInteger];
10816
11017
 
10817
11018
  class ArrowFunctionExpression extends FunctionBase {
10818
11019
  constructor() {
@@ -10861,11 +11062,11 @@ class ArrowFunctionExpression extends FunctionBase {
10861
11062
  this.parent.callee === this;
10862
11063
  return isIIFE || super.onlyFunctionCallUsed();
10863
11064
  }
10864
- include(context, includeChildrenRecursively) {
10865
- super.include(context, includeChildrenRecursively);
11065
+ includePath(_path, context, includeChildrenRecursively) {
11066
+ super.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
10866
11067
  for (const parameter of this.params) {
10867
11068
  if (!(parameter instanceof Identifier)) {
10868
- parameter.include(context, includeChildrenRecursively);
11069
+ parameter.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
10869
11070
  }
10870
11071
  }
10871
11072
  }
@@ -10888,13 +11089,18 @@ class ObjectPattern extends NodeBase {
10888
11089
  }
10889
11090
  }
10890
11091
  }
10891
- declare(kind, init) {
11092
+ declare(kind, destructuredInitPath, init) {
10892
11093
  const variables = [];
10893
11094
  for (const property of this.properties) {
10894
- variables.push(...property.declare(kind, init));
11095
+ variables.push(...property.declare(kind, destructuredInitPath, init));
10895
11096
  }
10896
11097
  return variables;
10897
11098
  }
11099
+ deoptimizeAssignment(destructuredInitPath, init) {
11100
+ for (const property of this.properties) {
11101
+ property.deoptimizeAssignment(destructuredInitPath, init);
11102
+ }
11103
+ }
10898
11104
  deoptimizePath(path) {
10899
11105
  if (path.length === 0) {
10900
11106
  for (const property of this.properties) {
@@ -10912,11 +11118,44 @@ class ObjectPattern extends NodeBase {
10912
11118
  }
10913
11119
  return false;
10914
11120
  }
11121
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
11122
+ for (const property of this.properties) {
11123
+ if (property.hasEffectsWhenDestructuring(context, destructuredInitPath, init))
11124
+ return true;
11125
+ }
11126
+ return false;
11127
+ }
11128
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11129
+ let included = false;
11130
+ for (const property of this.properties) {
11131
+ included =
11132
+ property.includeDestructuredIfNecessary(context, destructuredInitPath, init) || included;
11133
+ }
11134
+ return (this.included ||= included);
11135
+ }
10915
11136
  markDeclarationReached() {
10916
11137
  for (const property of this.properties) {
10917
11138
  property.markDeclarationReached();
10918
11139
  }
10919
11140
  }
11141
+ render(code, options) {
11142
+ if (this.properties.length > 0) {
11143
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
11144
+ let lastSeparatorPos = null;
11145
+ for (const { node, separator, start, end } of separatedNodes) {
11146
+ if (!node.included) {
11147
+ treeshakeNode(node, code, start, end);
11148
+ continue;
11149
+ }
11150
+ lastSeparatorPos = separator;
11151
+ node.render(code, options);
11152
+ }
11153
+ if (lastSeparatorPos) {
11154
+ code.remove(lastSeparatorPos, this.end - 1);
11155
+ }
11156
+ }
11157
+ }
11158
+ applyDeoptimizations() { }
10920
11159
  }
10921
11160
 
10922
11161
  class AssignmentExpression extends NodeBase {
@@ -10926,23 +11165,27 @@ class AssignmentExpression extends NodeBase {
10926
11165
  this.applyDeoptimizations();
10927
11166
  // MemberExpressions do not access the property before assignments if the
10928
11167
  // operator is '='.
10929
- return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '='));
11168
+ return (right.hasEffects(context) ||
11169
+ left.hasEffectsAsAssignmentTarget(context, operator !== '=') ||
11170
+ this.left.hasEffectsWhenDestructuring?.(context, EMPTY_PATH, right));
10930
11171
  }
10931
11172
  hasEffectsOnInteractionAtPath(path, interaction, context) {
10932
11173
  return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);
10933
11174
  }
10934
- include(context, includeChildrenRecursively) {
11175
+ includePath(_path, context, includeChildrenRecursively) {
10935
11176
  const { deoptimized, left, right, operator } = this;
10936
11177
  if (!deoptimized)
10937
11178
  this.applyDeoptimizations();
10938
11179
  this.included = true;
11180
+ const hasEffectsContext = createHasEffectsContext();
10939
11181
  if (includeChildrenRecursively ||
10940
11182
  operator !== '=' ||
10941
11183
  left.included ||
10942
- left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {
11184
+ left.hasEffectsAsAssignmentTarget(hasEffectsContext, false) ||
11185
+ left.hasEffectsWhenDestructuring?.(hasEffectsContext, EMPTY_PATH, right)) {
10943
11186
  left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');
10944
11187
  }
10945
- right.include(context, includeChildrenRecursively);
11188
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
10946
11189
  }
10947
11190
  initialise() {
10948
11191
  super.initialise();
@@ -11004,8 +11247,7 @@ class AssignmentExpression extends NodeBase {
11004
11247
  }
11005
11248
  applyDeoptimizations() {
11006
11249
  this.deoptimized = true;
11007
- this.left.deoptimizePath(EMPTY_PATH);
11008
- this.right.deoptimizePath(UNKNOWN_PATH);
11250
+ this.left.deoptimizeAssignment(EMPTY_PATH, this.right);
11009
11251
  this.scope.context.requestTreeshakingPass();
11010
11252
  }
11011
11253
  }
@@ -11014,8 +11256,11 @@ class AssignmentPattern extends NodeBase {
11014
11256
  addExportedVariables(variables, exportNamesByVariable) {
11015
11257
  this.left.addExportedVariables(variables, exportNamesByVariable);
11016
11258
  }
11017
- declare(kind, init) {
11018
- return this.left.declare(kind, init);
11259
+ declare(kind, destructuredInitPath, init) {
11260
+ return this.left.declare(kind, destructuredInitPath, init);
11261
+ }
11262
+ deoptimizeAssignment(destructuredInitPath, init) {
11263
+ this.left.deoptimizeAssignment(destructuredInitPath, init);
11019
11264
  }
11020
11265
  deoptimizePath(path) {
11021
11266
  if (path.length === 0) {
@@ -11025,6 +11270,17 @@ class AssignmentPattern extends NodeBase {
11025
11270
  hasEffectsOnInteractionAtPath(path, interaction, context) {
11026
11271
  return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
11027
11272
  }
11273
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
11274
+ return this.left.hasEffectsWhenDestructuring(context, destructuredInitPath, init);
11275
+ }
11276
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11277
+ let included = this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init) ||
11278
+ this.included;
11279
+ if ((included ||= this.right.shouldBeIncluded(context))) {
11280
+ this.right.includePath(UNKNOWN_PATH, context, false);
11281
+ }
11282
+ return (this.included = included);
11283
+ }
11028
11284
  markDeclarationReached() {
11029
11285
  this.left.markDeclarationReached();
11030
11286
  }
@@ -11046,7 +11302,7 @@ class AwaitExpression extends NodeBase {
11046
11302
  this.applyDeoptimizations();
11047
11303
  return true;
11048
11304
  }
11049
- include(context, includeChildrenRecursively) {
11305
+ includePath(path, context, includeChildrenRecursively) {
11050
11306
  if (!this.deoptimized)
11051
11307
  this.applyDeoptimizations();
11052
11308
  if (!this.included) {
@@ -11060,7 +11316,7 @@ class AwaitExpression extends NodeBase {
11060
11316
  this.scope.context.usesTopLevelAwait = true;
11061
11317
  }
11062
11318
  }
11063
- this.argument.include(context, includeChildrenRecursively);
11319
+ this.argument.includePath(path, context, includeChildrenRecursively);
11064
11320
  }
11065
11321
  }
11066
11322
 
@@ -11142,10 +11398,10 @@ class BreakStatement extends NodeBase {
11142
11398
  context.brokenFlow = true;
11143
11399
  return false;
11144
11400
  }
11145
- include(context) {
11401
+ includePath(_, context) {
11146
11402
  this.included = true;
11147
11403
  if (this.label) {
11148
- this.label.include();
11404
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
11149
11405
  context.includedLabels.add(this.label.name);
11150
11406
  }
11151
11407
  else {
@@ -11339,11 +11595,11 @@ class CallExpression extends CallExpressionBase {
11339
11595
  (calleeHasEffects ||
11340
11596
  this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)));
11341
11597
  }
11342
- include(context, includeChildrenRecursively) {
11598
+ includePath(path, context, includeChildrenRecursively) {
11343
11599
  if (!this.deoptimized)
11344
11600
  this.applyDeoptimizations();
11345
11601
  if (includeChildrenRecursively) {
11346
- super.include(context, includeChildrenRecursively);
11602
+ super.includePath(path, context, includeChildrenRecursively);
11347
11603
  if (includeChildrenRecursively === INCLUDE_PARAMETERS &&
11348
11604
  this.callee instanceof Identifier &&
11349
11605
  this.callee.variable) {
@@ -11352,9 +11608,18 @@ class CallExpression extends CallExpressionBase {
11352
11608
  }
11353
11609
  else {
11354
11610
  this.included = true;
11355
- this.callee.include(context, false);
11611
+ // If the callee is a member expression and does not have a variable, its
11612
+ // object will already be included via the first argument of the
11613
+ // interaction in includeCallArguments. Including it again can lead to
11614
+ // severe performance problems.
11615
+ if (this.callee instanceof MemberExpression && !this.callee.variable) {
11616
+ this.callee.property.includePath(UNKNOWN_PATH, context, false);
11617
+ }
11618
+ else {
11619
+ this.callee.includePath(UNKNOWN_PATH, context, false);
11620
+ }
11621
+ this.callee.includeCallArguments(context, this.interaction);
11356
11622
  }
11357
- this.callee.includeCallArguments(context, this.arguments);
11358
11623
  }
11359
11624
  initialise() {
11360
11625
  super.initialise();
@@ -11393,7 +11658,7 @@ class CatchClause extends NodeBase {
11393
11658
  this.type = type;
11394
11659
  if (param) {
11395
11660
  this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);
11396
- this.param.declare('parameter', UNKNOWN_EXPRESSION);
11661
+ this.param.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
11397
11662
  }
11398
11663
  this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);
11399
11664
  return super.parseNode(esTreeNode);
@@ -11421,7 +11686,7 @@ class ClassBodyScope extends ChildScope {
11421
11686
  constructor(parent, classNode) {
11422
11687
  const { context } = parent;
11423
11688
  super(parent, context);
11424
- this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));
11689
+ this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, EMPTY_PATH, context, 'other')));
11425
11690
  this.instanceScope = new ChildScope(this, context);
11426
11691
  this.instanceScope.variables.set('this', new ThisVariable(context));
11427
11692
  }
@@ -11434,11 +11699,11 @@ class ClassBody extends NodeBase {
11434
11699
  createScope(parentScope) {
11435
11700
  this.scope = new ClassBodyScope(parentScope, this.parent);
11436
11701
  }
11437
- include(context, includeChildrenRecursively) {
11702
+ includePath(_path, context, includeChildrenRecursively) {
11438
11703
  this.included = true;
11439
- this.scope.context.includeVariableInModule(this.scope.thisVariable);
11704
+ this.scope.context.includeVariableInModule(this.scope.thisVariable, UNKNOWN_PATH);
11440
11705
  for (const definition of this.body) {
11441
- definition.include(context, includeChildrenRecursively);
11706
+ definition.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11442
11707
  }
11443
11708
  }
11444
11709
  parseNode(esTreeNode) {
@@ -11562,26 +11827,26 @@ class ConditionalExpression extends NodeBase {
11562
11827
  }
11563
11828
  return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
11564
11829
  }
11565
- include(context, includeChildrenRecursively) {
11830
+ includePath(path, context, includeChildrenRecursively) {
11566
11831
  this.included = true;
11567
11832
  const usedBranch = this.getUsedBranch();
11568
11833
  if (includeChildrenRecursively || this.test.shouldBeIncluded(context) || usedBranch === null) {
11569
- this.test.include(context, includeChildrenRecursively);
11570
- this.consequent.include(context, includeChildrenRecursively);
11571
- this.alternate.include(context, includeChildrenRecursively);
11834
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11835
+ this.consequent.includePath(path, context, includeChildrenRecursively);
11836
+ this.alternate.includePath(path, context, includeChildrenRecursively);
11572
11837
  }
11573
11838
  else {
11574
- usedBranch.include(context, includeChildrenRecursively);
11839
+ usedBranch.includePath(path, context, includeChildrenRecursively);
11575
11840
  }
11576
11841
  }
11577
- includeCallArguments(context, parameters) {
11842
+ includeCallArguments(context, interaction) {
11578
11843
  const usedBranch = this.getUsedBranch();
11579
11844
  if (usedBranch) {
11580
- usedBranch.includeCallArguments(context, parameters);
11845
+ usedBranch.includeCallArguments(context, interaction);
11581
11846
  }
11582
11847
  else {
11583
- this.consequent.includeCallArguments(context, parameters);
11584
- this.alternate.includeCallArguments(context, parameters);
11848
+ this.consequent.includeCallArguments(context, interaction);
11849
+ this.alternate.includeCallArguments(context, interaction);
11585
11850
  }
11586
11851
  }
11587
11852
  removeAnnotations(code) {
@@ -11642,10 +11907,10 @@ class ContinueStatement extends NodeBase {
11642
11907
  context.brokenFlow = true;
11643
11908
  return false;
11644
11909
  }
11645
- include(context) {
11910
+ includePath(_, context) {
11646
11911
  this.included = true;
11647
11912
  if (this.label) {
11648
- this.label.include();
11913
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
11649
11914
  context.includedLabels.add(this.label.name);
11650
11915
  }
11651
11916
  else {
@@ -11688,7 +11953,7 @@ function includeLoopBody(context, body, includeChildrenRecursively) {
11688
11953
  const { brokenFlow, hasBreak, hasContinue } = context;
11689
11954
  context.hasBreak = false;
11690
11955
  context.hasContinue = false;
11691
- body.include(context, includeChildrenRecursively, { asSingleStatement: true });
11956
+ body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively, { asSingleStatement: true });
11692
11957
  context.hasBreak = hasBreak;
11693
11958
  context.hasContinue = hasContinue;
11694
11959
  context.brokenFlow = brokenFlow;
@@ -11700,9 +11965,9 @@ class DoWhileStatement extends NodeBase {
11700
11965
  return true;
11701
11966
  return hasLoopBodyEffects(context, this.body);
11702
11967
  }
11703
- include(context, includeChildrenRecursively) {
11968
+ includePath(_path, context, includeChildrenRecursively) {
11704
11969
  this.included = true;
11705
- this.test.include(context, includeChildrenRecursively);
11970
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11706
11971
  includeLoopBody(context, this.body, includeChildrenRecursively);
11707
11972
  }
11708
11973
  }
@@ -11773,13 +12038,13 @@ class ForInStatement extends NodeBase {
11773
12038
  return true;
11774
12039
  return hasLoopBodyEffects(context, body);
11775
12040
  }
11776
- include(context, includeChildrenRecursively) {
12041
+ includePath(_path, context, includeChildrenRecursively) {
11777
12042
  const { body, deoptimized, left, right } = this;
11778
12043
  if (!deoptimized)
11779
12044
  this.applyDeoptimizations();
11780
12045
  this.included = true;
11781
12046
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
11782
- right.include(context, includeChildrenRecursively);
12047
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11783
12048
  includeLoopBody(context, body, includeChildrenRecursively);
11784
12049
  }
11785
12050
  initialise() {
@@ -11818,13 +12083,13 @@ class ForOfStatement extends NodeBase {
11818
12083
  // Placeholder until proper Symbol.Iterator support
11819
12084
  return true;
11820
12085
  }
11821
- include(context, includeChildrenRecursively) {
12086
+ includePath(_path, context, includeChildrenRecursively) {
11822
12087
  const { body, deoptimized, left, right } = this;
11823
12088
  if (!deoptimized)
11824
12089
  this.applyDeoptimizations();
11825
12090
  this.included = true;
11826
12091
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
11827
- right.include(context, includeChildrenRecursively);
12092
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11828
12093
  includeLoopBody(context, body, includeChildrenRecursively);
11829
12094
  }
11830
12095
  initialise() {
@@ -11860,11 +12125,13 @@ class ForStatement extends NodeBase {
11860
12125
  }
11861
12126
  return hasLoopBodyEffects(context, this.body);
11862
12127
  }
11863
- include(context, includeChildrenRecursively) {
12128
+ includePath(_path, context, includeChildrenRecursively) {
11864
12129
  this.included = true;
11865
- this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true });
11866
- this.test?.include(context, includeChildrenRecursively);
11867
- this.update?.include(context, includeChildrenRecursively);
12130
+ this.init?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively, {
12131
+ asSingleStatement: true
12132
+ });
12133
+ this.test?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12134
+ this.update?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11868
12135
  includeLoopBody(context, this.body, includeChildrenRecursively);
11869
12136
  }
11870
12137
  render(code, options) {
@@ -11905,9 +12172,9 @@ class TrackingScope extends BlockScope {
11905
12172
  super(...arguments);
11906
12173
  this.hoistedDeclarations = [];
11907
12174
  }
11908
- addDeclaration(identifier, context, init, kind) {
12175
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
11909
12176
  this.hoistedDeclarations.push(identifier);
11910
- return super.addDeclaration(identifier, context, init, kind);
12177
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
11911
12178
  }
11912
12179
  }
11913
12180
 
@@ -11940,7 +12207,7 @@ class IfStatement extends NodeBase {
11940
12207
  }
11941
12208
  return testValue ? this.consequent.hasEffects(context) : !!this.alternate?.hasEffects(context);
11942
12209
  }
11943
- include(context, includeChildrenRecursively) {
12210
+ includePath(_, context, includeChildrenRecursively) {
11944
12211
  this.included = true;
11945
12212
  if (includeChildrenRecursively) {
11946
12213
  this.includeRecursively(includeChildrenRecursively, context);
@@ -12015,31 +12282,31 @@ class IfStatement extends NodeBase {
12015
12282
  }
12016
12283
  includeKnownTest(context, testValue) {
12017
12284
  if (this.test.shouldBeIncluded(context)) {
12018
- this.test.include(context, false);
12285
+ this.test.includePath(UNKNOWN_PATH, context, false);
12019
12286
  }
12020
12287
  if (testValue && this.consequent.shouldBeIncluded(context)) {
12021
- this.consequent.include(context, false, { asSingleStatement: true });
12288
+ this.consequent.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
12022
12289
  }
12023
12290
  if (!testValue && this.alternate?.shouldBeIncluded(context)) {
12024
- this.alternate.include(context, false, { asSingleStatement: true });
12291
+ this.alternate.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
12025
12292
  }
12026
12293
  }
12027
12294
  includeRecursively(includeChildrenRecursively, context) {
12028
- this.test.include(context, includeChildrenRecursively);
12029
- this.consequent.include(context, includeChildrenRecursively);
12030
- this.alternate?.include(context, includeChildrenRecursively);
12295
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12296
+ this.consequent.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12297
+ this.alternate?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12031
12298
  }
12032
12299
  includeUnknownTest(context) {
12033
- this.test.include(context, false);
12300
+ this.test.includePath(UNKNOWN_PATH, context, false);
12034
12301
  const { brokenFlow } = context;
12035
12302
  let consequentBrokenFlow = false;
12036
12303
  if (this.consequent.shouldBeIncluded(context)) {
12037
- this.consequent.include(context, false, { asSingleStatement: true });
12304
+ this.consequent.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
12038
12305
  consequentBrokenFlow = context.brokenFlow;
12039
12306
  context.brokenFlow = brokenFlow;
12040
12307
  }
12041
12308
  if (this.alternate?.shouldBeIncluded(context)) {
12042
- this.alternate.include(context, false, { asSingleStatement: true });
12309
+ this.alternate.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
12043
12310
  context.brokenFlow = context.brokenFlow && consequentBrokenFlow;
12044
12311
  }
12045
12312
  }
@@ -12107,7 +12374,7 @@ function isReassignedExportsMember(variable, exportNamesByVariable) {
12107
12374
  class VariableDeclarator extends NodeBase {
12108
12375
  declareDeclarator(kind, isUsingDeclaration) {
12109
12376
  this.isUsingDeclaration = isUsingDeclaration;
12110
- this.id.declare(kind, this.init || UNDEFINED_EXPRESSION);
12377
+ this.id.declare(kind, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION);
12111
12378
  }
12112
12379
  deoptimizePath(path) {
12113
12380
  this.id.deoptimizePath(path);
@@ -12117,17 +12384,25 @@ class VariableDeclarator extends NodeBase {
12117
12384
  this.applyDeoptimizations();
12118
12385
  const initEffect = this.init?.hasEffects(context);
12119
12386
  this.id.markDeclarationReached();
12120
- return initEffect || this.id.hasEffects(context) || this.isUsingDeclaration;
12121
- }
12122
- include(context, includeChildrenRecursively) {
12387
+ return (initEffect ||
12388
+ this.isUsingDeclaration ||
12389
+ this.id.hasEffects(context) ||
12390
+ (this.scope.context.options.treeshake
12391
+ .propertyReadSideEffects &&
12392
+ this.id.hasEffectsWhenDestructuring(context, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION)));
12393
+ }
12394
+ includePath(_path, context, includeChildrenRecursively) {
12123
12395
  const { deoptimized, id, init } = this;
12124
12396
  if (!deoptimized)
12125
12397
  this.applyDeoptimizations();
12126
12398
  this.included = true;
12127
- init?.include(context, includeChildrenRecursively);
12399
+ init?.includePath(EMPTY_PATH, context, includeChildrenRecursively);
12128
12400
  id.markDeclarationReached();
12129
- if (includeChildrenRecursively || id.shouldBeIncluded(context)) {
12130
- id.include(context, includeChildrenRecursively);
12401
+ if (includeChildrenRecursively) {
12402
+ id.includePath(EMPTY_PATH, context, includeChildrenRecursively);
12403
+ }
12404
+ else {
12405
+ id.includeDestructuredIfNecessary(context, EMPTY_PATH, init || UNDEFINED_EXPRESSION);
12131
12406
  }
12132
12407
  }
12133
12408
  removeAnnotations(code) {
@@ -12176,6 +12451,8 @@ class ImportExpression extends NodeBase {
12176
12451
  constructor() {
12177
12452
  super(...arguments);
12178
12453
  this.inlineNamespace = null;
12454
+ this.hasUnknownAccessedKey = false;
12455
+ this.accessedPropKey = new Set();
12179
12456
  this.attributes = null;
12180
12457
  this.mechanism = null;
12181
12458
  this.namespaceExportName = undefined;
@@ -12208,12 +12485,15 @@ class ImportExpression extends NodeBase {
12208
12485
  if (parent2 instanceof ExpressionStatement) {
12209
12486
  return EMPTY_ARRAY;
12210
12487
  }
12211
- // Case 1: const { foo } = await import('bar')
12488
+ // Case 1: const { foo } / module = await import('bar')
12212
12489
  if (parent2 instanceof VariableDeclarator) {
12213
12490
  const declaration = parent2.id;
12214
- return declaration instanceof ObjectPattern
12215
- ? getDeterministicObjectDestructure(declaration)
12216
- : undefined;
12491
+ if (declaration instanceof Identifier) {
12492
+ return this.hasUnknownAccessedKey ? undefined : [...this.accessedPropKey];
12493
+ }
12494
+ if (declaration instanceof ObjectPattern) {
12495
+ return getDeterministicObjectDestructure(declaration);
12496
+ }
12217
12497
  }
12218
12498
  // Case 2: (await import('bar')).foo
12219
12499
  if (parent2 instanceof MemberExpression) {
@@ -12262,13 +12542,23 @@ class ImportExpression extends NodeBase {
12262
12542
  hasEffects() {
12263
12543
  return true;
12264
12544
  }
12265
- include(context, includeChildrenRecursively) {
12545
+ includePath(path, context, includeChildrenRecursively) {
12266
12546
  if (!this.included) {
12267
12547
  this.included = true;
12268
12548
  this.scope.context.includeDynamicImport(this);
12269
12549
  this.scope.addAccessedDynamicImport(this);
12550
+ this.source.includePath(path, context, includeChildrenRecursively);
12551
+ }
12552
+ if (this.hasUnknownAccessedKey)
12553
+ return;
12554
+ if (path[0] === UnknownKey) {
12555
+ this.hasUnknownAccessedKey = true;
12556
+ this.scope.context.includeDynamicImport(this);
12557
+ }
12558
+ else if (typeof path[0] === 'string') {
12559
+ this.accessedPropKey.add(path[0]);
12560
+ this.scope.context.includeDynamicImport(this);
12270
12561
  }
12271
- this.source.include(context, includeChildrenRecursively);
12272
12562
  }
12273
12563
  initialise() {
12274
12564
  super.initialise();
@@ -12596,7 +12886,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
12596
12886
  if (preserve) {
12597
12887
  // This pretends we are accessing an included global variable of the same name
12598
12888
  const globalVariable = node.scope.findGlobal(baseName);
12599
- globalVariable.include();
12889
+ globalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
12600
12890
  // This excludes this variable from renaming
12601
12891
  factoryVariable.globalName = baseName;
12602
12892
  }
@@ -12604,7 +12894,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
12604
12894
  else {
12605
12895
  factoryVariable = node.scope.findGlobal(baseName);
12606
12896
  }
12607
- node.scope.context.includeVariableInModule(factoryVariable);
12897
+ node.scope.context.includeVariableInModule(factoryVariable, UNKNOWN_PATH);
12608
12898
  if (factoryVariable instanceof LocalVariable) {
12609
12899
  factoryVariable.consolidateInitializers();
12610
12900
  factoryVariable.addUsedPlace(node);
@@ -12626,7 +12916,7 @@ class JSXElementBase extends NodeBase {
12626
12916
  this.scope.context.addImportSource(importSource);
12627
12917
  }
12628
12918
  }
12629
- include(context, includeChildrenRecursively) {
12919
+ includePath(path, context, includeChildrenRecursively) {
12630
12920
  if (!this.included) {
12631
12921
  const { factory, importSource, mode } = this.jsxMode;
12632
12922
  if (factory) {
@@ -12634,7 +12924,7 @@ class JSXElementBase extends NodeBase {
12634
12924
  this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this);
12635
12925
  }
12636
12926
  }
12637
- super.include(context, includeChildrenRecursively);
12927
+ super.includePath(path, context, includeChildrenRecursively);
12638
12928
  }
12639
12929
  applyDeoptimizations() { }
12640
12930
  getRenderingMode() {
@@ -12896,7 +13186,7 @@ class JSXOpeningFragment extends NodeBase {
12896
13186
  this.fragment = null;
12897
13187
  this.fragmentVariable = null;
12898
13188
  }
12899
- include(context, includeChildrenRecursively) {
13189
+ includePath(path, context, includeChildrenRecursively) {
12900
13190
  if (!this.included) {
12901
13191
  const jsx = this.scope.context.options.jsx;
12902
13192
  if (jsx.mode === 'automatic') {
@@ -12911,7 +13201,7 @@ class JSXOpeningFragment extends NodeBase {
12911
13201
  }
12912
13202
  }
12913
13203
  }
12914
- super.include(context, includeChildrenRecursively);
13204
+ super.includePath(path, context, includeChildrenRecursively);
12915
13205
  }
12916
13206
  render(code, options) {
12917
13207
  const { mode } = this.scope.context.options.jsx;
@@ -12968,13 +13258,13 @@ class LabeledStatement extends NodeBase {
12968
13258
  context.includedLabels = new Set([...includedLabels, ...context.includedLabels]);
12969
13259
  return bodyHasEffects;
12970
13260
  }
12971
- include(context, includeChildrenRecursively) {
13261
+ includePath(_path, context, includeChildrenRecursively) {
12972
13262
  this.included = true;
12973
13263
  const { brokenFlow, includedLabels } = context;
12974
13264
  context.includedLabels = new Set();
12975
- this.body.include(context, includeChildrenRecursively);
13265
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12976
13266
  if (includeChildrenRecursively || context.includedLabels.has(this.label.name)) {
12977
- this.label.include();
13267
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
12978
13268
  context.includedLabels.delete(this.label.name);
12979
13269
  context.brokenFlow = brokenFlow;
12980
13270
  }
@@ -13071,17 +13361,17 @@ class LogicalExpression extends NodeBase {
13071
13361
  }
13072
13362
  return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
13073
13363
  }
13074
- include(context, includeChildrenRecursively) {
13364
+ includePath(path, context, includeChildrenRecursively) {
13075
13365
  this.included = true;
13076
13366
  const usedBranch = this.getUsedBranch();
13077
13367
  if (includeChildrenRecursively ||
13078
13368
  (usedBranch === this.right && this.left.shouldBeIncluded(context)) ||
13079
13369
  !usedBranch) {
13080
- this.left.include(context, includeChildrenRecursively);
13081
- this.right.include(context, includeChildrenRecursively);
13370
+ this.left.includePath(path, context, includeChildrenRecursively);
13371
+ this.right.includePath(path, context, includeChildrenRecursively);
13082
13372
  }
13083
13373
  else {
13084
- usedBranch.include(context, includeChildrenRecursively);
13374
+ usedBranch.includePath(path, context, includeChildrenRecursively);
13085
13375
  }
13086
13376
  }
13087
13377
  removeAnnotations(code) {
@@ -13153,17 +13443,17 @@ class NewExpression extends NodeBase {
13153
13443
  hasEffectsOnInteractionAtPath(path, { type }) {
13154
13444
  return path.length > 0 || type !== INTERACTION_ACCESSED;
13155
13445
  }
13156
- include(context, includeChildrenRecursively) {
13446
+ includePath(path, context, includeChildrenRecursively) {
13157
13447
  if (!this.deoptimized)
13158
13448
  this.applyDeoptimizations();
13159
13449
  if (includeChildrenRecursively) {
13160
- super.include(context, includeChildrenRecursively);
13450
+ super.includePath(path, context, includeChildrenRecursively);
13161
13451
  }
13162
13452
  else {
13163
13453
  this.included = true;
13164
- this.callee.include(context, false);
13454
+ this.callee.includePath(UNKNOWN_PATH, context, false);
13165
13455
  }
13166
- this.callee.includeCallArguments(context, this.arguments);
13456
+ this.callee.includeCallArguments(context, this.interaction);
13167
13457
  }
13168
13458
  initialise() {
13169
13459
  super.initialise();
@@ -13192,6 +13482,7 @@ class ObjectExpression extends NodeBase {
13192
13482
  constructor() {
13193
13483
  super(...arguments);
13194
13484
  this.objectEntity = null;
13485
+ this.protoProp = null;
13195
13486
  }
13196
13487
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
13197
13488
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -13211,13 +13502,32 @@ class ObjectExpression extends NodeBase {
13211
13502
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13212
13503
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
13213
13504
  }
13505
+ includePath(path, context, includeChildrenRecursively) {
13506
+ this.included = true;
13507
+ this.getObjectEntity().includePath(path, context, includeChildrenRecursively);
13508
+ this.protoProp?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13509
+ }
13214
13510
  render(code, options, { renderedSurroundingElement } = BLANK) {
13215
- super.render(code, options);
13216
13511
  if (renderedSurroundingElement === ExpressionStatement$1 ||
13217
13512
  renderedSurroundingElement === ArrowFunctionExpression$1) {
13218
13513
  code.appendRight(this.start, '(');
13219
13514
  code.prependLeft(this.end, ')');
13220
13515
  }
13516
+ if (this.properties.length > 0) {
13517
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
13518
+ let lastSeparatorPos = null;
13519
+ for (const { node, separator, start, end } of separatedNodes) {
13520
+ if (!node.included) {
13521
+ treeshakeNode(node, code, start, end);
13522
+ continue;
13523
+ }
13524
+ lastSeparatorPos = separator;
13525
+ node.render(code, options);
13526
+ }
13527
+ if (lastSeparatorPos) {
13528
+ code.remove(lastSeparatorPos, this.end - 1);
13529
+ }
13530
+ }
13221
13531
  }
13222
13532
  applyDeoptimizations() { }
13223
13533
  getObjectEntity() {
@@ -13248,6 +13558,7 @@ class ObjectExpression extends NodeBase {
13248
13558
  ? property.key.name
13249
13559
  : String(property.key.value);
13250
13560
  if (key === '__proto__' && property.kind === 'init') {
13561
+ this.protoProp = property;
13251
13562
  prototype =
13252
13563
  property.value instanceof Literal && property.value.value === null
13253
13564
  ? null
@@ -13314,11 +13625,11 @@ class Program extends NodeBase {
13314
13625
  }
13315
13626
  return false;
13316
13627
  }
13317
- include(context, includeChildrenRecursively) {
13628
+ includePath(_path, context, includeChildrenRecursively) {
13318
13629
  this.included = true;
13319
13630
  for (const node of this.body) {
13320
13631
  if (includeChildrenRecursively || node.shouldBeIncluded(context)) {
13321
- node.include(context, includeChildrenRecursively);
13632
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13322
13633
  }
13323
13634
  }
13324
13635
  }
@@ -13357,10 +13668,6 @@ class Program extends NodeBase {
13357
13668
  }
13358
13669
 
13359
13670
  class Property extends MethodBase {
13360
- constructor() {
13361
- super(...arguments);
13362
- this.declarationInit = null;
13363
- }
13364
13671
  //declare method: boolean;
13365
13672
  get method() {
13366
13673
  return isFlagSet(this.flags, 262144 /* Flag.method */);
@@ -13375,17 +13682,32 @@ class Property extends MethodBase {
13375
13682
  set shorthand(value) {
13376
13683
  this.flags = setFlag(this.flags, 524288 /* Flag.shorthand */, value);
13377
13684
  }
13378
- declare(kind, init) {
13379
- this.declarationInit = init;
13380
- return this.value.declare(kind, UNKNOWN_EXPRESSION);
13685
+ declare(kind, destructuredInitPath, init) {
13686
+ return this.value.declare(kind, this.getPathInProperty(destructuredInitPath), init);
13687
+ }
13688
+ deoptimizeAssignment(destructuredInitPath, init) {
13689
+ this.value.deoptimizeAssignment?.(this.getPathInProperty(destructuredInitPath), init);
13381
13690
  }
13382
13691
  hasEffects(context) {
13383
13692
  if (!this.deoptimized)
13384
13693
  this.applyDeoptimizations();
13385
- const propertyReadSideEffects = this.scope.context.options.treeshake.propertyReadSideEffects;
13386
- return ((this.parent.type === 'ObjectPattern' && propertyReadSideEffects === 'always') ||
13387
- this.key.hasEffects(context) ||
13388
- this.value.hasEffects(context));
13694
+ return this.key.hasEffects(context) || this.value.hasEffects(context);
13695
+ }
13696
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
13697
+ return this.value.hasEffectsWhenDestructuring?.(context, this.getPathInProperty(destructuredInitPath), init);
13698
+ }
13699
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
13700
+ let included = this.value.includeDestructuredIfNecessary(context, this.getPathInProperty(destructuredInitPath), init) || this.included;
13701
+ included ||= this.key.hasEffects(createHasEffectsContext());
13702
+ if (included) {
13703
+ this.key.includePath(EMPTY_PATH, context, false);
13704
+ }
13705
+ return (this.included = included);
13706
+ }
13707
+ includePath(path, context, includeChildrenRecursively) {
13708
+ this.included = true;
13709
+ this.key.includePath(EMPTY_PATH, context, includeChildrenRecursively);
13710
+ this.value.includePath(path, context, includeChildrenRecursively);
13389
13711
  }
13390
13712
  markDeclarationReached() {
13391
13713
  this.value.markDeclarationReached();
@@ -13396,12 +13718,17 @@ class Property extends MethodBase {
13396
13718
  }
13397
13719
  this.value.render(code, options, { isShorthandProperty: this.shorthand });
13398
13720
  }
13399
- applyDeoptimizations() {
13400
- this.deoptimized = true;
13401
- if (this.declarationInit !== null) {
13402
- this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
13403
- this.scope.context.requestTreeshakingPass();
13404
- }
13721
+ applyDeoptimizations() { }
13722
+ getPathInProperty(destructuredInitPath) {
13723
+ return destructuredInitPath.at(-1) === UnknownKey
13724
+ ? destructuredInitPath
13725
+ : // For now, we only consider static paths as we do not know how to
13726
+ // deoptimize the path in the dynamic case.
13727
+ this.computed
13728
+ ? [...destructuredInitPath, UnknownKey]
13729
+ : this.key instanceof Identifier
13730
+ ? [...destructuredInitPath, this.key.name]
13731
+ : [...destructuredInitPath, String(this.key.value)];
13405
13732
  }
13406
13733
  }
13407
13734
 
@@ -13446,9 +13773,9 @@ class ReturnStatement extends NodeBase {
13446
13773
  context.brokenFlow = true;
13447
13774
  return false;
13448
13775
  }
13449
- include(context, includeChildrenRecursively) {
13776
+ includePath(_path, context, includeChildrenRecursively) {
13450
13777
  this.included = true;
13451
- this.argument?.include(context, includeChildrenRecursively);
13778
+ this.argument?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13452
13779
  context.brokenFlow = true;
13453
13780
  }
13454
13781
  initialise() {
@@ -13485,14 +13812,14 @@ class SequenceExpression extends NodeBase {
13485
13812
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13486
13813
  return this.expressions[this.expressions.length - 1].hasEffectsOnInteractionAtPath(path, interaction, context);
13487
13814
  }
13488
- include(context, includeChildrenRecursively) {
13815
+ includePath(path, context, includeChildrenRecursively) {
13489
13816
  this.included = true;
13490
13817
  const lastExpression = this.expressions[this.expressions.length - 1];
13491
13818
  for (const expression of this.expressions) {
13492
13819
  if (includeChildrenRecursively ||
13493
13820
  (expression === lastExpression && !(this.parent instanceof ExpressionStatement)) ||
13494
13821
  expression.shouldBeIncluded(context))
13495
- expression.include(context, includeChildrenRecursively);
13822
+ expression.includePath(path, context, includeChildrenRecursively);
13496
13823
  }
13497
13824
  }
13498
13825
  removeAnnotations(code) {
@@ -13540,10 +13867,13 @@ class Super extends NodeBase {
13540
13867
  deoptimizePath(path) {
13541
13868
  this.variable.deoptimizePath(path);
13542
13869
  }
13543
- include() {
13870
+ includePath(path, context) {
13544
13871
  if (!this.included) {
13545
13872
  this.included = true;
13546
- this.scope.context.includeVariableInModule(this.variable);
13873
+ this.scope.context.includeVariableInModule(this.variable, path);
13874
+ }
13875
+ else if (path.length > 0) {
13876
+ this.variable.includePath(path, context);
13547
13877
  }
13548
13878
  }
13549
13879
  }
@@ -13560,12 +13890,12 @@ class SwitchCase extends NodeBase {
13560
13890
  }
13561
13891
  return false;
13562
13892
  }
13563
- include(context, includeChildrenRecursively) {
13893
+ includePath(_path, context, includeChildrenRecursively) {
13564
13894
  this.included = true;
13565
- this.test?.include(context, includeChildrenRecursively);
13895
+ this.test?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13566
13896
  for (const node of this.consequent) {
13567
13897
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
13568
- node.include(context, includeChildrenRecursively);
13898
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13569
13899
  }
13570
13900
  }
13571
13901
  render(code, options, nodeRenderOptions) {
@@ -13613,9 +13943,9 @@ class SwitchStatement extends NodeBase {
13613
13943
  context.hasBreak = hasBreak;
13614
13944
  return false;
13615
13945
  }
13616
- include(context, includeChildrenRecursively) {
13946
+ includePath(_path, context, includeChildrenRecursively) {
13617
13947
  this.included = true;
13618
- this.discriminant.include(context, includeChildrenRecursively);
13948
+ this.discriminant.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13619
13949
  const { brokenFlow, hasBreak } = context;
13620
13950
  context.hasBreak = false;
13621
13951
  let onlyHasBrokenFlow = true;
@@ -13632,7 +13962,7 @@ class SwitchStatement extends NodeBase {
13632
13962
  isCaseIncluded = switchCase.hasEffects(hasEffectsContext);
13633
13963
  }
13634
13964
  if (isCaseIncluded) {
13635
- switchCase.include(context, includeChildrenRecursively);
13965
+ switchCase.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13636
13966
  onlyHasBrokenFlow &&= context.brokenFlow && !context.hasBreak;
13637
13967
  context.hasBreak = false;
13638
13968
  context.brokenFlow = brokenFlow;
@@ -13689,21 +14019,21 @@ class TaggedTemplateExpression extends CallExpressionBase {
13689
14019
  return (this.tag.hasEffects(context) ||
13690
14020
  this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
13691
14021
  }
13692
- include(context, includeChildrenRecursively) {
14022
+ includePath(path, context, includeChildrenRecursively) {
13693
14023
  if (!this.deoptimized)
13694
14024
  this.applyDeoptimizations();
13695
14025
  if (includeChildrenRecursively) {
13696
- super.include(context, includeChildrenRecursively);
14026
+ super.includePath(path, context, includeChildrenRecursively);
13697
14027
  }
13698
14028
  else {
13699
14029
  this.included = true;
13700
- this.tag.include(context, includeChildrenRecursively);
13701
- this.quasi.include(context, includeChildrenRecursively);
14030
+ this.tag.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14031
+ this.quasi.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13702
14032
  }
13703
- this.tag.includeCallArguments(context, this.args);
14033
+ this.tag.includeCallArguments(context, this.interaction);
13704
14034
  const [returnExpression] = this.getReturnExpression();
13705
14035
  if (!returnExpression.included) {
13706
- returnExpression.include(context, false);
14036
+ returnExpression.includePath(UNKNOWN_PATH, context, false);
13707
14037
  }
13708
14038
  }
13709
14039
  initialise() {
@@ -13748,7 +14078,7 @@ class TemplateElement extends NodeBase {
13748
14078
  hasEffects() {
13749
14079
  return false;
13750
14080
  }
13751
- include() {
14081
+ includePath() {
13752
14082
  this.included = true;
13753
14083
  }
13754
14084
  parseNode(esTreeNode) {
@@ -13790,13 +14120,13 @@ class TemplateLiteral extends NodeBase {
13790
14120
  class ModuleScope extends ChildScope {
13791
14121
  constructor(parent, context) {
13792
14122
  super(parent, context);
13793
- this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, context, 'other'));
14123
+ this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, EMPTY_PATH, context, 'other'));
13794
14124
  }
13795
- addDeclaration(identifier, context, init, kind) {
14125
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
13796
14126
  if (this.context.module.importDescriptions.has(identifier.name)) {
13797
14127
  context.error(logRedeclarationError(identifier.name), identifier.start);
13798
14128
  }
13799
- return super.addDeclaration(identifier, context, init, kind);
14129
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
13800
14130
  }
13801
14131
  addExportDefaultDeclaration(name, exportDefaultDeclaration, context) {
13802
14132
  const variable = new ExportDefaultVariable(name, exportDefaultDeclaration, context);
@@ -13841,10 +14171,13 @@ class ThisExpression extends NodeBase {
13841
14171
  }
13842
14172
  return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
13843
14173
  }
13844
- include() {
14174
+ includePath(path, context) {
13845
14175
  if (!this.included) {
13846
14176
  this.included = true;
13847
- this.scope.context.includeVariableInModule(this.variable);
14177
+ this.scope.context.includeVariableInModule(this.variable, path);
14178
+ }
14179
+ else if (path.length > 0) {
14180
+ this.variable.includePath(path, context);
13848
14181
  }
13849
14182
  }
13850
14183
  initialise() {
@@ -13871,9 +14204,9 @@ class ThrowStatement extends NodeBase {
13871
14204
  hasEffects() {
13872
14205
  return true;
13873
14206
  }
13874
- include(context, includeChildrenRecursively) {
14207
+ includePath(_path, context, includeChildrenRecursively) {
13875
14208
  this.included = true;
13876
- this.argument.include(context, includeChildrenRecursively);
14209
+ this.argument.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13877
14210
  context.brokenFlow = true;
13878
14211
  }
13879
14212
  render(code, options) {
@@ -13895,13 +14228,13 @@ class TryStatement extends NodeBase {
13895
14228
  ? this.block.body.length > 0
13896
14229
  : this.block.hasEffects(context)) || !!this.finalizer?.hasEffects(context));
13897
14230
  }
13898
- include(context, includeChildrenRecursively) {
14231
+ includePath(_path, context, includeChildrenRecursively) {
13899
14232
  const tryCatchDeoptimization = this.scope.context.options.treeshake?.tryCatchDeoptimization;
13900
14233
  const { brokenFlow, includedLabels } = context;
13901
14234
  if (!this.directlyIncluded || !tryCatchDeoptimization) {
13902
14235
  this.included = true;
13903
14236
  this.directlyIncluded = true;
13904
- this.block.include(context, tryCatchDeoptimization ? INCLUDE_PARAMETERS : includeChildrenRecursively);
14237
+ this.block.includePath(UNKNOWN_PATH, context, tryCatchDeoptimization ? INCLUDE_PARAMETERS : includeChildrenRecursively);
13905
14238
  if (includedLabels.size > 0) {
13906
14239
  this.includedLabelsAfterBlock = [...includedLabels];
13907
14240
  }
@@ -13913,10 +14246,10 @@ class TryStatement extends NodeBase {
13913
14246
  }
13914
14247
  }
13915
14248
  if (this.handler !== null) {
13916
- this.handler.include(context, includeChildrenRecursively);
14249
+ this.handler.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13917
14250
  context.brokenFlow = brokenFlow;
13918
14251
  }
13919
- this.finalizer?.include(context, includeChildrenRecursively);
14252
+ this.finalizer?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13920
14253
  }
13921
14254
  }
13922
14255
 
@@ -13974,7 +14307,7 @@ class UpdateExpression extends NodeBase {
13974
14307
  hasEffectsOnInteractionAtPath(path, { type }) {
13975
14308
  return path.length > 1 || type !== INTERACTION_ACCESSED;
13976
14309
  }
13977
- include(context, includeChildrenRecursively) {
14310
+ includePath(_, context, includeChildrenRecursively) {
13978
14311
  if (!this.deoptimized)
13979
14312
  this.applyDeoptimizations();
13980
14313
  this.included = true;
@@ -14043,20 +14376,20 @@ class VariableDeclaration extends NodeBase {
14043
14376
  hasEffectsOnInteractionAtPath() {
14044
14377
  return false;
14045
14378
  }
14046
- include(context, includeChildrenRecursively, { asSingleStatement } = BLANK) {
14379
+ includePath(_path, context, includeChildrenRecursively, { asSingleStatement } = BLANK) {
14047
14380
  this.included = true;
14048
14381
  for (const declarator of this.declarations) {
14049
14382
  if (includeChildrenRecursively || declarator.shouldBeIncluded(context))
14050
- declarator.include(context, includeChildrenRecursively);
14383
+ declarator.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14051
14384
  const { id, init } = declarator;
14052
14385
  if (asSingleStatement) {
14053
- id.include(context, includeChildrenRecursively);
14386
+ id.includePath(EMPTY_PATH, context, includeChildrenRecursively);
14054
14387
  }
14055
14388
  if (init &&
14056
14389
  id.included &&
14057
14390
  !init.included &&
14058
14391
  (id instanceof ObjectPattern || id instanceof ArrayPattern)) {
14059
- init.include(context, includeChildrenRecursively);
14392
+ init.includePath(EMPTY_PATH, context, includeChildrenRecursively);
14060
14393
  }
14061
14394
  }
14062
14395
  }
@@ -14128,8 +14461,7 @@ class VariableDeclaration extends NodeBase {
14128
14461
  const singleSystemExport = gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregatedSystemExports);
14129
14462
  for (const { node, start, separator, contentEnd, end } of separatedNodes) {
14130
14463
  if (!node.included) {
14131
- code.remove(start, end);
14132
- node.removeAnnotations(code);
14464
+ treeshakeNode(node, code, start, end);
14133
14465
  continue;
14134
14466
  }
14135
14467
  node.render(code, options);
@@ -14206,9 +14538,9 @@ class WhileStatement extends NodeBase {
14206
14538
  return true;
14207
14539
  return hasLoopBodyEffects(context, this.body);
14208
14540
  }
14209
- include(context, includeChildrenRecursively) {
14541
+ includePath(_path, context, includeChildrenRecursively) {
14210
14542
  this.included = true;
14211
- this.test.include(context, includeChildrenRecursively);
14543
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14212
14544
  includeLoopBody(context, this.body, includeChildrenRecursively);
14213
14545
  }
14214
14546
  }
@@ -14452,7 +14784,7 @@ const bufferParsers = [
14452
14784
  const annotations = (node.annotations = convertAnnotations(buffer[position + 1], buffer));
14453
14785
  node.annotationNoSideEffects = annotations.some(comment => comment.type === 'noSideEffects');
14454
14786
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 2], buffer));
14455
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14787
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14456
14788
  node.body = convertNode(node, scope.bodyScope, buffer[position + 3], buffer);
14457
14789
  },
14458
14790
  function assignmentExpression(node, position, buffer) {
@@ -14498,7 +14830,7 @@ const bufferParsers = [
14498
14830
  const parameterPosition = buffer[position];
14499
14831
  const parameter = (node.param =
14500
14832
  parameterPosition === 0 ? null : convertNode(node, scope, parameterPosition, buffer));
14501
- parameter?.declare('parameter', UNKNOWN_EXPRESSION);
14833
+ parameter?.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
14502
14834
  node.body = convertNode(node, scope.bodyScope, buffer[position + 1], buffer);
14503
14835
  },
14504
14836
  function chainExpression(node, position, buffer) {
@@ -14636,7 +14968,7 @@ const bufferParsers = [
14636
14968
  node.id =
14637
14969
  idPosition === 0 ? null : convertNode(node, scope.parent, idPosition, buffer);
14638
14970
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
14639
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14971
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14640
14972
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
14641
14973
  },
14642
14974
  function functionExpression(node, position, buffer) {
@@ -14649,7 +14981,7 @@ const bufferParsers = [
14649
14981
  const idPosition = buffer[position + 2];
14650
14982
  node.id = idPosition === 0 ? null : convertNode(node, node.idScope, idPosition, buffer);
14651
14983
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
14652
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14984
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14653
14985
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
14654
14986
  },
14655
14987
  function identifier(node, position, buffer) {
@@ -15008,8 +15340,8 @@ class UnknownNode extends NodeBase {
15008
15340
  hasEffects() {
15009
15341
  return true;
15010
15342
  }
15011
- include(context) {
15012
- super.include(context, true);
15343
+ includePath(path, context) {
15344
+ super.includePath(path, context, true);
15013
15345
  }
15014
15346
  }
15015
15347
 
@@ -15113,8 +15445,8 @@ class ExportShimVariable extends Variable {
15113
15445
  super(MISSING_EXPORT_SHIM_VARIABLE);
15114
15446
  this.module = module;
15115
15447
  }
15116
- include() {
15117
- super.include();
15448
+ includePath(path, context) {
15449
+ super.includePath(path, context);
15118
15450
  this.module.needsExportShim = true;
15119
15451
  }
15120
15452
  }
@@ -15805,7 +16137,7 @@ class Module {
15805
16137
  include() {
15806
16138
  const context = createInclusionContext();
15807
16139
  if (this.ast.shouldBeIncluded(context))
15808
- this.ast.include(context, false);
16140
+ this.ast.includePath(EMPTY_PATH, context, false);
15809
16141
  }
15810
16142
  includeAllExports(includeNamespaceMembers) {
15811
16143
  if (!this.isExecuted) {
@@ -15819,9 +16151,7 @@ class Module {
15819
16151
  return error(logMissingEntryExport(exportName, this.id));
15820
16152
  }
15821
16153
  variable.deoptimizePath(UNKNOWN_PATH);
15822
- if (!variable.included) {
15823
- this.includeVariable(variable);
15824
- }
16154
+ this.includeVariable(variable, UNKNOWN_PATH);
15825
16155
  }
15826
16156
  }
15827
16157
  for (const name of this.getReexports()) {
@@ -15829,7 +16159,7 @@ class Module {
15829
16159
  if (variable) {
15830
16160
  variable.deoptimizePath(UNKNOWN_PATH);
15831
16161
  if (!variable.included) {
15832
- this.includeVariable(variable);
16162
+ this.includeVariable(variable, UNKNOWN_PATH);
15833
16163
  }
15834
16164
  if (variable instanceof ExternalVariable) {
15835
16165
  variable.module.reexported = true;
@@ -15841,7 +16171,7 @@ class Module {
15841
16171
  }
15842
16172
  }
15843
16173
  includeAllInBundle() {
15844
- this.ast.include(createInclusionContext(), true);
16174
+ this.ast.includePath(UNKNOWN_PATH, createInclusionContext(), true);
15845
16175
  this.includeAllExports(false);
15846
16176
  }
15847
16177
  includeExportsByNames(names) {
@@ -15855,7 +16185,7 @@ class Module {
15855
16185
  if (variable) {
15856
16186
  variable.deoptimizePath(UNKNOWN_PATH);
15857
16187
  if (!variable.included) {
15858
- this.includeVariable(variable);
16188
+ this.includeVariable(variable, UNKNOWN_PATH);
15859
16189
  }
15860
16190
  }
15861
16191
  if (!this.exports.has(name) && !this.reexportDescriptions.has(name)) {
@@ -16297,13 +16627,13 @@ class Module {
16297
16627
  for (const module of [this, ...this.exportAllModules]) {
16298
16628
  if (module instanceof ExternalModule) {
16299
16629
  const [externalVariable] = module.getVariableForExportName('*');
16300
- externalVariable.include();
16630
+ externalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
16301
16631
  this.includedImports.add(externalVariable);
16302
16632
  externalNamespaces.add(externalVariable);
16303
16633
  }
16304
16634
  else if (module.info.syntheticNamedExports) {
16305
16635
  const syntheticNamespace = module.getSyntheticNamespace();
16306
- syntheticNamespace.include();
16636
+ syntheticNamespace.includePath(UNKNOWN_PATH, createInclusionContext());
16307
16637
  this.includedImports.add(syntheticNamespace);
16308
16638
  syntheticNamespaces.add(syntheticNamespace);
16309
16639
  }
@@ -16313,7 +16643,9 @@ class Module {
16313
16643
  includeDynamicImport(node) {
16314
16644
  const resolution = this.dynamicImports.find(dynamicImport => dynamicImport.node === node).resolution;
16315
16645
  if (resolution instanceof Module) {
16316
- resolution.includedDynamicImporters.push(this);
16646
+ if (!resolution.includedDynamicImporters.includes(this)) {
16647
+ resolution.includedDynamicImporters.push(this);
16648
+ }
16317
16649
  const importedNames = this.options.treeshake
16318
16650
  ? node.getDeterministicImportedNames()
16319
16651
  : undefined;
@@ -16325,7 +16657,7 @@ class Module {
16325
16657
  }
16326
16658
  }
16327
16659
  }
16328
- includeVariable(variable) {
16660
+ includeVariable(variable, path) {
16329
16661
  const variableModule = variable.module;
16330
16662
  if (variable.included) {
16331
16663
  if (variableModule instanceof Module && variableModule !== this) {
@@ -16333,7 +16665,6 @@ class Module {
16333
16665
  }
16334
16666
  }
16335
16667
  else {
16336
- variable.include();
16337
16668
  this.graph.needsTreeshakingPass = true;
16338
16669
  if (variableModule instanceof Module) {
16339
16670
  if (!variableModule.isExecuted) {
@@ -16349,9 +16680,10 @@ class Module {
16349
16680
  }
16350
16681
  }
16351
16682
  }
16683
+ variable.includePath(path, createInclusionContext());
16352
16684
  }
16353
- includeVariableInModule(variable) {
16354
- this.includeVariable(variable);
16685
+ includeVariableInModule(variable, path) {
16686
+ this.includeVariable(variable, path);
16355
16687
  const variableModule = variable.module;
16356
16688
  if (variableModule && variableModule !== this) {
16357
16689
  this.includedImports.add(variable);
@@ -20948,7 +21280,7 @@ class Graph {
20948
21280
  this.options = options;
20949
21281
  this.astLru = flru(5);
20950
21282
  this.cachedModules = new Map();
20951
- this.deoptimizationTracker = new PathTracker();
21283
+ this.deoptimizationTracker = new EntityPathTracker();
20952
21284
  this.entryModules = [];
20953
21285
  this.modulesById = new Map();
20954
21286
  this.needsTreeshakingPass = false;
@@ -21948,7 +22280,7 @@ createColors();
21948
22280
 
21949
22281
  // @see https://no-color.org
21950
22282
  // @see https://www.npmjs.com/package/chalk
21951
- const { bold, cyan, dim, gray, green, red, underline, yellow } = createColors({
22283
+ const { bold, cyan, dim, red} = createColors({
21952
22284
  useColor: env$1.FORCE_COLOR !== '0' && !env$1.NO_COLOR
21953
22285
  });
21954
22286