@rollup/wasm-node 4.26.0 → 4.27.0-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,22 +1,22 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v4.26.0
4
- Wed, 13 Nov 2024 06:44:29 GMT - commit ae1d14b7855ff6568a6697d37271a5eb4d8e2d3e
3
+ Rollup.js v4.27.0-0
4
+ Wed, 13 Nov 2024 07:02:42 GMT - commit 5e6074f07843bcbcf26b916c557fdfd81d2adece
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-0";
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,50 @@ 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
+ init.includePath(destructuredInitPath, context, false);
5233
+ return true;
5234
+ }
5235
+ return false;
5236
+ }
5108
5237
  markDeclarationReached() {
5109
5238
  this.variable.initReached = true;
5110
5239
  }
@@ -5169,18 +5298,17 @@ class Scope {
5169
5298
  - then the variable is still declared in the hoisted outer scope, but the initializer is assigned to the parameter
5170
5299
  - const, let, class, and function except in the cases above cannot redeclare anything
5171
5300
  */
5172
- addDeclaration(identifier, context, init, kind) {
5301
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5173
5302
  const name = identifier.name;
5174
5303
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
5175
5304
  if (existingVariable) {
5176
- const existingKind = existingVariable.kind;
5177
- if (kind === 'var' && existingKind === 'var') {
5305
+ if (kind === 'var' && existingVariable.kind === 'var') {
5178
5306
  existingVariable.addDeclaration(identifier, init);
5179
5307
  return existingVariable;
5180
5308
  }
5181
5309
  context.error(logRedeclarationError(name), identifier.start);
5182
5310
  }
5183
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
5311
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
5184
5312
  this.variables.set(name, newVariable);
5185
5313
  return newVariable;
5186
5314
  }
@@ -5382,7 +5510,7 @@ class BlockScope extends ChildScope {
5382
5510
  constructor(parent) {
5383
5511
  super(parent, parent.context);
5384
5512
  }
5385
- addDeclaration(identifier, context, init, kind) {
5513
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5386
5514
  if (kind === 'var') {
5387
5515
  const name = identifier.name;
5388
5516
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -5394,7 +5522,7 @@ class BlockScope extends ChildScope {
5394
5522
  }
5395
5523
  return context.error(logRedeclarationError(name), identifier.start);
5396
5524
  }
5397
- const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind);
5525
+ const declaredVariable = this.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5398
5526
  // Necessary to make sure the init is deoptimized for conditional declarations.
5399
5527
  // We cannot call deoptimizePath here.
5400
5528
  declaredVariable.markInitializersForDeoptimization();
@@ -5402,7 +5530,7 @@ class BlockScope extends ChildScope {
5402
5530
  this.addHoistedVariable(name, declaredVariable);
5403
5531
  return declaredVariable;
5404
5532
  }
5405
- return super.addDeclaration(identifier, context, init, kind);
5533
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5406
5534
  }
5407
5535
  }
5408
5536
 
@@ -5417,11 +5545,11 @@ class StaticBlock extends NodeBase {
5417
5545
  }
5418
5546
  return false;
5419
5547
  }
5420
- include(context, includeChildrenRecursively) {
5548
+ includePath(_path, context, includeChildrenRecursively) {
5421
5549
  this.included = true;
5422
5550
  for (const node of this.body) {
5423
5551
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
5424
- node.include(context, includeChildrenRecursively);
5552
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
5425
5553
  }
5426
5554
  }
5427
5555
  render(code, options) {
@@ -5438,29 +5566,6 @@ function isStaticBlock(statement) {
5438
5566
  return statement.type === StaticBlock$1;
5439
5567
  }
5440
5568
 
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
5569
  class ClassNode extends NodeBase {
5465
5570
  constructor() {
5466
5571
  super(...arguments);
@@ -5500,22 +5605,22 @@ class ClassNode extends NodeBase {
5500
5605
  false
5501
5606
  : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
5502
5607
  }
5503
- include(context, includeChildrenRecursively) {
5608
+ includePath(_path, context, includeChildrenRecursively) {
5504
5609
  if (!this.deoptimized)
5505
5610
  this.applyDeoptimizations();
5506
5611
  this.included = true;
5507
- this.superClass?.include(context, includeChildrenRecursively);
5508
- this.body.include(context, includeChildrenRecursively);
5612
+ this.superClass?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
5613
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
5509
5614
  for (const decorator of this.decorators)
5510
- decorator.include(context, includeChildrenRecursively);
5615
+ decorator.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
5511
5616
  if (this.id) {
5512
5617
  this.id.markDeclarationReached();
5513
- this.id.include();
5618
+ this.id.includePath(UNKNOWN_PATH, createInclusionContext());
5514
5619
  }
5515
5620
  }
5516
5621
  initialise() {
5517
5622
  super.initialise();
5518
- this.id?.declare('class', this);
5623
+ this.id?.declare('class', EMPTY_PATH, this);
5519
5624
  for (const method of this.body.body) {
5520
5625
  if (method instanceof MethodDefinition && method.kind === 'constructor') {
5521
5626
  this.classConstructor = method;
@@ -5573,7 +5678,7 @@ class ClassNode extends NodeBase {
5573
5678
  staticProperties.unshift({
5574
5679
  key: 'prototype',
5575
5680
  kind: 'init',
5576
- property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE)
5681
+ property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, ['prototype']) : OBJECT_PROTOTYPE)
5577
5682
  });
5578
5683
  return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE));
5579
5684
  }
@@ -5630,7 +5735,7 @@ class ClassDeclaration extends ClassNode {
5630
5735
 
5631
5736
  class ArgumentsVariable extends LocalVariable {
5632
5737
  constructor(context) {
5633
- super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');
5738
+ super('arguments', null, UNKNOWN_EXPRESSION, EMPTY_PATH, context, 'other');
5634
5739
  this.deoptimizedArguments = [];
5635
5740
  }
5636
5741
  addArgumentToBeDeoptimized(argument) {
@@ -5644,8 +5749,8 @@ class ArgumentsVariable extends LocalVariable {
5644
5749
  hasEffectsOnInteractionAtPath(path, { type }) {
5645
5750
  return type !== INTERACTION_ACCESSED || path.length > 1;
5646
5751
  }
5647
- include() {
5648
- super.include();
5752
+ includePath(path, context) {
5753
+ super.includePath(path, context);
5649
5754
  for (const argument of this.deoptimizedArguments) {
5650
5755
  argument.deoptimizePath(UNKNOWN_PATH);
5651
5756
  }
@@ -5656,27 +5761,28 @@ class ArgumentsVariable extends LocalVariable {
5656
5761
  const MAX_TRACKED_INTERACTIONS = 20;
5657
5762
  const NO_INTERACTIONS = EMPTY_ARRAY;
5658
5763
  const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);
5659
- const EMPTY_PATH_TRACKER = new PathTracker();
5764
+ const EMPTY_PATH_TRACKER = new EntityPathTracker();
5660
5765
  const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);
5661
5766
  class ParameterVariable extends LocalVariable {
5662
- constructor(name, declarator, context) {
5663
- super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');
5767
+ constructor(name, declarator, argumentPath, context) {
5768
+ super(name, declarator, UNKNOWN_EXPRESSION, argumentPath, context, 'parameter');
5664
5769
  this.deoptimizationInteractions = [];
5665
- this.deoptimizations = new PathTracker();
5770
+ this.deoptimizations = new EntityPathTracker();
5666
5771
  this.deoptimizedFields = new Set();
5667
- this.entitiesToBeDeoptimized = new Set();
5668
- this.expressionsUseTheKnownValue = [];
5772
+ this.argumentsToBeDeoptimized = new Set();
5773
+ this.expressionsDependingOnKnownValue = [];
5669
5774
  this.knownValue = null;
5670
5775
  this.knownValueLiteral = UnknownValue;
5671
5776
  this.frozenValue = null;
5672
5777
  }
5673
- addEntityToBeDeoptimized(entity) {
5778
+ addArgumentValue(entity) {
5779
+ this.updateKnownValue(entity);
5674
5780
  if (entity === UNKNOWN_EXPRESSION) {
5675
5781
  // As unknown expressions fully deoptimize all interactions, we can clear
5676
5782
  // the interaction cache at this point provided we keep this optimization
5677
5783
  // in mind when adding new interactions
5678
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5679
- this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);
5784
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5785
+ this.argumentsToBeDeoptimized.add(UNKNOWN_EXPRESSION);
5680
5786
  for (const { interaction } of this.deoptimizationInteractions) {
5681
5787
  deoptimizeInteraction(interaction);
5682
5788
  }
@@ -5686,27 +5792,30 @@ class ParameterVariable extends LocalVariable {
5686
5792
  else if (this.deoptimizedFields.has(UnknownKey)) {
5687
5793
  // This means that we already deoptimized all interactions and no longer
5688
5794
  // track them
5689
- entity.deoptimizePath(UNKNOWN_PATH);
5795
+ entity.deoptimizePath([...this.initPath, UnknownKey]);
5690
5796
  }
5691
- else if (!this.entitiesToBeDeoptimized.has(entity)) {
5692
- this.entitiesToBeDeoptimized.add(entity);
5797
+ else if (!this.argumentsToBeDeoptimized.has(entity)) {
5798
+ this.argumentsToBeDeoptimized.add(entity);
5693
5799
  for (const field of this.deoptimizedFields) {
5694
- entity.deoptimizePath([field]);
5800
+ entity.deoptimizePath([...this.initPath, field]);
5695
5801
  }
5696
5802
  for (const { interaction, path } of this.deoptimizationInteractions) {
5697
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
5803
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
5698
5804
  }
5699
5805
  }
5700
5806
  }
5807
+ /** This says we should not make assumptions about the value of the parameter.
5808
+ * This is different from deoptimization that will also cause argument values
5809
+ * to be deoptimized. */
5701
5810
  markReassigned() {
5702
5811
  if (this.isReassigned) {
5703
5812
  return;
5704
5813
  }
5705
5814
  super.markReassigned();
5706
- for (const expression of this.expressionsUseTheKnownValue) {
5815
+ for (const expression of this.expressionsDependingOnKnownValue) {
5707
5816
  expression.deoptimizeCache();
5708
5817
  }
5709
- this.expressionsUseTheKnownValue = EMPTY_ARRAY;
5818
+ this.expressionsDependingOnKnownValue = EMPTY_ARRAY;
5710
5819
  }
5711
5820
  deoptimizeCache() {
5712
5821
  this.markReassigned();
@@ -5723,7 +5832,7 @@ class ParameterVariable extends LocalVariable {
5723
5832
  }
5724
5833
  if (this.knownValue === null) {
5725
5834
  this.knownValue = argument;
5726
- this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
5835
+ this.knownValueLiteral = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
5727
5836
  return;
5728
5837
  }
5729
5838
  // the same literal or identifier, do nothing
@@ -5739,7 +5848,7 @@ class ParameterVariable extends LocalVariable {
5739
5848
  return;
5740
5849
  }
5741
5850
  // add tracking for the new argument
5742
- const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
5851
+ const newValue = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
5743
5852
  if (newValue !== oldValue) {
5744
5853
  this.markReassigned();
5745
5854
  }
@@ -5761,20 +5870,25 @@ class ParameterVariable extends LocalVariable {
5761
5870
  return UnknownValue;
5762
5871
  }
5763
5872
  const knownValue = this.getKnownValue();
5764
- this.expressionsUseTheKnownValue.push(origin);
5765
- return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);
5873
+ this.expressionsDependingOnKnownValue.push(origin);
5874
+ return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin), UnknownValue);
5766
5875
  }
5767
5876
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5768
- if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) {
5877
+ const { type } = interaction;
5878
+ if (this.isReassigned || type === INTERACTION_ASSIGNED) {
5769
5879
  return super.hasEffectsOnInteractionAtPath(path, interaction, context);
5770
5880
  }
5771
- const knownValue = this.getKnownValue();
5772
- return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context);
5881
+ return (!(type === INTERACTION_CALLED
5882
+ ? (interaction.withNew
5883
+ ? context.instantiated
5884
+ : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)
5885
+ : context.accessed.trackEntityAtPathAndGetIfTracked(path, this)) &&
5886
+ this.getKnownValue().hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
5773
5887
  }
5774
5888
  deoptimizeArgumentsOnInteractionAtPath(interaction, path) {
5775
5889
  // For performance reasons, we fully deoptimize all deeper interactions
5776
5890
  if (path.length >= 2 ||
5777
- this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
5891
+ this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
5778
5892
  this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||
5779
5893
  (path.length === 1 &&
5780
5894
  (this.deoptimizedFields.has(UnknownKey) ||
@@ -5783,10 +5897,10 @@ class ParameterVariable extends LocalVariable {
5783
5897
  return;
5784
5898
  }
5785
5899
  if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {
5786
- for (const entity of this.entitiesToBeDeoptimized) {
5787
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
5900
+ for (const entity of this.argumentsToBeDeoptimized) {
5901
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
5788
5902
  }
5789
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5903
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5790
5904
  this.deoptimizationInteractions.push({
5791
5905
  interaction,
5792
5906
  path
@@ -5807,17 +5921,17 @@ class ParameterVariable extends LocalVariable {
5807
5921
  return;
5808
5922
  }
5809
5923
  this.deoptimizedFields.add(key);
5810
- for (const entity of this.entitiesToBeDeoptimized) {
5924
+ for (const entity of this.argumentsToBeDeoptimized) {
5811
5925
  // We do not need a recursion tracker here as we already track whether
5812
5926
  // this field is deoptimized
5813
- entity.deoptimizePath([key]);
5927
+ entity.deoptimizePath([...this.initPath, key]);
5814
5928
  }
5815
5929
  if (key === UnknownKey) {
5816
5930
  // save some memory
5817
5931
  this.deoptimizationInteractions = NO_INTERACTIONS;
5818
5932
  this.deoptimizations = EMPTY_PATH_TRACKER;
5819
5933
  this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;
5820
- this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
5934
+ this.argumentsToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
5821
5935
  }
5822
5936
  }
5823
5937
  getReturnExpressionWhenCalledAtPath(path) {
@@ -5832,11 +5946,14 @@ class ParameterVariable extends LocalVariable {
5832
5946
  }
5833
5947
  return UNKNOWN_RETURN_EXPRESSION;
5834
5948
  }
5949
+ includeArgumentPaths(entity, context) {
5950
+ this.includedPathTracker.includeAllPaths(entity, context, this.initPath);
5951
+ }
5835
5952
  }
5836
5953
 
5837
5954
  class ThisVariable extends ParameterVariable {
5838
5955
  constructor(context) {
5839
- super('this', null, context);
5956
+ super('this', null, EMPTY_PATH, context);
5840
5957
  }
5841
5958
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5842
5959
  return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);
@@ -5848,7 +5965,7 @@ class CatchBodyScope extends ChildScope {
5848
5965
  super(parent, parent.context);
5849
5966
  this.parent = parent;
5850
5967
  }
5851
- addDeclaration(identifier, context, init, kind) {
5968
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5852
5969
  if (kind === 'var') {
5853
5970
  const name = identifier.name;
5854
5971
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -5861,7 +5978,7 @@ class CatchBodyScope extends ChildScope {
5861
5978
  // the assignment actually goes to the parameter and the var is
5862
5979
  // hoisted without assignment. Locally, it is shadowed by the
5863
5980
  // parameter
5864
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, kind);
5981
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, destructuredInitPath, kind);
5865
5982
  // To avoid the need to rewrite the declaration, we link the variable
5866
5983
  // names. If we ever implement a logic that splits initialization and
5867
5984
  // assignment for hoisted vars, the "renderLikeHoisted" logic can be
@@ -5880,7 +5997,7 @@ class CatchBodyScope extends ChildScope {
5880
5997
  return context.error(logRedeclarationError(name), identifier.start);
5881
5998
  }
5882
5999
  // We only add parameters to parameter scopes
5883
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, kind);
6000
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5884
6001
  // Necessary to make sure the init is deoptimized for conditional declarations.
5885
6002
  // We cannot call deoptimizePath here.
5886
6003
  declaredVariable.markInitializersForDeoptimization();
@@ -5888,7 +6005,7 @@ class CatchBodyScope extends ChildScope {
5888
6005
  this.addHoistedVariable(name, declaredVariable);
5889
6006
  return declaredVariable;
5890
6007
  }
5891
- return super.addDeclaration(identifier, context, init, kind);
6008
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5892
6009
  }
5893
6010
  }
5894
6011
 
@@ -5898,7 +6015,7 @@ class FunctionBodyScope extends ChildScope {
5898
6015
  }
5899
6016
  // There is stuff that is only allowed in function scopes, i.e. functions can
5900
6017
  // be redeclared, functions and var can redeclare each other
5901
- addDeclaration(identifier, context, init, kind) {
6018
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5902
6019
  const name = identifier.name;
5903
6020
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
5904
6021
  if (existingVariable) {
@@ -5910,7 +6027,7 @@ class FunctionBodyScope extends ChildScope {
5910
6027
  }
5911
6028
  context.error(logRedeclarationError(name), identifier.start);
5912
6029
  }
5913
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
6030
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
5914
6031
  this.variables.set(name, newVariable);
5915
6032
  return newVariable;
5916
6033
  }
@@ -5919,21 +6036,21 @@ class FunctionBodyScope extends ChildScope {
5919
6036
  class ParameterScope extends ChildScope {
5920
6037
  constructor(parent, isCatchScope) {
5921
6038
  super(parent, parent.context);
5922
- this.parameters = [];
5923
6039
  this.hasRest = false;
6040
+ this.parameters = [];
5924
6041
  this.bodyScope = isCatchScope ? new CatchBodyScope(this) : new FunctionBodyScope(this);
5925
6042
  }
5926
6043
  /**
5927
6044
  * Adds a parameter to this scope. Parameters must be added in the correct
5928
6045
  * order, i.e. from left to right.
5929
6046
  */
5930
- addParameterDeclaration(identifier) {
6047
+ addParameterDeclaration(identifier, argumentPath) {
5931
6048
  const { name, start } = identifier;
5932
6049
  const existingParameter = this.variables.get(name);
5933
6050
  if (existingParameter) {
5934
6051
  return this.context.error(logDuplicateArgumentNameError(name), start);
5935
6052
  }
5936
- const variable = new ParameterVariable(name, identifier, this.context);
6053
+ const variable = new ParameterVariable(name, identifier, argumentPath, this.context);
5937
6054
  this.variables.set(name, variable);
5938
6055
  // We also add it to the body scope to detect name conflicts with local
5939
6056
  // variables. We still need the intermediate scope, though, as parameter
@@ -5951,43 +6068,54 @@ class ParameterScope extends ChildScope {
5951
6068
  }
5952
6069
  this.hasRest = hasRest;
5953
6070
  }
5954
- includeCallArguments(context, parameters) {
6071
+ includeCallArguments(context, interaction) {
5955
6072
  let calledFromTryStatement = false;
5956
6073
  let argumentIncluded = false;
5957
6074
  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;
6075
+ const { args } = interaction;
6076
+ let lastExplicitlyIncludedIndex = args.length - 1;
6077
+ // If there is a SpreadElement, we need to include all arguments after it
6078
+ // because we no longer know which argument corresponds to which parameter.
6079
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
6080
+ if (args[argumentIndex] instanceof SpreadElement && !argumentIncluded) {
6081
+ argumentIncluded = true;
6082
+ lastExplicitlyIncludedIndex = argumentIndex - 1;
6083
+ }
6084
+ if (argumentIncluded) {
6085
+ args[argumentIndex].includePath(UNKNOWN_PATH, context, false);
5964
6086
  }
5965
6087
  }
5966
- for (let index = parameters.length - 1; index >= 0; index--) {
5967
- const parameterVariables = this.parameters[index] || restParameter;
5968
- const argument = parameters[index];
6088
+ // Now we go backwards either starting from the last argument or before the
6089
+ // first SpreadElement to ensure all arguments before are included as needed
6090
+ for (let index = lastExplicitlyIncludedIndex; index >= 1; index--) {
6091
+ const parameterVariables = this.parameters[index - 1] || restParameter;
6092
+ const argument = args[index];
5969
6093
  if (parameterVariables) {
5970
6094
  calledFromTryStatement = false;
5971
6095
  if (parameterVariables.length === 0) {
5972
- // handle empty destructuring
6096
+ // handle empty destructuring to avoid destructuring undefined
5973
6097
  argumentIncluded = true;
5974
6098
  }
5975
6099
  else {
5976
6100
  for (const variable of parameterVariables) {
5977
- if (variable.included) {
5978
- argumentIncluded = true;
5979
- }
5980
6101
  if (variable.calledFromTryStatement) {
5981
6102
  calledFromTryStatement = true;
5982
6103
  }
6104
+ if (variable.included) {
6105
+ argumentIncluded = true;
6106
+ if (calledFromTryStatement) {
6107
+ argument.includePath(UNKNOWN_PATH, context, true);
6108
+ }
6109
+ else {
6110
+ variable.includeArgumentPaths(argument, context);
6111
+ }
6112
+ }
5983
6113
  }
5984
6114
  }
5985
6115
  }
5986
- if (!argumentIncluded && argument.shouldBeIncluded(context)) {
6116
+ if (!argument.included && (argumentIncluded || argument.shouldBeIncluded(context))) {
5987
6117
  argumentIncluded = true;
5988
- }
5989
- if (argumentIncluded) {
5990
- argument.include(context, calledFromTryStatement);
6118
+ argument.includePath(EMPTY_PATH, context, calledFromTryStatement);
5991
6119
  }
5992
6120
  }
5993
6121
  }
@@ -6002,11 +6130,61 @@ class ReturnValueScope extends ParameterScope {
6002
6130
  addReturnExpression(expression) {
6003
6131
  this.returnExpressions.push(expression);
6004
6132
  }
6133
+ deoptimizeArgumentsOnCall(interaction) {
6134
+ const { parameters } = this;
6135
+ const { args } = interaction;
6136
+ let position = 0;
6137
+ for (; position < args.length - 1; position++) {
6138
+ // Only the "this" argument arg[0] can be null
6139
+ const argument = args[position + 1];
6140
+ if (argument instanceof SpreadElement) {
6141
+ // This deoptimizes the current and remaining parameters and arguments
6142
+ for (; position < parameters.length; position++) {
6143
+ args[position + 1]?.deoptimizePath(UNKNOWN_PATH);
6144
+ parameters[position].forEach(variable => variable.markReassigned());
6145
+ }
6146
+ break;
6147
+ }
6148
+ if (this.hasRest && position >= parameters.length - 1) {
6149
+ argument.deoptimizePath(UNKNOWN_PATH);
6150
+ }
6151
+ else {
6152
+ const variables = parameters[position];
6153
+ if (variables) {
6154
+ for (const variable of variables) {
6155
+ variable.addArgumentValue(argument);
6156
+ }
6157
+ }
6158
+ this.addArgumentToBeDeoptimized(argument);
6159
+ }
6160
+ }
6161
+ for (; position < parameters.length; position++) {
6162
+ for (const variable of parameters[position]) {
6163
+ variable.addArgumentValue(UNDEFINED_EXPRESSION);
6164
+ }
6165
+ }
6166
+ }
6005
6167
  getReturnExpression() {
6006
6168
  if (this.returnExpression === null)
6007
6169
  this.updateReturnExpression();
6008
6170
  return this.returnExpression;
6009
6171
  }
6172
+ deoptimizeAllParameters() {
6173
+ for (const parameter of this.parameters) {
6174
+ for (const variable of parameter) {
6175
+ variable.deoptimizePath(UNKNOWN_PATH);
6176
+ variable.markReassigned();
6177
+ }
6178
+ }
6179
+ }
6180
+ reassignAllParameters() {
6181
+ for (const parameter of this.parameters) {
6182
+ for (const variable of parameter) {
6183
+ variable.markReassigned();
6184
+ }
6185
+ }
6186
+ }
6187
+ addArgumentToBeDeoptimized(_argument) { }
6010
6188
  updateReturnExpression() {
6011
6189
  if (this.returnExpressions.length === 1) {
6012
6190
  this.returnExpression = this.returnExpressions[0];
@@ -6022,24 +6200,26 @@ class ReturnValueScope extends ParameterScope {
6022
6200
 
6023
6201
  class FunctionScope extends ReturnValueScope {
6024
6202
  constructor(parent) {
6025
- const { context } = parent;
6026
6203
  super(parent, false);
6204
+ const { context } = parent;
6027
6205
  this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));
6028
6206
  this.variables.set('this', (this.thisVariable = new ThisVariable(context)));
6029
6207
  }
6030
6208
  findLexicalBoundary() {
6031
6209
  return this;
6032
6210
  }
6033
- includeCallArguments(context, parameters) {
6034
- super.includeCallArguments(context, parameters);
6211
+ includeCallArguments(context, interaction) {
6212
+ super.includeCallArguments(context, interaction);
6035
6213
  if (this.argumentsVariable.included) {
6036
- for (const argument of parameters) {
6037
- if (!argument.included) {
6038
- argument.include(context, false);
6039
- }
6214
+ const { args } = interaction;
6215
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
6216
+ args[argumentIndex]?.includePath(UNKNOWN_PATH, context, false);
6040
6217
  }
6041
6218
  }
6042
6219
  }
6220
+ addArgumentToBeDeoptimized(argument) {
6221
+ this.argumentsVariable.addArgumentToBeDeoptimized(argument);
6222
+ }
6043
6223
  }
6044
6224
 
6045
6225
  class ExpressionStatement extends NodeBase {
@@ -6105,7 +6285,7 @@ class BlockStatement extends NodeBase {
6105
6285
  }
6106
6286
  return false;
6107
6287
  }
6108
- include(context, includeChildrenRecursively) {
6288
+ includePath(_path, context, includeChildrenRecursively) {
6109
6289
  if (!(this.deoptimizeBody && this.directlyIncluded)) {
6110
6290
  this.included = true;
6111
6291
  this.directlyIncluded = true;
@@ -6113,7 +6293,7 @@ class BlockStatement extends NodeBase {
6113
6293
  includeChildrenRecursively = true;
6114
6294
  for (const node of this.body) {
6115
6295
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
6116
- node.include(context, includeChildrenRecursively);
6296
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
6117
6297
  }
6118
6298
  }
6119
6299
  }
@@ -6142,9 +6322,12 @@ class RestElement extends NodeBase {
6142
6322
  addExportedVariables(variables, exportNamesByVariable) {
6143
6323
  this.argument.addExportedVariables(variables, exportNamesByVariable);
6144
6324
  }
6145
- declare(kind, init) {
6325
+ declare(kind, destructuredInitPath, init) {
6146
6326
  this.declarationInit = init;
6147
- return this.argument.declare(kind, UNKNOWN_EXPRESSION);
6327
+ return this.argument.declare(kind, getIncludedPatternPath$1(destructuredInitPath), init);
6328
+ }
6329
+ deoptimizeAssignment(destructuredInitPath, init) {
6330
+ this.argument.deoptimizeAssignment(getIncludedPatternPath$1(destructuredInitPath), init);
6148
6331
  }
6149
6332
  deoptimizePath(path) {
6150
6333
  if (path.length === 0) {
@@ -6155,6 +6338,19 @@ class RestElement extends NodeBase {
6155
6338
  return (path.length > 0 ||
6156
6339
  this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
6157
6340
  }
6341
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
6342
+ return this.argument.hasEffectsWhenDestructuring(context, getIncludedPatternPath$1(destructuredInitPath), init);
6343
+ }
6344
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
6345
+ return (this.included =
6346
+ this.argument.includeDestructuredIfNecessary(context, getIncludedPatternPath$1(destructuredInitPath), init) || this.included);
6347
+ }
6348
+ includePath(_path, context, includeChildrenRecursively) {
6349
+ this.included = true;
6350
+ // This should just include the identifier, its properties should be
6351
+ // included where the variable is used.
6352
+ this.argument.includePath(EMPTY_PATH, context, includeChildrenRecursively);
6353
+ }
6158
6354
  markDeclarationReached() {
6159
6355
  this.argument.markDeclarationReached();
6160
6356
  }
@@ -6166,12 +6362,15 @@ class RestElement extends NodeBase {
6166
6362
  }
6167
6363
  }
6168
6364
  }
6365
+ const getIncludedPatternPath$1 = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
6366
+ ? destructuredInitPath
6367
+ : [...destructuredInitPath, UnknownKey];
6169
6368
 
6170
6369
  class FunctionBase extends NodeBase {
6171
6370
  constructor() {
6172
6371
  super(...arguments);
6173
- this.objectEntity = null;
6174
6372
  this.parameterVariableValuesDeoptimized = false;
6373
+ this.includeCallArguments = this.scope.includeCallArguments.bind(this.scope);
6175
6374
  }
6176
6375
  get async() {
6177
6376
  return isFlagSet(this.flags, 256 /* Flag.async */);
@@ -6191,53 +6390,9 @@ class FunctionBase extends NodeBase {
6191
6390
  set generator(value) {
6192
6391
  this.flags = setFlag(this.flags, 4194304 /* Flag.generator */, value);
6193
6392
  }
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
6393
  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);
6394
+ if (interaction.type === INTERACTION_CALLED && path.length === 0) {
6395
+ this.scope.deoptimizeArgumentsOnCall(interaction);
6241
6396
  }
6242
6397
  else {
6243
6398
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -6249,12 +6404,7 @@ class FunctionBase extends NodeBase {
6249
6404
  // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
6250
6405
  // which means the return expression and parameters need to be reassigned
6251
6406
  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
- }
6407
+ this.scope.deoptimizeAllParameters();
6258
6408
  }
6259
6409
  }
6260
6410
  getLiteralValueAtPath(path, recursionTracker, origin) {
@@ -6292,8 +6442,13 @@ class FunctionBase extends NodeBase {
6292
6442
  return true;
6293
6443
  }
6294
6444
  }
6295
- for (const parameter of this.params) {
6296
- if (parameter.hasEffects(context))
6445
+ const { propertyReadSideEffects } = this.scope.context.options
6446
+ .treeshake;
6447
+ for (let index = 0; index < this.params.length; index++) {
6448
+ const parameter = this.params[index];
6449
+ if (parameter.hasEffects(context) ||
6450
+ (propertyReadSideEffects &&
6451
+ parameter.hasEffectsWhenDestructuring(context, EMPTY_PATH, interaction.args[index + 1] || UNDEFINED_EXPRESSION)))
6297
6452
  return true;
6298
6453
  }
6299
6454
  return false;
@@ -6311,22 +6466,19 @@ class FunctionBase extends NodeBase {
6311
6466
  }
6312
6467
  return variable?.getOnlyFunctionCallUsed() ?? false;
6313
6468
  }
6314
- include(context, includeChildrenRecursively) {
6315
- if (!this.parameterVariableValuesDeoptimized && !this.onlyFunctionCallUsed()) {
6469
+ includePath(_path, context, includeChildrenRecursively) {
6470
+ if (!(this.parameterVariableValuesDeoptimized || this.onlyFunctionCallUsed())) {
6316
6471
  this.parameterVariableValuesDeoptimized = true;
6317
- this.deoptimizeParameterVariableValues();
6472
+ this.scope.reassignAllParameters();
6318
6473
  }
6319
6474
  if (!this.deoptimized)
6320
6475
  this.applyDeoptimizations();
6321
6476
  this.included = true;
6322
6477
  const { brokenFlow } = context;
6323
6478
  context.brokenFlow = false;
6324
- this.body.include(context, includeChildrenRecursively);
6479
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
6325
6480
  context.brokenFlow = brokenFlow;
6326
6481
  }
6327
- includeCallArguments(context, parameters) {
6328
- this.scope.includeCallArguments(context, parameters);
6329
- }
6330
6482
  initialise() {
6331
6483
  super.initialise();
6332
6484
  if (this.body instanceof BlockStatement) {
@@ -6348,11 +6500,10 @@ class FunctionBase extends NodeBase {
6348
6500
  // so that the scope already knows all parameters and can detect conflicts
6349
6501
  // when parsing the body.
6350
6502
  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);
6503
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
6352
6504
  this.body = new (context.getNodeConstructor(body.type))(this, bodyScope).parseNode(body);
6353
6505
  return super.parseNode(esTreeNode);
6354
6506
  }
6355
- addArgumentToBeDeoptimized(_argument) { }
6356
6507
  applyDeoptimizations() { }
6357
6508
  }
6358
6509
  FunctionBase.prototype.preventChildBlockScope = true;
@@ -6367,13 +6518,13 @@ class FunctionNode extends FunctionBase {
6367
6518
  this.constructedEntity = new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE);
6368
6519
  // This makes sure that all deoptimizations of "this" are applied to the
6369
6520
  // constructed entity.
6370
- this.scope.thisVariable.addEntityToBeDeoptimized(this.constructedEntity);
6521
+ this.scope.thisVariable.addArgumentValue(this.constructedEntity);
6371
6522
  }
6372
6523
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6373
6524
  super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
6374
6525
  if (interaction.type === INTERACTION_CALLED && path.length === 0 && interaction.args[0]) {
6375
6526
  // args[0] is the "this" argument
6376
- this.scope.thisVariable.addEntityToBeDeoptimized(interaction.args[0]);
6527
+ this.scope.thisVariable.addArgumentValue(interaction.args[0]);
6377
6528
  }
6378
6529
  }
6379
6530
  hasEffects(context) {
@@ -6414,22 +6565,19 @@ class FunctionNode extends FunctionBase {
6414
6565
  }
6415
6566
  return false;
6416
6567
  }
6417
- include(context, includeChildrenRecursively) {
6418
- super.include(context, includeChildrenRecursively);
6419
- this.id?.include();
6568
+ includePath(path, context, includeChildrenRecursively) {
6569
+ super.includePath(path, context, includeChildrenRecursively);
6570
+ this.id?.includePath(UNKNOWN_PATH, createInclusionContext());
6420
6571
  const hasArguments = this.scope.argumentsVariable.included;
6421
6572
  for (const parameter of this.params) {
6422
6573
  if (!(parameter instanceof Identifier) || hasArguments) {
6423
- parameter.include(context, includeChildrenRecursively);
6574
+ parameter.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
6424
6575
  }
6425
6576
  }
6426
6577
  }
6427
6578
  initialise() {
6428
6579
  super.initialise();
6429
- this.id?.declare('function', this);
6430
- }
6431
- addArgumentToBeDeoptimized(argument) {
6432
- this.scope.argumentsVariable.addArgumentToBeDeoptimized(argument);
6580
+ this.id?.declare('function', EMPTY_PATH, this);
6433
6581
  }
6434
6582
  getObjectEntity() {
6435
6583
  if (this.objectEntity !== null) {
@@ -6478,10 +6626,11 @@ function getFunctionIdInsertPosition(code, start) {
6478
6626
  return declarationEnd + generatorStarPos + 1;
6479
6627
  }
6480
6628
  class ExportDefaultDeclaration extends NodeBase {
6481
- include(context, includeChildrenRecursively) {
6482
- super.include(context, includeChildrenRecursively);
6629
+ includePath(path, context, includeChildrenRecursively) {
6630
+ this.included = true;
6631
+ this.declaration.includePath(path, context, includeChildrenRecursively);
6483
6632
  if (includeChildrenRecursively) {
6484
- this.scope.context.includeVariableInModule(this.variable);
6633
+ this.scope.context.includeVariableInModule(this.variable, path);
6485
6634
  }
6486
6635
  }
6487
6636
  initialise() {
@@ -6950,6 +7099,10 @@ class MemberExpression extends NodeBase {
6950
7099
  }
6951
7100
  }
6952
7101
  }
7102
+ deoptimizeAssignment(destructuredInitPath, init) {
7103
+ this.deoptimizePath(EMPTY_PATH);
7104
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
7105
+ }
6953
7106
  deoptimizeCache() {
6954
7107
  const { expressionsToBeDeoptimized, object } = this;
6955
7108
  this.expressionsToBeDeoptimized = EMPTY_ARRAY;
@@ -7054,28 +7207,42 @@ class MemberExpression extends NodeBase {
7054
7207
  }
7055
7208
  return true;
7056
7209
  }
7057
- include(context, includeChildrenRecursively) {
7210
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
7211
+ return (destructuredInitPath.length > 0 &&
7212
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
7213
+ }
7214
+ includePath(path, context, includeChildrenRecursively) {
7058
7215
  if (!this.deoptimized)
7059
7216
  this.applyDeoptimizations();
7060
- this.includeProperties(context, includeChildrenRecursively);
7217
+ this.includeProperties(path, [this.getPropertyKey(), ...path], context, includeChildrenRecursively);
7061
7218
  }
7062
7219
  includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {
7063
7220
  if (!this.assignmentDeoptimized)
7064
7221
  this.applyAssignmentDeoptimization();
7065
7222
  if (deoptimizeAccess) {
7066
- this.include(context, includeChildrenRecursively);
7223
+ this.includePath([this.getPropertyKey()], context, includeChildrenRecursively);
7067
7224
  }
7068
7225
  else {
7069
- this.includeProperties(context, includeChildrenRecursively);
7226
+ this.includeProperties(EMPTY_PATH, [this.getPropertyKey()], context, includeChildrenRecursively);
7070
7227
  }
7071
7228
  }
7072
- includeCallArguments(context, parameters) {
7229
+ includeCallArguments(context, interaction) {
7073
7230
  if (this.variable) {
7074
- this.variable.includeCallArguments(context, parameters);
7231
+ this.variable.includeCallArguments(context, interaction);
7075
7232
  }
7076
7233
  else {
7077
- super.includeCallArguments(context, parameters);
7234
+ super.includeCallArguments(context, interaction);
7235
+ }
7236
+ }
7237
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
7238
+ if ((this.included ||=
7239
+ destructuredInitPath.length > 0 &&
7240
+ !context.brokenFlow &&
7241
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext()))) {
7242
+ init.includePath(destructuredInitPath, context, false);
7243
+ return true;
7078
7244
  }
7245
+ return false;
7079
7246
  }
7080
7247
  initialise() {
7081
7248
  super.initialise();
@@ -7143,7 +7310,7 @@ class MemberExpression extends NodeBase {
7143
7310
  const variable = this.scope.findVariable(this.object.name);
7144
7311
  if (variable.isNamespace) {
7145
7312
  if (this.variable) {
7146
- this.scope.context.includeVariableInModule(this.variable);
7313
+ this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH);
7147
7314
  }
7148
7315
  this.scope.context.log(LOGLEVEL_WARN, logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);
7149
7316
  }
@@ -7170,15 +7337,18 @@ class MemberExpression extends NodeBase {
7170
7337
  (propertyReadSideEffects === 'always' ||
7171
7338
  this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));
7172
7339
  }
7173
- includeProperties(context, includeChildrenRecursively) {
7340
+ includeProperties(includedPath, objectPath, context, includeChildrenRecursively) {
7174
7341
  if (!this.included) {
7175
7342
  this.included = true;
7176
7343
  if (this.variable) {
7177
- this.scope.context.includeVariableInModule(this.variable);
7344
+ this.scope.context.includeVariableInModule(this.variable, includedPath);
7178
7345
  }
7179
7346
  }
7180
- this.object.include(context, includeChildrenRecursively);
7181
- this.property.include(context, includeChildrenRecursively);
7347
+ else if (includedPath.length > 0) {
7348
+ this.variable?.includePath(includedPath, context);
7349
+ }
7350
+ this.object.includePath(objectPath, context, includeChildrenRecursively);
7351
+ this.property.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7182
7352
  }
7183
7353
  }
7184
7354
  function resolveNamespaceVariables(baseVariable, path, astContext) {
@@ -7221,7 +7391,7 @@ class MetaProperty extends NodeBase {
7221
7391
  hasEffectsOnInteractionAtPath(path, { type }) {
7222
7392
  return path.length > 1 || type !== INTERACTION_ACCESSED;
7223
7393
  }
7224
- include() {
7394
+ includePath() {
7225
7395
  if (!this.included) {
7226
7396
  this.included = true;
7227
7397
  if (this.meta.name === IMPORT) {
@@ -7340,7 +7510,7 @@ class UndefinedVariable extends Variable {
7340
7510
 
7341
7511
  class ExportDefaultVariable extends LocalVariable {
7342
7512
  constructor(name, exportDefaultDeclaration, context) {
7343
- super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');
7513
+ super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, EMPTY_PATH, context, 'other');
7344
7514
  this.hasId = false;
7345
7515
  this.originalId = null;
7346
7516
  this.originalVariable = null;
@@ -7489,8 +7659,8 @@ class NamespaceVariable extends Variable {
7489
7659
  return (!memberVariable ||
7490
7660
  memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));
7491
7661
  }
7492
- include() {
7493
- super.include();
7662
+ includePath(path, context) {
7663
+ super.includePath(path, context);
7494
7664
  this.context.includeAllExports();
7495
7665
  }
7496
7666
  prepare(accessedGlobalsByScope) {
@@ -7583,9 +7753,9 @@ class SyntheticNamedExportVariable extends Variable {
7583
7753
  getName(getPropertyAccess) {
7584
7754
  return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;
7585
7755
  }
7586
- include() {
7587
- super.include();
7588
- this.context.includeVariableInModule(this.syntheticNamespace);
7756
+ includePath(path, context) {
7757
+ super.includePath(path, context);
7758
+ this.context.includeVariableInModule(this.syntheticNamespace, path);
7589
7759
  }
7590
7760
  setRenderNames(baseName, name) {
7591
7761
  super.setRenderNames(baseName, name);
@@ -10784,21 +10954,37 @@ class ArrayPattern extends NodeBase {
10784
10954
  element?.addExportedVariables(variables, exportNamesByVariable);
10785
10955
  }
10786
10956
  }
10787
- declare(kind) {
10957
+ declare(kind, destructuredInitPath, init) {
10788
10958
  const variables = [];
10959
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
10789
10960
  for (const element of this.elements) {
10790
10961
  if (element !== null) {
10791
- variables.push(...element.declare(kind, UNKNOWN_EXPRESSION));
10962
+ variables.push(...element.declare(kind, includedPatternPath, init));
10792
10963
  }
10793
10964
  }
10794
10965
  return variables;
10795
10966
  }
10967
+ deoptimizeAssignment(destructuredInitPath, init) {
10968
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
10969
+ for (const element of this.elements) {
10970
+ element?.deoptimizeAssignment(includedPatternPath, init);
10971
+ }
10972
+ }
10796
10973
  // Patterns can only be deoptimized at the empty path at the moment
10797
10974
  deoptimizePath() {
10798
10975
  for (const element of this.elements) {
10799
10976
  element?.deoptimizePath(EMPTY_PATH);
10800
10977
  }
10801
10978
  }
10979
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
10980
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
10981
+ for (const element of this.elements) {
10982
+ if (element?.hasEffectsWhenDestructuring(context, includedPatternPath, init)) {
10983
+ return true;
10984
+ }
10985
+ }
10986
+ return false;
10987
+ }
10802
10988
  // Patterns are only checked at the empty path at the moment
10803
10989
  hasEffectsOnInteractionAtPath(_path, interaction, context) {
10804
10990
  for (const element of this.elements) {
@@ -10807,12 +10993,24 @@ class ArrayPattern extends NodeBase {
10807
10993
  }
10808
10994
  return false;
10809
10995
  }
10996
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
10997
+ let included = false;
10998
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
10999
+ for (const element of this.elements) {
11000
+ included =
11001
+ element?.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
11002
+ }
11003
+ return (this.included ||= included);
11004
+ }
10810
11005
  markDeclarationReached() {
10811
11006
  for (const element of this.elements) {
10812
11007
  element?.markDeclarationReached();
10813
11008
  }
10814
11009
  }
10815
11010
  }
11011
+ const getIncludedPatternPath = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
11012
+ ? destructuredInitPath
11013
+ : [...destructuredInitPath, UnknownInteger];
10816
11014
 
10817
11015
  class ArrowFunctionExpression extends FunctionBase {
10818
11016
  constructor() {
@@ -10861,11 +11059,11 @@ class ArrowFunctionExpression extends FunctionBase {
10861
11059
  this.parent.callee === this;
10862
11060
  return isIIFE || super.onlyFunctionCallUsed();
10863
11061
  }
10864
- include(context, includeChildrenRecursively) {
10865
- super.include(context, includeChildrenRecursively);
11062
+ includePath(_path, context, includeChildrenRecursively) {
11063
+ super.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
10866
11064
  for (const parameter of this.params) {
10867
11065
  if (!(parameter instanceof Identifier)) {
10868
- parameter.include(context, includeChildrenRecursively);
11066
+ parameter.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
10869
11067
  }
10870
11068
  }
10871
11069
  }
@@ -10888,13 +11086,18 @@ class ObjectPattern extends NodeBase {
10888
11086
  }
10889
11087
  }
10890
11088
  }
10891
- declare(kind, init) {
11089
+ declare(kind, destructuredInitPath, init) {
10892
11090
  const variables = [];
10893
11091
  for (const property of this.properties) {
10894
- variables.push(...property.declare(kind, init));
11092
+ variables.push(...property.declare(kind, destructuredInitPath, init));
10895
11093
  }
10896
11094
  return variables;
10897
11095
  }
11096
+ deoptimizeAssignment(destructuredInitPath, init) {
11097
+ for (const property of this.properties) {
11098
+ property.deoptimizeAssignment(destructuredInitPath, init);
11099
+ }
11100
+ }
10898
11101
  deoptimizePath(path) {
10899
11102
  if (path.length === 0) {
10900
11103
  for (const property of this.properties) {
@@ -10912,11 +11115,44 @@ class ObjectPattern extends NodeBase {
10912
11115
  }
10913
11116
  return false;
10914
11117
  }
11118
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
11119
+ for (const property of this.properties) {
11120
+ if (property.hasEffectsWhenDestructuring(context, destructuredInitPath, init))
11121
+ return true;
11122
+ }
11123
+ return false;
11124
+ }
11125
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11126
+ let included = false;
11127
+ for (const property of this.properties) {
11128
+ included =
11129
+ property.includeDestructuredIfNecessary(context, destructuredInitPath, init) || included;
11130
+ }
11131
+ return (this.included ||= included);
11132
+ }
10915
11133
  markDeclarationReached() {
10916
11134
  for (const property of this.properties) {
10917
11135
  property.markDeclarationReached();
10918
11136
  }
10919
11137
  }
11138
+ render(code, options) {
11139
+ if (this.properties.length > 0) {
11140
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
11141
+ let lastSeparatorPos = null;
11142
+ for (const { node, separator, start, end } of separatedNodes) {
11143
+ if (!node.included) {
11144
+ treeshakeNode(node, code, start, end);
11145
+ continue;
11146
+ }
11147
+ lastSeparatorPos = separator;
11148
+ node.render(code, options);
11149
+ }
11150
+ if (lastSeparatorPos) {
11151
+ code.remove(lastSeparatorPos, this.end - 1);
11152
+ }
11153
+ }
11154
+ }
11155
+ applyDeoptimizations() { }
10920
11156
  }
10921
11157
 
10922
11158
  class AssignmentExpression extends NodeBase {
@@ -10926,23 +11162,27 @@ class AssignmentExpression extends NodeBase {
10926
11162
  this.applyDeoptimizations();
10927
11163
  // MemberExpressions do not access the property before assignments if the
10928
11164
  // operator is '='.
10929
- return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '='));
11165
+ return (right.hasEffects(context) ||
11166
+ left.hasEffectsAsAssignmentTarget(context, operator !== '=') ||
11167
+ this.left.hasEffectsWhenDestructuring?.(context, EMPTY_PATH, right));
10930
11168
  }
10931
11169
  hasEffectsOnInteractionAtPath(path, interaction, context) {
10932
11170
  return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);
10933
11171
  }
10934
- include(context, includeChildrenRecursively) {
11172
+ includePath(_path, context, includeChildrenRecursively) {
10935
11173
  const { deoptimized, left, right, operator } = this;
10936
11174
  if (!deoptimized)
10937
11175
  this.applyDeoptimizations();
10938
11176
  this.included = true;
11177
+ const hasEffectsContext = createHasEffectsContext();
10939
11178
  if (includeChildrenRecursively ||
10940
11179
  operator !== '=' ||
10941
11180
  left.included ||
10942
- left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {
11181
+ left.hasEffectsAsAssignmentTarget(hasEffectsContext, false) ||
11182
+ left.hasEffectsWhenDestructuring?.(hasEffectsContext, EMPTY_PATH, right)) {
10943
11183
  left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');
10944
11184
  }
10945
- right.include(context, includeChildrenRecursively);
11185
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
10946
11186
  }
10947
11187
  initialise() {
10948
11188
  super.initialise();
@@ -11004,8 +11244,7 @@ class AssignmentExpression extends NodeBase {
11004
11244
  }
11005
11245
  applyDeoptimizations() {
11006
11246
  this.deoptimized = true;
11007
- this.left.deoptimizePath(EMPTY_PATH);
11008
- this.right.deoptimizePath(UNKNOWN_PATH);
11247
+ this.left.deoptimizeAssignment(EMPTY_PATH, this.right);
11009
11248
  this.scope.context.requestTreeshakingPass();
11010
11249
  }
11011
11250
  }
@@ -11014,8 +11253,11 @@ class AssignmentPattern extends NodeBase {
11014
11253
  addExportedVariables(variables, exportNamesByVariable) {
11015
11254
  this.left.addExportedVariables(variables, exportNamesByVariable);
11016
11255
  }
11017
- declare(kind, init) {
11018
- return this.left.declare(kind, init);
11256
+ declare(kind, destructuredInitPath, init) {
11257
+ return this.left.declare(kind, destructuredInitPath, init);
11258
+ }
11259
+ deoptimizeAssignment(destructuredInitPath, init) {
11260
+ this.left.deoptimizeAssignment(destructuredInitPath, init);
11019
11261
  }
11020
11262
  deoptimizePath(path) {
11021
11263
  if (path.length === 0) {
@@ -11025,6 +11267,17 @@ class AssignmentPattern extends NodeBase {
11025
11267
  hasEffectsOnInteractionAtPath(path, interaction, context) {
11026
11268
  return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
11027
11269
  }
11270
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
11271
+ return this.left.hasEffectsWhenDestructuring(context, destructuredInitPath, init);
11272
+ }
11273
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11274
+ let included = this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init) ||
11275
+ this.included;
11276
+ if ((included ||= this.right.shouldBeIncluded(context))) {
11277
+ this.right.includePath(UNKNOWN_PATH, context, false);
11278
+ }
11279
+ return (this.included = included);
11280
+ }
11028
11281
  markDeclarationReached() {
11029
11282
  this.left.markDeclarationReached();
11030
11283
  }
@@ -11046,7 +11299,7 @@ class AwaitExpression extends NodeBase {
11046
11299
  this.applyDeoptimizations();
11047
11300
  return true;
11048
11301
  }
11049
- include(context, includeChildrenRecursively) {
11302
+ includePath(path, context, includeChildrenRecursively) {
11050
11303
  if (!this.deoptimized)
11051
11304
  this.applyDeoptimizations();
11052
11305
  if (!this.included) {
@@ -11060,7 +11313,7 @@ class AwaitExpression extends NodeBase {
11060
11313
  this.scope.context.usesTopLevelAwait = true;
11061
11314
  }
11062
11315
  }
11063
- this.argument.include(context, includeChildrenRecursively);
11316
+ this.argument.includePath(path, context, includeChildrenRecursively);
11064
11317
  }
11065
11318
  }
11066
11319
 
@@ -11142,10 +11395,10 @@ class BreakStatement extends NodeBase {
11142
11395
  context.brokenFlow = true;
11143
11396
  return false;
11144
11397
  }
11145
- include(context) {
11398
+ includePath(_, context) {
11146
11399
  this.included = true;
11147
11400
  if (this.label) {
11148
- this.label.include();
11401
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
11149
11402
  context.includedLabels.add(this.label.name);
11150
11403
  }
11151
11404
  else {
@@ -11339,11 +11592,11 @@ class CallExpression extends CallExpressionBase {
11339
11592
  (calleeHasEffects ||
11340
11593
  this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)));
11341
11594
  }
11342
- include(context, includeChildrenRecursively) {
11595
+ includePath(path, context, includeChildrenRecursively) {
11343
11596
  if (!this.deoptimized)
11344
11597
  this.applyDeoptimizations();
11345
11598
  if (includeChildrenRecursively) {
11346
- super.include(context, includeChildrenRecursively);
11599
+ super.includePath(path, context, includeChildrenRecursively);
11347
11600
  if (includeChildrenRecursively === INCLUDE_PARAMETERS &&
11348
11601
  this.callee instanceof Identifier &&
11349
11602
  this.callee.variable) {
@@ -11352,9 +11605,18 @@ class CallExpression extends CallExpressionBase {
11352
11605
  }
11353
11606
  else {
11354
11607
  this.included = true;
11355
- this.callee.include(context, false);
11608
+ // If the callee is a member expression and does not have a variable, its
11609
+ // object will already be included via the first argument of the
11610
+ // interaction in includeCallArguments. Including it again can lead to
11611
+ // severe performance problems.
11612
+ if (this.callee instanceof MemberExpression && !this.callee.variable) {
11613
+ this.callee.property.includePath(UNKNOWN_PATH, context, false);
11614
+ }
11615
+ else {
11616
+ this.callee.includePath(UNKNOWN_PATH, context, false);
11617
+ }
11618
+ this.callee.includeCallArguments(context, this.interaction);
11356
11619
  }
11357
- this.callee.includeCallArguments(context, this.arguments);
11358
11620
  }
11359
11621
  initialise() {
11360
11622
  super.initialise();
@@ -11393,7 +11655,7 @@ class CatchClause extends NodeBase {
11393
11655
  this.type = type;
11394
11656
  if (param) {
11395
11657
  this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);
11396
- this.param.declare('parameter', UNKNOWN_EXPRESSION);
11658
+ this.param.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
11397
11659
  }
11398
11660
  this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);
11399
11661
  return super.parseNode(esTreeNode);
@@ -11421,7 +11683,7 @@ class ClassBodyScope extends ChildScope {
11421
11683
  constructor(parent, classNode) {
11422
11684
  const { context } = parent;
11423
11685
  super(parent, context);
11424
- this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));
11686
+ this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, EMPTY_PATH, context, 'other')));
11425
11687
  this.instanceScope = new ChildScope(this, context);
11426
11688
  this.instanceScope.variables.set('this', new ThisVariable(context));
11427
11689
  }
@@ -11434,11 +11696,11 @@ class ClassBody extends NodeBase {
11434
11696
  createScope(parentScope) {
11435
11697
  this.scope = new ClassBodyScope(parentScope, this.parent);
11436
11698
  }
11437
- include(context, includeChildrenRecursively) {
11699
+ includePath(_path, context, includeChildrenRecursively) {
11438
11700
  this.included = true;
11439
- this.scope.context.includeVariableInModule(this.scope.thisVariable);
11701
+ this.scope.context.includeVariableInModule(this.scope.thisVariable, UNKNOWN_PATH);
11440
11702
  for (const definition of this.body) {
11441
- definition.include(context, includeChildrenRecursively);
11703
+ definition.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11442
11704
  }
11443
11705
  }
11444
11706
  parseNode(esTreeNode) {
@@ -11562,26 +11824,26 @@ class ConditionalExpression extends NodeBase {
11562
11824
  }
11563
11825
  return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
11564
11826
  }
11565
- include(context, includeChildrenRecursively) {
11827
+ includePath(path, context, includeChildrenRecursively) {
11566
11828
  this.included = true;
11567
11829
  const usedBranch = this.getUsedBranch();
11568
11830
  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);
11831
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11832
+ this.consequent.includePath(path, context, includeChildrenRecursively);
11833
+ this.alternate.includePath(path, context, includeChildrenRecursively);
11572
11834
  }
11573
11835
  else {
11574
- usedBranch.include(context, includeChildrenRecursively);
11836
+ usedBranch.includePath(path, context, includeChildrenRecursively);
11575
11837
  }
11576
11838
  }
11577
- includeCallArguments(context, parameters) {
11839
+ includeCallArguments(context, interaction) {
11578
11840
  const usedBranch = this.getUsedBranch();
11579
11841
  if (usedBranch) {
11580
- usedBranch.includeCallArguments(context, parameters);
11842
+ usedBranch.includeCallArguments(context, interaction);
11581
11843
  }
11582
11844
  else {
11583
- this.consequent.includeCallArguments(context, parameters);
11584
- this.alternate.includeCallArguments(context, parameters);
11845
+ this.consequent.includeCallArguments(context, interaction);
11846
+ this.alternate.includeCallArguments(context, interaction);
11585
11847
  }
11586
11848
  }
11587
11849
  removeAnnotations(code) {
@@ -11642,10 +11904,10 @@ class ContinueStatement extends NodeBase {
11642
11904
  context.brokenFlow = true;
11643
11905
  return false;
11644
11906
  }
11645
- include(context) {
11907
+ includePath(_, context) {
11646
11908
  this.included = true;
11647
11909
  if (this.label) {
11648
- this.label.include();
11910
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
11649
11911
  context.includedLabels.add(this.label.name);
11650
11912
  }
11651
11913
  else {
@@ -11688,7 +11950,7 @@ function includeLoopBody(context, body, includeChildrenRecursively) {
11688
11950
  const { brokenFlow, hasBreak, hasContinue } = context;
11689
11951
  context.hasBreak = false;
11690
11952
  context.hasContinue = false;
11691
- body.include(context, includeChildrenRecursively, { asSingleStatement: true });
11953
+ body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively, { asSingleStatement: true });
11692
11954
  context.hasBreak = hasBreak;
11693
11955
  context.hasContinue = hasContinue;
11694
11956
  context.brokenFlow = brokenFlow;
@@ -11700,9 +11962,9 @@ class DoWhileStatement extends NodeBase {
11700
11962
  return true;
11701
11963
  return hasLoopBodyEffects(context, this.body);
11702
11964
  }
11703
- include(context, includeChildrenRecursively) {
11965
+ includePath(_path, context, includeChildrenRecursively) {
11704
11966
  this.included = true;
11705
- this.test.include(context, includeChildrenRecursively);
11967
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11706
11968
  includeLoopBody(context, this.body, includeChildrenRecursively);
11707
11969
  }
11708
11970
  }
@@ -11773,13 +12035,13 @@ class ForInStatement extends NodeBase {
11773
12035
  return true;
11774
12036
  return hasLoopBodyEffects(context, body);
11775
12037
  }
11776
- include(context, includeChildrenRecursively) {
12038
+ includePath(_path, context, includeChildrenRecursively) {
11777
12039
  const { body, deoptimized, left, right } = this;
11778
12040
  if (!deoptimized)
11779
12041
  this.applyDeoptimizations();
11780
12042
  this.included = true;
11781
12043
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
11782
- right.include(context, includeChildrenRecursively);
12044
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11783
12045
  includeLoopBody(context, body, includeChildrenRecursively);
11784
12046
  }
11785
12047
  initialise() {
@@ -11818,13 +12080,13 @@ class ForOfStatement extends NodeBase {
11818
12080
  // Placeholder until proper Symbol.Iterator support
11819
12081
  return true;
11820
12082
  }
11821
- include(context, includeChildrenRecursively) {
12083
+ includePath(_path, context, includeChildrenRecursively) {
11822
12084
  const { body, deoptimized, left, right } = this;
11823
12085
  if (!deoptimized)
11824
12086
  this.applyDeoptimizations();
11825
12087
  this.included = true;
11826
12088
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
11827
- right.include(context, includeChildrenRecursively);
12089
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11828
12090
  includeLoopBody(context, body, includeChildrenRecursively);
11829
12091
  }
11830
12092
  initialise() {
@@ -11860,11 +12122,13 @@ class ForStatement extends NodeBase {
11860
12122
  }
11861
12123
  return hasLoopBodyEffects(context, this.body);
11862
12124
  }
11863
- include(context, includeChildrenRecursively) {
12125
+ includePath(_path, context, includeChildrenRecursively) {
11864
12126
  this.included = true;
11865
- this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true });
11866
- this.test?.include(context, includeChildrenRecursively);
11867
- this.update?.include(context, includeChildrenRecursively);
12127
+ this.init?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively, {
12128
+ asSingleStatement: true
12129
+ });
12130
+ this.test?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12131
+ this.update?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
11868
12132
  includeLoopBody(context, this.body, includeChildrenRecursively);
11869
12133
  }
11870
12134
  render(code, options) {
@@ -11905,9 +12169,9 @@ class TrackingScope extends BlockScope {
11905
12169
  super(...arguments);
11906
12170
  this.hoistedDeclarations = [];
11907
12171
  }
11908
- addDeclaration(identifier, context, init, kind) {
12172
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
11909
12173
  this.hoistedDeclarations.push(identifier);
11910
- return super.addDeclaration(identifier, context, init, kind);
12174
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
11911
12175
  }
11912
12176
  }
11913
12177
 
@@ -11940,7 +12204,7 @@ class IfStatement extends NodeBase {
11940
12204
  }
11941
12205
  return testValue ? this.consequent.hasEffects(context) : !!this.alternate?.hasEffects(context);
11942
12206
  }
11943
- include(context, includeChildrenRecursively) {
12207
+ includePath(_, context, includeChildrenRecursively) {
11944
12208
  this.included = true;
11945
12209
  if (includeChildrenRecursively) {
11946
12210
  this.includeRecursively(includeChildrenRecursively, context);
@@ -12015,31 +12279,31 @@ class IfStatement extends NodeBase {
12015
12279
  }
12016
12280
  includeKnownTest(context, testValue) {
12017
12281
  if (this.test.shouldBeIncluded(context)) {
12018
- this.test.include(context, false);
12282
+ this.test.includePath(UNKNOWN_PATH, context, false);
12019
12283
  }
12020
12284
  if (testValue && this.consequent.shouldBeIncluded(context)) {
12021
- this.consequent.include(context, false, { asSingleStatement: true });
12285
+ this.consequent.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
12022
12286
  }
12023
12287
  if (!testValue && this.alternate?.shouldBeIncluded(context)) {
12024
- this.alternate.include(context, false, { asSingleStatement: true });
12288
+ this.alternate.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
12025
12289
  }
12026
12290
  }
12027
12291
  includeRecursively(includeChildrenRecursively, context) {
12028
- this.test.include(context, includeChildrenRecursively);
12029
- this.consequent.include(context, includeChildrenRecursively);
12030
- this.alternate?.include(context, includeChildrenRecursively);
12292
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12293
+ this.consequent.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12294
+ this.alternate?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12031
12295
  }
12032
12296
  includeUnknownTest(context) {
12033
- this.test.include(context, false);
12297
+ this.test.includePath(UNKNOWN_PATH, context, false);
12034
12298
  const { brokenFlow } = context;
12035
12299
  let consequentBrokenFlow = false;
12036
12300
  if (this.consequent.shouldBeIncluded(context)) {
12037
- this.consequent.include(context, false, { asSingleStatement: true });
12301
+ this.consequent.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
12038
12302
  consequentBrokenFlow = context.brokenFlow;
12039
12303
  context.brokenFlow = brokenFlow;
12040
12304
  }
12041
12305
  if (this.alternate?.shouldBeIncluded(context)) {
12042
- this.alternate.include(context, false, { asSingleStatement: true });
12306
+ this.alternate.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
12043
12307
  context.brokenFlow = context.brokenFlow && consequentBrokenFlow;
12044
12308
  }
12045
12309
  }
@@ -12107,7 +12371,7 @@ function isReassignedExportsMember(variable, exportNamesByVariable) {
12107
12371
  class VariableDeclarator extends NodeBase {
12108
12372
  declareDeclarator(kind, isUsingDeclaration) {
12109
12373
  this.isUsingDeclaration = isUsingDeclaration;
12110
- this.id.declare(kind, this.init || UNDEFINED_EXPRESSION);
12374
+ this.id.declare(kind, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION);
12111
12375
  }
12112
12376
  deoptimizePath(path) {
12113
12377
  this.id.deoptimizePath(path);
@@ -12117,17 +12381,25 @@ class VariableDeclarator extends NodeBase {
12117
12381
  this.applyDeoptimizations();
12118
12382
  const initEffect = this.init?.hasEffects(context);
12119
12383
  this.id.markDeclarationReached();
12120
- return initEffect || this.id.hasEffects(context) || this.isUsingDeclaration;
12121
- }
12122
- include(context, includeChildrenRecursively) {
12384
+ return (initEffect ||
12385
+ this.isUsingDeclaration ||
12386
+ this.id.hasEffects(context) ||
12387
+ (this.scope.context.options.treeshake
12388
+ .propertyReadSideEffects &&
12389
+ this.id.hasEffectsWhenDestructuring(context, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION)));
12390
+ }
12391
+ includePath(_path, context, includeChildrenRecursively) {
12123
12392
  const { deoptimized, id, init } = this;
12124
12393
  if (!deoptimized)
12125
12394
  this.applyDeoptimizations();
12126
12395
  this.included = true;
12127
- init?.include(context, includeChildrenRecursively);
12396
+ init?.includePath(EMPTY_PATH, context, includeChildrenRecursively);
12128
12397
  id.markDeclarationReached();
12129
- if (includeChildrenRecursively || id.shouldBeIncluded(context)) {
12130
- id.include(context, includeChildrenRecursively);
12398
+ if (includeChildrenRecursively) {
12399
+ id.includePath(EMPTY_PATH, context, includeChildrenRecursively);
12400
+ }
12401
+ else {
12402
+ id.includeDestructuredIfNecessary(context, EMPTY_PATH, init || UNDEFINED_EXPRESSION);
12131
12403
  }
12132
12404
  }
12133
12405
  removeAnnotations(code) {
@@ -12176,6 +12448,8 @@ class ImportExpression extends NodeBase {
12176
12448
  constructor() {
12177
12449
  super(...arguments);
12178
12450
  this.inlineNamespace = null;
12451
+ this.hasUnknownAccessedKey = false;
12452
+ this.accessedPropKey = new Set();
12179
12453
  this.attributes = null;
12180
12454
  this.mechanism = null;
12181
12455
  this.namespaceExportName = undefined;
@@ -12208,12 +12482,15 @@ class ImportExpression extends NodeBase {
12208
12482
  if (parent2 instanceof ExpressionStatement) {
12209
12483
  return EMPTY_ARRAY;
12210
12484
  }
12211
- // Case 1: const { foo } = await import('bar')
12485
+ // Case 1: const { foo } / module = await import('bar')
12212
12486
  if (parent2 instanceof VariableDeclarator) {
12213
12487
  const declaration = parent2.id;
12214
- return declaration instanceof ObjectPattern
12215
- ? getDeterministicObjectDestructure(declaration)
12216
- : undefined;
12488
+ if (declaration instanceof Identifier) {
12489
+ return this.hasUnknownAccessedKey ? undefined : [...this.accessedPropKey];
12490
+ }
12491
+ if (declaration instanceof ObjectPattern) {
12492
+ return getDeterministicObjectDestructure(declaration);
12493
+ }
12217
12494
  }
12218
12495
  // Case 2: (await import('bar')).foo
12219
12496
  if (parent2 instanceof MemberExpression) {
@@ -12262,13 +12539,23 @@ class ImportExpression extends NodeBase {
12262
12539
  hasEffects() {
12263
12540
  return true;
12264
12541
  }
12265
- include(context, includeChildrenRecursively) {
12542
+ includePath(path, context, includeChildrenRecursively) {
12266
12543
  if (!this.included) {
12267
12544
  this.included = true;
12268
12545
  this.scope.context.includeDynamicImport(this);
12269
12546
  this.scope.addAccessedDynamicImport(this);
12547
+ this.source.includePath(path, context, includeChildrenRecursively);
12548
+ }
12549
+ if (this.hasUnknownAccessedKey)
12550
+ return;
12551
+ if (path[0] === UnknownKey) {
12552
+ this.hasUnknownAccessedKey = true;
12553
+ this.scope.context.includeDynamicImport(this);
12554
+ }
12555
+ else if (typeof path[0] === 'string') {
12556
+ this.accessedPropKey.add(path[0]);
12557
+ this.scope.context.includeDynamicImport(this);
12270
12558
  }
12271
- this.source.include(context, includeChildrenRecursively);
12272
12559
  }
12273
12560
  initialise() {
12274
12561
  super.initialise();
@@ -12596,7 +12883,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
12596
12883
  if (preserve) {
12597
12884
  // This pretends we are accessing an included global variable of the same name
12598
12885
  const globalVariable = node.scope.findGlobal(baseName);
12599
- globalVariable.include();
12886
+ globalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
12600
12887
  // This excludes this variable from renaming
12601
12888
  factoryVariable.globalName = baseName;
12602
12889
  }
@@ -12604,7 +12891,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
12604
12891
  else {
12605
12892
  factoryVariable = node.scope.findGlobal(baseName);
12606
12893
  }
12607
- node.scope.context.includeVariableInModule(factoryVariable);
12894
+ node.scope.context.includeVariableInModule(factoryVariable, UNKNOWN_PATH);
12608
12895
  if (factoryVariable instanceof LocalVariable) {
12609
12896
  factoryVariable.consolidateInitializers();
12610
12897
  factoryVariable.addUsedPlace(node);
@@ -12626,7 +12913,7 @@ class JSXElementBase extends NodeBase {
12626
12913
  this.scope.context.addImportSource(importSource);
12627
12914
  }
12628
12915
  }
12629
- include(context, includeChildrenRecursively) {
12916
+ includePath(path, context, includeChildrenRecursively) {
12630
12917
  if (!this.included) {
12631
12918
  const { factory, importSource, mode } = this.jsxMode;
12632
12919
  if (factory) {
@@ -12634,7 +12921,7 @@ class JSXElementBase extends NodeBase {
12634
12921
  this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this);
12635
12922
  }
12636
12923
  }
12637
- super.include(context, includeChildrenRecursively);
12924
+ super.includePath(path, context, includeChildrenRecursively);
12638
12925
  }
12639
12926
  applyDeoptimizations() { }
12640
12927
  getRenderingMode() {
@@ -12896,7 +13183,7 @@ class JSXOpeningFragment extends NodeBase {
12896
13183
  this.fragment = null;
12897
13184
  this.fragmentVariable = null;
12898
13185
  }
12899
- include(context, includeChildrenRecursively) {
13186
+ includePath(path, context, includeChildrenRecursively) {
12900
13187
  if (!this.included) {
12901
13188
  const jsx = this.scope.context.options.jsx;
12902
13189
  if (jsx.mode === 'automatic') {
@@ -12911,7 +13198,7 @@ class JSXOpeningFragment extends NodeBase {
12911
13198
  }
12912
13199
  }
12913
13200
  }
12914
- super.include(context, includeChildrenRecursively);
13201
+ super.includePath(path, context, includeChildrenRecursively);
12915
13202
  }
12916
13203
  render(code, options) {
12917
13204
  const { mode } = this.scope.context.options.jsx;
@@ -12968,13 +13255,13 @@ class LabeledStatement extends NodeBase {
12968
13255
  context.includedLabels = new Set([...includedLabels, ...context.includedLabels]);
12969
13256
  return bodyHasEffects;
12970
13257
  }
12971
- include(context, includeChildrenRecursively) {
13258
+ includePath(_path, context, includeChildrenRecursively) {
12972
13259
  this.included = true;
12973
13260
  const { brokenFlow, includedLabels } = context;
12974
13261
  context.includedLabels = new Set();
12975
- this.body.include(context, includeChildrenRecursively);
13262
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12976
13263
  if (includeChildrenRecursively || context.includedLabels.has(this.label.name)) {
12977
- this.label.include();
13264
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
12978
13265
  context.includedLabels.delete(this.label.name);
12979
13266
  context.brokenFlow = brokenFlow;
12980
13267
  }
@@ -13071,17 +13358,17 @@ class LogicalExpression extends NodeBase {
13071
13358
  }
13072
13359
  return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
13073
13360
  }
13074
- include(context, includeChildrenRecursively) {
13361
+ includePath(path, context, includeChildrenRecursively) {
13075
13362
  this.included = true;
13076
13363
  const usedBranch = this.getUsedBranch();
13077
13364
  if (includeChildrenRecursively ||
13078
13365
  (usedBranch === this.right && this.left.shouldBeIncluded(context)) ||
13079
13366
  !usedBranch) {
13080
- this.left.include(context, includeChildrenRecursively);
13081
- this.right.include(context, includeChildrenRecursively);
13367
+ this.left.includePath(path, context, includeChildrenRecursively);
13368
+ this.right.includePath(path, context, includeChildrenRecursively);
13082
13369
  }
13083
13370
  else {
13084
- usedBranch.include(context, includeChildrenRecursively);
13371
+ usedBranch.includePath(path, context, includeChildrenRecursively);
13085
13372
  }
13086
13373
  }
13087
13374
  removeAnnotations(code) {
@@ -13153,17 +13440,17 @@ class NewExpression extends NodeBase {
13153
13440
  hasEffectsOnInteractionAtPath(path, { type }) {
13154
13441
  return path.length > 0 || type !== INTERACTION_ACCESSED;
13155
13442
  }
13156
- include(context, includeChildrenRecursively) {
13443
+ includePath(path, context, includeChildrenRecursively) {
13157
13444
  if (!this.deoptimized)
13158
13445
  this.applyDeoptimizations();
13159
13446
  if (includeChildrenRecursively) {
13160
- super.include(context, includeChildrenRecursively);
13447
+ super.includePath(path, context, includeChildrenRecursively);
13161
13448
  }
13162
13449
  else {
13163
13450
  this.included = true;
13164
- this.callee.include(context, false);
13451
+ this.callee.includePath(UNKNOWN_PATH, context, false);
13165
13452
  }
13166
- this.callee.includeCallArguments(context, this.arguments);
13453
+ this.callee.includeCallArguments(context, this.interaction);
13167
13454
  }
13168
13455
  initialise() {
13169
13456
  super.initialise();
@@ -13192,6 +13479,7 @@ class ObjectExpression extends NodeBase {
13192
13479
  constructor() {
13193
13480
  super(...arguments);
13194
13481
  this.objectEntity = null;
13482
+ this.protoProp = null;
13195
13483
  }
13196
13484
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
13197
13485
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -13211,13 +13499,32 @@ class ObjectExpression extends NodeBase {
13211
13499
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13212
13500
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
13213
13501
  }
13502
+ includePath(path, context, includeChildrenRecursively) {
13503
+ this.included = true;
13504
+ this.getObjectEntity().includePath(path, context, includeChildrenRecursively);
13505
+ this.protoProp?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13506
+ }
13214
13507
  render(code, options, { renderedSurroundingElement } = BLANK) {
13215
- super.render(code, options);
13216
13508
  if (renderedSurroundingElement === ExpressionStatement$1 ||
13217
13509
  renderedSurroundingElement === ArrowFunctionExpression$1) {
13218
13510
  code.appendRight(this.start, '(');
13219
13511
  code.prependLeft(this.end, ')');
13220
13512
  }
13513
+ if (this.properties.length > 0) {
13514
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
13515
+ let lastSeparatorPos = null;
13516
+ for (const { node, separator, start, end } of separatedNodes) {
13517
+ if (!node.included) {
13518
+ treeshakeNode(node, code, start, end);
13519
+ continue;
13520
+ }
13521
+ lastSeparatorPos = separator;
13522
+ node.render(code, options);
13523
+ }
13524
+ if (lastSeparatorPos) {
13525
+ code.remove(lastSeparatorPos, this.end - 1);
13526
+ }
13527
+ }
13221
13528
  }
13222
13529
  applyDeoptimizations() { }
13223
13530
  getObjectEntity() {
@@ -13248,6 +13555,7 @@ class ObjectExpression extends NodeBase {
13248
13555
  ? property.key.name
13249
13556
  : String(property.key.value);
13250
13557
  if (key === '__proto__' && property.kind === 'init') {
13558
+ this.protoProp = property;
13251
13559
  prototype =
13252
13560
  property.value instanceof Literal && property.value.value === null
13253
13561
  ? null
@@ -13314,11 +13622,11 @@ class Program extends NodeBase {
13314
13622
  }
13315
13623
  return false;
13316
13624
  }
13317
- include(context, includeChildrenRecursively) {
13625
+ includePath(_path, context, includeChildrenRecursively) {
13318
13626
  this.included = true;
13319
13627
  for (const node of this.body) {
13320
13628
  if (includeChildrenRecursively || node.shouldBeIncluded(context)) {
13321
- node.include(context, includeChildrenRecursively);
13629
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13322
13630
  }
13323
13631
  }
13324
13632
  }
@@ -13357,10 +13665,6 @@ class Program extends NodeBase {
13357
13665
  }
13358
13666
 
13359
13667
  class Property extends MethodBase {
13360
- constructor() {
13361
- super(...arguments);
13362
- this.declarationInit = null;
13363
- }
13364
13668
  //declare method: boolean;
13365
13669
  get method() {
13366
13670
  return isFlagSet(this.flags, 262144 /* Flag.method */);
@@ -13375,17 +13679,32 @@ class Property extends MethodBase {
13375
13679
  set shorthand(value) {
13376
13680
  this.flags = setFlag(this.flags, 524288 /* Flag.shorthand */, value);
13377
13681
  }
13378
- declare(kind, init) {
13379
- this.declarationInit = init;
13380
- return this.value.declare(kind, UNKNOWN_EXPRESSION);
13682
+ declare(kind, destructuredInitPath, init) {
13683
+ return this.value.declare(kind, this.getPathInProperty(destructuredInitPath), init);
13684
+ }
13685
+ deoptimizeAssignment(destructuredInitPath, init) {
13686
+ this.value.deoptimizeAssignment?.(this.getPathInProperty(destructuredInitPath), init);
13381
13687
  }
13382
13688
  hasEffects(context) {
13383
13689
  if (!this.deoptimized)
13384
13690
  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));
13691
+ return this.key.hasEffects(context) || this.value.hasEffects(context);
13692
+ }
13693
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
13694
+ return this.value.hasEffectsWhenDestructuring?.(context, this.getPathInProperty(destructuredInitPath), init);
13695
+ }
13696
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
13697
+ let included = this.value.includeDestructuredIfNecessary(context, this.getPathInProperty(destructuredInitPath), init) || this.included;
13698
+ included ||= this.key.hasEffects(createHasEffectsContext());
13699
+ if (included) {
13700
+ this.key.includePath(EMPTY_PATH, context, false);
13701
+ }
13702
+ return (this.included = included);
13703
+ }
13704
+ includePath(path, context, includeChildrenRecursively) {
13705
+ this.included = true;
13706
+ this.key.includePath(EMPTY_PATH, context, includeChildrenRecursively);
13707
+ this.value.includePath(path, context, includeChildrenRecursively);
13389
13708
  }
13390
13709
  markDeclarationReached() {
13391
13710
  this.value.markDeclarationReached();
@@ -13396,12 +13715,17 @@ class Property extends MethodBase {
13396
13715
  }
13397
13716
  this.value.render(code, options, { isShorthandProperty: this.shorthand });
13398
13717
  }
13399
- applyDeoptimizations() {
13400
- this.deoptimized = true;
13401
- if (this.declarationInit !== null) {
13402
- this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
13403
- this.scope.context.requestTreeshakingPass();
13404
- }
13718
+ applyDeoptimizations() { }
13719
+ getPathInProperty(destructuredInitPath) {
13720
+ return destructuredInitPath.at(-1) === UnknownKey
13721
+ ? destructuredInitPath
13722
+ : // For now, we only consider static paths as we do not know how to
13723
+ // deoptimize the path in the dynamic case.
13724
+ this.computed
13725
+ ? [...destructuredInitPath, UnknownKey]
13726
+ : this.key instanceof Identifier
13727
+ ? [...destructuredInitPath, this.key.name]
13728
+ : [...destructuredInitPath, String(this.key.value)];
13405
13729
  }
13406
13730
  }
13407
13731
 
@@ -13446,9 +13770,9 @@ class ReturnStatement extends NodeBase {
13446
13770
  context.brokenFlow = true;
13447
13771
  return false;
13448
13772
  }
13449
- include(context, includeChildrenRecursively) {
13773
+ includePath(_path, context, includeChildrenRecursively) {
13450
13774
  this.included = true;
13451
- this.argument?.include(context, includeChildrenRecursively);
13775
+ this.argument?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13452
13776
  context.brokenFlow = true;
13453
13777
  }
13454
13778
  initialise() {
@@ -13485,14 +13809,14 @@ class SequenceExpression extends NodeBase {
13485
13809
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13486
13810
  return this.expressions[this.expressions.length - 1].hasEffectsOnInteractionAtPath(path, interaction, context);
13487
13811
  }
13488
- include(context, includeChildrenRecursively) {
13812
+ includePath(path, context, includeChildrenRecursively) {
13489
13813
  this.included = true;
13490
13814
  const lastExpression = this.expressions[this.expressions.length - 1];
13491
13815
  for (const expression of this.expressions) {
13492
13816
  if (includeChildrenRecursively ||
13493
13817
  (expression === lastExpression && !(this.parent instanceof ExpressionStatement)) ||
13494
13818
  expression.shouldBeIncluded(context))
13495
- expression.include(context, includeChildrenRecursively);
13819
+ expression.includePath(path, context, includeChildrenRecursively);
13496
13820
  }
13497
13821
  }
13498
13822
  removeAnnotations(code) {
@@ -13540,10 +13864,13 @@ class Super extends NodeBase {
13540
13864
  deoptimizePath(path) {
13541
13865
  this.variable.deoptimizePath(path);
13542
13866
  }
13543
- include() {
13867
+ includePath(path, context) {
13544
13868
  if (!this.included) {
13545
13869
  this.included = true;
13546
- this.scope.context.includeVariableInModule(this.variable);
13870
+ this.scope.context.includeVariableInModule(this.variable, path);
13871
+ }
13872
+ else if (path.length > 0) {
13873
+ this.variable.includePath(path, context);
13547
13874
  }
13548
13875
  }
13549
13876
  }
@@ -13560,12 +13887,12 @@ class SwitchCase extends NodeBase {
13560
13887
  }
13561
13888
  return false;
13562
13889
  }
13563
- include(context, includeChildrenRecursively) {
13890
+ includePath(_path, context, includeChildrenRecursively) {
13564
13891
  this.included = true;
13565
- this.test?.include(context, includeChildrenRecursively);
13892
+ this.test?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13566
13893
  for (const node of this.consequent) {
13567
13894
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
13568
- node.include(context, includeChildrenRecursively);
13895
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13569
13896
  }
13570
13897
  }
13571
13898
  render(code, options, nodeRenderOptions) {
@@ -13613,9 +13940,9 @@ class SwitchStatement extends NodeBase {
13613
13940
  context.hasBreak = hasBreak;
13614
13941
  return false;
13615
13942
  }
13616
- include(context, includeChildrenRecursively) {
13943
+ includePath(_path, context, includeChildrenRecursively) {
13617
13944
  this.included = true;
13618
- this.discriminant.include(context, includeChildrenRecursively);
13945
+ this.discriminant.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13619
13946
  const { brokenFlow, hasBreak } = context;
13620
13947
  context.hasBreak = false;
13621
13948
  let onlyHasBrokenFlow = true;
@@ -13632,7 +13959,7 @@ class SwitchStatement extends NodeBase {
13632
13959
  isCaseIncluded = switchCase.hasEffects(hasEffectsContext);
13633
13960
  }
13634
13961
  if (isCaseIncluded) {
13635
- switchCase.include(context, includeChildrenRecursively);
13962
+ switchCase.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13636
13963
  onlyHasBrokenFlow &&= context.brokenFlow && !context.hasBreak;
13637
13964
  context.hasBreak = false;
13638
13965
  context.brokenFlow = brokenFlow;
@@ -13689,21 +14016,21 @@ class TaggedTemplateExpression extends CallExpressionBase {
13689
14016
  return (this.tag.hasEffects(context) ||
13690
14017
  this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
13691
14018
  }
13692
- include(context, includeChildrenRecursively) {
14019
+ includePath(path, context, includeChildrenRecursively) {
13693
14020
  if (!this.deoptimized)
13694
14021
  this.applyDeoptimizations();
13695
14022
  if (includeChildrenRecursively) {
13696
- super.include(context, includeChildrenRecursively);
14023
+ super.includePath(path, context, includeChildrenRecursively);
13697
14024
  }
13698
14025
  else {
13699
14026
  this.included = true;
13700
- this.tag.include(context, includeChildrenRecursively);
13701
- this.quasi.include(context, includeChildrenRecursively);
14027
+ this.tag.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14028
+ this.quasi.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13702
14029
  }
13703
- this.tag.includeCallArguments(context, this.args);
14030
+ this.tag.includeCallArguments(context, this.interaction);
13704
14031
  const [returnExpression] = this.getReturnExpression();
13705
14032
  if (!returnExpression.included) {
13706
- returnExpression.include(context, false);
14033
+ returnExpression.includePath(UNKNOWN_PATH, context, false);
13707
14034
  }
13708
14035
  }
13709
14036
  initialise() {
@@ -13748,7 +14075,7 @@ class TemplateElement extends NodeBase {
13748
14075
  hasEffects() {
13749
14076
  return false;
13750
14077
  }
13751
- include() {
14078
+ includePath() {
13752
14079
  this.included = true;
13753
14080
  }
13754
14081
  parseNode(esTreeNode) {
@@ -13790,13 +14117,13 @@ class TemplateLiteral extends NodeBase {
13790
14117
  class ModuleScope extends ChildScope {
13791
14118
  constructor(parent, context) {
13792
14119
  super(parent, context);
13793
- this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, context, 'other'));
14120
+ this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, EMPTY_PATH, context, 'other'));
13794
14121
  }
13795
- addDeclaration(identifier, context, init, kind) {
14122
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
13796
14123
  if (this.context.module.importDescriptions.has(identifier.name)) {
13797
14124
  context.error(logRedeclarationError(identifier.name), identifier.start);
13798
14125
  }
13799
- return super.addDeclaration(identifier, context, init, kind);
14126
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
13800
14127
  }
13801
14128
  addExportDefaultDeclaration(name, exportDefaultDeclaration, context) {
13802
14129
  const variable = new ExportDefaultVariable(name, exportDefaultDeclaration, context);
@@ -13841,10 +14168,13 @@ class ThisExpression extends NodeBase {
13841
14168
  }
13842
14169
  return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
13843
14170
  }
13844
- include() {
14171
+ includePath(path, context) {
13845
14172
  if (!this.included) {
13846
14173
  this.included = true;
13847
- this.scope.context.includeVariableInModule(this.variable);
14174
+ this.scope.context.includeVariableInModule(this.variable, path);
14175
+ }
14176
+ else if (path.length > 0) {
14177
+ this.variable.includePath(path, context);
13848
14178
  }
13849
14179
  }
13850
14180
  initialise() {
@@ -13871,9 +14201,9 @@ class ThrowStatement extends NodeBase {
13871
14201
  hasEffects() {
13872
14202
  return true;
13873
14203
  }
13874
- include(context, includeChildrenRecursively) {
14204
+ includePath(_path, context, includeChildrenRecursively) {
13875
14205
  this.included = true;
13876
- this.argument.include(context, includeChildrenRecursively);
14206
+ this.argument.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13877
14207
  context.brokenFlow = true;
13878
14208
  }
13879
14209
  render(code, options) {
@@ -13895,13 +14225,13 @@ class TryStatement extends NodeBase {
13895
14225
  ? this.block.body.length > 0
13896
14226
  : this.block.hasEffects(context)) || !!this.finalizer?.hasEffects(context));
13897
14227
  }
13898
- include(context, includeChildrenRecursively) {
14228
+ includePath(_path, context, includeChildrenRecursively) {
13899
14229
  const tryCatchDeoptimization = this.scope.context.options.treeshake?.tryCatchDeoptimization;
13900
14230
  const { brokenFlow, includedLabels } = context;
13901
14231
  if (!this.directlyIncluded || !tryCatchDeoptimization) {
13902
14232
  this.included = true;
13903
14233
  this.directlyIncluded = true;
13904
- this.block.include(context, tryCatchDeoptimization ? INCLUDE_PARAMETERS : includeChildrenRecursively);
14234
+ this.block.includePath(UNKNOWN_PATH, context, tryCatchDeoptimization ? INCLUDE_PARAMETERS : includeChildrenRecursively);
13905
14235
  if (includedLabels.size > 0) {
13906
14236
  this.includedLabelsAfterBlock = [...includedLabels];
13907
14237
  }
@@ -13913,10 +14243,10 @@ class TryStatement extends NodeBase {
13913
14243
  }
13914
14244
  }
13915
14245
  if (this.handler !== null) {
13916
- this.handler.include(context, includeChildrenRecursively);
14246
+ this.handler.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13917
14247
  context.brokenFlow = brokenFlow;
13918
14248
  }
13919
- this.finalizer?.include(context, includeChildrenRecursively);
14249
+ this.finalizer?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13920
14250
  }
13921
14251
  }
13922
14252
 
@@ -13974,7 +14304,7 @@ class UpdateExpression extends NodeBase {
13974
14304
  hasEffectsOnInteractionAtPath(path, { type }) {
13975
14305
  return path.length > 1 || type !== INTERACTION_ACCESSED;
13976
14306
  }
13977
- include(context, includeChildrenRecursively) {
14307
+ includePath(_, context, includeChildrenRecursively) {
13978
14308
  if (!this.deoptimized)
13979
14309
  this.applyDeoptimizations();
13980
14310
  this.included = true;
@@ -14043,20 +14373,20 @@ class VariableDeclaration extends NodeBase {
14043
14373
  hasEffectsOnInteractionAtPath() {
14044
14374
  return false;
14045
14375
  }
14046
- include(context, includeChildrenRecursively, { asSingleStatement } = BLANK) {
14376
+ includePath(_path, context, includeChildrenRecursively, { asSingleStatement } = BLANK) {
14047
14377
  this.included = true;
14048
14378
  for (const declarator of this.declarations) {
14049
14379
  if (includeChildrenRecursively || declarator.shouldBeIncluded(context))
14050
- declarator.include(context, includeChildrenRecursively);
14380
+ declarator.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14051
14381
  const { id, init } = declarator;
14052
14382
  if (asSingleStatement) {
14053
- id.include(context, includeChildrenRecursively);
14383
+ id.includePath(EMPTY_PATH, context, includeChildrenRecursively);
14054
14384
  }
14055
14385
  if (init &&
14056
14386
  id.included &&
14057
14387
  !init.included &&
14058
14388
  (id instanceof ObjectPattern || id instanceof ArrayPattern)) {
14059
- init.include(context, includeChildrenRecursively);
14389
+ init.includePath(EMPTY_PATH, context, includeChildrenRecursively);
14060
14390
  }
14061
14391
  }
14062
14392
  }
@@ -14128,8 +14458,7 @@ class VariableDeclaration extends NodeBase {
14128
14458
  const singleSystemExport = gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregatedSystemExports);
14129
14459
  for (const { node, start, separator, contentEnd, end } of separatedNodes) {
14130
14460
  if (!node.included) {
14131
- code.remove(start, end);
14132
- node.removeAnnotations(code);
14461
+ treeshakeNode(node, code, start, end);
14133
14462
  continue;
14134
14463
  }
14135
14464
  node.render(code, options);
@@ -14206,9 +14535,9 @@ class WhileStatement extends NodeBase {
14206
14535
  return true;
14207
14536
  return hasLoopBodyEffects(context, this.body);
14208
14537
  }
14209
- include(context, includeChildrenRecursively) {
14538
+ includePath(_path, context, includeChildrenRecursively) {
14210
14539
  this.included = true;
14211
- this.test.include(context, includeChildrenRecursively);
14540
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14212
14541
  includeLoopBody(context, this.body, includeChildrenRecursively);
14213
14542
  }
14214
14543
  }
@@ -14452,7 +14781,7 @@ const bufferParsers = [
14452
14781
  const annotations = (node.annotations = convertAnnotations(buffer[position + 1], buffer));
14453
14782
  node.annotationNoSideEffects = annotations.some(comment => comment.type === 'noSideEffects');
14454
14783
  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);
14784
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14456
14785
  node.body = convertNode(node, scope.bodyScope, buffer[position + 3], buffer);
14457
14786
  },
14458
14787
  function assignmentExpression(node, position, buffer) {
@@ -14498,7 +14827,7 @@ const bufferParsers = [
14498
14827
  const parameterPosition = buffer[position];
14499
14828
  const parameter = (node.param =
14500
14829
  parameterPosition === 0 ? null : convertNode(node, scope, parameterPosition, buffer));
14501
- parameter?.declare('parameter', UNKNOWN_EXPRESSION);
14830
+ parameter?.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
14502
14831
  node.body = convertNode(node, scope.bodyScope, buffer[position + 1], buffer);
14503
14832
  },
14504
14833
  function chainExpression(node, position, buffer) {
@@ -14636,7 +14965,7 @@ const bufferParsers = [
14636
14965
  node.id =
14637
14966
  idPosition === 0 ? null : convertNode(node, scope.parent, idPosition, buffer);
14638
14967
  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);
14968
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14640
14969
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
14641
14970
  },
14642
14971
  function functionExpression(node, position, buffer) {
@@ -14649,7 +14978,7 @@ const bufferParsers = [
14649
14978
  const idPosition = buffer[position + 2];
14650
14979
  node.id = idPosition === 0 ? null : convertNode(node, node.idScope, idPosition, buffer);
14651
14980
  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);
14981
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14653
14982
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
14654
14983
  },
14655
14984
  function identifier(node, position, buffer) {
@@ -15008,8 +15337,8 @@ class UnknownNode extends NodeBase {
15008
15337
  hasEffects() {
15009
15338
  return true;
15010
15339
  }
15011
- include(context) {
15012
- super.include(context, true);
15340
+ includePath(path, context) {
15341
+ super.includePath(path, context, true);
15013
15342
  }
15014
15343
  }
15015
15344
 
@@ -15113,8 +15442,8 @@ class ExportShimVariable extends Variable {
15113
15442
  super(MISSING_EXPORT_SHIM_VARIABLE);
15114
15443
  this.module = module;
15115
15444
  }
15116
- include() {
15117
- super.include();
15445
+ includePath(path, context) {
15446
+ super.includePath(path, context);
15118
15447
  this.module.needsExportShim = true;
15119
15448
  }
15120
15449
  }
@@ -15805,7 +16134,7 @@ class Module {
15805
16134
  include() {
15806
16135
  const context = createInclusionContext();
15807
16136
  if (this.ast.shouldBeIncluded(context))
15808
- this.ast.include(context, false);
16137
+ this.ast.includePath(EMPTY_PATH, context, false);
15809
16138
  }
15810
16139
  includeAllExports(includeNamespaceMembers) {
15811
16140
  if (!this.isExecuted) {
@@ -15819,9 +16148,7 @@ class Module {
15819
16148
  return error(logMissingEntryExport(exportName, this.id));
15820
16149
  }
15821
16150
  variable.deoptimizePath(UNKNOWN_PATH);
15822
- if (!variable.included) {
15823
- this.includeVariable(variable);
15824
- }
16151
+ this.includeVariable(variable, UNKNOWN_PATH);
15825
16152
  }
15826
16153
  }
15827
16154
  for (const name of this.getReexports()) {
@@ -15829,7 +16156,7 @@ class Module {
15829
16156
  if (variable) {
15830
16157
  variable.deoptimizePath(UNKNOWN_PATH);
15831
16158
  if (!variable.included) {
15832
- this.includeVariable(variable);
16159
+ this.includeVariable(variable, UNKNOWN_PATH);
15833
16160
  }
15834
16161
  if (variable instanceof ExternalVariable) {
15835
16162
  variable.module.reexported = true;
@@ -15841,7 +16168,7 @@ class Module {
15841
16168
  }
15842
16169
  }
15843
16170
  includeAllInBundle() {
15844
- this.ast.include(createInclusionContext(), true);
16171
+ this.ast.includePath(UNKNOWN_PATH, createInclusionContext(), true);
15845
16172
  this.includeAllExports(false);
15846
16173
  }
15847
16174
  includeExportsByNames(names) {
@@ -15855,7 +16182,7 @@ class Module {
15855
16182
  if (variable) {
15856
16183
  variable.deoptimizePath(UNKNOWN_PATH);
15857
16184
  if (!variable.included) {
15858
- this.includeVariable(variable);
16185
+ this.includeVariable(variable, UNKNOWN_PATH);
15859
16186
  }
15860
16187
  }
15861
16188
  if (!this.exports.has(name) && !this.reexportDescriptions.has(name)) {
@@ -16297,13 +16624,13 @@ class Module {
16297
16624
  for (const module of [this, ...this.exportAllModules]) {
16298
16625
  if (module instanceof ExternalModule) {
16299
16626
  const [externalVariable] = module.getVariableForExportName('*');
16300
- externalVariable.include();
16627
+ externalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
16301
16628
  this.includedImports.add(externalVariable);
16302
16629
  externalNamespaces.add(externalVariable);
16303
16630
  }
16304
16631
  else if (module.info.syntheticNamedExports) {
16305
16632
  const syntheticNamespace = module.getSyntheticNamespace();
16306
- syntheticNamespace.include();
16633
+ syntheticNamespace.includePath(UNKNOWN_PATH, createInclusionContext());
16307
16634
  this.includedImports.add(syntheticNamespace);
16308
16635
  syntheticNamespaces.add(syntheticNamespace);
16309
16636
  }
@@ -16313,7 +16640,9 @@ class Module {
16313
16640
  includeDynamicImport(node) {
16314
16641
  const resolution = this.dynamicImports.find(dynamicImport => dynamicImport.node === node).resolution;
16315
16642
  if (resolution instanceof Module) {
16316
- resolution.includedDynamicImporters.push(this);
16643
+ if (!resolution.includedDynamicImporters.includes(this)) {
16644
+ resolution.includedDynamicImporters.push(this);
16645
+ }
16317
16646
  const importedNames = this.options.treeshake
16318
16647
  ? node.getDeterministicImportedNames()
16319
16648
  : undefined;
@@ -16325,7 +16654,7 @@ class Module {
16325
16654
  }
16326
16655
  }
16327
16656
  }
16328
- includeVariable(variable) {
16657
+ includeVariable(variable, path) {
16329
16658
  const variableModule = variable.module;
16330
16659
  if (variable.included) {
16331
16660
  if (variableModule instanceof Module && variableModule !== this) {
@@ -16333,7 +16662,6 @@ class Module {
16333
16662
  }
16334
16663
  }
16335
16664
  else {
16336
- variable.include();
16337
16665
  this.graph.needsTreeshakingPass = true;
16338
16666
  if (variableModule instanceof Module) {
16339
16667
  if (!variableModule.isExecuted) {
@@ -16349,9 +16677,10 @@ class Module {
16349
16677
  }
16350
16678
  }
16351
16679
  }
16680
+ variable.includePath(path, createInclusionContext());
16352
16681
  }
16353
- includeVariableInModule(variable) {
16354
- this.includeVariable(variable);
16682
+ includeVariableInModule(variable, path) {
16683
+ this.includeVariable(variable, path);
16355
16684
  const variableModule = variable.module;
16356
16685
  if (variableModule && variableModule !== this) {
16357
16686
  this.includedImports.add(variable);
@@ -20948,7 +21277,7 @@ class Graph {
20948
21277
  this.options = options;
20949
21278
  this.astLru = flru(5);
20950
21279
  this.cachedModules = new Map();
20951
- this.deoptimizationTracker = new PathTracker();
21280
+ this.deoptimizationTracker = new EntityPathTracker();
20952
21281
  this.entryModules = [];
20953
21282
  this.modulesById = new Map();
20954
21283
  this.needsTreeshakingPass = false;
@@ -21948,7 +22277,7 @@ createColors();
21948
22277
 
21949
22278
  // @see https://no-color.org
21950
22279
  // @see https://www.npmjs.com/package/chalk
21951
- const { bold, cyan, dim, gray, green, red, underline, yellow } = createColors({
22280
+ const { bold, cyan, dim, red} = createColors({
21952
22281
  useColor: env$1.FORCE_COLOR !== '0' && !env$1.NO_COLOR
21953
22282
  });
21954
22283