@rollup/wasm-node 4.33.0 → 4.34.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,21 +1,21 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v4.33.0
4
- Sat, 01 Feb 2025 07:11:29 GMT - commit 494483e8df7b5d04796b30e37f54d7e96fa91a97
3
+ Rollup.js v4.34.0
4
+ Sat, 01 Feb 2025 08:39:54 GMT - commit 979d62888dbe75f92e50fdd64246c737c52f5f1f
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, 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, logModuleParseError, logParseError, LOGLEVEL_INFO, logFirstSideEffect, locate, logInvalidAnnotation, Identifier as Identifier$1, logThisIsUndefined, getAstBuffer, convertAnnotations, FIXED_STRINGS, convertNode as convertNode$1, logImportAttributeIsInvalid, logImportOptionsAreInvalid, logSyntheticNamedExportsNeedNamespaceExport, logMissingEntryExport, logDuplicateExportError, logInvalidSourcemapForError, augmentCodeLocation, logInconsistentImportAttributes, logMissingJsxExport, logNamespaceConflict, logAmbiguousExternalNamespaces, logShimmedExport, parseAst, logInvalidFormatForTopLevelAwait, TemplateLiteral as TemplateLiteral$1, Literal as Literal$1, logCircularReexport, logAddonNotGenerated, logIncompatibleExportOptionValue, logMixedExport, logFailedValidation, isPathFragment, logCyclicCrossChunkReexport, getAliasName, logUnexpectedNamedImport, isAbsolute as isAbsolute$1, relative as relative$1, logUnexpectedNamespaceReexport, logEmptyChunk, logMissingGlobalName, logOptimizeChunkStatus, logSourcemapBroken, logConflictingSourcemapSources, logChunkInvalid, logInvalidOption, logCannotAssignModuleToChunk, URL_OUTPUT_FORMAT, URL_OUTPUT_DIR, URL_OUTPUT_SOURCEMAPFILE, URL_OUTPUT_AMD_ID, logAnonymousPluginCache, logDuplicatePluginName, logUnknownOption, LOGLEVEL_ERROR, logLevelPriority, LOGLEVEL_DEBUG, printQuotedStringList, logInvalidSetAssetSourceCall, logPluginError, logNoTransformMapOrAstWithoutCode, relativeId, logBadLoader, logExternalModulesCannotBeTransformedToModules, logInternalIdCannotBeExternal, isRelative, logUnresolvedImport, logUnresolvedImportTreatedAsExternal, logExternalSyntheticExports, logUnresolvedEntry, logUnresolvedImplicitDependant, logExternalModulesCannotBeIncludedInManualChunks, logEntryCannotBeExternal, logImplicitDependantCannotBeExternal, logNoAssetSourceSet, logFileReferenceIdNotFoundForFilename, logAssetReferenceIdNotFoundForSetSource, logAssetSourceAlreadySet, logInvalidRollupPhaseForChunkEmission, warnDeprecation, logChunkNotGeneratedForFileName, logAssetNotFinalisedForFileName, logFileNameConflict, URL_GENERATEBUNDLE, logInvalidLogPosition, logInputHookInOutputPlugin, logInvalidAddonPluginHook, logInvalidFunctionPluginHook, logImplicitDependantIsNotIncluded, logCircularDependency, augmentLogMessage, URL_TREESHAKE, URL_JSX, URL_TREESHAKE_MODULESIDEEFFECTS, URL_OUTPUT_INLINEDYNAMICIMPORTS, URL_PRESERVEENTRYSIGNATURES, URL_OUTPUT_GENERATEDCODE, isValidUrl, addTrailingSlashIfMissed, URL_OUTPUT_SOURCEMAPBASEURL, URL_OUTPUT_MANUALCHUNKS, logInvalidExportOptionValue, URL_OUTPUT_AMD_BASEPATH, URL_OUTPUT_INTEROP, URL_OUTPUT_EXTERNALIMPORTATTRIBUTES, logAlreadyClosed, logMissingFileOrDirOption, logCannotEmitFromOptionsHook, URL_WATCH } from './parseAst.js';
11
11
  import { relative, dirname, basename, extname, resolve as resolve$1 } from 'node:path';
12
- import { posix, win32, isAbsolute, resolve } from 'path';
13
- import { parseAsync, xxhashBase64Url, xxhashBase36, xxhashBase16 } from '../../native.js';
12
+ import { posix, isAbsolute, resolve, win32 } from 'path';
13
+ import { parseAsync, xxhashBase16, xxhashBase64Url, xxhashBase36 } from '../../native.js';
14
14
  import process$1, { env } 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
 
18
- var version = "4.33.0";
18
+ var version = "4.34.0";
19
19
 
20
20
  const comma = ','.charCodeAt(0);
21
21
  const semicolon = ';'.charCodeAt(0);
@@ -1964,71 +1964,6 @@ function renderSystemExportSequenceBeforeExpression(exportedVariable, expression
1964
1964
  }
1965
1965
  }
1966
1966
 
1967
- /** @import { Node } from 'estree' */
1968
-
1969
- /**
1970
- * @param {Node} node
1971
- * @param {Node} parent
1972
- * @returns {boolean}
1973
- */
1974
- function is_reference(node, parent) {
1975
- if (node.type === 'MemberExpression') {
1976
- return !node.computed && is_reference(node.object, node);
1977
- }
1978
-
1979
- if (node.type !== 'Identifier') return false;
1980
-
1981
- switch (parent?.type) {
1982
- // disregard `bar` in `foo.bar`
1983
- case 'MemberExpression':
1984
- return parent.computed || node === parent.object;
1985
-
1986
- // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
1987
- case 'MethodDefinition':
1988
- return parent.computed;
1989
-
1990
- // disregard the `meta` in `import.meta`
1991
- case 'MetaProperty':
1992
- return parent.meta === node;
1993
-
1994
- // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
1995
- case 'PropertyDefinition':
1996
- return parent.computed || node === parent.value;
1997
-
1998
- // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
1999
- case 'Property':
2000
- return parent.computed || node === parent.value;
2001
-
2002
- // disregard the `bar` in `export { foo as bar }` or
2003
- // the foo in `import { foo as bar }`
2004
- case 'ExportSpecifier':
2005
- case 'ImportSpecifier':
2006
- return node === parent.local;
2007
-
2008
- // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
2009
- case 'LabeledStatement':
2010
- case 'BreakStatement':
2011
- case 'ContinueStatement':
2012
- return false;
2013
-
2014
- default:
2015
- return true;
2016
- }
2017
- }
2018
-
2019
- const PureFunctionKey = Symbol('PureFunction');
2020
- const getPureFunctions = ({ treeshake }) => {
2021
- const pureFunctions = Object.create(null);
2022
- for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
2023
- let currentFunctions = pureFunctions;
2024
- for (const pathSegment of functionName.split('.')) {
2025
- currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
2026
- }
2027
- currentFunctions[PureFunctionKey] = true;
2028
- }
2029
- return pureFunctions;
2030
- };
2031
-
2032
1967
  function getOrCreate(map, key, init) {
2033
1968
  const existing = map.get(key);
2034
1969
  if (existing !== undefined) {
@@ -2059,7 +1994,7 @@ const UNKNOWN_PATH = [UnknownKey];
2059
1994
  const UNKNOWN_NON_ACCESSOR_PATH = [UnknownNonAccessorKey];
2060
1995
  const UNKNOWN_INTEGER_PATH = [UnknownInteger];
2061
1996
  const EntitiesKey = Symbol('Entities');
2062
- class PathTracker {
1997
+ class EntityPathTracker {
2063
1998
  constructor() {
2064
1999
  this.entityPaths = Object.create(null, {
2065
2000
  [EntitiesKey]: { value: new Set() }
@@ -2084,14 +2019,14 @@ class PathTracker {
2084
2019
  getEntities(path) {
2085
2020
  let currentPaths = this.entityPaths;
2086
2021
  for (const pathSegment of path) {
2087
- currentPaths = currentPaths[pathSegment] =
2088
- currentPaths[pathSegment] ||
2089
- Object.create(null, { [EntitiesKey]: { value: new Set() } });
2022
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
2023
+ [EntitiesKey]: { value: new Set() }
2024
+ });
2090
2025
  }
2091
2026
  return currentPaths[EntitiesKey];
2092
2027
  }
2093
2028
  }
2094
- const SHARED_RECURSION_TRACKER = new PathTracker();
2029
+ const SHARED_RECURSION_TRACKER = new EntityPathTracker();
2095
2030
  class DiscriminatedPathTracker {
2096
2031
  constructor() {
2097
2032
  this.entityPaths = Object.create(null, {
@@ -2101,9 +2036,9 @@ class DiscriminatedPathTracker {
2101
2036
  trackEntityAtPathAndGetIfTracked(path, discriminator, entity) {
2102
2037
  let currentPaths = this.entityPaths;
2103
2038
  for (const pathSegment of path) {
2104
- currentPaths = currentPaths[pathSegment] =
2105
- currentPaths[pathSegment] ||
2106
- Object.create(null, { [EntitiesKey]: { value: new Map() } });
2039
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
2040
+ [EntitiesKey]: { value: new Map() }
2041
+ });
2107
2042
  }
2108
2043
  const trackedEntities = getOrCreate(currentPaths[EntitiesKey], discriminator, (getNewSet));
2109
2044
  if (trackedEntities.has(entity))
@@ -2112,6 +2047,174 @@ class DiscriminatedPathTracker {
2112
2047
  return false;
2113
2048
  }
2114
2049
  }
2050
+ const UNKNOWN_INCLUDED_PATH = Object.freeze({ [UnknownKey]: EMPTY_OBJECT });
2051
+ class IncludedFullPathTracker {
2052
+ constructor() {
2053
+ this.includedPaths = null;
2054
+ }
2055
+ includePathAndGetIfIncluded(path) {
2056
+ let included = true;
2057
+ let parent = this;
2058
+ let parentSegment = 'includedPaths';
2059
+ let currentPaths = (this.includedPaths ||=
2060
+ ((included = false), Object.create(null)));
2061
+ for (const pathSegment of path) {
2062
+ // This means from here, all paths are included
2063
+ if (currentPaths[UnknownKey]) {
2064
+ return true;
2065
+ }
2066
+ // Including UnknownKey automatically includes all nested paths.
2067
+ // From above, we know that UnknownKey is not included yet.
2068
+ if (typeof pathSegment === 'symbol') {
2069
+ // Hopefully, this saves some memory over just setting
2070
+ // currentPaths[UnknownKey] = EMPTY_OBJECT
2071
+ parent[parentSegment] = UNKNOWN_INCLUDED_PATH;
2072
+ return false;
2073
+ }
2074
+ parent = currentPaths;
2075
+ parentSegment = pathSegment;
2076
+ currentPaths = currentPaths[pathSegment] ||= ((included = false), Object.create(null));
2077
+ }
2078
+ return included;
2079
+ }
2080
+ }
2081
+ const UNKNOWN_INCLUDED_TOP_LEVEL_PATH = Object.freeze({
2082
+ [UnknownKey]: true
2083
+ });
2084
+ class IncludedTopLevelPathTracker {
2085
+ constructor() {
2086
+ this.includedPaths = null;
2087
+ }
2088
+ includePathAndGetIfIncluded(path) {
2089
+ let included = true;
2090
+ const includedPaths = (this.includedPaths ||=
2091
+ ((included = false), Object.create(null)));
2092
+ if (includedPaths[UnknownKey]) {
2093
+ return true;
2094
+ }
2095
+ const [firstPathSegment, secondPathSegment] = path;
2096
+ if (!firstPathSegment) {
2097
+ return included;
2098
+ }
2099
+ if (typeof firstPathSegment === 'symbol') {
2100
+ this.includedPaths = UNKNOWN_INCLUDED_TOP_LEVEL_PATH;
2101
+ return false;
2102
+ }
2103
+ if (secondPathSegment) {
2104
+ if (includedPaths[firstPathSegment] === UnknownKey) {
2105
+ return true;
2106
+ }
2107
+ includedPaths[firstPathSegment] = UnknownKey;
2108
+ return false;
2109
+ }
2110
+ if (includedPaths[firstPathSegment]) {
2111
+ return true;
2112
+ }
2113
+ includedPaths[firstPathSegment] = true;
2114
+ return false;
2115
+ }
2116
+ includeAllPaths(entity, context, basePath) {
2117
+ const { includedPaths } = this;
2118
+ if (includedPaths) {
2119
+ if (includedPaths[UnknownKey]) {
2120
+ entity.includePath([...basePath, UnknownKey], context);
2121
+ }
2122
+ else {
2123
+ const inclusionEntries = Object.entries(includedPaths);
2124
+ if (inclusionEntries.length === 0) {
2125
+ entity.includePath(basePath, context);
2126
+ }
2127
+ else {
2128
+ for (const [key, value] of inclusionEntries) {
2129
+ entity.includePath(value === UnknownKey ? [...basePath, key, UnknownKey] : [...basePath, key], context);
2130
+ }
2131
+ }
2132
+ }
2133
+ }
2134
+ }
2135
+ }
2136
+
2137
+ /** @import { Node } from 'estree' */
2138
+
2139
+ /**
2140
+ * @param {Node} node
2141
+ * @param {Node} parent
2142
+ * @returns {boolean}
2143
+ */
2144
+ function is_reference(node, parent) {
2145
+ if (node.type === 'MemberExpression') {
2146
+ return !node.computed && is_reference(node.object, node);
2147
+ }
2148
+
2149
+ if (node.type !== 'Identifier') return false;
2150
+
2151
+ switch (parent?.type) {
2152
+ // disregard `bar` in `foo.bar`
2153
+ case 'MemberExpression':
2154
+ return parent.computed || node === parent.object;
2155
+
2156
+ // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
2157
+ case 'MethodDefinition':
2158
+ return parent.computed;
2159
+
2160
+ // disregard the `meta` in `import.meta`
2161
+ case 'MetaProperty':
2162
+ return parent.meta === node;
2163
+
2164
+ // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
2165
+ case 'PropertyDefinition':
2166
+ return parent.computed || node === parent.value;
2167
+
2168
+ // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
2169
+ case 'Property':
2170
+ return parent.computed || node === parent.value;
2171
+
2172
+ // disregard the `bar` in `export { foo as bar }` or
2173
+ // the foo in `import { foo as bar }`
2174
+ case 'ExportSpecifier':
2175
+ case 'ImportSpecifier':
2176
+ return node === parent.local;
2177
+
2178
+ // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
2179
+ case 'LabeledStatement':
2180
+ case 'BreakStatement':
2181
+ case 'ContinueStatement':
2182
+ return false;
2183
+
2184
+ default:
2185
+ return true;
2186
+ }
2187
+ }
2188
+
2189
+ function createInclusionContext() {
2190
+ return {
2191
+ brokenFlow: false,
2192
+ hasBreak: false,
2193
+ hasContinue: false,
2194
+ includedCallArguments: new Set(),
2195
+ includedLabels: new Set()
2196
+ };
2197
+ }
2198
+ function createHasEffectsContext() {
2199
+ return {
2200
+ accessed: new EntityPathTracker(),
2201
+ assigned: new EntityPathTracker(),
2202
+ brokenFlow: false,
2203
+ called: new DiscriminatedPathTracker(),
2204
+ hasBreak: false,
2205
+ hasContinue: false,
2206
+ ignore: {
2207
+ breaks: false,
2208
+ continues: false,
2209
+ labels: new Set(),
2210
+ returnYield: false,
2211
+ this: false
2212
+ },
2213
+ includedLabels: new Set(),
2214
+ instantiated: new DiscriminatedPathTracker(),
2215
+ replacedVariableInits: new Map()
2216
+ };
2217
+ }
2115
2218
 
2116
2219
  function isFlagSet(flags, flag) {
2117
2220
  return (flags & flag) !== 0;
@@ -2151,12 +2254,25 @@ class ExpressionEntity {
2151
2254
  hasEffectsOnInteractionAtPath(_path, _interaction, _context) {
2152
2255
  return true;
2153
2256
  }
2154
- include(_context, _includeChildrenRecursively, _options) {
2257
+ include(context, _includeChildrenRecursively, _options) {
2258
+ if (!this.included)
2259
+ this.includeNode(context);
2260
+ }
2261
+ includeNode(_context) {
2155
2262
  this.included = true;
2156
2263
  }
2157
- includeCallArguments(context, parameters) {
2158
- for (const argument of parameters) {
2159
- argument.include(context, false);
2264
+ includePath(_path, context) {
2265
+ if (!this.included)
2266
+ this.includeNode(context);
2267
+ }
2268
+ /* We are both including and including an unknown path here as the former
2269
+ * ensures that nested nodes are included while the latter ensures that all
2270
+ * paths of the expression are included.
2271
+ * */
2272
+ includeCallArguments(context, interaction) {
2273
+ for (const argument of interaction.args) {
2274
+ argument?.includePath(UNKNOWN_PATH, context);
2275
+ argument?.include(context, false);
2160
2276
  }
2161
2277
  }
2162
2278
  shouldBeIncluded(_context) {
@@ -2195,6 +2311,19 @@ const NODE_INTERACTION_UNKNOWN_CALL = {
2195
2311
  withNew: false
2196
2312
  };
2197
2313
 
2314
+ const PureFunctionKey = Symbol('PureFunction');
2315
+ const getPureFunctions = ({ treeshake }) => {
2316
+ const pureFunctions = Object.create(null);
2317
+ for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
2318
+ let currentFunctions = pureFunctions;
2319
+ for (const pathSegment of functionName.split('.')) {
2320
+ currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
2321
+ }
2322
+ currentFunctions[PureFunctionKey] = true;
2323
+ }
2324
+ return pureFunctions;
2325
+ };
2326
+
2198
2327
  class Variable extends ExpressionEntity {
2199
2328
  markReassigned() {
2200
2329
  this.isReassigned = true;
@@ -2271,9 +2400,9 @@ class Variable extends ExpressionEntity {
2271
2400
  * has not been included previously. Once a variable is included, it should
2272
2401
  * take care all its declarations are included.
2273
2402
  */
2274
- include() {
2403
+ includePath(path, context) {
2275
2404
  this.included = true;
2276
- this.renderedLikeHoisted?.include();
2405
+ this.renderedLikeHoisted?.includePath(path, context);
2277
2406
  }
2278
2407
  /**
2279
2408
  * Links the rendered name of this variable to another variable and includes
@@ -2305,8 +2434,8 @@ class ExternalVariable extends Variable {
2305
2434
  hasEffectsOnInteractionAtPath(path, { type }) {
2306
2435
  return type !== INTERACTION_ACCESSED || path.length > (this.isNamespace ? 1 : 0);
2307
2436
  }
2308
- include() {
2309
- super.include();
2437
+ includePath(path, context) {
2438
+ super.includePath(path, context);
2310
2439
  this.module.used = true;
2311
2440
  }
2312
2441
  }
@@ -2607,36 +2736,6 @@ const childNodeKeys = {
2607
2736
  YieldExpression: ['argument']
2608
2737
  };
2609
2738
 
2610
- function createInclusionContext() {
2611
- return {
2612
- brokenFlow: false,
2613
- hasBreak: false,
2614
- hasContinue: false,
2615
- includedCallArguments: new Set(),
2616
- includedLabels: new Set()
2617
- };
2618
- }
2619
- function createHasEffectsContext() {
2620
- return {
2621
- accessed: new PathTracker(),
2622
- assigned: new PathTracker(),
2623
- brokenFlow: false,
2624
- called: new DiscriminatedPathTracker(),
2625
- hasBreak: false,
2626
- hasContinue: false,
2627
- ignore: {
2628
- breaks: false,
2629
- continues: false,
2630
- labels: new Set(),
2631
- returnYield: false,
2632
- this: false
2633
- },
2634
- includedLabels: new Set(),
2635
- instantiated: new DiscriminatedPathTracker(),
2636
- replacedVariableInits: new Map()
2637
- };
2638
- }
2639
-
2640
2739
  const INCLUDE_PARAMETERS = 'variables';
2641
2740
  const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN');
2642
2741
  class NodeBase extends ExpressionEntity {
@@ -2706,9 +2805,8 @@ class NodeBase extends ExpressionEntity {
2706
2805
  this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));
2707
2806
  }
2708
2807
  include(context, includeChildrenRecursively, _options) {
2709
- if (!this.deoptimized)
2710
- this.applyDeoptimizations();
2711
- this.included = true;
2808
+ if (!this.included)
2809
+ this.includeNode(context);
2712
2810
  for (const key of childNodeKeys[this.type]) {
2713
2811
  const value = this[key];
2714
2812
  if (value === null)
@@ -2723,6 +2821,24 @@ class NodeBase extends ExpressionEntity {
2723
2821
  }
2724
2822
  }
2725
2823
  }
2824
+ includeNode(context) {
2825
+ this.included = true;
2826
+ if (!this.deoptimized)
2827
+ this.applyDeoptimizations();
2828
+ for (const key of childNodeKeys[this.type]) {
2829
+ const value = this[key];
2830
+ if (value === null)
2831
+ continue;
2832
+ if (Array.isArray(value)) {
2833
+ for (const child of value) {
2834
+ child?.includePath(UNKNOWN_PATH, context);
2835
+ }
2836
+ }
2837
+ else {
2838
+ value.includePath(UNKNOWN_PATH, context);
2839
+ }
2840
+ }
2841
+ }
2726
2842
  includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {
2727
2843
  this.include(context, includeChildrenRecursively);
2728
2844
  }
@@ -2826,6 +2942,17 @@ class NodeBase extends ExpressionEntity {
2826
2942
  function createChildNodeKeysForNode(esTreeNode) {
2827
2943
  return Object.keys(esTreeNode).filter(key => typeof esTreeNode[key] === 'object' && key.charCodeAt(0) !== 95 /* _ */);
2828
2944
  }
2945
+ function onlyIncludeSelf() {
2946
+ this.included = true;
2947
+ if (!this.deoptimized)
2948
+ this.applyDeoptimizations();
2949
+ }
2950
+ function onlyIncludeSelfNoDeoptimize() {
2951
+ this.included = true;
2952
+ }
2953
+ function doNotDeoptimize() {
2954
+ this.deoptimized = true;
2955
+ }
2829
2956
 
2830
2957
  function isObjectExpressionNode(node) {
2831
2958
  return node instanceof NodeBase && node.type === ObjectExpression$1;
@@ -2838,8 +2965,8 @@ function assembleMemberDescriptions(memberDescriptions, inheritedDescriptions =
2838
2965
  return Object.create(inheritedDescriptions, memberDescriptions);
2839
2966
  }
2840
2967
  const UNDEFINED_EXPRESSION = new (class UndefinedExpression extends ExpressionEntity {
2841
- getLiteralValueAtPath() {
2842
- return undefined;
2968
+ getLiteralValueAtPath(path) {
2969
+ return path.length > 0 ? UnknownValue : undefined;
2843
2970
  }
2844
2971
  })();
2845
2972
  const returnsUnknown = {
@@ -3036,31 +3163,6 @@ function getMemberReturnExpressionWhenCalled(members, memberName) {
3036
3163
  return [members[memberName].returns, false];
3037
3164
  }
3038
3165
 
3039
- class SpreadElement extends NodeBase {
3040
- deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
3041
- if (path.length > 0) {
3042
- this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker);
3043
- }
3044
- }
3045
- hasEffects(context) {
3046
- if (!this.deoptimized)
3047
- this.applyDeoptimizations();
3048
- const { propertyReadSideEffects } = this.scope.context.options
3049
- .treeshake;
3050
- return (this.argument.hasEffects(context) ||
3051
- (propertyReadSideEffects &&
3052
- (propertyReadSideEffects === 'always' ||
3053
- this.argument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context))));
3054
- }
3055
- applyDeoptimizations() {
3056
- this.deoptimized = true;
3057
- // Only properties of properties of the argument could become subject to reassignment
3058
- // This will also reassign the return values of iterators
3059
- this.argument.deoptimizePath([UnknownKey, UnknownKey]);
3060
- this.scope.context.requestTreeshakingPass();
3061
- }
3062
- }
3063
-
3064
3166
  class Method extends ExpressionEntity {
3065
3167
  constructor(description) {
3066
3168
  super();
@@ -3186,6 +3288,7 @@ class ObjectEntity extends ExpressionEntity {
3186
3288
  this.unknownIntegerProps = [];
3187
3289
  this.unmatchableGetters = [];
3188
3290
  this.unmatchablePropertiesAndGetters = [];
3291
+ this.unmatchablePropertiesAndSetters = [];
3189
3292
  this.unmatchableSetters = [];
3190
3293
  if (Array.isArray(properties)) {
3191
3294
  this.buildPropertyMaps(properties);
@@ -3342,7 +3445,12 @@ class ObjectEntity extends ExpressionEntity {
3342
3445
  }
3343
3446
  getLiteralValueAtPath(path, recursionTracker, origin) {
3344
3447
  if (path.length === 0) {
3345
- return UnknownTruthyValue;
3448
+ // This should actually be "UnknownTruthyValue". However, this currently
3449
+ // causes an issue with TypeScript enums in files with moduleSideEffects:
3450
+ // false because we cannot properly track whether a "var" has been
3451
+ // initialized. This should be reverted once we can properly track this.
3452
+ // return UnknownTruthyValue;
3453
+ return UnknownValue;
3346
3454
  }
3347
3455
  const key = path[0];
3348
3456
  const expressionAtPath = this.getMemberExpressionAndTrackDeopt(key, origin);
@@ -3420,9 +3528,36 @@ class ObjectEntity extends ExpressionEntity {
3420
3528
  }
3421
3529
  return false;
3422
3530
  }
3531
+ include(context, includeChildrenRecursively) {
3532
+ this.included = true;
3533
+ for (const property of this.allProperties) {
3534
+ if (includeChildrenRecursively || property.shouldBeIncluded(context)) {
3535
+ property.include(context, includeChildrenRecursively);
3536
+ }
3537
+ }
3538
+ this.prototypeExpression?.include(context, includeChildrenRecursively);
3539
+ }
3540
+ includePath(path, context) {
3541
+ this.included = true;
3542
+ if (path.length === 0)
3543
+ return;
3544
+ const [key, ...subPath] = path;
3545
+ const [includedMembers, includedPath] = typeof key === 'string'
3546
+ ? [
3547
+ new Set([
3548
+ ...(this.propertiesAndGettersByKey[key] || this.unmatchablePropertiesAndGetters),
3549
+ ...(this.propertiesAndSettersByKey[key] || this.unmatchablePropertiesAndSetters)
3550
+ ]),
3551
+ subPath
3552
+ ]
3553
+ : [this.allProperties, UNKNOWN_PATH];
3554
+ for (const property of includedMembers) {
3555
+ property.includePath(includedPath, context);
3556
+ }
3557
+ this.prototypeExpression?.includePath(path, context);
3558
+ }
3423
3559
  buildPropertyMaps(properties) {
3424
- const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchableGetters, unmatchableSetters } = this;
3425
- const unmatchablePropertiesAndSetters = [];
3560
+ const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchablePropertiesAndSetters, unmatchableGetters, unmatchableSetters } = this;
3426
3561
  for (let index = properties.length - 1; index >= 0; index--) {
3427
3562
  const { key, kind, property } = properties[index];
3428
3563
  allProperties.push(property);
@@ -3692,6 +3827,37 @@ const ARRAY_PROTOTYPE = new ObjectEntity({
3692
3827
  values: METHOD_DEOPTS_SELF_RETURNS_UNKNOWN
3693
3828
  }, OBJECT_PROTOTYPE, true);
3694
3829
 
3830
+ class SpreadElement extends NodeBase {
3831
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
3832
+ if (path.length > 0) {
3833
+ this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker);
3834
+ }
3835
+ }
3836
+ hasEffects(context) {
3837
+ if (!this.deoptimized)
3838
+ this.applyDeoptimizations();
3839
+ const { propertyReadSideEffects } = this.scope.context.options
3840
+ .treeshake;
3841
+ return (this.argument.hasEffects(context) ||
3842
+ (propertyReadSideEffects &&
3843
+ (propertyReadSideEffects === 'always' ||
3844
+ this.argument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context))));
3845
+ }
3846
+ includeNode(context) {
3847
+ this.included = true;
3848
+ if (!this.deoptimized)
3849
+ this.applyDeoptimizations();
3850
+ this.argument.includePath(UNKNOWN_PATH, context);
3851
+ }
3852
+ applyDeoptimizations() {
3853
+ this.deoptimized = true;
3854
+ // Only properties of properties of the argument could become subject to reassignment
3855
+ // This will also reassign the return values of iterators
3856
+ this.argument.deoptimizePath([UnknownKey, UnknownKey]);
3857
+ this.scope.context.requestTreeshakingPass();
3858
+ }
3859
+ }
3860
+
3695
3861
  class ArrayExpression extends NodeBase {
3696
3862
  constructor() {
3697
3863
  super(...arguments);
@@ -3712,6 +3878,16 @@ class ArrayExpression extends NodeBase {
3712
3878
  hasEffectsOnInteractionAtPath(path, interaction, context) {
3713
3879
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
3714
3880
  }
3881
+ includeNode(context) {
3882
+ this.included = true;
3883
+ if (!this.deoptimized)
3884
+ this.applyDeoptimizations();
3885
+ for (const element of this.elements) {
3886
+ if (element) {
3887
+ element?.includePath(UNKNOWN_PATH, context);
3888
+ }
3889
+ }
3890
+ }
3715
3891
  applyDeoptimizations() {
3716
3892
  this.deoptimized = true;
3717
3893
  let hasSpread = false;
@@ -4779,17 +4955,37 @@ class GlobalVariable extends Variable {
4779
4955
  }
4780
4956
  }
4781
4957
 
4958
+ // To avoid infinite recursions
4959
+ const MAX_PATH_DEPTH = 6;
4960
+ // If a path is longer than MAX_PATH_DEPTH, it is truncated so that it is at
4961
+ // most MAX_PATH_DEPTH long. The last element is always UnknownKey
4962
+ const limitConcatenatedPathDepth = (path1, path2) => {
4963
+ const { length: length1 } = path1;
4964
+ const { length: length2 } = path2;
4965
+ return length1 === 0
4966
+ ? path2
4967
+ : length2 === 0
4968
+ ? path1
4969
+ : length1 + length2 > MAX_PATH_DEPTH
4970
+ ? [...path1, ...path2.slice(0, MAX_PATH_DEPTH - 1 - path1.length), 'UnknownKey']
4971
+ : [...path1, ...path2];
4972
+ };
4973
+
4782
4974
  class LocalVariable extends Variable {
4783
- constructor(name, declarator, init, context, kind) {
4975
+ constructor(name, declarator, init,
4976
+ /** if this is non-empty, the actual init is this path of this.init */
4977
+ initPath, context, kind) {
4784
4978
  super(name);
4785
4979
  this.init = init;
4980
+ this.initPath = initPath;
4981
+ this.kind = kind;
4786
4982
  this.calledFromTryStatement = false;
4787
4983
  this.additionalInitializers = null;
4984
+ this.includedPathTracker = new IncludedFullPathTracker();
4788
4985
  this.expressionsToBeDeoptimized = [];
4789
4986
  this.declarations = declarator ? [declarator] : [];
4790
4987
  this.deoptimizationTracker = context.deoptimizationTracker;
4791
4988
  this.module = context.module;
4792
- this.kind = kind;
4793
4989
  }
4794
4990
  addDeclaration(identifier, init) {
4795
4991
  this.declarations.push(identifier);
@@ -4800,15 +4996,16 @@ class LocalVariable extends Variable {
4800
4996
  for (const initializer of this.additionalInitializers) {
4801
4997
  initializer.deoptimizePath(UNKNOWN_PATH);
4802
4998
  }
4803
- this.additionalInitializers = null;
4804
4999
  }
4805
5000
  }
4806
5001
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
4807
- if (this.isReassigned) {
5002
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
4808
5003
  deoptimizeInteraction(interaction);
4809
5004
  return;
4810
5005
  }
4811
- recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker), undefined);
5006
+ recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
5007
+ this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], recursionTracker);
5008
+ }, undefined);
4812
5009
  }
4813
5010
  deoptimizePath(path) {
4814
5011
  if (this.isReassigned ||
@@ -4822,37 +5019,40 @@ class LocalVariable extends Variable {
4822
5019
  for (const expression of expressionsToBeDeoptimized) {
4823
5020
  expression.deoptimizeCache();
4824
5021
  }
4825
- this.init.deoptimizePath(UNKNOWN_PATH);
5022
+ this.init.deoptimizePath([...this.initPath, UnknownKey]);
4826
5023
  }
4827
5024
  else {
4828
- this.init.deoptimizePath(path);
5025
+ this.init.deoptimizePath(limitConcatenatedPathDepth(this.initPath, path));
4829
5026
  }
4830
5027
  }
4831
5028
  getLiteralValueAtPath(path, recursionTracker, origin) {
4832
- if (this.isReassigned) {
5029
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
4833
5030
  return UnknownValue;
4834
5031
  }
4835
5032
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
4836
5033
  this.expressionsToBeDeoptimized.push(origin);
4837
- return this.init.getLiteralValueAtPath(path, recursionTracker, origin);
5034
+ return this.init.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin);
4838
5035
  }, UnknownValue);
4839
5036
  }
4840
5037
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
4841
- if (this.isReassigned) {
5038
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
4842
5039
  return UNKNOWN_RETURN_EXPRESSION;
4843
5040
  }
4844
5041
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
4845
5042
  this.expressionsToBeDeoptimized.push(origin);
4846
- return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
5043
+ return this.init.getReturnExpressionWhenCalledAtPath([...this.initPath, ...path], interaction, recursionTracker, origin);
4847
5044
  }, UNKNOWN_RETURN_EXPRESSION);
4848
5045
  }
4849
5046
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5047
+ if (path.length + this.initPath.length > MAX_PATH_DEPTH) {
5048
+ return true;
5049
+ }
4850
5050
  switch (interaction.type) {
4851
5051
  case INTERACTION_ACCESSED: {
4852
5052
  if (this.isReassigned)
4853
5053
  return true;
4854
5054
  return (!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
4855
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
5055
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4856
5056
  }
4857
5057
  case INTERACTION_ASSIGNED: {
4858
5058
  if (this.included)
@@ -4862,44 +5062,63 @@ class LocalVariable extends Variable {
4862
5062
  if (this.isReassigned)
4863
5063
  return true;
4864
5064
  return (!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
4865
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
5065
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4866
5066
  }
4867
5067
  case INTERACTION_CALLED: {
4868
5068
  if (this.isReassigned)
4869
5069
  return true;
4870
5070
  return (!(interaction.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this) &&
4871
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
5071
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4872
5072
  }
4873
5073
  }
4874
5074
  }
4875
- include() {
4876
- if (!this.included) {
4877
- super.include();
5075
+ includePath(path, context) {
5076
+ if (!this.includedPathTracker.includePathAndGetIfIncluded(path)) {
5077
+ this.module.scope.context.requestTreeshakingPass();
5078
+ if (!this.included) {
5079
+ // This will reduce the number of tree-shaking passes by eagerly
5080
+ // including inits. By pushing this here instead of directly including
5081
+ // we avoid deep call stacks.
5082
+ this.module.scope.context.newlyIncludedVariableInits.add(this.init);
5083
+ }
5084
+ super.includePath(path, context);
4878
5085
  for (const declaration of this.declarations) {
4879
5086
  // If node is a default export, it can save a tree-shaking run to include the full declaration now
4880
5087
  if (!declaration.included)
4881
- declaration.include(createInclusionContext(), false);
5088
+ declaration.include(context, false);
4882
5089
  let node = declaration.parent;
4883
5090
  while (!node.included) {
4884
5091
  // We do not want to properly include parents in case they are part of a dead branch
4885
5092
  // in which case .include() might pull in more dead code
4886
- node.included = true;
5093
+ node.includeNode(context);
4887
5094
  if (node.type === Program$1)
4888
5095
  break;
4889
5096
  node = node.parent;
4890
5097
  }
4891
5098
  }
5099
+ // We need to make sure we include the correct path of the init
5100
+ if (path.length > 0) {
5101
+ this.init.includePath(limitConcatenatedPathDepth(this.initPath, path), context);
5102
+ this.additionalInitializers?.forEach(initializer => initializer.includePath(UNKNOWN_PATH, context));
5103
+ }
4892
5104
  }
4893
5105
  }
4894
- includeCallArguments(context, parameters) {
4895
- if (this.isReassigned || context.includedCallArguments.has(this.init)) {
4896
- for (const argument of parameters) {
4897
- argument.include(context, false);
5106
+ includeCallArguments(context, interaction) {
5107
+ if (this.isReassigned ||
5108
+ context.includedCallArguments.has(this.init) ||
5109
+ // This can be removed again once we can include arguments when called at
5110
+ // a specific path
5111
+ this.initPath.length > 0) {
5112
+ for (const argument of interaction.args) {
5113
+ if (argument) {
5114
+ argument.includePath(UNKNOWN_PATH, context);
5115
+ argument.include(context, false);
5116
+ }
4898
5117
  }
4899
5118
  }
4900
5119
  else {
4901
5120
  context.includedCallArguments.add(this.init);
4902
- this.init.includeCallArguments(context, parameters);
5121
+ this.init.includeCallArguments(context, interaction);
4903
5122
  context.includedCallArguments.delete(this.init);
4904
5123
  }
4905
5124
  }
@@ -4979,18 +5198,31 @@ class IdentifierBase extends NodeBase {
4979
5198
  }
4980
5199
  }
4981
5200
  }
4982
- include() {
5201
+ include(context) {
5202
+ if (!this.included)
5203
+ this.includeNode(context);
5204
+ }
5205
+ includeNode(context) {
5206
+ this.included = true;
4983
5207
  if (!this.deoptimized)
4984
5208
  this.applyDeoptimizations();
5209
+ if (this.variable !== null) {
5210
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
5211
+ }
5212
+ }
5213
+ includePath(path, context) {
4985
5214
  if (!this.included) {
4986
5215
  this.included = true;
4987
5216
  if (this.variable !== null) {
4988
- this.scope.context.includeVariableInModule(this.variable);
5217
+ this.scope.context.includeVariableInModule(this.variable, path, context);
4989
5218
  }
4990
5219
  }
5220
+ else if (path.length > 0) {
5221
+ this.variable?.includePath(path, context);
5222
+ }
4991
5223
  }
4992
- includeCallArguments(context, parameters) {
4993
- this.variable.includeCallArguments(context, parameters);
5224
+ includeCallArguments(context, interaction) {
5225
+ this.variable.includeCallArguments(context, interaction);
4994
5226
  }
4995
5227
  isPossibleTDZ() {
4996
5228
  // return cached value to avoid issues with the next tree-shaking pass
@@ -5073,11 +5305,40 @@ function closestParentFunctionOrProgram(node) {
5073
5305
  return node;
5074
5306
  }
5075
5307
 
5308
+ class ObjectMember extends ExpressionEntity {
5309
+ constructor(object, path) {
5310
+ super();
5311
+ this.object = object;
5312
+ this.path = path;
5313
+ }
5314
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
5315
+ this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.path, ...path], recursionTracker);
5316
+ }
5317
+ deoptimizePath(path) {
5318
+ this.object.deoptimizePath([...this.path, ...path]);
5319
+ }
5320
+ getLiteralValueAtPath(path, recursionTracker, origin) {
5321
+ return this.object.getLiteralValueAtPath([...this.path, ...path], recursionTracker, origin);
5322
+ }
5323
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
5324
+ return this.object.getReturnExpressionWhenCalledAtPath([...this.path, ...path], interaction, recursionTracker, origin);
5325
+ }
5326
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
5327
+ return this.object.hasEffectsOnInteractionAtPath([...this.path, ...path], interaction, context);
5328
+ }
5329
+ }
5330
+
5076
5331
  class Identifier extends IdentifierBase {
5077
5332
  constructor() {
5078
5333
  super(...arguments);
5079
5334
  this.variable = null;
5080
5335
  }
5336
+ get isDestructuringDeoptimized() {
5337
+ return isFlagSet(this.flags, 16777216 /* Flag.destructuringDeoptimized */);
5338
+ }
5339
+ set isDestructuringDeoptimized(value) {
5340
+ this.flags = setFlag(this.flags, 16777216 /* Flag.destructuringDeoptimized */, value);
5341
+ }
5081
5342
  addExportedVariables(variables, exportNamesByVariable) {
5082
5343
  if (exportNamesByVariable.has(this.variable)) {
5083
5344
  variables.push(this.variable);
@@ -5089,44 +5350,54 @@ class Identifier extends IdentifierBase {
5089
5350
  this.variable.addReference(this);
5090
5351
  this.isVariableReference = true;
5091
5352
  }
5092
- }
5093
- declare(kind, init) {
5094
- let variable;
5095
- const { treeshake } = this.scope.context.options;
5096
- switch (kind) {
5097
- case 'var': {
5098
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5099
- if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
5100
- // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
5101
- variable.markInitializersForDeoptimization();
5102
- }
5103
- break;
5104
- }
5105
- case 'function': {
5106
- // in strict mode, functions are only hoisted within a scope but not across block scopes
5107
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5108
- break;
5109
- }
5110
- case 'let':
5111
- case 'const':
5112
- case 'using':
5113
- case 'await using':
5114
- case 'class': {
5115
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5116
- break;
5117
- }
5118
- case 'parameter': {
5119
- variable = this.scope.addParameterDeclaration(this);
5120
- break;
5121
- }
5122
- /* istanbul ignore next */
5123
- default: {
5124
- /* istanbul ignore next */
5125
- throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
5353
+ }
5354
+ declare(kind, destructuredInitPath, init) {
5355
+ let variable;
5356
+ const { treeshake } = this.scope.context.options;
5357
+ if (kind === 'parameter') {
5358
+ variable = this.scope.addParameterDeclaration(this, destructuredInitPath);
5359
+ }
5360
+ else {
5361
+ variable = this.scope.addDeclaration(this, this.scope.context, init, destructuredInitPath, kind);
5362
+ if (kind === 'var' && treeshake && treeshake.correctVarValueBeforeDeclaration) {
5363
+ // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
5364
+ variable.markInitializersForDeoptimization();
5126
5365
  }
5127
5366
  }
5128
5367
  return [(this.variable = variable)];
5129
5368
  }
5369
+ deoptimizeAssignment(destructuredInitPath, init) {
5370
+ this.deoptimizePath(EMPTY_PATH);
5371
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
5372
+ }
5373
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
5374
+ return (destructuredInitPath.length > 0 &&
5375
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
5376
+ }
5377
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
5378
+ if (destructuredInitPath.length > 0 && !this.isDestructuringDeoptimized) {
5379
+ this.isDestructuringDeoptimized = true;
5380
+ init.deoptimizeArgumentsOnInteractionAtPath({
5381
+ args: [new ObjectMember(init, destructuredInitPath.slice(0, -1))],
5382
+ type: INTERACTION_ACCESSED
5383
+ }, destructuredInitPath, SHARED_RECURSION_TRACKER);
5384
+ }
5385
+ const { propertyReadSideEffects } = this.scope.context.options
5386
+ .treeshake;
5387
+ if ((this.included ||=
5388
+ destructuredInitPath.length > 0 &&
5389
+ !context.brokenFlow &&
5390
+ propertyReadSideEffects &&
5391
+ (propertyReadSideEffects === 'always' ||
5392
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext())))) {
5393
+ if (this.variable && !this.variable.included) {
5394
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
5395
+ }
5396
+ init.includePath(destructuredInitPath, context);
5397
+ return true;
5398
+ }
5399
+ return false;
5400
+ }
5130
5401
  markDeclarationReached() {
5131
5402
  this.variable.initReached = true;
5132
5403
  }
@@ -5191,18 +5462,17 @@ class Scope {
5191
5462
  - then the variable is still declared in the hoisted outer scope, but the initializer is assigned to the parameter
5192
5463
  - const, let, class, and function except in the cases above cannot redeclare anything
5193
5464
  */
5194
- addDeclaration(identifier, context, init, kind) {
5465
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5195
5466
  const name = identifier.name;
5196
5467
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
5197
5468
  if (existingVariable) {
5198
- const existingKind = existingVariable.kind;
5199
- if (kind === 'var' && existingKind === 'var') {
5469
+ if (kind === 'var' && existingVariable.kind === 'var') {
5200
5470
  existingVariable.addDeclaration(identifier, init);
5201
5471
  return existingVariable;
5202
5472
  }
5203
5473
  context.error(logRedeclarationError(name), identifier.start);
5204
5474
  }
5205
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
5475
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
5206
5476
  this.variables.set(name, newVariable);
5207
5477
  return newVariable;
5208
5478
  }
@@ -5378,7 +5648,6 @@ class MethodBase extends NodeBase {
5378
5648
  }
5379
5649
  return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context);
5380
5650
  }
5381
- applyDeoptimizations() { }
5382
5651
  getAccessedValue() {
5383
5652
  if (this.accessedValue === null) {
5384
5653
  if (this.kind === 'get') {
@@ -5392,19 +5661,20 @@ class MethodBase extends NodeBase {
5392
5661
  return this.accessedValue;
5393
5662
  }
5394
5663
  }
5664
+ MethodBase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
5665
+ MethodBase.prototype.applyDeoptimizations = doNotDeoptimize;
5395
5666
 
5396
5667
  class MethodDefinition extends MethodBase {
5397
5668
  hasEffects(context) {
5398
5669
  return super.hasEffects(context) || checkEffectForNodes(this.decorators, context);
5399
5670
  }
5400
- applyDeoptimizations() { }
5401
5671
  }
5402
5672
 
5403
5673
  class BlockScope extends ChildScope {
5404
5674
  constructor(parent) {
5405
5675
  super(parent, parent.context);
5406
5676
  }
5407
- addDeclaration(identifier, context, init, kind) {
5677
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5408
5678
  if (kind === 'var') {
5409
5679
  const name = identifier.name;
5410
5680
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -5416,7 +5686,7 @@ class BlockScope extends ChildScope {
5416
5686
  }
5417
5687
  return context.error(logRedeclarationError(name), identifier.start);
5418
5688
  }
5419
- const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind);
5689
+ const declaredVariable = this.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5420
5690
  // Necessary to make sure the init is deoptimized for conditional declarations.
5421
5691
  // We cannot call deoptimizePath here.
5422
5692
  declaredVariable.markInitializersForDeoptimization();
@@ -5424,7 +5694,7 @@ class BlockScope extends ChildScope {
5424
5694
  this.addHoistedVariable(name, declaredVariable);
5425
5695
  return declaredVariable;
5426
5696
  }
5427
- return super.addDeclaration(identifier, context, init, kind);
5697
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5428
5698
  }
5429
5699
  }
5430
5700
 
@@ -5456,33 +5726,12 @@ class StaticBlock extends NodeBase {
5456
5726
  }
5457
5727
  }
5458
5728
  }
5729
+ StaticBlock.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
5730
+ StaticBlock.prototype.applyDeoptimizations = doNotDeoptimize;
5459
5731
  function isStaticBlock(statement) {
5460
5732
  return statement.type === StaticBlock$1;
5461
5733
  }
5462
5734
 
5463
- class ObjectMember extends ExpressionEntity {
5464
- constructor(object, key) {
5465
- super();
5466
- this.object = object;
5467
- this.key = key;
5468
- }
5469
- deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
5470
- this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker);
5471
- }
5472
- deoptimizePath(path) {
5473
- this.object.deoptimizePath([this.key, ...path]);
5474
- }
5475
- getLiteralValueAtPath(path, recursionTracker, origin) {
5476
- return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin);
5477
- }
5478
- getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
5479
- return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin);
5480
- }
5481
- hasEffectsOnInteractionAtPath(path, interaction, context) {
5482
- return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context);
5483
- }
5484
- }
5485
-
5486
5735
  class ClassNode extends NodeBase {
5487
5736
  constructor() {
5488
5737
  super(...arguments);
@@ -5523,21 +5772,20 @@ class ClassNode extends NodeBase {
5523
5772
  : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
5524
5773
  }
5525
5774
  include(context, includeChildrenRecursively) {
5526
- if (!this.deoptimized)
5527
- this.applyDeoptimizations();
5528
- this.included = true;
5775
+ if (!this.included)
5776
+ this.includeNode(context);
5529
5777
  this.superClass?.include(context, includeChildrenRecursively);
5530
5778
  this.body.include(context, includeChildrenRecursively);
5531
5779
  for (const decorator of this.decorators)
5532
5780
  decorator.include(context, includeChildrenRecursively);
5533
5781
  if (this.id) {
5534
5782
  this.id.markDeclarationReached();
5535
- this.id.include();
5783
+ this.id.include(context);
5536
5784
  }
5537
5785
  }
5538
5786
  initialise() {
5539
5787
  super.initialise();
5540
- this.id?.declare('class', this);
5788
+ this.id?.declare('class', EMPTY_PATH, this);
5541
5789
  for (const method of this.body.body) {
5542
5790
  if (method instanceof MethodDefinition && method.kind === 'constructor') {
5543
5791
  this.classConstructor = method;
@@ -5595,11 +5843,12 @@ class ClassNode extends NodeBase {
5595
5843
  staticProperties.unshift({
5596
5844
  key: 'prototype',
5597
5845
  kind: 'init',
5598
- property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE)
5846
+ property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, ['prototype']) : OBJECT_PROTOTYPE)
5599
5847
  });
5600
5848
  return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE));
5601
5849
  }
5602
5850
  }
5851
+ ClassNode.prototype.includeNode = onlyIncludeSelf;
5603
5852
 
5604
5853
  class ClassDeclaration extends ClassNode {
5605
5854
  initialise() {
@@ -5652,53 +5901,60 @@ class ClassDeclaration extends ClassNode {
5652
5901
 
5653
5902
  class ArgumentsVariable extends LocalVariable {
5654
5903
  constructor(context) {
5655
- super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');
5656
- this.deoptimizedArguments = [];
5904
+ super('arguments', null, UNKNOWN_EXPRESSION, EMPTY_PATH, context, 'other');
5657
5905
  }
5658
- addArgumentToBeDeoptimized(argument) {
5659
- if (this.included) {
5660
- argument.deoptimizePath(UNKNOWN_PATH);
5661
- }
5662
- else {
5663
- this.deoptimizedArguments.push(argument);
5664
- }
5906
+ addArgumentToBeDeoptimized(_argument) { }
5907
+ // Only If there is at least one reference, then we need to track all
5908
+ // arguments in order to be able to deoptimize them.
5909
+ addReference() {
5910
+ this.deoptimizedArguments = [];
5911
+ this.addArgumentToBeDeoptimized = addArgumentToBeDeoptimized;
5665
5912
  }
5666
5913
  hasEffectsOnInteractionAtPath(path, { type }) {
5667
5914
  return type !== INTERACTION_ACCESSED || path.length > 1;
5668
5915
  }
5669
- include() {
5670
- super.include();
5916
+ includePath(path, context) {
5917
+ super.includePath(path, context);
5671
5918
  for (const argument of this.deoptimizedArguments) {
5672
5919
  argument.deoptimizePath(UNKNOWN_PATH);
5673
5920
  }
5674
5921
  this.deoptimizedArguments.length = 0;
5675
5922
  }
5676
5923
  }
5924
+ function addArgumentToBeDeoptimized(argument) {
5925
+ if (this.included) {
5926
+ argument.deoptimizePath(UNKNOWN_PATH);
5927
+ }
5928
+ else {
5929
+ this.deoptimizedArguments?.push(argument);
5930
+ }
5931
+ }
5677
5932
 
5678
5933
  const MAX_TRACKED_INTERACTIONS = 20;
5679
5934
  const NO_INTERACTIONS = EMPTY_ARRAY;
5680
5935
  const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);
5681
- const EMPTY_PATH_TRACKER = new PathTracker();
5936
+ const EMPTY_PATH_TRACKER = new EntityPathTracker();
5682
5937
  const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);
5683
5938
  class ParameterVariable extends LocalVariable {
5684
- constructor(name, declarator, context) {
5685
- super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');
5939
+ constructor(name, declarator, argumentPath, context) {
5940
+ super(name, declarator, UNKNOWN_EXPRESSION, argumentPath, context, 'parameter');
5941
+ this.includedPathTracker = new IncludedTopLevelPathTracker();
5942
+ this.argumentsToBeDeoptimized = new Set();
5686
5943
  this.deoptimizationInteractions = [];
5687
- this.deoptimizations = new PathTracker();
5944
+ this.deoptimizations = new EntityPathTracker();
5688
5945
  this.deoptimizedFields = new Set();
5689
- this.entitiesToBeDeoptimized = new Set();
5690
- this.expressionsUseTheKnownValue = [];
5946
+ this.expressionsDependingOnKnownValue = [];
5691
5947
  this.knownValue = null;
5692
5948
  this.knownValueLiteral = UnknownValue;
5693
- this.frozenValue = null;
5694
5949
  }
5695
- addEntityToBeDeoptimized(entity) {
5950
+ addArgumentValue(entity) {
5951
+ this.updateKnownValue(entity);
5696
5952
  if (entity === UNKNOWN_EXPRESSION) {
5697
5953
  // As unknown expressions fully deoptimize all interactions, we can clear
5698
5954
  // the interaction cache at this point provided we keep this optimization
5699
5955
  // in mind when adding new interactions
5700
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5701
- this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);
5956
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5957
+ this.argumentsToBeDeoptimized.add(UNKNOWN_EXPRESSION);
5702
5958
  for (const { interaction } of this.deoptimizationInteractions) {
5703
5959
  deoptimizeInteraction(interaction);
5704
5960
  }
@@ -5708,27 +5964,30 @@ class ParameterVariable extends LocalVariable {
5708
5964
  else if (this.deoptimizedFields.has(UnknownKey)) {
5709
5965
  // This means that we already deoptimized all interactions and no longer
5710
5966
  // track them
5711
- entity.deoptimizePath(UNKNOWN_PATH);
5967
+ entity.deoptimizePath([...this.initPath, UnknownKey]);
5712
5968
  }
5713
- else if (!this.entitiesToBeDeoptimized.has(entity)) {
5714
- this.entitiesToBeDeoptimized.add(entity);
5969
+ else if (!this.argumentsToBeDeoptimized.has(entity)) {
5970
+ this.argumentsToBeDeoptimized.add(entity);
5715
5971
  for (const field of this.deoptimizedFields) {
5716
- entity.deoptimizePath([field]);
5972
+ entity.deoptimizePath([...this.initPath, field]);
5717
5973
  }
5718
5974
  for (const { interaction, path } of this.deoptimizationInteractions) {
5719
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
5975
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
5720
5976
  }
5721
5977
  }
5722
5978
  }
5979
+ /** This says we should not make assumptions about the value of the parameter.
5980
+ * This is different from deoptimization that will also cause argument values
5981
+ * to be deoptimized. */
5723
5982
  markReassigned() {
5724
5983
  if (this.isReassigned) {
5725
5984
  return;
5726
5985
  }
5727
5986
  super.markReassigned();
5728
- for (const expression of this.expressionsUseTheKnownValue) {
5987
+ for (const expression of this.expressionsDependingOnKnownValue) {
5729
5988
  expression.deoptimizeCache();
5730
5989
  }
5731
- this.expressionsUseTheKnownValue = EMPTY_ARRAY;
5990
+ this.expressionsDependingOnKnownValue = EMPTY_ARRAY;
5732
5991
  }
5733
5992
  deoptimizeCache() {
5734
5993
  this.markReassigned();
@@ -5745,7 +6004,7 @@ class ParameterVariable extends LocalVariable {
5745
6004
  }
5746
6005
  if (this.knownValue === null) {
5747
6006
  this.knownValue = argument;
5748
- this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
6007
+ this.knownValueLiteral = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
5749
6008
  return;
5750
6009
  }
5751
6010
  // the same literal or identifier, do nothing
@@ -5755,14 +6014,10 @@ class ParameterVariable extends LocalVariable {
5755
6014
  this.knownValue.variable === argument.variable)) {
5756
6015
  return;
5757
6016
  }
5758
- const oldValue = this.knownValueLiteral;
5759
- if (typeof oldValue === 'symbol') {
5760
- this.markReassigned();
5761
- return;
5762
- }
5763
- // add tracking for the new argument
5764
- const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
5765
- if (newValue !== oldValue) {
6017
+ const { knownValueLiteral } = this;
6018
+ if (typeof knownValueLiteral === 'symbol' ||
6019
+ argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this) !==
6020
+ knownValueLiteral) {
5766
6021
  this.markReassigned();
5767
6022
  }
5768
6023
  }
@@ -5773,42 +6028,47 @@ class ParameterVariable extends LocalVariable {
5773
6028
  * @returns the frozen value
5774
6029
  */
5775
6030
  getKnownValue() {
5776
- if (this.frozenValue === null) {
5777
- this.frozenValue = this.knownValue || UNKNOWN_EXPRESSION;
5778
- }
5779
- return this.frozenValue;
6031
+ return this.knownValue || UNKNOWN_EXPRESSION;
5780
6032
  }
5781
6033
  getLiteralValueAtPath(path, recursionTracker, origin) {
5782
- if (this.isReassigned) {
6034
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
5783
6035
  return UnknownValue;
5784
6036
  }
5785
6037
  const knownValue = this.getKnownValue();
5786
- this.expressionsUseTheKnownValue.push(origin);
5787
- return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);
6038
+ this.expressionsDependingOnKnownValue.push(origin);
6039
+ return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin), UnknownValue);
5788
6040
  }
5789
6041
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5790
- if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) {
6042
+ const { type } = interaction;
6043
+ if (this.isReassigned ||
6044
+ type === INTERACTION_ASSIGNED ||
6045
+ path.length + this.initPath.length > MAX_PATH_DEPTH) {
5791
6046
  return super.hasEffectsOnInteractionAtPath(path, interaction, context);
5792
6047
  }
5793
- const knownValue = this.getKnownValue();
5794
- return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context);
6048
+ return (!(type === INTERACTION_CALLED
6049
+ ? (interaction.withNew
6050
+ ? context.instantiated
6051
+ : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)
6052
+ : context.accessed.trackEntityAtPathAndGetIfTracked(path, this)) &&
6053
+ this.getKnownValue().hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
5795
6054
  }
5796
6055
  deoptimizeArgumentsOnInteractionAtPath(interaction, path) {
5797
6056
  // For performance reasons, we fully deoptimize all deeper interactions
5798
6057
  if (path.length >= 2 ||
5799
- this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
6058
+ this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
5800
6059
  this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||
5801
6060
  (path.length === 1 &&
5802
6061
  (this.deoptimizedFields.has(UnknownKey) ||
5803
- (interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0]))))) {
6062
+ (interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0])))) ||
6063
+ this.initPath.length + path.length > MAX_PATH_DEPTH) {
5804
6064
  deoptimizeInteraction(interaction);
5805
6065
  return;
5806
6066
  }
5807
6067
  if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {
5808
- for (const entity of this.entitiesToBeDeoptimized) {
5809
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
6068
+ for (const entity of this.argumentsToBeDeoptimized) {
6069
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
5810
6070
  }
5811
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
6071
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5812
6072
  this.deoptimizationInteractions.push({
5813
6073
  interaction,
5814
6074
  path
@@ -5829,17 +6089,17 @@ class ParameterVariable extends LocalVariable {
5829
6089
  return;
5830
6090
  }
5831
6091
  this.deoptimizedFields.add(key);
5832
- for (const entity of this.entitiesToBeDeoptimized) {
6092
+ for (const entity of this.argumentsToBeDeoptimized) {
5833
6093
  // We do not need a recursion tracker here as we already track whether
5834
6094
  // this field is deoptimized
5835
- entity.deoptimizePath([key]);
6095
+ entity.deoptimizePath([...this.initPath, key]);
5836
6096
  }
5837
6097
  if (key === UnknownKey) {
5838
6098
  // save some memory
5839
6099
  this.deoptimizationInteractions = NO_INTERACTIONS;
5840
6100
  this.deoptimizations = EMPTY_PATH_TRACKER;
5841
6101
  this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;
5842
- this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
6102
+ this.argumentsToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
5843
6103
  }
5844
6104
  }
5845
6105
  getReturnExpressionWhenCalledAtPath(path) {
@@ -5854,11 +6114,14 @@ class ParameterVariable extends LocalVariable {
5854
6114
  }
5855
6115
  return UNKNOWN_RETURN_EXPRESSION;
5856
6116
  }
6117
+ includeArgumentPaths(entity, context) {
6118
+ this.includedPathTracker.includeAllPaths(entity, context, this.initPath);
6119
+ }
5857
6120
  }
5858
6121
 
5859
6122
  class ThisVariable extends ParameterVariable {
5860
6123
  constructor(context) {
5861
- super('this', null, context);
6124
+ super('this', null, EMPTY_PATH, context);
5862
6125
  }
5863
6126
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5864
6127
  return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);
@@ -5870,7 +6133,7 @@ class CatchBodyScope extends ChildScope {
5870
6133
  super(parent, parent.context);
5871
6134
  this.parent = parent;
5872
6135
  }
5873
- addDeclaration(identifier, context, init, kind) {
6136
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5874
6137
  if (kind === 'var') {
5875
6138
  const name = identifier.name;
5876
6139
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -5883,7 +6146,7 @@ class CatchBodyScope extends ChildScope {
5883
6146
  // the assignment actually goes to the parameter and the var is
5884
6147
  // hoisted without assignment. Locally, it is shadowed by the
5885
6148
  // parameter
5886
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, kind);
6149
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, destructuredInitPath, kind);
5887
6150
  // To avoid the need to rewrite the declaration, we link the variable
5888
6151
  // names. If we ever implement a logic that splits initialization and
5889
6152
  // assignment for hoisted vars, the "renderLikeHoisted" logic can be
@@ -5902,7 +6165,7 @@ class CatchBodyScope extends ChildScope {
5902
6165
  return context.error(logRedeclarationError(name), identifier.start);
5903
6166
  }
5904
6167
  // We only add parameters to parameter scopes
5905
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, kind);
6168
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5906
6169
  // Necessary to make sure the init is deoptimized for conditional declarations.
5907
6170
  // We cannot call deoptimizePath here.
5908
6171
  declaredVariable.markInitializersForDeoptimization();
@@ -5910,7 +6173,7 @@ class CatchBodyScope extends ChildScope {
5910
6173
  this.addHoistedVariable(name, declaredVariable);
5911
6174
  return declaredVariable;
5912
6175
  }
5913
- return super.addDeclaration(identifier, context, init, kind);
6176
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5914
6177
  }
5915
6178
  }
5916
6179
 
@@ -5920,7 +6183,7 @@ class FunctionBodyScope extends ChildScope {
5920
6183
  }
5921
6184
  // There is stuff that is only allowed in function scopes, i.e. functions can
5922
6185
  // be redeclared, functions and var can redeclare each other
5923
- addDeclaration(identifier, context, init, kind) {
6186
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5924
6187
  const name = identifier.name;
5925
6188
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
5926
6189
  if (existingVariable) {
@@ -5932,7 +6195,7 @@ class FunctionBodyScope extends ChildScope {
5932
6195
  }
5933
6196
  context.error(logRedeclarationError(name), identifier.start);
5934
6197
  }
5935
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
6198
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
5936
6199
  this.variables.set(name, newVariable);
5937
6200
  return newVariable;
5938
6201
  }
@@ -5941,21 +6204,21 @@ class FunctionBodyScope extends ChildScope {
5941
6204
  class ParameterScope extends ChildScope {
5942
6205
  constructor(parent, isCatchScope) {
5943
6206
  super(parent, parent.context);
5944
- this.parameters = [];
5945
6207
  this.hasRest = false;
6208
+ this.parameters = [];
5946
6209
  this.bodyScope = isCatchScope ? new CatchBodyScope(this) : new FunctionBodyScope(this);
5947
6210
  }
5948
6211
  /**
5949
6212
  * Adds a parameter to this scope. Parameters must be added in the correct
5950
6213
  * order, i.e. from left to right.
5951
6214
  */
5952
- addParameterDeclaration(identifier) {
6215
+ addParameterDeclaration(identifier, argumentPath) {
5953
6216
  const { name, start } = identifier;
5954
6217
  const existingParameter = this.variables.get(name);
5955
6218
  if (existingParameter) {
5956
6219
  return this.context.error(logDuplicateArgumentNameError(name), start);
5957
6220
  }
5958
- const variable = new ParameterVariable(name, identifier, this.context);
6221
+ const variable = new ParameterVariable(name, identifier, argumentPath, this.context);
5959
6222
  this.variables.set(name, variable);
5960
6223
  // We also add it to the body scope to detect name conflicts with local
5961
6224
  // variables. We still need the intermediate scope, though, as parameter
@@ -5973,42 +6236,56 @@ class ParameterScope extends ChildScope {
5973
6236
  }
5974
6237
  this.hasRest = hasRest;
5975
6238
  }
5976
- includeCallArguments(context, parameters) {
6239
+ includeCallArguments(context, interaction) {
5977
6240
  let calledFromTryStatement = false;
5978
6241
  let argumentIncluded = false;
5979
6242
  const restParameter = this.hasRest && this.parameters[this.parameters.length - 1];
5980
- for (const checkedArgument of parameters) {
5981
- if (checkedArgument instanceof SpreadElement) {
5982
- for (const argument of parameters) {
5983
- argument.include(context, false);
5984
- }
5985
- break;
6243
+ const { args } = interaction;
6244
+ let lastExplicitlyIncludedIndex = args.length - 1;
6245
+ // If there is a SpreadElement, we need to include all arguments after it
6246
+ // because we no longer know which argument corresponds to which parameter.
6247
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
6248
+ const argument = args[argumentIndex];
6249
+ if (argument instanceof SpreadElement && !argumentIncluded) {
6250
+ argumentIncluded = true;
6251
+ lastExplicitlyIncludedIndex = argumentIndex - 1;
6252
+ }
6253
+ if (argumentIncluded) {
6254
+ argument.includePath(UNKNOWN_PATH, context);
6255
+ argument.include(context, false);
5986
6256
  }
5987
6257
  }
5988
- for (let index = parameters.length - 1; index >= 0; index--) {
5989
- const parameterVariables = this.parameters[index] || restParameter;
5990
- const argument = parameters[index];
6258
+ // Now we go backwards either starting from the last argument or before the
6259
+ // first SpreadElement to ensure all arguments before are included as needed
6260
+ for (let index = lastExplicitlyIncludedIndex; index >= 1; index--) {
6261
+ const parameterVariables = this.parameters[index - 1] || restParameter;
6262
+ const argument = args[index];
5991
6263
  if (parameterVariables) {
5992
6264
  calledFromTryStatement = false;
5993
6265
  if (parameterVariables.length === 0) {
5994
- // handle empty destructuring
6266
+ // handle empty destructuring to avoid destructuring undefined
5995
6267
  argumentIncluded = true;
5996
6268
  }
5997
6269
  else {
5998
- for (const variable of parameterVariables) {
5999
- if (variable.included) {
6000
- argumentIncluded = true;
6001
- }
6002
- if (variable.calledFromTryStatement) {
6270
+ for (const parameterVariable of parameterVariables) {
6271
+ if (parameterVariable.calledFromTryStatement) {
6003
6272
  calledFromTryStatement = true;
6004
6273
  }
6274
+ if (parameterVariable.included) {
6275
+ argumentIncluded = true;
6276
+ if (calledFromTryStatement) {
6277
+ argument.include(context, true);
6278
+ }
6279
+ else {
6280
+ parameterVariable.includeArgumentPaths(argument, context);
6281
+ argument.include(context, false);
6282
+ }
6283
+ }
6005
6284
  }
6006
6285
  }
6007
6286
  }
6008
- if (!argumentIncluded && argument.shouldBeIncluded(context)) {
6287
+ if (!argument.included && (argumentIncluded || argument.shouldBeIncluded(context))) {
6009
6288
  argumentIncluded = true;
6010
- }
6011
- if (argumentIncluded) {
6012
6289
  argument.include(context, calledFromTryStatement);
6013
6290
  }
6014
6291
  }
@@ -6024,11 +6301,62 @@ class ReturnValueScope extends ParameterScope {
6024
6301
  addReturnExpression(expression) {
6025
6302
  this.returnExpressions.push(expression);
6026
6303
  }
6304
+ deoptimizeArgumentsOnCall(interaction) {
6305
+ const { parameters } = this;
6306
+ const { args } = interaction;
6307
+ let position = 0;
6308
+ for (; position < args.length - 1; position++) {
6309
+ // Only the "this" argument arg[0] can be null
6310
+ const argument = args[position + 1];
6311
+ if (argument instanceof SpreadElement) {
6312
+ // This deoptimizes the current and remaining parameters and arguments
6313
+ for (; position < parameters.length; position++) {
6314
+ args[position + 1]?.deoptimizePath(UNKNOWN_PATH);
6315
+ parameters[position].forEach(variable => variable.markReassigned());
6316
+ }
6317
+ break;
6318
+ }
6319
+ if (this.hasRest && position >= parameters.length - 1) {
6320
+ argument.deoptimizePath(UNKNOWN_PATH);
6321
+ }
6322
+ else {
6323
+ const variables = parameters[position];
6324
+ if (variables) {
6325
+ for (const variable of variables) {
6326
+ variable.addArgumentValue(argument);
6327
+ }
6328
+ }
6329
+ this.addArgumentToBeDeoptimized(argument);
6330
+ }
6331
+ }
6332
+ const nonRestParameterLength = this.hasRest ? parameters.length - 1 : parameters.length;
6333
+ for (; position < nonRestParameterLength; position++) {
6334
+ for (const variable of parameters[position]) {
6335
+ variable.addArgumentValue(UNDEFINED_EXPRESSION);
6336
+ }
6337
+ }
6338
+ }
6027
6339
  getReturnExpression() {
6028
6340
  if (this.returnExpression === null)
6029
6341
  this.updateReturnExpression();
6030
6342
  return this.returnExpression;
6031
6343
  }
6344
+ deoptimizeAllParameters() {
6345
+ for (const parameter of this.parameters) {
6346
+ for (const variable of parameter) {
6347
+ variable.deoptimizePath(UNKNOWN_PATH);
6348
+ variable.markReassigned();
6349
+ }
6350
+ }
6351
+ }
6352
+ reassignAllParameters() {
6353
+ for (const parameter of this.parameters) {
6354
+ for (const variable of parameter) {
6355
+ variable.markReassigned();
6356
+ }
6357
+ }
6358
+ }
6359
+ addArgumentToBeDeoptimized(_argument) { }
6032
6360
  updateReturnExpression() {
6033
6361
  if (this.returnExpressions.length === 1) {
6034
6362
  this.returnExpression = this.returnExpressions[0];
@@ -6044,24 +6372,30 @@ class ReturnValueScope extends ParameterScope {
6044
6372
 
6045
6373
  class FunctionScope extends ReturnValueScope {
6046
6374
  constructor(parent) {
6047
- const { context } = parent;
6048
6375
  super(parent, false);
6376
+ const { context } = parent;
6049
6377
  this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));
6050
6378
  this.variables.set('this', (this.thisVariable = new ThisVariable(context)));
6051
6379
  }
6052
6380
  findLexicalBoundary() {
6053
6381
  return this;
6054
6382
  }
6055
- includeCallArguments(context, parameters) {
6056
- super.includeCallArguments(context, parameters);
6383
+ includeCallArguments(context, interaction) {
6384
+ super.includeCallArguments(context, interaction);
6057
6385
  if (this.argumentsVariable.included) {
6058
- for (const argument of parameters) {
6059
- if (!argument.included) {
6386
+ const { args } = interaction;
6387
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
6388
+ const argument = args[argumentIndex];
6389
+ if (argument) {
6390
+ argument.includePath(UNKNOWN_PATH, context);
6060
6391
  argument.include(context, false);
6061
6392
  }
6062
6393
  }
6063
6394
  }
6064
6395
  }
6396
+ addArgumentToBeDeoptimized(argument) {
6397
+ this.argumentsVariable.addArgumentToBeDeoptimized(argument);
6398
+ }
6065
6399
  }
6066
6400
 
6067
6401
  class ExpressionStatement extends NodeBase {
@@ -6089,8 +6423,9 @@ class ExpressionStatement extends NodeBase {
6089
6423
  return this.parent.type !== Program$1;
6090
6424
  return super.shouldBeIncluded(context);
6091
6425
  }
6092
- applyDeoptimizations() { }
6093
6426
  }
6427
+ ExpressionStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
6428
+ ExpressionStatement.prototype.applyDeoptimizations = doNotDeoptimize;
6094
6429
 
6095
6430
  class BlockStatement extends NodeBase {
6096
6431
  get deoptimizeBody() {
@@ -6155,6 +6490,8 @@ class BlockStatement extends NodeBase {
6155
6490
  }
6156
6491
  }
6157
6492
  }
6493
+ BlockStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
6494
+ BlockStatement.prototype.applyDeoptimizations = doNotDeoptimize;
6158
6495
 
6159
6496
  class RestElement extends NodeBase {
6160
6497
  constructor() {
@@ -6164,9 +6501,12 @@ class RestElement extends NodeBase {
6164
6501
  addExportedVariables(variables, exportNamesByVariable) {
6165
6502
  this.argument.addExportedVariables(variables, exportNamesByVariable);
6166
6503
  }
6167
- declare(kind, init) {
6504
+ declare(kind, destructuredInitPath, init) {
6168
6505
  this.declarationInit = init;
6169
- return this.argument.declare(kind, UNKNOWN_EXPRESSION);
6506
+ return this.argument.declare(kind, getIncludedPatternPath$1(destructuredInitPath), init);
6507
+ }
6508
+ deoptimizeAssignment(destructuredInitPath, init) {
6509
+ this.argument.deoptimizeAssignment(getIncludedPatternPath$1(destructuredInitPath), init);
6170
6510
  }
6171
6511
  deoptimizePath(path) {
6172
6512
  if (path.length === 0) {
@@ -6177,6 +6517,20 @@ class RestElement extends NodeBase {
6177
6517
  return (path.length > 0 ||
6178
6518
  this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
6179
6519
  }
6520
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
6521
+ return this.argument.hasEffectsWhenDestructuring(context, getIncludedPatternPath$1(destructuredInitPath), init);
6522
+ }
6523
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
6524
+ return (this.included =
6525
+ this.argument.includeDestructuredIfNecessary(context, getIncludedPatternPath$1(destructuredInitPath), init) || this.included);
6526
+ }
6527
+ include(context, includeChildrenRecursively) {
6528
+ if (!this.included)
6529
+ this.includeNode(context);
6530
+ // This should just include the identifier, its properties should be
6531
+ // included where the variable is used.
6532
+ this.argument.include(context, includeChildrenRecursively);
6533
+ }
6180
6534
  markDeclarationReached() {
6181
6535
  this.argument.markDeclarationReached();
6182
6536
  }
@@ -6188,12 +6542,16 @@ class RestElement extends NodeBase {
6188
6542
  }
6189
6543
  }
6190
6544
  }
6545
+ RestElement.prototype.includeNode = onlyIncludeSelf;
6546
+ const getIncludedPatternPath$1 = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
6547
+ ? destructuredInitPath
6548
+ : [...destructuredInitPath, UnknownKey];
6191
6549
 
6192
6550
  class FunctionBase extends NodeBase {
6193
6551
  constructor() {
6194
6552
  super(...arguments);
6195
- this.objectEntity = null;
6196
6553
  this.parameterVariableValuesDeoptimized = false;
6554
+ this.includeCallArguments = this.scope.includeCallArguments.bind(this.scope);
6197
6555
  }
6198
6556
  get async() {
6199
6557
  return isFlagSet(this.flags, 256 /* Flag.async */);
@@ -6213,53 +6571,15 @@ class FunctionBase extends NodeBase {
6213
6571
  set generator(value) {
6214
6572
  this.flags = setFlag(this.flags, 4194304 /* Flag.generator */, value);
6215
6573
  }
6216
- updateParameterVariableValues(_arguments) {
6217
- for (let position = 0; position < this.params.length; position++) {
6218
- const parameter = this.params[position];
6219
- if (!(parameter instanceof Identifier)) {
6220
- continue;
6221
- }
6222
- const parameterVariable = parameter.variable;
6223
- const argument = _arguments[position + 1] ?? UNDEFINED_EXPRESSION;
6224
- parameterVariable.updateKnownValue(argument);
6225
- }
6574
+ get hasCachedEffects() {
6575
+ return isFlagSet(this.flags, 67108864 /* Flag.hasEffects */);
6226
6576
  }
6227
- deoptimizeParameterVariableValues() {
6228
- for (const parameter of this.params) {
6229
- if (parameter instanceof Identifier) {
6230
- const parameterVariable = parameter.variable;
6231
- parameterVariable.markReassigned();
6232
- }
6233
- }
6577
+ set hasCachedEffects(value) {
6578
+ this.flags = setFlag(this.flags, 67108864 /* Flag.hasEffects */, value);
6234
6579
  }
6235
6580
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6236
- if (interaction.type === INTERACTION_CALLED) {
6237
- const { parameters } = this.scope;
6238
- const { args } = interaction;
6239
- let hasRest = false;
6240
- for (let position = 0; position < args.length - 1; position++) {
6241
- const parameter = this.params[position];
6242
- // Only the "this" argument arg[0] can be null
6243
- const argument = args[position + 1];
6244
- if (argument instanceof SpreadElement) {
6245
- this.deoptimizeParameterVariableValues();
6246
- }
6247
- if (hasRest || parameter instanceof RestElement) {
6248
- hasRest = true;
6249
- argument.deoptimizePath(UNKNOWN_PATH);
6250
- }
6251
- else if (parameter instanceof Identifier) {
6252
- parameters[position][0].addEntityToBeDeoptimized(argument);
6253
- this.addArgumentToBeDeoptimized(argument);
6254
- }
6255
- else if (parameter) {
6256
- argument.deoptimizePath(UNKNOWN_PATH);
6257
- }
6258
- else {
6259
- this.addArgumentToBeDeoptimized(argument);
6260
- }
6261
- }
6262
- this.updateParameterVariableValues(args);
6581
+ if (interaction.type === INTERACTION_CALLED && path.length === 0) {
6582
+ this.scope.deoptimizeArgumentsOnCall(interaction);
6263
6583
  }
6264
6584
  else {
6265
6585
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -6271,12 +6591,7 @@ class FunctionBase extends NodeBase {
6271
6591
  // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
6272
6592
  // which means the return expression and parameters need to be reassigned
6273
6593
  this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
6274
- for (const parameterList of this.scope.parameters) {
6275
- for (const parameter of parameterList) {
6276
- parameter.deoptimizePath(UNKNOWN_PATH);
6277
- parameter.markReassigned();
6278
- }
6279
- }
6594
+ this.scope.deoptimizeAllParameters();
6280
6595
  }
6281
6596
  }
6282
6597
  getLiteralValueAtPath(path, recursionTracker, origin) {
@@ -6300,8 +6615,8 @@ class FunctionBase extends NodeBase {
6300
6615
  if (path.length > 0 || interaction.type !== INTERACTION_CALLED) {
6301
6616
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
6302
6617
  }
6303
- if (this.annotationNoSideEffects) {
6304
- return false;
6618
+ if (this.hasCachedEffects) {
6619
+ return true;
6305
6620
  }
6306
6621
  if (this.async) {
6307
6622
  const { propertyReadSideEffects } = this.scope.context.options
@@ -6311,12 +6626,20 @@ class FunctionBase extends NodeBase {
6311
6626
  (propertyReadSideEffects &&
6312
6627
  (propertyReadSideEffects === 'always' ||
6313
6628
  returnExpression.hasEffectsOnInteractionAtPath(['then'], NODE_INTERACTION_UNKNOWN_ACCESS, context)))) {
6629
+ this.hasCachedEffects = true;
6314
6630
  return true;
6315
6631
  }
6316
6632
  }
6317
- for (const parameter of this.params) {
6318
- if (parameter.hasEffects(context))
6633
+ const { propertyReadSideEffects } = this.scope.context.options
6634
+ .treeshake;
6635
+ for (let index = 0; index < this.params.length; index++) {
6636
+ const parameter = this.params[index];
6637
+ if (parameter.hasEffects(context) ||
6638
+ (propertyReadSideEffects &&
6639
+ parameter.hasEffectsWhenDestructuring(context, EMPTY_PATH, interaction.args[index + 1] || UNDEFINED_EXPRESSION))) {
6640
+ this.hasCachedEffects = true;
6319
6641
  return true;
6642
+ }
6320
6643
  }
6321
6644
  return false;
6322
6645
  }
@@ -6334,21 +6657,17 @@ class FunctionBase extends NodeBase {
6334
6657
  return variable?.getOnlyFunctionCallUsed() ?? false;
6335
6658
  }
6336
6659
  include(context, includeChildrenRecursively) {
6337
- if (!this.parameterVariableValuesDeoptimized && !this.onlyFunctionCallUsed()) {
6660
+ if (!this.included)
6661
+ this.includeNode(context);
6662
+ if (!(this.parameterVariableValuesDeoptimized || this.onlyFunctionCallUsed())) {
6338
6663
  this.parameterVariableValuesDeoptimized = true;
6339
- this.deoptimizeParameterVariableValues();
6664
+ this.scope.reassignAllParameters();
6340
6665
  }
6341
- if (!this.deoptimized)
6342
- this.applyDeoptimizations();
6343
- this.included = true;
6344
6666
  const { brokenFlow } = context;
6345
6667
  context.brokenFlow = false;
6346
6668
  this.body.include(context, includeChildrenRecursively);
6347
6669
  context.brokenFlow = brokenFlow;
6348
6670
  }
6349
- includeCallArguments(context, parameters) {
6350
- this.scope.includeCallArguments(context, parameters);
6351
- }
6352
6671
  initialise() {
6353
6672
  super.initialise();
6354
6673
  if (this.body instanceof BlockStatement) {
@@ -6370,14 +6689,14 @@ class FunctionBase extends NodeBase {
6370
6689
  // so that the scope already knows all parameters and can detect conflicts
6371
6690
  // when parsing the body.
6372
6691
  const parameters = (this.params = params.map((parameter) => new (context.getNodeConstructor(parameter.type))(this, scope).parseNode(parameter)));
6373
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
6692
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
6374
6693
  this.body = new (context.getNodeConstructor(body.type))(this, bodyScope).parseNode(body);
6375
6694
  return super.parseNode(esTreeNode);
6376
6695
  }
6377
- addArgumentToBeDeoptimized(_argument) { }
6378
- applyDeoptimizations() { }
6379
6696
  }
6380
6697
  FunctionBase.prototype.preventChildBlockScope = true;
6698
+ FunctionBase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
6699
+ FunctionBase.prototype.applyDeoptimizations = doNotDeoptimize;
6381
6700
 
6382
6701
  class FunctionNode extends FunctionBase {
6383
6702
  constructor() {
@@ -6389,30 +6708,31 @@ class FunctionNode extends FunctionBase {
6389
6708
  this.constructedEntity = new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE);
6390
6709
  // This makes sure that all deoptimizations of "this" are applied to the
6391
6710
  // constructed entity.
6392
- this.scope.thisVariable.addEntityToBeDeoptimized(this.constructedEntity);
6711
+ this.scope.thisVariable.addArgumentValue(this.constructedEntity);
6393
6712
  }
6394
6713
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6395
6714
  super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
6396
6715
  if (interaction.type === INTERACTION_CALLED && path.length === 0 && interaction.args[0]) {
6397
6716
  // args[0] is the "this" argument
6398
- this.scope.thisVariable.addEntityToBeDeoptimized(interaction.args[0]);
6717
+ this.scope.thisVariable.addArgumentValue(interaction.args[0]);
6399
6718
  }
6400
6719
  }
6401
6720
  hasEffects(context) {
6402
- if (!this.deoptimized)
6403
- this.applyDeoptimizations();
6404
6721
  if (this.annotationNoSideEffects) {
6405
6722
  return false;
6406
6723
  }
6407
6724
  return !!this.id?.hasEffects(context);
6408
6725
  }
6409
6726
  hasEffectsOnInteractionAtPath(path, interaction, context) {
6410
- if (super.hasEffectsOnInteractionAtPath(path, interaction, context))
6411
- return true;
6412
- if (this.annotationNoSideEffects) {
6727
+ if (this.annotationNoSideEffects &&
6728
+ path.length === 0 &&
6729
+ interaction.type === INTERACTION_CALLED) {
6413
6730
  return false;
6414
6731
  }
6415
- if (interaction.type === INTERACTION_CALLED) {
6732
+ if (super.hasEffectsOnInteractionAtPath(path, interaction, context)) {
6733
+ return true;
6734
+ }
6735
+ if (path.length === 0 && interaction.type === INTERACTION_CALLED) {
6416
6736
  const thisInit = context.replacedVariableInits.get(this.scope.thisVariable);
6417
6737
  context.replacedVariableInits.set(this.scope.thisVariable, interaction.withNew ? this.constructedEntity : UNKNOWN_EXPRESSION);
6418
6738
  const { brokenFlow, ignore, replacedVariableInits } = context;
@@ -6423,8 +6743,10 @@ class FunctionNode extends FunctionBase {
6423
6743
  returnYield: true,
6424
6744
  this: interaction.withNew
6425
6745
  };
6426
- if (this.body.hasEffects(context))
6746
+ if (this.body.hasEffects(context)) {
6747
+ this.hasCachedEffects = true;
6427
6748
  return true;
6749
+ }
6428
6750
  context.brokenFlow = brokenFlow;
6429
6751
  if (thisInit) {
6430
6752
  replacedVariableInits.set(this.scope.thisVariable, thisInit);
@@ -6438,7 +6760,7 @@ class FunctionNode extends FunctionBase {
6438
6760
  }
6439
6761
  include(context, includeChildrenRecursively) {
6440
6762
  super.include(context, includeChildrenRecursively);
6441
- this.id?.include();
6763
+ this.id?.include(context);
6442
6764
  const hasArguments = this.scope.argumentsVariable.included;
6443
6765
  for (const parameter of this.params) {
6444
6766
  if (!(parameter instanceof Identifier) || hasArguments) {
@@ -6446,12 +6768,18 @@ class FunctionNode extends FunctionBase {
6446
6768
  }
6447
6769
  }
6448
6770
  }
6771
+ includeNode(context) {
6772
+ this.included = true;
6773
+ const hasArguments = this.scope.argumentsVariable.included;
6774
+ for (const parameter of this.params) {
6775
+ if (!(parameter instanceof Identifier) || hasArguments) {
6776
+ parameter.includePath(UNKNOWN_PATH, context);
6777
+ }
6778
+ }
6779
+ }
6449
6780
  initialise() {
6450
6781
  super.initialise();
6451
- this.id?.declare('function', this);
6452
- }
6453
- addArgumentToBeDeoptimized(argument) {
6454
- this.scope.argumentsVariable.addArgumentToBeDeoptimized(argument);
6782
+ this.id?.declare('function', EMPTY_PATH, this);
6455
6783
  }
6456
6784
  getObjectEntity() {
6457
6785
  if (this.objectEntity !== null) {
@@ -6501,11 +6829,16 @@ function getFunctionIdInsertPosition(code, start) {
6501
6829
  }
6502
6830
  class ExportDefaultDeclaration extends NodeBase {
6503
6831
  include(context, includeChildrenRecursively) {
6504
- super.include(context, includeChildrenRecursively);
6832
+ this.included = true;
6833
+ this.declaration.include(context, includeChildrenRecursively);
6505
6834
  if (includeChildrenRecursively) {
6506
- this.scope.context.includeVariableInModule(this.variable);
6835
+ this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, context);
6507
6836
  }
6508
6837
  }
6838
+ includePath(path, context) {
6839
+ this.included = true;
6840
+ this.declaration.includePath(path, context);
6841
+ }
6509
6842
  initialise() {
6510
6843
  super.initialise();
6511
6844
  const declaration = this.declaration;
@@ -6550,7 +6883,6 @@ class ExportDefaultDeclaration extends NodeBase {
6550
6883
  }
6551
6884
  this.declaration.render(code, options);
6552
6885
  }
6553
- applyDeoptimizations() { }
6554
6886
  renderNamedDeclaration(code, declarationStart, idInsertPosition, options) {
6555
6887
  const { exportNamesByVariable, format, snippets: { getPropertyAccess } } = options;
6556
6888
  const name = this.variable.getName(getPropertyAccess);
@@ -6581,6 +6913,8 @@ class ExportDefaultDeclaration extends NodeBase {
6581
6913
  }
6582
6914
  }
6583
6915
  ExportDefaultDeclaration.prototype.needsBoundaries = true;
6916
+ ExportDefaultDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
6917
+ ExportDefaultDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
6584
6918
 
6585
6919
  const needsEscapeRegEx = /[\n\r'\\\u2028\u2029]/;
6586
6920
  const quoteNewlineRegEx = /([\n\r'\u2028\u2029])/g;
@@ -6850,6 +7184,7 @@ class Literal extends NodeBase {
6850
7184
  }
6851
7185
  }
6852
7186
  }
7187
+ Literal.prototype.includeNode = onlyIncludeSelf;
6853
7188
 
6854
7189
  function getChainElementLiteralValueAtPath(element, object, path, recursionTracker, origin) {
6855
7190
  if ('getLiteralValueAtPathAsChainElement' in object) {
@@ -6865,8 +7200,6 @@ function getChainElementLiteralValueAtPath(element, object, path, recursionTrack
6865
7200
  return element.getLiteralValueAtPath(path, recursionTracker, origin);
6866
7201
  }
6867
7202
 
6868
- // To avoid infinite recursions
6869
- const MAX_PATH_DEPTH = 7;
6870
7203
  function getResolvablePropertyKey(memberExpression) {
6871
7204
  return memberExpression.computed
6872
7205
  ? getResolvableComputedPropertyKey(memberExpression.property)
@@ -6965,18 +7298,27 @@ class MemberExpression extends NodeBase {
6965
7298
  }
6966
7299
  else if (!this.isUndefined) {
6967
7300
  if (path.length < MAX_PATH_DEPTH) {
6968
- this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.getPropertyKey(), ...path], recursionTracker);
7301
+ this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, this.propertyKey === UnknownKey ? UNKNOWN_PATH : [this.propertyKey, ...path], recursionTracker);
6969
7302
  }
6970
7303
  else {
6971
7304
  deoptimizeInteraction(interaction);
6972
7305
  }
6973
7306
  }
6974
7307
  }
7308
+ deoptimizeAssignment(destructuredInitPath, init) {
7309
+ this.deoptimizePath(EMPTY_PATH);
7310
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
7311
+ }
6975
7312
  deoptimizeCache() {
7313
+ if (this.propertyKey === this.dynamicPropertyKey)
7314
+ return;
6976
7315
  const { expressionsToBeDeoptimized, object } = this;
6977
7316
  this.expressionsToBeDeoptimized = EMPTY_ARRAY;
6978
- this.propertyKey = UnknownKey;
7317
+ this.dynamicPropertyKey = this.propertyKey;
6979
7318
  object.deoptimizePath(UNKNOWN_PATH);
7319
+ if (this.included) {
7320
+ object.includePath(UNKNOWN_PATH, createInclusionContext());
7321
+ }
6980
7322
  for (const expression of expressionsToBeDeoptimized) {
6981
7323
  expression.deoptimizeCache();
6982
7324
  }
@@ -6987,11 +7329,13 @@ class MemberExpression extends NodeBase {
6987
7329
  if (this.variable) {
6988
7330
  this.variable.deoptimizePath(path);
6989
7331
  }
6990
- else if (!this.isUndefined && path.length < MAX_PATH_DEPTH) {
6991
- const propertyKey = this.getPropertyKey();
7332
+ else if (!this.isUndefined) {
7333
+ const { propertyKey } = this;
6992
7334
  this.object.deoptimizePath([
6993
7335
  propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey,
6994
- ...path
7336
+ ...(path.length < MAX_PATH_DEPTH
7337
+ ? path
7338
+ : [...path.slice(0, MAX_PATH_DEPTH), UnknownKey])
6995
7339
  ]);
6996
7340
  }
6997
7341
  }
@@ -7002,9 +7346,11 @@ class MemberExpression extends NodeBase {
7002
7346
  if (this.isUndefined) {
7003
7347
  return undefined;
7004
7348
  }
7005
- if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
7006
- this.expressionsToBeDeoptimized.push(origin);
7007
- return this.object.getLiteralValueAtPath([this.getPropertyKey(), ...path], recursionTracker, origin);
7349
+ const propertyKey = this.getDynamicPropertyKey();
7350
+ if (propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
7351
+ if (propertyKey !== this.propertyKey)
7352
+ this.expressionsToBeDeoptimized.push(origin);
7353
+ return this.object.getLiteralValueAtPath([propertyKey, ...path], recursionTracker, origin);
7008
7354
  }
7009
7355
  return UnknownValue;
7010
7356
  }
@@ -7024,9 +7370,11 @@ class MemberExpression extends NodeBase {
7024
7370
  if (this.isUndefined) {
7025
7371
  return [UNDEFINED_EXPRESSION, false];
7026
7372
  }
7027
- if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
7028
- this.expressionsToBeDeoptimized.push(origin);
7029
- return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin);
7373
+ const propertyKey = this.getDynamicPropertyKey();
7374
+ if (propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
7375
+ if (propertyKey !== this.propertyKey)
7376
+ this.expressionsToBeDeoptimized.push(origin);
7377
+ return this.object.getReturnExpressionWhenCalledAtPath([propertyKey, ...path], interaction, recursionTracker, origin);
7030
7378
  }
7031
7379
  return UNKNOWN_RETURN_EXPRESSION;
7032
7380
  }
@@ -7072,14 +7420,45 @@ class MemberExpression extends NodeBase {
7072
7420
  return true;
7073
7421
  }
7074
7422
  if (path.length < MAX_PATH_DEPTH) {
7075
- return this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey(), ...path], interaction, context);
7423
+ return this.object.hasEffectsOnInteractionAtPath([this.getDynamicPropertyKey(), ...path], interaction, context);
7076
7424
  }
7077
7425
  return true;
7078
7426
  }
7427
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
7428
+ return (destructuredInitPath.length > 0 &&
7429
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
7430
+ }
7079
7431
  include(context, includeChildrenRecursively) {
7432
+ if (!this.included)
7433
+ this.includeNode(context);
7434
+ this.object.include(context, includeChildrenRecursively);
7435
+ this.property.include(context, includeChildrenRecursively);
7436
+ }
7437
+ includeNode(context) {
7438
+ this.included = true;
7080
7439
  if (!this.deoptimized)
7081
7440
  this.applyDeoptimizations();
7082
- this.includeProperties(context, includeChildrenRecursively);
7441
+ if (this.variable) {
7442
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
7443
+ }
7444
+ else if (!this.isUndefined) {
7445
+ this.object.includePath([this.propertyKey], context);
7446
+ }
7447
+ }
7448
+ includePath(path, context) {
7449
+ if (!this.included)
7450
+ this.includeNode(context);
7451
+ if (this.variable) {
7452
+ this.variable?.includePath(path, context);
7453
+ }
7454
+ else if (!this.isUndefined) {
7455
+ this.object.includePath([
7456
+ this.propertyKey,
7457
+ ...(path.length < MAX_PATH_DEPTH
7458
+ ? path
7459
+ : [...path.slice(0, MAX_PATH_DEPTH), UnknownKey])
7460
+ ], context);
7461
+ }
7083
7462
  }
7084
7463
  includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {
7085
7464
  if (!this.assignmentDeoptimized)
@@ -7088,20 +7467,34 @@ class MemberExpression extends NodeBase {
7088
7467
  this.include(context, includeChildrenRecursively);
7089
7468
  }
7090
7469
  else {
7091
- this.includeProperties(context, includeChildrenRecursively);
7470
+ if (!this.included)
7471
+ this.includeNode(context);
7472
+ this.object.include(context, includeChildrenRecursively);
7473
+ this.property.include(context, includeChildrenRecursively);
7092
7474
  }
7093
7475
  }
7094
- includeCallArguments(context, parameters) {
7476
+ includeCallArguments(context, interaction) {
7095
7477
  if (this.variable) {
7096
- this.variable.includeCallArguments(context, parameters);
7478
+ this.variable.includeCallArguments(context, interaction);
7097
7479
  }
7098
7480
  else {
7099
- super.includeCallArguments(context, parameters);
7481
+ super.includeCallArguments(context, interaction);
7482
+ }
7483
+ }
7484
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
7485
+ if ((this.included ||=
7486
+ destructuredInitPath.length > 0 &&
7487
+ !context.brokenFlow &&
7488
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext()))) {
7489
+ init.include(context, false);
7490
+ return true;
7100
7491
  }
7492
+ return false;
7101
7493
  }
7102
7494
  initialise() {
7103
7495
  super.initialise();
7104
- this.propertyKey = getResolvablePropertyKey(this);
7496
+ this.dynamicPropertyKey = getResolvablePropertyKey(this);
7497
+ this.propertyKey = this.dynamicPropertyKey === null ? UnknownKey : this.dynamicPropertyKey;
7105
7498
  this.accessInteraction = { args: [this.object], type: INTERACTION_ACCESSED };
7106
7499
  }
7107
7500
  render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = BLANK) {
@@ -7138,8 +7531,7 @@ class MemberExpression extends NodeBase {
7138
7531
  this.bound &&
7139
7532
  propertyReadSideEffects &&
7140
7533
  !(this.variable || this.isUndefined)) {
7141
- const propertyKey = this.getPropertyKey();
7142
- this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER);
7534
+ this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [this.propertyKey], SHARED_RECURSION_TRACKER);
7143
7535
  this.scope.context.requestTreeshakingPass();
7144
7536
  }
7145
7537
  if (this.variable) {
@@ -7156,7 +7548,7 @@ class MemberExpression extends NodeBase {
7156
7548
  this.bound &&
7157
7549
  propertyReadSideEffects &&
7158
7550
  !(this.variable || this.isUndefined)) {
7159
- this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.getPropertyKey()], SHARED_RECURSION_TRACKER);
7551
+ this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.propertyKey], SHARED_RECURSION_TRACKER);
7160
7552
  this.scope.context.requestTreeshakingPass();
7161
7553
  }
7162
7554
  }
@@ -7165,24 +7557,24 @@ class MemberExpression extends NodeBase {
7165
7557
  const variable = this.scope.findVariable(this.object.name);
7166
7558
  if (variable.isNamespace) {
7167
7559
  if (this.variable) {
7168
- this.scope.context.includeVariableInModule(this.variable);
7560
+ this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, createInclusionContext());
7169
7561
  }
7170
7562
  this.scope.context.log(LOGLEVEL_WARN, logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);
7171
7563
  }
7172
7564
  }
7173
7565
  }
7174
- getPropertyKey() {
7175
- if (this.propertyKey === null) {
7176
- this.propertyKey = UnknownKey;
7566
+ getDynamicPropertyKey() {
7567
+ if (this.dynamicPropertyKey === null) {
7568
+ this.dynamicPropertyKey = this.propertyKey;
7177
7569
  const value = this.property.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
7178
- return (this.propertyKey =
7570
+ return (this.dynamicPropertyKey =
7179
7571
  value === SymbolToStringTag
7180
7572
  ? value
7181
7573
  : typeof value === 'symbol'
7182
7574
  ? UnknownKey
7183
7575
  : String(value));
7184
7576
  }
7185
- return this.propertyKey;
7577
+ return this.dynamicPropertyKey;
7186
7578
  }
7187
7579
  hasAccessEffect(context) {
7188
7580
  const { propertyReadSideEffects } = this.scope.context.options
@@ -7190,17 +7582,7 @@ class MemberExpression extends NodeBase {
7190
7582
  return (!(this.variable || this.isUndefined) &&
7191
7583
  propertyReadSideEffects &&
7192
7584
  (propertyReadSideEffects === 'always' ||
7193
- this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));
7194
- }
7195
- includeProperties(context, includeChildrenRecursively) {
7196
- if (!this.included) {
7197
- this.included = true;
7198
- if (this.variable) {
7199
- this.scope.context.includeVariableInModule(this.variable);
7200
- }
7201
- }
7202
- this.object.include(context, includeChildrenRecursively);
7203
- this.property.include(context, includeChildrenRecursively);
7585
+ this.object.hasEffectsOnInteractionAtPath([this.getDynamicPropertyKey()], this.accessInteraction, context)));
7204
7586
  }
7205
7587
  }
7206
7588
  function resolveNamespaceVariables(baseVariable, path, astContext) {
@@ -7244,18 +7626,20 @@ class MetaProperty extends NodeBase {
7244
7626
  return path.length > 1 || type !== INTERACTION_ACCESSED;
7245
7627
  }
7246
7628
  include() {
7247
- if (!this.included) {
7248
- this.included = true;
7249
- if (this.meta.name === IMPORT) {
7250
- this.scope.context.addImportMeta(this);
7251
- const parent = this.parent;
7252
- const metaProperty = (this.metaProperty =
7253
- parent instanceof MemberExpression && typeof parent.propertyKey === 'string'
7254
- ? parent.propertyKey
7255
- : null);
7256
- if (metaProperty?.startsWith(FILE_PREFIX)) {
7257
- this.referenceId = metaProperty.slice(FILE_PREFIX.length);
7258
- }
7629
+ if (!this.included)
7630
+ this.includeNode();
7631
+ }
7632
+ includeNode() {
7633
+ this.included = true;
7634
+ if (this.meta.name === IMPORT) {
7635
+ this.scope.context.addImportMeta(this);
7636
+ const parent = this.parent;
7637
+ const metaProperty = (this.metaProperty =
7638
+ parent instanceof MemberExpression && typeof parent.propertyKey === 'string'
7639
+ ? parent.propertyKey
7640
+ : null);
7641
+ if (metaProperty?.startsWith(FILE_PREFIX)) {
7642
+ this.referenceId = metaProperty.slice(FILE_PREFIX.length);
7259
7643
  }
7260
7644
  }
7261
7645
  }
@@ -7362,7 +7746,7 @@ class UndefinedVariable extends Variable {
7362
7746
 
7363
7747
  class ExportDefaultVariable extends LocalVariable {
7364
7748
  constructor(name, exportDefaultDeclaration, context) {
7365
- super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');
7749
+ super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, EMPTY_PATH, context, 'other');
7366
7750
  this.hasId = false;
7367
7751
  this.originalId = null;
7368
7752
  this.originalVariable = null;
@@ -7511,8 +7895,8 @@ class NamespaceVariable extends Variable {
7511
7895
  return (!memberVariable ||
7512
7896
  memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));
7513
7897
  }
7514
- include() {
7515
- super.include();
7898
+ includePath(path, context) {
7899
+ super.includePath(path, context);
7516
7900
  this.context.includeAllExports();
7517
7901
  }
7518
7902
  prepare(accessedGlobalsByScope) {
@@ -7605,9 +7989,9 @@ class SyntheticNamedExportVariable extends Variable {
7605
7989
  getName(getPropertyAccess) {
7606
7990
  return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;
7607
7991
  }
7608
- include() {
7609
- super.include();
7610
- this.context.includeVariableInModule(this.syntheticNamespace);
7992
+ includePath(path, context) {
7993
+ super.includePath(path, context);
7994
+ this.context.includeVariableInModule(this.syntheticNamespace, path, context);
7611
7995
  }
7612
7996
  setRenderNames(baseName, name) {
7613
7997
  super.setRenderNames(baseName, name);
@@ -10812,21 +11196,37 @@ class ArrayPattern extends NodeBase {
10812
11196
  element?.addExportedVariables(variables, exportNamesByVariable);
10813
11197
  }
10814
11198
  }
10815
- declare(kind) {
11199
+ declare(kind, destructuredInitPath, init) {
10816
11200
  const variables = [];
11201
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
10817
11202
  for (const element of this.elements) {
10818
11203
  if (element !== null) {
10819
- variables.push(...element.declare(kind, UNKNOWN_EXPRESSION));
11204
+ variables.push(...element.declare(kind, includedPatternPath, init));
10820
11205
  }
10821
11206
  }
10822
11207
  return variables;
10823
11208
  }
11209
+ deoptimizeAssignment(destructuredInitPath, init) {
11210
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
11211
+ for (const element of this.elements) {
11212
+ element?.deoptimizeAssignment(includedPatternPath, init);
11213
+ }
11214
+ }
10824
11215
  // Patterns can only be deoptimized at the empty path at the moment
10825
11216
  deoptimizePath() {
10826
11217
  for (const element of this.elements) {
10827
11218
  element?.deoptimizePath(EMPTY_PATH);
10828
11219
  }
10829
11220
  }
11221
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
11222
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
11223
+ for (const element of this.elements) {
11224
+ if (element?.hasEffectsWhenDestructuring(context, includedPatternPath, init)) {
11225
+ return true;
11226
+ }
11227
+ }
11228
+ return false;
11229
+ }
10830
11230
  // Patterns are only checked at the empty path at the moment
10831
11231
  hasEffectsOnInteractionAtPath(_path, interaction, context) {
10832
11232
  for (const element of this.elements) {
@@ -10835,12 +11235,38 @@ class ArrayPattern extends NodeBase {
10835
11235
  }
10836
11236
  return false;
10837
11237
  }
11238
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11239
+ let included = false;
11240
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
11241
+ for (const element of this.elements) {
11242
+ if (element) {
11243
+ element.included ||= included;
11244
+ included =
11245
+ element.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
11246
+ }
11247
+ }
11248
+ if (included) {
11249
+ // This is necessary so that if any pattern element is included, all are
11250
+ // included for proper deconflicting
11251
+ for (const element of this.elements) {
11252
+ if (element && !element.included) {
11253
+ element.included = true;
11254
+ element.includeDestructuredIfNecessary(context, includedPatternPath, init);
11255
+ }
11256
+ }
11257
+ }
11258
+ return (this.included ||= included);
11259
+ }
10838
11260
  markDeclarationReached() {
10839
11261
  for (const element of this.elements) {
10840
11262
  element?.markDeclarationReached();
10841
11263
  }
10842
11264
  }
10843
11265
  }
11266
+ ArrayPattern.prototype.includeNode = onlyIncludeSelf;
11267
+ const getIncludedPatternPath = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
11268
+ ? destructuredInitPath
11269
+ : [...destructuredInitPath, UnknownInteger];
10844
11270
 
10845
11271
  class ArrowFunctionExpression extends FunctionBase {
10846
11272
  constructor() {
@@ -10857,17 +11283,17 @@ class ArrowFunctionExpression extends FunctionBase {
10857
11283
  this.scope = new ReturnValueScope(parentScope, false);
10858
11284
  }
10859
11285
  hasEffects() {
10860
- if (!this.deoptimized)
10861
- this.applyDeoptimizations();
10862
11286
  return false;
10863
11287
  }
10864
11288
  hasEffectsOnInteractionAtPath(path, interaction, context) {
11289
+ if (this.annotationNoSideEffects &&
11290
+ path.length === 0 &&
11291
+ interaction.type === INTERACTION_CALLED) {
11292
+ return false;
11293
+ }
10865
11294
  if (super.hasEffectsOnInteractionAtPath(path, interaction, context)) {
10866
11295
  return true;
10867
11296
  }
10868
- if (this.annotationNoSideEffects) {
10869
- return false;
10870
- }
10871
11297
  if (interaction.type === INTERACTION_CALLED) {
10872
11298
  const { ignore, brokenFlow } = context;
10873
11299
  context.ignore = {
@@ -10897,6 +11323,15 @@ class ArrowFunctionExpression extends FunctionBase {
10897
11323
  }
10898
11324
  }
10899
11325
  }
11326
+ includeNode(context) {
11327
+ this.included = true;
11328
+ this.body.includePath(UNKNOWN_PATH, context);
11329
+ for (const parameter of this.params) {
11330
+ if (!(parameter instanceof Identifier)) {
11331
+ parameter.includePath(UNKNOWN_PATH, context);
11332
+ }
11333
+ }
11334
+ }
10900
11335
  getObjectEntity() {
10901
11336
  if (this.objectEntity !== null) {
10902
11337
  return this.objectEntity;
@@ -10916,13 +11351,18 @@ class ObjectPattern extends NodeBase {
10916
11351
  }
10917
11352
  }
10918
11353
  }
10919
- declare(kind, init) {
11354
+ declare(kind, destructuredInitPath, init) {
10920
11355
  const variables = [];
10921
11356
  for (const property of this.properties) {
10922
- variables.push(...property.declare(kind, init));
11357
+ variables.push(...property.declare(kind, destructuredInitPath, init));
10923
11358
  }
10924
11359
  return variables;
10925
11360
  }
11361
+ deoptimizeAssignment(destructuredInitPath, init) {
11362
+ for (const property of this.properties) {
11363
+ property.deoptimizeAssignment(destructuredInitPath, init);
11364
+ }
11365
+ }
10926
11366
  deoptimizePath(path) {
10927
11367
  if (path.length === 0) {
10928
11368
  for (const property of this.properties) {
@@ -10940,12 +11380,46 @@ class ObjectPattern extends NodeBase {
10940
11380
  }
10941
11381
  return false;
10942
11382
  }
11383
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
11384
+ for (const property of this.properties) {
11385
+ if (property.hasEffectsWhenDestructuring(context, destructuredInitPath, init))
11386
+ return true;
11387
+ }
11388
+ return false;
11389
+ }
11390
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11391
+ let included = false;
11392
+ for (const property of this.properties) {
11393
+ included =
11394
+ property.includeDestructuredIfNecessary(context, destructuredInitPath, init) || included;
11395
+ }
11396
+ return (this.included ||= included);
11397
+ }
10943
11398
  markDeclarationReached() {
10944
11399
  for (const property of this.properties) {
10945
11400
  property.markDeclarationReached();
10946
11401
  }
10947
11402
  }
11403
+ render(code, options) {
11404
+ if (this.properties.length > 0) {
11405
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
11406
+ let lastSeparatorPos = null;
11407
+ for (const { node, separator, start, end } of separatedNodes) {
11408
+ if (!node.included) {
11409
+ treeshakeNode(node, code, start, end);
11410
+ continue;
11411
+ }
11412
+ lastSeparatorPos = separator;
11413
+ node.render(code, options);
11414
+ }
11415
+ if (lastSeparatorPos) {
11416
+ code.remove(lastSeparatorPos, this.end - 1);
11417
+ }
11418
+ }
11419
+ }
10948
11420
  }
11421
+ ObjectPattern.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
11422
+ ObjectPattern.prototype.applyDeoptimizations = doNotDeoptimize;
10949
11423
 
10950
11424
  class AssignmentExpression extends NodeBase {
10951
11425
  hasEffects(context) {
@@ -10954,7 +11428,9 @@ class AssignmentExpression extends NodeBase {
10954
11428
  this.applyDeoptimizations();
10955
11429
  // MemberExpressions do not access the property before assignments if the
10956
11430
  // operator is '='.
10957
- return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '='));
11431
+ return (right.hasEffects(context) ||
11432
+ left.hasEffectsAsAssignmentTarget(context, operator !== '=') ||
11433
+ this.left.hasEffectsWhenDestructuring?.(context, EMPTY_PATH, right));
10958
11434
  }
10959
11435
  hasEffectsOnInteractionAtPath(path, interaction, context) {
10960
11436
  return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);
@@ -10963,15 +11439,24 @@ class AssignmentExpression extends NodeBase {
10963
11439
  const { deoptimized, left, right, operator } = this;
10964
11440
  if (!deoptimized)
10965
11441
  this.applyDeoptimizations();
10966
- this.included = true;
11442
+ if (!this.included)
11443
+ this.includeNode(context);
11444
+ const hasEffectsContext = createHasEffectsContext();
10967
11445
  if (includeChildrenRecursively ||
10968
11446
  operator !== '=' ||
10969
11447
  left.included ||
10970
- left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {
11448
+ left.hasEffectsAsAssignmentTarget(hasEffectsContext, false) ||
11449
+ left.hasEffectsWhenDestructuring?.(hasEffectsContext, EMPTY_PATH, right)) {
10971
11450
  left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');
10972
11451
  }
10973
11452
  right.include(context, includeChildrenRecursively);
10974
11453
  }
11454
+ includeNode(context) {
11455
+ this.included = true;
11456
+ if (!this.deoptimized)
11457
+ this.applyDeoptimizations();
11458
+ this.right.includePath(UNKNOWN_PATH, context);
11459
+ }
10975
11460
  initialise() {
10976
11461
  super.initialise();
10977
11462
  if (this.left instanceof Identifier) {
@@ -11032,8 +11517,7 @@ class AssignmentExpression extends NodeBase {
11032
11517
  }
11033
11518
  applyDeoptimizations() {
11034
11519
  this.deoptimized = true;
11035
- this.left.deoptimizePath(EMPTY_PATH);
11036
- this.right.deoptimizePath(UNKNOWN_PATH);
11520
+ this.left.deoptimizeAssignment(EMPTY_PATH, this.right);
11037
11521
  this.scope.context.requestTreeshakingPass();
11038
11522
  }
11039
11523
  }
@@ -11042,8 +11526,11 @@ class AssignmentPattern extends NodeBase {
11042
11526
  addExportedVariables(variables, exportNamesByVariable) {
11043
11527
  this.left.addExportedVariables(variables, exportNamesByVariable);
11044
11528
  }
11045
- declare(kind, init) {
11046
- return this.left.declare(kind, init);
11529
+ declare(kind, destructuredInitPath, init) {
11530
+ return this.left.declare(kind, destructuredInitPath, init);
11531
+ }
11532
+ deoptimizeAssignment(destructuredInitPath, init) {
11533
+ this.left.deoptimizeAssignment(destructuredInitPath, init);
11047
11534
  }
11048
11535
  deoptimizePath(path) {
11049
11536
  if (path.length === 0) {
@@ -11053,6 +11540,29 @@ class AssignmentPattern extends NodeBase {
11053
11540
  hasEffectsOnInteractionAtPath(path, interaction, context) {
11054
11541
  return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
11055
11542
  }
11543
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
11544
+ return this.left.hasEffectsWhenDestructuring(context, destructuredInitPath, init);
11545
+ }
11546
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11547
+ let included = this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init) ||
11548
+ this.included;
11549
+ if ((included ||= this.right.shouldBeIncluded(context))) {
11550
+ this.right.include(context, false);
11551
+ if (!this.left.included) {
11552
+ this.left.included = true;
11553
+ // Unfortunately, we need to include the left side again now, so that
11554
+ // any declared variables are properly included.
11555
+ this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init);
11556
+ }
11557
+ }
11558
+ return (this.included = included);
11559
+ }
11560
+ includeNode(context) {
11561
+ this.included = true;
11562
+ if (!this.deoptimized)
11563
+ this.applyDeoptimizations();
11564
+ this.right.includePath(UNKNOWN_PATH, context);
11565
+ }
11056
11566
  markDeclarationReached() {
11057
11567
  this.left.markDeclarationReached();
11058
11568
  }
@@ -11075,22 +11585,34 @@ class AwaitExpression extends NodeBase {
11075
11585
  return true;
11076
11586
  }
11077
11587
  include(context, includeChildrenRecursively) {
11588
+ if (!this.included)
11589
+ this.includeNode(context);
11590
+ this.argument.include(context, includeChildrenRecursively);
11591
+ }
11592
+ includeNode(context) {
11593
+ this.included = true;
11078
11594
  if (!this.deoptimized)
11079
11595
  this.applyDeoptimizations();
11080
- if (!this.included) {
11081
- this.included = true;
11082
- checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) {
11083
- let parent = this.parent;
11084
- do {
11085
- if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression)
11086
- break checkTopLevelAwait;
11087
- } while ((parent = parent.parent));
11088
- this.scope.context.usesTopLevelAwait = true;
11089
- }
11596
+ checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) {
11597
+ let parent = this.parent;
11598
+ do {
11599
+ if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression)
11600
+ break checkTopLevelAwait;
11601
+ } while ((parent = parent.parent));
11602
+ this.scope.context.usesTopLevelAwait = true;
11090
11603
  }
11091
- this.argument.include(context, includeChildrenRecursively);
11604
+ // Thenables need to be included
11605
+ this.argument.includePath(THEN_PATH, context);
11606
+ }
11607
+ includePath(path, context) {
11608
+ if (!this.deoptimized)
11609
+ this.applyDeoptimizations();
11610
+ if (!this.included)
11611
+ this.includeNode(context);
11612
+ this.argument.includePath(path, context);
11092
11613
  }
11093
11614
  }
11615
+ const THEN_PATH = ['then'];
11094
11616
 
11095
11617
  const binaryOperators = {
11096
11618
  '!=': (left, right) => left != right,
@@ -11146,6 +11668,12 @@ class BinaryExpression extends NodeBase {
11146
11668
  hasEffectsOnInteractionAtPath(path, { type }) {
11147
11669
  return type !== INTERACTION_ACCESSED || path.length > 1;
11148
11670
  }
11671
+ includeNode(context) {
11672
+ this.included = true;
11673
+ if (this.operator === 'in') {
11674
+ this.right.includePath(UNKNOWN_PATH, context);
11675
+ }
11676
+ }
11149
11677
  removeAnnotations(code) {
11150
11678
  this.left.removeAnnotations(code);
11151
11679
  }
@@ -11154,6 +11682,7 @@ class BinaryExpression extends NodeBase {
11154
11682
  this.right.render(code, options);
11155
11683
  }
11156
11684
  }
11685
+ BinaryExpression.prototype.applyDeoptimizations = doNotDeoptimize;
11157
11686
 
11158
11687
  class BreakStatement extends NodeBase {
11159
11688
  hasEffects(context) {
@@ -11173,7 +11702,7 @@ class BreakStatement extends NodeBase {
11173
11702
  include(context) {
11174
11703
  this.included = true;
11175
11704
  if (this.label) {
11176
- this.label.include();
11705
+ this.label.include(context);
11177
11706
  context.includedLabels.add(this.label.name);
11178
11707
  }
11179
11708
  else {
@@ -11182,6 +11711,8 @@ class BreakStatement extends NodeBase {
11182
11711
  context.brokenFlow = true;
11183
11712
  }
11184
11713
  }
11714
+ BreakStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
11715
+ BreakStatement.prototype.applyDeoptimizations = doNotDeoptimize;
11185
11716
 
11186
11717
  function renderCallArguments(code, options, node) {
11187
11718
  if (node.arguments.length > 0) {
@@ -11368,10 +11899,14 @@ class CallExpression extends CallExpressionBase {
11368
11899
  this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)));
11369
11900
  }
11370
11901
  include(context, includeChildrenRecursively) {
11371
- if (!this.deoptimized)
11372
- this.applyDeoptimizations();
11902
+ if (!this.included)
11903
+ this.includeNode(context);
11373
11904
  if (includeChildrenRecursively) {
11374
- super.include(context, includeChildrenRecursively);
11905
+ this.callee.include(context, true);
11906
+ for (const argument of this.arguments) {
11907
+ argument.includePath(UNKNOWN_PATH, context);
11908
+ argument.include(context, true);
11909
+ }
11375
11910
  if (includeChildrenRecursively === INCLUDE_PARAMETERS &&
11376
11911
  this.callee instanceof Identifier &&
11377
11912
  this.callee.variable) {
@@ -11379,10 +11914,24 @@ class CallExpression extends CallExpressionBase {
11379
11914
  }
11380
11915
  }
11381
11916
  else {
11382
- this.included = true;
11383
- this.callee.include(context, false);
11917
+ // If the callee is a member expression and does not have a variable, its
11918
+ // object will already be included via the first argument of the
11919
+ // interaction in includeCallArguments. Including it again can lead to
11920
+ // severe performance problems.
11921
+ if (this.callee instanceof MemberExpression && !this.callee.variable) {
11922
+ this.callee.property.include(context, false);
11923
+ }
11924
+ else {
11925
+ this.callee.include(context, false);
11926
+ }
11927
+ this.callee.includeCallArguments(context, this.interaction);
11384
11928
  }
11385
- this.callee.includeCallArguments(context, this.arguments);
11929
+ }
11930
+ includeNode(context) {
11931
+ this.included = true;
11932
+ if (!this.deoptimized)
11933
+ this.applyDeoptimizations();
11934
+ this.callee.includePath(UNKNOWN_PATH, context);
11386
11935
  }
11387
11936
  initialise() {
11388
11937
  super.initialise();
@@ -11421,13 +11970,14 @@ class CatchClause extends NodeBase {
11421
11970
  this.type = type;
11422
11971
  if (param) {
11423
11972
  this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);
11424
- this.param.declare('parameter', UNKNOWN_EXPRESSION);
11973
+ this.param.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
11425
11974
  }
11426
11975
  this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);
11427
11976
  return super.parseNode(esTreeNode);
11428
11977
  }
11429
11978
  }
11430
11979
  CatchClause.prototype.preventChildBlockScope = true;
11980
+ CatchClause.prototype.includeNode = onlyIncludeSelf;
11431
11981
 
11432
11982
  class ChainExpression extends NodeBase {
11433
11983
  // deoptimizations are not relevant as we are not caching values
@@ -11439,17 +11989,22 @@ class ChainExpression extends NodeBase {
11439
11989
  hasEffects(context) {
11440
11990
  return this.expression.hasEffectsAsChainElement(context) === true;
11441
11991
  }
11992
+ includePath(path, context) {
11993
+ this.included = true;
11994
+ this.expression.includePath(path, context);
11995
+ }
11442
11996
  removeAnnotations(code) {
11443
11997
  this.expression.removeAnnotations(code);
11444
11998
  }
11445
- applyDeoptimizations() { }
11446
11999
  }
12000
+ ChainExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12001
+ ChainExpression.prototype.applyDeoptimizations = doNotDeoptimize;
11447
12002
 
11448
12003
  class ClassBodyScope extends ChildScope {
11449
12004
  constructor(parent, classNode) {
11450
12005
  const { context } = parent;
11451
12006
  super(parent, context);
11452
- this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));
12007
+ this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, EMPTY_PATH, context, 'other')));
11453
12008
  this.instanceScope = new ChildScope(this, context);
11454
12009
  this.instanceScope.variables.set('this', new ThisVariable(context));
11455
12010
  }
@@ -11464,7 +12019,7 @@ class ClassBody extends NodeBase {
11464
12019
  }
11465
12020
  include(context, includeChildrenRecursively) {
11466
12021
  this.included = true;
11467
- this.scope.context.includeVariableInModule(this.scope.thisVariable);
12022
+ this.scope.context.includeVariableInModule(this.scope.thisVariable, UNKNOWN_PATH, context);
11468
12023
  for (const definition of this.body) {
11469
12024
  definition.include(context, includeChildrenRecursively);
11470
12025
  }
@@ -11477,8 +12032,9 @@ class ClassBody extends NodeBase {
11477
12032
  }
11478
12033
  return super.parseNode(esTreeNode);
11479
12034
  }
11480
- applyDeoptimizations() { }
11481
12035
  }
12036
+ ClassBody.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12037
+ ClassBody.prototype.applyDeoptimizations = doNotDeoptimize;
11482
12038
 
11483
12039
  class ClassExpression extends ClassNode {
11484
12040
  render(code, options, { renderedSurroundingElement } = BLANK) {
@@ -11549,6 +12105,9 @@ class ConditionalExpression extends NodeBase {
11549
12105
  const unusedBranch = this.usedBranch === this.consequent ? this.alternate : this.consequent;
11550
12106
  this.usedBranch = null;
11551
12107
  unusedBranch.deoptimizePath(UNKNOWN_PATH);
12108
+ if (this.included) {
12109
+ unusedBranch.includePath(UNKNOWN_PATH, createInclusionContext());
12110
+ }
11552
12111
  const { expressionsToBeDeoptimized } = this;
11553
12112
  this.expressionsToBeDeoptimized = EMPTY_ARRAY;
11554
12113
  for (const expression of expressionsToBeDeoptimized) {
@@ -11606,7 +12165,7 @@ class ConditionalExpression extends NodeBase {
11606
12165
  include(context, includeChildrenRecursively) {
11607
12166
  this.included = true;
11608
12167
  const usedBranch = this.getUsedBranch();
11609
- if (includeChildrenRecursively || this.test.shouldBeIncluded(context) || usedBranch === null) {
12168
+ if (usedBranch === null || includeChildrenRecursively || this.test.shouldBeIncluded(context)) {
11610
12169
  this.test.include(context, includeChildrenRecursively);
11611
12170
  this.consequent.include(context, includeChildrenRecursively);
11612
12171
  this.alternate.include(context, includeChildrenRecursively);
@@ -11615,27 +12174,38 @@ class ConditionalExpression extends NodeBase {
11615
12174
  usedBranch.include(context, includeChildrenRecursively);
11616
12175
  }
11617
12176
  }
11618
- includeCallArguments(context, parameters) {
12177
+ includePath(path, context) {
12178
+ this.included = true;
12179
+ const usedBranch = this.getUsedBranch();
12180
+ if (usedBranch === null || this.test.shouldBeIncluded(context)) {
12181
+ this.consequent.includePath(path, context);
12182
+ this.alternate.includePath(path, context);
12183
+ }
12184
+ else {
12185
+ usedBranch.includePath(path, context);
12186
+ }
12187
+ }
12188
+ includeCallArguments(context, interaction) {
11619
12189
  const usedBranch = this.getUsedBranch();
11620
12190
  if (usedBranch) {
11621
- usedBranch.includeCallArguments(context, parameters);
12191
+ usedBranch.includeCallArguments(context, interaction);
11622
12192
  }
11623
12193
  else {
11624
- this.consequent.includeCallArguments(context, parameters);
11625
- this.alternate.includeCallArguments(context, parameters);
12194
+ this.consequent.includeCallArguments(context, interaction);
12195
+ this.alternate.includeCallArguments(context, interaction);
11626
12196
  }
11627
12197
  }
11628
12198
  removeAnnotations(code) {
11629
12199
  this.test.removeAnnotations(code);
11630
12200
  }
11631
12201
  render(code, options, { isCalleeOfRenderedParent, preventASI, renderedParentType, renderedSurroundingElement } = BLANK) {
11632
- const usedBranch = this.getUsedBranch();
11633
12202
  if (this.test.included) {
11634
12203
  this.test.render(code, options, { renderedSurroundingElement });
11635
12204
  this.consequent.render(code, options);
11636
12205
  this.alternate.render(code, options);
11637
12206
  }
11638
12207
  else {
12208
+ const usedBranch = this.getUsedBranch();
11639
12209
  const colonPos = findFirstOccurrenceOutsideComment(code.original, ':', this.consequent.end);
11640
12210
  const inclusionStart = findNonWhiteSpace(code.original, (this.consequent.included
11641
12211
  ? findFirstOccurrenceOutsideComment(code.original, '?', this.test.end)
@@ -11667,6 +12237,8 @@ class ConditionalExpression extends NodeBase {
11667
12237
  : (this.usedBranch = testValue ? this.consequent : this.alternate);
11668
12238
  }
11669
12239
  }
12240
+ ConditionalExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12241
+ ConditionalExpression.prototype.applyDeoptimizations = doNotDeoptimize;
11670
12242
 
11671
12243
  class ContinueStatement extends NodeBase {
11672
12244
  hasEffects(context) {
@@ -11686,7 +12258,7 @@ class ContinueStatement extends NodeBase {
11686
12258
  include(context) {
11687
12259
  this.included = true;
11688
12260
  if (this.label) {
11689
- this.label.include();
12261
+ this.label.include(context);
11690
12262
  context.includedLabels.add(this.label.name);
11691
12263
  }
11692
12264
  else {
@@ -11695,12 +12267,15 @@ class ContinueStatement extends NodeBase {
11695
12267
  context.brokenFlow = true;
11696
12268
  }
11697
12269
  }
12270
+ ContinueStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12271
+ ContinueStatement.prototype.applyDeoptimizations = doNotDeoptimize;
11698
12272
 
11699
12273
  class DebuggerStatement extends NodeBase {
11700
12274
  hasEffects() {
11701
12275
  return true;
11702
12276
  }
11703
12277
  }
12278
+ DebuggerStatement.prototype.includeNode = onlyIncludeSelf;
11704
12279
 
11705
12280
  class Decorator extends NodeBase {
11706
12281
  hasEffects(context) {
@@ -11708,6 +12283,7 @@ class Decorator extends NodeBase {
11708
12283
  this.expression.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context));
11709
12284
  }
11710
12285
  }
12286
+ Decorator.prototype.includeNode = onlyIncludeSelf;
11711
12287
 
11712
12288
  function hasLoopBodyEffects(context, body) {
11713
12289
  const { brokenFlow, hasBreak, hasContinue, ignore } = context;
@@ -11747,12 +12323,15 @@ class DoWhileStatement extends NodeBase {
11747
12323
  includeLoopBody(context, this.body, includeChildrenRecursively);
11748
12324
  }
11749
12325
  }
12326
+ DoWhileStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12327
+ DoWhileStatement.prototype.applyDeoptimizations = doNotDeoptimize;
11750
12328
 
11751
12329
  class EmptyStatement extends NodeBase {
11752
12330
  hasEffects() {
11753
12331
  return false;
11754
12332
  }
11755
12333
  }
12334
+ EmptyStatement.prototype.includeNode = onlyIncludeSelf;
11756
12335
 
11757
12336
  class ExportAllDeclaration extends NodeBase {
11758
12337
  hasEffects() {
@@ -11765,9 +12344,10 @@ class ExportAllDeclaration extends NodeBase {
11765
12344
  render(code, _options, nodeRenderOptions) {
11766
12345
  code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
11767
12346
  }
11768
- applyDeoptimizations() { }
11769
12347
  }
11770
12348
  ExportAllDeclaration.prototype.needsBoundaries = true;
12349
+ ExportAllDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12350
+ ExportAllDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
11771
12351
 
11772
12352
  class ExportNamedDeclaration extends NodeBase {
11773
12353
  bind() {
@@ -11794,13 +12374,15 @@ class ExportNamedDeclaration extends NodeBase {
11794
12374
  this.declaration.render(code, options, { end, start });
11795
12375
  }
11796
12376
  }
11797
- applyDeoptimizations() { }
11798
12377
  }
11799
12378
  ExportNamedDeclaration.prototype.needsBoundaries = true;
12379
+ ExportNamedDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12380
+ ExportNamedDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
11800
12381
 
11801
12382
  class ExportSpecifier extends NodeBase {
11802
- applyDeoptimizations() { }
11803
12383
  }
12384
+ ExportSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12385
+ ExportSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
11804
12386
 
11805
12387
  class ForInStatement extends NodeBase {
11806
12388
  createScope(parentScope) {
@@ -11818,11 +12400,18 @@ class ForInStatement extends NodeBase {
11818
12400
  const { body, deoptimized, left, right } = this;
11819
12401
  if (!deoptimized)
11820
12402
  this.applyDeoptimizations();
11821
- this.included = true;
12403
+ if (!this.included)
12404
+ this.includeNode(context);
11822
12405
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
11823
12406
  right.include(context, includeChildrenRecursively);
11824
12407
  includeLoopBody(context, body, includeChildrenRecursively);
11825
12408
  }
12409
+ includeNode(context) {
12410
+ this.included = true;
12411
+ if (!this.deoptimized)
12412
+ this.applyDeoptimizations();
12413
+ this.right.includePath(UNKNOWN_PATH, context);
12414
+ }
11826
12415
  initialise() {
11827
12416
  super.initialise();
11828
12417
  this.left.setAssignedValue(UNKNOWN_EXPRESSION);
@@ -11863,11 +12452,18 @@ class ForOfStatement extends NodeBase {
11863
12452
  const { body, deoptimized, left, right } = this;
11864
12453
  if (!deoptimized)
11865
12454
  this.applyDeoptimizations();
11866
- this.included = true;
12455
+ if (!this.included)
12456
+ this.includeNode(context);
11867
12457
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
11868
12458
  right.include(context, includeChildrenRecursively);
11869
12459
  includeLoopBody(context, body, includeChildrenRecursively);
11870
12460
  }
12461
+ includeNode(context) {
12462
+ this.included = true;
12463
+ if (!this.deoptimized)
12464
+ this.applyDeoptimizations();
12465
+ this.right.includePath(UNKNOWN_PATH, context);
12466
+ }
11871
12467
  initialise() {
11872
12468
  super.initialise();
11873
12469
  this.left.setAssignedValue(UNKNOWN_EXPRESSION);
@@ -11903,7 +12499,9 @@ class ForStatement extends NodeBase {
11903
12499
  }
11904
12500
  include(context, includeChildrenRecursively) {
11905
12501
  this.included = true;
11906
- this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true });
12502
+ this.init?.include(context, includeChildrenRecursively, {
12503
+ asSingleStatement: true
12504
+ });
11907
12505
  this.test?.include(context, includeChildrenRecursively);
11908
12506
  this.update?.include(context, includeChildrenRecursively);
11909
12507
  includeLoopBody(context, this.body, includeChildrenRecursively);
@@ -11915,6 +12513,8 @@ class ForStatement extends NodeBase {
11915
12513
  this.body.render(code, options);
11916
12514
  }
11917
12515
  }
12516
+ ForStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12517
+ ForStatement.prototype.applyDeoptimizations = doNotDeoptimize;
11918
12518
 
11919
12519
  class FunctionExpression extends FunctionNode {
11920
12520
  createScope(parentScope) {
@@ -11946,9 +12546,9 @@ class TrackingScope extends BlockScope {
11946
12546
  super(...arguments);
11947
12547
  this.hoistedDeclarations = [];
11948
12548
  }
11949
- addDeclaration(identifier, context, init, kind) {
12549
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
11950
12550
  this.hoistedDeclarations.push(identifier);
11951
- return super.addDeclaration(identifier, context, init, kind);
12551
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
11952
12552
  }
11953
12553
  }
11954
12554
 
@@ -12047,7 +12647,6 @@ class IfStatement extends NodeBase {
12047
12647
  }
12048
12648
  this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess);
12049
12649
  }
12050
- applyDeoptimizations() { }
12051
12650
  getTestValue() {
12052
12651
  if (this.testValue === unset) {
12053
12652
  return (this.testValue = tryCastLiteralValueToBoolean(this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)));
@@ -12116,6 +12715,8 @@ class IfStatement extends NodeBase {
12116
12715
  return false;
12117
12716
  }
12118
12717
  }
12718
+ IfStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12719
+ IfStatement.prototype.applyDeoptimizations = doNotDeoptimize;
12119
12720
 
12120
12721
  class ImportAttribute extends NodeBase {
12121
12722
  }
@@ -12133,13 +12734,15 @@ class ImportDeclaration extends NodeBase {
12133
12734
  render(code, _options, nodeRenderOptions) {
12134
12735
  code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
12135
12736
  }
12136
- applyDeoptimizations() { }
12137
12737
  }
12138
12738
  ImportDeclaration.prototype.needsBoundaries = true;
12739
+ ImportDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12740
+ ImportDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
12139
12741
 
12140
12742
  class ImportDefaultSpecifier extends NodeBase {
12141
- applyDeoptimizations() { }
12142
12743
  }
12744
+ ImportDefaultSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12745
+ ImportDefaultSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
12143
12746
 
12144
12747
  function isReassignedExportsMember(variable, exportNamesByVariable) {
12145
12748
  return (variable.renderBaseName !== null && exportNamesByVariable.has(variable) && variable.isReassigned);
@@ -12148,28 +12751,33 @@ function isReassignedExportsMember(variable, exportNamesByVariable) {
12148
12751
  class VariableDeclarator extends NodeBase {
12149
12752
  declareDeclarator(kind, isUsingDeclaration) {
12150
12753
  this.isUsingDeclaration = isUsingDeclaration;
12151
- this.id.declare(kind, this.init || UNDEFINED_EXPRESSION);
12754
+ this.id.declare(kind, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION);
12152
12755
  }
12153
12756
  deoptimizePath(path) {
12154
12757
  this.id.deoptimizePath(path);
12155
12758
  }
12156
12759
  hasEffects(context) {
12157
- if (!this.deoptimized)
12158
- this.applyDeoptimizations();
12159
12760
  const initEffect = this.init?.hasEffects(context);
12160
12761
  this.id.markDeclarationReached();
12161
- return initEffect || this.id.hasEffects(context) || this.isUsingDeclaration;
12762
+ return (initEffect ||
12763
+ this.isUsingDeclaration ||
12764
+ this.id.hasEffects(context) ||
12765
+ (this.scope.context.options.treeshake
12766
+ .propertyReadSideEffects &&
12767
+ this.id.hasEffectsWhenDestructuring(context, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION)));
12162
12768
  }
12163
12769
  include(context, includeChildrenRecursively) {
12164
- const { deoptimized, id, init } = this;
12165
- if (!deoptimized)
12166
- this.applyDeoptimizations();
12167
- this.included = true;
12770
+ const { id, init } = this;
12771
+ if (!this.included)
12772
+ this.includeNode();
12168
12773
  init?.include(context, includeChildrenRecursively);
12169
12774
  id.markDeclarationReached();
12170
- if (includeChildrenRecursively || id.shouldBeIncluded(context)) {
12775
+ if (includeChildrenRecursively) {
12171
12776
  id.include(context, includeChildrenRecursively);
12172
12777
  }
12778
+ else {
12779
+ id.includeDestructuredIfNecessary(context, EMPTY_PATH, init || UNDEFINED_EXPRESSION);
12780
+ }
12173
12781
  }
12174
12782
  removeAnnotations(code) {
12175
12783
  this.init?.removeAnnotations(code);
@@ -12199,8 +12807,8 @@ class VariableDeclarator extends NodeBase {
12199
12807
  code.appendLeft(end, `${_}=${_}void 0`);
12200
12808
  }
12201
12809
  }
12202
- applyDeoptimizations() {
12203
- this.deoptimized = true;
12810
+ includeNode() {
12811
+ this.included = true;
12204
12812
  const { id, init } = this;
12205
12813
  if (init && id instanceof Identifier && init instanceof ClassExpression && !init.id) {
12206
12814
  const { name, variable } = id;
@@ -12212,11 +12820,14 @@ class VariableDeclarator extends NodeBase {
12212
12820
  }
12213
12821
  }
12214
12822
  }
12823
+ VariableDeclarator.prototype.applyDeoptimizations = doNotDeoptimize;
12215
12824
 
12216
12825
  class ImportExpression extends NodeBase {
12217
12826
  constructor() {
12218
12827
  super(...arguments);
12219
12828
  this.inlineNamespace = null;
12829
+ this.hasUnknownAccessedKey = false;
12830
+ this.accessedPropKey = new Set();
12220
12831
  this.attributes = null;
12221
12832
  this.mechanism = null;
12222
12833
  this.namespaceExportName = undefined;
@@ -12249,12 +12860,15 @@ class ImportExpression extends NodeBase {
12249
12860
  if (parent2 instanceof ExpressionStatement) {
12250
12861
  return EMPTY_ARRAY;
12251
12862
  }
12252
- // Case 1: const { foo } = await import('bar')
12863
+ // Case 1: const { foo } / module = await import('bar')
12253
12864
  if (parent2 instanceof VariableDeclarator) {
12254
12865
  const declaration = parent2.id;
12255
- return declaration instanceof ObjectPattern
12256
- ? getDeterministicObjectDestructure(declaration)
12257
- : undefined;
12866
+ if (declaration instanceof Identifier) {
12867
+ return this.hasUnknownAccessedKey ? undefined : [...this.accessedPropKey];
12868
+ }
12869
+ if (declaration instanceof ObjectPattern) {
12870
+ return getDeterministicObjectDestructure(declaration);
12871
+ }
12258
12872
  }
12259
12873
  // Case 2: (await import('bar')).foo
12260
12874
  if (parent2 instanceof MemberExpression) {
@@ -12304,13 +12918,30 @@ class ImportExpression extends NodeBase {
12304
12918
  return true;
12305
12919
  }
12306
12920
  include(context, includeChildrenRecursively) {
12307
- if (!this.included) {
12308
- this.included = true;
12309
- this.scope.context.includeDynamicImport(this);
12310
- this.scope.addAccessedDynamicImport(this);
12311
- }
12921
+ if (!this.included)
12922
+ this.includeNode();
12312
12923
  this.source.include(context, includeChildrenRecursively);
12313
12924
  }
12925
+ includeNode() {
12926
+ this.included = true;
12927
+ this.scope.context.includeDynamicImport(this);
12928
+ this.scope.addAccessedDynamicImport(this);
12929
+ }
12930
+ includePath(path) {
12931
+ if (!this.included)
12932
+ this.includeNode();
12933
+ // Technically, this is not correct as dynamic imports return a Promise.
12934
+ if (this.hasUnknownAccessedKey)
12935
+ return;
12936
+ if (path[0] === UnknownKey) {
12937
+ this.hasUnknownAccessedKey = true;
12938
+ }
12939
+ else if (typeof path[0] === 'string') {
12940
+ this.accessedPropKey.add(path[0]);
12941
+ }
12942
+ // Update included paths
12943
+ this.scope.context.includeDynamicImport(this);
12944
+ }
12314
12945
  initialise() {
12315
12946
  super.initialise();
12316
12947
  this.scope.context.addDynamicImport(this);
@@ -12379,7 +13010,6 @@ class ImportExpression extends NodeBase {
12379
13010
  setInternalResolution(inlineNamespace) {
12380
13011
  this.inlineNamespace = inlineNamespace;
12381
13012
  }
12382
- applyDeoptimizations() { }
12383
13013
  getDynamicImportMechanismAndHelper(resolution, exportMode, { compact, dynamicImportInCjs, format, generatedCode: { arrowFunctions }, interop }, { _, getDirectReturnFunction, getDirectReturnIifeLeft }, pluginDriver) {
12384
13014
  const mechanism = pluginDriver.hookFirstSync('renderDynamicImport', [
12385
13015
  {
@@ -12469,6 +13099,7 @@ class ImportExpression extends NodeBase {
12469
13099
  return { helper: null, mechanism: null };
12470
13100
  }
12471
13101
  }
13102
+ ImportExpression.prototype.applyDeoptimizations = doNotDeoptimize;
12472
13103
  function getInteropHelper(resolution, exportMode, interop) {
12473
13104
  return exportMode === 'external'
12474
13105
  ? namespaceInteropHelpersByInteropType[interop(resolution instanceof ExternalModule ? resolution.id : null)]
@@ -12492,12 +13123,14 @@ function getDeterministicObjectDestructure(objectPattern) {
12492
13123
  }
12493
13124
 
12494
13125
  class ImportNamespaceSpecifier extends NodeBase {
12495
- applyDeoptimizations() { }
12496
13126
  }
13127
+ ImportNamespaceSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13128
+ ImportNamespaceSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
12497
13129
 
12498
13130
  class ImportSpecifier extends NodeBase {
12499
- applyDeoptimizations() { }
12500
13131
  }
13132
+ ImportSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13133
+ ImportSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
12501
13134
 
12502
13135
  class JSXIdentifier extends IdentifierBase {
12503
13136
  constructor() {
@@ -12514,6 +13147,29 @@ class JSXIdentifier extends IdentifierBase {
12514
13147
  this.isNativeElement = true;
12515
13148
  }
12516
13149
  }
13150
+ include(context) {
13151
+ if (!this.included)
13152
+ this.includeNode(context);
13153
+ }
13154
+ includeNode(context) {
13155
+ this.included = true;
13156
+ if (!this.deoptimized)
13157
+ this.applyDeoptimizations();
13158
+ if (this.variable !== null) {
13159
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
13160
+ }
13161
+ }
13162
+ includePath(path, context) {
13163
+ if (!this.included) {
13164
+ this.included = true;
13165
+ if (this.variable !== null) {
13166
+ this.scope.context.includeVariableInModule(this.variable, path, context);
13167
+ }
13168
+ }
13169
+ else if (path.length > 0) {
13170
+ this.variable?.includePath(path, context);
13171
+ }
13172
+ }
12517
13173
  render(code, { snippets: { getPropertyAccess }, useOriginalName }) {
12518
13174
  if (this.variable) {
12519
13175
  const name = this.variable.getName(getPropertyAccess, useOriginalName);
@@ -12575,6 +13231,7 @@ class JSXAttribute extends NodeBase {
12575
13231
  }
12576
13232
  }
12577
13233
  }
13234
+ JSXAttribute.prototype.includeNode = onlyIncludeSelf;
12578
13235
 
12579
13236
  class JSXClosingBase extends NodeBase {
12580
13237
  render(code, options) {
@@ -12587,6 +13244,7 @@ class JSXClosingBase extends NodeBase {
12587
13244
  }
12588
13245
  }
12589
13246
  }
13247
+ JSXClosingBase.prototype.includeNode = onlyIncludeSelf;
12590
13248
 
12591
13249
  class JSXClosingElement extends JSXClosingBase {
12592
13250
  }
@@ -12607,8 +13265,15 @@ class JSXSpreadAttribute extends NodeBase {
12607
13265
 
12608
13266
  class JSXEmptyExpression extends NodeBase {
12609
13267
  }
13268
+ JSXEmptyExpression.prototype.includeNode = onlyIncludeSelf;
12610
13269
 
12611
13270
  class JSXExpressionContainer extends NodeBase {
13271
+ includeNode(context) {
13272
+ this.included = true;
13273
+ if (!this.deoptimized)
13274
+ this.applyDeoptimizations();
13275
+ this.expression.includePath(UNKNOWN_PATH, context);
13276
+ }
12612
13277
  render(code, options) {
12613
13278
  const { mode } = this.scope.context.options.jsx;
12614
13279
  if (mode !== 'preserve') {
@@ -12629,7 +13294,7 @@ function getRenderedJsxChildren(children) {
12629
13294
  return renderedChildren;
12630
13295
  }
12631
13296
 
12632
- function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
13297
+ function getAndIncludeFactoryVariable(factory, preserve, importSource, node, context) {
12633
13298
  const [baseName, nestedName] = factory.split('.');
12634
13299
  let factoryVariable;
12635
13300
  if (importSource) {
@@ -12637,7 +13302,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
12637
13302
  if (preserve) {
12638
13303
  // This pretends we are accessing an included global variable of the same name
12639
13304
  const globalVariable = node.scope.findGlobal(baseName);
12640
- globalVariable.include();
13305
+ globalVariable.includePath(UNKNOWN_PATH, context);
12641
13306
  // This excludes this variable from renaming
12642
13307
  factoryVariable.globalName = baseName;
12643
13308
  }
@@ -12645,7 +13310,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
12645
13310
  else {
12646
13311
  factoryVariable = node.scope.findGlobal(baseName);
12647
13312
  }
12648
- node.scope.context.includeVariableInModule(factoryVariable);
13313
+ node.scope.context.includeVariableInModule(factoryVariable, UNKNOWN_PATH, context);
12649
13314
  if (factoryVariable instanceof LocalVariable) {
12650
13315
  factoryVariable.consolidateInitializers();
12651
13316
  factoryVariable.addUsedPlace(node);
@@ -12668,16 +13333,20 @@ class JSXElementBase extends NodeBase {
12668
13333
  }
12669
13334
  }
12670
13335
  include(context, includeChildrenRecursively) {
12671
- if (!this.included) {
12672
- const { factory, importSource, mode } = this.jsxMode;
12673
- if (factory) {
12674
- this.factory = factory;
12675
- this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this);
12676
- }
13336
+ if (!this.included)
13337
+ this.includeNode(context);
13338
+ for (const child of this.children) {
13339
+ child.include(context, includeChildrenRecursively);
13340
+ }
13341
+ }
13342
+ includeNode(context) {
13343
+ this.included = true;
13344
+ const { factory, importSource, mode } = this.jsxMode;
13345
+ if (factory) {
13346
+ this.factory = factory;
13347
+ this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this, context);
12677
13348
  }
12678
- super.include(context, includeChildrenRecursively);
12679
13349
  }
12680
- applyDeoptimizations() { }
12681
13350
  getRenderingMode() {
12682
13351
  const jsx = this.scope.context.options.jsx;
12683
13352
  const { mode, factory, importSource } = jsx;
@@ -12715,8 +13384,14 @@ class JSXElementBase extends NodeBase {
12715
13384
  return { childrenEnd, firstChild, hasMultipleChildren };
12716
13385
  }
12717
13386
  }
13387
+ JSXElementBase.prototype.applyDeoptimizations = doNotDeoptimize;
12718
13388
 
12719
13389
  class JSXElement extends JSXElementBase {
13390
+ include(context, includeChildrenRecursively) {
13391
+ super.include(context, includeChildrenRecursively);
13392
+ this.openingElement.include(context, includeChildrenRecursively);
13393
+ this.closingElement?.include(context, includeChildrenRecursively);
13394
+ }
12720
13395
  render(code, options) {
12721
13396
  switch (this.jsxMode.mode) {
12722
13397
  case 'classic': {
@@ -12868,6 +13543,11 @@ class JSXElement extends JSXElementBase {
12868
13543
  }
12869
13544
 
12870
13545
  class JSXFragment extends JSXElementBase {
13546
+ include(context, includeChildrenRecursively) {
13547
+ super.include(context, includeChildrenRecursively);
13548
+ this.openingFragment.include(context, includeChildrenRecursively);
13549
+ this.closingFragment.include(context, includeChildrenRecursively);
13550
+ }
12871
13551
  render(code, options) {
12872
13552
  switch (this.jsxMode.mode) {
12873
13553
  case 'classic': {
@@ -12917,10 +13597,22 @@ class JSXFragment extends JSXElementBase {
12917
13597
  }
12918
13598
 
12919
13599
  class JSXMemberExpression extends NodeBase {
13600
+ includeNode(context) {
13601
+ this.included = true;
13602
+ if (!this.deoptimized)
13603
+ this.applyDeoptimizations();
13604
+ this.object.includePath([this.property.name], context);
13605
+ }
13606
+ includePath(path, context) {
13607
+ if (!this.included)
13608
+ this.includeNode(context);
13609
+ this.object.includePath([this.property.name, ...path], context);
13610
+ }
12920
13611
  }
12921
13612
 
12922
13613
  class JSXNamespacedName extends NodeBase {
12923
13614
  }
13615
+ JSXNamespacedName.prototype.includeNode = onlyIncludeSelf;
12924
13616
 
12925
13617
  class JSXOpeningElement extends NodeBase {
12926
13618
  render(code, options, { jsxMode = this.scope.context.options.jsx.mode } = {}) {
@@ -12930,6 +13622,7 @@ class JSXOpeningElement extends NodeBase {
12930
13622
  }
12931
13623
  }
12932
13624
  }
13625
+ JSXOpeningElement.prototype.includeNode = onlyIncludeSelf;
12933
13626
 
12934
13627
  class JSXOpeningFragment extends NodeBase {
12935
13628
  constructor() {
@@ -12937,22 +13630,22 @@ class JSXOpeningFragment extends NodeBase {
12937
13630
  this.fragment = null;
12938
13631
  this.fragmentVariable = null;
12939
13632
  }
12940
- include(context, includeChildrenRecursively) {
12941
- if (!this.included) {
12942
- const jsx = this.scope.context.options.jsx;
12943
- if (jsx.mode === 'automatic') {
12944
- this.fragment = 'Fragment';
12945
- this.fragmentVariable = getAndIncludeFactoryVariable('Fragment', false, jsx.jsxImportSource, this);
12946
- }
12947
- else {
12948
- const { fragment, importSource, mode } = jsx;
12949
- if (fragment != null) {
12950
- this.fragment = fragment;
12951
- this.fragmentVariable = getAndIncludeFactoryVariable(fragment, mode === 'preserve', importSource, this);
12952
- }
13633
+ includeNode(context) {
13634
+ this.included = true;
13635
+ if (!this.deoptimized)
13636
+ this.applyDeoptimizations();
13637
+ const jsx = this.scope.context.options.jsx;
13638
+ if (jsx.mode === 'automatic') {
13639
+ this.fragment = 'Fragment';
13640
+ this.fragmentVariable = getAndIncludeFactoryVariable('Fragment', false, jsx.jsxImportSource, this, context);
13641
+ }
13642
+ else {
13643
+ const { fragment, importSource, mode } = jsx;
13644
+ if (fragment != null) {
13645
+ this.fragment = fragment;
13646
+ this.fragmentVariable = getAndIncludeFactoryVariable(fragment, mode === 'preserve', importSource, this, context);
12953
13647
  }
12954
13648
  }
12955
- super.include(context, includeChildrenRecursively);
12956
13649
  }
12957
13650
  render(code, options) {
12958
13651
  const { mode } = this.scope.context.options.jsx;
@@ -12989,6 +13682,7 @@ class JSXText extends NodeBase {
12989
13682
  }
12990
13683
  }
12991
13684
  }
13685
+ JSXText.prototype.includeNode = onlyIncludeSelf;
12992
13686
 
12993
13687
  class LabeledStatement extends NodeBase {
12994
13688
  hasEffects(context) {
@@ -13010,17 +13704,22 @@ class LabeledStatement extends NodeBase {
13010
13704
  return bodyHasEffects;
13011
13705
  }
13012
13706
  include(context, includeChildrenRecursively) {
13013
- this.included = true;
13707
+ if (!this.included)
13708
+ this.includeNode(context);
13014
13709
  const { brokenFlow, includedLabels } = context;
13015
13710
  context.includedLabels = new Set();
13016
13711
  this.body.include(context, includeChildrenRecursively);
13017
13712
  if (includeChildrenRecursively || context.includedLabels.has(this.label.name)) {
13018
- this.label.include();
13713
+ this.label.include(context);
13019
13714
  context.includedLabels.delete(this.label.name);
13020
13715
  context.brokenFlow = brokenFlow;
13021
13716
  }
13022
13717
  context.includedLabels = new Set([...includedLabels, ...context.includedLabels]);
13023
13718
  }
13719
+ includeNode(context) {
13720
+ this.included = true;
13721
+ this.body.includePath(UNKNOWN_PATH, context);
13722
+ }
13024
13723
  render(code, options) {
13025
13724
  if (this.label.included) {
13026
13725
  this.label.render(code, options);
@@ -13031,6 +13730,7 @@ class LabeledStatement extends NodeBase {
13031
13730
  this.body.render(code, options);
13032
13731
  }
13033
13732
  }
13733
+ LabeledStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13034
13734
 
13035
13735
  class LogicalExpression extends NodeBase {
13036
13736
  constructor() {
@@ -13047,10 +13747,10 @@ class LogicalExpression extends NodeBase {
13047
13747
  this.flags = setFlag(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */, value);
13048
13748
  }
13049
13749
  get hasDeoptimizedCache() {
13050
- return isFlagSet(this.flags, 16777216 /* Flag.hasDeoptimizedCache */);
13750
+ return isFlagSet(this.flags, 33554432 /* Flag.hasDeoptimizedCache */);
13051
13751
  }
13052
13752
  set hasDeoptimizedCache(value) {
13053
- this.flags = setFlag(this.flags, 16777216 /* Flag.hasDeoptimizedCache */, value);
13753
+ this.flags = setFlag(this.flags, 33554432 /* Flag.hasDeoptimizedCache */, value);
13054
13754
  }
13055
13755
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
13056
13756
  this.left.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -13064,6 +13764,10 @@ class LogicalExpression extends NodeBase {
13064
13764
  const unusedBranch = this.usedBranch === this.left ? this.right : this.left;
13065
13765
  this.usedBranch = null;
13066
13766
  unusedBranch.deoptimizePath(UNKNOWN_PATH);
13767
+ if (this.included) {
13768
+ // As we are not tracking inclusions, we just include everything
13769
+ unusedBranch.includePath(UNKNOWN_PATH, createInclusionContext());
13770
+ }
13067
13771
  }
13068
13772
  const { scope: { context }, expressionsToBeDeoptimized } = this;
13069
13773
  this.expressionsToBeDeoptimized = EMPTY_ARRAY;
@@ -13110,16 +13814,17 @@ class LogicalExpression extends NodeBase {
13110
13814
  }
13111
13815
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
13112
13816
  const usedBranch = this.getUsedBranch();
13113
- if (!usedBranch)
13114
- return [
13115
- new MultiExpression([
13116
- this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
13117
- this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
13118
- ]),
13119
- false
13120
- ];
13121
- this.expressionsToBeDeoptimized.push(origin);
13122
- return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
13817
+ if (usedBranch) {
13818
+ this.expressionsToBeDeoptimized.push(origin);
13819
+ return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
13820
+ }
13821
+ return [
13822
+ new MultiExpression([
13823
+ this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
13824
+ this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
13825
+ ]),
13826
+ false
13827
+ ];
13123
13828
  }
13124
13829
  hasEffects(context) {
13125
13830
  if (this.left.hasEffects(context)) {
@@ -13132,18 +13837,18 @@ class LogicalExpression extends NodeBase {
13132
13837
  }
13133
13838
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13134
13839
  const usedBranch = this.getUsedBranch();
13135
- if (!usedBranch) {
13136
- return (this.left.hasEffectsOnInteractionAtPath(path, interaction, context) ||
13137
- this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
13840
+ if (usedBranch) {
13841
+ return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
13138
13842
  }
13139
- return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
13843
+ return (this.left.hasEffectsOnInteractionAtPath(path, interaction, context) ||
13844
+ this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
13140
13845
  }
13141
13846
  include(context, includeChildrenRecursively) {
13142
13847
  this.included = true;
13143
13848
  const usedBranch = this.getUsedBranch();
13144
13849
  if (includeChildrenRecursively ||
13145
- (usedBranch === this.right && this.left.shouldBeIncluded(context)) ||
13146
- !usedBranch) {
13850
+ !usedBranch ||
13851
+ (usedBranch === this.right && this.left.shouldBeIncluded(context))) {
13147
13852
  this.left.include(context, includeChildrenRecursively);
13148
13853
  this.right.include(context, includeChildrenRecursively);
13149
13854
  }
@@ -13151,6 +13856,17 @@ class LogicalExpression extends NodeBase {
13151
13856
  usedBranch.include(context, includeChildrenRecursively);
13152
13857
  }
13153
13858
  }
13859
+ includePath(path, context) {
13860
+ this.included = true;
13861
+ const usedBranch = this.getUsedBranch();
13862
+ if (!usedBranch || (usedBranch === this.right && this.left.shouldBeIncluded(context))) {
13863
+ this.left.includePath(path, context);
13864
+ this.right.includePath(path, context);
13865
+ }
13866
+ else {
13867
+ usedBranch.includePath(path, context);
13868
+ }
13869
+ }
13154
13870
  removeAnnotations(code) {
13155
13871
  this.left.removeAnnotations(code);
13156
13872
  }
@@ -13203,6 +13919,8 @@ class LogicalExpression extends NodeBase {
13203
13919
  return this.usedBranch;
13204
13920
  }
13205
13921
  }
13922
+ LogicalExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13923
+ LogicalExpression.prototype.applyDeoptimizations = doNotDeoptimize;
13206
13924
 
13207
13925
  class NewExpression extends NodeBase {
13208
13926
  hasEffects(context) {
@@ -13222,16 +13940,21 @@ class NewExpression extends NodeBase {
13222
13940
  return path.length > 0 || type !== INTERACTION_ACCESSED;
13223
13941
  }
13224
13942
  include(context, includeChildrenRecursively) {
13225
- if (!this.deoptimized)
13226
- this.applyDeoptimizations();
13227
13943
  if (includeChildrenRecursively) {
13228
13944
  super.include(context, includeChildrenRecursively);
13229
13945
  }
13230
13946
  else {
13231
- this.included = true;
13947
+ if (!this.included)
13948
+ this.includeNode(context);
13232
13949
  this.callee.include(context, false);
13233
13950
  }
13234
- this.callee.includeCallArguments(context, this.arguments);
13951
+ this.callee.includeCallArguments(context, this.interaction);
13952
+ }
13953
+ includeNode(context) {
13954
+ this.included = true;
13955
+ if (!this.deoptimized)
13956
+ this.applyDeoptimizations();
13957
+ this.callee.includePath(UNKNOWN_PATH, context);
13235
13958
  }
13236
13959
  initialise() {
13237
13960
  super.initialise();
@@ -13260,6 +13983,7 @@ class ObjectExpression extends NodeBase {
13260
13983
  constructor() {
13261
13984
  super(...arguments);
13262
13985
  this.objectEntity = null;
13986
+ this.protoProp = null;
13263
13987
  }
13264
13988
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
13265
13989
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -13279,15 +14003,43 @@ class ObjectExpression extends NodeBase {
13279
14003
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13280
14004
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
13281
14005
  }
14006
+ include(context, includeChildrenRecursively) {
14007
+ if (!this.included)
14008
+ this.includeNode(context);
14009
+ this.getObjectEntity().include(context, includeChildrenRecursively);
14010
+ this.protoProp?.include(context, includeChildrenRecursively);
14011
+ }
14012
+ includeNode(context) {
14013
+ this.included = true;
14014
+ this.protoProp?.includePath(UNKNOWN_PATH, context);
14015
+ }
14016
+ includePath(path, context) {
14017
+ if (!this.included)
14018
+ this.includeNode(context);
14019
+ this.getObjectEntity().includePath(path, context);
14020
+ }
13282
14021
  render(code, options, { renderedSurroundingElement } = BLANK) {
13283
- super.render(code, options);
13284
14022
  if (renderedSurroundingElement === ExpressionStatement$1 ||
13285
14023
  renderedSurroundingElement === ArrowFunctionExpression$1) {
13286
14024
  code.appendRight(this.start, '(');
13287
14025
  code.prependLeft(this.end, ')');
13288
14026
  }
14027
+ if (this.properties.length > 0) {
14028
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
14029
+ let lastSeparatorPos = null;
14030
+ for (const { node, separator, start, end } of separatedNodes) {
14031
+ if (!node.included) {
14032
+ treeshakeNode(node, code, start, end);
14033
+ continue;
14034
+ }
14035
+ lastSeparatorPos = separator;
14036
+ node.render(code, options);
14037
+ }
14038
+ if (lastSeparatorPos) {
14039
+ code.remove(lastSeparatorPos, this.end - 1);
14040
+ }
14041
+ }
13289
14042
  }
13290
- applyDeoptimizations() { }
13291
14043
  getObjectEntity() {
13292
14044
  if (this.objectEntity !== null) {
13293
14045
  return this.objectEntity;
@@ -13316,6 +14068,7 @@ class ObjectExpression extends NodeBase {
13316
14068
  ? property.key.name
13317
14069
  : String(property.key.value);
13318
14070
  if (key === '__proto__' && property.kind === 'init') {
14071
+ this.protoProp = property;
13319
14072
  prototype =
13320
14073
  property.value instanceof Literal && property.value.value === null
13321
14074
  ? null
@@ -13328,6 +14081,7 @@ class ObjectExpression extends NodeBase {
13328
14081
  return (this.objectEntity = new ObjectEntity(properties, prototype));
13329
14082
  }
13330
14083
  }
14084
+ ObjectExpression.prototype.applyDeoptimizations = doNotDeoptimize;
13331
14085
 
13332
14086
  class PanicError extends NodeBase {
13333
14087
  initialise() {
@@ -13354,6 +14108,7 @@ class ParseError extends NodeBase {
13354
14108
 
13355
14109
  class PrivateIdentifier extends NodeBase {
13356
14110
  }
14111
+ PrivateIdentifier.prototype.includeNode = onlyIncludeSelf;
13357
14112
 
13358
14113
  class Program extends NodeBase {
13359
14114
  constructor() {
@@ -13421,14 +14176,11 @@ class Program extends NodeBase {
13421
14176
  super.render(code, options);
13422
14177
  }
13423
14178
  }
13424
- applyDeoptimizations() { }
13425
14179
  }
14180
+ Program.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14181
+ Program.prototype.applyDeoptimizations = doNotDeoptimize;
13426
14182
 
13427
14183
  class Property extends MethodBase {
13428
- constructor() {
13429
- super(...arguments);
13430
- this.declarationInit = null;
13431
- }
13432
14184
  //declare method: boolean;
13433
14185
  get method() {
13434
14186
  return isFlagSet(this.flags, 262144 /* Flag.method */);
@@ -13443,17 +14195,41 @@ class Property extends MethodBase {
13443
14195
  set shorthand(value) {
13444
14196
  this.flags = setFlag(this.flags, 524288 /* Flag.shorthand */, value);
13445
14197
  }
13446
- declare(kind, init) {
13447
- this.declarationInit = init;
13448
- return this.value.declare(kind, UNKNOWN_EXPRESSION);
14198
+ declare(kind, destructuredInitPath, init) {
14199
+ return this.value.declare(kind, this.getPathInProperty(destructuredInitPath), init);
14200
+ }
14201
+ deoptimizeAssignment(destructuredInitPath, init) {
14202
+ this.value.deoptimizeAssignment?.(this.getPathInProperty(destructuredInitPath), init);
13449
14203
  }
13450
14204
  hasEffects(context) {
13451
- if (!this.deoptimized)
13452
- this.applyDeoptimizations();
13453
- const propertyReadSideEffects = this.scope.context.options.treeshake.propertyReadSideEffects;
13454
- return ((this.parent.type === 'ObjectPattern' && propertyReadSideEffects === 'always') ||
13455
- this.key.hasEffects(context) ||
13456
- this.value.hasEffects(context));
14205
+ return this.key.hasEffects(context) || this.value.hasEffects(context);
14206
+ }
14207
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
14208
+ return this.value.hasEffectsWhenDestructuring?.(context, this.getPathInProperty(destructuredInitPath), init);
14209
+ }
14210
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
14211
+ const path = this.getPathInProperty(destructuredInitPath);
14212
+ let included = this.value.includeDestructuredIfNecessary(context, path, init) ||
14213
+ this.included;
14214
+ if ((included ||= this.key.hasEffects(createHasEffectsContext()))) {
14215
+ this.key.include(context, false);
14216
+ if (!this.value.included) {
14217
+ this.value.included = true;
14218
+ // Unfortunately, we need to include the value again now, so that any
14219
+ // declared variables are properly included.
14220
+ this.value.includeDestructuredIfNecessary(context, path, init);
14221
+ }
14222
+ }
14223
+ return (this.included = included);
14224
+ }
14225
+ include(context, includeChildrenRecursively) {
14226
+ this.included = true;
14227
+ this.key.include(context, includeChildrenRecursively);
14228
+ this.value.include(context, includeChildrenRecursively);
14229
+ }
14230
+ includePath(path, context) {
14231
+ this.included = true;
14232
+ this.value.includePath(path, context);
13457
14233
  }
13458
14234
  markDeclarationReached() {
13459
14235
  this.value.markDeclarationReached();
@@ -13464,14 +14240,20 @@ class Property extends MethodBase {
13464
14240
  }
13465
14241
  this.value.render(code, options, { isShorthandProperty: this.shorthand });
13466
14242
  }
13467
- applyDeoptimizations() {
13468
- this.deoptimized = true;
13469
- if (this.declarationInit !== null) {
13470
- this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
13471
- this.scope.context.requestTreeshakingPass();
13472
- }
14243
+ getPathInProperty(destructuredInitPath) {
14244
+ return destructuredInitPath.at(-1) === UnknownKey
14245
+ ? destructuredInitPath
14246
+ : // For now, we only consider static paths as we do not know how to
14247
+ // deoptimize the path in the dynamic case.
14248
+ this.computed
14249
+ ? [...destructuredInitPath, UnknownKey]
14250
+ : this.key instanceof Identifier
14251
+ ? [...destructuredInitPath, this.key.name]
14252
+ : [...destructuredInitPath, String(this.key.value)];
13473
14253
  }
13474
14254
  }
14255
+ Property.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14256
+ Property.prototype.applyDeoptimizations = doNotDeoptimize;
13475
14257
 
13476
14258
  class PropertyDefinition extends NodeBase {
13477
14259
  get computed() {
@@ -13504,8 +14286,15 @@ class PropertyDefinition extends NodeBase {
13504
14286
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13505
14287
  return !this.value || this.value.hasEffectsOnInteractionAtPath(path, interaction, context);
13506
14288
  }
13507
- applyDeoptimizations() { }
14289
+ includeNode(context) {
14290
+ this.included = true;
14291
+ this.value?.includePath(UNKNOWN_PATH, context);
14292
+ for (const decorator of this.decorators) {
14293
+ decorator.includePath(UNKNOWN_PATH, context);
14294
+ }
14295
+ }
13508
14296
  }
14297
+ PropertyDefinition.prototype.applyDeoptimizations = doNotDeoptimize;
13509
14298
 
13510
14299
  class ReturnStatement extends NodeBase {
13511
14300
  hasEffects(context) {
@@ -13515,10 +14304,15 @@ class ReturnStatement extends NodeBase {
13515
14304
  return false;
13516
14305
  }
13517
14306
  include(context, includeChildrenRecursively) {
13518
- this.included = true;
14307
+ if (!this.included)
14308
+ this.includeNode(context);
13519
14309
  this.argument?.include(context, includeChildrenRecursively);
13520
14310
  context.brokenFlow = true;
13521
14311
  }
14312
+ includeNode(context) {
14313
+ this.included = true;
14314
+ this.argument?.includePath(UNKNOWN_PATH, context);
14315
+ }
13522
14316
  initialise() {
13523
14317
  super.initialise();
13524
14318
  this.scope.addReturnExpression(this.argument || UNKNOWN_EXPRESSION);
@@ -13532,6 +14326,7 @@ class ReturnStatement extends NodeBase {
13532
14326
  }
13533
14327
  }
13534
14328
  }
14329
+ ReturnStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13535
14330
 
13536
14331
  class SequenceExpression extends NodeBase {
13537
14332
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
@@ -13559,10 +14354,15 @@ class SequenceExpression extends NodeBase {
13559
14354
  for (const expression of this.expressions) {
13560
14355
  if (includeChildrenRecursively ||
13561
14356
  (expression === lastExpression && !(this.parent instanceof ExpressionStatement)) ||
13562
- expression.shouldBeIncluded(context))
14357
+ expression.shouldBeIncluded(context)) {
13563
14358
  expression.include(context, includeChildrenRecursively);
14359
+ }
13564
14360
  }
13565
14361
  }
14362
+ includePath(path, context) {
14363
+ this.included = true;
14364
+ this.expressions[this.expressions.length - 1].includePath(path, context);
14365
+ }
13566
14366
  removeAnnotations(code) {
13567
14367
  this.expressions[0].removeAnnotations(code);
13568
14368
  }
@@ -13597,6 +14397,8 @@ class SequenceExpression extends NodeBase {
13597
14397
  }
13598
14398
  }
13599
14399
  }
14400
+ SequenceExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14401
+ SequenceExpression.prototype.applyDeoptimizations = doNotDeoptimize;
13600
14402
 
13601
14403
  class Super extends NodeBase {
13602
14404
  bind() {
@@ -13608,11 +14410,15 @@ class Super extends NodeBase {
13608
14410
  deoptimizePath(path) {
13609
14411
  this.variable.deoptimizePath(path);
13610
14412
  }
13611
- include() {
13612
- if (!this.included) {
13613
- this.included = true;
13614
- this.scope.context.includeVariableInModule(this.variable);
13615
- }
14413
+ include(context) {
14414
+ if (!this.included)
14415
+ this.includeNode(context);
14416
+ }
14417
+ includeNode(context) {
14418
+ this.included = true;
14419
+ if (!this.deoptimized)
14420
+ this.applyDeoptimizations();
14421
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
13616
14422
  }
13617
14423
  }
13618
14424
 
@@ -13653,6 +14459,8 @@ class SwitchCase extends NodeBase {
13653
14459
  }
13654
14460
  }
13655
14461
  SwitchCase.prototype.needsBoundaries = true;
14462
+ SwitchCase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14463
+ SwitchCase.prototype.applyDeoptimizations = doNotDeoptimize;
13656
14464
 
13657
14465
  class SwitchStatement extends NodeBase {
13658
14466
  createScope(parentScope) {
@@ -13735,6 +14543,8 @@ class SwitchStatement extends NodeBase {
13735
14543
  }
13736
14544
  }
13737
14545
  }
14546
+ SwitchStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14547
+ SwitchStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13738
14548
 
13739
14549
  class TaggedTemplateExpression extends CallExpressionBase {
13740
14550
  bind() {
@@ -13758,8 +14568,8 @@ class TaggedTemplateExpression extends CallExpressionBase {
13758
14568
  this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
13759
14569
  }
13760
14570
  include(context, includeChildrenRecursively) {
13761
- if (!this.deoptimized)
13762
- this.applyDeoptimizations();
14571
+ if (!this.included)
14572
+ this.includeNode(context);
13763
14573
  if (includeChildrenRecursively) {
13764
14574
  super.include(context, includeChildrenRecursively);
13765
14575
  }
@@ -13768,7 +14578,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
13768
14578
  this.tag.include(context, includeChildrenRecursively);
13769
14579
  this.quasi.include(context, includeChildrenRecursively);
13770
14580
  }
13771
- this.tag.includeCallArguments(context, this.args);
14581
+ this.tag.includeCallArguments(context, this.interaction);
13772
14582
  const [returnExpression] = this.getReturnExpression();
13773
14583
  if (!returnExpression.included) {
13774
14584
  returnExpression.include(context, false);
@@ -13803,6 +14613,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
13803
14613
  return this.returnExpression;
13804
14614
  }
13805
14615
  }
14616
+ TaggedTemplateExpression.prototype.includeNode = onlyIncludeSelf;
13806
14617
 
13807
14618
  class TemplateElement extends NodeBase {
13808
14619
  get tail() {
@@ -13816,15 +14627,13 @@ class TemplateElement extends NodeBase {
13816
14627
  hasEffects() {
13817
14628
  return false;
13818
14629
  }
13819
- include() {
13820
- this.included = true;
13821
- }
13822
14630
  parseNode(esTreeNode) {
13823
14631
  this.value = esTreeNode.value;
13824
14632
  return super.parseNode(esTreeNode);
13825
14633
  }
13826
14634
  render() { }
13827
14635
  }
14636
+ TemplateElement.prototype.includeNode = onlyIncludeSelf;
13828
14637
 
13829
14638
  class TemplateLiteral extends NodeBase {
13830
14639
  deoptimizeArgumentsOnInteractionAtPath() { }
@@ -13849,6 +14658,14 @@ class TemplateLiteral extends NodeBase {
13849
14658
  }
13850
14659
  return true;
13851
14660
  }
14661
+ includeNode(context) {
14662
+ this.included = true;
14663
+ if (!this.deoptimized)
14664
+ this.applyDeoptimizations();
14665
+ for (const node of this.expressions) {
14666
+ node.includePath(UNKNOWN_PATH, context);
14667
+ }
14668
+ }
13852
14669
  render(code, options) {
13853
14670
  code.indentExclusionRanges.push([this.start, this.end]);
13854
14671
  super.render(code, options);
@@ -13858,13 +14675,13 @@ class TemplateLiteral extends NodeBase {
13858
14675
  class ModuleScope extends ChildScope {
13859
14676
  constructor(parent, context) {
13860
14677
  super(parent, context);
13861
- this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, context, 'other'));
14678
+ this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, EMPTY_PATH, context, 'other'));
13862
14679
  }
13863
- addDeclaration(identifier, context, init, kind) {
14680
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
13864
14681
  if (this.context.module.importDescriptions.has(identifier.name)) {
13865
14682
  context.error(logRedeclarationError(identifier.name), identifier.start);
13866
14683
  }
13867
- return super.addDeclaration(identifier, context, init, kind);
14684
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
13868
14685
  }
13869
14686
  addExportDefaultDeclaration(name, exportDefaultDeclaration, context) {
13870
14687
  const variable = new ExportDefaultVariable(name, exportDefaultDeclaration, context);
@@ -13909,10 +14726,23 @@ class ThisExpression extends NodeBase {
13909
14726
  }
13910
14727
  return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
13911
14728
  }
13912
- include() {
14729
+ include(context) {
14730
+ if (!this.included)
14731
+ this.includeNode(context);
14732
+ }
14733
+ includeNode(context) {
14734
+ this.included = true;
14735
+ if (!this.deoptimized)
14736
+ this.applyDeoptimizations();
14737
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
14738
+ }
14739
+ includePath(path, context) {
13913
14740
  if (!this.included) {
13914
14741
  this.included = true;
13915
- this.scope.context.includeVariableInModule(this.variable);
14742
+ this.scope.context.includeVariableInModule(this.variable, path, context);
14743
+ }
14744
+ else if (path.length > 0) {
14745
+ this.variable.includePath(path, context);
13916
14746
  }
13917
14747
  }
13918
14748
  initialise() {
@@ -13940,7 +14770,8 @@ class ThrowStatement extends NodeBase {
13940
14770
  return true;
13941
14771
  }
13942
14772
  include(context, includeChildrenRecursively) {
13943
- this.included = true;
14773
+ if (!this.included)
14774
+ this.includeNode(context);
13944
14775
  this.argument.include(context, includeChildrenRecursively);
13945
14776
  context.brokenFlow = true;
13946
14777
  }
@@ -13951,6 +14782,7 @@ class ThrowStatement extends NodeBase {
13951
14782
  }
13952
14783
  }
13953
14784
  }
14785
+ ThrowStatement.prototype.includeNode = onlyIncludeSelf;
13954
14786
 
13955
14787
  class TryStatement extends NodeBase {
13956
14788
  constructor() {
@@ -13987,6 +14819,8 @@ class TryStatement extends NodeBase {
13987
14819
  this.finalizer?.include(context, includeChildrenRecursively);
13988
14820
  }
13989
14821
  }
14822
+ TryStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14823
+ TryStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13990
14824
 
13991
14825
  const unaryOperators = {
13992
14826
  '!': value => !value,
@@ -14102,6 +14936,7 @@ function getSimplifiedNumber(value) {
14102
14936
  const stringifiedValue = String(value).replace('+', '');
14103
14937
  return finalizedExp.length < stringifiedValue.length ? finalizedExp : stringifiedValue;
14104
14938
  }
14939
+ UnaryExpression.prototype.includeNode = onlyIncludeSelf;
14105
14940
 
14106
14941
  class UpdateExpression extends NodeBase {
14107
14942
  hasEffects(context) {
@@ -14113,9 +14948,8 @@ class UpdateExpression extends NodeBase {
14113
14948
  return path.length > 1 || type !== INTERACTION_ACCESSED;
14114
14949
  }
14115
14950
  include(context, includeChildrenRecursively) {
14116
- if (!this.deoptimized)
14117
- this.applyDeoptimizations();
14118
- this.included = true;
14951
+ if (!this.included)
14952
+ this.includeNode(context);
14119
14953
  this.argument.includeAsAssignmentTarget(context, includeChildrenRecursively, true);
14120
14954
  }
14121
14955
  initialise() {
@@ -14154,6 +14988,7 @@ class UpdateExpression extends NodeBase {
14154
14988
  this.scope.context.requestTreeshakingPass();
14155
14989
  }
14156
14990
  }
14991
+ UpdateExpression.prototype.includeNode = onlyIncludeSelf;
14157
14992
 
14158
14993
  function areAllDeclarationsIncludedAndNotExported(declarations, exportNamesByVariable) {
14159
14994
  for (const declarator of declarations) {
@@ -14184,8 +15019,9 @@ class VariableDeclaration extends NodeBase {
14184
15019
  include(context, includeChildrenRecursively, { asSingleStatement } = BLANK) {
14185
15020
  this.included = true;
14186
15021
  for (const declarator of this.declarations) {
14187
- if (includeChildrenRecursively || declarator.shouldBeIncluded(context))
15022
+ if (includeChildrenRecursively || declarator.shouldBeIncluded(context)) {
14188
15023
  declarator.include(context, includeChildrenRecursively);
15024
+ }
14189
15025
  const { id, init } = declarator;
14190
15026
  if (asSingleStatement) {
14191
15027
  id.include(context, includeChildrenRecursively);
@@ -14223,7 +15059,6 @@ class VariableDeclaration extends NodeBase {
14223
15059
  this.renderReplacedDeclarations(code, options);
14224
15060
  }
14225
15061
  }
14226
- applyDeoptimizations() { }
14227
15062
  renderDeclarationEnd(code, separatorString, lastSeparatorPos, actualContentEnd, renderedContentEnd, systemPatternExports, options) {
14228
15063
  if (code.original.charCodeAt(this.end - 1) === 59 /*";"*/) {
14229
15064
  code.remove(this.end - 1, this.end);
@@ -14266,8 +15101,7 @@ class VariableDeclaration extends NodeBase {
14266
15101
  const singleSystemExport = gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregatedSystemExports);
14267
15102
  for (const { node, start, separator, contentEnd, end } of separatedNodes) {
14268
15103
  if (!node.included) {
14269
- code.remove(start, end);
14270
- node.removeAnnotations(code);
15104
+ treeshakeNode(node, code, start, end);
14271
15105
  continue;
14272
15106
  }
14273
15107
  node.render(code, options);
@@ -14337,6 +15171,8 @@ function gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregat
14337
15171
  }
14338
15172
  return singleSystemExport;
14339
15173
  }
15174
+ VariableDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
15175
+ VariableDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
14340
15176
 
14341
15177
  class WhileStatement extends NodeBase {
14342
15178
  hasEffects(context) {
@@ -14350,13 +15186,25 @@ class WhileStatement extends NodeBase {
14350
15186
  includeLoopBody(context, this.body, includeChildrenRecursively);
14351
15187
  }
14352
15188
  }
15189
+ WhileStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
15190
+ WhileStatement.prototype.applyDeoptimizations = doNotDeoptimize;
14353
15191
 
14354
15192
  class YieldExpression extends NodeBase {
15193
+ applyDeoptimizations() {
15194
+ this.deoptimized = true;
15195
+ this.argument?.deoptimizePath(UNKNOWN_PATH);
15196
+ }
14355
15197
  hasEffects(context) {
14356
15198
  if (!this.deoptimized)
14357
15199
  this.applyDeoptimizations();
14358
15200
  return !(context.ignore.returnYield && !this.argument?.hasEffects(context));
14359
15201
  }
15202
+ includeNode(context) {
15203
+ this.included = true;
15204
+ if (!this.deoptimized)
15205
+ this.applyDeoptimizations();
15206
+ this.argument?.includePath(UNKNOWN_PATH, context);
15207
+ }
14360
15208
  render(code, options) {
14361
15209
  if (this.argument) {
14362
15210
  this.argument.render(code, options, { preventASI: true });
@@ -14590,7 +15438,7 @@ const bufferParsers = [
14590
15438
  const annotations = (node.annotations = convertAnnotations(buffer[position + 1], buffer));
14591
15439
  node.annotationNoSideEffects = annotations.some(comment => comment.type === 'noSideEffects');
14592
15440
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 2], buffer));
14593
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
15441
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14594
15442
  node.body = convertNode(node, scope.bodyScope, buffer[position + 3], buffer);
14595
15443
  },
14596
15444
  function assignmentExpression(node, position, buffer) {
@@ -14636,7 +15484,7 @@ const bufferParsers = [
14636
15484
  const parameterPosition = buffer[position];
14637
15485
  const parameter = (node.param =
14638
15486
  parameterPosition === 0 ? null : convertNode(node, scope, parameterPosition, buffer));
14639
- parameter?.declare('parameter', UNKNOWN_EXPRESSION);
15487
+ parameter?.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
14640
15488
  node.body = convertNode(node, scope.bodyScope, buffer[position + 1], buffer);
14641
15489
  },
14642
15490
  function chainExpression(node, position, buffer) {
@@ -14774,7 +15622,7 @@ const bufferParsers = [
14774
15622
  node.id =
14775
15623
  idPosition === 0 ? null : convertNode(node, scope.parent, idPosition, buffer);
14776
15624
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
14777
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
15625
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14778
15626
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
14779
15627
  },
14780
15628
  function functionExpression(node, position, buffer) {
@@ -14787,7 +15635,7 @@ const bufferParsers = [
14787
15635
  const idPosition = buffer[position + 2];
14788
15636
  node.id = idPosition === 0 ? null : convertNode(node, node.idScope, idPosition, buffer);
14789
15637
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
14790
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
15638
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14791
15639
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
14792
15640
  },
14793
15641
  function identifier(node, position, buffer) {
@@ -15251,8 +16099,8 @@ class ExportShimVariable extends Variable {
15251
16099
  super(MISSING_EXPORT_SHIM_VARIABLE);
15252
16100
  this.module = module;
15253
16101
  }
15254
- include() {
15255
- super.include();
16102
+ includePath(path, context) {
16103
+ super.includePath(path, context);
15256
16104
  this.module.needsExportShim = true;
15257
16105
  }
15258
16106
  }
@@ -15950,16 +16798,15 @@ class Module {
15950
16798
  markModuleAndImpureDependenciesAsExecuted(this);
15951
16799
  this.graph.needsTreeshakingPass = true;
15952
16800
  }
16801
+ const inclusionContext = createInclusionContext();
15953
16802
  for (const exportName of this.exports.keys()) {
15954
16803
  if (includeNamespaceMembers || exportName !== this.info.syntheticNamedExports) {
15955
16804
  const variable = this.getVariableForExportName(exportName)[0];
15956
16805
  if (!variable) {
15957
16806
  return error(logMissingEntryExport(exportName, this.id));
15958
16807
  }
16808
+ this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
15959
16809
  variable.deoptimizePath(UNKNOWN_PATH);
15960
- if (!variable.included) {
15961
- this.includeVariable(variable);
15962
- }
15963
16810
  }
15964
16811
  }
15965
16812
  for (const name of this.getReexports()) {
@@ -15967,7 +16814,7 @@ class Module {
15967
16814
  if (variable) {
15968
16815
  variable.deoptimizePath(UNKNOWN_PATH);
15969
16816
  if (!variable.included) {
15970
- this.includeVariable(variable);
16817
+ this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
15971
16818
  }
15972
16819
  if (variable instanceof ExternalVariable) {
15973
16820
  variable.module.reexported = true;
@@ -15988,13 +16835,12 @@ class Module {
15988
16835
  this.graph.needsTreeshakingPass = true;
15989
16836
  }
15990
16837
  let includeNamespaceMembers = false;
16838
+ const inclusionContext = createInclusionContext();
15991
16839
  for (const name of names) {
15992
16840
  const variable = this.getVariableForExportName(name)[0];
15993
16841
  if (variable) {
15994
16842
  variable.deoptimizePath(UNKNOWN_PATH);
15995
- if (!variable.included) {
15996
- this.includeVariable(variable);
15997
- }
16843
+ this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
15998
16844
  }
15999
16845
  if (!this.exports.has(name) && !this.reexportDescriptions.has(name)) {
16000
16846
  includeNamespaceMembers = true;
@@ -16095,6 +16941,7 @@ class Module {
16095
16941
  manualPureFunctions: this.graph.pureFunctions,
16096
16942
  module: this,
16097
16943
  moduleContext: this.context,
16944
+ newlyIncludedVariableInits: this.graph.newlyIncludedVariableInits,
16098
16945
  options: this.options,
16099
16946
  requestTreeshakingPass: () => (this.graph.needsTreeshakingPass = true),
16100
16947
  traceExport: (name) => this.getVariableForExportName(name)[0],
@@ -16435,13 +17282,13 @@ class Module {
16435
17282
  for (const module of [this, ...this.exportAllModules]) {
16436
17283
  if (module instanceof ExternalModule) {
16437
17284
  const [externalVariable] = module.getVariableForExportName('*');
16438
- externalVariable.include();
17285
+ externalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
16439
17286
  this.includedImports.add(externalVariable);
16440
17287
  externalNamespaces.add(externalVariable);
16441
17288
  }
16442
17289
  else if (module.info.syntheticNamedExports) {
16443
17290
  const syntheticNamespace = module.getSyntheticNamespace();
16444
- syntheticNamespace.include();
17291
+ syntheticNamespace.includePath(UNKNOWN_PATH, createInclusionContext());
16445
17292
  this.includedImports.add(syntheticNamespace);
16446
17293
  syntheticNamespaces.add(syntheticNamespace);
16447
17294
  }
@@ -16451,7 +17298,9 @@ class Module {
16451
17298
  includeDynamicImport(node) {
16452
17299
  const resolution = this.dynamicImports.find(dynamicImport => dynamicImport.node === node).resolution;
16453
17300
  if (resolution instanceof Module) {
16454
- resolution.includedDynamicImporters.push(this);
17301
+ if (!resolution.includedDynamicImporters.includes(this)) {
17302
+ resolution.includedDynamicImporters.push(this);
17303
+ }
16455
17304
  const importedNames = this.options.treeshake
16456
17305
  ? node.getDeterministicImportedNames()
16457
17306
  : undefined;
@@ -16463,15 +17312,15 @@ class Module {
16463
17312
  }
16464
17313
  }
16465
17314
  }
16466
- includeVariable(variable) {
16467
- const variableModule = variable.module;
16468
- if (variable.included) {
17315
+ includeVariable(variable, path, context) {
17316
+ const { included, module: variableModule } = variable;
17317
+ variable.includePath(path, context);
17318
+ if (included) {
16469
17319
  if (variableModule instanceof Module && variableModule !== this) {
16470
17320
  getAndExtendSideEffectModules(variable, this);
16471
17321
  }
16472
17322
  }
16473
17323
  else {
16474
- variable.include();
16475
17324
  this.graph.needsTreeshakingPass = true;
16476
17325
  if (variableModule instanceof Module) {
16477
17326
  if (!variableModule.isExecuted) {
@@ -16488,8 +17337,8 @@ class Module {
16488
17337
  }
16489
17338
  }
16490
17339
  }
16491
- includeVariableInModule(variable) {
16492
- this.includeVariable(variable);
17340
+ includeVariableInModule(variable, path, context) {
17341
+ this.includeVariable(variable, path, context);
16493
17342
  const variableModule = variable.module;
16494
17343
  if (variableModule && variableModule !== this) {
16495
17344
  this.includedImports.add(variable);
@@ -21097,10 +21946,11 @@ class Graph {
21097
21946
  this.options = options;
21098
21947
  this.astLru = flru(5);
21099
21948
  this.cachedModules = new Map();
21100
- this.deoptimizationTracker = new PathTracker();
21949
+ this.deoptimizationTracker = new EntityPathTracker();
21101
21950
  this.entryModules = [];
21102
21951
  this.modulesById = new Map();
21103
21952
  this.needsTreeshakingPass = false;
21953
+ this.newlyIncludedVariableInits = new Set();
21104
21954
  this.phase = BuildPhase.LOAD_AND_PARSE;
21105
21955
  this.scope = new GlobalScope();
21106
21956
  this.watchFiles = Object.create(null);
@@ -21194,6 +22044,7 @@ class Graph {
21194
22044
  }
21195
22045
  if (this.options.treeshake) {
21196
22046
  let treeshakingPass = 1;
22047
+ this.newlyIncludedVariableInits.clear();
21197
22048
  do {
21198
22049
  timeStart(`treeshaking pass ${treeshakingPass}`, 3);
21199
22050
  this.needsTreeshakingPass = false;
@@ -21206,6 +22057,10 @@ class Graph {
21206
22057
  else {
21207
22058
  module.include();
21208
22059
  }
22060
+ for (const entity of this.newlyIncludedVariableInits) {
22061
+ this.newlyIncludedVariableInits.delete(entity);
22062
+ entity.include(createInclusionContext(), false);
22063
+ }
21209
22064
  }
21210
22065
  }
21211
22066
  if (treeshakingPass === 1) {
@@ -22078,7 +22933,7 @@ const pc = /*@__PURE__*/getDefaultExportFromCjs(picocolorsExports);
22078
22933
 
22079
22934
  // @see https://no-color.org
22080
22935
  // @see https://www.npmjs.com/package/chalk
22081
- const { bold, cyan, dim, gray, green, red, underline, yellow } = pc.createColors(env.FORCE_COLOR !== '0' && !env.NO_COLOR);
22936
+ const { bold, cyan, dim, red} = pc.createColors(env.FORCE_COLOR !== '0' && !env.NO_COLOR);
22082
22937
 
22083
22938
  // log to stderr to keep `rollup main.js > bundle.js` from breaking
22084
22939
  const stderr = (...parameters) => process$1.stderr.write(`${parameters.join('')}\n`);