rollup 2.75.4 → 2.75.7

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 v2.75.4
4
- Tue, 31 May 2022 11:26:29 GMT - commit 0409bf0d8859a43f2d5d40dc23ebf74afadb83f7
3
+ Rollup.js v2.75.7
4
+ Mon, 20 Jun 2022 07:24:02 GMT - commit 057171c2d3bc2092b7f543fc05ead01f12595f12
5
5
 
6
6
  https://github.com/rollup/rollup
7
7
 
@@ -14,7 +14,7 @@ import { createHash as createHash$1 } from 'crypto';
14
14
  import { promises } from 'fs';
15
15
  import { EventEmitter } from 'events';
16
16
 
17
- var version$1 = "2.75.4";
17
+ var version$1 = "2.75.7";
18
18
 
19
19
  var charToInteger = {};
20
20
  var chars$1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
@@ -1593,10 +1593,9 @@ class ExpressionEntity {
1593
1593
  constructor() {
1594
1594
  this.included = false;
1595
1595
  }
1596
- deoptimizeCallParameters() { }
1597
1596
  deoptimizePath(_path) { }
1598
- deoptimizeThisOnEventAtPath(_event, _path, thisParameter, _recursionTracker) {
1599
- thisParameter.deoptimizePath(UNKNOWN_PATH);
1597
+ deoptimizeThisOnInteractionAtPath({ thisArg }, _path, _recursionTracker) {
1598
+ thisArg.deoptimizePath(UNKNOWN_PATH);
1600
1599
  }
1601
1600
  /**
1602
1601
  * If possible it returns a stringifyable literal value for this node that can be used
@@ -1606,16 +1605,10 @@ class ExpressionEntity {
1606
1605
  getLiteralValueAtPath(_path, _recursionTracker, _origin) {
1607
1606
  return UnknownValue;
1608
1607
  }
1609
- getReturnExpressionWhenCalledAtPath(_path, _callOptions, _recursionTracker, _origin) {
1608
+ getReturnExpressionWhenCalledAtPath(_path, _interaction, _recursionTracker, _origin) {
1610
1609
  return UNKNOWN_EXPRESSION;
1611
1610
  }
1612
- hasEffectsWhenAccessedAtPath(_path, _context) {
1613
- return true;
1614
- }
1615
- hasEffectsWhenAssignedAtPath(_path, _context) {
1616
- return true;
1617
- }
1618
- hasEffectsWhenCalledAtPath(_path, _callOptions, _context) {
1611
+ hasEffectsOnInteractionAtPath(_path, _interaction, _context) {
1619
1612
  return true;
1620
1613
  }
1621
1614
  include(_context, _includeChildrenRecursively, _options) {
@@ -1633,6 +1626,30 @@ class ExpressionEntity {
1633
1626
  const UNKNOWN_EXPRESSION = new (class UnknownExpression extends ExpressionEntity {
1634
1627
  })();
1635
1628
 
1629
+ const INTERACTION_ACCESSED = 0;
1630
+ const INTERACTION_ASSIGNED = 1;
1631
+ const INTERACTION_CALLED = 2;
1632
+ const NODE_INTERACTION_UNKNOWN_ACCESS = {
1633
+ thisArg: null,
1634
+ type: INTERACTION_ACCESSED
1635
+ };
1636
+ const UNKNOWN_ARG = [UNKNOWN_EXPRESSION];
1637
+ const NODE_INTERACTION_UNKNOWN_ASSIGNMENT = {
1638
+ args: UNKNOWN_ARG,
1639
+ thisArg: null,
1640
+ type: INTERACTION_ASSIGNED
1641
+ };
1642
+ const NO_ARGS = [];
1643
+ // While this is technically a call without arguments, we can compare against
1644
+ // this reference in places where precise values or thisArg would make a
1645
+ // difference
1646
+ const NODE_INTERACTION_UNKNOWN_CALL = {
1647
+ args: NO_ARGS,
1648
+ thisArg: null,
1649
+ type: INTERACTION_CALLED,
1650
+ withNew: false
1651
+ };
1652
+
1636
1653
  class Variable extends ExpressionEntity {
1637
1654
  constructor(name) {
1638
1655
  super();
@@ -1657,8 +1674,8 @@ class Variable extends ExpressionEntity {
1657
1674
  const name = this.renderName || this.name;
1658
1675
  return this.renderBaseName ? `${this.renderBaseName}${getPropertyAccess(name)}` : name;
1659
1676
  }
1660
- hasEffectsWhenAccessedAtPath(path, _context) {
1661
- return path.length > 0;
1677
+ hasEffectsOnInteractionAtPath(path, { type }, _context) {
1678
+ return type !== INTERACTION_ACCESSED || path.length > 0;
1662
1679
  }
1663
1680
  /**
1664
1681
  * Marks this variable as being part of the bundle, which is usually the case when one of
@@ -1689,8 +1706,8 @@ class ExternalVariable extends Variable {
1689
1706
  this.module.suggestName(identifier.name);
1690
1707
  }
1691
1708
  }
1692
- hasEffectsWhenAccessedAtPath(path) {
1693
- return path.length > (this.isNamespace ? 1 : 0);
1709
+ hasEffectsOnInteractionAtPath(path, { type }) {
1710
+ return type !== INTERACTION_ACCESSED || path.length > (this.isNamespace ? 1 : 0);
1694
1711
  }
1695
1712
  include() {
1696
1713
  if (!this.included) {
@@ -4580,8 +4597,6 @@ function createHasEffectsContext() {
4580
4597
  };
4581
4598
  }
4582
4599
 
4583
- const NO_ARGS = [];
4584
-
4585
4600
  function assembleMemberDescriptions(memberDescriptions, inheritedDescriptions = null) {
4586
4601
  return Object.create(inheritedDescriptions, memberDescriptions);
4587
4602
  }
@@ -4603,12 +4618,12 @@ const UNKNOWN_LITERAL_BOOLEAN = new (class UnknownBoolean extends ExpressionEnti
4603
4618
  }
4604
4619
  return UNKNOWN_EXPRESSION;
4605
4620
  }
4606
- hasEffectsWhenAccessedAtPath(path) {
4607
- return path.length > 1;
4608
- }
4609
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
4610
- if (path.length === 1) {
4611
- return hasMemberEffectWhenCalled(literalBooleanMembers, path[0], callOptions, context);
4621
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
4622
+ if (interaction.type === INTERACTION_ACCESSED) {
4623
+ return path.length > 1;
4624
+ }
4625
+ if (interaction.type === INTERACTION_CALLED && path.length === 1) {
4626
+ return hasMemberEffectWhenCalled(literalBooleanMembers, path[0], interaction, context);
4612
4627
  }
4613
4628
  return true;
4614
4629
  }
@@ -4626,12 +4641,12 @@ const UNKNOWN_LITERAL_NUMBER = new (class UnknownNumber extends ExpressionEntity
4626
4641
  }
4627
4642
  return UNKNOWN_EXPRESSION;
4628
4643
  }
4629
- hasEffectsWhenAccessedAtPath(path) {
4630
- return path.length > 1;
4631
- }
4632
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
4633
- if (path.length === 1) {
4634
- return hasMemberEffectWhenCalled(literalNumberMembers, path[0], callOptions, context);
4644
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
4645
+ if (interaction.type === INTERACTION_ACCESSED) {
4646
+ return path.length > 1;
4647
+ }
4648
+ if (interaction.type === INTERACTION_CALLED && path.length === 1) {
4649
+ return hasMemberEffectWhenCalled(literalNumberMembers, path[0], interaction, context);
4635
4650
  }
4636
4651
  return true;
4637
4652
  }
@@ -4649,12 +4664,12 @@ const UNKNOWN_LITERAL_STRING = new (class UnknownString extends ExpressionEntity
4649
4664
  }
4650
4665
  return UNKNOWN_EXPRESSION;
4651
4666
  }
4652
- hasEffectsWhenAccessedAtPath(path) {
4653
- return path.length > 1;
4654
- }
4655
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
4656
- if (path.length === 1) {
4657
- return hasMemberEffectWhenCalled(literalStringMembers, path[0], callOptions, context);
4667
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
4668
+ if (interaction.type === INTERACTION_ACCESSED) {
4669
+ return path.length > 1;
4670
+ }
4671
+ if (interaction.type === INTERACTION_CALLED && path.length === 1) {
4672
+ return hasMemberEffectWhenCalled(literalStringMembers, path[0], interaction, context);
4658
4673
  }
4659
4674
  return true;
4660
4675
  }
@@ -4667,17 +4682,13 @@ const returnsString = {
4667
4682
  };
4668
4683
  const stringReplace = {
4669
4684
  value: {
4670
- hasEffectsWhenCalled(callOptions, context) {
4671
- const arg1 = callOptions.args[1];
4672
- return (callOptions.args.length < 2 ||
4685
+ hasEffectsWhenCalled({ args }, context) {
4686
+ const arg1 = args[1];
4687
+ return (args.length < 2 ||
4673
4688
  (typeof arg1.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, {
4674
4689
  deoptimizeCache() { }
4675
4690
  }) === 'symbol' &&
4676
- arg1.hasEffectsWhenCalledAtPath(EMPTY_PATH, {
4677
- args: NO_ARGS,
4678
- thisParam: null,
4679
- withNew: false
4680
- }, context)));
4691
+ arg1.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context)));
4681
4692
  },
4682
4693
  returns: UNKNOWN_LITERAL_STRING
4683
4694
  }
@@ -4761,12 +4772,12 @@ function getLiteralMembersForValue(value) {
4761
4772
  }
4762
4773
  return Object.create(null);
4763
4774
  }
4764
- function hasMemberEffectWhenCalled(members, memberName, callOptions, context) {
4775
+ function hasMemberEffectWhenCalled(members, memberName, interaction, context) {
4765
4776
  var _a, _b;
4766
4777
  if (typeof memberName !== 'string' || !members[memberName]) {
4767
4778
  return true;
4768
4779
  }
4769
- return ((_b = (_a = members[memberName]).hasEffectsWhenCalled) === null || _b === void 0 ? void 0 : _b.call(_a, callOptions, context)) || false;
4780
+ return ((_b = (_a = members[memberName]).hasEffectsWhenCalled) === null || _b === void 0 ? void 0 : _b.call(_a, interaction, context)) || false;
4770
4781
  }
4771
4782
  function getMemberReturnExpressionWhenCalled(members, memberName) {
4772
4783
  if (typeof memberName !== 'string' || !members[memberName])
@@ -5205,10 +5216,12 @@ const INCLUDE_PARAMETERS = 'variables';
5205
5216
  class NodeBase extends ExpressionEntity {
5206
5217
  constructor(esTreeNode, parent, parentScope) {
5207
5218
  super();
5208
- // Nodes can apply custom deoptimizations once they become part of the
5209
- // executed code. To do this, they must initialize this as false, implement
5210
- // applyDeoptimizations and call this from include and hasEffects if they
5211
- // have custom handlers
5219
+ /**
5220
+ * Nodes can apply custom deoptimizations once they become part of the
5221
+ * executed code. To do this, they must initialize this as false, implement
5222
+ * applyDeoptimizations and call this from include and hasEffects if they have
5223
+ * custom handlers
5224
+ */
5212
5225
  this.deoptimized = false;
5213
5226
  this.esTreeNode = esTreeNode;
5214
5227
  this.keys = keys[esTreeNode.type] || getAndCreateKeys(esTreeNode);
@@ -5264,6 +5277,10 @@ class NodeBase extends ExpressionEntity {
5264
5277
  }
5265
5278
  return false;
5266
5279
  }
5280
+ hasEffectsAsAssignmentTarget(context, _checkAccess) {
5281
+ return (this.hasEffects(context) ||
5282
+ this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));
5283
+ }
5267
5284
  include(context, includeChildrenRecursively, _options) {
5268
5285
  if (!this.deoptimized)
5269
5286
  this.applyDeoptimizations();
@@ -5282,6 +5299,9 @@ class NodeBase extends ExpressionEntity {
5282
5299
  }
5283
5300
  }
5284
5301
  }
5302
+ includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {
5303
+ this.include(context, includeChildrenRecursively);
5304
+ }
5285
5305
  /**
5286
5306
  * Override to perform special initialisation steps after the scope is initialised
5287
5307
  */
@@ -5336,6 +5356,9 @@ class NodeBase extends ExpressionEntity {
5336
5356
  }
5337
5357
  }
5338
5358
  }
5359
+ setAssignedValue(value) {
5360
+ this.assignmentInteraction = { args: [value], thisArg: null, type: INTERACTION_ASSIGNED };
5361
+ }
5339
5362
  shouldBeIncluded(context) {
5340
5363
  return this.included || (!context.brokenFlow && this.hasEffects(createHasEffectsContext()));
5341
5364
  }
@@ -5364,9 +5387,9 @@ class NodeBase extends ExpressionEntity {
5364
5387
  }
5365
5388
 
5366
5389
  class SpreadElement extends NodeBase {
5367
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
5390
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
5368
5391
  if (path.length > 0) {
5369
- this.argument.deoptimizeThisOnEventAtPath(event, [UnknownKey, ...path], thisParameter, recursionTracker);
5392
+ this.argument.deoptimizeThisOnInteractionAtPath(interaction, [UnknownKey, ...path], recursionTracker);
5370
5393
  }
5371
5394
  }
5372
5395
  hasEffects(context) {
@@ -5377,7 +5400,7 @@ class SpreadElement extends NodeBase {
5377
5400
  return (this.argument.hasEffects(context) ||
5378
5401
  (propertyReadSideEffects &&
5379
5402
  (propertyReadSideEffects === 'always' ||
5380
- this.argument.hasEffectsWhenAccessedAtPath(UNKNOWN_PATH, context))));
5403
+ this.argument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context))));
5381
5404
  }
5382
5405
  applyDeoptimizations() {
5383
5406
  this.deoptimized = true;
@@ -5388,53 +5411,43 @@ class SpreadElement extends NodeBase {
5388
5411
  }
5389
5412
  }
5390
5413
 
5391
- const EVENT_ACCESSED = 0;
5392
- const EVENT_ASSIGNED = 1;
5393
- const EVENT_CALLED = 2;
5394
-
5395
5414
  class Method extends ExpressionEntity {
5396
5415
  constructor(description) {
5397
5416
  super();
5398
5417
  this.description = description;
5399
5418
  }
5400
- deoptimizeThisOnEventAtPath(event, path, thisParameter) {
5401
- if (event === EVENT_CALLED && path.length === 0 && this.description.mutatesSelfAsArray) {
5402
- thisParameter.deoptimizePath(UNKNOWN_INTEGER_PATH);
5419
+ deoptimizeThisOnInteractionAtPath({ type, thisArg }, path) {
5420
+ if (type === INTERACTION_CALLED && path.length === 0 && this.description.mutatesSelfAsArray) {
5421
+ thisArg.deoptimizePath(UNKNOWN_INTEGER_PATH);
5403
5422
  }
5404
5423
  }
5405
- getReturnExpressionWhenCalledAtPath(path, callOptions) {
5424
+ getReturnExpressionWhenCalledAtPath(path, { thisArg }) {
5406
5425
  if (path.length > 0) {
5407
5426
  return UNKNOWN_EXPRESSION;
5408
5427
  }
5409
5428
  return (this.description.returnsPrimitive ||
5410
5429
  (this.description.returns === 'self'
5411
- ? callOptions.thisParam || UNKNOWN_EXPRESSION
5430
+ ? thisArg || UNKNOWN_EXPRESSION
5412
5431
  : this.description.returns()));
5413
5432
  }
5414
- hasEffectsWhenAccessedAtPath(path) {
5415
- return path.length > 1;
5416
- }
5417
- hasEffectsWhenAssignedAtPath(path) {
5418
- return path.length > 0;
5419
- }
5420
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
5433
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
5421
5434
  var _a, _b;
5422
- if (path.length > 0 ||
5423
- (this.description.mutatesSelfAsArray === true &&
5424
- ((_a = callOptions.thisParam) === null || _a === void 0 ? void 0 : _a.hasEffectsWhenAssignedAtPath(UNKNOWN_INTEGER_PATH, context)))) {
5435
+ const { type } = interaction;
5436
+ if (path.length > (type === INTERACTION_ACCESSED ? 1 : 0)) {
5425
5437
  return true;
5426
5438
  }
5427
- if (!this.description.callsArgs) {
5428
- return false;
5429
- }
5430
- for (const argIndex of this.description.callsArgs) {
5431
- if ((_b = callOptions.args[argIndex]) === null || _b === void 0 ? void 0 : _b.hasEffectsWhenCalledAtPath(EMPTY_PATH, {
5432
- args: NO_ARGS,
5433
- thisParam: null,
5434
- withNew: false
5435
- }, context)) {
5439
+ if (type === INTERACTION_CALLED) {
5440
+ if (this.description.mutatesSelfAsArray === true &&
5441
+ ((_a = interaction.thisArg) === null || _a === void 0 ? void 0 : _a.hasEffectsOnInteractionAtPath(UNKNOWN_INTEGER_PATH, NODE_INTERACTION_UNKNOWN_ASSIGNMENT, context))) {
5436
5442
  return true;
5437
5443
  }
5444
+ if (this.description.callsArgs) {
5445
+ for (const argIndex of this.description.callsArgs) {
5446
+ if ((_b = interaction.args[argIndex]) === null || _b === void 0 ? void 0 : _b.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context)) {
5447
+ return true;
5448
+ }
5449
+ }
5450
+ }
5438
5451
  }
5439
5452
  return false;
5440
5453
  }
@@ -5576,24 +5589,24 @@ class ObjectEntity extends ExpressionEntity {
5576
5589
  }
5577
5590
  (_a = this.prototypeExpression) === null || _a === void 0 ? void 0 : _a.deoptimizePath(path.length === 1 ? [...path, UnknownKey] : path);
5578
5591
  }
5579
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
5592
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
5580
5593
  var _a;
5581
5594
  const [key, ...subPath] = path;
5582
5595
  if (this.hasLostTrack ||
5583
5596
  // single paths that are deoptimized will not become getters or setters
5584
- ((event === EVENT_CALLED || path.length > 1) &&
5597
+ ((interaction.type === INTERACTION_CALLED || path.length > 1) &&
5585
5598
  (this.hasUnknownDeoptimizedProperty ||
5586
5599
  (typeof key === 'string' && this.deoptimizedPaths[key])))) {
5587
- thisParameter.deoptimizePath(UNKNOWN_PATH);
5600
+ interaction.thisArg.deoptimizePath(UNKNOWN_PATH);
5588
5601
  return;
5589
5602
  }
5590
- const [propertiesForExactMatchByKey, relevantPropertiesByKey, relevantUnmatchableProperties] = event === EVENT_CALLED || path.length > 1
5603
+ const [propertiesForExactMatchByKey, relevantPropertiesByKey, relevantUnmatchableProperties] = interaction.type === INTERACTION_CALLED || path.length > 1
5591
5604
  ? [
5592
5605
  this.propertiesAndGettersByKey,
5593
5606
  this.propertiesAndGettersByKey,
5594
5607
  this.unmatchablePropertiesAndGetters
5595
5608
  ]
5596
- : event === EVENT_ACCESSED
5609
+ : interaction.type === INTERACTION_ACCESSED
5597
5610
  ? [this.propertiesAndGettersByKey, this.gettersByKey, this.unmatchableGetters]
5598
5611
  : [this.propertiesAndSettersByKey, this.settersByKey, this.unmatchableSetters];
5599
5612
  if (typeof key === 'string') {
@@ -5601,20 +5614,20 @@ class ObjectEntity extends ExpressionEntity {
5601
5614
  const properties = relevantPropertiesByKey[key];
5602
5615
  if (properties) {
5603
5616
  for (const property of properties) {
5604
- property.deoptimizeThisOnEventAtPath(event, subPath, thisParameter, recursionTracker);
5617
+ property.deoptimizeThisOnInteractionAtPath(interaction, subPath, recursionTracker);
5605
5618
  }
5606
5619
  }
5607
5620
  if (!this.immutable) {
5608
- this.thisParametersToBeDeoptimized.add(thisParameter);
5621
+ this.thisParametersToBeDeoptimized.add(interaction.thisArg);
5609
5622
  }
5610
5623
  return;
5611
5624
  }
5612
5625
  for (const property of relevantUnmatchableProperties) {
5613
- property.deoptimizeThisOnEventAtPath(event, subPath, thisParameter, recursionTracker);
5626
+ property.deoptimizeThisOnInteractionAtPath(interaction, subPath, recursionTracker);
5614
5627
  }
5615
5628
  if (INTEGER_REG_EXP.test(key)) {
5616
5629
  for (const property of this.unknownIntegerProps) {
5617
- property.deoptimizeThisOnEventAtPath(event, subPath, thisParameter, recursionTracker);
5630
+ property.deoptimizeThisOnInteractionAtPath(interaction, subPath, recursionTracker);
5618
5631
  }
5619
5632
  }
5620
5633
  }
@@ -5623,17 +5636,17 @@ class ObjectEntity extends ExpressionEntity {
5623
5636
  relevantUnmatchableProperties
5624
5637
  ])) {
5625
5638
  for (const property of properties) {
5626
- property.deoptimizeThisOnEventAtPath(event, subPath, thisParameter, recursionTracker);
5639
+ property.deoptimizeThisOnInteractionAtPath(interaction, subPath, recursionTracker);
5627
5640
  }
5628
5641
  }
5629
5642
  for (const property of this.unknownIntegerProps) {
5630
- property.deoptimizeThisOnEventAtPath(event, subPath, thisParameter, recursionTracker);
5643
+ property.deoptimizeThisOnInteractionAtPath(interaction, subPath, recursionTracker);
5631
5644
  }
5632
5645
  }
5633
5646
  if (!this.immutable) {
5634
- this.thisParametersToBeDeoptimized.add(thisParameter);
5647
+ this.thisParametersToBeDeoptimized.add(interaction.thisArg);
5635
5648
  }
5636
- (_a = this.prototypeExpression) === null || _a === void 0 ? void 0 : _a.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
5649
+ (_a = this.prototypeExpression) === null || _a === void 0 ? void 0 : _a.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
5637
5650
  }
5638
5651
  getLiteralValueAtPath(path, recursionTracker, origin) {
5639
5652
  if (path.length === 0) {
@@ -5652,79 +5665,29 @@ class ObjectEntity extends ExpressionEntity {
5652
5665
  }
5653
5666
  return UnknownValue;
5654
5667
  }
5655
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
5668
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
5656
5669
  if (path.length === 0) {
5657
5670
  return UNKNOWN_EXPRESSION;
5658
5671
  }
5659
- const key = path[0];
5672
+ const [key, ...subPath] = path;
5660
5673
  const expressionAtPath = this.getMemberExpressionAndTrackDeopt(key, origin);
5661
5674
  if (expressionAtPath) {
5662
- return expressionAtPath.getReturnExpressionWhenCalledAtPath(path.slice(1), callOptions, recursionTracker, origin);
5675
+ return expressionAtPath.getReturnExpressionWhenCalledAtPath(subPath, interaction, recursionTracker, origin);
5663
5676
  }
5664
5677
  if (this.prototypeExpression) {
5665
- return this.prototypeExpression.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
5678
+ return this.prototypeExpression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
5666
5679
  }
5667
5680
  return UNKNOWN_EXPRESSION;
5668
5681
  }
5669
- hasEffectsWhenAccessedAtPath(path, context) {
5670
- const [key, ...subPath] = path;
5671
- if (path.length > 1) {
5672
- if (typeof key !== 'string') {
5673
- return true;
5674
- }
5675
- const expressionAtPath = this.getMemberExpression(key);
5676
- if (expressionAtPath) {
5677
- return expressionAtPath.hasEffectsWhenAccessedAtPath(subPath, context);
5678
- }
5679
- if (this.prototypeExpression) {
5680
- return this.prototypeExpression.hasEffectsWhenAccessedAtPath(path, context);
5681
- }
5682
- return true;
5683
- }
5684
- if (this.hasLostTrack)
5685
- return true;
5686
- if (typeof key === 'string') {
5687
- if (this.propertiesAndGettersByKey[key]) {
5688
- const getters = this.gettersByKey[key];
5689
- if (getters) {
5690
- for (const getter of getters) {
5691
- if (getter.hasEffectsWhenAccessedAtPath(subPath, context))
5692
- return true;
5693
- }
5694
- }
5695
- return false;
5696
- }
5697
- for (const getter of this.unmatchableGetters) {
5698
- if (getter.hasEffectsWhenAccessedAtPath(subPath, context)) {
5699
- return true;
5700
- }
5701
- }
5702
- }
5703
- else {
5704
- for (const getters of Object.values(this.gettersByKey).concat([this.unmatchableGetters])) {
5705
- for (const getter of getters) {
5706
- if (getter.hasEffectsWhenAccessedAtPath(subPath, context))
5707
- return true;
5708
- }
5709
- }
5710
- }
5711
- if (this.prototypeExpression) {
5712
- return this.prototypeExpression.hasEffectsWhenAccessedAtPath(path, context);
5713
- }
5714
- return false;
5715
- }
5716
- hasEffectsWhenAssignedAtPath(path, context) {
5682
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
5717
5683
  const [key, ...subPath] = path;
5718
- if (path.length > 1) {
5719
- if (typeof key !== 'string') {
5720
- return true;
5721
- }
5684
+ if (subPath.length || interaction.type === INTERACTION_CALLED) {
5722
5685
  const expressionAtPath = this.getMemberExpression(key);
5723
5686
  if (expressionAtPath) {
5724
- return expressionAtPath.hasEffectsWhenAssignedAtPath(subPath, context);
5687
+ return expressionAtPath.hasEffectsOnInteractionAtPath(subPath, interaction, context);
5725
5688
  }
5726
5689
  if (this.prototypeExpression) {
5727
- return this.prototypeExpression.hasEffectsWhenAssignedAtPath(path, context);
5690
+ return this.prototypeExpression.hasEffectsOnInteractionAtPath(path, interaction, context);
5728
5691
  }
5729
5692
  return true;
5730
5693
  }
@@ -5732,47 +5695,39 @@ class ObjectEntity extends ExpressionEntity {
5732
5695
  return false;
5733
5696
  if (this.hasLostTrack)
5734
5697
  return true;
5698
+ const [propertiesAndAccessorsByKey, accessorsByKey, unmatchableAccessors] = interaction.type === INTERACTION_ACCESSED
5699
+ ? [this.propertiesAndGettersByKey, this.gettersByKey, this.unmatchableGetters]
5700
+ : [this.propertiesAndSettersByKey, this.settersByKey, this.unmatchableSetters];
5735
5701
  if (typeof key === 'string') {
5736
- if (this.propertiesAndSettersByKey[key]) {
5737
- const setters = this.settersByKey[key];
5738
- if (setters) {
5739
- for (const setter of setters) {
5740
- if (setter.hasEffectsWhenAssignedAtPath(subPath, context))
5702
+ if (propertiesAndAccessorsByKey[key]) {
5703
+ const accessors = accessorsByKey[key];
5704
+ if (accessors) {
5705
+ for (const accessor of accessors) {
5706
+ if (accessor.hasEffectsOnInteractionAtPath(subPath, interaction, context))
5741
5707
  return true;
5742
5708
  }
5743
5709
  }
5744
5710
  return false;
5745
5711
  }
5746
- for (const property of this.unmatchableSetters) {
5747
- if (property.hasEffectsWhenAssignedAtPath(subPath, context)) {
5712
+ for (const accessor of unmatchableAccessors) {
5713
+ if (accessor.hasEffectsOnInteractionAtPath(subPath, interaction, context)) {
5748
5714
  return true;
5749
5715
  }
5750
5716
  }
5751
5717
  }
5752
5718
  else {
5753
- for (const setters of Object.values(this.settersByKey).concat([this.unmatchableSetters])) {
5754
- for (const setter of setters) {
5755
- if (setter.hasEffectsWhenAssignedAtPath(subPath, context))
5719
+ for (const accessors of Object.values(accessorsByKey).concat([unmatchableAccessors])) {
5720
+ for (const accessor of accessors) {
5721
+ if (accessor.hasEffectsOnInteractionAtPath(subPath, interaction, context))
5756
5722
  return true;
5757
5723
  }
5758
5724
  }
5759
5725
  }
5760
5726
  if (this.prototypeExpression) {
5761
- return this.prototypeExpression.hasEffectsWhenAssignedAtPath(path, context);
5727
+ return this.prototypeExpression.hasEffectsOnInteractionAtPath(path, interaction, context);
5762
5728
  }
5763
5729
  return false;
5764
5730
  }
5765
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
5766
- const key = path[0];
5767
- const expressionAtPath = this.getMemberExpression(key);
5768
- if (expressionAtPath) {
5769
- return expressionAtPath.hasEffectsWhenCalledAtPath(path.slice(1), callOptions, context);
5770
- }
5771
- if (this.prototypeExpression) {
5772
- return this.prototypeExpression.hasEffectsWhenCalledAtPath(path, callOptions, context);
5773
- }
5774
- return true;
5775
- }
5776
5731
  buildPropertyMaps(properties) {
5777
5732
  const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchableGetters, unmatchableSetters } = this;
5778
5733
  const unmatchablePropertiesAndSetters = [];
@@ -5878,9 +5833,9 @@ const isInteger = (prop) => typeof prop === 'string' && /^\d+$/.test(prop);
5878
5833
  // properties as we do not expect new builtin properties to be numbers, this
5879
5834
  // will improve tree-shaking for out-of-bounds array properties
5880
5835
  const OBJECT_PROTOTYPE_FALLBACK = new (class ObjectPrototypeFallbackExpression extends ExpressionEntity {
5881
- deoptimizeThisOnEventAtPath(event, path, thisParameter) {
5882
- if (event === EVENT_CALLED && path.length === 1 && !isInteger(path[0])) {
5883
- thisParameter.deoptimizePath(UNKNOWN_PATH);
5836
+ deoptimizeThisOnInteractionAtPath({ type, thisArg }, path) {
5837
+ if (type === INTERACTION_CALLED && path.length === 1 && !isInteger(path[0])) {
5838
+ thisArg.deoptimizePath(UNKNOWN_PATH);
5884
5839
  }
5885
5840
  }
5886
5841
  getLiteralValueAtPath(path) {
@@ -5889,11 +5844,8 @@ const OBJECT_PROTOTYPE_FALLBACK = new (class ObjectPrototypeFallbackExpression e
5889
5844
  // "undefined"
5890
5845
  return path.length === 1 && isInteger(path[0]) ? undefined : UnknownValue;
5891
5846
  }
5892
- hasEffectsWhenAccessedAtPath(path) {
5893
- return path.length > 1;
5894
- }
5895
- hasEffectsWhenAssignedAtPath(path) {
5896
- return path.length > 1;
5847
+ hasEffectsOnInteractionAtPath(path, { type }) {
5848
+ return path.length > 1 || type === INTERACTION_CALLED;
5897
5849
  }
5898
5850
  })();
5899
5851
  const OBJECT_PROTOTYPE = new ObjectEntity({
@@ -6015,8 +5967,8 @@ const ARRAY_PROTOTYPE = new ObjectEntity({
6015
5967
  flat: METHOD_DEOPTS_SELF_RETURNS_NEW_ARRAY,
6016
5968
  flatMap: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_NEW_ARRAY,
6017
5969
  forEach: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN,
6018
- groupBy: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN,
6019
- groupByToMap: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN,
5970
+ group: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN,
5971
+ groupToMap: METHOD_CALLS_ARG_DEOPTS_SELF_RETURNS_UNKNOWN,
6020
5972
  includes: METHOD_RETURNS_BOOLEAN,
6021
5973
  indexOf: METHOD_RETURNS_NUMBER,
6022
5974
  join: METHOD_RETURNS_STRING,
@@ -6047,23 +5999,17 @@ class ArrayExpression extends NodeBase {
6047
5999
  deoptimizePath(path) {
6048
6000
  this.getObjectEntity().deoptimizePath(path);
6049
6001
  }
6050
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
6051
- this.getObjectEntity().deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
6002
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
6003
+ this.getObjectEntity().deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
6052
6004
  }
6053
6005
  getLiteralValueAtPath(path, recursionTracker, origin) {
6054
6006
  return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);
6055
6007
  }
6056
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
6057
- return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
6008
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
6009
+ return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
6058
6010
  }
6059
- hasEffectsWhenAccessedAtPath(path, context) {
6060
- return this.getObjectEntity().hasEffectsWhenAccessedAtPath(path, context);
6061
- }
6062
- hasEffectsWhenAssignedAtPath(path, context) {
6063
- return this.getObjectEntity().hasEffectsWhenAssignedAtPath(path, context);
6064
- }
6065
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
6066
- return this.getObjectEntity().hasEffectsWhenCalledAtPath(path, callOptions, context);
6011
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
6012
+ return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
6067
6013
  }
6068
6014
  applyDeoptimizations() {
6069
6015
  this.deoptimized = true;
@@ -6073,13 +6019,8 @@ class ArrayExpression extends NodeBase {
6073
6019
  if (element) {
6074
6020
  if (hasSpread || element instanceof SpreadElement) {
6075
6021
  hasSpread = true;
6076
- // This also deoptimizes parameter defaults
6077
6022
  element.deoptimizePath(UNKNOWN_PATH);
6078
6023
  }
6079
- else {
6080
- // We do not track parameter defaults in arrays
6081
- element.deoptimizeCallParameters();
6082
- }
6083
6024
  }
6084
6025
  }
6085
6026
  this.context.requestTreeshakingPass();
@@ -6133,9 +6074,9 @@ class ArrayPattern extends NodeBase {
6133
6074
  }
6134
6075
  }
6135
6076
  // Patterns are only checked at the emtpy path at the moment
6136
- hasEffectsWhenAssignedAtPath(_path, context) {
6077
+ hasEffectsOnInteractionAtPath(_path, interaction, context) {
6137
6078
  for (const element of this.elements) {
6138
- if (element === null || element === void 0 ? void 0 : element.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context))
6079
+ if (element === null || element === void 0 ? void 0 : element.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context))
6139
6080
  return true;
6140
6081
  }
6141
6082
  return false;
@@ -6173,10 +6114,6 @@ class LocalVariable extends Variable {
6173
6114
  this.additionalInitializers = null;
6174
6115
  }
6175
6116
  }
6176
- deoptimizeCallParameters() {
6177
- var _a;
6178
- (_a = this.init) === null || _a === void 0 ? void 0 : _a.deoptimizeCallParameters();
6179
- }
6180
6117
  deoptimizePath(path) {
6181
6118
  var _a, _b;
6182
6119
  if (this.isReassigned ||
@@ -6198,11 +6135,11 @@ class LocalVariable extends Variable {
6198
6135
  (_b = this.init) === null || _b === void 0 ? void 0 : _b.deoptimizePath(path);
6199
6136
  }
6200
6137
  }
6201
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
6138
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
6202
6139
  if (this.isReassigned || !this.init) {
6203
- return thisParameter.deoptimizePath(UNKNOWN_PATH);
6140
+ return interaction.thisArg.deoptimizePath(UNKNOWN_PATH);
6204
6141
  }
6205
- recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker), undefined);
6142
+ recursionTracker.withTrackedEntityAtPath(path, this.init, () => this.init.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker), undefined);
6206
6143
  }
6207
6144
  getLiteralValueAtPath(path, recursionTracker, origin) {
6208
6145
  if (this.isReassigned || !this.init) {
@@ -6213,39 +6150,40 @@ class LocalVariable extends Variable {
6213
6150
  return this.init.getLiteralValueAtPath(path, recursionTracker, origin);
6214
6151
  }, UnknownValue);
6215
6152
  }
6216
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
6153
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
6217
6154
  if (this.isReassigned || !this.init) {
6218
6155
  return UNKNOWN_EXPRESSION;
6219
6156
  }
6220
6157
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
6221
6158
  this.expressionsToBeDeoptimized.push(origin);
6222
- return this.init.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
6159
+ return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
6223
6160
  }, UNKNOWN_EXPRESSION);
6224
6161
  }
6225
- hasEffectsWhenAccessedAtPath(path, context) {
6226
- if (this.isReassigned)
6227
- return true;
6228
- return (this.init &&
6229
- !context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
6230
- this.init.hasEffectsWhenAccessedAtPath(path, context));
6231
- }
6232
- hasEffectsWhenAssignedAtPath(path, context) {
6233
- if (this.included)
6234
- return true;
6235
- if (path.length === 0)
6236
- return false;
6237
- if (this.isReassigned)
6238
- return true;
6239
- return (this.init &&
6240
- !context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
6241
- this.init.hasEffectsWhenAssignedAtPath(path, context));
6242
- }
6243
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
6244
- if (this.isReassigned)
6245
- return true;
6246
- return (this.init &&
6247
- !(callOptions.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, callOptions, this) &&
6248
- this.init.hasEffectsWhenCalledAtPath(path, callOptions, context));
6162
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
6163
+ switch (interaction.type) {
6164
+ case INTERACTION_ACCESSED:
6165
+ if (this.isReassigned)
6166
+ return true;
6167
+ return (this.init &&
6168
+ !context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
6169
+ this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
6170
+ case INTERACTION_ASSIGNED:
6171
+ if (this.included)
6172
+ return true;
6173
+ if (path.length === 0)
6174
+ return false;
6175
+ if (this.isReassigned)
6176
+ return true;
6177
+ return (this.init &&
6178
+ !context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
6179
+ this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
6180
+ case INTERACTION_CALLED:
6181
+ if (this.isReassigned)
6182
+ return true;
6183
+ return (this.init &&
6184
+ !(interaction.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this) &&
6185
+ this.init.hasEffectsOnInteractionAtPath(path, interaction, context));
6186
+ }
6249
6187
  }
6250
6188
  include() {
6251
6189
  if (!this.included) {
@@ -6522,641 +6460,87 @@ class ReturnValueScope extends ParameterScope {
6522
6460
  }
6523
6461
  }
6524
6462
 
6525
- class AssignmentPattern extends NodeBase {
6526
- addExportedVariables(variables, exportNamesByVariable) {
6527
- this.left.addExportedVariables(variables, exportNamesByVariable);
6528
- }
6529
- declare(kind, init) {
6530
- return this.left.declare(kind, init);
6531
- }
6532
- deoptimizePath(path) {
6533
- path.length === 0 && this.left.deoptimizePath(path);
6534
- }
6535
- hasEffectsWhenAssignedAtPath(path, context) {
6536
- return path.length > 0 || this.left.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context);
6537
- }
6538
- // Note that FunctionBase may directly include .left and .right without
6539
- // including the pattern itself. This is how default parameter tree-shaking
6540
- // works at the moment.
6541
- include(context, includeChildrenRecursively) {
6542
- this.included = true;
6543
- this.left.include(context, includeChildrenRecursively);
6544
- this.right.include(context, includeChildrenRecursively);
6545
- }
6546
- markDeclarationReached() {
6547
- this.left.markDeclarationReached();
6548
- }
6549
- render(code, options, { isShorthandProperty } = BLANK) {
6550
- this.left.render(code, options, { isShorthandProperty });
6551
- if (this.right.included) {
6552
- this.right.render(code, options);
6553
- }
6554
- else {
6555
- code.remove(this.left.end, this.end);
6556
- }
6557
- }
6558
- applyDeoptimizations() {
6559
- this.deoptimized = true;
6560
- this.left.deoptimizePath(EMPTY_PATH);
6561
- this.right.deoptimizePath(UNKNOWN_PATH);
6562
- this.context.requestTreeshakingPass();
6563
- }
6564
- }
6463
+ //@ts-check
6464
+ /** @typedef { import('estree').Node} Node */
6465
+ /** @typedef {Node | {
6466
+ * type: 'PropertyDefinition';
6467
+ * computed: boolean;
6468
+ * value: Node
6469
+ * }} NodeWithPropertyDefinition */
6565
6470
 
6566
- function treeshakeNode(node, code, start, end) {
6567
- code.remove(start, end);
6568
- if (node.annotations) {
6569
- for (const annotation of node.annotations) {
6570
- if (annotation.start < start) {
6571
- code.remove(annotation.start, annotation.end);
6572
- }
6573
- else {
6574
- return;
6575
- }
6576
- }
6577
- }
6471
+ /**
6472
+ *
6473
+ * @param {NodeWithPropertyDefinition} node
6474
+ * @param {NodeWithPropertyDefinition} parent
6475
+ * @returns boolean
6476
+ */
6477
+ function is_reference (node, parent) {
6478
+ if (node.type === 'MemberExpression') {
6479
+ return !node.computed && is_reference(node.object, node);
6480
+ }
6481
+
6482
+ if (node.type === 'Identifier') {
6483
+ if (!parent) return true;
6484
+
6485
+ switch (parent.type) {
6486
+ // disregard `bar` in `foo.bar`
6487
+ case 'MemberExpression': return parent.computed || node === parent.object;
6488
+
6489
+ // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
6490
+ case 'MethodDefinition': return parent.computed;
6491
+
6492
+ // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
6493
+ case 'PropertyDefinition': return parent.computed || node === parent.value;
6494
+
6495
+ // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
6496
+ case 'Property': return parent.computed || node === parent.value;
6497
+
6498
+ // disregard the `bar` in `export { foo as bar }` or
6499
+ // the foo in `import { foo as bar }`
6500
+ case 'ExportSpecifier':
6501
+ case 'ImportSpecifier': return node === parent.local;
6502
+
6503
+ // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
6504
+ case 'LabeledStatement':
6505
+ case 'BreakStatement':
6506
+ case 'ContinueStatement': return false;
6507
+ default: return true;
6508
+ }
6509
+ }
6510
+
6511
+ return false;
6578
6512
  }
6579
- function removeAnnotations(node, code) {
6580
- if (!node.annotations && node.parent.type === ExpressionStatement$1) {
6581
- node = node.parent;
6513
+
6514
+ /* eslint sort-keys: "off" */
6515
+ const ValueProperties = Symbol('Value Properties');
6516
+ const PURE = {
6517
+ hasEffectsWhenCalled() {
6518
+ return false;
6582
6519
  }
6583
- if (node.annotations) {
6584
- for (const annotation of node.annotations) {
6585
- code.remove(annotation.start, annotation.end);
6586
- }
6520
+ };
6521
+ const IMPURE = {
6522
+ hasEffectsWhenCalled() {
6523
+ return true;
6587
6524
  }
6588
- }
6589
-
6590
- const NO_SEMICOLON = { isNoStatement: true };
6591
- // This assumes there are only white-space and comments between start and the string we are looking for
6592
- function findFirstOccurrenceOutsideComment(code, searchString, start = 0) {
6593
- let searchPos, charCodeAfterSlash;
6594
- searchPos = code.indexOf(searchString, start);
6595
- while (true) {
6596
- start = code.indexOf('/', start);
6597
- if (start === -1 || start >= searchPos)
6598
- return searchPos;
6599
- charCodeAfterSlash = code.charCodeAt(++start);
6600
- ++start;
6601
- // With our assumption, '/' always starts a comment. Determine comment type:
6602
- start =
6603
- charCodeAfterSlash === 47 /*"/"*/
6604
- ? code.indexOf('\n', start) + 1
6605
- : code.indexOf('*/', start) + 2;
6606
- if (start > searchPos) {
6607
- searchPos = code.indexOf(searchString, start);
6608
- }
6609
- }
6610
- }
6611
- const NON_WHITESPACE = /\S/g;
6612
- function findNonWhiteSpace(code, index) {
6613
- NON_WHITESPACE.lastIndex = index;
6614
- const result = NON_WHITESPACE.exec(code);
6615
- return result.index;
6616
- }
6617
- // This assumes "code" only contains white-space and comments
6618
- // Returns position of line-comment if applicable
6619
- function findFirstLineBreakOutsideComment(code) {
6620
- let lineBreakPos, charCodeAfterSlash, start = 0;
6621
- lineBreakPos = code.indexOf('\n', start);
6622
- while (true) {
6623
- start = code.indexOf('/', start);
6624
- if (start === -1 || start > lineBreakPos)
6625
- return [lineBreakPos, lineBreakPos + 1];
6626
- // With our assumption, '/' always starts a comment. Determine comment type:
6627
- charCodeAfterSlash = code.charCodeAt(start + 1);
6628
- if (charCodeAfterSlash === 47 /*"/"*/)
6629
- return [start, lineBreakPos + 1];
6630
- start = code.indexOf('*/', start + 3) + 2;
6631
- if (start > lineBreakPos) {
6632
- lineBreakPos = code.indexOf('\n', start);
6633
- }
6634
- }
6635
- }
6636
- function renderStatementList(statements, code, start, end, options) {
6637
- let currentNode, currentNodeStart, currentNodeNeedsBoundaries, nextNodeStart;
6638
- let nextNode = statements[0];
6639
- let nextNodeNeedsBoundaries = !nextNode.included || nextNode.needsBoundaries;
6640
- if (nextNodeNeedsBoundaries) {
6641
- nextNodeStart =
6642
- start + findFirstLineBreakOutsideComment(code.original.slice(start, nextNode.start))[1];
6643
- }
6644
- for (let nextIndex = 1; nextIndex <= statements.length; nextIndex++) {
6645
- currentNode = nextNode;
6646
- currentNodeStart = nextNodeStart;
6647
- currentNodeNeedsBoundaries = nextNodeNeedsBoundaries;
6648
- nextNode = statements[nextIndex];
6649
- nextNodeNeedsBoundaries =
6650
- nextNode === undefined ? false : !nextNode.included || nextNode.needsBoundaries;
6651
- if (currentNodeNeedsBoundaries || nextNodeNeedsBoundaries) {
6652
- nextNodeStart =
6653
- currentNode.end +
6654
- findFirstLineBreakOutsideComment(code.original.slice(currentNode.end, nextNode === undefined ? end : nextNode.start))[1];
6655
- if (currentNode.included) {
6656
- currentNodeNeedsBoundaries
6657
- ? currentNode.render(code, options, {
6658
- end: nextNodeStart,
6659
- start: currentNodeStart
6660
- })
6661
- : currentNode.render(code, options);
6662
- }
6663
- else {
6664
- treeshakeNode(currentNode, code, currentNodeStart, nextNodeStart);
6665
- }
6666
- }
6667
- else {
6668
- currentNode.render(code, options);
6669
- }
6670
- }
6671
- }
6672
- // This assumes that the first character is not part of the first node
6673
- function getCommaSeparatedNodesWithBoundaries(nodes, code, start, end) {
6674
- const splitUpNodes = [];
6675
- let node, nextNode, nextNodeStart, contentEnd, char;
6676
- let separator = start - 1;
6677
- for (let nextIndex = 0; nextIndex < nodes.length; nextIndex++) {
6678
- nextNode = nodes[nextIndex];
6679
- if (node !== undefined) {
6680
- separator =
6681
- node.end +
6682
- findFirstOccurrenceOutsideComment(code.original.slice(node.end, nextNode.start), ',');
6683
- }
6684
- nextNodeStart = contentEnd =
6685
- separator +
6686
- 1 +
6687
- findFirstLineBreakOutsideComment(code.original.slice(separator + 1, nextNode.start))[1];
6688
- while (((char = code.original.charCodeAt(nextNodeStart)),
6689
- char === 32 /*" "*/ || char === 9 /*"\t"*/ || char === 10 /*"\n"*/ || char === 13) /*"\r"*/)
6690
- nextNodeStart++;
6691
- if (node !== undefined) {
6692
- splitUpNodes.push({
6693
- contentEnd,
6694
- end: nextNodeStart,
6695
- node,
6696
- separator,
6697
- start
6698
- });
6699
- }
6700
- node = nextNode;
6701
- start = nextNodeStart;
6702
- }
6703
- splitUpNodes.push({
6704
- contentEnd: end,
6705
- end,
6706
- node: node,
6707
- separator: null,
6708
- start
6709
- });
6710
- return splitUpNodes;
6711
- }
6712
- // This assumes there are only white-space and comments between start and end
6713
- function removeLineBreaks(code, start, end) {
6714
- while (true) {
6715
- const [removeStart, removeEnd] = findFirstLineBreakOutsideComment(code.original.slice(start, end));
6716
- if (removeStart === -1) {
6717
- break;
6718
- }
6719
- code.remove(start + removeStart, (start += removeEnd));
6720
- }
6721
- }
6722
-
6723
- class BlockScope extends ChildScope {
6724
- addDeclaration(identifier, context, init, isHoisted) {
6725
- if (isHoisted) {
6726
- const variable = this.parent.addDeclaration(identifier, context, init, isHoisted);
6727
- // Necessary to make sure the init is deoptimized for conditional declarations.
6728
- // We cannot call deoptimizePath here.
6729
- variable.markInitializersForDeoptimization();
6730
- return variable;
6731
- }
6732
- else {
6733
- return super.addDeclaration(identifier, context, init, false);
6734
- }
6735
- }
6736
- }
6737
-
6738
- class ExpressionStatement extends NodeBase {
6739
- initialise() {
6740
- if (this.directive &&
6741
- this.directive !== 'use strict' &&
6742
- this.parent.type === Program$1) {
6743
- this.context.warn(
6744
- // This is necessary, because either way (deleting or not) can lead to errors.
6745
- {
6746
- code: 'MODULE_LEVEL_DIRECTIVE',
6747
- message: `Module level directives cause errors when bundled, '${this.directive}' was ignored.`
6748
- }, this.start);
6749
- }
6750
- }
6751
- render(code, options) {
6752
- super.render(code, options);
6753
- if (this.included)
6754
- this.insertSemicolon(code);
6755
- }
6756
- shouldBeIncluded(context) {
6757
- if (this.directive && this.directive !== 'use strict')
6758
- return this.parent.type !== Program$1;
6759
- return super.shouldBeIncluded(context);
6760
- }
6761
- applyDeoptimizations() { }
6762
- }
6763
-
6764
- class BlockStatement extends NodeBase {
6765
- constructor() {
6766
- super(...arguments);
6767
- this.directlyIncluded = false;
6768
- }
6769
- addImplicitReturnExpressionToScope() {
6770
- const lastStatement = this.body[this.body.length - 1];
6771
- if (!lastStatement || lastStatement.type !== ReturnStatement$1) {
6772
- this.scope.addReturnExpression(UNKNOWN_EXPRESSION);
6773
- }
6774
- }
6775
- createScope(parentScope) {
6776
- this.scope = this.parent.preventChildBlockScope
6777
- ? parentScope
6778
- : new BlockScope(parentScope);
6779
- }
6780
- hasEffects(context) {
6781
- if (this.deoptimizeBody)
6782
- return true;
6783
- for (const node of this.body) {
6784
- if (context.brokenFlow)
6785
- break;
6786
- if (node.hasEffects(context))
6787
- return true;
6788
- }
6789
- return false;
6790
- }
6791
- include(context, includeChildrenRecursively) {
6792
- if (!(this.deoptimizeBody && this.directlyIncluded)) {
6793
- this.included = true;
6794
- this.directlyIncluded = true;
6795
- if (this.deoptimizeBody)
6796
- includeChildrenRecursively = true;
6797
- for (const node of this.body) {
6798
- if (includeChildrenRecursively || node.shouldBeIncluded(context))
6799
- node.include(context, includeChildrenRecursively);
6800
- }
6801
- }
6802
- }
6803
- initialise() {
6804
- const firstBodyStatement = this.body[0];
6805
- this.deoptimizeBody =
6806
- firstBodyStatement instanceof ExpressionStatement &&
6807
- firstBodyStatement.directive === 'use asm';
6808
- }
6809
- render(code, options) {
6810
- if (this.body.length) {
6811
- renderStatementList(this.body, code, this.start + 1, this.end - 1, options);
6812
- }
6813
- else {
6814
- super.render(code, options);
6815
- }
6816
- }
6817
- }
6818
-
6819
- class RestElement extends NodeBase {
6820
- constructor() {
6821
- super(...arguments);
6822
- this.declarationInit = null;
6823
- }
6824
- addExportedVariables(variables, exportNamesByVariable) {
6825
- this.argument.addExportedVariables(variables, exportNamesByVariable);
6826
- }
6827
- declare(kind, init) {
6828
- this.declarationInit = init;
6829
- return this.argument.declare(kind, UNKNOWN_EXPRESSION);
6830
- }
6831
- deoptimizePath(path) {
6832
- path.length === 0 && this.argument.deoptimizePath(EMPTY_PATH);
6833
- }
6834
- hasEffectsWhenAssignedAtPath(path, context) {
6835
- return path.length > 0 || this.argument.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context);
6836
- }
6837
- markDeclarationReached() {
6838
- this.argument.markDeclarationReached();
6839
- }
6840
- applyDeoptimizations() {
6841
- this.deoptimized = true;
6842
- if (this.declarationInit !== null) {
6843
- this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
6844
- this.context.requestTreeshakingPass();
6845
- }
6846
- }
6847
- }
6848
-
6849
- class FunctionBase extends NodeBase {
6850
- constructor() {
6851
- super(...arguments);
6852
- this.objectEntity = null;
6853
- this.deoptimizedReturn = false;
6854
- this.forceIncludeParameters = false;
6855
- }
6856
- deoptimizeCache() {
6857
- this.forceIncludeParameters = true;
6858
- }
6859
- deoptimizeCallParameters() {
6860
- this.forceIncludeParameters = true;
6861
- }
6862
- deoptimizePath(path) {
6863
- this.getObjectEntity().deoptimizePath(path);
6864
- if (path.length === 1 && path[0] === UnknownKey) {
6865
- // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
6866
- // which means the return expression needs to be reassigned
6867
- this.forceIncludeParameters = true;
6868
- this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
6869
- }
6870
- }
6871
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
6872
- if (path.length > 0) {
6873
- this.getObjectEntity().deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
6874
- }
6875
- }
6876
- getLiteralValueAtPath(path, recursionTracker, origin) {
6877
- return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);
6878
- }
6879
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
6880
- if (path.length > 0) {
6881
- return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
6882
- }
6883
- if (this.async) {
6884
- if (!this.deoptimizedReturn) {
6885
- this.deoptimizedReturn = true;
6886
- this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
6887
- this.context.requestTreeshakingPass();
6888
- }
6889
- return UNKNOWN_EXPRESSION;
6890
- }
6891
- return this.scope.getReturnExpression();
6892
- }
6893
- hasEffectsWhenAccessedAtPath(path, context) {
6894
- return this.getObjectEntity().hasEffectsWhenAccessedAtPath(path, context);
6895
- }
6896
- hasEffectsWhenAssignedAtPath(path, context) {
6897
- return this.getObjectEntity().hasEffectsWhenAssignedAtPath(path, context);
6898
- }
6899
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
6900
- var _a;
6901
- if (path.length > 0) {
6902
- return this.getObjectEntity().hasEffectsWhenCalledAtPath(path, callOptions, context);
6903
- }
6904
- if (this.async) {
6905
- const { propertyReadSideEffects } = this.context.options
6906
- .treeshake;
6907
- const returnExpression = this.scope.getReturnExpression();
6908
- if (returnExpression.hasEffectsWhenCalledAtPath(['then'], { args: NO_ARGS, thisParam: null, withNew: false }, context) ||
6909
- (propertyReadSideEffects &&
6910
- (propertyReadSideEffects === 'always' ||
6911
- returnExpression.hasEffectsWhenAccessedAtPath(['then'], context)))) {
6912
- return true;
6913
- }
6914
- }
6915
- for (let position = 0; position < this.params.length; position++) {
6916
- const parameter = this.params[position];
6917
- if (parameter instanceof AssignmentPattern) {
6918
- if (parameter.left.hasEffects(context)) {
6919
- return true;
6920
- }
6921
- const argumentValue = (_a = callOptions.args[position]) === null || _a === void 0 ? void 0 : _a.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
6922
- if ((argumentValue === undefined || argumentValue === UnknownValue) &&
6923
- parameter.right.hasEffects(context)) {
6924
- return true;
6925
- }
6926
- }
6927
- else if (parameter.hasEffects(context)) {
6928
- return true;
6929
- }
6930
- }
6931
- return false;
6932
- }
6933
- include(context, includeChildrenRecursively, { includeWithoutParameterDefaults } = BLANK) {
6934
- if (!this.deoptimized)
6935
- this.applyDeoptimizations();
6936
- this.included = true;
6937
- const { brokenFlow } = context;
6938
- context.brokenFlow = BROKEN_FLOW_NONE;
6939
- this.body.include(context, includeChildrenRecursively);
6940
- context.brokenFlow = brokenFlow;
6941
- if (!includeWithoutParameterDefaults ||
6942
- includeChildrenRecursively ||
6943
- this.forceIncludeParameters) {
6944
- for (const param of this.params) {
6945
- param.include(context, includeChildrenRecursively);
6946
- }
6947
- }
6948
- }
6949
- includeCallArguments(context, args) {
6950
- var _a;
6951
- for (let position = 0; position < this.params.length; position++) {
6952
- const parameter = this.params[position];
6953
- if (parameter instanceof AssignmentPattern) {
6954
- if (parameter.left.shouldBeIncluded(context)) {
6955
- parameter.left.include(context, false);
6956
- }
6957
- const argumentValue = (_a = args[position]) === null || _a === void 0 ? void 0 : _a.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
6958
- // If argumentValue === UnknownTruthyValue, then we do not need to
6959
- // include the default
6960
- if ((argumentValue === undefined || argumentValue === UnknownValue) &&
6961
- (this.parameterVariables[position].some(variable => variable.included) ||
6962
- parameter.right.shouldBeIncluded(context))) {
6963
- parameter.right.include(context, false);
6964
- }
6965
- }
6966
- else if (parameter.shouldBeIncluded(context)) {
6967
- parameter.include(context, false);
6968
- }
6969
- }
6970
- this.scope.includeCallArguments(context, args);
6971
- }
6972
- initialise() {
6973
- this.parameterVariables = this.params.map(param => param.declare('parameter', UNKNOWN_EXPRESSION));
6974
- this.scope.addParameterVariables(this.parameterVariables, this.params[this.params.length - 1] instanceof RestElement);
6975
- if (this.body instanceof BlockStatement) {
6976
- this.body.addImplicitReturnExpressionToScope();
6977
- }
6978
- else {
6979
- this.scope.addReturnExpression(this.body);
6980
- }
6981
- }
6982
- parseNode(esTreeNode) {
6983
- if (esTreeNode.body.type === BlockStatement$1) {
6984
- this.body = new BlockStatement(esTreeNode.body, this, this.scope.hoistedBodyVarScope);
6985
- }
6986
- super.parseNode(esTreeNode);
6987
- }
6988
- applyDeoptimizations() {
6989
- // We currently do not track deoptimizations of default values, deoptimize them
6990
- // just as we deoptimize call arguments
6991
- for (const param of this.params) {
6992
- if (param instanceof AssignmentPattern) {
6993
- param.right.deoptimizePath(UNKNOWN_PATH);
6994
- }
6995
- }
6996
- }
6997
- }
6998
- FunctionBase.prototype.preventChildBlockScope = true;
6999
-
7000
- class ArrowFunctionExpression extends FunctionBase {
7001
- constructor() {
7002
- super(...arguments);
7003
- this.objectEntity = null;
7004
- }
7005
- createScope(parentScope) {
7006
- this.scope = new ReturnValueScope(parentScope, this.context);
7007
- }
7008
- hasEffects() {
7009
- if (!this.deoptimized)
7010
- this.applyDeoptimizations();
7011
- return false;
7012
- }
7013
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
7014
- if (super.hasEffectsWhenCalledAtPath(path, callOptions, context))
7015
- return true;
7016
- const { ignore, brokenFlow } = context;
7017
- context.ignore = {
7018
- breaks: false,
7019
- continues: false,
7020
- labels: new Set(),
7021
- returnYield: true
7022
- };
7023
- if (this.body.hasEffects(context))
7024
- return true;
7025
- context.ignore = ignore;
7026
- context.brokenFlow = brokenFlow;
7027
- return false;
7028
- }
7029
- getObjectEntity() {
7030
- if (this.objectEntity !== null) {
7031
- return this.objectEntity;
7032
- }
7033
- return (this.objectEntity = new ObjectEntity([], OBJECT_PROTOTYPE));
7034
- }
7035
- }
7036
-
7037
- function getSystemExportStatement(exportedVariables, { exportNamesByVariable, snippets: { _, getObject, getPropertyAccess } }, modifier = '') {
7038
- if (exportedVariables.length === 1 &&
7039
- exportNamesByVariable.get(exportedVariables[0]).length === 1) {
7040
- const variable = exportedVariables[0];
7041
- return `exports('${exportNamesByVariable.get(variable)}',${_}${variable.getName(getPropertyAccess)}${modifier})`;
7042
- }
7043
- else {
7044
- const fields = [];
7045
- for (const variable of exportedVariables) {
7046
- for (const exportName of exportNamesByVariable.get(variable)) {
7047
- fields.push([exportName, variable.getName(getPropertyAccess) + modifier]);
7048
- }
7049
- }
7050
- return `exports(${getObject(fields, { lineBreakIndent: null })})`;
7051
- }
7052
- }
7053
- function renderSystemExportExpression(exportedVariable, expressionStart, expressionEnd, code, { exportNamesByVariable, snippets: { _ } }) {
7054
- code.prependRight(expressionStart, `exports('${exportNamesByVariable.get(exportedVariable)}',${_}`);
7055
- code.appendLeft(expressionEnd, ')');
7056
- }
7057
- function renderSystemExportFunction(exportedVariables, expressionStart, expressionEnd, needsParens, code, options) {
7058
- const { _, getDirectReturnIifeLeft } = options.snippets;
7059
- code.prependRight(expressionStart, getDirectReturnIifeLeft(['v'], `${getSystemExportStatement(exportedVariables, options)},${_}v`, { needsArrowReturnParens: true, needsWrappedFunction: needsParens }));
7060
- code.appendLeft(expressionEnd, ')');
7061
- }
7062
- function renderSystemExportSequenceAfterExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options) {
7063
- const { _, getPropertyAccess } = options.snippets;
7064
- code.appendLeft(expressionEnd, `,${_}${getSystemExportStatement([exportedVariable], options)},${_}${exportedVariable.getName(getPropertyAccess)}`);
7065
- if (needsParens) {
7066
- code.prependRight(expressionStart, '(');
7067
- code.appendLeft(expressionEnd, ')');
7068
- }
7069
- }
7070
- function renderSystemExportSequenceBeforeExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options, modifier) {
7071
- const { _ } = options.snippets;
7072
- code.prependRight(expressionStart, `${getSystemExportStatement([exportedVariable], options, modifier)},${_}`);
7073
- if (needsParens) {
7074
- code.prependRight(expressionStart, '(');
7075
- code.appendLeft(expressionEnd, ')');
7076
- }
7077
- }
7078
-
7079
- //@ts-check
7080
- /** @typedef { import('estree').Node} Node */
7081
- /** @typedef {Node | {
7082
- * type: 'PropertyDefinition';
7083
- * computed: boolean;
7084
- * value: Node
7085
- * }} NodeWithPropertyDefinition */
7086
-
7087
- /**
7088
- *
7089
- * @param {NodeWithPropertyDefinition} node
7090
- * @param {NodeWithPropertyDefinition} parent
7091
- * @returns boolean
7092
- */
7093
- function is_reference (node, parent) {
7094
- if (node.type === 'MemberExpression') {
7095
- return !node.computed && is_reference(node.object, node);
7096
- }
7097
-
7098
- if (node.type === 'Identifier') {
7099
- if (!parent) return true;
7100
-
7101
- switch (parent.type) {
7102
- // disregard `bar` in `foo.bar`
7103
- case 'MemberExpression': return parent.computed || node === parent.object;
7104
-
7105
- // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
7106
- case 'MethodDefinition': return parent.computed;
7107
-
7108
- // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
7109
- case 'PropertyDefinition': return parent.computed || node === parent.value;
7110
-
7111
- // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
7112
- case 'Property': return parent.computed || node === parent.value;
7113
-
7114
- // disregard the `bar` in `export { foo as bar }` or
7115
- // the foo in `import { foo as bar }`
7116
- case 'ExportSpecifier':
7117
- case 'ImportSpecifier': return node === parent.local;
7118
-
7119
- // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
7120
- case 'LabeledStatement':
7121
- case 'BreakStatement':
7122
- case 'ContinueStatement': return false;
7123
- default: return true;
7124
- }
7125
- }
7126
-
7127
- return false;
7128
- }
7129
-
7130
- /* eslint sort-keys: "off" */
7131
- const ValueProperties = Symbol('Value Properties');
7132
- const PURE = {
7133
- hasEffectsWhenCalled() {
7134
- return false;
7135
- }
7136
- };
7137
- const IMPURE = {
7138
- hasEffectsWhenCalled() {
7139
- return true;
7140
- }
7141
- };
7142
- // We use shortened variables to reduce file size here
7143
- /* OBJECT */
7144
- const O = {
7145
- __proto__: null,
7146
- [ValueProperties]: IMPURE
7147
- };
7148
- /* PURE FUNCTION */
7149
- const PF = {
7150
- __proto__: null,
7151
- [ValueProperties]: PURE
7152
- };
7153
- /* FUNCTION THAT MUTATES FIRST ARG WITHOUT TRIGGERING ACCESSORS */
7154
- const MUTATES_ARG_WITHOUT_ACCESSOR = {
7155
- __proto__: null,
7156
- [ValueProperties]: {
7157
- hasEffectsWhenCalled(callOptions, context) {
7158
- return (!callOptions.args.length ||
7159
- callOptions.args[0].hasEffectsWhenAssignedAtPath(UNKNOWN_NON_ACCESSOR_PATH, context));
6525
+ };
6526
+ // We use shortened variables to reduce file size here
6527
+ /* OBJECT */
6528
+ const O = {
6529
+ __proto__: null,
6530
+ [ValueProperties]: IMPURE
6531
+ };
6532
+ /* PURE FUNCTION */
6533
+ const PF = {
6534
+ __proto__: null,
6535
+ [ValueProperties]: PURE
6536
+ };
6537
+ /* FUNCTION THAT MUTATES FIRST ARG WITHOUT TRIGGERING ACCESSORS */
6538
+ const MUTATES_ARG_WITHOUT_ACCESSOR = {
6539
+ __proto__: null,
6540
+ [ValueProperties]: {
6541
+ hasEffectsWhenCalled({ args }, context) {
6542
+ return (!args.length ||
6543
+ args[0].hasEffectsOnInteractionAtPath(UNKNOWN_NON_ACCESSOR_PATH, NODE_INTERACTION_UNKNOWN_ASSIGNMENT, context));
7160
6544
  }
7161
6545
  }
7162
6546
  };
@@ -7973,227 +7357,691 @@ const knownGlobals = {
7973
7357
  for (const global of ['window', 'global', 'self', 'globalThis']) {
7974
7358
  knownGlobals[global] = knownGlobals;
7975
7359
  }
7976
- function getGlobalAtPath(path) {
7977
- let currentGlobal = knownGlobals;
7978
- for (const pathSegment of path) {
7979
- if (typeof pathSegment !== 'string') {
7980
- return null;
7360
+ function getGlobalAtPath(path) {
7361
+ let currentGlobal = knownGlobals;
7362
+ for (const pathSegment of path) {
7363
+ if (typeof pathSegment !== 'string') {
7364
+ return null;
7365
+ }
7366
+ currentGlobal = currentGlobal[pathSegment];
7367
+ if (!currentGlobal) {
7368
+ return null;
7369
+ }
7370
+ }
7371
+ return currentGlobal[ValueProperties];
7372
+ }
7373
+
7374
+ class GlobalVariable extends Variable {
7375
+ constructor() {
7376
+ super(...arguments);
7377
+ // Ensure we use live-bindings for globals as we do not know if they have
7378
+ // been reassigned
7379
+ this.isReassigned = true;
7380
+ }
7381
+ getLiteralValueAtPath(path, _recursionTracker, _origin) {
7382
+ return getGlobalAtPath([this.name, ...path]) ? UnknownTruthyValue : UnknownValue;
7383
+ }
7384
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
7385
+ switch (interaction.type) {
7386
+ case INTERACTION_ACCESSED:
7387
+ if (path.length === 0) {
7388
+ // Technically, "undefined" is a global variable of sorts
7389
+ return this.name !== 'undefined' && !getGlobalAtPath([this.name]);
7390
+ }
7391
+ return !getGlobalAtPath([this.name, ...path].slice(0, -1));
7392
+ case INTERACTION_ASSIGNED:
7393
+ return true;
7394
+ case INTERACTION_CALLED: {
7395
+ const globalAtPath = getGlobalAtPath([this.name, ...path]);
7396
+ return !globalAtPath || globalAtPath.hasEffectsWhenCalled(interaction, context);
7397
+ }
7398
+ }
7399
+ }
7400
+ }
7401
+
7402
+ const tdzVariableKinds = {
7403
+ __proto__: null,
7404
+ class: true,
7405
+ const: true,
7406
+ let: true,
7407
+ var: true
7408
+ };
7409
+ class Identifier extends NodeBase {
7410
+ constructor() {
7411
+ super(...arguments);
7412
+ this.variable = null;
7413
+ this.isTDZAccess = null;
7414
+ }
7415
+ addExportedVariables(variables, exportNamesByVariable) {
7416
+ if (exportNamesByVariable.has(this.variable)) {
7417
+ variables.push(this.variable);
7418
+ }
7419
+ }
7420
+ bind() {
7421
+ if (!this.variable && is_reference(this, this.parent)) {
7422
+ this.variable = this.scope.findVariable(this.name);
7423
+ this.variable.addReference(this);
7424
+ }
7425
+ }
7426
+ declare(kind, init) {
7427
+ let variable;
7428
+ const { treeshake } = this.context.options;
7429
+ switch (kind) {
7430
+ case 'var':
7431
+ variable = this.scope.addDeclaration(this, this.context, init, true);
7432
+ if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
7433
+ // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
7434
+ variable.markInitializersForDeoptimization();
7435
+ }
7436
+ break;
7437
+ case 'function':
7438
+ // in strict mode, functions are only hoisted within a scope but not across block scopes
7439
+ variable = this.scope.addDeclaration(this, this.context, init, false);
7440
+ break;
7441
+ case 'let':
7442
+ case 'const':
7443
+ case 'class':
7444
+ variable = this.scope.addDeclaration(this, this.context, init, false);
7445
+ break;
7446
+ case 'parameter':
7447
+ variable = this.scope.addParameterDeclaration(this);
7448
+ break;
7449
+ /* istanbul ignore next */
7450
+ default:
7451
+ /* istanbul ignore next */
7452
+ throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
7453
+ }
7454
+ variable.kind = kind;
7455
+ return [(this.variable = variable)];
7456
+ }
7457
+ deoptimizePath(path) {
7458
+ var _a;
7459
+ if (path.length === 0 && !this.scope.contains(this.name)) {
7460
+ this.disallowImportReassignment();
7461
+ }
7462
+ // We keep conditional chaining because an unknown Node could have an
7463
+ // Identifier as property that might be deoptimized by default
7464
+ (_a = this.variable) === null || _a === void 0 ? void 0 : _a.deoptimizePath(path);
7465
+ }
7466
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
7467
+ this.variable.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
7468
+ }
7469
+ getLiteralValueAtPath(path, recursionTracker, origin) {
7470
+ return this.getVariableRespectingTDZ().getLiteralValueAtPath(path, recursionTracker, origin);
7471
+ }
7472
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
7473
+ return this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
7474
+ }
7475
+ hasEffects(context) {
7476
+ if (!this.deoptimized)
7477
+ this.applyDeoptimizations();
7478
+ if (this.isPossibleTDZ() && this.variable.kind !== 'var') {
7479
+ return true;
7480
+ }
7481
+ return (this.context.options.treeshake.unknownGlobalSideEffects &&
7482
+ this.variable instanceof GlobalVariable &&
7483
+ this.variable.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context));
7484
+ }
7485
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
7486
+ switch (interaction.type) {
7487
+ case INTERACTION_ACCESSED:
7488
+ return (this.variable !== null &&
7489
+ this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));
7490
+ case INTERACTION_ASSIGNED:
7491
+ return (path.length > 0 ? this.getVariableRespectingTDZ() : this.variable).hasEffectsOnInteractionAtPath(path, interaction, context);
7492
+ case INTERACTION_CALLED:
7493
+ return this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context);
7494
+ }
7495
+ }
7496
+ include() {
7497
+ if (!this.deoptimized)
7498
+ this.applyDeoptimizations();
7499
+ if (!this.included) {
7500
+ this.included = true;
7501
+ if (this.variable !== null) {
7502
+ this.context.includeVariableInModule(this.variable);
7503
+ }
7504
+ }
7505
+ }
7506
+ includeCallArguments(context, args) {
7507
+ this.variable.includeCallArguments(context, args);
7508
+ }
7509
+ isPossibleTDZ() {
7510
+ // return cached value to avoid issues with the next tree-shaking pass
7511
+ if (this.isTDZAccess !== null)
7512
+ return this.isTDZAccess;
7513
+ if (!(this.variable instanceof LocalVariable) ||
7514
+ !this.variable.kind ||
7515
+ !(this.variable.kind in tdzVariableKinds)) {
7516
+ return (this.isTDZAccess = false);
7517
+ }
7518
+ let decl_id;
7519
+ if (this.variable.declarations &&
7520
+ this.variable.declarations.length === 1 &&
7521
+ (decl_id = this.variable.declarations[0]) &&
7522
+ this.start < decl_id.start &&
7523
+ closestParentFunctionOrProgram(this) === closestParentFunctionOrProgram(decl_id)) {
7524
+ // a variable accessed before its declaration
7525
+ // in the same function or at top level of module
7526
+ return (this.isTDZAccess = true);
7527
+ }
7528
+ if (!this.variable.initReached) {
7529
+ // Either a const/let TDZ violation or
7530
+ // var use before declaration was encountered.
7531
+ return (this.isTDZAccess = true);
7532
+ }
7533
+ return (this.isTDZAccess = false);
7534
+ }
7535
+ markDeclarationReached() {
7536
+ this.variable.initReached = true;
7537
+ }
7538
+ render(code, { snippets: { getPropertyAccess } }, { renderedParentType, isCalleeOfRenderedParent, isShorthandProperty } = BLANK) {
7539
+ if (this.variable) {
7540
+ const name = this.variable.getName(getPropertyAccess);
7541
+ if (name !== this.name) {
7542
+ code.overwrite(this.start, this.end, name, {
7543
+ contentOnly: true,
7544
+ storeName: true
7545
+ });
7546
+ if (isShorthandProperty) {
7547
+ code.prependRight(this.start, `${this.name}: `);
7548
+ }
7549
+ }
7550
+ // In strict mode, any variable named "eval" must be the actual "eval" function
7551
+ if (name === 'eval' &&
7552
+ renderedParentType === CallExpression$1 &&
7553
+ isCalleeOfRenderedParent) {
7554
+ code.appendRight(this.start, '0, ');
7555
+ }
7556
+ }
7557
+ }
7558
+ applyDeoptimizations() {
7559
+ this.deoptimized = true;
7560
+ if (this.variable instanceof LocalVariable) {
7561
+ this.variable.consolidateInitializers();
7562
+ this.context.requestTreeshakingPass();
7563
+ }
7564
+ }
7565
+ disallowImportReassignment() {
7566
+ return this.context.error({
7567
+ code: 'ILLEGAL_REASSIGNMENT',
7568
+ message: `Illegal reassignment to import '${this.name}'`
7569
+ }, this.start);
7570
+ }
7571
+ getVariableRespectingTDZ() {
7572
+ if (this.isPossibleTDZ()) {
7573
+ return UNKNOWN_EXPRESSION;
7574
+ }
7575
+ return this.variable;
7576
+ }
7577
+ }
7578
+ function closestParentFunctionOrProgram(node) {
7579
+ while (node && !/^Program|Function/.test(node.type)) {
7580
+ node = node.parent;
7581
+ }
7582
+ // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program
7583
+ return node;
7584
+ }
7585
+
7586
+ function treeshakeNode(node, code, start, end) {
7587
+ code.remove(start, end);
7588
+ if (node.annotations) {
7589
+ for (const annotation of node.annotations) {
7590
+ if (annotation.start < start) {
7591
+ code.remove(annotation.start, annotation.end);
7592
+ }
7593
+ else {
7594
+ return;
7595
+ }
7596
+ }
7597
+ }
7598
+ }
7599
+ function removeAnnotations(node, code) {
7600
+ if (!node.annotations && node.parent.type === ExpressionStatement$1) {
7601
+ node = node.parent;
7602
+ }
7603
+ if (node.annotations) {
7604
+ for (const annotation of node.annotations) {
7605
+ code.remove(annotation.start, annotation.end);
7606
+ }
7607
+ }
7608
+ }
7609
+
7610
+ const NO_SEMICOLON = { isNoStatement: true };
7611
+ // This assumes there are only white-space and comments between start and the string we are looking for
7612
+ function findFirstOccurrenceOutsideComment(code, searchString, start = 0) {
7613
+ let searchPos, charCodeAfterSlash;
7614
+ searchPos = code.indexOf(searchString, start);
7615
+ while (true) {
7616
+ start = code.indexOf('/', start);
7617
+ if (start === -1 || start >= searchPos)
7618
+ return searchPos;
7619
+ charCodeAfterSlash = code.charCodeAt(++start);
7620
+ ++start;
7621
+ // With our assumption, '/' always starts a comment. Determine comment type:
7622
+ start =
7623
+ charCodeAfterSlash === 47 /*"/"*/
7624
+ ? code.indexOf('\n', start) + 1
7625
+ : code.indexOf('*/', start) + 2;
7626
+ if (start > searchPos) {
7627
+ searchPos = code.indexOf(searchString, start);
7628
+ }
7629
+ }
7630
+ }
7631
+ const NON_WHITESPACE = /\S/g;
7632
+ function findNonWhiteSpace(code, index) {
7633
+ NON_WHITESPACE.lastIndex = index;
7634
+ const result = NON_WHITESPACE.exec(code);
7635
+ return result.index;
7636
+ }
7637
+ // This assumes "code" only contains white-space and comments
7638
+ // Returns position of line-comment if applicable
7639
+ function findFirstLineBreakOutsideComment(code) {
7640
+ let lineBreakPos, charCodeAfterSlash, start = 0;
7641
+ lineBreakPos = code.indexOf('\n', start);
7642
+ while (true) {
7643
+ start = code.indexOf('/', start);
7644
+ if (start === -1 || start > lineBreakPos)
7645
+ return [lineBreakPos, lineBreakPos + 1];
7646
+ // With our assumption, '/' always starts a comment. Determine comment type:
7647
+ charCodeAfterSlash = code.charCodeAt(start + 1);
7648
+ if (charCodeAfterSlash === 47 /*"/"*/)
7649
+ return [start, lineBreakPos + 1];
7650
+ start = code.indexOf('*/', start + 3) + 2;
7651
+ if (start > lineBreakPos) {
7652
+ lineBreakPos = code.indexOf('\n', start);
7653
+ }
7654
+ }
7655
+ }
7656
+ function renderStatementList(statements, code, start, end, options) {
7657
+ let currentNode, currentNodeStart, currentNodeNeedsBoundaries, nextNodeStart;
7658
+ let nextNode = statements[0];
7659
+ let nextNodeNeedsBoundaries = !nextNode.included || nextNode.needsBoundaries;
7660
+ if (nextNodeNeedsBoundaries) {
7661
+ nextNodeStart =
7662
+ start + findFirstLineBreakOutsideComment(code.original.slice(start, nextNode.start))[1];
7663
+ }
7664
+ for (let nextIndex = 1; nextIndex <= statements.length; nextIndex++) {
7665
+ currentNode = nextNode;
7666
+ currentNodeStart = nextNodeStart;
7667
+ currentNodeNeedsBoundaries = nextNodeNeedsBoundaries;
7668
+ nextNode = statements[nextIndex];
7669
+ nextNodeNeedsBoundaries =
7670
+ nextNode === undefined ? false : !nextNode.included || nextNode.needsBoundaries;
7671
+ if (currentNodeNeedsBoundaries || nextNodeNeedsBoundaries) {
7672
+ nextNodeStart =
7673
+ currentNode.end +
7674
+ findFirstLineBreakOutsideComment(code.original.slice(currentNode.end, nextNode === undefined ? end : nextNode.start))[1];
7675
+ if (currentNode.included) {
7676
+ currentNodeNeedsBoundaries
7677
+ ? currentNode.render(code, options, {
7678
+ end: nextNodeStart,
7679
+ start: currentNodeStart
7680
+ })
7681
+ : currentNode.render(code, options);
7682
+ }
7683
+ else {
7684
+ treeshakeNode(currentNode, code, currentNodeStart, nextNodeStart);
7685
+ }
7686
+ }
7687
+ else {
7688
+ currentNode.render(code, options);
7689
+ }
7690
+ }
7691
+ }
7692
+ // This assumes that the first character is not part of the first node
7693
+ function getCommaSeparatedNodesWithBoundaries(nodes, code, start, end) {
7694
+ const splitUpNodes = [];
7695
+ let node, nextNode, nextNodeStart, contentEnd, char;
7696
+ let separator = start - 1;
7697
+ for (let nextIndex = 0; nextIndex < nodes.length; nextIndex++) {
7698
+ nextNode = nodes[nextIndex];
7699
+ if (node !== undefined) {
7700
+ separator =
7701
+ node.end +
7702
+ findFirstOccurrenceOutsideComment(code.original.slice(node.end, nextNode.start), ',');
7703
+ }
7704
+ nextNodeStart = contentEnd =
7705
+ separator +
7706
+ 1 +
7707
+ findFirstLineBreakOutsideComment(code.original.slice(separator + 1, nextNode.start))[1];
7708
+ while (((char = code.original.charCodeAt(nextNodeStart)),
7709
+ char === 32 /*" "*/ || char === 9 /*"\t"*/ || char === 10 /*"\n"*/ || char === 13) /*"\r"*/)
7710
+ nextNodeStart++;
7711
+ if (node !== undefined) {
7712
+ splitUpNodes.push({
7713
+ contentEnd,
7714
+ end: nextNodeStart,
7715
+ node,
7716
+ separator,
7717
+ start
7718
+ });
7719
+ }
7720
+ node = nextNode;
7721
+ start = nextNodeStart;
7722
+ }
7723
+ splitUpNodes.push({
7724
+ contentEnd: end,
7725
+ end,
7726
+ node: node,
7727
+ separator: null,
7728
+ start
7729
+ });
7730
+ return splitUpNodes;
7731
+ }
7732
+ // This assumes there are only white-space and comments between start and end
7733
+ function removeLineBreaks(code, start, end) {
7734
+ while (true) {
7735
+ const [removeStart, removeEnd] = findFirstLineBreakOutsideComment(code.original.slice(start, end));
7736
+ if (removeStart === -1) {
7737
+ break;
7738
+ }
7739
+ code.remove(start + removeStart, (start += removeEnd));
7740
+ }
7741
+ }
7742
+
7743
+ class BlockScope extends ChildScope {
7744
+ addDeclaration(identifier, context, init, isHoisted) {
7745
+ if (isHoisted) {
7746
+ const variable = this.parent.addDeclaration(identifier, context, init, isHoisted);
7747
+ // Necessary to make sure the init is deoptimized for conditional declarations.
7748
+ // We cannot call deoptimizePath here.
7749
+ variable.markInitializersForDeoptimization();
7750
+ return variable;
7981
7751
  }
7982
- currentGlobal = currentGlobal[pathSegment];
7983
- if (!currentGlobal) {
7984
- return null;
7752
+ else {
7753
+ return super.addDeclaration(identifier, context, init, false);
7985
7754
  }
7986
7755
  }
7987
- return currentGlobal[ValueProperties];
7988
7756
  }
7989
7757
 
7990
- class GlobalVariable extends Variable {
7758
+ class ExpressionStatement extends NodeBase {
7759
+ initialise() {
7760
+ if (this.directive &&
7761
+ this.directive !== 'use strict' &&
7762
+ this.parent.type === Program$1) {
7763
+ this.context.warn(
7764
+ // This is necessary, because either way (deleting or not) can lead to errors.
7765
+ {
7766
+ code: 'MODULE_LEVEL_DIRECTIVE',
7767
+ message: `Module level directives cause errors when bundled, '${this.directive}' was ignored.`
7768
+ }, this.start);
7769
+ }
7770
+ }
7771
+ render(code, options) {
7772
+ super.render(code, options);
7773
+ if (this.included)
7774
+ this.insertSemicolon(code);
7775
+ }
7776
+ shouldBeIncluded(context) {
7777
+ if (this.directive && this.directive !== 'use strict')
7778
+ return this.parent.type !== Program$1;
7779
+ return super.shouldBeIncluded(context);
7780
+ }
7781
+ applyDeoptimizations() { }
7782
+ }
7783
+
7784
+ class BlockStatement extends NodeBase {
7991
7785
  constructor() {
7992
7786
  super(...arguments);
7993
- // Ensure we use live-bindings for globals as we do not know if they have
7994
- // been reassigned
7995
- this.isReassigned = true;
7787
+ this.directlyIncluded = false;
7996
7788
  }
7997
- getLiteralValueAtPath(path, _recursionTracker, _origin) {
7998
- return getGlobalAtPath([this.name, ...path]) ? UnknownTruthyValue : UnknownValue;
7789
+ addImplicitReturnExpressionToScope() {
7790
+ const lastStatement = this.body[this.body.length - 1];
7791
+ if (!lastStatement || lastStatement.type !== ReturnStatement$1) {
7792
+ this.scope.addReturnExpression(UNKNOWN_EXPRESSION);
7793
+ }
7999
7794
  }
8000
- hasEffectsWhenAccessedAtPath(path) {
8001
- if (path.length === 0) {
8002
- // Technically, "undefined" is a global variable of sorts
8003
- return this.name !== 'undefined' && !getGlobalAtPath([this.name]);
7795
+ createScope(parentScope) {
7796
+ this.scope = this.parent.preventChildBlockScope
7797
+ ? parentScope
7798
+ : new BlockScope(parentScope);
7799
+ }
7800
+ hasEffects(context) {
7801
+ if (this.deoptimizeBody)
7802
+ return true;
7803
+ for (const node of this.body) {
7804
+ if (context.brokenFlow)
7805
+ break;
7806
+ if (node.hasEffects(context))
7807
+ return true;
7808
+ }
7809
+ return false;
7810
+ }
7811
+ include(context, includeChildrenRecursively) {
7812
+ if (!(this.deoptimizeBody && this.directlyIncluded)) {
7813
+ this.included = true;
7814
+ this.directlyIncluded = true;
7815
+ if (this.deoptimizeBody)
7816
+ includeChildrenRecursively = true;
7817
+ for (const node of this.body) {
7818
+ if (includeChildrenRecursively || node.shouldBeIncluded(context))
7819
+ node.include(context, includeChildrenRecursively);
7820
+ }
8004
7821
  }
8005
- return !getGlobalAtPath([this.name, ...path].slice(0, -1));
8006
7822
  }
8007
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
8008
- const globalAtPath = getGlobalAtPath([this.name, ...path]);
8009
- return !globalAtPath || globalAtPath.hasEffectsWhenCalled(callOptions, context);
7823
+ initialise() {
7824
+ const firstBodyStatement = this.body[0];
7825
+ this.deoptimizeBody =
7826
+ firstBodyStatement instanceof ExpressionStatement &&
7827
+ firstBodyStatement.directive === 'use asm';
7828
+ }
7829
+ render(code, options) {
7830
+ if (this.body.length) {
7831
+ renderStatementList(this.body, code, this.start + 1, this.end - 1, options);
7832
+ }
7833
+ else {
7834
+ super.render(code, options);
7835
+ }
8010
7836
  }
8011
7837
  }
8012
7838
 
8013
- const tdzVariableKinds = {
8014
- __proto__: null,
8015
- class: true,
8016
- const: true,
8017
- let: true,
8018
- var: true
8019
- };
8020
- class Identifier extends NodeBase {
7839
+ class RestElement extends NodeBase {
8021
7840
  constructor() {
8022
7841
  super(...arguments);
8023
- this.variable = null;
8024
- this.isTDZAccess = null;
7842
+ this.declarationInit = null;
8025
7843
  }
8026
7844
  addExportedVariables(variables, exportNamesByVariable) {
8027
- if (exportNamesByVariable.has(this.variable)) {
8028
- variables.push(this.variable);
8029
- }
8030
- }
8031
- bind() {
8032
- if (!this.variable && is_reference(this, this.parent)) {
8033
- this.variable = this.scope.findVariable(this.name);
8034
- this.variable.addReference(this);
8035
- }
7845
+ this.argument.addExportedVariables(variables, exportNamesByVariable);
8036
7846
  }
8037
7847
  declare(kind, init) {
8038
- let variable;
8039
- const { treeshake } = this.context.options;
8040
- switch (kind) {
8041
- case 'var':
8042
- variable = this.scope.addDeclaration(this, this.context, init, true);
8043
- if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
8044
- // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
8045
- variable.markInitializersForDeoptimization();
8046
- }
8047
- break;
8048
- case 'function':
8049
- // in strict mode, functions are only hoisted within a scope but not across block scopes
8050
- variable = this.scope.addDeclaration(this, this.context, init, false);
8051
- break;
8052
- case 'let':
8053
- case 'const':
8054
- case 'class':
8055
- variable = this.scope.addDeclaration(this, this.context, init, false);
8056
- break;
8057
- case 'parameter':
8058
- variable = this.scope.addParameterDeclaration(this);
8059
- break;
8060
- /* istanbul ignore next */
8061
- default:
8062
- /* istanbul ignore next */
8063
- throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
7848
+ this.declarationInit = init;
7849
+ return this.argument.declare(kind, UNKNOWN_EXPRESSION);
7850
+ }
7851
+ deoptimizePath(path) {
7852
+ path.length === 0 && this.argument.deoptimizePath(EMPTY_PATH);
7853
+ }
7854
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
7855
+ return (path.length > 0 ||
7856
+ this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
7857
+ }
7858
+ markDeclarationReached() {
7859
+ this.argument.markDeclarationReached();
7860
+ }
7861
+ applyDeoptimizations() {
7862
+ this.deoptimized = true;
7863
+ if (this.declarationInit !== null) {
7864
+ this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
7865
+ this.context.requestTreeshakingPass();
8064
7866
  }
8065
- variable.kind = kind;
8066
- return [(this.variable = variable)];
8067
7867
  }
8068
- deoptimizeCallParameters() {
8069
- this.variable.deoptimizeCallParameters();
7868
+ }
7869
+
7870
+ class FunctionBase extends NodeBase {
7871
+ constructor() {
7872
+ super(...arguments);
7873
+ this.objectEntity = null;
7874
+ this.deoptimizedReturn = false;
8070
7875
  }
8071
7876
  deoptimizePath(path) {
8072
- var _a;
8073
- if (path.length === 0 && !this.scope.contains(this.name)) {
8074
- this.disallowImportReassignment();
7877
+ this.getObjectEntity().deoptimizePath(path);
7878
+ if (path.length === 1 && path[0] === UnknownKey) {
7879
+ // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
7880
+ // which means the return expression needs to be reassigned
7881
+ this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
8075
7882
  }
8076
- // We keep conditional chaining because an unknown Node could have an
8077
- // Identifier as property that might be deoptimized by default
8078
- (_a = this.variable) === null || _a === void 0 ? void 0 : _a.deoptimizePath(path);
8079
7883
  }
8080
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
8081
- this.variable.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
7884
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
7885
+ if (path.length > 0) {
7886
+ this.getObjectEntity().deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
7887
+ }
8082
7888
  }
8083
7889
  getLiteralValueAtPath(path, recursionTracker, origin) {
8084
- return this.getVariableRespectingTDZ().getLiteralValueAtPath(path, recursionTracker, origin);
7890
+ return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);
8085
7891
  }
8086
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
8087
- return this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
7892
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
7893
+ if (path.length > 0) {
7894
+ return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
7895
+ }
7896
+ if (this.async) {
7897
+ if (!this.deoptimizedReturn) {
7898
+ this.deoptimizedReturn = true;
7899
+ this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
7900
+ this.context.requestTreeshakingPass();
7901
+ }
7902
+ return UNKNOWN_EXPRESSION;
7903
+ }
7904
+ return this.scope.getReturnExpression();
8088
7905
  }
8089
- hasEffects() {
7906
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
7907
+ if (path.length > 0 || interaction.type !== INTERACTION_CALLED) {
7908
+ return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
7909
+ }
7910
+ if (this.async) {
7911
+ const { propertyReadSideEffects } = this.context.options
7912
+ .treeshake;
7913
+ const returnExpression = this.scope.getReturnExpression();
7914
+ if (returnExpression.hasEffectsOnInteractionAtPath(['then'], NODE_INTERACTION_UNKNOWN_CALL, context) ||
7915
+ (propertyReadSideEffects &&
7916
+ (propertyReadSideEffects === 'always' ||
7917
+ returnExpression.hasEffectsOnInteractionAtPath(['then'], NODE_INTERACTION_UNKNOWN_ACCESS, context)))) {
7918
+ return true;
7919
+ }
7920
+ }
7921
+ for (const param of this.params) {
7922
+ if (param.hasEffects(context))
7923
+ return true;
7924
+ }
7925
+ return false;
7926
+ }
7927
+ include(context, includeChildrenRecursively) {
8090
7928
  if (!this.deoptimized)
8091
7929
  this.applyDeoptimizations();
8092
- if (this.isPossibleTDZ() && this.variable.kind !== 'var') {
8093
- return true;
7930
+ this.included = true;
7931
+ const { brokenFlow } = context;
7932
+ context.brokenFlow = BROKEN_FLOW_NONE;
7933
+ this.body.include(context, includeChildrenRecursively);
7934
+ context.brokenFlow = brokenFlow;
7935
+ }
7936
+ includeCallArguments(context, args) {
7937
+ this.scope.includeCallArguments(context, args);
7938
+ }
7939
+ initialise() {
7940
+ this.scope.addParameterVariables(this.params.map(param => param.declare('parameter', UNKNOWN_EXPRESSION)), this.params[this.params.length - 1] instanceof RestElement);
7941
+ if (this.body instanceof BlockStatement) {
7942
+ this.body.addImplicitReturnExpressionToScope();
7943
+ }
7944
+ else {
7945
+ this.scope.addReturnExpression(this.body);
8094
7946
  }
8095
- return (this.context.options.treeshake.unknownGlobalSideEffects &&
8096
- this.variable instanceof GlobalVariable &&
8097
- this.variable.hasEffectsWhenAccessedAtPath(EMPTY_PATH));
8098
7947
  }
8099
- hasEffectsWhenAccessedAtPath(path, context) {
8100
- return (this.variable !== null &&
8101
- this.getVariableRespectingTDZ().hasEffectsWhenAccessedAtPath(path, context));
7948
+ parseNode(esTreeNode) {
7949
+ if (esTreeNode.body.type === BlockStatement$1) {
7950
+ this.body = new BlockStatement(esTreeNode.body, this, this.scope.hoistedBodyVarScope);
7951
+ }
7952
+ super.parseNode(esTreeNode);
8102
7953
  }
8103
- hasEffectsWhenAssignedAtPath(path, context) {
8104
- return (path.length > 0 ? this.getVariableRespectingTDZ() : this.variable).hasEffectsWhenAssignedAtPath(path, context);
7954
+ applyDeoptimizations() { }
7955
+ }
7956
+ FunctionBase.prototype.preventChildBlockScope = true;
7957
+
7958
+ class ArrowFunctionExpression extends FunctionBase {
7959
+ constructor() {
7960
+ super(...arguments);
7961
+ this.objectEntity = null;
8105
7962
  }
8106
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
8107
- return this.getVariableRespectingTDZ().hasEffectsWhenCalledAtPath(path, callOptions, context);
7963
+ createScope(parentScope) {
7964
+ this.scope = new ReturnValueScope(parentScope, this.context);
8108
7965
  }
8109
- include() {
7966
+ hasEffects() {
8110
7967
  if (!this.deoptimized)
8111
7968
  this.applyDeoptimizations();
8112
- if (!this.included) {
8113
- this.included = true;
8114
- if (this.variable !== null) {
8115
- this.context.includeVariableInModule(this.variable);
8116
- }
8117
- }
8118
- }
8119
- includeCallArguments(context, args) {
8120
- this.variable.includeCallArguments(context, args);
7969
+ return false;
8121
7970
  }
8122
- isPossibleTDZ() {
8123
- // return cached value to avoid issues with the next tree-shaking pass
8124
- if (this.isTDZAccess !== null)
8125
- return this.isTDZAccess;
8126
- if (!(this.variable instanceof LocalVariable) ||
8127
- !this.variable.kind ||
8128
- !(this.variable.kind in tdzVariableKinds)) {
8129
- return (this.isTDZAccess = false);
8130
- }
8131
- let decl_id;
8132
- if (this.variable.declarations &&
8133
- this.variable.declarations.length === 1 &&
8134
- (decl_id = this.variable.declarations[0]) &&
8135
- this.start < decl_id.start &&
8136
- closestParentFunctionOrProgram(this) === closestParentFunctionOrProgram(decl_id)) {
8137
- // a variable accessed before its declaration
8138
- // in the same function or at top level of module
8139
- return (this.isTDZAccess = true);
8140
- }
8141
- if (!this.variable.initReached) {
8142
- // Either a const/let TDZ violation or
8143
- // var use before declaration was encountered.
8144
- return (this.isTDZAccess = true);
7971
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
7972
+ if (super.hasEffectsOnInteractionAtPath(path, interaction, context))
7973
+ return true;
7974
+ if (interaction.type === INTERACTION_CALLED) {
7975
+ const { ignore, brokenFlow } = context;
7976
+ context.ignore = {
7977
+ breaks: false,
7978
+ continues: false,
7979
+ labels: new Set(),
7980
+ returnYield: true
7981
+ };
7982
+ if (this.body.hasEffects(context))
7983
+ return true;
7984
+ context.ignore = ignore;
7985
+ context.brokenFlow = brokenFlow;
8145
7986
  }
8146
- return (this.isTDZAccess = false);
8147
- }
8148
- markDeclarationReached() {
8149
- this.variable.initReached = true;
7987
+ return false;
8150
7988
  }
8151
- render(code, { snippets: { getPropertyAccess } }, { renderedParentType, isCalleeOfRenderedParent, isShorthandProperty } = BLANK) {
8152
- if (this.variable) {
8153
- const name = this.variable.getName(getPropertyAccess);
8154
- if (name !== this.name) {
8155
- code.overwrite(this.start, this.end, name, {
8156
- contentOnly: true,
8157
- storeName: true
8158
- });
8159
- if (isShorthandProperty) {
8160
- code.prependRight(this.start, `${this.name}: `);
8161
- }
8162
- }
8163
- // In strict mode, any variable named "eval" must be the actual "eval" function
8164
- if (name === 'eval' &&
8165
- renderedParentType === CallExpression$1 &&
8166
- isCalleeOfRenderedParent) {
8167
- code.appendRight(this.start, '0, ');
7989
+ include(context, includeChildrenRecursively) {
7990
+ super.include(context, includeChildrenRecursively);
7991
+ for (const param of this.params) {
7992
+ if (!(param instanceof Identifier)) {
7993
+ param.include(context, includeChildrenRecursively);
8168
7994
  }
8169
7995
  }
8170
7996
  }
8171
- applyDeoptimizations() {
8172
- this.deoptimized = true;
8173
- if (this.variable instanceof LocalVariable) {
8174
- this.variable.consolidateInitializers();
8175
- this.context.requestTreeshakingPass();
7997
+ getObjectEntity() {
7998
+ if (this.objectEntity !== null) {
7999
+ return this.objectEntity;
8176
8000
  }
8001
+ return (this.objectEntity = new ObjectEntity([], OBJECT_PROTOTYPE));
8177
8002
  }
8178
- disallowImportReassignment() {
8179
- return this.context.error({
8180
- code: 'ILLEGAL_REASSIGNMENT',
8181
- message: `Illegal reassignment to import '${this.name}'`
8182
- }, this.start);
8003
+ }
8004
+
8005
+ function getSystemExportStatement(exportedVariables, { exportNamesByVariable, snippets: { _, getObject, getPropertyAccess } }, modifier = '') {
8006
+ if (exportedVariables.length === 1 &&
8007
+ exportNamesByVariable.get(exportedVariables[0]).length === 1) {
8008
+ const variable = exportedVariables[0];
8009
+ return `exports('${exportNamesByVariable.get(variable)}',${_}${variable.getName(getPropertyAccess)}${modifier})`;
8183
8010
  }
8184
- getVariableRespectingTDZ() {
8185
- if (this.isPossibleTDZ()) {
8186
- return UNKNOWN_EXPRESSION;
8011
+ else {
8012
+ const fields = [];
8013
+ for (const variable of exportedVariables) {
8014
+ for (const exportName of exportNamesByVariable.get(variable)) {
8015
+ fields.push([exportName, variable.getName(getPropertyAccess) + modifier]);
8016
+ }
8187
8017
  }
8188
- return this.variable;
8018
+ return `exports(${getObject(fields, { lineBreakIndent: null })})`;
8189
8019
  }
8190
8020
  }
8191
- function closestParentFunctionOrProgram(node) {
8192
- while (node && !/^Program|Function/.test(node.type)) {
8193
- node = node.parent;
8021
+ function renderSystemExportExpression(exportedVariable, expressionStart, expressionEnd, code, { exportNamesByVariable, snippets: { _ } }) {
8022
+ code.prependRight(expressionStart, `exports('${exportNamesByVariable.get(exportedVariable)}',${_}`);
8023
+ code.appendLeft(expressionEnd, ')');
8024
+ }
8025
+ function renderSystemExportFunction(exportedVariables, expressionStart, expressionEnd, needsParens, code, options) {
8026
+ const { _, getDirectReturnIifeLeft } = options.snippets;
8027
+ code.prependRight(expressionStart, getDirectReturnIifeLeft(['v'], `${getSystemExportStatement(exportedVariables, options)},${_}v`, { needsArrowReturnParens: true, needsWrappedFunction: needsParens }));
8028
+ code.appendLeft(expressionEnd, ')');
8029
+ }
8030
+ function renderSystemExportSequenceAfterExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options) {
8031
+ const { _, getPropertyAccess } = options.snippets;
8032
+ code.appendLeft(expressionEnd, `,${_}${getSystemExportStatement([exportedVariable], options)},${_}${exportedVariable.getName(getPropertyAccess)}`);
8033
+ if (needsParens) {
8034
+ code.prependRight(expressionStart, '(');
8035
+ code.appendLeft(expressionEnd, ')');
8036
+ }
8037
+ }
8038
+ function renderSystemExportSequenceBeforeExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options, modifier) {
8039
+ const { _ } = options.snippets;
8040
+ code.prependRight(expressionStart, `${getSystemExportStatement([exportedVariable], options, modifier)},${_}`);
8041
+ if (needsParens) {
8042
+ code.prependRight(expressionStart, '(');
8043
+ code.appendLeft(expressionEnd, ')');
8194
8044
  }
8195
- // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program
8196
- return node;
8197
8045
  }
8198
8046
 
8199
8047
  class ObjectPattern extends NodeBase {
@@ -8221,11 +8069,12 @@ class ObjectPattern extends NodeBase {
8221
8069
  }
8222
8070
  }
8223
8071
  }
8224
- hasEffectsWhenAssignedAtPath(path, context) {
8225
- if (path.length > 0)
8226
- return true;
8072
+ hasEffectsOnInteractionAtPath(
8073
+ // At the moment, this is only triggered for assignment left-hand sides,
8074
+ // where the path is empty
8075
+ _path, interaction, context) {
8227
8076
  for (const property of this.properties) {
8228
- if (property.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context))
8077
+ if (property.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context))
8229
8078
  return true;
8230
8079
  }
8231
8080
  return false;
@@ -8239,75 +8088,78 @@ class ObjectPattern extends NodeBase {
8239
8088
 
8240
8089
  class AssignmentExpression extends NodeBase {
8241
8090
  hasEffects(context) {
8242
- if (!this.deoptimized)
8091
+ const { deoptimized, left, right } = this;
8092
+ if (!deoptimized)
8243
8093
  this.applyDeoptimizations();
8244
- return (this.right.hasEffects(context) ||
8245
- this.left.hasEffects(context) ||
8246
- this.left.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context));
8094
+ // MemberExpressions do not access the property before assignments if the
8095
+ // operator is '='.
8096
+ return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, this.operator !== '='));
8247
8097
  }
8248
- hasEffectsWhenAccessedAtPath(path, context) {
8249
- return path.length > 0 && this.right.hasEffectsWhenAccessedAtPath(path, context);
8098
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
8099
+ return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);
8250
8100
  }
8251
8101
  include(context, includeChildrenRecursively) {
8252
- if (!this.deoptimized)
8102
+ const { deoptimized, left, right, operator } = this;
8103
+ if (!deoptimized)
8253
8104
  this.applyDeoptimizations();
8254
8105
  this.included = true;
8255
- let hasEffectsContext;
8256
8106
  if (includeChildrenRecursively ||
8257
- this.operator !== '=' ||
8258
- this.left.included ||
8259
- ((hasEffectsContext = createHasEffectsContext()),
8260
- this.left.hasEffects(hasEffectsContext) ||
8261
- this.left.hasEffectsWhenAssignedAtPath(EMPTY_PATH, hasEffectsContext))) {
8262
- this.left.include(context, includeChildrenRecursively);
8107
+ operator !== '=' ||
8108
+ left.included ||
8109
+ left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {
8110
+ left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');
8263
8111
  }
8264
- this.right.include(context, includeChildrenRecursively);
8112
+ right.include(context, includeChildrenRecursively);
8113
+ }
8114
+ initialise() {
8115
+ this.left.setAssignedValue(this.right);
8265
8116
  }
8266
8117
  render(code, options, { preventASI, renderedParentType, renderedSurroundingElement } = BLANK) {
8267
- if (this.left.included) {
8268
- this.left.render(code, options);
8269
- this.right.render(code, options);
8118
+ const { left, right, start, end, parent } = this;
8119
+ if (left.included) {
8120
+ left.render(code, options);
8121
+ right.render(code, options);
8270
8122
  }
8271
8123
  else {
8272
- const inclusionStart = findNonWhiteSpace(code.original, findFirstOccurrenceOutsideComment(code.original, '=', this.left.end) + 1);
8273
- code.remove(this.start, inclusionStart);
8124
+ const inclusionStart = findNonWhiteSpace(code.original, findFirstOccurrenceOutsideComment(code.original, '=', left.end) + 1);
8125
+ code.remove(start, inclusionStart);
8274
8126
  if (preventASI) {
8275
- removeLineBreaks(code, inclusionStart, this.right.start);
8127
+ removeLineBreaks(code, inclusionStart, right.start);
8276
8128
  }
8277
- this.right.render(code, options, {
8278
- renderedParentType: renderedParentType || this.parent.type,
8279
- renderedSurroundingElement: renderedSurroundingElement || this.parent.type
8129
+ right.render(code, options, {
8130
+ renderedParentType: renderedParentType || parent.type,
8131
+ renderedSurroundingElement: renderedSurroundingElement || parent.type
8280
8132
  });
8281
8133
  }
8282
8134
  if (options.format === 'system') {
8283
- if (this.left instanceof Identifier) {
8284
- const variable = this.left.variable;
8135
+ if (left instanceof Identifier) {
8136
+ const variable = left.variable;
8285
8137
  const exportNames = options.exportNamesByVariable.get(variable);
8286
8138
  if (exportNames) {
8287
8139
  if (exportNames.length === 1) {
8288
- renderSystemExportExpression(variable, this.start, this.end, code, options);
8140
+ renderSystemExportExpression(variable, start, end, code, options);
8289
8141
  }
8290
8142
  else {
8291
- renderSystemExportSequenceAfterExpression(variable, this.start, this.end, this.parent.type !== ExpressionStatement$1, code, options);
8143
+ renderSystemExportSequenceAfterExpression(variable, start, end, parent.type !== ExpressionStatement$1, code, options);
8292
8144
  }
8293
8145
  return;
8294
8146
  }
8295
8147
  }
8296
8148
  else {
8297
8149
  const systemPatternExports = [];
8298
- this.left.addExportedVariables(systemPatternExports, options.exportNamesByVariable);
8150
+ left.addExportedVariables(systemPatternExports, options.exportNamesByVariable);
8299
8151
  if (systemPatternExports.length > 0) {
8300
- renderSystemExportFunction(systemPatternExports, this.start, this.end, renderedSurroundingElement === ExpressionStatement$1, code, options);
8152
+ renderSystemExportFunction(systemPatternExports, start, end, renderedSurroundingElement === ExpressionStatement$1, code, options);
8301
8153
  return;
8302
8154
  }
8303
8155
  }
8304
8156
  }
8305
- if (this.left.included &&
8306
- this.left instanceof ObjectPattern &&
8157
+ if (left.included &&
8158
+ left instanceof ObjectPattern &&
8307
8159
  (renderedSurroundingElement === ExpressionStatement$1 ||
8308
8160
  renderedSurroundingElement === ArrowFunctionExpression$1)) {
8309
- code.appendRight(this.start, '(');
8310
- code.prependLeft(this.end, ')');
8161
+ code.appendRight(start, '(');
8162
+ code.prependLeft(end, ')');
8311
8163
  }
8312
8164
  }
8313
8165
  applyDeoptimizations() {
@@ -8318,18 +8170,40 @@ class AssignmentExpression extends NodeBase {
8318
8170
  }
8319
8171
  }
8320
8172
 
8173
+ class AssignmentPattern extends NodeBase {
8174
+ addExportedVariables(variables, exportNamesByVariable) {
8175
+ this.left.addExportedVariables(variables, exportNamesByVariable);
8176
+ }
8177
+ declare(kind, init) {
8178
+ return this.left.declare(kind, init);
8179
+ }
8180
+ deoptimizePath(path) {
8181
+ path.length === 0 && this.left.deoptimizePath(path);
8182
+ }
8183
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
8184
+ return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
8185
+ }
8186
+ markDeclarationReached() {
8187
+ this.left.markDeclarationReached();
8188
+ }
8189
+ render(code, options, { isShorthandProperty } = BLANK) {
8190
+ this.left.render(code, options, { isShorthandProperty });
8191
+ this.right.render(code, options);
8192
+ }
8193
+ applyDeoptimizations() {
8194
+ this.deoptimized = true;
8195
+ this.left.deoptimizePath(EMPTY_PATH);
8196
+ this.right.deoptimizePath(UNKNOWN_PATH);
8197
+ this.context.requestTreeshakingPass();
8198
+ }
8199
+ }
8200
+
8321
8201
  class ArgumentsVariable extends LocalVariable {
8322
8202
  constructor(context) {
8323
8203
  super('arguments', null, UNKNOWN_EXPRESSION, context);
8324
8204
  }
8325
- hasEffectsWhenAccessedAtPath(path) {
8326
- return path.length > 1;
8327
- }
8328
- hasEffectsWhenAssignedAtPath() {
8329
- return true;
8330
- }
8331
- hasEffectsWhenCalledAtPath() {
8332
- return true;
8205
+ hasEffectsOnInteractionAtPath(path, { type }) {
8206
+ return type !== INTERACTION_ACCESSED || path.length > 1;
8333
8207
  }
8334
8208
  }
8335
8209
 
@@ -8345,8 +8219,8 @@ class ThisVariable extends LocalVariable {
8345
8219
  for (const path of this.deoptimizedPaths) {
8346
8220
  entity.deoptimizePath(path);
8347
8221
  }
8348
- for (const thisDeoptimization of this.thisDeoptimizationList) {
8349
- this.applyThisDeoptimizationEvent(entity, thisDeoptimization);
8222
+ for (const { interaction, path } of this.thisDeoptimizationList) {
8223
+ entity.deoptimizeThisOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
8350
8224
  }
8351
8225
  this.entitiesToBeDeoptimized.add(entity);
8352
8226
  }
@@ -8360,29 +8234,21 @@ class ThisVariable extends LocalVariable {
8360
8234
  entity.deoptimizePath(path);
8361
8235
  }
8362
8236
  }
8363
- deoptimizeThisOnEventAtPath(event, path, thisParameter) {
8237
+ deoptimizeThisOnInteractionAtPath(interaction, path) {
8364
8238
  const thisDeoptimization = {
8365
- event,
8366
- path,
8367
- thisParameter
8239
+ interaction,
8240
+ path
8368
8241
  };
8369
- if (!this.thisDeoptimizations.trackEntityAtPathAndGetIfTracked(path, event, thisParameter)) {
8242
+ if (!this.thisDeoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.type, interaction.thisArg)) {
8370
8243
  for (const entity of this.entitiesToBeDeoptimized) {
8371
- this.applyThisDeoptimizationEvent(entity, thisDeoptimization);
8244
+ entity.deoptimizeThisOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
8372
8245
  }
8373
8246
  this.thisDeoptimizationList.push(thisDeoptimization);
8374
8247
  }
8375
8248
  }
8376
- hasEffectsWhenAccessedAtPath(path, context) {
8377
- return (this.getInit(context).hasEffectsWhenAccessedAtPath(path, context) ||
8378
- super.hasEffectsWhenAccessedAtPath(path, context));
8379
- }
8380
- hasEffectsWhenAssignedAtPath(path, context) {
8381
- return (this.getInit(context).hasEffectsWhenAssignedAtPath(path, context) ||
8382
- super.hasEffectsWhenAssignedAtPath(path, context));
8383
- }
8384
- applyThisDeoptimizationEvent(entity, { event, path, thisParameter }) {
8385
- entity.deoptimizeThisOnEventAtPath(event, path, thisParameter === this ? entity : thisParameter, SHARED_RECURSION_TRACKER);
8249
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
8250
+ return (this.getInit(context).hasEffectsOnInteractionAtPath(path, interaction, context) ||
8251
+ super.hasEffectsOnInteractionAtPath(path, interaction, context));
8386
8252
  }
8387
8253
  getInit(context) {
8388
8254
  return context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION;
@@ -8418,50 +8284,56 @@ class FunctionNode extends FunctionBase {
8418
8284
  createScope(parentScope) {
8419
8285
  this.scope = new FunctionScope(parentScope, this.context);
8420
8286
  }
8421
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
8422
- super.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
8423
- if (event === EVENT_CALLED && path.length === 0) {
8424
- this.scope.thisVariable.addEntityToBeDeoptimized(thisParameter);
8287
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
8288
+ super.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
8289
+ if (interaction.type === INTERACTION_CALLED && path.length === 0) {
8290
+ this.scope.thisVariable.addEntityToBeDeoptimized(interaction.thisArg);
8425
8291
  }
8426
8292
  }
8427
- hasEffects() {
8293
+ hasEffects(context) {
8428
8294
  var _a;
8429
8295
  if (!this.deoptimized)
8430
8296
  this.applyDeoptimizations();
8431
- return !!((_a = this.id) === null || _a === void 0 ? void 0 : _a.hasEffects());
8297
+ return !!((_a = this.id) === null || _a === void 0 ? void 0 : _a.hasEffects(context));
8432
8298
  }
8433
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
8434
- if (super.hasEffectsWhenCalledAtPath(path, callOptions, context))
8435
- return true;
8436
- const thisInit = context.replacedVariableInits.get(this.scope.thisVariable);
8437
- context.replacedVariableInits.set(this.scope.thisVariable, callOptions.withNew
8438
- ? new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE)
8439
- : UNKNOWN_EXPRESSION);
8440
- const { brokenFlow, ignore } = context;
8441
- context.ignore = {
8442
- breaks: false,
8443
- continues: false,
8444
- labels: new Set(),
8445
- returnYield: true
8446
- };
8447
- if (this.body.hasEffects(context))
8299
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
8300
+ if (super.hasEffectsOnInteractionAtPath(path, interaction, context))
8448
8301
  return true;
8449
- context.brokenFlow = brokenFlow;
8450
- if (thisInit) {
8451
- context.replacedVariableInits.set(this.scope.thisVariable, thisInit);
8452
- }
8453
- else {
8454
- context.replacedVariableInits.delete(this.scope.thisVariable);
8302
+ if (interaction.type === INTERACTION_CALLED) {
8303
+ const thisInit = context.replacedVariableInits.get(this.scope.thisVariable);
8304
+ context.replacedVariableInits.set(this.scope.thisVariable, interaction.withNew
8305
+ ? new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE)
8306
+ : UNKNOWN_EXPRESSION);
8307
+ const { brokenFlow, ignore } = context;
8308
+ context.ignore = {
8309
+ breaks: false,
8310
+ continues: false,
8311
+ labels: new Set(),
8312
+ returnYield: true
8313
+ };
8314
+ if (this.body.hasEffects(context))
8315
+ return true;
8316
+ context.brokenFlow = brokenFlow;
8317
+ if (thisInit) {
8318
+ context.replacedVariableInits.set(this.scope.thisVariable, thisInit);
8319
+ }
8320
+ else {
8321
+ context.replacedVariableInits.delete(this.scope.thisVariable);
8322
+ }
8323
+ context.ignore = ignore;
8455
8324
  }
8456
- context.ignore = ignore;
8457
8325
  return false;
8458
8326
  }
8459
- include(context, includeChildrenRecursively, { includeWithoutParameterDefaults } = BLANK) {
8327
+ include(context, includeChildrenRecursively) {
8460
8328
  var _a;
8329
+ super.include(context, includeChildrenRecursively);
8461
8330
  (_a = this.id) === null || _a === void 0 ? void 0 : _a.include();
8462
- super.include(context, includeChildrenRecursively, {
8463
- includeWithoutParameterDefaults: includeWithoutParameterDefaults && !this.scope.argumentsVariable.included
8464
- });
8331
+ const hasArguments = this.scope.argumentsVariable.included;
8332
+ for (const param of this.params) {
8333
+ if (!(param instanceof Identifier) || hasArguments) {
8334
+ param.include(context, includeChildrenRecursively);
8335
+ }
8336
+ }
8465
8337
  }
8466
8338
  initialise() {
8467
8339
  var _a;
@@ -8552,12 +8424,13 @@ class BinaryExpression extends NodeBase {
8552
8424
  // support some implicit type coercion runtime errors
8553
8425
  if (this.operator === '+' &&
8554
8426
  this.parent instanceof ExpressionStatement &&
8555
- this.left.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) === '')
8427
+ this.left.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) === '') {
8556
8428
  return true;
8429
+ }
8557
8430
  return super.hasEffects(context);
8558
8431
  }
8559
- hasEffectsWhenAccessedAtPath(path) {
8560
- return path.length > 1;
8432
+ hasEffectsOnInteractionAtPath(path, { type }) {
8433
+ return type !== INTERACTION_ACCESSED || path.length > 1;
8561
8434
  }
8562
8435
  render(code, options, { renderedSurroundingElement } = BLANK) {
8563
8436
  this.left.render(code, options, { renderedSurroundingElement });
@@ -8590,8 +8463,33 @@ class BreakStatement extends NodeBase {
8590
8463
  }
8591
8464
  }
8592
8465
 
8466
+ function renderCallArguments(code, options, node) {
8467
+ if (node.arguments.length > 0) {
8468
+ if (node.arguments[node.arguments.length - 1].included) {
8469
+ for (const arg of node.arguments) {
8470
+ arg.render(code, options);
8471
+ }
8472
+ }
8473
+ else {
8474
+ let lastIncludedIndex = node.arguments.length - 2;
8475
+ while (lastIncludedIndex >= 0 && !node.arguments[lastIncludedIndex].included) {
8476
+ lastIncludedIndex--;
8477
+ }
8478
+ if (lastIncludedIndex >= 0) {
8479
+ for (let index = 0; index <= lastIncludedIndex; index++) {
8480
+ node.arguments[index].render(code, options);
8481
+ }
8482
+ code.remove(findFirstOccurrenceOutsideComment(code.original, ',', node.arguments[lastIncludedIndex].end), node.end - 1);
8483
+ }
8484
+ else {
8485
+ code.remove(findFirstOccurrenceOutsideComment(code.original, '(', node.callee.end) + 1, node.end - 1);
8486
+ }
8487
+ }
8488
+ }
8489
+ }
8490
+
8593
8491
  class Literal extends NodeBase {
8594
- deoptimizeThisOnEventAtPath() { }
8492
+ deoptimizeThisOnInteractionAtPath() { }
8595
8493
  getLiteralValueAtPath(path) {
8596
8494
  if (path.length > 0 ||
8597
8495
  // unknown literals can also be null but do not start with an "n"
@@ -8608,17 +8506,16 @@ class Literal extends NodeBase {
8608
8506
  return UNKNOWN_EXPRESSION;
8609
8507
  return getMemberReturnExpressionWhenCalled(this.members, path[0]);
8610
8508
  }
8611
- hasEffectsWhenAccessedAtPath(path) {
8612
- if (this.value === null) {
8613
- return path.length > 0;
8614
- }
8615
- return path.length > 1;
8616
- }
8617
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
8618
- if (path.length === 1) {
8619
- return hasMemberEffectWhenCalled(this.members, path[0], callOptions, context);
8509
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
8510
+ switch (interaction.type) {
8511
+ case INTERACTION_ACCESSED:
8512
+ return path.length > (this.value === null ? 0 : 1);
8513
+ case INTERACTION_ASSIGNED:
8514
+ return true;
8515
+ case INTERACTION_CALLED:
8516
+ return (path.length !== 1 ||
8517
+ hasMemberEffectWhenCalled(this.members, path[0], interaction, context));
8620
8518
  }
8621
- return true;
8622
8519
  }
8623
8520
  initialise() {
8624
8521
  this.members = getLiteralMembersForValue(this.value);
@@ -8676,6 +8573,7 @@ class MemberExpression extends NodeBase {
8676
8573
  constructor() {
8677
8574
  super(...arguments);
8678
8575
  this.variable = null;
8576
+ this.assignmentDeoptimized = false;
8679
8577
  this.bound = false;
8680
8578
  this.expressionsToBeDeoptimized = [];
8681
8579
  this.replacement = null;
@@ -8685,7 +8583,7 @@ class MemberExpression extends NodeBase {
8685
8583
  const path = getPathIfNotComputed(this);
8686
8584
  const baseVariable = path && this.scope.findVariable(path[0].key);
8687
8585
  if (baseVariable && baseVariable.isNamespace) {
8688
- const resolvedVariable = this.resolveNamespaceVariables(baseVariable, path.slice(1));
8586
+ const resolvedVariable = resolveNamespaceVariables(baseVariable, path.slice(1), this.context);
8689
8587
  if (!resolvedVariable) {
8690
8588
  super.bind();
8691
8589
  }
@@ -8726,21 +8624,21 @@ class MemberExpression extends NodeBase {
8726
8624
  }
8727
8625
  }
8728
8626
  }
8729
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
8627
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
8730
8628
  if (this.variable) {
8731
- this.variable.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
8629
+ this.variable.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
8732
8630
  }
8733
8631
  else if (!this.replacement) {
8734
8632
  if (path.length < MAX_PATH_DEPTH) {
8735
- this.object.deoptimizeThisOnEventAtPath(event, [this.getPropertyKey(), ...path], thisParameter, recursionTracker);
8633
+ this.object.deoptimizeThisOnInteractionAtPath(interaction, [this.getPropertyKey(), ...path], recursionTracker);
8736
8634
  }
8737
8635
  else {
8738
- thisParameter.deoptimizePath(UNKNOWN_PATH);
8636
+ interaction.thisArg.deoptimizePath(UNKNOWN_PATH);
8739
8637
  }
8740
8638
  }
8741
8639
  }
8742
8640
  getLiteralValueAtPath(path, recursionTracker, origin) {
8743
- if (this.variable !== null) {
8641
+ if (this.variable) {
8744
8642
  return this.variable.getLiteralValueAtPath(path, recursionTracker, origin);
8745
8643
  }
8746
8644
  if (this.replacement) {
@@ -8752,81 +8650,62 @@ class MemberExpression extends NodeBase {
8752
8650
  }
8753
8651
  return UnknownValue;
8754
8652
  }
8755
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
8756
- if (this.variable !== null) {
8757
- return this.variable.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
8653
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
8654
+ if (this.variable) {
8655
+ return this.variable.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
8758
8656
  }
8759
8657
  if (this.replacement) {
8760
8658
  return UNKNOWN_EXPRESSION;
8761
8659
  }
8762
8660
  this.expressionsToBeDeoptimized.push(origin);
8763
8661
  if (path.length < MAX_PATH_DEPTH) {
8764
- return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], callOptions, recursionTracker, origin);
8662
+ return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin);
8765
8663
  }
8766
8664
  return UNKNOWN_EXPRESSION;
8767
8665
  }
8768
8666
  hasEffects(context) {
8769
8667
  if (!this.deoptimized)
8770
8668
  this.applyDeoptimizations();
8771
- const { propertyReadSideEffects } = this.context.options
8772
- .treeshake;
8773
8669
  return (this.property.hasEffects(context) ||
8774
8670
  this.object.hasEffects(context) ||
8775
- // Assignments do not access the property before assigning
8776
- (!(this.variable ||
8777
- this.replacement ||
8778
- (this.parent instanceof AssignmentExpression && this.parent.operator === '=')) &&
8779
- propertyReadSideEffects &&
8780
- (propertyReadSideEffects === 'always' ||
8781
- this.object.hasEffectsWhenAccessedAtPath([this.getPropertyKey()], context))));
8782
- }
8783
- hasEffectsWhenAccessedAtPath(path, context) {
8784
- if (this.variable !== null) {
8785
- return this.variable.hasEffectsWhenAccessedAtPath(path, context);
8786
- }
8787
- if (this.replacement) {
8788
- return true;
8789
- }
8790
- if (path.length < MAX_PATH_DEPTH) {
8791
- return this.object.hasEffectsWhenAccessedAtPath([this.getPropertyKey(), ...path], context);
8792
- }
8793
- return true;
8671
+ this.hasAccessEffect(context));
8794
8672
  }
8795
- hasEffectsWhenAssignedAtPath(path, context) {
8796
- if (this.variable !== null) {
8797
- return this.variable.hasEffectsWhenAssignedAtPath(path, context);
8798
- }
8799
- if (this.replacement) {
8800
- return true;
8801
- }
8802
- if (path.length < MAX_PATH_DEPTH) {
8803
- return this.object.hasEffectsWhenAssignedAtPath([this.getPropertyKey(), ...path], context);
8804
- }
8805
- return true;
8673
+ hasEffectsAsAssignmentTarget(context, checkAccess) {
8674
+ if (checkAccess && !this.deoptimized)
8675
+ this.applyDeoptimizations();
8676
+ if (!this.assignmentDeoptimized)
8677
+ this.applyAssignmentDeoptimization();
8678
+ return (this.property.hasEffects(context) ||
8679
+ this.object.hasEffects(context) ||
8680
+ (checkAccess && this.hasAccessEffect(context)) ||
8681
+ this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));
8806
8682
  }
8807
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
8808
- if (this.variable !== null) {
8809
- return this.variable.hasEffectsWhenCalledAtPath(path, callOptions, context);
8683
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
8684
+ if (this.variable) {
8685
+ return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
8810
8686
  }
8811
8687
  if (this.replacement) {
8812
8688
  return true;
8813
8689
  }
8814
8690
  if (path.length < MAX_PATH_DEPTH) {
8815
- return this.object.hasEffectsWhenCalledAtPath([this.getPropertyKey(), ...path], callOptions, context);
8691
+ return this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey(), ...path], interaction, context);
8816
8692
  }
8817
8693
  return true;
8818
8694
  }
8819
8695
  include(context, includeChildrenRecursively) {
8820
8696
  if (!this.deoptimized)
8821
8697
  this.applyDeoptimizations();
8822
- if (!this.included) {
8823
- this.included = true;
8824
- if (this.variable !== null) {
8825
- this.context.includeVariableInModule(this.variable);
8826
- }
8698
+ this.includeProperties(context, includeChildrenRecursively);
8699
+ }
8700
+ includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {
8701
+ if (!this.assignmentDeoptimized)
8702
+ this.applyAssignmentDeoptimization();
8703
+ if (deoptimizeAccess) {
8704
+ this.include(context, includeChildrenRecursively);
8705
+ }
8706
+ else {
8707
+ this.includeProperties(context, includeChildrenRecursively);
8827
8708
  }
8828
- this.object.include(context, includeChildrenRecursively);
8829
- this.property.include(context, includeChildrenRecursively);
8830
8709
  }
8831
8710
  includeCallArguments(context, args) {
8832
8711
  if (this.variable) {
@@ -8838,6 +8717,7 @@ class MemberExpression extends NodeBase {
8838
8717
  }
8839
8718
  initialise() {
8840
8719
  this.propertyKey = getResolvablePropertyKey(this);
8720
+ this.accessInteraction = { thisArg: this.object, type: INTERACTION_ACCESSED };
8841
8721
  }
8842
8722
  render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = BLANK) {
8843
8723
  if (this.variable || this.replacement) {
@@ -8858,8 +8738,29 @@ class MemberExpression extends NodeBase {
8858
8738
  this.property.render(code, options);
8859
8739
  }
8860
8740
  }
8861
- applyDeoptimizations() {
8862
- this.deoptimized = true;
8741
+ setAssignedValue(value) {
8742
+ this.assignmentInteraction = {
8743
+ args: [value],
8744
+ thisArg: this.object,
8745
+ type: INTERACTION_ASSIGNED
8746
+ };
8747
+ }
8748
+ applyDeoptimizations() {
8749
+ this.deoptimized = true;
8750
+ const { propertyReadSideEffects } = this.context.options
8751
+ .treeshake;
8752
+ if (
8753
+ // Namespaces are not bound and should not be deoptimized
8754
+ this.bound &&
8755
+ propertyReadSideEffects &&
8756
+ !(this.variable || this.replacement)) {
8757
+ const propertyKey = this.getPropertyKey();
8758
+ this.object.deoptimizeThisOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER);
8759
+ this.context.requestTreeshakingPass();
8760
+ }
8761
+ }
8762
+ applyAssignmentDeoptimization() {
8763
+ this.assignmentDeoptimized = true;
8863
8764
  const { propertyReadSideEffects } = this.context.options
8864
8765
  .treeshake;
8865
8766
  if (
@@ -8867,13 +8768,7 @@ class MemberExpression extends NodeBase {
8867
8768
  this.bound &&
8868
8769
  propertyReadSideEffects &&
8869
8770
  !(this.variable || this.replacement)) {
8870
- // Regular Assignments do not access the property before assigning
8871
- if (!(this.parent instanceof AssignmentExpression && this.parent.operator === '=')) {
8872
- this.object.deoptimizeThisOnEventAtPath(EVENT_ACCESSED, [this.propertyKey], this.object, SHARED_RECURSION_TRACKER);
8873
- }
8874
- if (this.parent instanceof AssignmentExpression) {
8875
- this.object.deoptimizeThisOnEventAtPath(EVENT_ASSIGNED, [this.propertyKey], this.object, SHARED_RECURSION_TRACKER);
8876
- }
8771
+ this.object.deoptimizeThisOnInteractionAtPath(this.assignmentInteraction, [this.getPropertyKey()], SHARED_RECURSION_TRACKER);
8877
8772
  this.context.requestTreeshakingPass();
8878
8773
  }
8879
8774
  }
@@ -8899,28 +8794,46 @@ class MemberExpression extends NodeBase {
8899
8794
  }
8900
8795
  return this.propertyKey;
8901
8796
  }
8902
- resolveNamespaceVariables(baseVariable, path) {
8903
- if (path.length === 0)
8904
- return baseVariable;
8905
- if (!baseVariable.isNamespace || baseVariable instanceof ExternalVariable)
8906
- return null;
8907
- const exportName = path[0].key;
8908
- const variable = baseVariable.context.traceExport(exportName);
8909
- if (!variable) {
8910
- const fileName = baseVariable.context.fileName;
8911
- this.context.warn({
8912
- code: 'MISSING_EXPORT',
8913
- exporter: relativeId(fileName),
8914
- importer: relativeId(this.context.fileName),
8915
- message: `'${exportName}' is not exported by '${relativeId(fileName)}'`,
8916
- missing: exportName,
8917
- url: `https://rollupjs.org/guide/en/#error-name-is-not-exported-by-module`
8918
- }, path[0].pos);
8919
- return 'undefined';
8797
+ hasAccessEffect(context) {
8798
+ const { propertyReadSideEffects } = this.context.options
8799
+ .treeshake;
8800
+ return (!(this.variable || this.replacement) &&
8801
+ propertyReadSideEffects &&
8802
+ (propertyReadSideEffects === 'always' ||
8803
+ this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));
8804
+ }
8805
+ includeProperties(context, includeChildrenRecursively) {
8806
+ if (!this.included) {
8807
+ this.included = true;
8808
+ if (this.variable) {
8809
+ this.context.includeVariableInModule(this.variable);
8810
+ }
8920
8811
  }
8921
- return this.resolveNamespaceVariables(variable, path.slice(1));
8812
+ this.object.include(context, includeChildrenRecursively);
8813
+ this.property.include(context, includeChildrenRecursively);
8922
8814
  }
8923
8815
  }
8816
+ function resolveNamespaceVariables(baseVariable, path, astContext) {
8817
+ if (path.length === 0)
8818
+ return baseVariable;
8819
+ if (!baseVariable.isNamespace || baseVariable instanceof ExternalVariable)
8820
+ return null;
8821
+ const exportName = path[0].key;
8822
+ const variable = baseVariable.context.traceExport(exportName);
8823
+ if (!variable) {
8824
+ const fileName = baseVariable.context.fileName;
8825
+ astContext.warn({
8826
+ code: 'MISSING_EXPORT',
8827
+ exporter: relativeId(fileName),
8828
+ importer: relativeId(astContext.fileName),
8829
+ message: `'${exportName}' is not exported by '${relativeId(fileName)}'`,
8830
+ missing: exportName,
8831
+ url: `https://rollupjs.org/guide/en/#error-name-is-not-exported-by-module`
8832
+ }, path[0].pos);
8833
+ return 'undefined';
8834
+ }
8835
+ return resolveNamespaceVariables(variable, path.slice(1), astContext);
8836
+ }
8924
8837
 
8925
8838
  class CallExpressionBase extends NodeBase {
8926
8839
  constructor() {
@@ -8950,15 +8863,15 @@ class CallExpressionBase extends NodeBase {
8950
8863
  returnExpression.deoptimizePath(path);
8951
8864
  }
8952
8865
  }
8953
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
8866
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
8954
8867
  const returnExpression = this.getReturnExpression(recursionTracker);
8955
8868
  if (returnExpression === UNKNOWN_EXPRESSION) {
8956
- thisParameter.deoptimizePath(UNKNOWN_PATH);
8869
+ interaction.thisArg.deoptimizePath(UNKNOWN_PATH);
8957
8870
  }
8958
8871
  else {
8959
8872
  recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {
8960
- this.expressionsToBeDeoptimized.add(thisParameter);
8961
- returnExpression.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
8873
+ this.expressionsToBeDeoptimized.add(interaction.thisArg);
8874
+ returnExpression.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
8962
8875
  }, undefined);
8963
8876
  }
8964
8877
  }
@@ -8972,27 +8885,31 @@ class CallExpressionBase extends NodeBase {
8972
8885
  return returnExpression.getLiteralValueAtPath(path, recursionTracker, origin);
8973
8886
  }, UnknownValue);
8974
8887
  }
8975
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
8888
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
8976
8889
  const returnExpression = this.getReturnExpression(recursionTracker);
8977
8890
  if (this.returnExpression === UNKNOWN_EXPRESSION) {
8978
8891
  return UNKNOWN_EXPRESSION;
8979
8892
  }
8980
8893
  return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {
8981
8894
  this.deoptimizableDependentExpressions.push(origin);
8982
- return returnExpression.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
8895
+ return returnExpression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
8983
8896
  }, UNKNOWN_EXPRESSION);
8984
8897
  }
8985
- hasEffectsWhenAccessedAtPath(path, context) {
8986
- return (!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
8987
- this.getReturnExpression().hasEffectsWhenAccessedAtPath(path, context));
8988
- }
8989
- hasEffectsWhenAssignedAtPath(path, context) {
8990
- return (!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
8991
- this.getReturnExpression().hasEffectsWhenAssignedAtPath(path, context));
8992
- }
8993
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
8994
- return (!(callOptions.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, callOptions, this) &&
8995
- this.getReturnExpression().hasEffectsWhenCalledAtPath(path, callOptions, context));
8898
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
8899
+ const { type } = interaction;
8900
+ if (type === INTERACTION_CALLED) {
8901
+ if ((interaction.withNew
8902
+ ? context.instantiated
8903
+ : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)) {
8904
+ return false;
8905
+ }
8906
+ }
8907
+ else if ((type === INTERACTION_ASSIGNED
8908
+ ? context.assigned
8909
+ : context.accessed).trackEntityAtPathAndGetIfTracked(path, this)) {
8910
+ return false;
8911
+ }
8912
+ return this.getReturnExpression().hasEffectsOnInteractionAtPath(path, interaction, context);
8996
8913
  }
8997
8914
  }
8998
8915
 
@@ -9015,11 +8932,12 @@ class CallExpression extends CallExpressionBase {
9015
8932
  }, this.start);
9016
8933
  }
9017
8934
  }
9018
- this.callOptions = {
8935
+ this.interaction = {
9019
8936
  args: this.arguments,
9020
- thisParam: this.callee instanceof MemberExpression && !this.callee.variable
8937
+ thisArg: this.callee instanceof MemberExpression && !this.callee.variable
9021
8938
  ? this.callee.object
9022
8939
  : null,
8940
+ type: INTERACTION_CALLED,
9023
8941
  withNew: false
9024
8942
  };
9025
8943
  }
@@ -9033,7 +8951,7 @@ class CallExpression extends CallExpressionBase {
9033
8951
  this.annotations)
9034
8952
  return false;
9035
8953
  return (this.callee.hasEffects(context) ||
9036
- this.callee.hasEffectsWhenCalledAtPath(EMPTY_PATH, this.callOptions, context));
8954
+ this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
9037
8955
  }
9038
8956
  finally {
9039
8957
  if (!this.deoptimized)
@@ -9053,7 +8971,7 @@ class CallExpression extends CallExpressionBase {
9053
8971
  }
9054
8972
  else {
9055
8973
  this.included = true;
9056
- this.callee.include(context, false, { includeWithoutParameterDefaults: true });
8974
+ this.callee.include(context, false);
9057
8975
  }
9058
8976
  this.callee.includeCallArguments(context, this.arguments);
9059
8977
  const returnExpression = this.getReturnExpression();
@@ -9066,34 +8984,12 @@ class CallExpression extends CallExpressionBase {
9066
8984
  isCalleeOfRenderedParent: true,
9067
8985
  renderedSurroundingElement
9068
8986
  });
9069
- if (this.arguments.length > 0) {
9070
- if (this.arguments[this.arguments.length - 1].included) {
9071
- for (const arg of this.arguments) {
9072
- arg.render(code, options);
9073
- }
9074
- }
9075
- else {
9076
- let lastIncludedIndex = this.arguments.length - 2;
9077
- while (lastIncludedIndex >= 0 && !this.arguments[lastIncludedIndex].included) {
9078
- lastIncludedIndex--;
9079
- }
9080
- if (lastIncludedIndex >= 0) {
9081
- for (let index = 0; index <= lastIncludedIndex; index++) {
9082
- this.arguments[index].render(code, options);
9083
- }
9084
- code.remove(findFirstOccurrenceOutsideComment(code.original, ',', this.arguments[lastIncludedIndex].end), this.end - 1);
9085
- }
9086
- else {
9087
- code.remove(findFirstOccurrenceOutsideComment(code.original, '(', this.callee.end) + 1, this.end - 1);
9088
- }
9089
- }
9090
- }
8987
+ renderCallArguments(code, options, this);
9091
8988
  }
9092
8989
  applyDeoptimizations() {
9093
8990
  this.deoptimized = true;
9094
- const { thisParam } = this.callOptions;
9095
- if (thisParam) {
9096
- this.callee.deoptimizeThisOnEventAtPath(EVENT_CALLED, EMPTY_PATH, thisParam, SHARED_RECURSION_TRACKER);
8991
+ if (this.interaction.thisArg) {
8992
+ this.callee.deoptimizeThisOnInteractionAtPath(this.interaction, EMPTY_PATH, SHARED_RECURSION_TRACKER);
9097
8993
  }
9098
8994
  for (const argument of this.arguments) {
9099
8995
  // This will make sure all properties of parameters behave as "unknown"
@@ -9104,7 +9000,7 @@ class CallExpression extends CallExpressionBase {
9104
9000
  getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) {
9105
9001
  if (this.returnExpression === null) {
9106
9002
  this.returnExpression = UNKNOWN_EXPRESSION;
9107
- return (this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.callOptions, recursionTracker, this));
9003
+ return (this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this));
9108
9004
  }
9109
9005
  return this.returnExpression;
9110
9006
  }
@@ -9182,11 +9078,6 @@ class MethodBase extends NodeBase {
9182
9078
  constructor() {
9183
9079
  super(...arguments);
9184
9080
  this.accessedValue = null;
9185
- this.accessorCallOptions = {
9186
- args: NO_ARGS,
9187
- thisParam: null,
9188
- withNew: false
9189
- };
9190
9081
  }
9191
9082
  // As getter properties directly receive their values from fixed function
9192
9083
  // expressions, there is no known situation where a getter is deoptimized.
@@ -9194,45 +9085,60 @@ class MethodBase extends NodeBase {
9194
9085
  deoptimizePath(path) {
9195
9086
  this.getAccessedValue().deoptimizePath(path);
9196
9087
  }
9197
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
9198
- if (event === EVENT_ACCESSED && this.kind === 'get' && path.length === 0) {
9199
- return this.value.deoptimizeThisOnEventAtPath(EVENT_CALLED, EMPTY_PATH, thisParameter, recursionTracker);
9088
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
9089
+ if (interaction.type === INTERACTION_ACCESSED && this.kind === 'get' && path.length === 0) {
9090
+ return this.value.deoptimizeThisOnInteractionAtPath({
9091
+ args: NO_ARGS,
9092
+ thisArg: interaction.thisArg,
9093
+ type: INTERACTION_CALLED,
9094
+ withNew: false
9095
+ }, EMPTY_PATH, recursionTracker);
9200
9096
  }
9201
- if (event === EVENT_ASSIGNED && this.kind === 'set' && path.length === 0) {
9202
- return this.value.deoptimizeThisOnEventAtPath(EVENT_CALLED, EMPTY_PATH, thisParameter, recursionTracker);
9097
+ if (interaction.type === INTERACTION_ASSIGNED && this.kind === 'set' && path.length === 0) {
9098
+ return this.value.deoptimizeThisOnInteractionAtPath({
9099
+ args: interaction.args,
9100
+ thisArg: interaction.thisArg,
9101
+ type: INTERACTION_CALLED,
9102
+ withNew: false
9103
+ }, EMPTY_PATH, recursionTracker);
9203
9104
  }
9204
- this.getAccessedValue().deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
9105
+ this.getAccessedValue().deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
9205
9106
  }
9206
9107
  getLiteralValueAtPath(path, recursionTracker, origin) {
9207
9108
  return this.getAccessedValue().getLiteralValueAtPath(path, recursionTracker, origin);
9208
9109
  }
9209
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
9210
- return this.getAccessedValue().getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
9110
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9111
+ return this.getAccessedValue().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9211
9112
  }
9212
9113
  hasEffects(context) {
9213
9114
  return this.key.hasEffects(context);
9214
9115
  }
9215
- hasEffectsWhenAccessedAtPath(path, context) {
9216
- if (this.kind === 'get' && path.length === 0) {
9217
- return this.value.hasEffectsWhenCalledAtPath(EMPTY_PATH, this.accessorCallOptions, context);
9218
- }
9219
- return this.getAccessedValue().hasEffectsWhenAccessedAtPath(path, context);
9220
- }
9221
- hasEffectsWhenAssignedAtPath(path, context) {
9222
- if (this.kind === 'set') {
9223
- return this.value.hasEffectsWhenCalledAtPath(EMPTY_PATH, this.accessorCallOptions, context);
9116
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
9117
+ if (this.kind === 'get' && interaction.type === INTERACTION_ACCESSED && path.length === 0) {
9118
+ return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, {
9119
+ args: NO_ARGS,
9120
+ thisArg: interaction.thisArg,
9121
+ type: INTERACTION_CALLED,
9122
+ withNew: false
9123
+ }, context);
9124
+ }
9125
+ // setters are only called for empty paths
9126
+ if (this.kind === 'set' && interaction.type === INTERACTION_ASSIGNED) {
9127
+ return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, {
9128
+ args: interaction.args,
9129
+ thisArg: interaction.thisArg,
9130
+ type: INTERACTION_CALLED,
9131
+ withNew: false
9132
+ }, context);
9224
9133
  }
9225
- return this.getAccessedValue().hasEffectsWhenAssignedAtPath(path, context);
9226
- }
9227
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
9228
- return this.getAccessedValue().hasEffectsWhenCalledAtPath(path, callOptions, context);
9134
+ return this.getAccessedValue().hasEffectsOnInteractionAtPath(path, interaction, context);
9229
9135
  }
9230
9136
  applyDeoptimizations() { }
9231
9137
  getAccessedValue() {
9232
9138
  if (this.accessedValue === null) {
9233
9139
  if (this.kind === 'get') {
9234
9140
  this.accessedValue = UNKNOWN_EXPRESSION;
9235
- return (this.accessedValue = this.value.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.accessorCallOptions, SHARED_RECURSION_TRACKER, this));
9141
+ return (this.accessedValue = this.value.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, SHARED_RECURSION_TRACKER, this));
9236
9142
  }
9237
9143
  else {
9238
9144
  return (this.accessedValue = this.value);
@@ -9246,41 +9152,6 @@ class MethodDefinition extends MethodBase {
9246
9152
  applyDeoptimizations() { }
9247
9153
  }
9248
9154
 
9249
- class PropertyDefinition extends NodeBase {
9250
- deoptimizePath(path) {
9251
- var _a;
9252
- (_a = this.value) === null || _a === void 0 ? void 0 : _a.deoptimizePath(path);
9253
- }
9254
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
9255
- var _a;
9256
- (_a = this.value) === null || _a === void 0 ? void 0 : _a.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
9257
- }
9258
- getLiteralValueAtPath(path, recursionTracker, origin) {
9259
- return this.value
9260
- ? this.value.getLiteralValueAtPath(path, recursionTracker, origin)
9261
- : UnknownValue;
9262
- }
9263
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
9264
- return this.value
9265
- ? this.value.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin)
9266
- : UNKNOWN_EXPRESSION;
9267
- }
9268
- hasEffects(context) {
9269
- var _a;
9270
- return this.key.hasEffects(context) || (this.static && !!((_a = this.value) === null || _a === void 0 ? void 0 : _a.hasEffects(context)));
9271
- }
9272
- hasEffectsWhenAccessedAtPath(path, context) {
9273
- return !this.value || this.value.hasEffectsWhenAccessedAtPath(path, context);
9274
- }
9275
- hasEffectsWhenAssignedAtPath(path, context) {
9276
- return !this.value || this.value.hasEffectsWhenAssignedAtPath(path, context);
9277
- }
9278
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
9279
- return !this.value || this.value.hasEffectsWhenCalledAtPath(path, callOptions, context);
9280
- }
9281
- applyDeoptimizations() { }
9282
- }
9283
-
9284
9155
  class ObjectMember extends ExpressionEntity {
9285
9156
  constructor(object, key) {
9286
9157
  super();
@@ -9290,23 +9161,17 @@ class ObjectMember extends ExpressionEntity {
9290
9161
  deoptimizePath(path) {
9291
9162
  this.object.deoptimizePath([this.key, ...path]);
9292
9163
  }
9293
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
9294
- this.object.deoptimizeThisOnEventAtPath(event, [this.key, ...path], thisParameter, recursionTracker);
9164
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
9165
+ this.object.deoptimizeThisOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker);
9295
9166
  }
9296
9167
  getLiteralValueAtPath(path, recursionTracker, origin) {
9297
9168
  return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin);
9298
9169
  }
9299
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
9300
- return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], callOptions, recursionTracker, origin);
9170
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9171
+ return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin);
9301
9172
  }
9302
- hasEffectsWhenAccessedAtPath(path, context) {
9303
- return this.object.hasEffectsWhenAccessedAtPath([this.key, ...path], context);
9304
- }
9305
- hasEffectsWhenAssignedAtPath(path, context) {
9306
- return this.object.hasEffectsWhenAssignedAtPath([this.key, ...path], context);
9307
- }
9308
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
9309
- return this.object.hasEffectsWhenCalledAtPath([this.key, ...path], callOptions, context);
9173
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
9174
+ return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context);
9310
9175
  }
9311
9176
  }
9312
9177
 
@@ -9322,23 +9187,16 @@ class ClassNode extends NodeBase {
9322
9187
  this.getObjectEntity().deoptimizeAllProperties();
9323
9188
  }
9324
9189
  deoptimizePath(path) {
9325
- var _a, _b;
9326
9190
  this.getObjectEntity().deoptimizePath(path);
9327
- if (path.length === 1 && path[0] === UnknownKey) {
9328
- // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
9329
- // which means the constructor needs to be reassigned
9330
- (_a = this.classConstructor) === null || _a === void 0 ? void 0 : _a.deoptimizePath(UNKNOWN_PATH);
9331
- (_b = this.superClass) === null || _b === void 0 ? void 0 : _b.deoptimizePath(UNKNOWN_PATH);
9332
- }
9333
9191
  }
9334
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
9335
- this.getObjectEntity().deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
9192
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
9193
+ this.getObjectEntity().deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
9336
9194
  }
9337
9195
  getLiteralValueAtPath(path, recursionTracker, origin) {
9338
9196
  return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);
9339
9197
  }
9340
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
9341
- return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
9198
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9199
+ return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9342
9200
  }
9343
9201
  hasEffects(context) {
9344
9202
  var _a, _b;
@@ -9348,23 +9206,17 @@ class ClassNode extends NodeBase {
9348
9206
  (_b = this.id) === null || _b === void 0 ? void 0 : _b.markDeclarationReached();
9349
9207
  return initEffect || super.hasEffects(context);
9350
9208
  }
9351
- hasEffectsWhenAccessedAtPath(path, context) {
9352
- return this.getObjectEntity().hasEffectsWhenAccessedAtPath(path, context);
9353
- }
9354
- hasEffectsWhenAssignedAtPath(path, context) {
9355
- return this.getObjectEntity().hasEffectsWhenAssignedAtPath(path, context);
9356
- }
9357
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
9209
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
9358
9210
  var _a;
9359
- if (path.length === 0) {
9360
- return (!callOptions.withNew ||
9211
+ if (interaction.type === INTERACTION_CALLED && path.length === 0) {
9212
+ return (!interaction.withNew ||
9361
9213
  (this.classConstructor !== null
9362
- ? this.classConstructor.hasEffectsWhenCalledAtPath(EMPTY_PATH, callOptions, context)
9363
- : (_a = this.superClass) === null || _a === void 0 ? void 0 : _a.hasEffectsWhenCalledAtPath(path, callOptions, context)) ||
9214
+ ? this.classConstructor.hasEffectsOnInteractionAtPath(path, interaction, context)
9215
+ : (_a = this.superClass) === null || _a === void 0 ? void 0 : _a.hasEffectsOnInteractionAtPath(path, interaction, context)) ||
9364
9216
  false);
9365
9217
  }
9366
9218
  else {
9367
- return this.getObjectEntity().hasEffectsWhenCalledAtPath(path, callOptions, context);
9219
+ return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
9368
9220
  }
9369
9221
  }
9370
9222
  include(context, includeChildrenRecursively) {
@@ -9391,7 +9243,6 @@ class ClassNode extends NodeBase {
9391
9243
  this.classConstructor = null;
9392
9244
  }
9393
9245
  applyDeoptimizations() {
9394
- var _a, _b;
9395
9246
  this.deoptimized = true;
9396
9247
  for (const definition of this.body.body) {
9397
9248
  if (!(definition.static ||
@@ -9399,11 +9250,7 @@ class ClassNode extends NodeBase {
9399
9250
  // Calls to methods are not tracked, ensure that the return value is deoptimized
9400
9251
  definition.deoptimizePath(UNKNOWN_PATH);
9401
9252
  }
9402
- else if (definition instanceof PropertyDefinition) {
9403
- (_a = definition.value) === null || _a === void 0 ? void 0 : _a.deoptimizeCallParameters();
9404
- }
9405
9253
  }
9406
- (_b = this.superClass) === null || _b === void 0 ? void 0 : _b.deoptimizeCallParameters();
9407
9254
  this.context.requestTreeshakingPass();
9408
9255
  }
9409
9256
  getObjectEntity() {
@@ -9490,26 +9337,12 @@ class MultiExpression extends ExpressionEntity {
9490
9337
  expression.deoptimizePath(path);
9491
9338
  }
9492
9339
  }
9493
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
9494
- return new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin)));
9495
- }
9496
- hasEffectsWhenAccessedAtPath(path, context) {
9497
- for (const expression of this.expressions) {
9498
- if (expression.hasEffectsWhenAccessedAtPath(path, context))
9499
- return true;
9500
- }
9501
- return false;
9502
- }
9503
- hasEffectsWhenAssignedAtPath(path, context) {
9504
- for (const expression of this.expressions) {
9505
- if (expression.hasEffectsWhenAssignedAtPath(path, context))
9506
- return true;
9507
- }
9508
- return false;
9340
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9341
+ return new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)));
9509
9342
  }
9510
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
9343
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
9511
9344
  for (const expression of this.expressions) {
9512
- if (expression.hasEffectsWhenCalledAtPath(path, callOptions, context))
9345
+ if (expression.hasEffectsOnInteractionAtPath(path, interaction, context))
9513
9346
  return true;
9514
9347
  }
9515
9348
  return false;
@@ -9552,9 +9385,9 @@ class ConditionalExpression extends NodeBase {
9552
9385
  usedBranch.deoptimizePath(path);
9553
9386
  }
9554
9387
  }
9555
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
9556
- this.consequent.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
9557
- this.alternate.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
9388
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
9389
+ this.consequent.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
9390
+ this.alternate.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
9558
9391
  }
9559
9392
  getLiteralValueAtPath(path, recursionTracker, origin) {
9560
9393
  const usedBranch = this.getUsedBranch();
@@ -9563,15 +9396,15 @@ class ConditionalExpression extends NodeBase {
9563
9396
  this.expressionsToBeDeoptimized.push(origin);
9564
9397
  return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin);
9565
9398
  }
9566
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
9399
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9567
9400
  const usedBranch = this.getUsedBranch();
9568
9401
  if (!usedBranch)
9569
9402
  return new MultiExpression([
9570
- this.consequent.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin),
9571
- this.alternate.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin)
9403
+ this.consequent.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin),
9404
+ this.alternate.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)
9572
9405
  ]);
9573
9406
  this.expressionsToBeDeoptimized.push(origin);
9574
- return usedBranch.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
9407
+ return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9575
9408
  }
9576
9409
  hasEffects(context) {
9577
9410
  if (this.test.hasEffects(context))
@@ -9582,29 +9415,13 @@ class ConditionalExpression extends NodeBase {
9582
9415
  }
9583
9416
  return usedBranch.hasEffects(context);
9584
9417
  }
9585
- hasEffectsWhenAccessedAtPath(path, context) {
9586
- const usedBranch = this.getUsedBranch();
9587
- if (!usedBranch) {
9588
- return (this.consequent.hasEffectsWhenAccessedAtPath(path, context) ||
9589
- this.alternate.hasEffectsWhenAccessedAtPath(path, context));
9590
- }
9591
- return usedBranch.hasEffectsWhenAccessedAtPath(path, context);
9592
- }
9593
- hasEffectsWhenAssignedAtPath(path, context) {
9594
- const usedBranch = this.getUsedBranch();
9595
- if (!usedBranch) {
9596
- return (this.consequent.hasEffectsWhenAssignedAtPath(path, context) ||
9597
- this.alternate.hasEffectsWhenAssignedAtPath(path, context));
9598
- }
9599
- return usedBranch.hasEffectsWhenAssignedAtPath(path, context);
9600
- }
9601
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
9418
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
9602
9419
  const usedBranch = this.getUsedBranch();
9603
9420
  if (!usedBranch) {
9604
- return (this.consequent.hasEffectsWhenCalledAtPath(path, callOptions, context) ||
9605
- this.alternate.hasEffectsWhenCalledAtPath(path, callOptions, context));
9421
+ return (this.consequent.hasEffectsOnInteractionAtPath(path, interaction, context) ||
9422
+ this.alternate.hasEffectsOnInteractionAtPath(path, interaction, context));
9606
9423
  }
9607
- return usedBranch.hasEffectsWhenCalledAtPath(path, callOptions, context);
9424
+ return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
9608
9425
  }
9609
9426
  include(context, includeChildrenRecursively) {
9610
9427
  this.included = true;
@@ -9737,9 +9554,6 @@ class ExportAllDeclaration extends NodeBase {
9737
9554
  ExportAllDeclaration.prototype.needsBoundaries = true;
9738
9555
 
9739
9556
  class FunctionDeclaration extends FunctionNode {
9740
- include(context, includeChildrenRecursively) {
9741
- super.include(context, includeChildrenRecursively, { includeWithoutParameterDefaults: true });
9742
- }
9743
9557
  initialise() {
9744
9558
  super.initialise();
9745
9559
  if (this.id !== null) {
@@ -9878,12 +9692,10 @@ class ForInStatement extends NodeBase {
9878
9692
  this.scope = new BlockScope(parentScope);
9879
9693
  }
9880
9694
  hasEffects(context) {
9881
- if (!this.deoptimized)
9695
+ const { deoptimized, left, right } = this;
9696
+ if (!deoptimized)
9882
9697
  this.applyDeoptimizations();
9883
- if ((this.left &&
9884
- (this.left.hasEffects(context) ||
9885
- this.left.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context))) ||
9886
- (this.right && this.right.hasEffects(context)))
9698
+ if (left.hasEffectsAsAssignmentTarget(context, false) || right.hasEffects(context))
9887
9699
  return true;
9888
9700
  const { brokenFlow, ignore: { breaks, continues } } = context;
9889
9701
  context.ignore.breaks = true;
@@ -9896,15 +9708,19 @@ class ForInStatement extends NodeBase {
9896
9708
  return false;
9897
9709
  }
9898
9710
  include(context, includeChildrenRecursively) {
9899
- if (!this.deoptimized)
9711
+ const { body, deoptimized, left, right } = this;
9712
+ if (!deoptimized)
9900
9713
  this.applyDeoptimizations();
9901
9714
  this.included = true;
9902
- this.left.include(context, includeChildrenRecursively || true);
9903
- this.right.include(context, includeChildrenRecursively);
9715
+ left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
9716
+ right.include(context, includeChildrenRecursively);
9904
9717
  const { brokenFlow } = context;
9905
- this.body.include(context, includeChildrenRecursively, { asSingleStatement: true });
9718
+ body.include(context, includeChildrenRecursively, { asSingleStatement: true });
9906
9719
  context.brokenFlow = brokenFlow;
9907
9720
  }
9721
+ initialise() {
9722
+ this.left.setAssignedValue(UNKNOWN_EXPRESSION);
9723
+ }
9908
9724
  render(code, options) {
9909
9725
  this.left.render(code, options, NO_SEMICOLON);
9910
9726
  this.right.render(code, options, NO_SEMICOLON);
@@ -9932,15 +9748,19 @@ class ForOfStatement extends NodeBase {
9932
9748
  return true;
9933
9749
  }
9934
9750
  include(context, includeChildrenRecursively) {
9935
- if (!this.deoptimized)
9751
+ const { body, deoptimized, left, right } = this;
9752
+ if (!deoptimized)
9936
9753
  this.applyDeoptimizations();
9937
9754
  this.included = true;
9938
- this.left.include(context, includeChildrenRecursively || true);
9939
- this.right.include(context, includeChildrenRecursively);
9755
+ left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
9756
+ right.include(context, includeChildrenRecursively);
9940
9757
  const { brokenFlow } = context;
9941
- this.body.include(context, includeChildrenRecursively, { asSingleStatement: true });
9758
+ body.include(context, includeChildrenRecursively, { asSingleStatement: true });
9942
9759
  context.brokenFlow = brokenFlow;
9943
9760
  }
9761
+ initialise() {
9762
+ this.left.setAssignedValue(UNKNOWN_EXPRESSION);
9763
+ }
9944
9764
  render(code, options) {
9945
9765
  this.left.render(code, options, NO_SEMICOLON);
9946
9766
  this.right.render(code, options, NO_SEMICOLON);
@@ -10625,13 +10445,16 @@ class LogicalExpression extends NodeBase {
10625
10445
  this.usedBranch = null;
10626
10446
  }
10627
10447
  deoptimizeCache() {
10628
- if (this.usedBranch !== null) {
10448
+ if (this.usedBranch) {
10629
10449
  const unusedBranch = this.usedBranch === this.left ? this.right : this.left;
10630
10450
  this.usedBranch = null;
10631
10451
  unusedBranch.deoptimizePath(UNKNOWN_PATH);
10632
10452
  for (const expression of this.expressionsToBeDeoptimized) {
10633
10453
  expression.deoptimizeCache();
10634
10454
  }
10455
+ // Request another pass because we need to ensure "include" runs again if
10456
+ // it is rendered
10457
+ this.context.requestTreeshakingPass();
10635
10458
  }
10636
10459
  }
10637
10460
  deoptimizePath(path) {
@@ -10644,9 +10467,9 @@ class LogicalExpression extends NodeBase {
10644
10467
  usedBranch.deoptimizePath(path);
10645
10468
  }
10646
10469
  }
10647
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
10648
- this.left.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
10649
- this.right.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
10470
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
10471
+ this.left.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
10472
+ this.right.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
10650
10473
  }
10651
10474
  getLiteralValueAtPath(path, recursionTracker, origin) {
10652
10475
  const usedBranch = this.getUsedBranch();
@@ -10655,15 +10478,15 @@ class LogicalExpression extends NodeBase {
10655
10478
  this.expressionsToBeDeoptimized.push(origin);
10656
10479
  return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin);
10657
10480
  }
10658
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
10481
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
10659
10482
  const usedBranch = this.getUsedBranch();
10660
10483
  if (!usedBranch)
10661
10484
  return new MultiExpression([
10662
- this.left.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin),
10663
- this.right.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin)
10485
+ this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin),
10486
+ this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)
10664
10487
  ]);
10665
10488
  this.expressionsToBeDeoptimized.push(origin);
10666
- return usedBranch.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
10489
+ return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
10667
10490
  }
10668
10491
  hasEffects(context) {
10669
10492
  if (this.left.hasEffects(context)) {
@@ -10674,29 +10497,13 @@ class LogicalExpression extends NodeBase {
10674
10497
  }
10675
10498
  return false;
10676
10499
  }
10677
- hasEffectsWhenAccessedAtPath(path, context) {
10678
- const usedBranch = this.getUsedBranch();
10679
- if (!usedBranch) {
10680
- return (this.left.hasEffectsWhenAccessedAtPath(path, context) ||
10681
- this.right.hasEffectsWhenAccessedAtPath(path, context));
10682
- }
10683
- return usedBranch.hasEffectsWhenAccessedAtPath(path, context);
10684
- }
10685
- hasEffectsWhenAssignedAtPath(path, context) {
10686
- const usedBranch = this.getUsedBranch();
10687
- if (!usedBranch) {
10688
- return (this.left.hasEffectsWhenAssignedAtPath(path, context) ||
10689
- this.right.hasEffectsWhenAssignedAtPath(path, context));
10690
- }
10691
- return usedBranch.hasEffectsWhenAssignedAtPath(path, context);
10692
- }
10693
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
10500
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
10694
10501
  const usedBranch = this.getUsedBranch();
10695
10502
  if (!usedBranch) {
10696
- return (this.left.hasEffectsWhenCalledAtPath(path, callOptions, context) ||
10697
- this.right.hasEffectsWhenCalledAtPath(path, callOptions, context));
10503
+ return (this.left.hasEffectsOnInteractionAtPath(path, interaction, context) ||
10504
+ this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
10698
10505
  }
10699
- return usedBranch.hasEffectsWhenCalledAtPath(path, callOptions, context);
10506
+ return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
10700
10507
  }
10701
10508
  include(context, includeChildrenRecursively) {
10702
10509
  this.included = true;
@@ -10786,8 +10593,8 @@ class MetaProperty extends NodeBase {
10786
10593
  hasEffects() {
10787
10594
  return false;
10788
10595
  }
10789
- hasEffectsWhenAccessedAtPath(path) {
10790
- return path.length > 1;
10596
+ hasEffectsOnInteractionAtPath(path, { type }) {
10597
+ return path.length > 1 || type !== INTERACTION_ACCESSED;
10791
10598
  }
10792
10599
  include() {
10793
10600
  if (!this.included) {
@@ -10932,18 +10739,19 @@ class NewExpression extends NodeBase {
10932
10739
  return true;
10933
10740
  }
10934
10741
  if (this.context.options.treeshake.annotations &&
10935
- this.annotations)
10742
+ this.annotations) {
10936
10743
  return false;
10744
+ }
10937
10745
  return (this.callee.hasEffects(context) ||
10938
- this.callee.hasEffectsWhenCalledAtPath(EMPTY_PATH, this.callOptions, context));
10746
+ this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
10939
10747
  }
10940
10748
  finally {
10941
10749
  if (!this.deoptimized)
10942
10750
  this.applyDeoptimizations();
10943
10751
  }
10944
10752
  }
10945
- hasEffectsWhenAccessedAtPath(path) {
10946
- return path.length > 0;
10753
+ hasEffectsOnInteractionAtPath(path, { type }) {
10754
+ return path.length > 0 || type !== INTERACTION_ACCESSED;
10947
10755
  }
10948
10756
  include(context, includeChildrenRecursively) {
10949
10757
  if (!this.deoptimized)
@@ -10958,12 +10766,17 @@ class NewExpression extends NodeBase {
10958
10766
  this.callee.includeCallArguments(context, this.arguments);
10959
10767
  }
10960
10768
  initialise() {
10961
- this.callOptions = {
10769
+ this.interaction = {
10962
10770
  args: this.arguments,
10963
- thisParam: null,
10771
+ thisArg: null,
10772
+ type: INTERACTION_CALLED,
10964
10773
  withNew: true
10965
10774
  };
10966
10775
  }
10776
+ render(code, options) {
10777
+ this.callee.render(code, options);
10778
+ renderCallArguments(code, options, this);
10779
+ }
10967
10780
  applyDeoptimizations() {
10968
10781
  this.deoptimized = true;
10969
10782
  for (const argument of this.arguments) {
@@ -10974,42 +10787,6 @@ class NewExpression extends NodeBase {
10974
10787
  }
10975
10788
  }
10976
10789
 
10977
- class Property extends MethodBase {
10978
- constructor() {
10979
- super(...arguments);
10980
- this.declarationInit = null;
10981
- }
10982
- declare(kind, init) {
10983
- this.declarationInit = init;
10984
- return this.value.declare(kind, UNKNOWN_EXPRESSION);
10985
- }
10986
- hasEffects(context) {
10987
- if (!this.deoptimized)
10988
- this.applyDeoptimizations();
10989
- const propertyReadSideEffects = this.context.options.treeshake
10990
- .propertyReadSideEffects;
10991
- return ((this.parent.type === 'ObjectPattern' && propertyReadSideEffects === 'always') ||
10992
- this.key.hasEffects(context) ||
10993
- this.value.hasEffects(context));
10994
- }
10995
- markDeclarationReached() {
10996
- this.value.markDeclarationReached();
10997
- }
10998
- render(code, options) {
10999
- if (!this.shorthand) {
11000
- this.key.render(code, options);
11001
- }
11002
- this.value.render(code, options, { isShorthandProperty: this.shorthand });
11003
- }
11004
- applyDeoptimizations() {
11005
- this.deoptimized = true;
11006
- if (this.declarationInit !== null) {
11007
- this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
11008
- this.context.requestTreeshakingPass();
11009
- }
11010
- }
11011
- }
11012
-
11013
10790
  class ObjectExpression extends NodeBase {
11014
10791
  constructor() {
11015
10792
  super(...arguments);
@@ -11021,23 +10798,17 @@ class ObjectExpression extends NodeBase {
11021
10798
  deoptimizePath(path) {
11022
10799
  this.getObjectEntity().deoptimizePath(path);
11023
10800
  }
11024
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
11025
- this.getObjectEntity().deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
10801
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
10802
+ this.getObjectEntity().deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
11026
10803
  }
11027
10804
  getLiteralValueAtPath(path, recursionTracker, origin) {
11028
10805
  return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);
11029
10806
  }
11030
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
11031
- return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
11032
- }
11033
- hasEffectsWhenAccessedAtPath(path, context) {
11034
- return this.getObjectEntity().hasEffectsWhenAccessedAtPath(path, context);
11035
- }
11036
- hasEffectsWhenAssignedAtPath(path, context) {
11037
- return this.getObjectEntity().hasEffectsWhenAssignedAtPath(path, context);
10807
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
10808
+ return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
11038
10809
  }
11039
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
11040
- return this.getObjectEntity().hasEffectsWhenCalledAtPath(path, callOptions, context);
10810
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
10811
+ return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
11041
10812
  }
11042
10813
  render(code, options, { renderedSurroundingElement } = BLANK) {
11043
10814
  super.render(code, options);
@@ -11047,14 +10818,7 @@ class ObjectExpression extends NodeBase {
11047
10818
  code.prependLeft(this.end, ')');
11048
10819
  }
11049
10820
  }
11050
- applyDeoptimizations() {
11051
- this.deoptimized = true;
11052
- for (const property of this.properties) {
11053
- if (property instanceof Property) {
11054
- property.value.deoptimizeCallParameters();
11055
- }
11056
- }
11057
- }
10821
+ applyDeoptimizations() { }
11058
10822
  getObjectEntity() {
11059
10823
  if (this.objectEntity !== null) {
11060
10824
  return this.objectEntity;
@@ -11134,6 +10898,71 @@ class Program extends NodeBase {
11134
10898
  applyDeoptimizations() { }
11135
10899
  }
11136
10900
 
10901
+ class Property extends MethodBase {
10902
+ constructor() {
10903
+ super(...arguments);
10904
+ this.declarationInit = null;
10905
+ }
10906
+ declare(kind, init) {
10907
+ this.declarationInit = init;
10908
+ return this.value.declare(kind, UNKNOWN_EXPRESSION);
10909
+ }
10910
+ hasEffects(context) {
10911
+ if (!this.deoptimized)
10912
+ this.applyDeoptimizations();
10913
+ const propertyReadSideEffects = this.context.options.treeshake
10914
+ .propertyReadSideEffects;
10915
+ return ((this.parent.type === 'ObjectPattern' && propertyReadSideEffects === 'always') ||
10916
+ this.key.hasEffects(context) ||
10917
+ this.value.hasEffects(context));
10918
+ }
10919
+ markDeclarationReached() {
10920
+ this.value.markDeclarationReached();
10921
+ }
10922
+ render(code, options) {
10923
+ if (!this.shorthand) {
10924
+ this.key.render(code, options);
10925
+ }
10926
+ this.value.render(code, options, { isShorthandProperty: this.shorthand });
10927
+ }
10928
+ applyDeoptimizations() {
10929
+ this.deoptimized = true;
10930
+ if (this.declarationInit !== null) {
10931
+ this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
10932
+ this.context.requestTreeshakingPass();
10933
+ }
10934
+ }
10935
+ }
10936
+
10937
+ class PropertyDefinition extends NodeBase {
10938
+ deoptimizePath(path) {
10939
+ var _a;
10940
+ (_a = this.value) === null || _a === void 0 ? void 0 : _a.deoptimizePath(path);
10941
+ }
10942
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
10943
+ var _a;
10944
+ (_a = this.value) === null || _a === void 0 ? void 0 : _a.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
10945
+ }
10946
+ getLiteralValueAtPath(path, recursionTracker, origin) {
10947
+ return this.value
10948
+ ? this.value.getLiteralValueAtPath(path, recursionTracker, origin)
10949
+ : UnknownValue;
10950
+ }
10951
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
10952
+ return this.value
10953
+ ? this.value.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)
10954
+ : UNKNOWN_EXPRESSION;
10955
+ }
10956
+ hasEffects(context) {
10957
+ var _a;
10958
+ return this.key.hasEffects(context) || (this.static && !!((_a = this.value) === null || _a === void 0 ? void 0 : _a.hasEffects(context)));
10959
+ }
10960
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
10961
+ return !this.value || this.value.hasEffectsOnInteractionAtPath(path, interaction, context);
10962
+ }
10963
+ applyDeoptimizations() { }
10964
+ }
10965
+
11137
10966
  class ReturnStatement extends NodeBase {
11138
10967
  hasEffects(context) {
11139
10968
  var _a;
@@ -11165,8 +10994,8 @@ class SequenceExpression extends NodeBase {
11165
10994
  deoptimizePath(path) {
11166
10995
  this.expressions[this.expressions.length - 1].deoptimizePath(path);
11167
10996
  }
11168
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
11169
- this.expressions[this.expressions.length - 1].deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
10997
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
10998
+ this.expressions[this.expressions.length - 1].deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
11170
10999
  }
11171
11000
  getLiteralValueAtPath(path, recursionTracker, origin) {
11172
11001
  return this.expressions[this.expressions.length - 1].getLiteralValueAtPath(path, recursionTracker, origin);
@@ -11178,15 +11007,8 @@ class SequenceExpression extends NodeBase {
11178
11007
  }
11179
11008
  return false;
11180
11009
  }
11181
- hasEffectsWhenAccessedAtPath(path, context) {
11182
- return (path.length > 0 &&
11183
- this.expressions[this.expressions.length - 1].hasEffectsWhenAccessedAtPath(path, context));
11184
- }
11185
- hasEffectsWhenAssignedAtPath(path, context) {
11186
- return this.expressions[this.expressions.length - 1].hasEffectsWhenAssignedAtPath(path, context);
11187
- }
11188
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
11189
- return this.expressions[this.expressions.length - 1].hasEffectsWhenCalledAtPath(path, callOptions, context);
11010
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
11011
+ return this.expressions[this.expressions.length - 1].hasEffectsOnInteractionAtPath(path, interaction, context);
11190
11012
  }
11191
11013
  include(context, includeChildrenRecursively) {
11192
11014
  this.included = true;
@@ -11265,8 +11087,8 @@ class Super extends NodeBase {
11265
11087
  deoptimizePath(path) {
11266
11088
  this.variable.deoptimizePath(path);
11267
11089
  }
11268
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
11269
- this.variable.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
11090
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
11091
+ this.variable.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
11270
11092
  }
11271
11093
  include() {
11272
11094
  if (!this.included) {
@@ -11406,7 +11228,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
11406
11228
  return true;
11407
11229
  }
11408
11230
  return (this.tag.hasEffects(context) ||
11409
- this.tag.hasEffectsWhenCalledAtPath(EMPTY_PATH, this.callOptions, context));
11231
+ this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
11410
11232
  }
11411
11233
  finally {
11412
11234
  if (!this.deoptimized)
@@ -11424,16 +11246,17 @@ class TaggedTemplateExpression extends CallExpressionBase {
11424
11246
  this.tag.include(context, includeChildrenRecursively);
11425
11247
  this.quasi.include(context, includeChildrenRecursively);
11426
11248
  }
11427
- this.tag.includeCallArguments(context, this.callOptions.args);
11249
+ this.tag.includeCallArguments(context, this.interaction.args);
11428
11250
  const returnExpression = this.getReturnExpression();
11429
11251
  if (!returnExpression.included) {
11430
11252
  returnExpression.include(context, false);
11431
11253
  }
11432
11254
  }
11433
11255
  initialise() {
11434
- this.callOptions = {
11256
+ this.interaction = {
11435
11257
  args: [UNKNOWN_EXPRESSION, ...this.quasi.expressions],
11436
- thisParam: this.tag instanceof MemberExpression && !this.tag.variable ? this.tag.object : null,
11258
+ thisArg: this.tag instanceof MemberExpression && !this.tag.variable ? this.tag.object : null,
11259
+ type: INTERACTION_CALLED,
11437
11260
  withNew: false
11438
11261
  };
11439
11262
  }
@@ -11443,9 +11266,8 @@ class TaggedTemplateExpression extends CallExpressionBase {
11443
11266
  }
11444
11267
  applyDeoptimizations() {
11445
11268
  this.deoptimized = true;
11446
- const { thisParam } = this.callOptions;
11447
- if (thisParam) {
11448
- this.tag.deoptimizeThisOnEventAtPath(EVENT_CALLED, EMPTY_PATH, thisParam, SHARED_RECURSION_TRACKER);
11269
+ if (this.interaction.thisArg) {
11270
+ this.tag.deoptimizeThisOnInteractionAtPath(this.interaction, EMPTY_PATH, SHARED_RECURSION_TRACKER);
11449
11271
  }
11450
11272
  for (const argument of this.quasi.expressions) {
11451
11273
  // This will make sure all properties of parameters behave as "unknown"
@@ -11456,7 +11278,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
11456
11278
  getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) {
11457
11279
  if (this.returnExpression === null) {
11458
11280
  this.returnExpression = UNKNOWN_EXPRESSION;
11459
- return (this.returnExpression = this.tag.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.callOptions, recursionTracker, this));
11281
+ return (this.returnExpression = this.tag.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this));
11460
11282
  }
11461
11283
  return this.returnExpression;
11462
11284
  }
@@ -11479,7 +11301,7 @@ class TemplateElement extends NodeBase {
11479
11301
  }
11480
11302
 
11481
11303
  class TemplateLiteral extends NodeBase {
11482
- deoptimizeThisOnEventAtPath() { }
11304
+ deoptimizeThisOnInteractionAtPath() { }
11483
11305
  getLiteralValueAtPath(path) {
11484
11306
  if (path.length > 0 || this.quasis.length !== 1) {
11485
11307
  return UnknownValue;
@@ -11492,12 +11314,12 @@ class TemplateLiteral extends NodeBase {
11492
11314
  }
11493
11315
  return getMemberReturnExpressionWhenCalled(literalStringMembers, path[0]);
11494
11316
  }
11495
- hasEffectsWhenAccessedAtPath(path) {
11496
- return path.length > 1;
11497
- }
11498
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
11499
- if (path.length === 1) {
11500
- return hasMemberEffectWhenCalled(literalStringMembers, path[0], callOptions, context);
11317
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
11318
+ if (interaction.type === INTERACTION_ACCESSED) {
11319
+ return path.length > 1;
11320
+ }
11321
+ if (interaction.type === INTERACTION_CALLED && path.length === 1) {
11322
+ return hasMemberEffectWhenCalled(literalStringMembers, path[0], interaction, context);
11501
11323
  }
11502
11324
  return true;
11503
11325
  }
@@ -11625,16 +11447,15 @@ class ThisExpression extends NodeBase {
11625
11447
  deoptimizePath(path) {
11626
11448
  this.variable.deoptimizePath(path);
11627
11449
  }
11628
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
11629
- this.variable.deoptimizeThisOnEventAtPath(event, path,
11450
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
11630
11451
  // We rewrite the parameter so that a ThisVariable can detect self-mutations
11631
- thisParameter === this ? this.variable : thisParameter, recursionTracker);
11632
- }
11633
- hasEffectsWhenAccessedAtPath(path, context) {
11634
- return path.length > 0 && this.variable.hasEffectsWhenAccessedAtPath(path, context);
11452
+ this.variable.deoptimizeThisOnInteractionAtPath(interaction.thisArg === this ? { ...interaction, thisArg: this.variable } : interaction, path, recursionTracker);
11635
11453
  }
11636
- hasEffectsWhenAssignedAtPath(path, context) {
11637
- return this.variable.hasEffectsWhenAssignedAtPath(path, context);
11454
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
11455
+ if (path.length === 0) {
11456
+ return interaction.type !== INTERACTION_ACCESSED;
11457
+ }
11458
+ return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
11638
11459
  }
11639
11460
  include() {
11640
11461
  if (!this.included) {
@@ -11743,13 +11564,10 @@ class UnaryExpression extends NodeBase {
11743
11564
  return false;
11744
11565
  return (this.argument.hasEffects(context) ||
11745
11566
  (this.operator === 'delete' &&
11746
- this.argument.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context)));
11567
+ this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_ASSIGNMENT, context)));
11747
11568
  }
11748
- hasEffectsWhenAccessedAtPath(path) {
11749
- if (this.operator === 'void') {
11750
- return path.length > 0;
11751
- }
11752
- return path.length > 1;
11569
+ hasEffectsOnInteractionAtPath(path, { type }) {
11570
+ return type !== INTERACTION_ACCESSED || path.length > (this.operator === 'void' ? 0 : 1);
11753
11571
  }
11754
11572
  applyDeoptimizations() {
11755
11573
  this.deoptimized = true;
@@ -11773,11 +11591,19 @@ class UpdateExpression extends NodeBase {
11773
11591
  hasEffects(context) {
11774
11592
  if (!this.deoptimized)
11775
11593
  this.applyDeoptimizations();
11776
- return (this.argument.hasEffects(context) ||
11777
- this.argument.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context));
11594
+ return this.argument.hasEffectsAsAssignmentTarget(context, true);
11778
11595
  }
11779
- hasEffectsWhenAccessedAtPath(path) {
11780
- return path.length > 1;
11596
+ hasEffectsOnInteractionAtPath(path, { type }) {
11597
+ return path.length > 1 || type !== INTERACTION_ACCESSED;
11598
+ }
11599
+ include(context, includeChildrenRecursively) {
11600
+ if (!this.deoptimized)
11601
+ this.applyDeoptimizations();
11602
+ this.included = true;
11603
+ this.argument.includeAsAssignmentTarget(context, includeChildrenRecursively, true);
11604
+ }
11605
+ initialise() {
11606
+ this.argument.setAssignedValue(UNKNOWN_EXPRESSION);
11781
11607
  }
11782
11608
  render(code, options) {
11783
11609
  const { exportNamesByVariable, format, snippets: { _ } } = options;
@@ -11839,7 +11665,7 @@ class VariableDeclaration extends NodeBase {
11839
11665
  declarator.deoptimizePath(EMPTY_PATH);
11840
11666
  }
11841
11667
  }
11842
- hasEffectsWhenAssignedAtPath() {
11668
+ hasEffectsOnInteractionAtPath() {
11843
11669
  return false;
11844
11670
  }
11845
11671
  include(context, includeChildrenRecursively, { asSingleStatement } = BLANK) {
@@ -12002,9 +11828,7 @@ class VariableDeclarator extends NodeBase {
12002
11828
  include(context, includeChildrenRecursively) {
12003
11829
  var _a;
12004
11830
  this.included = true;
12005
- (_a = this.init) === null || _a === void 0 ? void 0 : _a.include(context, includeChildrenRecursively, {
12006
- includeWithoutParameterDefaults: true
12007
- });
11831
+ (_a = this.init) === null || _a === void 0 ? void 0 : _a.include(context, includeChildrenRecursively);
12008
11832
  this.id.markDeclarationReached();
12009
11833
  if (includeChildrenRecursively || this.id.shouldBeIncluded(context)) {
12010
11834
  this.id.include(context, includeChildrenRecursively);
@@ -12059,7 +11883,7 @@ class YieldExpression extends NodeBase {
12059
11883
  var _a;
12060
11884
  if (!this.deoptimized)
12061
11885
  this.applyDeoptimizations();
12062
- return !context.ignore.returnYield || !!((_a = this.argument) === null || _a === void 0 ? void 0 : _a.hasEffects(context));
11886
+ return !(context.ignore.returnYield && !((_a = this.argument) === null || _a === void 0 ? void 0 : _a.hasEffects(context)));
12063
11887
  }
12064
11888
  render(code, options) {
12065
11889
  if (this.argument) {