@rollup/wasm-node 4.28.1 → 4.29.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.28.1
4
- Fri, 06 Dec 2024 11:44:27 GMT - commit e60fb1c5d4e54ed5257495215eeda1bb43cf54ba
3
+ Rollup.js v4.29.0-1
4
+ Thu, 19 Dec 2024 06:37:00 GMT - commit fa5064084196636acd98263f95ffea59f8362e32
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.28.1";
19
+ var version = "4.29.0-1";
20
20
 
21
21
  const comma = ','.charCodeAt(0);
22
22
  const semicolon = ';'.charCodeAt(0);
@@ -1948,71 +1948,6 @@ function renderSystemExportSequenceBeforeExpression(exportedVariable, expression
1948
1948
  }
1949
1949
  }
1950
1950
 
1951
- /** @import { Node } from 'estree' */
1952
-
1953
- /**
1954
- * @param {Node} node
1955
- * @param {Node} parent
1956
- * @returns {boolean}
1957
- */
1958
- function is_reference(node, parent) {
1959
- if (node.type === 'MemberExpression') {
1960
- return !node.computed && is_reference(node.object, node);
1961
- }
1962
-
1963
- if (node.type !== 'Identifier') return false;
1964
-
1965
- switch (parent?.type) {
1966
- // disregard `bar` in `foo.bar`
1967
- case 'MemberExpression':
1968
- return parent.computed || node === parent.object;
1969
-
1970
- // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
1971
- case 'MethodDefinition':
1972
- return parent.computed;
1973
-
1974
- // disregard the `meta` in `import.meta`
1975
- case 'MetaProperty':
1976
- return parent.meta === node;
1977
-
1978
- // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
1979
- case 'PropertyDefinition':
1980
- return parent.computed || node === parent.value;
1981
-
1982
- // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
1983
- case 'Property':
1984
- return parent.computed || node === parent.value;
1985
-
1986
- // disregard the `bar` in `export { foo as bar }` or
1987
- // the foo in `import { foo as bar }`
1988
- case 'ExportSpecifier':
1989
- case 'ImportSpecifier':
1990
- return node === parent.local;
1991
-
1992
- // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
1993
- case 'LabeledStatement':
1994
- case 'BreakStatement':
1995
- case 'ContinueStatement':
1996
- return false;
1997
-
1998
- default:
1999
- return true;
2000
- }
2001
- }
2002
-
2003
- const PureFunctionKey = Symbol('PureFunction');
2004
- const getPureFunctions = ({ treeshake }) => {
2005
- const pureFunctions = Object.create(null);
2006
- for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
2007
- let currentFunctions = pureFunctions;
2008
- for (const pathSegment of functionName.split('.')) {
2009
- currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
2010
- }
2011
- currentFunctions[PureFunctionKey] = true;
2012
- }
2013
- return pureFunctions;
2014
- };
2015
-
2016
1951
  function getOrCreate(map, key, init) {
2017
1952
  const existing = map.get(key);
2018
1953
  if (existing !== undefined) {
@@ -2043,7 +1978,7 @@ const UNKNOWN_PATH = [UnknownKey];
2043
1978
  const UNKNOWN_NON_ACCESSOR_PATH = [UnknownNonAccessorKey];
2044
1979
  const UNKNOWN_INTEGER_PATH = [UnknownInteger];
2045
1980
  const EntitiesKey = Symbol('Entities');
2046
- class PathTracker {
1981
+ class EntityPathTracker {
2047
1982
  constructor() {
2048
1983
  this.entityPaths = Object.create(null, {
2049
1984
  [EntitiesKey]: { value: new Set() }
@@ -2068,14 +2003,14 @@ class PathTracker {
2068
2003
  getEntities(path) {
2069
2004
  let currentPaths = this.entityPaths;
2070
2005
  for (const pathSegment of path) {
2071
- currentPaths = currentPaths[pathSegment] =
2072
- currentPaths[pathSegment] ||
2073
- Object.create(null, { [EntitiesKey]: { value: new Set() } });
2006
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
2007
+ [EntitiesKey]: { value: new Set() }
2008
+ });
2074
2009
  }
2075
2010
  return currentPaths[EntitiesKey];
2076
2011
  }
2077
2012
  }
2078
- const SHARED_RECURSION_TRACKER = new PathTracker();
2013
+ const SHARED_RECURSION_TRACKER = new EntityPathTracker();
2079
2014
  class DiscriminatedPathTracker {
2080
2015
  constructor() {
2081
2016
  this.entityPaths = Object.create(null, {
@@ -2085,9 +2020,9 @@ class DiscriminatedPathTracker {
2085
2020
  trackEntityAtPathAndGetIfTracked(path, discriminator, entity) {
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 Map() } });
2023
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
2024
+ [EntitiesKey]: { value: new Map() }
2025
+ });
2091
2026
  }
2092
2027
  const trackedEntities = getOrCreate(currentPaths[EntitiesKey], discriminator, (getNewSet));
2093
2028
  if (trackedEntities.has(entity))
@@ -2096,6 +2031,137 @@ class DiscriminatedPathTracker {
2096
2031
  return false;
2097
2032
  }
2098
2033
  }
2034
+ const UNKNOWN_INCLUDED_PATH = Object.freeze({ [UnknownKey]: EMPTY_OBJECT });
2035
+ class IncludedPathTracker {
2036
+ constructor() {
2037
+ this.includedPaths = null;
2038
+ }
2039
+ includePathAndGetIfIncluded(path) {
2040
+ let included = true;
2041
+ let parent = this;
2042
+ let parentSegment = 'includedPaths';
2043
+ let currentPaths = (this.includedPaths ||=
2044
+ ((included = false), Object.create(null)));
2045
+ for (const pathSegment of path) {
2046
+ // This means from here, all paths are included
2047
+ if (currentPaths[UnknownKey]) {
2048
+ return true;
2049
+ }
2050
+ // Including UnknownKey automatically includes all nested paths.
2051
+ // From above, we know that UnknownKey is not included yet.
2052
+ if (typeof pathSegment === 'symbol') {
2053
+ // Hopefully, this saves some memory over just setting
2054
+ // currentPaths[UnknownKey] = EMPTY_OBJECT
2055
+ parent[parentSegment] = UNKNOWN_INCLUDED_PATH;
2056
+ return false;
2057
+ }
2058
+ parent = currentPaths;
2059
+ parentSegment = pathSegment;
2060
+ currentPaths = currentPaths[pathSegment] ||= ((included = false), Object.create(null));
2061
+ }
2062
+ return included;
2063
+ }
2064
+ includeAllPaths(entity, context, basePath) {
2065
+ const { includedPaths } = this;
2066
+ if (includedPaths) {
2067
+ includeAllPaths(entity, context, basePath, includedPaths);
2068
+ }
2069
+ }
2070
+ }
2071
+ function includeAllPaths(entity, context, basePath, currentPaths) {
2072
+ if (currentPaths[UnknownKey]) {
2073
+ return entity.includePath([...basePath, UnknownKey], context);
2074
+ }
2075
+ const keys = Object.keys(currentPaths);
2076
+ if (keys.length === 0) {
2077
+ return entity.includePath(basePath, context);
2078
+ }
2079
+ for (const key of keys) {
2080
+ includeAllPaths(entity, context, [...basePath, key], currentPaths[key]);
2081
+ }
2082
+ }
2083
+
2084
+ /** @import { Node } from 'estree' */
2085
+
2086
+ /**
2087
+ * @param {Node} node
2088
+ * @param {Node} parent
2089
+ * @returns {boolean}
2090
+ */
2091
+ function is_reference(node, parent) {
2092
+ if (node.type === 'MemberExpression') {
2093
+ return !node.computed && is_reference(node.object, node);
2094
+ }
2095
+
2096
+ if (node.type !== 'Identifier') return false;
2097
+
2098
+ switch (parent?.type) {
2099
+ // disregard `bar` in `foo.bar`
2100
+ case 'MemberExpression':
2101
+ return parent.computed || node === parent.object;
2102
+
2103
+ // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
2104
+ case 'MethodDefinition':
2105
+ return parent.computed;
2106
+
2107
+ // disregard the `meta` in `import.meta`
2108
+ case 'MetaProperty':
2109
+ return parent.meta === node;
2110
+
2111
+ // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
2112
+ case 'PropertyDefinition':
2113
+ return parent.computed || node === parent.value;
2114
+
2115
+ // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
2116
+ case 'Property':
2117
+ return parent.computed || node === parent.value;
2118
+
2119
+ // disregard the `bar` in `export { foo as bar }` or
2120
+ // the foo in `import { foo as bar }`
2121
+ case 'ExportSpecifier':
2122
+ case 'ImportSpecifier':
2123
+ return node === parent.local;
2124
+
2125
+ // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
2126
+ case 'LabeledStatement':
2127
+ case 'BreakStatement':
2128
+ case 'ContinueStatement':
2129
+ return false;
2130
+
2131
+ default:
2132
+ return true;
2133
+ }
2134
+ }
2135
+
2136
+ function createInclusionContext() {
2137
+ return {
2138
+ brokenFlow: false,
2139
+ hasBreak: false,
2140
+ hasContinue: false,
2141
+ includedCallArguments: new Set(),
2142
+ includedLabels: new Set()
2143
+ };
2144
+ }
2145
+ function createHasEffectsContext() {
2146
+ return {
2147
+ accessed: new EntityPathTracker(),
2148
+ assigned: new EntityPathTracker(),
2149
+ brokenFlow: false,
2150
+ called: new DiscriminatedPathTracker(),
2151
+ hasBreak: false,
2152
+ hasContinue: false,
2153
+ ignore: {
2154
+ breaks: false,
2155
+ continues: false,
2156
+ labels: new Set(),
2157
+ returnYield: false,
2158
+ this: false
2159
+ },
2160
+ includedLabels: new Set(),
2161
+ instantiated: new DiscriminatedPathTracker(),
2162
+ replacedVariableInits: new Map()
2163
+ };
2164
+ }
2099
2165
 
2100
2166
  function isFlagSet(flags, flag) {
2101
2167
  return (flags & flag) !== 0;
@@ -2134,12 +2200,25 @@ class ExpressionEntity {
2134
2200
  hasEffectsOnInteractionAtPath(_path, _interaction, _context) {
2135
2201
  return true;
2136
2202
  }
2137
- include(_context, _includeChildrenRecursively, _options) {
2203
+ include(context, _includeChildrenRecursively, _options) {
2204
+ if (!this.included)
2205
+ this.includeNode(context);
2206
+ }
2207
+ includeNode(_context) {
2138
2208
  this.included = true;
2139
2209
  }
2140
- includeCallArguments(context, parameters) {
2141
- for (const argument of parameters) {
2142
- argument.include(context, false);
2210
+ includePath(_path, context) {
2211
+ if (!this.included)
2212
+ this.includeNode(context);
2213
+ }
2214
+ /* We are both including and including an unknown path here as the former
2215
+ * ensures that nested nodes are included while the latter ensures that all
2216
+ * paths of the expression are included.
2217
+ * */
2218
+ includeCallArguments(context, interaction) {
2219
+ for (const argument of interaction.args) {
2220
+ argument?.includePath(UNKNOWN_PATH, context);
2221
+ argument?.include(context, false);
2143
2222
  }
2144
2223
  }
2145
2224
  shouldBeIncluded(_context) {
@@ -2178,6 +2257,19 @@ const NODE_INTERACTION_UNKNOWN_CALL = {
2178
2257
  withNew: false
2179
2258
  };
2180
2259
 
2260
+ const PureFunctionKey = Symbol('PureFunction');
2261
+ const getPureFunctions = ({ treeshake }) => {
2262
+ const pureFunctions = Object.create(null);
2263
+ for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
2264
+ let currentFunctions = pureFunctions;
2265
+ for (const pathSegment of functionName.split('.')) {
2266
+ currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
2267
+ }
2268
+ currentFunctions[PureFunctionKey] = true;
2269
+ }
2270
+ return pureFunctions;
2271
+ };
2272
+
2181
2273
  class Variable extends ExpressionEntity {
2182
2274
  markReassigned() {
2183
2275
  this.isReassigned = true;
@@ -2254,9 +2346,9 @@ class Variable extends ExpressionEntity {
2254
2346
  * has not been included previously. Once a variable is included, it should
2255
2347
  * take care all its declarations are included.
2256
2348
  */
2257
- include() {
2349
+ includePath(path, context) {
2258
2350
  this.included = true;
2259
- this.renderedLikeHoisted?.include();
2351
+ this.renderedLikeHoisted?.includePath(path, context);
2260
2352
  }
2261
2353
  /**
2262
2354
  * Links the rendered name of this variable to another variable and includes
@@ -2288,8 +2380,8 @@ class ExternalVariable extends Variable {
2288
2380
  hasEffectsOnInteractionAtPath(path, { type }) {
2289
2381
  return type !== INTERACTION_ACCESSED || path.length > (this.isNamespace ? 1 : 0);
2290
2382
  }
2291
- include() {
2292
- super.include();
2383
+ includePath(path, context) {
2384
+ super.includePath(path, context);
2293
2385
  this.module.used = true;
2294
2386
  }
2295
2387
  }
@@ -2590,36 +2682,6 @@ const childNodeKeys = {
2590
2682
  YieldExpression: ['argument']
2591
2683
  };
2592
2684
 
2593
- function createInclusionContext() {
2594
- return {
2595
- brokenFlow: false,
2596
- hasBreak: false,
2597
- hasContinue: false,
2598
- includedCallArguments: new Set(),
2599
- includedLabels: new Set()
2600
- };
2601
- }
2602
- function createHasEffectsContext() {
2603
- return {
2604
- accessed: new PathTracker(),
2605
- assigned: new PathTracker(),
2606
- brokenFlow: false,
2607
- called: new DiscriminatedPathTracker(),
2608
- hasBreak: false,
2609
- hasContinue: false,
2610
- ignore: {
2611
- breaks: false,
2612
- continues: false,
2613
- labels: new Set(),
2614
- returnYield: false,
2615
- this: false
2616
- },
2617
- includedLabels: new Set(),
2618
- instantiated: new DiscriminatedPathTracker(),
2619
- replacedVariableInits: new Map()
2620
- };
2621
- }
2622
-
2623
2685
  const INCLUDE_PARAMETERS = 'variables';
2624
2686
  const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN');
2625
2687
  class NodeBase extends ExpressionEntity {
@@ -2689,9 +2751,8 @@ class NodeBase extends ExpressionEntity {
2689
2751
  this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));
2690
2752
  }
2691
2753
  include(context, includeChildrenRecursively, _options) {
2692
- if (!this.deoptimized)
2693
- this.applyDeoptimizations();
2694
- this.included = true;
2754
+ if (!this.included)
2755
+ this.includeNode(context);
2695
2756
  for (const key of childNodeKeys[this.type]) {
2696
2757
  const value = this[key];
2697
2758
  if (value === null)
@@ -2706,6 +2767,24 @@ class NodeBase extends ExpressionEntity {
2706
2767
  }
2707
2768
  }
2708
2769
  }
2770
+ includeNode(context) {
2771
+ this.included = true;
2772
+ if (!this.deoptimized)
2773
+ this.applyDeoptimizations();
2774
+ for (const key of childNodeKeys[this.type]) {
2775
+ const value = this[key];
2776
+ if (value === null)
2777
+ continue;
2778
+ if (Array.isArray(value)) {
2779
+ for (const child of value) {
2780
+ child?.includePath(UNKNOWN_PATH, context);
2781
+ }
2782
+ }
2783
+ else {
2784
+ value.includePath(UNKNOWN_PATH, context);
2785
+ }
2786
+ }
2787
+ }
2709
2788
  includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {
2710
2789
  this.include(context, includeChildrenRecursively);
2711
2790
  }
@@ -2809,6 +2888,17 @@ class NodeBase extends ExpressionEntity {
2809
2888
  function createChildNodeKeysForNode(esTreeNode) {
2810
2889
  return Object.keys(esTreeNode).filter(key => typeof esTreeNode[key] === 'object' && key.charCodeAt(0) !== 95 /* _ */);
2811
2890
  }
2891
+ function onlyIncludeSelf() {
2892
+ this.included = true;
2893
+ if (!this.deoptimized)
2894
+ this.applyDeoptimizations();
2895
+ }
2896
+ function onlyIncludeSelfNoDeoptimize() {
2897
+ this.included = true;
2898
+ }
2899
+ function doNotDeoptimize() {
2900
+ this.deoptimized = true;
2901
+ }
2812
2902
 
2813
2903
  function isObjectExpressionNode(node) {
2814
2904
  return node instanceof NodeBase && node.type === ObjectExpression$1;
@@ -2821,8 +2911,8 @@ function assembleMemberDescriptions(memberDescriptions, inheritedDescriptions =
2821
2911
  return Object.create(inheritedDescriptions, memberDescriptions);
2822
2912
  }
2823
2913
  const UNDEFINED_EXPRESSION = new (class UndefinedExpression extends ExpressionEntity {
2824
- getLiteralValueAtPath() {
2825
- return undefined;
2914
+ getLiteralValueAtPath(path) {
2915
+ return path.length > 0 ? UnknownValue : undefined;
2826
2916
  }
2827
2917
  })();
2828
2918
  const returnsUnknown = {
@@ -3019,31 +3109,6 @@ function getMemberReturnExpressionWhenCalled(members, memberName) {
3019
3109
  return [members[memberName].returns, false];
3020
3110
  }
3021
3111
 
3022
- class SpreadElement extends NodeBase {
3023
- deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
3024
- if (path.length > 0) {
3025
- this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker);
3026
- }
3027
- }
3028
- hasEffects(context) {
3029
- if (!this.deoptimized)
3030
- this.applyDeoptimizations();
3031
- const { propertyReadSideEffects } = this.scope.context.options
3032
- .treeshake;
3033
- return (this.argument.hasEffects(context) ||
3034
- (propertyReadSideEffects &&
3035
- (propertyReadSideEffects === 'always' ||
3036
- this.argument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context))));
3037
- }
3038
- applyDeoptimizations() {
3039
- this.deoptimized = true;
3040
- // Only properties of properties of the argument could become subject to reassignment
3041
- // This will also reassign the return values of iterators
3042
- this.argument.deoptimizePath([UnknownKey, UnknownKey]);
3043
- this.scope.context.requestTreeshakingPass();
3044
- }
3045
- }
3046
-
3047
3112
  class Method extends ExpressionEntity {
3048
3113
  constructor(description) {
3049
3114
  super();
@@ -3169,6 +3234,7 @@ class ObjectEntity extends ExpressionEntity {
3169
3234
  this.unknownIntegerProps = [];
3170
3235
  this.unmatchableGetters = [];
3171
3236
  this.unmatchablePropertiesAndGetters = [];
3237
+ this.unmatchablePropertiesAndSetters = [];
3172
3238
  this.unmatchableSetters = [];
3173
3239
  if (Array.isArray(properties)) {
3174
3240
  this.buildPropertyMaps(properties);
@@ -3403,9 +3469,38 @@ class ObjectEntity extends ExpressionEntity {
3403
3469
  }
3404
3470
  return false;
3405
3471
  }
3472
+ include(context, includeChildrenRecursively) {
3473
+ this.included = true;
3474
+ for (const property of this.allProperties) {
3475
+ if (includeChildrenRecursively || property.shouldBeIncluded(context)) {
3476
+ property.include(context, includeChildrenRecursively);
3477
+ }
3478
+ }
3479
+ this.prototypeExpression?.include(context, includeChildrenRecursively);
3480
+ }
3481
+ includePath(path, context) {
3482
+ this.included = true;
3483
+ if (path.length === 0)
3484
+ return;
3485
+ const [key, ...subPath] = path;
3486
+ const [includedMembers, includedPath] = typeof key === 'string'
3487
+ ? [
3488
+ [
3489
+ ...new Set([
3490
+ ...(this.propertiesAndGettersByKey[key] || this.unmatchablePropertiesAndGetters),
3491
+ ...(this.propertiesAndSettersByKey[key] || this.unmatchablePropertiesAndSetters)
3492
+ ])
3493
+ ],
3494
+ subPath
3495
+ ]
3496
+ : [this.allProperties, UNKNOWN_PATH];
3497
+ for (const property of includedMembers) {
3498
+ property.includePath(includedPath, context);
3499
+ }
3500
+ this.prototypeExpression?.includePath(path, context);
3501
+ }
3406
3502
  buildPropertyMaps(properties) {
3407
- const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchableGetters, unmatchableSetters } = this;
3408
- const unmatchablePropertiesAndSetters = [];
3503
+ const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchablePropertiesAndSetters, unmatchableGetters, unmatchableSetters } = this;
3409
3504
  for (let index = properties.length - 1; index >= 0; index--) {
3410
3505
  const { key, kind, property } = properties[index];
3411
3506
  allProperties.push(property);
@@ -3675,6 +3770,37 @@ const ARRAY_PROTOTYPE = new ObjectEntity({
3675
3770
  values: METHOD_DEOPTS_SELF_RETURNS_UNKNOWN
3676
3771
  }, OBJECT_PROTOTYPE, true);
3677
3772
 
3773
+ class SpreadElement extends NodeBase {
3774
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
3775
+ if (path.length > 0) {
3776
+ this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker);
3777
+ }
3778
+ }
3779
+ hasEffects(context) {
3780
+ if (!this.deoptimized)
3781
+ this.applyDeoptimizations();
3782
+ const { propertyReadSideEffects } = this.scope.context.options
3783
+ .treeshake;
3784
+ return (this.argument.hasEffects(context) ||
3785
+ (propertyReadSideEffects &&
3786
+ (propertyReadSideEffects === 'always' ||
3787
+ this.argument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context))));
3788
+ }
3789
+ includeNode(context) {
3790
+ this.included = true;
3791
+ if (!this.deoptimized)
3792
+ this.applyDeoptimizations();
3793
+ this.argument.includePath(UNKNOWN_PATH, context);
3794
+ }
3795
+ applyDeoptimizations() {
3796
+ this.deoptimized = true;
3797
+ // Only properties of properties of the argument could become subject to reassignment
3798
+ // This will also reassign the return values of iterators
3799
+ this.argument.deoptimizePath([UnknownKey, UnknownKey]);
3800
+ this.scope.context.requestTreeshakingPass();
3801
+ }
3802
+ }
3803
+
3678
3804
  class ArrayExpression extends NodeBase {
3679
3805
  constructor() {
3680
3806
  super(...arguments);
@@ -3695,6 +3821,16 @@ class ArrayExpression extends NodeBase {
3695
3821
  hasEffectsOnInteractionAtPath(path, interaction, context) {
3696
3822
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
3697
3823
  }
3824
+ includeNode(context) {
3825
+ this.included = true;
3826
+ if (!this.deoptimized)
3827
+ this.applyDeoptimizations();
3828
+ for (const element of this.elements) {
3829
+ if (element) {
3830
+ element?.includePath(UNKNOWN_PATH, context);
3831
+ }
3832
+ }
3833
+ }
3698
3834
  applyDeoptimizations() {
3699
3835
  this.deoptimized = true;
3700
3836
  let hasSpread = false;
@@ -4762,17 +4898,37 @@ class GlobalVariable extends Variable {
4762
4898
  }
4763
4899
  }
4764
4900
 
4901
+ // To avoid infinite recursions
4902
+ const MAX_PATH_DEPTH = 6;
4903
+ // If a path is longer than MAX_PATH_DEPTH, it is truncated so that it is at
4904
+ // most MAX_PATH_DEPTH long. The last element is always UnknownKey
4905
+ const limitConcatenatedPathDepth = (path1, path2) => {
4906
+ const { length: length1 } = path1;
4907
+ const { length: length2 } = path2;
4908
+ return length1 === 0
4909
+ ? path2
4910
+ : length2 === 0
4911
+ ? path1
4912
+ : length1 + length2 > MAX_PATH_DEPTH
4913
+ ? [...path1, ...path2.slice(0, MAX_PATH_DEPTH - 1 - path1.length), 'UnknownKey']
4914
+ : [...path1, ...path2];
4915
+ };
4916
+
4765
4917
  class LocalVariable extends Variable {
4766
- constructor(name, declarator, init, context, kind) {
4918
+ constructor(name, declarator, init,
4919
+ /** if this is non-empty, the actual init is this path of this.init */
4920
+ initPath, context, kind) {
4767
4921
  super(name);
4768
4922
  this.init = init;
4923
+ this.initPath = initPath;
4924
+ this.kind = kind;
4769
4925
  this.calledFromTryStatement = false;
4770
4926
  this.additionalInitializers = null;
4927
+ this.includedPathTracker = new IncludedPathTracker();
4771
4928
  this.expressionsToBeDeoptimized = [];
4772
4929
  this.declarations = declarator ? [declarator] : [];
4773
4930
  this.deoptimizationTracker = context.deoptimizationTracker;
4774
4931
  this.module = context.module;
4775
- this.kind = kind;
4776
4932
  }
4777
4933
  addDeclaration(identifier, init) {
4778
4934
  this.declarations.push(identifier);
@@ -4783,15 +4939,16 @@ class LocalVariable extends Variable {
4783
4939
  for (const initializer of this.additionalInitializers) {
4784
4940
  initializer.deoptimizePath(UNKNOWN_PATH);
4785
4941
  }
4786
- this.additionalInitializers = null;
4787
4942
  }
4788
4943
  }
4789
4944
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
4790
- if (this.isReassigned) {
4945
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
4791
4946
  deoptimizeInteraction(interaction);
4792
4947
  return;
4793
4948
  }
4794
- recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker), undefined);
4949
+ recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
4950
+ this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], recursionTracker);
4951
+ }, undefined);
4795
4952
  }
4796
4953
  deoptimizePath(path) {
4797
4954
  if (this.isReassigned ||
@@ -4805,37 +4962,40 @@ class LocalVariable extends Variable {
4805
4962
  for (const expression of expressionsToBeDeoptimized) {
4806
4963
  expression.deoptimizeCache();
4807
4964
  }
4808
- this.init.deoptimizePath(UNKNOWN_PATH);
4965
+ this.init.deoptimizePath([...this.initPath, UnknownKey]);
4809
4966
  }
4810
4967
  else {
4811
- this.init.deoptimizePath(path);
4968
+ this.init.deoptimizePath(limitConcatenatedPathDepth(this.initPath, path));
4812
4969
  }
4813
4970
  }
4814
4971
  getLiteralValueAtPath(path, recursionTracker, origin) {
4815
- if (this.isReassigned) {
4972
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
4816
4973
  return UnknownValue;
4817
4974
  }
4818
4975
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
4819
4976
  this.expressionsToBeDeoptimized.push(origin);
4820
- return this.init.getLiteralValueAtPath(path, recursionTracker, origin);
4977
+ return this.init.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin);
4821
4978
  }, UnknownValue);
4822
4979
  }
4823
4980
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
4824
- if (this.isReassigned) {
4981
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
4825
4982
  return UNKNOWN_RETURN_EXPRESSION;
4826
4983
  }
4827
4984
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
4828
4985
  this.expressionsToBeDeoptimized.push(origin);
4829
- return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
4986
+ return this.init.getReturnExpressionWhenCalledAtPath([...this.initPath, ...path], interaction, recursionTracker, origin);
4830
4987
  }, UNKNOWN_RETURN_EXPRESSION);
4831
4988
  }
4832
4989
  hasEffectsOnInteractionAtPath(path, interaction, context) {
4990
+ if (path.length + this.initPath.length > MAX_PATH_DEPTH) {
4991
+ return true;
4992
+ }
4833
4993
  switch (interaction.type) {
4834
4994
  case INTERACTION_ACCESSED: {
4835
4995
  if (this.isReassigned)
4836
4996
  return true;
4837
4997
  return (!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
4838
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
4998
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4839
4999
  }
4840
5000
  case INTERACTION_ASSIGNED: {
4841
5001
  if (this.included)
@@ -4845,44 +5005,63 @@ class LocalVariable extends Variable {
4845
5005
  if (this.isReassigned)
4846
5006
  return true;
4847
5007
  return (!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
4848
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
5008
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4849
5009
  }
4850
5010
  case INTERACTION_CALLED: {
4851
5011
  if (this.isReassigned)
4852
5012
  return true;
4853
5013
  return (!(interaction.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this) &&
4854
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
5014
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
4855
5015
  }
4856
5016
  }
4857
5017
  }
4858
- include() {
4859
- if (!this.included) {
4860
- super.include();
5018
+ includePath(path, context) {
5019
+ if (!this.includedPathTracker.includePathAndGetIfIncluded(path)) {
5020
+ this.module.scope.context.requestTreeshakingPass();
5021
+ if (!this.included) {
5022
+ // This will reduce the number of tree-shaking passes by eagerly
5023
+ // including inits. By pushing this here instead of directly including
5024
+ // we avoid deep call stacks.
5025
+ this.module.scope.context.newlyIncludedVariableInits.add(this.init);
5026
+ }
5027
+ super.includePath(path, context);
4861
5028
  for (const declaration of this.declarations) {
4862
5029
  // If node is a default export, it can save a tree-shaking run to include the full declaration now
4863
5030
  if (!declaration.included)
4864
- declaration.include(createInclusionContext(), false);
5031
+ declaration.include(context, false);
4865
5032
  let node = declaration.parent;
4866
5033
  while (!node.included) {
4867
5034
  // We do not want to properly include parents in case they are part of a dead branch
4868
5035
  // in which case .include() might pull in more dead code
4869
- node.included = true;
5036
+ node.includeNode(context);
4870
5037
  if (node.type === Program$1)
4871
5038
  break;
4872
5039
  node = node.parent;
4873
5040
  }
4874
5041
  }
5042
+ // We need to make sure we include the correct path of the init
5043
+ if (path.length > 0) {
5044
+ this.init.includePath(limitConcatenatedPathDepth(this.initPath, path), context);
5045
+ this.additionalInitializers?.forEach(initializer => initializer.includePath(UNKNOWN_PATH, context));
5046
+ }
4875
5047
  }
4876
5048
  }
4877
- includeCallArguments(context, parameters) {
4878
- if (this.isReassigned || context.includedCallArguments.has(this.init)) {
4879
- for (const argument of parameters) {
4880
- argument.include(context, false);
5049
+ includeCallArguments(context, interaction) {
5050
+ if (this.isReassigned ||
5051
+ context.includedCallArguments.has(this.init) ||
5052
+ // This can be removed again once we can include arguments when called at
5053
+ // a specific path
5054
+ this.initPath.length > 0) {
5055
+ for (const argument of interaction.args) {
5056
+ if (argument) {
5057
+ argument.includePath(UNKNOWN_PATH, context);
5058
+ argument.include(context, false);
5059
+ }
4881
5060
  }
4882
5061
  }
4883
5062
  else {
4884
5063
  context.includedCallArguments.add(this.init);
4885
- this.init.includeCallArguments(context, parameters);
5064
+ this.init.includeCallArguments(context, interaction);
4886
5065
  context.includedCallArguments.delete(this.init);
4887
5066
  }
4888
5067
  }
@@ -4962,18 +5141,31 @@ class IdentifierBase extends NodeBase {
4962
5141
  }
4963
5142
  }
4964
5143
  }
4965
- include() {
5144
+ include(context) {
5145
+ if (!this.included)
5146
+ this.includeNode(context);
5147
+ }
5148
+ includeNode(context) {
5149
+ this.included = true;
4966
5150
  if (!this.deoptimized)
4967
5151
  this.applyDeoptimizations();
5152
+ if (this.variable !== null) {
5153
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
5154
+ }
5155
+ }
5156
+ includePath(path, context) {
4968
5157
  if (!this.included) {
4969
5158
  this.included = true;
4970
5159
  if (this.variable !== null) {
4971
- this.scope.context.includeVariableInModule(this.variable);
5160
+ this.scope.context.includeVariableInModule(this.variable, path, context);
4972
5161
  }
4973
5162
  }
5163
+ else if (path.length > 0) {
5164
+ this.variable?.includePath(path, context);
5165
+ }
4974
5166
  }
4975
- includeCallArguments(context, parameters) {
4976
- this.variable.includeCallArguments(context, parameters);
5167
+ includeCallArguments(context, interaction) {
5168
+ this.variable.includeCallArguments(context, interaction);
4977
5169
  }
4978
5170
  isPossibleTDZ() {
4979
5171
  // return cached value to avoid issues with the next tree-shaking pass
@@ -5047,13 +5239,36 @@ class IdentifierBase extends NodeBase {
5047
5239
  }
5048
5240
  return currentPureFunction?.[PureFunctionKey];
5049
5241
  }
5050
- }
5051
- function closestParentFunctionOrProgram(node) {
5052
- while (node && !/^Program|Function/.test(node.type)) {
5053
- node = node.parent;
5242
+ }
5243
+ function closestParentFunctionOrProgram(node) {
5244
+ while (node && !/^Program|Function/.test(node.type)) {
5245
+ node = node.parent;
5246
+ }
5247
+ // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program
5248
+ return node;
5249
+ }
5250
+
5251
+ class ObjectMember extends ExpressionEntity {
5252
+ constructor(object, path) {
5253
+ super();
5254
+ this.object = object;
5255
+ this.path = path;
5256
+ }
5257
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
5258
+ this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.path, ...path], recursionTracker);
5259
+ }
5260
+ deoptimizePath(path) {
5261
+ this.object.deoptimizePath([...this.path, ...path]);
5262
+ }
5263
+ getLiteralValueAtPath(path, recursionTracker, origin) {
5264
+ return this.object.getLiteralValueAtPath([...this.path, ...path], recursionTracker, origin);
5265
+ }
5266
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
5267
+ return this.object.getReturnExpressionWhenCalledAtPath([...this.path, ...path], interaction, recursionTracker, origin);
5268
+ }
5269
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
5270
+ return this.object.hasEffectsOnInteractionAtPath([...this.path, ...path], interaction, context);
5054
5271
  }
5055
- // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program
5056
- return node;
5057
5272
  }
5058
5273
 
5059
5274
  class Identifier extends IdentifierBase {
@@ -5061,6 +5276,12 @@ class Identifier extends IdentifierBase {
5061
5276
  super(...arguments);
5062
5277
  this.variable = null;
5063
5278
  }
5279
+ get isDestructuringDeoptimized() {
5280
+ return isFlagSet(this.flags, 8388608 /* Flag.destructuringDeoptimized */);
5281
+ }
5282
+ set isDestructuringDeoptimized(value) {
5283
+ this.flags = setFlag(this.flags, 8388608 /* Flag.destructuringDeoptimized */, value);
5284
+ }
5064
5285
  addExportedVariables(variables, exportNamesByVariable) {
5065
5286
  if (exportNamesByVariable.has(this.variable)) {
5066
5287
  variables.push(this.variable);
@@ -5073,43 +5294,53 @@ class Identifier extends IdentifierBase {
5073
5294
  this.isVariableReference = true;
5074
5295
  }
5075
5296
  }
5076
- declare(kind, init) {
5297
+ declare(kind, destructuredInitPath, init) {
5077
5298
  let variable;
5078
5299
  const { treeshake } = this.scope.context.options;
5079
- switch (kind) {
5080
- case 'var': {
5081
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5082
- if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
5083
- // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
5084
- variable.markInitializersForDeoptimization();
5085
- }
5086
- break;
5087
- }
5088
- case 'function': {
5089
- // in strict mode, functions are only hoisted within a scope but not across block scopes
5090
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5091
- break;
5092
- }
5093
- case 'let':
5094
- case 'const':
5095
- case 'using':
5096
- case 'await using':
5097
- case 'class': {
5098
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
5099
- break;
5100
- }
5101
- case 'parameter': {
5102
- variable = this.scope.addParameterDeclaration(this);
5103
- break;
5104
- }
5105
- /* istanbul ignore next */
5106
- default: {
5107
- /* istanbul ignore next */
5108
- throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
5300
+ if (kind === 'parameter') {
5301
+ variable = this.scope.addParameterDeclaration(this, destructuredInitPath);
5302
+ }
5303
+ else {
5304
+ variable = this.scope.addDeclaration(this, this.scope.context, init, destructuredInitPath, kind);
5305
+ if (kind === 'var' && treeshake && treeshake.correctVarValueBeforeDeclaration) {
5306
+ // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
5307
+ variable.markInitializersForDeoptimization();
5109
5308
  }
5110
5309
  }
5111
5310
  return [(this.variable = variable)];
5112
5311
  }
5312
+ deoptimizeAssignment(destructuredInitPath, init) {
5313
+ this.deoptimizePath(EMPTY_PATH);
5314
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
5315
+ }
5316
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
5317
+ return (destructuredInitPath.length > 0 &&
5318
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
5319
+ }
5320
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
5321
+ if (destructuredInitPath.length > 0 && !this.isDestructuringDeoptimized) {
5322
+ this.isDestructuringDeoptimized = true;
5323
+ init.deoptimizeArgumentsOnInteractionAtPath({
5324
+ args: [new ObjectMember(init, destructuredInitPath.slice(0, -1))],
5325
+ type: INTERACTION_ACCESSED
5326
+ }, destructuredInitPath, SHARED_RECURSION_TRACKER);
5327
+ }
5328
+ const { propertyReadSideEffects } = this.scope.context.options
5329
+ .treeshake;
5330
+ if ((this.included ||=
5331
+ destructuredInitPath.length > 0 &&
5332
+ !context.brokenFlow &&
5333
+ propertyReadSideEffects &&
5334
+ (propertyReadSideEffects === 'always' ||
5335
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext())))) {
5336
+ if (this.variable && !this.variable.included) {
5337
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
5338
+ }
5339
+ init.includePath(destructuredInitPath, context);
5340
+ return true;
5341
+ }
5342
+ return false;
5343
+ }
5113
5344
  markDeclarationReached() {
5114
5345
  this.variable.initReached = true;
5115
5346
  }
@@ -5174,18 +5405,17 @@ class Scope {
5174
5405
  - then the variable is still declared in the hoisted outer scope, but the initializer is assigned to the parameter
5175
5406
  - const, let, class, and function except in the cases above cannot redeclare anything
5176
5407
  */
5177
- addDeclaration(identifier, context, init, kind) {
5408
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5178
5409
  const name = identifier.name;
5179
5410
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
5180
5411
  if (existingVariable) {
5181
- const existingKind = existingVariable.kind;
5182
- if (kind === 'var' && existingKind === 'var') {
5412
+ if (kind === 'var' && existingVariable.kind === 'var') {
5183
5413
  existingVariable.addDeclaration(identifier, init);
5184
5414
  return existingVariable;
5185
5415
  }
5186
5416
  context.error(logRedeclarationError(name), identifier.start);
5187
5417
  }
5188
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
5418
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
5189
5419
  this.variables.set(name, newVariable);
5190
5420
  return newVariable;
5191
5421
  }
@@ -5361,7 +5591,6 @@ class MethodBase extends NodeBase {
5361
5591
  }
5362
5592
  return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context);
5363
5593
  }
5364
- applyDeoptimizations() { }
5365
5594
  getAccessedValue() {
5366
5595
  if (this.accessedValue === null) {
5367
5596
  if (this.kind === 'get') {
@@ -5375,19 +5604,20 @@ class MethodBase extends NodeBase {
5375
5604
  return this.accessedValue;
5376
5605
  }
5377
5606
  }
5607
+ MethodBase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
5608
+ MethodBase.prototype.applyDeoptimizations = doNotDeoptimize;
5378
5609
 
5379
5610
  class MethodDefinition extends MethodBase {
5380
5611
  hasEffects(context) {
5381
5612
  return super.hasEffects(context) || checkEffectForNodes(this.decorators, context);
5382
5613
  }
5383
- applyDeoptimizations() { }
5384
5614
  }
5385
5615
 
5386
5616
  class BlockScope extends ChildScope {
5387
5617
  constructor(parent) {
5388
5618
  super(parent, parent.context);
5389
5619
  }
5390
- addDeclaration(identifier, context, init, kind) {
5620
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5391
5621
  if (kind === 'var') {
5392
5622
  const name = identifier.name;
5393
5623
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -5399,7 +5629,7 @@ class BlockScope extends ChildScope {
5399
5629
  }
5400
5630
  return context.error(logRedeclarationError(name), identifier.start);
5401
5631
  }
5402
- const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind);
5632
+ const declaredVariable = this.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5403
5633
  // Necessary to make sure the init is deoptimized for conditional declarations.
5404
5634
  // We cannot call deoptimizePath here.
5405
5635
  declaredVariable.markInitializersForDeoptimization();
@@ -5407,7 +5637,7 @@ class BlockScope extends ChildScope {
5407
5637
  this.addHoistedVariable(name, declaredVariable);
5408
5638
  return declaredVariable;
5409
5639
  }
5410
- return super.addDeclaration(identifier, context, init, kind);
5640
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5411
5641
  }
5412
5642
  }
5413
5643
 
@@ -5439,33 +5669,12 @@ class StaticBlock extends NodeBase {
5439
5669
  }
5440
5670
  }
5441
5671
  }
5672
+ StaticBlock.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
5673
+ StaticBlock.prototype.applyDeoptimizations = doNotDeoptimize;
5442
5674
  function isStaticBlock(statement) {
5443
5675
  return statement.type === StaticBlock$1;
5444
5676
  }
5445
5677
 
5446
- class ObjectMember extends ExpressionEntity {
5447
- constructor(object, key) {
5448
- super();
5449
- this.object = object;
5450
- this.key = key;
5451
- }
5452
- deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
5453
- this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker);
5454
- }
5455
- deoptimizePath(path) {
5456
- this.object.deoptimizePath([this.key, ...path]);
5457
- }
5458
- getLiteralValueAtPath(path, recursionTracker, origin) {
5459
- return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin);
5460
- }
5461
- getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
5462
- return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin);
5463
- }
5464
- hasEffectsOnInteractionAtPath(path, interaction, context) {
5465
- return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context);
5466
- }
5467
- }
5468
-
5469
5678
  class ClassNode extends NodeBase {
5470
5679
  constructor() {
5471
5680
  super(...arguments);
@@ -5506,21 +5715,20 @@ class ClassNode extends NodeBase {
5506
5715
  : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
5507
5716
  }
5508
5717
  include(context, includeChildrenRecursively) {
5509
- if (!this.deoptimized)
5510
- this.applyDeoptimizations();
5511
- this.included = true;
5718
+ if (!this.included)
5719
+ this.includeNode(context);
5512
5720
  this.superClass?.include(context, includeChildrenRecursively);
5513
5721
  this.body.include(context, includeChildrenRecursively);
5514
5722
  for (const decorator of this.decorators)
5515
5723
  decorator.include(context, includeChildrenRecursively);
5516
5724
  if (this.id) {
5517
5725
  this.id.markDeclarationReached();
5518
- this.id.include();
5726
+ this.id.include(context);
5519
5727
  }
5520
5728
  }
5521
5729
  initialise() {
5522
5730
  super.initialise();
5523
- this.id?.declare('class', this);
5731
+ this.id?.declare('class', EMPTY_PATH, this);
5524
5732
  for (const method of this.body.body) {
5525
5733
  if (method instanceof MethodDefinition && method.kind === 'constructor') {
5526
5734
  this.classConstructor = method;
@@ -5578,11 +5786,12 @@ class ClassNode extends NodeBase {
5578
5786
  staticProperties.unshift({
5579
5787
  key: 'prototype',
5580
5788
  kind: 'init',
5581
- property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE)
5789
+ property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, ['prototype']) : OBJECT_PROTOTYPE)
5582
5790
  });
5583
5791
  return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE));
5584
5792
  }
5585
5793
  }
5794
+ ClassNode.prototype.includeNode = onlyIncludeSelf;
5586
5795
 
5587
5796
  class ClassDeclaration extends ClassNode {
5588
5797
  initialise() {
@@ -5635,7 +5844,7 @@ class ClassDeclaration extends ClassNode {
5635
5844
 
5636
5845
  class ArgumentsVariable extends LocalVariable {
5637
5846
  constructor(context) {
5638
- super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');
5847
+ super('arguments', null, UNKNOWN_EXPRESSION, EMPTY_PATH, context, 'other');
5639
5848
  this.deoptimizedArguments = [];
5640
5849
  }
5641
5850
  addArgumentToBeDeoptimized(argument) {
@@ -5649,8 +5858,8 @@ class ArgumentsVariable extends LocalVariable {
5649
5858
  hasEffectsOnInteractionAtPath(path, { type }) {
5650
5859
  return type !== INTERACTION_ACCESSED || path.length > 1;
5651
5860
  }
5652
- include() {
5653
- super.include();
5861
+ includePath(path, context) {
5862
+ super.includePath(path, context);
5654
5863
  for (const argument of this.deoptimizedArguments) {
5655
5864
  argument.deoptimizePath(UNKNOWN_PATH);
5656
5865
  }
@@ -5661,27 +5870,28 @@ class ArgumentsVariable extends LocalVariable {
5661
5870
  const MAX_TRACKED_INTERACTIONS = 20;
5662
5871
  const NO_INTERACTIONS = EMPTY_ARRAY;
5663
5872
  const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);
5664
- const EMPTY_PATH_TRACKER = new PathTracker();
5873
+ const EMPTY_PATH_TRACKER = new EntityPathTracker();
5665
5874
  const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);
5666
5875
  class ParameterVariable extends LocalVariable {
5667
- constructor(name, declarator, context) {
5668
- super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');
5876
+ constructor(name, declarator, argumentPath, context) {
5877
+ super(name, declarator, UNKNOWN_EXPRESSION, argumentPath, context, 'parameter');
5669
5878
  this.deoptimizationInteractions = [];
5670
- this.deoptimizations = new PathTracker();
5879
+ this.deoptimizations = new EntityPathTracker();
5671
5880
  this.deoptimizedFields = new Set();
5672
- this.entitiesToBeDeoptimized = new Set();
5673
- this.expressionsUseTheKnownValue = [];
5881
+ this.argumentsToBeDeoptimized = new Set();
5882
+ this.expressionsDependingOnKnownValue = [];
5674
5883
  this.knownValue = null;
5675
5884
  this.knownValueLiteral = UnknownValue;
5676
5885
  this.frozenValue = null;
5677
5886
  }
5678
- addEntityToBeDeoptimized(entity) {
5887
+ addArgumentValue(entity) {
5888
+ this.updateKnownValue(entity);
5679
5889
  if (entity === UNKNOWN_EXPRESSION) {
5680
5890
  // As unknown expressions fully deoptimize all interactions, we can clear
5681
5891
  // the interaction cache at this point provided we keep this optimization
5682
5892
  // in mind when adding new interactions
5683
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5684
- this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);
5893
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5894
+ this.argumentsToBeDeoptimized.add(UNKNOWN_EXPRESSION);
5685
5895
  for (const { interaction } of this.deoptimizationInteractions) {
5686
5896
  deoptimizeInteraction(interaction);
5687
5897
  }
@@ -5691,27 +5901,34 @@ class ParameterVariable extends LocalVariable {
5691
5901
  else if (this.deoptimizedFields.has(UnknownKey)) {
5692
5902
  // This means that we already deoptimized all interactions and no longer
5693
5903
  // track them
5694
- entity.deoptimizePath(UNKNOWN_PATH);
5904
+ entity.deoptimizePath([...this.initPath, UnknownKey]);
5695
5905
  }
5696
- else if (!this.entitiesToBeDeoptimized.has(entity)) {
5697
- this.entitiesToBeDeoptimized.add(entity);
5906
+ else if (!this.argumentsToBeDeoptimized.has(entity)) {
5907
+ this.argumentsToBeDeoptimized.add(entity);
5698
5908
  for (const field of this.deoptimizedFields) {
5699
- entity.deoptimizePath([field]);
5909
+ entity.deoptimizePath([...this.initPath, field]);
5700
5910
  }
5701
5911
  for (const { interaction, path } of this.deoptimizationInteractions) {
5702
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
5912
+ if (this.initPath.length + path.length > MAX_PATH_DEPTH) {
5913
+ deoptimizeInteraction(interaction);
5914
+ continue;
5915
+ }
5916
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
5703
5917
  }
5704
5918
  }
5705
5919
  }
5920
+ /** This says we should not make assumptions about the value of the parameter.
5921
+ * This is different from deoptimization that will also cause argument values
5922
+ * to be deoptimized. */
5706
5923
  markReassigned() {
5707
5924
  if (this.isReassigned) {
5708
5925
  return;
5709
5926
  }
5710
5927
  super.markReassigned();
5711
- for (const expression of this.expressionsUseTheKnownValue) {
5928
+ for (const expression of this.expressionsDependingOnKnownValue) {
5712
5929
  expression.deoptimizeCache();
5713
5930
  }
5714
- this.expressionsUseTheKnownValue = EMPTY_ARRAY;
5931
+ this.expressionsDependingOnKnownValue = EMPTY_ARRAY;
5715
5932
  }
5716
5933
  deoptimizeCache() {
5717
5934
  this.markReassigned();
@@ -5728,7 +5945,7 @@ class ParameterVariable extends LocalVariable {
5728
5945
  }
5729
5946
  if (this.knownValue === null) {
5730
5947
  this.knownValue = argument;
5731
- this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
5948
+ this.knownValueLiteral = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
5732
5949
  return;
5733
5950
  }
5734
5951
  // the same literal or identifier, do nothing
@@ -5744,7 +5961,7 @@ class ParameterVariable extends LocalVariable {
5744
5961
  return;
5745
5962
  }
5746
5963
  // add tracking for the new argument
5747
- const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
5964
+ const newValue = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
5748
5965
  if (newValue !== oldValue) {
5749
5966
  this.markReassigned();
5750
5967
  }
@@ -5762,24 +5979,31 @@ class ParameterVariable extends LocalVariable {
5762
5979
  return this.frozenValue;
5763
5980
  }
5764
5981
  getLiteralValueAtPath(path, recursionTracker, origin) {
5765
- if (this.isReassigned) {
5982
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
5766
5983
  return UnknownValue;
5767
5984
  }
5768
5985
  const knownValue = this.getKnownValue();
5769
- this.expressionsUseTheKnownValue.push(origin);
5770
- return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);
5986
+ this.expressionsDependingOnKnownValue.push(origin);
5987
+ return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin), UnknownValue);
5771
5988
  }
5772
5989
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5773
- if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) {
5990
+ const { type } = interaction;
5991
+ if (this.isReassigned ||
5992
+ type === INTERACTION_ASSIGNED ||
5993
+ path.length + this.initPath.length > MAX_PATH_DEPTH) {
5774
5994
  return super.hasEffectsOnInteractionAtPath(path, interaction, context);
5775
5995
  }
5776
- const knownValue = this.getKnownValue();
5777
- return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context);
5996
+ return (!(type === INTERACTION_CALLED
5997
+ ? (interaction.withNew
5998
+ ? context.instantiated
5999
+ : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)
6000
+ : context.accessed.trackEntityAtPathAndGetIfTracked(path, this)) &&
6001
+ this.getKnownValue().hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
5778
6002
  }
5779
6003
  deoptimizeArgumentsOnInteractionAtPath(interaction, path) {
5780
6004
  // For performance reasons, we fully deoptimize all deeper interactions
5781
6005
  if (path.length >= 2 ||
5782
- this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
6006
+ this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
5783
6007
  this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||
5784
6008
  (path.length === 1 &&
5785
6009
  (this.deoptimizedFields.has(UnknownKey) ||
@@ -5788,10 +6012,10 @@ class ParameterVariable extends LocalVariable {
5788
6012
  return;
5789
6013
  }
5790
6014
  if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {
5791
- for (const entity of this.entitiesToBeDeoptimized) {
5792
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
6015
+ for (const entity of this.argumentsToBeDeoptimized) {
6016
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
5793
6017
  }
5794
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
6018
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
5795
6019
  this.deoptimizationInteractions.push({
5796
6020
  interaction,
5797
6021
  path
@@ -5812,17 +6036,17 @@ class ParameterVariable extends LocalVariable {
5812
6036
  return;
5813
6037
  }
5814
6038
  this.deoptimizedFields.add(key);
5815
- for (const entity of this.entitiesToBeDeoptimized) {
6039
+ for (const entity of this.argumentsToBeDeoptimized) {
5816
6040
  // We do not need a recursion tracker here as we already track whether
5817
6041
  // this field is deoptimized
5818
- entity.deoptimizePath([key]);
6042
+ entity.deoptimizePath([...this.initPath, key]);
5819
6043
  }
5820
6044
  if (key === UnknownKey) {
5821
6045
  // save some memory
5822
6046
  this.deoptimizationInteractions = NO_INTERACTIONS;
5823
6047
  this.deoptimizations = EMPTY_PATH_TRACKER;
5824
6048
  this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;
5825
- this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
6049
+ this.argumentsToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
5826
6050
  }
5827
6051
  }
5828
6052
  getReturnExpressionWhenCalledAtPath(path) {
@@ -5837,11 +6061,14 @@ class ParameterVariable extends LocalVariable {
5837
6061
  }
5838
6062
  return UNKNOWN_RETURN_EXPRESSION;
5839
6063
  }
6064
+ includeArgumentPaths(entity, context) {
6065
+ this.includedPathTracker.includeAllPaths(entity, context, this.initPath);
6066
+ }
5840
6067
  }
5841
6068
 
5842
6069
  class ThisVariable extends ParameterVariable {
5843
6070
  constructor(context) {
5844
- super('this', null, context);
6071
+ super('this', null, EMPTY_PATH, context);
5845
6072
  }
5846
6073
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5847
6074
  return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);
@@ -5853,7 +6080,7 @@ class CatchBodyScope extends ChildScope {
5853
6080
  super(parent, parent.context);
5854
6081
  this.parent = parent;
5855
6082
  }
5856
- addDeclaration(identifier, context, init, kind) {
6083
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5857
6084
  if (kind === 'var') {
5858
6085
  const name = identifier.name;
5859
6086
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -5866,7 +6093,7 @@ class CatchBodyScope extends ChildScope {
5866
6093
  // the assignment actually goes to the parameter and the var is
5867
6094
  // hoisted without assignment. Locally, it is shadowed by the
5868
6095
  // parameter
5869
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, kind);
6096
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, destructuredInitPath, kind);
5870
6097
  // To avoid the need to rewrite the declaration, we link the variable
5871
6098
  // names. If we ever implement a logic that splits initialization and
5872
6099
  // assignment for hoisted vars, the "renderLikeHoisted" logic can be
@@ -5885,7 +6112,7 @@ class CatchBodyScope extends ChildScope {
5885
6112
  return context.error(logRedeclarationError(name), identifier.start);
5886
6113
  }
5887
6114
  // We only add parameters to parameter scopes
5888
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, kind);
6115
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5889
6116
  // Necessary to make sure the init is deoptimized for conditional declarations.
5890
6117
  // We cannot call deoptimizePath here.
5891
6118
  declaredVariable.markInitializersForDeoptimization();
@@ -5893,7 +6120,7 @@ class CatchBodyScope extends ChildScope {
5893
6120
  this.addHoistedVariable(name, declaredVariable);
5894
6121
  return declaredVariable;
5895
6122
  }
5896
- return super.addDeclaration(identifier, context, init, kind);
6123
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
5897
6124
  }
5898
6125
  }
5899
6126
 
@@ -5903,7 +6130,7 @@ class FunctionBodyScope extends ChildScope {
5903
6130
  }
5904
6131
  // There is stuff that is only allowed in function scopes, i.e. functions can
5905
6132
  // be redeclared, functions and var can redeclare each other
5906
- addDeclaration(identifier, context, init, kind) {
6133
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
5907
6134
  const name = identifier.name;
5908
6135
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
5909
6136
  if (existingVariable) {
@@ -5915,7 +6142,7 @@ class FunctionBodyScope extends ChildScope {
5915
6142
  }
5916
6143
  context.error(logRedeclarationError(name), identifier.start);
5917
6144
  }
5918
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
6145
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
5919
6146
  this.variables.set(name, newVariable);
5920
6147
  return newVariable;
5921
6148
  }
@@ -5924,21 +6151,21 @@ class FunctionBodyScope extends ChildScope {
5924
6151
  class ParameterScope extends ChildScope {
5925
6152
  constructor(parent, isCatchScope) {
5926
6153
  super(parent, parent.context);
5927
- this.parameters = [];
5928
6154
  this.hasRest = false;
6155
+ this.parameters = [];
5929
6156
  this.bodyScope = isCatchScope ? new CatchBodyScope(this) : new FunctionBodyScope(this);
5930
6157
  }
5931
6158
  /**
5932
6159
  * Adds a parameter to this scope. Parameters must be added in the correct
5933
6160
  * order, i.e. from left to right.
5934
6161
  */
5935
- addParameterDeclaration(identifier) {
6162
+ addParameterDeclaration(identifier, argumentPath) {
5936
6163
  const { name, start } = identifier;
5937
6164
  const existingParameter = this.variables.get(name);
5938
6165
  if (existingParameter) {
5939
6166
  return this.context.error(logDuplicateArgumentNameError(name), start);
5940
6167
  }
5941
- const variable = new ParameterVariable(name, identifier, this.context);
6168
+ const variable = new ParameterVariable(name, identifier, argumentPath, this.context);
5942
6169
  this.variables.set(name, variable);
5943
6170
  // We also add it to the body scope to detect name conflicts with local
5944
6171
  // variables. We still need the intermediate scope, though, as parameter
@@ -5956,42 +6183,56 @@ class ParameterScope extends ChildScope {
5956
6183
  }
5957
6184
  this.hasRest = hasRest;
5958
6185
  }
5959
- includeCallArguments(context, parameters) {
6186
+ includeCallArguments(context, interaction) {
5960
6187
  let calledFromTryStatement = false;
5961
6188
  let argumentIncluded = false;
5962
6189
  const restParameter = this.hasRest && this.parameters[this.parameters.length - 1];
5963
- for (const checkedArgument of parameters) {
5964
- if (checkedArgument instanceof SpreadElement) {
5965
- for (const argument of parameters) {
5966
- argument.include(context, false);
5967
- }
5968
- break;
6190
+ const { args } = interaction;
6191
+ let lastExplicitlyIncludedIndex = args.length - 1;
6192
+ // If there is a SpreadElement, we need to include all arguments after it
6193
+ // because we no longer know which argument corresponds to which parameter.
6194
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
6195
+ const argument = args[argumentIndex];
6196
+ if (argument instanceof SpreadElement && !argumentIncluded) {
6197
+ argumentIncluded = true;
6198
+ lastExplicitlyIncludedIndex = argumentIndex - 1;
6199
+ }
6200
+ if (argumentIncluded) {
6201
+ argument.includePath(UNKNOWN_PATH, context);
6202
+ argument.include(context, false);
5969
6203
  }
5970
6204
  }
5971
- for (let index = parameters.length - 1; index >= 0; index--) {
5972
- const parameterVariables = this.parameters[index] || restParameter;
5973
- const argument = parameters[index];
6205
+ // Now we go backwards either starting from the last argument or before the
6206
+ // first SpreadElement to ensure all arguments before are included as needed
6207
+ for (let index = lastExplicitlyIncludedIndex; index >= 1; index--) {
6208
+ const parameterVariables = this.parameters[index - 1] || restParameter;
6209
+ const argument = args[index];
5974
6210
  if (parameterVariables) {
5975
6211
  calledFromTryStatement = false;
5976
6212
  if (parameterVariables.length === 0) {
5977
- // handle empty destructuring
6213
+ // handle empty destructuring to avoid destructuring undefined
5978
6214
  argumentIncluded = true;
5979
6215
  }
5980
6216
  else {
5981
6217
  for (const variable of parameterVariables) {
5982
- if (variable.included) {
5983
- argumentIncluded = true;
5984
- }
5985
6218
  if (variable.calledFromTryStatement) {
5986
6219
  calledFromTryStatement = true;
5987
6220
  }
6221
+ if (variable.included) {
6222
+ argumentIncluded = true;
6223
+ if (calledFromTryStatement) {
6224
+ argument.include(context, true);
6225
+ }
6226
+ else {
6227
+ variable.includeArgumentPaths(argument, context);
6228
+ argument.include(context, false);
6229
+ }
6230
+ }
5988
6231
  }
5989
6232
  }
5990
6233
  }
5991
- if (!argumentIncluded && argument.shouldBeIncluded(context)) {
6234
+ if (!argument.included && (argumentIncluded || argument.shouldBeIncluded(context))) {
5992
6235
  argumentIncluded = true;
5993
- }
5994
- if (argumentIncluded) {
5995
6236
  argument.include(context, calledFromTryStatement);
5996
6237
  }
5997
6238
  }
@@ -6007,11 +6248,62 @@ class ReturnValueScope extends ParameterScope {
6007
6248
  addReturnExpression(expression) {
6008
6249
  this.returnExpressions.push(expression);
6009
6250
  }
6251
+ deoptimizeArgumentsOnCall(interaction) {
6252
+ const { parameters } = this;
6253
+ const { args } = interaction;
6254
+ let position = 0;
6255
+ for (; position < args.length - 1; position++) {
6256
+ // Only the "this" argument arg[0] can be null
6257
+ const argument = args[position + 1];
6258
+ if (argument instanceof SpreadElement) {
6259
+ // This deoptimizes the current and remaining parameters and arguments
6260
+ for (; position < parameters.length; position++) {
6261
+ args[position + 1]?.deoptimizePath(UNKNOWN_PATH);
6262
+ parameters[position].forEach(variable => variable.markReassigned());
6263
+ }
6264
+ break;
6265
+ }
6266
+ if (this.hasRest && position >= parameters.length - 1) {
6267
+ argument.deoptimizePath(UNKNOWN_PATH);
6268
+ }
6269
+ else {
6270
+ const variables = parameters[position];
6271
+ if (variables) {
6272
+ for (const variable of variables) {
6273
+ variable.addArgumentValue(argument);
6274
+ }
6275
+ }
6276
+ this.addArgumentToBeDeoptimized(argument);
6277
+ }
6278
+ }
6279
+ const nonRestParameterLength = this.hasRest ? parameters.length - 1 : parameters.length;
6280
+ for (; position < nonRestParameterLength; position++) {
6281
+ for (const variable of parameters[position]) {
6282
+ variable.addArgumentValue(UNDEFINED_EXPRESSION);
6283
+ }
6284
+ }
6285
+ }
6010
6286
  getReturnExpression() {
6011
6287
  if (this.returnExpression === null)
6012
6288
  this.updateReturnExpression();
6013
6289
  return this.returnExpression;
6014
6290
  }
6291
+ deoptimizeAllParameters() {
6292
+ for (const parameter of this.parameters) {
6293
+ for (const variable of parameter) {
6294
+ variable.deoptimizePath(UNKNOWN_PATH);
6295
+ variable.markReassigned();
6296
+ }
6297
+ }
6298
+ }
6299
+ reassignAllParameters() {
6300
+ for (const parameter of this.parameters) {
6301
+ for (const variable of parameter) {
6302
+ variable.markReassigned();
6303
+ }
6304
+ }
6305
+ }
6306
+ addArgumentToBeDeoptimized(_argument) { }
6015
6307
  updateReturnExpression() {
6016
6308
  if (this.returnExpressions.length === 1) {
6017
6309
  this.returnExpression = this.returnExpressions[0];
@@ -6027,24 +6319,30 @@ class ReturnValueScope extends ParameterScope {
6027
6319
 
6028
6320
  class FunctionScope extends ReturnValueScope {
6029
6321
  constructor(parent) {
6030
- const { context } = parent;
6031
6322
  super(parent, false);
6323
+ const { context } = parent;
6032
6324
  this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));
6033
6325
  this.variables.set('this', (this.thisVariable = new ThisVariable(context)));
6034
6326
  }
6035
6327
  findLexicalBoundary() {
6036
6328
  return this;
6037
6329
  }
6038
- includeCallArguments(context, parameters) {
6039
- super.includeCallArguments(context, parameters);
6330
+ includeCallArguments(context, interaction) {
6331
+ super.includeCallArguments(context, interaction);
6040
6332
  if (this.argumentsVariable.included) {
6041
- for (const argument of parameters) {
6042
- if (!argument.included) {
6333
+ const { args } = interaction;
6334
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
6335
+ const argument = args[argumentIndex];
6336
+ if (argument) {
6337
+ argument.includePath(UNKNOWN_PATH, context);
6043
6338
  argument.include(context, false);
6044
6339
  }
6045
6340
  }
6046
6341
  }
6047
6342
  }
6343
+ addArgumentToBeDeoptimized(argument) {
6344
+ this.argumentsVariable.addArgumentToBeDeoptimized(argument);
6345
+ }
6048
6346
  }
6049
6347
 
6050
6348
  class ExpressionStatement extends NodeBase {
@@ -6072,8 +6370,9 @@ class ExpressionStatement extends NodeBase {
6072
6370
  return this.parent.type !== Program$1;
6073
6371
  return super.shouldBeIncluded(context);
6074
6372
  }
6075
- applyDeoptimizations() { }
6076
6373
  }
6374
+ ExpressionStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
6375
+ ExpressionStatement.prototype.applyDeoptimizations = doNotDeoptimize;
6077
6376
 
6078
6377
  class BlockStatement extends NodeBase {
6079
6378
  get deoptimizeBody() {
@@ -6138,6 +6437,8 @@ class BlockStatement extends NodeBase {
6138
6437
  }
6139
6438
  }
6140
6439
  }
6440
+ BlockStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
6441
+ BlockStatement.prototype.applyDeoptimizations = doNotDeoptimize;
6141
6442
 
6142
6443
  class RestElement extends NodeBase {
6143
6444
  constructor() {
@@ -6147,9 +6448,12 @@ class RestElement extends NodeBase {
6147
6448
  addExportedVariables(variables, exportNamesByVariable) {
6148
6449
  this.argument.addExportedVariables(variables, exportNamesByVariable);
6149
6450
  }
6150
- declare(kind, init) {
6451
+ declare(kind, destructuredInitPath, init) {
6151
6452
  this.declarationInit = init;
6152
- return this.argument.declare(kind, UNKNOWN_EXPRESSION);
6453
+ return this.argument.declare(kind, getIncludedPatternPath$1(destructuredInitPath), init);
6454
+ }
6455
+ deoptimizeAssignment(destructuredInitPath, init) {
6456
+ this.argument.deoptimizeAssignment(getIncludedPatternPath$1(destructuredInitPath), init);
6153
6457
  }
6154
6458
  deoptimizePath(path) {
6155
6459
  if (path.length === 0) {
@@ -6160,6 +6464,20 @@ class RestElement extends NodeBase {
6160
6464
  return (path.length > 0 ||
6161
6465
  this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
6162
6466
  }
6467
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
6468
+ return this.argument.hasEffectsWhenDestructuring(context, getIncludedPatternPath$1(destructuredInitPath), init);
6469
+ }
6470
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
6471
+ return (this.included =
6472
+ this.argument.includeDestructuredIfNecessary(context, getIncludedPatternPath$1(destructuredInitPath), init) || this.included);
6473
+ }
6474
+ include(context, includeChildrenRecursively) {
6475
+ if (!this.included)
6476
+ this.includeNode(context);
6477
+ // This should just include the identifier, its properties should be
6478
+ // included where the variable is used.
6479
+ this.argument.include(context, includeChildrenRecursively);
6480
+ }
6163
6481
  markDeclarationReached() {
6164
6482
  this.argument.markDeclarationReached();
6165
6483
  }
@@ -6171,12 +6489,16 @@ class RestElement extends NodeBase {
6171
6489
  }
6172
6490
  }
6173
6491
  }
6492
+ RestElement.prototype.includeNode = onlyIncludeSelf;
6493
+ const getIncludedPatternPath$1 = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
6494
+ ? destructuredInitPath
6495
+ : [...destructuredInitPath, UnknownKey];
6174
6496
 
6175
6497
  class FunctionBase extends NodeBase {
6176
6498
  constructor() {
6177
6499
  super(...arguments);
6178
- this.objectEntity = null;
6179
6500
  this.parameterVariableValuesDeoptimized = false;
6501
+ this.includeCallArguments = this.scope.includeCallArguments.bind(this.scope);
6180
6502
  }
6181
6503
  get async() {
6182
6504
  return isFlagSet(this.flags, 256 /* Flag.async */);
@@ -6196,53 +6518,9 @@ class FunctionBase extends NodeBase {
6196
6518
  set generator(value) {
6197
6519
  this.flags = setFlag(this.flags, 4194304 /* Flag.generator */, value);
6198
6520
  }
6199
- updateParameterVariableValues(_arguments) {
6200
- for (let position = 0; position < this.params.length; position++) {
6201
- const parameter = this.params[position];
6202
- if (!(parameter instanceof Identifier)) {
6203
- continue;
6204
- }
6205
- const parameterVariable = parameter.variable;
6206
- const argument = _arguments[position + 1] ?? UNDEFINED_EXPRESSION;
6207
- parameterVariable.updateKnownValue(argument);
6208
- }
6209
- }
6210
- deoptimizeParameterVariableValues() {
6211
- for (const parameter of this.params) {
6212
- if (parameter instanceof Identifier) {
6213
- const parameterVariable = parameter.variable;
6214
- parameterVariable.markReassigned();
6215
- }
6216
- }
6217
- }
6218
6521
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6219
- if (interaction.type === INTERACTION_CALLED) {
6220
- const { parameters } = this.scope;
6221
- const { args } = interaction;
6222
- let hasRest = false;
6223
- for (let position = 0; position < args.length - 1; position++) {
6224
- const parameter = this.params[position];
6225
- // Only the "this" argument arg[0] can be null
6226
- const argument = args[position + 1];
6227
- if (argument instanceof SpreadElement) {
6228
- this.deoptimizeParameterVariableValues();
6229
- }
6230
- if (hasRest || parameter instanceof RestElement) {
6231
- hasRest = true;
6232
- argument.deoptimizePath(UNKNOWN_PATH);
6233
- }
6234
- else if (parameter instanceof Identifier) {
6235
- parameters[position][0].addEntityToBeDeoptimized(argument);
6236
- this.addArgumentToBeDeoptimized(argument);
6237
- }
6238
- else if (parameter) {
6239
- argument.deoptimizePath(UNKNOWN_PATH);
6240
- }
6241
- else {
6242
- this.addArgumentToBeDeoptimized(argument);
6243
- }
6244
- }
6245
- this.updateParameterVariableValues(args);
6522
+ if (interaction.type === INTERACTION_CALLED && path.length === 0) {
6523
+ this.scope.deoptimizeArgumentsOnCall(interaction);
6246
6524
  }
6247
6525
  else {
6248
6526
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -6254,12 +6532,7 @@ class FunctionBase extends NodeBase {
6254
6532
  // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
6255
6533
  // which means the return expression and parameters need to be reassigned
6256
6534
  this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
6257
- for (const parameterList of this.scope.parameters) {
6258
- for (const parameter of parameterList) {
6259
- parameter.deoptimizePath(UNKNOWN_PATH);
6260
- parameter.markReassigned();
6261
- }
6262
- }
6535
+ this.scope.deoptimizeAllParameters();
6263
6536
  }
6264
6537
  }
6265
6538
  getLiteralValueAtPath(path, recursionTracker, origin) {
@@ -6297,8 +6570,13 @@ class FunctionBase extends NodeBase {
6297
6570
  return true;
6298
6571
  }
6299
6572
  }
6300
- for (const parameter of this.params) {
6301
- if (parameter.hasEffects(context))
6573
+ const { propertyReadSideEffects } = this.scope.context.options
6574
+ .treeshake;
6575
+ for (let index = 0; index < this.params.length; index++) {
6576
+ const parameter = this.params[index];
6577
+ if (parameter.hasEffects(context) ||
6578
+ (propertyReadSideEffects &&
6579
+ parameter.hasEffectsWhenDestructuring(context, EMPTY_PATH, interaction.args[index + 1] || UNDEFINED_EXPRESSION)))
6302
6580
  return true;
6303
6581
  }
6304
6582
  return false;
@@ -6317,21 +6595,17 @@ class FunctionBase extends NodeBase {
6317
6595
  return variable?.getOnlyFunctionCallUsed() ?? false;
6318
6596
  }
6319
6597
  include(context, includeChildrenRecursively) {
6320
- if (!this.parameterVariableValuesDeoptimized && !this.onlyFunctionCallUsed()) {
6598
+ if (!this.included)
6599
+ this.includeNode(context);
6600
+ if (!(this.parameterVariableValuesDeoptimized || this.onlyFunctionCallUsed())) {
6321
6601
  this.parameterVariableValuesDeoptimized = true;
6322
- this.deoptimizeParameterVariableValues();
6602
+ this.scope.reassignAllParameters();
6323
6603
  }
6324
- if (!this.deoptimized)
6325
- this.applyDeoptimizations();
6326
- this.included = true;
6327
6604
  const { brokenFlow } = context;
6328
6605
  context.brokenFlow = false;
6329
6606
  this.body.include(context, includeChildrenRecursively);
6330
6607
  context.brokenFlow = brokenFlow;
6331
6608
  }
6332
- includeCallArguments(context, parameters) {
6333
- this.scope.includeCallArguments(context, parameters);
6334
- }
6335
6609
  initialise() {
6336
6610
  super.initialise();
6337
6611
  if (this.body instanceof BlockStatement) {
@@ -6353,14 +6627,14 @@ class FunctionBase extends NodeBase {
6353
6627
  // so that the scope already knows all parameters and can detect conflicts
6354
6628
  // when parsing the body.
6355
6629
  const parameters = (this.params = params.map((parameter) => new (context.getNodeConstructor(parameter.type))(this, scope).parseNode(parameter)));
6356
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
6630
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
6357
6631
  this.body = new (context.getNodeConstructor(body.type))(this, bodyScope).parseNode(body);
6358
6632
  return super.parseNode(esTreeNode);
6359
6633
  }
6360
- addArgumentToBeDeoptimized(_argument) { }
6361
- applyDeoptimizations() { }
6362
6634
  }
6363
6635
  FunctionBase.prototype.preventChildBlockScope = true;
6636
+ FunctionBase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
6637
+ FunctionBase.prototype.applyDeoptimizations = doNotDeoptimize;
6364
6638
 
6365
6639
  class FunctionNode extends FunctionBase {
6366
6640
  constructor() {
@@ -6372,18 +6646,16 @@ class FunctionNode extends FunctionBase {
6372
6646
  this.constructedEntity = new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE);
6373
6647
  // This makes sure that all deoptimizations of "this" are applied to the
6374
6648
  // constructed entity.
6375
- this.scope.thisVariable.addEntityToBeDeoptimized(this.constructedEntity);
6649
+ this.scope.thisVariable.addArgumentValue(this.constructedEntity);
6376
6650
  }
6377
6651
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6378
6652
  super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
6379
6653
  if (interaction.type === INTERACTION_CALLED && path.length === 0 && interaction.args[0]) {
6380
6654
  // args[0] is the "this" argument
6381
- this.scope.thisVariable.addEntityToBeDeoptimized(interaction.args[0]);
6655
+ this.scope.thisVariable.addArgumentValue(interaction.args[0]);
6382
6656
  }
6383
6657
  }
6384
6658
  hasEffects(context) {
6385
- if (!this.deoptimized)
6386
- this.applyDeoptimizations();
6387
6659
  if (this.annotationNoSideEffects) {
6388
6660
  return false;
6389
6661
  }
@@ -6421,7 +6693,7 @@ class FunctionNode extends FunctionBase {
6421
6693
  }
6422
6694
  include(context, includeChildrenRecursively) {
6423
6695
  super.include(context, includeChildrenRecursively);
6424
- this.id?.include();
6696
+ this.id?.include(context);
6425
6697
  const hasArguments = this.scope.argumentsVariable.included;
6426
6698
  for (const parameter of this.params) {
6427
6699
  if (!(parameter instanceof Identifier) || hasArguments) {
@@ -6429,12 +6701,18 @@ class FunctionNode extends FunctionBase {
6429
6701
  }
6430
6702
  }
6431
6703
  }
6704
+ includeNode(context) {
6705
+ this.included = true;
6706
+ const hasArguments = this.scope.argumentsVariable.included;
6707
+ for (const parameter of this.params) {
6708
+ if (!(parameter instanceof Identifier) || hasArguments) {
6709
+ parameter.includePath(UNKNOWN_PATH, context);
6710
+ }
6711
+ }
6712
+ }
6432
6713
  initialise() {
6433
6714
  super.initialise();
6434
- this.id?.declare('function', this);
6435
- }
6436
- addArgumentToBeDeoptimized(argument) {
6437
- this.scope.argumentsVariable.addArgumentToBeDeoptimized(argument);
6715
+ this.id?.declare('function', EMPTY_PATH, this);
6438
6716
  }
6439
6717
  getObjectEntity() {
6440
6718
  if (this.objectEntity !== null) {
@@ -6484,11 +6762,16 @@ function getFunctionIdInsertPosition(code, start) {
6484
6762
  }
6485
6763
  class ExportDefaultDeclaration extends NodeBase {
6486
6764
  include(context, includeChildrenRecursively) {
6487
- super.include(context, includeChildrenRecursively);
6765
+ this.included = true;
6766
+ this.declaration.include(context, includeChildrenRecursively);
6488
6767
  if (includeChildrenRecursively) {
6489
- this.scope.context.includeVariableInModule(this.variable);
6768
+ this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, context);
6490
6769
  }
6491
6770
  }
6771
+ includePath(path, context) {
6772
+ this.included = true;
6773
+ this.declaration.includePath(path, context);
6774
+ }
6492
6775
  initialise() {
6493
6776
  super.initialise();
6494
6777
  const declaration = this.declaration;
@@ -6533,7 +6816,6 @@ class ExportDefaultDeclaration extends NodeBase {
6533
6816
  }
6534
6817
  this.declaration.render(code, options);
6535
6818
  }
6536
- applyDeoptimizations() { }
6537
6819
  renderNamedDeclaration(code, declarationStart, idInsertPosition, options) {
6538
6820
  const { exportNamesByVariable, format, snippets: { getPropertyAccess } } = options;
6539
6821
  const name = this.variable.getName(getPropertyAccess);
@@ -6564,6 +6846,8 @@ class ExportDefaultDeclaration extends NodeBase {
6564
6846
  }
6565
6847
  }
6566
6848
  ExportDefaultDeclaration.prototype.needsBoundaries = true;
6849
+ ExportDefaultDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
6850
+ ExportDefaultDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
6567
6851
 
6568
6852
  const needsEscapeRegEx = /[\n\r'\\\u2028\u2029]/;
6569
6853
  const quoteNewlineRegEx = /([\n\r'\u2028\u2029])/g;
@@ -6833,6 +7117,7 @@ class Literal extends NodeBase {
6833
7117
  }
6834
7118
  }
6835
7119
  }
7120
+ Literal.prototype.includeNode = onlyIncludeSelf;
6836
7121
 
6837
7122
  function getChainElementLiteralValueAtPath(element, object, path, recursionTracker, origin) {
6838
7123
  if ('getLiteralValueAtPathAsChainElement' in object) {
@@ -6848,8 +7133,6 @@ function getChainElementLiteralValueAtPath(element, object, path, recursionTrack
6848
7133
  return element.getLiteralValueAtPath(path, recursionTracker, origin);
6849
7134
  }
6850
7135
 
6851
- // To avoid infinite recursions
6852
- const MAX_PATH_DEPTH = 7;
6853
7136
  function getResolvablePropertyKey(memberExpression) {
6854
7137
  return memberExpression.computed
6855
7138
  ? getResolvableComputedPropertyKey(memberExpression.property)
@@ -6948,18 +7231,27 @@ class MemberExpression extends NodeBase {
6948
7231
  }
6949
7232
  else if (!this.isUndefined) {
6950
7233
  if (path.length < MAX_PATH_DEPTH) {
6951
- this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.getPropertyKey(), ...path], recursionTracker);
7234
+ this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, this.propertyKey === UnknownKey ? UNKNOWN_PATH : [this.propertyKey, ...path], recursionTracker);
6952
7235
  }
6953
7236
  else {
6954
7237
  deoptimizeInteraction(interaction);
6955
7238
  }
6956
7239
  }
6957
7240
  }
7241
+ deoptimizeAssignment(destructuredInitPath, init) {
7242
+ this.deoptimizePath(EMPTY_PATH);
7243
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
7244
+ }
6958
7245
  deoptimizeCache() {
7246
+ if (this.propertyKey === this.dynamicPropertyKey)
7247
+ return;
6959
7248
  const { expressionsToBeDeoptimized, object } = this;
6960
7249
  this.expressionsToBeDeoptimized = EMPTY_ARRAY;
6961
- this.propertyKey = UnknownKey;
7250
+ this.dynamicPropertyKey = this.propertyKey;
6962
7251
  object.deoptimizePath(UNKNOWN_PATH);
7252
+ if (this.included) {
7253
+ object.includePath(UNKNOWN_PATH, createInclusionContext());
7254
+ }
6963
7255
  for (const expression of expressionsToBeDeoptimized) {
6964
7256
  expression.deoptimizeCache();
6965
7257
  }
@@ -6970,11 +7262,13 @@ class MemberExpression extends NodeBase {
6970
7262
  if (this.variable) {
6971
7263
  this.variable.deoptimizePath(path);
6972
7264
  }
6973
- else if (!this.isUndefined && path.length < MAX_PATH_DEPTH) {
6974
- const propertyKey = this.getPropertyKey();
7265
+ else if (!this.isUndefined) {
7266
+ const { propertyKey } = this;
6975
7267
  this.object.deoptimizePath([
6976
7268
  propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey,
6977
- ...path
7269
+ ...(path.length < MAX_PATH_DEPTH
7270
+ ? path
7271
+ : [...path.slice(0, MAX_PATH_DEPTH), UnknownKey])
6978
7272
  ]);
6979
7273
  }
6980
7274
  }
@@ -6985,9 +7279,11 @@ class MemberExpression extends NodeBase {
6985
7279
  if (this.isUndefined) {
6986
7280
  return undefined;
6987
7281
  }
6988
- if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
6989
- this.expressionsToBeDeoptimized.push(origin);
6990
- return this.object.getLiteralValueAtPath([this.getPropertyKey(), ...path], recursionTracker, origin);
7282
+ const propertyKey = this.getDynamicPropertyKey();
7283
+ if (propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
7284
+ if (propertyKey !== this.propertyKey)
7285
+ this.expressionsToBeDeoptimized.push(origin);
7286
+ return this.object.getLiteralValueAtPath([propertyKey, ...path], recursionTracker, origin);
6991
7287
  }
6992
7288
  return UnknownValue;
6993
7289
  }
@@ -7007,9 +7303,11 @@ class MemberExpression extends NodeBase {
7007
7303
  if (this.isUndefined) {
7008
7304
  return [UNDEFINED_EXPRESSION, false];
7009
7305
  }
7010
- if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
7011
- this.expressionsToBeDeoptimized.push(origin);
7012
- return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin);
7306
+ const propertyKey = this.getDynamicPropertyKey();
7307
+ if (propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
7308
+ if (propertyKey !== this.propertyKey)
7309
+ this.expressionsToBeDeoptimized.push(origin);
7310
+ return this.object.getReturnExpressionWhenCalledAtPath([propertyKey, ...path], interaction, recursionTracker, origin);
7013
7311
  }
7014
7312
  return UNKNOWN_RETURN_EXPRESSION;
7015
7313
  }
@@ -7055,14 +7353,45 @@ class MemberExpression extends NodeBase {
7055
7353
  return true;
7056
7354
  }
7057
7355
  if (path.length < MAX_PATH_DEPTH) {
7058
- return this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey(), ...path], interaction, context);
7356
+ return this.object.hasEffectsOnInteractionAtPath([this.getDynamicPropertyKey(), ...path], interaction, context);
7059
7357
  }
7060
7358
  return true;
7061
7359
  }
7360
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
7361
+ return (destructuredInitPath.length > 0 &&
7362
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
7363
+ }
7062
7364
  include(context, includeChildrenRecursively) {
7365
+ if (!this.included)
7366
+ this.includeNode(context);
7367
+ this.object.include(context, includeChildrenRecursively);
7368
+ this.property.include(context, includeChildrenRecursively);
7369
+ }
7370
+ includeNode(context) {
7371
+ this.included = true;
7063
7372
  if (!this.deoptimized)
7064
7373
  this.applyDeoptimizations();
7065
- this.includeProperties(context, includeChildrenRecursively);
7374
+ if (this.variable) {
7375
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
7376
+ }
7377
+ else if (!this.isUndefined) {
7378
+ this.object.includePath([this.propertyKey], context);
7379
+ }
7380
+ }
7381
+ includePath(path, context) {
7382
+ if (!this.included)
7383
+ this.includeNode(context);
7384
+ if (this.variable) {
7385
+ this.variable?.includePath(path, context);
7386
+ }
7387
+ else if (!this.isUndefined) {
7388
+ this.object.includePath([
7389
+ this.propertyKey,
7390
+ ...(path.length < MAX_PATH_DEPTH
7391
+ ? path
7392
+ : [...path.slice(0, MAX_PATH_DEPTH), UnknownKey])
7393
+ ], context);
7394
+ }
7066
7395
  }
7067
7396
  includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {
7068
7397
  if (!this.assignmentDeoptimized)
@@ -7071,20 +7400,34 @@ class MemberExpression extends NodeBase {
7071
7400
  this.include(context, includeChildrenRecursively);
7072
7401
  }
7073
7402
  else {
7074
- this.includeProperties(context, includeChildrenRecursively);
7403
+ if (!this.included)
7404
+ this.includeNode(context);
7405
+ this.object.include(context, includeChildrenRecursively);
7406
+ this.property.include(context, includeChildrenRecursively);
7075
7407
  }
7076
7408
  }
7077
- includeCallArguments(context, parameters) {
7409
+ includeCallArguments(context, interaction) {
7078
7410
  if (this.variable) {
7079
- this.variable.includeCallArguments(context, parameters);
7411
+ this.variable.includeCallArguments(context, interaction);
7080
7412
  }
7081
7413
  else {
7082
- super.includeCallArguments(context, parameters);
7414
+ super.includeCallArguments(context, interaction);
7415
+ }
7416
+ }
7417
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
7418
+ if ((this.included ||=
7419
+ destructuredInitPath.length > 0 &&
7420
+ !context.brokenFlow &&
7421
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext()))) {
7422
+ init.include(context, false);
7423
+ return true;
7083
7424
  }
7425
+ return false;
7084
7426
  }
7085
7427
  initialise() {
7086
7428
  super.initialise();
7087
- this.propertyKey = getResolvablePropertyKey(this);
7429
+ this.dynamicPropertyKey = getResolvablePropertyKey(this);
7430
+ this.propertyKey = this.dynamicPropertyKey === null ? UnknownKey : this.dynamicPropertyKey;
7088
7431
  this.accessInteraction = { args: [this.object], type: INTERACTION_ACCESSED };
7089
7432
  }
7090
7433
  render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = BLANK) {
@@ -7121,8 +7464,7 @@ class MemberExpression extends NodeBase {
7121
7464
  this.bound &&
7122
7465
  propertyReadSideEffects &&
7123
7466
  !(this.variable || this.isUndefined)) {
7124
- const propertyKey = this.getPropertyKey();
7125
- this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER);
7467
+ this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [this.propertyKey], SHARED_RECURSION_TRACKER);
7126
7468
  this.scope.context.requestTreeshakingPass();
7127
7469
  }
7128
7470
  if (this.variable) {
@@ -7139,7 +7481,7 @@ class MemberExpression extends NodeBase {
7139
7481
  this.bound &&
7140
7482
  propertyReadSideEffects &&
7141
7483
  !(this.variable || this.isUndefined)) {
7142
- this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.getPropertyKey()], SHARED_RECURSION_TRACKER);
7484
+ this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.propertyKey], SHARED_RECURSION_TRACKER);
7143
7485
  this.scope.context.requestTreeshakingPass();
7144
7486
  }
7145
7487
  }
@@ -7148,24 +7490,24 @@ class MemberExpression extends NodeBase {
7148
7490
  const variable = this.scope.findVariable(this.object.name);
7149
7491
  if (variable.isNamespace) {
7150
7492
  if (this.variable) {
7151
- this.scope.context.includeVariableInModule(this.variable);
7493
+ this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, createInclusionContext());
7152
7494
  }
7153
7495
  this.scope.context.log(LOGLEVEL_WARN, logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);
7154
7496
  }
7155
7497
  }
7156
7498
  }
7157
- getPropertyKey() {
7158
- if (this.propertyKey === null) {
7159
- this.propertyKey = UnknownKey;
7499
+ getDynamicPropertyKey() {
7500
+ if (this.dynamicPropertyKey === null) {
7501
+ this.dynamicPropertyKey = this.propertyKey;
7160
7502
  const value = this.property.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
7161
- return (this.propertyKey =
7503
+ return (this.dynamicPropertyKey =
7162
7504
  value === SymbolToStringTag
7163
7505
  ? value
7164
7506
  : typeof value === 'symbol'
7165
7507
  ? UnknownKey
7166
7508
  : String(value));
7167
7509
  }
7168
- return this.propertyKey;
7510
+ return this.dynamicPropertyKey;
7169
7511
  }
7170
7512
  hasAccessEffect(context) {
7171
7513
  const { propertyReadSideEffects } = this.scope.context.options
@@ -7173,17 +7515,7 @@ class MemberExpression extends NodeBase {
7173
7515
  return (!(this.variable || this.isUndefined) &&
7174
7516
  propertyReadSideEffects &&
7175
7517
  (propertyReadSideEffects === 'always' ||
7176
- this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));
7177
- }
7178
- includeProperties(context, includeChildrenRecursively) {
7179
- if (!this.included) {
7180
- this.included = true;
7181
- if (this.variable) {
7182
- this.scope.context.includeVariableInModule(this.variable);
7183
- }
7184
- }
7185
- this.object.include(context, includeChildrenRecursively);
7186
- this.property.include(context, includeChildrenRecursively);
7518
+ this.object.hasEffectsOnInteractionAtPath([this.getDynamicPropertyKey()], this.accessInteraction, context)));
7187
7519
  }
7188
7520
  }
7189
7521
  function resolveNamespaceVariables(baseVariable, path, astContext) {
@@ -7227,18 +7559,20 @@ class MetaProperty extends NodeBase {
7227
7559
  return path.length > 1 || type !== INTERACTION_ACCESSED;
7228
7560
  }
7229
7561
  include() {
7230
- if (!this.included) {
7231
- this.included = true;
7232
- if (this.meta.name === IMPORT) {
7233
- this.scope.context.addImportMeta(this);
7234
- const parent = this.parent;
7235
- const metaProperty = (this.metaProperty =
7236
- parent instanceof MemberExpression && typeof parent.propertyKey === 'string'
7237
- ? parent.propertyKey
7238
- : null);
7239
- if (metaProperty?.startsWith(FILE_PREFIX)) {
7240
- this.referenceId = metaProperty.slice(FILE_PREFIX.length);
7241
- }
7562
+ if (!this.included)
7563
+ this.includeNode();
7564
+ }
7565
+ includeNode() {
7566
+ this.included = true;
7567
+ if (this.meta.name === IMPORT) {
7568
+ this.scope.context.addImportMeta(this);
7569
+ const parent = this.parent;
7570
+ const metaProperty = (this.metaProperty =
7571
+ parent instanceof MemberExpression && typeof parent.propertyKey === 'string'
7572
+ ? parent.propertyKey
7573
+ : null);
7574
+ if (metaProperty?.startsWith(FILE_PREFIX)) {
7575
+ this.referenceId = metaProperty.slice(FILE_PREFIX.length);
7242
7576
  }
7243
7577
  }
7244
7578
  }
@@ -7345,7 +7679,7 @@ class UndefinedVariable extends Variable {
7345
7679
 
7346
7680
  class ExportDefaultVariable extends LocalVariable {
7347
7681
  constructor(name, exportDefaultDeclaration, context) {
7348
- super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');
7682
+ super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, EMPTY_PATH, context, 'other');
7349
7683
  this.hasId = false;
7350
7684
  this.originalId = null;
7351
7685
  this.originalVariable = null;
@@ -7494,8 +7828,8 @@ class NamespaceVariable extends Variable {
7494
7828
  return (!memberVariable ||
7495
7829
  memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));
7496
7830
  }
7497
- include() {
7498
- super.include();
7831
+ includePath(path, context) {
7832
+ super.includePath(path, context);
7499
7833
  this.context.includeAllExports();
7500
7834
  }
7501
7835
  prepare(accessedGlobalsByScope) {
@@ -7588,9 +7922,9 @@ class SyntheticNamedExportVariable extends Variable {
7588
7922
  getName(getPropertyAccess) {
7589
7923
  return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;
7590
7924
  }
7591
- include() {
7592
- super.include();
7593
- this.context.includeVariableInModule(this.syntheticNamespace);
7925
+ includePath(path, context) {
7926
+ super.includePath(path, context);
7927
+ this.context.includeVariableInModule(this.syntheticNamespace, path, context);
7594
7928
  }
7595
7929
  setRenderNames(baseName, name) {
7596
7930
  super.setRenderNames(baseName, name);
@@ -10789,21 +11123,37 @@ class ArrayPattern extends NodeBase {
10789
11123
  element?.addExportedVariables(variables, exportNamesByVariable);
10790
11124
  }
10791
11125
  }
10792
- declare(kind) {
11126
+ declare(kind, destructuredInitPath, init) {
10793
11127
  const variables = [];
11128
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
10794
11129
  for (const element of this.elements) {
10795
11130
  if (element !== null) {
10796
- variables.push(...element.declare(kind, UNKNOWN_EXPRESSION));
11131
+ variables.push(...element.declare(kind, includedPatternPath, init));
10797
11132
  }
10798
11133
  }
10799
11134
  return variables;
10800
11135
  }
11136
+ deoptimizeAssignment(destructuredInitPath, init) {
11137
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
11138
+ for (const element of this.elements) {
11139
+ element?.deoptimizeAssignment(includedPatternPath, init);
11140
+ }
11141
+ }
10801
11142
  // Patterns can only be deoptimized at the empty path at the moment
10802
11143
  deoptimizePath() {
10803
11144
  for (const element of this.elements) {
10804
11145
  element?.deoptimizePath(EMPTY_PATH);
10805
11146
  }
10806
11147
  }
11148
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
11149
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
11150
+ for (const element of this.elements) {
11151
+ if (element?.hasEffectsWhenDestructuring(context, includedPatternPath, init)) {
11152
+ return true;
11153
+ }
11154
+ }
11155
+ return false;
11156
+ }
10807
11157
  // Patterns are only checked at the empty path at the moment
10808
11158
  hasEffectsOnInteractionAtPath(_path, interaction, context) {
10809
11159
  for (const element of this.elements) {
@@ -10812,12 +11162,38 @@ class ArrayPattern extends NodeBase {
10812
11162
  }
10813
11163
  return false;
10814
11164
  }
11165
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11166
+ let included = false;
11167
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
11168
+ for (const element of this.elements) {
11169
+ if (element) {
11170
+ element.included ||= included;
11171
+ included =
11172
+ element.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
11173
+ }
11174
+ }
11175
+ if (included) {
11176
+ // This is necessary so that if any pattern element is included, all are
11177
+ // included for proper deconflicting
11178
+ for (const element of this.elements) {
11179
+ if (element && !element.included) {
11180
+ element.included = true;
11181
+ element.includeDestructuredIfNecessary(context, includedPatternPath, init);
11182
+ }
11183
+ }
11184
+ }
11185
+ return (this.included ||= included);
11186
+ }
10815
11187
  markDeclarationReached() {
10816
11188
  for (const element of this.elements) {
10817
11189
  element?.markDeclarationReached();
10818
11190
  }
10819
11191
  }
10820
11192
  }
11193
+ ArrayPattern.prototype.includeNode = onlyIncludeSelf;
11194
+ const getIncludedPatternPath = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
11195
+ ? destructuredInitPath
11196
+ : [...destructuredInitPath, UnknownInteger];
10821
11197
 
10822
11198
  class ArrowFunctionExpression extends FunctionBase {
10823
11199
  constructor() {
@@ -10834,8 +11210,6 @@ class ArrowFunctionExpression extends FunctionBase {
10834
11210
  this.scope = new ReturnValueScope(parentScope, false);
10835
11211
  }
10836
11212
  hasEffects() {
10837
- if (!this.deoptimized)
10838
- this.applyDeoptimizations();
10839
11213
  return false;
10840
11214
  }
10841
11215
  hasEffectsOnInteractionAtPath(path, interaction, context) {
@@ -10874,6 +11248,15 @@ class ArrowFunctionExpression extends FunctionBase {
10874
11248
  }
10875
11249
  }
10876
11250
  }
11251
+ includeNode(context) {
11252
+ this.included = true;
11253
+ this.body.includePath(UNKNOWN_PATH, context);
11254
+ for (const parameter of this.params) {
11255
+ if (!(parameter instanceof Identifier)) {
11256
+ parameter.includePath(UNKNOWN_PATH, context);
11257
+ }
11258
+ }
11259
+ }
10877
11260
  getObjectEntity() {
10878
11261
  if (this.objectEntity !== null) {
10879
11262
  return this.objectEntity;
@@ -10893,13 +11276,18 @@ class ObjectPattern extends NodeBase {
10893
11276
  }
10894
11277
  }
10895
11278
  }
10896
- declare(kind, init) {
11279
+ declare(kind, destructuredInitPath, init) {
10897
11280
  const variables = [];
10898
11281
  for (const property of this.properties) {
10899
- variables.push(...property.declare(kind, init));
11282
+ variables.push(...property.declare(kind, destructuredInitPath, init));
10900
11283
  }
10901
11284
  return variables;
10902
11285
  }
11286
+ deoptimizeAssignment(destructuredInitPath, init) {
11287
+ for (const property of this.properties) {
11288
+ property.deoptimizeAssignment(destructuredInitPath, init);
11289
+ }
11290
+ }
10903
11291
  deoptimizePath(path) {
10904
11292
  if (path.length === 0) {
10905
11293
  for (const property of this.properties) {
@@ -10917,12 +11305,46 @@ class ObjectPattern extends NodeBase {
10917
11305
  }
10918
11306
  return false;
10919
11307
  }
11308
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
11309
+ for (const property of this.properties) {
11310
+ if (property.hasEffectsWhenDestructuring(context, destructuredInitPath, init))
11311
+ return true;
11312
+ }
11313
+ return false;
11314
+ }
11315
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11316
+ let included = false;
11317
+ for (const property of this.properties) {
11318
+ included =
11319
+ property.includeDestructuredIfNecessary(context, destructuredInitPath, init) || included;
11320
+ }
11321
+ return (this.included ||= included);
11322
+ }
10920
11323
  markDeclarationReached() {
10921
11324
  for (const property of this.properties) {
10922
11325
  property.markDeclarationReached();
10923
11326
  }
10924
11327
  }
11328
+ render(code, options) {
11329
+ if (this.properties.length > 0) {
11330
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
11331
+ let lastSeparatorPos = null;
11332
+ for (const { node, separator, start, end } of separatedNodes) {
11333
+ if (!node.included) {
11334
+ treeshakeNode(node, code, start, end);
11335
+ continue;
11336
+ }
11337
+ lastSeparatorPos = separator;
11338
+ node.render(code, options);
11339
+ }
11340
+ if (lastSeparatorPos) {
11341
+ code.remove(lastSeparatorPos, this.end - 1);
11342
+ }
11343
+ }
11344
+ }
10925
11345
  }
11346
+ ObjectPattern.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
11347
+ ObjectPattern.prototype.applyDeoptimizations = doNotDeoptimize;
10926
11348
 
10927
11349
  class AssignmentExpression extends NodeBase {
10928
11350
  hasEffects(context) {
@@ -10931,7 +11353,9 @@ class AssignmentExpression extends NodeBase {
10931
11353
  this.applyDeoptimizations();
10932
11354
  // MemberExpressions do not access the property before assignments if the
10933
11355
  // operator is '='.
10934
- return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '='));
11356
+ return (right.hasEffects(context) ||
11357
+ left.hasEffectsAsAssignmentTarget(context, operator !== '=') ||
11358
+ this.left.hasEffectsWhenDestructuring?.(context, EMPTY_PATH, right));
10935
11359
  }
10936
11360
  hasEffectsOnInteractionAtPath(path, interaction, context) {
10937
11361
  return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);
@@ -10940,15 +11364,24 @@ class AssignmentExpression extends NodeBase {
10940
11364
  const { deoptimized, left, right, operator } = this;
10941
11365
  if (!deoptimized)
10942
11366
  this.applyDeoptimizations();
10943
- this.included = true;
11367
+ if (!this.included)
11368
+ this.includeNode(context);
11369
+ const hasEffectsContext = createHasEffectsContext();
10944
11370
  if (includeChildrenRecursively ||
10945
11371
  operator !== '=' ||
10946
11372
  left.included ||
10947
- left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {
11373
+ left.hasEffectsAsAssignmentTarget(hasEffectsContext, false) ||
11374
+ left.hasEffectsWhenDestructuring?.(hasEffectsContext, EMPTY_PATH, right)) {
10948
11375
  left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');
10949
11376
  }
10950
11377
  right.include(context, includeChildrenRecursively);
10951
11378
  }
11379
+ includeNode(context) {
11380
+ this.included = true;
11381
+ if (!this.deoptimized)
11382
+ this.applyDeoptimizations();
11383
+ this.right.includePath(UNKNOWN_PATH, context);
11384
+ }
10952
11385
  initialise() {
10953
11386
  super.initialise();
10954
11387
  if (this.left instanceof Identifier) {
@@ -11009,8 +11442,7 @@ class AssignmentExpression extends NodeBase {
11009
11442
  }
11010
11443
  applyDeoptimizations() {
11011
11444
  this.deoptimized = true;
11012
- this.left.deoptimizePath(EMPTY_PATH);
11013
- this.right.deoptimizePath(UNKNOWN_PATH);
11445
+ this.left.deoptimizeAssignment(EMPTY_PATH, this.right);
11014
11446
  this.scope.context.requestTreeshakingPass();
11015
11447
  }
11016
11448
  }
@@ -11019,8 +11451,11 @@ class AssignmentPattern extends NodeBase {
11019
11451
  addExportedVariables(variables, exportNamesByVariable) {
11020
11452
  this.left.addExportedVariables(variables, exportNamesByVariable);
11021
11453
  }
11022
- declare(kind, init) {
11023
- return this.left.declare(kind, init);
11454
+ declare(kind, destructuredInitPath, init) {
11455
+ return this.left.declare(kind, destructuredInitPath, init);
11456
+ }
11457
+ deoptimizeAssignment(destructuredInitPath, init) {
11458
+ this.left.deoptimizeAssignment(destructuredInitPath, init);
11024
11459
  }
11025
11460
  deoptimizePath(path) {
11026
11461
  if (path.length === 0) {
@@ -11030,6 +11465,29 @@ class AssignmentPattern extends NodeBase {
11030
11465
  hasEffectsOnInteractionAtPath(path, interaction, context) {
11031
11466
  return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
11032
11467
  }
11468
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
11469
+ return this.left.hasEffectsWhenDestructuring(context, destructuredInitPath, init);
11470
+ }
11471
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
11472
+ let included = this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init) ||
11473
+ this.included;
11474
+ if ((included ||= this.right.shouldBeIncluded(context))) {
11475
+ this.right.include(context, false);
11476
+ if (!this.left.included) {
11477
+ this.left.included = true;
11478
+ // Unfortunately, we need to include the left side again now, so that
11479
+ // any declared variables are properly included.
11480
+ this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init);
11481
+ }
11482
+ }
11483
+ return (this.included = included);
11484
+ }
11485
+ includeNode(context) {
11486
+ this.included = true;
11487
+ if (!this.deoptimized)
11488
+ this.applyDeoptimizations();
11489
+ this.right.includePath(UNKNOWN_PATH, context);
11490
+ }
11033
11491
  markDeclarationReached() {
11034
11492
  this.left.markDeclarationReached();
11035
11493
  }
@@ -11052,22 +11510,34 @@ class AwaitExpression extends NodeBase {
11052
11510
  return true;
11053
11511
  }
11054
11512
  include(context, includeChildrenRecursively) {
11513
+ if (!this.included)
11514
+ this.includeNode(context);
11515
+ this.argument.include(context, includeChildrenRecursively);
11516
+ }
11517
+ includeNode(context) {
11518
+ this.included = true;
11055
11519
  if (!this.deoptimized)
11056
11520
  this.applyDeoptimizations();
11057
- if (!this.included) {
11058
- this.included = true;
11059
- checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) {
11060
- let parent = this.parent;
11061
- do {
11062
- if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression)
11063
- break checkTopLevelAwait;
11064
- } while ((parent = parent.parent));
11065
- this.scope.context.usesTopLevelAwait = true;
11066
- }
11521
+ checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) {
11522
+ let parent = this.parent;
11523
+ do {
11524
+ if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression)
11525
+ break checkTopLevelAwait;
11526
+ } while ((parent = parent.parent));
11527
+ this.scope.context.usesTopLevelAwait = true;
11067
11528
  }
11068
- this.argument.include(context, includeChildrenRecursively);
11529
+ // Thenables need to be included
11530
+ this.argument.includePath(THEN_PATH, context);
11531
+ }
11532
+ includePath(path, context) {
11533
+ if (!this.deoptimized)
11534
+ this.applyDeoptimizations();
11535
+ if (!this.included)
11536
+ this.includeNode(context);
11537
+ this.argument.includePath(path, context);
11069
11538
  }
11070
11539
  }
11540
+ const THEN_PATH = ['then'];
11071
11541
 
11072
11542
  const binaryOperators = {
11073
11543
  '!=': (left, right) => left != right,
@@ -11131,6 +11601,8 @@ class BinaryExpression extends NodeBase {
11131
11601
  this.right.render(code, options);
11132
11602
  }
11133
11603
  }
11604
+ BinaryExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
11605
+ BinaryExpression.prototype.applyDeoptimizations = doNotDeoptimize;
11134
11606
 
11135
11607
  class BreakStatement extends NodeBase {
11136
11608
  hasEffects(context) {
@@ -11150,7 +11622,7 @@ class BreakStatement extends NodeBase {
11150
11622
  include(context) {
11151
11623
  this.included = true;
11152
11624
  if (this.label) {
11153
- this.label.include();
11625
+ this.label.include(context);
11154
11626
  context.includedLabels.add(this.label.name);
11155
11627
  }
11156
11628
  else {
@@ -11159,6 +11631,8 @@ class BreakStatement extends NodeBase {
11159
11631
  context.brokenFlow = true;
11160
11632
  }
11161
11633
  }
11634
+ BreakStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
11635
+ BreakStatement.prototype.applyDeoptimizations = doNotDeoptimize;
11162
11636
 
11163
11637
  function renderCallArguments(code, options, node) {
11164
11638
  if (node.arguments.length > 0) {
@@ -11345,8 +11819,6 @@ class CallExpression extends CallExpressionBase {
11345
11819
  this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)));
11346
11820
  }
11347
11821
  include(context, includeChildrenRecursively) {
11348
- if (!this.deoptimized)
11349
- this.applyDeoptimizations();
11350
11822
  if (includeChildrenRecursively) {
11351
11823
  super.include(context, includeChildrenRecursively);
11352
11824
  if (includeChildrenRecursively === INCLUDE_PARAMETERS &&
@@ -11356,10 +11828,26 @@ class CallExpression extends CallExpressionBase {
11356
11828
  }
11357
11829
  }
11358
11830
  else {
11359
- this.included = true;
11360
- this.callee.include(context, false);
11831
+ if (!this.included)
11832
+ this.includeNode(context);
11833
+ // If the callee is a member expression and does not have a variable, its
11834
+ // object will already be included via the first argument of the
11835
+ // interaction in includeCallArguments. Including it again can lead to
11836
+ // severe performance problems.
11837
+ if (this.callee instanceof MemberExpression && !this.callee.variable) {
11838
+ this.callee.property.include(context, false);
11839
+ }
11840
+ else {
11841
+ this.callee.include(context, false);
11842
+ }
11843
+ this.callee.includeCallArguments(context, this.interaction);
11361
11844
  }
11362
- this.callee.includeCallArguments(context, this.arguments);
11845
+ }
11846
+ includeNode(context) {
11847
+ this.included = true;
11848
+ if (!this.deoptimized)
11849
+ this.applyDeoptimizations();
11850
+ this.callee.includePath(UNKNOWN_PATH, context);
11363
11851
  }
11364
11852
  initialise() {
11365
11853
  super.initialise();
@@ -11398,13 +11886,14 @@ class CatchClause extends NodeBase {
11398
11886
  this.type = type;
11399
11887
  if (param) {
11400
11888
  this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);
11401
- this.param.declare('parameter', UNKNOWN_EXPRESSION);
11889
+ this.param.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
11402
11890
  }
11403
11891
  this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);
11404
11892
  return super.parseNode(esTreeNode);
11405
11893
  }
11406
11894
  }
11407
11895
  CatchClause.prototype.preventChildBlockScope = true;
11896
+ CatchClause.prototype.includeNode = onlyIncludeSelf;
11408
11897
 
11409
11898
  class ChainExpression extends NodeBase {
11410
11899
  // deoptimizations are not relevant as we are not caching values
@@ -11416,17 +11905,22 @@ class ChainExpression extends NodeBase {
11416
11905
  hasEffects(context) {
11417
11906
  return this.expression.hasEffectsAsChainElement(context) === true;
11418
11907
  }
11908
+ includePath(path, context) {
11909
+ this.included = true;
11910
+ this.expression.includePath(path, context);
11911
+ }
11419
11912
  removeAnnotations(code) {
11420
11913
  this.expression.removeAnnotations(code);
11421
11914
  }
11422
- applyDeoptimizations() { }
11423
11915
  }
11916
+ ChainExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
11917
+ ChainExpression.prototype.applyDeoptimizations = doNotDeoptimize;
11424
11918
 
11425
11919
  class ClassBodyScope extends ChildScope {
11426
11920
  constructor(parent, classNode) {
11427
11921
  const { context } = parent;
11428
11922
  super(parent, context);
11429
- this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));
11923
+ this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, EMPTY_PATH, context, 'other')));
11430
11924
  this.instanceScope = new ChildScope(this, context);
11431
11925
  this.instanceScope.variables.set('this', new ThisVariable(context));
11432
11926
  }
@@ -11441,7 +11935,7 @@ class ClassBody extends NodeBase {
11441
11935
  }
11442
11936
  include(context, includeChildrenRecursively) {
11443
11937
  this.included = true;
11444
- this.scope.context.includeVariableInModule(this.scope.thisVariable);
11938
+ this.scope.context.includeVariableInModule(this.scope.thisVariable, UNKNOWN_PATH, context);
11445
11939
  for (const definition of this.body) {
11446
11940
  definition.include(context, includeChildrenRecursively);
11447
11941
  }
@@ -11454,8 +11948,9 @@ class ClassBody extends NodeBase {
11454
11948
  }
11455
11949
  return super.parseNode(esTreeNode);
11456
11950
  }
11457
- applyDeoptimizations() { }
11458
11951
  }
11952
+ ClassBody.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
11953
+ ClassBody.prototype.applyDeoptimizations = doNotDeoptimize;
11459
11954
 
11460
11955
  class ClassExpression extends ClassNode {
11461
11956
  render(code, options, { renderedSurroundingElement } = BLANK) {
@@ -11513,6 +12008,9 @@ class ConditionalExpression extends NodeBase {
11513
12008
  const unusedBranch = this.usedBranch === this.consequent ? this.alternate : this.consequent;
11514
12009
  this.usedBranch = null;
11515
12010
  unusedBranch.deoptimizePath(UNKNOWN_PATH);
12011
+ if (this.included) {
12012
+ unusedBranch.includePath(UNKNOWN_PATH, createInclusionContext());
12013
+ }
11516
12014
  const { expressionsToBeDeoptimized } = this;
11517
12015
  this.expressionsToBeDeoptimized = EMPTY_ARRAY;
11518
12016
  for (const expression of expressionsToBeDeoptimized) {
@@ -11570,7 +12068,7 @@ class ConditionalExpression extends NodeBase {
11570
12068
  include(context, includeChildrenRecursively) {
11571
12069
  this.included = true;
11572
12070
  const usedBranch = this.getUsedBranch();
11573
- if (includeChildrenRecursively || this.test.shouldBeIncluded(context) || usedBranch === null) {
12071
+ if (usedBranch === null || includeChildrenRecursively || this.test.shouldBeIncluded(context)) {
11574
12072
  this.test.include(context, includeChildrenRecursively);
11575
12073
  this.consequent.include(context, includeChildrenRecursively);
11576
12074
  this.alternate.include(context, includeChildrenRecursively);
@@ -11579,27 +12077,38 @@ class ConditionalExpression extends NodeBase {
11579
12077
  usedBranch.include(context, includeChildrenRecursively);
11580
12078
  }
11581
12079
  }
11582
- includeCallArguments(context, parameters) {
12080
+ includePath(path, context) {
12081
+ this.included = true;
12082
+ const usedBranch = this.getUsedBranch();
12083
+ if (usedBranch === null || this.test.shouldBeIncluded(context)) {
12084
+ this.consequent.includePath(path, context);
12085
+ this.alternate.includePath(path, context);
12086
+ }
12087
+ else {
12088
+ usedBranch.includePath(path, context);
12089
+ }
12090
+ }
12091
+ includeCallArguments(context, interaction) {
11583
12092
  const usedBranch = this.getUsedBranch();
11584
12093
  if (usedBranch) {
11585
- usedBranch.includeCallArguments(context, parameters);
12094
+ usedBranch.includeCallArguments(context, interaction);
11586
12095
  }
11587
12096
  else {
11588
- this.consequent.includeCallArguments(context, parameters);
11589
- this.alternate.includeCallArguments(context, parameters);
12097
+ this.consequent.includeCallArguments(context, interaction);
12098
+ this.alternate.includeCallArguments(context, interaction);
11590
12099
  }
11591
12100
  }
11592
12101
  removeAnnotations(code) {
11593
12102
  this.test.removeAnnotations(code);
11594
12103
  }
11595
12104
  render(code, options, { isCalleeOfRenderedParent, preventASI, renderedParentType, renderedSurroundingElement } = BLANK) {
11596
- const usedBranch = this.getUsedBranch();
11597
12105
  if (this.test.included) {
11598
12106
  this.test.render(code, options, { renderedSurroundingElement });
11599
12107
  this.consequent.render(code, options);
11600
12108
  this.alternate.render(code, options);
11601
12109
  }
11602
12110
  else {
12111
+ const usedBranch = this.getUsedBranch();
11603
12112
  const colonPos = findFirstOccurrenceOutsideComment(code.original, ':', this.consequent.end);
11604
12113
  const inclusionStart = findNonWhiteSpace(code.original, (this.consequent.included
11605
12114
  ? findFirstOccurrenceOutsideComment(code.original, '?', this.test.end)
@@ -11631,6 +12140,8 @@ class ConditionalExpression extends NodeBase {
11631
12140
  : (this.usedBranch = testValue ? this.consequent : this.alternate);
11632
12141
  }
11633
12142
  }
12143
+ ConditionalExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12144
+ ConditionalExpression.prototype.applyDeoptimizations = doNotDeoptimize;
11634
12145
 
11635
12146
  class ContinueStatement extends NodeBase {
11636
12147
  hasEffects(context) {
@@ -11650,7 +12161,7 @@ class ContinueStatement extends NodeBase {
11650
12161
  include(context) {
11651
12162
  this.included = true;
11652
12163
  if (this.label) {
11653
- this.label.include();
12164
+ this.label.include(context);
11654
12165
  context.includedLabels.add(this.label.name);
11655
12166
  }
11656
12167
  else {
@@ -11659,12 +12170,15 @@ class ContinueStatement extends NodeBase {
11659
12170
  context.brokenFlow = true;
11660
12171
  }
11661
12172
  }
12173
+ ContinueStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12174
+ ContinueStatement.prototype.applyDeoptimizations = doNotDeoptimize;
11662
12175
 
11663
12176
  class DebuggerStatement extends NodeBase {
11664
12177
  hasEffects() {
11665
12178
  return true;
11666
12179
  }
11667
12180
  }
12181
+ DebuggerStatement.prototype.includeNode = onlyIncludeSelf;
11668
12182
 
11669
12183
  class Decorator extends NodeBase {
11670
12184
  hasEffects(context) {
@@ -11672,6 +12186,7 @@ class Decorator extends NodeBase {
11672
12186
  this.expression.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context));
11673
12187
  }
11674
12188
  }
12189
+ Decorator.prototype.includeNode = onlyIncludeSelf;
11675
12190
 
11676
12191
  function hasLoopBodyEffects(context, body) {
11677
12192
  const { brokenFlow, hasBreak, hasContinue, ignore } = context;
@@ -11711,12 +12226,15 @@ class DoWhileStatement extends NodeBase {
11711
12226
  includeLoopBody(context, this.body, includeChildrenRecursively);
11712
12227
  }
11713
12228
  }
12229
+ DoWhileStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12230
+ DoWhileStatement.prototype.applyDeoptimizations = doNotDeoptimize;
11714
12231
 
11715
12232
  class EmptyStatement extends NodeBase {
11716
12233
  hasEffects() {
11717
12234
  return false;
11718
12235
  }
11719
12236
  }
12237
+ EmptyStatement.prototype.includeNode = onlyIncludeSelf;
11720
12238
 
11721
12239
  class ExportAllDeclaration extends NodeBase {
11722
12240
  hasEffects() {
@@ -11729,9 +12247,10 @@ class ExportAllDeclaration extends NodeBase {
11729
12247
  render(code, _options, nodeRenderOptions) {
11730
12248
  code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
11731
12249
  }
11732
- applyDeoptimizations() { }
11733
12250
  }
11734
12251
  ExportAllDeclaration.prototype.needsBoundaries = true;
12252
+ ExportAllDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12253
+ ExportAllDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
11735
12254
 
11736
12255
  class ExportNamedDeclaration extends NodeBase {
11737
12256
  bind() {
@@ -11758,13 +12277,15 @@ class ExportNamedDeclaration extends NodeBase {
11758
12277
  this.declaration.render(code, options, { end, start });
11759
12278
  }
11760
12279
  }
11761
- applyDeoptimizations() { }
11762
12280
  }
11763
12281
  ExportNamedDeclaration.prototype.needsBoundaries = true;
12282
+ ExportNamedDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12283
+ ExportNamedDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
11764
12284
 
11765
12285
  class ExportSpecifier extends NodeBase {
11766
- applyDeoptimizations() { }
11767
12286
  }
12287
+ ExportSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12288
+ ExportSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
11768
12289
 
11769
12290
  class ForInStatement extends NodeBase {
11770
12291
  createScope(parentScope) {
@@ -11782,11 +12303,18 @@ class ForInStatement extends NodeBase {
11782
12303
  const { body, deoptimized, left, right } = this;
11783
12304
  if (!deoptimized)
11784
12305
  this.applyDeoptimizations();
11785
- this.included = true;
12306
+ if (!this.included)
12307
+ this.includeNode(context);
11786
12308
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
11787
12309
  right.include(context, includeChildrenRecursively);
11788
12310
  includeLoopBody(context, body, includeChildrenRecursively);
11789
12311
  }
12312
+ includeNode(context) {
12313
+ this.included = true;
12314
+ if (!this.deoptimized)
12315
+ this.applyDeoptimizations();
12316
+ this.right.includePath(UNKNOWN_PATH, context);
12317
+ }
11790
12318
  initialise() {
11791
12319
  super.initialise();
11792
12320
  this.left.setAssignedValue(UNKNOWN_EXPRESSION);
@@ -11827,11 +12355,18 @@ class ForOfStatement extends NodeBase {
11827
12355
  const { body, deoptimized, left, right } = this;
11828
12356
  if (!deoptimized)
11829
12357
  this.applyDeoptimizations();
11830
- this.included = true;
12358
+ if (!this.included)
12359
+ this.includeNode(context);
11831
12360
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
11832
12361
  right.include(context, includeChildrenRecursively);
11833
12362
  includeLoopBody(context, body, includeChildrenRecursively);
11834
12363
  }
12364
+ includeNode(context) {
12365
+ this.included = true;
12366
+ if (!this.deoptimized)
12367
+ this.applyDeoptimizations();
12368
+ this.right.includePath(UNKNOWN_PATH, context);
12369
+ }
11835
12370
  initialise() {
11836
12371
  super.initialise();
11837
12372
  this.left.setAssignedValue(UNKNOWN_EXPRESSION);
@@ -11867,7 +12402,9 @@ class ForStatement extends NodeBase {
11867
12402
  }
11868
12403
  include(context, includeChildrenRecursively) {
11869
12404
  this.included = true;
11870
- this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true });
12405
+ this.init?.include(context, includeChildrenRecursively, {
12406
+ asSingleStatement: true
12407
+ });
11871
12408
  this.test?.include(context, includeChildrenRecursively);
11872
12409
  this.update?.include(context, includeChildrenRecursively);
11873
12410
  includeLoopBody(context, this.body, includeChildrenRecursively);
@@ -11879,6 +12416,8 @@ class ForStatement extends NodeBase {
11879
12416
  this.body.render(code, options);
11880
12417
  }
11881
12418
  }
12419
+ ForStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12420
+ ForStatement.prototype.applyDeoptimizations = doNotDeoptimize;
11882
12421
 
11883
12422
  class FunctionExpression extends FunctionNode {
11884
12423
  createScope(parentScope) {
@@ -11910,9 +12449,9 @@ class TrackingScope extends BlockScope {
11910
12449
  super(...arguments);
11911
12450
  this.hoistedDeclarations = [];
11912
12451
  }
11913
- addDeclaration(identifier, context, init, kind) {
12452
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
11914
12453
  this.hoistedDeclarations.push(identifier);
11915
- return super.addDeclaration(identifier, context, init, kind);
12454
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
11916
12455
  }
11917
12456
  }
11918
12457
 
@@ -12011,7 +12550,6 @@ class IfStatement extends NodeBase {
12011
12550
  }
12012
12551
  this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess);
12013
12552
  }
12014
- applyDeoptimizations() { }
12015
12553
  getTestValue() {
12016
12554
  if (this.testValue === unset) {
12017
12555
  return (this.testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this));
@@ -12080,6 +12618,8 @@ class IfStatement extends NodeBase {
12080
12618
  return false;
12081
12619
  }
12082
12620
  }
12621
+ IfStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12622
+ IfStatement.prototype.applyDeoptimizations = doNotDeoptimize;
12083
12623
 
12084
12624
  class ImportAttribute extends NodeBase {
12085
12625
  }
@@ -12097,13 +12637,15 @@ class ImportDeclaration extends NodeBase {
12097
12637
  render(code, _options, nodeRenderOptions) {
12098
12638
  code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
12099
12639
  }
12100
- applyDeoptimizations() { }
12101
12640
  }
12102
12641
  ImportDeclaration.prototype.needsBoundaries = true;
12642
+ ImportDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12643
+ ImportDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
12103
12644
 
12104
12645
  class ImportDefaultSpecifier extends NodeBase {
12105
- applyDeoptimizations() { }
12106
12646
  }
12647
+ ImportDefaultSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12648
+ ImportDefaultSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
12107
12649
 
12108
12650
  function isReassignedExportsMember(variable, exportNamesByVariable) {
12109
12651
  return (variable.renderBaseName !== null && exportNamesByVariable.has(variable) && variable.isReassigned);
@@ -12112,28 +12654,33 @@ function isReassignedExportsMember(variable, exportNamesByVariable) {
12112
12654
  class VariableDeclarator extends NodeBase {
12113
12655
  declareDeclarator(kind, isUsingDeclaration) {
12114
12656
  this.isUsingDeclaration = isUsingDeclaration;
12115
- this.id.declare(kind, this.init || UNDEFINED_EXPRESSION);
12657
+ this.id.declare(kind, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION);
12116
12658
  }
12117
12659
  deoptimizePath(path) {
12118
12660
  this.id.deoptimizePath(path);
12119
12661
  }
12120
12662
  hasEffects(context) {
12121
- if (!this.deoptimized)
12122
- this.applyDeoptimizations();
12123
12663
  const initEffect = this.init?.hasEffects(context);
12124
12664
  this.id.markDeclarationReached();
12125
- return initEffect || this.id.hasEffects(context) || this.isUsingDeclaration;
12665
+ return (initEffect ||
12666
+ this.isUsingDeclaration ||
12667
+ this.id.hasEffects(context) ||
12668
+ (this.scope.context.options.treeshake
12669
+ .propertyReadSideEffects &&
12670
+ this.id.hasEffectsWhenDestructuring(context, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION)));
12126
12671
  }
12127
12672
  include(context, includeChildrenRecursively) {
12128
- const { deoptimized, id, init } = this;
12129
- if (!deoptimized)
12130
- this.applyDeoptimizations();
12131
- this.included = true;
12673
+ const { id, init } = this;
12674
+ if (!this.included)
12675
+ this.includeNode();
12132
12676
  init?.include(context, includeChildrenRecursively);
12133
12677
  id.markDeclarationReached();
12134
- if (includeChildrenRecursively || id.shouldBeIncluded(context)) {
12678
+ if (includeChildrenRecursively) {
12135
12679
  id.include(context, includeChildrenRecursively);
12136
12680
  }
12681
+ else {
12682
+ id.includeDestructuredIfNecessary(context, EMPTY_PATH, init || UNDEFINED_EXPRESSION);
12683
+ }
12137
12684
  }
12138
12685
  removeAnnotations(code) {
12139
12686
  this.init?.removeAnnotations(code);
@@ -12163,8 +12710,8 @@ class VariableDeclarator extends NodeBase {
12163
12710
  code.appendLeft(end, `${_}=${_}void 0`);
12164
12711
  }
12165
12712
  }
12166
- applyDeoptimizations() {
12167
- this.deoptimized = true;
12713
+ includeNode() {
12714
+ this.included = true;
12168
12715
  const { id, init } = this;
12169
12716
  if (init && id instanceof Identifier && init instanceof ClassExpression && !init.id) {
12170
12717
  const { name, variable } = id;
@@ -12176,11 +12723,14 @@ class VariableDeclarator extends NodeBase {
12176
12723
  }
12177
12724
  }
12178
12725
  }
12726
+ VariableDeclarator.prototype.applyDeoptimizations = doNotDeoptimize;
12179
12727
 
12180
12728
  class ImportExpression extends NodeBase {
12181
12729
  constructor() {
12182
12730
  super(...arguments);
12183
12731
  this.inlineNamespace = null;
12732
+ this.hasUnknownAccessedKey = false;
12733
+ this.accessedPropKey = new Set();
12184
12734
  this.attributes = null;
12185
12735
  this.mechanism = null;
12186
12736
  this.namespaceExportName = undefined;
@@ -12213,12 +12763,15 @@ class ImportExpression extends NodeBase {
12213
12763
  if (parent2 instanceof ExpressionStatement) {
12214
12764
  return EMPTY_ARRAY;
12215
12765
  }
12216
- // Case 1: const { foo } = await import('bar')
12766
+ // Case 1: const { foo } / module = await import('bar')
12217
12767
  if (parent2 instanceof VariableDeclarator) {
12218
12768
  const declaration = parent2.id;
12219
- return declaration instanceof ObjectPattern
12220
- ? getDeterministicObjectDestructure(declaration)
12221
- : undefined;
12769
+ if (declaration instanceof Identifier) {
12770
+ return this.hasUnknownAccessedKey ? undefined : [...this.accessedPropKey];
12771
+ }
12772
+ if (declaration instanceof ObjectPattern) {
12773
+ return getDeterministicObjectDestructure(declaration);
12774
+ }
12222
12775
  }
12223
12776
  // Case 2: (await import('bar')).foo
12224
12777
  if (parent2 instanceof MemberExpression) {
@@ -12268,13 +12821,30 @@ class ImportExpression extends NodeBase {
12268
12821
  return true;
12269
12822
  }
12270
12823
  include(context, includeChildrenRecursively) {
12271
- if (!this.included) {
12272
- this.included = true;
12273
- this.scope.context.includeDynamicImport(this);
12274
- this.scope.addAccessedDynamicImport(this);
12275
- }
12824
+ if (!this.included)
12825
+ this.includeNode();
12276
12826
  this.source.include(context, includeChildrenRecursively);
12277
12827
  }
12828
+ includeNode() {
12829
+ this.included = true;
12830
+ this.scope.context.includeDynamicImport(this);
12831
+ this.scope.addAccessedDynamicImport(this);
12832
+ }
12833
+ includePath(path) {
12834
+ if (!this.included)
12835
+ this.includeNode();
12836
+ // Technically, this is not correct as dynamic imports return a Promise.
12837
+ if (this.hasUnknownAccessedKey)
12838
+ return;
12839
+ if (path[0] === UnknownKey) {
12840
+ this.hasUnknownAccessedKey = true;
12841
+ }
12842
+ else if (typeof path[0] === 'string') {
12843
+ this.accessedPropKey.add(path[0]);
12844
+ }
12845
+ // Update included paths
12846
+ this.scope.context.includeDynamicImport(this);
12847
+ }
12278
12848
  initialise() {
12279
12849
  super.initialise();
12280
12850
  this.scope.context.addDynamicImport(this);
@@ -12343,7 +12913,6 @@ class ImportExpression extends NodeBase {
12343
12913
  setInternalResolution(inlineNamespace) {
12344
12914
  this.inlineNamespace = inlineNamespace;
12345
12915
  }
12346
- applyDeoptimizations() { }
12347
12916
  getDynamicImportMechanismAndHelper(resolution, exportMode, { compact, dynamicImportInCjs, format, generatedCode: { arrowFunctions }, interop }, { _, getDirectReturnFunction, getDirectReturnIifeLeft }, pluginDriver) {
12348
12917
  const mechanism = pluginDriver.hookFirstSync('renderDynamicImport', [
12349
12918
  {
@@ -12433,6 +13002,7 @@ class ImportExpression extends NodeBase {
12433
13002
  return { helper: null, mechanism: null };
12434
13003
  }
12435
13004
  }
13005
+ ImportExpression.prototype.applyDeoptimizations = doNotDeoptimize;
12436
13006
  function getInteropHelper(resolution, exportMode, interop) {
12437
13007
  return exportMode === 'external'
12438
13008
  ? namespaceInteropHelpersByInteropType[interop(resolution instanceof ExternalModule ? resolution.id : null)]
@@ -12456,12 +13026,14 @@ function getDeterministicObjectDestructure(objectPattern) {
12456
13026
  }
12457
13027
 
12458
13028
  class ImportNamespaceSpecifier extends NodeBase {
12459
- applyDeoptimizations() { }
12460
13029
  }
13030
+ ImportNamespaceSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13031
+ ImportNamespaceSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
12461
13032
 
12462
13033
  class ImportSpecifier extends NodeBase {
12463
- applyDeoptimizations() { }
12464
13034
  }
13035
+ ImportSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13036
+ ImportSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
12465
13037
 
12466
13038
  class JSXIdentifier extends IdentifierBase {
12467
13039
  constructor() {
@@ -12478,6 +13050,29 @@ class JSXIdentifier extends IdentifierBase {
12478
13050
  this.isNativeElement = true;
12479
13051
  }
12480
13052
  }
13053
+ include(context) {
13054
+ if (!this.included)
13055
+ this.includeNode(context);
13056
+ }
13057
+ includeNode(context) {
13058
+ this.included = true;
13059
+ if (!this.deoptimized)
13060
+ this.applyDeoptimizations();
13061
+ if (this.variable !== null) {
13062
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
13063
+ }
13064
+ }
13065
+ includePath(path, context) {
13066
+ if (!this.included) {
13067
+ this.included = true;
13068
+ if (this.variable !== null) {
13069
+ this.scope.context.includeVariableInModule(this.variable, path, context);
13070
+ }
13071
+ }
13072
+ else if (path.length > 0) {
13073
+ this.variable?.includePath(path, context);
13074
+ }
13075
+ }
12481
13076
  render(code, { snippets: { getPropertyAccess }, useOriginalName }) {
12482
13077
  if (this.variable) {
12483
13078
  const name = this.variable.getName(getPropertyAccess, useOriginalName);
@@ -12539,6 +13134,7 @@ class JSXAttribute extends NodeBase {
12539
13134
  }
12540
13135
  }
12541
13136
  }
13137
+ JSXAttribute.prototype.includeNode = onlyIncludeSelf;
12542
13138
 
12543
13139
  class JSXClosingBase extends NodeBase {
12544
13140
  render(code, options) {
@@ -12551,6 +13147,7 @@ class JSXClosingBase extends NodeBase {
12551
13147
  }
12552
13148
  }
12553
13149
  }
13150
+ JSXClosingBase.prototype.includeNode = onlyIncludeSelf;
12554
13151
 
12555
13152
  class JSXClosingElement extends JSXClosingBase {
12556
13153
  }
@@ -12571,8 +13168,15 @@ class JSXSpreadAttribute extends NodeBase {
12571
13168
 
12572
13169
  class JSXEmptyExpression extends NodeBase {
12573
13170
  }
13171
+ JSXEmptyExpression.prototype.includeNode = onlyIncludeSelf;
12574
13172
 
12575
13173
  class JSXExpressionContainer extends NodeBase {
13174
+ includeNode(context) {
13175
+ this.included = true;
13176
+ if (!this.deoptimized)
13177
+ this.applyDeoptimizations();
13178
+ this.expression.includePath(UNKNOWN_PATH, context);
13179
+ }
12576
13180
  render(code, options) {
12577
13181
  const { mode } = this.scope.context.options.jsx;
12578
13182
  if (mode !== 'preserve') {
@@ -12593,7 +13197,7 @@ function getRenderedJsxChildren(children) {
12593
13197
  return renderedChildren;
12594
13198
  }
12595
13199
 
12596
- function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
13200
+ function getAndIncludeFactoryVariable(factory, preserve, importSource, node, context) {
12597
13201
  const [baseName, nestedName] = factory.split('.');
12598
13202
  let factoryVariable;
12599
13203
  if (importSource) {
@@ -12601,7 +13205,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
12601
13205
  if (preserve) {
12602
13206
  // This pretends we are accessing an included global variable of the same name
12603
13207
  const globalVariable = node.scope.findGlobal(baseName);
12604
- globalVariable.include();
13208
+ globalVariable.includePath(UNKNOWN_PATH, context);
12605
13209
  // This excludes this variable from renaming
12606
13210
  factoryVariable.globalName = baseName;
12607
13211
  }
@@ -12609,7 +13213,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
12609
13213
  else {
12610
13214
  factoryVariable = node.scope.findGlobal(baseName);
12611
13215
  }
12612
- node.scope.context.includeVariableInModule(factoryVariable);
13216
+ node.scope.context.includeVariableInModule(factoryVariable, UNKNOWN_PATH, context);
12613
13217
  if (factoryVariable instanceof LocalVariable) {
12614
13218
  factoryVariable.consolidateInitializers();
12615
13219
  factoryVariable.addUsedPlace(node);
@@ -12632,16 +13236,20 @@ class JSXElementBase extends NodeBase {
12632
13236
  }
12633
13237
  }
12634
13238
  include(context, includeChildrenRecursively) {
12635
- if (!this.included) {
12636
- const { factory, importSource, mode } = this.jsxMode;
12637
- if (factory) {
12638
- this.factory = factory;
12639
- this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this);
12640
- }
13239
+ if (!this.included)
13240
+ this.includeNode(context);
13241
+ for (const child of this.children) {
13242
+ child.include(context, includeChildrenRecursively);
13243
+ }
13244
+ }
13245
+ includeNode(context) {
13246
+ this.included = true;
13247
+ const { factory, importSource, mode } = this.jsxMode;
13248
+ if (factory) {
13249
+ this.factory = factory;
13250
+ this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this, context);
12641
13251
  }
12642
- super.include(context, includeChildrenRecursively);
12643
13252
  }
12644
- applyDeoptimizations() { }
12645
13253
  getRenderingMode() {
12646
13254
  const jsx = this.scope.context.options.jsx;
12647
13255
  const { mode, factory, importSource } = jsx;
@@ -12679,8 +13287,14 @@ class JSXElementBase extends NodeBase {
12679
13287
  return { childrenEnd, firstChild, hasMultipleChildren };
12680
13288
  }
12681
13289
  }
13290
+ JSXElementBase.prototype.applyDeoptimizations = doNotDeoptimize;
12682
13291
 
12683
13292
  class JSXElement extends JSXElementBase {
13293
+ include(context, includeChildrenRecursively) {
13294
+ super.include(context, includeChildrenRecursively);
13295
+ this.openingElement.include(context, includeChildrenRecursively);
13296
+ this.closingElement?.include(context, includeChildrenRecursively);
13297
+ }
12684
13298
  render(code, options) {
12685
13299
  switch (this.jsxMode.mode) {
12686
13300
  case 'classic': {
@@ -12832,6 +13446,11 @@ class JSXElement extends JSXElementBase {
12832
13446
  }
12833
13447
 
12834
13448
  class JSXFragment extends JSXElementBase {
13449
+ include(context, includeChildrenRecursively) {
13450
+ super.include(context, includeChildrenRecursively);
13451
+ this.openingFragment.include(context, includeChildrenRecursively);
13452
+ this.closingFragment.include(context, includeChildrenRecursively);
13453
+ }
12835
13454
  render(code, options) {
12836
13455
  switch (this.jsxMode.mode) {
12837
13456
  case 'classic': {
@@ -12881,10 +13500,22 @@ class JSXFragment extends JSXElementBase {
12881
13500
  }
12882
13501
 
12883
13502
  class JSXMemberExpression extends NodeBase {
13503
+ includeNode(context) {
13504
+ this.included = true;
13505
+ if (!this.deoptimized)
13506
+ this.applyDeoptimizations();
13507
+ this.object.includePath([this.property.name], context);
13508
+ }
13509
+ includePath(path, context) {
13510
+ if (!this.included)
13511
+ this.includeNode(context);
13512
+ this.object.includePath([this.property.name, ...path], context);
13513
+ }
12884
13514
  }
12885
13515
 
12886
13516
  class JSXNamespacedName extends NodeBase {
12887
13517
  }
13518
+ JSXNamespacedName.prototype.includeNode = onlyIncludeSelf;
12888
13519
 
12889
13520
  class JSXOpeningElement extends NodeBase {
12890
13521
  render(code, options, { jsxMode = this.scope.context.options.jsx.mode } = {}) {
@@ -12894,6 +13525,7 @@ class JSXOpeningElement extends NodeBase {
12894
13525
  }
12895
13526
  }
12896
13527
  }
13528
+ JSXOpeningElement.prototype.includeNode = onlyIncludeSelf;
12897
13529
 
12898
13530
  class JSXOpeningFragment extends NodeBase {
12899
13531
  constructor() {
@@ -12901,22 +13533,22 @@ class JSXOpeningFragment extends NodeBase {
12901
13533
  this.fragment = null;
12902
13534
  this.fragmentVariable = null;
12903
13535
  }
12904
- include(context, includeChildrenRecursively) {
12905
- if (!this.included) {
12906
- const jsx = this.scope.context.options.jsx;
12907
- if (jsx.mode === 'automatic') {
12908
- this.fragment = 'Fragment';
12909
- this.fragmentVariable = getAndIncludeFactoryVariable('Fragment', false, jsx.jsxImportSource, this);
12910
- }
12911
- else {
12912
- const { fragment, importSource, mode } = jsx;
12913
- if (fragment != null) {
12914
- this.fragment = fragment;
12915
- this.fragmentVariable = getAndIncludeFactoryVariable(fragment, mode === 'preserve', importSource, this);
12916
- }
13536
+ includeNode(context) {
13537
+ this.included = true;
13538
+ if (!this.deoptimized)
13539
+ this.applyDeoptimizations();
13540
+ const jsx = this.scope.context.options.jsx;
13541
+ if (jsx.mode === 'automatic') {
13542
+ this.fragment = 'Fragment';
13543
+ this.fragmentVariable = getAndIncludeFactoryVariable('Fragment', false, jsx.jsxImportSource, this, context);
13544
+ }
13545
+ else {
13546
+ const { fragment, importSource, mode } = jsx;
13547
+ if (fragment != null) {
13548
+ this.fragment = fragment;
13549
+ this.fragmentVariable = getAndIncludeFactoryVariable(fragment, mode === 'preserve', importSource, this, context);
12917
13550
  }
12918
13551
  }
12919
- super.include(context, includeChildrenRecursively);
12920
13552
  }
12921
13553
  render(code, options) {
12922
13554
  const { mode } = this.scope.context.options.jsx;
@@ -12953,6 +13585,7 @@ class JSXText extends NodeBase {
12953
13585
  }
12954
13586
  }
12955
13587
  }
13588
+ JSXText.prototype.includeNode = onlyIncludeSelf;
12956
13589
 
12957
13590
  class LabeledStatement extends NodeBase {
12958
13591
  hasEffects(context) {
@@ -12974,17 +13607,22 @@ class LabeledStatement extends NodeBase {
12974
13607
  return bodyHasEffects;
12975
13608
  }
12976
13609
  include(context, includeChildrenRecursively) {
12977
- this.included = true;
13610
+ if (!this.included)
13611
+ this.includeNode(context);
12978
13612
  const { brokenFlow, includedLabels } = context;
12979
13613
  context.includedLabels = new Set();
12980
13614
  this.body.include(context, includeChildrenRecursively);
12981
13615
  if (includeChildrenRecursively || context.includedLabels.has(this.label.name)) {
12982
- this.label.include();
13616
+ this.label.include(context);
12983
13617
  context.includedLabels.delete(this.label.name);
12984
13618
  context.brokenFlow = brokenFlow;
12985
13619
  }
12986
13620
  context.includedLabels = new Set([...includedLabels, ...context.includedLabels]);
12987
13621
  }
13622
+ includeNode(context) {
13623
+ this.included = true;
13624
+ this.body.includePath(UNKNOWN_PATH, context);
13625
+ }
12988
13626
  render(code, options) {
12989
13627
  if (this.label.included) {
12990
13628
  this.label.render(code, options);
@@ -12995,6 +13633,7 @@ class LabeledStatement extends NodeBase {
12995
13633
  this.body.render(code, options);
12996
13634
  }
12997
13635
  }
13636
+ LabeledStatement.prototype.applyDeoptimizations = doNotDeoptimize;
12998
13637
 
12999
13638
  class LogicalExpression extends NodeBase {
13000
13639
  constructor() {
@@ -13019,6 +13658,10 @@ class LogicalExpression extends NodeBase {
13019
13658
  const unusedBranch = this.usedBranch === this.left ? this.right : this.left;
13020
13659
  this.usedBranch = null;
13021
13660
  unusedBranch.deoptimizePath(UNKNOWN_PATH);
13661
+ if (this.included) {
13662
+ // As we are not tracking inclusions, we just include everything
13663
+ unusedBranch.includePath(UNKNOWN_PATH, createInclusionContext());
13664
+ }
13022
13665
  const { scope: { context }, expressionsToBeDeoptimized } = this;
13023
13666
  this.expressionsToBeDeoptimized = EMPTY_ARRAY;
13024
13667
  for (const expression of expressionsToBeDeoptimized) {
@@ -13041,23 +13684,25 @@ class LogicalExpression extends NodeBase {
13041
13684
  }
13042
13685
  getLiteralValueAtPath(path, recursionTracker, origin) {
13043
13686
  const usedBranch = this.getUsedBranch();
13044
- if (!usedBranch)
13045
- return UnknownValue;
13046
- this.expressionsToBeDeoptimized.push(origin);
13047
- return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin);
13687
+ if (usedBranch) {
13688
+ this.expressionsToBeDeoptimized.push(origin);
13689
+ return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin);
13690
+ }
13691
+ return UnknownValue;
13048
13692
  }
13049
13693
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
13050
13694
  const usedBranch = this.getUsedBranch();
13051
- if (!usedBranch)
13052
- return [
13053
- new MultiExpression([
13054
- this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
13055
- this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
13056
- ]),
13057
- false
13058
- ];
13059
- this.expressionsToBeDeoptimized.push(origin);
13060
- return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
13695
+ if (usedBranch) {
13696
+ this.expressionsToBeDeoptimized.push(origin);
13697
+ return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
13698
+ }
13699
+ return [
13700
+ new MultiExpression([
13701
+ this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
13702
+ this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
13703
+ ]),
13704
+ false
13705
+ ];
13061
13706
  }
13062
13707
  hasEffects(context) {
13063
13708
  if (this.left.hasEffects(context)) {
@@ -13070,18 +13715,18 @@ class LogicalExpression extends NodeBase {
13070
13715
  }
13071
13716
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13072
13717
  const usedBranch = this.getUsedBranch();
13073
- if (!usedBranch) {
13074
- return (this.left.hasEffectsOnInteractionAtPath(path, interaction, context) ||
13075
- this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
13718
+ if (usedBranch) {
13719
+ return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
13076
13720
  }
13077
- return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
13721
+ return (this.left.hasEffectsOnInteractionAtPath(path, interaction, context) ||
13722
+ this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
13078
13723
  }
13079
13724
  include(context, includeChildrenRecursively) {
13080
13725
  this.included = true;
13081
13726
  const usedBranch = this.getUsedBranch();
13082
13727
  if (includeChildrenRecursively ||
13083
- (usedBranch === this.right && this.left.shouldBeIncluded(context)) ||
13084
- !usedBranch) {
13728
+ !usedBranch ||
13729
+ (usedBranch === this.right && this.left.shouldBeIncluded(context))) {
13085
13730
  this.left.include(context, includeChildrenRecursively);
13086
13731
  this.right.include(context, includeChildrenRecursively);
13087
13732
  }
@@ -13089,6 +13734,17 @@ class LogicalExpression extends NodeBase {
13089
13734
  usedBranch.include(context, includeChildrenRecursively);
13090
13735
  }
13091
13736
  }
13737
+ includePath(path, context) {
13738
+ this.included = true;
13739
+ const usedBranch = this.getUsedBranch();
13740
+ if (!usedBranch || (usedBranch === this.right && this.left.shouldBeIncluded(context))) {
13741
+ this.left.includePath(path, context);
13742
+ this.right.includePath(path, context);
13743
+ }
13744
+ else {
13745
+ usedBranch.includePath(path, context);
13746
+ }
13747
+ }
13092
13748
  removeAnnotations(code) {
13093
13749
  this.left.removeAnnotations(code);
13094
13750
  }
@@ -13140,6 +13796,8 @@ class LogicalExpression extends NodeBase {
13140
13796
  return this.usedBranch;
13141
13797
  }
13142
13798
  }
13799
+ LogicalExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13800
+ LogicalExpression.prototype.applyDeoptimizations = doNotDeoptimize;
13143
13801
 
13144
13802
  class NewExpression extends NodeBase {
13145
13803
  hasEffects(context) {
@@ -13159,16 +13817,21 @@ class NewExpression extends NodeBase {
13159
13817
  return path.length > 0 || type !== INTERACTION_ACCESSED;
13160
13818
  }
13161
13819
  include(context, includeChildrenRecursively) {
13162
- if (!this.deoptimized)
13163
- this.applyDeoptimizations();
13164
13820
  if (includeChildrenRecursively) {
13165
13821
  super.include(context, includeChildrenRecursively);
13166
13822
  }
13167
13823
  else {
13168
- this.included = true;
13824
+ if (!this.included)
13825
+ this.includeNode(context);
13169
13826
  this.callee.include(context, false);
13170
13827
  }
13171
- this.callee.includeCallArguments(context, this.arguments);
13828
+ this.callee.includeCallArguments(context, this.interaction);
13829
+ }
13830
+ includeNode(context) {
13831
+ this.included = true;
13832
+ if (!this.deoptimized)
13833
+ this.applyDeoptimizations();
13834
+ this.callee.includePath(UNKNOWN_PATH, context);
13172
13835
  }
13173
13836
  initialise() {
13174
13837
  super.initialise();
@@ -13197,6 +13860,7 @@ class ObjectExpression extends NodeBase {
13197
13860
  constructor() {
13198
13861
  super(...arguments);
13199
13862
  this.objectEntity = null;
13863
+ this.protoProp = null;
13200
13864
  }
13201
13865
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
13202
13866
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -13216,15 +13880,43 @@ class ObjectExpression extends NodeBase {
13216
13880
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13217
13881
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
13218
13882
  }
13883
+ include(context, includeChildrenRecursively) {
13884
+ if (!this.included)
13885
+ this.includeNode(context);
13886
+ this.getObjectEntity().include(context, includeChildrenRecursively);
13887
+ this.protoProp?.include(context, includeChildrenRecursively);
13888
+ }
13889
+ includeNode(context) {
13890
+ this.included = true;
13891
+ this.protoProp?.includePath(UNKNOWN_PATH, context);
13892
+ }
13893
+ includePath(path, context) {
13894
+ if (!this.included)
13895
+ this.includeNode(context);
13896
+ this.getObjectEntity().includePath(path, context);
13897
+ }
13219
13898
  render(code, options, { renderedSurroundingElement } = BLANK) {
13220
- super.render(code, options);
13221
13899
  if (renderedSurroundingElement === ExpressionStatement$1 ||
13222
13900
  renderedSurroundingElement === ArrowFunctionExpression$1) {
13223
13901
  code.appendRight(this.start, '(');
13224
13902
  code.prependLeft(this.end, ')');
13225
13903
  }
13904
+ if (this.properties.length > 0) {
13905
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
13906
+ let lastSeparatorPos = null;
13907
+ for (const { node, separator, start, end } of separatedNodes) {
13908
+ if (!node.included) {
13909
+ treeshakeNode(node, code, start, end);
13910
+ continue;
13911
+ }
13912
+ lastSeparatorPos = separator;
13913
+ node.render(code, options);
13914
+ }
13915
+ if (lastSeparatorPos) {
13916
+ code.remove(lastSeparatorPos, this.end - 1);
13917
+ }
13918
+ }
13226
13919
  }
13227
- applyDeoptimizations() { }
13228
13920
  getObjectEntity() {
13229
13921
  if (this.objectEntity !== null) {
13230
13922
  return this.objectEntity;
@@ -13253,6 +13945,7 @@ class ObjectExpression extends NodeBase {
13253
13945
  ? property.key.name
13254
13946
  : String(property.key.value);
13255
13947
  if (key === '__proto__' && property.kind === 'init') {
13948
+ this.protoProp = property;
13256
13949
  prototype =
13257
13950
  property.value instanceof Literal && property.value.value === null
13258
13951
  ? null
@@ -13265,6 +13958,7 @@ class ObjectExpression extends NodeBase {
13265
13958
  return (this.objectEntity = new ObjectEntity(properties, prototype));
13266
13959
  }
13267
13960
  }
13961
+ ObjectExpression.prototype.applyDeoptimizations = doNotDeoptimize;
13268
13962
 
13269
13963
  class PanicError extends NodeBase {
13270
13964
  initialise() {
@@ -13291,6 +13985,7 @@ class ParseError extends NodeBase {
13291
13985
 
13292
13986
  class PrivateIdentifier extends NodeBase {
13293
13987
  }
13988
+ PrivateIdentifier.prototype.includeNode = onlyIncludeSelf;
13294
13989
 
13295
13990
  class Program extends NodeBase {
13296
13991
  constructor() {
@@ -13358,14 +14053,11 @@ class Program extends NodeBase {
13358
14053
  super.render(code, options);
13359
14054
  }
13360
14055
  }
13361
- applyDeoptimizations() { }
13362
14056
  }
14057
+ Program.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14058
+ Program.prototype.applyDeoptimizations = doNotDeoptimize;
13363
14059
 
13364
14060
  class Property extends MethodBase {
13365
- constructor() {
13366
- super(...arguments);
13367
- this.declarationInit = null;
13368
- }
13369
14061
  //declare method: boolean;
13370
14062
  get method() {
13371
14063
  return isFlagSet(this.flags, 262144 /* Flag.method */);
@@ -13380,17 +14072,41 @@ class Property extends MethodBase {
13380
14072
  set shorthand(value) {
13381
14073
  this.flags = setFlag(this.flags, 524288 /* Flag.shorthand */, value);
13382
14074
  }
13383
- declare(kind, init) {
13384
- this.declarationInit = init;
13385
- return this.value.declare(kind, UNKNOWN_EXPRESSION);
14075
+ declare(kind, destructuredInitPath, init) {
14076
+ return this.value.declare(kind, this.getPathInProperty(destructuredInitPath), init);
14077
+ }
14078
+ deoptimizeAssignment(destructuredInitPath, init) {
14079
+ this.value.deoptimizeAssignment?.(this.getPathInProperty(destructuredInitPath), init);
13386
14080
  }
13387
14081
  hasEffects(context) {
13388
- if (!this.deoptimized)
13389
- this.applyDeoptimizations();
13390
- const propertyReadSideEffects = this.scope.context.options.treeshake.propertyReadSideEffects;
13391
- return ((this.parent.type === 'ObjectPattern' && propertyReadSideEffects === 'always') ||
13392
- this.key.hasEffects(context) ||
13393
- this.value.hasEffects(context));
14082
+ return this.key.hasEffects(context) || this.value.hasEffects(context);
14083
+ }
14084
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
14085
+ return this.value.hasEffectsWhenDestructuring?.(context, this.getPathInProperty(destructuredInitPath), init);
14086
+ }
14087
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
14088
+ const path = this.getPathInProperty(destructuredInitPath);
14089
+ let included = this.value.includeDestructuredIfNecessary(context, path, init) ||
14090
+ this.included;
14091
+ if ((included ||= this.key.hasEffects(createHasEffectsContext()))) {
14092
+ this.key.include(context, false);
14093
+ if (!this.value.included) {
14094
+ this.value.included = true;
14095
+ // Unfortunately, we need to include the value again now, so that any
14096
+ // declared variables are properly included.
14097
+ this.value.includeDestructuredIfNecessary(context, path, init);
14098
+ }
14099
+ }
14100
+ return (this.included = included);
14101
+ }
14102
+ include(context, includeChildrenRecursively) {
14103
+ this.included = true;
14104
+ this.key.include(context, includeChildrenRecursively);
14105
+ this.value.include(context, includeChildrenRecursively);
14106
+ }
14107
+ includePath(path, context) {
14108
+ this.included = true;
14109
+ this.value.includePath(path, context);
13394
14110
  }
13395
14111
  markDeclarationReached() {
13396
14112
  this.value.markDeclarationReached();
@@ -13401,14 +14117,20 @@ class Property extends MethodBase {
13401
14117
  }
13402
14118
  this.value.render(code, options, { isShorthandProperty: this.shorthand });
13403
14119
  }
13404
- applyDeoptimizations() {
13405
- this.deoptimized = true;
13406
- if (this.declarationInit !== null) {
13407
- this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
13408
- this.scope.context.requestTreeshakingPass();
13409
- }
14120
+ getPathInProperty(destructuredInitPath) {
14121
+ return destructuredInitPath.at(-1) === UnknownKey
14122
+ ? destructuredInitPath
14123
+ : // For now, we only consider static paths as we do not know how to
14124
+ // deoptimize the path in the dynamic case.
14125
+ this.computed
14126
+ ? [...destructuredInitPath, UnknownKey]
14127
+ : this.key instanceof Identifier
14128
+ ? [...destructuredInitPath, this.key.name]
14129
+ : [...destructuredInitPath, String(this.key.value)];
13410
14130
  }
13411
14131
  }
14132
+ Property.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14133
+ Property.prototype.applyDeoptimizations = doNotDeoptimize;
13412
14134
 
13413
14135
  class PropertyDefinition extends NodeBase {
13414
14136
  get computed() {
@@ -13441,8 +14163,15 @@ class PropertyDefinition extends NodeBase {
13441
14163
  hasEffectsOnInteractionAtPath(path, interaction, context) {
13442
14164
  return !this.value || this.value.hasEffectsOnInteractionAtPath(path, interaction, context);
13443
14165
  }
13444
- applyDeoptimizations() { }
14166
+ includeNode(context) {
14167
+ this.included = true;
14168
+ this.value?.includePath(UNKNOWN_PATH, context);
14169
+ for (const decorator of this.decorators) {
14170
+ decorator.includePath(UNKNOWN_PATH, context);
14171
+ }
14172
+ }
13445
14173
  }
14174
+ PropertyDefinition.prototype.applyDeoptimizations = doNotDeoptimize;
13446
14175
 
13447
14176
  class ReturnStatement extends NodeBase {
13448
14177
  hasEffects(context) {
@@ -13452,10 +14181,15 @@ class ReturnStatement extends NodeBase {
13452
14181
  return false;
13453
14182
  }
13454
14183
  include(context, includeChildrenRecursively) {
13455
- this.included = true;
14184
+ if (!this.included)
14185
+ this.includeNode(context);
13456
14186
  this.argument?.include(context, includeChildrenRecursively);
13457
14187
  context.brokenFlow = true;
13458
14188
  }
14189
+ includeNode(context) {
14190
+ this.included = true;
14191
+ this.argument?.includePath(UNKNOWN_PATH, context);
14192
+ }
13459
14193
  initialise() {
13460
14194
  super.initialise();
13461
14195
  this.scope.addReturnExpression(this.argument || UNKNOWN_EXPRESSION);
@@ -13469,6 +14203,7 @@ class ReturnStatement extends NodeBase {
13469
14203
  }
13470
14204
  }
13471
14205
  }
14206
+ ReturnStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13472
14207
 
13473
14208
  class SequenceExpression extends NodeBase {
13474
14209
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
@@ -13496,10 +14231,15 @@ class SequenceExpression extends NodeBase {
13496
14231
  for (const expression of this.expressions) {
13497
14232
  if (includeChildrenRecursively ||
13498
14233
  (expression === lastExpression && !(this.parent instanceof ExpressionStatement)) ||
13499
- expression.shouldBeIncluded(context))
14234
+ expression.shouldBeIncluded(context)) {
13500
14235
  expression.include(context, includeChildrenRecursively);
14236
+ }
13501
14237
  }
13502
14238
  }
14239
+ includePath(path, context) {
14240
+ this.included = true;
14241
+ this.expressions[this.expressions.length - 1].includePath(path, context);
14242
+ }
13503
14243
  removeAnnotations(code) {
13504
14244
  this.expressions[0].removeAnnotations(code);
13505
14245
  }
@@ -13534,6 +14274,8 @@ class SequenceExpression extends NodeBase {
13534
14274
  }
13535
14275
  }
13536
14276
  }
14277
+ SequenceExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14278
+ SequenceExpression.prototype.applyDeoptimizations = doNotDeoptimize;
13537
14279
 
13538
14280
  class Super extends NodeBase {
13539
14281
  bind() {
@@ -13545,11 +14287,15 @@ class Super extends NodeBase {
13545
14287
  deoptimizePath(path) {
13546
14288
  this.variable.deoptimizePath(path);
13547
14289
  }
13548
- include() {
13549
- if (!this.included) {
13550
- this.included = true;
13551
- this.scope.context.includeVariableInModule(this.variable);
13552
- }
14290
+ include(context) {
14291
+ if (!this.included)
14292
+ this.includeNode(context);
14293
+ }
14294
+ includeNode(context) {
14295
+ this.included = true;
14296
+ if (!this.deoptimized)
14297
+ this.applyDeoptimizations();
14298
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
13553
14299
  }
13554
14300
  }
13555
14301
 
@@ -13590,6 +14336,8 @@ class SwitchCase extends NodeBase {
13590
14336
  }
13591
14337
  }
13592
14338
  SwitchCase.prototype.needsBoundaries = true;
14339
+ SwitchCase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14340
+ SwitchCase.prototype.applyDeoptimizations = doNotDeoptimize;
13593
14341
 
13594
14342
  class SwitchStatement extends NodeBase {
13595
14343
  createScope(parentScope) {
@@ -13672,6 +14420,8 @@ class SwitchStatement extends NodeBase {
13672
14420
  }
13673
14421
  }
13674
14422
  }
14423
+ SwitchStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14424
+ SwitchStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13675
14425
 
13676
14426
  class TaggedTemplateExpression extends CallExpressionBase {
13677
14427
  bind() {
@@ -13695,8 +14445,8 @@ class TaggedTemplateExpression extends CallExpressionBase {
13695
14445
  this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
13696
14446
  }
13697
14447
  include(context, includeChildrenRecursively) {
13698
- if (!this.deoptimized)
13699
- this.applyDeoptimizations();
14448
+ if (!this.included)
14449
+ this.includeNode(context);
13700
14450
  if (includeChildrenRecursively) {
13701
14451
  super.include(context, includeChildrenRecursively);
13702
14452
  }
@@ -13705,7 +14455,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
13705
14455
  this.tag.include(context, includeChildrenRecursively);
13706
14456
  this.quasi.include(context, includeChildrenRecursively);
13707
14457
  }
13708
- this.tag.includeCallArguments(context, this.args);
14458
+ this.tag.includeCallArguments(context, this.interaction);
13709
14459
  const [returnExpression] = this.getReturnExpression();
13710
14460
  if (!returnExpression.included) {
13711
14461
  returnExpression.include(context, false);
@@ -13740,6 +14490,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
13740
14490
  return this.returnExpression;
13741
14491
  }
13742
14492
  }
14493
+ TaggedTemplateExpression.prototype.includeNode = onlyIncludeSelf;
13743
14494
 
13744
14495
  class TemplateElement extends NodeBase {
13745
14496
  get tail() {
@@ -13753,15 +14504,13 @@ class TemplateElement extends NodeBase {
13753
14504
  hasEffects() {
13754
14505
  return false;
13755
14506
  }
13756
- include() {
13757
- this.included = true;
13758
- }
13759
14507
  parseNode(esTreeNode) {
13760
14508
  this.value = esTreeNode.value;
13761
14509
  return super.parseNode(esTreeNode);
13762
14510
  }
13763
14511
  render() { }
13764
14512
  }
14513
+ TemplateElement.prototype.includeNode = onlyIncludeSelf;
13765
14514
 
13766
14515
  class TemplateLiteral extends NodeBase {
13767
14516
  deoptimizeArgumentsOnInteractionAtPath() { }
@@ -13786,6 +14535,14 @@ class TemplateLiteral extends NodeBase {
13786
14535
  }
13787
14536
  return true;
13788
14537
  }
14538
+ includeNode(context) {
14539
+ this.included = true;
14540
+ if (!this.deoptimized)
14541
+ this.applyDeoptimizations();
14542
+ for (const node of this.expressions) {
14543
+ node.includePath(UNKNOWN_PATH, context);
14544
+ }
14545
+ }
13789
14546
  render(code, options) {
13790
14547
  code.indentExclusionRanges.push([this.start, this.end]);
13791
14548
  super.render(code, options);
@@ -13795,13 +14552,13 @@ class TemplateLiteral extends NodeBase {
13795
14552
  class ModuleScope extends ChildScope {
13796
14553
  constructor(parent, context) {
13797
14554
  super(parent, context);
13798
- this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, context, 'other'));
14555
+ this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, EMPTY_PATH, context, 'other'));
13799
14556
  }
13800
- addDeclaration(identifier, context, init, kind) {
14557
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
13801
14558
  if (this.context.module.importDescriptions.has(identifier.name)) {
13802
14559
  context.error(logRedeclarationError(identifier.name), identifier.start);
13803
14560
  }
13804
- return super.addDeclaration(identifier, context, init, kind);
14561
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
13805
14562
  }
13806
14563
  addExportDefaultDeclaration(name, exportDefaultDeclaration, context) {
13807
14564
  const variable = new ExportDefaultVariable(name, exportDefaultDeclaration, context);
@@ -13846,10 +14603,23 @@ class ThisExpression extends NodeBase {
13846
14603
  }
13847
14604
  return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
13848
14605
  }
13849
- include() {
14606
+ include(context) {
14607
+ if (!this.included)
14608
+ this.includeNode(context);
14609
+ }
14610
+ includeNode(context) {
14611
+ this.included = true;
14612
+ if (!this.deoptimized)
14613
+ this.applyDeoptimizations();
14614
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
14615
+ }
14616
+ includePath(path, context) {
13850
14617
  if (!this.included) {
13851
14618
  this.included = true;
13852
- this.scope.context.includeVariableInModule(this.variable);
14619
+ this.scope.context.includeVariableInModule(this.variable, path, context);
14620
+ }
14621
+ else if (path.length > 0) {
14622
+ this.variable.includePath(path, context);
13853
14623
  }
13854
14624
  }
13855
14625
  initialise() {
@@ -13877,7 +14647,8 @@ class ThrowStatement extends NodeBase {
13877
14647
  return true;
13878
14648
  }
13879
14649
  include(context, includeChildrenRecursively) {
13880
- this.included = true;
14650
+ if (!this.included)
14651
+ this.includeNode(context);
13881
14652
  this.argument.include(context, includeChildrenRecursively);
13882
14653
  context.brokenFlow = true;
13883
14654
  }
@@ -13888,6 +14659,7 @@ class ThrowStatement extends NodeBase {
13888
14659
  }
13889
14660
  }
13890
14661
  }
14662
+ ThrowStatement.prototype.includeNode = onlyIncludeSelf;
13891
14663
 
13892
14664
  class TryStatement extends NodeBase {
13893
14665
  constructor() {
@@ -13924,6 +14696,8 @@ class TryStatement extends NodeBase {
13924
14696
  this.finalizer?.include(context, includeChildrenRecursively);
13925
14697
  }
13926
14698
  }
14699
+ TryStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14700
+ TryStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13927
14701
 
13928
14702
  const unaryOperators = {
13929
14703
  '!': value => !value,
@@ -13969,6 +14743,7 @@ class UnaryExpression extends NodeBase {
13969
14743
  }
13970
14744
  }
13971
14745
  }
14746
+ UnaryExpression.prototype.includeNode = onlyIncludeSelf;
13972
14747
 
13973
14748
  class UpdateExpression extends NodeBase {
13974
14749
  hasEffects(context) {
@@ -13980,9 +14755,8 @@ class UpdateExpression extends NodeBase {
13980
14755
  return path.length > 1 || type !== INTERACTION_ACCESSED;
13981
14756
  }
13982
14757
  include(context, includeChildrenRecursively) {
13983
- if (!this.deoptimized)
13984
- this.applyDeoptimizations();
13985
- this.included = true;
14758
+ if (!this.included)
14759
+ this.includeNode(context);
13986
14760
  this.argument.includeAsAssignmentTarget(context, includeChildrenRecursively, true);
13987
14761
  }
13988
14762
  initialise() {
@@ -14021,6 +14795,7 @@ class UpdateExpression extends NodeBase {
14021
14795
  this.scope.context.requestTreeshakingPass();
14022
14796
  }
14023
14797
  }
14798
+ UpdateExpression.prototype.includeNode = onlyIncludeSelf;
14024
14799
 
14025
14800
  function areAllDeclarationsIncludedAndNotExported(declarations, exportNamesByVariable) {
14026
14801
  for (const declarator of declarations) {
@@ -14051,8 +14826,9 @@ class VariableDeclaration extends NodeBase {
14051
14826
  include(context, includeChildrenRecursively, { asSingleStatement } = BLANK) {
14052
14827
  this.included = true;
14053
14828
  for (const declarator of this.declarations) {
14054
- if (includeChildrenRecursively || declarator.shouldBeIncluded(context))
14829
+ if (includeChildrenRecursively || declarator.shouldBeIncluded(context)) {
14055
14830
  declarator.include(context, includeChildrenRecursively);
14831
+ }
14056
14832
  const { id, init } = declarator;
14057
14833
  if (asSingleStatement) {
14058
14834
  id.include(context, includeChildrenRecursively);
@@ -14090,7 +14866,6 @@ class VariableDeclaration extends NodeBase {
14090
14866
  this.renderReplacedDeclarations(code, options);
14091
14867
  }
14092
14868
  }
14093
- applyDeoptimizations() { }
14094
14869
  renderDeclarationEnd(code, separatorString, lastSeparatorPos, actualContentEnd, renderedContentEnd, systemPatternExports, options) {
14095
14870
  if (code.original.charCodeAt(this.end - 1) === 59 /*";"*/) {
14096
14871
  code.remove(this.end - 1, this.end);
@@ -14133,8 +14908,7 @@ class VariableDeclaration extends NodeBase {
14133
14908
  const singleSystemExport = gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregatedSystemExports);
14134
14909
  for (const { node, start, separator, contentEnd, end } of separatedNodes) {
14135
14910
  if (!node.included) {
14136
- code.remove(start, end);
14137
- node.removeAnnotations(code);
14911
+ treeshakeNode(node, code, start, end);
14138
14912
  continue;
14139
14913
  }
14140
14914
  node.render(code, options);
@@ -14204,6 +14978,8 @@ function gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregat
14204
14978
  }
14205
14979
  return singleSystemExport;
14206
14980
  }
14981
+ VariableDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14982
+ VariableDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
14207
14983
 
14208
14984
  class WhileStatement extends NodeBase {
14209
14985
  hasEffects(context) {
@@ -14217,13 +14993,25 @@ class WhileStatement extends NodeBase {
14217
14993
  includeLoopBody(context, this.body, includeChildrenRecursively);
14218
14994
  }
14219
14995
  }
14996
+ WhileStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14997
+ WhileStatement.prototype.applyDeoptimizations = doNotDeoptimize;
14220
14998
 
14221
14999
  class YieldExpression extends NodeBase {
15000
+ applyDeoptimizations() {
15001
+ this.deoptimized = true;
15002
+ this.argument?.deoptimizePath(UNKNOWN_PATH);
15003
+ }
14222
15004
  hasEffects(context) {
14223
15005
  if (!this.deoptimized)
14224
15006
  this.applyDeoptimizations();
14225
15007
  return !(context.ignore.returnYield && !this.argument?.hasEffects(context));
14226
15008
  }
15009
+ includeNode(context) {
15010
+ this.included = true;
15011
+ if (!this.deoptimized)
15012
+ this.applyDeoptimizations();
15013
+ this.argument?.includePath(UNKNOWN_PATH, context);
15014
+ }
14227
15015
  render(code, options) {
14228
15016
  if (this.argument) {
14229
15017
  this.argument.render(code, options, { preventASI: true });
@@ -14457,7 +15245,7 @@ const bufferParsers = [
14457
15245
  const annotations = (node.annotations = convertAnnotations(buffer[position + 1], buffer));
14458
15246
  node.annotationNoSideEffects = annotations.some(comment => comment.type === 'noSideEffects');
14459
15247
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 2], buffer));
14460
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
15248
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14461
15249
  node.body = convertNode(node, scope.bodyScope, buffer[position + 3], buffer);
14462
15250
  },
14463
15251
  function assignmentExpression(node, position, buffer) {
@@ -14503,7 +15291,7 @@ const bufferParsers = [
14503
15291
  const parameterPosition = buffer[position];
14504
15292
  const parameter = (node.param =
14505
15293
  parameterPosition === 0 ? null : convertNode(node, scope, parameterPosition, buffer));
14506
- parameter?.declare('parameter', UNKNOWN_EXPRESSION);
15294
+ parameter?.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
14507
15295
  node.body = convertNode(node, scope.bodyScope, buffer[position + 1], buffer);
14508
15296
  },
14509
15297
  function chainExpression(node, position, buffer) {
@@ -14641,7 +15429,7 @@ const bufferParsers = [
14641
15429
  node.id =
14642
15430
  idPosition === 0 ? null : convertNode(node, scope.parent, idPosition, buffer);
14643
15431
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
14644
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
15432
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14645
15433
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
14646
15434
  },
14647
15435
  function functionExpression(node, position, buffer) {
@@ -14654,7 +15442,7 @@ const bufferParsers = [
14654
15442
  const idPosition = buffer[position + 2];
14655
15443
  node.id = idPosition === 0 ? null : convertNode(node, node.idScope, idPosition, buffer);
14656
15444
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
14657
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
15445
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
14658
15446
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
14659
15447
  },
14660
15448
  function identifier(node, position, buffer) {
@@ -15118,8 +15906,8 @@ class ExportShimVariable extends Variable {
15118
15906
  super(MISSING_EXPORT_SHIM_VARIABLE);
15119
15907
  this.module = module;
15120
15908
  }
15121
- include() {
15122
- super.include();
15909
+ includePath(path, context) {
15910
+ super.includePath(path, context);
15123
15911
  this.module.needsExportShim = true;
15124
15912
  }
15125
15913
  }
@@ -15817,16 +16605,15 @@ class Module {
15817
16605
  markModuleAndImpureDependenciesAsExecuted(this);
15818
16606
  this.graph.needsTreeshakingPass = true;
15819
16607
  }
16608
+ const inclusionContext = createInclusionContext();
15820
16609
  for (const exportName of this.exports.keys()) {
15821
16610
  if (includeNamespaceMembers || exportName !== this.info.syntheticNamedExports) {
15822
16611
  const variable = this.getVariableForExportName(exportName)[0];
15823
16612
  if (!variable) {
15824
16613
  return error(logMissingEntryExport(exportName, this.id));
15825
16614
  }
16615
+ this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
15826
16616
  variable.deoptimizePath(UNKNOWN_PATH);
15827
- if (!variable.included) {
15828
- this.includeVariable(variable);
15829
- }
15830
16617
  }
15831
16618
  }
15832
16619
  for (const name of this.getReexports()) {
@@ -15834,7 +16621,7 @@ class Module {
15834
16621
  if (variable) {
15835
16622
  variable.deoptimizePath(UNKNOWN_PATH);
15836
16623
  if (!variable.included) {
15837
- this.includeVariable(variable);
16624
+ this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
15838
16625
  }
15839
16626
  if (variable instanceof ExternalVariable) {
15840
16627
  variable.module.reexported = true;
@@ -15855,13 +16642,12 @@ class Module {
15855
16642
  this.graph.needsTreeshakingPass = true;
15856
16643
  }
15857
16644
  let includeNamespaceMembers = false;
16645
+ const inclusionContext = createInclusionContext();
15858
16646
  for (const name of names) {
15859
16647
  const variable = this.getVariableForExportName(name)[0];
15860
16648
  if (variable) {
15861
16649
  variable.deoptimizePath(UNKNOWN_PATH);
15862
- if (!variable.included) {
15863
- this.includeVariable(variable);
15864
- }
16650
+ this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
15865
16651
  }
15866
16652
  if (!this.exports.has(name) && !this.reexportDescriptions.has(name)) {
15867
16653
  includeNamespaceMembers = true;
@@ -15962,6 +16748,7 @@ class Module {
15962
16748
  manualPureFunctions: this.graph.pureFunctions,
15963
16749
  module: this,
15964
16750
  moduleContext: this.context,
16751
+ newlyIncludedVariableInits: this.graph.newlyIncludedVariableInits,
15965
16752
  options: this.options,
15966
16753
  requestTreeshakingPass: () => (this.graph.needsTreeshakingPass = true),
15967
16754
  traceExport: (name) => this.getVariableForExportName(name)[0],
@@ -16302,13 +17089,13 @@ class Module {
16302
17089
  for (const module of [this, ...this.exportAllModules]) {
16303
17090
  if (module instanceof ExternalModule) {
16304
17091
  const [externalVariable] = module.getVariableForExportName('*');
16305
- externalVariable.include();
17092
+ externalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
16306
17093
  this.includedImports.add(externalVariable);
16307
17094
  externalNamespaces.add(externalVariable);
16308
17095
  }
16309
17096
  else if (module.info.syntheticNamedExports) {
16310
17097
  const syntheticNamespace = module.getSyntheticNamespace();
16311
- syntheticNamespace.include();
17098
+ syntheticNamespace.includePath(UNKNOWN_PATH, createInclusionContext());
16312
17099
  this.includedImports.add(syntheticNamespace);
16313
17100
  syntheticNamespaces.add(syntheticNamespace);
16314
17101
  }
@@ -16318,7 +17105,9 @@ class Module {
16318
17105
  includeDynamicImport(node) {
16319
17106
  const resolution = this.dynamicImports.find(dynamicImport => dynamicImport.node === node).resolution;
16320
17107
  if (resolution instanceof Module) {
16321
- resolution.includedDynamicImporters.push(this);
17108
+ if (!resolution.includedDynamicImporters.includes(this)) {
17109
+ resolution.includedDynamicImporters.push(this);
17110
+ }
16322
17111
  const importedNames = this.options.treeshake
16323
17112
  ? node.getDeterministicImportedNames()
16324
17113
  : undefined;
@@ -16330,15 +17119,15 @@ class Module {
16330
17119
  }
16331
17120
  }
16332
17121
  }
16333
- includeVariable(variable) {
16334
- const variableModule = variable.module;
16335
- if (variable.included) {
17122
+ includeVariable(variable, path, context) {
17123
+ const { included, module: variableModule } = variable;
17124
+ variable.includePath(path, context);
17125
+ if (included) {
16336
17126
  if (variableModule instanceof Module && variableModule !== this) {
16337
17127
  getAndExtendSideEffectModules(variable, this);
16338
17128
  }
16339
17129
  }
16340
17130
  else {
16341
- variable.include();
16342
17131
  this.graph.needsTreeshakingPass = true;
16343
17132
  if (variableModule instanceof Module) {
16344
17133
  if (!variableModule.isExecuted) {
@@ -16355,8 +17144,8 @@ class Module {
16355
17144
  }
16356
17145
  }
16357
17146
  }
16358
- includeVariableInModule(variable) {
16359
- this.includeVariable(variable);
17147
+ includeVariableInModule(variable, path, context) {
17148
+ this.includeVariable(variable, path, context);
16360
17149
  const variableModule = variable.module;
16361
17150
  if (variableModule && variableModule !== this) {
16362
17151
  this.includedImports.add(variable);
@@ -20953,10 +21742,11 @@ class Graph {
20953
21742
  this.options = options;
20954
21743
  this.astLru = flru(5);
20955
21744
  this.cachedModules = new Map();
20956
- this.deoptimizationTracker = new PathTracker();
21745
+ this.deoptimizationTracker = new EntityPathTracker();
20957
21746
  this.entryModules = [];
20958
21747
  this.modulesById = new Map();
20959
21748
  this.needsTreeshakingPass = false;
21749
+ this.newlyIncludedVariableInits = new Set();
20960
21750
  this.phase = BuildPhase.LOAD_AND_PARSE;
20961
21751
  this.scope = new GlobalScope();
20962
21752
  this.watchFiles = Object.create(null);
@@ -21050,6 +21840,7 @@ class Graph {
21050
21840
  }
21051
21841
  if (this.options.treeshake) {
21052
21842
  let treeshakingPass = 1;
21843
+ this.newlyIncludedVariableInits.clear();
21053
21844
  do {
21054
21845
  timeStart(`treeshaking pass ${treeshakingPass}`, 3);
21055
21846
  this.needsTreeshakingPass = false;
@@ -21074,6 +21865,10 @@ class Graph {
21074
21865
  }
21075
21866
  }
21076
21867
  }
21868
+ for (const entity of this.newlyIncludedVariableInits) {
21869
+ this.newlyIncludedVariableInits.delete(entity);
21870
+ entity.include(createInclusionContext(), false);
21871
+ }
21077
21872
  timeEnd(`treeshaking pass ${treeshakingPass++}`, 3);
21078
21873
  } while (this.needsTreeshakingPass);
21079
21874
  }
@@ -21953,7 +22748,7 @@ createColors();
21953
22748
 
21954
22749
  // @see https://no-color.org
21955
22750
  // @see https://www.npmjs.com/package/chalk
21956
- const { bold, cyan, dim, gray, green, red, underline, yellow } = createColors({
22751
+ const { bold, cyan, dim, red} = createColors({
21957
22752
  useColor: env$1.FORCE_COLOR !== '0' && !env$1.NO_COLOR
21958
22753
  });
21959
22754