@rollup/wasm-node 4.25.0 → 4.27.0-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v4.25.0
4
- Sat, 09 Nov 2024 08:36:52 GMT - commit 42e587e0e37bc0661aa39fe7ad6f1d7fd33f825c
3
+ Rollup.js v4.27.0-0
4
+ Wed, 13 Nov 2024 07:02:42 GMT - commit 5e6074f07843bcbcf26b916c557fdfd81d2adece
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -31,7 +31,7 @@ function _interopNamespaceDefault(e) {
31
31
 
32
32
  const tty__namespace = /*#__PURE__*/_interopNamespaceDefault(tty);
33
33
 
34
- var version = "4.25.0";
34
+ var version = "4.27.0-0";
35
35
 
36
36
  function ensureArray$1(items) {
37
37
  if (Array.isArray(items)) {
@@ -1500,48 +1500,8 @@ const createColors = ({ useColor = isColorSupported } = {}) =>
1500
1500
  );
1501
1501
 
1502
1502
  const {
1503
- reset,
1504
- bold: bold$1,
1505
- dim: dim$1,
1506
- italic,
1507
- underline: underline$1,
1508
- inverse,
1509
- hidden,
1510
- strikethrough,
1511
- black,
1512
- red: red$1,
1513
- green: green$1,
1514
- yellow: yellow$1,
1515
1503
  blue,
1516
- magenta,
1517
- cyan: cyan$1,
1518
- white,
1519
- gray: gray$1,
1520
- bgBlack,
1521
- bgRed,
1522
- bgGreen,
1523
- bgYellow,
1524
- bgBlue,
1525
- bgMagenta,
1526
- bgCyan,
1527
- bgWhite,
1528
- blackBright,
1529
- redBright,
1530
- greenBright,
1531
- yellowBright,
1532
- blueBright,
1533
- magentaBright,
1534
- cyanBright,
1535
- whiteBright,
1536
- bgBlackBright,
1537
- bgRedBright,
1538
- bgGreenBright,
1539
- bgYellowBright,
1540
- bgBlueBright,
1541
- bgMagentaBright,
1542
- bgCyanBright,
1543
- bgWhiteBright,
1544
- } = createColors();
1504
+ cyan: cyan$1} = createColors();
1545
1505
 
1546
1506
  // @see https://no-color.org
1547
1507
  // @see https://www.npmjs.com/package/chalk
@@ -3568,19 +3528,6 @@ function is_reference (node, parent) {
3568
3528
  return false;
3569
3529
  }
3570
3530
 
3571
- const PureFunctionKey = Symbol('PureFunction');
3572
- const getPureFunctions = ({ treeshake }) => {
3573
- const pureFunctions = Object.create(null);
3574
- for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
3575
- let currentFunctions = pureFunctions;
3576
- for (const pathSegment of functionName.split('.')) {
3577
- currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
3578
- }
3579
- currentFunctions[PureFunctionKey] = true;
3580
- }
3581
- return pureFunctions;
3582
- };
3583
-
3584
3531
  const UnknownKey = Symbol('Unknown Key');
3585
3532
  const UnknownNonAccessorKey = Symbol('Unknown Non-Accessor Key');
3586
3533
  const UnknownInteger = Symbol('Unknown Integer');
@@ -3595,7 +3542,7 @@ const UNKNOWN_PATH = [UnknownKey];
3595
3542
  const UNKNOWN_NON_ACCESSOR_PATH = [UnknownNonAccessorKey];
3596
3543
  const UNKNOWN_INTEGER_PATH = [UnknownInteger];
3597
3544
  const EntitiesKey = Symbol('Entities');
3598
- class PathTracker {
3545
+ class EntityPathTracker {
3599
3546
  constructor() {
3600
3547
  this.entityPaths = Object.create(null, {
3601
3548
  [EntitiesKey]: { value: new Set() }
@@ -3620,14 +3567,14 @@ class PathTracker {
3620
3567
  getEntities(path) {
3621
3568
  let currentPaths = this.entityPaths;
3622
3569
  for (const pathSegment of path) {
3623
- currentPaths = currentPaths[pathSegment] =
3624
- currentPaths[pathSegment] ||
3625
- Object.create(null, { [EntitiesKey]: { value: new Set() } });
3570
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
3571
+ [EntitiesKey]: { value: new Set() }
3572
+ });
3626
3573
  }
3627
3574
  return currentPaths[EntitiesKey];
3628
3575
  }
3629
3576
  }
3630
- const SHARED_RECURSION_TRACKER = new PathTracker();
3577
+ const SHARED_RECURSION_TRACKER = new EntityPathTracker();
3631
3578
  class DiscriminatedPathTracker {
3632
3579
  constructor() {
3633
3580
  this.entityPaths = Object.create(null, {
@@ -3637,9 +3584,9 @@ class DiscriminatedPathTracker {
3637
3584
  trackEntityAtPathAndGetIfTracked(path, discriminator, entity) {
3638
3585
  let currentPaths = this.entityPaths;
3639
3586
  for (const pathSegment of path) {
3640
- currentPaths = currentPaths[pathSegment] =
3641
- currentPaths[pathSegment] ||
3642
- Object.create(null, { [EntitiesKey]: { value: new Map() } });
3587
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
3588
+ [EntitiesKey]: { value: new Map() }
3589
+ });
3643
3590
  }
3644
3591
  const trackedEntities = getOrCreate(currentPaths[EntitiesKey], discriminator, (getNewSet));
3645
3592
  if (trackedEntities.has(entity))
@@ -3648,6 +3595,85 @@ class DiscriminatedPathTracker {
3648
3595
  return false;
3649
3596
  }
3650
3597
  }
3598
+ const UNKNOWN_INCLUDED_PATH = Object.freeze({ [UnknownKey]: parseAst_js.EMPTY_OBJECT });
3599
+ class IncludedPathTracker {
3600
+ constructor() {
3601
+ this.includedPaths = null;
3602
+ }
3603
+ includePathAndGetIfIncluded(path) {
3604
+ let included = true;
3605
+ let parent = this;
3606
+ let parentSegment = 'includedPaths';
3607
+ let currentPaths = (this.includedPaths ||=
3608
+ ((included = false), Object.create(null)));
3609
+ for (const pathSegment of path) {
3610
+ // This means from here, all paths are included
3611
+ if (currentPaths[UnknownKey]) {
3612
+ return true;
3613
+ }
3614
+ // Including UnknownKey automatically includes all nested paths.
3615
+ // From above, we know that UnknownKey is not included yet.
3616
+ if (typeof pathSegment === 'symbol') {
3617
+ // Hopefully, this saves some memory over just setting
3618
+ // currentPaths[UnknownKey] = EMPTY_OBJECT
3619
+ parent[parentSegment] = UNKNOWN_INCLUDED_PATH;
3620
+ return false;
3621
+ }
3622
+ parent = currentPaths;
3623
+ parentSegment = pathSegment;
3624
+ currentPaths = currentPaths[pathSegment] ||= ((included = false), Object.create(null));
3625
+ }
3626
+ return included;
3627
+ }
3628
+ includeAllPaths(entity, context, basePath) {
3629
+ const { includedPaths } = this;
3630
+ if (includedPaths) {
3631
+ includeAllPaths(entity, context, basePath, includedPaths);
3632
+ }
3633
+ }
3634
+ }
3635
+ function includeAllPaths(entity, context, basePath, currentPaths) {
3636
+ if (currentPaths[UnknownKey]) {
3637
+ return entity.includePath([...basePath, UnknownKey], context, false);
3638
+ }
3639
+ const keys = Object.keys(currentPaths);
3640
+ if (keys.length === 0) {
3641
+ return entity.includePath(basePath, context, false);
3642
+ }
3643
+ for (const key of keys) {
3644
+ includeAllPaths(entity, context, [...basePath, key], currentPaths[key]);
3645
+ }
3646
+ }
3647
+
3648
+ function createInclusionContext() {
3649
+ return {
3650
+ brokenFlow: false,
3651
+ hasBreak: false,
3652
+ hasContinue: false,
3653
+ includedCallArguments: new Set(),
3654
+ includedLabels: new Set()
3655
+ };
3656
+ }
3657
+ function createHasEffectsContext() {
3658
+ return {
3659
+ accessed: new EntityPathTracker(),
3660
+ assigned: new EntityPathTracker(),
3661
+ brokenFlow: false,
3662
+ called: new DiscriminatedPathTracker(),
3663
+ hasBreak: false,
3664
+ hasContinue: false,
3665
+ ignore: {
3666
+ breaks: false,
3667
+ continues: false,
3668
+ labels: new Set(),
3669
+ returnYield: false,
3670
+ this: false
3671
+ },
3672
+ includedLabels: new Set(),
3673
+ instantiated: new DiscriminatedPathTracker(),
3674
+ replacedVariableInits: new Map()
3675
+ };
3676
+ }
3651
3677
 
3652
3678
  function isFlagSet(flags, flag) {
3653
3679
  return (flags & flag) !== 0;
@@ -3686,12 +3712,12 @@ class ExpressionEntity {
3686
3712
  hasEffectsOnInteractionAtPath(_path, _interaction, _context) {
3687
3713
  return true;
3688
3714
  }
3689
- include(_context, _includeChildrenRecursively, _options) {
3715
+ includePath(_path, _context, _includeChildrenRecursively, _options) {
3690
3716
  this.included = true;
3691
3717
  }
3692
- includeCallArguments(context, parameters) {
3693
- for (const argument of parameters) {
3694
- argument.include(context, false);
3718
+ includeCallArguments(context, interaction) {
3719
+ for (const argument of interaction.args) {
3720
+ argument?.includePath(UNKNOWN_PATH, context, false);
3695
3721
  }
3696
3722
  }
3697
3723
  shouldBeIncluded(_context) {
@@ -3730,6 +3756,19 @@ const NODE_INTERACTION_UNKNOWN_CALL = {
3730
3756
  withNew: false
3731
3757
  };
3732
3758
 
3759
+ const PureFunctionKey = Symbol('PureFunction');
3760
+ const getPureFunctions = ({ treeshake }) => {
3761
+ const pureFunctions = Object.create(null);
3762
+ for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
3763
+ let currentFunctions = pureFunctions;
3764
+ for (const pathSegment of functionName.split('.')) {
3765
+ currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
3766
+ }
3767
+ currentFunctions[PureFunctionKey] = true;
3768
+ }
3769
+ return pureFunctions;
3770
+ };
3771
+
3733
3772
  class Variable extends ExpressionEntity {
3734
3773
  markReassigned() {
3735
3774
  this.isReassigned = true;
@@ -3806,9 +3845,9 @@ class Variable extends ExpressionEntity {
3806
3845
  * has not been included previously. Once a variable is included, it should
3807
3846
  * take care all its declarations are included.
3808
3847
  */
3809
- include() {
3848
+ includePath(path, context) {
3810
3849
  this.included = true;
3811
- this.renderedLikeHoisted?.include();
3850
+ this.renderedLikeHoisted?.includePath(path, context);
3812
3851
  }
3813
3852
  /**
3814
3853
  * Links the rendered name of this variable to another variable and includes
@@ -3840,8 +3879,8 @@ class ExternalVariable extends Variable {
3840
3879
  hasEffectsOnInteractionAtPath(path, { type }) {
3841
3880
  return type !== INTERACTION_ACCESSED || path.length > (this.isNamespace ? 1 : 0);
3842
3881
  }
3843
- include() {
3844
- super.include();
3882
+ includePath(path, context) {
3883
+ super.includePath(path, context);
3845
3884
  this.module.used = true;
3846
3885
  }
3847
3886
  }
@@ -4140,36 +4179,6 @@ const childNodeKeys = {
4140
4179
  YieldExpression: ['argument']
4141
4180
  };
4142
4181
 
4143
- function createInclusionContext() {
4144
- return {
4145
- brokenFlow: false,
4146
- hasBreak: false,
4147
- hasContinue: false,
4148
- includedCallArguments: new Set(),
4149
- includedLabels: new Set()
4150
- };
4151
- }
4152
- function createHasEffectsContext() {
4153
- return {
4154
- accessed: new PathTracker(),
4155
- assigned: new PathTracker(),
4156
- brokenFlow: false,
4157
- called: new DiscriminatedPathTracker(),
4158
- hasBreak: false,
4159
- hasContinue: false,
4160
- ignore: {
4161
- breaks: false,
4162
- continues: false,
4163
- labels: new Set(),
4164
- returnYield: false,
4165
- this: false
4166
- },
4167
- includedLabels: new Set(),
4168
- instantiated: new DiscriminatedPathTracker(),
4169
- replacedVariableInits: new Map()
4170
- };
4171
- }
4172
-
4173
4182
  const INCLUDE_PARAMETERS = 'variables';
4174
4183
  const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN');
4175
4184
  class NodeBase extends ExpressionEntity {
@@ -4238,7 +4247,7 @@ class NodeBase extends ExpressionEntity {
4238
4247
  return (this.hasEffects(context) ||
4239
4248
  this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));
4240
4249
  }
4241
- include(context, includeChildrenRecursively, _options) {
4250
+ includePath(_path, context, includeChildrenRecursively, _options) {
4242
4251
  if (!this.deoptimized)
4243
4252
  this.applyDeoptimizations();
4244
4253
  this.included = true;
@@ -4248,16 +4257,16 @@ class NodeBase extends ExpressionEntity {
4248
4257
  continue;
4249
4258
  if (Array.isArray(value)) {
4250
4259
  for (const child of value) {
4251
- child?.include(context, includeChildrenRecursively);
4260
+ child?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
4252
4261
  }
4253
4262
  }
4254
4263
  else {
4255
- value.include(context, includeChildrenRecursively);
4264
+ value.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
4256
4265
  }
4257
4266
  }
4258
4267
  }
4259
4268
  includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {
4260
- this.include(context, includeChildrenRecursively);
4269
+ this.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
4261
4270
  }
4262
4271
  /**
4263
4272
  * Override to perform special initialisation steps after the scope is
@@ -4719,6 +4728,7 @@ class ObjectEntity extends ExpressionEntity {
4719
4728
  this.unknownIntegerProps = [];
4720
4729
  this.unmatchableGetters = [];
4721
4730
  this.unmatchablePropertiesAndGetters = [];
4731
+ this.unmatchablePropertiesAndSetters = [];
4722
4732
  this.unmatchableSetters = [];
4723
4733
  if (Array.isArray(properties)) {
4724
4734
  this.buildPropertyMaps(properties);
@@ -4953,9 +4963,37 @@ class ObjectEntity extends ExpressionEntity {
4953
4963
  }
4954
4964
  return false;
4955
4965
  }
4966
+ includePath(path, context, includeChildrenRecursively) {
4967
+ this.included = true;
4968
+ const [key, ...subPath] = path;
4969
+ if (key == null || includeChildrenRecursively) {
4970
+ for (const property of this.allProperties) {
4971
+ if (includeChildrenRecursively || property.shouldBeIncluded(context)) {
4972
+ property.includePath(EMPTY_PATH, context, includeChildrenRecursively);
4973
+ }
4974
+ }
4975
+ this.prototypeExpression?.includePath(EMPTY_PATH, context, includeChildrenRecursively);
4976
+ }
4977
+ else {
4978
+ const [includedMembers, includedPath] = typeof key === 'string'
4979
+ ? [
4980
+ [
4981
+ ...new Set([
4982
+ ...(this.propertiesAndGettersByKey[key] || this.unmatchablePropertiesAndGetters),
4983
+ ...(this.propertiesAndSettersByKey[key] || this.unmatchablePropertiesAndSetters)
4984
+ ])
4985
+ ],
4986
+ subPath
4987
+ ]
4988
+ : [this.allProperties, UNKNOWN_PATH];
4989
+ for (const property of includedMembers) {
4990
+ property.includePath(includedPath, context, includeChildrenRecursively);
4991
+ }
4992
+ this.prototypeExpression?.includePath(path, context, includeChildrenRecursively);
4993
+ }
4994
+ }
4956
4995
  buildPropertyMaps(properties) {
4957
- const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchableGetters, unmatchableSetters } = this;
4958
- const unmatchablePropertiesAndSetters = [];
4996
+ const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchablePropertiesAndSetters, unmatchableGetters, unmatchableSetters } = this;
4959
4997
  for (let index = properties.length - 1; index >= 0; index--) {
4960
4998
  const { key, kind, property } = properties[index];
4961
4999
  allProperties.push(property);
@@ -6313,16 +6351,20 @@ class GlobalVariable extends Variable {
6313
6351
  }
6314
6352
 
6315
6353
  class LocalVariable extends Variable {
6316
- constructor(name, declarator, init, context, kind) {
6354
+ constructor(name, declarator, init,
6355
+ /** if this is non-empty, the actual init is this path of this.init */
6356
+ initPath, context, kind) {
6317
6357
  super(name);
6318
6358
  this.init = init;
6359
+ this.initPath = initPath;
6360
+ this.kind = kind;
6319
6361
  this.calledFromTryStatement = false;
6320
6362
  this.additionalInitializers = null;
6363
+ this.includedPathTracker = new IncludedPathTracker();
6321
6364
  this.expressionsToBeDeoptimized = [];
6322
6365
  this.declarations = declarator ? [declarator] : [];
6323
6366
  this.deoptimizationTracker = context.deoptimizationTracker;
6324
6367
  this.module = context.module;
6325
- this.kind = kind;
6326
6368
  }
6327
6369
  addDeclaration(identifier, init) {
6328
6370
  this.declarations.push(identifier);
@@ -6333,7 +6375,6 @@ class LocalVariable extends Variable {
6333
6375
  for (const initializer of this.additionalInitializers) {
6334
6376
  initializer.deoptimizePath(UNKNOWN_PATH);
6335
6377
  }
6336
- this.additionalInitializers = null;
6337
6378
  }
6338
6379
  }
6339
6380
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
@@ -6341,7 +6382,7 @@ class LocalVariable extends Variable {
6341
6382
  deoptimizeInteraction(interaction);
6342
6383
  return;
6343
6384
  }
6344
- recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker), undefined);
6385
+ recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], recursionTracker), undefined);
6345
6386
  }
6346
6387
  deoptimizePath(path) {
6347
6388
  if (this.isReassigned ||
@@ -6355,10 +6396,10 @@ class LocalVariable extends Variable {
6355
6396
  for (const expression of expressionsToBeDeoptimized) {
6356
6397
  expression.deoptimizeCache();
6357
6398
  }
6358
- this.init.deoptimizePath(UNKNOWN_PATH);
6399
+ this.init.deoptimizePath([...this.initPath, UnknownKey]);
6359
6400
  }
6360
6401
  else {
6361
- this.init.deoptimizePath(path);
6402
+ this.init.deoptimizePath([...this.initPath, ...path]);
6362
6403
  }
6363
6404
  }
6364
6405
  getLiteralValueAtPath(path, recursionTracker, origin) {
@@ -6367,7 +6408,7 @@ class LocalVariable extends Variable {
6367
6408
  }
6368
6409
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
6369
6410
  this.expressionsToBeDeoptimized.push(origin);
6370
- return this.init.getLiteralValueAtPath(path, recursionTracker, origin);
6411
+ return this.init.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin);
6371
6412
  }, UnknownValue);
6372
6413
  }
6373
6414
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
@@ -6376,7 +6417,7 @@ class LocalVariable extends Variable {
6376
6417
  }
6377
6418
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
6378
6419
  this.expressionsToBeDeoptimized.push(origin);
6379
- return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
6420
+ return this.init.getReturnExpressionWhenCalledAtPath([...this.initPath, ...path], interaction, recursionTracker, origin);
6380
6421
  }, UNKNOWN_RETURN_EXPRESSION);
6381
6422
  }
6382
6423
  hasEffectsOnInteractionAtPath(path, interaction, context) {
@@ -6385,7 +6426,7 @@ class LocalVariable extends Variable {
6385
6426
  if (this.isReassigned)
6386
6427
  return true;
6387
6428
  return (!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
6388
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
6429
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
6389
6430
  }
6390
6431
  case INTERACTION_ASSIGNED: {
6391
6432
  if (this.included)
@@ -6395,23 +6436,23 @@ class LocalVariable extends Variable {
6395
6436
  if (this.isReassigned)
6396
6437
  return true;
6397
6438
  return (!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
6398
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
6439
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
6399
6440
  }
6400
6441
  case INTERACTION_CALLED: {
6401
6442
  if (this.isReassigned)
6402
6443
  return true;
6403
6444
  return (!(interaction.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this) &&
6404
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
6445
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
6405
6446
  }
6406
6447
  }
6407
6448
  }
6408
- include() {
6409
- if (!this.included) {
6410
- super.include();
6449
+ includePath(path, context) {
6450
+ if (!this.includedPathTracker.includePathAndGetIfIncluded(path)) {
6451
+ super.includePath(path, context);
6411
6452
  for (const declaration of this.declarations) {
6412
6453
  // If node is a default export, it can save a tree-shaking run to include the full declaration now
6413
6454
  if (!declaration.included)
6414
- declaration.include(createInclusionContext(), false);
6455
+ declaration.includePath(EMPTY_PATH, context, false);
6415
6456
  let node = declaration.parent;
6416
6457
  while (!node.included) {
6417
6458
  // We do not want to properly include parents in case they are part of a dead branch
@@ -6422,17 +6463,26 @@ class LocalVariable extends Variable {
6422
6463
  node = node.parent;
6423
6464
  }
6424
6465
  }
6466
+ // We need to make sure we include the correct path of the init
6467
+ if (path.length > 0) {
6468
+ this.init.includePath([...this.initPath, ...path], context, false);
6469
+ this.additionalInitializers?.forEach(initializer => initializer.includePath(UNKNOWN_PATH, context, false));
6470
+ }
6425
6471
  }
6426
6472
  }
6427
- includeCallArguments(context, parameters) {
6428
- if (this.isReassigned || context.includedCallArguments.has(this.init)) {
6429
- for (const argument of parameters) {
6430
- argument.include(context, false);
6473
+ includeCallArguments(context, interaction) {
6474
+ if (this.isReassigned ||
6475
+ context.includedCallArguments.has(this.init) ||
6476
+ // This can be removed again once we can include arguments when called at
6477
+ // a specific path
6478
+ this.initPath.length > 0) {
6479
+ for (const argument of interaction.args) {
6480
+ argument?.includePath(UNKNOWN_PATH, context, false);
6431
6481
  }
6432
6482
  }
6433
6483
  else {
6434
6484
  context.includedCallArguments.add(this.init);
6435
- this.init.includeCallArguments(context, parameters);
6485
+ this.init.includeCallArguments(context, interaction);
6436
6486
  context.includedCallArguments.delete(this.init);
6437
6487
  }
6438
6488
  }
@@ -6512,18 +6562,21 @@ class IdentifierBase extends NodeBase {
6512
6562
  }
6513
6563
  }
6514
6564
  }
6515
- include() {
6565
+ includePath(path, context) {
6516
6566
  if (!this.deoptimized)
6517
6567
  this.applyDeoptimizations();
6518
6568
  if (!this.included) {
6519
6569
  this.included = true;
6520
6570
  if (this.variable !== null) {
6521
- this.scope.context.includeVariableInModule(this.variable);
6571
+ this.scope.context.includeVariableInModule(this.variable, path);
6522
6572
  }
6523
6573
  }
6574
+ else if (path.length > 0) {
6575
+ this.variable?.includePath(path, context);
6576
+ }
6524
6577
  }
6525
- includeCallArguments(context, parameters) {
6526
- this.variable.includeCallArguments(context, parameters);
6578
+ includeCallArguments(context, interaction) {
6579
+ this.variable.includeCallArguments(context, interaction);
6527
6580
  }
6528
6581
  isPossibleTDZ() {
6529
6582
  // return cached value to avoid issues with the next tree-shaking pass
@@ -6606,11 +6659,40 @@ function closestParentFunctionOrProgram(node) {
6606
6659
  return node;
6607
6660
  }
6608
6661
 
6662
+ class ObjectMember extends ExpressionEntity {
6663
+ constructor(object, path) {
6664
+ super();
6665
+ this.object = object;
6666
+ this.path = path;
6667
+ }
6668
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6669
+ this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.path, ...path], recursionTracker);
6670
+ }
6671
+ deoptimizePath(path) {
6672
+ this.object.deoptimizePath([...this.path, ...path]);
6673
+ }
6674
+ getLiteralValueAtPath(path, recursionTracker, origin) {
6675
+ return this.object.getLiteralValueAtPath([...this.path, ...path], recursionTracker, origin);
6676
+ }
6677
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
6678
+ return this.object.getReturnExpressionWhenCalledAtPath([...this.path, ...path], interaction, recursionTracker, origin);
6679
+ }
6680
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
6681
+ return this.object.hasEffectsOnInteractionAtPath([...this.path, ...path], interaction, context);
6682
+ }
6683
+ }
6684
+
6609
6685
  class Identifier extends IdentifierBase {
6610
6686
  constructor() {
6611
6687
  super(...arguments);
6612
6688
  this.variable = null;
6613
6689
  }
6690
+ get isDestructuringDeoptimized() {
6691
+ return isFlagSet(this.flags, 8388608 /* Flag.destructuringDeoptimized */);
6692
+ }
6693
+ set isDestructuringDeoptimized(value) {
6694
+ this.flags = setFlag(this.flags, 8388608 /* Flag.destructuringDeoptimized */, value);
6695
+ }
6614
6696
  addExportedVariables(variables, exportNamesByVariable) {
6615
6697
  if (exportNamesByVariable.has(this.variable)) {
6616
6698
  variables.push(this.variable);
@@ -6623,43 +6705,50 @@ class Identifier extends IdentifierBase {
6623
6705
  this.isVariableReference = true;
6624
6706
  }
6625
6707
  }
6626
- declare(kind, init) {
6708
+ declare(kind, destructuredInitPath, init) {
6627
6709
  let variable;
6628
6710
  const { treeshake } = this.scope.context.options;
6629
- switch (kind) {
6630
- case 'var': {
6631
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
6632
- if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
6633
- // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
6634
- variable.markInitializersForDeoptimization();
6635
- }
6636
- break;
6637
- }
6638
- case 'function': {
6639
- // in strict mode, functions are only hoisted within a scope but not across block scopes
6640
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
6641
- break;
6642
- }
6643
- case 'let':
6644
- case 'const':
6645
- case 'using':
6646
- case 'await using':
6647
- case 'class': {
6648
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
6649
- break;
6650
- }
6651
- case 'parameter': {
6652
- variable = this.scope.addParameterDeclaration(this);
6653
- break;
6654
- }
6655
- /* istanbul ignore next */
6656
- default: {
6657
- /* istanbul ignore next */
6658
- throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
6711
+ if (kind === 'parameter') {
6712
+ variable = this.scope.addParameterDeclaration(this, destructuredInitPath);
6713
+ }
6714
+ else {
6715
+ variable = this.scope.addDeclaration(this, this.scope.context, init, destructuredInitPath, kind);
6716
+ if (kind === 'var' && treeshake && treeshake.correctVarValueBeforeDeclaration) {
6717
+ // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
6718
+ variable.markInitializersForDeoptimization();
6659
6719
  }
6660
6720
  }
6661
6721
  return [(this.variable = variable)];
6662
6722
  }
6723
+ deoptimizeAssignment(destructuredInitPath, init) {
6724
+ this.deoptimizePath(EMPTY_PATH);
6725
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
6726
+ }
6727
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
6728
+ return (destructuredInitPath.length > 0 &&
6729
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
6730
+ }
6731
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
6732
+ if (destructuredInitPath.length > 0 && !this.isDestructuringDeoptimized) {
6733
+ this.isDestructuringDeoptimized = true;
6734
+ init.deoptimizeArgumentsOnInteractionAtPath({
6735
+ args: [new ObjectMember(init, destructuredInitPath.slice(0, -1))],
6736
+ type: INTERACTION_ACCESSED
6737
+ }, destructuredInitPath, SHARED_RECURSION_TRACKER);
6738
+ }
6739
+ const { propertyReadSideEffects } = this.scope.context.options
6740
+ .treeshake;
6741
+ if ((this.included ||=
6742
+ destructuredInitPath.length > 0 &&
6743
+ !context.brokenFlow &&
6744
+ propertyReadSideEffects &&
6745
+ (propertyReadSideEffects === 'always' ||
6746
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext())))) {
6747
+ init.includePath(destructuredInitPath, context, false);
6748
+ return true;
6749
+ }
6750
+ return false;
6751
+ }
6663
6752
  markDeclarationReached() {
6664
6753
  this.variable.initReached = true;
6665
6754
  }
@@ -6712,18 +6801,17 @@ class Scope {
6712
6801
  - then the variable is still declared in the hoisted outer scope, but the initializer is assigned to the parameter
6713
6802
  - const, let, class, and function except in the cases above cannot redeclare anything
6714
6803
  */
6715
- addDeclaration(identifier, context, init, kind) {
6804
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
6716
6805
  const name = identifier.name;
6717
6806
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
6718
6807
  if (existingVariable) {
6719
- const existingKind = existingVariable.kind;
6720
- if (kind === 'var' && existingKind === 'var') {
6808
+ if (kind === 'var' && existingVariable.kind === 'var') {
6721
6809
  existingVariable.addDeclaration(identifier, init);
6722
6810
  return existingVariable;
6723
6811
  }
6724
6812
  context.error(parseAst_js.logRedeclarationError(name), identifier.start);
6725
6813
  }
6726
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
6814
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
6727
6815
  this.variables.set(name, newVariable);
6728
6816
  return newVariable;
6729
6817
  }
@@ -6925,7 +7013,7 @@ class BlockScope extends ChildScope {
6925
7013
  constructor(parent) {
6926
7014
  super(parent, parent.context);
6927
7015
  }
6928
- addDeclaration(identifier, context, init, kind) {
7016
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
6929
7017
  if (kind === 'var') {
6930
7018
  const name = identifier.name;
6931
7019
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -6937,7 +7025,7 @@ class BlockScope extends ChildScope {
6937
7025
  }
6938
7026
  return context.error(parseAst_js.logRedeclarationError(name), identifier.start);
6939
7027
  }
6940
- const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind);
7028
+ const declaredVariable = this.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
6941
7029
  // Necessary to make sure the init is deoptimized for conditional declarations.
6942
7030
  // We cannot call deoptimizePath here.
6943
7031
  declaredVariable.markInitializersForDeoptimization();
@@ -6945,7 +7033,7 @@ class BlockScope extends ChildScope {
6945
7033
  this.addHoistedVariable(name, declaredVariable);
6946
7034
  return declaredVariable;
6947
7035
  }
6948
- return super.addDeclaration(identifier, context, init, kind);
7036
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
6949
7037
  }
6950
7038
  }
6951
7039
 
@@ -6960,11 +7048,11 @@ class StaticBlock extends NodeBase {
6960
7048
  }
6961
7049
  return false;
6962
7050
  }
6963
- include(context, includeChildrenRecursively) {
7051
+ includePath(_path, context, includeChildrenRecursively) {
6964
7052
  this.included = true;
6965
7053
  for (const node of this.body) {
6966
7054
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
6967
- node.include(context, includeChildrenRecursively);
7055
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
6968
7056
  }
6969
7057
  }
6970
7058
  render(code, options) {
@@ -6981,29 +7069,6 @@ function isStaticBlock(statement) {
6981
7069
  return statement.type === parseAst_js.StaticBlock;
6982
7070
  }
6983
7071
 
6984
- class ObjectMember extends ExpressionEntity {
6985
- constructor(object, key) {
6986
- super();
6987
- this.object = object;
6988
- this.key = key;
6989
- }
6990
- deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6991
- this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker);
6992
- }
6993
- deoptimizePath(path) {
6994
- this.object.deoptimizePath([this.key, ...path]);
6995
- }
6996
- getLiteralValueAtPath(path, recursionTracker, origin) {
6997
- return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin);
6998
- }
6999
- getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
7000
- return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin);
7001
- }
7002
- hasEffectsOnInteractionAtPath(path, interaction, context) {
7003
- return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context);
7004
- }
7005
- }
7006
-
7007
7072
  class ClassNode extends NodeBase {
7008
7073
  constructor() {
7009
7074
  super(...arguments);
@@ -7043,22 +7108,22 @@ class ClassNode extends NodeBase {
7043
7108
  false
7044
7109
  : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
7045
7110
  }
7046
- include(context, includeChildrenRecursively) {
7111
+ includePath(_path, context, includeChildrenRecursively) {
7047
7112
  if (!this.deoptimized)
7048
7113
  this.applyDeoptimizations();
7049
7114
  this.included = true;
7050
- this.superClass?.include(context, includeChildrenRecursively);
7051
- this.body.include(context, includeChildrenRecursively);
7115
+ this.superClass?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7116
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7052
7117
  for (const decorator of this.decorators)
7053
- decorator.include(context, includeChildrenRecursively);
7118
+ decorator.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7054
7119
  if (this.id) {
7055
7120
  this.id.markDeclarationReached();
7056
- this.id.include();
7121
+ this.id.includePath(UNKNOWN_PATH, createInclusionContext());
7057
7122
  }
7058
7123
  }
7059
7124
  initialise() {
7060
7125
  super.initialise();
7061
- this.id?.declare('class', this);
7126
+ this.id?.declare('class', EMPTY_PATH, this);
7062
7127
  for (const method of this.body.body) {
7063
7128
  if (method instanceof MethodDefinition && method.kind === 'constructor') {
7064
7129
  this.classConstructor = method;
@@ -7116,7 +7181,7 @@ class ClassNode extends NodeBase {
7116
7181
  staticProperties.unshift({
7117
7182
  key: 'prototype',
7118
7183
  kind: 'init',
7119
- property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE)
7184
+ property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, ['prototype']) : OBJECT_PROTOTYPE)
7120
7185
  });
7121
7186
  return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE));
7122
7187
  }
@@ -7173,7 +7238,7 @@ class ClassDeclaration extends ClassNode {
7173
7238
 
7174
7239
  class ArgumentsVariable extends LocalVariable {
7175
7240
  constructor(context) {
7176
- super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');
7241
+ super('arguments', null, UNKNOWN_EXPRESSION, EMPTY_PATH, context, 'other');
7177
7242
  this.deoptimizedArguments = [];
7178
7243
  }
7179
7244
  addArgumentToBeDeoptimized(argument) {
@@ -7187,8 +7252,8 @@ class ArgumentsVariable extends LocalVariable {
7187
7252
  hasEffectsOnInteractionAtPath(path, { type }) {
7188
7253
  return type !== INTERACTION_ACCESSED || path.length > 1;
7189
7254
  }
7190
- include() {
7191
- super.include();
7255
+ includePath(path, context) {
7256
+ super.includePath(path, context);
7192
7257
  for (const argument of this.deoptimizedArguments) {
7193
7258
  argument.deoptimizePath(UNKNOWN_PATH);
7194
7259
  }
@@ -7199,27 +7264,28 @@ class ArgumentsVariable extends LocalVariable {
7199
7264
  const MAX_TRACKED_INTERACTIONS = 20;
7200
7265
  const NO_INTERACTIONS = parseAst_js.EMPTY_ARRAY;
7201
7266
  const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);
7202
- const EMPTY_PATH_TRACKER = new PathTracker();
7267
+ const EMPTY_PATH_TRACKER = new EntityPathTracker();
7203
7268
  const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);
7204
7269
  class ParameterVariable extends LocalVariable {
7205
- constructor(name, declarator, context) {
7206
- super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');
7270
+ constructor(name, declarator, argumentPath, context) {
7271
+ super(name, declarator, UNKNOWN_EXPRESSION, argumentPath, context, 'parameter');
7207
7272
  this.deoptimizationInteractions = [];
7208
- this.deoptimizations = new PathTracker();
7273
+ this.deoptimizations = new EntityPathTracker();
7209
7274
  this.deoptimizedFields = new Set();
7210
- this.entitiesToBeDeoptimized = new Set();
7211
- this.expressionsUseTheKnownValue = [];
7275
+ this.argumentsToBeDeoptimized = new Set();
7276
+ this.expressionsDependingOnKnownValue = [];
7212
7277
  this.knownValue = null;
7213
7278
  this.knownValueLiteral = UnknownValue;
7214
7279
  this.frozenValue = null;
7215
7280
  }
7216
- addEntityToBeDeoptimized(entity) {
7281
+ addArgumentValue(entity) {
7282
+ this.updateKnownValue(entity);
7217
7283
  if (entity === UNKNOWN_EXPRESSION) {
7218
7284
  // As unknown expressions fully deoptimize all interactions, we can clear
7219
7285
  // the interaction cache at this point provided we keep this optimization
7220
7286
  // in mind when adding new interactions
7221
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7222
- this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);
7287
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7288
+ this.argumentsToBeDeoptimized.add(UNKNOWN_EXPRESSION);
7223
7289
  for (const { interaction } of this.deoptimizationInteractions) {
7224
7290
  deoptimizeInteraction(interaction);
7225
7291
  }
@@ -7229,27 +7295,30 @@ class ParameterVariable extends LocalVariable {
7229
7295
  else if (this.deoptimizedFields.has(UnknownKey)) {
7230
7296
  // This means that we already deoptimized all interactions and no longer
7231
7297
  // track them
7232
- entity.deoptimizePath(UNKNOWN_PATH);
7298
+ entity.deoptimizePath([...this.initPath, UnknownKey]);
7233
7299
  }
7234
- else if (!this.entitiesToBeDeoptimized.has(entity)) {
7235
- this.entitiesToBeDeoptimized.add(entity);
7300
+ else if (!this.argumentsToBeDeoptimized.has(entity)) {
7301
+ this.argumentsToBeDeoptimized.add(entity);
7236
7302
  for (const field of this.deoptimizedFields) {
7237
- entity.deoptimizePath([field]);
7303
+ entity.deoptimizePath([...this.initPath, field]);
7238
7304
  }
7239
7305
  for (const { interaction, path } of this.deoptimizationInteractions) {
7240
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
7306
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
7241
7307
  }
7242
7308
  }
7243
7309
  }
7310
+ /** This says we should not make assumptions about the value of the parameter.
7311
+ * This is different from deoptimization that will also cause argument values
7312
+ * to be deoptimized. */
7244
7313
  markReassigned() {
7245
7314
  if (this.isReassigned) {
7246
7315
  return;
7247
7316
  }
7248
7317
  super.markReassigned();
7249
- for (const expression of this.expressionsUseTheKnownValue) {
7318
+ for (const expression of this.expressionsDependingOnKnownValue) {
7250
7319
  expression.deoptimizeCache();
7251
7320
  }
7252
- this.expressionsUseTheKnownValue = parseAst_js.EMPTY_ARRAY;
7321
+ this.expressionsDependingOnKnownValue = parseAst_js.EMPTY_ARRAY;
7253
7322
  }
7254
7323
  deoptimizeCache() {
7255
7324
  this.markReassigned();
@@ -7266,7 +7335,7 @@ class ParameterVariable extends LocalVariable {
7266
7335
  }
7267
7336
  if (this.knownValue === null) {
7268
7337
  this.knownValue = argument;
7269
- this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
7338
+ this.knownValueLiteral = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
7270
7339
  return;
7271
7340
  }
7272
7341
  // the same literal or identifier, do nothing
@@ -7282,7 +7351,7 @@ class ParameterVariable extends LocalVariable {
7282
7351
  return;
7283
7352
  }
7284
7353
  // add tracking for the new argument
7285
- const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
7354
+ const newValue = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
7286
7355
  if (newValue !== oldValue) {
7287
7356
  this.markReassigned();
7288
7357
  }
@@ -7304,20 +7373,25 @@ class ParameterVariable extends LocalVariable {
7304
7373
  return UnknownValue;
7305
7374
  }
7306
7375
  const knownValue = this.getKnownValue();
7307
- this.expressionsUseTheKnownValue.push(origin);
7308
- return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);
7376
+ this.expressionsDependingOnKnownValue.push(origin);
7377
+ return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin), UnknownValue);
7309
7378
  }
7310
7379
  hasEffectsOnInteractionAtPath(path, interaction, context) {
7311
- if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) {
7380
+ const { type } = interaction;
7381
+ if (this.isReassigned || type === INTERACTION_ASSIGNED) {
7312
7382
  return super.hasEffectsOnInteractionAtPath(path, interaction, context);
7313
7383
  }
7314
- const knownValue = this.getKnownValue();
7315
- return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context);
7384
+ return (!(type === INTERACTION_CALLED
7385
+ ? (interaction.withNew
7386
+ ? context.instantiated
7387
+ : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)
7388
+ : context.accessed.trackEntityAtPathAndGetIfTracked(path, this)) &&
7389
+ this.getKnownValue().hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
7316
7390
  }
7317
7391
  deoptimizeArgumentsOnInteractionAtPath(interaction, path) {
7318
7392
  // For performance reasons, we fully deoptimize all deeper interactions
7319
7393
  if (path.length >= 2 ||
7320
- this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
7394
+ this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
7321
7395
  this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||
7322
7396
  (path.length === 1 &&
7323
7397
  (this.deoptimizedFields.has(UnknownKey) ||
@@ -7326,10 +7400,10 @@ class ParameterVariable extends LocalVariable {
7326
7400
  return;
7327
7401
  }
7328
7402
  if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {
7329
- for (const entity of this.entitiesToBeDeoptimized) {
7330
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
7403
+ for (const entity of this.argumentsToBeDeoptimized) {
7404
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
7331
7405
  }
7332
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7406
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7333
7407
  this.deoptimizationInteractions.push({
7334
7408
  interaction,
7335
7409
  path
@@ -7350,17 +7424,17 @@ class ParameterVariable extends LocalVariable {
7350
7424
  return;
7351
7425
  }
7352
7426
  this.deoptimizedFields.add(key);
7353
- for (const entity of this.entitiesToBeDeoptimized) {
7427
+ for (const entity of this.argumentsToBeDeoptimized) {
7354
7428
  // We do not need a recursion tracker here as we already track whether
7355
7429
  // this field is deoptimized
7356
- entity.deoptimizePath([key]);
7430
+ entity.deoptimizePath([...this.initPath, key]);
7357
7431
  }
7358
7432
  if (key === UnknownKey) {
7359
7433
  // save some memory
7360
7434
  this.deoptimizationInteractions = NO_INTERACTIONS;
7361
7435
  this.deoptimizations = EMPTY_PATH_TRACKER;
7362
7436
  this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;
7363
- this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
7437
+ this.argumentsToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
7364
7438
  }
7365
7439
  }
7366
7440
  getReturnExpressionWhenCalledAtPath(path) {
@@ -7375,11 +7449,14 @@ class ParameterVariable extends LocalVariable {
7375
7449
  }
7376
7450
  return UNKNOWN_RETURN_EXPRESSION;
7377
7451
  }
7452
+ includeArgumentPaths(entity, context) {
7453
+ this.includedPathTracker.includeAllPaths(entity, context, this.initPath);
7454
+ }
7378
7455
  }
7379
7456
 
7380
7457
  class ThisVariable extends ParameterVariable {
7381
7458
  constructor(context) {
7382
- super('this', null, context);
7459
+ super('this', null, EMPTY_PATH, context);
7383
7460
  }
7384
7461
  hasEffectsOnInteractionAtPath(path, interaction, context) {
7385
7462
  return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);
@@ -7391,7 +7468,7 @@ class CatchBodyScope extends ChildScope {
7391
7468
  super(parent, parent.context);
7392
7469
  this.parent = parent;
7393
7470
  }
7394
- addDeclaration(identifier, context, init, kind) {
7471
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
7395
7472
  if (kind === 'var') {
7396
7473
  const name = identifier.name;
7397
7474
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -7404,7 +7481,7 @@ class CatchBodyScope extends ChildScope {
7404
7481
  // the assignment actually goes to the parameter and the var is
7405
7482
  // hoisted without assignment. Locally, it is shadowed by the
7406
7483
  // parameter
7407
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, kind);
7484
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, destructuredInitPath, kind);
7408
7485
  // To avoid the need to rewrite the declaration, we link the variable
7409
7486
  // names. If we ever implement a logic that splits initialization and
7410
7487
  // assignment for hoisted vars, the "renderLikeHoisted" logic can be
@@ -7423,7 +7500,7 @@ class CatchBodyScope extends ChildScope {
7423
7500
  return context.error(parseAst_js.logRedeclarationError(name), identifier.start);
7424
7501
  }
7425
7502
  // We only add parameters to parameter scopes
7426
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, kind);
7503
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
7427
7504
  // Necessary to make sure the init is deoptimized for conditional declarations.
7428
7505
  // We cannot call deoptimizePath here.
7429
7506
  declaredVariable.markInitializersForDeoptimization();
@@ -7431,7 +7508,7 @@ class CatchBodyScope extends ChildScope {
7431
7508
  this.addHoistedVariable(name, declaredVariable);
7432
7509
  return declaredVariable;
7433
7510
  }
7434
- return super.addDeclaration(identifier, context, init, kind);
7511
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
7435
7512
  }
7436
7513
  }
7437
7514
 
@@ -7441,7 +7518,7 @@ class FunctionBodyScope extends ChildScope {
7441
7518
  }
7442
7519
  // There is stuff that is only allowed in function scopes, i.e. functions can
7443
7520
  // be redeclared, functions and var can redeclare each other
7444
- addDeclaration(identifier, context, init, kind) {
7521
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
7445
7522
  const name = identifier.name;
7446
7523
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
7447
7524
  if (existingVariable) {
@@ -7453,7 +7530,7 @@ class FunctionBodyScope extends ChildScope {
7453
7530
  }
7454
7531
  context.error(parseAst_js.logRedeclarationError(name), identifier.start);
7455
7532
  }
7456
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
7533
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
7457
7534
  this.variables.set(name, newVariable);
7458
7535
  return newVariable;
7459
7536
  }
@@ -7462,21 +7539,21 @@ class FunctionBodyScope extends ChildScope {
7462
7539
  class ParameterScope extends ChildScope {
7463
7540
  constructor(parent, isCatchScope) {
7464
7541
  super(parent, parent.context);
7465
- this.parameters = [];
7466
7542
  this.hasRest = false;
7543
+ this.parameters = [];
7467
7544
  this.bodyScope = isCatchScope ? new CatchBodyScope(this) : new FunctionBodyScope(this);
7468
7545
  }
7469
7546
  /**
7470
7547
  * Adds a parameter to this scope. Parameters must be added in the correct
7471
7548
  * order, i.e. from left to right.
7472
7549
  */
7473
- addParameterDeclaration(identifier) {
7550
+ addParameterDeclaration(identifier, argumentPath) {
7474
7551
  const { name, start } = identifier;
7475
7552
  const existingParameter = this.variables.get(name);
7476
7553
  if (existingParameter) {
7477
7554
  return this.context.error(parseAst_js.logDuplicateArgumentNameError(name), start);
7478
7555
  }
7479
- const variable = new ParameterVariable(name, identifier, this.context);
7556
+ const variable = new ParameterVariable(name, identifier, argumentPath, this.context);
7480
7557
  this.variables.set(name, variable);
7481
7558
  // We also add it to the body scope to detect name conflicts with local
7482
7559
  // variables. We still need the intermediate scope, though, as parameter
@@ -7494,43 +7571,54 @@ class ParameterScope extends ChildScope {
7494
7571
  }
7495
7572
  this.hasRest = hasRest;
7496
7573
  }
7497
- includeCallArguments(context, parameters) {
7574
+ includeCallArguments(context, interaction) {
7498
7575
  let calledFromTryStatement = false;
7499
7576
  let argumentIncluded = false;
7500
7577
  const restParameter = this.hasRest && this.parameters[this.parameters.length - 1];
7501
- for (const checkedArgument of parameters) {
7502
- if (checkedArgument instanceof SpreadElement) {
7503
- for (const argument of parameters) {
7504
- argument.include(context, false);
7505
- }
7506
- break;
7578
+ const { args } = interaction;
7579
+ let lastExplicitlyIncludedIndex = args.length - 1;
7580
+ // If there is a SpreadElement, we need to include all arguments after it
7581
+ // because we no longer know which argument corresponds to which parameter.
7582
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
7583
+ if (args[argumentIndex] instanceof SpreadElement && !argumentIncluded) {
7584
+ argumentIncluded = true;
7585
+ lastExplicitlyIncludedIndex = argumentIndex - 1;
7586
+ }
7587
+ if (argumentIncluded) {
7588
+ args[argumentIndex].includePath(UNKNOWN_PATH, context, false);
7507
7589
  }
7508
7590
  }
7509
- for (let index = parameters.length - 1; index >= 0; index--) {
7510
- const parameterVariables = this.parameters[index] || restParameter;
7511
- const argument = parameters[index];
7591
+ // Now we go backwards either starting from the last argument or before the
7592
+ // first SpreadElement to ensure all arguments before are included as needed
7593
+ for (let index = lastExplicitlyIncludedIndex; index >= 1; index--) {
7594
+ const parameterVariables = this.parameters[index - 1] || restParameter;
7595
+ const argument = args[index];
7512
7596
  if (parameterVariables) {
7513
7597
  calledFromTryStatement = false;
7514
7598
  if (parameterVariables.length === 0) {
7515
- // handle empty destructuring
7599
+ // handle empty destructuring to avoid destructuring undefined
7516
7600
  argumentIncluded = true;
7517
7601
  }
7518
7602
  else {
7519
7603
  for (const variable of parameterVariables) {
7520
- if (variable.included) {
7521
- argumentIncluded = true;
7522
- }
7523
7604
  if (variable.calledFromTryStatement) {
7524
7605
  calledFromTryStatement = true;
7525
7606
  }
7607
+ if (variable.included) {
7608
+ argumentIncluded = true;
7609
+ if (calledFromTryStatement) {
7610
+ argument.includePath(UNKNOWN_PATH, context, true);
7611
+ }
7612
+ else {
7613
+ variable.includeArgumentPaths(argument, context);
7614
+ }
7615
+ }
7526
7616
  }
7527
7617
  }
7528
7618
  }
7529
- if (!argumentIncluded && argument.shouldBeIncluded(context)) {
7619
+ if (!argument.included && (argumentIncluded || argument.shouldBeIncluded(context))) {
7530
7620
  argumentIncluded = true;
7531
- }
7532
- if (argumentIncluded) {
7533
- argument.include(context, calledFromTryStatement);
7621
+ argument.includePath(EMPTY_PATH, context, calledFromTryStatement);
7534
7622
  }
7535
7623
  }
7536
7624
  }
@@ -7545,11 +7633,61 @@ class ReturnValueScope extends ParameterScope {
7545
7633
  addReturnExpression(expression) {
7546
7634
  this.returnExpressions.push(expression);
7547
7635
  }
7636
+ deoptimizeArgumentsOnCall(interaction) {
7637
+ const { parameters } = this;
7638
+ const { args } = interaction;
7639
+ let position = 0;
7640
+ for (; position < args.length - 1; position++) {
7641
+ // Only the "this" argument arg[0] can be null
7642
+ const argument = args[position + 1];
7643
+ if (argument instanceof SpreadElement) {
7644
+ // This deoptimizes the current and remaining parameters and arguments
7645
+ for (; position < parameters.length; position++) {
7646
+ args[position + 1]?.deoptimizePath(UNKNOWN_PATH);
7647
+ parameters[position].forEach(variable => variable.markReassigned());
7648
+ }
7649
+ break;
7650
+ }
7651
+ if (this.hasRest && position >= parameters.length - 1) {
7652
+ argument.deoptimizePath(UNKNOWN_PATH);
7653
+ }
7654
+ else {
7655
+ const variables = parameters[position];
7656
+ if (variables) {
7657
+ for (const variable of variables) {
7658
+ variable.addArgumentValue(argument);
7659
+ }
7660
+ }
7661
+ this.addArgumentToBeDeoptimized(argument);
7662
+ }
7663
+ }
7664
+ for (; position < parameters.length; position++) {
7665
+ for (const variable of parameters[position]) {
7666
+ variable.addArgumentValue(UNDEFINED_EXPRESSION);
7667
+ }
7668
+ }
7669
+ }
7548
7670
  getReturnExpression() {
7549
7671
  if (this.returnExpression === null)
7550
7672
  this.updateReturnExpression();
7551
7673
  return this.returnExpression;
7552
7674
  }
7675
+ deoptimizeAllParameters() {
7676
+ for (const parameter of this.parameters) {
7677
+ for (const variable of parameter) {
7678
+ variable.deoptimizePath(UNKNOWN_PATH);
7679
+ variable.markReassigned();
7680
+ }
7681
+ }
7682
+ }
7683
+ reassignAllParameters() {
7684
+ for (const parameter of this.parameters) {
7685
+ for (const variable of parameter) {
7686
+ variable.markReassigned();
7687
+ }
7688
+ }
7689
+ }
7690
+ addArgumentToBeDeoptimized(_argument) { }
7553
7691
  updateReturnExpression() {
7554
7692
  if (this.returnExpressions.length === 1) {
7555
7693
  this.returnExpression = this.returnExpressions[0];
@@ -7565,24 +7703,26 @@ class ReturnValueScope extends ParameterScope {
7565
7703
 
7566
7704
  class FunctionScope extends ReturnValueScope {
7567
7705
  constructor(parent) {
7568
- const { context } = parent;
7569
7706
  super(parent, false);
7707
+ const { context } = parent;
7570
7708
  this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));
7571
7709
  this.variables.set('this', (this.thisVariable = new ThisVariable(context)));
7572
7710
  }
7573
7711
  findLexicalBoundary() {
7574
7712
  return this;
7575
7713
  }
7576
- includeCallArguments(context, parameters) {
7577
- super.includeCallArguments(context, parameters);
7714
+ includeCallArguments(context, interaction) {
7715
+ super.includeCallArguments(context, interaction);
7578
7716
  if (this.argumentsVariable.included) {
7579
- for (const argument of parameters) {
7580
- if (!argument.included) {
7581
- argument.include(context, false);
7582
- }
7717
+ const { args } = interaction;
7718
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
7719
+ args[argumentIndex]?.includePath(UNKNOWN_PATH, context, false);
7583
7720
  }
7584
7721
  }
7585
7722
  }
7723
+ addArgumentToBeDeoptimized(argument) {
7724
+ this.argumentsVariable.addArgumentToBeDeoptimized(argument);
7725
+ }
7586
7726
  }
7587
7727
 
7588
7728
  class ExpressionStatement extends NodeBase {
@@ -7648,7 +7788,7 @@ class BlockStatement extends NodeBase {
7648
7788
  }
7649
7789
  return false;
7650
7790
  }
7651
- include(context, includeChildrenRecursively) {
7791
+ includePath(_path, context, includeChildrenRecursively) {
7652
7792
  if (!(this.deoptimizeBody && this.directlyIncluded)) {
7653
7793
  this.included = true;
7654
7794
  this.directlyIncluded = true;
@@ -7656,7 +7796,7 @@ class BlockStatement extends NodeBase {
7656
7796
  includeChildrenRecursively = true;
7657
7797
  for (const node of this.body) {
7658
7798
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
7659
- node.include(context, includeChildrenRecursively);
7799
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7660
7800
  }
7661
7801
  }
7662
7802
  }
@@ -7685,9 +7825,12 @@ class RestElement extends NodeBase {
7685
7825
  addExportedVariables(variables, exportNamesByVariable) {
7686
7826
  this.argument.addExportedVariables(variables, exportNamesByVariable);
7687
7827
  }
7688
- declare(kind, init) {
7828
+ declare(kind, destructuredInitPath, init) {
7689
7829
  this.declarationInit = init;
7690
- return this.argument.declare(kind, UNKNOWN_EXPRESSION);
7830
+ return this.argument.declare(kind, getIncludedPatternPath$1(destructuredInitPath), init);
7831
+ }
7832
+ deoptimizeAssignment(destructuredInitPath, init) {
7833
+ this.argument.deoptimizeAssignment(getIncludedPatternPath$1(destructuredInitPath), init);
7691
7834
  }
7692
7835
  deoptimizePath(path) {
7693
7836
  if (path.length === 0) {
@@ -7698,6 +7841,19 @@ class RestElement extends NodeBase {
7698
7841
  return (path.length > 0 ||
7699
7842
  this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
7700
7843
  }
7844
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
7845
+ return this.argument.hasEffectsWhenDestructuring(context, getIncludedPatternPath$1(destructuredInitPath), init);
7846
+ }
7847
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
7848
+ return (this.included =
7849
+ this.argument.includeDestructuredIfNecessary(context, getIncludedPatternPath$1(destructuredInitPath), init) || this.included);
7850
+ }
7851
+ includePath(_path, context, includeChildrenRecursively) {
7852
+ this.included = true;
7853
+ // This should just include the identifier, its properties should be
7854
+ // included where the variable is used.
7855
+ this.argument.includePath(EMPTY_PATH, context, includeChildrenRecursively);
7856
+ }
7701
7857
  markDeclarationReached() {
7702
7858
  this.argument.markDeclarationReached();
7703
7859
  }
@@ -7709,12 +7865,15 @@ class RestElement extends NodeBase {
7709
7865
  }
7710
7866
  }
7711
7867
  }
7868
+ const getIncludedPatternPath$1 = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
7869
+ ? destructuredInitPath
7870
+ : [...destructuredInitPath, UnknownKey];
7712
7871
 
7713
7872
  class FunctionBase extends NodeBase {
7714
7873
  constructor() {
7715
7874
  super(...arguments);
7716
- this.objectEntity = null;
7717
7875
  this.parameterVariableValuesDeoptimized = false;
7876
+ this.includeCallArguments = this.scope.includeCallArguments.bind(this.scope);
7718
7877
  }
7719
7878
  get async() {
7720
7879
  return isFlagSet(this.flags, 256 /* Flag.async */);
@@ -7734,53 +7893,9 @@ class FunctionBase extends NodeBase {
7734
7893
  set generator(value) {
7735
7894
  this.flags = setFlag(this.flags, 4194304 /* Flag.generator */, value);
7736
7895
  }
7737
- updateParameterVariableValues(_arguments) {
7738
- for (let position = 0; position < this.params.length; position++) {
7739
- const parameter = this.params[position];
7740
- if (!(parameter instanceof Identifier)) {
7741
- continue;
7742
- }
7743
- const parameterVariable = parameter.variable;
7744
- const argument = _arguments[position + 1] ?? UNDEFINED_EXPRESSION;
7745
- parameterVariable.updateKnownValue(argument);
7746
- }
7747
- }
7748
- deoptimizeParameterVariableValues() {
7749
- for (const parameter of this.params) {
7750
- if (parameter instanceof Identifier) {
7751
- const parameterVariable = parameter.variable;
7752
- parameterVariable.markReassigned();
7753
- }
7754
- }
7755
- }
7756
7896
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
7757
- if (interaction.type === INTERACTION_CALLED) {
7758
- const { parameters } = this.scope;
7759
- const { args } = interaction;
7760
- let hasRest = false;
7761
- for (let position = 0; position < args.length - 1; position++) {
7762
- const parameter = this.params[position];
7763
- // Only the "this" argument arg[0] can be null
7764
- const argument = args[position + 1];
7765
- if (argument instanceof SpreadElement) {
7766
- this.deoptimizeParameterVariableValues();
7767
- }
7768
- if (hasRest || parameter instanceof RestElement) {
7769
- hasRest = true;
7770
- argument.deoptimizePath(UNKNOWN_PATH);
7771
- }
7772
- else if (parameter instanceof Identifier) {
7773
- parameters[position][0].addEntityToBeDeoptimized(argument);
7774
- this.addArgumentToBeDeoptimized(argument);
7775
- }
7776
- else if (parameter) {
7777
- argument.deoptimizePath(UNKNOWN_PATH);
7778
- }
7779
- else {
7780
- this.addArgumentToBeDeoptimized(argument);
7781
- }
7782
- }
7783
- this.updateParameterVariableValues(args);
7897
+ if (interaction.type === INTERACTION_CALLED && path.length === 0) {
7898
+ this.scope.deoptimizeArgumentsOnCall(interaction);
7784
7899
  }
7785
7900
  else {
7786
7901
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -7792,12 +7907,7 @@ class FunctionBase extends NodeBase {
7792
7907
  // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
7793
7908
  // which means the return expression and parameters need to be reassigned
7794
7909
  this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
7795
- for (const parameterList of this.scope.parameters) {
7796
- for (const parameter of parameterList) {
7797
- parameter.deoptimizePath(UNKNOWN_PATH);
7798
- parameter.markReassigned();
7799
- }
7800
- }
7910
+ this.scope.deoptimizeAllParameters();
7801
7911
  }
7802
7912
  }
7803
7913
  getLiteralValueAtPath(path, recursionTracker, origin) {
@@ -7835,8 +7945,13 @@ class FunctionBase extends NodeBase {
7835
7945
  return true;
7836
7946
  }
7837
7947
  }
7838
- for (const parameter of this.params) {
7839
- if (parameter.hasEffects(context))
7948
+ const { propertyReadSideEffects } = this.scope.context.options
7949
+ .treeshake;
7950
+ for (let index = 0; index < this.params.length; index++) {
7951
+ const parameter = this.params[index];
7952
+ if (parameter.hasEffects(context) ||
7953
+ (propertyReadSideEffects &&
7954
+ parameter.hasEffectsWhenDestructuring(context, EMPTY_PATH, interaction.args[index + 1] || UNDEFINED_EXPRESSION)))
7840
7955
  return true;
7841
7956
  }
7842
7957
  return false;
@@ -7854,22 +7969,19 @@ class FunctionBase extends NodeBase {
7854
7969
  }
7855
7970
  return variable?.getOnlyFunctionCallUsed() ?? false;
7856
7971
  }
7857
- include(context, includeChildrenRecursively) {
7858
- if (!this.parameterVariableValuesDeoptimized && !this.onlyFunctionCallUsed()) {
7972
+ includePath(_path, context, includeChildrenRecursively) {
7973
+ if (!(this.parameterVariableValuesDeoptimized || this.onlyFunctionCallUsed())) {
7859
7974
  this.parameterVariableValuesDeoptimized = true;
7860
- this.deoptimizeParameterVariableValues();
7975
+ this.scope.reassignAllParameters();
7861
7976
  }
7862
7977
  if (!this.deoptimized)
7863
7978
  this.applyDeoptimizations();
7864
7979
  this.included = true;
7865
7980
  const { brokenFlow } = context;
7866
7981
  context.brokenFlow = false;
7867
- this.body.include(context, includeChildrenRecursively);
7982
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7868
7983
  context.brokenFlow = brokenFlow;
7869
7984
  }
7870
- includeCallArguments(context, parameters) {
7871
- this.scope.includeCallArguments(context, parameters);
7872
- }
7873
7985
  initialise() {
7874
7986
  super.initialise();
7875
7987
  if (this.body instanceof BlockStatement) {
@@ -7891,11 +8003,10 @@ class FunctionBase extends NodeBase {
7891
8003
  // so that the scope already knows all parameters and can detect conflicts
7892
8004
  // when parsing the body.
7893
8005
  const parameters = (this.params = params.map((parameter) => new (context.getNodeConstructor(parameter.type))(this, scope).parseNode(parameter)));
7894
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
8006
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
7895
8007
  this.body = new (context.getNodeConstructor(body.type))(this, bodyScope).parseNode(body);
7896
8008
  return super.parseNode(esTreeNode);
7897
8009
  }
7898
- addArgumentToBeDeoptimized(_argument) { }
7899
8010
  applyDeoptimizations() { }
7900
8011
  }
7901
8012
  FunctionBase.prototype.preventChildBlockScope = true;
@@ -7910,13 +8021,13 @@ class FunctionNode extends FunctionBase {
7910
8021
  this.constructedEntity = new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE);
7911
8022
  // This makes sure that all deoptimizations of "this" are applied to the
7912
8023
  // constructed entity.
7913
- this.scope.thisVariable.addEntityToBeDeoptimized(this.constructedEntity);
8024
+ this.scope.thisVariable.addArgumentValue(this.constructedEntity);
7914
8025
  }
7915
8026
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
7916
8027
  super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
7917
8028
  if (interaction.type === INTERACTION_CALLED && path.length === 0 && interaction.args[0]) {
7918
8029
  // args[0] is the "this" argument
7919
- this.scope.thisVariable.addEntityToBeDeoptimized(interaction.args[0]);
8030
+ this.scope.thisVariable.addArgumentValue(interaction.args[0]);
7920
8031
  }
7921
8032
  }
7922
8033
  hasEffects(context) {
@@ -7957,22 +8068,19 @@ class FunctionNode extends FunctionBase {
7957
8068
  }
7958
8069
  return false;
7959
8070
  }
7960
- include(context, includeChildrenRecursively) {
7961
- super.include(context, includeChildrenRecursively);
7962
- this.id?.include();
8071
+ includePath(path, context, includeChildrenRecursively) {
8072
+ super.includePath(path, context, includeChildrenRecursively);
8073
+ this.id?.includePath(UNKNOWN_PATH, createInclusionContext());
7963
8074
  const hasArguments = this.scope.argumentsVariable.included;
7964
8075
  for (const parameter of this.params) {
7965
8076
  if (!(parameter instanceof Identifier) || hasArguments) {
7966
- parameter.include(context, includeChildrenRecursively);
8077
+ parameter.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7967
8078
  }
7968
8079
  }
7969
8080
  }
7970
8081
  initialise() {
7971
8082
  super.initialise();
7972
- this.id?.declare('function', this);
7973
- }
7974
- addArgumentToBeDeoptimized(argument) {
7975
- this.scope.argumentsVariable.addArgumentToBeDeoptimized(argument);
8083
+ this.id?.declare('function', EMPTY_PATH, this);
7976
8084
  }
7977
8085
  getObjectEntity() {
7978
8086
  if (this.objectEntity !== null) {
@@ -8021,10 +8129,11 @@ function getFunctionIdInsertPosition(code, start) {
8021
8129
  return declarationEnd + generatorStarPos + 1;
8022
8130
  }
8023
8131
  class ExportDefaultDeclaration extends NodeBase {
8024
- include(context, includeChildrenRecursively) {
8025
- super.include(context, includeChildrenRecursively);
8132
+ includePath(path, context, includeChildrenRecursively) {
8133
+ this.included = true;
8134
+ this.declaration.includePath(path, context, includeChildrenRecursively);
8026
8135
  if (includeChildrenRecursively) {
8027
- this.scope.context.includeVariableInModule(this.variable);
8136
+ this.scope.context.includeVariableInModule(this.variable, path);
8028
8137
  }
8029
8138
  }
8030
8139
  initialise() {
@@ -8493,6 +8602,10 @@ class MemberExpression extends NodeBase {
8493
8602
  }
8494
8603
  }
8495
8604
  }
8605
+ deoptimizeAssignment(destructuredInitPath, init) {
8606
+ this.deoptimizePath(EMPTY_PATH);
8607
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
8608
+ }
8496
8609
  deoptimizeCache() {
8497
8610
  const { expressionsToBeDeoptimized, object } = this;
8498
8611
  this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;
@@ -8597,29 +8710,43 @@ class MemberExpression extends NodeBase {
8597
8710
  }
8598
8711
  return true;
8599
8712
  }
8600
- include(context, includeChildrenRecursively) {
8713
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
8714
+ return (destructuredInitPath.length > 0 &&
8715
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
8716
+ }
8717
+ includePath(path, context, includeChildrenRecursively) {
8601
8718
  if (!this.deoptimized)
8602
8719
  this.applyDeoptimizations();
8603
- this.includeProperties(context, includeChildrenRecursively);
8720
+ this.includeProperties(path, [this.getPropertyKey(), ...path], context, includeChildrenRecursively);
8604
8721
  }
8605
8722
  includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {
8606
8723
  if (!this.assignmentDeoptimized)
8607
8724
  this.applyAssignmentDeoptimization();
8608
8725
  if (deoptimizeAccess) {
8609
- this.include(context, includeChildrenRecursively);
8726
+ this.includePath([this.getPropertyKey()], context, includeChildrenRecursively);
8610
8727
  }
8611
8728
  else {
8612
- this.includeProperties(context, includeChildrenRecursively);
8729
+ this.includeProperties(EMPTY_PATH, [this.getPropertyKey()], context, includeChildrenRecursively);
8613
8730
  }
8614
8731
  }
8615
- includeCallArguments(context, parameters) {
8732
+ includeCallArguments(context, interaction) {
8616
8733
  if (this.variable) {
8617
- this.variable.includeCallArguments(context, parameters);
8734
+ this.variable.includeCallArguments(context, interaction);
8618
8735
  }
8619
8736
  else {
8620
- super.includeCallArguments(context, parameters);
8737
+ super.includeCallArguments(context, interaction);
8621
8738
  }
8622
8739
  }
8740
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
8741
+ if ((this.included ||=
8742
+ destructuredInitPath.length > 0 &&
8743
+ !context.brokenFlow &&
8744
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext()))) {
8745
+ init.includePath(destructuredInitPath, context, false);
8746
+ return true;
8747
+ }
8748
+ return false;
8749
+ }
8623
8750
  initialise() {
8624
8751
  super.initialise();
8625
8752
  this.propertyKey = getResolvablePropertyKey(this);
@@ -8686,7 +8813,7 @@ class MemberExpression extends NodeBase {
8686
8813
  const variable = this.scope.findVariable(this.object.name);
8687
8814
  if (variable.isNamespace) {
8688
8815
  if (this.variable) {
8689
- this.scope.context.includeVariableInModule(this.variable);
8816
+ this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH);
8690
8817
  }
8691
8818
  this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);
8692
8819
  }
@@ -8713,15 +8840,18 @@ class MemberExpression extends NodeBase {
8713
8840
  (propertyReadSideEffects === 'always' ||
8714
8841
  this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));
8715
8842
  }
8716
- includeProperties(context, includeChildrenRecursively) {
8843
+ includeProperties(includedPath, objectPath, context, includeChildrenRecursively) {
8717
8844
  if (!this.included) {
8718
8845
  this.included = true;
8719
8846
  if (this.variable) {
8720
- this.scope.context.includeVariableInModule(this.variable);
8847
+ this.scope.context.includeVariableInModule(this.variable, includedPath);
8721
8848
  }
8722
8849
  }
8723
- this.object.include(context, includeChildrenRecursively);
8724
- this.property.include(context, includeChildrenRecursively);
8850
+ else if (includedPath.length > 0) {
8851
+ this.variable?.includePath(includedPath, context);
8852
+ }
8853
+ this.object.includePath(objectPath, context, includeChildrenRecursively);
8854
+ this.property.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
8725
8855
  }
8726
8856
  }
8727
8857
  function resolveNamespaceVariables(baseVariable, path, astContext) {
@@ -8764,7 +8894,7 @@ class MetaProperty extends NodeBase {
8764
8894
  hasEffectsOnInteractionAtPath(path, { type }) {
8765
8895
  return path.length > 1 || type !== INTERACTION_ACCESSED;
8766
8896
  }
8767
- include() {
8897
+ includePath() {
8768
8898
  if (!this.included) {
8769
8899
  this.included = true;
8770
8900
  if (this.meta.name === IMPORT) {
@@ -8883,7 +9013,7 @@ class UndefinedVariable extends Variable {
8883
9013
 
8884
9014
  class ExportDefaultVariable extends LocalVariable {
8885
9015
  constructor(name, exportDefaultDeclaration, context) {
8886
- super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');
9016
+ super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, EMPTY_PATH, context, 'other');
8887
9017
  this.hasId = false;
8888
9018
  this.originalId = null;
8889
9019
  this.originalVariable = null;
@@ -9032,8 +9162,8 @@ class NamespaceVariable extends Variable {
9032
9162
  return (!memberVariable ||
9033
9163
  memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));
9034
9164
  }
9035
- include() {
9036
- super.include();
9165
+ includePath(path, context) {
9166
+ super.includePath(path, context);
9037
9167
  this.context.includeAllExports();
9038
9168
  }
9039
9169
  prepare(accessedGlobalsByScope) {
@@ -9126,9 +9256,9 @@ class SyntheticNamedExportVariable extends Variable {
9126
9256
  getName(getPropertyAccess) {
9127
9257
  return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;
9128
9258
  }
9129
- include() {
9130
- super.include();
9131
- this.context.includeVariableInModule(this.syntheticNamespace);
9259
+ includePath(path, context) {
9260
+ super.includePath(path, context);
9261
+ this.context.includeVariableInModule(this.syntheticNamespace, path);
9132
9262
  }
9133
9263
  setRenderNames(baseName, name) {
9134
9264
  super.setRenderNames(baseName, name);
@@ -12327,21 +12457,37 @@ class ArrayPattern extends NodeBase {
12327
12457
  element?.addExportedVariables(variables, exportNamesByVariable);
12328
12458
  }
12329
12459
  }
12330
- declare(kind) {
12460
+ declare(kind, destructuredInitPath, init) {
12331
12461
  const variables = [];
12462
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
12332
12463
  for (const element of this.elements) {
12333
12464
  if (element !== null) {
12334
- variables.push(...element.declare(kind, UNKNOWN_EXPRESSION));
12465
+ variables.push(...element.declare(kind, includedPatternPath, init));
12335
12466
  }
12336
12467
  }
12337
12468
  return variables;
12338
12469
  }
12470
+ deoptimizeAssignment(destructuredInitPath, init) {
12471
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
12472
+ for (const element of this.elements) {
12473
+ element?.deoptimizeAssignment(includedPatternPath, init);
12474
+ }
12475
+ }
12339
12476
  // Patterns can only be deoptimized at the empty path at the moment
12340
12477
  deoptimizePath() {
12341
12478
  for (const element of this.elements) {
12342
12479
  element?.deoptimizePath(EMPTY_PATH);
12343
12480
  }
12344
12481
  }
12482
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
12483
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
12484
+ for (const element of this.elements) {
12485
+ if (element?.hasEffectsWhenDestructuring(context, includedPatternPath, init)) {
12486
+ return true;
12487
+ }
12488
+ }
12489
+ return false;
12490
+ }
12345
12491
  // Patterns are only checked at the empty path at the moment
12346
12492
  hasEffectsOnInteractionAtPath(_path, interaction, context) {
12347
12493
  for (const element of this.elements) {
@@ -12350,12 +12496,24 @@ class ArrayPattern extends NodeBase {
12350
12496
  }
12351
12497
  return false;
12352
12498
  }
12499
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
12500
+ let included = false;
12501
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
12502
+ for (const element of this.elements) {
12503
+ included =
12504
+ element?.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
12505
+ }
12506
+ return (this.included ||= included);
12507
+ }
12353
12508
  markDeclarationReached() {
12354
12509
  for (const element of this.elements) {
12355
12510
  element?.markDeclarationReached();
12356
12511
  }
12357
12512
  }
12358
12513
  }
12514
+ const getIncludedPatternPath = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
12515
+ ? destructuredInitPath
12516
+ : [...destructuredInitPath, UnknownInteger];
12359
12517
 
12360
12518
  class ArrowFunctionExpression extends FunctionBase {
12361
12519
  constructor() {
@@ -12404,11 +12562,11 @@ class ArrowFunctionExpression extends FunctionBase {
12404
12562
  this.parent.callee === this;
12405
12563
  return isIIFE || super.onlyFunctionCallUsed();
12406
12564
  }
12407
- include(context, includeChildrenRecursively) {
12408
- super.include(context, includeChildrenRecursively);
12565
+ includePath(_path, context, includeChildrenRecursively) {
12566
+ super.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12409
12567
  for (const parameter of this.params) {
12410
12568
  if (!(parameter instanceof Identifier)) {
12411
- parameter.include(context, includeChildrenRecursively);
12569
+ parameter.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12412
12570
  }
12413
12571
  }
12414
12572
  }
@@ -12431,13 +12589,18 @@ class ObjectPattern extends NodeBase {
12431
12589
  }
12432
12590
  }
12433
12591
  }
12434
- declare(kind, init) {
12592
+ declare(kind, destructuredInitPath, init) {
12435
12593
  const variables = [];
12436
12594
  for (const property of this.properties) {
12437
- variables.push(...property.declare(kind, init));
12595
+ variables.push(...property.declare(kind, destructuredInitPath, init));
12438
12596
  }
12439
12597
  return variables;
12440
12598
  }
12599
+ deoptimizeAssignment(destructuredInitPath, init) {
12600
+ for (const property of this.properties) {
12601
+ property.deoptimizeAssignment(destructuredInitPath, init);
12602
+ }
12603
+ }
12441
12604
  deoptimizePath(path) {
12442
12605
  if (path.length === 0) {
12443
12606
  for (const property of this.properties) {
@@ -12455,11 +12618,44 @@ class ObjectPattern extends NodeBase {
12455
12618
  }
12456
12619
  return false;
12457
12620
  }
12621
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
12622
+ for (const property of this.properties) {
12623
+ if (property.hasEffectsWhenDestructuring(context, destructuredInitPath, init))
12624
+ return true;
12625
+ }
12626
+ return false;
12627
+ }
12628
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
12629
+ let included = false;
12630
+ for (const property of this.properties) {
12631
+ included =
12632
+ property.includeDestructuredIfNecessary(context, destructuredInitPath, init) || included;
12633
+ }
12634
+ return (this.included ||= included);
12635
+ }
12458
12636
  markDeclarationReached() {
12459
12637
  for (const property of this.properties) {
12460
12638
  property.markDeclarationReached();
12461
12639
  }
12462
12640
  }
12641
+ render(code, options) {
12642
+ if (this.properties.length > 0) {
12643
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
12644
+ let lastSeparatorPos = null;
12645
+ for (const { node, separator, start, end } of separatedNodes) {
12646
+ if (!node.included) {
12647
+ treeshakeNode(node, code, start, end);
12648
+ continue;
12649
+ }
12650
+ lastSeparatorPos = separator;
12651
+ node.render(code, options);
12652
+ }
12653
+ if (lastSeparatorPos) {
12654
+ code.remove(lastSeparatorPos, this.end - 1);
12655
+ }
12656
+ }
12657
+ }
12658
+ applyDeoptimizations() { }
12463
12659
  }
12464
12660
 
12465
12661
  class AssignmentExpression extends NodeBase {
@@ -12469,23 +12665,27 @@ class AssignmentExpression extends NodeBase {
12469
12665
  this.applyDeoptimizations();
12470
12666
  // MemberExpressions do not access the property before assignments if the
12471
12667
  // operator is '='.
12472
- return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '='));
12668
+ return (right.hasEffects(context) ||
12669
+ left.hasEffectsAsAssignmentTarget(context, operator !== '=') ||
12670
+ this.left.hasEffectsWhenDestructuring?.(context, EMPTY_PATH, right));
12473
12671
  }
12474
12672
  hasEffectsOnInteractionAtPath(path, interaction, context) {
12475
12673
  return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);
12476
12674
  }
12477
- include(context, includeChildrenRecursively) {
12675
+ includePath(_path, context, includeChildrenRecursively) {
12478
12676
  const { deoptimized, left, right, operator } = this;
12479
12677
  if (!deoptimized)
12480
12678
  this.applyDeoptimizations();
12481
12679
  this.included = true;
12680
+ const hasEffectsContext = createHasEffectsContext();
12482
12681
  if (includeChildrenRecursively ||
12483
12682
  operator !== '=' ||
12484
12683
  left.included ||
12485
- left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {
12684
+ left.hasEffectsAsAssignmentTarget(hasEffectsContext, false) ||
12685
+ left.hasEffectsWhenDestructuring?.(hasEffectsContext, EMPTY_PATH, right)) {
12486
12686
  left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');
12487
12687
  }
12488
- right.include(context, includeChildrenRecursively);
12688
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12489
12689
  }
12490
12690
  initialise() {
12491
12691
  super.initialise();
@@ -12547,8 +12747,7 @@ class AssignmentExpression extends NodeBase {
12547
12747
  }
12548
12748
  applyDeoptimizations() {
12549
12749
  this.deoptimized = true;
12550
- this.left.deoptimizePath(EMPTY_PATH);
12551
- this.right.deoptimizePath(UNKNOWN_PATH);
12750
+ this.left.deoptimizeAssignment(EMPTY_PATH, this.right);
12552
12751
  this.scope.context.requestTreeshakingPass();
12553
12752
  }
12554
12753
  }
@@ -12557,8 +12756,11 @@ class AssignmentPattern extends NodeBase {
12557
12756
  addExportedVariables(variables, exportNamesByVariable) {
12558
12757
  this.left.addExportedVariables(variables, exportNamesByVariable);
12559
12758
  }
12560
- declare(kind, init) {
12561
- return this.left.declare(kind, init);
12759
+ declare(kind, destructuredInitPath, init) {
12760
+ return this.left.declare(kind, destructuredInitPath, init);
12761
+ }
12762
+ deoptimizeAssignment(destructuredInitPath, init) {
12763
+ this.left.deoptimizeAssignment(destructuredInitPath, init);
12562
12764
  }
12563
12765
  deoptimizePath(path) {
12564
12766
  if (path.length === 0) {
@@ -12568,6 +12770,17 @@ class AssignmentPattern extends NodeBase {
12568
12770
  hasEffectsOnInteractionAtPath(path, interaction, context) {
12569
12771
  return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
12570
12772
  }
12773
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
12774
+ return this.left.hasEffectsWhenDestructuring(context, destructuredInitPath, init);
12775
+ }
12776
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
12777
+ let included = this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init) ||
12778
+ this.included;
12779
+ if ((included ||= this.right.shouldBeIncluded(context))) {
12780
+ this.right.includePath(UNKNOWN_PATH, context, false);
12781
+ }
12782
+ return (this.included = included);
12783
+ }
12571
12784
  markDeclarationReached() {
12572
12785
  this.left.markDeclarationReached();
12573
12786
  }
@@ -12589,7 +12802,7 @@ class AwaitExpression extends NodeBase {
12589
12802
  this.applyDeoptimizations();
12590
12803
  return true;
12591
12804
  }
12592
- include(context, includeChildrenRecursively) {
12805
+ includePath(path, context, includeChildrenRecursively) {
12593
12806
  if (!this.deoptimized)
12594
12807
  this.applyDeoptimizations();
12595
12808
  if (!this.included) {
@@ -12603,7 +12816,7 @@ class AwaitExpression extends NodeBase {
12603
12816
  this.scope.context.usesTopLevelAwait = true;
12604
12817
  }
12605
12818
  }
12606
- this.argument.include(context, includeChildrenRecursively);
12819
+ this.argument.includePath(path, context, includeChildrenRecursively);
12607
12820
  }
12608
12821
  }
12609
12822
 
@@ -12685,10 +12898,10 @@ class BreakStatement extends NodeBase {
12685
12898
  context.brokenFlow = true;
12686
12899
  return false;
12687
12900
  }
12688
- include(context) {
12901
+ includePath(_, context) {
12689
12902
  this.included = true;
12690
12903
  if (this.label) {
12691
- this.label.include();
12904
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
12692
12905
  context.includedLabels.add(this.label.name);
12693
12906
  }
12694
12907
  else {
@@ -12882,11 +13095,11 @@ class CallExpression extends CallExpressionBase {
12882
13095
  (calleeHasEffects ||
12883
13096
  this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)));
12884
13097
  }
12885
- include(context, includeChildrenRecursively) {
13098
+ includePath(path, context, includeChildrenRecursively) {
12886
13099
  if (!this.deoptimized)
12887
13100
  this.applyDeoptimizations();
12888
13101
  if (includeChildrenRecursively) {
12889
- super.include(context, includeChildrenRecursively);
13102
+ super.includePath(path, context, includeChildrenRecursively);
12890
13103
  if (includeChildrenRecursively === INCLUDE_PARAMETERS &&
12891
13104
  this.callee instanceof Identifier &&
12892
13105
  this.callee.variable) {
@@ -12895,9 +13108,18 @@ class CallExpression extends CallExpressionBase {
12895
13108
  }
12896
13109
  else {
12897
13110
  this.included = true;
12898
- this.callee.include(context, false);
13111
+ // If the callee is a member expression and does not have a variable, its
13112
+ // object will already be included via the first argument of the
13113
+ // interaction in includeCallArguments. Including it again can lead to
13114
+ // severe performance problems.
13115
+ if (this.callee instanceof MemberExpression && !this.callee.variable) {
13116
+ this.callee.property.includePath(UNKNOWN_PATH, context, false);
13117
+ }
13118
+ else {
13119
+ this.callee.includePath(UNKNOWN_PATH, context, false);
13120
+ }
13121
+ this.callee.includeCallArguments(context, this.interaction);
12899
13122
  }
12900
- this.callee.includeCallArguments(context, this.arguments);
12901
13123
  }
12902
13124
  initialise() {
12903
13125
  super.initialise();
@@ -12936,7 +13158,7 @@ class CatchClause extends NodeBase {
12936
13158
  this.type = type;
12937
13159
  if (param) {
12938
13160
  this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);
12939
- this.param.declare('parameter', UNKNOWN_EXPRESSION);
13161
+ this.param.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
12940
13162
  }
12941
13163
  this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);
12942
13164
  return super.parseNode(esTreeNode);
@@ -12964,7 +13186,7 @@ class ClassBodyScope extends ChildScope {
12964
13186
  constructor(parent, classNode) {
12965
13187
  const { context } = parent;
12966
13188
  super(parent, context);
12967
- this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));
13189
+ this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, EMPTY_PATH, context, 'other')));
12968
13190
  this.instanceScope = new ChildScope(this, context);
12969
13191
  this.instanceScope.variables.set('this', new ThisVariable(context));
12970
13192
  }
@@ -12977,11 +13199,11 @@ class ClassBody extends NodeBase {
12977
13199
  createScope(parentScope) {
12978
13200
  this.scope = new ClassBodyScope(parentScope, this.parent);
12979
13201
  }
12980
- include(context, includeChildrenRecursively) {
13202
+ includePath(_path, context, includeChildrenRecursively) {
12981
13203
  this.included = true;
12982
- this.scope.context.includeVariableInModule(this.scope.thisVariable);
13204
+ this.scope.context.includeVariableInModule(this.scope.thisVariable, UNKNOWN_PATH);
12983
13205
  for (const definition of this.body) {
12984
- definition.include(context, includeChildrenRecursively);
13206
+ definition.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12985
13207
  }
12986
13208
  }
12987
13209
  parseNode(esTreeNode) {
@@ -13105,26 +13327,26 @@ class ConditionalExpression extends NodeBase {
13105
13327
  }
13106
13328
  return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
13107
13329
  }
13108
- include(context, includeChildrenRecursively) {
13330
+ includePath(path, context, includeChildrenRecursively) {
13109
13331
  this.included = true;
13110
13332
  const usedBranch = this.getUsedBranch();
13111
13333
  if (includeChildrenRecursively || this.test.shouldBeIncluded(context) || usedBranch === null) {
13112
- this.test.include(context, includeChildrenRecursively);
13113
- this.consequent.include(context, includeChildrenRecursively);
13114
- this.alternate.include(context, includeChildrenRecursively);
13334
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13335
+ this.consequent.includePath(path, context, includeChildrenRecursively);
13336
+ this.alternate.includePath(path, context, includeChildrenRecursively);
13115
13337
  }
13116
13338
  else {
13117
- usedBranch.include(context, includeChildrenRecursively);
13339
+ usedBranch.includePath(path, context, includeChildrenRecursively);
13118
13340
  }
13119
13341
  }
13120
- includeCallArguments(context, parameters) {
13342
+ includeCallArguments(context, interaction) {
13121
13343
  const usedBranch = this.getUsedBranch();
13122
13344
  if (usedBranch) {
13123
- usedBranch.includeCallArguments(context, parameters);
13345
+ usedBranch.includeCallArguments(context, interaction);
13124
13346
  }
13125
13347
  else {
13126
- this.consequent.includeCallArguments(context, parameters);
13127
- this.alternate.includeCallArguments(context, parameters);
13348
+ this.consequent.includeCallArguments(context, interaction);
13349
+ this.alternate.includeCallArguments(context, interaction);
13128
13350
  }
13129
13351
  }
13130
13352
  removeAnnotations(code) {
@@ -13185,10 +13407,10 @@ class ContinueStatement extends NodeBase {
13185
13407
  context.brokenFlow = true;
13186
13408
  return false;
13187
13409
  }
13188
- include(context) {
13410
+ includePath(_, context) {
13189
13411
  this.included = true;
13190
13412
  if (this.label) {
13191
- this.label.include();
13413
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
13192
13414
  context.includedLabels.add(this.label.name);
13193
13415
  }
13194
13416
  else {
@@ -13231,7 +13453,7 @@ function includeLoopBody(context, body, includeChildrenRecursively) {
13231
13453
  const { brokenFlow, hasBreak, hasContinue } = context;
13232
13454
  context.hasBreak = false;
13233
13455
  context.hasContinue = false;
13234
- body.include(context, includeChildrenRecursively, { asSingleStatement: true });
13456
+ body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively, { asSingleStatement: true });
13235
13457
  context.hasBreak = hasBreak;
13236
13458
  context.hasContinue = hasContinue;
13237
13459
  context.brokenFlow = brokenFlow;
@@ -13243,9 +13465,9 @@ class DoWhileStatement extends NodeBase {
13243
13465
  return true;
13244
13466
  return hasLoopBodyEffects(context, this.body);
13245
13467
  }
13246
- include(context, includeChildrenRecursively) {
13468
+ includePath(_path, context, includeChildrenRecursively) {
13247
13469
  this.included = true;
13248
- this.test.include(context, includeChildrenRecursively);
13470
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13249
13471
  includeLoopBody(context, this.body, includeChildrenRecursively);
13250
13472
  }
13251
13473
  }
@@ -13316,13 +13538,13 @@ class ForInStatement extends NodeBase {
13316
13538
  return true;
13317
13539
  return hasLoopBodyEffects(context, body);
13318
13540
  }
13319
- include(context, includeChildrenRecursively) {
13541
+ includePath(_path, context, includeChildrenRecursively) {
13320
13542
  const { body, deoptimized, left, right } = this;
13321
13543
  if (!deoptimized)
13322
13544
  this.applyDeoptimizations();
13323
13545
  this.included = true;
13324
13546
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
13325
- right.include(context, includeChildrenRecursively);
13547
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13326
13548
  includeLoopBody(context, body, includeChildrenRecursively);
13327
13549
  }
13328
13550
  initialise() {
@@ -13361,13 +13583,13 @@ class ForOfStatement extends NodeBase {
13361
13583
  // Placeholder until proper Symbol.Iterator support
13362
13584
  return true;
13363
13585
  }
13364
- include(context, includeChildrenRecursively) {
13586
+ includePath(_path, context, includeChildrenRecursively) {
13365
13587
  const { body, deoptimized, left, right } = this;
13366
13588
  if (!deoptimized)
13367
13589
  this.applyDeoptimizations();
13368
13590
  this.included = true;
13369
13591
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
13370
- right.include(context, includeChildrenRecursively);
13592
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13371
13593
  includeLoopBody(context, body, includeChildrenRecursively);
13372
13594
  }
13373
13595
  initialise() {
@@ -13403,11 +13625,13 @@ class ForStatement extends NodeBase {
13403
13625
  }
13404
13626
  return hasLoopBodyEffects(context, this.body);
13405
13627
  }
13406
- include(context, includeChildrenRecursively) {
13628
+ includePath(_path, context, includeChildrenRecursively) {
13407
13629
  this.included = true;
13408
- this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true });
13409
- this.test?.include(context, includeChildrenRecursively);
13410
- this.update?.include(context, includeChildrenRecursively);
13630
+ this.init?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively, {
13631
+ asSingleStatement: true
13632
+ });
13633
+ this.test?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13634
+ this.update?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13411
13635
  includeLoopBody(context, this.body, includeChildrenRecursively);
13412
13636
  }
13413
13637
  render(code, options) {
@@ -13448,9 +13672,9 @@ class TrackingScope extends BlockScope {
13448
13672
  super(...arguments);
13449
13673
  this.hoistedDeclarations = [];
13450
13674
  }
13451
- addDeclaration(identifier, context, init, kind) {
13675
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
13452
13676
  this.hoistedDeclarations.push(identifier);
13453
- return super.addDeclaration(identifier, context, init, kind);
13677
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
13454
13678
  }
13455
13679
  }
13456
13680
 
@@ -13483,7 +13707,7 @@ class IfStatement extends NodeBase {
13483
13707
  }
13484
13708
  return testValue ? this.consequent.hasEffects(context) : !!this.alternate?.hasEffects(context);
13485
13709
  }
13486
- include(context, includeChildrenRecursively) {
13710
+ includePath(_, context, includeChildrenRecursively) {
13487
13711
  this.included = true;
13488
13712
  if (includeChildrenRecursively) {
13489
13713
  this.includeRecursively(includeChildrenRecursively, context);
@@ -13558,31 +13782,31 @@ class IfStatement extends NodeBase {
13558
13782
  }
13559
13783
  includeKnownTest(context, testValue) {
13560
13784
  if (this.test.shouldBeIncluded(context)) {
13561
- this.test.include(context, false);
13785
+ this.test.includePath(UNKNOWN_PATH, context, false);
13562
13786
  }
13563
13787
  if (testValue && this.consequent.shouldBeIncluded(context)) {
13564
- this.consequent.include(context, false, { asSingleStatement: true });
13788
+ this.consequent.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
13565
13789
  }
13566
13790
  if (!testValue && this.alternate?.shouldBeIncluded(context)) {
13567
- this.alternate.include(context, false, { asSingleStatement: true });
13791
+ this.alternate.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
13568
13792
  }
13569
13793
  }
13570
13794
  includeRecursively(includeChildrenRecursively, context) {
13571
- this.test.include(context, includeChildrenRecursively);
13572
- this.consequent.include(context, includeChildrenRecursively);
13573
- this.alternate?.include(context, includeChildrenRecursively);
13795
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13796
+ this.consequent.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13797
+ this.alternate?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13574
13798
  }
13575
13799
  includeUnknownTest(context) {
13576
- this.test.include(context, false);
13800
+ this.test.includePath(UNKNOWN_PATH, context, false);
13577
13801
  const { brokenFlow } = context;
13578
13802
  let consequentBrokenFlow = false;
13579
13803
  if (this.consequent.shouldBeIncluded(context)) {
13580
- this.consequent.include(context, false, { asSingleStatement: true });
13804
+ this.consequent.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
13581
13805
  consequentBrokenFlow = context.brokenFlow;
13582
13806
  context.brokenFlow = brokenFlow;
13583
13807
  }
13584
13808
  if (this.alternate?.shouldBeIncluded(context)) {
13585
- this.alternate.include(context, false, { asSingleStatement: true });
13809
+ this.alternate.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
13586
13810
  context.brokenFlow = context.brokenFlow && consequentBrokenFlow;
13587
13811
  }
13588
13812
  }
@@ -13650,7 +13874,7 @@ function isReassignedExportsMember(variable, exportNamesByVariable) {
13650
13874
  class VariableDeclarator extends NodeBase {
13651
13875
  declareDeclarator(kind, isUsingDeclaration) {
13652
13876
  this.isUsingDeclaration = isUsingDeclaration;
13653
- this.id.declare(kind, this.init || UNDEFINED_EXPRESSION);
13877
+ this.id.declare(kind, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION);
13654
13878
  }
13655
13879
  deoptimizePath(path) {
13656
13880
  this.id.deoptimizePath(path);
@@ -13660,17 +13884,25 @@ class VariableDeclarator extends NodeBase {
13660
13884
  this.applyDeoptimizations();
13661
13885
  const initEffect = this.init?.hasEffects(context);
13662
13886
  this.id.markDeclarationReached();
13663
- return initEffect || this.id.hasEffects(context) || this.isUsingDeclaration;
13664
- }
13665
- include(context, includeChildrenRecursively) {
13887
+ return (initEffect ||
13888
+ this.isUsingDeclaration ||
13889
+ this.id.hasEffects(context) ||
13890
+ (this.scope.context.options.treeshake
13891
+ .propertyReadSideEffects &&
13892
+ this.id.hasEffectsWhenDestructuring(context, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION)));
13893
+ }
13894
+ includePath(_path, context, includeChildrenRecursively) {
13666
13895
  const { deoptimized, id, init } = this;
13667
13896
  if (!deoptimized)
13668
13897
  this.applyDeoptimizations();
13669
13898
  this.included = true;
13670
- init?.include(context, includeChildrenRecursively);
13899
+ init?.includePath(EMPTY_PATH, context, includeChildrenRecursively);
13671
13900
  id.markDeclarationReached();
13672
- if (includeChildrenRecursively || id.shouldBeIncluded(context)) {
13673
- id.include(context, includeChildrenRecursively);
13901
+ if (includeChildrenRecursively) {
13902
+ id.includePath(EMPTY_PATH, context, includeChildrenRecursively);
13903
+ }
13904
+ else {
13905
+ id.includeDestructuredIfNecessary(context, EMPTY_PATH, init || UNDEFINED_EXPRESSION);
13674
13906
  }
13675
13907
  }
13676
13908
  removeAnnotations(code) {
@@ -13719,6 +13951,8 @@ class ImportExpression extends NodeBase {
13719
13951
  constructor() {
13720
13952
  super(...arguments);
13721
13953
  this.inlineNamespace = null;
13954
+ this.hasUnknownAccessedKey = false;
13955
+ this.accessedPropKey = new Set();
13722
13956
  this.attributes = null;
13723
13957
  this.mechanism = null;
13724
13958
  this.namespaceExportName = undefined;
@@ -13751,12 +13985,15 @@ class ImportExpression extends NodeBase {
13751
13985
  if (parent2 instanceof ExpressionStatement) {
13752
13986
  return parseAst_js.EMPTY_ARRAY;
13753
13987
  }
13754
- // Case 1: const { foo } = await import('bar')
13988
+ // Case 1: const { foo } / module = await import('bar')
13755
13989
  if (parent2 instanceof VariableDeclarator) {
13756
13990
  const declaration = parent2.id;
13757
- return declaration instanceof ObjectPattern
13758
- ? getDeterministicObjectDestructure(declaration)
13759
- : undefined;
13991
+ if (declaration instanceof Identifier) {
13992
+ return this.hasUnknownAccessedKey ? undefined : [...this.accessedPropKey];
13993
+ }
13994
+ if (declaration instanceof ObjectPattern) {
13995
+ return getDeterministicObjectDestructure(declaration);
13996
+ }
13760
13997
  }
13761
13998
  // Case 2: (await import('bar')).foo
13762
13999
  if (parent2 instanceof MemberExpression) {
@@ -13805,13 +14042,23 @@ class ImportExpression extends NodeBase {
13805
14042
  hasEffects() {
13806
14043
  return true;
13807
14044
  }
13808
- include(context, includeChildrenRecursively) {
14045
+ includePath(path, context, includeChildrenRecursively) {
13809
14046
  if (!this.included) {
13810
14047
  this.included = true;
13811
14048
  this.scope.context.includeDynamicImport(this);
13812
14049
  this.scope.addAccessedDynamicImport(this);
14050
+ this.source.includePath(path, context, includeChildrenRecursively);
14051
+ }
14052
+ if (this.hasUnknownAccessedKey)
14053
+ return;
14054
+ if (path[0] === UnknownKey) {
14055
+ this.hasUnknownAccessedKey = true;
14056
+ this.scope.context.includeDynamicImport(this);
14057
+ }
14058
+ else if (typeof path[0] === 'string') {
14059
+ this.accessedPropKey.add(path[0]);
14060
+ this.scope.context.includeDynamicImport(this);
13813
14061
  }
13814
- this.source.include(context, includeChildrenRecursively);
13815
14062
  }
13816
14063
  initialise() {
13817
14064
  super.initialise();
@@ -14139,7 +14386,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
14139
14386
  if (preserve) {
14140
14387
  // This pretends we are accessing an included global variable of the same name
14141
14388
  const globalVariable = node.scope.findGlobal(baseName);
14142
- globalVariable.include();
14389
+ globalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
14143
14390
  // This excludes this variable from renaming
14144
14391
  factoryVariable.globalName = baseName;
14145
14392
  }
@@ -14147,7 +14394,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
14147
14394
  else {
14148
14395
  factoryVariable = node.scope.findGlobal(baseName);
14149
14396
  }
14150
- node.scope.context.includeVariableInModule(factoryVariable);
14397
+ node.scope.context.includeVariableInModule(factoryVariable, UNKNOWN_PATH);
14151
14398
  if (factoryVariable instanceof LocalVariable) {
14152
14399
  factoryVariable.consolidateInitializers();
14153
14400
  factoryVariable.addUsedPlace(node);
@@ -14169,7 +14416,7 @@ class JSXElementBase extends NodeBase {
14169
14416
  this.scope.context.addImportSource(importSource);
14170
14417
  }
14171
14418
  }
14172
- include(context, includeChildrenRecursively) {
14419
+ includePath(path, context, includeChildrenRecursively) {
14173
14420
  if (!this.included) {
14174
14421
  const { factory, importSource, mode } = this.jsxMode;
14175
14422
  if (factory) {
@@ -14177,7 +14424,7 @@ class JSXElementBase extends NodeBase {
14177
14424
  this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this);
14178
14425
  }
14179
14426
  }
14180
- super.include(context, includeChildrenRecursively);
14427
+ super.includePath(path, context, includeChildrenRecursively);
14181
14428
  }
14182
14429
  applyDeoptimizations() { }
14183
14430
  getRenderingMode() {
@@ -14439,7 +14686,7 @@ class JSXOpeningFragment extends NodeBase {
14439
14686
  this.fragment = null;
14440
14687
  this.fragmentVariable = null;
14441
14688
  }
14442
- include(context, includeChildrenRecursively) {
14689
+ includePath(path, context, includeChildrenRecursively) {
14443
14690
  if (!this.included) {
14444
14691
  const jsx = this.scope.context.options.jsx;
14445
14692
  if (jsx.mode === 'automatic') {
@@ -14454,7 +14701,7 @@ class JSXOpeningFragment extends NodeBase {
14454
14701
  }
14455
14702
  }
14456
14703
  }
14457
- super.include(context, includeChildrenRecursively);
14704
+ super.includePath(path, context, includeChildrenRecursively);
14458
14705
  }
14459
14706
  render(code, options) {
14460
14707
  const { mode } = this.scope.context.options.jsx;
@@ -14511,13 +14758,13 @@ class LabeledStatement extends NodeBase {
14511
14758
  context.includedLabels = new Set([...includedLabels, ...context.includedLabels]);
14512
14759
  return bodyHasEffects;
14513
14760
  }
14514
- include(context, includeChildrenRecursively) {
14761
+ includePath(_path, context, includeChildrenRecursively) {
14515
14762
  this.included = true;
14516
14763
  const { brokenFlow, includedLabels } = context;
14517
14764
  context.includedLabels = new Set();
14518
- this.body.include(context, includeChildrenRecursively);
14765
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14519
14766
  if (includeChildrenRecursively || context.includedLabels.has(this.label.name)) {
14520
- this.label.include();
14767
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
14521
14768
  context.includedLabels.delete(this.label.name);
14522
14769
  context.brokenFlow = brokenFlow;
14523
14770
  }
@@ -14614,17 +14861,17 @@ class LogicalExpression extends NodeBase {
14614
14861
  }
14615
14862
  return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
14616
14863
  }
14617
- include(context, includeChildrenRecursively) {
14864
+ includePath(path, context, includeChildrenRecursively) {
14618
14865
  this.included = true;
14619
14866
  const usedBranch = this.getUsedBranch();
14620
14867
  if (includeChildrenRecursively ||
14621
14868
  (usedBranch === this.right && this.left.shouldBeIncluded(context)) ||
14622
14869
  !usedBranch) {
14623
- this.left.include(context, includeChildrenRecursively);
14624
- this.right.include(context, includeChildrenRecursively);
14870
+ this.left.includePath(path, context, includeChildrenRecursively);
14871
+ this.right.includePath(path, context, includeChildrenRecursively);
14625
14872
  }
14626
14873
  else {
14627
- usedBranch.include(context, includeChildrenRecursively);
14874
+ usedBranch.includePath(path, context, includeChildrenRecursively);
14628
14875
  }
14629
14876
  }
14630
14877
  removeAnnotations(code) {
@@ -14696,17 +14943,17 @@ class NewExpression extends NodeBase {
14696
14943
  hasEffectsOnInteractionAtPath(path, { type }) {
14697
14944
  return path.length > 0 || type !== INTERACTION_ACCESSED;
14698
14945
  }
14699
- include(context, includeChildrenRecursively) {
14946
+ includePath(path, context, includeChildrenRecursively) {
14700
14947
  if (!this.deoptimized)
14701
14948
  this.applyDeoptimizations();
14702
14949
  if (includeChildrenRecursively) {
14703
- super.include(context, includeChildrenRecursively);
14950
+ super.includePath(path, context, includeChildrenRecursively);
14704
14951
  }
14705
14952
  else {
14706
14953
  this.included = true;
14707
- this.callee.include(context, false);
14954
+ this.callee.includePath(UNKNOWN_PATH, context, false);
14708
14955
  }
14709
- this.callee.includeCallArguments(context, this.arguments);
14956
+ this.callee.includeCallArguments(context, this.interaction);
14710
14957
  }
14711
14958
  initialise() {
14712
14959
  super.initialise();
@@ -14735,6 +14982,7 @@ class ObjectExpression extends NodeBase {
14735
14982
  constructor() {
14736
14983
  super(...arguments);
14737
14984
  this.objectEntity = null;
14985
+ this.protoProp = null;
14738
14986
  }
14739
14987
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
14740
14988
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -14754,13 +15002,32 @@ class ObjectExpression extends NodeBase {
14754
15002
  hasEffectsOnInteractionAtPath(path, interaction, context) {
14755
15003
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
14756
15004
  }
15005
+ includePath(path, context, includeChildrenRecursively) {
15006
+ this.included = true;
15007
+ this.getObjectEntity().includePath(path, context, includeChildrenRecursively);
15008
+ this.protoProp?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15009
+ }
14757
15010
  render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {
14758
- super.render(code, options);
14759
15011
  if (renderedSurroundingElement === parseAst_js.ExpressionStatement ||
14760
15012
  renderedSurroundingElement === parseAst_js.ArrowFunctionExpression) {
14761
15013
  code.appendRight(this.start, '(');
14762
15014
  code.prependLeft(this.end, ')');
14763
15015
  }
15016
+ if (this.properties.length > 0) {
15017
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
15018
+ let lastSeparatorPos = null;
15019
+ for (const { node, separator, start, end } of separatedNodes) {
15020
+ if (!node.included) {
15021
+ treeshakeNode(node, code, start, end);
15022
+ continue;
15023
+ }
15024
+ lastSeparatorPos = separator;
15025
+ node.render(code, options);
15026
+ }
15027
+ if (lastSeparatorPos) {
15028
+ code.remove(lastSeparatorPos, this.end - 1);
15029
+ }
15030
+ }
14764
15031
  }
14765
15032
  applyDeoptimizations() { }
14766
15033
  getObjectEntity() {
@@ -14791,6 +15058,7 @@ class ObjectExpression extends NodeBase {
14791
15058
  ? property.key.name
14792
15059
  : String(property.key.value);
14793
15060
  if (key === '__proto__' && property.kind === 'init') {
15061
+ this.protoProp = property;
14794
15062
  prototype =
14795
15063
  property.value instanceof Literal && property.value.value === null
14796
15064
  ? null
@@ -14857,11 +15125,11 @@ class Program extends NodeBase {
14857
15125
  }
14858
15126
  return false;
14859
15127
  }
14860
- include(context, includeChildrenRecursively) {
15128
+ includePath(_path, context, includeChildrenRecursively) {
14861
15129
  this.included = true;
14862
15130
  for (const node of this.body) {
14863
15131
  if (includeChildrenRecursively || node.shouldBeIncluded(context)) {
14864
- node.include(context, includeChildrenRecursively);
15132
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14865
15133
  }
14866
15134
  }
14867
15135
  }
@@ -14900,10 +15168,6 @@ class Program extends NodeBase {
14900
15168
  }
14901
15169
 
14902
15170
  class Property extends MethodBase {
14903
- constructor() {
14904
- super(...arguments);
14905
- this.declarationInit = null;
14906
- }
14907
15171
  //declare method: boolean;
14908
15172
  get method() {
14909
15173
  return isFlagSet(this.flags, 262144 /* Flag.method */);
@@ -14918,17 +15182,32 @@ class Property extends MethodBase {
14918
15182
  set shorthand(value) {
14919
15183
  this.flags = setFlag(this.flags, 524288 /* Flag.shorthand */, value);
14920
15184
  }
14921
- declare(kind, init) {
14922
- this.declarationInit = init;
14923
- return this.value.declare(kind, UNKNOWN_EXPRESSION);
15185
+ declare(kind, destructuredInitPath, init) {
15186
+ return this.value.declare(kind, this.getPathInProperty(destructuredInitPath), init);
15187
+ }
15188
+ deoptimizeAssignment(destructuredInitPath, init) {
15189
+ this.value.deoptimizeAssignment?.(this.getPathInProperty(destructuredInitPath), init);
14924
15190
  }
14925
15191
  hasEffects(context) {
14926
15192
  if (!this.deoptimized)
14927
15193
  this.applyDeoptimizations();
14928
- const propertyReadSideEffects = this.scope.context.options.treeshake.propertyReadSideEffects;
14929
- return ((this.parent.type === 'ObjectPattern' && propertyReadSideEffects === 'always') ||
14930
- this.key.hasEffects(context) ||
14931
- this.value.hasEffects(context));
15194
+ return this.key.hasEffects(context) || this.value.hasEffects(context);
15195
+ }
15196
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
15197
+ return this.value.hasEffectsWhenDestructuring?.(context, this.getPathInProperty(destructuredInitPath), init);
15198
+ }
15199
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
15200
+ let included = this.value.includeDestructuredIfNecessary(context, this.getPathInProperty(destructuredInitPath), init) || this.included;
15201
+ included ||= this.key.hasEffects(createHasEffectsContext());
15202
+ if (included) {
15203
+ this.key.includePath(EMPTY_PATH, context, false);
15204
+ }
15205
+ return (this.included = included);
15206
+ }
15207
+ includePath(path, context, includeChildrenRecursively) {
15208
+ this.included = true;
15209
+ this.key.includePath(EMPTY_PATH, context, includeChildrenRecursively);
15210
+ this.value.includePath(path, context, includeChildrenRecursively);
14932
15211
  }
14933
15212
  markDeclarationReached() {
14934
15213
  this.value.markDeclarationReached();
@@ -14939,12 +15218,17 @@ class Property extends MethodBase {
14939
15218
  }
14940
15219
  this.value.render(code, options, { isShorthandProperty: this.shorthand });
14941
15220
  }
14942
- applyDeoptimizations() {
14943
- this.deoptimized = true;
14944
- if (this.declarationInit !== null) {
14945
- this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
14946
- this.scope.context.requestTreeshakingPass();
14947
- }
15221
+ applyDeoptimizations() { }
15222
+ getPathInProperty(destructuredInitPath) {
15223
+ return destructuredInitPath.at(-1) === UnknownKey
15224
+ ? destructuredInitPath
15225
+ : // For now, we only consider static paths as we do not know how to
15226
+ // deoptimize the path in the dynamic case.
15227
+ this.computed
15228
+ ? [...destructuredInitPath, UnknownKey]
15229
+ : this.key instanceof Identifier
15230
+ ? [...destructuredInitPath, this.key.name]
15231
+ : [...destructuredInitPath, String(this.key.value)];
14948
15232
  }
14949
15233
  }
14950
15234
 
@@ -14989,9 +15273,9 @@ class ReturnStatement extends NodeBase {
14989
15273
  context.brokenFlow = true;
14990
15274
  return false;
14991
15275
  }
14992
- include(context, includeChildrenRecursively) {
15276
+ includePath(_path, context, includeChildrenRecursively) {
14993
15277
  this.included = true;
14994
- this.argument?.include(context, includeChildrenRecursively);
15278
+ this.argument?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14995
15279
  context.brokenFlow = true;
14996
15280
  }
14997
15281
  initialise() {
@@ -15028,14 +15312,14 @@ class SequenceExpression extends NodeBase {
15028
15312
  hasEffectsOnInteractionAtPath(path, interaction, context) {
15029
15313
  return this.expressions[this.expressions.length - 1].hasEffectsOnInteractionAtPath(path, interaction, context);
15030
15314
  }
15031
- include(context, includeChildrenRecursively) {
15315
+ includePath(path, context, includeChildrenRecursively) {
15032
15316
  this.included = true;
15033
15317
  const lastExpression = this.expressions[this.expressions.length - 1];
15034
15318
  for (const expression of this.expressions) {
15035
15319
  if (includeChildrenRecursively ||
15036
15320
  (expression === lastExpression && !(this.parent instanceof ExpressionStatement)) ||
15037
15321
  expression.shouldBeIncluded(context))
15038
- expression.include(context, includeChildrenRecursively);
15322
+ expression.includePath(path, context, includeChildrenRecursively);
15039
15323
  }
15040
15324
  }
15041
15325
  removeAnnotations(code) {
@@ -15083,10 +15367,13 @@ class Super extends NodeBase {
15083
15367
  deoptimizePath(path) {
15084
15368
  this.variable.deoptimizePath(path);
15085
15369
  }
15086
- include() {
15370
+ includePath(path, context) {
15087
15371
  if (!this.included) {
15088
15372
  this.included = true;
15089
- this.scope.context.includeVariableInModule(this.variable);
15373
+ this.scope.context.includeVariableInModule(this.variable, path);
15374
+ }
15375
+ else if (path.length > 0) {
15376
+ this.variable.includePath(path, context);
15090
15377
  }
15091
15378
  }
15092
15379
  }
@@ -15103,12 +15390,12 @@ class SwitchCase extends NodeBase {
15103
15390
  }
15104
15391
  return false;
15105
15392
  }
15106
- include(context, includeChildrenRecursively) {
15393
+ includePath(_path, context, includeChildrenRecursively) {
15107
15394
  this.included = true;
15108
- this.test?.include(context, includeChildrenRecursively);
15395
+ this.test?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15109
15396
  for (const node of this.consequent) {
15110
15397
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
15111
- node.include(context, includeChildrenRecursively);
15398
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15112
15399
  }
15113
15400
  }
15114
15401
  render(code, options, nodeRenderOptions) {
@@ -15156,9 +15443,9 @@ class SwitchStatement extends NodeBase {
15156
15443
  context.hasBreak = hasBreak;
15157
15444
  return false;
15158
15445
  }
15159
- include(context, includeChildrenRecursively) {
15446
+ includePath(_path, context, includeChildrenRecursively) {
15160
15447
  this.included = true;
15161
- this.discriminant.include(context, includeChildrenRecursively);
15448
+ this.discriminant.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15162
15449
  const { brokenFlow, hasBreak } = context;
15163
15450
  context.hasBreak = false;
15164
15451
  let onlyHasBrokenFlow = true;
@@ -15175,7 +15462,7 @@ class SwitchStatement extends NodeBase {
15175
15462
  isCaseIncluded = switchCase.hasEffects(hasEffectsContext);
15176
15463
  }
15177
15464
  if (isCaseIncluded) {
15178
- switchCase.include(context, includeChildrenRecursively);
15465
+ switchCase.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15179
15466
  onlyHasBrokenFlow &&= context.brokenFlow && !context.hasBreak;
15180
15467
  context.hasBreak = false;
15181
15468
  context.brokenFlow = brokenFlow;
@@ -15232,21 +15519,21 @@ class TaggedTemplateExpression extends CallExpressionBase {
15232
15519
  return (this.tag.hasEffects(context) ||
15233
15520
  this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
15234
15521
  }
15235
- include(context, includeChildrenRecursively) {
15522
+ includePath(path, context, includeChildrenRecursively) {
15236
15523
  if (!this.deoptimized)
15237
15524
  this.applyDeoptimizations();
15238
15525
  if (includeChildrenRecursively) {
15239
- super.include(context, includeChildrenRecursively);
15526
+ super.includePath(path, context, includeChildrenRecursively);
15240
15527
  }
15241
15528
  else {
15242
15529
  this.included = true;
15243
- this.tag.include(context, includeChildrenRecursively);
15244
- this.quasi.include(context, includeChildrenRecursively);
15530
+ this.tag.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15531
+ this.quasi.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15245
15532
  }
15246
- this.tag.includeCallArguments(context, this.args);
15533
+ this.tag.includeCallArguments(context, this.interaction);
15247
15534
  const [returnExpression] = this.getReturnExpression();
15248
15535
  if (!returnExpression.included) {
15249
- returnExpression.include(context, false);
15536
+ returnExpression.includePath(UNKNOWN_PATH, context, false);
15250
15537
  }
15251
15538
  }
15252
15539
  initialise() {
@@ -15291,7 +15578,7 @@ class TemplateElement extends NodeBase {
15291
15578
  hasEffects() {
15292
15579
  return false;
15293
15580
  }
15294
- include() {
15581
+ includePath() {
15295
15582
  this.included = true;
15296
15583
  }
15297
15584
  parseNode(esTreeNode) {
@@ -15333,13 +15620,13 @@ class TemplateLiteral extends NodeBase {
15333
15620
  class ModuleScope extends ChildScope {
15334
15621
  constructor(parent, context) {
15335
15622
  super(parent, context);
15336
- this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, context, 'other'));
15623
+ this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, EMPTY_PATH, context, 'other'));
15337
15624
  }
15338
- addDeclaration(identifier, context, init, kind) {
15625
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
15339
15626
  if (this.context.module.importDescriptions.has(identifier.name)) {
15340
15627
  context.error(parseAst_js.logRedeclarationError(identifier.name), identifier.start);
15341
15628
  }
15342
- return super.addDeclaration(identifier, context, init, kind);
15629
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
15343
15630
  }
15344
15631
  addExportDefaultDeclaration(name, exportDefaultDeclaration, context) {
15345
15632
  const variable = new ExportDefaultVariable(name, exportDefaultDeclaration, context);
@@ -15384,10 +15671,13 @@ class ThisExpression extends NodeBase {
15384
15671
  }
15385
15672
  return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
15386
15673
  }
15387
- include() {
15674
+ includePath(path, context) {
15388
15675
  if (!this.included) {
15389
15676
  this.included = true;
15390
- this.scope.context.includeVariableInModule(this.variable);
15677
+ this.scope.context.includeVariableInModule(this.variable, path);
15678
+ }
15679
+ else if (path.length > 0) {
15680
+ this.variable.includePath(path, context);
15391
15681
  }
15392
15682
  }
15393
15683
  initialise() {
@@ -15414,9 +15704,9 @@ class ThrowStatement extends NodeBase {
15414
15704
  hasEffects() {
15415
15705
  return true;
15416
15706
  }
15417
- include(context, includeChildrenRecursively) {
15707
+ includePath(_path, context, includeChildrenRecursively) {
15418
15708
  this.included = true;
15419
- this.argument.include(context, includeChildrenRecursively);
15709
+ this.argument.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15420
15710
  context.brokenFlow = true;
15421
15711
  }
15422
15712
  render(code, options) {
@@ -15438,13 +15728,13 @@ class TryStatement extends NodeBase {
15438
15728
  ? this.block.body.length > 0
15439
15729
  : this.block.hasEffects(context)) || !!this.finalizer?.hasEffects(context));
15440
15730
  }
15441
- include(context, includeChildrenRecursively) {
15731
+ includePath(_path, context, includeChildrenRecursively) {
15442
15732
  const tryCatchDeoptimization = this.scope.context.options.treeshake?.tryCatchDeoptimization;
15443
15733
  const { brokenFlow, includedLabels } = context;
15444
15734
  if (!this.directlyIncluded || !tryCatchDeoptimization) {
15445
15735
  this.included = true;
15446
15736
  this.directlyIncluded = true;
15447
- this.block.include(context, tryCatchDeoptimization ? INCLUDE_PARAMETERS : includeChildrenRecursively);
15737
+ this.block.includePath(UNKNOWN_PATH, context, tryCatchDeoptimization ? INCLUDE_PARAMETERS : includeChildrenRecursively);
15448
15738
  if (includedLabels.size > 0) {
15449
15739
  this.includedLabelsAfterBlock = [...includedLabels];
15450
15740
  }
@@ -15456,10 +15746,10 @@ class TryStatement extends NodeBase {
15456
15746
  }
15457
15747
  }
15458
15748
  if (this.handler !== null) {
15459
- this.handler.include(context, includeChildrenRecursively);
15749
+ this.handler.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15460
15750
  context.brokenFlow = brokenFlow;
15461
15751
  }
15462
- this.finalizer?.include(context, includeChildrenRecursively);
15752
+ this.finalizer?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15463
15753
  }
15464
15754
  }
15465
15755
 
@@ -15517,7 +15807,7 @@ class UpdateExpression extends NodeBase {
15517
15807
  hasEffectsOnInteractionAtPath(path, { type }) {
15518
15808
  return path.length > 1 || type !== INTERACTION_ACCESSED;
15519
15809
  }
15520
- include(context, includeChildrenRecursively) {
15810
+ includePath(_, context, includeChildrenRecursively) {
15521
15811
  if (!this.deoptimized)
15522
15812
  this.applyDeoptimizations();
15523
15813
  this.included = true;
@@ -15586,20 +15876,20 @@ class VariableDeclaration extends NodeBase {
15586
15876
  hasEffectsOnInteractionAtPath() {
15587
15877
  return false;
15588
15878
  }
15589
- include(context, includeChildrenRecursively, { asSingleStatement } = parseAst_js.BLANK) {
15879
+ includePath(_path, context, includeChildrenRecursively, { asSingleStatement } = parseAst_js.BLANK) {
15590
15880
  this.included = true;
15591
15881
  for (const declarator of this.declarations) {
15592
15882
  if (includeChildrenRecursively || declarator.shouldBeIncluded(context))
15593
- declarator.include(context, includeChildrenRecursively);
15883
+ declarator.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15594
15884
  const { id, init } = declarator;
15595
15885
  if (asSingleStatement) {
15596
- id.include(context, includeChildrenRecursively);
15886
+ id.includePath(EMPTY_PATH, context, includeChildrenRecursively);
15597
15887
  }
15598
15888
  if (init &&
15599
15889
  id.included &&
15600
15890
  !init.included &&
15601
15891
  (id instanceof ObjectPattern || id instanceof ArrayPattern)) {
15602
- init.include(context, includeChildrenRecursively);
15892
+ init.includePath(EMPTY_PATH, context, includeChildrenRecursively);
15603
15893
  }
15604
15894
  }
15605
15895
  }
@@ -15671,8 +15961,7 @@ class VariableDeclaration extends NodeBase {
15671
15961
  const singleSystemExport = gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregatedSystemExports);
15672
15962
  for (const { node, start, separator, contentEnd, end } of separatedNodes) {
15673
15963
  if (!node.included) {
15674
- code.remove(start, end);
15675
- node.removeAnnotations(code);
15964
+ treeshakeNode(node, code, start, end);
15676
15965
  continue;
15677
15966
  }
15678
15967
  node.render(code, options);
@@ -15749,9 +16038,9 @@ class WhileStatement extends NodeBase {
15749
16038
  return true;
15750
16039
  return hasLoopBodyEffects(context, this.body);
15751
16040
  }
15752
- include(context, includeChildrenRecursively) {
16041
+ includePath(_path, context, includeChildrenRecursively) {
15753
16042
  this.included = true;
15754
- this.test.include(context, includeChildrenRecursively);
16043
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15755
16044
  includeLoopBody(context, this.body, includeChildrenRecursively);
15756
16045
  }
15757
16046
  }
@@ -15995,7 +16284,7 @@ const bufferParsers = [
15995
16284
  const annotations = (node.annotations = parseAst_js.convertAnnotations(buffer[position + 1], buffer));
15996
16285
  node.annotationNoSideEffects = annotations.some(comment => comment.type === 'noSideEffects');
15997
16286
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 2], buffer));
15998
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
16287
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
15999
16288
  node.body = convertNode(node, scope.bodyScope, buffer[position + 3], buffer);
16000
16289
  },
16001
16290
  function assignmentExpression(node, position, buffer) {
@@ -16041,7 +16330,7 @@ const bufferParsers = [
16041
16330
  const parameterPosition = buffer[position];
16042
16331
  const parameter = (node.param =
16043
16332
  parameterPosition === 0 ? null : convertNode(node, scope, parameterPosition, buffer));
16044
- parameter?.declare('parameter', UNKNOWN_EXPRESSION);
16333
+ parameter?.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
16045
16334
  node.body = convertNode(node, scope.bodyScope, buffer[position + 1], buffer);
16046
16335
  },
16047
16336
  function chainExpression(node, position, buffer) {
@@ -16179,7 +16468,7 @@ const bufferParsers = [
16179
16468
  node.id =
16180
16469
  idPosition === 0 ? null : convertNode(node, scope.parent, idPosition, buffer);
16181
16470
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
16182
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
16471
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
16183
16472
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
16184
16473
  },
16185
16474
  function functionExpression(node, position, buffer) {
@@ -16192,7 +16481,7 @@ const bufferParsers = [
16192
16481
  const idPosition = buffer[position + 2];
16193
16482
  node.id = idPosition === 0 ? null : convertNode(node, node.idScope, idPosition, buffer);
16194
16483
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
16195
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
16484
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
16196
16485
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
16197
16486
  },
16198
16487
  function identifier(node, position, buffer) {
@@ -16551,8 +16840,8 @@ class UnknownNode extends NodeBase {
16551
16840
  hasEffects() {
16552
16841
  return true;
16553
16842
  }
16554
- include(context) {
16555
- super.include(context, true);
16843
+ includePath(path, context) {
16844
+ super.includePath(path, context, true);
16556
16845
  }
16557
16846
  }
16558
16847
 
@@ -16656,8 +16945,8 @@ class ExportShimVariable extends Variable {
16656
16945
  super(MISSING_EXPORT_SHIM_VARIABLE);
16657
16946
  this.module = module;
16658
16947
  }
16659
- include() {
16660
- super.include();
16948
+ includePath(path, context) {
16949
+ super.includePath(path, context);
16661
16950
  this.module.needsExportShim = true;
16662
16951
  }
16663
16952
  }
@@ -17341,7 +17630,7 @@ class Module {
17341
17630
  include() {
17342
17631
  const context = createInclusionContext();
17343
17632
  if (this.ast.shouldBeIncluded(context))
17344
- this.ast.include(context, false);
17633
+ this.ast.includePath(EMPTY_PATH, context, false);
17345
17634
  }
17346
17635
  includeAllExports(includeNamespaceMembers) {
17347
17636
  if (!this.isExecuted) {
@@ -17355,9 +17644,7 @@ class Module {
17355
17644
  return parseAst_js.error(parseAst_js.logMissingEntryExport(exportName, this.id));
17356
17645
  }
17357
17646
  variable.deoptimizePath(UNKNOWN_PATH);
17358
- if (!variable.included) {
17359
- this.includeVariable(variable);
17360
- }
17647
+ this.includeVariable(variable, UNKNOWN_PATH);
17361
17648
  }
17362
17649
  }
17363
17650
  for (const name of this.getReexports()) {
@@ -17365,7 +17652,7 @@ class Module {
17365
17652
  if (variable) {
17366
17653
  variable.deoptimizePath(UNKNOWN_PATH);
17367
17654
  if (!variable.included) {
17368
- this.includeVariable(variable);
17655
+ this.includeVariable(variable, UNKNOWN_PATH);
17369
17656
  }
17370
17657
  if (variable instanceof ExternalVariable) {
17371
17658
  variable.module.reexported = true;
@@ -17377,7 +17664,7 @@ class Module {
17377
17664
  }
17378
17665
  }
17379
17666
  includeAllInBundle() {
17380
- this.ast.include(createInclusionContext(), true);
17667
+ this.ast.includePath(UNKNOWN_PATH, createInclusionContext(), true);
17381
17668
  this.includeAllExports(false);
17382
17669
  }
17383
17670
  includeExportsByNames(names) {
@@ -17391,7 +17678,7 @@ class Module {
17391
17678
  if (variable) {
17392
17679
  variable.deoptimizePath(UNKNOWN_PATH);
17393
17680
  if (!variable.included) {
17394
- this.includeVariable(variable);
17681
+ this.includeVariable(variable, UNKNOWN_PATH);
17395
17682
  }
17396
17683
  }
17397
17684
  if (!this.exports.has(name) && !this.reexportDescriptions.has(name)) {
@@ -17833,13 +18120,13 @@ class Module {
17833
18120
  for (const module of [this, ...this.exportAllModules]) {
17834
18121
  if (module instanceof ExternalModule) {
17835
18122
  const [externalVariable] = module.getVariableForExportName('*');
17836
- externalVariable.include();
18123
+ externalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
17837
18124
  this.includedImports.add(externalVariable);
17838
18125
  externalNamespaces.add(externalVariable);
17839
18126
  }
17840
18127
  else if (module.info.syntheticNamedExports) {
17841
18128
  const syntheticNamespace = module.getSyntheticNamespace();
17842
- syntheticNamespace.include();
18129
+ syntheticNamespace.includePath(UNKNOWN_PATH, createInclusionContext());
17843
18130
  this.includedImports.add(syntheticNamespace);
17844
18131
  syntheticNamespaces.add(syntheticNamespace);
17845
18132
  }
@@ -17849,7 +18136,9 @@ class Module {
17849
18136
  includeDynamicImport(node) {
17850
18137
  const resolution = this.dynamicImports.find(dynamicImport => dynamicImport.node === node).resolution;
17851
18138
  if (resolution instanceof Module) {
17852
- resolution.includedDynamicImporters.push(this);
18139
+ if (!resolution.includedDynamicImporters.includes(this)) {
18140
+ resolution.includedDynamicImporters.push(this);
18141
+ }
17853
18142
  const importedNames = this.options.treeshake
17854
18143
  ? node.getDeterministicImportedNames()
17855
18144
  : undefined;
@@ -17861,7 +18150,7 @@ class Module {
17861
18150
  }
17862
18151
  }
17863
18152
  }
17864
- includeVariable(variable) {
18153
+ includeVariable(variable, path) {
17865
18154
  const variableModule = variable.module;
17866
18155
  if (variable.included) {
17867
18156
  if (variableModule instanceof Module && variableModule !== this) {
@@ -17869,7 +18158,6 @@ class Module {
17869
18158
  }
17870
18159
  }
17871
18160
  else {
17872
- variable.include();
17873
18161
  this.graph.needsTreeshakingPass = true;
17874
18162
  if (variableModule instanceof Module) {
17875
18163
  if (!variableModule.isExecuted) {
@@ -17885,9 +18173,10 @@ class Module {
17885
18173
  }
17886
18174
  }
17887
18175
  }
18176
+ variable.includePath(path, createInclusionContext());
17888
18177
  }
17889
- includeVariableInModule(variable) {
17890
- this.includeVariable(variable);
18178
+ includeVariableInModule(variable, path) {
18179
+ this.includeVariable(variable, path);
17891
18180
  const variableModule = variable.module;
17892
18181
  if (variableModule && variableModule !== this) {
17893
18182
  this.includedImports.add(variable);
@@ -21390,7 +21679,7 @@ class Graph {
21390
21679
  this.options = options;
21391
21680
  this.astLru = flru(5);
21392
21681
  this.cachedModules = new Map();
21393
- this.deoptimizationTracker = new PathTracker();
21682
+ this.deoptimizationTracker = new EntityPathTracker();
21394
21683
  this.entryModules = [];
21395
21684
  this.modulesById = new Map();
21396
21685
  this.needsTreeshakingPass = false;
@@ -22059,6 +22348,8 @@ const getSourcemapBaseUrl = (config) => {
22059
22348
  }
22060
22349
  };
22061
22350
 
22351
+ // @ts-expect-error TS2540: the polyfill of `asyncDispose`.
22352
+ Symbol.asyncDispose ??= Symbol('Symbol.asyncDispose');
22062
22353
  function rollup(rawInputOptions) {
22063
22354
  return rollupInternal(rawInputOptions, null);
22064
22355
  }
@@ -22102,6 +22393,9 @@ async function rollupInternal(rawInputOptions, watcher) {
22102
22393
  await graph.pluginDriver.hookParallel('closeBundle', []);
22103
22394
  },
22104
22395
  closed: false,
22396
+ async [Symbol.asyncDispose]() {
22397
+ await this.close();
22398
+ },
22105
22399
  async generate(rawOutputOptions) {
22106
22400
  if (result.closed)
22107
22401
  return parseAst_js.error(parseAst_js.logAlreadyClosed());