@rollup/wasm-node 4.29.1 → 4.30.0-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v4.29.1
4
- Sat, 21 Dec 2024 07:15:31 GMT - commit 5d3777803404c67ce14c62b8b05d6e26e46856f5
3
+ Rollup.js v4.30.0-0
4
+ Sat, 21 Dec 2024 07:16:43 GMT - commit 2339f1d8384a8999645823f83f9042a9fc7b3bf7
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.29.1";
34
+ var version = "4.30.0-0";
35
35
 
36
36
  function ensureArray$1(items) {
37
37
  if (Array.isArray(items)) {
@@ -1501,48 +1501,8 @@ const createColors = ({ useColor = isColorSupported } = {}) =>
1501
1501
  );
1502
1502
 
1503
1503
  const {
1504
- reset,
1505
- bold: bold$1,
1506
- dim: dim$1,
1507
- italic,
1508
- underline: underline$1,
1509
- inverse,
1510
- hidden,
1511
- strikethrough,
1512
- black,
1513
- red: red$1,
1514
- green: green$1,
1515
- yellow: yellow$1,
1516
1504
  blue,
1517
- magenta,
1518
- cyan: cyan$1,
1519
- white,
1520
- gray: gray$1,
1521
- bgBlack,
1522
- bgRed,
1523
- bgGreen,
1524
- bgYellow,
1525
- bgBlue,
1526
- bgMagenta,
1527
- bgCyan,
1528
- bgWhite,
1529
- blackBright,
1530
- redBright,
1531
- greenBright,
1532
- yellowBright,
1533
- blueBright,
1534
- magentaBright,
1535
- cyanBright,
1536
- whiteBright,
1537
- bgBlackBright,
1538
- bgRedBright,
1539
- bgGreenBright,
1540
- bgYellowBright,
1541
- bgBlueBright,
1542
- bgMagentaBright,
1543
- bgCyanBright,
1544
- bgWhiteBright,
1545
- } = createColors();
1505
+ cyan: cyan$1} = createColors();
1546
1506
 
1547
1507
  // @see https://no-color.org
1548
1508
  // @see https://www.npmjs.com/package/chalk
@@ -3539,71 +3499,6 @@ function renderSystemExportSequenceBeforeExpression(exportedVariable, expression
3539
3499
  }
3540
3500
  }
3541
3501
 
3542
- /** @import { Node } from 'estree' */
3543
-
3544
- /**
3545
- * @param {Node} node
3546
- * @param {Node} parent
3547
- * @returns {boolean}
3548
- */
3549
- function is_reference(node, parent) {
3550
- if (node.type === 'MemberExpression') {
3551
- return !node.computed && is_reference(node.object, node);
3552
- }
3553
-
3554
- if (node.type !== 'Identifier') return false;
3555
-
3556
- switch (parent?.type) {
3557
- // disregard `bar` in `foo.bar`
3558
- case 'MemberExpression':
3559
- return parent.computed || node === parent.object;
3560
-
3561
- // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
3562
- case 'MethodDefinition':
3563
- return parent.computed;
3564
-
3565
- // disregard the `meta` in `import.meta`
3566
- case 'MetaProperty':
3567
- return parent.meta === node;
3568
-
3569
- // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
3570
- case 'PropertyDefinition':
3571
- return parent.computed || node === parent.value;
3572
-
3573
- // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
3574
- case 'Property':
3575
- return parent.computed || node === parent.value;
3576
-
3577
- // disregard the `bar` in `export { foo as bar }` or
3578
- // the foo in `import { foo as bar }`
3579
- case 'ExportSpecifier':
3580
- case 'ImportSpecifier':
3581
- return node === parent.local;
3582
-
3583
- // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
3584
- case 'LabeledStatement':
3585
- case 'BreakStatement':
3586
- case 'ContinueStatement':
3587
- return false;
3588
-
3589
- default:
3590
- return true;
3591
- }
3592
- }
3593
-
3594
- const PureFunctionKey = Symbol('PureFunction');
3595
- const getPureFunctions = ({ treeshake }) => {
3596
- const pureFunctions = Object.create(null);
3597
- for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
3598
- let currentFunctions = pureFunctions;
3599
- for (const pathSegment of functionName.split('.')) {
3600
- currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
3601
- }
3602
- currentFunctions[PureFunctionKey] = true;
3603
- }
3604
- return pureFunctions;
3605
- };
3606
-
3607
3502
  const UnknownKey = Symbol('Unknown Key');
3608
3503
  const UnknownNonAccessorKey = Symbol('Unknown Non-Accessor Key');
3609
3504
  const UnknownInteger = Symbol('Unknown Integer');
@@ -3618,7 +3513,7 @@ const UNKNOWN_PATH = [UnknownKey];
3618
3513
  const UNKNOWN_NON_ACCESSOR_PATH = [UnknownNonAccessorKey];
3619
3514
  const UNKNOWN_INTEGER_PATH = [UnknownInteger];
3620
3515
  const EntitiesKey = Symbol('Entities');
3621
- class PathTracker {
3516
+ class EntityPathTracker {
3622
3517
  constructor() {
3623
3518
  this.entityPaths = Object.create(null, {
3624
3519
  [EntitiesKey]: { value: new Set() }
@@ -3643,14 +3538,14 @@ class PathTracker {
3643
3538
  getEntities(path) {
3644
3539
  let currentPaths = this.entityPaths;
3645
3540
  for (const pathSegment of path) {
3646
- currentPaths = currentPaths[pathSegment] =
3647
- currentPaths[pathSegment] ||
3648
- Object.create(null, { [EntitiesKey]: { value: new Set() } });
3541
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
3542
+ [EntitiesKey]: { value: new Set() }
3543
+ });
3649
3544
  }
3650
3545
  return currentPaths[EntitiesKey];
3651
3546
  }
3652
3547
  }
3653
- const SHARED_RECURSION_TRACKER = new PathTracker();
3548
+ const SHARED_RECURSION_TRACKER = new EntityPathTracker();
3654
3549
  class DiscriminatedPathTracker {
3655
3550
  constructor() {
3656
3551
  this.entityPaths = Object.create(null, {
@@ -3660,9 +3555,9 @@ class DiscriminatedPathTracker {
3660
3555
  trackEntityAtPathAndGetIfTracked(path, discriminator, entity) {
3661
3556
  let currentPaths = this.entityPaths;
3662
3557
  for (const pathSegment of path) {
3663
- currentPaths = currentPaths[pathSegment] =
3664
- currentPaths[pathSegment] ||
3665
- Object.create(null, { [EntitiesKey]: { value: new Map() } });
3558
+ currentPaths = currentPaths[pathSegment] ||= Object.create(null, {
3559
+ [EntitiesKey]: { value: new Map() }
3560
+ });
3666
3561
  }
3667
3562
  const trackedEntities = getOrCreate(currentPaths[EntitiesKey], discriminator, (getNewSet));
3668
3563
  if (trackedEntities.has(entity))
@@ -3671,6 +3566,137 @@ class DiscriminatedPathTracker {
3671
3566
  return false;
3672
3567
  }
3673
3568
  }
3569
+ const UNKNOWN_INCLUDED_PATH = Object.freeze({ [UnknownKey]: parseAst_js.EMPTY_OBJECT });
3570
+ class IncludedPathTracker {
3571
+ constructor() {
3572
+ this.includedPaths = null;
3573
+ }
3574
+ includePathAndGetIfIncluded(path) {
3575
+ let included = true;
3576
+ let parent = this;
3577
+ let parentSegment = 'includedPaths';
3578
+ let currentPaths = (this.includedPaths ||=
3579
+ ((included = false), Object.create(null)));
3580
+ for (const pathSegment of path) {
3581
+ // This means from here, all paths are included
3582
+ if (currentPaths[UnknownKey]) {
3583
+ return true;
3584
+ }
3585
+ // Including UnknownKey automatically includes all nested paths.
3586
+ // From above, we know that UnknownKey is not included yet.
3587
+ if (typeof pathSegment === 'symbol') {
3588
+ // Hopefully, this saves some memory over just setting
3589
+ // currentPaths[UnknownKey] = EMPTY_OBJECT
3590
+ parent[parentSegment] = UNKNOWN_INCLUDED_PATH;
3591
+ return false;
3592
+ }
3593
+ parent = currentPaths;
3594
+ parentSegment = pathSegment;
3595
+ currentPaths = currentPaths[pathSegment] ||= ((included = false), Object.create(null));
3596
+ }
3597
+ return included;
3598
+ }
3599
+ includeAllPaths(entity, context, basePath) {
3600
+ const { includedPaths } = this;
3601
+ if (includedPaths) {
3602
+ includeAllPaths(entity, context, basePath, includedPaths);
3603
+ }
3604
+ }
3605
+ }
3606
+ function includeAllPaths(entity, context, basePath, currentPaths) {
3607
+ if (currentPaths[UnknownKey]) {
3608
+ return entity.includePath([...basePath, UnknownKey], context);
3609
+ }
3610
+ const keys = Object.keys(currentPaths);
3611
+ if (keys.length === 0) {
3612
+ return entity.includePath(basePath, context);
3613
+ }
3614
+ for (const key of keys) {
3615
+ includeAllPaths(entity, context, [...basePath, key], currentPaths[key]);
3616
+ }
3617
+ }
3618
+
3619
+ /** @import { Node } from 'estree' */
3620
+
3621
+ /**
3622
+ * @param {Node} node
3623
+ * @param {Node} parent
3624
+ * @returns {boolean}
3625
+ */
3626
+ function is_reference(node, parent) {
3627
+ if (node.type === 'MemberExpression') {
3628
+ return !node.computed && is_reference(node.object, node);
3629
+ }
3630
+
3631
+ if (node.type !== 'Identifier') return false;
3632
+
3633
+ switch (parent?.type) {
3634
+ // disregard `bar` in `foo.bar`
3635
+ case 'MemberExpression':
3636
+ return parent.computed || node === parent.object;
3637
+
3638
+ // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
3639
+ case 'MethodDefinition':
3640
+ return parent.computed;
3641
+
3642
+ // disregard the `meta` in `import.meta`
3643
+ case 'MetaProperty':
3644
+ return parent.meta === node;
3645
+
3646
+ // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
3647
+ case 'PropertyDefinition':
3648
+ return parent.computed || node === parent.value;
3649
+
3650
+ // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
3651
+ case 'Property':
3652
+ return parent.computed || node === parent.value;
3653
+
3654
+ // disregard the `bar` in `export { foo as bar }` or
3655
+ // the foo in `import { foo as bar }`
3656
+ case 'ExportSpecifier':
3657
+ case 'ImportSpecifier':
3658
+ return node === parent.local;
3659
+
3660
+ // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
3661
+ case 'LabeledStatement':
3662
+ case 'BreakStatement':
3663
+ case 'ContinueStatement':
3664
+ return false;
3665
+
3666
+ default:
3667
+ return true;
3668
+ }
3669
+ }
3670
+
3671
+ function createInclusionContext() {
3672
+ return {
3673
+ brokenFlow: false,
3674
+ hasBreak: false,
3675
+ hasContinue: false,
3676
+ includedCallArguments: new Set(),
3677
+ includedLabels: new Set()
3678
+ };
3679
+ }
3680
+ function createHasEffectsContext() {
3681
+ return {
3682
+ accessed: new EntityPathTracker(),
3683
+ assigned: new EntityPathTracker(),
3684
+ brokenFlow: false,
3685
+ called: new DiscriminatedPathTracker(),
3686
+ hasBreak: false,
3687
+ hasContinue: false,
3688
+ ignore: {
3689
+ breaks: false,
3690
+ continues: false,
3691
+ labels: new Set(),
3692
+ returnYield: false,
3693
+ this: false
3694
+ },
3695
+ includedLabels: new Set(),
3696
+ instantiated: new DiscriminatedPathTracker(),
3697
+ replacedVariableInits: new Map()
3698
+ };
3699
+ }
3674
3700
 
3675
3701
  function isFlagSet(flags, flag) {
3676
3702
  return (flags & flag) !== 0;
@@ -3710,12 +3736,25 @@ class ExpressionEntity {
3710
3736
  hasEffectsOnInteractionAtPath(_path, _interaction, _context) {
3711
3737
  return true;
3712
3738
  }
3713
- include(_context, _includeChildrenRecursively, _options) {
3739
+ include(context, _includeChildrenRecursively, _options) {
3740
+ if (!this.included)
3741
+ this.includeNode(context);
3742
+ }
3743
+ includeNode(_context) {
3714
3744
  this.included = true;
3715
3745
  }
3716
- includeCallArguments(context, parameters) {
3717
- for (const argument of parameters) {
3718
- argument.include(context, false);
3746
+ includePath(_path, context) {
3747
+ if (!this.included)
3748
+ this.includeNode(context);
3749
+ }
3750
+ /* We are both including and including an unknown path here as the former
3751
+ * ensures that nested nodes are included while the latter ensures that all
3752
+ * paths of the expression are included.
3753
+ * */
3754
+ includeCallArguments(context, interaction) {
3755
+ for (const argument of interaction.args) {
3756
+ argument?.includePath(UNKNOWN_PATH, context);
3757
+ argument?.include(context, false);
3719
3758
  }
3720
3759
  }
3721
3760
  shouldBeIncluded(_context) {
@@ -3754,6 +3793,19 @@ const NODE_INTERACTION_UNKNOWN_CALL = {
3754
3793
  withNew: false
3755
3794
  };
3756
3795
 
3796
+ const PureFunctionKey = Symbol('PureFunction');
3797
+ const getPureFunctions = ({ treeshake }) => {
3798
+ const pureFunctions = Object.create(null);
3799
+ for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {
3800
+ let currentFunctions = pureFunctions;
3801
+ for (const pathSegment of functionName.split('.')) {
3802
+ currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);
3803
+ }
3804
+ currentFunctions[PureFunctionKey] = true;
3805
+ }
3806
+ return pureFunctions;
3807
+ };
3808
+
3757
3809
  class Variable extends ExpressionEntity {
3758
3810
  markReassigned() {
3759
3811
  this.isReassigned = true;
@@ -3830,9 +3882,9 @@ class Variable extends ExpressionEntity {
3830
3882
  * has not been included previously. Once a variable is included, it should
3831
3883
  * take care all its declarations are included.
3832
3884
  */
3833
- include() {
3885
+ includePath(path, context) {
3834
3886
  this.included = true;
3835
- this.renderedLikeHoisted?.include();
3887
+ this.renderedLikeHoisted?.includePath(path, context);
3836
3888
  }
3837
3889
  /**
3838
3890
  * Links the rendered name of this variable to another variable and includes
@@ -3864,8 +3916,8 @@ class ExternalVariable extends Variable {
3864
3916
  hasEffectsOnInteractionAtPath(path, { type }) {
3865
3917
  return type !== INTERACTION_ACCESSED || path.length > (this.isNamespace ? 1 : 0);
3866
3918
  }
3867
- include() {
3868
- super.include();
3919
+ includePath(path, context) {
3920
+ super.includePath(path, context);
3869
3921
  this.module.used = true;
3870
3922
  }
3871
3923
  }
@@ -4164,36 +4216,6 @@ const childNodeKeys = {
4164
4216
  YieldExpression: ['argument']
4165
4217
  };
4166
4218
 
4167
- function createInclusionContext() {
4168
- return {
4169
- brokenFlow: false,
4170
- hasBreak: false,
4171
- hasContinue: false,
4172
- includedCallArguments: new Set(),
4173
- includedLabels: new Set()
4174
- };
4175
- }
4176
- function createHasEffectsContext() {
4177
- return {
4178
- accessed: new PathTracker(),
4179
- assigned: new PathTracker(),
4180
- brokenFlow: false,
4181
- called: new DiscriminatedPathTracker(),
4182
- hasBreak: false,
4183
- hasContinue: false,
4184
- ignore: {
4185
- breaks: false,
4186
- continues: false,
4187
- labels: new Set(),
4188
- returnYield: false,
4189
- this: false
4190
- },
4191
- includedLabels: new Set(),
4192
- instantiated: new DiscriminatedPathTracker(),
4193
- replacedVariableInits: new Map()
4194
- };
4195
- }
4196
-
4197
4219
  const INCLUDE_PARAMETERS = 'variables';
4198
4220
  const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN');
4199
4221
  class NodeBase extends ExpressionEntity {
@@ -4263,9 +4285,8 @@ class NodeBase extends ExpressionEntity {
4263
4285
  this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));
4264
4286
  }
4265
4287
  include(context, includeChildrenRecursively, _options) {
4266
- if (!this.deoptimized)
4267
- this.applyDeoptimizations();
4268
- this.included = true;
4288
+ if (!this.included)
4289
+ this.includeNode(context);
4269
4290
  for (const key of childNodeKeys[this.type]) {
4270
4291
  const value = this[key];
4271
4292
  if (value === null)
@@ -4280,6 +4301,24 @@ class NodeBase extends ExpressionEntity {
4280
4301
  }
4281
4302
  }
4282
4303
  }
4304
+ includeNode(context) {
4305
+ this.included = true;
4306
+ if (!this.deoptimized)
4307
+ this.applyDeoptimizations();
4308
+ for (const key of childNodeKeys[this.type]) {
4309
+ const value = this[key];
4310
+ if (value === null)
4311
+ continue;
4312
+ if (Array.isArray(value)) {
4313
+ for (const child of value) {
4314
+ child?.includePath(UNKNOWN_PATH, context);
4315
+ }
4316
+ }
4317
+ else {
4318
+ value.includePath(UNKNOWN_PATH, context);
4319
+ }
4320
+ }
4321
+ }
4283
4322
  includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {
4284
4323
  this.include(context, includeChildrenRecursively);
4285
4324
  }
@@ -4383,6 +4422,17 @@ class NodeBase extends ExpressionEntity {
4383
4422
  function createChildNodeKeysForNode(esTreeNode) {
4384
4423
  return Object.keys(esTreeNode).filter(key => typeof esTreeNode[key] === 'object' && key.charCodeAt(0) !== 95 /* _ */);
4385
4424
  }
4425
+ function onlyIncludeSelf() {
4426
+ this.included = true;
4427
+ if (!this.deoptimized)
4428
+ this.applyDeoptimizations();
4429
+ }
4430
+ function onlyIncludeSelfNoDeoptimize() {
4431
+ this.included = true;
4432
+ }
4433
+ function doNotDeoptimize() {
4434
+ this.deoptimized = true;
4435
+ }
4386
4436
 
4387
4437
  function isObjectExpressionNode(node) {
4388
4438
  return node instanceof NodeBase && node.type === parseAst_js.ObjectExpression;
@@ -4395,8 +4445,8 @@ function assembleMemberDescriptions(memberDescriptions, inheritedDescriptions =
4395
4445
  return Object.create(inheritedDescriptions, memberDescriptions);
4396
4446
  }
4397
4447
  const UNDEFINED_EXPRESSION = new (class UndefinedExpression extends ExpressionEntity {
4398
- getLiteralValueAtPath() {
4399
- return undefined;
4448
+ getLiteralValueAtPath(path) {
4449
+ return path.length > 0 ? UnknownValue : undefined;
4400
4450
  }
4401
4451
  })();
4402
4452
  const returnsUnknown = {
@@ -4593,31 +4643,6 @@ function getMemberReturnExpressionWhenCalled(members, memberName) {
4593
4643
  return [members[memberName].returns, false];
4594
4644
  }
4595
4645
 
4596
- class SpreadElement extends NodeBase {
4597
- deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
4598
- if (path.length > 0) {
4599
- this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker);
4600
- }
4601
- }
4602
- hasEffects(context) {
4603
- if (!this.deoptimized)
4604
- this.applyDeoptimizations();
4605
- const { propertyReadSideEffects } = this.scope.context.options
4606
- .treeshake;
4607
- return (this.argument.hasEffects(context) ||
4608
- (propertyReadSideEffects &&
4609
- (propertyReadSideEffects === 'always' ||
4610
- this.argument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context))));
4611
- }
4612
- applyDeoptimizations() {
4613
- this.deoptimized = true;
4614
- // Only properties of properties of the argument could become subject to reassignment
4615
- // This will also reassign the return values of iterators
4616
- this.argument.deoptimizePath([UnknownKey, UnknownKey]);
4617
- this.scope.context.requestTreeshakingPass();
4618
- }
4619
- }
4620
-
4621
4646
  class Method extends ExpressionEntity {
4622
4647
  constructor(description) {
4623
4648
  super();
@@ -4743,6 +4768,7 @@ class ObjectEntity extends ExpressionEntity {
4743
4768
  this.unknownIntegerProps = [];
4744
4769
  this.unmatchableGetters = [];
4745
4770
  this.unmatchablePropertiesAndGetters = [];
4771
+ this.unmatchablePropertiesAndSetters = [];
4746
4772
  this.unmatchableSetters = [];
4747
4773
  if (Array.isArray(properties)) {
4748
4774
  this.buildPropertyMaps(properties);
@@ -4977,9 +5003,38 @@ class ObjectEntity extends ExpressionEntity {
4977
5003
  }
4978
5004
  return false;
4979
5005
  }
5006
+ include(context, includeChildrenRecursively) {
5007
+ this.included = true;
5008
+ for (const property of this.allProperties) {
5009
+ if (includeChildrenRecursively || property.shouldBeIncluded(context)) {
5010
+ property.include(context, includeChildrenRecursively);
5011
+ }
5012
+ }
5013
+ this.prototypeExpression?.include(context, includeChildrenRecursively);
5014
+ }
5015
+ includePath(path, context) {
5016
+ this.included = true;
5017
+ if (path.length === 0)
5018
+ return;
5019
+ const [key, ...subPath] = path;
5020
+ const [includedMembers, includedPath] = typeof key === 'string'
5021
+ ? [
5022
+ [
5023
+ ...new Set([
5024
+ ...(this.propertiesAndGettersByKey[key] || this.unmatchablePropertiesAndGetters),
5025
+ ...(this.propertiesAndSettersByKey[key] || this.unmatchablePropertiesAndSetters)
5026
+ ])
5027
+ ],
5028
+ subPath
5029
+ ]
5030
+ : [this.allProperties, UNKNOWN_PATH];
5031
+ for (const property of includedMembers) {
5032
+ property.includePath(includedPath, context);
5033
+ }
5034
+ this.prototypeExpression?.includePath(path, context);
5035
+ }
4980
5036
  buildPropertyMaps(properties) {
4981
- const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchableGetters, unmatchableSetters } = this;
4982
- const unmatchablePropertiesAndSetters = [];
5037
+ const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchablePropertiesAndSetters, unmatchableGetters, unmatchableSetters } = this;
4983
5038
  for (let index = properties.length - 1; index >= 0; index--) {
4984
5039
  const { key, kind, property } = properties[index];
4985
5040
  allProperties.push(property);
@@ -5249,6 +5304,37 @@ const ARRAY_PROTOTYPE = new ObjectEntity({
5249
5304
  values: METHOD_DEOPTS_SELF_RETURNS_UNKNOWN
5250
5305
  }, OBJECT_PROTOTYPE, true);
5251
5306
 
5307
+ class SpreadElement extends NodeBase {
5308
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
5309
+ if (path.length > 0) {
5310
+ this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker);
5311
+ }
5312
+ }
5313
+ hasEffects(context) {
5314
+ if (!this.deoptimized)
5315
+ this.applyDeoptimizations();
5316
+ const { propertyReadSideEffects } = this.scope.context.options
5317
+ .treeshake;
5318
+ return (this.argument.hasEffects(context) ||
5319
+ (propertyReadSideEffects &&
5320
+ (propertyReadSideEffects === 'always' ||
5321
+ this.argument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context))));
5322
+ }
5323
+ includeNode(context) {
5324
+ this.included = true;
5325
+ if (!this.deoptimized)
5326
+ this.applyDeoptimizations();
5327
+ this.argument.includePath(UNKNOWN_PATH, context);
5328
+ }
5329
+ applyDeoptimizations() {
5330
+ this.deoptimized = true;
5331
+ // Only properties of properties of the argument could become subject to reassignment
5332
+ // This will also reassign the return values of iterators
5333
+ this.argument.deoptimizePath([UnknownKey, UnknownKey]);
5334
+ this.scope.context.requestTreeshakingPass();
5335
+ }
5336
+ }
5337
+
5252
5338
  class ArrayExpression extends NodeBase {
5253
5339
  constructor() {
5254
5340
  super(...arguments);
@@ -5269,6 +5355,16 @@ class ArrayExpression extends NodeBase {
5269
5355
  hasEffectsOnInteractionAtPath(path, interaction, context) {
5270
5356
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
5271
5357
  }
5358
+ includeNode(context) {
5359
+ this.included = true;
5360
+ if (!this.deoptimized)
5361
+ this.applyDeoptimizations();
5362
+ for (const element of this.elements) {
5363
+ if (element) {
5364
+ element?.includePath(UNKNOWN_PATH, context);
5365
+ }
5366
+ }
5367
+ }
5272
5368
  applyDeoptimizations() {
5273
5369
  this.deoptimized = true;
5274
5370
  let hasSpread = false;
@@ -6336,17 +6432,37 @@ class GlobalVariable extends Variable {
6336
6432
  }
6337
6433
  }
6338
6434
 
6435
+ // To avoid infinite recursions
6436
+ const MAX_PATH_DEPTH = 6;
6437
+ // If a path is longer than MAX_PATH_DEPTH, it is truncated so that it is at
6438
+ // most MAX_PATH_DEPTH long. The last element is always UnknownKey
6439
+ const limitConcatenatedPathDepth = (path1, path2) => {
6440
+ const { length: length1 } = path1;
6441
+ const { length: length2 } = path2;
6442
+ return length1 === 0
6443
+ ? path2
6444
+ : length2 === 0
6445
+ ? path1
6446
+ : length1 + length2 > MAX_PATH_DEPTH
6447
+ ? [...path1, ...path2.slice(0, MAX_PATH_DEPTH - 1 - path1.length), 'UnknownKey']
6448
+ : [...path1, ...path2];
6449
+ };
6450
+
6339
6451
  class LocalVariable extends Variable {
6340
- constructor(name, declarator, init, context, kind) {
6452
+ constructor(name, declarator, init,
6453
+ /** if this is non-empty, the actual init is this path of this.init */
6454
+ initPath, context, kind) {
6341
6455
  super(name);
6342
6456
  this.init = init;
6457
+ this.initPath = initPath;
6458
+ this.kind = kind;
6343
6459
  this.calledFromTryStatement = false;
6344
6460
  this.additionalInitializers = null;
6461
+ this.includedPathTracker = new IncludedPathTracker();
6345
6462
  this.expressionsToBeDeoptimized = [];
6346
6463
  this.declarations = declarator ? [declarator] : [];
6347
6464
  this.deoptimizationTracker = context.deoptimizationTracker;
6348
6465
  this.module = context.module;
6349
- this.kind = kind;
6350
6466
  }
6351
6467
  addDeclaration(identifier, init) {
6352
6468
  this.declarations.push(identifier);
@@ -6357,15 +6473,16 @@ class LocalVariable extends Variable {
6357
6473
  for (const initializer of this.additionalInitializers) {
6358
6474
  initializer.deoptimizePath(UNKNOWN_PATH);
6359
6475
  }
6360
- this.additionalInitializers = null;
6361
6476
  }
6362
6477
  }
6363
6478
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6364
- if (this.isReassigned) {
6479
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
6365
6480
  deoptimizeInteraction(interaction);
6366
6481
  return;
6367
6482
  }
6368
- recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker), undefined);
6483
+ recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
6484
+ this.init.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], recursionTracker);
6485
+ }, undefined);
6369
6486
  }
6370
6487
  deoptimizePath(path) {
6371
6488
  if (this.isReassigned ||
@@ -6379,37 +6496,40 @@ class LocalVariable extends Variable {
6379
6496
  for (const expression of expressionsToBeDeoptimized) {
6380
6497
  expression.deoptimizeCache();
6381
6498
  }
6382
- this.init.deoptimizePath(UNKNOWN_PATH);
6499
+ this.init.deoptimizePath([...this.initPath, UnknownKey]);
6383
6500
  }
6384
6501
  else {
6385
- this.init.deoptimizePath(path);
6502
+ this.init.deoptimizePath(limitConcatenatedPathDepth(this.initPath, path));
6386
6503
  }
6387
6504
  }
6388
6505
  getLiteralValueAtPath(path, recursionTracker, origin) {
6389
- if (this.isReassigned) {
6506
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
6390
6507
  return UnknownValue;
6391
6508
  }
6392
6509
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
6393
6510
  this.expressionsToBeDeoptimized.push(origin);
6394
- return this.init.getLiteralValueAtPath(path, recursionTracker, origin);
6511
+ return this.init.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin);
6395
6512
  }, UnknownValue);
6396
6513
  }
6397
6514
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
6398
- if (this.isReassigned) {
6515
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
6399
6516
  return UNKNOWN_RETURN_EXPRESSION;
6400
6517
  }
6401
6518
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
6402
6519
  this.expressionsToBeDeoptimized.push(origin);
6403
- return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
6520
+ return this.init.getReturnExpressionWhenCalledAtPath([...this.initPath, ...path], interaction, recursionTracker, origin);
6404
6521
  }, UNKNOWN_RETURN_EXPRESSION);
6405
6522
  }
6406
6523
  hasEffectsOnInteractionAtPath(path, interaction, context) {
6524
+ if (path.length + this.initPath.length > MAX_PATH_DEPTH) {
6525
+ return true;
6526
+ }
6407
6527
  switch (interaction.type) {
6408
6528
  case INTERACTION_ACCESSED: {
6409
6529
  if (this.isReassigned)
6410
6530
  return true;
6411
6531
  return (!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
6412
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
6532
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
6413
6533
  }
6414
6534
  case INTERACTION_ASSIGNED: {
6415
6535
  if (this.included)
@@ -6419,44 +6539,63 @@ class LocalVariable extends Variable {
6419
6539
  if (this.isReassigned)
6420
6540
  return true;
6421
6541
  return (!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
6422
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
6542
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
6423
6543
  }
6424
6544
  case INTERACTION_CALLED: {
6425
6545
  if (this.isReassigned)
6426
6546
  return true;
6427
6547
  return (!(interaction.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this) &&
6428
- this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
6548
+ this.init.hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
6429
6549
  }
6430
6550
  }
6431
6551
  }
6432
- include() {
6433
- if (!this.included) {
6434
- super.include();
6552
+ includePath(path, context) {
6553
+ if (!this.includedPathTracker.includePathAndGetIfIncluded(path)) {
6554
+ this.module.scope.context.requestTreeshakingPass();
6555
+ if (!this.included) {
6556
+ // This will reduce the number of tree-shaking passes by eagerly
6557
+ // including inits. By pushing this here instead of directly including
6558
+ // we avoid deep call stacks.
6559
+ this.module.scope.context.newlyIncludedVariableInits.add(this.init);
6560
+ }
6561
+ super.includePath(path, context);
6435
6562
  for (const declaration of this.declarations) {
6436
6563
  // If node is a default export, it can save a tree-shaking run to include the full declaration now
6437
6564
  if (!declaration.included)
6438
- declaration.include(createInclusionContext(), false);
6565
+ declaration.include(context, false);
6439
6566
  let node = declaration.parent;
6440
6567
  while (!node.included) {
6441
6568
  // We do not want to properly include parents in case they are part of a dead branch
6442
6569
  // in which case .include() might pull in more dead code
6443
- node.included = true;
6570
+ node.includeNode(context);
6444
6571
  if (node.type === parseAst_js.Program)
6445
6572
  break;
6446
6573
  node = node.parent;
6447
6574
  }
6448
6575
  }
6576
+ // We need to make sure we include the correct path of the init
6577
+ if (path.length > 0) {
6578
+ this.init.includePath(limitConcatenatedPathDepth(this.initPath, path), context);
6579
+ this.additionalInitializers?.forEach(initializer => initializer.includePath(UNKNOWN_PATH, context));
6580
+ }
6449
6581
  }
6450
6582
  }
6451
- includeCallArguments(context, parameters) {
6452
- if (this.isReassigned || context.includedCallArguments.has(this.init)) {
6453
- for (const argument of parameters) {
6454
- argument.include(context, false);
6583
+ includeCallArguments(context, interaction) {
6584
+ if (this.isReassigned ||
6585
+ context.includedCallArguments.has(this.init) ||
6586
+ // This can be removed again once we can include arguments when called at
6587
+ // a specific path
6588
+ this.initPath.length > 0) {
6589
+ for (const argument of interaction.args) {
6590
+ if (argument) {
6591
+ argument.includePath(UNKNOWN_PATH, context);
6592
+ argument.include(context, false);
6593
+ }
6455
6594
  }
6456
6595
  }
6457
6596
  else {
6458
6597
  context.includedCallArguments.add(this.init);
6459
- this.init.includeCallArguments(context, parameters);
6598
+ this.init.includeCallArguments(context, interaction);
6460
6599
  context.includedCallArguments.delete(this.init);
6461
6600
  }
6462
6601
  }
@@ -6536,18 +6675,31 @@ class IdentifierBase extends NodeBase {
6536
6675
  }
6537
6676
  }
6538
6677
  }
6539
- include() {
6678
+ include(context) {
6679
+ if (!this.included)
6680
+ this.includeNode(context);
6681
+ }
6682
+ includeNode(context) {
6683
+ this.included = true;
6540
6684
  if (!this.deoptimized)
6541
6685
  this.applyDeoptimizations();
6686
+ if (this.variable !== null) {
6687
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
6688
+ }
6689
+ }
6690
+ includePath(path, context) {
6542
6691
  if (!this.included) {
6543
6692
  this.included = true;
6544
6693
  if (this.variable !== null) {
6545
- this.scope.context.includeVariableInModule(this.variable);
6694
+ this.scope.context.includeVariableInModule(this.variable, path, context);
6546
6695
  }
6547
6696
  }
6697
+ else if (path.length > 0) {
6698
+ this.variable?.includePath(path, context);
6699
+ }
6548
6700
  }
6549
- includeCallArguments(context, parameters) {
6550
- this.variable.includeCallArguments(context, parameters);
6701
+ includeCallArguments(context, interaction) {
6702
+ this.variable.includeCallArguments(context, interaction);
6551
6703
  }
6552
6704
  isPossibleTDZ() {
6553
6705
  // return cached value to avoid issues with the next tree-shaking pass
@@ -6630,11 +6782,40 @@ function closestParentFunctionOrProgram(node) {
6630
6782
  return node;
6631
6783
  }
6632
6784
 
6785
+ class ObjectMember extends ExpressionEntity {
6786
+ constructor(object, path) {
6787
+ super();
6788
+ this.object = object;
6789
+ this.path = path;
6790
+ }
6791
+ deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
6792
+ this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.path, ...path], recursionTracker);
6793
+ }
6794
+ deoptimizePath(path) {
6795
+ this.object.deoptimizePath([...this.path, ...path]);
6796
+ }
6797
+ getLiteralValueAtPath(path, recursionTracker, origin) {
6798
+ return this.object.getLiteralValueAtPath([...this.path, ...path], recursionTracker, origin);
6799
+ }
6800
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
6801
+ return this.object.getReturnExpressionWhenCalledAtPath([...this.path, ...path], interaction, recursionTracker, origin);
6802
+ }
6803
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
6804
+ return this.object.hasEffectsOnInteractionAtPath([...this.path, ...path], interaction, context);
6805
+ }
6806
+ }
6807
+
6633
6808
  class Identifier extends IdentifierBase {
6634
6809
  constructor() {
6635
6810
  super(...arguments);
6636
6811
  this.variable = null;
6637
6812
  }
6813
+ get isDestructuringDeoptimized() {
6814
+ return isFlagSet(this.flags, 16777216 /* Flag.destructuringDeoptimized */);
6815
+ }
6816
+ set isDestructuringDeoptimized(value) {
6817
+ this.flags = setFlag(this.flags, 16777216 /* Flag.destructuringDeoptimized */, value);
6818
+ }
6638
6819
  addExportedVariables(variables, exportNamesByVariable) {
6639
6820
  if (exportNamesByVariable.has(this.variable)) {
6640
6821
  variables.push(this.variable);
@@ -6647,43 +6828,53 @@ class Identifier extends IdentifierBase {
6647
6828
  this.isVariableReference = true;
6648
6829
  }
6649
6830
  }
6650
- declare(kind, init) {
6831
+ declare(kind, destructuredInitPath, init) {
6651
6832
  let variable;
6652
6833
  const { treeshake } = this.scope.context.options;
6653
- switch (kind) {
6654
- case 'var': {
6655
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
6656
- if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
6657
- // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
6658
- variable.markInitializersForDeoptimization();
6659
- }
6660
- break;
6661
- }
6662
- case 'function': {
6663
- // in strict mode, functions are only hoisted within a scope but not across block scopes
6664
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
6665
- break;
6666
- }
6667
- case 'let':
6668
- case 'const':
6669
- case 'using':
6670
- case 'await using':
6671
- case 'class': {
6672
- variable = this.scope.addDeclaration(this, this.scope.context, init, kind);
6673
- break;
6674
- }
6675
- case 'parameter': {
6676
- variable = this.scope.addParameterDeclaration(this);
6677
- break;
6678
- }
6679
- /* istanbul ignore next */
6680
- default: {
6681
- /* istanbul ignore next */
6682
- throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
6834
+ if (kind === 'parameter') {
6835
+ variable = this.scope.addParameterDeclaration(this, destructuredInitPath);
6836
+ }
6837
+ else {
6838
+ variable = this.scope.addDeclaration(this, this.scope.context, init, destructuredInitPath, kind);
6839
+ if (kind === 'var' && treeshake && treeshake.correctVarValueBeforeDeclaration) {
6840
+ // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
6841
+ variable.markInitializersForDeoptimization();
6683
6842
  }
6684
6843
  }
6685
6844
  return [(this.variable = variable)];
6686
6845
  }
6846
+ deoptimizeAssignment(destructuredInitPath, init) {
6847
+ this.deoptimizePath(EMPTY_PATH);
6848
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
6849
+ }
6850
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
6851
+ return (destructuredInitPath.length > 0 &&
6852
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
6853
+ }
6854
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
6855
+ if (destructuredInitPath.length > 0 && !this.isDestructuringDeoptimized) {
6856
+ this.isDestructuringDeoptimized = true;
6857
+ init.deoptimizeArgumentsOnInteractionAtPath({
6858
+ args: [new ObjectMember(init, destructuredInitPath.slice(0, -1))],
6859
+ type: INTERACTION_ACCESSED
6860
+ }, destructuredInitPath, SHARED_RECURSION_TRACKER);
6861
+ }
6862
+ const { propertyReadSideEffects } = this.scope.context.options
6863
+ .treeshake;
6864
+ if ((this.included ||=
6865
+ destructuredInitPath.length > 0 &&
6866
+ !context.brokenFlow &&
6867
+ propertyReadSideEffects &&
6868
+ (propertyReadSideEffects === 'always' ||
6869
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext())))) {
6870
+ if (this.variable && !this.variable.included) {
6871
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
6872
+ }
6873
+ init.includePath(destructuredInitPath, context);
6874
+ return true;
6875
+ }
6876
+ return false;
6877
+ }
6687
6878
  markDeclarationReached() {
6688
6879
  this.variable.initReached = true;
6689
6880
  }
@@ -6736,18 +6927,17 @@ class Scope {
6736
6927
  - then the variable is still declared in the hoisted outer scope, but the initializer is assigned to the parameter
6737
6928
  - const, let, class, and function except in the cases above cannot redeclare anything
6738
6929
  */
6739
- addDeclaration(identifier, context, init, kind) {
6930
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
6740
6931
  const name = identifier.name;
6741
6932
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
6742
6933
  if (existingVariable) {
6743
- const existingKind = existingVariable.kind;
6744
- if (kind === 'var' && existingKind === 'var') {
6934
+ if (kind === 'var' && existingVariable.kind === 'var') {
6745
6935
  existingVariable.addDeclaration(identifier, init);
6746
6936
  return existingVariable;
6747
6937
  }
6748
6938
  context.error(parseAst_js.logRedeclarationError(name), identifier.start);
6749
6939
  }
6750
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
6940
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
6751
6941
  this.variables.set(name, newVariable);
6752
6942
  return newVariable;
6753
6943
  }
@@ -6923,7 +7113,6 @@ class MethodBase extends NodeBase {
6923
7113
  }
6924
7114
  return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context);
6925
7115
  }
6926
- applyDeoptimizations() { }
6927
7116
  getAccessedValue() {
6928
7117
  if (this.accessedValue === null) {
6929
7118
  if (this.kind === 'get') {
@@ -6937,19 +7126,20 @@ class MethodBase extends NodeBase {
6937
7126
  return this.accessedValue;
6938
7127
  }
6939
7128
  }
7129
+ MethodBase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
7130
+ MethodBase.prototype.applyDeoptimizations = doNotDeoptimize;
6940
7131
 
6941
7132
  class MethodDefinition extends MethodBase {
6942
7133
  hasEffects(context) {
6943
7134
  return super.hasEffects(context) || checkEffectForNodes(this.decorators, context);
6944
7135
  }
6945
- applyDeoptimizations() { }
6946
7136
  }
6947
7137
 
6948
7138
  class BlockScope extends ChildScope {
6949
7139
  constructor(parent) {
6950
7140
  super(parent, parent.context);
6951
7141
  }
6952
- addDeclaration(identifier, context, init, kind) {
7142
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
6953
7143
  if (kind === 'var') {
6954
7144
  const name = identifier.name;
6955
7145
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -6961,7 +7151,7 @@ class BlockScope extends ChildScope {
6961
7151
  }
6962
7152
  return context.error(parseAst_js.logRedeclarationError(name), identifier.start);
6963
7153
  }
6964
- const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind);
7154
+ const declaredVariable = this.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
6965
7155
  // Necessary to make sure the init is deoptimized for conditional declarations.
6966
7156
  // We cannot call deoptimizePath here.
6967
7157
  declaredVariable.markInitializersForDeoptimization();
@@ -6969,7 +7159,7 @@ class BlockScope extends ChildScope {
6969
7159
  this.addHoistedVariable(name, declaredVariable);
6970
7160
  return declaredVariable;
6971
7161
  }
6972
- return super.addDeclaration(identifier, context, init, kind);
7162
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
6973
7163
  }
6974
7164
  }
6975
7165
 
@@ -7001,33 +7191,12 @@ class StaticBlock extends NodeBase {
7001
7191
  }
7002
7192
  }
7003
7193
  }
7194
+ StaticBlock.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
7195
+ StaticBlock.prototype.applyDeoptimizations = doNotDeoptimize;
7004
7196
  function isStaticBlock(statement) {
7005
7197
  return statement.type === parseAst_js.StaticBlock;
7006
7198
  }
7007
7199
 
7008
- class ObjectMember extends ExpressionEntity {
7009
- constructor(object, key) {
7010
- super();
7011
- this.object = object;
7012
- this.key = key;
7013
- }
7014
- deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
7015
- this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker);
7016
- }
7017
- deoptimizePath(path) {
7018
- this.object.deoptimizePath([this.key, ...path]);
7019
- }
7020
- getLiteralValueAtPath(path, recursionTracker, origin) {
7021
- return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin);
7022
- }
7023
- getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
7024
- return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin);
7025
- }
7026
- hasEffectsOnInteractionAtPath(path, interaction, context) {
7027
- return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context);
7028
- }
7029
- }
7030
-
7031
7200
  class ClassNode extends NodeBase {
7032
7201
  constructor() {
7033
7202
  super(...arguments);
@@ -7068,21 +7237,20 @@ class ClassNode extends NodeBase {
7068
7237
  : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
7069
7238
  }
7070
7239
  include(context, includeChildrenRecursively) {
7071
- if (!this.deoptimized)
7072
- this.applyDeoptimizations();
7073
- this.included = true;
7240
+ if (!this.included)
7241
+ this.includeNode(context);
7074
7242
  this.superClass?.include(context, includeChildrenRecursively);
7075
7243
  this.body.include(context, includeChildrenRecursively);
7076
7244
  for (const decorator of this.decorators)
7077
7245
  decorator.include(context, includeChildrenRecursively);
7078
7246
  if (this.id) {
7079
7247
  this.id.markDeclarationReached();
7080
- this.id.include();
7248
+ this.id.include(context);
7081
7249
  }
7082
7250
  }
7083
7251
  initialise() {
7084
7252
  super.initialise();
7085
- this.id?.declare('class', this);
7253
+ this.id?.declare('class', EMPTY_PATH, this);
7086
7254
  for (const method of this.body.body) {
7087
7255
  if (method instanceof MethodDefinition && method.kind === 'constructor') {
7088
7256
  this.classConstructor = method;
@@ -7140,11 +7308,12 @@ class ClassNode extends NodeBase {
7140
7308
  staticProperties.unshift({
7141
7309
  key: 'prototype',
7142
7310
  kind: 'init',
7143
- property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE)
7311
+ property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, ['prototype']) : OBJECT_PROTOTYPE)
7144
7312
  });
7145
7313
  return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE));
7146
7314
  }
7147
7315
  }
7316
+ ClassNode.prototype.includeNode = onlyIncludeSelf;
7148
7317
 
7149
7318
  class ClassDeclaration extends ClassNode {
7150
7319
  initialise() {
@@ -7197,7 +7366,7 @@ class ClassDeclaration extends ClassNode {
7197
7366
 
7198
7367
  class ArgumentsVariable extends LocalVariable {
7199
7368
  constructor(context) {
7200
- super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');
7369
+ super('arguments', null, UNKNOWN_EXPRESSION, EMPTY_PATH, context, 'other');
7201
7370
  this.deoptimizedArguments = [];
7202
7371
  }
7203
7372
  addArgumentToBeDeoptimized(argument) {
@@ -7211,8 +7380,8 @@ class ArgumentsVariable extends LocalVariable {
7211
7380
  hasEffectsOnInteractionAtPath(path, { type }) {
7212
7381
  return type !== INTERACTION_ACCESSED || path.length > 1;
7213
7382
  }
7214
- include() {
7215
- super.include();
7383
+ includePath(path, context) {
7384
+ super.includePath(path, context);
7216
7385
  for (const argument of this.deoptimizedArguments) {
7217
7386
  argument.deoptimizePath(UNKNOWN_PATH);
7218
7387
  }
@@ -7223,27 +7392,28 @@ class ArgumentsVariable extends LocalVariable {
7223
7392
  const MAX_TRACKED_INTERACTIONS = 20;
7224
7393
  const NO_INTERACTIONS = parseAst_js.EMPTY_ARRAY;
7225
7394
  const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);
7226
- const EMPTY_PATH_TRACKER = new PathTracker();
7395
+ const EMPTY_PATH_TRACKER = new EntityPathTracker();
7227
7396
  const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);
7228
7397
  class ParameterVariable extends LocalVariable {
7229
- constructor(name, declarator, context) {
7230
- super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');
7398
+ constructor(name, declarator, argumentPath, context) {
7399
+ super(name, declarator, UNKNOWN_EXPRESSION, argumentPath, context, 'parameter');
7231
7400
  this.deoptimizationInteractions = [];
7232
- this.deoptimizations = new PathTracker();
7401
+ this.deoptimizations = new EntityPathTracker();
7233
7402
  this.deoptimizedFields = new Set();
7234
- this.entitiesToBeDeoptimized = new Set();
7235
- this.expressionsUseTheKnownValue = [];
7403
+ this.argumentsToBeDeoptimized = new Set();
7404
+ this.expressionsDependingOnKnownValue = [];
7236
7405
  this.knownValue = null;
7237
7406
  this.knownValueLiteral = UnknownValue;
7238
7407
  this.frozenValue = null;
7239
7408
  }
7240
- addEntityToBeDeoptimized(entity) {
7409
+ addArgumentValue(entity) {
7410
+ this.updateKnownValue(entity);
7241
7411
  if (entity === UNKNOWN_EXPRESSION) {
7242
7412
  // As unknown expressions fully deoptimize all interactions, we can clear
7243
7413
  // the interaction cache at this point provided we keep this optimization
7244
7414
  // in mind when adding new interactions
7245
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7246
- this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);
7415
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7416
+ this.argumentsToBeDeoptimized.add(UNKNOWN_EXPRESSION);
7247
7417
  for (const { interaction } of this.deoptimizationInteractions) {
7248
7418
  deoptimizeInteraction(interaction);
7249
7419
  }
@@ -7253,27 +7423,34 @@ class ParameterVariable extends LocalVariable {
7253
7423
  else if (this.deoptimizedFields.has(UnknownKey)) {
7254
7424
  // This means that we already deoptimized all interactions and no longer
7255
7425
  // track them
7256
- entity.deoptimizePath(UNKNOWN_PATH);
7426
+ entity.deoptimizePath([...this.initPath, UnknownKey]);
7257
7427
  }
7258
- else if (!this.entitiesToBeDeoptimized.has(entity)) {
7259
- this.entitiesToBeDeoptimized.add(entity);
7428
+ else if (!this.argumentsToBeDeoptimized.has(entity)) {
7429
+ this.argumentsToBeDeoptimized.add(entity);
7260
7430
  for (const field of this.deoptimizedFields) {
7261
- entity.deoptimizePath([field]);
7431
+ entity.deoptimizePath([...this.initPath, field]);
7262
7432
  }
7263
7433
  for (const { interaction, path } of this.deoptimizationInteractions) {
7264
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
7434
+ if (this.initPath.length + path.length > MAX_PATH_DEPTH) {
7435
+ deoptimizeInteraction(interaction);
7436
+ continue;
7437
+ }
7438
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
7265
7439
  }
7266
7440
  }
7267
7441
  }
7442
+ /** This says we should not make assumptions about the value of the parameter.
7443
+ * This is different from deoptimization that will also cause argument values
7444
+ * to be deoptimized. */
7268
7445
  markReassigned() {
7269
7446
  if (this.isReassigned) {
7270
7447
  return;
7271
7448
  }
7272
7449
  super.markReassigned();
7273
- for (const expression of this.expressionsUseTheKnownValue) {
7450
+ for (const expression of this.expressionsDependingOnKnownValue) {
7274
7451
  expression.deoptimizeCache();
7275
7452
  }
7276
- this.expressionsUseTheKnownValue = parseAst_js.EMPTY_ARRAY;
7453
+ this.expressionsDependingOnKnownValue = parseAst_js.EMPTY_ARRAY;
7277
7454
  }
7278
7455
  deoptimizeCache() {
7279
7456
  this.markReassigned();
@@ -7290,7 +7467,7 @@ class ParameterVariable extends LocalVariable {
7290
7467
  }
7291
7468
  if (this.knownValue === null) {
7292
7469
  this.knownValue = argument;
7293
- this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
7470
+ this.knownValueLiteral = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
7294
7471
  return;
7295
7472
  }
7296
7473
  // the same literal or identifier, do nothing
@@ -7306,7 +7483,7 @@ class ParameterVariable extends LocalVariable {
7306
7483
  return;
7307
7484
  }
7308
7485
  // add tracking for the new argument
7309
- const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
7486
+ const newValue = argument.getLiteralValueAtPath(this.initPath, SHARED_RECURSION_TRACKER, this);
7310
7487
  if (newValue !== oldValue) {
7311
7488
  this.markReassigned();
7312
7489
  }
@@ -7324,24 +7501,31 @@ class ParameterVariable extends LocalVariable {
7324
7501
  return this.frozenValue;
7325
7502
  }
7326
7503
  getLiteralValueAtPath(path, recursionTracker, origin) {
7327
- if (this.isReassigned) {
7504
+ if (this.isReassigned || path.length + this.initPath.length > MAX_PATH_DEPTH) {
7328
7505
  return UnknownValue;
7329
7506
  }
7330
7507
  const knownValue = this.getKnownValue();
7331
- this.expressionsUseTheKnownValue.push(origin);
7332
- return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);
7508
+ this.expressionsDependingOnKnownValue.push(origin);
7509
+ return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath([...this.initPath, ...path], recursionTracker, origin), UnknownValue);
7333
7510
  }
7334
7511
  hasEffectsOnInteractionAtPath(path, interaction, context) {
7335
- if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) {
7512
+ const { type } = interaction;
7513
+ if (this.isReassigned ||
7514
+ type === INTERACTION_ASSIGNED ||
7515
+ path.length + this.initPath.length > MAX_PATH_DEPTH) {
7336
7516
  return super.hasEffectsOnInteractionAtPath(path, interaction, context);
7337
7517
  }
7338
- const knownValue = this.getKnownValue();
7339
- return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context);
7518
+ return (!(type === INTERACTION_CALLED
7519
+ ? (interaction.withNew
7520
+ ? context.instantiated
7521
+ : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)
7522
+ : context.accessed.trackEntityAtPathAndGetIfTracked(path, this)) &&
7523
+ this.getKnownValue().hasEffectsOnInteractionAtPath([...this.initPath, ...path], interaction, context));
7340
7524
  }
7341
7525
  deoptimizeArgumentsOnInteractionAtPath(interaction, path) {
7342
7526
  // For performance reasons, we fully deoptimize all deeper interactions
7343
7527
  if (path.length >= 2 ||
7344
- this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
7528
+ this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||
7345
7529
  this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||
7346
7530
  (path.length === 1 &&
7347
7531
  (this.deoptimizedFields.has(UnknownKey) ||
@@ -7350,10 +7534,10 @@ class ParameterVariable extends LocalVariable {
7350
7534
  return;
7351
7535
  }
7352
7536
  if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {
7353
- for (const entity of this.entitiesToBeDeoptimized) {
7354
- entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
7537
+ for (const entity of this.argumentsToBeDeoptimized) {
7538
+ entity.deoptimizeArgumentsOnInteractionAtPath(interaction, [...this.initPath, ...path], SHARED_RECURSION_TRACKER);
7355
7539
  }
7356
- if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7540
+ if (!this.argumentsToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {
7357
7541
  this.deoptimizationInteractions.push({
7358
7542
  interaction,
7359
7543
  path
@@ -7374,17 +7558,17 @@ class ParameterVariable extends LocalVariable {
7374
7558
  return;
7375
7559
  }
7376
7560
  this.deoptimizedFields.add(key);
7377
- for (const entity of this.entitiesToBeDeoptimized) {
7561
+ for (const entity of this.argumentsToBeDeoptimized) {
7378
7562
  // We do not need a recursion tracker here as we already track whether
7379
7563
  // this field is deoptimized
7380
- entity.deoptimizePath([key]);
7564
+ entity.deoptimizePath([...this.initPath, key]);
7381
7565
  }
7382
7566
  if (key === UnknownKey) {
7383
7567
  // save some memory
7384
7568
  this.deoptimizationInteractions = NO_INTERACTIONS;
7385
7569
  this.deoptimizations = EMPTY_PATH_TRACKER;
7386
7570
  this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;
7387
- this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
7571
+ this.argumentsToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;
7388
7572
  }
7389
7573
  }
7390
7574
  getReturnExpressionWhenCalledAtPath(path) {
@@ -7399,11 +7583,14 @@ class ParameterVariable extends LocalVariable {
7399
7583
  }
7400
7584
  return UNKNOWN_RETURN_EXPRESSION;
7401
7585
  }
7586
+ includeArgumentPaths(entity, context) {
7587
+ this.includedPathTracker.includeAllPaths(entity, context, this.initPath);
7588
+ }
7402
7589
  }
7403
7590
 
7404
7591
  class ThisVariable extends ParameterVariable {
7405
7592
  constructor(context) {
7406
- super('this', null, context);
7593
+ super('this', null, EMPTY_PATH, context);
7407
7594
  }
7408
7595
  hasEffectsOnInteractionAtPath(path, interaction, context) {
7409
7596
  return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);
@@ -7415,7 +7602,7 @@ class CatchBodyScope extends ChildScope {
7415
7602
  super(parent, parent.context);
7416
7603
  this.parent = parent;
7417
7604
  }
7418
- addDeclaration(identifier, context, init, kind) {
7605
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
7419
7606
  if (kind === 'var') {
7420
7607
  const name = identifier.name;
7421
7608
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
@@ -7428,7 +7615,7 @@ class CatchBodyScope extends ChildScope {
7428
7615
  // the assignment actually goes to the parameter and the var is
7429
7616
  // hoisted without assignment. Locally, it is shadowed by the
7430
7617
  // parameter
7431
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, kind);
7618
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, destructuredInitPath, kind);
7432
7619
  // To avoid the need to rewrite the declaration, we link the variable
7433
7620
  // names. If we ever implement a logic that splits initialization and
7434
7621
  // assignment for hoisted vars, the "renderLikeHoisted" logic can be
@@ -7447,7 +7634,7 @@ class CatchBodyScope extends ChildScope {
7447
7634
  return context.error(parseAst_js.logRedeclarationError(name), identifier.start);
7448
7635
  }
7449
7636
  // We only add parameters to parameter scopes
7450
- const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, kind);
7637
+ const declaredVariable = this.parent.parent.addDeclaration(identifier, context, init, destructuredInitPath, kind);
7451
7638
  // Necessary to make sure the init is deoptimized for conditional declarations.
7452
7639
  // We cannot call deoptimizePath here.
7453
7640
  declaredVariable.markInitializersForDeoptimization();
@@ -7455,7 +7642,7 @@ class CatchBodyScope extends ChildScope {
7455
7642
  this.addHoistedVariable(name, declaredVariable);
7456
7643
  return declaredVariable;
7457
7644
  }
7458
- return super.addDeclaration(identifier, context, init, kind);
7645
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
7459
7646
  }
7460
7647
  }
7461
7648
 
@@ -7465,7 +7652,7 @@ class FunctionBodyScope extends ChildScope {
7465
7652
  }
7466
7653
  // There is stuff that is only allowed in function scopes, i.e. functions can
7467
7654
  // be redeclared, functions and var can redeclare each other
7468
- addDeclaration(identifier, context, init, kind) {
7655
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
7469
7656
  const name = identifier.name;
7470
7657
  const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name);
7471
7658
  if (existingVariable) {
@@ -7477,7 +7664,7 @@ class FunctionBodyScope extends ChildScope {
7477
7664
  }
7478
7665
  context.error(parseAst_js.logRedeclarationError(name), identifier.start);
7479
7666
  }
7480
- const newVariable = new LocalVariable(identifier.name, identifier, init, context, kind);
7667
+ const newVariable = new LocalVariable(identifier.name, identifier, init, destructuredInitPath, context, kind);
7481
7668
  this.variables.set(name, newVariable);
7482
7669
  return newVariable;
7483
7670
  }
@@ -7486,21 +7673,21 @@ class FunctionBodyScope extends ChildScope {
7486
7673
  class ParameterScope extends ChildScope {
7487
7674
  constructor(parent, isCatchScope) {
7488
7675
  super(parent, parent.context);
7489
- this.parameters = [];
7490
7676
  this.hasRest = false;
7677
+ this.parameters = [];
7491
7678
  this.bodyScope = isCatchScope ? new CatchBodyScope(this) : new FunctionBodyScope(this);
7492
7679
  }
7493
7680
  /**
7494
7681
  * Adds a parameter to this scope. Parameters must be added in the correct
7495
7682
  * order, i.e. from left to right.
7496
7683
  */
7497
- addParameterDeclaration(identifier) {
7684
+ addParameterDeclaration(identifier, argumentPath) {
7498
7685
  const { name, start } = identifier;
7499
7686
  const existingParameter = this.variables.get(name);
7500
7687
  if (existingParameter) {
7501
7688
  return this.context.error(parseAst_js.logDuplicateArgumentNameError(name), start);
7502
7689
  }
7503
- const variable = new ParameterVariable(name, identifier, this.context);
7690
+ const variable = new ParameterVariable(name, identifier, argumentPath, this.context);
7504
7691
  this.variables.set(name, variable);
7505
7692
  // We also add it to the body scope to detect name conflicts with local
7506
7693
  // variables. We still need the intermediate scope, though, as parameter
@@ -7518,42 +7705,56 @@ class ParameterScope extends ChildScope {
7518
7705
  }
7519
7706
  this.hasRest = hasRest;
7520
7707
  }
7521
- includeCallArguments(context, parameters) {
7708
+ includeCallArguments(context, interaction) {
7522
7709
  let calledFromTryStatement = false;
7523
7710
  let argumentIncluded = false;
7524
7711
  const restParameter = this.hasRest && this.parameters[this.parameters.length - 1];
7525
- for (const checkedArgument of parameters) {
7526
- if (checkedArgument instanceof SpreadElement) {
7527
- for (const argument of parameters) {
7528
- argument.include(context, false);
7529
- }
7530
- break;
7712
+ const { args } = interaction;
7713
+ let lastExplicitlyIncludedIndex = args.length - 1;
7714
+ // If there is a SpreadElement, we need to include all arguments after it
7715
+ // because we no longer know which argument corresponds to which parameter.
7716
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
7717
+ const argument = args[argumentIndex];
7718
+ if (argument instanceof SpreadElement && !argumentIncluded) {
7719
+ argumentIncluded = true;
7720
+ lastExplicitlyIncludedIndex = argumentIndex - 1;
7721
+ }
7722
+ if (argumentIncluded) {
7723
+ argument.includePath(UNKNOWN_PATH, context);
7724
+ argument.include(context, false);
7531
7725
  }
7532
7726
  }
7533
- for (let index = parameters.length - 1; index >= 0; index--) {
7534
- const parameterVariables = this.parameters[index] || restParameter;
7535
- const argument = parameters[index];
7727
+ // Now we go backwards either starting from the last argument or before the
7728
+ // first SpreadElement to ensure all arguments before are included as needed
7729
+ for (let index = lastExplicitlyIncludedIndex; index >= 1; index--) {
7730
+ const parameterVariables = this.parameters[index - 1] || restParameter;
7731
+ const argument = args[index];
7536
7732
  if (parameterVariables) {
7537
7733
  calledFromTryStatement = false;
7538
7734
  if (parameterVariables.length === 0) {
7539
- // handle empty destructuring
7735
+ // handle empty destructuring to avoid destructuring undefined
7540
7736
  argumentIncluded = true;
7541
7737
  }
7542
7738
  else {
7543
7739
  for (const variable of parameterVariables) {
7544
- if (variable.included) {
7545
- argumentIncluded = true;
7546
- }
7547
7740
  if (variable.calledFromTryStatement) {
7548
7741
  calledFromTryStatement = true;
7549
7742
  }
7743
+ if (variable.included) {
7744
+ argumentIncluded = true;
7745
+ if (calledFromTryStatement) {
7746
+ argument.include(context, true);
7747
+ }
7748
+ else {
7749
+ variable.includeArgumentPaths(argument, context);
7750
+ argument.include(context, false);
7751
+ }
7752
+ }
7550
7753
  }
7551
7754
  }
7552
7755
  }
7553
- if (!argumentIncluded && argument.shouldBeIncluded(context)) {
7756
+ if (!argument.included && (argumentIncluded || argument.shouldBeIncluded(context))) {
7554
7757
  argumentIncluded = true;
7555
- }
7556
- if (argumentIncluded) {
7557
7758
  argument.include(context, calledFromTryStatement);
7558
7759
  }
7559
7760
  }
@@ -7569,11 +7770,62 @@ class ReturnValueScope extends ParameterScope {
7569
7770
  addReturnExpression(expression) {
7570
7771
  this.returnExpressions.push(expression);
7571
7772
  }
7773
+ deoptimizeArgumentsOnCall(interaction) {
7774
+ const { parameters } = this;
7775
+ const { args } = interaction;
7776
+ let position = 0;
7777
+ for (; position < args.length - 1; position++) {
7778
+ // Only the "this" argument arg[0] can be null
7779
+ const argument = args[position + 1];
7780
+ if (argument instanceof SpreadElement) {
7781
+ // This deoptimizes the current and remaining parameters and arguments
7782
+ for (; position < parameters.length; position++) {
7783
+ args[position + 1]?.deoptimizePath(UNKNOWN_PATH);
7784
+ parameters[position].forEach(variable => variable.markReassigned());
7785
+ }
7786
+ break;
7787
+ }
7788
+ if (this.hasRest && position >= parameters.length - 1) {
7789
+ argument.deoptimizePath(UNKNOWN_PATH);
7790
+ }
7791
+ else {
7792
+ const variables = parameters[position];
7793
+ if (variables) {
7794
+ for (const variable of variables) {
7795
+ variable.addArgumentValue(argument);
7796
+ }
7797
+ }
7798
+ this.addArgumentToBeDeoptimized(argument);
7799
+ }
7800
+ }
7801
+ const nonRestParameterLength = this.hasRest ? parameters.length - 1 : parameters.length;
7802
+ for (; position < nonRestParameterLength; position++) {
7803
+ for (const variable of parameters[position]) {
7804
+ variable.addArgumentValue(UNDEFINED_EXPRESSION);
7805
+ }
7806
+ }
7807
+ }
7572
7808
  getReturnExpression() {
7573
7809
  if (this.returnExpression === null)
7574
7810
  this.updateReturnExpression();
7575
7811
  return this.returnExpression;
7576
7812
  }
7813
+ deoptimizeAllParameters() {
7814
+ for (const parameter of this.parameters) {
7815
+ for (const variable of parameter) {
7816
+ variable.deoptimizePath(UNKNOWN_PATH);
7817
+ variable.markReassigned();
7818
+ }
7819
+ }
7820
+ }
7821
+ reassignAllParameters() {
7822
+ for (const parameter of this.parameters) {
7823
+ for (const variable of parameter) {
7824
+ variable.markReassigned();
7825
+ }
7826
+ }
7827
+ }
7828
+ addArgumentToBeDeoptimized(_argument) { }
7577
7829
  updateReturnExpression() {
7578
7830
  if (this.returnExpressions.length === 1) {
7579
7831
  this.returnExpression = this.returnExpressions[0];
@@ -7589,24 +7841,30 @@ class ReturnValueScope extends ParameterScope {
7589
7841
 
7590
7842
  class FunctionScope extends ReturnValueScope {
7591
7843
  constructor(parent) {
7592
- const { context } = parent;
7593
7844
  super(parent, false);
7845
+ const { context } = parent;
7594
7846
  this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));
7595
7847
  this.variables.set('this', (this.thisVariable = new ThisVariable(context)));
7596
7848
  }
7597
7849
  findLexicalBoundary() {
7598
7850
  return this;
7599
7851
  }
7600
- includeCallArguments(context, parameters) {
7601
- super.includeCallArguments(context, parameters);
7852
+ includeCallArguments(context, interaction) {
7853
+ super.includeCallArguments(context, interaction);
7602
7854
  if (this.argumentsVariable.included) {
7603
- for (const argument of parameters) {
7604
- if (!argument.included) {
7855
+ const { args } = interaction;
7856
+ for (let argumentIndex = 1; argumentIndex < args.length; argumentIndex++) {
7857
+ const argument = args[argumentIndex];
7858
+ if (argument) {
7859
+ argument.includePath(UNKNOWN_PATH, context);
7605
7860
  argument.include(context, false);
7606
7861
  }
7607
7862
  }
7608
7863
  }
7609
7864
  }
7865
+ addArgumentToBeDeoptimized(argument) {
7866
+ this.argumentsVariable.addArgumentToBeDeoptimized(argument);
7867
+ }
7610
7868
  }
7611
7869
 
7612
7870
  class ExpressionStatement extends NodeBase {
@@ -7634,8 +7892,9 @@ class ExpressionStatement extends NodeBase {
7634
7892
  return this.parent.type !== parseAst_js.Program;
7635
7893
  return super.shouldBeIncluded(context);
7636
7894
  }
7637
- applyDeoptimizations() { }
7638
7895
  }
7896
+ ExpressionStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
7897
+ ExpressionStatement.prototype.applyDeoptimizations = doNotDeoptimize;
7639
7898
 
7640
7899
  class BlockStatement extends NodeBase {
7641
7900
  get deoptimizeBody() {
@@ -7700,6 +7959,8 @@ class BlockStatement extends NodeBase {
7700
7959
  }
7701
7960
  }
7702
7961
  }
7962
+ BlockStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
7963
+ BlockStatement.prototype.applyDeoptimizations = doNotDeoptimize;
7703
7964
 
7704
7965
  class RestElement extends NodeBase {
7705
7966
  constructor() {
@@ -7709,9 +7970,12 @@ class RestElement extends NodeBase {
7709
7970
  addExportedVariables(variables, exportNamesByVariable) {
7710
7971
  this.argument.addExportedVariables(variables, exportNamesByVariable);
7711
7972
  }
7712
- declare(kind, init) {
7973
+ declare(kind, destructuredInitPath, init) {
7713
7974
  this.declarationInit = init;
7714
- return this.argument.declare(kind, UNKNOWN_EXPRESSION);
7975
+ return this.argument.declare(kind, getIncludedPatternPath$1(destructuredInitPath), init);
7976
+ }
7977
+ deoptimizeAssignment(destructuredInitPath, init) {
7978
+ this.argument.deoptimizeAssignment(getIncludedPatternPath$1(destructuredInitPath), init);
7715
7979
  }
7716
7980
  deoptimizePath(path) {
7717
7981
  if (path.length === 0) {
@@ -7722,6 +7986,20 @@ class RestElement extends NodeBase {
7722
7986
  return (path.length > 0 ||
7723
7987
  this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
7724
7988
  }
7989
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
7990
+ return this.argument.hasEffectsWhenDestructuring(context, getIncludedPatternPath$1(destructuredInitPath), init);
7991
+ }
7992
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
7993
+ return (this.included =
7994
+ this.argument.includeDestructuredIfNecessary(context, getIncludedPatternPath$1(destructuredInitPath), init) || this.included);
7995
+ }
7996
+ include(context, includeChildrenRecursively) {
7997
+ if (!this.included)
7998
+ this.includeNode(context);
7999
+ // This should just include the identifier, its properties should be
8000
+ // included where the variable is used.
8001
+ this.argument.include(context, includeChildrenRecursively);
8002
+ }
7725
8003
  markDeclarationReached() {
7726
8004
  this.argument.markDeclarationReached();
7727
8005
  }
@@ -7733,12 +8011,16 @@ class RestElement extends NodeBase {
7733
8011
  }
7734
8012
  }
7735
8013
  }
8014
+ RestElement.prototype.includeNode = onlyIncludeSelf;
8015
+ const getIncludedPatternPath$1 = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
8016
+ ? destructuredInitPath
8017
+ : [...destructuredInitPath, UnknownKey];
7736
8018
 
7737
8019
  class FunctionBase extends NodeBase {
7738
8020
  constructor() {
7739
8021
  super(...arguments);
7740
- this.objectEntity = null;
7741
8022
  this.parameterVariableValuesDeoptimized = false;
8023
+ this.includeCallArguments = this.scope.includeCallArguments.bind(this.scope);
7742
8024
  }
7743
8025
  get async() {
7744
8026
  return isFlagSet(this.flags, 256 /* Flag.async */);
@@ -7758,53 +8040,9 @@ class FunctionBase extends NodeBase {
7758
8040
  set generator(value) {
7759
8041
  this.flags = setFlag(this.flags, 4194304 /* Flag.generator */, value);
7760
8042
  }
7761
- updateParameterVariableValues(_arguments) {
7762
- for (let position = 0; position < this.params.length; position++) {
7763
- const parameter = this.params[position];
7764
- if (!(parameter instanceof Identifier)) {
7765
- continue;
7766
- }
7767
- const parameterVariable = parameter.variable;
7768
- const argument = _arguments[position + 1] ?? UNDEFINED_EXPRESSION;
7769
- parameterVariable.updateKnownValue(argument);
7770
- }
7771
- }
7772
- deoptimizeParameterVariableValues() {
7773
- for (const parameter of this.params) {
7774
- if (parameter instanceof Identifier) {
7775
- const parameterVariable = parameter.variable;
7776
- parameterVariable.markReassigned();
7777
- }
7778
- }
7779
- }
7780
8043
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
7781
- if (interaction.type === INTERACTION_CALLED) {
7782
- const { parameters } = this.scope;
7783
- const { args } = interaction;
7784
- let hasRest = false;
7785
- for (let position = 0; position < args.length - 1; position++) {
7786
- const parameter = this.params[position];
7787
- // Only the "this" argument arg[0] can be null
7788
- const argument = args[position + 1];
7789
- if (argument instanceof SpreadElement) {
7790
- this.deoptimizeParameterVariableValues();
7791
- }
7792
- if (hasRest || parameter instanceof RestElement) {
7793
- hasRest = true;
7794
- argument.deoptimizePath(UNKNOWN_PATH);
7795
- }
7796
- else if (parameter instanceof Identifier) {
7797
- parameters[position][0].addEntityToBeDeoptimized(argument);
7798
- this.addArgumentToBeDeoptimized(argument);
7799
- }
7800
- else if (parameter) {
7801
- argument.deoptimizePath(UNKNOWN_PATH);
7802
- }
7803
- else {
7804
- this.addArgumentToBeDeoptimized(argument);
7805
- }
7806
- }
7807
- this.updateParameterVariableValues(args);
8044
+ if (interaction.type === INTERACTION_CALLED && path.length === 0) {
8045
+ this.scope.deoptimizeArgumentsOnCall(interaction);
7808
8046
  }
7809
8047
  else {
7810
8048
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -7816,12 +8054,7 @@ class FunctionBase extends NodeBase {
7816
8054
  // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
7817
8055
  // which means the return expression and parameters need to be reassigned
7818
8056
  this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
7819
- for (const parameterList of this.scope.parameters) {
7820
- for (const parameter of parameterList) {
7821
- parameter.deoptimizePath(UNKNOWN_PATH);
7822
- parameter.markReassigned();
7823
- }
7824
- }
8057
+ this.scope.deoptimizeAllParameters();
7825
8058
  }
7826
8059
  }
7827
8060
  getLiteralValueAtPath(path, recursionTracker, origin) {
@@ -7859,8 +8092,13 @@ class FunctionBase extends NodeBase {
7859
8092
  return true;
7860
8093
  }
7861
8094
  }
7862
- for (const parameter of this.params) {
7863
- if (parameter.hasEffects(context))
8095
+ const { propertyReadSideEffects } = this.scope.context.options
8096
+ .treeshake;
8097
+ for (let index = 0; index < this.params.length; index++) {
8098
+ const parameter = this.params[index];
8099
+ if (parameter.hasEffects(context) ||
8100
+ (propertyReadSideEffects &&
8101
+ parameter.hasEffectsWhenDestructuring(context, EMPTY_PATH, interaction.args[index + 1] || UNDEFINED_EXPRESSION)))
7864
8102
  return true;
7865
8103
  }
7866
8104
  return false;
@@ -7879,21 +8117,17 @@ class FunctionBase extends NodeBase {
7879
8117
  return variable?.getOnlyFunctionCallUsed() ?? false;
7880
8118
  }
7881
8119
  include(context, includeChildrenRecursively) {
7882
- if (!this.parameterVariableValuesDeoptimized && !this.onlyFunctionCallUsed()) {
8120
+ if (!this.included)
8121
+ this.includeNode(context);
8122
+ if (!(this.parameterVariableValuesDeoptimized || this.onlyFunctionCallUsed())) {
7883
8123
  this.parameterVariableValuesDeoptimized = true;
7884
- this.deoptimizeParameterVariableValues();
8124
+ this.scope.reassignAllParameters();
7885
8125
  }
7886
- if (!this.deoptimized)
7887
- this.applyDeoptimizations();
7888
- this.included = true;
7889
8126
  const { brokenFlow } = context;
7890
8127
  context.brokenFlow = false;
7891
8128
  this.body.include(context, includeChildrenRecursively);
7892
8129
  context.brokenFlow = brokenFlow;
7893
8130
  }
7894
- includeCallArguments(context, parameters) {
7895
- this.scope.includeCallArguments(context, parameters);
7896
- }
7897
8131
  initialise() {
7898
8132
  super.initialise();
7899
8133
  if (this.body instanceof BlockStatement) {
@@ -7915,14 +8149,14 @@ class FunctionBase extends NodeBase {
7915
8149
  // so that the scope already knows all parameters and can detect conflicts
7916
8150
  // when parsing the body.
7917
8151
  const parameters = (this.params = params.map((parameter) => new (context.getNodeConstructor(parameter.type))(this, scope).parseNode(parameter)));
7918
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
8152
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
7919
8153
  this.body = new (context.getNodeConstructor(body.type))(this, bodyScope).parseNode(body);
7920
8154
  return super.parseNode(esTreeNode);
7921
8155
  }
7922
- addArgumentToBeDeoptimized(_argument) { }
7923
- applyDeoptimizations() { }
7924
8156
  }
7925
8157
  FunctionBase.prototype.preventChildBlockScope = true;
8158
+ FunctionBase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
8159
+ FunctionBase.prototype.applyDeoptimizations = doNotDeoptimize;
7926
8160
 
7927
8161
  class FunctionNode extends FunctionBase {
7928
8162
  constructor() {
@@ -7934,18 +8168,16 @@ class FunctionNode extends FunctionBase {
7934
8168
  this.constructedEntity = new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE);
7935
8169
  // This makes sure that all deoptimizations of "this" are applied to the
7936
8170
  // constructed entity.
7937
- this.scope.thisVariable.addEntityToBeDeoptimized(this.constructedEntity);
8171
+ this.scope.thisVariable.addArgumentValue(this.constructedEntity);
7938
8172
  }
7939
8173
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
7940
8174
  super.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
7941
8175
  if (interaction.type === INTERACTION_CALLED && path.length === 0 && interaction.args[0]) {
7942
8176
  // args[0] is the "this" argument
7943
- this.scope.thisVariable.addEntityToBeDeoptimized(interaction.args[0]);
8177
+ this.scope.thisVariable.addArgumentValue(interaction.args[0]);
7944
8178
  }
7945
8179
  }
7946
8180
  hasEffects(context) {
7947
- if (!this.deoptimized)
7948
- this.applyDeoptimizations();
7949
8181
  if (this.annotationNoSideEffects) {
7950
8182
  return false;
7951
8183
  }
@@ -7983,7 +8215,7 @@ class FunctionNode extends FunctionBase {
7983
8215
  }
7984
8216
  include(context, includeChildrenRecursively) {
7985
8217
  super.include(context, includeChildrenRecursively);
7986
- this.id?.include();
8218
+ this.id?.include(context);
7987
8219
  const hasArguments = this.scope.argumentsVariable.included;
7988
8220
  for (const parameter of this.params) {
7989
8221
  if (!(parameter instanceof Identifier) || hasArguments) {
@@ -7991,12 +8223,18 @@ class FunctionNode extends FunctionBase {
7991
8223
  }
7992
8224
  }
7993
8225
  }
8226
+ includeNode(context) {
8227
+ this.included = true;
8228
+ const hasArguments = this.scope.argumentsVariable.included;
8229
+ for (const parameter of this.params) {
8230
+ if (!(parameter instanceof Identifier) || hasArguments) {
8231
+ parameter.includePath(UNKNOWN_PATH, context);
8232
+ }
8233
+ }
8234
+ }
7994
8235
  initialise() {
7995
8236
  super.initialise();
7996
- this.id?.declare('function', this);
7997
- }
7998
- addArgumentToBeDeoptimized(argument) {
7999
- this.scope.argumentsVariable.addArgumentToBeDeoptimized(argument);
8237
+ this.id?.declare('function', EMPTY_PATH, this);
8000
8238
  }
8001
8239
  getObjectEntity() {
8002
8240
  if (this.objectEntity !== null) {
@@ -8046,11 +8284,16 @@ function getFunctionIdInsertPosition(code, start) {
8046
8284
  }
8047
8285
  class ExportDefaultDeclaration extends NodeBase {
8048
8286
  include(context, includeChildrenRecursively) {
8049
- super.include(context, includeChildrenRecursively);
8287
+ this.included = true;
8288
+ this.declaration.include(context, includeChildrenRecursively);
8050
8289
  if (includeChildrenRecursively) {
8051
- this.scope.context.includeVariableInModule(this.variable);
8290
+ this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, context);
8052
8291
  }
8053
8292
  }
8293
+ includePath(path, context) {
8294
+ this.included = true;
8295
+ this.declaration.includePath(path, context);
8296
+ }
8054
8297
  initialise() {
8055
8298
  super.initialise();
8056
8299
  const declaration = this.declaration;
@@ -8095,7 +8338,6 @@ class ExportDefaultDeclaration extends NodeBase {
8095
8338
  }
8096
8339
  this.declaration.render(code, options);
8097
8340
  }
8098
- applyDeoptimizations() { }
8099
8341
  renderNamedDeclaration(code, declarationStart, idInsertPosition, options) {
8100
8342
  const { exportNamesByVariable, format, snippets: { getPropertyAccess } } = options;
8101
8343
  const name = this.variable.getName(getPropertyAccess);
@@ -8126,6 +8368,8 @@ class ExportDefaultDeclaration extends NodeBase {
8126
8368
  }
8127
8369
  }
8128
8370
  ExportDefaultDeclaration.prototype.needsBoundaries = true;
8371
+ ExportDefaultDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
8372
+ ExportDefaultDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
8129
8373
 
8130
8374
  const needsEscapeRegEx = /[\n\r'\\\u2028\u2029]/;
8131
8375
  const quoteNewlineRegEx = /([\n\r'\u2028\u2029])/g;
@@ -8395,6 +8639,7 @@ class Literal extends NodeBase {
8395
8639
  }
8396
8640
  }
8397
8641
  }
8642
+ Literal.prototype.includeNode = onlyIncludeSelf;
8398
8643
 
8399
8644
  function getChainElementLiteralValueAtPath(element, object, path, recursionTracker, origin) {
8400
8645
  if ('getLiteralValueAtPathAsChainElement' in object) {
@@ -8410,8 +8655,6 @@ function getChainElementLiteralValueAtPath(element, object, path, recursionTrack
8410
8655
  return element.getLiteralValueAtPath(path, recursionTracker, origin);
8411
8656
  }
8412
8657
 
8413
- // To avoid infinite recursions
8414
- const MAX_PATH_DEPTH = 7;
8415
8658
  function getResolvablePropertyKey(memberExpression) {
8416
8659
  return memberExpression.computed
8417
8660
  ? getResolvableComputedPropertyKey(memberExpression.property)
@@ -8510,18 +8753,27 @@ class MemberExpression extends NodeBase {
8510
8753
  }
8511
8754
  else if (!this.isUndefined) {
8512
8755
  if (path.length < MAX_PATH_DEPTH) {
8513
- this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.getPropertyKey(), ...path], recursionTracker);
8756
+ this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, this.propertyKey === UnknownKey ? UNKNOWN_PATH : [this.propertyKey, ...path], recursionTracker);
8514
8757
  }
8515
8758
  else {
8516
8759
  deoptimizeInteraction(interaction);
8517
8760
  }
8518
8761
  }
8519
8762
  }
8763
+ deoptimizeAssignment(destructuredInitPath, init) {
8764
+ this.deoptimizePath(EMPTY_PATH);
8765
+ init.deoptimizePath([...destructuredInitPath, UnknownKey]);
8766
+ }
8520
8767
  deoptimizeCache() {
8768
+ if (this.propertyKey === this.dynamicPropertyKey)
8769
+ return;
8521
8770
  const { expressionsToBeDeoptimized, object } = this;
8522
8771
  this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;
8523
- this.propertyKey = UnknownKey;
8772
+ this.dynamicPropertyKey = this.propertyKey;
8524
8773
  object.deoptimizePath(UNKNOWN_PATH);
8774
+ if (this.included) {
8775
+ object.includePath(UNKNOWN_PATH, createInclusionContext());
8776
+ }
8525
8777
  for (const expression of expressionsToBeDeoptimized) {
8526
8778
  expression.deoptimizeCache();
8527
8779
  }
@@ -8532,11 +8784,13 @@ class MemberExpression extends NodeBase {
8532
8784
  if (this.variable) {
8533
8785
  this.variable.deoptimizePath(path);
8534
8786
  }
8535
- else if (!this.isUndefined && path.length < MAX_PATH_DEPTH) {
8536
- const propertyKey = this.getPropertyKey();
8787
+ else if (!this.isUndefined) {
8788
+ const { propertyKey } = this;
8537
8789
  this.object.deoptimizePath([
8538
8790
  propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey,
8539
- ...path
8791
+ ...(path.length < MAX_PATH_DEPTH
8792
+ ? path
8793
+ : [...path.slice(0, MAX_PATH_DEPTH), UnknownKey])
8540
8794
  ]);
8541
8795
  }
8542
8796
  }
@@ -8547,9 +8801,11 @@ class MemberExpression extends NodeBase {
8547
8801
  if (this.isUndefined) {
8548
8802
  return undefined;
8549
8803
  }
8550
- if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
8551
- this.expressionsToBeDeoptimized.push(origin);
8552
- return this.object.getLiteralValueAtPath([this.getPropertyKey(), ...path], recursionTracker, origin);
8804
+ const propertyKey = this.getDynamicPropertyKey();
8805
+ if (propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
8806
+ if (propertyKey !== this.propertyKey)
8807
+ this.expressionsToBeDeoptimized.push(origin);
8808
+ return this.object.getLiteralValueAtPath([propertyKey, ...path], recursionTracker, origin);
8553
8809
  }
8554
8810
  return UnknownValue;
8555
8811
  }
@@ -8569,9 +8825,11 @@ class MemberExpression extends NodeBase {
8569
8825
  if (this.isUndefined) {
8570
8826
  return [UNDEFINED_EXPRESSION, false];
8571
8827
  }
8572
- if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
8573
- this.expressionsToBeDeoptimized.push(origin);
8574
- return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin);
8828
+ const propertyKey = this.getDynamicPropertyKey();
8829
+ if (propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {
8830
+ if (propertyKey !== this.propertyKey)
8831
+ this.expressionsToBeDeoptimized.push(origin);
8832
+ return this.object.getReturnExpressionWhenCalledAtPath([propertyKey, ...path], interaction, recursionTracker, origin);
8575
8833
  }
8576
8834
  return UNKNOWN_RETURN_EXPRESSION;
8577
8835
  }
@@ -8617,14 +8875,45 @@ class MemberExpression extends NodeBase {
8617
8875
  return true;
8618
8876
  }
8619
8877
  if (path.length < MAX_PATH_DEPTH) {
8620
- return this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey(), ...path], interaction, context);
8878
+ return this.object.hasEffectsOnInteractionAtPath([this.getDynamicPropertyKey(), ...path], interaction, context);
8621
8879
  }
8622
8880
  return true;
8623
8881
  }
8882
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
8883
+ return (destructuredInitPath.length > 0 &&
8884
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, context));
8885
+ }
8624
8886
  include(context, includeChildrenRecursively) {
8887
+ if (!this.included)
8888
+ this.includeNode(context);
8889
+ this.object.include(context, includeChildrenRecursively);
8890
+ this.property.include(context, includeChildrenRecursively);
8891
+ }
8892
+ includeNode(context) {
8893
+ this.included = true;
8625
8894
  if (!this.deoptimized)
8626
8895
  this.applyDeoptimizations();
8627
- this.includeProperties(context, includeChildrenRecursively);
8896
+ if (this.variable) {
8897
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
8898
+ }
8899
+ else if (!this.isUndefined) {
8900
+ this.object.includePath([this.propertyKey], context);
8901
+ }
8902
+ }
8903
+ includePath(path, context) {
8904
+ if (!this.included)
8905
+ this.includeNode(context);
8906
+ if (this.variable) {
8907
+ this.variable?.includePath(path, context);
8908
+ }
8909
+ else if (!this.isUndefined) {
8910
+ this.object.includePath([
8911
+ this.propertyKey,
8912
+ ...(path.length < MAX_PATH_DEPTH
8913
+ ? path
8914
+ : [...path.slice(0, MAX_PATH_DEPTH), UnknownKey])
8915
+ ], context);
8916
+ }
8628
8917
  }
8629
8918
  includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {
8630
8919
  if (!this.assignmentDeoptimized)
@@ -8633,20 +8922,34 @@ class MemberExpression extends NodeBase {
8633
8922
  this.include(context, includeChildrenRecursively);
8634
8923
  }
8635
8924
  else {
8636
- this.includeProperties(context, includeChildrenRecursively);
8925
+ if (!this.included)
8926
+ this.includeNode(context);
8927
+ this.object.include(context, includeChildrenRecursively);
8928
+ this.property.include(context, includeChildrenRecursively);
8637
8929
  }
8638
8930
  }
8639
- includeCallArguments(context, parameters) {
8931
+ includeCallArguments(context, interaction) {
8640
8932
  if (this.variable) {
8641
- this.variable.includeCallArguments(context, parameters);
8933
+ this.variable.includeCallArguments(context, interaction);
8642
8934
  }
8643
8935
  else {
8644
- super.includeCallArguments(context, parameters);
8936
+ super.includeCallArguments(context, interaction);
8645
8937
  }
8646
8938
  }
8939
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
8940
+ if ((this.included ||=
8941
+ destructuredInitPath.length > 0 &&
8942
+ !context.brokenFlow &&
8943
+ init.hasEffectsOnInteractionAtPath(destructuredInitPath, NODE_INTERACTION_UNKNOWN_ACCESS, createHasEffectsContext()))) {
8944
+ init.include(context, false);
8945
+ return true;
8946
+ }
8947
+ return false;
8948
+ }
8647
8949
  initialise() {
8648
8950
  super.initialise();
8649
- this.propertyKey = getResolvablePropertyKey(this);
8951
+ this.dynamicPropertyKey = getResolvablePropertyKey(this);
8952
+ this.propertyKey = this.dynamicPropertyKey === null ? UnknownKey : this.dynamicPropertyKey;
8650
8953
  this.accessInteraction = { args: [this.object], type: INTERACTION_ACCESSED };
8651
8954
  }
8652
8955
  render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = parseAst_js.BLANK) {
@@ -8683,8 +8986,7 @@ class MemberExpression extends NodeBase {
8683
8986
  this.bound &&
8684
8987
  propertyReadSideEffects &&
8685
8988
  !(this.variable || this.isUndefined)) {
8686
- const propertyKey = this.getPropertyKey();
8687
- this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER);
8989
+ this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [this.propertyKey], SHARED_RECURSION_TRACKER);
8688
8990
  this.scope.context.requestTreeshakingPass();
8689
8991
  }
8690
8992
  if (this.variable) {
@@ -8701,7 +9003,7 @@ class MemberExpression extends NodeBase {
8701
9003
  this.bound &&
8702
9004
  propertyReadSideEffects &&
8703
9005
  !(this.variable || this.isUndefined)) {
8704
- this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.getPropertyKey()], SHARED_RECURSION_TRACKER);
9006
+ this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.propertyKey], SHARED_RECURSION_TRACKER);
8705
9007
  this.scope.context.requestTreeshakingPass();
8706
9008
  }
8707
9009
  }
@@ -8710,24 +9012,24 @@ class MemberExpression extends NodeBase {
8710
9012
  const variable = this.scope.findVariable(this.object.name);
8711
9013
  if (variable.isNamespace) {
8712
9014
  if (this.variable) {
8713
- this.scope.context.includeVariableInModule(this.variable);
9015
+ this.scope.context.includeVariableInModule(this.variable, UNKNOWN_PATH, createInclusionContext());
8714
9016
  }
8715
9017
  this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);
8716
9018
  }
8717
9019
  }
8718
9020
  }
8719
- getPropertyKey() {
8720
- if (this.propertyKey === null) {
8721
- this.propertyKey = UnknownKey;
9021
+ getDynamicPropertyKey() {
9022
+ if (this.dynamicPropertyKey === null) {
9023
+ this.dynamicPropertyKey = this.propertyKey;
8722
9024
  const value = this.property.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
8723
- return (this.propertyKey =
9025
+ return (this.dynamicPropertyKey =
8724
9026
  value === SymbolToStringTag
8725
9027
  ? value
8726
9028
  : typeof value === 'symbol'
8727
9029
  ? UnknownKey
8728
9030
  : String(value));
8729
9031
  }
8730
- return this.propertyKey;
9032
+ return this.dynamicPropertyKey;
8731
9033
  }
8732
9034
  hasAccessEffect(context) {
8733
9035
  const { propertyReadSideEffects } = this.scope.context.options
@@ -8735,17 +9037,7 @@ class MemberExpression extends NodeBase {
8735
9037
  return (!(this.variable || this.isUndefined) &&
8736
9038
  propertyReadSideEffects &&
8737
9039
  (propertyReadSideEffects === 'always' ||
8738
- this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));
8739
- }
8740
- includeProperties(context, includeChildrenRecursively) {
8741
- if (!this.included) {
8742
- this.included = true;
8743
- if (this.variable) {
8744
- this.scope.context.includeVariableInModule(this.variable);
8745
- }
8746
- }
8747
- this.object.include(context, includeChildrenRecursively);
8748
- this.property.include(context, includeChildrenRecursively);
9040
+ this.object.hasEffectsOnInteractionAtPath([this.getDynamicPropertyKey()], this.accessInteraction, context)));
8749
9041
  }
8750
9042
  }
8751
9043
  function resolveNamespaceVariables(baseVariable, path, astContext) {
@@ -8789,18 +9081,20 @@ class MetaProperty extends NodeBase {
8789
9081
  return path.length > 1 || type !== INTERACTION_ACCESSED;
8790
9082
  }
8791
9083
  include() {
8792
- if (!this.included) {
8793
- this.included = true;
8794
- if (this.meta.name === IMPORT) {
8795
- this.scope.context.addImportMeta(this);
8796
- const parent = this.parent;
8797
- const metaProperty = (this.metaProperty =
8798
- parent instanceof MemberExpression && typeof parent.propertyKey === 'string'
8799
- ? parent.propertyKey
8800
- : null);
8801
- if (metaProperty?.startsWith(FILE_PREFIX)) {
8802
- this.referenceId = metaProperty.slice(FILE_PREFIX.length);
8803
- }
9084
+ if (!this.included)
9085
+ this.includeNode();
9086
+ }
9087
+ includeNode() {
9088
+ this.included = true;
9089
+ if (this.meta.name === IMPORT) {
9090
+ this.scope.context.addImportMeta(this);
9091
+ const parent = this.parent;
9092
+ const metaProperty = (this.metaProperty =
9093
+ parent instanceof MemberExpression && typeof parent.propertyKey === 'string'
9094
+ ? parent.propertyKey
9095
+ : null);
9096
+ if (metaProperty?.startsWith(FILE_PREFIX)) {
9097
+ this.referenceId = metaProperty.slice(FILE_PREFIX.length);
8804
9098
  }
8805
9099
  }
8806
9100
  }
@@ -8907,7 +9201,7 @@ class UndefinedVariable extends Variable {
8907
9201
 
8908
9202
  class ExportDefaultVariable extends LocalVariable {
8909
9203
  constructor(name, exportDefaultDeclaration, context) {
8910
- super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');
9204
+ super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, EMPTY_PATH, context, 'other');
8911
9205
  this.hasId = false;
8912
9206
  this.originalId = null;
8913
9207
  this.originalVariable = null;
@@ -9056,8 +9350,8 @@ class NamespaceVariable extends Variable {
9056
9350
  return (!memberVariable ||
9057
9351
  memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));
9058
9352
  }
9059
- include() {
9060
- super.include();
9353
+ includePath(path, context) {
9354
+ super.includePath(path, context);
9061
9355
  this.context.includeAllExports();
9062
9356
  }
9063
9357
  prepare(accessedGlobalsByScope) {
@@ -9150,9 +9444,9 @@ class SyntheticNamedExportVariable extends Variable {
9150
9444
  getName(getPropertyAccess) {
9151
9445
  return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;
9152
9446
  }
9153
- include() {
9154
- super.include();
9155
- this.context.includeVariableInModule(this.syntheticNamespace);
9447
+ includePath(path, context) {
9448
+ super.includePath(path, context);
9449
+ this.context.includeVariableInModule(this.syntheticNamespace, path, context);
9156
9450
  }
9157
9451
  setRenderNames(baseName, name) {
9158
9452
  super.setRenderNames(baseName, name);
@@ -12357,21 +12651,37 @@ class ArrayPattern extends NodeBase {
12357
12651
  element?.addExportedVariables(variables, exportNamesByVariable);
12358
12652
  }
12359
12653
  }
12360
- declare(kind) {
12654
+ declare(kind, destructuredInitPath, init) {
12361
12655
  const variables = [];
12656
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
12362
12657
  for (const element of this.elements) {
12363
12658
  if (element !== null) {
12364
- variables.push(...element.declare(kind, UNKNOWN_EXPRESSION));
12659
+ variables.push(...element.declare(kind, includedPatternPath, init));
12365
12660
  }
12366
12661
  }
12367
12662
  return variables;
12368
12663
  }
12664
+ deoptimizeAssignment(destructuredInitPath, init) {
12665
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
12666
+ for (const element of this.elements) {
12667
+ element?.deoptimizeAssignment(includedPatternPath, init);
12668
+ }
12669
+ }
12369
12670
  // Patterns can only be deoptimized at the empty path at the moment
12370
12671
  deoptimizePath() {
12371
12672
  for (const element of this.elements) {
12372
12673
  element?.deoptimizePath(EMPTY_PATH);
12373
12674
  }
12374
12675
  }
12676
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
12677
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
12678
+ for (const element of this.elements) {
12679
+ if (element?.hasEffectsWhenDestructuring(context, includedPatternPath, init)) {
12680
+ return true;
12681
+ }
12682
+ }
12683
+ return false;
12684
+ }
12375
12685
  // Patterns are only checked at the empty path at the moment
12376
12686
  hasEffectsOnInteractionAtPath(_path, interaction, context) {
12377
12687
  for (const element of this.elements) {
@@ -12380,12 +12690,38 @@ class ArrayPattern extends NodeBase {
12380
12690
  }
12381
12691
  return false;
12382
12692
  }
12693
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
12694
+ let included = false;
12695
+ const includedPatternPath = getIncludedPatternPath(destructuredInitPath);
12696
+ for (const element of this.elements) {
12697
+ if (element) {
12698
+ element.included ||= included;
12699
+ included =
12700
+ element.includeDestructuredIfNecessary(context, includedPatternPath, init) || included;
12701
+ }
12702
+ }
12703
+ if (included) {
12704
+ // This is necessary so that if any pattern element is included, all are
12705
+ // included for proper deconflicting
12706
+ for (const element of this.elements) {
12707
+ if (element && !element.included) {
12708
+ element.included = true;
12709
+ element.includeDestructuredIfNecessary(context, includedPatternPath, init);
12710
+ }
12711
+ }
12712
+ }
12713
+ return (this.included ||= included);
12714
+ }
12383
12715
  markDeclarationReached() {
12384
12716
  for (const element of this.elements) {
12385
12717
  element?.markDeclarationReached();
12386
12718
  }
12387
12719
  }
12388
12720
  }
12721
+ ArrayPattern.prototype.includeNode = onlyIncludeSelf;
12722
+ const getIncludedPatternPath = (destructuredInitPath) => destructuredInitPath.at(-1) === UnknownKey
12723
+ ? destructuredInitPath
12724
+ : [...destructuredInitPath, UnknownInteger];
12389
12725
 
12390
12726
  class ArrowFunctionExpression extends FunctionBase {
12391
12727
  constructor() {
@@ -12402,8 +12738,6 @@ class ArrowFunctionExpression extends FunctionBase {
12402
12738
  this.scope = new ReturnValueScope(parentScope, false);
12403
12739
  }
12404
12740
  hasEffects() {
12405
- if (!this.deoptimized)
12406
- this.applyDeoptimizations();
12407
12741
  return false;
12408
12742
  }
12409
12743
  hasEffectsOnInteractionAtPath(path, interaction, context) {
@@ -12442,6 +12776,15 @@ class ArrowFunctionExpression extends FunctionBase {
12442
12776
  }
12443
12777
  }
12444
12778
  }
12779
+ includeNode(context) {
12780
+ this.included = true;
12781
+ this.body.includePath(UNKNOWN_PATH, context);
12782
+ for (const parameter of this.params) {
12783
+ if (!(parameter instanceof Identifier)) {
12784
+ parameter.includePath(UNKNOWN_PATH, context);
12785
+ }
12786
+ }
12787
+ }
12445
12788
  getObjectEntity() {
12446
12789
  if (this.objectEntity !== null) {
12447
12790
  return this.objectEntity;
@@ -12461,13 +12804,18 @@ class ObjectPattern extends NodeBase {
12461
12804
  }
12462
12805
  }
12463
12806
  }
12464
- declare(kind, init) {
12807
+ declare(kind, destructuredInitPath, init) {
12465
12808
  const variables = [];
12466
12809
  for (const property of this.properties) {
12467
- variables.push(...property.declare(kind, init));
12810
+ variables.push(...property.declare(kind, destructuredInitPath, init));
12468
12811
  }
12469
12812
  return variables;
12470
12813
  }
12814
+ deoptimizeAssignment(destructuredInitPath, init) {
12815
+ for (const property of this.properties) {
12816
+ property.deoptimizeAssignment(destructuredInitPath, init);
12817
+ }
12818
+ }
12471
12819
  deoptimizePath(path) {
12472
12820
  if (path.length === 0) {
12473
12821
  for (const property of this.properties) {
@@ -12485,12 +12833,46 @@ class ObjectPattern extends NodeBase {
12485
12833
  }
12486
12834
  return false;
12487
12835
  }
12836
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
12837
+ for (const property of this.properties) {
12838
+ if (property.hasEffectsWhenDestructuring(context, destructuredInitPath, init))
12839
+ return true;
12840
+ }
12841
+ return false;
12842
+ }
12843
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
12844
+ let included = false;
12845
+ for (const property of this.properties) {
12846
+ included =
12847
+ property.includeDestructuredIfNecessary(context, destructuredInitPath, init) || included;
12848
+ }
12849
+ return (this.included ||= included);
12850
+ }
12488
12851
  markDeclarationReached() {
12489
12852
  for (const property of this.properties) {
12490
12853
  property.markDeclarationReached();
12491
12854
  }
12492
12855
  }
12856
+ render(code, options) {
12857
+ if (this.properties.length > 0) {
12858
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
12859
+ let lastSeparatorPos = null;
12860
+ for (const { node, separator, start, end } of separatedNodes) {
12861
+ if (!node.included) {
12862
+ treeshakeNode(node, code, start, end);
12863
+ continue;
12864
+ }
12865
+ lastSeparatorPos = separator;
12866
+ node.render(code, options);
12867
+ }
12868
+ if (lastSeparatorPos) {
12869
+ code.remove(lastSeparatorPos, this.end - 1);
12870
+ }
12871
+ }
12872
+ }
12493
12873
  }
12874
+ ObjectPattern.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
12875
+ ObjectPattern.prototype.applyDeoptimizations = doNotDeoptimize;
12494
12876
 
12495
12877
  class AssignmentExpression extends NodeBase {
12496
12878
  hasEffects(context) {
@@ -12499,7 +12881,9 @@ class AssignmentExpression extends NodeBase {
12499
12881
  this.applyDeoptimizations();
12500
12882
  // MemberExpressions do not access the property before assignments if the
12501
12883
  // operator is '='.
12502
- return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '='));
12884
+ return (right.hasEffects(context) ||
12885
+ left.hasEffectsAsAssignmentTarget(context, operator !== '=') ||
12886
+ this.left.hasEffectsWhenDestructuring?.(context, EMPTY_PATH, right));
12503
12887
  }
12504
12888
  hasEffectsOnInteractionAtPath(path, interaction, context) {
12505
12889
  return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);
@@ -12508,15 +12892,24 @@ class AssignmentExpression extends NodeBase {
12508
12892
  const { deoptimized, left, right, operator } = this;
12509
12893
  if (!deoptimized)
12510
12894
  this.applyDeoptimizations();
12511
- this.included = true;
12895
+ if (!this.included)
12896
+ this.includeNode(context);
12897
+ const hasEffectsContext = createHasEffectsContext();
12512
12898
  if (includeChildrenRecursively ||
12513
12899
  operator !== '=' ||
12514
12900
  left.included ||
12515
- left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {
12901
+ left.hasEffectsAsAssignmentTarget(hasEffectsContext, false) ||
12902
+ left.hasEffectsWhenDestructuring?.(hasEffectsContext, EMPTY_PATH, right)) {
12516
12903
  left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');
12517
12904
  }
12518
12905
  right.include(context, includeChildrenRecursively);
12519
12906
  }
12907
+ includeNode(context) {
12908
+ this.included = true;
12909
+ if (!this.deoptimized)
12910
+ this.applyDeoptimizations();
12911
+ this.right.includePath(UNKNOWN_PATH, context);
12912
+ }
12520
12913
  initialise() {
12521
12914
  super.initialise();
12522
12915
  if (this.left instanceof Identifier) {
@@ -12577,8 +12970,7 @@ class AssignmentExpression extends NodeBase {
12577
12970
  }
12578
12971
  applyDeoptimizations() {
12579
12972
  this.deoptimized = true;
12580
- this.left.deoptimizePath(EMPTY_PATH);
12581
- this.right.deoptimizePath(UNKNOWN_PATH);
12973
+ this.left.deoptimizeAssignment(EMPTY_PATH, this.right);
12582
12974
  this.scope.context.requestTreeshakingPass();
12583
12975
  }
12584
12976
  }
@@ -12587,8 +12979,11 @@ class AssignmentPattern extends NodeBase {
12587
12979
  addExportedVariables(variables, exportNamesByVariable) {
12588
12980
  this.left.addExportedVariables(variables, exportNamesByVariable);
12589
12981
  }
12590
- declare(kind, init) {
12591
- return this.left.declare(kind, init);
12982
+ declare(kind, destructuredInitPath, init) {
12983
+ return this.left.declare(kind, destructuredInitPath, init);
12984
+ }
12985
+ deoptimizeAssignment(destructuredInitPath, init) {
12986
+ this.left.deoptimizeAssignment(destructuredInitPath, init);
12592
12987
  }
12593
12988
  deoptimizePath(path) {
12594
12989
  if (path.length === 0) {
@@ -12598,6 +12993,29 @@ class AssignmentPattern extends NodeBase {
12598
12993
  hasEffectsOnInteractionAtPath(path, interaction, context) {
12599
12994
  return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
12600
12995
  }
12996
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
12997
+ return this.left.hasEffectsWhenDestructuring(context, destructuredInitPath, init);
12998
+ }
12999
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
13000
+ let included = this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init) ||
13001
+ this.included;
13002
+ if ((included ||= this.right.shouldBeIncluded(context))) {
13003
+ this.right.include(context, false);
13004
+ if (!this.left.included) {
13005
+ this.left.included = true;
13006
+ // Unfortunately, we need to include the left side again now, so that
13007
+ // any declared variables are properly included.
13008
+ this.left.includeDestructuredIfNecessary(context, destructuredInitPath, init);
13009
+ }
13010
+ }
13011
+ return (this.included = included);
13012
+ }
13013
+ includeNode(context) {
13014
+ this.included = true;
13015
+ if (!this.deoptimized)
13016
+ this.applyDeoptimizations();
13017
+ this.right.includePath(UNKNOWN_PATH, context);
13018
+ }
12601
13019
  markDeclarationReached() {
12602
13020
  this.left.markDeclarationReached();
12603
13021
  }
@@ -12620,22 +13038,34 @@ class AwaitExpression extends NodeBase {
12620
13038
  return true;
12621
13039
  }
12622
13040
  include(context, includeChildrenRecursively) {
13041
+ if (!this.included)
13042
+ this.includeNode(context);
13043
+ this.argument.include(context, includeChildrenRecursively);
13044
+ }
13045
+ includeNode(context) {
13046
+ this.included = true;
12623
13047
  if (!this.deoptimized)
12624
13048
  this.applyDeoptimizations();
12625
- if (!this.included) {
12626
- this.included = true;
12627
- checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) {
12628
- let parent = this.parent;
12629
- do {
12630
- if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression)
12631
- break checkTopLevelAwait;
12632
- } while ((parent = parent.parent));
12633
- this.scope.context.usesTopLevelAwait = true;
12634
- }
13049
+ checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) {
13050
+ let parent = this.parent;
13051
+ do {
13052
+ if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression)
13053
+ break checkTopLevelAwait;
13054
+ } while ((parent = parent.parent));
13055
+ this.scope.context.usesTopLevelAwait = true;
12635
13056
  }
12636
- this.argument.include(context, includeChildrenRecursively);
13057
+ // Thenables need to be included
13058
+ this.argument.includePath(THEN_PATH, context);
13059
+ }
13060
+ includePath(path, context) {
13061
+ if (!this.deoptimized)
13062
+ this.applyDeoptimizations();
13063
+ if (!this.included)
13064
+ this.includeNode(context);
13065
+ this.argument.includePath(path, context);
12637
13066
  }
12638
13067
  }
13068
+ const THEN_PATH = ['then'];
12639
13069
 
12640
13070
  const binaryOperators = {
12641
13071
  '!=': (left, right) => left != right,
@@ -12691,6 +13121,12 @@ class BinaryExpression extends NodeBase {
12691
13121
  hasEffectsOnInteractionAtPath(path, { type }) {
12692
13122
  return type !== INTERACTION_ACCESSED || path.length > 1;
12693
13123
  }
13124
+ includeNode(context) {
13125
+ this.included = true;
13126
+ if (this.operator === 'in') {
13127
+ this.right.includePath(UNKNOWN_PATH, context);
13128
+ }
13129
+ }
12694
13130
  removeAnnotations(code) {
12695
13131
  this.left.removeAnnotations(code);
12696
13132
  }
@@ -12699,6 +13135,7 @@ class BinaryExpression extends NodeBase {
12699
13135
  this.right.render(code, options);
12700
13136
  }
12701
13137
  }
13138
+ BinaryExpression.prototype.applyDeoptimizations = doNotDeoptimize;
12702
13139
 
12703
13140
  class BreakStatement extends NodeBase {
12704
13141
  hasEffects(context) {
@@ -12718,7 +13155,7 @@ class BreakStatement extends NodeBase {
12718
13155
  include(context) {
12719
13156
  this.included = true;
12720
13157
  if (this.label) {
12721
- this.label.include();
13158
+ this.label.include(context);
12722
13159
  context.includedLabels.add(this.label.name);
12723
13160
  }
12724
13161
  else {
@@ -12727,6 +13164,8 @@ class BreakStatement extends NodeBase {
12727
13164
  context.brokenFlow = true;
12728
13165
  }
12729
13166
  }
13167
+ BreakStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13168
+ BreakStatement.prototype.applyDeoptimizations = doNotDeoptimize;
12730
13169
 
12731
13170
  function renderCallArguments(code, options, node) {
12732
13171
  if (node.arguments.length > 0) {
@@ -12913,10 +13352,14 @@ class CallExpression extends CallExpressionBase {
12913
13352
  this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)));
12914
13353
  }
12915
13354
  include(context, includeChildrenRecursively) {
12916
- if (!this.deoptimized)
12917
- this.applyDeoptimizations();
13355
+ if (!this.included)
13356
+ this.includeNode(context);
12918
13357
  if (includeChildrenRecursively) {
12919
- super.include(context, includeChildrenRecursively);
13358
+ this.callee.include(context, true);
13359
+ for (const argument of this.arguments) {
13360
+ argument.includePath(UNKNOWN_PATH, context);
13361
+ argument.include(context, true);
13362
+ }
12920
13363
  if (includeChildrenRecursively === INCLUDE_PARAMETERS &&
12921
13364
  this.callee instanceof Identifier &&
12922
13365
  this.callee.variable) {
@@ -12924,10 +13367,24 @@ class CallExpression extends CallExpressionBase {
12924
13367
  }
12925
13368
  }
12926
13369
  else {
12927
- this.included = true;
12928
- this.callee.include(context, false);
13370
+ // If the callee is a member expression and does not have a variable, its
13371
+ // object will already be included via the first argument of the
13372
+ // interaction in includeCallArguments. Including it again can lead to
13373
+ // severe performance problems.
13374
+ if (this.callee instanceof MemberExpression && !this.callee.variable) {
13375
+ this.callee.property.include(context, false);
13376
+ }
13377
+ else {
13378
+ this.callee.include(context, false);
13379
+ }
13380
+ this.callee.includeCallArguments(context, this.interaction);
12929
13381
  }
12930
- this.callee.includeCallArguments(context, this.arguments);
13382
+ }
13383
+ includeNode(context) {
13384
+ this.included = true;
13385
+ if (!this.deoptimized)
13386
+ this.applyDeoptimizations();
13387
+ this.callee.includePath(UNKNOWN_PATH, context);
12931
13388
  }
12932
13389
  initialise() {
12933
13390
  super.initialise();
@@ -12966,13 +13423,14 @@ class CatchClause extends NodeBase {
12966
13423
  this.type = type;
12967
13424
  if (param) {
12968
13425
  this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);
12969
- this.param.declare('parameter', UNKNOWN_EXPRESSION);
13426
+ this.param.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
12970
13427
  }
12971
13428
  this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);
12972
13429
  return super.parseNode(esTreeNode);
12973
13430
  }
12974
13431
  }
12975
13432
  CatchClause.prototype.preventChildBlockScope = true;
13433
+ CatchClause.prototype.includeNode = onlyIncludeSelf;
12976
13434
 
12977
13435
  class ChainExpression extends NodeBase {
12978
13436
  // deoptimizations are not relevant as we are not caching values
@@ -12984,17 +13442,22 @@ class ChainExpression extends NodeBase {
12984
13442
  hasEffects(context) {
12985
13443
  return this.expression.hasEffectsAsChainElement(context) === true;
12986
13444
  }
13445
+ includePath(path, context) {
13446
+ this.included = true;
13447
+ this.expression.includePath(path, context);
13448
+ }
12987
13449
  removeAnnotations(code) {
12988
13450
  this.expression.removeAnnotations(code);
12989
13451
  }
12990
- applyDeoptimizations() { }
12991
13452
  }
13453
+ ChainExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13454
+ ChainExpression.prototype.applyDeoptimizations = doNotDeoptimize;
12992
13455
 
12993
13456
  class ClassBodyScope extends ChildScope {
12994
13457
  constructor(parent, classNode) {
12995
13458
  const { context } = parent;
12996
13459
  super(parent, context);
12997
- this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));
13460
+ this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, EMPTY_PATH, context, 'other')));
12998
13461
  this.instanceScope = new ChildScope(this, context);
12999
13462
  this.instanceScope.variables.set('this', new ThisVariable(context));
13000
13463
  }
@@ -13009,7 +13472,7 @@ class ClassBody extends NodeBase {
13009
13472
  }
13010
13473
  include(context, includeChildrenRecursively) {
13011
13474
  this.included = true;
13012
- this.scope.context.includeVariableInModule(this.scope.thisVariable);
13475
+ this.scope.context.includeVariableInModule(this.scope.thisVariable, UNKNOWN_PATH, context);
13013
13476
  for (const definition of this.body) {
13014
13477
  definition.include(context, includeChildrenRecursively);
13015
13478
  }
@@ -13022,8 +13485,9 @@ class ClassBody extends NodeBase {
13022
13485
  }
13023
13486
  return super.parseNode(esTreeNode);
13024
13487
  }
13025
- applyDeoptimizations() { }
13026
13488
  }
13489
+ ClassBody.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13490
+ ClassBody.prototype.applyDeoptimizations = doNotDeoptimize;
13027
13491
 
13028
13492
  class ClassExpression extends ClassNode {
13029
13493
  render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {
@@ -13094,6 +13558,9 @@ class ConditionalExpression extends NodeBase {
13094
13558
  const unusedBranch = this.usedBranch === this.consequent ? this.alternate : this.consequent;
13095
13559
  this.usedBranch = null;
13096
13560
  unusedBranch.deoptimizePath(UNKNOWN_PATH);
13561
+ if (this.included) {
13562
+ unusedBranch.includePath(UNKNOWN_PATH, createInclusionContext());
13563
+ }
13097
13564
  const { expressionsToBeDeoptimized } = this;
13098
13565
  this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;
13099
13566
  for (const expression of expressionsToBeDeoptimized) {
@@ -13151,7 +13618,7 @@ class ConditionalExpression extends NodeBase {
13151
13618
  include(context, includeChildrenRecursively) {
13152
13619
  this.included = true;
13153
13620
  const usedBranch = this.getUsedBranch();
13154
- if (includeChildrenRecursively || this.test.shouldBeIncluded(context) || usedBranch === null) {
13621
+ if (usedBranch === null || includeChildrenRecursively || this.test.shouldBeIncluded(context)) {
13155
13622
  this.test.include(context, includeChildrenRecursively);
13156
13623
  this.consequent.include(context, includeChildrenRecursively);
13157
13624
  this.alternate.include(context, includeChildrenRecursively);
@@ -13160,27 +13627,38 @@ class ConditionalExpression extends NodeBase {
13160
13627
  usedBranch.include(context, includeChildrenRecursively);
13161
13628
  }
13162
13629
  }
13163
- includeCallArguments(context, parameters) {
13630
+ includePath(path, context) {
13631
+ this.included = true;
13632
+ const usedBranch = this.getUsedBranch();
13633
+ if (usedBranch === null || this.test.shouldBeIncluded(context)) {
13634
+ this.consequent.includePath(path, context);
13635
+ this.alternate.includePath(path, context);
13636
+ }
13637
+ else {
13638
+ usedBranch.includePath(path, context);
13639
+ }
13640
+ }
13641
+ includeCallArguments(context, interaction) {
13164
13642
  const usedBranch = this.getUsedBranch();
13165
13643
  if (usedBranch) {
13166
- usedBranch.includeCallArguments(context, parameters);
13644
+ usedBranch.includeCallArguments(context, interaction);
13167
13645
  }
13168
13646
  else {
13169
- this.consequent.includeCallArguments(context, parameters);
13170
- this.alternate.includeCallArguments(context, parameters);
13647
+ this.consequent.includeCallArguments(context, interaction);
13648
+ this.alternate.includeCallArguments(context, interaction);
13171
13649
  }
13172
13650
  }
13173
13651
  removeAnnotations(code) {
13174
13652
  this.test.removeAnnotations(code);
13175
13653
  }
13176
13654
  render(code, options, { isCalleeOfRenderedParent, preventASI, renderedParentType, renderedSurroundingElement } = parseAst_js.BLANK) {
13177
- const usedBranch = this.getUsedBranch();
13178
13655
  if (this.test.included) {
13179
13656
  this.test.render(code, options, { renderedSurroundingElement });
13180
13657
  this.consequent.render(code, options);
13181
13658
  this.alternate.render(code, options);
13182
13659
  }
13183
13660
  else {
13661
+ const usedBranch = this.getUsedBranch();
13184
13662
  const colonPos = findFirstOccurrenceOutsideComment(code.original, ':', this.consequent.end);
13185
13663
  const inclusionStart = findNonWhiteSpace(code.original, (this.consequent.included
13186
13664
  ? findFirstOccurrenceOutsideComment(code.original, '?', this.test.end)
@@ -13212,6 +13690,8 @@ class ConditionalExpression extends NodeBase {
13212
13690
  : (this.usedBranch = testValue ? this.consequent : this.alternate);
13213
13691
  }
13214
13692
  }
13693
+ ConditionalExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13694
+ ConditionalExpression.prototype.applyDeoptimizations = doNotDeoptimize;
13215
13695
 
13216
13696
  class ContinueStatement extends NodeBase {
13217
13697
  hasEffects(context) {
@@ -13231,7 +13711,7 @@ class ContinueStatement extends NodeBase {
13231
13711
  include(context) {
13232
13712
  this.included = true;
13233
13713
  if (this.label) {
13234
- this.label.include();
13714
+ this.label.include(context);
13235
13715
  context.includedLabels.add(this.label.name);
13236
13716
  }
13237
13717
  else {
@@ -13240,12 +13720,15 @@ class ContinueStatement extends NodeBase {
13240
13720
  context.brokenFlow = true;
13241
13721
  }
13242
13722
  }
13723
+ ContinueStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13724
+ ContinueStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13243
13725
 
13244
13726
  class DebuggerStatement extends NodeBase {
13245
13727
  hasEffects() {
13246
13728
  return true;
13247
13729
  }
13248
13730
  }
13731
+ DebuggerStatement.prototype.includeNode = onlyIncludeSelf;
13249
13732
 
13250
13733
  class Decorator extends NodeBase {
13251
13734
  hasEffects(context) {
@@ -13253,6 +13736,7 @@ class Decorator extends NodeBase {
13253
13736
  this.expression.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context));
13254
13737
  }
13255
13738
  }
13739
+ Decorator.prototype.includeNode = onlyIncludeSelf;
13256
13740
 
13257
13741
  function hasLoopBodyEffects(context, body) {
13258
13742
  const { brokenFlow, hasBreak, hasContinue, ignore } = context;
@@ -13292,12 +13776,15 @@ class DoWhileStatement extends NodeBase {
13292
13776
  includeLoopBody(context, this.body, includeChildrenRecursively);
13293
13777
  }
13294
13778
  }
13779
+ DoWhileStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13780
+ DoWhileStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13295
13781
 
13296
13782
  class EmptyStatement extends NodeBase {
13297
13783
  hasEffects() {
13298
13784
  return false;
13299
13785
  }
13300
13786
  }
13787
+ EmptyStatement.prototype.includeNode = onlyIncludeSelf;
13301
13788
 
13302
13789
  class ExportAllDeclaration extends NodeBase {
13303
13790
  hasEffects() {
@@ -13310,9 +13797,10 @@ class ExportAllDeclaration extends NodeBase {
13310
13797
  render(code, _options, nodeRenderOptions) {
13311
13798
  code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
13312
13799
  }
13313
- applyDeoptimizations() { }
13314
13800
  }
13315
13801
  ExportAllDeclaration.prototype.needsBoundaries = true;
13802
+ ExportAllDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13803
+ ExportAllDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
13316
13804
 
13317
13805
  class ExportNamedDeclaration extends NodeBase {
13318
13806
  bind() {
@@ -13339,13 +13827,15 @@ class ExportNamedDeclaration extends NodeBase {
13339
13827
  this.declaration.render(code, options, { end, start });
13340
13828
  }
13341
13829
  }
13342
- applyDeoptimizations() { }
13343
13830
  }
13344
13831
  ExportNamedDeclaration.prototype.needsBoundaries = true;
13832
+ ExportNamedDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13833
+ ExportNamedDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
13345
13834
 
13346
13835
  class ExportSpecifier extends NodeBase {
13347
- applyDeoptimizations() { }
13348
13836
  }
13837
+ ExportSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13838
+ ExportSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
13349
13839
 
13350
13840
  class ForInStatement extends NodeBase {
13351
13841
  createScope(parentScope) {
@@ -13363,11 +13853,18 @@ class ForInStatement extends NodeBase {
13363
13853
  const { body, deoptimized, left, right } = this;
13364
13854
  if (!deoptimized)
13365
13855
  this.applyDeoptimizations();
13366
- this.included = true;
13856
+ if (!this.included)
13857
+ this.includeNode(context);
13367
13858
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
13368
13859
  right.include(context, includeChildrenRecursively);
13369
13860
  includeLoopBody(context, body, includeChildrenRecursively);
13370
13861
  }
13862
+ includeNode(context) {
13863
+ this.included = true;
13864
+ if (!this.deoptimized)
13865
+ this.applyDeoptimizations();
13866
+ this.right.includePath(UNKNOWN_PATH, context);
13867
+ }
13371
13868
  initialise() {
13372
13869
  super.initialise();
13373
13870
  this.left.setAssignedValue(UNKNOWN_EXPRESSION);
@@ -13408,11 +13905,18 @@ class ForOfStatement extends NodeBase {
13408
13905
  const { body, deoptimized, left, right } = this;
13409
13906
  if (!deoptimized)
13410
13907
  this.applyDeoptimizations();
13411
- this.included = true;
13908
+ if (!this.included)
13909
+ this.includeNode(context);
13412
13910
  left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
13413
13911
  right.include(context, includeChildrenRecursively);
13414
13912
  includeLoopBody(context, body, includeChildrenRecursively);
13415
13913
  }
13914
+ includeNode(context) {
13915
+ this.included = true;
13916
+ if (!this.deoptimized)
13917
+ this.applyDeoptimizations();
13918
+ this.right.includePath(UNKNOWN_PATH, context);
13919
+ }
13416
13920
  initialise() {
13417
13921
  super.initialise();
13418
13922
  this.left.setAssignedValue(UNKNOWN_EXPRESSION);
@@ -13448,7 +13952,9 @@ class ForStatement extends NodeBase {
13448
13952
  }
13449
13953
  include(context, includeChildrenRecursively) {
13450
13954
  this.included = true;
13451
- this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true });
13955
+ this.init?.include(context, includeChildrenRecursively, {
13956
+ asSingleStatement: true
13957
+ });
13452
13958
  this.test?.include(context, includeChildrenRecursively);
13453
13959
  this.update?.include(context, includeChildrenRecursively);
13454
13960
  includeLoopBody(context, this.body, includeChildrenRecursively);
@@ -13460,6 +13966,8 @@ class ForStatement extends NodeBase {
13460
13966
  this.body.render(code, options);
13461
13967
  }
13462
13968
  }
13969
+ ForStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
13970
+ ForStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13463
13971
 
13464
13972
  class FunctionExpression extends FunctionNode {
13465
13973
  createScope(parentScope) {
@@ -13491,9 +13999,9 @@ class TrackingScope extends BlockScope {
13491
13999
  super(...arguments);
13492
14000
  this.hoistedDeclarations = [];
13493
14001
  }
13494
- addDeclaration(identifier, context, init, kind) {
14002
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
13495
14003
  this.hoistedDeclarations.push(identifier);
13496
- return super.addDeclaration(identifier, context, init, kind);
14004
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
13497
14005
  }
13498
14006
  }
13499
14007
 
@@ -13592,7 +14100,6 @@ class IfStatement extends NodeBase {
13592
14100
  }
13593
14101
  this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess);
13594
14102
  }
13595
- applyDeoptimizations() { }
13596
14103
  getTestValue() {
13597
14104
  if (this.testValue === unset) {
13598
14105
  return (this.testValue = tryCastLiteralValueToBoolean(this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)));
@@ -13661,6 +14168,8 @@ class IfStatement extends NodeBase {
13661
14168
  return false;
13662
14169
  }
13663
14170
  }
14171
+ IfStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14172
+ IfStatement.prototype.applyDeoptimizations = doNotDeoptimize;
13664
14173
 
13665
14174
  class ImportAttribute extends NodeBase {
13666
14175
  }
@@ -13678,13 +14187,15 @@ class ImportDeclaration extends NodeBase {
13678
14187
  render(code, _options, nodeRenderOptions) {
13679
14188
  code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
13680
14189
  }
13681
- applyDeoptimizations() { }
13682
14190
  }
13683
14191
  ImportDeclaration.prototype.needsBoundaries = true;
14192
+ ImportDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14193
+ ImportDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
13684
14194
 
13685
14195
  class ImportDefaultSpecifier extends NodeBase {
13686
- applyDeoptimizations() { }
13687
14196
  }
14197
+ ImportDefaultSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14198
+ ImportDefaultSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
13688
14199
 
13689
14200
  function isReassignedExportsMember(variable, exportNamesByVariable) {
13690
14201
  return (variable.renderBaseName !== null && exportNamesByVariable.has(variable) && variable.isReassigned);
@@ -13693,28 +14204,33 @@ function isReassignedExportsMember(variable, exportNamesByVariable) {
13693
14204
  class VariableDeclarator extends NodeBase {
13694
14205
  declareDeclarator(kind, isUsingDeclaration) {
13695
14206
  this.isUsingDeclaration = isUsingDeclaration;
13696
- this.id.declare(kind, this.init || UNDEFINED_EXPRESSION);
14207
+ this.id.declare(kind, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION);
13697
14208
  }
13698
14209
  deoptimizePath(path) {
13699
14210
  this.id.deoptimizePath(path);
13700
14211
  }
13701
14212
  hasEffects(context) {
13702
- if (!this.deoptimized)
13703
- this.applyDeoptimizations();
13704
14213
  const initEffect = this.init?.hasEffects(context);
13705
14214
  this.id.markDeclarationReached();
13706
- return initEffect || this.id.hasEffects(context) || this.isUsingDeclaration;
14215
+ return (initEffect ||
14216
+ this.isUsingDeclaration ||
14217
+ this.id.hasEffects(context) ||
14218
+ (this.scope.context.options.treeshake
14219
+ .propertyReadSideEffects &&
14220
+ this.id.hasEffectsWhenDestructuring(context, EMPTY_PATH, this.init || UNDEFINED_EXPRESSION)));
13707
14221
  }
13708
14222
  include(context, includeChildrenRecursively) {
13709
- const { deoptimized, id, init } = this;
13710
- if (!deoptimized)
13711
- this.applyDeoptimizations();
13712
- this.included = true;
14223
+ const { id, init } = this;
14224
+ if (!this.included)
14225
+ this.includeNode();
13713
14226
  init?.include(context, includeChildrenRecursively);
13714
14227
  id.markDeclarationReached();
13715
- if (includeChildrenRecursively || id.shouldBeIncluded(context)) {
14228
+ if (includeChildrenRecursively) {
13716
14229
  id.include(context, includeChildrenRecursively);
13717
14230
  }
14231
+ else {
14232
+ id.includeDestructuredIfNecessary(context, EMPTY_PATH, init || UNDEFINED_EXPRESSION);
14233
+ }
13718
14234
  }
13719
14235
  removeAnnotations(code) {
13720
14236
  this.init?.removeAnnotations(code);
@@ -13744,8 +14260,8 @@ class VariableDeclarator extends NodeBase {
13744
14260
  code.appendLeft(end, `${_}=${_}void 0`);
13745
14261
  }
13746
14262
  }
13747
- applyDeoptimizations() {
13748
- this.deoptimized = true;
14263
+ includeNode() {
14264
+ this.included = true;
13749
14265
  const { id, init } = this;
13750
14266
  if (init && id instanceof Identifier && init instanceof ClassExpression && !init.id) {
13751
14267
  const { name, variable } = id;
@@ -13757,11 +14273,14 @@ class VariableDeclarator extends NodeBase {
13757
14273
  }
13758
14274
  }
13759
14275
  }
14276
+ VariableDeclarator.prototype.applyDeoptimizations = doNotDeoptimize;
13760
14277
 
13761
14278
  class ImportExpression extends NodeBase {
13762
14279
  constructor() {
13763
14280
  super(...arguments);
13764
14281
  this.inlineNamespace = null;
14282
+ this.hasUnknownAccessedKey = false;
14283
+ this.accessedPropKey = new Set();
13765
14284
  this.attributes = null;
13766
14285
  this.mechanism = null;
13767
14286
  this.namespaceExportName = undefined;
@@ -13794,12 +14313,15 @@ class ImportExpression extends NodeBase {
13794
14313
  if (parent2 instanceof ExpressionStatement) {
13795
14314
  return parseAst_js.EMPTY_ARRAY;
13796
14315
  }
13797
- // Case 1: const { foo } = await import('bar')
14316
+ // Case 1: const { foo } / module = await import('bar')
13798
14317
  if (parent2 instanceof VariableDeclarator) {
13799
14318
  const declaration = parent2.id;
13800
- return declaration instanceof ObjectPattern
13801
- ? getDeterministicObjectDestructure(declaration)
13802
- : undefined;
14319
+ if (declaration instanceof Identifier) {
14320
+ return this.hasUnknownAccessedKey ? undefined : [...this.accessedPropKey];
14321
+ }
14322
+ if (declaration instanceof ObjectPattern) {
14323
+ return getDeterministicObjectDestructure(declaration);
14324
+ }
13803
14325
  }
13804
14326
  // Case 2: (await import('bar')).foo
13805
14327
  if (parent2 instanceof MemberExpression) {
@@ -13849,13 +14371,30 @@ class ImportExpression extends NodeBase {
13849
14371
  return true;
13850
14372
  }
13851
14373
  include(context, includeChildrenRecursively) {
13852
- if (!this.included) {
13853
- this.included = true;
13854
- this.scope.context.includeDynamicImport(this);
13855
- this.scope.addAccessedDynamicImport(this);
13856
- }
14374
+ if (!this.included)
14375
+ this.includeNode();
13857
14376
  this.source.include(context, includeChildrenRecursively);
13858
14377
  }
14378
+ includeNode() {
14379
+ this.included = true;
14380
+ this.scope.context.includeDynamicImport(this);
14381
+ this.scope.addAccessedDynamicImport(this);
14382
+ }
14383
+ includePath(path) {
14384
+ if (!this.included)
14385
+ this.includeNode();
14386
+ // Technically, this is not correct as dynamic imports return a Promise.
14387
+ if (this.hasUnknownAccessedKey)
14388
+ return;
14389
+ if (path[0] === UnknownKey) {
14390
+ this.hasUnknownAccessedKey = true;
14391
+ }
14392
+ else if (typeof path[0] === 'string') {
14393
+ this.accessedPropKey.add(path[0]);
14394
+ }
14395
+ // Update included paths
14396
+ this.scope.context.includeDynamicImport(this);
14397
+ }
13859
14398
  initialise() {
13860
14399
  super.initialise();
13861
14400
  this.scope.context.addDynamicImport(this);
@@ -13924,7 +14463,6 @@ class ImportExpression extends NodeBase {
13924
14463
  setInternalResolution(inlineNamespace) {
13925
14464
  this.inlineNamespace = inlineNamespace;
13926
14465
  }
13927
- applyDeoptimizations() { }
13928
14466
  getDynamicImportMechanismAndHelper(resolution, exportMode, { compact, dynamicImportInCjs, format, generatedCode: { arrowFunctions }, interop }, { _, getDirectReturnFunction, getDirectReturnIifeLeft }, pluginDriver) {
13929
14467
  const mechanism = pluginDriver.hookFirstSync('renderDynamicImport', [
13930
14468
  {
@@ -14014,6 +14552,7 @@ class ImportExpression extends NodeBase {
14014
14552
  return { helper: null, mechanism: null };
14015
14553
  }
14016
14554
  }
14555
+ ImportExpression.prototype.applyDeoptimizations = doNotDeoptimize;
14017
14556
  function getInteropHelper(resolution, exportMode, interop) {
14018
14557
  return exportMode === 'external'
14019
14558
  ? namespaceInteropHelpersByInteropType[interop(resolution instanceof ExternalModule ? resolution.id : null)]
@@ -14037,12 +14576,14 @@ function getDeterministicObjectDestructure(objectPattern) {
14037
14576
  }
14038
14577
 
14039
14578
  class ImportNamespaceSpecifier extends NodeBase {
14040
- applyDeoptimizations() { }
14041
14579
  }
14580
+ ImportNamespaceSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14581
+ ImportNamespaceSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
14042
14582
 
14043
14583
  class ImportSpecifier extends NodeBase {
14044
- applyDeoptimizations() { }
14045
14584
  }
14585
+ ImportSpecifier.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
14586
+ ImportSpecifier.prototype.applyDeoptimizations = doNotDeoptimize;
14046
14587
 
14047
14588
  class JSXIdentifier extends IdentifierBase {
14048
14589
  constructor() {
@@ -14059,6 +14600,29 @@ class JSXIdentifier extends IdentifierBase {
14059
14600
  this.isNativeElement = true;
14060
14601
  }
14061
14602
  }
14603
+ include(context) {
14604
+ if (!this.included)
14605
+ this.includeNode(context);
14606
+ }
14607
+ includeNode(context) {
14608
+ this.included = true;
14609
+ if (!this.deoptimized)
14610
+ this.applyDeoptimizations();
14611
+ if (this.variable !== null) {
14612
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
14613
+ }
14614
+ }
14615
+ includePath(path, context) {
14616
+ if (!this.included) {
14617
+ this.included = true;
14618
+ if (this.variable !== null) {
14619
+ this.scope.context.includeVariableInModule(this.variable, path, context);
14620
+ }
14621
+ }
14622
+ else if (path.length > 0) {
14623
+ this.variable?.includePath(path, context);
14624
+ }
14625
+ }
14062
14626
  render(code, { snippets: { getPropertyAccess }, useOriginalName }) {
14063
14627
  if (this.variable) {
14064
14628
  const name = this.variable.getName(getPropertyAccess, useOriginalName);
@@ -14120,6 +14684,7 @@ class JSXAttribute extends NodeBase {
14120
14684
  }
14121
14685
  }
14122
14686
  }
14687
+ JSXAttribute.prototype.includeNode = onlyIncludeSelf;
14123
14688
 
14124
14689
  class JSXClosingBase extends NodeBase {
14125
14690
  render(code, options) {
@@ -14132,6 +14697,7 @@ class JSXClosingBase extends NodeBase {
14132
14697
  }
14133
14698
  }
14134
14699
  }
14700
+ JSXClosingBase.prototype.includeNode = onlyIncludeSelf;
14135
14701
 
14136
14702
  class JSXClosingElement extends JSXClosingBase {
14137
14703
  }
@@ -14152,8 +14718,15 @@ class JSXSpreadAttribute extends NodeBase {
14152
14718
 
14153
14719
  class JSXEmptyExpression extends NodeBase {
14154
14720
  }
14721
+ JSXEmptyExpression.prototype.includeNode = onlyIncludeSelf;
14155
14722
 
14156
14723
  class JSXExpressionContainer extends NodeBase {
14724
+ includeNode(context) {
14725
+ this.included = true;
14726
+ if (!this.deoptimized)
14727
+ this.applyDeoptimizations();
14728
+ this.expression.includePath(UNKNOWN_PATH, context);
14729
+ }
14157
14730
  render(code, options) {
14158
14731
  const { mode } = this.scope.context.options.jsx;
14159
14732
  if (mode !== 'preserve') {
@@ -14174,7 +14747,7 @@ function getRenderedJsxChildren(children) {
14174
14747
  return renderedChildren;
14175
14748
  }
14176
14749
 
14177
- function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
14750
+ function getAndIncludeFactoryVariable(factory, preserve, importSource, node, context) {
14178
14751
  const [baseName, nestedName] = factory.split('.');
14179
14752
  let factoryVariable;
14180
14753
  if (importSource) {
@@ -14182,7 +14755,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
14182
14755
  if (preserve) {
14183
14756
  // This pretends we are accessing an included global variable of the same name
14184
14757
  const globalVariable = node.scope.findGlobal(baseName);
14185
- globalVariable.include();
14758
+ globalVariable.includePath(UNKNOWN_PATH, context);
14186
14759
  // This excludes this variable from renaming
14187
14760
  factoryVariable.globalName = baseName;
14188
14761
  }
@@ -14190,7 +14763,7 @@ function getAndIncludeFactoryVariable(factory, preserve, importSource, node) {
14190
14763
  else {
14191
14764
  factoryVariable = node.scope.findGlobal(baseName);
14192
14765
  }
14193
- node.scope.context.includeVariableInModule(factoryVariable);
14766
+ node.scope.context.includeVariableInModule(factoryVariable, UNKNOWN_PATH, context);
14194
14767
  if (factoryVariable instanceof LocalVariable) {
14195
14768
  factoryVariable.consolidateInitializers();
14196
14769
  factoryVariable.addUsedPlace(node);
@@ -14213,16 +14786,20 @@ class JSXElementBase extends NodeBase {
14213
14786
  }
14214
14787
  }
14215
14788
  include(context, includeChildrenRecursively) {
14216
- if (!this.included) {
14217
- const { factory, importSource, mode } = this.jsxMode;
14218
- if (factory) {
14219
- this.factory = factory;
14220
- this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this);
14221
- }
14789
+ if (!this.included)
14790
+ this.includeNode(context);
14791
+ for (const child of this.children) {
14792
+ child.include(context, includeChildrenRecursively);
14793
+ }
14794
+ }
14795
+ includeNode(context) {
14796
+ this.included = true;
14797
+ const { factory, importSource, mode } = this.jsxMode;
14798
+ if (factory) {
14799
+ this.factory = factory;
14800
+ this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this, context);
14222
14801
  }
14223
- super.include(context, includeChildrenRecursively);
14224
14802
  }
14225
- applyDeoptimizations() { }
14226
14803
  getRenderingMode() {
14227
14804
  const jsx = this.scope.context.options.jsx;
14228
14805
  const { mode, factory, importSource } = jsx;
@@ -14260,8 +14837,14 @@ class JSXElementBase extends NodeBase {
14260
14837
  return { childrenEnd, firstChild, hasMultipleChildren };
14261
14838
  }
14262
14839
  }
14840
+ JSXElementBase.prototype.applyDeoptimizations = doNotDeoptimize;
14263
14841
 
14264
14842
  class JSXElement extends JSXElementBase {
14843
+ include(context, includeChildrenRecursively) {
14844
+ super.include(context, includeChildrenRecursively);
14845
+ this.openingElement.include(context, includeChildrenRecursively);
14846
+ this.closingElement?.include(context, includeChildrenRecursively);
14847
+ }
14265
14848
  render(code, options) {
14266
14849
  switch (this.jsxMode.mode) {
14267
14850
  case 'classic': {
@@ -14413,6 +14996,11 @@ class JSXElement extends JSXElementBase {
14413
14996
  }
14414
14997
 
14415
14998
  class JSXFragment extends JSXElementBase {
14999
+ include(context, includeChildrenRecursively) {
15000
+ super.include(context, includeChildrenRecursively);
15001
+ this.openingFragment.include(context, includeChildrenRecursively);
15002
+ this.closingFragment.include(context, includeChildrenRecursively);
15003
+ }
14416
15004
  render(code, options) {
14417
15005
  switch (this.jsxMode.mode) {
14418
15006
  case 'classic': {
@@ -14462,10 +15050,22 @@ class JSXFragment extends JSXElementBase {
14462
15050
  }
14463
15051
 
14464
15052
  class JSXMemberExpression extends NodeBase {
15053
+ includeNode(context) {
15054
+ this.included = true;
15055
+ if (!this.deoptimized)
15056
+ this.applyDeoptimizations();
15057
+ this.object.includePath([this.property.name], context);
15058
+ }
15059
+ includePath(path, context) {
15060
+ if (!this.included)
15061
+ this.includeNode(context);
15062
+ this.object.includePath([this.property.name, ...path], context);
15063
+ }
14465
15064
  }
14466
15065
 
14467
15066
  class JSXNamespacedName extends NodeBase {
14468
15067
  }
15068
+ JSXNamespacedName.prototype.includeNode = onlyIncludeSelf;
14469
15069
 
14470
15070
  class JSXOpeningElement extends NodeBase {
14471
15071
  render(code, options, { jsxMode = this.scope.context.options.jsx.mode } = {}) {
@@ -14475,6 +15075,7 @@ class JSXOpeningElement extends NodeBase {
14475
15075
  }
14476
15076
  }
14477
15077
  }
15078
+ JSXOpeningElement.prototype.includeNode = onlyIncludeSelf;
14478
15079
 
14479
15080
  class JSXOpeningFragment extends NodeBase {
14480
15081
  constructor() {
@@ -14482,22 +15083,22 @@ class JSXOpeningFragment extends NodeBase {
14482
15083
  this.fragment = null;
14483
15084
  this.fragmentVariable = null;
14484
15085
  }
14485
- include(context, includeChildrenRecursively) {
14486
- if (!this.included) {
14487
- const jsx = this.scope.context.options.jsx;
14488
- if (jsx.mode === 'automatic') {
14489
- this.fragment = 'Fragment';
14490
- this.fragmentVariable = getAndIncludeFactoryVariable('Fragment', false, jsx.jsxImportSource, this);
14491
- }
14492
- else {
14493
- const { fragment, importSource, mode } = jsx;
14494
- if (fragment != null) {
14495
- this.fragment = fragment;
14496
- this.fragmentVariable = getAndIncludeFactoryVariable(fragment, mode === 'preserve', importSource, this);
14497
- }
15086
+ includeNode(context) {
15087
+ this.included = true;
15088
+ if (!this.deoptimized)
15089
+ this.applyDeoptimizations();
15090
+ const jsx = this.scope.context.options.jsx;
15091
+ if (jsx.mode === 'automatic') {
15092
+ this.fragment = 'Fragment';
15093
+ this.fragmentVariable = getAndIncludeFactoryVariable('Fragment', false, jsx.jsxImportSource, this, context);
15094
+ }
15095
+ else {
15096
+ const { fragment, importSource, mode } = jsx;
15097
+ if (fragment != null) {
15098
+ this.fragment = fragment;
15099
+ this.fragmentVariable = getAndIncludeFactoryVariable(fragment, mode === 'preserve', importSource, this, context);
14498
15100
  }
14499
15101
  }
14500
- super.include(context, includeChildrenRecursively);
14501
15102
  }
14502
15103
  render(code, options) {
14503
15104
  const { mode } = this.scope.context.options.jsx;
@@ -14534,6 +15135,7 @@ class JSXText extends NodeBase {
14534
15135
  }
14535
15136
  }
14536
15137
  }
15138
+ JSXText.prototype.includeNode = onlyIncludeSelf;
14537
15139
 
14538
15140
  class LabeledStatement extends NodeBase {
14539
15141
  hasEffects(context) {
@@ -14555,17 +15157,22 @@ class LabeledStatement extends NodeBase {
14555
15157
  return bodyHasEffects;
14556
15158
  }
14557
15159
  include(context, includeChildrenRecursively) {
14558
- this.included = true;
15160
+ if (!this.included)
15161
+ this.includeNode(context);
14559
15162
  const { brokenFlow, includedLabels } = context;
14560
15163
  context.includedLabels = new Set();
14561
15164
  this.body.include(context, includeChildrenRecursively);
14562
15165
  if (includeChildrenRecursively || context.includedLabels.has(this.label.name)) {
14563
- this.label.include();
15166
+ this.label.include(context);
14564
15167
  context.includedLabels.delete(this.label.name);
14565
15168
  context.brokenFlow = brokenFlow;
14566
15169
  }
14567
15170
  context.includedLabels = new Set([...includedLabels, ...context.includedLabels]);
14568
15171
  }
15172
+ includeNode(context) {
15173
+ this.included = true;
15174
+ this.body.includePath(UNKNOWN_PATH, context);
15175
+ }
14569
15176
  render(code, options) {
14570
15177
  if (this.label.included) {
14571
15178
  this.label.render(code, options);
@@ -14576,6 +15183,7 @@ class LabeledStatement extends NodeBase {
14576
15183
  this.body.render(code, options);
14577
15184
  }
14578
15185
  }
15186
+ LabeledStatement.prototype.applyDeoptimizations = doNotDeoptimize;
14579
15187
 
14580
15188
  class LogicalExpression extends NodeBase {
14581
15189
  constructor() {
@@ -14592,10 +15200,10 @@ class LogicalExpression extends NodeBase {
14592
15200
  this.flags = setFlag(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */, value);
14593
15201
  }
14594
15202
  get hasDeoptimizedCache() {
14595
- return isFlagSet(this.flags, 16777216 /* Flag.hasDeoptimizedCache */);
15203
+ return isFlagSet(this.flags, 33554432 /* Flag.hasDeoptimizedCache */);
14596
15204
  }
14597
15205
  set hasDeoptimizedCache(value) {
14598
- this.flags = setFlag(this.flags, 16777216 /* Flag.hasDeoptimizedCache */, value);
15206
+ this.flags = setFlag(this.flags, 33554432 /* Flag.hasDeoptimizedCache */, value);
14599
15207
  }
14600
15208
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
14601
15209
  this.left.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -14608,6 +15216,10 @@ class LogicalExpression extends NodeBase {
14608
15216
  const unusedBranch = this.usedBranch === this.left ? this.right : this.left;
14609
15217
  this.usedBranch = null;
14610
15218
  unusedBranch.deoptimizePath(UNKNOWN_PATH);
15219
+ if (this.included) {
15220
+ // As we are not tracking inclusions, we just include everything
15221
+ unusedBranch.includePath(UNKNOWN_PATH, createInclusionContext());
15222
+ }
14611
15223
  }
14612
15224
  const { scope: { context }, expressionsToBeDeoptimized } = this;
14613
15225
  this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;
@@ -14653,16 +15265,17 @@ class LogicalExpression extends NodeBase {
14653
15265
  }
14654
15266
  getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
14655
15267
  const usedBranch = this.getUsedBranch();
14656
- if (!usedBranch)
14657
- return [
14658
- new MultiExpression([
14659
- this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
14660
- this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
14661
- ]),
14662
- false
14663
- ];
14664
- this.expressionsToBeDeoptimized.push(origin);
14665
- return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
15268
+ if (usedBranch) {
15269
+ this.expressionsToBeDeoptimized.push(origin);
15270
+ return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
15271
+ }
15272
+ return [
15273
+ new MultiExpression([
15274
+ this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],
15275
+ this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]
15276
+ ]),
15277
+ false
15278
+ ];
14666
15279
  }
14667
15280
  hasEffects(context) {
14668
15281
  if (this.left.hasEffects(context)) {
@@ -14675,18 +15288,18 @@ class LogicalExpression extends NodeBase {
14675
15288
  }
14676
15289
  hasEffectsOnInteractionAtPath(path, interaction, context) {
14677
15290
  const usedBranch = this.getUsedBranch();
14678
- if (!usedBranch) {
14679
- return (this.left.hasEffectsOnInteractionAtPath(path, interaction, context) ||
14680
- this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
15291
+ if (usedBranch) {
15292
+ return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
14681
15293
  }
14682
- return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
15294
+ return (this.left.hasEffectsOnInteractionAtPath(path, interaction, context) ||
15295
+ this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
14683
15296
  }
14684
15297
  include(context, includeChildrenRecursively) {
14685
15298
  this.included = true;
14686
15299
  const usedBranch = this.getUsedBranch();
14687
15300
  if (includeChildrenRecursively ||
14688
- (usedBranch === this.right && this.left.shouldBeIncluded(context)) ||
14689
- !usedBranch) {
15301
+ !usedBranch ||
15302
+ (usedBranch === this.right && this.left.shouldBeIncluded(context))) {
14690
15303
  this.left.include(context, includeChildrenRecursively);
14691
15304
  this.right.include(context, includeChildrenRecursively);
14692
15305
  }
@@ -14694,6 +15307,17 @@ class LogicalExpression extends NodeBase {
14694
15307
  usedBranch.include(context, includeChildrenRecursively);
14695
15308
  }
14696
15309
  }
15310
+ includePath(path, context) {
15311
+ this.included = true;
15312
+ const usedBranch = this.getUsedBranch();
15313
+ if (!usedBranch || (usedBranch === this.right && this.left.shouldBeIncluded(context))) {
15314
+ this.left.includePath(path, context);
15315
+ this.right.includePath(path, context);
15316
+ }
15317
+ else {
15318
+ usedBranch.includePath(path, context);
15319
+ }
15320
+ }
14697
15321
  removeAnnotations(code) {
14698
15322
  this.left.removeAnnotations(code);
14699
15323
  }
@@ -14746,6 +15370,8 @@ class LogicalExpression extends NodeBase {
14746
15370
  return this.usedBranch;
14747
15371
  }
14748
15372
  }
15373
+ LogicalExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
15374
+ LogicalExpression.prototype.applyDeoptimizations = doNotDeoptimize;
14749
15375
 
14750
15376
  class NewExpression extends NodeBase {
14751
15377
  hasEffects(context) {
@@ -14765,16 +15391,21 @@ class NewExpression extends NodeBase {
14765
15391
  return path.length > 0 || type !== INTERACTION_ACCESSED;
14766
15392
  }
14767
15393
  include(context, includeChildrenRecursively) {
14768
- if (!this.deoptimized)
14769
- this.applyDeoptimizations();
14770
15394
  if (includeChildrenRecursively) {
14771
15395
  super.include(context, includeChildrenRecursively);
14772
15396
  }
14773
15397
  else {
14774
- this.included = true;
15398
+ if (!this.included)
15399
+ this.includeNode(context);
14775
15400
  this.callee.include(context, false);
14776
15401
  }
14777
- this.callee.includeCallArguments(context, this.arguments);
15402
+ this.callee.includeCallArguments(context, this.interaction);
15403
+ }
15404
+ includeNode(context) {
15405
+ this.included = true;
15406
+ if (!this.deoptimized)
15407
+ this.applyDeoptimizations();
15408
+ this.callee.includePath(UNKNOWN_PATH, context);
14778
15409
  }
14779
15410
  initialise() {
14780
15411
  super.initialise();
@@ -14803,6 +15434,7 @@ class ObjectExpression extends NodeBase {
14803
15434
  constructor() {
14804
15435
  super(...arguments);
14805
15436
  this.objectEntity = null;
15437
+ this.protoProp = null;
14806
15438
  }
14807
15439
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
14808
15440
  this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);
@@ -14822,15 +15454,43 @@ class ObjectExpression extends NodeBase {
14822
15454
  hasEffectsOnInteractionAtPath(path, interaction, context) {
14823
15455
  return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
14824
15456
  }
15457
+ include(context, includeChildrenRecursively) {
15458
+ if (!this.included)
15459
+ this.includeNode(context);
15460
+ this.getObjectEntity().include(context, includeChildrenRecursively);
15461
+ this.protoProp?.include(context, includeChildrenRecursively);
15462
+ }
15463
+ includeNode(context) {
15464
+ this.included = true;
15465
+ this.protoProp?.includePath(UNKNOWN_PATH, context);
15466
+ }
15467
+ includePath(path, context) {
15468
+ if (!this.included)
15469
+ this.includeNode(context);
15470
+ this.getObjectEntity().includePath(path, context);
15471
+ }
14825
15472
  render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {
14826
- super.render(code, options);
14827
15473
  if (renderedSurroundingElement === parseAst_js.ExpressionStatement ||
14828
15474
  renderedSurroundingElement === parseAst_js.ArrowFunctionExpression) {
14829
15475
  code.appendRight(this.start, '(');
14830
15476
  code.prependLeft(this.end, ')');
14831
15477
  }
15478
+ if (this.properties.length > 0) {
15479
+ const separatedNodes = getCommaSeparatedNodesWithBoundaries(this.properties, code, this.start + 1, this.end - 1);
15480
+ let lastSeparatorPos = null;
15481
+ for (const { node, separator, start, end } of separatedNodes) {
15482
+ if (!node.included) {
15483
+ treeshakeNode(node, code, start, end);
15484
+ continue;
15485
+ }
15486
+ lastSeparatorPos = separator;
15487
+ node.render(code, options);
15488
+ }
15489
+ if (lastSeparatorPos) {
15490
+ code.remove(lastSeparatorPos, this.end - 1);
15491
+ }
15492
+ }
14832
15493
  }
14833
- applyDeoptimizations() { }
14834
15494
  getObjectEntity() {
14835
15495
  if (this.objectEntity !== null) {
14836
15496
  return this.objectEntity;
@@ -14859,6 +15519,7 @@ class ObjectExpression extends NodeBase {
14859
15519
  ? property.key.name
14860
15520
  : String(property.key.value);
14861
15521
  if (key === '__proto__' && property.kind === 'init') {
15522
+ this.protoProp = property;
14862
15523
  prototype =
14863
15524
  property.value instanceof Literal && property.value.value === null
14864
15525
  ? null
@@ -14871,6 +15532,7 @@ class ObjectExpression extends NodeBase {
14871
15532
  return (this.objectEntity = new ObjectEntity(properties, prototype));
14872
15533
  }
14873
15534
  }
15535
+ ObjectExpression.prototype.applyDeoptimizations = doNotDeoptimize;
14874
15536
 
14875
15537
  class PanicError extends NodeBase {
14876
15538
  initialise() {
@@ -14897,6 +15559,7 @@ class ParseError extends NodeBase {
14897
15559
 
14898
15560
  class PrivateIdentifier extends NodeBase {
14899
15561
  }
15562
+ PrivateIdentifier.prototype.includeNode = onlyIncludeSelf;
14900
15563
 
14901
15564
  class Program extends NodeBase {
14902
15565
  constructor() {
@@ -14964,14 +15627,11 @@ class Program extends NodeBase {
14964
15627
  super.render(code, options);
14965
15628
  }
14966
15629
  }
14967
- applyDeoptimizations() { }
14968
15630
  }
15631
+ Program.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
15632
+ Program.prototype.applyDeoptimizations = doNotDeoptimize;
14969
15633
 
14970
15634
  class Property extends MethodBase {
14971
- constructor() {
14972
- super(...arguments);
14973
- this.declarationInit = null;
14974
- }
14975
15635
  //declare method: boolean;
14976
15636
  get method() {
14977
15637
  return isFlagSet(this.flags, 262144 /* Flag.method */);
@@ -14986,17 +15646,41 @@ class Property extends MethodBase {
14986
15646
  set shorthand(value) {
14987
15647
  this.flags = setFlag(this.flags, 524288 /* Flag.shorthand */, value);
14988
15648
  }
14989
- declare(kind, init) {
14990
- this.declarationInit = init;
14991
- return this.value.declare(kind, UNKNOWN_EXPRESSION);
15649
+ declare(kind, destructuredInitPath, init) {
15650
+ return this.value.declare(kind, this.getPathInProperty(destructuredInitPath), init);
15651
+ }
15652
+ deoptimizeAssignment(destructuredInitPath, init) {
15653
+ this.value.deoptimizeAssignment?.(this.getPathInProperty(destructuredInitPath), init);
14992
15654
  }
14993
15655
  hasEffects(context) {
14994
- if (!this.deoptimized)
14995
- this.applyDeoptimizations();
14996
- const propertyReadSideEffects = this.scope.context.options.treeshake.propertyReadSideEffects;
14997
- return ((this.parent.type === 'ObjectPattern' && propertyReadSideEffects === 'always') ||
14998
- this.key.hasEffects(context) ||
14999
- this.value.hasEffects(context));
15656
+ return this.key.hasEffects(context) || this.value.hasEffects(context);
15657
+ }
15658
+ hasEffectsWhenDestructuring(context, destructuredInitPath, init) {
15659
+ return this.value.hasEffectsWhenDestructuring?.(context, this.getPathInProperty(destructuredInitPath), init);
15660
+ }
15661
+ includeDestructuredIfNecessary(context, destructuredInitPath, init) {
15662
+ const path = this.getPathInProperty(destructuredInitPath);
15663
+ let included = this.value.includeDestructuredIfNecessary(context, path, init) ||
15664
+ this.included;
15665
+ if ((included ||= this.key.hasEffects(createHasEffectsContext()))) {
15666
+ this.key.include(context, false);
15667
+ if (!this.value.included) {
15668
+ this.value.included = true;
15669
+ // Unfortunately, we need to include the value again now, so that any
15670
+ // declared variables are properly included.
15671
+ this.value.includeDestructuredIfNecessary(context, path, init);
15672
+ }
15673
+ }
15674
+ return (this.included = included);
15675
+ }
15676
+ include(context, includeChildrenRecursively) {
15677
+ this.included = true;
15678
+ this.key.include(context, includeChildrenRecursively);
15679
+ this.value.include(context, includeChildrenRecursively);
15680
+ }
15681
+ includePath(path, context) {
15682
+ this.included = true;
15683
+ this.value.includePath(path, context);
15000
15684
  }
15001
15685
  markDeclarationReached() {
15002
15686
  this.value.markDeclarationReached();
@@ -15007,14 +15691,20 @@ class Property extends MethodBase {
15007
15691
  }
15008
15692
  this.value.render(code, options, { isShorthandProperty: this.shorthand });
15009
15693
  }
15010
- applyDeoptimizations() {
15011
- this.deoptimized = true;
15012
- if (this.declarationInit !== null) {
15013
- this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
15014
- this.scope.context.requestTreeshakingPass();
15015
- }
15694
+ getPathInProperty(destructuredInitPath) {
15695
+ return destructuredInitPath.at(-1) === UnknownKey
15696
+ ? destructuredInitPath
15697
+ : // For now, we only consider static paths as we do not know how to
15698
+ // deoptimize the path in the dynamic case.
15699
+ this.computed
15700
+ ? [...destructuredInitPath, UnknownKey]
15701
+ : this.key instanceof Identifier
15702
+ ? [...destructuredInitPath, this.key.name]
15703
+ : [...destructuredInitPath, String(this.key.value)];
15016
15704
  }
15017
15705
  }
15706
+ Property.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
15707
+ Property.prototype.applyDeoptimizations = doNotDeoptimize;
15018
15708
 
15019
15709
  class PropertyDefinition extends NodeBase {
15020
15710
  get computed() {
@@ -15047,8 +15737,15 @@ class PropertyDefinition extends NodeBase {
15047
15737
  hasEffectsOnInteractionAtPath(path, interaction, context) {
15048
15738
  return !this.value || this.value.hasEffectsOnInteractionAtPath(path, interaction, context);
15049
15739
  }
15050
- applyDeoptimizations() { }
15740
+ includeNode(context) {
15741
+ this.included = true;
15742
+ this.value?.includePath(UNKNOWN_PATH, context);
15743
+ for (const decorator of this.decorators) {
15744
+ decorator.includePath(UNKNOWN_PATH, context);
15745
+ }
15746
+ }
15051
15747
  }
15748
+ PropertyDefinition.prototype.applyDeoptimizations = doNotDeoptimize;
15052
15749
 
15053
15750
  class ReturnStatement extends NodeBase {
15054
15751
  hasEffects(context) {
@@ -15058,10 +15755,15 @@ class ReturnStatement extends NodeBase {
15058
15755
  return false;
15059
15756
  }
15060
15757
  include(context, includeChildrenRecursively) {
15061
- this.included = true;
15758
+ if (!this.included)
15759
+ this.includeNode(context);
15062
15760
  this.argument?.include(context, includeChildrenRecursively);
15063
15761
  context.brokenFlow = true;
15064
15762
  }
15763
+ includeNode(context) {
15764
+ this.included = true;
15765
+ this.argument?.includePath(UNKNOWN_PATH, context);
15766
+ }
15065
15767
  initialise() {
15066
15768
  super.initialise();
15067
15769
  this.scope.addReturnExpression(this.argument || UNKNOWN_EXPRESSION);
@@ -15075,6 +15777,7 @@ class ReturnStatement extends NodeBase {
15075
15777
  }
15076
15778
  }
15077
15779
  }
15780
+ ReturnStatement.prototype.applyDeoptimizations = doNotDeoptimize;
15078
15781
 
15079
15782
  class SequenceExpression extends NodeBase {
15080
15783
  deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {
@@ -15102,10 +15805,15 @@ class SequenceExpression extends NodeBase {
15102
15805
  for (const expression of this.expressions) {
15103
15806
  if (includeChildrenRecursively ||
15104
15807
  (expression === lastExpression && !(this.parent instanceof ExpressionStatement)) ||
15105
- expression.shouldBeIncluded(context))
15808
+ expression.shouldBeIncluded(context)) {
15106
15809
  expression.include(context, includeChildrenRecursively);
15810
+ }
15107
15811
  }
15108
15812
  }
15813
+ includePath(path, context) {
15814
+ this.included = true;
15815
+ this.expressions[this.expressions.length - 1].includePath(path, context);
15816
+ }
15109
15817
  removeAnnotations(code) {
15110
15818
  this.expressions[0].removeAnnotations(code);
15111
15819
  }
@@ -15140,6 +15848,8 @@ class SequenceExpression extends NodeBase {
15140
15848
  }
15141
15849
  }
15142
15850
  }
15851
+ SequenceExpression.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
15852
+ SequenceExpression.prototype.applyDeoptimizations = doNotDeoptimize;
15143
15853
 
15144
15854
  class Super extends NodeBase {
15145
15855
  bind() {
@@ -15151,11 +15861,15 @@ class Super extends NodeBase {
15151
15861
  deoptimizePath(path) {
15152
15862
  this.variable.deoptimizePath(path);
15153
15863
  }
15154
- include() {
15155
- if (!this.included) {
15156
- this.included = true;
15157
- this.scope.context.includeVariableInModule(this.variable);
15158
- }
15864
+ include(context) {
15865
+ if (!this.included)
15866
+ this.includeNode(context);
15867
+ }
15868
+ includeNode(context) {
15869
+ this.included = true;
15870
+ if (!this.deoptimized)
15871
+ this.applyDeoptimizations();
15872
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
15159
15873
  }
15160
15874
  }
15161
15875
 
@@ -15196,6 +15910,8 @@ class SwitchCase extends NodeBase {
15196
15910
  }
15197
15911
  }
15198
15912
  SwitchCase.prototype.needsBoundaries = true;
15913
+ SwitchCase.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
15914
+ SwitchCase.prototype.applyDeoptimizations = doNotDeoptimize;
15199
15915
 
15200
15916
  class SwitchStatement extends NodeBase {
15201
15917
  createScope(parentScope) {
@@ -15278,6 +15994,8 @@ class SwitchStatement extends NodeBase {
15278
15994
  }
15279
15995
  }
15280
15996
  }
15997
+ SwitchStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
15998
+ SwitchStatement.prototype.applyDeoptimizations = doNotDeoptimize;
15281
15999
 
15282
16000
  class TaggedTemplateExpression extends CallExpressionBase {
15283
16001
  bind() {
@@ -15301,8 +16019,8 @@ class TaggedTemplateExpression extends CallExpressionBase {
15301
16019
  this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
15302
16020
  }
15303
16021
  include(context, includeChildrenRecursively) {
15304
- if (!this.deoptimized)
15305
- this.applyDeoptimizations();
16022
+ if (!this.included)
16023
+ this.includeNode(context);
15306
16024
  if (includeChildrenRecursively) {
15307
16025
  super.include(context, includeChildrenRecursively);
15308
16026
  }
@@ -15311,7 +16029,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
15311
16029
  this.tag.include(context, includeChildrenRecursively);
15312
16030
  this.quasi.include(context, includeChildrenRecursively);
15313
16031
  }
15314
- this.tag.includeCallArguments(context, this.args);
16032
+ this.tag.includeCallArguments(context, this.interaction);
15315
16033
  const [returnExpression] = this.getReturnExpression();
15316
16034
  if (!returnExpression.included) {
15317
16035
  returnExpression.include(context, false);
@@ -15346,6 +16064,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
15346
16064
  return this.returnExpression;
15347
16065
  }
15348
16066
  }
16067
+ TaggedTemplateExpression.prototype.includeNode = onlyIncludeSelf;
15349
16068
 
15350
16069
  class TemplateElement extends NodeBase {
15351
16070
  get tail() {
@@ -15359,15 +16078,13 @@ class TemplateElement extends NodeBase {
15359
16078
  hasEffects() {
15360
16079
  return false;
15361
16080
  }
15362
- include() {
15363
- this.included = true;
15364
- }
15365
16081
  parseNode(esTreeNode) {
15366
16082
  this.value = esTreeNode.value;
15367
16083
  return super.parseNode(esTreeNode);
15368
16084
  }
15369
16085
  render() { }
15370
16086
  }
16087
+ TemplateElement.prototype.includeNode = onlyIncludeSelf;
15371
16088
 
15372
16089
  class TemplateLiteral extends NodeBase {
15373
16090
  deoptimizeArgumentsOnInteractionAtPath() { }
@@ -15392,6 +16109,14 @@ class TemplateLiteral extends NodeBase {
15392
16109
  }
15393
16110
  return true;
15394
16111
  }
16112
+ includeNode(context) {
16113
+ this.included = true;
16114
+ if (!this.deoptimized)
16115
+ this.applyDeoptimizations();
16116
+ for (const node of this.expressions) {
16117
+ node.includePath(UNKNOWN_PATH, context);
16118
+ }
16119
+ }
15395
16120
  render(code, options) {
15396
16121
  code.indentExclusionRanges.push([this.start, this.end]);
15397
16122
  super.render(code, options);
@@ -15401,13 +16126,13 @@ class TemplateLiteral extends NodeBase {
15401
16126
  class ModuleScope extends ChildScope {
15402
16127
  constructor(parent, context) {
15403
16128
  super(parent, context);
15404
- this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, context, 'other'));
16129
+ this.variables.set('this', new LocalVariable('this', null, UNDEFINED_EXPRESSION, EMPTY_PATH, context, 'other'));
15405
16130
  }
15406
- addDeclaration(identifier, context, init, kind) {
16131
+ addDeclaration(identifier, context, init, destructuredInitPath, kind) {
15407
16132
  if (this.context.module.importDescriptions.has(identifier.name)) {
15408
16133
  context.error(parseAst_js.logRedeclarationError(identifier.name), identifier.start);
15409
16134
  }
15410
- return super.addDeclaration(identifier, context, init, kind);
16135
+ return super.addDeclaration(identifier, context, init, destructuredInitPath, kind);
15411
16136
  }
15412
16137
  addExportDefaultDeclaration(name, exportDefaultDeclaration, context) {
15413
16138
  const variable = new ExportDefaultVariable(name, exportDefaultDeclaration, context);
@@ -15452,10 +16177,23 @@ class ThisExpression extends NodeBase {
15452
16177
  }
15453
16178
  return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
15454
16179
  }
15455
- include() {
16180
+ include(context) {
16181
+ if (!this.included)
16182
+ this.includeNode(context);
16183
+ }
16184
+ includeNode(context) {
16185
+ this.included = true;
16186
+ if (!this.deoptimized)
16187
+ this.applyDeoptimizations();
16188
+ this.scope.context.includeVariableInModule(this.variable, EMPTY_PATH, context);
16189
+ }
16190
+ includePath(path, context) {
15456
16191
  if (!this.included) {
15457
16192
  this.included = true;
15458
- this.scope.context.includeVariableInModule(this.variable);
16193
+ this.scope.context.includeVariableInModule(this.variable, path, context);
16194
+ }
16195
+ else if (path.length > 0) {
16196
+ this.variable.includePath(path, context);
15459
16197
  }
15460
16198
  }
15461
16199
  initialise() {
@@ -15483,7 +16221,8 @@ class ThrowStatement extends NodeBase {
15483
16221
  return true;
15484
16222
  }
15485
16223
  include(context, includeChildrenRecursively) {
15486
- this.included = true;
16224
+ if (!this.included)
16225
+ this.includeNode(context);
15487
16226
  this.argument.include(context, includeChildrenRecursively);
15488
16227
  context.brokenFlow = true;
15489
16228
  }
@@ -15494,6 +16233,7 @@ class ThrowStatement extends NodeBase {
15494
16233
  }
15495
16234
  }
15496
16235
  }
16236
+ ThrowStatement.prototype.includeNode = onlyIncludeSelf;
15497
16237
 
15498
16238
  class TryStatement extends NodeBase {
15499
16239
  constructor() {
@@ -15530,6 +16270,8 @@ class TryStatement extends NodeBase {
15530
16270
  this.finalizer?.include(context, includeChildrenRecursively);
15531
16271
  }
15532
16272
  }
16273
+ TryStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
16274
+ TryStatement.prototype.applyDeoptimizations = doNotDeoptimize;
15533
16275
 
15534
16276
  const unaryOperators = {
15535
16277
  '!': value => !value,
@@ -15575,6 +16317,7 @@ class UnaryExpression extends NodeBase {
15575
16317
  }
15576
16318
  }
15577
16319
  }
16320
+ UnaryExpression.prototype.includeNode = onlyIncludeSelf;
15578
16321
 
15579
16322
  class UpdateExpression extends NodeBase {
15580
16323
  hasEffects(context) {
@@ -15586,9 +16329,8 @@ class UpdateExpression extends NodeBase {
15586
16329
  return path.length > 1 || type !== INTERACTION_ACCESSED;
15587
16330
  }
15588
16331
  include(context, includeChildrenRecursively) {
15589
- if (!this.deoptimized)
15590
- this.applyDeoptimizations();
15591
- this.included = true;
16332
+ if (!this.included)
16333
+ this.includeNode(context);
15592
16334
  this.argument.includeAsAssignmentTarget(context, includeChildrenRecursively, true);
15593
16335
  }
15594
16336
  initialise() {
@@ -15627,6 +16369,7 @@ class UpdateExpression extends NodeBase {
15627
16369
  this.scope.context.requestTreeshakingPass();
15628
16370
  }
15629
16371
  }
16372
+ UpdateExpression.prototype.includeNode = onlyIncludeSelf;
15630
16373
 
15631
16374
  function areAllDeclarationsIncludedAndNotExported(declarations, exportNamesByVariable) {
15632
16375
  for (const declarator of declarations) {
@@ -15657,8 +16400,9 @@ class VariableDeclaration extends NodeBase {
15657
16400
  include(context, includeChildrenRecursively, { asSingleStatement } = parseAst_js.BLANK) {
15658
16401
  this.included = true;
15659
16402
  for (const declarator of this.declarations) {
15660
- if (includeChildrenRecursively || declarator.shouldBeIncluded(context))
16403
+ if (includeChildrenRecursively || declarator.shouldBeIncluded(context)) {
15661
16404
  declarator.include(context, includeChildrenRecursively);
16405
+ }
15662
16406
  const { id, init } = declarator;
15663
16407
  if (asSingleStatement) {
15664
16408
  id.include(context, includeChildrenRecursively);
@@ -15696,7 +16440,6 @@ class VariableDeclaration extends NodeBase {
15696
16440
  this.renderReplacedDeclarations(code, options);
15697
16441
  }
15698
16442
  }
15699
- applyDeoptimizations() { }
15700
16443
  renderDeclarationEnd(code, separatorString, lastSeparatorPos, actualContentEnd, renderedContentEnd, systemPatternExports, options) {
15701
16444
  if (code.original.charCodeAt(this.end - 1) === 59 /*";"*/) {
15702
16445
  code.remove(this.end - 1, this.end);
@@ -15739,8 +16482,7 @@ class VariableDeclaration extends NodeBase {
15739
16482
  const singleSystemExport = gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregatedSystemExports);
15740
16483
  for (const { node, start, separator, contentEnd, end } of separatedNodes) {
15741
16484
  if (!node.included) {
15742
- code.remove(start, end);
15743
- node.removeAnnotations(code);
16485
+ treeshakeNode(node, code, start, end);
15744
16486
  continue;
15745
16487
  }
15746
16488
  node.render(code, options);
@@ -15810,6 +16552,8 @@ function gatherSystemExportsAndGetSingleExport(separatedNodes, options, aggregat
15810
16552
  }
15811
16553
  return singleSystemExport;
15812
16554
  }
16555
+ VariableDeclaration.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
16556
+ VariableDeclaration.prototype.applyDeoptimizations = doNotDeoptimize;
15813
16557
 
15814
16558
  class WhileStatement extends NodeBase {
15815
16559
  hasEffects(context) {
@@ -15823,13 +16567,25 @@ class WhileStatement extends NodeBase {
15823
16567
  includeLoopBody(context, this.body, includeChildrenRecursively);
15824
16568
  }
15825
16569
  }
16570
+ WhileStatement.prototype.includeNode = onlyIncludeSelfNoDeoptimize;
16571
+ WhileStatement.prototype.applyDeoptimizations = doNotDeoptimize;
15826
16572
 
15827
16573
  class YieldExpression extends NodeBase {
16574
+ applyDeoptimizations() {
16575
+ this.deoptimized = true;
16576
+ this.argument?.deoptimizePath(UNKNOWN_PATH);
16577
+ }
15828
16578
  hasEffects(context) {
15829
16579
  if (!this.deoptimized)
15830
16580
  this.applyDeoptimizations();
15831
16581
  return !(context.ignore.returnYield && !this.argument?.hasEffects(context));
15832
16582
  }
16583
+ includeNode(context) {
16584
+ this.included = true;
16585
+ if (!this.deoptimized)
16586
+ this.applyDeoptimizations();
16587
+ this.argument?.includePath(UNKNOWN_PATH, context);
16588
+ }
15833
16589
  render(code, options) {
15834
16590
  if (this.argument) {
15835
16591
  this.argument.render(code, options, { preventASI: true });
@@ -16063,7 +16819,7 @@ const bufferParsers = [
16063
16819
  const annotations = (node.annotations = parseAst_js.convertAnnotations(buffer[position + 1], buffer));
16064
16820
  node.annotationNoSideEffects = annotations.some(comment => comment.type === 'noSideEffects');
16065
16821
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 2], buffer));
16066
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
16822
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
16067
16823
  node.body = convertNode(node, scope.bodyScope, buffer[position + 3], buffer);
16068
16824
  },
16069
16825
  function assignmentExpression(node, position, buffer) {
@@ -16109,7 +16865,7 @@ const bufferParsers = [
16109
16865
  const parameterPosition = buffer[position];
16110
16866
  const parameter = (node.param =
16111
16867
  parameterPosition === 0 ? null : convertNode(node, scope, parameterPosition, buffer));
16112
- parameter?.declare('parameter', UNKNOWN_EXPRESSION);
16868
+ parameter?.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION);
16113
16869
  node.body = convertNode(node, scope.bodyScope, buffer[position + 1], buffer);
16114
16870
  },
16115
16871
  function chainExpression(node, position, buffer) {
@@ -16247,7 +17003,7 @@ const bufferParsers = [
16247
17003
  node.id =
16248
17004
  idPosition === 0 ? null : convertNode(node, scope.parent, idPosition, buffer);
16249
17005
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
16250
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
17006
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
16251
17007
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
16252
17008
  },
16253
17009
  function functionExpression(node, position, buffer) {
@@ -16260,7 +17016,7 @@ const bufferParsers = [
16260
17016
  const idPosition = buffer[position + 2];
16261
17017
  node.id = idPosition === 0 ? null : convertNode(node, node.idScope, idPosition, buffer);
16262
17018
  const parameters = (node.params = convertNodeList(node, scope, buffer[position + 3], buffer));
16263
- scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
17019
+ scope.addParameterVariables(parameters.map(parameter => parameter.declare('parameter', EMPTY_PATH, UNKNOWN_EXPRESSION)), parameters[parameters.length - 1] instanceof RestElement);
16264
17020
  node.body = convertNode(node, scope.bodyScope, buffer[position + 4], buffer);
16265
17021
  },
16266
17022
  function identifier(node, position, buffer) {
@@ -16724,8 +17480,8 @@ class ExportShimVariable extends Variable {
16724
17480
  super(MISSING_EXPORT_SHIM_VARIABLE);
16725
17481
  this.module = module;
16726
17482
  }
16727
- include() {
16728
- super.include();
17483
+ includePath(path, context) {
17484
+ super.includePath(path, context);
16729
17485
  this.module.needsExportShim = true;
16730
17486
  }
16731
17487
  }
@@ -17416,16 +18172,15 @@ class Module {
17416
18172
  markModuleAndImpureDependenciesAsExecuted(this);
17417
18173
  this.graph.needsTreeshakingPass = true;
17418
18174
  }
18175
+ const inclusionContext = createInclusionContext();
17419
18176
  for (const exportName of this.exports.keys()) {
17420
18177
  if (includeNamespaceMembers || exportName !== this.info.syntheticNamedExports) {
17421
18178
  const variable = this.getVariableForExportName(exportName)[0];
17422
18179
  if (!variable) {
17423
18180
  return parseAst_js.error(parseAst_js.logMissingEntryExport(exportName, this.id));
17424
18181
  }
18182
+ this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
17425
18183
  variable.deoptimizePath(UNKNOWN_PATH);
17426
- if (!variable.included) {
17427
- this.includeVariable(variable);
17428
- }
17429
18184
  }
17430
18185
  }
17431
18186
  for (const name of this.getReexports()) {
@@ -17433,7 +18188,7 @@ class Module {
17433
18188
  if (variable) {
17434
18189
  variable.deoptimizePath(UNKNOWN_PATH);
17435
18190
  if (!variable.included) {
17436
- this.includeVariable(variable);
18191
+ this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
17437
18192
  }
17438
18193
  if (variable instanceof ExternalVariable) {
17439
18194
  variable.module.reexported = true;
@@ -17454,13 +18209,12 @@ class Module {
17454
18209
  this.graph.needsTreeshakingPass = true;
17455
18210
  }
17456
18211
  let includeNamespaceMembers = false;
18212
+ const inclusionContext = createInclusionContext();
17457
18213
  for (const name of names) {
17458
18214
  const variable = this.getVariableForExportName(name)[0];
17459
18215
  if (variable) {
17460
18216
  variable.deoptimizePath(UNKNOWN_PATH);
17461
- if (!variable.included) {
17462
- this.includeVariable(variable);
17463
- }
18217
+ this.includeVariable(variable, UNKNOWN_PATH, inclusionContext);
17464
18218
  }
17465
18219
  if (!this.exports.has(name) && !this.reexportDescriptions.has(name)) {
17466
18220
  includeNamespaceMembers = true;
@@ -17561,6 +18315,7 @@ class Module {
17561
18315
  manualPureFunctions: this.graph.pureFunctions,
17562
18316
  module: this,
17563
18317
  moduleContext: this.context,
18318
+ newlyIncludedVariableInits: this.graph.newlyIncludedVariableInits,
17564
18319
  options: this.options,
17565
18320
  requestTreeshakingPass: () => (this.graph.needsTreeshakingPass = true),
17566
18321
  traceExport: (name) => this.getVariableForExportName(name)[0],
@@ -17901,13 +18656,13 @@ class Module {
17901
18656
  for (const module of [this, ...this.exportAllModules]) {
17902
18657
  if (module instanceof ExternalModule) {
17903
18658
  const [externalVariable] = module.getVariableForExportName('*');
17904
- externalVariable.include();
18659
+ externalVariable.includePath(UNKNOWN_PATH, createInclusionContext());
17905
18660
  this.includedImports.add(externalVariable);
17906
18661
  externalNamespaces.add(externalVariable);
17907
18662
  }
17908
18663
  else if (module.info.syntheticNamedExports) {
17909
18664
  const syntheticNamespace = module.getSyntheticNamespace();
17910
- syntheticNamespace.include();
18665
+ syntheticNamespace.includePath(UNKNOWN_PATH, createInclusionContext());
17911
18666
  this.includedImports.add(syntheticNamespace);
17912
18667
  syntheticNamespaces.add(syntheticNamespace);
17913
18668
  }
@@ -17917,7 +18672,9 @@ class Module {
17917
18672
  includeDynamicImport(node) {
17918
18673
  const resolution = this.dynamicImports.find(dynamicImport => dynamicImport.node === node).resolution;
17919
18674
  if (resolution instanceof Module) {
17920
- resolution.includedDynamicImporters.push(this);
18675
+ if (!resolution.includedDynamicImporters.includes(this)) {
18676
+ resolution.includedDynamicImporters.push(this);
18677
+ }
17921
18678
  const importedNames = this.options.treeshake
17922
18679
  ? node.getDeterministicImportedNames()
17923
18680
  : undefined;
@@ -17929,15 +18686,15 @@ class Module {
17929
18686
  }
17930
18687
  }
17931
18688
  }
17932
- includeVariable(variable) {
17933
- const variableModule = variable.module;
17934
- if (variable.included) {
18689
+ includeVariable(variable, path, context) {
18690
+ const { included, module: variableModule } = variable;
18691
+ variable.includePath(path, context);
18692
+ if (included) {
17935
18693
  if (variableModule instanceof Module && variableModule !== this) {
17936
18694
  getAndExtendSideEffectModules(variable, this);
17937
18695
  }
17938
18696
  }
17939
18697
  else {
17940
- variable.include();
17941
18698
  this.graph.needsTreeshakingPass = true;
17942
18699
  if (variableModule instanceof Module) {
17943
18700
  if (!variableModule.isExecuted) {
@@ -17954,8 +18711,8 @@ class Module {
17954
18711
  }
17955
18712
  }
17956
18713
  }
17957
- includeVariableInModule(variable) {
17958
- this.includeVariable(variable);
18714
+ includeVariableInModule(variable, path, context) {
18715
+ this.includeVariable(variable, path, context);
17959
18716
  const variableModule = variable.module;
17960
18717
  if (variableModule && variableModule !== this) {
17961
18718
  this.includedImports.add(variable);
@@ -21458,10 +22215,11 @@ class Graph {
21458
22215
  this.options = options;
21459
22216
  this.astLru = flru(5);
21460
22217
  this.cachedModules = new Map();
21461
- this.deoptimizationTracker = new PathTracker();
22218
+ this.deoptimizationTracker = new EntityPathTracker();
21462
22219
  this.entryModules = [];
21463
22220
  this.modulesById = new Map();
21464
22221
  this.needsTreeshakingPass = false;
22222
+ this.newlyIncludedVariableInits = new Set();
21465
22223
  this.phase = BuildPhase.LOAD_AND_PARSE;
21466
22224
  this.scope = new GlobalScope();
21467
22225
  this.watchFiles = Object.create(null);
@@ -21555,6 +22313,7 @@ class Graph {
21555
22313
  }
21556
22314
  if (this.options.treeshake) {
21557
22315
  let treeshakingPass = 1;
22316
+ this.newlyIncludedVariableInits.clear();
21558
22317
  do {
21559
22318
  timeStart(`treeshaking pass ${treeshakingPass}`, 3);
21560
22319
  this.needsTreeshakingPass = false;
@@ -21579,6 +22338,10 @@ class Graph {
21579
22338
  }
21580
22339
  }
21581
22340
  }
22341
+ for (const entity of this.newlyIncludedVariableInits) {
22342
+ this.newlyIncludedVariableInits.delete(entity);
22343
+ entity.include(createInclusionContext(), false);
22344
+ }
21582
22345
  timeEnd(`treeshaking pass ${treeshakingPass++}`, 3);
21583
22346
  } while (this.needsTreeshakingPass);
21584
22347
  }