@rollup/wasm-node 4.29.1 → 4.30.0-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,22 +1,22 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v4.29.1
4
- Sat, 21 Dec 2024 07:15:31 GMT - commit 5d3777803404c67ce14c62b8b05d6e26e46856f5
3
+ Rollup.js v4.30.0-1
4
+ Mon, 30 Dec 2024 06:51:45 GMT - commit 41ab39a6e4a5181e9be21e816dd6f11c57e1c52a
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 as env$1 } from 'node:process';
15
15
  import { performance } from 'node:perf_hooks';
16
16
  import { lstat, realpath, readdir, readFile, mkdir, writeFile } from 'node:fs/promises';
17
17
  import * as tty from 'tty';
18
18
 
19
- var version = "4.29.1";
19
+ var version = "4.30.0-1";
20
20
 
21
21
  const comma = ','.charCodeAt(0);
22
22
  const semicolon = ';'.charCodeAt(0);
@@ -1965,71 +1965,6 @@ function renderSystemExportSequenceBeforeExpression(exportedVariable, expression
1965
1965
  }
1966
1966
  }
1967
1967
 
1968
- /** @import { Node } from 'estree' */
1969
-
1970
- /**
1971
- * @param {Node} node
1972
- * @param {Node} parent
1973
- * @returns {boolean}
1974
- */
1975
- function is_reference(node, parent) {
1976
- if (node.type === 'MemberExpression') {
1977
- return !node.computed && is_reference(node.object, node);
1978
- }
1979
-
1980
- if (node.type !== 'Identifier') return false;
1981
-
1982
- switch (parent?.type) {
1983
- // disregard `bar` in `foo.bar`
1984
- case 'MemberExpression':
1985
- return parent.computed || node === parent.object;
1986
-
1987
- // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
1988
- case 'MethodDefinition':
1989
- return parent.computed;
1990
-
1991
- // disregard the `meta` in `import.meta`
1992
- case 'MetaProperty':
1993
- return parent.meta === node;
1994
-
1995
- // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
1996
- case 'PropertyDefinition':
1997
- return parent.computed || node === parent.value;
1998
-
1999
- // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
2000
- case 'Property':
2001
- return parent.computed || node === parent.value;
2002
-
2003
- // disregard the `bar` in `export { foo as bar }` or
2004
- // the foo in `import { foo as bar }`
2005
- case 'ExportSpecifier':
2006
- case 'ImportSpecifier':
2007
- return node === parent.local;
2008
-
2009
- // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
2010
- case 'LabeledStatement':
2011
- case 'BreakStatement':
2012
- case 'ContinueStatement':
2013
- return false;
2014
-
2015
- default:
2016
- return true;
2017
- }
2018
- }
2019
-
2020
- const PureFunctionKey = Symbol('PureFunction');
2021
- const getPureFunctions = ({ treeshake }) => {
2022
- const pureFunctions = Object.create(null);
2023
- for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
2024
- let currentFunctions = pureFunctions;
2025
- for (const pathSegment of functionName.split('.')) {
2026
- currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
2027
- }
2028
- currentFunctions[PureFunctionKey] = true;
2029
- }
2030
- return pureFunctions;
2031
- };
2032
-
2033
1968
  function getOrCreate(map, key, init) {
2034
1969
  const existing = map.get(key);
2035
1970
  if (existing !== undefined) {
@@ -2060,7 +1995,7 @@ const UNKNOWN_PATH = [UnknownKey];
2060
1995
  const UNKNOWN_NON_ACCESSOR_PATH = [UnknownNonAccessorKey];
2061
1996
  const UNKNOWN_INTEGER_PATH = [UnknownInteger];
2062
1997
  const EntitiesKey = Symbol('Entities');
2063
- class PathTracker {
1998
+ class EntityPathTracker {
2064
1999
  constructor() {
2065
2000
  this.entityPaths = Object.create(null, {
2066
2001
  [EntitiesKey]: { value: new Set() }
@@ -2085,14 +2020,14 @@ class PathTracker {
2085
2020
  getEntities(path) {
2086
2021
  let currentPaths = this.entityPaths;
2087
2022
  for (const pathSegment of path) {
2088
- currentPaths = currentPaths[pathSegment] =
2089
- currentPaths[pathSegment] ||
2090
- Object.create(null, { [EntitiesKey]: { value: new Set() } });
2023
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
2024
+ [EntitiesKey]: { value: new Set() }
2025
+ });
2091
2026
  }
2092
2027
  return currentPaths[EntitiesKey];
2093
2028
  }
2094
2029
  }
2095
- const SHARED_RECURSION_TRACKER = new PathTracker();
2030
+ const SHARED_RECURSION_TRACKER = new EntityPathTracker();
2096
2031
  class DiscriminatedPathTracker {
2097
2032
  constructor() {
2098
2033
  this.entityPaths = Object.create(null, {
@@ -2102,9 +2037,9 @@ class DiscriminatedPathTracker {
2102
2037
  trackEntityAtPathAndGetIfTracked(path, discriminator, entity) {
2103
2038
  let currentPaths = this.entityPaths;
2104
2039
  for (const pathSegment of path) {
2105
- currentPaths = currentPaths[pathSegment] =
2106
- currentPaths[pathSegment] ||
2107
- Object.create(null, { [EntitiesKey]: { value: new Map() } });
2040
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
2041
+ [EntitiesKey]: { value: new Map() }
2042
+ });
2108
2043
  }
2109
2044
  const trackedEntities = getOrCreate(currentPaths[EntitiesKey], discriminator, (getNewSet));
2110
2045
  if (trackedEntities.has(entity))
@@ -2113,6 +2048,137 @@ class DiscriminatedPathTracker {
2113
2048
  return false;
2114
2049
  }
2115
2050
  }
2051
+ const UNKNOWN_INCLUDED_PATH = Object.freeze({ [UnknownKey]: EMPTY_OBJECT });
2052
+ class IncludedPathTracker {
2053
+ constructor() {
2054
+ this.includedPaths = null;
2055
+ }
2056
+ includePathAndGetIfIncluded(path) {
2057
+ let included = true;
2058
+ let parent = this;
2059
+ let parentSegment = 'includedPaths';
2060
+ let currentPaths = (this.includedPaths ||=
2061
+ ((included = false), Object.create(null)));
2062
+ for (const pathSegment of path) {
2063
+ // This means from here, all paths are included
2064
+ if (currentPaths[UnknownKey]) {
2065
+ return true;
2066
+ }
2067
+ // Including UnknownKey automatically includes all nested paths.
2068
+ // From above, we know that UnknownKey is not included yet.
2069
+ if (typeof pathSegment === 'symbol') {
2070
+ // Hopefully, this saves some memory over just setting
2071
+ // currentPaths[UnknownKey] = EMPTY_OBJECT
2072
+ parent[parentSegment] = UNKNOWN_INCLUDED_PATH;
2073
+ return false;
2074
+ }
2075
+ parent = currentPaths;
2076
+ parentSegment = pathSegment;
2077
+ currentPaths = currentPaths[pathSegment] ||= ((included = false), Object.create(null));
2078
+ }
2079
+ return included;
2080
+ }
2081
+ includeAllPaths(entity, context, basePath) {
2082
+ const { includedPaths } = this;
2083
+ if (includedPaths) {
2084
+ includeAllPaths(entity, context, basePath, includedPaths);
2085
+ }
2086
+ }
2087
+ }
2088
+ function includeAllPaths(entity, context, basePath, currentPaths) {
2089
+ if (currentPaths[UnknownKey]) {
2090
+ return entity.includePath([...basePath, UnknownKey], context);
2091
+ }
2092
+ const keys = Object.keys(currentPaths);
2093
+ if (keys.length === 0) {
2094
+ return entity.includePath(basePath, context);
2095
+ }
2096
+ for (const key of keys) {
2097
+ includeAllPaths(entity, context, [...basePath, key], currentPaths[key]);
2098
+ }
2099
+ }
2100
+
2101
+ /** @import { Node } from 'estree' */
2102
+
2103
+ /**
2104
+ * @param {Node} node
2105
+ * @param {Node} parent
2106
+ * @returns {boolean}
2107
+ */
2108
+ function is_reference(node, parent) {
2109
+ if (node.type === 'MemberExpression') {
2110
+ return !node.computed && is_reference(node.object, node);
2111
+ }
2112
+
2113
+ if (node.type !== 'Identifier') return false;
2114
+
2115
+ switch (parent?.type) {
2116
+ // disregard `bar` in `foo.bar`
2117
+ case 'MemberExpression':
2118
+ return parent.computed || node === parent.object;
2119
+
2120
+ // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
2121
+ case 'MethodDefinition':
2122
+ return parent.computed;
2123
+
2124
+ // disregard the `meta` in `import.meta`
2125
+ case 'MetaProperty':
2126
+ return parent.meta === node;
2127
+
2128
+ // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
2129
+ case 'PropertyDefinition':
2130
+ return parent.computed || node === parent.value;
2131
+
2132
+ // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
2133
+ case 'Property':
2134
+ return parent.computed || node === parent.value;
2135
+
2136
+ // disregard the `bar` in `export { foo as bar }` or
2137
+ // the foo in `import { foo as bar }`
2138
+ case 'ExportSpecifier':
2139
+ case 'ImportSpecifier':
2140
+ return node === parent.local;
2141
+
2142
+ // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
2143
+ case 'LabeledStatement':
2144
+ case 'BreakStatement':
2145
+ case 'ContinueStatement':
2146
+ return false;
2147
+
2148
+ default:
2149
+ return true;
2150
+ }
2151
+ }
2152
+
2153
+ function createInclusionContext() {
2154
+ return {
2155
+ brokenFlow: false,
2156
+ hasBreak: false,
2157
+ hasContinue: false,
2158
+ includedCallArguments: new Set(),
2159
+ includedLabels: new Set()
2160
+ };
2161
+ }
2162
+ function createHasEffectsContext() {
2163
+ return {
2164
+ accessed: new EntityPathTracker(),
2165
+ assigned: new EntityPathTracker(),
2166
+ brokenFlow: false,
2167
+ called: new DiscriminatedPathTracker(),
2168
+ hasBreak: false,
2169
+ hasContinue: false,
2170
+ ignore: {
2171
+ breaks: false,
2172
+ continues: false,
2173
+ labels: new Set(),
2174
+ returnYield: false,
2175
+ this: false
2176
+ },
2177
+ includedLabels: new Set(),
2178
+ instantiated: new DiscriminatedPathTracker(),
2179
+ replacedVariableInits: new Map()
2180
+ };
2181
+ }
2116
2182
 
2117
2183
  function isFlagSet(flags, flag) {
2118
2184
  return (flags & flag) !== 0;
@@ -2152,12 +2218,25 @@ class ExpressionEntity {
2152
2218
  hasEffectsOnInteractionAtPath(_path, _interaction, _context) {
2153
2219
  return true;
2154
2220
  }
2155
- include(_context, _includeChildrenRecursively, _options) {
2221
+ include(context, _includeChildrenRecursively, _options) {
2222
+ if (!this.included)
2223
+ this.includeNode(context);
2224
+ }
2225
+ includeNode(_context) {
2156
2226
  this.included = true;
2157
2227
  }
2158
- includeCallArguments(context, parameters) {
2159
- for (const argument of parameters) {
2160
- argument.include(context, false);
2228
+ includePath(_path, context) {
2229
+ if (!this.included)
2230
+ this.includeNode(context);
2231
+ }
2232
+ /* We are both including and including an unknown path here as the former
2233
+ * ensures that nested nodes are included while the latter ensures that all
2234
+ * paths of the expression are included.
2235
+ * */
2236
+ includeCallArguments(context, interaction) {
2237
+ for (const argument of interaction.args) {
2238
+ argument?.includePath(UNKNOWN_PATH, context);
2239
+ argument?.include(context, false);
2161
2240
  }
2162
2241
  }
2163
2242
  shouldBeIncluded(_context) {
@@ -2196,6 +2275,19 @@ const NODE_INTERACTION_UNKNOWN_CALL = {
2196
2275
  withNew: false
2197
2276
  };
2198
2277
 
2278
+ const PureFunctionKey = Symbol('PureFunction');
2279
+ const getPureFunctions = ({ treeshake }) => {
2280
+ const pureFunctions = Object.create(null);
2281
+ for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
2282
+ let currentFunctions = pureFunctions;
2283
+ for (const pathSegment of functionName.split('.')) {
2284
+ currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
2285
+ }
2286
+ currentFunctions[PureFunctionKey] = true;
2287
+ }
2288
+ return pureFunctions;
2289
+ };
2290
+
2199
2291
  class Variable extends ExpressionEntity {
2200
2292
  markReassigned() {
2201
2293
  this.isReassigned = true;
@@ -2272,9 +2364,9 @@ class Variable extends ExpressionEntity {
2272
2364
  * has not been included previously. Once a variable is included, it should
2273
2365
  * take care all its declarations are included.
2274
2366
  */
2275
- include() {
2367
+ includePath(path, context) {
2276
2368
  this.included = true;
2277
- this.renderedLikeHoisted?.include();
2369
+ this.renderedLikeHoisted?.includePath(path, context);
2278
2370
  }
2279
2371
  /**
2280
2372
  * Links the rendered name of this variable to another variable and includes
@@ -2306,8 +2398,8 @@ class ExternalVariable extends Variable {
2306
2398
  hasEffectsOnInteractionAtPath(path, { type }) {
2307
2399
  return type !== INTERACTION_ACCESSED || path.length > (this.isNamespace ? 1 : 0);
2308
2400
  }
2309
- include() {
2310
- super.include();
2401
+ includePath(path, context) {
2402
+ super.includePath(path, context);
2311
2403
  this.module.used = true;
2312
2404
  }
2313
2405
  }
@@ -2608,36 +2700,6 @@ const childNodeKeys = {
2608
2700
  YieldExpression: ['argument']
2609
2701
  };
2610
2702
 
2611
- function createInclusionContext() {
2612
- return {
2613
- brokenFlow: false,
2614
- hasBreak: false,
2615
- hasContinue: false,
2616
- includedCallArguments: new Set(),
2617
- includedLabels: new Set()
2618
- };
2619
- }
2620
- function createHasEffectsContext() {
2621
- return {
2622
- accessed: new PathTracker(),
2623
- assigned: new PathTracker(),
2624
- brokenFlow: false,
2625
- called: new DiscriminatedPathTracker(),
2626
- hasBreak: false,
2627
- hasContinue: false,
2628
- ignore: {
2629
- breaks: false,
2630
- continues: false,
2631
- labels: new Set(),
2632
- returnYield: false,
2633
- this: false
2634
- },
2635
- includedLabels: new Set(),
2636
- instantiated: new DiscriminatedPathTracker(),
2637
- replacedVariableInits: new Map()
2638
- };
2639
- }
2640
-
2641
2703
  const INCLUDE_PARAMETERS = 'variables';
2642
2704
  const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN');
2643
2705
  class NodeBase extends ExpressionEntity {
@@ -2707,9 +2769,8 @@ class NodeBase extends ExpressionEntity {
2707
2769
  this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));
2708
2770
  }
2709
2771
  include(context, includeChildrenRecursively, _options) {
2710
- if (!this.deoptimized)
2711
- this.applyDeoptimizations();
2712
- this.included = true;
2772
+ if (!this.included)
2773
+ this.includeNode(context);
2713
2774
  for (const key of childNodeKeys[this.type]) {
2714
2775
  const value = this[key];
2715
2776
  if (value === null)
@@ -2724,6 +2785,24 @@ class NodeBase extends ExpressionEntity {
2724
2785
  }
2725
2786
  }
2726
2787
  }
2788
+ includeNode(context) {
2789
+ this.included = true;
2790
+ if (!this.deoptimized)
2791
+ this.applyDeoptimizations();
2792
+ for (const key of childNodeKeys[this.type]) {
2793
+ const value = this[key];
2794
+ if (value === null)
2795
+ continue;
2796
+ if (Array.isArray(value)) {
2797
+ for (const child of value) {
2798
+ child?.includePath(UNKNOWN_PATH, context);
2799
+ }
2800
+ }
2801
+ else {
2802
+ value.includePath(UNKNOWN_PATH, context);
2803
+ }
2804
+ }
2805
+ }
2727
2806
  includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {
2728
2807
  this.include(context, includeChildrenRecursively);
2729
2808
  }
@@ -2827,6 +2906,17 @@ class NodeBase extends ExpressionEntity {
2827
2906
  function createChildNodeKeysForNode(esTreeNode) {
2828
2907
  return Object.keys(esTreeNode).filter(key => typeof esTreeNode[key] === 'object' && key.charCodeAt(0) !== 95 /* _ */);
2829
2908
  }
2909
+ function onlyIncludeSelf() {
2910
+ this.included = true;
2911
+ if (!this.deoptimized)
2912
+ this.applyDeoptimizations();
2913
+ }
2914
+ function onlyIncludeSelfNoDeoptimize() {
2915
+ this.included = true;
2916
+ }
2917
+ function doNotDeoptimize() {
2918
+ this.deoptimized = true;
2919
+ }
2830
2920
 
2831
2921
  function isObjectExpressionNode(node) {
2832
2922
  return node instanceof NodeBase && node.type === ObjectExpression$1;
@@ -2839,8 +2929,8 @@ function assembleMemberDescriptions(memberDescriptions, inheritedDescriptions =
2839
2929
  return Object.create(inheritedDescriptions, memberDescriptions);
2840
2930
  }
2841
2931
  const UNDEFINED_EXPRESSION = new (class UndefinedExpression extends ExpressionEntity {
2842
- getLiteralValueAtPath() {
2843
- return undefined;
2932
+ getLiteralValueAtPath(path) {
2933
+ return path.length > 0 ? UnknownValue : undefined;
2844
2934
  }
2845
2935
  })();
2846
2936
  const returnsUnknown = {
@@ -3037,31 +3127,6 @@ function getMemberReturnExpressionWhenCalled(members, memberName) {
3037
3127
  return [members[memberName].returns, false];
3038
3128
  }
3039
3129
 
3040
- class SpreadElement extends NodeBase {
3041
- deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
3042
- if (path.length > 0) {
3043
- this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker);
3044
- }
3045
- }
3046
- hasEffects(context) {
3047
- if (!this.deoptimized)
3048
- this.applyDeoptimizations();
3049
- const { propertyReadSideEffects } = this.scope.context.options
3050
- .treeshake;
3051
- return (this.argument.hasEffects(context) ||
3052
- (propertyReadSideEffects &&
3053
- (propertyReadSideEffects === 'always' ||
3054
- this.argument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context))));
3055
- }
3056
- applyDeoptimizations() {
3057
- this.deoptimized = true;
3058
- // Only properties of properties of the argument could become subject to reassignment
3059
- // This will also reassign the return values of iterators
3060
- this.argument.deoptimizePath([UnknownKey, UnknownKey]);
3061
- this.scope.context.requestTreeshakingPass();
3062
- }
3063
- }
3064
-
3065
3130
  class Method extends ExpressionEntity {
3066
3131
  constructor(description) {
3067
3132
  super();
@@ -3187,6 +3252,7 @@ class ObjectEntity extends ExpressionEntity {
3187
3252
  this.unknownIntegerProps = [];
3188
3253
  this.unmatchableGetters = [];
3189
3254
  this.unmatchablePropertiesAndGetters = [];
3255
+ this.unmatchablePropertiesAndSetters = [];
3190
3256
  this.unmatchableSetters = [];
3191
3257
  if (Array.isArray(properties)) {
3192
3258
  this.buildPropertyMaps(properties);
@@ -3343,7 +3409,12 @@ class ObjectEntity extends ExpressionEntity {
3343
3409
  }
3344
3410
  getLiteralValueAtPath(path, recursionTracker, origin) {
3345
3411
  if (path.length === 0) {
3346
- return UnknownTruthyValue;
3412
+ // This should actually be "UnknownTruthyValue". However, this currently
3413
+ // causes an issue with TypeScript enums in files with moduleSideEffects:
3414
+ // false because we cannot properly track whether a "var" has been
3415
+ // initialized. This should be reverted once we can properly track this.
3416
+ // return UnknownTruthyValue;
3417
+ return UnknownValue;
3347
3418
  }
3348
3419
  const key = path[0];
3349
3420
  const expressionAtPath = this.getMemberExpressionAndTrackDeopt(key, origin);
@@ -3421,9 +3492,38 @@ class ObjectEntity extends ExpressionEntity {
3421
3492
  }
3422
3493
  return false;
3423
3494
  }
3495
+ include(context, includeChildrenRecursively) {
3496
+ this.included = true;
3497
+ for (const property of this.allProperties) {
3498
+ if (includeChildrenRecursively || property.shouldBeIncluded(context)) {
3499
+ property.include(context, includeChildrenRecursively);
3500
+ }
3501
+ }
3502
+ this.prototypeExpression?.include(context, includeChildrenRecursively);
3503
+ }
3504
+ includePath(path, context) {
3505
+ this.included = true;
3506
+ if (path.length === 0)
3507
+ return;
3508
+ const [key, ...subPath] = path;
3509
+ const [includedMembers, includedPath] = typeof key === 'string'
3510
+ ? [
3511
+ [
3512
+ ...new Set([
3513
+ ...(this.propertiesAndGettersByKey[key] || this.unmatchablePropertiesAndGetters),
3514
+ ...(this.propertiesAndSettersByKey[key] || this.unmatchablePropertiesAndSetters)
3515
+ ])
3516
+ ],
3517
+ subPath
3518
+ ]
3519
+ : [this.allProperties, UNKNOWN_PATH];
3520
+ for (const property of includedMembers) {
3521
+ property.includePath(includedPath, context);
3522
+ }
3523
+ this.prototypeExpression?.includePath(path, context);
3524
+ }
3424
3525
  buildPropertyMaps(properties) {
3425
- const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchableGetters, unmatchableSetters } = this;
3426
- const unmatchablePropertiesAndSetters = [];
3526
+ const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchablePropertiesAndSetters, unmatchableGetters, unmatchableSetters } = this;
3427
3527
  for (let index = properties.length - 1; index >= 0; index--) {
3428
3528
  const { key, kind, property } = properties[index];
3429
3529
  allProperties.push(property);
@@ -3693,6 +3793,37 @@ const ARRAY_PROTOTYPE = new ObjectEntity({
3693
3793
  values: METHOD_DEOPTS_SELF_RETURNS_UNKNOWN
3694
3794
  }, OBJECT_PROTOTYPE, true);
3695
3795
 
3796
+ class SpreadElement extends NodeBase {
3797
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
3798
+ if (path.length > 0) {
3799
+ this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker);
3800
+ }
3801
+ }
3802
+ hasEffects(context) {
3803
+ if (!this.deoptimized)
3804
+ this.applyDeoptimizations();
3805
+ const { propertyReadSideEffects } = this.scope.context.options
3806
+ .treeshake;
3807
+ return (this.argument.hasEffects(context) ||
3808
+ (propertyReadSideEffects &&
3809
+ (propertyReadSideEffects === 'always' ||
3810
+ this.argument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context))));
3811
+ }
3812
+ includeNode(context) {
3813
+ this.included = true;
3814
+ if (!this.deoptimized)
3815
+ this.applyDeoptimizations();
3816
+ this.argument.includePath(UNKNOWN_PATH, context);
3817
+ }
3818
+ applyDeoptimizations() {
3819
+ this.deoptimized = true;
3820
+ // Only properties of properties of the argument could become subject to reassignment
3821
+ // This will also reassign the return values of iterators
3822
+ this.argument.deoptimizePath([UnknownKey, UnknownKey]);
3823
+ this.scope.context.requestTreeshakingPass();
3824
+ }
3825
+ }
3826
+
3696
3827
  class ArrayExpression extends NodeBase {
3697
3828
  constructor() {
3698
3829
  super(...arguments);
@@ -3713,6 +3844,16 @@ class ArrayExpression extends NodeBase {
3713
3844
  hasEffectsOnInteractionAtPath(path, interaction, context) {
3714
3845
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
3715
3846
  }
3847
+ includeNode(context) {
3848
+ this.included = true;
3849
+ if (!this.deoptimized)
3850
+ this.applyDeoptimizations();
3851
+ for (const element of this.elements) {
3852
+ if (element) {
3853
+ element?.includePath(UNKNOWN_PATH, context);
3854
+ }
3855
+ }
3856
+ }
3716
3857
  applyDeoptimizations() {
3717
3858
  this.deoptimized = true;
3718
3859
  let hasSpread = false;
@@ -4780,17 +4921,37 @@ class GlobalVariable extends Variable {
4780
4921
  }
4781
4922
  }
4782
4923
 
4924
+ // To avoid infinite recursions
4925
+ const MAX_PATH_DEPTH = 6;
4926
+ // If a path is longer than MAX_PATH_DEPTH, it is truncated so that it is at
4927
+ // most MAX_PATH_DEPTH long. The last element is always UnknownKey
4928
+ const limitConcatenatedPathDepth = (path1, path2) => {
4929
+ const { length: length1 } = path1;
4930
+ const { length: length2 } = path2;
4931
+ return length1 === 0
4932
+ ? path2
4933
+ : length2 === 0
4934
+ ? path1
4935
+ : length1 + length2 > MAX_PATH_DEPTH
4936
+ ? [...path1, ...path2.slice(0, MAX_PATH_DEPTH - 1 - path1.length), 'UnknownKey']
4937
+ : [...path1, ...path2];
4938
+ };
4939
+
4783
4940
  class LocalVariable extends Variable {
4784
- constructor(name, declarator, init, context, kind) {
4941
+ constructor(name, declarator, init,
4942
+ /** if this is non-empty, the actual init is this path of this.init */
4943
+ initPath, context, kind) {
4785
4944
  super(name);
4786
4945
  this.init = init;
4946
+ this.initPath = initPath;
4947
+ this.kind = kind;
4787
4948
  this.calledFromTryStatement = false;
4788
4949
  this.additionalInitializers = null;
4950
+ this.includedPathTracker = new IncludedPathTracker();
4789
4951
  this.expressionsToBeDeoptimized = [];
4790
4952
  this.declarations = declarator ? [declarator] : [];
4791
4953
  this.deoptimizationTracker = context.deoptimizationTracker;
4792
4954
  this.module = context.module;
4793
- this.kind = kind;
4794
4955
  }
4795
4956
  addDeclaration(identifier, init) {
4796
4957
  this.declarations.push(identifier);
@@ -4801,15 +4962,16 @@ class LocalVariable extends Variable {
4801
4962
  for (const initializer of this.additionalInitializers) {
4802
4963
  initializer.deoptimizePath(UNKNOWN_PATH);
4803
4964
  }
4804
- this.additionalInitializers = null;
4805
4965
  }
4806
4966
  }
4807
4967
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
4808
- if (this.isReassigned) {
4968
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
4809
4969
  deoptimizeInteraction(interaction);
4810
4970
  return;
4811
4971
  }
4812
- recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker), undefined);
4972
+ recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
4973
+ this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], recursionTracker);
4974
+ }, undefined);
4813
4975
  }
4814
4976
  deoptimizePath(path) {
4815
4977
  if (this.isReassigned ||
@@ -4823,37 +4985,40 @@ class LocalVariable extends Variable {
4823
4985
  for (const expression of expressionsToBeDeoptimized) {
4824
4986
  expression.deoptimizeCache();
4825
4987
  }
4826
- this.init.deoptimizePath(UNKNOWN_PATH);
4988
+ this.init.deoptimizePath([...this.initPath, UnknownKey]);
4827
4989
  }
4828
4990
  else {
4829
- this.init.deoptimizePath(path);
4991
+ this.init.deoptimizePath(limitConcatenatedPathDepth(this.initPath, path));
4830
4992
  }
4831
4993
  }
4832
4994
  getLiteralValueAtPath(path, recursionTracker, origin) {
4833
- if (this.isReassigned) {
4995
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
4834
4996
  return UnknownValue;
4835
4997
  }
4836
4998
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
4837
4999
  this.expressionsToBeDeoptimized.push(origin);
4838
- return this.init.getLiteralValueAtPath(path, recursionTracker, origin);
5000
+ return this.init.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin);
4839
5001
  }, UnknownValue);
4840
5002
  }
4841
5003
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
4842
- if (this.isReassigned) {
5004
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
4843
5005
  return UNKNOWN_RETURN_EXPRESSION;
4844
5006
  }
4845
5007
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
4846
5008
  this.expressionsToBeDeoptimized.push(origin);
4847
- return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
5009
+ return this.init.getReturnExpressionWhenCalledAtPath([...this.initPath, ...path], interaction, recursionTracker, origin);
4848
5010
  }, UNKNOWN_RETURN_EXPRESSION);
4849
5011
  }
4850
5012
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5013
+ if (path.length + this.initPath.length > MAX_PATH_DEPTH) {
5014
+ return true;
5015
+ }
4851
5016
  switch (interaction.type) {
4852
5017
  case INTERACTION_ACCESSED: {
4853
5018
  if (this.isReassigned)
4854
5019
  return true;
4855
5020
  return (!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
4856
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
5021
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4857
5022
  }
4858
5023
  case INTERACTION_ASSIGNED: {
4859
5024
  if (this.included)
@@ -4863,44 +5028,63 @@ class LocalVariable extends Variable {
4863
5028
  if (this.isReassigned)
4864
5029
  return true;
4865
5030
  return (!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
4866
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
5031
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4867
5032
  }
4868
5033
  case INTERACTION_CALLED: {
4869
5034
  if (this.isReassigned)
4870
5035
  return true;
4871
5036
  return (!(interaction.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this) &&
4872
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
5037
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4873
5038
  }
4874
5039
  }
4875
5040
  }
4876
- include() {
4877
- if (!this.included) {
4878
- super.include();
5041
+ includePath(path, context) {
5042
+ if (!this.includedPathTracker.includePathAndGetIfIncluded(path)) {
5043
+ this.module.scope.context.requestTreeshakingPass();
5044
+ if (!this.included) {
5045
+ // This will reduce the number of tree-shaking passes by eagerly
5046
+ // including inits. By pushing this here instead of directly including
5047
+ // we avoid deep call stacks.
5048
+ this.module.scope.context.newlyIncludedVariableInits.add(this.init);
5049
+ }
5050
+ super.includePath(path, context);
4879
5051
  for (const declaration of this.declarations) {
4880
5052
  // If node is a default export, it can save a tree-shaking run to include the full declaration now
4881
5053
  if (!declaration.included)
4882
- declaration.include(createInclusionContext(), false);
5054
+ declaration.include(context, false);
4883
5055
  let node = declaration.parent;
4884
5056
  while (!node.included) {
4885
5057
  // We do not want to properly include parents in case they are part of a dead branch
4886
5058
  // in which case .include() might pull in more dead code
4887
- node.included = true;
5059
+ node.includeNode(context);
4888
5060
  if (node.type === Program$1)
4889
5061
  break;
4890
5062
  node = node.parent;
4891
5063
  }
4892
5064
  }
5065
+ // We need to make sure we include the correct path of the init
5066
+ if (path.length > 0) {
5067
+ this.init.includePath(limitConcatenatedPathDepth(this.initPath, path), context);
5068
+ this.additionalInitializers?.forEach(initializer => initializer.includePath(UNKNOWN_PATH, context));
5069
+ }
4893
5070
  }
4894
5071
  }
4895
- includeCallArguments(context, parameters) {
4896
- if (this.isReassigned || context.includedCallArguments.has(this.init)) {
4897
- for (const argument of parameters) {
4898
- argument.include(context, false);
5072
+ includeCallArguments(context, interaction) {
5073
+ if (this.isReassigned ||
5074
+ context.includedCallArguments.has(this.init) ||
5075
+ // This can be removed again once we can include arguments when called at
5076
+ // a specific path
5077
+ this.initPath.length > 0) {
5078
+ for (const argument of interaction.args) {
5079
+ if (argument) {
5080
+ argument.includePath(UNKNOWN_PATH, context);
5081
+ argument.include(context, false);
5082
+ }
4899
5083
  }
4900
5084
  }
4901
5085
  else {
4902
5086
  context.includedCallArguments.add(this.init);
4903
- this.init.includeCallArguments(context, parameters);
5087
+ this.init.includeCallArguments(context, interaction);
4904
5088
  context.includedCallArguments.delete(this.init);
4905
5089
  }
4906
5090
  }
@@ -4980,18 +5164,31 @@ class IdentifierBase extends NodeBase {
4980
5164
  }
4981
5165
  }
4982
5166
  }
4983
- include() {
5167
+ include(context) {
5168
+ if (!this.included)
5169
+ this.includeNode(context);
5170
+ }
5171
+ includeNode(context) {
5172
+ this.included = true;
4984
5173
  if (!this.deoptimized)
4985
5174
  this.applyDeoptimizations();
5175
+ if (this.variable !== null) {
5176
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
5177
+ }
5178
+ }
5179
+ includePath(path, context) {
4986
5180
  if (!this.included) {
4987
5181
  this.included = true;
4988
5182
  if (this.variable !== null) {
4989
- this.scope.context.includeVariableInModule(this.variable);
5183
+ this.scope.context.includeVariableInModule(this.variable, path, context);
4990
5184
  }
4991
5185
  }
5186
+ else if (path.length > 0) {
5187
+ this.variable?.includePath(path, context);
5188
+ }
4992
5189
  }
4993
- includeCallArguments(context, parameters) {
4994
- this.variable.includeCallArguments(context, parameters);
5190
+ includeCallArguments(context, interaction) {
5191
+ this.variable.includeCallArguments(context, interaction);
4995
5192
  }
4996
5193
  isPossibleTDZ() {
4997
5194
  // return cached value to avoid issues with the next tree-shaking pass
@@ -5074,11 +5271,40 @@ function closestParentFunctionOrProgram(node) {
5074
5271
  return node;
5075
5272
  }
5076
5273
 
5274
+ class ObjectMember extends ExpressionEntity {
5275
+ constructor(object, path) {
5276
+ super();
5277
+ this.object = object;
5278
+ this.path = path;
5279
+ }
5280
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
5281
+ this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.path, ...path], recursionTracker);
5282
+ }
5283
+ deoptimizePath(path) {
5284
+ this.object.deoptimizePath([...this.path, ...path]);
5285
+ }
5286
+ getLiteralValueAtPath(path, recursionTracker, origin) {
5287
+ return this.object.getLiteralValueAtPath([...this.path, ...path], recursionTracker, origin);
5288
+ }
5289
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
5290
+ return this.object.getReturnExpressionWhenCalledAtPath([...this.path, ...path], interaction, recursionTracker, origin);
5291
+ }
5292
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
5293
+ return this.object.hasEffectsOnInteractionAtPath([...this.path, ...path], interaction, context);
5294
+ }
5295
+ }
5296
+
5077
5297
  class Identifier extends IdentifierBase {
5078
5298
  constructor() {
5079
5299
  super(...arguments);
5080
5300
  this.variable = null;
5081
5301
  }
5302
+ get isDestructuringDeoptimized() {
5303
+ return isFlagSet(this.flags, 16777216 /* Flag.destructuringDeoptimized */);
5304
+ }
5305
+ set isDestructuringDeoptimized(value) {
5306
+ this.flags = setFlag(this.flags, 16777216 /* Flag.destructuringDeoptimized */, value);
5307
+ }
5082
5308
  addExportedVariables(variables, exportNamesByVariable) {
5083
5309
  if (exportNamesByVariable.has(this.variable)) {
5084
5310
  variables.push(this.variable);
@@ -5091,43 +5317,53 @@ class Identifier extends IdentifierBase {
5091
5317
  this.isVariableReference = true;
5092
5318
  }
5093
5319
  }
5094
- declare(kind, init) {
5320
+ declare(kind, destructuredInitPath, init) {
5095
5321
  let variable;
5096
5322
  const { treeshake } = this.scope.context.options;
5097
- switch (kind) {
5098
- case 'var': {
5099
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5100
- if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
5101
- // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
5102
- variable.markInitializersForDeoptimization();
5103
- }
5104
- break;
5105
- }
5106
- case 'function': {
5107
- // in strict mode, functions are only hoisted within a scope but not across block scopes
5108
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5109
- break;
5110
- }
5111
- case 'let':
5112
- case 'const':
5113
- case 'using':
5114
- case 'await using':
5115
- case 'class': {
5116
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5117
- break;
5118
- }
5119
- case 'parameter': {
5120
- variable = this.scope.addParameterDeclaration(this);
5121
- break;
5122
- }
5123
- /* istanbul ignore next */
5124
- default: {
5125
- /* istanbul ignore next */
5126
- throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
5323
+ if (kind === 'parameter') {
5324
+ variable = this.scope.addParameterDeclaration(this, destructuredInitPath);
5325
+ }
5326
+ else {
5327
+ variable = this.scope.addDeclaration(this, this.scope.context, init, destructuredInitPath, kind);
5328
+ if (kind === 'var' && treeshake && treeshake.correctVarValueBeforeDeclaration) {
5329
+ // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
5330
+ variable.markInitializersForDeoptimization();
5127
5331
  }
5128
5332
  }
5129
5333
  return [(this.variable = variable)];
5130
5334
  }
5335
+ deoptimizeAssignment(destructuredInitPath, init) {
5336
+ this.deoptimizePath(EMPTY_PATH);
5337
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
5338
+ }
5339
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
5340
+ return (destructuredInitPath.length > 0 &&
5341
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
5342
+ }
5343
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
5344
+ if (destructuredInitPath.length > 0 && !this.isDestructuringDeoptimized) {
5345
+ this.isDestructuringDeoptimized = true;
5346
+ init.deoptimizeArgumentsOnInteractionAtPath({
5347
+ args: [new ObjectMember(init, destructuredInitPath.slice(0, -1))],
5348
+ type: INTERACTION_ACCESSED
5349
+ }, destructuredInitPath, SHARED_RECURSION_TRACKER);
5350
+ }
5351
+ const { propertyReadSideEffects } = this.scope.context.options
5352
+ .treeshake;
5353
+ if ((this.included ||=
5354
+ destructuredInitPath.length > 0 &&
5355
+ !context.brokenFlow &&
5356
+ propertyReadSideEffects &&
5357
+ (propertyReadSideEffects === 'always' ||
5358
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext())))) {
5359
+ if (this.variable && !this.variable.included) {
5360
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
5361
+ }
5362
+ init.includePath(destructuredInitPath, context);
5363
+ return true;
5364
+ }
5365
+ return false;
5366
+ }
5131
5367
  markDeclarationReached() {
5132
5368
  this.variable.initReached = true;
5133
5369
  }
@@ -5192,18 +5428,17 @@ class Scope {
5192
5428
  - then the variable is still declared in the hoisted outer scope, but the initializer is assigned to the parameter
5193
5429
  - const, let, class, and function except in the cases above cannot redeclare anything
5194
5430
  */
5195
- addDeclaration(identifier, context, init, kind) {
5431
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5196
5432
  const name = identifier.name;
5197
5433
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
5198
5434
  if (existingVariable) {
5199
- const existingKind = existingVariable.kind;
5200
- if (kind === 'var' && existingKind === 'var') {
5435
+ if (kind === 'var' && existingVariable.kind === 'var') {
5201
5436
  existingVariable.addDeclaration(identifier, init);
5202
5437
  return existingVariable;
5203
5438
  }
5204
5439
  context.error(logRedeclarationError(name), identifier.start);
5205
5440
  }
5206
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
5441
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
5207
5442
  this.variables.set(name, newVariable);
5208
5443
  return newVariable;
5209
5444
  }
@@ -5379,7 +5614,6 @@ class MethodBase extends NodeBase {
5379
5614
  }
5380
5615
  return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context);
5381
5616
  }
5382
- applyDeoptimizations() { }
5383
5617
  getAccessedValue() {
5384
5618
  if (this.accessedValue === null) {
5385
5619
  if (this.kind === 'get') {
@@ -5393,19 +5627,20 @@ class MethodBase extends NodeBase {
5393
5627
  return this.accessedValue;
5394
5628
  }
5395
5629
  }
5630
+ MethodBase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
5631
+ MethodBase.prototype.applyDeoptimizations = doNotDeoptimize;
5396
5632
 
5397
5633
  class MethodDefinition extends MethodBase {
5398
5634
  hasEffects(context) {
5399
5635
  return super.hasEffects(context) || checkEffectForNodes(this.decorators, context);
5400
5636
  }
5401
- applyDeoptimizations() { }
5402
5637
  }
5403
5638
 
5404
5639
  class BlockScope extends ChildScope {
5405
5640
  constructor(parent) {
5406
5641
  super(parent, parent.context);
5407
5642
  }
5408
- addDeclaration(identifier, context, init, kind) {
5643
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5409
5644
  if (kind === 'var') {
5410
5645
  const name = identifier.name;
5411
5646
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -5417,7 +5652,7 @@ class BlockScope extends ChildScope {
5417
5652
  }
5418
5653
  return context.error(logRedeclarationError(name), identifier.start);
5419
5654
  }
5420
- const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind);
5655
+ const declaredVariable = this.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5421
5656
  // Necessary to make sure the init is deoptimized for conditional declarations.
5422
5657
  // We cannot call deoptimizePath here.
5423
5658
  declaredVariable.markInitializersForDeoptimization();
@@ -5425,7 +5660,7 @@ class BlockScope extends ChildScope {
5425
5660
  this.addHoistedVariable(name, declaredVariable);
5426
5661
  return declaredVariable;
5427
5662
  }
5428
- return super.addDeclaration(identifier, context, init, kind);
5663
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5429
5664
  }
5430
5665
  }
5431
5666
 
@@ -5457,33 +5692,12 @@ class StaticBlock extends NodeBase {
5457
5692
  }
5458
5693
  }
5459
5694
  }
5695
+ StaticBlock.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
5696
+ StaticBlock.prototype.applyDeoptimizations = doNotDeoptimize;
5460
5697
  function isStaticBlock(statement) {
5461
5698
  return statement.type === StaticBlock$1;
5462
5699
  }
5463
5700
 
5464
- class ObjectMember extends ExpressionEntity {
5465
- constructor(object, key) {
5466
- super();
5467
- this.object = object;
5468
- this.key = key;
5469
- }
5470
- deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
5471
- this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker);
5472
- }
5473
- deoptimizePath(path) {
5474
- this.object.deoptimizePath([this.key, ...path]);
5475
- }
5476
- getLiteralValueAtPath(path, recursionTracker, origin) {
5477
- return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin);
5478
- }
5479
- getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
5480
- return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin);
5481
- }
5482
- hasEffectsOnInteractionAtPath(path, interaction, context) {
5483
- return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context);
5484
- }
5485
- }
5486
-
5487
5701
  class ClassNode extends NodeBase {
5488
5702
  constructor() {
5489
5703
  super(...arguments);
@@ -5524,21 +5738,20 @@ class ClassNode extends NodeBase {
5524
5738
  : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
5525
5739
  }
5526
5740
  include(context, includeChildrenRecursively) {
5527
- if (!this.deoptimized)
5528
- this.applyDeoptimizations();
5529
- this.included = true;
5741
+ if (!this.included)
5742
+ this.includeNode(context);
5530
5743
  this.superClass?.include(context, includeChildrenRecursively);
5531
5744
  this.body.include(context, includeChildrenRecursively);
5532
5745
  for (const decorator of this.decorators)
5533
5746
  decorator.include(context, includeChildrenRecursively);
5534
5747
  if (this.id) {
5535
5748
  this.id.markDeclarationReached();
5536
- this.id.include();
5749
+ this.id.include(context);
5537
5750
  }
5538
5751
  }
5539
5752
  initialise() {
5540
5753
  super.initialise();
5541
- this.id?.declare('class', this);
5754
+ this.id?.declare('class', EMPTY_PATH, this);
5542
5755
  for (const method of this.body.body) {
5543
5756
  if (method instanceof MethodDefinition && method.kind === 'constructor') {
5544
5757
  this.classConstructor = method;
@@ -5596,11 +5809,12 @@ class ClassNode extends NodeBase {
5596
5809
  staticProperties.unshift({
5597
5810
  key: 'prototype',
5598
5811
  kind: 'init',
5599
- property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE)
5812
+ property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, ['prototype']) : OBJECT_PROTOTYPE)
5600
5813
  });
5601
5814
  return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE));
5602
5815
  }
5603
5816
  }
5817
+ ClassNode.prototype.includeNode = onlyIncludeSelf;
5604
5818
 
5605
5819
  class ClassDeclaration extends ClassNode {
5606
5820
  initialise() {
@@ -5653,7 +5867,7 @@ class ClassDeclaration extends ClassNode {
5653
5867
 
5654
5868
  class ArgumentsVariable extends LocalVariable {
5655
5869
  constructor(context) {
5656
- super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');
5870
+ super('arguments', null, UNKNOWN_EXPRESSION, EMPTY_PATH, context, 'other');
5657
5871
  this.deoptimizedArguments = [];
5658
5872
  }
5659
5873
  addArgumentToBeDeoptimized(argument) {
@@ -5667,8 +5881,8 @@ class ArgumentsVariable extends LocalVariable {
5667
5881
  hasEffectsOnInteractionAtPath(path, { type }) {
5668
5882
  return type !== INTERACTION_ACCESSED || path.length > 1;
5669
5883
  }
5670
- include() {
5671
- super.include();
5884
+ includePath(path, context) {
5885
+ super.includePath(path, context);
5672
5886
  for (const argument of this.deoptimizedArguments) {
5673
5887
  argument.deoptimizePath(UNKNOWN_PATH);
5674
5888
  }
@@ -5679,27 +5893,28 @@ class ArgumentsVariable extends LocalVariable {
5679
5893
  const MAX_TRACKED_INTERACTIONS = 20;
5680
5894
  const NO_INTERACTIONS = EMPTY_ARRAY;
5681
5895
  const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);
5682
- const EMPTY_PATH_TRACKER = new PathTracker();
5896
+ const EMPTY_PATH_TRACKER = new EntityPathTracker();
5683
5897
  const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);
5684
5898
  class ParameterVariable extends LocalVariable {
5685
- constructor(name, declarator, context) {
5686
- super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');
5899
+ constructor(name, declarator, argumentPath, context) {
5900
+ super(name, declarator, UNKNOWN_EXPRESSION, argumentPath, context, 'parameter');
5687
5901
  this.deoptimizationInteractions = [];
5688
- this.deoptimizations = new PathTracker();
5902
+ this.deoptimizations = new EntityPathTracker();
5689
5903
  this.deoptimizedFields = new Set();
5690
- this.entitiesToBeDeoptimized = new Set();
5691
- this.expressionsUseTheKnownValue = [];
5904
+ this.argumentsToBeDeoptimized = new Set();
5905
+ this.expressionsDependingOnKnownValue = [];
5692
5906
  this.knownValue = null;
5693
5907
  this.knownValueLiteral = UnknownValue;
5694
5908
  this.frozenValue = null;
5695
5909
  }
5696
- addEntityToBeDeoptimized(entity) {
5910
+ addArgumentValue(entity) {
5911
+ this.updateKnownValue(entity);
5697
5912
  if (entity === UNKNOWN_EXPRESSION) {
5698
5913
  // As unknown expressions fully deoptimize all interactions, we can clear
5699
5914
  // the interaction cache at this point provided we keep this optimization
5700
5915
  // in mind when adding new interactions
5701
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5702
- this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);
5916
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5917
+ this.argumentsToBeDeoptimized.add(UNKNOWN_EXPRESSION);
5703
5918
  for (const { interaction } of this.deoptimizationInteractions) {
5704
5919
  deoptimizeInteraction(interaction);
5705
5920
  }
@@ -5709,27 +5924,34 @@ class ParameterVariable extends LocalVariable {
5709
5924
  else if (this.deoptimizedFields.has(UnknownKey)) {
5710
5925
  // This means that we already deoptimized all interactions and no longer
5711
5926
  // track them
5712
- entity.deoptimizePath(UNKNOWN_PATH);
5927
+ entity.deoptimizePath([...this.initPath, UnknownKey]);
5713
5928
  }
5714
- else if (!this.entitiesToBeDeoptimized.has(entity)) {
5715
- this.entitiesToBeDeoptimized.add(entity);
5929
+ else if (!this.argumentsToBeDeoptimized.has(entity)) {
5930
+ this.argumentsToBeDeoptimized.add(entity);
5716
5931
  for (const field of this.deoptimizedFields) {
5717
- entity.deoptimizePath([field]);
5932
+ entity.deoptimizePath([...this.initPath, field]);
5718
5933
  }
5719
5934
  for (const { interaction, path } of this.deoptimizationInteractions) {
5720
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
5935
+ if (this.initPath.length + path.length > MAX_PATH_DEPTH) {
5936
+ deoptimizeInteraction(interaction);
5937
+ continue;
5938
+ }
5939
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
5721
5940
  }
5722
5941
  }
5723
5942
  }
5943
+ /** This says we should not make assumptions about the value of the parameter.
5944
+ * This is different from deoptimization that will also cause argument values
5945
+ * to be deoptimized. */
5724
5946
  markReassigned() {
5725
5947
  if (this.isReassigned) {
5726
5948
  return;
5727
5949
  }
5728
5950
  super.markReassigned();
5729
- for (const expression of this.expressionsUseTheKnownValue) {
5951
+ for (const expression of this.expressionsDependingOnKnownValue) {
5730
5952
  expression.deoptimizeCache();
5731
5953
  }
5732
- this.expressionsUseTheKnownValue = EMPTY_ARRAY;
5954
+ this.expressionsDependingOnKnownValue = EMPTY_ARRAY;
5733
5955
  }
5734
5956
  deoptimizeCache() {
5735
5957
  this.markReassigned();
@@ -5746,7 +5968,7 @@ class ParameterVariable extends LocalVariable {
5746
5968
  }
5747
5969
  if (this.knownValue === null) {
5748
5970
  this.knownValue = argument;
5749
- this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
5971
+ this.knownValueLiteral = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
5750
5972
  return;
5751
5973
  }
5752
5974
  // the same literal or identifier, do nothing
@@ -5762,7 +5984,7 @@ class ParameterVariable extends LocalVariable {
5762
5984
  return;
5763
5985
  }
5764
5986
  // add tracking for the new argument
5765
- const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
5987
+ const newValue = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
5766
5988
  if (newValue !== oldValue) {
5767
5989
  this.markReassigned();
5768
5990
  }
@@ -5780,24 +6002,31 @@ class ParameterVariable extends LocalVariable {
5780
6002
  return this.frozenValue;
5781
6003
  }
5782
6004
  getLiteralValueAtPath(path, recursionTracker, origin) {
5783
- if (this.isReassigned) {
6005
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
5784
6006
  return UnknownValue;
5785
6007
  }
5786
6008
  const knownValue = this.getKnownValue();
5787
- this.expressionsUseTheKnownValue.push(origin);
5788
- return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);
6009
+ this.expressionsDependingOnKnownValue.push(origin);
6010
+ return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin), UnknownValue);
5789
6011
  }
5790
6012
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5791
- if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) {
6013
+ const { type } = interaction;
6014
+ if (this.isReassigned ||
6015
+ type === INTERACTION_ASSIGNED ||
6016
+ path.length + this.initPath.length > MAX_PATH_DEPTH) {
5792
6017
  return super.hasEffectsOnInteractionAtPath(path, interaction, context);
5793
6018
  }
5794
- const knownValue = this.getKnownValue();
5795
- return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context);
6019
+ return (!(type === INTERACTION_CALLED
6020
+ ? (interaction.withNew
6021
+ ? context.instantiated
6022
+ : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)
6023
+ : context.accessed.trackEntityAtPathAndGetIfTracked(path, this)) &&
6024
+ this.getKnownValue().hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
5796
6025
  }
5797
6026
  deoptimizeArgumentsOnInteractionAtPath(interaction, path) {
5798
6027
  // For performance reasons, we fully deoptimize all deeper interactions
5799
6028
  if (path.length >= 2 ||
5800
- this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
6029
+ this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
5801
6030
  this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||
5802
6031
  (path.length === 1 &&
5803
6032
  (this.deoptimizedFields.has(UnknownKey) ||
@@ -5806,10 +6035,10 @@ class ParameterVariable extends LocalVariable {
5806
6035
  return;
5807
6036
  }
5808
6037
  if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {
5809
- for (const entity of this.entitiesToBeDeoptimized) {
5810
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
6038
+ for (const entity of this.argumentsToBeDeoptimized) {
6039
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
5811
6040
  }
5812
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
6041
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5813
6042
  this.deoptimizationInteractions.push({
5814
6043
  interaction,
5815
6044
  path
@@ -5830,17 +6059,17 @@ class ParameterVariable extends LocalVariable {
5830
6059
  return;
5831
6060
  }
5832
6061
  this.deoptimizedFields.add(key);
5833
- for (const entity of this.entitiesToBeDeoptimized) {
6062
+ for (const entity of this.argumentsToBeDeoptimized) {
5834
6063
  // We do not need a recursion tracker here as we already track whether
5835
6064
  // this field is deoptimized
5836
- entity.deoptimizePath([key]);
6065
+ entity.deoptimizePath([...this.initPath, key]);
5837
6066
  }
5838
6067
  if (key === UnknownKey) {
5839
6068
  // save some memory
5840
6069
  this.deoptimizationInteractions = NO_INTERACTIONS;
5841
6070
  this.deoptimizations = EMPTY_PATH_TRACKER;
5842
6071
  this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;
5843
- this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
6072
+ this.argumentsToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
5844
6073
  }
5845
6074
  }
5846
6075
  getReturnExpressionWhenCalledAtPath(path) {
@@ -5855,11 +6084,14 @@ class ParameterVariable extends LocalVariable {
5855
6084
  }
5856
6085
  return UNKNOWN_RETURN_EXPRESSION;
5857
6086
  }
6087
+ includeArgumentPaths(entity, context) {
6088
+ this.includedPathTracker.includeAllPaths(entity, context, this.initPath);
6089
+ }
5858
6090
  }
5859
6091
 
5860
6092
  class ThisVariable extends ParameterVariable {
5861
6093
  constructor(context) {
5862
- super('this', null, context);
6094
+ super('this', null, EMPTY_PATH, context);
5863
6095
  }
5864
6096
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5865
6097
  return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);
@@ -5871,7 +6103,7 @@ class CatchBodyScope extends ChildScope {
5871
6103
  super(parent, parent.context);
5872
6104
  this.parent = parent;
5873
6105
  }
5874
- addDeclaration(identifier, context, init, kind) {
6106
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5875
6107
  if (kind === 'var') {
5876
6108
  const name = identifier.name;
5877
6109
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -5884,7 +6116,7 @@ class CatchBodyScope extends ChildScope {
5884
6116
  // the assignment actually goes to the parameter and the var is
5885
6117
  // hoisted without assignment. Locally, it is shadowed by the
5886
6118
  // parameter
5887
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, kind);
6119
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, destructuredInitPath, kind);
5888
6120
  // To avoid the need to rewrite the declaration, we link the variable
5889
6121
  // names. If we ever implement a logic that splits initialization and
5890
6122
  // assignment for hoisted vars, the "renderLikeHoisted" logic can be
@@ -5903,7 +6135,7 @@ class CatchBodyScope extends ChildScope {
5903
6135
  return context.error(logRedeclarationError(name), identifier.start);
5904
6136
  }
5905
6137
  // We only add parameters to parameter scopes
5906
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, kind);
6138
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5907
6139
  // Necessary to make sure the init is deoptimized for conditional declarations.
5908
6140
  // We cannot call deoptimizePath here.
5909
6141
  declaredVariable.markInitializersForDeoptimization();
@@ -5911,7 +6143,7 @@ class CatchBodyScope extends ChildScope {
5911
6143
  this.addHoistedVariable(name, declaredVariable);
5912
6144
  return declaredVariable;
5913
6145
  }
5914
- return super.addDeclaration(identifier, context, init, kind);
6146
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5915
6147
  }
5916
6148
  }
5917
6149
 
@@ -5921,7 +6153,7 @@ class FunctionBodyScope extends ChildScope {
5921
6153
  }
5922
6154
  // There is stuff that is only allowed in function scopes, i.e. functions can
5923
6155
  // be redeclared, functions and var can redeclare each other
5924
- addDeclaration(identifier, context, init, kind) {
6156
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5925
6157
  const name = identifier.name;
5926
6158
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
5927
6159
  if (existingVariable) {
@@ -5933,7 +6165,7 @@ class FunctionBodyScope extends ChildScope {
5933
6165
  }
5934
6166
  context.error(logRedeclarationError(name), identifier.start);
5935
6167
  }
5936
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
6168
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
5937
6169
  this.variables.set(name, newVariable);
5938
6170
  return newVariable;
5939
6171
  }
@@ -5942,21 +6174,21 @@ class FunctionBodyScope extends ChildScope {
5942
6174
  class ParameterScope extends ChildScope {
5943
6175
  constructor(parent, isCatchScope) {
5944
6176
  super(parent, parent.context);
5945
- this.parameters = [];
5946
6177
  this.hasRest = false;
6178
+ this.parameters = [];
5947
6179
  this.bodyScope = isCatchScope ? new CatchBodyScope(this) : new FunctionBodyScope(this);
5948
6180
  }
5949
6181
  /**
5950
6182
  * Adds a parameter to this scope. Parameters must be added in the correct
5951
6183
  * order, i.e. from left to right.
5952
6184
  */
5953
- addParameterDeclaration(identifier) {
6185
+ addParameterDeclaration(identifier, argumentPath) {
5954
6186
  const { name, start } = identifier;
5955
6187
  const existingParameter = this.variables.get(name);
5956
6188
  if (existingParameter) {
5957
6189
  return this.context.error(logDuplicateArgumentNameError(name), start);
5958
6190
  }
5959
- const variable = new ParameterVariable(name, identifier, this.context);
6191
+ const variable = new ParameterVariable(name, identifier, argumentPath, this.context);
5960
6192
  this.variables.set(name, variable);
5961
6193
  // We also add it to the body scope to detect name conflicts with local
5962
6194
  // variables. We still need the intermediate scope, though, as parameter
@@ -5974,42 +6206,56 @@ class ParameterScope extends ChildScope {
5974
6206
  }
5975
6207
  this.hasRest = hasRest;
5976
6208
  }
5977
- includeCallArguments(context, parameters) {
6209
+ includeCallArguments(context, interaction) {
5978
6210
  let calledFromTryStatement = false;
5979
6211
  let argumentIncluded = false;
5980
6212
  const restParameter = this.hasRest && this.parameters[this.parameters.length - 1];
5981
- for (const checkedArgument of parameters) {
5982
- if (checkedArgument instanceof SpreadElement) {
5983
- for (const argument of parameters) {
5984
- argument.include(context, false);
5985
- }
5986
- break;
6213
+ const { args } = interaction;
6214
+ let lastExplicitlyIncludedIndex = args.length - 1;
6215
+ // If there is a SpreadElement, we need to include all arguments after it
6216
+ // because we no longer know which argument corresponds to which parameter.
6217
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
6218
+ const argument = args[argumentIndex];
6219
+ if (argument instanceof SpreadElement && !argumentIncluded) {
6220
+ argumentIncluded = true;
6221
+ lastExplicitlyIncludedIndex = argumentIndex - 1;
6222
+ }
6223
+ if (argumentIncluded) {
6224
+ argument.includePath(UNKNOWN_PATH, context);
6225
+ argument.include(context, false);
5987
6226
  }
5988
6227
  }
5989
- for (let index = parameters.length - 1; index >= 0; index--) {
5990
- const parameterVariables = this.parameters[index] || restParameter;
5991
- const argument = parameters[index];
6228
+ // Now we go backwards either starting from the last argument or before the
6229
+ // first SpreadElement to ensure all arguments before are included as needed
6230
+ for (let index = lastExplicitlyIncludedIndex; index >= 1; index--) {
6231
+ const parameterVariables = this.parameters[index - 1] || restParameter;
6232
+ const argument = args[index];
5992
6233
  if (parameterVariables) {
5993
6234
  calledFromTryStatement = false;
5994
6235
  if (parameterVariables.length === 0) {
5995
- // handle empty destructuring
6236
+ // handle empty destructuring to avoid destructuring undefined
5996
6237
  argumentIncluded = true;
5997
6238
  }
5998
6239
  else {
5999
6240
  for (const variable of parameterVariables) {
6000
- if (variable.included) {
6001
- argumentIncluded = true;
6002
- }
6003
6241
  if (variable.calledFromTryStatement) {
6004
6242
  calledFromTryStatement = true;
6005
6243
  }
6244
+ if (variable.included) {
6245
+ argumentIncluded = true;
6246
+ if (calledFromTryStatement) {
6247
+ argument.include(context, true);
6248
+ }
6249
+ else {
6250
+ variable.includeArgumentPaths(argument, context);
6251
+ argument.include(context, false);
6252
+ }
6253
+ }
6006
6254
  }
6007
6255
  }
6008
6256
  }
6009
- if (!argumentIncluded && argument.shouldBeIncluded(context)) {
6257
+ if (!argument.included && (argumentIncluded || argument.shouldBeIncluded(context))) {
6010
6258
  argumentIncluded = true;
6011
- }
6012
- if (argumentIncluded) {
6013
6259
  argument.include(context, calledFromTryStatement);
6014
6260
  }
6015
6261
  }
@@ -6025,11 +6271,62 @@ class ReturnValueScope extends ParameterScope {
6025
6271
  addReturnExpression(expression) {
6026
6272
  this.returnExpressions.push(expression);
6027
6273
  }
6274
+ deoptimizeArgumentsOnCall(interaction) {
6275
+ const { parameters } = this;
6276
+ const { args } = interaction;
6277
+ let position = 0;
6278
+ for (; position < args.length - 1; position++) {
6279
+ // Only the "this" argument arg[0] can be null
6280
+ const argument = args[position + 1];
6281
+ if (argument instanceof SpreadElement) {
6282
+ // This deoptimizes the current and remaining parameters and arguments
6283
+ for (; position < parameters.length; position++) {
6284
+ args[position + 1]?.deoptimizePath(UNKNOWN_PATH);
6285
+ parameters[position].forEach(variable => variable.markReassigned());
6286
+ }
6287
+ break;
6288
+ }
6289
+ if (this.hasRest && position >= parameters.length - 1) {
6290
+ argument.deoptimizePath(UNKNOWN_PATH);
6291
+ }
6292
+ else {
6293
+ const variables = parameters[position];
6294
+ if (variables) {
6295
+ for (const variable of variables) {
6296
+ variable.addArgumentValue(argument);
6297
+ }
6298
+ }
6299
+ this.addArgumentToBeDeoptimized(argument);
6300
+ }
6301
+ }
6302
+ const nonRestParameterLength = this.hasRest ? parameters.length - 1 : parameters.length;
6303
+ for (; position < nonRestParameterLength; position++) {
6304
+ for (const variable of parameters[position]) {
6305
+ variable.addArgumentValue(UNDEFINED_EXPRESSION);
6306
+ }
6307
+ }
6308
+ }
6028
6309
  getReturnExpression() {
6029
6310
  if (this.returnExpression === null)
6030
6311
  this.updateReturnExpression();
6031
6312
  return this.returnExpression;
6032
6313
  }
6314
+ deoptimizeAllParameters() {
6315
+ for (const parameter of this.parameters) {
6316
+ for (const variable of parameter) {
6317
+ variable.deoptimizePath(UNKNOWN_PATH);
6318
+ variable.markReassigned();
6319
+ }
6320
+ }
6321
+ }
6322
+ reassignAllParameters() {
6323
+ for (const parameter of this.parameters) {
6324
+ for (const variable of parameter) {
6325
+ variable.markReassigned();
6326
+ }
6327
+ }
6328
+ }
6329
+ addArgumentToBeDeoptimized(_argument) { }
6033
6330
  updateReturnExpression() {
6034
6331
  if (this.returnExpressions.length === 1) {
6035
6332
  this.returnExpression = this.returnExpressions[0];
@@ -6045,24 +6342,30 @@ class ReturnValueScope extends ParameterScope {
6045
6342
 
6046
6343
  class FunctionScope extends ReturnValueScope {
6047
6344
  constructor(parent) {
6048
- const { context } = parent;
6049
6345
  super(parent, false);
6346
+ const { context } = parent;
6050
6347
  this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));
6051
6348
  this.variables.set('this', (this.thisVariable = new ThisVariable(context)));
6052
6349
  }
6053
6350
  findLexicalBoundary() {
6054
6351
  return this;
6055
6352
  }
6056
- includeCallArguments(context, parameters) {
6057
- super.includeCallArguments(context, parameters);
6353
+ includeCallArguments(context, interaction) {
6354
+ super.includeCallArguments(context, interaction);
6058
6355
  if (this.argumentsVariable.included) {
6059
- for (const argument of parameters) {
6060
- if (!argument.included) {
6356
+ const { args } = interaction;
6357
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
6358
+ const argument = args[argumentIndex];
6359
+ if (argument) {
6360
+ argument.includePath(UNKNOWN_PATH, context);
6061
6361
  argument.include(context, false);
6062
6362
  }
6063
6363
  }
6064
6364
  }
6065
6365
  }
6366
+ addArgumentToBeDeoptimized(argument) {
6367
+ this.argumentsVariable.addArgumentToBeDeoptimized(argument);
6368
+ }
6066
6369
  }
6067
6370
 
6068
6371
  class ExpressionStatement extends NodeBase {
@@ -6090,8 +6393,9 @@ class ExpressionStatement extends NodeBase {
6090
6393
  return this.parent.type !== Program$1;
6091
6394
  return super.shouldBeIncluded(context);
6092
6395
  }
6093
- applyDeoptimizations() { }
6094
6396
  }
6397
+ ExpressionStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
6398
+ ExpressionStatement.prototype.applyDeoptimizations = doNotDeoptimize;
6095
6399
 
6096
6400
  class BlockStatement extends NodeBase {
6097
6401
  get deoptimizeBody() {
@@ -6156,6 +6460,8 @@ class BlockStatement extends NodeBase {
6156
6460
  }
6157
6461
  }
6158
6462
  }
6463
+ BlockStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
6464
+ BlockStatement.prototype.applyDeoptimizations = doNotDeoptimize;
6159
6465
 
6160
6466
  class RestElement extends NodeBase {
6161
6467
  constructor() {
@@ -6165,9 +6471,12 @@ class RestElement extends NodeBase {
6165
6471
  addExportedVariables(variables, exportNamesByVariable) {
6166
6472
  this.argument.addExportedVariables(variables, exportNamesByVariable);
6167
6473
  }
6168
- declare(kind, init) {
6474
+ declare(kind, destructuredInitPath, init) {
6169
6475
  this.declarationInit = init;
6170
- return this.argument.declare(kind, UNKNOWN_EXPRESSION);
6476
+ return this.argument.declare(kind, getIncludedPatternPath$1(destructuredInitPath), init);
6477
+ }
6478
+ deoptimizeAssignment(destructuredInitPath, init) {
6479
+ this.argument.deoptimizeAssignment(getIncludedPatternPath$1(destructuredInitPath), init);
6171
6480
  }
6172
6481
  deoptimizePath(path) {
6173
6482
  if (path.length === 0) {
@@ -6178,6 +6487,20 @@ class RestElement extends NodeBase {
6178
6487
  return (path.length > 0 ||
6179
6488
  this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
6180
6489
  }
6490
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
6491
+ return this.argument.hasEffectsWhenDestructuring(context, getIncludedPatternPath$1(destructuredInitPath), init);
6492
+ }
6493
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
6494
+ return (this.included =
6495
+ this.argument.includeDestructuredIfNecessary(context, getIncludedPatternPath$1(destructuredInitPath), init) || this.included);
6496
+ }
6497
+ include(context, includeChildrenRecursively) {
6498
+ if (!this.included)
6499
+ this.includeNode(context);
6500
+ // This should just include the identifier, its properties should be
6501
+ // included where the variable is used.
6502
+ this.argument.include(context, includeChildrenRecursively);
6503
+ }
6181
6504
  markDeclarationReached() {
6182
6505
  this.argument.markDeclarationReached();
6183
6506
  }
@@ -6189,12 +6512,16 @@ class RestElement extends NodeBase {
6189
6512
  }
6190
6513
  }
6191
6514
  }
6515
+ RestElement.prototype.includeNode = onlyIncludeSelf;
6516
+ const getIncludedPatternPath$1 = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
6517
+ ? destructuredInitPath
6518
+ : [...destructuredInitPath, UnknownKey];
6192
6519
 
6193
6520
  class FunctionBase extends NodeBase {
6194
6521
  constructor() {
6195
6522
  super(...arguments);
6196
- this.objectEntity = null;
6197
6523
  this.parameterVariableValuesDeoptimized = false;
6524
+ this.includeCallArguments = this.scope.includeCallArguments.bind(this.scope);
6198
6525
  }
6199
6526
  get async() {
6200
6527
  return isFlagSet(this.flags, 256 /* Flag.async */);
@@ -6214,53 +6541,9 @@ class FunctionBase extends NodeBase {
6214
6541
  set generator(value) {
6215
6542
  this.flags = setFlag(this.flags, 4194304 /* Flag.generator */, value);
6216
6543
  }
6217
- updateParameterVariableValues(_arguments) {
6218
- for (let position = 0; position < this.params.length; position++) {
6219
- const parameter = this.params[position];
6220
- if (!(parameter instanceof Identifier)) {
6221
- continue;
6222
- }
6223
- const parameterVariable = parameter.variable;
6224
- const argument = _arguments[position + 1] ?? UNDEFINED_EXPRESSION;
6225
- parameterVariable.updateKnownValue(argument);
6226
- }
6227
- }
6228
- deoptimizeParameterVariableValues() {
6229
- for (const parameter of this.params) {
6230
- if (parameter instanceof Identifier) {
6231
- const parameterVariable = parameter.variable;
6232
- parameterVariable.markReassigned();
6233
- }
6234
- }
6235
- }
6236
6544
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6237
- if (interaction.type === INTERACTION_CALLED) {
6238
- const { parameters } = this.scope;
6239
- const { args } = interaction;
6240
- let hasRest = false;
6241
- for (let position = 0; position < args.length - 1; position++) {
6242
- const parameter = this.params[position];
6243
- // Only the "this" argument arg[0] can be null
6244
- const argument = args[position + 1];
6245
- if (argument instanceof SpreadElement) {
6246
- this.deoptimizeParameterVariableValues();
6247
- }
6248
- if (hasRest || parameter instanceof RestElement) {
6249
- hasRest = true;
6250
- argument.deoptimizePath(UNKNOWN_PATH);
6251
- }
6252
- else if (parameter instanceof Identifier) {
6253
- parameters[position][0].addEntityToBeDeoptimized(argument);
6254
- this.addArgumentToBeDeoptimized(argument);
6255
- }
6256
- else if (parameter) {
6257
- argument.deoptimizePath(UNKNOWN_PATH);
6258
- }
6259
- else {
6260
- this.addArgumentToBeDeoptimized(argument);
6261
- }
6262
- }
6263
- this.updateParameterVariableValues(args);
6545
+ if (interaction.type === INTERACTION_CALLED && path.length === 0) {
6546
+ this.scope.deoptimizeArgumentsOnCall(interaction);
6264
6547
  }
6265
6548
  else {
6266
6549
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -6272,12 +6555,7 @@ class FunctionBase extends NodeBase {
6272
6555
  // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
6273
6556
  // which means the return expression and parameters need to be reassigned
6274
6557
  this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
6275
- for (const parameterList of this.scope.parameters) {
6276
- for (const parameter of parameterList) {
6277
- parameter.deoptimizePath(UNKNOWN_PATH);
6278
- parameter.markReassigned();
6279
- }
6280
- }
6558
+ this.scope.deoptimizeAllParameters();
6281
6559
  }
6282
6560
  }
6283
6561
  getLiteralValueAtPath(path, recursionTracker, origin) {
@@ -6315,8 +6593,13 @@ class FunctionBase extends NodeBase {
6315
6593
  return true;
6316
6594
  }
6317
6595
  }
6318
- for (const parameter of this.params) {
6319
- if (parameter.hasEffects(context))
6596
+ const { propertyReadSideEffects } = this.scope.context.options
6597
+ .treeshake;
6598
+ for (let index = 0; index < this.params.length; index++) {
6599
+ const parameter = this.params[index];
6600
+ if (parameter.hasEffects(context) ||
6601
+ (propertyReadSideEffects &&
6602
+ parameter.hasEffectsWhenDestructuring(context, EMPTY_PATH, interaction.args[index + 1] || UNDEFINED_EXPRESSION)))
6320
6603
  return true;
6321
6604
  }
6322
6605
  return false;
@@ -6335,21 +6618,17 @@ class FunctionBase extends NodeBase {
6335
6618
  return variable?.getOnlyFunctionCallUsed() ?? false;
6336
6619
  }
6337
6620
  include(context, includeChildrenRecursively) {
6338
- if (!this.parameterVariableValuesDeoptimized && !this.onlyFunctionCallUsed()) {
6621
+ if (!this.included)
6622
+ this.includeNode(context);
6623
+ if (!(this.parameterVariableValuesDeoptimized || this.onlyFunctionCallUsed())) {
6339
6624
  this.parameterVariableValuesDeoptimized = true;
6340
- this.deoptimizeParameterVariableValues();
6625
+ this.scope.reassignAllParameters();
6341
6626
  }
6342
- if (!this.deoptimized)
6343
- this.applyDeoptimizations();
6344
- this.included = true;
6345
6627
  const { brokenFlow } = context;
6346
6628
  context.brokenFlow = false;
6347
6629
  this.body.include(context, includeChildrenRecursively);
6348
6630
  context.brokenFlow = brokenFlow;
6349
6631
  }
6350
- includeCallArguments(context, parameters) {
6351
- this.scope.includeCallArguments(context, parameters);
6352
- }
6353
6632
  initialise() {
6354
6633
  super.initialise();
6355
6634
  if (this.body instanceof BlockStatement) {
@@ -6371,14 +6650,14 @@ class FunctionBase extends NodeBase {
6371
6650
  // so that the scope already knows all parameters and can detect conflicts
6372
6651
  // when parsing the body.
6373
6652
  const parameters = (this.params = params.map((parameter) => new (context.getNodeConstructor(parameter.type))(this, scope).parseNode(parameter)));
6374
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
6653
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
6375
6654
  this.body = new (context.getNodeConstructor(body.type))(this, bodyScope).parseNode(body);
6376
6655
  return super.parseNode(esTreeNode);
6377
6656
  }
6378
- addArgumentToBeDeoptimized(_argument) { }
6379
- applyDeoptimizations() { }
6380
6657
  }
6381
6658
  FunctionBase.prototype.preventChildBlockScope = true;
6659
+ FunctionBase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
6660
+ FunctionBase.prototype.applyDeoptimizations = doNotDeoptimize;
6382
6661
 
6383
6662
  class FunctionNode extends FunctionBase {
6384
6663
  constructor() {
@@ -6390,18 +6669,16 @@ class FunctionNode extends FunctionBase {
6390
6669
  this.constructedEntity = new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE);
6391
6670
  // This makes sure that all deoptimizations of "this" are applied to the
6392
6671
  // constructed entity.
6393
- this.scope.thisVariable.addEntityToBeDeoptimized(this.constructedEntity);
6672
+ this.scope.thisVariable.addArgumentValue(this.constructedEntity);
6394
6673
  }
6395
6674
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6396
6675
  super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
6397
6676
  if (interaction.type === INTERACTION_CALLED && path.length === 0 && interaction.args[0]) {
6398
6677
  // args[0] is the "this" argument
6399
- this.scope.thisVariable.addEntityToBeDeoptimized(interaction.args[0]);
6678
+ this.scope.thisVariable.addArgumentValue(interaction.args[0]);
6400
6679
  }
6401
6680
  }
6402
6681
  hasEffects(context) {
6403
- if (!this.deoptimized)
6404
- this.applyDeoptimizations();
6405
6682
  if (this.annotationNoSideEffects) {
6406
6683
  return false;
6407
6684
  }
@@ -6439,7 +6716,7 @@ class FunctionNode extends FunctionBase {
6439
6716
  }
6440
6717
  include(context, includeChildrenRecursively) {
6441
6718
  super.include(context, includeChildrenRecursively);
6442
- this.id?.include();
6719
+ this.id?.include(context);
6443
6720
  const hasArguments = this.scope.argumentsVariable.included;
6444
6721
  for (const parameter of this.params) {
6445
6722
  if (!(parameter instanceof Identifier) || hasArguments) {
@@ -6447,12 +6724,18 @@ class FunctionNode extends FunctionBase {
6447
6724
  }
6448
6725
  }
6449
6726
  }
6727
+ includeNode(context) {
6728
+ this.included = true;
6729
+ const hasArguments = this.scope.argumentsVariable.included;
6730
+ for (const parameter of this.params) {
6731
+ if (!(parameter instanceof Identifier) || hasArguments) {
6732
+ parameter.includePath(UNKNOWN_PATH, context);
6733
+ }
6734
+ }
6735
+ }
6450
6736
  initialise() {
6451
6737
  super.initialise();
6452
- this.id?.declare('function', this);
6453
- }
6454
- addArgumentToBeDeoptimized(argument) {
6455
- this.scope.argumentsVariable.addArgumentToBeDeoptimized(argument);
6738
+ this.id?.declare('function', EMPTY_PATH, this);
6456
6739
  }
6457
6740
  getObjectEntity() {
6458
6741
  if (this.objectEntity !== null) {
@@ -6502,11 +6785,16 @@ function getFunctionIdInsertPosition(code, start) {
6502
6785
  }
6503
6786
  class ExportDefaultDeclaration extends NodeBase {
6504
6787
  include(context, includeChildrenRecursively) {
6505
- super.include(context, includeChildrenRecursively);
6788
+ this.included = true;
6789
+ this.declaration.include(context, includeChildrenRecursively);
6506
6790
  if (includeChildrenRecursively) {
6507
- this.scope.context.includeVariableInModule(this.variable);
6791
+ this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, context);
6508
6792
  }
6509
6793
  }
6794
+ includePath(path, context) {
6795
+ this.included = true;
6796
+ this.declaration.includePath(path, context);
6797
+ }
6510
6798
  initialise() {
6511
6799
  super.initialise();
6512
6800
  const declaration = this.declaration;
@@ -6551,7 +6839,6 @@ class ExportDefaultDeclaration extends NodeBase {
6551
6839
  }
6552
6840
  this.declaration.render(code, options);
6553
6841
  }
6554
- applyDeoptimizations() { }
6555
6842
  renderNamedDeclaration(code, declarationStart, idInsertPosition, options) {
6556
6843
  const { exportNamesByVariable, format, snippets: { getPropertyAccess } } = options;
6557
6844
  const name = this.variable.getName(getPropertyAccess);
@@ -6582,6 +6869,8 @@ class ExportDefaultDeclaration extends NodeBase {
6582
6869
  }
6583
6870
  }
6584
6871
  ExportDefaultDeclaration.prototype.needsBoundaries = true;
6872
+ ExportDefaultDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
6873
+ ExportDefaultDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
6585
6874
 
6586
6875
  const needsEscapeRegEx = /[\n\r'\\\u2028\u2029]/;
6587
6876
  const quoteNewlineRegEx = /([\n\r'\u2028\u2029])/g;
@@ -6851,6 +7140,7 @@ class Literal extends NodeBase {
6851
7140
  }
6852
7141
  }
6853
7142
  }
7143
+ Literal.prototype.includeNode = onlyIncludeSelf;
6854
7144
 
6855
7145
  function getChainElementLiteralValueAtPath(element, object, path, recursionTracker, origin) {
6856
7146
  if ('getLiteralValueAtPathAsChainElement' in object) {
@@ -6866,8 +7156,6 @@ function getChainElementLiteralValueAtPath(element, object, path, recursionTrack
6866
7156
  return element.getLiteralValueAtPath(path, recursionTracker, origin);
6867
7157
  }
6868
7158
 
6869
- // To avoid infinite recursions
6870
- const MAX_PATH_DEPTH = 7;
6871
7159
  function getResolvablePropertyKey(memberExpression) {
6872
7160
  return memberExpression.computed
6873
7161
  ? getResolvableComputedPropertyKey(memberExpression.property)
@@ -6966,18 +7254,27 @@ class MemberExpression extends NodeBase {
6966
7254
  }
6967
7255
  else if (!this.isUndefined) {
6968
7256
  if (path.length < MAX_PATH_DEPTH) {
6969
- this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.getPropertyKey(), ...path], recursionTracker);
7257
+ this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, this.propertyKey === UnknownKey ? UNKNOWN_PATH : [this.propertyKey, ...path], recursionTracker);
6970
7258
  }
6971
7259
  else {
6972
7260
  deoptimizeInteraction(interaction);
6973
7261
  }
6974
7262
  }
6975
7263
  }
7264
+ deoptimizeAssignment(destructuredInitPath, init) {
7265
+ this.deoptimizePath(EMPTY_PATH);
7266
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
7267
+ }
6976
7268
  deoptimizeCache() {
7269
+ if (this.propertyKey === this.dynamicPropertyKey)
7270
+ return;
6977
7271
  const { expressionsToBeDeoptimized, object } = this;
6978
7272
  this.expressionsToBeDeoptimized = EMPTY_ARRAY;
6979
- this.propertyKey = UnknownKey;
7273
+ this.dynamicPropertyKey = this.propertyKey;
6980
7274
  object.deoptimizePath(UNKNOWN_PATH);
7275
+ if (this.included) {
7276
+ object.includePath(UNKNOWN_PATH, createInclusionContext());
7277
+ }
6981
7278
  for (const expression of expressionsToBeDeoptimized) {
6982
7279
  expression.deoptimizeCache();
6983
7280
  }
@@ -6988,11 +7285,13 @@ class MemberExpression extends NodeBase {
6988
7285
  if (this.variable) {
6989
7286
  this.variable.deoptimizePath(path);
6990
7287
  }
6991
- else if (!this.isUndefined && path.length < MAX_PATH_DEPTH) {
6992
- const propertyKey = this.getPropertyKey();
7288
+ else if (!this.isUndefined) {
7289
+ const { propertyKey } = this;
6993
7290
  this.object.deoptimizePath([
6994
7291
  propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey,
6995
- ...path
7292
+ ...(path.length < MAX_PATH_DEPTH
7293
+ ? path
7294
+ : [...path.slice(0, MAX_PATH_DEPTH), UnknownKey])
6996
7295
  ]);
6997
7296
  }
6998
7297
  }
@@ -7003,9 +7302,11 @@ class MemberExpression extends NodeBase {
7003
7302
  if (this.isUndefined) {
7004
7303
  return undefined;
7005
7304
  }
7006
- if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
7007
- this.expressionsToBeDeoptimized.push(origin);
7008
- return this.object.getLiteralValueAtPath([this.getPropertyKey(), ...path], recursionTracker, origin);
7305
+ const propertyKey = this.getDynamicPropertyKey();
7306
+ if (propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
7307
+ if (propertyKey !== this.propertyKey)
7308
+ this.expressionsToBeDeoptimized.push(origin);
7309
+ return this.object.getLiteralValueAtPath([propertyKey, ...path], recursionTracker, origin);
7009
7310
  }
7010
7311
  return UnknownValue;
7011
7312
  }
@@ -7025,9 +7326,11 @@ class MemberExpression extends NodeBase {
7025
7326
  if (this.isUndefined) {
7026
7327
  return [UNDEFINED_EXPRESSION, false];
7027
7328
  }
7028
- if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
7029
- this.expressionsToBeDeoptimized.push(origin);
7030
- return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin);
7329
+ const propertyKey = this.getDynamicPropertyKey();
7330
+ if (propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
7331
+ if (propertyKey !== this.propertyKey)
7332
+ this.expressionsToBeDeoptimized.push(origin);
7333
+ return this.object.getReturnExpressionWhenCalledAtPath([propertyKey, ...path], interaction, recursionTracker, origin);
7031
7334
  }
7032
7335
  return UNKNOWN_RETURN_EXPRESSION;
7033
7336
  }
@@ -7073,14 +7376,45 @@ class MemberExpression extends NodeBase {
7073
7376
  return true;
7074
7377
  }
7075
7378
  if (path.length < MAX_PATH_DEPTH) {
7076
- return this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey(), ...path], interaction, context);
7379
+ return this.object.hasEffectsOnInteractionAtPath([this.getDynamicPropertyKey(), ...path], interaction, context);
7077
7380
  }
7078
7381
  return true;
7079
7382
  }
7383
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
7384
+ return (destructuredInitPath.length > 0 &&
7385
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
7386
+ }
7080
7387
  include(context, includeChildrenRecursively) {
7388
+ if (!this.included)
7389
+ this.includeNode(context);
7390
+ this.object.include(context, includeChildrenRecursively);
7391
+ this.property.include(context, includeChildrenRecursively);
7392
+ }
7393
+ includeNode(context) {
7394
+ this.included = true;
7081
7395
  if (!this.deoptimized)
7082
7396
  this.applyDeoptimizations();
7083
- this.includeProperties(context, includeChildrenRecursively);
7397
+ if (this.variable) {
7398
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
7399
+ }
7400
+ else if (!this.isUndefined) {
7401
+ this.object.includePath([this.propertyKey], context);
7402
+ }
7403
+ }
7404
+ includePath(path, context) {
7405
+ if (!this.included)
7406
+ this.includeNode(context);
7407
+ if (this.variable) {
7408
+ this.variable?.includePath(path, context);
7409
+ }
7410
+ else if (!this.isUndefined) {
7411
+ this.object.includePath([
7412
+ this.propertyKey,
7413
+ ...(path.length < MAX_PATH_DEPTH
7414
+ ? path
7415
+ : [...path.slice(0, MAX_PATH_DEPTH), UnknownKey])
7416
+ ], context);
7417
+ }
7084
7418
  }
7085
7419
  includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {
7086
7420
  if (!this.assignmentDeoptimized)
@@ -7089,20 +7423,34 @@ class MemberExpression extends NodeBase {
7089
7423
  this.include(context, includeChildrenRecursively);
7090
7424
  }
7091
7425
  else {
7092
- this.includeProperties(context, includeChildrenRecursively);
7426
+ if (!this.included)
7427
+ this.includeNode(context);
7428
+ this.object.include(context, includeChildrenRecursively);
7429
+ this.property.include(context, includeChildrenRecursively);
7093
7430
  }
7094
7431
  }
7095
- includeCallArguments(context, parameters) {
7432
+ includeCallArguments(context, interaction) {
7096
7433
  if (this.variable) {
7097
- this.variable.includeCallArguments(context, parameters);
7434
+ this.variable.includeCallArguments(context, interaction);
7098
7435
  }
7099
7436
  else {
7100
- super.includeCallArguments(context, parameters);
7437
+ super.includeCallArguments(context, interaction);
7101
7438
  }
7102
7439
  }
7440
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
7441
+ if ((this.included ||=
7442
+ destructuredInitPath.length > 0 &&
7443
+ !context.brokenFlow &&
7444
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext()))) {
7445
+ init.include(context, false);
7446
+ return true;
7447
+ }
7448
+ return false;
7449
+ }
7103
7450
  initialise() {
7104
7451
  super.initialise();
7105
- this.propertyKey = getResolvablePropertyKey(this);
7452
+ this.dynamicPropertyKey = getResolvablePropertyKey(this);
7453
+ this.propertyKey = this.dynamicPropertyKey === null ? UnknownKey : this.dynamicPropertyKey;
7106
7454
  this.accessInteraction = { args: [this.object], type: INTERACTION_ACCESSED };
7107
7455
  }
7108
7456
  render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = BLANK) {
@@ -7139,8 +7487,7 @@ class MemberExpression extends NodeBase {
7139
7487
  this.bound &&
7140
7488
  propertyReadSideEffects &&
7141
7489
  !(this.variable || this.isUndefined)) {
7142
- const propertyKey = this.getPropertyKey();
7143
- this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER);
7490
+ this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [this.propertyKey], SHARED_RECURSION_TRACKER);
7144
7491
  this.scope.context.requestTreeshakingPass();
7145
7492
  }
7146
7493
  if (this.variable) {
@@ -7157,7 +7504,7 @@ class MemberExpression extends NodeBase {
7157
7504
  this.bound &&
7158
7505
  propertyReadSideEffects &&
7159
7506
  !(this.variable || this.isUndefined)) {
7160
- this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.getPropertyKey()], SHARED_RECURSION_TRACKER);
7507
+ this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.propertyKey], SHARED_RECURSION_TRACKER);
7161
7508
  this.scope.context.requestTreeshakingPass();
7162
7509
  }
7163
7510
  }
@@ -7166,24 +7513,24 @@ class MemberExpression extends NodeBase {
7166
7513
  const variable = this.scope.findVariable(this.object.name);
7167
7514
  if (variable.isNamespace) {
7168
7515
  if (this.variable) {
7169
- this.scope.context.includeVariableInModule(this.variable);
7516
+ this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, createInclusionContext());
7170
7517
  }
7171
7518
  this.scope.context.log(LOGLEVEL_WARN, logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);
7172
7519
  }
7173
7520
  }
7174
7521
  }
7175
- getPropertyKey() {
7176
- if (this.propertyKey === null) {
7177
- this.propertyKey = UnknownKey;
7522
+ getDynamicPropertyKey() {
7523
+ if (this.dynamicPropertyKey === null) {
7524
+ this.dynamicPropertyKey = this.propertyKey;
7178
7525
  const value = this.property.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
7179
- return (this.propertyKey =
7526
+ return (this.dynamicPropertyKey =
7180
7527
  value === SymbolToStringTag
7181
7528
  ? value
7182
7529
  : typeof value === 'symbol'
7183
7530
  ? UnknownKey
7184
7531
  : String(value));
7185
7532
  }
7186
- return this.propertyKey;
7533
+ return this.dynamicPropertyKey;
7187
7534
  }
7188
7535
  hasAccessEffect(context) {
7189
7536
  const { propertyReadSideEffects } = this.scope.context.options
@@ -7191,17 +7538,7 @@ class MemberExpression extends NodeBase {
7191
7538
  return (!(this.variable || this.isUndefined) &&
7192
7539
  propertyReadSideEffects &&
7193
7540
  (propertyReadSideEffects === 'always' ||
7194
- this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));
7195
- }
7196
- includeProperties(context, includeChildrenRecursively) {
7197
- if (!this.included) {
7198
- this.included = true;
7199
- if (this.variable) {
7200
- this.scope.context.includeVariableInModule(this.variable);
7201
- }
7202
- }
7203
- this.object.include(context, includeChildrenRecursively);
7204
- this.property.include(context, includeChildrenRecursively);
7541
+ this.object.hasEffectsOnInteractionAtPath([this.getDynamicPropertyKey()], this.accessInteraction, context)));
7205
7542
  }
7206
7543
  }
7207
7544
  function resolveNamespaceVariables(baseVariable, path, astContext) {
@@ -7245,18 +7582,20 @@ class MetaProperty extends NodeBase {
7245
7582
  return path.length > 1 || type !== INTERACTION_ACCESSED;
7246
7583
  }
7247
7584
  include() {
7248
- if (!this.included) {
7249
- this.included = true;
7250
- if (this.meta.name === IMPORT) {
7251
- this.scope.context.addImportMeta(this);
7252
- const parent = this.parent;
7253
- const metaProperty = (this.metaProperty =
7254
- parent instanceof MemberExpression && typeof parent.propertyKey === 'string'
7255
- ? parent.propertyKey
7256
- : null);
7257
- if (metaProperty?.startsWith(FILE_PREFIX)) {
7258
- this.referenceId = metaProperty.slice(FILE_PREFIX.length);
7259
- }
7585
+ if (!this.included)
7586
+ this.includeNode();
7587
+ }
7588
+ includeNode() {
7589
+ this.included = true;
7590
+ if (this.meta.name === IMPORT) {
7591
+ this.scope.context.addImportMeta(this);
7592
+ const parent = this.parent;
7593
+ const metaProperty = (this.metaProperty =
7594
+ parent instanceof MemberExpression && typeof parent.propertyKey === 'string'
7595
+ ? parent.propertyKey
7596
+ : null);
7597
+ if (metaProperty?.startsWith(FILE_PREFIX)) {
7598
+ this.referenceId = metaProperty.slice(FILE_PREFIX.length);
7260
7599
  }
7261
7600
  }
7262
7601
  }
@@ -7363,7 +7702,7 @@ class UndefinedVariable extends Variable {
7363
7702
 
7364
7703
  class ExportDefaultVariable extends LocalVariable {
7365
7704
  constructor(name, exportDefaultDeclaration, context) {
7366
- super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');
7705
+ super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, EMPTY_PATH, context, 'other');
7367
7706
  this.hasId = false;
7368
7707
  this.originalId = null;
7369
7708
  this.originalVariable = null;
@@ -7512,8 +7851,8 @@ class NamespaceVariable extends Variable {
7512
7851
  return (!memberVariable ||
7513
7852
  memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));
7514
7853
  }
7515
- include() {
7516
- super.include();
7854
+ includePath(path, context) {
7855
+ super.includePath(path, context);
7517
7856
  this.context.includeAllExports();
7518
7857
  }
7519
7858
  prepare(accessedGlobalsByScope) {
@@ -7606,9 +7945,9 @@ class SyntheticNamedExportVariable extends Variable {
7606
7945
  getName(getPropertyAccess) {
7607
7946
  return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;
7608
7947
  }
7609
- include() {
7610
- super.include();
7611
- this.context.includeVariableInModule(this.syntheticNamespace);
7948
+ includePath(path, context) {
7949
+ super.includePath(path, context);
7950
+ this.context.includeVariableInModule(this.syntheticNamespace, path, context);
7612
7951
  }
7613
7952
  setRenderNames(baseName, name) {
7614
7953
  super.setRenderNames(baseName, name);
@@ -10813,21 +11152,37 @@ class ArrayPattern extends NodeBase {
10813
11152
  element?.addExportedVariables(variables, exportNamesByVariable);
10814
11153
  }
10815
11154
  }
10816
- declare(kind) {
11155
+ declare(kind, destructuredInitPath, init) {
10817
11156
  const variables = [];
11157
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
10818
11158
  for (const element of this.elements) {
10819
11159
  if (element !== null) {
10820
- variables.push(...element.declare(kind, UNKNOWN_EXPRESSION));
11160
+ variables.push(...element.declare(kind, includedPatternPath, init));
10821
11161
  }
10822
11162
  }
10823
11163
  return variables;
10824
11164
  }
11165
+ deoptimizeAssignment(destructuredInitPath, init) {
11166
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
11167
+ for (const element of this.elements) {
11168
+ element?.deoptimizeAssignment(includedPatternPath, init);
11169
+ }
11170
+ }
10825
11171
  // Patterns can only be deoptimized at the empty path at the moment
10826
11172
  deoptimizePath() {
10827
11173
  for (const element of this.elements) {
10828
11174
  element?.deoptimizePath(EMPTY_PATH);
10829
11175
  }
10830
11176
  }
11177
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
11178
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
11179
+ for (const element of this.elements) {
11180
+ if (element?.hasEffectsWhenDestructuring(context, includedPatternPath, init)) {
11181
+ return true;
11182
+ }
11183
+ }
11184
+ return false;
11185
+ }
10831
11186
  // Patterns are only checked at the empty path at the moment
10832
11187
  hasEffectsOnInteractionAtPath(_path, interaction, context) {
10833
11188
  for (const element of this.elements) {
@@ -10836,12 +11191,38 @@ class ArrayPattern extends NodeBase {
10836
11191
  }
10837
11192
  return false;
10838
11193
  }
11194
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11195
+ let included = false;
11196
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
11197
+ for (const element of this.elements) {
11198
+ if (element) {
11199
+ element.included ||= included;
11200
+ included =
11201
+ element.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
11202
+ }
11203
+ }
11204
+ if (included) {
11205
+ // This is necessary so that if any pattern element is included, all are
11206
+ // included for proper deconflicting
11207
+ for (const element of this.elements) {
11208
+ if (element && !element.included) {
11209
+ element.included = true;
11210
+ element.includeDestructuredIfNecessary(context, includedPatternPath, init);
11211
+ }
11212
+ }
11213
+ }
11214
+ return (this.included ||= included);
11215
+ }
10839
11216
  markDeclarationReached() {
10840
11217
  for (const element of this.elements) {
10841
11218
  element?.markDeclarationReached();
10842
11219
  }
10843
11220
  }
10844
11221
  }
11222
+ ArrayPattern.prototype.includeNode = onlyIncludeSelf;
11223
+ const getIncludedPatternPath = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
11224
+ ? destructuredInitPath
11225
+ : [...destructuredInitPath, UnknownInteger];
10845
11226
 
10846
11227
  class ArrowFunctionExpression extends FunctionBase {
10847
11228
  constructor() {
@@ -10858,8 +11239,6 @@ class ArrowFunctionExpression extends FunctionBase {
10858
11239
  this.scope = new ReturnValueScope(parentScope, false);
10859
11240
  }
10860
11241
  hasEffects() {
10861
- if (!this.deoptimized)
10862
- this.applyDeoptimizations();
10863
11242
  return false;
10864
11243
  }
10865
11244
  hasEffectsOnInteractionAtPath(path, interaction, context) {
@@ -10898,6 +11277,15 @@ class ArrowFunctionExpression extends FunctionBase {
10898
11277
  }
10899
11278
  }
10900
11279
  }
11280
+ includeNode(context) {
11281
+ this.included = true;
11282
+ this.body.includePath(UNKNOWN_PATH, context);
11283
+ for (const parameter of this.params) {
11284
+ if (!(parameter instanceof Identifier)) {
11285
+ parameter.includePath(UNKNOWN_PATH, context);
11286
+ }
11287
+ }
11288
+ }
10901
11289
  getObjectEntity() {
10902
11290
  if (this.objectEntity !== null) {
10903
11291
  return this.objectEntity;
@@ -10917,13 +11305,18 @@ class ObjectPattern extends NodeBase {
10917
11305
  }
10918
11306
  }
10919
11307
  }
10920
- declare(kind, init) {
11308
+ declare(kind, destructuredInitPath, init) {
10921
11309
  const variables = [];
10922
11310
  for (const property of this.properties) {
10923
- variables.push(...property.declare(kind, init));
11311
+ variables.push(...property.declare(kind, destructuredInitPath, init));
10924
11312
  }
10925
11313
  return variables;
10926
11314
  }
11315
+ deoptimizeAssignment(destructuredInitPath, init) {
11316
+ for (const property of this.properties) {
11317
+ property.deoptimizeAssignment(destructuredInitPath, init);
11318
+ }
11319
+ }
10927
11320
  deoptimizePath(path) {
10928
11321
  if (path.length === 0) {
10929
11322
  for (const property of this.properties) {
@@ -10941,12 +11334,46 @@ class ObjectPattern extends NodeBase {
10941
11334
  }
10942
11335
  return false;
10943
11336
  }
11337
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
11338
+ for (const property of this.properties) {
11339
+ if (property.hasEffectsWhenDestructuring(context, destructuredInitPath, init))
11340
+ return true;
11341
+ }
11342
+ return false;
11343
+ }
11344
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11345
+ let included = false;
11346
+ for (const property of this.properties) {
11347
+ included =
11348
+ property.includeDestructuredIfNecessary(context, destructuredInitPath, init) || included;
11349
+ }
11350
+ return (this.included ||= included);
11351
+ }
10944
11352
  markDeclarationReached() {
10945
11353
  for (const property of this.properties) {
10946
11354
  property.markDeclarationReached();
10947
11355
  }
10948
11356
  }
11357
+ render(code, options) {
11358
+ if (this.properties.length > 0) {
11359
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
11360
+ let lastSeparatorPos = null;
11361
+ for (const { node, separator, start, end } of separatedNodes) {
11362
+ if (!node.included) {
11363
+ treeshakeNode(node, code, start, end);
11364
+ continue;
11365
+ }
11366
+ lastSeparatorPos = separator;
11367
+ node.render(code, options);
11368
+ }
11369
+ if (lastSeparatorPos) {
11370
+ code.remove(lastSeparatorPos, this.end - 1);
11371
+ }
11372
+ }
11373
+ }
10949
11374
  }
11375
+ ObjectPattern.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
11376
+ ObjectPattern.prototype.applyDeoptimizations = doNotDeoptimize;
10950
11377
 
10951
11378
  class AssignmentExpression extends NodeBase {
10952
11379
  hasEffects(context) {
@@ -10955,7 +11382,9 @@ class AssignmentExpression extends NodeBase {
10955
11382
  this.applyDeoptimizations();
10956
11383
  // MemberExpressions do not access the property before assignments if the
10957
11384
  // operator is '='.
10958
- return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '='));
11385
+ return (right.hasEffects(context) ||
11386
+ left.hasEffectsAsAssignmentTarget(context, operator !== '=') ||
11387
+ this.left.hasEffectsWhenDestructuring?.(context, EMPTY_PATH, right));
10959
11388
  }
10960
11389
  hasEffectsOnInteractionAtPath(path, interaction, context) {
10961
11390
  return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);
@@ -10964,15 +11393,24 @@ class AssignmentExpression extends NodeBase {
10964
11393
  const { deoptimized, left, right, operator } = this;
10965
11394
  if (!deoptimized)
10966
11395
  this.applyDeoptimizations();
10967
- this.included = true;
11396
+ if (!this.included)
11397
+ this.includeNode(context);
11398
+ const hasEffectsContext = createHasEffectsContext();
10968
11399
  if (includeChildrenRecursively ||
10969
11400
  operator !== '=' ||
10970
11401
  left.included ||
10971
- left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {
11402
+ left.hasEffectsAsAssignmentTarget(hasEffectsContext, false) ||
11403
+ left.hasEffectsWhenDestructuring?.(hasEffectsContext, EMPTY_PATH, right)) {
10972
11404
  left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');
10973
11405
  }
10974
11406
  right.include(context, includeChildrenRecursively);
10975
11407
  }
11408
+ includeNode(context) {
11409
+ this.included = true;
11410
+ if (!this.deoptimized)
11411
+ this.applyDeoptimizations();
11412
+ this.right.includePath(UNKNOWN_PATH, context);
11413
+ }
10976
11414
  initialise() {
10977
11415
  super.initialise();
10978
11416
  if (this.left instanceof Identifier) {
@@ -11033,8 +11471,7 @@ class AssignmentExpression extends NodeBase {
11033
11471
  }
11034
11472
  applyDeoptimizations() {
11035
11473
  this.deoptimized = true;
11036
- this.left.deoptimizePath(EMPTY_PATH);
11037
- this.right.deoptimizePath(UNKNOWN_PATH);
11474
+ this.left.deoptimizeAssignment(EMPTY_PATH, this.right);
11038
11475
  this.scope.context.requestTreeshakingPass();
11039
11476
  }
11040
11477
  }
@@ -11043,8 +11480,11 @@ class AssignmentPattern extends NodeBase {
11043
11480
  addExportedVariables(variables, exportNamesByVariable) {
11044
11481
  this.left.addExportedVariables(variables, exportNamesByVariable);
11045
11482
  }
11046
- declare(kind, init) {
11047
- return this.left.declare(kind, init);
11483
+ declare(kind, destructuredInitPath, init) {
11484
+ return this.left.declare(kind, destructuredInitPath, init);
11485
+ }
11486
+ deoptimizeAssignment(destructuredInitPath, init) {
11487
+ this.left.deoptimizeAssignment(destructuredInitPath, init);
11048
11488
  }
11049
11489
  deoptimizePath(path) {
11050
11490
  if (path.length === 0) {
@@ -11054,6 +11494,29 @@ class AssignmentPattern extends NodeBase {
11054
11494
  hasEffectsOnInteractionAtPath(path, interaction, context) {
11055
11495
  return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
11056
11496
  }
11497
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
11498
+ return this.left.hasEffectsWhenDestructuring(context, destructuredInitPath, init);
11499
+ }
11500
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11501
+ let included = this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init) ||
11502
+ this.included;
11503
+ if ((included ||= this.right.shouldBeIncluded(context))) {
11504
+ this.right.include(context, false);
11505
+ if (!this.left.included) {
11506
+ this.left.included = true;
11507
+ // Unfortunately, we need to include the left side again now, so that
11508
+ // any declared variables are properly included.
11509
+ this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init);
11510
+ }
11511
+ }
11512
+ return (this.included = included);
11513
+ }
11514
+ includeNode(context) {
11515
+ this.included = true;
11516
+ if (!this.deoptimized)
11517
+ this.applyDeoptimizations();
11518
+ this.right.includePath(UNKNOWN_PATH, context);
11519
+ }
11057
11520
  markDeclarationReached() {
11058
11521
  this.left.markDeclarationReached();
11059
11522
  }
@@ -11076,22 +11539,34 @@ class AwaitExpression extends NodeBase {
11076
11539
  return true;
11077
11540
  }
11078
11541
  include(context, includeChildrenRecursively) {
11542
+ if (!this.included)
11543
+ this.includeNode(context);
11544
+ this.argument.include(context, includeChildrenRecursively);
11545
+ }
11546
+ includeNode(context) {
11547
+ this.included = true;
11079
11548
  if (!this.deoptimized)
11080
11549
  this.applyDeoptimizations();
11081
- if (!this.included) {
11082
- this.included = true;
11083
- checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) {
11084
- let parent = this.parent;
11085
- do {
11086
- if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression)
11087
- break checkTopLevelAwait;
11088
- } while ((parent = parent.parent));
11089
- this.scope.context.usesTopLevelAwait = true;
11090
- }
11550
+ checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) {
11551
+ let parent = this.parent;
11552
+ do {
11553
+ if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression)
11554
+ break checkTopLevelAwait;
11555
+ } while ((parent = parent.parent));
11556
+ this.scope.context.usesTopLevelAwait = true;
11091
11557
  }
11092
- this.argument.include(context, includeChildrenRecursively);
11558
+ // Thenables need to be included
11559
+ this.argument.includePath(THEN_PATH, context);
11560
+ }
11561
+ includePath(path, context) {
11562
+ if (!this.deoptimized)
11563
+ this.applyDeoptimizations();
11564
+ if (!this.included)
11565
+ this.includeNode(context);
11566
+ this.argument.includePath(path, context);
11093
11567
  }
11094
11568
  }
11569
+ const THEN_PATH = ['then'];
11095
11570
 
11096
11571
  const binaryOperators = {
11097
11572
  '!=': (left, right) => left != right,
@@ -11147,6 +11622,12 @@ class BinaryExpression extends NodeBase {
11147
11622
  hasEffectsOnInteractionAtPath(path, { type }) {
11148
11623
  return type !== INTERACTION_ACCESSED || path.length > 1;
11149
11624
  }
11625
+ includeNode(context) {
11626
+ this.included = true;
11627
+ if (this.operator === 'in') {
11628
+ this.right.includePath(UNKNOWN_PATH, context);
11629
+ }
11630
+ }
11150
11631
  removeAnnotations(code) {
11151
11632
  this.left.removeAnnotations(code);
11152
11633
  }
@@ -11155,6 +11636,7 @@ class BinaryExpression extends NodeBase {
11155
11636
  this.right.render(code, options);
11156
11637
  }
11157
11638
  }
11639
+ BinaryExpression.prototype.applyDeoptimizations = doNotDeoptimize;
11158
11640
 
11159
11641
  class BreakStatement extends NodeBase {
11160
11642
  hasEffects(context) {
@@ -11174,7 +11656,7 @@ class BreakStatement extends NodeBase {
11174
11656
  include(context) {
11175
11657
  this.included = true;
11176
11658
  if (this.label) {
11177
- this.label.include();
11659
+ this.label.include(context);
11178
11660
  context.includedLabels.add(this.label.name);
11179
11661
  }
11180
11662
  else {
@@ -11183,6 +11665,8 @@ class BreakStatement extends NodeBase {
11183
11665
  context.brokenFlow = true;
11184
11666
  }
11185
11667
  }
11668
+ BreakStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
11669
+ BreakStatement.prototype.applyDeoptimizations = doNotDeoptimize;
11186
11670
 
11187
11671
  function renderCallArguments(code, options, node) {
11188
11672
  if (node.arguments.length > 0) {
@@ -11369,10 +11853,14 @@ class CallExpression extends CallExpressionBase {
11369
11853
  this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)));
11370
11854
  }
11371
11855
  include(context, includeChildrenRecursively) {
11372
- if (!this.deoptimized)
11373
- this.applyDeoptimizations();
11856
+ if (!this.included)
11857
+ this.includeNode(context);
11374
11858
  if (includeChildrenRecursively) {
11375
- super.include(context, includeChildrenRecursively);
11859
+ this.callee.include(context, true);
11860
+ for (const argument of this.arguments) {
11861
+ argument.includePath(UNKNOWN_PATH, context);
11862
+ argument.include(context, true);
11863
+ }
11376
11864
  if (includeChildrenRecursively === INCLUDE_PARAMETERS &&
11377
11865
  this.callee instanceof Identifier &&
11378
11866
  this.callee.variable) {
@@ -11380,10 +11868,24 @@ class CallExpression extends CallExpressionBase {
11380
11868
  }
11381
11869
  }
11382
11870
  else {
11383
- this.included = true;
11384
- this.callee.include(context, false);
11871
+ // If the callee is a member expression and does not have a variable, its
11872
+ // object will already be included via the first argument of the
11873
+ // interaction in includeCallArguments. Including it again can lead to
11874
+ // severe performance problems.
11875
+ if (this.callee instanceof MemberExpression && !this.callee.variable) {
11876
+ this.callee.property.include(context, false);
11877
+ }
11878
+ else {
11879
+ this.callee.include(context, false);
11880
+ }
11881
+ this.callee.includeCallArguments(context, this.interaction);
11385
11882
  }
11386
- this.callee.includeCallArguments(context, this.arguments);
11883
+ }
11884
+ includeNode(context) {
11885
+ this.included = true;
11886
+ if (!this.deoptimized)
11887
+ this.applyDeoptimizations();
11888
+ this.callee.includePath(UNKNOWN_PATH, context);
11387
11889
  }
11388
11890
  initialise() {
11389
11891
  super.initialise();
@@ -11422,13 +11924,14 @@ class CatchClause extends NodeBase {
11422
11924
  this.type = type;
11423
11925
  if (param) {
11424
11926
  this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);
11425
- this.param.declare('parameter', UNKNOWN_EXPRESSION);
11927
+ this.param.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
11426
11928
  }
11427
11929
  this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);
11428
11930
  return super.parseNode(esTreeNode);
11429
11931
  }
11430
11932
  }
11431
11933
  CatchClause.prototype.preventChildBlockScope = true;
11934
+ CatchClause.prototype.includeNode = onlyIncludeSelf;
11432
11935
 
11433
11936
  class ChainExpression extends NodeBase {
11434
11937
  // deoptimizations are not relevant as we are not caching values
@@ -11440,17 +11943,22 @@ class ChainExpression extends NodeBase {
11440
11943
  hasEffects(context) {
11441
11944
  return this.expression.hasEffectsAsChainElement(context) === true;
11442
11945
  }
11946
+ includePath(path, context) {
11947
+ this.included = true;
11948
+ this.expression.includePath(path, context);
11949
+ }
11443
11950
  removeAnnotations(code) {
11444
11951
  this.expression.removeAnnotations(code);
11445
11952
  }
11446
- applyDeoptimizations() { }
11447
11953
  }
11954
+ ChainExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
11955
+ ChainExpression.prototype.applyDeoptimizations = doNotDeoptimize;
11448
11956
 
11449
11957
  class ClassBodyScope extends ChildScope {
11450
11958
  constructor(parent, classNode) {
11451
11959
  const { context } = parent;
11452
11960
  super(parent, context);
11453
- this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));
11961
+ this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, EMPTY_PATH, context, 'other')));
11454
11962
  this.instanceScope = new ChildScope(this, context);
11455
11963
  this.instanceScope.variables.set('this', new ThisVariable(context));
11456
11964
  }
@@ -11465,7 +11973,7 @@ class ClassBody extends NodeBase {
11465
11973
  }
11466
11974
  include(context, includeChildrenRecursively) {
11467
11975
  this.included = true;
11468
- this.scope.context.includeVariableInModule(this.scope.thisVariable);
11976
+ this.scope.context.includeVariableInModule(this.scope.thisVariable, UNKNOWN_PATH, context);
11469
11977
  for (const definition of this.body) {
11470
11978
  definition.include(context, includeChildrenRecursively);
11471
11979
  }
@@ -11478,8 +11986,9 @@ class ClassBody extends NodeBase {
11478
11986
  }
11479
11987
  return super.parseNode(esTreeNode);
11480
11988
  }
11481
- applyDeoptimizations() { }
11482
11989
  }
11990
+ ClassBody.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
11991
+ ClassBody.prototype.applyDeoptimizations = doNotDeoptimize;
11483
11992
 
11484
11993
  class ClassExpression extends ClassNode {
11485
11994
  render(code, options, { renderedSurroundingElement } = BLANK) {
@@ -11550,6 +12059,9 @@ class ConditionalExpression extends NodeBase {
11550
12059
  const unusedBranch = this.usedBranch === this.consequent ? this.alternate : this.consequent;
11551
12060
  this.usedBranch = null;
11552
12061
  unusedBranch.deoptimizePath(UNKNOWN_PATH);
12062
+ if (this.included) {
12063
+ unusedBranch.includePath(UNKNOWN_PATH, createInclusionContext());
12064
+ }
11553
12065
  const { expressionsToBeDeoptimized } = this;
11554
12066
  this.expressionsToBeDeoptimized = EMPTY_ARRAY;
11555
12067
  for (const expression of expressionsToBeDeoptimized) {
@@ -11607,7 +12119,7 @@ class ConditionalExpression extends NodeBase {
11607
12119
  include(context, includeChildrenRecursively) {
11608
12120
  this.included = true;
11609
12121
  const usedBranch = this.getUsedBranch();
11610
- if (includeChildrenRecursively || this.test.shouldBeIncluded(context) || usedBranch === null) {
12122
+ if (usedBranch === null || includeChildrenRecursively || this.test.shouldBeIncluded(context)) {
11611
12123
  this.test.include(context, includeChildrenRecursively);
11612
12124
  this.consequent.include(context, includeChildrenRecursively);
11613
12125
  this.alternate.include(context, includeChildrenRecursively);
@@ -11616,27 +12128,38 @@ class ConditionalExpression extends NodeBase {
11616
12128
  usedBranch.include(context, includeChildrenRecursively);
11617
12129
  }
11618
12130
  }
11619
- includeCallArguments(context, parameters) {
12131
+ includePath(path, context) {
12132
+ this.included = true;
12133
+ const usedBranch = this.getUsedBranch();
12134
+ if (usedBranch === null || this.test.shouldBeIncluded(context)) {
12135
+ this.consequent.includePath(path, context);
12136
+ this.alternate.includePath(path, context);
12137
+ }
12138
+ else {
12139
+ usedBranch.includePath(path, context);
12140
+ }
12141
+ }
12142
+ includeCallArguments(context, interaction) {
11620
12143
  const usedBranch = this.getUsedBranch();
11621
12144
  if (usedBranch) {
11622
- usedBranch.includeCallArguments(context, parameters);
12145
+ usedBranch.includeCallArguments(context, interaction);
11623
12146
  }
11624
12147
  else {
11625
- this.consequent.includeCallArguments(context, parameters);
11626
- this.alternate.includeCallArguments(context, parameters);
12148
+ this.consequent.includeCallArguments(context, interaction);
12149
+ this.alternate.includeCallArguments(context, interaction);
11627
12150
  }
11628
12151
  }
11629
12152
  removeAnnotations(code) {
11630
12153
  this.test.removeAnnotations(code);
11631
12154
  }
11632
12155
  render(code, options, { isCalleeOfRenderedParent, preventASI, renderedParentType, renderedSurroundingElement } = BLANK) {
11633
- const usedBranch = this.getUsedBranch();
11634
12156
  if (this.test.included) {
11635
12157
  this.test.render(code, options, { renderedSurroundingElement });
11636
12158
  this.consequent.render(code, options);
11637
12159
  this.alternate.render(code, options);
11638
12160
  }
11639
12161
  else {
12162
+ const usedBranch = this.getUsedBranch();
11640
12163
  const colonPos = findFirstOccurrenceOutsideComment(code.original, ':', this.consequent.end);
11641
12164
  const inclusionStart = findNonWhiteSpace(code.original, (this.consequent.included
11642
12165
  ? findFirstOccurrenceOutsideComment(code.original, '?', this.test.end)
@@ -11668,6 +12191,8 @@ class ConditionalExpression extends NodeBase {
11668
12191
  : (this.usedBranch = testValue ? this.consequent : this.alternate);
11669
12192
  }
11670
12193
  }
12194
+ ConditionalExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12195
+ ConditionalExpression.prototype.applyDeoptimizations = doNotDeoptimize;
11671
12196
 
11672
12197
  class ContinueStatement extends NodeBase {
11673
12198
  hasEffects(context) {
@@ -11687,7 +12212,7 @@ class ContinueStatement extends NodeBase {
11687
12212
  include(context) {
11688
12213
  this.included = true;
11689
12214
  if (this.label) {
11690
- this.label.include();
12215
+ this.label.include(context);
11691
12216
  context.includedLabels.add(this.label.name);
11692
12217
  }
11693
12218
  else {
@@ -11696,12 +12221,15 @@ class ContinueStatement extends NodeBase {
11696
12221
  context.brokenFlow = true;
11697
12222
  }
11698
12223
  }
12224
+ ContinueStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12225
+ ContinueStatement.prototype.applyDeoptimizations = doNotDeoptimize;
11699
12226
 
11700
12227
  class DebuggerStatement extends NodeBase {
11701
12228
  hasEffects() {
11702
12229
  return true;
11703
12230
  }
11704
12231
  }
12232
+ DebuggerStatement.prototype.includeNode = onlyIncludeSelf;
11705
12233
 
11706
12234
  class Decorator extends NodeBase {
11707
12235
  hasEffects(context) {
@@ -11709,6 +12237,7 @@ class Decorator extends NodeBase {
11709
12237
  this.expression.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context));
11710
12238
  }
11711
12239
  }
12240
+ Decorator.prototype.includeNode = onlyIncludeSelf;
11712
12241
 
11713
12242
  function hasLoopBodyEffects(context, body) {
11714
12243
  const { brokenFlow, hasBreak, hasContinue, ignore } = context;
@@ -11748,12 +12277,15 @@ class DoWhileStatement extends NodeBase {
11748
12277
  includeLoopBody(context, this.body, includeChildrenRecursively);
11749
12278
  }
11750
12279
  }
12280
+ DoWhileStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12281
+ DoWhileStatement.prototype.applyDeoptimizations = doNotDeoptimize;
11751
12282
 
11752
12283
  class EmptyStatement extends NodeBase {
11753
12284
  hasEffects() {
11754
12285
  return false;
11755
12286
  }
11756
12287
  }
12288
+ EmptyStatement.prototype.includeNode = onlyIncludeSelf;
11757
12289
 
11758
12290
  class ExportAllDeclaration extends NodeBase {
11759
12291
  hasEffects() {
@@ -11766,9 +12298,10 @@ class ExportAllDeclaration extends NodeBase {
11766
12298
  render(code, _options, nodeRenderOptions) {
11767
12299
  code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
11768
12300
  }
11769
- applyDeoptimizations() { }
11770
12301
  }
11771
12302
  ExportAllDeclaration.prototype.needsBoundaries = true;
12303
+ ExportAllDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12304
+ ExportAllDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
11772
12305
 
11773
12306
  class ExportNamedDeclaration extends NodeBase {
11774
12307
  bind() {
@@ -11795,13 +12328,15 @@ class ExportNamedDeclaration extends NodeBase {
11795
12328
  this.declaration.render(code, options, { end, start });
11796
12329
  }
11797
12330
  }
11798
- applyDeoptimizations() { }
11799
12331
  }
11800
12332
  ExportNamedDeclaration.prototype.needsBoundaries = true;
12333
+ ExportNamedDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12334
+ ExportNamedDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
11801
12335
 
11802
12336
  class ExportSpecifier extends NodeBase {
11803
- applyDeoptimizations() { }
11804
12337
  }
12338
+ ExportSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12339
+ ExportSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
11805
12340
 
11806
12341
  class ForInStatement extends NodeBase {
11807
12342
  createScope(parentScope) {
@@ -11819,11 +12354,18 @@ class ForInStatement extends NodeBase {
11819
12354
  const { body, deoptimized, left, right } = this;
11820
12355
  if (!deoptimized)
11821
12356
  this.applyDeoptimizations();
11822
- this.included = true;
12357
+ if (!this.included)
12358
+ this.includeNode(context);
11823
12359
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
11824
12360
  right.include(context, includeChildrenRecursively);
11825
12361
  includeLoopBody(context, body, includeChildrenRecursively);
11826
12362
  }
12363
+ includeNode(context) {
12364
+ this.included = true;
12365
+ if (!this.deoptimized)
12366
+ this.applyDeoptimizations();
12367
+ this.right.includePath(UNKNOWN_PATH, context);
12368
+ }
11827
12369
  initialise() {
11828
12370
  super.initialise();
11829
12371
  this.left.setAssignedValue(UNKNOWN_EXPRESSION);
@@ -11864,11 +12406,18 @@ class ForOfStatement extends NodeBase {
11864
12406
  const { body, deoptimized, left, right } = this;
11865
12407
  if (!deoptimized)
11866
12408
  this.applyDeoptimizations();
11867
- this.included = true;
12409
+ if (!this.included)
12410
+ this.includeNode(context);
11868
12411
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
11869
12412
  right.include(context, includeChildrenRecursively);
11870
12413
  includeLoopBody(context, body, includeChildrenRecursively);
11871
12414
  }
12415
+ includeNode(context) {
12416
+ this.included = true;
12417
+ if (!this.deoptimized)
12418
+ this.applyDeoptimizations();
12419
+ this.right.includePath(UNKNOWN_PATH, context);
12420
+ }
11872
12421
  initialise() {
11873
12422
  super.initialise();
11874
12423
  this.left.setAssignedValue(UNKNOWN_EXPRESSION);
@@ -11904,7 +12453,9 @@ class ForStatement extends NodeBase {
11904
12453
  }
11905
12454
  include(context, includeChildrenRecursively) {
11906
12455
  this.included = true;
11907
- this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true });
12456
+ this.init?.include(context, includeChildrenRecursively, {
12457
+ asSingleStatement: true
12458
+ });
11908
12459
  this.test?.include(context, includeChildrenRecursively);
11909
12460
  this.update?.include(context, includeChildrenRecursively);
11910
12461
  includeLoopBody(context, this.body, includeChildrenRecursively);
@@ -11916,6 +12467,8 @@ class ForStatement extends NodeBase {
11916
12467
  this.body.render(code, options);
11917
12468
  }
11918
12469
  }
12470
+ ForStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12471
+ ForStatement.prototype.applyDeoptimizations = doNotDeoptimize;
11919
12472
 
11920
12473
  class FunctionExpression extends FunctionNode {
11921
12474
  createScope(parentScope) {
@@ -11947,9 +12500,9 @@ class TrackingScope extends BlockScope {
11947
12500
  super(...arguments);
11948
12501
  this.hoistedDeclarations = [];
11949
12502
  }
11950
- addDeclaration(identifier, context, init, kind) {
12503
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
11951
12504
  this.hoistedDeclarations.push(identifier);
11952
- return super.addDeclaration(identifier, context, init, kind);
12505
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
11953
12506
  }
11954
12507
  }
11955
12508
 
@@ -12048,7 +12601,6 @@ class IfStatement extends NodeBase {
12048
12601
  }
12049
12602
  this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess);
12050
12603
  }
12051
- applyDeoptimizations() { }
12052
12604
  getTestValue() {
12053
12605
  if (this.testValue === unset) {
12054
12606
  return (this.testValue = tryCastLiteralValueToBoolean(this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)));
@@ -12117,6 +12669,8 @@ class IfStatement extends NodeBase {
12117
12669
  return false;
12118
12670
  }
12119
12671
  }
12672
+ IfStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12673
+ IfStatement.prototype.applyDeoptimizations = doNotDeoptimize;
12120
12674
 
12121
12675
  class ImportAttribute extends NodeBase {
12122
12676
  }
@@ -12134,13 +12688,15 @@ class ImportDeclaration extends NodeBase {
12134
12688
  render(code, _options, nodeRenderOptions) {
12135
12689
  code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
12136
12690
  }
12137
- applyDeoptimizations() { }
12138
12691
  }
12139
12692
  ImportDeclaration.prototype.needsBoundaries = true;
12693
+ ImportDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12694
+ ImportDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
12140
12695
 
12141
12696
  class ImportDefaultSpecifier extends NodeBase {
12142
- applyDeoptimizations() { }
12143
12697
  }
12698
+ ImportDefaultSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12699
+ ImportDefaultSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
12144
12700
 
12145
12701
  function isReassignedExportsMember(variable, exportNamesByVariable) {
12146
12702
  return (variable.renderBaseName !== null && exportNamesByVariable.has(variable) && variable.isReassigned);
@@ -12149,28 +12705,33 @@ function isReassignedExportsMember(variable, exportNamesByVariable) {
12149
12705
  class VariableDeclarator extends NodeBase {
12150
12706
  declareDeclarator(kind, isUsingDeclaration) {
12151
12707
  this.isUsingDeclaration = isUsingDeclaration;
12152
- this.id.declare(kind, this.init || UNDEFINED_EXPRESSION);
12708
+ this.id.declare(kind, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION);
12153
12709
  }
12154
12710
  deoptimizePath(path) {
12155
12711
  this.id.deoptimizePath(path);
12156
12712
  }
12157
12713
  hasEffects(context) {
12158
- if (!this.deoptimized)
12159
- this.applyDeoptimizations();
12160
12714
  const initEffect = this.init?.hasEffects(context);
12161
12715
  this.id.markDeclarationReached();
12162
- return initEffect || this.id.hasEffects(context) || this.isUsingDeclaration;
12716
+ return (initEffect ||
12717
+ this.isUsingDeclaration ||
12718
+ this.id.hasEffects(context) ||
12719
+ (this.scope.context.options.treeshake
12720
+ .propertyReadSideEffects &&
12721
+ this.id.hasEffectsWhenDestructuring(context, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION)));
12163
12722
  }
12164
12723
  include(context, includeChildrenRecursively) {
12165
- const { deoptimized, id, init } = this;
12166
- if (!deoptimized)
12167
- this.applyDeoptimizations();
12168
- this.included = true;
12724
+ const { id, init } = this;
12725
+ if (!this.included)
12726
+ this.includeNode();
12169
12727
  init?.include(context, includeChildrenRecursively);
12170
12728
  id.markDeclarationReached();
12171
- if (includeChildrenRecursively || id.shouldBeIncluded(context)) {
12729
+ if (includeChildrenRecursively) {
12172
12730
  id.include(context, includeChildrenRecursively);
12173
12731
  }
12732
+ else {
12733
+ id.includeDestructuredIfNecessary(context, EMPTY_PATH, init || UNDEFINED_EXPRESSION);
12734
+ }
12174
12735
  }
12175
12736
  removeAnnotations(code) {
12176
12737
  this.init?.removeAnnotations(code);
@@ -12200,8 +12761,8 @@ class VariableDeclarator extends NodeBase {
12200
12761
  code.appendLeft(end, `${_}=${_}void 0`);
12201
12762
  }
12202
12763
  }
12203
- applyDeoptimizations() {
12204
- this.deoptimized = true;
12764
+ includeNode() {
12765
+ this.included = true;
12205
12766
  const { id, init } = this;
12206
12767
  if (init && id instanceof Identifier && init instanceof ClassExpression && !init.id) {
12207
12768
  const { name, variable } = id;
@@ -12213,11 +12774,14 @@ class VariableDeclarator extends NodeBase {
12213
12774
  }
12214
12775
  }
12215
12776
  }
12777
+ VariableDeclarator.prototype.applyDeoptimizations = doNotDeoptimize;
12216
12778
 
12217
12779
  class ImportExpression extends NodeBase {
12218
12780
  constructor() {
12219
12781
  super(...arguments);
12220
12782
  this.inlineNamespace = null;
12783
+ this.hasUnknownAccessedKey = false;
12784
+ this.accessedPropKey = new Set();
12221
12785
  this.attributes = null;
12222
12786
  this.mechanism = null;
12223
12787
  this.namespaceExportName = undefined;
@@ -12250,12 +12814,15 @@ class ImportExpression extends NodeBase {
12250
12814
  if (parent2 instanceof ExpressionStatement) {
12251
12815
  return EMPTY_ARRAY;
12252
12816
  }
12253
- // Case 1: const { foo } = await import('bar')
12817
+ // Case 1: const { foo } / module = await import('bar')
12254
12818
  if (parent2 instanceof VariableDeclarator) {
12255
12819
  const declaration = parent2.id;
12256
- return declaration instanceof ObjectPattern
12257
- ? getDeterministicObjectDestructure(declaration)
12258
- : undefined;
12820
+ if (declaration instanceof Identifier) {
12821
+ return this.hasUnknownAccessedKey ? undefined : [...this.accessedPropKey];
12822
+ }
12823
+ if (declaration instanceof ObjectPattern) {
12824
+ return getDeterministicObjectDestructure(declaration);
12825
+ }
12259
12826
  }
12260
12827
  // Case 2: (await import('bar')).foo
12261
12828
  if (parent2 instanceof MemberExpression) {
@@ -12305,13 +12872,30 @@ class ImportExpression extends NodeBase {
12305
12872
  return true;
12306
12873
  }
12307
12874
  include(context, includeChildrenRecursively) {
12308
- if (!this.included) {
12309
- this.included = true;
12310
- this.scope.context.includeDynamicImport(this);
12311
- this.scope.addAccessedDynamicImport(this);
12312
- }
12875
+ if (!this.included)
12876
+ this.includeNode();
12313
12877
  this.source.include(context, includeChildrenRecursively);
12314
12878
  }
12879
+ includeNode() {
12880
+ this.included = true;
12881
+ this.scope.context.includeDynamicImport(this);
12882
+ this.scope.addAccessedDynamicImport(this);
12883
+ }
12884
+ includePath(path) {
12885
+ if (!this.included)
12886
+ this.includeNode();
12887
+ // Technically, this is not correct as dynamic imports return a Promise.
12888
+ if (this.hasUnknownAccessedKey)
12889
+ return;
12890
+ if (path[0] === UnknownKey) {
12891
+ this.hasUnknownAccessedKey = true;
12892
+ }
12893
+ else if (typeof path[0] === 'string') {
12894
+ this.accessedPropKey.add(path[0]);
12895
+ }
12896
+ // Update included paths
12897
+ this.scope.context.includeDynamicImport(this);
12898
+ }
12315
12899
  initialise() {
12316
12900
  super.initialise();
12317
12901
  this.scope.context.addDynamicImport(this);
@@ -12380,7 +12964,6 @@ class ImportExpression extends NodeBase {
12380
12964
  setInternalResolution(inlineNamespace) {
12381
12965
  this.inlineNamespace = inlineNamespace;
12382
12966
  }
12383
- applyDeoptimizations() { }
12384
12967
  getDynamicImportMechanismAndHelper(resolution, exportMode, { compact, dynamicImportInCjs, format, generatedCode: { arrowFunctions }, interop }, { _, getDirectReturnFunction, getDirectReturnIifeLeft }, pluginDriver) {
12385
12968
  const mechanism = pluginDriver.hookFirstSync('renderDynamicImport', [
12386
12969
  {
@@ -12470,6 +13053,7 @@ class ImportExpression extends NodeBase {
12470
13053
  return { helper: null, mechanism: null };
12471
13054
  }
12472
13055
  }
13056
+ ImportExpression.prototype.applyDeoptimizations = doNotDeoptimize;
12473
13057
  function getInteropHelper(resolution, exportMode, interop) {
12474
13058
  return exportMode === 'external'
12475
13059
  ? namespaceInteropHelpersByInteropType[interop(resolution instanceof ExternalModule ? resolution.id : null)]
@@ -12493,12 +13077,14 @@ function getDeterministicObjectDestructure(objectPattern) {
12493
13077
  }
12494
13078
 
12495
13079
  class ImportNamespaceSpecifier extends NodeBase {
12496
- applyDeoptimizations() { }
12497
13080
  }
13081
+ ImportNamespaceSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13082
+ ImportNamespaceSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
12498
13083
 
12499
13084
  class ImportSpecifier extends NodeBase {
12500
- applyDeoptimizations() { }
12501
13085
  }
13086
+ ImportSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13087
+ ImportSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
12502
13088
 
12503
13089
  class JSXIdentifier extends IdentifierBase {
12504
13090
  constructor() {
@@ -12515,6 +13101,29 @@ class JSXIdentifier extends IdentifierBase {
12515
13101
  this.isNativeElement = true;
12516
13102
  }
12517
13103
  }
13104
+ include(context) {
13105
+ if (!this.included)
13106
+ this.includeNode(context);
13107
+ }
13108
+ includeNode(context) {
13109
+ this.included = true;
13110
+ if (!this.deoptimized)
13111
+ this.applyDeoptimizations();
13112
+ if (this.variable !== null) {
13113
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
13114
+ }
13115
+ }
13116
+ includePath(path, context) {
13117
+ if (!this.included) {
13118
+ this.included = true;
13119
+ if (this.variable !== null) {
13120
+ this.scope.context.includeVariableInModule(this.variable, path, context);
13121
+ }
13122
+ }
13123
+ else if (path.length > 0) {
13124
+ this.variable?.includePath(path, context);
13125
+ }
13126
+ }
12518
13127
  render(code, { snippets: { getPropertyAccess }, useOriginalName }) {
12519
13128
  if (this.variable) {
12520
13129
  const name = this.variable.getName(getPropertyAccess, useOriginalName);
@@ -12576,6 +13185,7 @@ class JSXAttribute extends NodeBase {
12576
13185
  }
12577
13186
  }
12578
13187
  }
13188
+ JSXAttribute.prototype.includeNode = onlyIncludeSelf;
12579
13189
 
12580
13190
  class JSXClosingBase extends NodeBase {
12581
13191
  render(code, options) {
@@ -12588,6 +13198,7 @@ class JSXClosingBase extends NodeBase {
12588
13198
  }
12589
13199
  }
12590
13200
  }
13201
+ JSXClosingBase.prototype.includeNode = onlyIncludeSelf;
12591
13202
 
12592
13203
  class JSXClosingElement extends JSXClosingBase {
12593
13204
  }
@@ -12608,8 +13219,15 @@ class JSXSpreadAttribute extends NodeBase {
12608
13219
 
12609
13220
  class JSXEmptyExpression extends NodeBase {
12610
13221
  }
13222
+ JSXEmptyExpression.prototype.includeNode = onlyIncludeSelf;
12611
13223
 
12612
13224
  class JSXExpressionContainer extends NodeBase {
13225
+ includeNode(context) {
13226
+ this.included = true;
13227
+ if (!this.deoptimized)
13228
+ this.applyDeoptimizations();
13229
+ this.expression.includePath(UNKNOWN_PATH, context);
13230
+ }
12613
13231
  render(code, options) {
12614
13232
  const { mode } = this.scope.context.options.jsx;
12615
13233
  if (mode !== 'preserve') {
@@ -12630,7 +13248,7 @@ function getRenderedJsxChildren(children) {
12630
13248
  return renderedChildren;
12631
13249
  }
12632
13250
 
12633
- function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
13251
+ function getAndIncludeFactoryVariable(factory, preserve, importSource, node, context) {
12634
13252
  const [baseName, nestedName] = factory.split('.');
12635
13253
  let factoryVariable;
12636
13254
  if (importSource) {
@@ -12638,7 +13256,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
12638
13256
  if (preserve) {
12639
13257
  // This pretends we are accessing an included global variable of the same name
12640
13258
  const globalVariable = node.scope.findGlobal(baseName);
12641
- globalVariable.include();
13259
+ globalVariable.includePath(UNKNOWN_PATH, context);
12642
13260
  // This excludes this variable from renaming
12643
13261
  factoryVariable.globalName = baseName;
12644
13262
  }
@@ -12646,7 +13264,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
12646
13264
  else {
12647
13265
  factoryVariable = node.scope.findGlobal(baseName);
12648
13266
  }
12649
- node.scope.context.includeVariableInModule(factoryVariable);
13267
+ node.scope.context.includeVariableInModule(factoryVariable, UNKNOWN_PATH, context);
12650
13268
  if (factoryVariable instanceof LocalVariable) {
12651
13269
  factoryVariable.consolidateInitializers();
12652
13270
  factoryVariable.addUsedPlace(node);
@@ -12669,16 +13287,20 @@ class JSXElementBase extends NodeBase {
12669
13287
  }
12670
13288
  }
12671
13289
  include(context, includeChildrenRecursively) {
12672
- if (!this.included) {
12673
- const { factory, importSource, mode } = this.jsxMode;
12674
- if (factory) {
12675
- this.factory = factory;
12676
- this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this);
12677
- }
13290
+ if (!this.included)
13291
+ this.includeNode(context);
13292
+ for (const child of this.children) {
13293
+ child.include(context, includeChildrenRecursively);
13294
+ }
13295
+ }
13296
+ includeNode(context) {
13297
+ this.included = true;
13298
+ const { factory, importSource, mode } = this.jsxMode;
13299
+ if (factory) {
13300
+ this.factory = factory;
13301
+ this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this, context);
12678
13302
  }
12679
- super.include(context, includeChildrenRecursively);
12680
13303
  }
12681
- applyDeoptimizations() { }
12682
13304
  getRenderingMode() {
12683
13305
  const jsx = this.scope.context.options.jsx;
12684
13306
  const { mode, factory, importSource } = jsx;
@@ -12716,8 +13338,14 @@ class JSXElementBase extends NodeBase {
12716
13338
  return { childrenEnd, firstChild, hasMultipleChildren };
12717
13339
  }
12718
13340
  }
13341
+ JSXElementBase.prototype.applyDeoptimizations = doNotDeoptimize;
12719
13342
 
12720
13343
  class JSXElement extends JSXElementBase {
13344
+ include(context, includeChildrenRecursively) {
13345
+ super.include(context, includeChildrenRecursively);
13346
+ this.openingElement.include(context, includeChildrenRecursively);
13347
+ this.closingElement?.include(context, includeChildrenRecursively);
13348
+ }
12721
13349
  render(code, options) {
12722
13350
  switch (this.jsxMode.mode) {
12723
13351
  case 'classic': {
@@ -12869,6 +13497,11 @@ class JSXElement extends JSXElementBase {
12869
13497
  }
12870
13498
 
12871
13499
  class JSXFragment extends JSXElementBase {
13500
+ include(context, includeChildrenRecursively) {
13501
+ super.include(context, includeChildrenRecursively);
13502
+ this.openingFragment.include(context, includeChildrenRecursively);
13503
+ this.closingFragment.include(context, includeChildrenRecursively);
13504
+ }
12872
13505
  render(code, options) {
12873
13506
  switch (this.jsxMode.mode) {
12874
13507
  case 'classic': {
@@ -12918,10 +13551,22 @@ class JSXFragment extends JSXElementBase {
12918
13551
  }
12919
13552
 
12920
13553
  class JSXMemberExpression extends NodeBase {
13554
+ includeNode(context) {
13555
+ this.included = true;
13556
+ if (!this.deoptimized)
13557
+ this.applyDeoptimizations();
13558
+ this.object.includePath([this.property.name], context);
13559
+ }
13560
+ includePath(path, context) {
13561
+ if (!this.included)
13562
+ this.includeNode(context);
13563
+ this.object.includePath([this.property.name, ...path], context);
13564
+ }
12921
13565
  }
12922
13566
 
12923
13567
  class JSXNamespacedName extends NodeBase {
12924
13568
  }
13569
+ JSXNamespacedName.prototype.includeNode = onlyIncludeSelf;
12925
13570
 
12926
13571
  class JSXOpeningElement extends NodeBase {
12927
13572
  render(code, options, { jsxMode = this.scope.context.options.jsx.mode } = {}) {
@@ -12931,6 +13576,7 @@ class JSXOpeningElement extends NodeBase {
12931
13576
  }
12932
13577
  }
12933
13578
  }
13579
+ JSXOpeningElement.prototype.includeNode = onlyIncludeSelf;
12934
13580
 
12935
13581
  class JSXOpeningFragment extends NodeBase {
12936
13582
  constructor() {
@@ -12938,22 +13584,22 @@ class JSXOpeningFragment extends NodeBase {
12938
13584
  this.fragment = null;
12939
13585
  this.fragmentVariable = null;
12940
13586
  }
12941
- include(context, includeChildrenRecursively) {
12942
- if (!this.included) {
12943
- const jsx = this.scope.context.options.jsx;
12944
- if (jsx.mode === 'automatic') {
12945
- this.fragment = 'Fragment';
12946
- this.fragmentVariable = getAndIncludeFactoryVariable('Fragment', false, jsx.jsxImportSource, this);
12947
- }
12948
- else {
12949
- const { fragment, importSource, mode } = jsx;
12950
- if (fragment != null) {
12951
- this.fragment = fragment;
12952
- this.fragmentVariable = getAndIncludeFactoryVariable(fragment, mode === 'preserve', importSource, this);
12953
- }
13587
+ includeNode(context) {
13588
+ this.included = true;
13589
+ if (!this.deoptimized)
13590
+ this.applyDeoptimizations();
13591
+ const jsx = this.scope.context.options.jsx;
13592
+ if (jsx.mode === 'automatic') {
13593
+ this.fragment = 'Fragment';
13594
+ this.fragmentVariable = getAndIncludeFactoryVariable('Fragment', false, jsx.jsxImportSource, this, context);
13595
+ }
13596
+ else {
13597
+ const { fragment, importSource, mode } = jsx;
13598
+ if (fragment != null) {
13599
+ this.fragment = fragment;
13600
+ this.fragmentVariable = getAndIncludeFactoryVariable(fragment, mode === 'preserve', importSource, this, context);
12954
13601
  }
12955
13602
  }
12956
- super.include(context, includeChildrenRecursively);
12957
13603
  }
12958
13604
  render(code, options) {
12959
13605
  const { mode } = this.scope.context.options.jsx;
@@ -12990,6 +13636,7 @@ class JSXText extends NodeBase {
12990
13636
  }
12991
13637
  }
12992
13638
  }
13639
+ JSXText.prototype.includeNode = onlyIncludeSelf;
12993
13640
 
12994
13641
  class LabeledStatement extends NodeBase {
12995
13642
  hasEffects(context) {
@@ -13011,17 +13658,22 @@ class LabeledStatement extends NodeBase {
13011
13658
  return bodyHasEffects;
13012
13659
  }
13013
13660
  include(context, includeChildrenRecursively) {
13014
- this.included = true;
13661
+ if (!this.included)
13662
+ this.includeNode(context);
13015
13663
  const { brokenFlow, includedLabels } = context;
13016
13664
  context.includedLabels = new Set();
13017
13665
  this.body.include(context, includeChildrenRecursively);
13018
13666
  if (includeChildrenRecursively || context.includedLabels.has(this.label.name)) {
13019
- this.label.include();
13667
+ this.label.include(context);
13020
13668
  context.includedLabels.delete(this.label.name);
13021
13669
  context.brokenFlow = brokenFlow;
13022
13670
  }
13023
13671
  context.includedLabels = new Set([...includedLabels, ...context.includedLabels]);
13024
13672
  }
13673
+ includeNode(context) {
13674
+ this.included = true;
13675
+ this.body.includePath(UNKNOWN_PATH, context);
13676
+ }
13025
13677
  render(code, options) {
13026
13678
  if (this.label.included) {
13027
13679
  this.label.render(code, options);
@@ -13032,6 +13684,7 @@ class LabeledStatement extends NodeBase {
13032
13684
  this.body.render(code, options);
13033
13685
  }
13034
13686
  }
13687
+ LabeledStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13035
13688
 
13036
13689
  class LogicalExpression extends NodeBase {
13037
13690
  constructor() {
@@ -13048,10 +13701,10 @@ class LogicalExpression extends NodeBase {
13048
13701
  this.flags = setFlag(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */, value);
13049
13702
  }
13050
13703
  get hasDeoptimizedCache() {
13051
- return isFlagSet(this.flags, 16777216 /* Flag.hasDeoptimizedCache */);
13704
+ return isFlagSet(this.flags, 33554432 /* Flag.hasDeoptimizedCache */);
13052
13705
  }
13053
13706
  set hasDeoptimizedCache(value) {
13054
- this.flags = setFlag(this.flags, 16777216 /* Flag.hasDeoptimizedCache */, value);
13707
+ this.flags = setFlag(this.flags, 33554432 /* Flag.hasDeoptimizedCache */, value);
13055
13708
  }
13056
13709
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
13057
13710
  this.left.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -13064,6 +13717,10 @@ class LogicalExpression extends NodeBase {
13064
13717
  const unusedBranch = this.usedBranch === this.left ? this.right : this.left;
13065
13718
  this.usedBranch = null;
13066
13719
  unusedBranch.deoptimizePath(UNKNOWN_PATH);
13720
+ if (this.included) {
13721
+ // As we are not tracking inclusions, we just include everything
13722
+ unusedBranch.includePath(UNKNOWN_PATH, createInclusionContext());
13723
+ }
13067
13724
  }
13068
13725
  const { scope: { context }, expressionsToBeDeoptimized } = this;
13069
13726
  this.expressionsToBeDeoptimized = EMPTY_ARRAY;
@@ -13109,16 +13766,17 @@ class LogicalExpression extends NodeBase {
13109
13766
  }
13110
13767
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
13111
13768
  const usedBranch = this.getUsedBranch();
13112
- if (!usedBranch)
13113
- return [
13114
- new MultiExpression([
13115
- this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
13116
- this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
13117
- ]),
13118
- false
13119
- ];
13120
- this.expressionsToBeDeoptimized.push(origin);
13121
- return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
13769
+ if (usedBranch) {
13770
+ this.expressionsToBeDeoptimized.push(origin);
13771
+ return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
13772
+ }
13773
+ return [
13774
+ new MultiExpression([
13775
+ this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
13776
+ this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
13777
+ ]),
13778
+ false
13779
+ ];
13122
13780
  }
13123
13781
  hasEffects(context) {
13124
13782
  if (this.left.hasEffects(context)) {
@@ -13131,18 +13789,18 @@ class LogicalExpression extends NodeBase {
13131
13789
  }
13132
13790
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13133
13791
  const usedBranch = this.getUsedBranch();
13134
- if (!usedBranch) {
13135
- return (this.left.hasEffectsOnInteractionAtPath(path, interaction, context) ||
13136
- this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
13792
+ if (usedBranch) {
13793
+ return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
13137
13794
  }
13138
- return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
13795
+ return (this.left.hasEffectsOnInteractionAtPath(path, interaction, context) ||
13796
+ this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
13139
13797
  }
13140
13798
  include(context, includeChildrenRecursively) {
13141
13799
  this.included = true;
13142
13800
  const usedBranch = this.getUsedBranch();
13143
13801
  if (includeChildrenRecursively ||
13144
- (usedBranch === this.right && this.left.shouldBeIncluded(context)) ||
13145
- !usedBranch) {
13802
+ !usedBranch ||
13803
+ (usedBranch === this.right && this.left.shouldBeIncluded(context))) {
13146
13804
  this.left.include(context, includeChildrenRecursively);
13147
13805
  this.right.include(context, includeChildrenRecursively);
13148
13806
  }
@@ -13150,6 +13808,17 @@ class LogicalExpression extends NodeBase {
13150
13808
  usedBranch.include(context, includeChildrenRecursively);
13151
13809
  }
13152
13810
  }
13811
+ includePath(path, context) {
13812
+ this.included = true;
13813
+ const usedBranch = this.getUsedBranch();
13814
+ if (!usedBranch || (usedBranch === this.right && this.left.shouldBeIncluded(context))) {
13815
+ this.left.includePath(path, context);
13816
+ this.right.includePath(path, context);
13817
+ }
13818
+ else {
13819
+ usedBranch.includePath(path, context);
13820
+ }
13821
+ }
13153
13822
  removeAnnotations(code) {
13154
13823
  this.left.removeAnnotations(code);
13155
13824
  }
@@ -13202,6 +13871,8 @@ class LogicalExpression extends NodeBase {
13202
13871
  return this.usedBranch;
13203
13872
  }
13204
13873
  }
13874
+ LogicalExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13875
+ LogicalExpression.prototype.applyDeoptimizations = doNotDeoptimize;
13205
13876
 
13206
13877
  class NewExpression extends NodeBase {
13207
13878
  hasEffects(context) {
@@ -13221,16 +13892,21 @@ class NewExpression extends NodeBase {
13221
13892
  return path.length > 0 || type !== INTERACTION_ACCESSED;
13222
13893
  }
13223
13894
  include(context, includeChildrenRecursively) {
13224
- if (!this.deoptimized)
13225
- this.applyDeoptimizations();
13226
13895
  if (includeChildrenRecursively) {
13227
13896
  super.include(context, includeChildrenRecursively);
13228
13897
  }
13229
13898
  else {
13230
- this.included = true;
13899
+ if (!this.included)
13900
+ this.includeNode(context);
13231
13901
  this.callee.include(context, false);
13232
13902
  }
13233
- this.callee.includeCallArguments(context, this.arguments);
13903
+ this.callee.includeCallArguments(context, this.interaction);
13904
+ }
13905
+ includeNode(context) {
13906
+ this.included = true;
13907
+ if (!this.deoptimized)
13908
+ this.applyDeoptimizations();
13909
+ this.callee.includePath(UNKNOWN_PATH, context);
13234
13910
  }
13235
13911
  initialise() {
13236
13912
  super.initialise();
@@ -13259,6 +13935,7 @@ class ObjectExpression extends NodeBase {
13259
13935
  constructor() {
13260
13936
  super(...arguments);
13261
13937
  this.objectEntity = null;
13938
+ this.protoProp = null;
13262
13939
  }
13263
13940
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
13264
13941
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -13278,15 +13955,43 @@ class ObjectExpression extends NodeBase {
13278
13955
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13279
13956
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
13280
13957
  }
13958
+ include(context, includeChildrenRecursively) {
13959
+ if (!this.included)
13960
+ this.includeNode(context);
13961
+ this.getObjectEntity().include(context, includeChildrenRecursively);
13962
+ this.protoProp?.include(context, includeChildrenRecursively);
13963
+ }
13964
+ includeNode(context) {
13965
+ this.included = true;
13966
+ this.protoProp?.includePath(UNKNOWN_PATH, context);
13967
+ }
13968
+ includePath(path, context) {
13969
+ if (!this.included)
13970
+ this.includeNode(context);
13971
+ this.getObjectEntity().includePath(path, context);
13972
+ }
13281
13973
  render(code, options, { renderedSurroundingElement } = BLANK) {
13282
- super.render(code, options);
13283
13974
  if (renderedSurroundingElement === ExpressionStatement$1 ||
13284
13975
  renderedSurroundingElement === ArrowFunctionExpression$1) {
13285
13976
  code.appendRight(this.start, '(');
13286
13977
  code.prependLeft(this.end, ')');
13287
13978
  }
13979
+ if (this.properties.length > 0) {
13980
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
13981
+ let lastSeparatorPos = null;
13982
+ for (const { node, separator, start, end } of separatedNodes) {
13983
+ if (!node.included) {
13984
+ treeshakeNode(node, code, start, end);
13985
+ continue;
13986
+ }
13987
+ lastSeparatorPos = separator;
13988
+ node.render(code, options);
13989
+ }
13990
+ if (lastSeparatorPos) {
13991
+ code.remove(lastSeparatorPos, this.end - 1);
13992
+ }
13993
+ }
13288
13994
  }
13289
- applyDeoptimizations() { }
13290
13995
  getObjectEntity() {
13291
13996
  if (this.objectEntity !== null) {
13292
13997
  return this.objectEntity;
@@ -13315,6 +14020,7 @@ class ObjectExpression extends NodeBase {
13315
14020
  ? property.key.name
13316
14021
  : String(property.key.value);
13317
14022
  if (key === '__proto__' && property.kind === 'init') {
14023
+ this.protoProp = property;
13318
14024
  prototype =
13319
14025
  property.value instanceof Literal && property.value.value === null
13320
14026
  ? null
@@ -13327,6 +14033,7 @@ class ObjectExpression extends NodeBase {
13327
14033
  return (this.objectEntity = new ObjectEntity(properties, prototype));
13328
14034
  }
13329
14035
  }
14036
+ ObjectExpression.prototype.applyDeoptimizations = doNotDeoptimize;
13330
14037
 
13331
14038
  class PanicError extends NodeBase {
13332
14039
  initialise() {
@@ -13353,6 +14060,7 @@ class ParseError extends NodeBase {
13353
14060
 
13354
14061
  class PrivateIdentifier extends NodeBase {
13355
14062
  }
14063
+ PrivateIdentifier.prototype.includeNode = onlyIncludeSelf;
13356
14064
 
13357
14065
  class Program extends NodeBase {
13358
14066
  constructor() {
@@ -13420,14 +14128,11 @@ class Program extends NodeBase {
13420
14128
  super.render(code, options);
13421
14129
  }
13422
14130
  }
13423
- applyDeoptimizations() { }
13424
14131
  }
14132
+ Program.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14133
+ Program.prototype.applyDeoptimizations = doNotDeoptimize;
13425
14134
 
13426
14135
  class Property extends MethodBase {
13427
- constructor() {
13428
- super(...arguments);
13429
- this.declarationInit = null;
13430
- }
13431
14136
  //declare method: boolean;
13432
14137
  get method() {
13433
14138
  return isFlagSet(this.flags, 262144 /* Flag.method */);
@@ -13442,17 +14147,41 @@ class Property extends MethodBase {
13442
14147
  set shorthand(value) {
13443
14148
  this.flags = setFlag(this.flags, 524288 /* Flag.shorthand */, value);
13444
14149
  }
13445
- declare(kind, init) {
13446
- this.declarationInit = init;
13447
- return this.value.declare(kind, UNKNOWN_EXPRESSION);
14150
+ declare(kind, destructuredInitPath, init) {
14151
+ return this.value.declare(kind, this.getPathInProperty(destructuredInitPath), init);
14152
+ }
14153
+ deoptimizeAssignment(destructuredInitPath, init) {
14154
+ this.value.deoptimizeAssignment?.(this.getPathInProperty(destructuredInitPath), init);
13448
14155
  }
13449
14156
  hasEffects(context) {
13450
- if (!this.deoptimized)
13451
- this.applyDeoptimizations();
13452
- const propertyReadSideEffects = this.scope.context.options.treeshake.propertyReadSideEffects;
13453
- return ((this.parent.type === 'ObjectPattern' && propertyReadSideEffects === 'always') ||
13454
- this.key.hasEffects(context) ||
13455
- this.value.hasEffects(context));
14157
+ return this.key.hasEffects(context) || this.value.hasEffects(context);
14158
+ }
14159
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
14160
+ return this.value.hasEffectsWhenDestructuring?.(context, this.getPathInProperty(destructuredInitPath), init);
14161
+ }
14162
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
14163
+ const path = this.getPathInProperty(destructuredInitPath);
14164
+ let included = this.value.includeDestructuredIfNecessary(context, path, init) ||
14165
+ this.included;
14166
+ if ((included ||= this.key.hasEffects(createHasEffectsContext()))) {
14167
+ this.key.include(context, false);
14168
+ if (!this.value.included) {
14169
+ this.value.included = true;
14170
+ // Unfortunately, we need to include the value again now, so that any
14171
+ // declared variables are properly included.
14172
+ this.value.includeDestructuredIfNecessary(context, path, init);
14173
+ }
14174
+ }
14175
+ return (this.included = included);
14176
+ }
14177
+ include(context, includeChildrenRecursively) {
14178
+ this.included = true;
14179
+ this.key.include(context, includeChildrenRecursively);
14180
+ this.value.include(context, includeChildrenRecursively);
14181
+ }
14182
+ includePath(path, context) {
14183
+ this.included = true;
14184
+ this.value.includePath(path, context);
13456
14185
  }
13457
14186
  markDeclarationReached() {
13458
14187
  this.value.markDeclarationReached();
@@ -13463,14 +14192,20 @@ class Property extends MethodBase {
13463
14192
  }
13464
14193
  this.value.render(code, options, { isShorthandProperty: this.shorthand });
13465
14194
  }
13466
- applyDeoptimizations() {
13467
- this.deoptimized = true;
13468
- if (this.declarationInit !== null) {
13469
- this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
13470
- this.scope.context.requestTreeshakingPass();
13471
- }
14195
+ getPathInProperty(destructuredInitPath) {
14196
+ return destructuredInitPath.at(-1) === UnknownKey
14197
+ ? destructuredInitPath
14198
+ : // For now, we only consider static paths as we do not know how to
14199
+ // deoptimize the path in the dynamic case.
14200
+ this.computed
14201
+ ? [...destructuredInitPath, UnknownKey]
14202
+ : this.key instanceof Identifier
14203
+ ? [...destructuredInitPath, this.key.name]
14204
+ : [...destructuredInitPath, String(this.key.value)];
13472
14205
  }
13473
14206
  }
14207
+ Property.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14208
+ Property.prototype.applyDeoptimizations = doNotDeoptimize;
13474
14209
 
13475
14210
  class PropertyDefinition extends NodeBase {
13476
14211
  get computed() {
@@ -13503,8 +14238,15 @@ class PropertyDefinition extends NodeBase {
13503
14238
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13504
14239
  return !this.value || this.value.hasEffectsOnInteractionAtPath(path, interaction, context);
13505
14240
  }
13506
- applyDeoptimizations() { }
14241
+ includeNode(context) {
14242
+ this.included = true;
14243
+ this.value?.includePath(UNKNOWN_PATH, context);
14244
+ for (const decorator of this.decorators) {
14245
+ decorator.includePath(UNKNOWN_PATH, context);
14246
+ }
14247
+ }
13507
14248
  }
14249
+ PropertyDefinition.prototype.applyDeoptimizations = doNotDeoptimize;
13508
14250
 
13509
14251
  class ReturnStatement extends NodeBase {
13510
14252
  hasEffects(context) {
@@ -13514,10 +14256,15 @@ class ReturnStatement extends NodeBase {
13514
14256
  return false;
13515
14257
  }
13516
14258
  include(context, includeChildrenRecursively) {
13517
- this.included = true;
14259
+ if (!this.included)
14260
+ this.includeNode(context);
13518
14261
  this.argument?.include(context, includeChildrenRecursively);
13519
14262
  context.brokenFlow = true;
13520
14263
  }
14264
+ includeNode(context) {
14265
+ this.included = true;
14266
+ this.argument?.includePath(UNKNOWN_PATH, context);
14267
+ }
13521
14268
  initialise() {
13522
14269
  super.initialise();
13523
14270
  this.scope.addReturnExpression(this.argument || UNKNOWN_EXPRESSION);
@@ -13531,6 +14278,7 @@ class ReturnStatement extends NodeBase {
13531
14278
  }
13532
14279
  }
13533
14280
  }
14281
+ ReturnStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13534
14282
 
13535
14283
  class SequenceExpression extends NodeBase {
13536
14284
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
@@ -13558,10 +14306,15 @@ class SequenceExpression extends NodeBase {
13558
14306
  for (const expression of this.expressions) {
13559
14307
  if (includeChildrenRecursively ||
13560
14308
  (expression === lastExpression && !(this.parent instanceof ExpressionStatement)) ||
13561
- expression.shouldBeIncluded(context))
14309
+ expression.shouldBeIncluded(context)) {
13562
14310
  expression.include(context, includeChildrenRecursively);
14311
+ }
13563
14312
  }
13564
14313
  }
14314
+ includePath(path, context) {
14315
+ this.included = true;
14316
+ this.expressions[this.expressions.length - 1].includePath(path, context);
14317
+ }
13565
14318
  removeAnnotations(code) {
13566
14319
  this.expressions[0].removeAnnotations(code);
13567
14320
  }
@@ -13596,6 +14349,8 @@ class SequenceExpression extends NodeBase {
13596
14349
  }
13597
14350
  }
13598
14351
  }
14352
+ SequenceExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14353
+ SequenceExpression.prototype.applyDeoptimizations = doNotDeoptimize;
13599
14354
 
13600
14355
  class Super extends NodeBase {
13601
14356
  bind() {
@@ -13607,11 +14362,15 @@ class Super extends NodeBase {
13607
14362
  deoptimizePath(path) {
13608
14363
  this.variable.deoptimizePath(path);
13609
14364
  }
13610
- include() {
13611
- if (!this.included) {
13612
- this.included = true;
13613
- this.scope.context.includeVariableInModule(this.variable);
13614
- }
14365
+ include(context) {
14366
+ if (!this.included)
14367
+ this.includeNode(context);
14368
+ }
14369
+ includeNode(context) {
14370
+ this.included = true;
14371
+ if (!this.deoptimized)
14372
+ this.applyDeoptimizations();
14373
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
13615
14374
  }
13616
14375
  }
13617
14376
 
@@ -13652,6 +14411,8 @@ class SwitchCase extends NodeBase {
13652
14411
  }
13653
14412
  }
13654
14413
  SwitchCase.prototype.needsBoundaries = true;
14414
+ SwitchCase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14415
+ SwitchCase.prototype.applyDeoptimizations = doNotDeoptimize;
13655
14416
 
13656
14417
  class SwitchStatement extends NodeBase {
13657
14418
  createScope(parentScope) {
@@ -13734,6 +14495,8 @@ class SwitchStatement extends NodeBase {
13734
14495
  }
13735
14496
  }
13736
14497
  }
14498
+ SwitchStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14499
+ SwitchStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13737
14500
 
13738
14501
  class TaggedTemplateExpression extends CallExpressionBase {
13739
14502
  bind() {
@@ -13757,8 +14520,8 @@ class TaggedTemplateExpression extends CallExpressionBase {
13757
14520
  this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
13758
14521
  }
13759
14522
  include(context, includeChildrenRecursively) {
13760
- if (!this.deoptimized)
13761
- this.applyDeoptimizations();
14523
+ if (!this.included)
14524
+ this.includeNode(context);
13762
14525
  if (includeChildrenRecursively) {
13763
14526
  super.include(context, includeChildrenRecursively);
13764
14527
  }
@@ -13767,7 +14530,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
13767
14530
  this.tag.include(context, includeChildrenRecursively);
13768
14531
  this.quasi.include(context, includeChildrenRecursively);
13769
14532
  }
13770
- this.tag.includeCallArguments(context, this.args);
14533
+ this.tag.includeCallArguments(context, this.interaction);
13771
14534
  const [returnExpression] = this.getReturnExpression();
13772
14535
  if (!returnExpression.included) {
13773
14536
  returnExpression.include(context, false);
@@ -13802,6 +14565,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
13802
14565
  return this.returnExpression;
13803
14566
  }
13804
14567
  }
14568
+ TaggedTemplateExpression.prototype.includeNode = onlyIncludeSelf;
13805
14569
 
13806
14570
  class TemplateElement extends NodeBase {
13807
14571
  get tail() {
@@ -13815,15 +14579,13 @@ class TemplateElement extends NodeBase {
13815
14579
  hasEffects() {
13816
14580
  return false;
13817
14581
  }
13818
- include() {
13819
- this.included = true;
13820
- }
13821
14582
  parseNode(esTreeNode) {
13822
14583
  this.value = esTreeNode.value;
13823
14584
  return super.parseNode(esTreeNode);
13824
14585
  }
13825
14586
  render() { }
13826
14587
  }
14588
+ TemplateElement.prototype.includeNode = onlyIncludeSelf;
13827
14589
 
13828
14590
  class TemplateLiteral extends NodeBase {
13829
14591
  deoptimizeArgumentsOnInteractionAtPath() { }
@@ -13848,6 +14610,14 @@ class TemplateLiteral extends NodeBase {
13848
14610
  }
13849
14611
  return true;
13850
14612
  }
14613
+ includeNode(context) {
14614
+ this.included = true;
14615
+ if (!this.deoptimized)
14616
+ this.applyDeoptimizations();
14617
+ for (const node of this.expressions) {
14618
+ node.includePath(UNKNOWN_PATH, context);
14619
+ }
14620
+ }
13851
14621
  render(code, options) {
13852
14622
  code.indentExclusionRanges.push([this.start, this.end]);
13853
14623
  super.render(code, options);
@@ -13857,13 +14627,13 @@ class TemplateLiteral extends NodeBase {
13857
14627
  class ModuleScope extends ChildScope {
13858
14628
  constructor(parent, context) {
13859
14629
  super(parent, context);
13860
- this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, context, 'other'));
14630
+ this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, EMPTY_PATH, context, 'other'));
13861
14631
  }
13862
- addDeclaration(identifier, context, init, kind) {
14632
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
13863
14633
  if (this.context.module.importDescriptions.has(identifier.name)) {
13864
14634
  context.error(logRedeclarationError(identifier.name), identifier.start);
13865
14635
  }
13866
- return super.addDeclaration(identifier, context, init, kind);
14636
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
13867
14637
  }
13868
14638
  addExportDefaultDeclaration(name, exportDefaultDeclaration, context) {
13869
14639
  const variable = new ExportDefaultVariable(name, exportDefaultDeclaration, context);
@@ -13908,10 +14678,23 @@ class ThisExpression extends NodeBase {
13908
14678
  }
13909
14679
  return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
13910
14680
  }
13911
- include() {
14681
+ include(context) {
14682
+ if (!this.included)
14683
+ this.includeNode(context);
14684
+ }
14685
+ includeNode(context) {
14686
+ this.included = true;
14687
+ if (!this.deoptimized)
14688
+ this.applyDeoptimizations();
14689
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
14690
+ }
14691
+ includePath(path, context) {
13912
14692
  if (!this.included) {
13913
14693
  this.included = true;
13914
- this.scope.context.includeVariableInModule(this.variable);
14694
+ this.scope.context.includeVariableInModule(this.variable, path, context);
14695
+ }
14696
+ else if (path.length > 0) {
14697
+ this.variable.includePath(path, context);
13915
14698
  }
13916
14699
  }
13917
14700
  initialise() {
@@ -13939,7 +14722,8 @@ class ThrowStatement extends NodeBase {
13939
14722
  return true;
13940
14723
  }
13941
14724
  include(context, includeChildrenRecursively) {
13942
- this.included = true;
14725
+ if (!this.included)
14726
+ this.includeNode(context);
13943
14727
  this.argument.include(context, includeChildrenRecursively);
13944
14728
  context.brokenFlow = true;
13945
14729
  }
@@ -13950,6 +14734,7 @@ class ThrowStatement extends NodeBase {
13950
14734
  }
13951
14735
  }
13952
14736
  }
14737
+ ThrowStatement.prototype.includeNode = onlyIncludeSelf;
13953
14738
 
13954
14739
  class TryStatement extends NodeBase {
13955
14740
  constructor() {
@@ -13986,6 +14771,8 @@ class TryStatement extends NodeBase {
13986
14771
  this.finalizer?.include(context, includeChildrenRecursively);
13987
14772
  }
13988
14773
  }
14774
+ TryStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14775
+ TryStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13989
14776
 
13990
14777
  const unaryOperators = {
13991
14778
  '!': value => !value,
@@ -14031,6 +14818,7 @@ class UnaryExpression extends NodeBase {
14031
14818
  }
14032
14819
  }
14033
14820
  }
14821
+ UnaryExpression.prototype.includeNode = onlyIncludeSelf;
14034
14822
 
14035
14823
  class UpdateExpression extends NodeBase {
14036
14824
  hasEffects(context) {
@@ -14042,9 +14830,8 @@ class UpdateExpression extends NodeBase {
14042
14830
  return path.length > 1 || type !== INTERACTION_ACCESSED;
14043
14831
  }
14044
14832
  include(context, includeChildrenRecursively) {
14045
- if (!this.deoptimized)
14046
- this.applyDeoptimizations();
14047
- this.included = true;
14833
+ if (!this.included)
14834
+ this.includeNode(context);
14048
14835
  this.argument.includeAsAssignmentTarget(context, includeChildrenRecursively, true);
14049
14836
  }
14050
14837
  initialise() {
@@ -14083,6 +14870,7 @@ class UpdateExpression extends NodeBase {
14083
14870
  this.scope.context.requestTreeshakingPass();
14084
14871
  }
14085
14872
  }
14873
+ UpdateExpression.prototype.includeNode = onlyIncludeSelf;
14086
14874
 
14087
14875
  function areAllDeclarationsIncludedAndNotExported(declarations, exportNamesByVariable) {
14088
14876
  for (const declarator of declarations) {
@@ -14113,8 +14901,9 @@ class VariableDeclaration extends NodeBase {
14113
14901
  include(context, includeChildrenRecursively, { asSingleStatement } = BLANK) {
14114
14902
  this.included = true;
14115
14903
  for (const declarator of this.declarations) {
14116
- if (includeChildrenRecursively || declarator.shouldBeIncluded(context))
14904
+ if (includeChildrenRecursively || declarator.shouldBeIncluded(context)) {
14117
14905
  declarator.include(context, includeChildrenRecursively);
14906
+ }
14118
14907
  const { id, init } = declarator;
14119
14908
  if (asSingleStatement) {
14120
14909
  id.include(context, includeChildrenRecursively);
@@ -14152,7 +14941,6 @@ class VariableDeclaration extends NodeBase {
14152
14941
  this.renderReplacedDeclarations(code, options);
14153
14942
  }
14154
14943
  }
14155
- applyDeoptimizations() { }
14156
14944
  renderDeclarationEnd(code, separatorString, lastSeparatorPos, actualContentEnd, renderedContentEnd, systemPatternExports, options) {
14157
14945
  if (code.original.charCodeAt(this.end - 1) === 59 /*";"*/) {
14158
14946
  code.remove(this.end - 1, this.end);
@@ -14195,8 +14983,7 @@ class VariableDeclaration extends NodeBase {
14195
14983
  const singleSystemExport = gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregatedSystemExports);
14196
14984
  for (const { node, start, separator, contentEnd, end } of separatedNodes) {
14197
14985
  if (!node.included) {
14198
- code.remove(start, end);
14199
- node.removeAnnotations(code);
14986
+ treeshakeNode(node, code, start, end);
14200
14987
  continue;
14201
14988
  }
14202
14989
  node.render(code, options);
@@ -14266,6 +15053,8 @@ function gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregat
14266
15053
  }
14267
15054
  return singleSystemExport;
14268
15055
  }
15056
+ VariableDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
15057
+ VariableDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
14269
15058
 
14270
15059
  class WhileStatement extends NodeBase {
14271
15060
  hasEffects(context) {
@@ -14279,13 +15068,25 @@ class WhileStatement extends NodeBase {
14279
15068
  includeLoopBody(context, this.body, includeChildrenRecursively);
14280
15069
  }
14281
15070
  }
15071
+ WhileStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
15072
+ WhileStatement.prototype.applyDeoptimizations = doNotDeoptimize;
14282
15073
 
14283
15074
  class YieldExpression extends NodeBase {
15075
+ applyDeoptimizations() {
15076
+ this.deoptimized = true;
15077
+ this.argument?.deoptimizePath(UNKNOWN_PATH);
15078
+ }
14284
15079
  hasEffects(context) {
14285
15080
  if (!this.deoptimized)
14286
15081
  this.applyDeoptimizations();
14287
15082
  return !(context.ignore.returnYield && !this.argument?.hasEffects(context));
14288
15083
  }
15084
+ includeNode(context) {
15085
+ this.included = true;
15086
+ if (!this.deoptimized)
15087
+ this.applyDeoptimizations();
15088
+ this.argument?.includePath(UNKNOWN_PATH, context);
15089
+ }
14289
15090
  render(code, options) {
14290
15091
  if (this.argument) {
14291
15092
  this.argument.render(code, options, { preventASI: true });
@@ -14519,7 +15320,7 @@ const bufferParsers = [
14519
15320
  const annotations = (node.annotations = convertAnnotations(buffer[position + 1], buffer));
14520
15321
  node.annotationNoSideEffects = annotations.some(comment => comment.type === 'noSideEffects');
14521
15322
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 2], buffer));
14522
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
15323
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14523
15324
  node.body = convertNode(node, scope.bodyScope, buffer[position + 3], buffer);
14524
15325
  },
14525
15326
  function assignmentExpression(node, position, buffer) {
@@ -14565,7 +15366,7 @@ const bufferParsers = [
14565
15366
  const parameterPosition = buffer[position];
14566
15367
  const parameter = (node.param =
14567
15368
  parameterPosition === 0 ? null : convertNode(node, scope, parameterPosition, buffer));
14568
- parameter?.declare('parameter', UNKNOWN_EXPRESSION);
15369
+ parameter?.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
14569
15370
  node.body = convertNode(node, scope.bodyScope, buffer[position + 1], buffer);
14570
15371
  },
14571
15372
  function chainExpression(node, position, buffer) {
@@ -14703,7 +15504,7 @@ const bufferParsers = [
14703
15504
  node.id =
14704
15505
  idPosition === 0 ? null : convertNode(node, scope.parent, idPosition, buffer);
14705
15506
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
14706
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
15507
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14707
15508
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
14708
15509
  },
14709
15510
  function functionExpression(node, position, buffer) {
@@ -14716,7 +15517,7 @@ const bufferParsers = [
14716
15517
  const idPosition = buffer[position + 2];
14717
15518
  node.id = idPosition === 0 ? null : convertNode(node, node.idScope, idPosition, buffer);
14718
15519
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
14719
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
15520
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14720
15521
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
14721
15522
  },
14722
15523
  function identifier(node, position, buffer) {
@@ -15180,8 +15981,8 @@ class ExportShimVariable extends Variable {
15180
15981
  super(MISSING_EXPORT_SHIM_VARIABLE);
15181
15982
  this.module = module;
15182
15983
  }
15183
- include() {
15184
- super.include();
15984
+ includePath(path, context) {
15985
+ super.includePath(path, context);
15185
15986
  this.module.needsExportShim = true;
15186
15987
  }
15187
15988
  }
@@ -15879,16 +16680,15 @@ class Module {
15879
16680
  markModuleAndImpureDependenciesAsExecuted(this);
15880
16681
  this.graph.needsTreeshakingPass = true;
15881
16682
  }
16683
+ const inclusionContext = createInclusionContext();
15882
16684
  for (const exportName of this.exports.keys()) {
15883
16685
  if (includeNamespaceMembers || exportName !== this.info.syntheticNamedExports) {
15884
16686
  const variable = this.getVariableForExportName(exportName)[0];
15885
16687
  if (!variable) {
15886
16688
  return error(logMissingEntryExport(exportName, this.id));
15887
16689
  }
16690
+ this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
15888
16691
  variable.deoptimizePath(UNKNOWN_PATH);
15889
- if (!variable.included) {
15890
- this.includeVariable(variable);
15891
- }
15892
16692
  }
15893
16693
  }
15894
16694
  for (const name of this.getReexports()) {
@@ -15896,7 +16696,7 @@ class Module {
15896
16696
  if (variable) {
15897
16697
  variable.deoptimizePath(UNKNOWN_PATH);
15898
16698
  if (!variable.included) {
15899
- this.includeVariable(variable);
16699
+ this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
15900
16700
  }
15901
16701
  if (variable instanceof ExternalVariable) {
15902
16702
  variable.module.reexported = true;
@@ -15917,13 +16717,12 @@ class Module {
15917
16717
  this.graph.needsTreeshakingPass = true;
15918
16718
  }
15919
16719
  let includeNamespaceMembers = false;
16720
+ const inclusionContext = createInclusionContext();
15920
16721
  for (const name of names) {
15921
16722
  const variable = this.getVariableForExportName(name)[0];
15922
16723
  if (variable) {
15923
16724
  variable.deoptimizePath(UNKNOWN_PATH);
15924
- if (!variable.included) {
15925
- this.includeVariable(variable);
15926
- }
16725
+ this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
15927
16726
  }
15928
16727
  if (!this.exports.has(name) && !this.reexportDescriptions.has(name)) {
15929
16728
  includeNamespaceMembers = true;
@@ -16024,6 +16823,7 @@ class Module {
16024
16823
  manualPureFunctions: this.graph.pureFunctions,
16025
16824
  module: this,
16026
16825
  moduleContext: this.context,
16826
+ newlyIncludedVariableInits: this.graph.newlyIncludedVariableInits,
16027
16827
  options: this.options,
16028
16828
  requestTreeshakingPass: () => (this.graph.needsTreeshakingPass = true),
16029
16829
  traceExport: (name) => this.getVariableForExportName(name)[0],
@@ -16364,13 +17164,13 @@ class Module {
16364
17164
  for (const module of [this, ...this.exportAllModules]) {
16365
17165
  if (module instanceof ExternalModule) {
16366
17166
  const [externalVariable] = module.getVariableForExportName('*');
16367
- externalVariable.include();
17167
+ externalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
16368
17168
  this.includedImports.add(externalVariable);
16369
17169
  externalNamespaces.add(externalVariable);
16370
17170
  }
16371
17171
  else if (module.info.syntheticNamedExports) {
16372
17172
  const syntheticNamespace = module.getSyntheticNamespace();
16373
- syntheticNamespace.include();
17173
+ syntheticNamespace.includePath(UNKNOWN_PATH, createInclusionContext());
16374
17174
  this.includedImports.add(syntheticNamespace);
16375
17175
  syntheticNamespaces.add(syntheticNamespace);
16376
17176
  }
@@ -16380,7 +17180,9 @@ class Module {
16380
17180
  includeDynamicImport(node) {
16381
17181
  const resolution = this.dynamicImports.find(dynamicImport => dynamicImport.node === node).resolution;
16382
17182
  if (resolution instanceof Module) {
16383
- resolution.includedDynamicImporters.push(this);
17183
+ if (!resolution.includedDynamicImporters.includes(this)) {
17184
+ resolution.includedDynamicImporters.push(this);
17185
+ }
16384
17186
  const importedNames = this.options.treeshake
16385
17187
  ? node.getDeterministicImportedNames()
16386
17188
  : undefined;
@@ -16392,15 +17194,15 @@ class Module {
16392
17194
  }
16393
17195
  }
16394
17196
  }
16395
- includeVariable(variable) {
16396
- const variableModule = variable.module;
16397
- if (variable.included) {
17197
+ includeVariable(variable, path, context) {
17198
+ const { included, module: variableModule } = variable;
17199
+ variable.includePath(path, context);
17200
+ if (included) {
16398
17201
  if (variableModule instanceof Module && variableModule !== this) {
16399
17202
  getAndExtendSideEffectModules(variable, this);
16400
17203
  }
16401
17204
  }
16402
17205
  else {
16403
- variable.include();
16404
17206
  this.graph.needsTreeshakingPass = true;
16405
17207
  if (variableModule instanceof Module) {
16406
17208
  if (!variableModule.isExecuted) {
@@ -16417,8 +17219,8 @@ class Module {
16417
17219
  }
16418
17220
  }
16419
17221
  }
16420
- includeVariableInModule(variable) {
16421
- this.includeVariable(variable);
17222
+ includeVariableInModule(variable, path, context) {
17223
+ this.includeVariable(variable, path, context);
16422
17224
  const variableModule = variable.module;
16423
17225
  if (variableModule && variableModule !== this) {
16424
17226
  this.includedImports.add(variable);
@@ -21015,10 +21817,11 @@ class Graph {
21015
21817
  this.options = options;
21016
21818
  this.astLru = flru(5);
21017
21819
  this.cachedModules = new Map();
21018
- this.deoptimizationTracker = new PathTracker();
21820
+ this.deoptimizationTracker = new EntityPathTracker();
21019
21821
  this.entryModules = [];
21020
21822
  this.modulesById = new Map();
21021
21823
  this.needsTreeshakingPass = false;
21824
+ this.newlyIncludedVariableInits = new Set();
21022
21825
  this.phase = BuildPhase.LOAD_AND_PARSE;
21023
21826
  this.scope = new GlobalScope();
21024
21827
  this.watchFiles = Object.create(null);
@@ -21112,6 +21915,7 @@ class Graph {
21112
21915
  }
21113
21916
  if (this.options.treeshake) {
21114
21917
  let treeshakingPass = 1;
21918
+ this.newlyIncludedVariableInits.clear();
21115
21919
  do {
21116
21920
  timeStart(`treeshaking pass ${treeshakingPass}`, 3);
21117
21921
  this.needsTreeshakingPass = false;
@@ -21136,6 +21940,10 @@ class Graph {
21136
21940
  }
21137
21941
  }
21138
21942
  }
21943
+ for (const entity of this.newlyIncludedVariableInits) {
21944
+ this.newlyIncludedVariableInits.delete(entity);
21945
+ entity.include(createInclusionContext(), false);
21946
+ }
21139
21947
  timeEnd(`treeshaking pass ${treeshakingPass++}`, 3);
21140
21948
  } while (this.needsTreeshakingPass);
21141
21949
  }
@@ -22015,7 +22823,7 @@ createColors();
22015
22823
 
22016
22824
  // @see https://no-color.org
22017
22825
  // @see https://www.npmjs.com/package/chalk
22018
- const { bold, cyan, dim, gray, green, red, underline, yellow } = createColors({
22826
+ const { bold, cyan, dim, red} = createColors({
22019
22827
  useColor: env$1.FORCE_COLOR !== '0' && !env$1.NO_COLOR
22020
22828
  });
22021
22829