@rollup/wasm-node 4.26.0 → 4.27.0-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v4.26.0
4
- Wed, 13 Nov 2024 06:44:29 GMT - commit ae1d14b7855ff6568a6697d37271a5eb4d8e2d3e
3
+ Rollup.js v4.27.0-1
4
+ Thu, 14 Nov 2024 06:32:38 GMT - commit 81f5021d7d7e2a488639dc036f2334995b3761fc
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.26.0";
34
+ var version = "4.27.0-1";
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,53 @@ 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
+ if (this.variable && !this.variable.included) {
6748
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH);
6749
+ }
6750
+ init.includePath(destructuredInitPath, context, false);
6751
+ return true;
6752
+ }
6753
+ return false;
6754
+ }
6663
6755
  markDeclarationReached() {
6664
6756
  this.variable.initReached = true;
6665
6757
  }
@@ -6712,18 +6804,17 @@ class Scope {
6712
6804
  - then the variable is still declared in the hoisted outer scope, but the initializer is assigned to the parameter
6713
6805
  - const, let, class, and function except in the cases above cannot redeclare anything
6714
6806
  */
6715
- addDeclaration(identifier, context, init, kind) {
6807
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
6716
6808
  const name = identifier.name;
6717
6809
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
6718
6810
  if (existingVariable) {
6719
- const existingKind = existingVariable.kind;
6720
- if (kind === 'var' && existingKind === 'var') {
6811
+ if (kind === 'var' && existingVariable.kind === 'var') {
6721
6812
  existingVariable.addDeclaration(identifier, init);
6722
6813
  return existingVariable;
6723
6814
  }
6724
6815
  context.error(parseAst_js.logRedeclarationError(name), identifier.start);
6725
6816
  }
6726
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
6817
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
6727
6818
  this.variables.set(name, newVariable);
6728
6819
  return newVariable;
6729
6820
  }
@@ -6925,7 +7016,7 @@ class BlockScope extends ChildScope {
6925
7016
  constructor(parent) {
6926
7017
  super(parent, parent.context);
6927
7018
  }
6928
- addDeclaration(identifier, context, init, kind) {
7019
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
6929
7020
  if (kind === 'var') {
6930
7021
  const name = identifier.name;
6931
7022
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -6937,7 +7028,7 @@ class BlockScope extends ChildScope {
6937
7028
  }
6938
7029
  return context.error(parseAst_js.logRedeclarationError(name), identifier.start);
6939
7030
  }
6940
- const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind);
7031
+ const declaredVariable = this.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
6941
7032
  // Necessary to make sure the init is deoptimized for conditional declarations.
6942
7033
  // We cannot call deoptimizePath here.
6943
7034
  declaredVariable.markInitializersForDeoptimization();
@@ -6945,7 +7036,7 @@ class BlockScope extends ChildScope {
6945
7036
  this.addHoistedVariable(name, declaredVariable);
6946
7037
  return declaredVariable;
6947
7038
  }
6948
- return super.addDeclaration(identifier, context, init, kind);
7039
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
6949
7040
  }
6950
7041
  }
6951
7042
 
@@ -6960,11 +7051,11 @@ class StaticBlock extends NodeBase {
6960
7051
  }
6961
7052
  return false;
6962
7053
  }
6963
- include(context, includeChildrenRecursively) {
7054
+ includePath(_path, context, includeChildrenRecursively) {
6964
7055
  this.included = true;
6965
7056
  for (const node of this.body) {
6966
7057
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
6967
- node.include(context, includeChildrenRecursively);
7058
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
6968
7059
  }
6969
7060
  }
6970
7061
  render(code, options) {
@@ -6981,29 +7072,6 @@ function isStaticBlock(statement) {
6981
7072
  return statement.type === parseAst_js.StaticBlock;
6982
7073
  }
6983
7074
 
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
7075
  class ClassNode extends NodeBase {
7008
7076
  constructor() {
7009
7077
  super(...arguments);
@@ -7043,22 +7111,22 @@ class ClassNode extends NodeBase {
7043
7111
  false
7044
7112
  : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
7045
7113
  }
7046
- include(context, includeChildrenRecursively) {
7114
+ includePath(_path, context, includeChildrenRecursively) {
7047
7115
  if (!this.deoptimized)
7048
7116
  this.applyDeoptimizations();
7049
7117
  this.included = true;
7050
- this.superClass?.include(context, includeChildrenRecursively);
7051
- this.body.include(context, includeChildrenRecursively);
7118
+ this.superClass?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7119
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7052
7120
  for (const decorator of this.decorators)
7053
- decorator.include(context, includeChildrenRecursively);
7121
+ decorator.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7054
7122
  if (this.id) {
7055
7123
  this.id.markDeclarationReached();
7056
- this.id.include();
7124
+ this.id.includePath(UNKNOWN_PATH, createInclusionContext());
7057
7125
  }
7058
7126
  }
7059
7127
  initialise() {
7060
7128
  super.initialise();
7061
- this.id?.declare('class', this);
7129
+ this.id?.declare('class', EMPTY_PATH, this);
7062
7130
  for (const method of this.body.body) {
7063
7131
  if (method instanceof MethodDefinition && method.kind === 'constructor') {
7064
7132
  this.classConstructor = method;
@@ -7116,7 +7184,7 @@ class ClassNode extends NodeBase {
7116
7184
  staticProperties.unshift({
7117
7185
  key: 'prototype',
7118
7186
  kind: 'init',
7119
- property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE)
7187
+ property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, ['prototype']) : OBJECT_PROTOTYPE)
7120
7188
  });
7121
7189
  return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE));
7122
7190
  }
@@ -7173,7 +7241,7 @@ class ClassDeclaration extends ClassNode {
7173
7241
 
7174
7242
  class ArgumentsVariable extends LocalVariable {
7175
7243
  constructor(context) {
7176
- super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');
7244
+ super('arguments', null, UNKNOWN_EXPRESSION, EMPTY_PATH, context, 'other');
7177
7245
  this.deoptimizedArguments = [];
7178
7246
  }
7179
7247
  addArgumentToBeDeoptimized(argument) {
@@ -7187,8 +7255,8 @@ class ArgumentsVariable extends LocalVariable {
7187
7255
  hasEffectsOnInteractionAtPath(path, { type }) {
7188
7256
  return type !== INTERACTION_ACCESSED || path.length > 1;
7189
7257
  }
7190
- include() {
7191
- super.include();
7258
+ includePath(path, context) {
7259
+ super.includePath(path, context);
7192
7260
  for (const argument of this.deoptimizedArguments) {
7193
7261
  argument.deoptimizePath(UNKNOWN_PATH);
7194
7262
  }
@@ -7199,27 +7267,28 @@ class ArgumentsVariable extends LocalVariable {
7199
7267
  const MAX_TRACKED_INTERACTIONS = 20;
7200
7268
  const NO_INTERACTIONS = parseAst_js.EMPTY_ARRAY;
7201
7269
  const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);
7202
- const EMPTY_PATH_TRACKER = new PathTracker();
7270
+ const EMPTY_PATH_TRACKER = new EntityPathTracker();
7203
7271
  const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);
7204
7272
  class ParameterVariable extends LocalVariable {
7205
- constructor(name, declarator, context) {
7206
- super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');
7273
+ constructor(name, declarator, argumentPath, context) {
7274
+ super(name, declarator, UNKNOWN_EXPRESSION, argumentPath, context, 'parameter');
7207
7275
  this.deoptimizationInteractions = [];
7208
- this.deoptimizations = new PathTracker();
7276
+ this.deoptimizations = new EntityPathTracker();
7209
7277
  this.deoptimizedFields = new Set();
7210
- this.entitiesToBeDeoptimized = new Set();
7211
- this.expressionsUseTheKnownValue = [];
7278
+ this.argumentsToBeDeoptimized = new Set();
7279
+ this.expressionsDependingOnKnownValue = [];
7212
7280
  this.knownValue = null;
7213
7281
  this.knownValueLiteral = UnknownValue;
7214
7282
  this.frozenValue = null;
7215
7283
  }
7216
- addEntityToBeDeoptimized(entity) {
7284
+ addArgumentValue(entity) {
7285
+ this.updateKnownValue(entity);
7217
7286
  if (entity === UNKNOWN_EXPRESSION) {
7218
7287
  // As unknown expressions fully deoptimize all interactions, we can clear
7219
7288
  // the interaction cache at this point provided we keep this optimization
7220
7289
  // in mind when adding new interactions
7221
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7222
- this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);
7290
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7291
+ this.argumentsToBeDeoptimized.add(UNKNOWN_EXPRESSION);
7223
7292
  for (const { interaction } of this.deoptimizationInteractions) {
7224
7293
  deoptimizeInteraction(interaction);
7225
7294
  }
@@ -7229,27 +7298,30 @@ class ParameterVariable extends LocalVariable {
7229
7298
  else if (this.deoptimizedFields.has(UnknownKey)) {
7230
7299
  // This means that we already deoptimized all interactions and no longer
7231
7300
  // track them
7232
- entity.deoptimizePath(UNKNOWN_PATH);
7301
+ entity.deoptimizePath([...this.initPath, UnknownKey]);
7233
7302
  }
7234
- else if (!this.entitiesToBeDeoptimized.has(entity)) {
7235
- this.entitiesToBeDeoptimized.add(entity);
7303
+ else if (!this.argumentsToBeDeoptimized.has(entity)) {
7304
+ this.argumentsToBeDeoptimized.add(entity);
7236
7305
  for (const field of this.deoptimizedFields) {
7237
- entity.deoptimizePath([field]);
7306
+ entity.deoptimizePath([...this.initPath, field]);
7238
7307
  }
7239
7308
  for (const { interaction, path } of this.deoptimizationInteractions) {
7240
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
7309
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
7241
7310
  }
7242
7311
  }
7243
7312
  }
7313
+ /** This says we should not make assumptions about the value of the parameter.
7314
+ * This is different from deoptimization that will also cause argument values
7315
+ * to be deoptimized. */
7244
7316
  markReassigned() {
7245
7317
  if (this.isReassigned) {
7246
7318
  return;
7247
7319
  }
7248
7320
  super.markReassigned();
7249
- for (const expression of this.expressionsUseTheKnownValue) {
7321
+ for (const expression of this.expressionsDependingOnKnownValue) {
7250
7322
  expression.deoptimizeCache();
7251
7323
  }
7252
- this.expressionsUseTheKnownValue = parseAst_js.EMPTY_ARRAY;
7324
+ this.expressionsDependingOnKnownValue = parseAst_js.EMPTY_ARRAY;
7253
7325
  }
7254
7326
  deoptimizeCache() {
7255
7327
  this.markReassigned();
@@ -7266,7 +7338,7 @@ class ParameterVariable extends LocalVariable {
7266
7338
  }
7267
7339
  if (this.knownValue === null) {
7268
7340
  this.knownValue = argument;
7269
- this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
7341
+ this.knownValueLiteral = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
7270
7342
  return;
7271
7343
  }
7272
7344
  // the same literal or identifier, do nothing
@@ -7282,7 +7354,7 @@ class ParameterVariable extends LocalVariable {
7282
7354
  return;
7283
7355
  }
7284
7356
  // add tracking for the new argument
7285
- const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
7357
+ const newValue = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
7286
7358
  if (newValue !== oldValue) {
7287
7359
  this.markReassigned();
7288
7360
  }
@@ -7304,20 +7376,25 @@ class ParameterVariable extends LocalVariable {
7304
7376
  return UnknownValue;
7305
7377
  }
7306
7378
  const knownValue = this.getKnownValue();
7307
- this.expressionsUseTheKnownValue.push(origin);
7308
- return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);
7379
+ this.expressionsDependingOnKnownValue.push(origin);
7380
+ return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin), UnknownValue);
7309
7381
  }
7310
7382
  hasEffectsOnInteractionAtPath(path, interaction, context) {
7311
- if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) {
7383
+ const { type } = interaction;
7384
+ if (this.isReassigned || type === INTERACTION_ASSIGNED) {
7312
7385
  return super.hasEffectsOnInteractionAtPath(path, interaction, context);
7313
7386
  }
7314
- const knownValue = this.getKnownValue();
7315
- return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context);
7387
+ return (!(type === INTERACTION_CALLED
7388
+ ? (interaction.withNew
7389
+ ? context.instantiated
7390
+ : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)
7391
+ : context.accessed.trackEntityAtPathAndGetIfTracked(path, this)) &&
7392
+ this.getKnownValue().hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
7316
7393
  }
7317
7394
  deoptimizeArgumentsOnInteractionAtPath(interaction, path) {
7318
7395
  // For performance reasons, we fully deoptimize all deeper interactions
7319
7396
  if (path.length >= 2 ||
7320
- this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
7397
+ this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
7321
7398
  this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||
7322
7399
  (path.length === 1 &&
7323
7400
  (this.deoptimizedFields.has(UnknownKey) ||
@@ -7326,10 +7403,10 @@ class ParameterVariable extends LocalVariable {
7326
7403
  return;
7327
7404
  }
7328
7405
  if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {
7329
- for (const entity of this.entitiesToBeDeoptimized) {
7330
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
7406
+ for (const entity of this.argumentsToBeDeoptimized) {
7407
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
7331
7408
  }
7332
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7409
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7333
7410
  this.deoptimizationInteractions.push({
7334
7411
  interaction,
7335
7412
  path
@@ -7350,17 +7427,17 @@ class ParameterVariable extends LocalVariable {
7350
7427
  return;
7351
7428
  }
7352
7429
  this.deoptimizedFields.add(key);
7353
- for (const entity of this.entitiesToBeDeoptimized) {
7430
+ for (const entity of this.argumentsToBeDeoptimized) {
7354
7431
  // We do not need a recursion tracker here as we already track whether
7355
7432
  // this field is deoptimized
7356
- entity.deoptimizePath([key]);
7433
+ entity.deoptimizePath([...this.initPath, key]);
7357
7434
  }
7358
7435
  if (key === UnknownKey) {
7359
7436
  // save some memory
7360
7437
  this.deoptimizationInteractions = NO_INTERACTIONS;
7361
7438
  this.deoptimizations = EMPTY_PATH_TRACKER;
7362
7439
  this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;
7363
- this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
7440
+ this.argumentsToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
7364
7441
  }
7365
7442
  }
7366
7443
  getReturnExpressionWhenCalledAtPath(path) {
@@ -7375,11 +7452,14 @@ class ParameterVariable extends LocalVariable {
7375
7452
  }
7376
7453
  return UNKNOWN_RETURN_EXPRESSION;
7377
7454
  }
7455
+ includeArgumentPaths(entity, context) {
7456
+ this.includedPathTracker.includeAllPaths(entity, context, this.initPath);
7457
+ }
7378
7458
  }
7379
7459
 
7380
7460
  class ThisVariable extends ParameterVariable {
7381
7461
  constructor(context) {
7382
- super('this', null, context);
7462
+ super('this', null, EMPTY_PATH, context);
7383
7463
  }
7384
7464
  hasEffectsOnInteractionAtPath(path, interaction, context) {
7385
7465
  return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);
@@ -7391,7 +7471,7 @@ class CatchBodyScope extends ChildScope {
7391
7471
  super(parent, parent.context);
7392
7472
  this.parent = parent;
7393
7473
  }
7394
- addDeclaration(identifier, context, init, kind) {
7474
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
7395
7475
  if (kind === 'var') {
7396
7476
  const name = identifier.name;
7397
7477
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -7404,7 +7484,7 @@ class CatchBodyScope extends ChildScope {
7404
7484
  // the assignment actually goes to the parameter and the var is
7405
7485
  // hoisted without assignment. Locally, it is shadowed by the
7406
7486
  // parameter
7407
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, kind);
7487
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, destructuredInitPath, kind);
7408
7488
  // To avoid the need to rewrite the declaration, we link the variable
7409
7489
  // names. If we ever implement a logic that splits initialization and
7410
7490
  // assignment for hoisted vars, the "renderLikeHoisted" logic can be
@@ -7423,7 +7503,7 @@ class CatchBodyScope extends ChildScope {
7423
7503
  return context.error(parseAst_js.logRedeclarationError(name), identifier.start);
7424
7504
  }
7425
7505
  // We only add parameters to parameter scopes
7426
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, kind);
7506
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
7427
7507
  // Necessary to make sure the init is deoptimized for conditional declarations.
7428
7508
  // We cannot call deoptimizePath here.
7429
7509
  declaredVariable.markInitializersForDeoptimization();
@@ -7431,7 +7511,7 @@ class CatchBodyScope extends ChildScope {
7431
7511
  this.addHoistedVariable(name, declaredVariable);
7432
7512
  return declaredVariable;
7433
7513
  }
7434
- return super.addDeclaration(identifier, context, init, kind);
7514
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
7435
7515
  }
7436
7516
  }
7437
7517
 
@@ -7441,7 +7521,7 @@ class FunctionBodyScope extends ChildScope {
7441
7521
  }
7442
7522
  // There is stuff that is only allowed in function scopes, i.e. functions can
7443
7523
  // be redeclared, functions and var can redeclare each other
7444
- addDeclaration(identifier, context, init, kind) {
7524
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
7445
7525
  const name = identifier.name;
7446
7526
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
7447
7527
  if (existingVariable) {
@@ -7453,7 +7533,7 @@ class FunctionBodyScope extends ChildScope {
7453
7533
  }
7454
7534
  context.error(parseAst_js.logRedeclarationError(name), identifier.start);
7455
7535
  }
7456
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
7536
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
7457
7537
  this.variables.set(name, newVariable);
7458
7538
  return newVariable;
7459
7539
  }
@@ -7462,21 +7542,21 @@ class FunctionBodyScope extends ChildScope {
7462
7542
  class ParameterScope extends ChildScope {
7463
7543
  constructor(parent, isCatchScope) {
7464
7544
  super(parent, parent.context);
7465
- this.parameters = [];
7466
7545
  this.hasRest = false;
7546
+ this.parameters = [];
7467
7547
  this.bodyScope = isCatchScope ? new CatchBodyScope(this) : new FunctionBodyScope(this);
7468
7548
  }
7469
7549
  /**
7470
7550
  * Adds a parameter to this scope. Parameters must be added in the correct
7471
7551
  * order, i.e. from left to right.
7472
7552
  */
7473
- addParameterDeclaration(identifier) {
7553
+ addParameterDeclaration(identifier, argumentPath) {
7474
7554
  const { name, start } = identifier;
7475
7555
  const existingParameter = this.variables.get(name);
7476
7556
  if (existingParameter) {
7477
7557
  return this.context.error(parseAst_js.logDuplicateArgumentNameError(name), start);
7478
7558
  }
7479
- const variable = new ParameterVariable(name, identifier, this.context);
7559
+ const variable = new ParameterVariable(name, identifier, argumentPath, this.context);
7480
7560
  this.variables.set(name, variable);
7481
7561
  // We also add it to the body scope to detect name conflicts with local
7482
7562
  // variables. We still need the intermediate scope, though, as parameter
@@ -7494,43 +7574,54 @@ class ParameterScope extends ChildScope {
7494
7574
  }
7495
7575
  this.hasRest = hasRest;
7496
7576
  }
7497
- includeCallArguments(context, parameters) {
7577
+ includeCallArguments(context, interaction) {
7498
7578
  let calledFromTryStatement = false;
7499
7579
  let argumentIncluded = false;
7500
7580
  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;
7581
+ const { args } = interaction;
7582
+ let lastExplicitlyIncludedIndex = args.length - 1;
7583
+ // If there is a SpreadElement, we need to include all arguments after it
7584
+ // because we no longer know which argument corresponds to which parameter.
7585
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
7586
+ if (args[argumentIndex] instanceof SpreadElement && !argumentIncluded) {
7587
+ argumentIncluded = true;
7588
+ lastExplicitlyIncludedIndex = argumentIndex - 1;
7589
+ }
7590
+ if (argumentIncluded) {
7591
+ args[argumentIndex].includePath(UNKNOWN_PATH, context, false);
7507
7592
  }
7508
7593
  }
7509
- for (let index = parameters.length - 1; index >= 0; index--) {
7510
- const parameterVariables = this.parameters[index] || restParameter;
7511
- const argument = parameters[index];
7594
+ // Now we go backwards either starting from the last argument or before the
7595
+ // first SpreadElement to ensure all arguments before are included as needed
7596
+ for (let index = lastExplicitlyIncludedIndex; index >= 1; index--) {
7597
+ const parameterVariables = this.parameters[index - 1] || restParameter;
7598
+ const argument = args[index];
7512
7599
  if (parameterVariables) {
7513
7600
  calledFromTryStatement = false;
7514
7601
  if (parameterVariables.length === 0) {
7515
- // handle empty destructuring
7602
+ // handle empty destructuring to avoid destructuring undefined
7516
7603
  argumentIncluded = true;
7517
7604
  }
7518
7605
  else {
7519
7606
  for (const variable of parameterVariables) {
7520
- if (variable.included) {
7521
- argumentIncluded = true;
7522
- }
7523
7607
  if (variable.calledFromTryStatement) {
7524
7608
  calledFromTryStatement = true;
7525
7609
  }
7610
+ if (variable.included) {
7611
+ argumentIncluded = true;
7612
+ if (calledFromTryStatement) {
7613
+ argument.includePath(UNKNOWN_PATH, context, true);
7614
+ }
7615
+ else {
7616
+ variable.includeArgumentPaths(argument, context);
7617
+ }
7618
+ }
7526
7619
  }
7527
7620
  }
7528
7621
  }
7529
- if (!argumentIncluded && argument.shouldBeIncluded(context)) {
7622
+ if (!argument.included && (argumentIncluded || argument.shouldBeIncluded(context))) {
7530
7623
  argumentIncluded = true;
7531
- }
7532
- if (argumentIncluded) {
7533
- argument.include(context, calledFromTryStatement);
7624
+ argument.includePath(EMPTY_PATH, context, calledFromTryStatement);
7534
7625
  }
7535
7626
  }
7536
7627
  }
@@ -7545,11 +7636,61 @@ class ReturnValueScope extends ParameterScope {
7545
7636
  addReturnExpression(expression) {
7546
7637
  this.returnExpressions.push(expression);
7547
7638
  }
7639
+ deoptimizeArgumentsOnCall(interaction) {
7640
+ const { parameters } = this;
7641
+ const { args } = interaction;
7642
+ let position = 0;
7643
+ for (; position < args.length - 1; position++) {
7644
+ // Only the "this" argument arg[0] can be null
7645
+ const argument = args[position + 1];
7646
+ if (argument instanceof SpreadElement) {
7647
+ // This deoptimizes the current and remaining parameters and arguments
7648
+ for (; position < parameters.length; position++) {
7649
+ args[position + 1]?.deoptimizePath(UNKNOWN_PATH);
7650
+ parameters[position].forEach(variable => variable.markReassigned());
7651
+ }
7652
+ break;
7653
+ }
7654
+ if (this.hasRest && position >= parameters.length - 1) {
7655
+ argument.deoptimizePath(UNKNOWN_PATH);
7656
+ }
7657
+ else {
7658
+ const variables = parameters[position];
7659
+ if (variables) {
7660
+ for (const variable of variables) {
7661
+ variable.addArgumentValue(argument);
7662
+ }
7663
+ }
7664
+ this.addArgumentToBeDeoptimized(argument);
7665
+ }
7666
+ }
7667
+ for (; position < parameters.length; position++) {
7668
+ for (const variable of parameters[position]) {
7669
+ variable.addArgumentValue(UNDEFINED_EXPRESSION);
7670
+ }
7671
+ }
7672
+ }
7548
7673
  getReturnExpression() {
7549
7674
  if (this.returnExpression === null)
7550
7675
  this.updateReturnExpression();
7551
7676
  return this.returnExpression;
7552
7677
  }
7678
+ deoptimizeAllParameters() {
7679
+ for (const parameter of this.parameters) {
7680
+ for (const variable of parameter) {
7681
+ variable.deoptimizePath(UNKNOWN_PATH);
7682
+ variable.markReassigned();
7683
+ }
7684
+ }
7685
+ }
7686
+ reassignAllParameters() {
7687
+ for (const parameter of this.parameters) {
7688
+ for (const variable of parameter) {
7689
+ variable.markReassigned();
7690
+ }
7691
+ }
7692
+ }
7693
+ addArgumentToBeDeoptimized(_argument) { }
7553
7694
  updateReturnExpression() {
7554
7695
  if (this.returnExpressions.length === 1) {
7555
7696
  this.returnExpression = this.returnExpressions[0];
@@ -7565,24 +7706,26 @@ class ReturnValueScope extends ParameterScope {
7565
7706
 
7566
7707
  class FunctionScope extends ReturnValueScope {
7567
7708
  constructor(parent) {
7568
- const { context } = parent;
7569
7709
  super(parent, false);
7710
+ const { context } = parent;
7570
7711
  this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));
7571
7712
  this.variables.set('this', (this.thisVariable = new ThisVariable(context)));
7572
7713
  }
7573
7714
  findLexicalBoundary() {
7574
7715
  return this;
7575
7716
  }
7576
- includeCallArguments(context, parameters) {
7577
- super.includeCallArguments(context, parameters);
7717
+ includeCallArguments(context, interaction) {
7718
+ super.includeCallArguments(context, interaction);
7578
7719
  if (this.argumentsVariable.included) {
7579
- for (const argument of parameters) {
7580
- if (!argument.included) {
7581
- argument.include(context, false);
7582
- }
7720
+ const { args } = interaction;
7721
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
7722
+ args[argumentIndex]?.includePath(UNKNOWN_PATH, context, false);
7583
7723
  }
7584
7724
  }
7585
7725
  }
7726
+ addArgumentToBeDeoptimized(argument) {
7727
+ this.argumentsVariable.addArgumentToBeDeoptimized(argument);
7728
+ }
7586
7729
  }
7587
7730
 
7588
7731
  class ExpressionStatement extends NodeBase {
@@ -7648,7 +7791,7 @@ class BlockStatement extends NodeBase {
7648
7791
  }
7649
7792
  return false;
7650
7793
  }
7651
- include(context, includeChildrenRecursively) {
7794
+ includePath(_path, context, includeChildrenRecursively) {
7652
7795
  if (!(this.deoptimizeBody && this.directlyIncluded)) {
7653
7796
  this.included = true;
7654
7797
  this.directlyIncluded = true;
@@ -7656,7 +7799,7 @@ class BlockStatement extends NodeBase {
7656
7799
  includeChildrenRecursively = true;
7657
7800
  for (const node of this.body) {
7658
7801
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
7659
- node.include(context, includeChildrenRecursively);
7802
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7660
7803
  }
7661
7804
  }
7662
7805
  }
@@ -7685,9 +7828,12 @@ class RestElement extends NodeBase {
7685
7828
  addExportedVariables(variables, exportNamesByVariable) {
7686
7829
  this.argument.addExportedVariables(variables, exportNamesByVariable);
7687
7830
  }
7688
- declare(kind, init) {
7831
+ declare(kind, destructuredInitPath, init) {
7689
7832
  this.declarationInit = init;
7690
- return this.argument.declare(kind, UNKNOWN_EXPRESSION);
7833
+ return this.argument.declare(kind, getIncludedPatternPath$1(destructuredInitPath), init);
7834
+ }
7835
+ deoptimizeAssignment(destructuredInitPath, init) {
7836
+ this.argument.deoptimizeAssignment(getIncludedPatternPath$1(destructuredInitPath), init);
7691
7837
  }
7692
7838
  deoptimizePath(path) {
7693
7839
  if (path.length === 0) {
@@ -7698,6 +7844,19 @@ class RestElement extends NodeBase {
7698
7844
  return (path.length > 0 ||
7699
7845
  this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
7700
7846
  }
7847
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
7848
+ return this.argument.hasEffectsWhenDestructuring(context, getIncludedPatternPath$1(destructuredInitPath), init);
7849
+ }
7850
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
7851
+ return (this.included =
7852
+ this.argument.includeDestructuredIfNecessary(context, getIncludedPatternPath$1(destructuredInitPath), init) || this.included);
7853
+ }
7854
+ includePath(_path, context, includeChildrenRecursively) {
7855
+ this.included = true;
7856
+ // This should just include the identifier, its properties should be
7857
+ // included where the variable is used.
7858
+ this.argument.includePath(EMPTY_PATH, context, includeChildrenRecursively);
7859
+ }
7701
7860
  markDeclarationReached() {
7702
7861
  this.argument.markDeclarationReached();
7703
7862
  }
@@ -7709,12 +7868,15 @@ class RestElement extends NodeBase {
7709
7868
  }
7710
7869
  }
7711
7870
  }
7871
+ const getIncludedPatternPath$1 = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
7872
+ ? destructuredInitPath
7873
+ : [...destructuredInitPath, UnknownKey];
7712
7874
 
7713
7875
  class FunctionBase extends NodeBase {
7714
7876
  constructor() {
7715
7877
  super(...arguments);
7716
- this.objectEntity = null;
7717
7878
  this.parameterVariableValuesDeoptimized = false;
7879
+ this.includeCallArguments = this.scope.includeCallArguments.bind(this.scope);
7718
7880
  }
7719
7881
  get async() {
7720
7882
  return isFlagSet(this.flags, 256 /* Flag.async */);
@@ -7734,53 +7896,9 @@ class FunctionBase extends NodeBase {
7734
7896
  set generator(value) {
7735
7897
  this.flags = setFlag(this.flags, 4194304 /* Flag.generator */, value);
7736
7898
  }
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
7899
  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);
7900
+ if (interaction.type === INTERACTION_CALLED && path.length === 0) {
7901
+ this.scope.deoptimizeArgumentsOnCall(interaction);
7784
7902
  }
7785
7903
  else {
7786
7904
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -7792,12 +7910,7 @@ class FunctionBase extends NodeBase {
7792
7910
  // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
7793
7911
  // which means the return expression and parameters need to be reassigned
7794
7912
  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
- }
7913
+ this.scope.deoptimizeAllParameters();
7801
7914
  }
7802
7915
  }
7803
7916
  getLiteralValueAtPath(path, recursionTracker, origin) {
@@ -7835,8 +7948,13 @@ class FunctionBase extends NodeBase {
7835
7948
  return true;
7836
7949
  }
7837
7950
  }
7838
- for (const parameter of this.params) {
7839
- if (parameter.hasEffects(context))
7951
+ const { propertyReadSideEffects } = this.scope.context.options
7952
+ .treeshake;
7953
+ for (let index = 0; index < this.params.length; index++) {
7954
+ const parameter = this.params[index];
7955
+ if (parameter.hasEffects(context) ||
7956
+ (propertyReadSideEffects &&
7957
+ parameter.hasEffectsWhenDestructuring(context, EMPTY_PATH, interaction.args[index + 1] || UNDEFINED_EXPRESSION)))
7840
7958
  return true;
7841
7959
  }
7842
7960
  return false;
@@ -7854,22 +7972,19 @@ class FunctionBase extends NodeBase {
7854
7972
  }
7855
7973
  return variable?.getOnlyFunctionCallUsed() ?? false;
7856
7974
  }
7857
- include(context, includeChildrenRecursively) {
7858
- if (!this.parameterVariableValuesDeoptimized && !this.onlyFunctionCallUsed()) {
7975
+ includePath(_path, context, includeChildrenRecursively) {
7976
+ if (!(this.parameterVariableValuesDeoptimized || this.onlyFunctionCallUsed())) {
7859
7977
  this.parameterVariableValuesDeoptimized = true;
7860
- this.deoptimizeParameterVariableValues();
7978
+ this.scope.reassignAllParameters();
7861
7979
  }
7862
7980
  if (!this.deoptimized)
7863
7981
  this.applyDeoptimizations();
7864
7982
  this.included = true;
7865
7983
  const { brokenFlow } = context;
7866
7984
  context.brokenFlow = false;
7867
- this.body.include(context, includeChildrenRecursively);
7985
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7868
7986
  context.brokenFlow = brokenFlow;
7869
7987
  }
7870
- includeCallArguments(context, parameters) {
7871
- this.scope.includeCallArguments(context, parameters);
7872
- }
7873
7988
  initialise() {
7874
7989
  super.initialise();
7875
7990
  if (this.body instanceof BlockStatement) {
@@ -7891,11 +8006,10 @@ class FunctionBase extends NodeBase {
7891
8006
  // so that the scope already knows all parameters and can detect conflicts
7892
8007
  // when parsing the body.
7893
8008
  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);
8009
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
7895
8010
  this.body = new (context.getNodeConstructor(body.type))(this, bodyScope).parseNode(body);
7896
8011
  return super.parseNode(esTreeNode);
7897
8012
  }
7898
- addArgumentToBeDeoptimized(_argument) { }
7899
8013
  applyDeoptimizations() { }
7900
8014
  }
7901
8015
  FunctionBase.prototype.preventChildBlockScope = true;
@@ -7910,13 +8024,13 @@ class FunctionNode extends FunctionBase {
7910
8024
  this.constructedEntity = new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE);
7911
8025
  // This makes sure that all deoptimizations of "this" are applied to the
7912
8026
  // constructed entity.
7913
- this.scope.thisVariable.addEntityToBeDeoptimized(this.constructedEntity);
8027
+ this.scope.thisVariable.addArgumentValue(this.constructedEntity);
7914
8028
  }
7915
8029
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
7916
8030
  super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
7917
8031
  if (interaction.type === INTERACTION_CALLED && path.length === 0 && interaction.args[0]) {
7918
8032
  // args[0] is the "this" argument
7919
- this.scope.thisVariable.addEntityToBeDeoptimized(interaction.args[0]);
8033
+ this.scope.thisVariable.addArgumentValue(interaction.args[0]);
7920
8034
  }
7921
8035
  }
7922
8036
  hasEffects(context) {
@@ -7957,22 +8071,19 @@ class FunctionNode extends FunctionBase {
7957
8071
  }
7958
8072
  return false;
7959
8073
  }
7960
- include(context, includeChildrenRecursively) {
7961
- super.include(context, includeChildrenRecursively);
7962
- this.id?.include();
8074
+ includePath(path, context, includeChildrenRecursively) {
8075
+ super.includePath(path, context, includeChildrenRecursively);
8076
+ this.id?.includePath(UNKNOWN_PATH, createInclusionContext());
7963
8077
  const hasArguments = this.scope.argumentsVariable.included;
7964
8078
  for (const parameter of this.params) {
7965
8079
  if (!(parameter instanceof Identifier) || hasArguments) {
7966
- parameter.include(context, includeChildrenRecursively);
8080
+ parameter.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
7967
8081
  }
7968
8082
  }
7969
8083
  }
7970
8084
  initialise() {
7971
8085
  super.initialise();
7972
- this.id?.declare('function', this);
7973
- }
7974
- addArgumentToBeDeoptimized(argument) {
7975
- this.scope.argumentsVariable.addArgumentToBeDeoptimized(argument);
8086
+ this.id?.declare('function', EMPTY_PATH, this);
7976
8087
  }
7977
8088
  getObjectEntity() {
7978
8089
  if (this.objectEntity !== null) {
@@ -8021,10 +8132,11 @@ function getFunctionIdInsertPosition(code, start) {
8021
8132
  return declarationEnd + generatorStarPos + 1;
8022
8133
  }
8023
8134
  class ExportDefaultDeclaration extends NodeBase {
8024
- include(context, includeChildrenRecursively) {
8025
- super.include(context, includeChildrenRecursively);
8135
+ includePath(path, context, includeChildrenRecursively) {
8136
+ this.included = true;
8137
+ this.declaration.includePath(path, context, includeChildrenRecursively);
8026
8138
  if (includeChildrenRecursively) {
8027
- this.scope.context.includeVariableInModule(this.variable);
8139
+ this.scope.context.includeVariableInModule(this.variable, path);
8028
8140
  }
8029
8141
  }
8030
8142
  initialise() {
@@ -8493,6 +8605,10 @@ class MemberExpression extends NodeBase {
8493
8605
  }
8494
8606
  }
8495
8607
  }
8608
+ deoptimizeAssignment(destructuredInitPath, init) {
8609
+ this.deoptimizePath(EMPTY_PATH);
8610
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
8611
+ }
8496
8612
  deoptimizeCache() {
8497
8613
  const { expressionsToBeDeoptimized, object } = this;
8498
8614
  this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;
@@ -8597,28 +8713,42 @@ class MemberExpression extends NodeBase {
8597
8713
  }
8598
8714
  return true;
8599
8715
  }
8600
- include(context, includeChildrenRecursively) {
8716
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
8717
+ return (destructuredInitPath.length > 0 &&
8718
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
8719
+ }
8720
+ includePath(path, context, includeChildrenRecursively) {
8601
8721
  if (!this.deoptimized)
8602
8722
  this.applyDeoptimizations();
8603
- this.includeProperties(context, includeChildrenRecursively);
8723
+ this.includeProperties(path, [this.getPropertyKey(), ...path], context, includeChildrenRecursively);
8604
8724
  }
8605
8725
  includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {
8606
8726
  if (!this.assignmentDeoptimized)
8607
8727
  this.applyAssignmentDeoptimization();
8608
8728
  if (deoptimizeAccess) {
8609
- this.include(context, includeChildrenRecursively);
8729
+ this.includePath([this.getPropertyKey()], context, includeChildrenRecursively);
8610
8730
  }
8611
8731
  else {
8612
- this.includeProperties(context, includeChildrenRecursively);
8732
+ this.includeProperties(EMPTY_PATH, [this.getPropertyKey()], context, includeChildrenRecursively);
8613
8733
  }
8614
8734
  }
8615
- includeCallArguments(context, parameters) {
8735
+ includeCallArguments(context, interaction) {
8616
8736
  if (this.variable) {
8617
- this.variable.includeCallArguments(context, parameters);
8737
+ this.variable.includeCallArguments(context, interaction);
8618
8738
  }
8619
8739
  else {
8620
- super.includeCallArguments(context, parameters);
8740
+ super.includeCallArguments(context, interaction);
8741
+ }
8742
+ }
8743
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
8744
+ if ((this.included ||=
8745
+ destructuredInitPath.length > 0 &&
8746
+ !context.brokenFlow &&
8747
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext()))) {
8748
+ init.includePath(destructuredInitPath, context, false);
8749
+ return true;
8621
8750
  }
8751
+ return false;
8622
8752
  }
8623
8753
  initialise() {
8624
8754
  super.initialise();
@@ -8686,7 +8816,7 @@ class MemberExpression extends NodeBase {
8686
8816
  const variable = this.scope.findVariable(this.object.name);
8687
8817
  if (variable.isNamespace) {
8688
8818
  if (this.variable) {
8689
- this.scope.context.includeVariableInModule(this.variable);
8819
+ this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH);
8690
8820
  }
8691
8821
  this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);
8692
8822
  }
@@ -8713,15 +8843,18 @@ class MemberExpression extends NodeBase {
8713
8843
  (propertyReadSideEffects === 'always' ||
8714
8844
  this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));
8715
8845
  }
8716
- includeProperties(context, includeChildrenRecursively) {
8846
+ includeProperties(includedPath, objectPath, context, includeChildrenRecursively) {
8717
8847
  if (!this.included) {
8718
8848
  this.included = true;
8719
8849
  if (this.variable) {
8720
- this.scope.context.includeVariableInModule(this.variable);
8850
+ this.scope.context.includeVariableInModule(this.variable, includedPath);
8721
8851
  }
8722
8852
  }
8723
- this.object.include(context, includeChildrenRecursively);
8724
- this.property.include(context, includeChildrenRecursively);
8853
+ else if (includedPath.length > 0) {
8854
+ this.variable?.includePath(includedPath, context);
8855
+ }
8856
+ this.object.includePath(objectPath, context, includeChildrenRecursively);
8857
+ this.property.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
8725
8858
  }
8726
8859
  }
8727
8860
  function resolveNamespaceVariables(baseVariable, path, astContext) {
@@ -8764,7 +8897,7 @@ class MetaProperty extends NodeBase {
8764
8897
  hasEffectsOnInteractionAtPath(path, { type }) {
8765
8898
  return path.length > 1 || type !== INTERACTION_ACCESSED;
8766
8899
  }
8767
- include() {
8900
+ includePath() {
8768
8901
  if (!this.included) {
8769
8902
  this.included = true;
8770
8903
  if (this.meta.name === IMPORT) {
@@ -8883,7 +9016,7 @@ class UndefinedVariable extends Variable {
8883
9016
 
8884
9017
  class ExportDefaultVariable extends LocalVariable {
8885
9018
  constructor(name, exportDefaultDeclaration, context) {
8886
- super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');
9019
+ super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, EMPTY_PATH, context, 'other');
8887
9020
  this.hasId = false;
8888
9021
  this.originalId = null;
8889
9022
  this.originalVariable = null;
@@ -9032,8 +9165,8 @@ class NamespaceVariable extends Variable {
9032
9165
  return (!memberVariable ||
9033
9166
  memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));
9034
9167
  }
9035
- include() {
9036
- super.include();
9168
+ includePath(path, context) {
9169
+ super.includePath(path, context);
9037
9170
  this.context.includeAllExports();
9038
9171
  }
9039
9172
  prepare(accessedGlobalsByScope) {
@@ -9126,9 +9259,9 @@ class SyntheticNamedExportVariable extends Variable {
9126
9259
  getName(getPropertyAccess) {
9127
9260
  return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;
9128
9261
  }
9129
- include() {
9130
- super.include();
9131
- this.context.includeVariableInModule(this.syntheticNamespace);
9262
+ includePath(path, context) {
9263
+ super.includePath(path, context);
9264
+ this.context.includeVariableInModule(this.syntheticNamespace, path);
9132
9265
  }
9133
9266
  setRenderNames(baseName, name) {
9134
9267
  super.setRenderNames(baseName, name);
@@ -12327,21 +12460,37 @@ class ArrayPattern extends NodeBase {
12327
12460
  element?.addExportedVariables(variables, exportNamesByVariable);
12328
12461
  }
12329
12462
  }
12330
- declare(kind) {
12463
+ declare(kind, destructuredInitPath, init) {
12331
12464
  const variables = [];
12465
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
12332
12466
  for (const element of this.elements) {
12333
12467
  if (element !== null) {
12334
- variables.push(...element.declare(kind, UNKNOWN_EXPRESSION));
12468
+ variables.push(...element.declare(kind, includedPatternPath, init));
12335
12469
  }
12336
12470
  }
12337
12471
  return variables;
12338
12472
  }
12473
+ deoptimizeAssignment(destructuredInitPath, init) {
12474
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
12475
+ for (const element of this.elements) {
12476
+ element?.deoptimizeAssignment(includedPatternPath, init);
12477
+ }
12478
+ }
12339
12479
  // Patterns can only be deoptimized at the empty path at the moment
12340
12480
  deoptimizePath() {
12341
12481
  for (const element of this.elements) {
12342
12482
  element?.deoptimizePath(EMPTY_PATH);
12343
12483
  }
12344
12484
  }
12485
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
12486
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
12487
+ for (const element of this.elements) {
12488
+ if (element?.hasEffectsWhenDestructuring(context, includedPatternPath, init)) {
12489
+ return true;
12490
+ }
12491
+ }
12492
+ return false;
12493
+ }
12345
12494
  // Patterns are only checked at the empty path at the moment
12346
12495
  hasEffectsOnInteractionAtPath(_path, interaction, context) {
12347
12496
  for (const element of this.elements) {
@@ -12350,12 +12499,24 @@ class ArrayPattern extends NodeBase {
12350
12499
  }
12351
12500
  return false;
12352
12501
  }
12502
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
12503
+ let included = false;
12504
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
12505
+ for (const element of this.elements) {
12506
+ included =
12507
+ element?.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
12508
+ }
12509
+ return (this.included ||= included);
12510
+ }
12353
12511
  markDeclarationReached() {
12354
12512
  for (const element of this.elements) {
12355
12513
  element?.markDeclarationReached();
12356
12514
  }
12357
12515
  }
12358
12516
  }
12517
+ const getIncludedPatternPath = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
12518
+ ? destructuredInitPath
12519
+ : [...destructuredInitPath, UnknownInteger];
12359
12520
 
12360
12521
  class ArrowFunctionExpression extends FunctionBase {
12361
12522
  constructor() {
@@ -12404,11 +12565,11 @@ class ArrowFunctionExpression extends FunctionBase {
12404
12565
  this.parent.callee === this;
12405
12566
  return isIIFE || super.onlyFunctionCallUsed();
12406
12567
  }
12407
- include(context, includeChildrenRecursively) {
12408
- super.include(context, includeChildrenRecursively);
12568
+ includePath(_path, context, includeChildrenRecursively) {
12569
+ super.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12409
12570
  for (const parameter of this.params) {
12410
12571
  if (!(parameter instanceof Identifier)) {
12411
- parameter.include(context, includeChildrenRecursively);
12572
+ parameter.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12412
12573
  }
12413
12574
  }
12414
12575
  }
@@ -12431,13 +12592,18 @@ class ObjectPattern extends NodeBase {
12431
12592
  }
12432
12593
  }
12433
12594
  }
12434
- declare(kind, init) {
12595
+ declare(kind, destructuredInitPath, init) {
12435
12596
  const variables = [];
12436
12597
  for (const property of this.properties) {
12437
- variables.push(...property.declare(kind, init));
12598
+ variables.push(...property.declare(kind, destructuredInitPath, init));
12438
12599
  }
12439
12600
  return variables;
12440
12601
  }
12602
+ deoptimizeAssignment(destructuredInitPath, init) {
12603
+ for (const property of this.properties) {
12604
+ property.deoptimizeAssignment(destructuredInitPath, init);
12605
+ }
12606
+ }
12441
12607
  deoptimizePath(path) {
12442
12608
  if (path.length === 0) {
12443
12609
  for (const property of this.properties) {
@@ -12455,11 +12621,44 @@ class ObjectPattern extends NodeBase {
12455
12621
  }
12456
12622
  return false;
12457
12623
  }
12624
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
12625
+ for (const property of this.properties) {
12626
+ if (property.hasEffectsWhenDestructuring(context, destructuredInitPath, init))
12627
+ return true;
12628
+ }
12629
+ return false;
12630
+ }
12631
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
12632
+ let included = false;
12633
+ for (const property of this.properties) {
12634
+ included =
12635
+ property.includeDestructuredIfNecessary(context, destructuredInitPath, init) || included;
12636
+ }
12637
+ return (this.included ||= included);
12638
+ }
12458
12639
  markDeclarationReached() {
12459
12640
  for (const property of this.properties) {
12460
12641
  property.markDeclarationReached();
12461
12642
  }
12462
12643
  }
12644
+ render(code, options) {
12645
+ if (this.properties.length > 0) {
12646
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
12647
+ let lastSeparatorPos = null;
12648
+ for (const { node, separator, start, end } of separatedNodes) {
12649
+ if (!node.included) {
12650
+ treeshakeNode(node, code, start, end);
12651
+ continue;
12652
+ }
12653
+ lastSeparatorPos = separator;
12654
+ node.render(code, options);
12655
+ }
12656
+ if (lastSeparatorPos) {
12657
+ code.remove(lastSeparatorPos, this.end - 1);
12658
+ }
12659
+ }
12660
+ }
12661
+ applyDeoptimizations() { }
12463
12662
  }
12464
12663
 
12465
12664
  class AssignmentExpression extends NodeBase {
@@ -12469,23 +12668,27 @@ class AssignmentExpression extends NodeBase {
12469
12668
  this.applyDeoptimizations();
12470
12669
  // MemberExpressions do not access the property before assignments if the
12471
12670
  // operator is '='.
12472
- return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '='));
12671
+ return (right.hasEffects(context) ||
12672
+ left.hasEffectsAsAssignmentTarget(context, operator !== '=') ||
12673
+ this.left.hasEffectsWhenDestructuring?.(context, EMPTY_PATH, right));
12473
12674
  }
12474
12675
  hasEffectsOnInteractionAtPath(path, interaction, context) {
12475
12676
  return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);
12476
12677
  }
12477
- include(context, includeChildrenRecursively) {
12678
+ includePath(_path, context, includeChildrenRecursively) {
12478
12679
  const { deoptimized, left, right, operator } = this;
12479
12680
  if (!deoptimized)
12480
12681
  this.applyDeoptimizations();
12481
12682
  this.included = true;
12683
+ const hasEffectsContext = createHasEffectsContext();
12482
12684
  if (includeChildrenRecursively ||
12483
12685
  operator !== '=' ||
12484
12686
  left.included ||
12485
- left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {
12687
+ left.hasEffectsAsAssignmentTarget(hasEffectsContext, false) ||
12688
+ left.hasEffectsWhenDestructuring?.(hasEffectsContext, EMPTY_PATH, right)) {
12486
12689
  left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');
12487
12690
  }
12488
- right.include(context, includeChildrenRecursively);
12691
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12489
12692
  }
12490
12693
  initialise() {
12491
12694
  super.initialise();
@@ -12547,8 +12750,7 @@ class AssignmentExpression extends NodeBase {
12547
12750
  }
12548
12751
  applyDeoptimizations() {
12549
12752
  this.deoptimized = true;
12550
- this.left.deoptimizePath(EMPTY_PATH);
12551
- this.right.deoptimizePath(UNKNOWN_PATH);
12753
+ this.left.deoptimizeAssignment(EMPTY_PATH, this.right);
12552
12754
  this.scope.context.requestTreeshakingPass();
12553
12755
  }
12554
12756
  }
@@ -12557,8 +12759,11 @@ class AssignmentPattern extends NodeBase {
12557
12759
  addExportedVariables(variables, exportNamesByVariable) {
12558
12760
  this.left.addExportedVariables(variables, exportNamesByVariable);
12559
12761
  }
12560
- declare(kind, init) {
12561
- return this.left.declare(kind, init);
12762
+ declare(kind, destructuredInitPath, init) {
12763
+ return this.left.declare(kind, destructuredInitPath, init);
12764
+ }
12765
+ deoptimizeAssignment(destructuredInitPath, init) {
12766
+ this.left.deoptimizeAssignment(destructuredInitPath, init);
12562
12767
  }
12563
12768
  deoptimizePath(path) {
12564
12769
  if (path.length === 0) {
@@ -12568,6 +12773,17 @@ class AssignmentPattern extends NodeBase {
12568
12773
  hasEffectsOnInteractionAtPath(path, interaction, context) {
12569
12774
  return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
12570
12775
  }
12776
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
12777
+ return this.left.hasEffectsWhenDestructuring(context, destructuredInitPath, init);
12778
+ }
12779
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
12780
+ let included = this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init) ||
12781
+ this.included;
12782
+ if ((included ||= this.right.shouldBeIncluded(context))) {
12783
+ this.right.includePath(UNKNOWN_PATH, context, false);
12784
+ }
12785
+ return (this.included = included);
12786
+ }
12571
12787
  markDeclarationReached() {
12572
12788
  this.left.markDeclarationReached();
12573
12789
  }
@@ -12589,7 +12805,7 @@ class AwaitExpression extends NodeBase {
12589
12805
  this.applyDeoptimizations();
12590
12806
  return true;
12591
12807
  }
12592
- include(context, includeChildrenRecursively) {
12808
+ includePath(path, context, includeChildrenRecursively) {
12593
12809
  if (!this.deoptimized)
12594
12810
  this.applyDeoptimizations();
12595
12811
  if (!this.included) {
@@ -12603,7 +12819,7 @@ class AwaitExpression extends NodeBase {
12603
12819
  this.scope.context.usesTopLevelAwait = true;
12604
12820
  }
12605
12821
  }
12606
- this.argument.include(context, includeChildrenRecursively);
12822
+ this.argument.includePath(path, context, includeChildrenRecursively);
12607
12823
  }
12608
12824
  }
12609
12825
 
@@ -12685,10 +12901,10 @@ class BreakStatement extends NodeBase {
12685
12901
  context.brokenFlow = true;
12686
12902
  return false;
12687
12903
  }
12688
- include(context) {
12904
+ includePath(_, context) {
12689
12905
  this.included = true;
12690
12906
  if (this.label) {
12691
- this.label.include();
12907
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
12692
12908
  context.includedLabels.add(this.label.name);
12693
12909
  }
12694
12910
  else {
@@ -12882,11 +13098,11 @@ class CallExpression extends CallExpressionBase {
12882
13098
  (calleeHasEffects ||
12883
13099
  this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)));
12884
13100
  }
12885
- include(context, includeChildrenRecursively) {
13101
+ includePath(path, context, includeChildrenRecursively) {
12886
13102
  if (!this.deoptimized)
12887
13103
  this.applyDeoptimizations();
12888
13104
  if (includeChildrenRecursively) {
12889
- super.include(context, includeChildrenRecursively);
13105
+ super.includePath(path, context, includeChildrenRecursively);
12890
13106
  if (includeChildrenRecursively === INCLUDE_PARAMETERS &&
12891
13107
  this.callee instanceof Identifier &&
12892
13108
  this.callee.variable) {
@@ -12895,9 +13111,18 @@ class CallExpression extends CallExpressionBase {
12895
13111
  }
12896
13112
  else {
12897
13113
  this.included = true;
12898
- this.callee.include(context, false);
13114
+ // If the callee is a member expression and does not have a variable, its
13115
+ // object will already be included via the first argument of the
13116
+ // interaction in includeCallArguments. Including it again can lead to
13117
+ // severe performance problems.
13118
+ if (this.callee instanceof MemberExpression && !this.callee.variable) {
13119
+ this.callee.property.includePath(UNKNOWN_PATH, context, false);
13120
+ }
13121
+ else {
13122
+ this.callee.includePath(UNKNOWN_PATH, context, false);
13123
+ }
13124
+ this.callee.includeCallArguments(context, this.interaction);
12899
13125
  }
12900
- this.callee.includeCallArguments(context, this.arguments);
12901
13126
  }
12902
13127
  initialise() {
12903
13128
  super.initialise();
@@ -12936,7 +13161,7 @@ class CatchClause extends NodeBase {
12936
13161
  this.type = type;
12937
13162
  if (param) {
12938
13163
  this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);
12939
- this.param.declare('parameter', UNKNOWN_EXPRESSION);
13164
+ this.param.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
12940
13165
  }
12941
13166
  this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);
12942
13167
  return super.parseNode(esTreeNode);
@@ -12964,7 +13189,7 @@ class ClassBodyScope extends ChildScope {
12964
13189
  constructor(parent, classNode) {
12965
13190
  const { context } = parent;
12966
13191
  super(parent, context);
12967
- this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));
13192
+ this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, EMPTY_PATH, context, 'other')));
12968
13193
  this.instanceScope = new ChildScope(this, context);
12969
13194
  this.instanceScope.variables.set('this', new ThisVariable(context));
12970
13195
  }
@@ -12977,11 +13202,11 @@ class ClassBody extends NodeBase {
12977
13202
  createScope(parentScope) {
12978
13203
  this.scope = new ClassBodyScope(parentScope, this.parent);
12979
13204
  }
12980
- include(context, includeChildrenRecursively) {
13205
+ includePath(_path, context, includeChildrenRecursively) {
12981
13206
  this.included = true;
12982
- this.scope.context.includeVariableInModule(this.scope.thisVariable);
13207
+ this.scope.context.includeVariableInModule(this.scope.thisVariable, UNKNOWN_PATH);
12983
13208
  for (const definition of this.body) {
12984
- definition.include(context, includeChildrenRecursively);
13209
+ definition.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
12985
13210
  }
12986
13211
  }
12987
13212
  parseNode(esTreeNode) {
@@ -13105,26 +13330,26 @@ class ConditionalExpression extends NodeBase {
13105
13330
  }
13106
13331
  return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
13107
13332
  }
13108
- include(context, includeChildrenRecursively) {
13333
+ includePath(path, context, includeChildrenRecursively) {
13109
13334
  this.included = true;
13110
13335
  const usedBranch = this.getUsedBranch();
13111
13336
  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);
13337
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13338
+ this.consequent.includePath(path, context, includeChildrenRecursively);
13339
+ this.alternate.includePath(path, context, includeChildrenRecursively);
13115
13340
  }
13116
13341
  else {
13117
- usedBranch.include(context, includeChildrenRecursively);
13342
+ usedBranch.includePath(path, context, includeChildrenRecursively);
13118
13343
  }
13119
13344
  }
13120
- includeCallArguments(context, parameters) {
13345
+ includeCallArguments(context, interaction) {
13121
13346
  const usedBranch = this.getUsedBranch();
13122
13347
  if (usedBranch) {
13123
- usedBranch.includeCallArguments(context, parameters);
13348
+ usedBranch.includeCallArguments(context, interaction);
13124
13349
  }
13125
13350
  else {
13126
- this.consequent.includeCallArguments(context, parameters);
13127
- this.alternate.includeCallArguments(context, parameters);
13351
+ this.consequent.includeCallArguments(context, interaction);
13352
+ this.alternate.includeCallArguments(context, interaction);
13128
13353
  }
13129
13354
  }
13130
13355
  removeAnnotations(code) {
@@ -13185,10 +13410,10 @@ class ContinueStatement extends NodeBase {
13185
13410
  context.brokenFlow = true;
13186
13411
  return false;
13187
13412
  }
13188
- include(context) {
13413
+ includePath(_, context) {
13189
13414
  this.included = true;
13190
13415
  if (this.label) {
13191
- this.label.include();
13416
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
13192
13417
  context.includedLabels.add(this.label.name);
13193
13418
  }
13194
13419
  else {
@@ -13231,7 +13456,7 @@ function includeLoopBody(context, body, includeChildrenRecursively) {
13231
13456
  const { brokenFlow, hasBreak, hasContinue } = context;
13232
13457
  context.hasBreak = false;
13233
13458
  context.hasContinue = false;
13234
- body.include(context, includeChildrenRecursively, { asSingleStatement: true });
13459
+ body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively, { asSingleStatement: true });
13235
13460
  context.hasBreak = hasBreak;
13236
13461
  context.hasContinue = hasContinue;
13237
13462
  context.brokenFlow = brokenFlow;
@@ -13243,9 +13468,9 @@ class DoWhileStatement extends NodeBase {
13243
13468
  return true;
13244
13469
  return hasLoopBodyEffects(context, this.body);
13245
13470
  }
13246
- include(context, includeChildrenRecursively) {
13471
+ includePath(_path, context, includeChildrenRecursively) {
13247
13472
  this.included = true;
13248
- this.test.include(context, includeChildrenRecursively);
13473
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13249
13474
  includeLoopBody(context, this.body, includeChildrenRecursively);
13250
13475
  }
13251
13476
  }
@@ -13316,13 +13541,13 @@ class ForInStatement extends NodeBase {
13316
13541
  return true;
13317
13542
  return hasLoopBodyEffects(context, body);
13318
13543
  }
13319
- include(context, includeChildrenRecursively) {
13544
+ includePath(_path, context, includeChildrenRecursively) {
13320
13545
  const { body, deoptimized, left, right } = this;
13321
13546
  if (!deoptimized)
13322
13547
  this.applyDeoptimizations();
13323
13548
  this.included = true;
13324
13549
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
13325
- right.include(context, includeChildrenRecursively);
13550
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13326
13551
  includeLoopBody(context, body, includeChildrenRecursively);
13327
13552
  }
13328
13553
  initialise() {
@@ -13361,13 +13586,13 @@ class ForOfStatement extends NodeBase {
13361
13586
  // Placeholder until proper Symbol.Iterator support
13362
13587
  return true;
13363
13588
  }
13364
- include(context, includeChildrenRecursively) {
13589
+ includePath(_path, context, includeChildrenRecursively) {
13365
13590
  const { body, deoptimized, left, right } = this;
13366
13591
  if (!deoptimized)
13367
13592
  this.applyDeoptimizations();
13368
13593
  this.included = true;
13369
13594
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
13370
- right.include(context, includeChildrenRecursively);
13595
+ right.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13371
13596
  includeLoopBody(context, body, includeChildrenRecursively);
13372
13597
  }
13373
13598
  initialise() {
@@ -13403,11 +13628,13 @@ class ForStatement extends NodeBase {
13403
13628
  }
13404
13629
  return hasLoopBodyEffects(context, this.body);
13405
13630
  }
13406
- include(context, includeChildrenRecursively) {
13631
+ includePath(_path, context, includeChildrenRecursively) {
13407
13632
  this.included = true;
13408
- this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true });
13409
- this.test?.include(context, includeChildrenRecursively);
13410
- this.update?.include(context, includeChildrenRecursively);
13633
+ this.init?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively, {
13634
+ asSingleStatement: true
13635
+ });
13636
+ this.test?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13637
+ this.update?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13411
13638
  includeLoopBody(context, this.body, includeChildrenRecursively);
13412
13639
  }
13413
13640
  render(code, options) {
@@ -13448,9 +13675,9 @@ class TrackingScope extends BlockScope {
13448
13675
  super(...arguments);
13449
13676
  this.hoistedDeclarations = [];
13450
13677
  }
13451
- addDeclaration(identifier, context, init, kind) {
13678
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
13452
13679
  this.hoistedDeclarations.push(identifier);
13453
- return super.addDeclaration(identifier, context, init, kind);
13680
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
13454
13681
  }
13455
13682
  }
13456
13683
 
@@ -13483,7 +13710,7 @@ class IfStatement extends NodeBase {
13483
13710
  }
13484
13711
  return testValue ? this.consequent.hasEffects(context) : !!this.alternate?.hasEffects(context);
13485
13712
  }
13486
- include(context, includeChildrenRecursively) {
13713
+ includePath(_, context, includeChildrenRecursively) {
13487
13714
  this.included = true;
13488
13715
  if (includeChildrenRecursively) {
13489
13716
  this.includeRecursively(includeChildrenRecursively, context);
@@ -13558,31 +13785,31 @@ class IfStatement extends NodeBase {
13558
13785
  }
13559
13786
  includeKnownTest(context, testValue) {
13560
13787
  if (this.test.shouldBeIncluded(context)) {
13561
- this.test.include(context, false);
13788
+ this.test.includePath(UNKNOWN_PATH, context, false);
13562
13789
  }
13563
13790
  if (testValue && this.consequent.shouldBeIncluded(context)) {
13564
- this.consequent.include(context, false, { asSingleStatement: true });
13791
+ this.consequent.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
13565
13792
  }
13566
13793
  if (!testValue && this.alternate?.shouldBeIncluded(context)) {
13567
- this.alternate.include(context, false, { asSingleStatement: true });
13794
+ this.alternate.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
13568
13795
  }
13569
13796
  }
13570
13797
  includeRecursively(includeChildrenRecursively, context) {
13571
- this.test.include(context, includeChildrenRecursively);
13572
- this.consequent.include(context, includeChildrenRecursively);
13573
- this.alternate?.include(context, includeChildrenRecursively);
13798
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13799
+ this.consequent.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13800
+ this.alternate?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
13574
13801
  }
13575
13802
  includeUnknownTest(context) {
13576
- this.test.include(context, false);
13803
+ this.test.includePath(UNKNOWN_PATH, context, false);
13577
13804
  const { brokenFlow } = context;
13578
13805
  let consequentBrokenFlow = false;
13579
13806
  if (this.consequent.shouldBeIncluded(context)) {
13580
- this.consequent.include(context, false, { asSingleStatement: true });
13807
+ this.consequent.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
13581
13808
  consequentBrokenFlow = context.brokenFlow;
13582
13809
  context.brokenFlow = brokenFlow;
13583
13810
  }
13584
13811
  if (this.alternate?.shouldBeIncluded(context)) {
13585
- this.alternate.include(context, false, { asSingleStatement: true });
13812
+ this.alternate.includePath(UNKNOWN_PATH, context, false, { asSingleStatement: true });
13586
13813
  context.brokenFlow = context.brokenFlow && consequentBrokenFlow;
13587
13814
  }
13588
13815
  }
@@ -13650,7 +13877,7 @@ function isReassignedExportsMember(variable, exportNamesByVariable) {
13650
13877
  class VariableDeclarator extends NodeBase {
13651
13878
  declareDeclarator(kind, isUsingDeclaration) {
13652
13879
  this.isUsingDeclaration = isUsingDeclaration;
13653
- this.id.declare(kind, this.init || UNDEFINED_EXPRESSION);
13880
+ this.id.declare(kind, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION);
13654
13881
  }
13655
13882
  deoptimizePath(path) {
13656
13883
  this.id.deoptimizePath(path);
@@ -13660,17 +13887,25 @@ class VariableDeclarator extends NodeBase {
13660
13887
  this.applyDeoptimizations();
13661
13888
  const initEffect = this.init?.hasEffects(context);
13662
13889
  this.id.markDeclarationReached();
13663
- return initEffect || this.id.hasEffects(context) || this.isUsingDeclaration;
13664
- }
13665
- include(context, includeChildrenRecursively) {
13890
+ return (initEffect ||
13891
+ this.isUsingDeclaration ||
13892
+ this.id.hasEffects(context) ||
13893
+ (this.scope.context.options.treeshake
13894
+ .propertyReadSideEffects &&
13895
+ this.id.hasEffectsWhenDestructuring(context, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION)));
13896
+ }
13897
+ includePath(_path, context, includeChildrenRecursively) {
13666
13898
  const { deoptimized, id, init } = this;
13667
13899
  if (!deoptimized)
13668
13900
  this.applyDeoptimizations();
13669
13901
  this.included = true;
13670
- init?.include(context, includeChildrenRecursively);
13902
+ init?.includePath(EMPTY_PATH, context, includeChildrenRecursively);
13671
13903
  id.markDeclarationReached();
13672
- if (includeChildrenRecursively || id.shouldBeIncluded(context)) {
13673
- id.include(context, includeChildrenRecursively);
13904
+ if (includeChildrenRecursively) {
13905
+ id.includePath(EMPTY_PATH, context, includeChildrenRecursively);
13906
+ }
13907
+ else {
13908
+ id.includeDestructuredIfNecessary(context, EMPTY_PATH, init || UNDEFINED_EXPRESSION);
13674
13909
  }
13675
13910
  }
13676
13911
  removeAnnotations(code) {
@@ -13719,6 +13954,8 @@ class ImportExpression extends NodeBase {
13719
13954
  constructor() {
13720
13955
  super(...arguments);
13721
13956
  this.inlineNamespace = null;
13957
+ this.hasUnknownAccessedKey = false;
13958
+ this.accessedPropKey = new Set();
13722
13959
  this.attributes = null;
13723
13960
  this.mechanism = null;
13724
13961
  this.namespaceExportName = undefined;
@@ -13751,12 +13988,15 @@ class ImportExpression extends NodeBase {
13751
13988
  if (parent2 instanceof ExpressionStatement) {
13752
13989
  return parseAst_js.EMPTY_ARRAY;
13753
13990
  }
13754
- // Case 1: const { foo } = await import('bar')
13991
+ // Case 1: const { foo } / module = await import('bar')
13755
13992
  if (parent2 instanceof VariableDeclarator) {
13756
13993
  const declaration = parent2.id;
13757
- return declaration instanceof ObjectPattern
13758
- ? getDeterministicObjectDestructure(declaration)
13759
- : undefined;
13994
+ if (declaration instanceof Identifier) {
13995
+ return this.hasUnknownAccessedKey ? undefined : [...this.accessedPropKey];
13996
+ }
13997
+ if (declaration instanceof ObjectPattern) {
13998
+ return getDeterministicObjectDestructure(declaration);
13999
+ }
13760
14000
  }
13761
14001
  // Case 2: (await import('bar')).foo
13762
14002
  if (parent2 instanceof MemberExpression) {
@@ -13805,13 +14045,23 @@ class ImportExpression extends NodeBase {
13805
14045
  hasEffects() {
13806
14046
  return true;
13807
14047
  }
13808
- include(context, includeChildrenRecursively) {
14048
+ includePath(path, context, includeChildrenRecursively) {
13809
14049
  if (!this.included) {
13810
14050
  this.included = true;
13811
14051
  this.scope.context.includeDynamicImport(this);
13812
14052
  this.scope.addAccessedDynamicImport(this);
14053
+ this.source.includePath(path, context, includeChildrenRecursively);
14054
+ }
14055
+ if (this.hasUnknownAccessedKey)
14056
+ return;
14057
+ if (path[0] === UnknownKey) {
14058
+ this.hasUnknownAccessedKey = true;
14059
+ this.scope.context.includeDynamicImport(this);
14060
+ }
14061
+ else if (typeof path[0] === 'string') {
14062
+ this.accessedPropKey.add(path[0]);
14063
+ this.scope.context.includeDynamicImport(this);
13813
14064
  }
13814
- this.source.include(context, includeChildrenRecursively);
13815
14065
  }
13816
14066
  initialise() {
13817
14067
  super.initialise();
@@ -14139,7 +14389,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
14139
14389
  if (preserve) {
14140
14390
  // This pretends we are accessing an included global variable of the same name
14141
14391
  const globalVariable = node.scope.findGlobal(baseName);
14142
- globalVariable.include();
14392
+ globalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
14143
14393
  // This excludes this variable from renaming
14144
14394
  factoryVariable.globalName = baseName;
14145
14395
  }
@@ -14147,7 +14397,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
14147
14397
  else {
14148
14398
  factoryVariable = node.scope.findGlobal(baseName);
14149
14399
  }
14150
- node.scope.context.includeVariableInModule(factoryVariable);
14400
+ node.scope.context.includeVariableInModule(factoryVariable, UNKNOWN_PATH);
14151
14401
  if (factoryVariable instanceof LocalVariable) {
14152
14402
  factoryVariable.consolidateInitializers();
14153
14403
  factoryVariable.addUsedPlace(node);
@@ -14169,7 +14419,7 @@ class JSXElementBase extends NodeBase {
14169
14419
  this.scope.context.addImportSource(importSource);
14170
14420
  }
14171
14421
  }
14172
- include(context, includeChildrenRecursively) {
14422
+ includePath(path, context, includeChildrenRecursively) {
14173
14423
  if (!this.included) {
14174
14424
  const { factory, importSource, mode } = this.jsxMode;
14175
14425
  if (factory) {
@@ -14177,7 +14427,7 @@ class JSXElementBase extends NodeBase {
14177
14427
  this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this);
14178
14428
  }
14179
14429
  }
14180
- super.include(context, includeChildrenRecursively);
14430
+ super.includePath(path, context, includeChildrenRecursively);
14181
14431
  }
14182
14432
  applyDeoptimizations() { }
14183
14433
  getRenderingMode() {
@@ -14439,7 +14689,7 @@ class JSXOpeningFragment extends NodeBase {
14439
14689
  this.fragment = null;
14440
14690
  this.fragmentVariable = null;
14441
14691
  }
14442
- include(context, includeChildrenRecursively) {
14692
+ includePath(path, context, includeChildrenRecursively) {
14443
14693
  if (!this.included) {
14444
14694
  const jsx = this.scope.context.options.jsx;
14445
14695
  if (jsx.mode === 'automatic') {
@@ -14454,7 +14704,7 @@ class JSXOpeningFragment extends NodeBase {
14454
14704
  }
14455
14705
  }
14456
14706
  }
14457
- super.include(context, includeChildrenRecursively);
14707
+ super.includePath(path, context, includeChildrenRecursively);
14458
14708
  }
14459
14709
  render(code, options) {
14460
14710
  const { mode } = this.scope.context.options.jsx;
@@ -14511,13 +14761,13 @@ class LabeledStatement extends NodeBase {
14511
14761
  context.includedLabels = new Set([...includedLabels, ...context.includedLabels]);
14512
14762
  return bodyHasEffects;
14513
14763
  }
14514
- include(context, includeChildrenRecursively) {
14764
+ includePath(_path, context, includeChildrenRecursively) {
14515
14765
  this.included = true;
14516
14766
  const { brokenFlow, includedLabels } = context;
14517
14767
  context.includedLabels = new Set();
14518
- this.body.include(context, includeChildrenRecursively);
14768
+ this.body.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14519
14769
  if (includeChildrenRecursively || context.includedLabels.has(this.label.name)) {
14520
- this.label.include();
14770
+ this.label.includePath(UNKNOWN_PATH, createInclusionContext());
14521
14771
  context.includedLabels.delete(this.label.name);
14522
14772
  context.brokenFlow = brokenFlow;
14523
14773
  }
@@ -14614,17 +14864,17 @@ class LogicalExpression extends NodeBase {
14614
14864
  }
14615
14865
  return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
14616
14866
  }
14617
- include(context, includeChildrenRecursively) {
14867
+ includePath(path, context, includeChildrenRecursively) {
14618
14868
  this.included = true;
14619
14869
  const usedBranch = this.getUsedBranch();
14620
14870
  if (includeChildrenRecursively ||
14621
14871
  (usedBranch === this.right && this.left.shouldBeIncluded(context)) ||
14622
14872
  !usedBranch) {
14623
- this.left.include(context, includeChildrenRecursively);
14624
- this.right.include(context, includeChildrenRecursively);
14873
+ this.left.includePath(path, context, includeChildrenRecursively);
14874
+ this.right.includePath(path, context, includeChildrenRecursively);
14625
14875
  }
14626
14876
  else {
14627
- usedBranch.include(context, includeChildrenRecursively);
14877
+ usedBranch.includePath(path, context, includeChildrenRecursively);
14628
14878
  }
14629
14879
  }
14630
14880
  removeAnnotations(code) {
@@ -14696,17 +14946,17 @@ class NewExpression extends NodeBase {
14696
14946
  hasEffectsOnInteractionAtPath(path, { type }) {
14697
14947
  return path.length > 0 || type !== INTERACTION_ACCESSED;
14698
14948
  }
14699
- include(context, includeChildrenRecursively) {
14949
+ includePath(path, context, includeChildrenRecursively) {
14700
14950
  if (!this.deoptimized)
14701
14951
  this.applyDeoptimizations();
14702
14952
  if (includeChildrenRecursively) {
14703
- super.include(context, includeChildrenRecursively);
14953
+ super.includePath(path, context, includeChildrenRecursively);
14704
14954
  }
14705
14955
  else {
14706
14956
  this.included = true;
14707
- this.callee.include(context, false);
14957
+ this.callee.includePath(UNKNOWN_PATH, context, false);
14708
14958
  }
14709
- this.callee.includeCallArguments(context, this.arguments);
14959
+ this.callee.includeCallArguments(context, this.interaction);
14710
14960
  }
14711
14961
  initialise() {
14712
14962
  super.initialise();
@@ -14735,6 +14985,7 @@ class ObjectExpression extends NodeBase {
14735
14985
  constructor() {
14736
14986
  super(...arguments);
14737
14987
  this.objectEntity = null;
14988
+ this.protoProp = null;
14738
14989
  }
14739
14990
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
14740
14991
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -14754,13 +15005,32 @@ class ObjectExpression extends NodeBase {
14754
15005
  hasEffectsOnInteractionAtPath(path, interaction, context) {
14755
15006
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
14756
15007
  }
15008
+ includePath(path, context, includeChildrenRecursively) {
15009
+ this.included = true;
15010
+ this.getObjectEntity().includePath(path, context, includeChildrenRecursively);
15011
+ this.protoProp?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15012
+ }
14757
15013
  render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {
14758
- super.render(code, options);
14759
15014
  if (renderedSurroundingElement === parseAst_js.ExpressionStatement ||
14760
15015
  renderedSurroundingElement === parseAst_js.ArrowFunctionExpression) {
14761
15016
  code.appendRight(this.start, '(');
14762
15017
  code.prependLeft(this.end, ')');
14763
15018
  }
15019
+ if (this.properties.length > 0) {
15020
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
15021
+ let lastSeparatorPos = null;
15022
+ for (const { node, separator, start, end } of separatedNodes) {
15023
+ if (!node.included) {
15024
+ treeshakeNode(node, code, start, end);
15025
+ continue;
15026
+ }
15027
+ lastSeparatorPos = separator;
15028
+ node.render(code, options);
15029
+ }
15030
+ if (lastSeparatorPos) {
15031
+ code.remove(lastSeparatorPos, this.end - 1);
15032
+ }
15033
+ }
14764
15034
  }
14765
15035
  applyDeoptimizations() { }
14766
15036
  getObjectEntity() {
@@ -14791,6 +15061,7 @@ class ObjectExpression extends NodeBase {
14791
15061
  ? property.key.name
14792
15062
  : String(property.key.value);
14793
15063
  if (key === '__proto__' && property.kind === 'init') {
15064
+ this.protoProp = property;
14794
15065
  prototype =
14795
15066
  property.value instanceof Literal && property.value.value === null
14796
15067
  ? null
@@ -14857,11 +15128,11 @@ class Program extends NodeBase {
14857
15128
  }
14858
15129
  return false;
14859
15130
  }
14860
- include(context, includeChildrenRecursively) {
15131
+ includePath(_path, context, includeChildrenRecursively) {
14861
15132
  this.included = true;
14862
15133
  for (const node of this.body) {
14863
15134
  if (includeChildrenRecursively || node.shouldBeIncluded(context)) {
14864
- node.include(context, includeChildrenRecursively);
15135
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14865
15136
  }
14866
15137
  }
14867
15138
  }
@@ -14900,10 +15171,6 @@ class Program extends NodeBase {
14900
15171
  }
14901
15172
 
14902
15173
  class Property extends MethodBase {
14903
- constructor() {
14904
- super(...arguments);
14905
- this.declarationInit = null;
14906
- }
14907
15174
  //declare method: boolean;
14908
15175
  get method() {
14909
15176
  return isFlagSet(this.flags, 262144 /* Flag.method */);
@@ -14918,17 +15185,32 @@ class Property extends MethodBase {
14918
15185
  set shorthand(value) {
14919
15186
  this.flags = setFlag(this.flags, 524288 /* Flag.shorthand */, value);
14920
15187
  }
14921
- declare(kind, init) {
14922
- this.declarationInit = init;
14923
- return this.value.declare(kind, UNKNOWN_EXPRESSION);
15188
+ declare(kind, destructuredInitPath, init) {
15189
+ return this.value.declare(kind, this.getPathInProperty(destructuredInitPath), init);
15190
+ }
15191
+ deoptimizeAssignment(destructuredInitPath, init) {
15192
+ this.value.deoptimizeAssignment?.(this.getPathInProperty(destructuredInitPath), init);
14924
15193
  }
14925
15194
  hasEffects(context) {
14926
15195
  if (!this.deoptimized)
14927
15196
  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));
15197
+ return this.key.hasEffects(context) || this.value.hasEffects(context);
15198
+ }
15199
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
15200
+ return this.value.hasEffectsWhenDestructuring?.(context, this.getPathInProperty(destructuredInitPath), init);
15201
+ }
15202
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
15203
+ let included = this.value.includeDestructuredIfNecessary(context, this.getPathInProperty(destructuredInitPath), init) || this.included;
15204
+ included ||= this.key.hasEffects(createHasEffectsContext());
15205
+ if (included) {
15206
+ this.key.includePath(EMPTY_PATH, context, false);
15207
+ }
15208
+ return (this.included = included);
15209
+ }
15210
+ includePath(path, context, includeChildrenRecursively) {
15211
+ this.included = true;
15212
+ this.key.includePath(EMPTY_PATH, context, includeChildrenRecursively);
15213
+ this.value.includePath(path, context, includeChildrenRecursively);
14932
15214
  }
14933
15215
  markDeclarationReached() {
14934
15216
  this.value.markDeclarationReached();
@@ -14939,12 +15221,17 @@ class Property extends MethodBase {
14939
15221
  }
14940
15222
  this.value.render(code, options, { isShorthandProperty: this.shorthand });
14941
15223
  }
14942
- applyDeoptimizations() {
14943
- this.deoptimized = true;
14944
- if (this.declarationInit !== null) {
14945
- this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
14946
- this.scope.context.requestTreeshakingPass();
14947
- }
15224
+ applyDeoptimizations() { }
15225
+ getPathInProperty(destructuredInitPath) {
15226
+ return destructuredInitPath.at(-1) === UnknownKey
15227
+ ? destructuredInitPath
15228
+ : // For now, we only consider static paths as we do not know how to
15229
+ // deoptimize the path in the dynamic case.
15230
+ this.computed
15231
+ ? [...destructuredInitPath, UnknownKey]
15232
+ : this.key instanceof Identifier
15233
+ ? [...destructuredInitPath, this.key.name]
15234
+ : [...destructuredInitPath, String(this.key.value)];
14948
15235
  }
14949
15236
  }
14950
15237
 
@@ -14989,9 +15276,9 @@ class ReturnStatement extends NodeBase {
14989
15276
  context.brokenFlow = true;
14990
15277
  return false;
14991
15278
  }
14992
- include(context, includeChildrenRecursively) {
15279
+ includePath(_path, context, includeChildrenRecursively) {
14993
15280
  this.included = true;
14994
- this.argument?.include(context, includeChildrenRecursively);
15281
+ this.argument?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
14995
15282
  context.brokenFlow = true;
14996
15283
  }
14997
15284
  initialise() {
@@ -15028,14 +15315,14 @@ class SequenceExpression extends NodeBase {
15028
15315
  hasEffectsOnInteractionAtPath(path, interaction, context) {
15029
15316
  return this.expressions[this.expressions.length - 1].hasEffectsOnInteractionAtPath(path, interaction, context);
15030
15317
  }
15031
- include(context, includeChildrenRecursively) {
15318
+ includePath(path, context, includeChildrenRecursively) {
15032
15319
  this.included = true;
15033
15320
  const lastExpression = this.expressions[this.expressions.length - 1];
15034
15321
  for (const expression of this.expressions) {
15035
15322
  if (includeChildrenRecursively ||
15036
15323
  (expression === lastExpression && !(this.parent instanceof ExpressionStatement)) ||
15037
15324
  expression.shouldBeIncluded(context))
15038
- expression.include(context, includeChildrenRecursively);
15325
+ expression.includePath(path, context, includeChildrenRecursively);
15039
15326
  }
15040
15327
  }
15041
15328
  removeAnnotations(code) {
@@ -15083,10 +15370,13 @@ class Super extends NodeBase {
15083
15370
  deoptimizePath(path) {
15084
15371
  this.variable.deoptimizePath(path);
15085
15372
  }
15086
- include() {
15373
+ includePath(path, context) {
15087
15374
  if (!this.included) {
15088
15375
  this.included = true;
15089
- this.scope.context.includeVariableInModule(this.variable);
15376
+ this.scope.context.includeVariableInModule(this.variable, path);
15377
+ }
15378
+ else if (path.length > 0) {
15379
+ this.variable.includePath(path, context);
15090
15380
  }
15091
15381
  }
15092
15382
  }
@@ -15103,12 +15393,12 @@ class SwitchCase extends NodeBase {
15103
15393
  }
15104
15394
  return false;
15105
15395
  }
15106
- include(context, includeChildrenRecursively) {
15396
+ includePath(_path, context, includeChildrenRecursively) {
15107
15397
  this.included = true;
15108
- this.test?.include(context, includeChildrenRecursively);
15398
+ this.test?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15109
15399
  for (const node of this.consequent) {
15110
15400
  if (includeChildrenRecursively || node.shouldBeIncluded(context))
15111
- node.include(context, includeChildrenRecursively);
15401
+ node.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15112
15402
  }
15113
15403
  }
15114
15404
  render(code, options, nodeRenderOptions) {
@@ -15156,9 +15446,9 @@ class SwitchStatement extends NodeBase {
15156
15446
  context.hasBreak = hasBreak;
15157
15447
  return false;
15158
15448
  }
15159
- include(context, includeChildrenRecursively) {
15449
+ includePath(_path, context, includeChildrenRecursively) {
15160
15450
  this.included = true;
15161
- this.discriminant.include(context, includeChildrenRecursively);
15451
+ this.discriminant.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15162
15452
  const { brokenFlow, hasBreak } = context;
15163
15453
  context.hasBreak = false;
15164
15454
  let onlyHasBrokenFlow = true;
@@ -15175,7 +15465,7 @@ class SwitchStatement extends NodeBase {
15175
15465
  isCaseIncluded = switchCase.hasEffects(hasEffectsContext);
15176
15466
  }
15177
15467
  if (isCaseIncluded) {
15178
- switchCase.include(context, includeChildrenRecursively);
15468
+ switchCase.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15179
15469
  onlyHasBrokenFlow &&= context.brokenFlow && !context.hasBreak;
15180
15470
  context.hasBreak = false;
15181
15471
  context.brokenFlow = brokenFlow;
@@ -15232,21 +15522,21 @@ class TaggedTemplateExpression extends CallExpressionBase {
15232
15522
  return (this.tag.hasEffects(context) ||
15233
15523
  this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
15234
15524
  }
15235
- include(context, includeChildrenRecursively) {
15525
+ includePath(path, context, includeChildrenRecursively) {
15236
15526
  if (!this.deoptimized)
15237
15527
  this.applyDeoptimizations();
15238
15528
  if (includeChildrenRecursively) {
15239
- super.include(context, includeChildrenRecursively);
15529
+ super.includePath(path, context, includeChildrenRecursively);
15240
15530
  }
15241
15531
  else {
15242
15532
  this.included = true;
15243
- this.tag.include(context, includeChildrenRecursively);
15244
- this.quasi.include(context, includeChildrenRecursively);
15533
+ this.tag.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15534
+ this.quasi.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15245
15535
  }
15246
- this.tag.includeCallArguments(context, this.args);
15536
+ this.tag.includeCallArguments(context, this.interaction);
15247
15537
  const [returnExpression] = this.getReturnExpression();
15248
15538
  if (!returnExpression.included) {
15249
- returnExpression.include(context, false);
15539
+ returnExpression.includePath(UNKNOWN_PATH, context, false);
15250
15540
  }
15251
15541
  }
15252
15542
  initialise() {
@@ -15291,7 +15581,7 @@ class TemplateElement extends NodeBase {
15291
15581
  hasEffects() {
15292
15582
  return false;
15293
15583
  }
15294
- include() {
15584
+ includePath() {
15295
15585
  this.included = true;
15296
15586
  }
15297
15587
  parseNode(esTreeNode) {
@@ -15333,13 +15623,13 @@ class TemplateLiteral extends NodeBase {
15333
15623
  class ModuleScope extends ChildScope {
15334
15624
  constructor(parent, context) {
15335
15625
  super(parent, context);
15336
- this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, context, 'other'));
15626
+ this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, EMPTY_PATH, context, 'other'));
15337
15627
  }
15338
- addDeclaration(identifier, context, init, kind) {
15628
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
15339
15629
  if (this.context.module.importDescriptions.has(identifier.name)) {
15340
15630
  context.error(parseAst_js.logRedeclarationError(identifier.name), identifier.start);
15341
15631
  }
15342
- return super.addDeclaration(identifier, context, init, kind);
15632
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
15343
15633
  }
15344
15634
  addExportDefaultDeclaration(name, exportDefaultDeclaration, context) {
15345
15635
  const variable = new ExportDefaultVariable(name, exportDefaultDeclaration, context);
@@ -15384,10 +15674,13 @@ class ThisExpression extends NodeBase {
15384
15674
  }
15385
15675
  return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
15386
15676
  }
15387
- include() {
15677
+ includePath(path, context) {
15388
15678
  if (!this.included) {
15389
15679
  this.included = true;
15390
- this.scope.context.includeVariableInModule(this.variable);
15680
+ this.scope.context.includeVariableInModule(this.variable, path);
15681
+ }
15682
+ else if (path.length > 0) {
15683
+ this.variable.includePath(path, context);
15391
15684
  }
15392
15685
  }
15393
15686
  initialise() {
@@ -15414,9 +15707,9 @@ class ThrowStatement extends NodeBase {
15414
15707
  hasEffects() {
15415
15708
  return true;
15416
15709
  }
15417
- include(context, includeChildrenRecursively) {
15710
+ includePath(_path, context, includeChildrenRecursively) {
15418
15711
  this.included = true;
15419
- this.argument.include(context, includeChildrenRecursively);
15712
+ this.argument.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15420
15713
  context.brokenFlow = true;
15421
15714
  }
15422
15715
  render(code, options) {
@@ -15438,13 +15731,13 @@ class TryStatement extends NodeBase {
15438
15731
  ? this.block.body.length > 0
15439
15732
  : this.block.hasEffects(context)) || !!this.finalizer?.hasEffects(context));
15440
15733
  }
15441
- include(context, includeChildrenRecursively) {
15734
+ includePath(_path, context, includeChildrenRecursively) {
15442
15735
  const tryCatchDeoptimization = this.scope.context.options.treeshake?.tryCatchDeoptimization;
15443
15736
  const { brokenFlow, includedLabels } = context;
15444
15737
  if (!this.directlyIncluded || !tryCatchDeoptimization) {
15445
15738
  this.included = true;
15446
15739
  this.directlyIncluded = true;
15447
- this.block.include(context, tryCatchDeoptimization ? INCLUDE_PARAMETERS : includeChildrenRecursively);
15740
+ this.block.includePath(UNKNOWN_PATH, context, tryCatchDeoptimization ? INCLUDE_PARAMETERS : includeChildrenRecursively);
15448
15741
  if (includedLabels.size > 0) {
15449
15742
  this.includedLabelsAfterBlock = [...includedLabels];
15450
15743
  }
@@ -15456,10 +15749,10 @@ class TryStatement extends NodeBase {
15456
15749
  }
15457
15750
  }
15458
15751
  if (this.handler !== null) {
15459
- this.handler.include(context, includeChildrenRecursively);
15752
+ this.handler.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15460
15753
  context.brokenFlow = brokenFlow;
15461
15754
  }
15462
- this.finalizer?.include(context, includeChildrenRecursively);
15755
+ this.finalizer?.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15463
15756
  }
15464
15757
  }
15465
15758
 
@@ -15517,7 +15810,7 @@ class UpdateExpression extends NodeBase {
15517
15810
  hasEffectsOnInteractionAtPath(path, { type }) {
15518
15811
  return path.length > 1 || type !== INTERACTION_ACCESSED;
15519
15812
  }
15520
- include(context, includeChildrenRecursively) {
15813
+ includePath(_, context, includeChildrenRecursively) {
15521
15814
  if (!this.deoptimized)
15522
15815
  this.applyDeoptimizations();
15523
15816
  this.included = true;
@@ -15586,20 +15879,20 @@ class VariableDeclaration extends NodeBase {
15586
15879
  hasEffectsOnInteractionAtPath() {
15587
15880
  return false;
15588
15881
  }
15589
- include(context, includeChildrenRecursively, { asSingleStatement } = parseAst_js.BLANK) {
15882
+ includePath(_path, context, includeChildrenRecursively, { asSingleStatement } = parseAst_js.BLANK) {
15590
15883
  this.included = true;
15591
15884
  for (const declarator of this.declarations) {
15592
15885
  if (includeChildrenRecursively || declarator.shouldBeIncluded(context))
15593
- declarator.include(context, includeChildrenRecursively);
15886
+ declarator.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15594
15887
  const { id, init } = declarator;
15595
15888
  if (asSingleStatement) {
15596
- id.include(context, includeChildrenRecursively);
15889
+ id.includePath(EMPTY_PATH, context, includeChildrenRecursively);
15597
15890
  }
15598
15891
  if (init &&
15599
15892
  id.included &&
15600
15893
  !init.included &&
15601
15894
  (id instanceof ObjectPattern || id instanceof ArrayPattern)) {
15602
- init.include(context, includeChildrenRecursively);
15895
+ init.includePath(EMPTY_PATH, context, includeChildrenRecursively);
15603
15896
  }
15604
15897
  }
15605
15898
  }
@@ -15671,8 +15964,7 @@ class VariableDeclaration extends NodeBase {
15671
15964
  const singleSystemExport = gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregatedSystemExports);
15672
15965
  for (const { node, start, separator, contentEnd, end } of separatedNodes) {
15673
15966
  if (!node.included) {
15674
- code.remove(start, end);
15675
- node.removeAnnotations(code);
15967
+ treeshakeNode(node, code, start, end);
15676
15968
  continue;
15677
15969
  }
15678
15970
  node.render(code, options);
@@ -15749,9 +16041,9 @@ class WhileStatement extends NodeBase {
15749
16041
  return true;
15750
16042
  return hasLoopBodyEffects(context, this.body);
15751
16043
  }
15752
- include(context, includeChildrenRecursively) {
16044
+ includePath(_path, context, includeChildrenRecursively) {
15753
16045
  this.included = true;
15754
- this.test.include(context, includeChildrenRecursively);
16046
+ this.test.includePath(UNKNOWN_PATH, context, includeChildrenRecursively);
15755
16047
  includeLoopBody(context, this.body, includeChildrenRecursively);
15756
16048
  }
15757
16049
  }
@@ -15995,7 +16287,7 @@ const bufferParsers = [
15995
16287
  const annotations = (node.annotations = parseAst_js.convertAnnotations(buffer[position + 1], buffer));
15996
16288
  node.annotationNoSideEffects = annotations.some(comment => comment.type === 'noSideEffects');
15997
16289
  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);
16290
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
15999
16291
  node.body = convertNode(node, scope.bodyScope, buffer[position + 3], buffer);
16000
16292
  },
16001
16293
  function assignmentExpression(node, position, buffer) {
@@ -16041,7 +16333,7 @@ const bufferParsers = [
16041
16333
  const parameterPosition = buffer[position];
16042
16334
  const parameter = (node.param =
16043
16335
  parameterPosition === 0 ? null : convertNode(node, scope, parameterPosition, buffer));
16044
- parameter?.declare('parameter', UNKNOWN_EXPRESSION);
16336
+ parameter?.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
16045
16337
  node.body = convertNode(node, scope.bodyScope, buffer[position + 1], buffer);
16046
16338
  },
16047
16339
  function chainExpression(node, position, buffer) {
@@ -16179,7 +16471,7 @@ const bufferParsers = [
16179
16471
  node.id =
16180
16472
  idPosition === 0 ? null : convertNode(node, scope.parent, idPosition, buffer);
16181
16473
  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);
16474
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
16183
16475
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
16184
16476
  },
16185
16477
  function functionExpression(node, position, buffer) {
@@ -16192,7 +16484,7 @@ const bufferParsers = [
16192
16484
  const idPosition = buffer[position + 2];
16193
16485
  node.id = idPosition === 0 ? null : convertNode(node, node.idScope, idPosition, buffer);
16194
16486
  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);
16487
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
16196
16488
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
16197
16489
  },
16198
16490
  function identifier(node, position, buffer) {
@@ -16551,8 +16843,8 @@ class UnknownNode extends NodeBase {
16551
16843
  hasEffects() {
16552
16844
  return true;
16553
16845
  }
16554
- include(context) {
16555
- super.include(context, true);
16846
+ includePath(path, context) {
16847
+ super.includePath(path, context, true);
16556
16848
  }
16557
16849
  }
16558
16850
 
@@ -16656,8 +16948,8 @@ class ExportShimVariable extends Variable {
16656
16948
  super(MISSING_EXPORT_SHIM_VARIABLE);
16657
16949
  this.module = module;
16658
16950
  }
16659
- include() {
16660
- super.include();
16951
+ includePath(path, context) {
16952
+ super.includePath(path, context);
16661
16953
  this.module.needsExportShim = true;
16662
16954
  }
16663
16955
  }
@@ -17341,7 +17633,7 @@ class Module {
17341
17633
  include() {
17342
17634
  const context = createInclusionContext();
17343
17635
  if (this.ast.shouldBeIncluded(context))
17344
- this.ast.include(context, false);
17636
+ this.ast.includePath(EMPTY_PATH, context, false);
17345
17637
  }
17346
17638
  includeAllExports(includeNamespaceMembers) {
17347
17639
  if (!this.isExecuted) {
@@ -17355,9 +17647,7 @@ class Module {
17355
17647
  return parseAst_js.error(parseAst_js.logMissingEntryExport(exportName, this.id));
17356
17648
  }
17357
17649
  variable.deoptimizePath(UNKNOWN_PATH);
17358
- if (!variable.included) {
17359
- this.includeVariable(variable);
17360
- }
17650
+ this.includeVariable(variable, UNKNOWN_PATH);
17361
17651
  }
17362
17652
  }
17363
17653
  for (const name of this.getReexports()) {
@@ -17365,7 +17655,7 @@ class Module {
17365
17655
  if (variable) {
17366
17656
  variable.deoptimizePath(UNKNOWN_PATH);
17367
17657
  if (!variable.included) {
17368
- this.includeVariable(variable);
17658
+ this.includeVariable(variable, UNKNOWN_PATH);
17369
17659
  }
17370
17660
  if (variable instanceof ExternalVariable) {
17371
17661
  variable.module.reexported = true;
@@ -17377,7 +17667,7 @@ class Module {
17377
17667
  }
17378
17668
  }
17379
17669
  includeAllInBundle() {
17380
- this.ast.include(createInclusionContext(), true);
17670
+ this.ast.includePath(UNKNOWN_PATH, createInclusionContext(), true);
17381
17671
  this.includeAllExports(false);
17382
17672
  }
17383
17673
  includeExportsByNames(names) {
@@ -17391,7 +17681,7 @@ class Module {
17391
17681
  if (variable) {
17392
17682
  variable.deoptimizePath(UNKNOWN_PATH);
17393
17683
  if (!variable.included) {
17394
- this.includeVariable(variable);
17684
+ this.includeVariable(variable, UNKNOWN_PATH);
17395
17685
  }
17396
17686
  }
17397
17687
  if (!this.exports.has(name) && !this.reexportDescriptions.has(name)) {
@@ -17833,13 +18123,13 @@ class Module {
17833
18123
  for (const module of [this, ...this.exportAllModules]) {
17834
18124
  if (module instanceof ExternalModule) {
17835
18125
  const [externalVariable] = module.getVariableForExportName('*');
17836
- externalVariable.include();
18126
+ externalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
17837
18127
  this.includedImports.add(externalVariable);
17838
18128
  externalNamespaces.add(externalVariable);
17839
18129
  }
17840
18130
  else if (module.info.syntheticNamedExports) {
17841
18131
  const syntheticNamespace = module.getSyntheticNamespace();
17842
- syntheticNamespace.include();
18132
+ syntheticNamespace.includePath(UNKNOWN_PATH, createInclusionContext());
17843
18133
  this.includedImports.add(syntheticNamespace);
17844
18134
  syntheticNamespaces.add(syntheticNamespace);
17845
18135
  }
@@ -17849,7 +18139,9 @@ class Module {
17849
18139
  includeDynamicImport(node) {
17850
18140
  const resolution = this.dynamicImports.find(dynamicImport => dynamicImport.node === node).resolution;
17851
18141
  if (resolution instanceof Module) {
17852
- resolution.includedDynamicImporters.push(this);
18142
+ if (!resolution.includedDynamicImporters.includes(this)) {
18143
+ resolution.includedDynamicImporters.push(this);
18144
+ }
17853
18145
  const importedNames = this.options.treeshake
17854
18146
  ? node.getDeterministicImportedNames()
17855
18147
  : undefined;
@@ -17861,7 +18153,7 @@ class Module {
17861
18153
  }
17862
18154
  }
17863
18155
  }
17864
- includeVariable(variable) {
18156
+ includeVariable(variable, path) {
17865
18157
  const variableModule = variable.module;
17866
18158
  if (variable.included) {
17867
18159
  if (variableModule instanceof Module && variableModule !== this) {
@@ -17869,7 +18161,6 @@ class Module {
17869
18161
  }
17870
18162
  }
17871
18163
  else {
17872
- variable.include();
17873
18164
  this.graph.needsTreeshakingPass = true;
17874
18165
  if (variableModule instanceof Module) {
17875
18166
  if (!variableModule.isExecuted) {
@@ -17885,9 +18176,10 @@ class Module {
17885
18176
  }
17886
18177
  }
17887
18178
  }
18179
+ variable.includePath(path, createInclusionContext());
17888
18180
  }
17889
- includeVariableInModule(variable) {
17890
- this.includeVariable(variable);
18181
+ includeVariableInModule(variable, path) {
18182
+ this.includeVariable(variable, path);
17891
18183
  const variableModule = variable.module;
17892
18184
  if (variableModule && variableModule !== this) {
17893
18185
  this.includedImports.add(variable);
@@ -21390,7 +21682,7 @@ class Graph {
21390
21682
  this.options = options;
21391
21683
  this.astLru = flru(5);
21392
21684
  this.cachedModules = new Map();
21393
- this.deoptimizationTracker = new PathTracker();
21685
+ this.deoptimizationTracker = new EntityPathTracker();
21394
21686
  this.entryModules = [];
21395
21687
  this.modulesById = new Map();
21396
21688
  this.needsTreeshakingPass = false;