rollup 2.75.3 → 2.75.6

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.3
4
- Sun, 29 May 2022 14:46:24 GMT - commit 279581594d642307218126f20092aaf822084d6a
3
+ Rollup.js v2.75.6
4
+ Tue, 07 Jun 2022 14:42:22 GMT - commit 0ab16cc04b7d6dfe5bd14340ba7448085a379e25
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.3";
17
+ var version$1 = "2.75.6";
18
18
 
19
19
  var charToInteger = {};
20
20
  var chars$1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
@@ -1594,8 +1594,8 @@ class ExpressionEntity {
1594
1594
  this.included = false;
1595
1595
  }
1596
1596
  deoptimizePath(_path) { }
1597
- deoptimizeThisOnEventAtPath(_event, _path, thisParameter, _recursionTracker) {
1598
- thisParameter.deoptimizePath(UNKNOWN_PATH);
1597
+ deoptimizeThisOnInteractionAtPath({ thisArg }, _path, _recursionTracker) {
1598
+ thisArg.deoptimizePath(UNKNOWN_PATH);
1599
1599
  }
1600
1600
  /**
1601
1601
  * If possible it returns a stringifyable literal value for this node that can be used
@@ -1605,16 +1605,10 @@ class ExpressionEntity {
1605
1605
  getLiteralValueAtPath(_path, _recursionTracker, _origin) {
1606
1606
  return UnknownValue;
1607
1607
  }
1608
- getReturnExpressionWhenCalledAtPath(_path, _callOptions, _recursionTracker, _origin) {
1608
+ getReturnExpressionWhenCalledAtPath(_path, _interaction, _recursionTracker, _origin) {
1609
1609
  return UNKNOWN_EXPRESSION;
1610
1610
  }
1611
- hasEffectsWhenAccessedAtPath(_path, _context) {
1612
- return true;
1613
- }
1614
- hasEffectsWhenAssignedAtPath(_path, _context) {
1615
- return true;
1616
- }
1617
- hasEffectsWhenCalledAtPath(_path, _callOptions, _context) {
1611
+ hasEffectsOnInteractionAtPath(_path, _interaction, _context) {
1618
1612
  return true;
1619
1613
  }
1620
1614
  include(_context, _includeChildrenRecursively, _options) {
@@ -1632,6 +1626,30 @@ class ExpressionEntity {
1632
1626
  const UNKNOWN_EXPRESSION = new (class UnknownExpression extends ExpressionEntity {
1633
1627
  })();
1634
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
+
1635
1653
  class Variable extends ExpressionEntity {
1636
1654
  constructor(name) {
1637
1655
  super();
@@ -1656,8 +1674,8 @@ class Variable extends ExpressionEntity {
1656
1674
  const name = this.renderName || this.name;
1657
1675
  return this.renderBaseName ? `${this.renderBaseName}${getPropertyAccess(name)}` : name;
1658
1676
  }
1659
- hasEffectsWhenAccessedAtPath(path, _context) {
1660
- return path.length > 0;
1677
+ hasEffectsOnInteractionAtPath(path, { type }, _context) {
1678
+ return type !== INTERACTION_ACCESSED || path.length > 0;
1661
1679
  }
1662
1680
  /**
1663
1681
  * Marks this variable as being part of the bundle, which is usually the case when one of
@@ -1688,8 +1706,8 @@ class ExternalVariable extends Variable {
1688
1706
  this.module.suggestName(identifier.name);
1689
1707
  }
1690
1708
  }
1691
- hasEffectsWhenAccessedAtPath(path) {
1692
- return path.length > (this.isNamespace ? 1 : 0);
1709
+ hasEffectsOnInteractionAtPath(path, { type }) {
1710
+ return type !== INTERACTION_ACCESSED || path.length > (this.isNamespace ? 1 : 0);
1693
1711
  }
1694
1712
  include() {
1695
1713
  if (!this.included) {
@@ -4579,8 +4597,6 @@ function createHasEffectsContext() {
4579
4597
  };
4580
4598
  }
4581
4599
 
4582
- const NO_ARGS = [];
4583
-
4584
4600
  function assembleMemberDescriptions(memberDescriptions, inheritedDescriptions = null) {
4585
4601
  return Object.create(inheritedDescriptions, memberDescriptions);
4586
4602
  }
@@ -4602,12 +4618,12 @@ const UNKNOWN_LITERAL_BOOLEAN = new (class UnknownBoolean extends ExpressionEnti
4602
4618
  }
4603
4619
  return UNKNOWN_EXPRESSION;
4604
4620
  }
4605
- hasEffectsWhenAccessedAtPath(path) {
4606
- return path.length > 1;
4607
- }
4608
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
4609
- if (path.length === 1) {
4610
- 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);
4611
4627
  }
4612
4628
  return true;
4613
4629
  }
@@ -4625,12 +4641,12 @@ const UNKNOWN_LITERAL_NUMBER = new (class UnknownNumber extends ExpressionEntity
4625
4641
  }
4626
4642
  return UNKNOWN_EXPRESSION;
4627
4643
  }
4628
- hasEffectsWhenAccessedAtPath(path) {
4629
- return path.length > 1;
4630
- }
4631
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
4632
- if (path.length === 1) {
4633
- 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);
4634
4650
  }
4635
4651
  return true;
4636
4652
  }
@@ -4648,12 +4664,12 @@ const UNKNOWN_LITERAL_STRING = new (class UnknownString extends ExpressionEntity
4648
4664
  }
4649
4665
  return UNKNOWN_EXPRESSION;
4650
4666
  }
4651
- hasEffectsWhenAccessedAtPath(path) {
4652
- return path.length > 1;
4653
- }
4654
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
4655
- if (path.length === 1) {
4656
- 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);
4657
4673
  }
4658
4674
  return true;
4659
4675
  }
@@ -4666,17 +4682,13 @@ const returnsString = {
4666
4682
  };
4667
4683
  const stringReplace = {
4668
4684
  value: {
4669
- hasEffectsWhenCalled(callOptions, context) {
4670
- const arg1 = callOptions.args[1];
4671
- return (callOptions.args.length < 2 ||
4685
+ hasEffectsWhenCalled({ args }, context) {
4686
+ const arg1 = args[1];
4687
+ return (args.length < 2 ||
4672
4688
  (typeof arg1.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, {
4673
4689
  deoptimizeCache() { }
4674
4690
  }) === 'symbol' &&
4675
- arg1.hasEffectsWhenCalledAtPath(EMPTY_PATH, {
4676
- args: NO_ARGS,
4677
- thisParam: null,
4678
- withNew: false
4679
- }, context)));
4691
+ arg1.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context)));
4680
4692
  },
4681
4693
  returns: UNKNOWN_LITERAL_STRING
4682
4694
  }
@@ -4760,12 +4772,12 @@ function getLiteralMembersForValue(value) {
4760
4772
  }
4761
4773
  return Object.create(null);
4762
4774
  }
4763
- function hasMemberEffectWhenCalled(members, memberName, callOptions, context) {
4775
+ function hasMemberEffectWhenCalled(members, memberName, interaction, context) {
4764
4776
  var _a, _b;
4765
4777
  if (typeof memberName !== 'string' || !members[memberName]) {
4766
4778
  return true;
4767
4779
  }
4768
- 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;
4769
4781
  }
4770
4782
  function getMemberReturnExpressionWhenCalled(members, memberName) {
4771
4783
  if (typeof memberName !== 'string' || !members[memberName])
@@ -5204,6 +5216,13 @@ const INCLUDE_PARAMETERS = 'variables';
5204
5216
  class NodeBase extends ExpressionEntity {
5205
5217
  constructor(esTreeNode, parent, parentScope) {
5206
5218
  super();
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
+ */
5225
+ this.deoptimized = false;
5207
5226
  this.esTreeNode = esTreeNode;
5208
5227
  this.keys = keys[esTreeNode.type] || getAndCreateKeys(esTreeNode);
5209
5228
  this.parent = parent;
@@ -5241,7 +5260,7 @@ class NodeBase extends ExpressionEntity {
5241
5260
  this.scope = parentScope;
5242
5261
  }
5243
5262
  hasEffects(context) {
5244
- if (this.deoptimized === false)
5263
+ if (!this.deoptimized)
5245
5264
  this.applyDeoptimizations();
5246
5265
  for (const key of this.keys) {
5247
5266
  const value = this[key];
@@ -5258,8 +5277,12 @@ class NodeBase extends ExpressionEntity {
5258
5277
  }
5259
5278
  return false;
5260
5279
  }
5280
+ hasEffectsAsAssignmentTarget(context, _checkAccess) {
5281
+ return (this.hasEffects(context) ||
5282
+ this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));
5283
+ }
5261
5284
  include(context, includeChildrenRecursively, _options) {
5262
- if (this.deoptimized === false)
5285
+ if (!this.deoptimized)
5263
5286
  this.applyDeoptimizations();
5264
5287
  this.included = true;
5265
5288
  for (const key of this.keys) {
@@ -5276,6 +5299,9 @@ class NodeBase extends ExpressionEntity {
5276
5299
  }
5277
5300
  }
5278
5301
  }
5302
+ includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {
5303
+ this.include(context, includeChildrenRecursively);
5304
+ }
5279
5305
  /**
5280
5306
  * Override to perform special initialisation steps after the scope is initialised
5281
5307
  */
@@ -5330,6 +5356,9 @@ class NodeBase extends ExpressionEntity {
5330
5356
  }
5331
5357
  }
5332
5358
  }
5359
+ setAssignedValue(value) {
5360
+ this.assignmentInteraction = { args: [value], thisArg: null, type: INTERACTION_ASSIGNED };
5361
+ }
5333
5362
  shouldBeIncluded(context) {
5334
5363
  return this.included || (!context.brokenFlow && this.hasEffects(createHasEffectsContext()));
5335
5364
  }
@@ -5358,13 +5387,9 @@ class NodeBase extends ExpressionEntity {
5358
5387
  }
5359
5388
 
5360
5389
  class SpreadElement extends NodeBase {
5361
- constructor() {
5362
- super(...arguments);
5363
- this.deoptimized = false;
5364
- }
5365
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
5390
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
5366
5391
  if (path.length > 0) {
5367
- this.argument.deoptimizeThisOnEventAtPath(event, [UnknownKey, ...path], thisParameter, recursionTracker);
5392
+ this.argument.deoptimizeThisOnInteractionAtPath(interaction, [UnknownKey, ...path], recursionTracker);
5368
5393
  }
5369
5394
  }
5370
5395
  hasEffects(context) {
@@ -5375,7 +5400,7 @@ class SpreadElement extends NodeBase {
5375
5400
  return (this.argument.hasEffects(context) ||
5376
5401
  (propertyReadSideEffects &&
5377
5402
  (propertyReadSideEffects === 'always' ||
5378
- this.argument.hasEffectsWhenAccessedAtPath(UNKNOWN_PATH, context))));
5403
+ this.argument.hasEffectsOnInteractionAtPath(UNKNOWN_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context))));
5379
5404
  }
5380
5405
  applyDeoptimizations() {
5381
5406
  this.deoptimized = true;
@@ -5386,53 +5411,43 @@ class SpreadElement extends NodeBase {
5386
5411
  }
5387
5412
  }
5388
5413
 
5389
- const EVENT_ACCESSED = 0;
5390
- const EVENT_ASSIGNED = 1;
5391
- const EVENT_CALLED = 2;
5392
-
5393
5414
  class Method extends ExpressionEntity {
5394
5415
  constructor(description) {
5395
5416
  super();
5396
5417
  this.description = description;
5397
5418
  }
5398
- deoptimizeThisOnEventAtPath(event, path, thisParameter) {
5399
- if (event === EVENT_CALLED && path.length === 0 && this.description.mutatesSelfAsArray) {
5400
- 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);
5401
5422
  }
5402
5423
  }
5403
- getReturnExpressionWhenCalledAtPath(path, callOptions) {
5424
+ getReturnExpressionWhenCalledAtPath(path, { thisArg }) {
5404
5425
  if (path.length > 0) {
5405
5426
  return UNKNOWN_EXPRESSION;
5406
5427
  }
5407
5428
  return (this.description.returnsPrimitive ||
5408
5429
  (this.description.returns === 'self'
5409
- ? callOptions.thisParam || UNKNOWN_EXPRESSION
5430
+ ? thisArg || UNKNOWN_EXPRESSION
5410
5431
  : this.description.returns()));
5411
5432
  }
5412
- hasEffectsWhenAccessedAtPath(path) {
5413
- return path.length > 1;
5414
- }
5415
- hasEffectsWhenAssignedAtPath(path) {
5416
- return path.length > 0;
5417
- }
5418
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
5433
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
5419
5434
  var _a, _b;
5420
- if (path.length > 0 ||
5421
- (this.description.mutatesSelfAsArray === true &&
5422
- ((_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)) {
5423
5437
  return true;
5424
5438
  }
5425
- if (!this.description.callsArgs) {
5426
- return false;
5427
- }
5428
- for (const argIndex of this.description.callsArgs) {
5429
- if ((_b = callOptions.args[argIndex]) === null || _b === void 0 ? void 0 : _b.hasEffectsWhenCalledAtPath(EMPTY_PATH, {
5430
- args: NO_ARGS,
5431
- thisParam: null,
5432
- withNew: false
5433
- }, 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))) {
5434
5442
  return true;
5435
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
+ }
5436
5451
  }
5437
5452
  return false;
5438
5453
  }
@@ -5574,24 +5589,24 @@ class ObjectEntity extends ExpressionEntity {
5574
5589
  }
5575
5590
  (_a = this.prototypeExpression) === null || _a === void 0 ? void 0 : _a.deoptimizePath(path.length === 1 ? [...path, UnknownKey] : path);
5576
5591
  }
5577
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
5592
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
5578
5593
  var _a;
5579
5594
  const [key, ...subPath] = path;
5580
5595
  if (this.hasLostTrack ||
5581
5596
  // single paths that are deoptimized will not become getters or setters
5582
- ((event === EVENT_CALLED || path.length > 1) &&
5597
+ ((interaction.type === INTERACTION_CALLED || path.length > 1) &&
5583
5598
  (this.hasUnknownDeoptimizedProperty ||
5584
5599
  (typeof key === 'string' && this.deoptimizedPaths[key])))) {
5585
- thisParameter.deoptimizePath(UNKNOWN_PATH);
5600
+ interaction.thisArg.deoptimizePath(UNKNOWN_PATH);
5586
5601
  return;
5587
5602
  }
5588
- const [propertiesForExactMatchByKey, relevantPropertiesByKey, relevantUnmatchableProperties] = event === EVENT_CALLED || path.length > 1
5603
+ const [propertiesForExactMatchByKey, relevantPropertiesByKey, relevantUnmatchableProperties] = interaction.type === INTERACTION_CALLED || path.length > 1
5589
5604
  ? [
5590
5605
  this.propertiesAndGettersByKey,
5591
5606
  this.propertiesAndGettersByKey,
5592
5607
  this.unmatchablePropertiesAndGetters
5593
5608
  ]
5594
- : event === EVENT_ACCESSED
5609
+ : interaction.type === INTERACTION_ACCESSED
5595
5610
  ? [this.propertiesAndGettersByKey, this.gettersByKey, this.unmatchableGetters]
5596
5611
  : [this.propertiesAndSettersByKey, this.settersByKey, this.unmatchableSetters];
5597
5612
  if (typeof key === 'string') {
@@ -5599,20 +5614,20 @@ class ObjectEntity extends ExpressionEntity {
5599
5614
  const properties = relevantPropertiesByKey[key];
5600
5615
  if (properties) {
5601
5616
  for (const property of properties) {
5602
- property.deoptimizeThisOnEventAtPath(event, subPath, thisParameter, recursionTracker);
5617
+ property.deoptimizeThisOnInteractionAtPath(interaction, subPath, recursionTracker);
5603
5618
  }
5604
5619
  }
5605
5620
  if (!this.immutable) {
5606
- this.thisParametersToBeDeoptimized.add(thisParameter);
5621
+ this.thisParametersToBeDeoptimized.add(interaction.thisArg);
5607
5622
  }
5608
5623
  return;
5609
5624
  }
5610
5625
  for (const property of relevantUnmatchableProperties) {
5611
- property.deoptimizeThisOnEventAtPath(event, subPath, thisParameter, recursionTracker);
5626
+ property.deoptimizeThisOnInteractionAtPath(interaction, subPath, recursionTracker);
5612
5627
  }
5613
5628
  if (INTEGER_REG_EXP.test(key)) {
5614
5629
  for (const property of this.unknownIntegerProps) {
5615
- property.deoptimizeThisOnEventAtPath(event, subPath, thisParameter, recursionTracker);
5630
+ property.deoptimizeThisOnInteractionAtPath(interaction, subPath, recursionTracker);
5616
5631
  }
5617
5632
  }
5618
5633
  }
@@ -5621,17 +5636,17 @@ class ObjectEntity extends ExpressionEntity {
5621
5636
  relevantUnmatchableProperties
5622
5637
  ])) {
5623
5638
  for (const property of properties) {
5624
- property.deoptimizeThisOnEventAtPath(event, subPath, thisParameter, recursionTracker);
5639
+ property.deoptimizeThisOnInteractionAtPath(interaction, subPath, recursionTracker);
5625
5640
  }
5626
5641
  }
5627
5642
  for (const property of this.unknownIntegerProps) {
5628
- property.deoptimizeThisOnEventAtPath(event, subPath, thisParameter, recursionTracker);
5643
+ property.deoptimizeThisOnInteractionAtPath(interaction, subPath, recursionTracker);
5629
5644
  }
5630
5645
  }
5631
5646
  if (!this.immutable) {
5632
- this.thisParametersToBeDeoptimized.add(thisParameter);
5647
+ this.thisParametersToBeDeoptimized.add(interaction.thisArg);
5633
5648
  }
5634
- (_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);
5635
5650
  }
5636
5651
  getLiteralValueAtPath(path, recursionTracker, origin) {
5637
5652
  if (path.length === 0) {
@@ -5650,79 +5665,29 @@ class ObjectEntity extends ExpressionEntity {
5650
5665
  }
5651
5666
  return UnknownValue;
5652
5667
  }
5653
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
5668
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
5654
5669
  if (path.length === 0) {
5655
5670
  return UNKNOWN_EXPRESSION;
5656
5671
  }
5657
- const key = path[0];
5672
+ const [key, ...subPath] = path;
5658
5673
  const expressionAtPath = this.getMemberExpressionAndTrackDeopt(key, origin);
5659
5674
  if (expressionAtPath) {
5660
- return expressionAtPath.getReturnExpressionWhenCalledAtPath(path.slice(1), callOptions, recursionTracker, origin);
5675
+ return expressionAtPath.getReturnExpressionWhenCalledAtPath(subPath, interaction, recursionTracker, origin);
5661
5676
  }
5662
5677
  if (this.prototypeExpression) {
5663
- return this.prototypeExpression.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
5678
+ return this.prototypeExpression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
5664
5679
  }
5665
5680
  return UNKNOWN_EXPRESSION;
5666
5681
  }
5667
- hasEffectsWhenAccessedAtPath(path, context) {
5668
- const [key, ...subPath] = path;
5669
- if (path.length > 1) {
5670
- if (typeof key !== 'string') {
5671
- return true;
5672
- }
5673
- const expressionAtPath = this.getMemberExpression(key);
5674
- if (expressionAtPath) {
5675
- return expressionAtPath.hasEffectsWhenAccessedAtPath(subPath, context);
5676
- }
5677
- if (this.prototypeExpression) {
5678
- return this.prototypeExpression.hasEffectsWhenAccessedAtPath(path, context);
5679
- }
5680
- return true;
5681
- }
5682
- if (this.hasLostTrack)
5683
- return true;
5684
- if (typeof key === 'string') {
5685
- if (this.propertiesAndGettersByKey[key]) {
5686
- const getters = this.gettersByKey[key];
5687
- if (getters) {
5688
- for (const getter of getters) {
5689
- if (getter.hasEffectsWhenAccessedAtPath(subPath, context))
5690
- return true;
5691
- }
5692
- }
5693
- return false;
5694
- }
5695
- for (const getter of this.unmatchableGetters) {
5696
- if (getter.hasEffectsWhenAccessedAtPath(subPath, context)) {
5697
- return true;
5698
- }
5699
- }
5700
- }
5701
- else {
5702
- for (const getters of Object.values(this.gettersByKey).concat([this.unmatchableGetters])) {
5703
- for (const getter of getters) {
5704
- if (getter.hasEffectsWhenAccessedAtPath(subPath, context))
5705
- return true;
5706
- }
5707
- }
5708
- }
5709
- if (this.prototypeExpression) {
5710
- return this.prototypeExpression.hasEffectsWhenAccessedAtPath(path, context);
5711
- }
5712
- return false;
5713
- }
5714
- hasEffectsWhenAssignedAtPath(path, context) {
5682
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
5715
5683
  const [key, ...subPath] = path;
5716
- if (path.length > 1) {
5717
- if (typeof key !== 'string') {
5718
- return true;
5719
- }
5684
+ if (subPath.length || interaction.type === INTERACTION_CALLED) {
5720
5685
  const expressionAtPath = this.getMemberExpression(key);
5721
5686
  if (expressionAtPath) {
5722
- return expressionAtPath.hasEffectsWhenAssignedAtPath(subPath, context);
5687
+ return expressionAtPath.hasEffectsOnInteractionAtPath(subPath, interaction, context);
5723
5688
  }
5724
5689
  if (this.prototypeExpression) {
5725
- return this.prototypeExpression.hasEffectsWhenAssignedAtPath(path, context);
5690
+ return this.prototypeExpression.hasEffectsOnInteractionAtPath(path, interaction, context);
5726
5691
  }
5727
5692
  return true;
5728
5693
  }
@@ -5730,47 +5695,39 @@ class ObjectEntity extends ExpressionEntity {
5730
5695
  return false;
5731
5696
  if (this.hasLostTrack)
5732
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];
5733
5701
  if (typeof key === 'string') {
5734
- if (this.propertiesAndSettersByKey[key]) {
5735
- const setters = this.settersByKey[key];
5736
- if (setters) {
5737
- for (const setter of setters) {
5738
- 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))
5739
5707
  return true;
5740
5708
  }
5741
5709
  }
5742
5710
  return false;
5743
5711
  }
5744
- for (const property of this.unmatchableSetters) {
5745
- if (property.hasEffectsWhenAssignedAtPath(subPath, context)) {
5712
+ for (const accessor of unmatchableAccessors) {
5713
+ if (accessor.hasEffectsOnInteractionAtPath(subPath, interaction, context)) {
5746
5714
  return true;
5747
5715
  }
5748
5716
  }
5749
5717
  }
5750
5718
  else {
5751
- for (const setters of Object.values(this.settersByKey).concat([this.unmatchableSetters])) {
5752
- for (const setter of setters) {
5753
- 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))
5754
5722
  return true;
5755
5723
  }
5756
5724
  }
5757
5725
  }
5758
5726
  if (this.prototypeExpression) {
5759
- return this.prototypeExpression.hasEffectsWhenAssignedAtPath(path, context);
5727
+ return this.prototypeExpression.hasEffectsOnInteractionAtPath(path, interaction, context);
5760
5728
  }
5761
5729
  return false;
5762
5730
  }
5763
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
5764
- const key = path[0];
5765
- const expressionAtPath = this.getMemberExpression(key);
5766
- if (expressionAtPath) {
5767
- return expressionAtPath.hasEffectsWhenCalledAtPath(path.slice(1), callOptions, context);
5768
- }
5769
- if (this.prototypeExpression) {
5770
- return this.prototypeExpression.hasEffectsWhenCalledAtPath(path, callOptions, context);
5771
- }
5772
- return true;
5773
- }
5774
5731
  buildPropertyMaps(properties) {
5775
5732
  const { allProperties, propertiesAndGettersByKey, propertiesAndSettersByKey, settersByKey, gettersByKey, unknownIntegerProps, unmatchablePropertiesAndGetters, unmatchableGetters, unmatchableSetters } = this;
5776
5733
  const unmatchablePropertiesAndSetters = [];
@@ -5876,9 +5833,9 @@ const isInteger = (prop) => typeof prop === 'string' && /^\d+$/.test(prop);
5876
5833
  // properties as we do not expect new builtin properties to be numbers, this
5877
5834
  // will improve tree-shaking for out-of-bounds array properties
5878
5835
  const OBJECT_PROTOTYPE_FALLBACK = new (class ObjectPrototypeFallbackExpression extends ExpressionEntity {
5879
- deoptimizeThisOnEventAtPath(event, path, thisParameter) {
5880
- if (event === EVENT_CALLED && path.length === 1 && !isInteger(path[0])) {
5881
- 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);
5882
5839
  }
5883
5840
  }
5884
5841
  getLiteralValueAtPath(path) {
@@ -5887,11 +5844,8 @@ const OBJECT_PROTOTYPE_FALLBACK = new (class ObjectPrototypeFallbackExpression e
5887
5844
  // "undefined"
5888
5845
  return path.length === 1 && isInteger(path[0]) ? undefined : UnknownValue;
5889
5846
  }
5890
- hasEffectsWhenAccessedAtPath(path) {
5891
- return path.length > 1;
5892
- }
5893
- hasEffectsWhenAssignedAtPath(path) {
5894
- return path.length > 1;
5847
+ hasEffectsOnInteractionAtPath(path, { type }) {
5848
+ return path.length > 1 || type === INTERACTION_CALLED;
5895
5849
  }
5896
5850
  })();
5897
5851
  const OBJECT_PROTOTYPE = new ObjectEntity({
@@ -6040,37 +5994,30 @@ const ARRAY_PROTOTYPE = new ObjectEntity({
6040
5994
  class ArrayExpression extends NodeBase {
6041
5995
  constructor() {
6042
5996
  super(...arguments);
6043
- this.deoptimized = false;
6044
5997
  this.objectEntity = null;
6045
5998
  }
6046
5999
  deoptimizePath(path) {
6047
6000
  this.getObjectEntity().deoptimizePath(path);
6048
6001
  }
6049
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
6050
- this.getObjectEntity().deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
6002
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
6003
+ this.getObjectEntity().deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
6051
6004
  }
6052
6005
  getLiteralValueAtPath(path, recursionTracker, origin) {
6053
6006
  return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);
6054
6007
  }
6055
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
6056
- return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
6008
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
6009
+ return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
6057
6010
  }
6058
- hasEffectsWhenAccessedAtPath(path, context) {
6059
- return this.getObjectEntity().hasEffectsWhenAccessedAtPath(path, context);
6060
- }
6061
- hasEffectsWhenAssignedAtPath(path, context) {
6062
- return this.getObjectEntity().hasEffectsWhenAssignedAtPath(path, context);
6063
- }
6064
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
6065
- return this.getObjectEntity().hasEffectsWhenCalledAtPath(path, callOptions, context);
6011
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
6012
+ return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
6066
6013
  }
6067
6014
  applyDeoptimizations() {
6068
6015
  this.deoptimized = true;
6069
6016
  let hasSpread = false;
6070
6017
  for (let index = 0; index < this.elements.length; index++) {
6071
6018
  const element = this.elements[index];
6072
- if (hasSpread || element instanceof SpreadElement) {
6073
- if (element) {
6019
+ if (element) {
6020
+ if (hasSpread || element instanceof SpreadElement) {
6074
6021
  hasSpread = true;
6075
6022
  element.deoptimizePath(UNKNOWN_PATH);
6076
6023
  }
@@ -6127,9 +6074,9 @@ class ArrayPattern extends NodeBase {
6127
6074
  }
6128
6075
  }
6129
6076
  // Patterns are only checked at the emtpy path at the moment
6130
- hasEffectsWhenAssignedAtPath(_path, context) {
6077
+ hasEffectsOnInteractionAtPath(_path, interaction, context) {
6131
6078
  for (const element of this.elements) {
6132
- 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))
6133
6080
  return true;
6134
6081
  }
6135
6082
  return false;
@@ -6188,11 +6135,11 @@ class LocalVariable extends Variable {
6188
6135
  (_b = this.init) === null || _b === void 0 ? void 0 : _b.deoptimizePath(path);
6189
6136
  }
6190
6137
  }
6191
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
6138
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
6192
6139
  if (this.isReassigned || !this.init) {
6193
- return thisParameter.deoptimizePath(UNKNOWN_PATH);
6140
+ return interaction.thisArg.deoptimizePath(UNKNOWN_PATH);
6194
6141
  }
6195
- 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);
6196
6143
  }
6197
6144
  getLiteralValueAtPath(path, recursionTracker, origin) {
6198
6145
  if (this.isReassigned || !this.init) {
@@ -6203,39 +6150,40 @@ class LocalVariable extends Variable {
6203
6150
  return this.init.getLiteralValueAtPath(path, recursionTracker, origin);
6204
6151
  }, UnknownValue);
6205
6152
  }
6206
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
6153
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
6207
6154
  if (this.isReassigned || !this.init) {
6208
6155
  return UNKNOWN_EXPRESSION;
6209
6156
  }
6210
6157
  return recursionTracker.withTrackedEntityAtPath(path, this.init, () => {
6211
6158
  this.expressionsToBeDeoptimized.push(origin);
6212
- return this.init.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
6159
+ return this.init.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
6213
6160
  }, UNKNOWN_EXPRESSION);
6214
6161
  }
6215
- hasEffectsWhenAccessedAtPath(path, context) {
6216
- if (this.isReassigned)
6217
- return true;
6218
- return (this.init &&
6219
- !context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
6220
- this.init.hasEffectsWhenAccessedAtPath(path, context));
6221
- }
6222
- hasEffectsWhenAssignedAtPath(path, context) {
6223
- if (this.included)
6224
- return true;
6225
- if (path.length === 0)
6226
- return false;
6227
- if (this.isReassigned)
6228
- return true;
6229
- return (this.init &&
6230
- !context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
6231
- this.init.hasEffectsWhenAssignedAtPath(path, context));
6232
- }
6233
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
6234
- if (this.isReassigned)
6235
- return true;
6236
- return (this.init &&
6237
- !(callOptions.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, callOptions, this) &&
6238
- 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
+ }
6239
6187
  }
6240
6188
  include() {
6241
6189
  if (!this.included) {
@@ -6512,642 +6460,87 @@ class ReturnValueScope extends ParameterScope {
6512
6460
  }
6513
6461
  }
6514
6462
 
6515
- class AssignmentPattern extends NodeBase {
6516
- constructor() {
6517
- super(...arguments);
6518
- this.deoptimized = false;
6519
- }
6520
- addExportedVariables(variables, exportNamesByVariable) {
6521
- this.left.addExportedVariables(variables, exportNamesByVariable);
6522
- }
6523
- declare(kind, init) {
6524
- return this.left.declare(kind, init);
6525
- }
6526
- deoptimizePath(path) {
6527
- path.length === 0 && this.left.deoptimizePath(path);
6528
- }
6529
- hasEffectsWhenAssignedAtPath(path, context) {
6530
- return path.length > 0 || this.left.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context);
6531
- }
6532
- // Note that FunctionBase may directly include .left and .right without
6533
- // including the pattern itself. This is how default parameter tree-shaking
6534
- // works at the moment.
6535
- include(context, includeChildrenRecursively) {
6536
- this.included = true;
6537
- this.left.include(context, includeChildrenRecursively);
6538
- this.right.include(context, includeChildrenRecursively);
6539
- }
6540
- markDeclarationReached() {
6541
- this.left.markDeclarationReached();
6542
- }
6543
- render(code, options, { isShorthandProperty } = BLANK) {
6544
- this.left.render(code, options, { isShorthandProperty });
6545
- if (this.right.included) {
6546
- this.right.render(code, options);
6547
- }
6548
- else {
6549
- code.remove(this.left.end, this.end);
6550
- }
6551
- }
6552
- applyDeoptimizations() {
6553
- this.deoptimized = true;
6554
- this.left.deoptimizePath(EMPTY_PATH);
6555
- this.right.deoptimizePath(UNKNOWN_PATH);
6556
- this.context.requestTreeshakingPass();
6557
- }
6558
- }
6463
+ //@ts-check
6464
+ /** @typedef { import('estree').Node} Node */
6465
+ /** @typedef {Node | {
6466
+ * type: 'PropertyDefinition';
6467
+ * computed: boolean;
6468
+ * value: Node
6469
+ * }} NodeWithPropertyDefinition */
6559
6470
 
6560
- function treeshakeNode(node, code, start, end) {
6561
- code.remove(start, end);
6562
- if (node.annotations) {
6563
- for (const annotation of node.annotations) {
6564
- if (annotation.start < start) {
6565
- code.remove(annotation.start, annotation.end);
6566
- }
6567
- else {
6568
- return;
6569
- }
6570
- }
6571
- }
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;
6572
6512
  }
6573
- function removeAnnotations(node, code) {
6574
- if (!node.annotations && node.parent.type === ExpressionStatement$1) {
6575
- node = node.parent;
6513
+
6514
+ /* eslint sort-keys: "off" */
6515
+ const ValueProperties = Symbol('Value Properties');
6516
+ const PURE = {
6517
+ hasEffectsWhenCalled() {
6518
+ return false;
6576
6519
  }
6577
- if (node.annotations) {
6578
- for (const annotation of node.annotations) {
6579
- code.remove(annotation.start, annotation.end);
6580
- }
6520
+ };
6521
+ const IMPURE = {
6522
+ hasEffectsWhenCalled() {
6523
+ return true;
6581
6524
  }
6582
- }
6583
-
6584
- const NO_SEMICOLON = { isNoStatement: true };
6585
- // This assumes there are only white-space and comments between start and the string we are looking for
6586
- function findFirstOccurrenceOutsideComment(code, searchString, start = 0) {
6587
- let searchPos, charCodeAfterSlash;
6588
- searchPos = code.indexOf(searchString, start);
6589
- while (true) {
6590
- start = code.indexOf('/', start);
6591
- if (start === -1 || start >= searchPos)
6592
- return searchPos;
6593
- charCodeAfterSlash = code.charCodeAt(++start);
6594
- ++start;
6595
- // With our assumption, '/' always starts a comment. Determine comment type:
6596
- start =
6597
- charCodeAfterSlash === 47 /*"/"*/
6598
- ? code.indexOf('\n', start) + 1
6599
- : code.indexOf('*/', start) + 2;
6600
- if (start > searchPos) {
6601
- searchPos = code.indexOf(searchString, start);
6602
- }
6603
- }
6604
- }
6605
- const NON_WHITESPACE = /\S/g;
6606
- function findNonWhiteSpace(code, index) {
6607
- NON_WHITESPACE.lastIndex = index;
6608
- const result = NON_WHITESPACE.exec(code);
6609
- return result.index;
6610
- }
6611
- // This assumes "code" only contains white-space and comments
6612
- // Returns position of line-comment if applicable
6613
- function findFirstLineBreakOutsideComment(code) {
6614
- let lineBreakPos, charCodeAfterSlash, start = 0;
6615
- lineBreakPos = code.indexOf('\n', start);
6616
- while (true) {
6617
- start = code.indexOf('/', start);
6618
- if (start === -1 || start > lineBreakPos)
6619
- return [lineBreakPos, lineBreakPos + 1];
6620
- // With our assumption, '/' always starts a comment. Determine comment type:
6621
- charCodeAfterSlash = code.charCodeAt(start + 1);
6622
- if (charCodeAfterSlash === 47 /*"/"*/)
6623
- return [start, lineBreakPos + 1];
6624
- start = code.indexOf('*/', start + 3) + 2;
6625
- if (start > lineBreakPos) {
6626
- lineBreakPos = code.indexOf('\n', start);
6627
- }
6628
- }
6629
- }
6630
- function renderStatementList(statements, code, start, end, options) {
6631
- let currentNode, currentNodeStart, currentNodeNeedsBoundaries, nextNodeStart;
6632
- let nextNode = statements[0];
6633
- let nextNodeNeedsBoundaries = !nextNode.included || nextNode.needsBoundaries;
6634
- if (nextNodeNeedsBoundaries) {
6635
- nextNodeStart =
6636
- start + findFirstLineBreakOutsideComment(code.original.slice(start, nextNode.start))[1];
6637
- }
6638
- for (let nextIndex = 1; nextIndex <= statements.length; nextIndex++) {
6639
- currentNode = nextNode;
6640
- currentNodeStart = nextNodeStart;
6641
- currentNodeNeedsBoundaries = nextNodeNeedsBoundaries;
6642
- nextNode = statements[nextIndex];
6643
- nextNodeNeedsBoundaries =
6644
- nextNode === undefined ? false : !nextNode.included || nextNode.needsBoundaries;
6645
- if (currentNodeNeedsBoundaries || nextNodeNeedsBoundaries) {
6646
- nextNodeStart =
6647
- currentNode.end +
6648
- findFirstLineBreakOutsideComment(code.original.slice(currentNode.end, nextNode === undefined ? end : nextNode.start))[1];
6649
- if (currentNode.included) {
6650
- currentNodeNeedsBoundaries
6651
- ? currentNode.render(code, options, {
6652
- end: nextNodeStart,
6653
- start: currentNodeStart
6654
- })
6655
- : currentNode.render(code, options);
6656
- }
6657
- else {
6658
- treeshakeNode(currentNode, code, currentNodeStart, nextNodeStart);
6659
- }
6660
- }
6661
- else {
6662
- currentNode.render(code, options);
6663
- }
6664
- }
6665
- }
6666
- // This assumes that the first character is not part of the first node
6667
- function getCommaSeparatedNodesWithBoundaries(nodes, code, start, end) {
6668
- const splitUpNodes = [];
6669
- let node, nextNode, nextNodeStart, contentEnd, char;
6670
- let separator = start - 1;
6671
- for (let nextIndex = 0; nextIndex < nodes.length; nextIndex++) {
6672
- nextNode = nodes[nextIndex];
6673
- if (node !== undefined) {
6674
- separator =
6675
- node.end +
6676
- findFirstOccurrenceOutsideComment(code.original.slice(node.end, nextNode.start), ',');
6677
- }
6678
- nextNodeStart = contentEnd =
6679
- separator +
6680
- 1 +
6681
- findFirstLineBreakOutsideComment(code.original.slice(separator + 1, nextNode.start))[1];
6682
- while (((char = code.original.charCodeAt(nextNodeStart)),
6683
- char === 32 /*" "*/ || char === 9 /*"\t"*/ || char === 10 /*"\n"*/ || char === 13) /*"\r"*/)
6684
- nextNodeStart++;
6685
- if (node !== undefined) {
6686
- splitUpNodes.push({
6687
- contentEnd,
6688
- end: nextNodeStart,
6689
- node,
6690
- separator,
6691
- start
6692
- });
6693
- }
6694
- node = nextNode;
6695
- start = nextNodeStart;
6696
- }
6697
- splitUpNodes.push({
6698
- contentEnd: end,
6699
- end,
6700
- node: node,
6701
- separator: null,
6702
- start
6703
- });
6704
- return splitUpNodes;
6705
- }
6706
- // This assumes there are only white-space and comments between start and end
6707
- function removeLineBreaks(code, start, end) {
6708
- while (true) {
6709
- const [removeStart, removeEnd] = findFirstLineBreakOutsideComment(code.original.slice(start, end));
6710
- if (removeStart === -1) {
6711
- break;
6712
- }
6713
- code.remove(start + removeStart, (start += removeEnd));
6714
- }
6715
- }
6716
-
6717
- class BlockScope extends ChildScope {
6718
- addDeclaration(identifier, context, init, isHoisted) {
6719
- if (isHoisted) {
6720
- const variable = this.parent.addDeclaration(identifier, context, init, isHoisted);
6721
- // Necessary to make sure the init is deoptimized for conditional declarations.
6722
- // We cannot call deoptimizePath here.
6723
- variable.markInitializersForDeoptimization();
6724
- return variable;
6725
- }
6726
- else {
6727
- return super.addDeclaration(identifier, context, init, false);
6728
- }
6729
- }
6730
- }
6731
-
6732
- class ExpressionStatement extends NodeBase {
6733
- initialise() {
6734
- if (this.directive &&
6735
- this.directive !== 'use strict' &&
6736
- this.parent.type === Program$1) {
6737
- this.context.warn(
6738
- // This is necessary, because either way (deleting or not) can lead to errors.
6739
- {
6740
- code: 'MODULE_LEVEL_DIRECTIVE',
6741
- message: `Module level directives cause errors when bundled, '${this.directive}' was ignored.`
6742
- }, this.start);
6743
- }
6744
- }
6745
- render(code, options) {
6746
- super.render(code, options);
6747
- if (this.included)
6748
- this.insertSemicolon(code);
6749
- }
6750
- shouldBeIncluded(context) {
6751
- if (this.directive && this.directive !== 'use strict')
6752
- return this.parent.type !== Program$1;
6753
- return super.shouldBeIncluded(context);
6754
- }
6755
- }
6756
-
6757
- class BlockStatement extends NodeBase {
6758
- constructor() {
6759
- super(...arguments);
6760
- this.directlyIncluded = false;
6761
- }
6762
- addImplicitReturnExpressionToScope() {
6763
- const lastStatement = this.body[this.body.length - 1];
6764
- if (!lastStatement || lastStatement.type !== ReturnStatement$1) {
6765
- this.scope.addReturnExpression(UNKNOWN_EXPRESSION);
6766
- }
6767
- }
6768
- createScope(parentScope) {
6769
- this.scope = this.parent.preventChildBlockScope
6770
- ? parentScope
6771
- : new BlockScope(parentScope);
6772
- }
6773
- hasEffects(context) {
6774
- if (this.deoptimizeBody)
6775
- return true;
6776
- for (const node of this.body) {
6777
- if (context.brokenFlow)
6778
- break;
6779
- if (node.hasEffects(context))
6780
- return true;
6781
- }
6782
- return false;
6783
- }
6784
- include(context, includeChildrenRecursively) {
6785
- if (!(this.deoptimizeBody && this.directlyIncluded)) {
6786
- this.included = true;
6787
- this.directlyIncluded = true;
6788
- if (this.deoptimizeBody)
6789
- includeChildrenRecursively = true;
6790
- for (const node of this.body) {
6791
- if (includeChildrenRecursively || node.shouldBeIncluded(context))
6792
- node.include(context, includeChildrenRecursively);
6793
- }
6794
- }
6795
- }
6796
- initialise() {
6797
- const firstBodyStatement = this.body[0];
6798
- this.deoptimizeBody =
6799
- firstBodyStatement instanceof ExpressionStatement &&
6800
- firstBodyStatement.directive === 'use asm';
6801
- }
6802
- render(code, options) {
6803
- if (this.body.length) {
6804
- renderStatementList(this.body, code, this.start + 1, this.end - 1, options);
6805
- }
6806
- else {
6807
- super.render(code, options);
6808
- }
6809
- }
6810
- }
6811
-
6812
- class RestElement extends NodeBase {
6813
- constructor() {
6814
- super(...arguments);
6815
- this.deoptimized = false;
6816
- this.declarationInit = null;
6817
- }
6818
- addExportedVariables(variables, exportNamesByVariable) {
6819
- this.argument.addExportedVariables(variables, exportNamesByVariable);
6820
- }
6821
- declare(kind, init) {
6822
- this.declarationInit = init;
6823
- return this.argument.declare(kind, UNKNOWN_EXPRESSION);
6824
- }
6825
- deoptimizePath(path) {
6826
- path.length === 0 && this.argument.deoptimizePath(EMPTY_PATH);
6827
- }
6828
- hasEffectsWhenAssignedAtPath(path, context) {
6829
- return path.length > 0 || this.argument.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context);
6830
- }
6831
- markDeclarationReached() {
6832
- this.argument.markDeclarationReached();
6833
- }
6834
- applyDeoptimizations() {
6835
- this.deoptimized = true;
6836
- if (this.declarationInit !== null) {
6837
- this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
6838
- this.context.requestTreeshakingPass();
6839
- }
6840
- }
6841
- }
6842
-
6843
- class FunctionBase extends NodeBase {
6844
- constructor() {
6845
- super(...arguments);
6846
- this.objectEntity = null;
6847
- this.deoptimizedReturn = false;
6848
- this.forceIncludeParameters = false;
6849
- }
6850
- deoptimizeCache() {
6851
- this.forceIncludeParameters = true;
6852
- }
6853
- deoptimizePath(path) {
6854
- this.getObjectEntity().deoptimizePath(path);
6855
- if (path.length === 1 && path[0] === UnknownKey) {
6856
- // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
6857
- // which means the return expression needs to be reassigned
6858
- this.forceIncludeParameters = true;
6859
- this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
6860
- }
6861
- }
6862
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
6863
- if (path.length > 0) {
6864
- this.getObjectEntity().deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
6865
- }
6866
- }
6867
- getLiteralValueAtPath(path, recursionTracker, origin) {
6868
- return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);
6869
- }
6870
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
6871
- if (path.length > 0) {
6872
- return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
6873
- }
6874
- if (this.async) {
6875
- if (!this.deoptimizedReturn) {
6876
- this.deoptimizedReturn = true;
6877
- this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
6878
- this.context.requestTreeshakingPass();
6879
- }
6880
- return UNKNOWN_EXPRESSION;
6881
- }
6882
- return this.scope.getReturnExpression();
6883
- }
6884
- hasEffectsWhenAccessedAtPath(path, context) {
6885
- return this.getObjectEntity().hasEffectsWhenAccessedAtPath(path, context);
6886
- }
6887
- hasEffectsWhenAssignedAtPath(path, context) {
6888
- return this.getObjectEntity().hasEffectsWhenAssignedAtPath(path, context);
6889
- }
6890
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
6891
- var _a;
6892
- if (path.length > 0) {
6893
- return this.getObjectEntity().hasEffectsWhenCalledAtPath(path, callOptions, context);
6894
- }
6895
- if (this.async) {
6896
- const { propertyReadSideEffects } = this.context.options
6897
- .treeshake;
6898
- const returnExpression = this.scope.getReturnExpression();
6899
- if (returnExpression.hasEffectsWhenCalledAtPath(['then'], { args: NO_ARGS, thisParam: null, withNew: false }, context) ||
6900
- (propertyReadSideEffects &&
6901
- (propertyReadSideEffects === 'always' ||
6902
- returnExpression.hasEffectsWhenAccessedAtPath(['then'], context)))) {
6903
- return true;
6904
- }
6905
- }
6906
- for (let position = 0; position < this.params.length; position++) {
6907
- const parameter = this.params[position];
6908
- if (parameter instanceof AssignmentPattern) {
6909
- if (parameter.left.hasEffects(context)) {
6910
- return true;
6911
- }
6912
- const argumentValue = (_a = callOptions.args[position]) === null || _a === void 0 ? void 0 : _a.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
6913
- if ((argumentValue === undefined || argumentValue === UnknownValue) &&
6914
- parameter.right.hasEffects(context)) {
6915
- return true;
6916
- }
6917
- }
6918
- else if (parameter.hasEffects(context)) {
6919
- return true;
6920
- }
6921
- }
6922
- return false;
6923
- }
6924
- include(context, includeChildrenRecursively, { includeWithoutParameterDefaults } = BLANK) {
6925
- if (!this.deoptimized)
6926
- this.applyDeoptimizations();
6927
- this.included = true;
6928
- const { brokenFlow } = context;
6929
- context.brokenFlow = BROKEN_FLOW_NONE;
6930
- this.body.include(context, includeChildrenRecursively);
6931
- context.brokenFlow = brokenFlow;
6932
- if (!includeWithoutParameterDefaults ||
6933
- includeChildrenRecursively ||
6934
- this.forceIncludeParameters) {
6935
- for (const param of this.params) {
6936
- param.include(context, includeChildrenRecursively);
6937
- }
6938
- }
6939
- }
6940
- includeCallArguments(context, args) {
6941
- var _a;
6942
- for (let position = 0; position < this.params.length; position++) {
6943
- const parameter = this.params[position];
6944
- if (parameter instanceof AssignmentPattern) {
6945
- if (parameter.left.shouldBeIncluded(context)) {
6946
- parameter.left.include(context, false);
6947
- }
6948
- const argumentValue = (_a = args[position]) === null || _a === void 0 ? void 0 : _a.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);
6949
- // If argumentValue === UnknownTruthyValue, then we do not need to
6950
- // include the default
6951
- if ((argumentValue === undefined || argumentValue === UnknownValue) &&
6952
- (this.parameterVariables[position].some(variable => variable.included) ||
6953
- parameter.right.shouldBeIncluded(context))) {
6954
- parameter.right.include(context, false);
6955
- }
6956
- }
6957
- else if (parameter.shouldBeIncluded(context)) {
6958
- parameter.include(context, false);
6959
- }
6960
- }
6961
- this.scope.includeCallArguments(context, args);
6962
- }
6963
- initialise() {
6964
- this.parameterVariables = this.params.map(param => param.declare('parameter', UNKNOWN_EXPRESSION));
6965
- this.scope.addParameterVariables(this.parameterVariables, this.params[this.params.length - 1] instanceof RestElement);
6966
- if (this.body instanceof BlockStatement) {
6967
- this.body.addImplicitReturnExpressionToScope();
6968
- }
6969
- else {
6970
- this.scope.addReturnExpression(this.body);
6971
- }
6972
- }
6973
- parseNode(esTreeNode) {
6974
- if (esTreeNode.body.type === BlockStatement$1) {
6975
- this.body = new BlockStatement(esTreeNode.body, this, this.scope.hoistedBodyVarScope);
6976
- }
6977
- super.parseNode(esTreeNode);
6978
- }
6979
- applyDeoptimizations() {
6980
- // We currently do not track deoptimizations of default values, deoptimize them
6981
- // just as we deoptimize call arguments
6982
- for (const param of this.params) {
6983
- if (param instanceof AssignmentPattern) {
6984
- param.right.deoptimizePath(UNKNOWN_PATH);
6985
- }
6986
- }
6987
- }
6988
- }
6989
- FunctionBase.prototype.preventChildBlockScope = true;
6990
-
6991
- class ArrowFunctionExpression extends FunctionBase {
6992
- constructor() {
6993
- super(...arguments);
6994
- this.objectEntity = null;
6995
- }
6996
- createScope(parentScope) {
6997
- this.scope = new ReturnValueScope(parentScope, this.context);
6998
- }
6999
- hasEffects() {
7000
- if (!this.deoptimized)
7001
- this.applyDeoptimizations();
7002
- return false;
7003
- }
7004
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
7005
- if (super.hasEffectsWhenCalledAtPath(path, callOptions, context))
7006
- return true;
7007
- const { ignore, brokenFlow } = context;
7008
- context.ignore = {
7009
- breaks: false,
7010
- continues: false,
7011
- labels: new Set(),
7012
- returnYield: true
7013
- };
7014
- if (this.body.hasEffects(context))
7015
- return true;
7016
- context.ignore = ignore;
7017
- context.brokenFlow = brokenFlow;
7018
- return false;
7019
- }
7020
- getObjectEntity() {
7021
- if (this.objectEntity !== null) {
7022
- return this.objectEntity;
7023
- }
7024
- return (this.objectEntity = new ObjectEntity([], OBJECT_PROTOTYPE));
7025
- }
7026
- }
7027
-
7028
- function getSystemExportStatement(exportedVariables, { exportNamesByVariable, snippets: { _, getObject, getPropertyAccess } }, modifier = '') {
7029
- if (exportedVariables.length === 1 &&
7030
- exportNamesByVariable.get(exportedVariables[0]).length === 1) {
7031
- const variable = exportedVariables[0];
7032
- return `exports('${exportNamesByVariable.get(variable)}',${_}${variable.getName(getPropertyAccess)}${modifier})`;
7033
- }
7034
- else {
7035
- const fields = [];
7036
- for (const variable of exportedVariables) {
7037
- for (const exportName of exportNamesByVariable.get(variable)) {
7038
- fields.push([exportName, variable.getName(getPropertyAccess) + modifier]);
7039
- }
7040
- }
7041
- return `exports(${getObject(fields, { lineBreakIndent: null })})`;
7042
- }
7043
- }
7044
- function renderSystemExportExpression(exportedVariable, expressionStart, expressionEnd, code, { exportNamesByVariable, snippets: { _ } }) {
7045
- code.prependRight(expressionStart, `exports('${exportNamesByVariable.get(exportedVariable)}',${_}`);
7046
- code.appendLeft(expressionEnd, ')');
7047
- }
7048
- function renderSystemExportFunction(exportedVariables, expressionStart, expressionEnd, needsParens, code, options) {
7049
- const { _, getDirectReturnIifeLeft } = options.snippets;
7050
- code.prependRight(expressionStart, getDirectReturnIifeLeft(['v'], `${getSystemExportStatement(exportedVariables, options)},${_}v`, { needsArrowReturnParens: true, needsWrappedFunction: needsParens }));
7051
- code.appendLeft(expressionEnd, ')');
7052
- }
7053
- function renderSystemExportSequenceAfterExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options) {
7054
- const { _, getPropertyAccess } = options.snippets;
7055
- code.appendLeft(expressionEnd, `,${_}${getSystemExportStatement([exportedVariable], options)},${_}${exportedVariable.getName(getPropertyAccess)}`);
7056
- if (needsParens) {
7057
- code.prependRight(expressionStart, '(');
7058
- code.appendLeft(expressionEnd, ')');
7059
- }
7060
- }
7061
- function renderSystemExportSequenceBeforeExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options, modifier) {
7062
- const { _ } = options.snippets;
7063
- code.prependRight(expressionStart, `${getSystemExportStatement([exportedVariable], options, modifier)},${_}`);
7064
- if (needsParens) {
7065
- code.prependRight(expressionStart, '(');
7066
- code.appendLeft(expressionEnd, ')');
7067
- }
7068
- }
7069
-
7070
- //@ts-check
7071
- /** @typedef { import('estree').Node} Node */
7072
- /** @typedef {Node | {
7073
- * type: 'PropertyDefinition';
7074
- * computed: boolean;
7075
- * value: Node
7076
- * }} NodeWithPropertyDefinition */
7077
-
7078
- /**
7079
- *
7080
- * @param {NodeWithPropertyDefinition} node
7081
- * @param {NodeWithPropertyDefinition} parent
7082
- * @returns boolean
7083
- */
7084
- function is_reference (node, parent) {
7085
- if (node.type === 'MemberExpression') {
7086
- return !node.computed && is_reference(node.object, node);
7087
- }
7088
-
7089
- if (node.type === 'Identifier') {
7090
- if (!parent) return true;
7091
-
7092
- switch (parent.type) {
7093
- // disregard `bar` in `foo.bar`
7094
- case 'MemberExpression': return parent.computed || node === parent.object;
7095
-
7096
- // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
7097
- case 'MethodDefinition': return parent.computed;
7098
-
7099
- // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
7100
- case 'PropertyDefinition': return parent.computed || node === parent.value;
7101
-
7102
- // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
7103
- case 'Property': return parent.computed || node === parent.value;
7104
-
7105
- // disregard the `bar` in `export { foo as bar }` or
7106
- // the foo in `import { foo as bar }`
7107
- case 'ExportSpecifier':
7108
- case 'ImportSpecifier': return node === parent.local;
7109
-
7110
- // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
7111
- case 'LabeledStatement':
7112
- case 'BreakStatement':
7113
- case 'ContinueStatement': return false;
7114
- default: return true;
7115
- }
7116
- }
7117
-
7118
- return false;
7119
- }
7120
-
7121
- /* eslint sort-keys: "off" */
7122
- const ValueProperties = Symbol('Value Properties');
7123
- const PURE = {
7124
- hasEffectsWhenCalled() {
7125
- return false;
7126
- }
7127
- };
7128
- const IMPURE = {
7129
- hasEffectsWhenCalled() {
7130
- return true;
7131
- }
7132
- };
7133
- // We use shortened variables to reduce file size here
7134
- /* OBJECT */
7135
- const O = {
7136
- __proto__: null,
7137
- [ValueProperties]: IMPURE
7138
- };
7139
- /* PURE FUNCTION */
7140
- const PF = {
7141
- __proto__: null,
7142
- [ValueProperties]: PURE
7143
- };
7144
- /* FUNCTION THAT MUTATES FIRST ARG WITHOUT TRIGGERING ACCESSORS */
7145
- const MUTATES_ARG_WITHOUT_ACCESSOR = {
7146
- __proto__: null,
7147
- [ValueProperties]: {
7148
- hasEffectsWhenCalled(callOptions, context) {
7149
- return (!callOptions.args.length ||
7150
- 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));
7151
6544
  }
7152
6545
  }
7153
6546
  };
@@ -7964,222 +7357,691 @@ const knownGlobals = {
7964
7357
  for (const global of ['window', 'global', 'self', 'globalThis']) {
7965
7358
  knownGlobals[global] = knownGlobals;
7966
7359
  }
7967
- function getGlobalAtPath(path) {
7968
- let currentGlobal = knownGlobals;
7969
- for (const pathSegment of path) {
7970
- if (typeof pathSegment !== 'string') {
7971
- 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);
7972
7653
  }
7973
- currentGlobal = currentGlobal[pathSegment];
7974
- if (!currentGlobal) {
7975
- return null;
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);
7976
7689
  }
7977
7690
  }
7978
- return currentGlobal[ValueProperties];
7979
7691
  }
7980
-
7981
- class GlobalVariable extends Variable {
7982
- constructor() {
7983
- super(...arguments);
7984
- // Ensure we use live-bindings for globals as we do not know if they have
7985
- // been reassigned
7986
- this.isReassigned = true;
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;
7987
7722
  }
7988
- getLiteralValueAtPath(path, _recursionTracker, _origin) {
7989
- return getGlobalAtPath([this.name, ...path]) ? UnknownTruthyValue : UnknownValue;
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));
7990
7740
  }
7991
- hasEffectsWhenAccessedAtPath(path) {
7992
- if (path.length === 0) {
7993
- // Technically, "undefined" is a global variable of sorts
7994
- return this.name !== 'undefined' && !getGlobalAtPath([this.name]);
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;
7751
+ }
7752
+ else {
7753
+ return super.addDeclaration(identifier, context, init, false);
7754
+ }
7755
+ }
7756
+ }
7757
+
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);
7995
7769
  }
7996
- return !getGlobalAtPath([this.name, ...path].slice(0, -1));
7997
7770
  }
7998
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
7999
- const globalAtPath = getGlobalAtPath([this.name, ...path]);
8000
- return !globalAtPath || globalAtPath.hasEffectsWhenCalled(callOptions, context);
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);
8001
7780
  }
7781
+ applyDeoptimizations() { }
8002
7782
  }
8003
7783
 
8004
- const tdzVariableKinds = {
8005
- __proto__: null,
8006
- class: true,
8007
- const: true,
8008
- let: true,
8009
- var: true
8010
- };
8011
- class Identifier extends NodeBase {
7784
+ class BlockStatement extends NodeBase {
8012
7785
  constructor() {
8013
7786
  super(...arguments);
8014
- this.variable = null;
8015
- this.deoptimized = false;
8016
- this.isTDZAccess = null;
7787
+ this.directlyIncluded = false;
8017
7788
  }
8018
- addExportedVariables(variables, exportNamesByVariable) {
8019
- if (exportNamesByVariable.has(this.variable)) {
8020
- variables.push(this.variable);
7789
+ addImplicitReturnExpressionToScope() {
7790
+ const lastStatement = this.body[this.body.length - 1];
7791
+ if (!lastStatement || lastStatement.type !== ReturnStatement$1) {
7792
+ this.scope.addReturnExpression(UNKNOWN_EXPRESSION);
8021
7793
  }
8022
7794
  }
8023
- bind() {
8024
- if (!this.variable && is_reference(this, this.parent)) {
8025
- this.variable = this.scope.findVariable(this.name);
8026
- this.variable.addReference(this);
8027
- }
7795
+ createScope(parentScope) {
7796
+ this.scope = this.parent.preventChildBlockScope
7797
+ ? parentScope
7798
+ : new BlockScope(parentScope);
8028
7799
  }
8029
- declare(kind, init) {
8030
- let variable;
8031
- const { treeshake } = this.context.options;
8032
- switch (kind) {
8033
- case 'var':
8034
- variable = this.scope.addDeclaration(this, this.context, init, true);
8035
- if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
8036
- // Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
8037
- variable.markInitializersForDeoptimization();
8038
- }
8039
- break;
8040
- case 'function':
8041
- // in strict mode, functions are only hoisted within a scope but not across block scopes
8042
- variable = this.scope.addDeclaration(this, this.context, init, false);
8043
- break;
8044
- case 'let':
8045
- case 'const':
8046
- case 'class':
8047
- variable = this.scope.addDeclaration(this, this.context, init, false);
8048
- break;
8049
- case 'parameter':
8050
- variable = this.scope.addParameterDeclaration(this);
7800
+ hasEffects(context) {
7801
+ if (this.deoptimizeBody)
7802
+ return true;
7803
+ for (const node of this.body) {
7804
+ if (context.brokenFlow)
8051
7805
  break;
8052
- /* istanbul ignore next */
8053
- default:
8054
- /* istanbul ignore next */
8055
- throw new Error(`Internal Error: Unexpected identifier kind ${kind}.`);
7806
+ if (node.hasEffects(context))
7807
+ return true;
8056
7808
  }
8057
- variable.kind = kind;
8058
- return [(this.variable = variable)];
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
+ }
7821
+ }
7822
+ }
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
+ }
7836
+ }
7837
+ }
7838
+
7839
+ class RestElement extends NodeBase {
7840
+ constructor() {
7841
+ super(...arguments);
7842
+ this.declarationInit = null;
7843
+ }
7844
+ addExportedVariables(variables, exportNamesByVariable) {
7845
+ this.argument.addExportedVariables(variables, exportNamesByVariable);
7846
+ }
7847
+ declare(kind, init) {
7848
+ this.declarationInit = init;
7849
+ return this.argument.declare(kind, UNKNOWN_EXPRESSION);
8059
7850
  }
8060
7851
  deoptimizePath(path) {
8061
- if (path.length === 0 && !this.scope.contains(this.name)) {
8062
- this.disallowImportReassignment();
8063
- }
8064
- this.variable.deoptimizePath(path);
7852
+ path.length === 0 && this.argument.deoptimizePath(EMPTY_PATH);
8065
7853
  }
8066
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
8067
- this.variable.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
7854
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
7855
+ return (path.length > 0 ||
7856
+ this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));
8068
7857
  }
8069
- getLiteralValueAtPath(path, recursionTracker, origin) {
8070
- return this.getVariableRespectingTDZ().getLiteralValueAtPath(path, recursionTracker, origin);
7858
+ markDeclarationReached() {
7859
+ this.argument.markDeclarationReached();
8071
7860
  }
8072
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
8073
- return this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
7861
+ applyDeoptimizations() {
7862
+ this.deoptimized = true;
7863
+ if (this.declarationInit !== null) {
7864
+ this.declarationInit.deoptimizePath([UnknownKey, UnknownKey]);
7865
+ this.context.requestTreeshakingPass();
7866
+ }
8074
7867
  }
8075
- hasEffects() {
8076
- if (!this.deoptimized)
8077
- this.applyDeoptimizations();
8078
- if (this.isPossibleTDZ() && this.variable.kind !== 'var') {
8079
- return true;
7868
+ }
7869
+
7870
+ class FunctionBase extends NodeBase {
7871
+ constructor() {
7872
+ super(...arguments);
7873
+ this.objectEntity = null;
7874
+ this.deoptimizedReturn = false;
7875
+ }
7876
+ deoptimizePath(path) {
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);
8080
7882
  }
8081
- return (this.context.options.treeshake.unknownGlobalSideEffects &&
8082
- this.variable instanceof GlobalVariable &&
8083
- this.variable.hasEffectsWhenAccessedAtPath(EMPTY_PATH));
8084
7883
  }
8085
- hasEffectsWhenAccessedAtPath(path, context) {
8086
- return (this.variable !== null &&
8087
- this.getVariableRespectingTDZ().hasEffectsWhenAccessedAtPath(path, context));
7884
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
7885
+ if (path.length > 0) {
7886
+ this.getObjectEntity().deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
7887
+ }
8088
7888
  }
8089
- hasEffectsWhenAssignedAtPath(path, context) {
8090
- return (path.length > 0 ? this.getVariableRespectingTDZ() : this.variable).hasEffectsWhenAssignedAtPath(path, context);
7889
+ getLiteralValueAtPath(path, recursionTracker, origin) {
7890
+ return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);
8091
7891
  }
8092
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
8093
- return this.getVariableRespectingTDZ().hasEffectsWhenCalledAtPath(path, callOptions, context);
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();
8094
7905
  }
8095
- include() {
8096
- if (!this.deoptimized)
8097
- this.applyDeoptimizations();
8098
- if (!this.included) {
8099
- this.included = true;
8100
- if (this.variable !== null) {
8101
- this.context.includeVariableInModule(this.variable);
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;
8102
7919
  }
8103
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) {
7928
+ if (!this.deoptimized)
7929
+ this.applyDeoptimizations();
7930
+ this.included = true;
7931
+ const { brokenFlow } = context;
7932
+ context.brokenFlow = BROKEN_FLOW_NONE;
7933
+ this.body.include(context, includeChildrenRecursively);
7934
+ context.brokenFlow = brokenFlow;
8104
7935
  }
8105
7936
  includeCallArguments(context, args) {
8106
- this.variable.includeCallArguments(context, args);
7937
+ this.scope.includeCallArguments(context, args);
8107
7938
  }
8108
- isPossibleTDZ() {
8109
- // return cached value to avoid issues with the next tree-shaking pass
8110
- if (this.isTDZAccess !== null)
8111
- return this.isTDZAccess;
8112
- if (!(this.variable instanceof LocalVariable) ||
8113
- !this.variable.kind ||
8114
- !(this.variable.kind in tdzVariableKinds)) {
8115
- return (this.isTDZAccess = false);
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();
8116
7943
  }
8117
- let decl_id;
8118
- if (this.variable.declarations &&
8119
- this.variable.declarations.length === 1 &&
8120
- (decl_id = this.variable.declarations[0]) &&
8121
- this.start < decl_id.start &&
8122
- closestParentFunctionOrProgram(this) === closestParentFunctionOrProgram(decl_id)) {
8123
- // a variable accessed before its declaration
8124
- // in the same function or at top level of module
8125
- return (this.isTDZAccess = true);
7944
+ else {
7945
+ this.scope.addReturnExpression(this.body);
8126
7946
  }
8127
- if (!this.variable.initReached) {
8128
- // Either a const/let TDZ violation or
8129
- // var use before declaration was encountered.
8130
- return (this.isTDZAccess = true);
7947
+ }
7948
+ parseNode(esTreeNode) {
7949
+ if (esTreeNode.body.type === BlockStatement$1) {
7950
+ this.body = new BlockStatement(esTreeNode.body, this, this.scope.hoistedBodyVarScope);
8131
7951
  }
8132
- return (this.isTDZAccess = false);
7952
+ super.parseNode(esTreeNode);
8133
7953
  }
8134
- markDeclarationReached() {
8135
- this.variable.initReached = true;
7954
+ applyDeoptimizations() { }
7955
+ }
7956
+ FunctionBase.prototype.preventChildBlockScope = true;
7957
+
7958
+ class ArrowFunctionExpression extends FunctionBase {
7959
+ constructor() {
7960
+ super(...arguments);
7961
+ this.objectEntity = null;
8136
7962
  }
8137
- render(code, { snippets: { getPropertyAccess } }, { renderedParentType, isCalleeOfRenderedParent, isShorthandProperty } = BLANK) {
8138
- if (this.variable) {
8139
- const name = this.variable.getName(getPropertyAccess);
8140
- if (name !== this.name) {
8141
- code.overwrite(this.start, this.end, name, {
8142
- contentOnly: true,
8143
- storeName: true
8144
- });
8145
- if (isShorthandProperty) {
8146
- code.prependRight(this.start, `${this.name}: `);
8147
- }
8148
- }
8149
- // In strict mode, any variable named "eval" must be the actual "eval" function
8150
- if (name === 'eval' &&
8151
- renderedParentType === CallExpression$1 &&
8152
- isCalleeOfRenderedParent) {
8153
- code.appendRight(this.start, '0, ');
7963
+ createScope(parentScope) {
7964
+ this.scope = new ReturnValueScope(parentScope, this.context);
7965
+ }
7966
+ hasEffects() {
7967
+ if (!this.deoptimized)
7968
+ this.applyDeoptimizations();
7969
+ return false;
7970
+ }
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;
7986
+ }
7987
+ return false;
7988
+ }
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);
8154
7994
  }
8155
7995
  }
8156
7996
  }
8157
- applyDeoptimizations() {
8158
- this.deoptimized = true;
8159
- if (this.variable instanceof LocalVariable) {
8160
- this.variable.consolidateInitializers();
8161
- this.context.requestTreeshakingPass();
7997
+ getObjectEntity() {
7998
+ if (this.objectEntity !== null) {
7999
+ return this.objectEntity;
8162
8000
  }
8001
+ return (this.objectEntity = new ObjectEntity([], OBJECT_PROTOTYPE));
8163
8002
  }
8164
- disallowImportReassignment() {
8165
- return this.context.error({
8166
- code: 'ILLEGAL_REASSIGNMENT',
8167
- message: `Illegal reassignment to import '${this.name}'`
8168
- }, 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})`;
8169
8010
  }
8170
- getVariableRespectingTDZ() {
8171
- if (this.isPossibleTDZ()) {
8172
- 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
+ }
8173
8017
  }
8174
- return this.variable;
8018
+ return `exports(${getObject(fields, { lineBreakIndent: null })})`;
8175
8019
  }
8176
8020
  }
8177
- function closestParentFunctionOrProgram(node) {
8178
- while (node && !/^Program|Function/.test(node.type)) {
8179
- 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, ')');
8180
8044
  }
8181
- // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program
8182
- return node;
8183
8045
  }
8184
8046
 
8185
8047
  class ObjectPattern extends NodeBase {
@@ -8207,11 +8069,12 @@ class ObjectPattern extends NodeBase {
8207
8069
  }
8208
8070
  }
8209
8071
  }
8210
- hasEffectsWhenAssignedAtPath(path, context) {
8211
- if (path.length > 0)
8212
- 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) {
8213
8076
  for (const property of this.properties) {
8214
- if (property.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context))
8077
+ if (property.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context))
8215
8078
  return true;
8216
8079
  }
8217
8080
  return false;
@@ -8224,80 +8087,79 @@ class ObjectPattern extends NodeBase {
8224
8087
  }
8225
8088
 
8226
8089
  class AssignmentExpression extends NodeBase {
8227
- constructor() {
8228
- super(...arguments);
8229
- this.deoptimized = false;
8230
- }
8231
8090
  hasEffects(context) {
8232
- if (!this.deoptimized)
8091
+ const { deoptimized, left, right } = this;
8092
+ if (!deoptimized)
8233
8093
  this.applyDeoptimizations();
8234
- return (this.right.hasEffects(context) ||
8235
- this.left.hasEffects(context) ||
8236
- 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 !== '='));
8237
8097
  }
8238
- hasEffectsWhenAccessedAtPath(path, context) {
8239
- return path.length > 0 && this.right.hasEffectsWhenAccessedAtPath(path, context);
8098
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
8099
+ return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);
8240
8100
  }
8241
8101
  include(context, includeChildrenRecursively) {
8242
- if (!this.deoptimized)
8102
+ const { deoptimized, left, right, operator } = this;
8103
+ if (!deoptimized)
8243
8104
  this.applyDeoptimizations();
8244
8105
  this.included = true;
8245
- let hasEffectsContext;
8246
8106
  if (includeChildrenRecursively ||
8247
- this.operator !== '=' ||
8248
- this.left.included ||
8249
- ((hasEffectsContext = createHasEffectsContext()),
8250
- this.left.hasEffects(hasEffectsContext) ||
8251
- this.left.hasEffectsWhenAssignedAtPath(EMPTY_PATH, hasEffectsContext))) {
8252
- this.left.include(context, includeChildrenRecursively);
8107
+ operator !== '=' ||
8108
+ left.included ||
8109
+ left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {
8110
+ left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');
8253
8111
  }
8254
- this.right.include(context, includeChildrenRecursively);
8112
+ right.include(context, includeChildrenRecursively);
8113
+ }
8114
+ initialise() {
8115
+ this.left.setAssignedValue(this.right);
8255
8116
  }
8256
8117
  render(code, options, { preventASI, renderedParentType, renderedSurroundingElement } = BLANK) {
8257
- if (this.left.included) {
8258
- this.left.render(code, options);
8259
- 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);
8260
8122
  }
8261
8123
  else {
8262
- const inclusionStart = findNonWhiteSpace(code.original, findFirstOccurrenceOutsideComment(code.original, '=', this.left.end) + 1);
8263
- code.remove(this.start, inclusionStart);
8124
+ const inclusionStart = findNonWhiteSpace(code.original, findFirstOccurrenceOutsideComment(code.original, '=', left.end) + 1);
8125
+ code.remove(start, inclusionStart);
8264
8126
  if (preventASI) {
8265
- removeLineBreaks(code, inclusionStart, this.right.start);
8127
+ removeLineBreaks(code, inclusionStart, right.start);
8266
8128
  }
8267
- this.right.render(code, options, {
8268
- renderedParentType: renderedParentType || this.parent.type,
8269
- renderedSurroundingElement: renderedSurroundingElement || this.parent.type
8129
+ right.render(code, options, {
8130
+ renderedParentType: renderedParentType || parent.type,
8131
+ renderedSurroundingElement: renderedSurroundingElement || parent.type
8270
8132
  });
8271
8133
  }
8272
8134
  if (options.format === 'system') {
8273
- if (this.left instanceof Identifier) {
8274
- const variable = this.left.variable;
8135
+ if (left instanceof Identifier) {
8136
+ const variable = left.variable;
8275
8137
  const exportNames = options.exportNamesByVariable.get(variable);
8276
8138
  if (exportNames) {
8277
8139
  if (exportNames.length === 1) {
8278
- renderSystemExportExpression(variable, this.start, this.end, code, options);
8140
+ renderSystemExportExpression(variable, start, end, code, options);
8279
8141
  }
8280
8142
  else {
8281
- renderSystemExportSequenceAfterExpression(variable, this.start, this.end, this.parent.type !== ExpressionStatement$1, code, options);
8143
+ renderSystemExportSequenceAfterExpression(variable, start, end, parent.type !== ExpressionStatement$1, code, options);
8282
8144
  }
8283
8145
  return;
8284
8146
  }
8285
8147
  }
8286
8148
  else {
8287
8149
  const systemPatternExports = [];
8288
- this.left.addExportedVariables(systemPatternExports, options.exportNamesByVariable);
8150
+ left.addExportedVariables(systemPatternExports, options.exportNamesByVariable);
8289
8151
  if (systemPatternExports.length > 0) {
8290
- renderSystemExportFunction(systemPatternExports, this.start, this.end, renderedSurroundingElement === ExpressionStatement$1, code, options);
8152
+ renderSystemExportFunction(systemPatternExports, start, end, renderedSurroundingElement === ExpressionStatement$1, code, options);
8291
8153
  return;
8292
8154
  }
8293
8155
  }
8294
8156
  }
8295
- if (this.left.included &&
8296
- this.left instanceof ObjectPattern &&
8157
+ if (left.included &&
8158
+ left instanceof ObjectPattern &&
8297
8159
  (renderedSurroundingElement === ExpressionStatement$1 ||
8298
8160
  renderedSurroundingElement === ArrowFunctionExpression$1)) {
8299
- code.appendRight(this.start, '(');
8300
- code.prependLeft(this.end, ')');
8161
+ code.appendRight(start, '(');
8162
+ code.prependLeft(end, ')');
8301
8163
  }
8302
8164
  }
8303
8165
  applyDeoptimizations() {
@@ -8308,18 +8170,40 @@ class AssignmentExpression extends NodeBase {
8308
8170
  }
8309
8171
  }
8310
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
+
8311
8201
  class ArgumentsVariable extends LocalVariable {
8312
8202
  constructor(context) {
8313
8203
  super('arguments', null, UNKNOWN_EXPRESSION, context);
8314
8204
  }
8315
- hasEffectsWhenAccessedAtPath(path) {
8316
- return path.length > 1;
8317
- }
8318
- hasEffectsWhenAssignedAtPath() {
8319
- return true;
8320
- }
8321
- hasEffectsWhenCalledAtPath() {
8322
- return true;
8205
+ hasEffectsOnInteractionAtPath(path, { type }) {
8206
+ return type !== INTERACTION_ACCESSED || path.length > 1;
8323
8207
  }
8324
8208
  }
8325
8209
 
@@ -8335,8 +8219,8 @@ class ThisVariable extends LocalVariable {
8335
8219
  for (const path of this.deoptimizedPaths) {
8336
8220
  entity.deoptimizePath(path);
8337
8221
  }
8338
- for (const thisDeoptimization of this.thisDeoptimizationList) {
8339
- this.applyThisDeoptimizationEvent(entity, thisDeoptimization);
8222
+ for (const { interaction, path } of this.thisDeoptimizationList) {
8223
+ entity.deoptimizeThisOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
8340
8224
  }
8341
8225
  this.entitiesToBeDeoptimized.add(entity);
8342
8226
  }
@@ -8350,29 +8234,21 @@ class ThisVariable extends LocalVariable {
8350
8234
  entity.deoptimizePath(path);
8351
8235
  }
8352
8236
  }
8353
- deoptimizeThisOnEventAtPath(event, path, thisParameter) {
8237
+ deoptimizeThisOnInteractionAtPath(interaction, path) {
8354
8238
  const thisDeoptimization = {
8355
- event,
8356
- path,
8357
- thisParameter
8239
+ interaction,
8240
+ path
8358
8241
  };
8359
- if (!this.thisDeoptimizations.trackEntityAtPathAndGetIfTracked(path, event, thisParameter)) {
8242
+ if (!this.thisDeoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.type, interaction.thisArg)) {
8360
8243
  for (const entity of this.entitiesToBeDeoptimized) {
8361
- this.applyThisDeoptimizationEvent(entity, thisDeoptimization);
8244
+ entity.deoptimizeThisOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);
8362
8245
  }
8363
8246
  this.thisDeoptimizationList.push(thisDeoptimization);
8364
8247
  }
8365
8248
  }
8366
- hasEffectsWhenAccessedAtPath(path, context) {
8367
- return (this.getInit(context).hasEffectsWhenAccessedAtPath(path, context) ||
8368
- super.hasEffectsWhenAccessedAtPath(path, context));
8369
- }
8370
- hasEffectsWhenAssignedAtPath(path, context) {
8371
- return (this.getInit(context).hasEffectsWhenAssignedAtPath(path, context) ||
8372
- super.hasEffectsWhenAssignedAtPath(path, context));
8373
- }
8374
- applyThisDeoptimizationEvent(entity, { event, path, thisParameter }) {
8375
- 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));
8376
8252
  }
8377
8253
  getInit(context) {
8378
8254
  return context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION;
@@ -8408,50 +8284,56 @@ class FunctionNode extends FunctionBase {
8408
8284
  createScope(parentScope) {
8409
8285
  this.scope = new FunctionScope(parentScope, this.context);
8410
8286
  }
8411
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
8412
- super.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
8413
- if (event === EVENT_CALLED && path.length === 0) {
8414
- 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);
8415
8291
  }
8416
8292
  }
8417
- hasEffects() {
8293
+ hasEffects(context) {
8418
8294
  var _a;
8419
8295
  if (!this.deoptimized)
8420
8296
  this.applyDeoptimizations();
8421
- 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));
8422
8298
  }
8423
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
8424
- if (super.hasEffectsWhenCalledAtPath(path, callOptions, context))
8425
- return true;
8426
- const thisInit = context.replacedVariableInits.get(this.scope.thisVariable);
8427
- context.replacedVariableInits.set(this.scope.thisVariable, callOptions.withNew
8428
- ? new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE)
8429
- : UNKNOWN_EXPRESSION);
8430
- const { brokenFlow, ignore } = context;
8431
- context.ignore = {
8432
- breaks: false,
8433
- continues: false,
8434
- labels: new Set(),
8435
- returnYield: true
8436
- };
8437
- if (this.body.hasEffects(context))
8299
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
8300
+ if (super.hasEffectsOnInteractionAtPath(path, interaction, context))
8438
8301
  return true;
8439
- context.brokenFlow = brokenFlow;
8440
- if (thisInit) {
8441
- context.replacedVariableInits.set(this.scope.thisVariable, thisInit);
8442
- }
8443
- else {
8444
- 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;
8445
8324
  }
8446
- context.ignore = ignore;
8447
8325
  return false;
8448
8326
  }
8449
- include(context, includeChildrenRecursively, { includeWithoutParameterDefaults } = BLANK) {
8327
+ include(context, includeChildrenRecursively) {
8450
8328
  var _a;
8329
+ super.include(context, includeChildrenRecursively);
8451
8330
  (_a = this.id) === null || _a === void 0 ? void 0 : _a.include();
8452
- super.include(context, includeChildrenRecursively, {
8453
- includeWithoutParameterDefaults: includeWithoutParameterDefaults && !this.scope.argumentsVariable.included
8454
- });
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
+ }
8455
8337
  }
8456
8338
  initialise() {
8457
8339
  var _a;
@@ -8473,10 +8355,6 @@ class FunctionNode extends FunctionBase {
8473
8355
  }
8474
8356
 
8475
8357
  class AwaitExpression extends NodeBase {
8476
- constructor() {
8477
- super(...arguments);
8478
- this.deoptimized = false;
8479
- }
8480
8358
  hasEffects() {
8481
8359
  if (!this.deoptimized)
8482
8360
  this.applyDeoptimizations();
@@ -8550,8 +8428,8 @@ class BinaryExpression extends NodeBase {
8550
8428
  return true;
8551
8429
  return super.hasEffects(context);
8552
8430
  }
8553
- hasEffectsWhenAccessedAtPath(path) {
8554
- return path.length > 1;
8431
+ hasEffectsOnInteractionAtPath(path, { type }) {
8432
+ return type !== INTERACTION_ACCESSED || path.length > 1;
8555
8433
  }
8556
8434
  render(code, options, { renderedSurroundingElement } = BLANK) {
8557
8435
  this.left.render(code, options, { renderedSurroundingElement });
@@ -8584,8 +8462,33 @@ class BreakStatement extends NodeBase {
8584
8462
  }
8585
8463
  }
8586
8464
 
8465
+ function renderCallArguments(code, options, node) {
8466
+ if (node.arguments.length > 0) {
8467
+ if (node.arguments[node.arguments.length - 1].included) {
8468
+ for (const arg of node.arguments) {
8469
+ arg.render(code, options);
8470
+ }
8471
+ }
8472
+ else {
8473
+ let lastIncludedIndex = node.arguments.length - 2;
8474
+ while (lastIncludedIndex >= 0 && !node.arguments[lastIncludedIndex].included) {
8475
+ lastIncludedIndex--;
8476
+ }
8477
+ if (lastIncludedIndex >= 0) {
8478
+ for (let index = 0; index <= lastIncludedIndex; index++) {
8479
+ node.arguments[index].render(code, options);
8480
+ }
8481
+ code.remove(findFirstOccurrenceOutsideComment(code.original, ',', node.arguments[lastIncludedIndex].end), node.end - 1);
8482
+ }
8483
+ else {
8484
+ code.remove(findFirstOccurrenceOutsideComment(code.original, '(', node.callee.end) + 1, node.end - 1);
8485
+ }
8486
+ }
8487
+ }
8488
+ }
8489
+
8587
8490
  class Literal extends NodeBase {
8588
- deoptimizeThisOnEventAtPath() { }
8491
+ deoptimizeThisOnInteractionAtPath() { }
8589
8492
  getLiteralValueAtPath(path) {
8590
8493
  if (path.length > 0 ||
8591
8494
  // unknown literals can also be null but do not start with an "n"
@@ -8602,17 +8505,16 @@ class Literal extends NodeBase {
8602
8505
  return UNKNOWN_EXPRESSION;
8603
8506
  return getMemberReturnExpressionWhenCalled(this.members, path[0]);
8604
8507
  }
8605
- hasEffectsWhenAccessedAtPath(path) {
8606
- if (this.value === null) {
8607
- return path.length > 0;
8608
- }
8609
- return path.length > 1;
8610
- }
8611
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
8612
- if (path.length === 1) {
8613
- return hasMemberEffectWhenCalled(this.members, path[0], callOptions, context);
8508
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
8509
+ switch (interaction.type) {
8510
+ case INTERACTION_ACCESSED:
8511
+ return path.length > (this.value === null ? 0 : 1);
8512
+ case INTERACTION_ASSIGNED:
8513
+ return true;
8514
+ case INTERACTION_CALLED:
8515
+ return (path.length !== 1 ||
8516
+ hasMemberEffectWhenCalled(this.members, path[0], interaction, context));
8614
8517
  }
8615
- return true;
8616
8518
  }
8617
8519
  initialise() {
8618
8520
  this.members = getLiteralMembersForValue(this.value);
@@ -8670,7 +8572,7 @@ class MemberExpression extends NodeBase {
8670
8572
  constructor() {
8671
8573
  super(...arguments);
8672
8574
  this.variable = null;
8673
- this.deoptimized = false;
8575
+ this.assignmentDeoptimized = false;
8674
8576
  this.bound = false;
8675
8577
  this.expressionsToBeDeoptimized = [];
8676
8578
  this.replacement = null;
@@ -8680,7 +8582,7 @@ class MemberExpression extends NodeBase {
8680
8582
  const path = getPathIfNotComputed(this);
8681
8583
  const baseVariable = path && this.scope.findVariable(path[0].key);
8682
8584
  if (baseVariable && baseVariable.isNamespace) {
8683
- const resolvedVariable = this.resolveNamespaceVariables(baseVariable, path.slice(1));
8585
+ const resolvedVariable = resolveNamespaceVariables(baseVariable, path.slice(1), this.context);
8684
8586
  if (!resolvedVariable) {
8685
8587
  super.bind();
8686
8588
  }
@@ -8721,21 +8623,21 @@ class MemberExpression extends NodeBase {
8721
8623
  }
8722
8624
  }
8723
8625
  }
8724
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
8626
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
8725
8627
  if (this.variable) {
8726
- this.variable.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
8628
+ this.variable.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
8727
8629
  }
8728
8630
  else if (!this.replacement) {
8729
8631
  if (path.length < MAX_PATH_DEPTH) {
8730
- this.object.deoptimizeThisOnEventAtPath(event, [this.getPropertyKey(), ...path], thisParameter, recursionTracker);
8632
+ this.object.deoptimizeThisOnInteractionAtPath(interaction, [this.getPropertyKey(), ...path], recursionTracker);
8731
8633
  }
8732
8634
  else {
8733
- thisParameter.deoptimizePath(UNKNOWN_PATH);
8635
+ interaction.thisArg.deoptimizePath(UNKNOWN_PATH);
8734
8636
  }
8735
8637
  }
8736
8638
  }
8737
8639
  getLiteralValueAtPath(path, recursionTracker, origin) {
8738
- if (this.variable !== null) {
8640
+ if (this.variable) {
8739
8641
  return this.variable.getLiteralValueAtPath(path, recursionTracker, origin);
8740
8642
  }
8741
8643
  if (this.replacement) {
@@ -8747,81 +8649,62 @@ class MemberExpression extends NodeBase {
8747
8649
  }
8748
8650
  return UnknownValue;
8749
8651
  }
8750
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
8751
- if (this.variable !== null) {
8752
- return this.variable.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
8652
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
8653
+ if (this.variable) {
8654
+ return this.variable.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
8753
8655
  }
8754
8656
  if (this.replacement) {
8755
8657
  return UNKNOWN_EXPRESSION;
8756
8658
  }
8757
8659
  this.expressionsToBeDeoptimized.push(origin);
8758
8660
  if (path.length < MAX_PATH_DEPTH) {
8759
- return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], callOptions, recursionTracker, origin);
8661
+ return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin);
8760
8662
  }
8761
8663
  return UNKNOWN_EXPRESSION;
8762
8664
  }
8763
8665
  hasEffects(context) {
8764
8666
  if (!this.deoptimized)
8765
8667
  this.applyDeoptimizations();
8766
- const { propertyReadSideEffects } = this.context.options
8767
- .treeshake;
8768
8668
  return (this.property.hasEffects(context) ||
8769
8669
  this.object.hasEffects(context) ||
8770
- // Assignments do not access the property before assigning
8771
- (!(this.variable ||
8772
- this.replacement ||
8773
- (this.parent instanceof AssignmentExpression && this.parent.operator === '=')) &&
8774
- propertyReadSideEffects &&
8775
- (propertyReadSideEffects === 'always' ||
8776
- this.object.hasEffectsWhenAccessedAtPath([this.getPropertyKey()], context))));
8777
- }
8778
- hasEffectsWhenAccessedAtPath(path, context) {
8779
- if (this.variable !== null) {
8780
- return this.variable.hasEffectsWhenAccessedAtPath(path, context);
8781
- }
8782
- if (this.replacement) {
8783
- return true;
8784
- }
8785
- if (path.length < MAX_PATH_DEPTH) {
8786
- return this.object.hasEffectsWhenAccessedAtPath([this.getPropertyKey(), ...path], context);
8787
- }
8788
- return true;
8670
+ this.hasAccessEffect(context));
8789
8671
  }
8790
- hasEffectsWhenAssignedAtPath(path, context) {
8791
- if (this.variable !== null) {
8792
- return this.variable.hasEffectsWhenAssignedAtPath(path, context);
8793
- }
8794
- if (this.replacement) {
8795
- return true;
8796
- }
8797
- if (path.length < MAX_PATH_DEPTH) {
8798
- return this.object.hasEffectsWhenAssignedAtPath([this.getPropertyKey(), ...path], context);
8799
- }
8800
- return true;
8672
+ hasEffectsAsAssignmentTarget(context, checkAccess) {
8673
+ if (checkAccess && !this.deoptimized)
8674
+ this.applyDeoptimizations();
8675
+ if (!this.assignmentDeoptimized)
8676
+ this.applyAssignmentDeoptimization();
8677
+ return (this.property.hasEffects(context) ||
8678
+ this.object.hasEffects(context) ||
8679
+ (checkAccess && this.hasAccessEffect(context)) ||
8680
+ this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));
8801
8681
  }
8802
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
8803
- if (this.variable !== null) {
8804
- return this.variable.hasEffectsWhenCalledAtPath(path, callOptions, context);
8682
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
8683
+ if (this.variable) {
8684
+ return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
8805
8685
  }
8806
8686
  if (this.replacement) {
8807
8687
  return true;
8808
8688
  }
8809
8689
  if (path.length < MAX_PATH_DEPTH) {
8810
- return this.object.hasEffectsWhenCalledAtPath([this.getPropertyKey(), ...path], callOptions, context);
8690
+ return this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey(), ...path], interaction, context);
8811
8691
  }
8812
8692
  return true;
8813
8693
  }
8814
8694
  include(context, includeChildrenRecursively) {
8815
8695
  if (!this.deoptimized)
8816
8696
  this.applyDeoptimizations();
8817
- if (!this.included) {
8818
- this.included = true;
8819
- if (this.variable !== null) {
8820
- this.context.includeVariableInModule(this.variable);
8821
- }
8697
+ this.includeProperties(context, includeChildrenRecursively);
8698
+ }
8699
+ includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {
8700
+ if (!this.assignmentDeoptimized)
8701
+ this.applyAssignmentDeoptimization();
8702
+ if (deoptimizeAccess) {
8703
+ this.include(context, includeChildrenRecursively);
8704
+ }
8705
+ else {
8706
+ this.includeProperties(context, includeChildrenRecursively);
8822
8707
  }
8823
- this.object.include(context, includeChildrenRecursively);
8824
- this.property.include(context, includeChildrenRecursively);
8825
8708
  }
8826
8709
  includeCallArguments(context, args) {
8827
8710
  if (this.variable) {
@@ -8833,6 +8716,7 @@ class MemberExpression extends NodeBase {
8833
8716
  }
8834
8717
  initialise() {
8835
8718
  this.propertyKey = getResolvablePropertyKey(this);
8719
+ this.accessInteraction = { thisArg: this.object, type: INTERACTION_ACCESSED };
8836
8720
  }
8837
8721
  render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = BLANK) {
8838
8722
  if (this.variable || this.replacement) {
@@ -8853,6 +8737,13 @@ class MemberExpression extends NodeBase {
8853
8737
  this.property.render(code, options);
8854
8738
  }
8855
8739
  }
8740
+ setAssignedValue(value) {
8741
+ this.assignmentInteraction = {
8742
+ args: [value],
8743
+ thisArg: this.object,
8744
+ type: INTERACTION_ASSIGNED
8745
+ };
8746
+ }
8856
8747
  applyDeoptimizations() {
8857
8748
  this.deoptimized = true;
8858
8749
  const { propertyReadSideEffects } = this.context.options
@@ -8862,13 +8753,21 @@ class MemberExpression extends NodeBase {
8862
8753
  this.bound &&
8863
8754
  propertyReadSideEffects &&
8864
8755
  !(this.variable || this.replacement)) {
8865
- // Regular Assignments do not access the property before assigning
8866
- if (!(this.parent instanceof AssignmentExpression && this.parent.operator === '=')) {
8867
- this.object.deoptimizeThisOnEventAtPath(EVENT_ACCESSED, [this.propertyKey], this.object, SHARED_RECURSION_TRACKER);
8868
- }
8869
- if (this.parent instanceof AssignmentExpression) {
8870
- this.object.deoptimizeThisOnEventAtPath(EVENT_ASSIGNED, [this.propertyKey], this.object, SHARED_RECURSION_TRACKER);
8871
- }
8756
+ const propertyKey = this.getPropertyKey();
8757
+ this.object.deoptimizeThisOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER);
8758
+ this.context.requestTreeshakingPass();
8759
+ }
8760
+ }
8761
+ applyAssignmentDeoptimization() {
8762
+ this.assignmentDeoptimized = true;
8763
+ const { propertyReadSideEffects } = this.context.options
8764
+ .treeshake;
8765
+ if (
8766
+ // Namespaces are not bound and should not be deoptimized
8767
+ this.bound &&
8768
+ propertyReadSideEffects &&
8769
+ !(this.variable || this.replacement)) {
8770
+ this.object.deoptimizeThisOnInteractionAtPath(this.assignmentInteraction, [this.getPropertyKey()], SHARED_RECURSION_TRACKER);
8872
8771
  this.context.requestTreeshakingPass();
8873
8772
  }
8874
8773
  }
@@ -8894,33 +8793,50 @@ class MemberExpression extends NodeBase {
8894
8793
  }
8895
8794
  return this.propertyKey;
8896
8795
  }
8897
- resolveNamespaceVariables(baseVariable, path) {
8898
- if (path.length === 0)
8899
- return baseVariable;
8900
- if (!baseVariable.isNamespace || baseVariable instanceof ExternalVariable)
8901
- return null;
8902
- const exportName = path[0].key;
8903
- const variable = baseVariable.context.traceExport(exportName);
8904
- if (!variable) {
8905
- const fileName = baseVariable.context.fileName;
8906
- this.context.warn({
8907
- code: 'MISSING_EXPORT',
8908
- exporter: relativeId(fileName),
8909
- importer: relativeId(this.context.fileName),
8910
- message: `'${exportName}' is not exported by '${relativeId(fileName)}'`,
8911
- missing: exportName,
8912
- url: `https://rollupjs.org/guide/en/#error-name-is-not-exported-by-module`
8913
- }, path[0].pos);
8914
- return 'undefined';
8796
+ hasAccessEffect(context) {
8797
+ const { propertyReadSideEffects } = this.context.options
8798
+ .treeshake;
8799
+ return (!(this.variable || this.replacement) &&
8800
+ propertyReadSideEffects &&
8801
+ (propertyReadSideEffects === 'always' ||
8802
+ this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));
8803
+ }
8804
+ includeProperties(context, includeChildrenRecursively) {
8805
+ if (!this.included) {
8806
+ this.included = true;
8807
+ if (this.variable) {
8808
+ this.context.includeVariableInModule(this.variable);
8809
+ }
8915
8810
  }
8916
- return this.resolveNamespaceVariables(variable, path.slice(1));
8811
+ this.object.include(context, includeChildrenRecursively);
8812
+ this.property.include(context, includeChildrenRecursively);
8917
8813
  }
8918
8814
  }
8815
+ function resolveNamespaceVariables(baseVariable, path, astContext) {
8816
+ if (path.length === 0)
8817
+ return baseVariable;
8818
+ if (!baseVariable.isNamespace || baseVariable instanceof ExternalVariable)
8819
+ return null;
8820
+ const exportName = path[0].key;
8821
+ const variable = baseVariable.context.traceExport(exportName);
8822
+ if (!variable) {
8823
+ const fileName = baseVariable.context.fileName;
8824
+ astContext.warn({
8825
+ code: 'MISSING_EXPORT',
8826
+ exporter: relativeId(fileName),
8827
+ importer: relativeId(astContext.fileName),
8828
+ message: `'${exportName}' is not exported by '${relativeId(fileName)}'`,
8829
+ missing: exportName,
8830
+ url: `https://rollupjs.org/guide/en/#error-name-is-not-exported-by-module`
8831
+ }, path[0].pos);
8832
+ return 'undefined';
8833
+ }
8834
+ return resolveNamespaceVariables(variable, path.slice(1), astContext);
8835
+ }
8919
8836
 
8920
8837
  class CallExpressionBase extends NodeBase {
8921
8838
  constructor() {
8922
8839
  super(...arguments);
8923
- this.deoptimized = false;
8924
8840
  this.returnExpression = null;
8925
8841
  this.deoptimizableDependentExpressions = [];
8926
8842
  this.expressionsToBeDeoptimized = new Set();
@@ -8946,15 +8862,15 @@ class CallExpressionBase extends NodeBase {
8946
8862
  returnExpression.deoptimizePath(path);
8947
8863
  }
8948
8864
  }
8949
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
8865
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
8950
8866
  const returnExpression = this.getReturnExpression(recursionTracker);
8951
8867
  if (returnExpression === UNKNOWN_EXPRESSION) {
8952
- thisParameter.deoptimizePath(UNKNOWN_PATH);
8868
+ interaction.thisArg.deoptimizePath(UNKNOWN_PATH);
8953
8869
  }
8954
8870
  else {
8955
8871
  recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {
8956
- this.expressionsToBeDeoptimized.add(thisParameter);
8957
- returnExpression.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
8872
+ this.expressionsToBeDeoptimized.add(interaction.thisArg);
8873
+ returnExpression.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
8958
8874
  }, undefined);
8959
8875
  }
8960
8876
  }
@@ -8968,27 +8884,31 @@ class CallExpressionBase extends NodeBase {
8968
8884
  return returnExpression.getLiteralValueAtPath(path, recursionTracker, origin);
8969
8885
  }, UnknownValue);
8970
8886
  }
8971
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
8887
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
8972
8888
  const returnExpression = this.getReturnExpression(recursionTracker);
8973
8889
  if (this.returnExpression === UNKNOWN_EXPRESSION) {
8974
8890
  return UNKNOWN_EXPRESSION;
8975
8891
  }
8976
8892
  return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {
8977
8893
  this.deoptimizableDependentExpressions.push(origin);
8978
- return returnExpression.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
8894
+ return returnExpression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
8979
8895
  }, UNKNOWN_EXPRESSION);
8980
8896
  }
8981
- hasEffectsWhenAccessedAtPath(path, context) {
8982
- return (!context.accessed.trackEntityAtPathAndGetIfTracked(path, this) &&
8983
- this.getReturnExpression().hasEffectsWhenAccessedAtPath(path, context));
8984
- }
8985
- hasEffectsWhenAssignedAtPath(path, context) {
8986
- return (!context.assigned.trackEntityAtPathAndGetIfTracked(path, this) &&
8987
- this.getReturnExpression().hasEffectsWhenAssignedAtPath(path, context));
8988
- }
8989
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
8990
- return (!(callOptions.withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, callOptions, this) &&
8991
- this.getReturnExpression().hasEffectsWhenCalledAtPath(path, callOptions, context));
8897
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
8898
+ const { type } = interaction;
8899
+ if (type === INTERACTION_CALLED) {
8900
+ if ((interaction.withNew
8901
+ ? context.instantiated
8902
+ : context.called).trackEntityAtPathAndGetIfTracked(path, interaction.args, this)) {
8903
+ return false;
8904
+ }
8905
+ }
8906
+ else if ((type === INTERACTION_ASSIGNED
8907
+ ? context.assigned
8908
+ : context.accessed).trackEntityAtPathAndGetIfTracked(path, this)) {
8909
+ return false;
8910
+ }
8911
+ return this.getReturnExpression().hasEffectsOnInteractionAtPath(path, interaction, context);
8992
8912
  }
8993
8913
  }
8994
8914
 
@@ -9011,11 +8931,12 @@ class CallExpression extends CallExpressionBase {
9011
8931
  }, this.start);
9012
8932
  }
9013
8933
  }
9014
- this.callOptions = {
8934
+ this.interaction = {
9015
8935
  args: this.arguments,
9016
- thisParam: this.callee instanceof MemberExpression && !this.callee.variable
8936
+ thisArg: this.callee instanceof MemberExpression && !this.callee.variable
9017
8937
  ? this.callee.object
9018
8938
  : null,
8939
+ type: INTERACTION_CALLED,
9019
8940
  withNew: false
9020
8941
  };
9021
8942
  }
@@ -9029,7 +8950,7 @@ class CallExpression extends CallExpressionBase {
9029
8950
  this.annotations)
9030
8951
  return false;
9031
8952
  return (this.callee.hasEffects(context) ||
9032
- this.callee.hasEffectsWhenCalledAtPath(EMPTY_PATH, this.callOptions, context));
8953
+ this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
9033
8954
  }
9034
8955
  finally {
9035
8956
  if (!this.deoptimized)
@@ -9049,7 +8970,7 @@ class CallExpression extends CallExpressionBase {
9049
8970
  }
9050
8971
  else {
9051
8972
  this.included = true;
9052
- this.callee.include(context, false, { includeWithoutParameterDefaults: true });
8973
+ this.callee.include(context, false);
9053
8974
  }
9054
8975
  this.callee.includeCallArguments(context, this.arguments);
9055
8976
  const returnExpression = this.getReturnExpression();
@@ -9062,34 +8983,12 @@ class CallExpression extends CallExpressionBase {
9062
8983
  isCalleeOfRenderedParent: true,
9063
8984
  renderedSurroundingElement
9064
8985
  });
9065
- if (this.arguments.length > 0) {
9066
- if (this.arguments[this.arguments.length - 1].included) {
9067
- for (const arg of this.arguments) {
9068
- arg.render(code, options);
9069
- }
9070
- }
9071
- else {
9072
- let lastIncludedIndex = this.arguments.length - 2;
9073
- while (lastIncludedIndex >= 0 && !this.arguments[lastIncludedIndex].included) {
9074
- lastIncludedIndex--;
9075
- }
9076
- if (lastIncludedIndex >= 0) {
9077
- for (let index = 0; index <= lastIncludedIndex; index++) {
9078
- this.arguments[index].render(code, options);
9079
- }
9080
- code.remove(findFirstOccurrenceOutsideComment(code.original, ',', this.arguments[lastIncludedIndex].end), this.end - 1);
9081
- }
9082
- else {
9083
- code.remove(findFirstOccurrenceOutsideComment(code.original, '(', this.callee.end) + 1, this.end - 1);
9084
- }
9085
- }
9086
- }
8986
+ renderCallArguments(code, options, this);
9087
8987
  }
9088
8988
  applyDeoptimizations() {
9089
8989
  this.deoptimized = true;
9090
- const { thisParam } = this.callOptions;
9091
- if (thisParam) {
9092
- this.callee.deoptimizeThisOnEventAtPath(EVENT_CALLED, EMPTY_PATH, thisParam, SHARED_RECURSION_TRACKER);
8990
+ if (this.interaction.thisArg) {
8991
+ this.callee.deoptimizeThisOnInteractionAtPath(this.interaction, EMPTY_PATH, SHARED_RECURSION_TRACKER);
9093
8992
  }
9094
8993
  for (const argument of this.arguments) {
9095
8994
  // This will make sure all properties of parameters behave as "unknown"
@@ -9100,7 +8999,7 @@ class CallExpression extends CallExpressionBase {
9100
8999
  getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) {
9101
9000
  if (this.returnExpression === null) {
9102
9001
  this.returnExpression = UNKNOWN_EXPRESSION;
9103
- return (this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.callOptions, recursionTracker, this));
9002
+ return (this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this));
9104
9003
  }
9105
9004
  return this.returnExpression;
9106
9005
  }
@@ -9171,17 +9070,13 @@ class ClassBody extends NodeBase {
9171
9070
  }
9172
9071
  super.parseNode(esTreeNode);
9173
9072
  }
9073
+ applyDeoptimizations() { }
9174
9074
  }
9175
9075
 
9176
9076
  class MethodBase extends NodeBase {
9177
9077
  constructor() {
9178
9078
  super(...arguments);
9179
9079
  this.accessedValue = null;
9180
- this.accessorCallOptions = {
9181
- args: NO_ARGS,
9182
- thisParam: null,
9183
- withNew: false
9184
- };
9185
9080
  }
9186
9081
  // As getter properties directly receive their values from fixed function
9187
9082
  // expressions, there is no known situation where a getter is deoptimized.
@@ -9189,44 +9084,60 @@ class MethodBase extends NodeBase {
9189
9084
  deoptimizePath(path) {
9190
9085
  this.getAccessedValue().deoptimizePath(path);
9191
9086
  }
9192
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
9193
- if (event === EVENT_ACCESSED && this.kind === 'get' && path.length === 0) {
9194
- return this.value.deoptimizeThisOnEventAtPath(EVENT_CALLED, EMPTY_PATH, thisParameter, recursionTracker);
9087
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
9088
+ if (interaction.type === INTERACTION_ACCESSED && this.kind === 'get' && path.length === 0) {
9089
+ return this.value.deoptimizeThisOnInteractionAtPath({
9090
+ args: NO_ARGS,
9091
+ thisArg: interaction.thisArg,
9092
+ type: INTERACTION_CALLED,
9093
+ withNew: false
9094
+ }, EMPTY_PATH, recursionTracker);
9195
9095
  }
9196
- if (event === EVENT_ASSIGNED && this.kind === 'set' && path.length === 0) {
9197
- return this.value.deoptimizeThisOnEventAtPath(EVENT_CALLED, EMPTY_PATH, thisParameter, recursionTracker);
9096
+ if (interaction.type === INTERACTION_ASSIGNED && this.kind === 'set' && path.length === 0) {
9097
+ return this.value.deoptimizeThisOnInteractionAtPath({
9098
+ args: interaction.args,
9099
+ thisArg: interaction.thisArg,
9100
+ type: INTERACTION_CALLED,
9101
+ withNew: false
9102
+ }, EMPTY_PATH, recursionTracker);
9198
9103
  }
9199
- this.getAccessedValue().deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
9104
+ this.getAccessedValue().deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
9200
9105
  }
9201
9106
  getLiteralValueAtPath(path, recursionTracker, origin) {
9202
9107
  return this.getAccessedValue().getLiteralValueAtPath(path, recursionTracker, origin);
9203
9108
  }
9204
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
9205
- return this.getAccessedValue().getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
9109
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9110
+ return this.getAccessedValue().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9206
9111
  }
9207
9112
  hasEffects(context) {
9208
9113
  return this.key.hasEffects(context);
9209
9114
  }
9210
- hasEffectsWhenAccessedAtPath(path, context) {
9211
- if (this.kind === 'get' && path.length === 0) {
9212
- return this.value.hasEffectsWhenCalledAtPath(EMPTY_PATH, this.accessorCallOptions, context);
9213
- }
9214
- return this.getAccessedValue().hasEffectsWhenAccessedAtPath(path, context);
9215
- }
9216
- hasEffectsWhenAssignedAtPath(path, context) {
9217
- if (this.kind === 'set') {
9218
- return this.value.hasEffectsWhenCalledAtPath(EMPTY_PATH, this.accessorCallOptions, context);
9115
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
9116
+ if (this.kind === 'get' && interaction.type === INTERACTION_ACCESSED && path.length === 0) {
9117
+ return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, {
9118
+ args: NO_ARGS,
9119
+ thisArg: interaction.thisArg,
9120
+ type: INTERACTION_CALLED,
9121
+ withNew: false
9122
+ }, context);
9123
+ }
9124
+ // setters are only called for empty paths
9125
+ if (this.kind === 'set' && interaction.type === INTERACTION_ASSIGNED) {
9126
+ return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, {
9127
+ args: interaction.args,
9128
+ thisArg: interaction.thisArg,
9129
+ type: INTERACTION_CALLED,
9130
+ withNew: false
9131
+ }, context);
9219
9132
  }
9220
- return this.getAccessedValue().hasEffectsWhenAssignedAtPath(path, context);
9221
- }
9222
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
9223
- return this.getAccessedValue().hasEffectsWhenCalledAtPath(path, callOptions, context);
9133
+ return this.getAccessedValue().hasEffectsOnInteractionAtPath(path, interaction, context);
9224
9134
  }
9135
+ applyDeoptimizations() { }
9225
9136
  getAccessedValue() {
9226
9137
  if (this.accessedValue === null) {
9227
9138
  if (this.kind === 'get') {
9228
9139
  this.accessedValue = UNKNOWN_EXPRESSION;
9229
- return (this.accessedValue = this.value.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.accessorCallOptions, SHARED_RECURSION_TRACKER, this));
9140
+ return (this.accessedValue = this.value.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, SHARED_RECURSION_TRACKER, this));
9230
9141
  }
9231
9142
  else {
9232
9143
  return (this.accessedValue = this.value);
@@ -9237,6 +9148,7 @@ class MethodBase extends NodeBase {
9237
9148
  }
9238
9149
 
9239
9150
  class MethodDefinition extends MethodBase {
9151
+ applyDeoptimizations() { }
9240
9152
  }
9241
9153
 
9242
9154
  class ObjectMember extends ExpressionEntity {
@@ -9248,30 +9160,23 @@ class ObjectMember extends ExpressionEntity {
9248
9160
  deoptimizePath(path) {
9249
9161
  this.object.deoptimizePath([this.key, ...path]);
9250
9162
  }
9251
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
9252
- this.object.deoptimizeThisOnEventAtPath(event, [this.key, ...path], thisParameter, recursionTracker);
9163
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
9164
+ this.object.deoptimizeThisOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker);
9253
9165
  }
9254
9166
  getLiteralValueAtPath(path, recursionTracker, origin) {
9255
9167
  return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin);
9256
9168
  }
9257
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
9258
- return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], callOptions, recursionTracker, origin);
9259
- }
9260
- hasEffectsWhenAccessedAtPath(path, context) {
9261
- return this.object.hasEffectsWhenAccessedAtPath([this.key, ...path], context);
9262
- }
9263
- hasEffectsWhenAssignedAtPath(path, context) {
9264
- return this.object.hasEffectsWhenAssignedAtPath([this.key, ...path], context);
9169
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9170
+ return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin);
9265
9171
  }
9266
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
9267
- return this.object.hasEffectsWhenCalledAtPath([this.key, ...path], callOptions, context);
9172
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
9173
+ return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context);
9268
9174
  }
9269
9175
  }
9270
9176
 
9271
9177
  class ClassNode extends NodeBase {
9272
9178
  constructor() {
9273
9179
  super(...arguments);
9274
- this.deoptimized = false;
9275
9180
  this.objectEntity = null;
9276
9181
  }
9277
9182
  createScope(parentScope) {
@@ -9281,23 +9186,16 @@ class ClassNode extends NodeBase {
9281
9186
  this.getObjectEntity().deoptimizeAllProperties();
9282
9187
  }
9283
9188
  deoptimizePath(path) {
9284
- var _a, _b;
9285
9189
  this.getObjectEntity().deoptimizePath(path);
9286
- if (path.length === 1 && path[0] === UnknownKey) {
9287
- // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
9288
- // which means the constructor needs to be reassigned
9289
- (_a = this.classConstructor) === null || _a === void 0 ? void 0 : _a.deoptimizePath(UNKNOWN_PATH);
9290
- (_b = this.superClass) === null || _b === void 0 ? void 0 : _b.deoptimizePath(UNKNOWN_PATH);
9291
- }
9292
9190
  }
9293
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
9294
- this.getObjectEntity().deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
9191
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
9192
+ this.getObjectEntity().deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
9295
9193
  }
9296
9194
  getLiteralValueAtPath(path, recursionTracker, origin) {
9297
9195
  return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);
9298
9196
  }
9299
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
9300
- return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
9197
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9198
+ return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9301
9199
  }
9302
9200
  hasEffects(context) {
9303
9201
  var _a, _b;
@@ -9307,23 +9205,17 @@ class ClassNode extends NodeBase {
9307
9205
  (_b = this.id) === null || _b === void 0 ? void 0 : _b.markDeclarationReached();
9308
9206
  return initEffect || super.hasEffects(context);
9309
9207
  }
9310
- hasEffectsWhenAccessedAtPath(path, context) {
9311
- return this.getObjectEntity().hasEffectsWhenAccessedAtPath(path, context);
9312
- }
9313
- hasEffectsWhenAssignedAtPath(path, context) {
9314
- return this.getObjectEntity().hasEffectsWhenAssignedAtPath(path, context);
9315
- }
9316
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
9208
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
9317
9209
  var _a;
9318
- if (path.length === 0) {
9319
- return (!callOptions.withNew ||
9210
+ if (interaction.type === INTERACTION_CALLED && path.length === 0) {
9211
+ return (!interaction.withNew ||
9320
9212
  (this.classConstructor !== null
9321
- ? this.classConstructor.hasEffectsWhenCalledAtPath(EMPTY_PATH, callOptions, context)
9322
- : (_a = this.superClass) === null || _a === void 0 ? void 0 : _a.hasEffectsWhenCalledAtPath(path, callOptions, context)) ||
9213
+ ? this.classConstructor.hasEffectsOnInteractionAtPath(path, interaction, context)
9214
+ : (_a = this.superClass) === null || _a === void 0 ? void 0 : _a.hasEffectsOnInteractionAtPath(path, interaction, context)) ||
9323
9215
  false);
9324
9216
  }
9325
9217
  else {
9326
- return this.getObjectEntity().hasEffectsWhenCalledAtPath(path, callOptions, context);
9218
+ return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
9327
9219
  }
9328
9220
  }
9329
9221
  include(context, includeChildrenRecursively) {
@@ -9444,26 +9336,12 @@ class MultiExpression extends ExpressionEntity {
9444
9336
  expression.deoptimizePath(path);
9445
9337
  }
9446
9338
  }
9447
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
9448
- return new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin)));
9449
- }
9450
- hasEffectsWhenAccessedAtPath(path, context) {
9451
- for (const expression of this.expressions) {
9452
- if (expression.hasEffectsWhenAccessedAtPath(path, context))
9453
- return true;
9454
- }
9455
- return false;
9456
- }
9457
- hasEffectsWhenAssignedAtPath(path, context) {
9458
- for (const expression of this.expressions) {
9459
- if (expression.hasEffectsWhenAssignedAtPath(path, context))
9460
- return true;
9461
- }
9462
- return false;
9339
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9340
+ return new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)));
9463
9341
  }
9464
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
9342
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
9465
9343
  for (const expression of this.expressions) {
9466
- if (expression.hasEffectsWhenCalledAtPath(path, callOptions, context))
9344
+ if (expression.hasEffectsOnInteractionAtPath(path, interaction, context))
9467
9345
  return true;
9468
9346
  }
9469
9347
  return false;
@@ -9506,9 +9384,9 @@ class ConditionalExpression extends NodeBase {
9506
9384
  usedBranch.deoptimizePath(path);
9507
9385
  }
9508
9386
  }
9509
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
9510
- this.consequent.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
9511
- this.alternate.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
9387
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
9388
+ this.consequent.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
9389
+ this.alternate.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
9512
9390
  }
9513
9391
  getLiteralValueAtPath(path, recursionTracker, origin) {
9514
9392
  const usedBranch = this.getUsedBranch();
@@ -9517,15 +9395,15 @@ class ConditionalExpression extends NodeBase {
9517
9395
  this.expressionsToBeDeoptimized.push(origin);
9518
9396
  return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin);
9519
9397
  }
9520
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
9398
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
9521
9399
  const usedBranch = this.getUsedBranch();
9522
9400
  if (!usedBranch)
9523
9401
  return new MultiExpression([
9524
- this.consequent.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin),
9525
- this.alternate.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin)
9402
+ this.consequent.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin),
9403
+ this.alternate.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)
9526
9404
  ]);
9527
9405
  this.expressionsToBeDeoptimized.push(origin);
9528
- return usedBranch.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
9406
+ return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
9529
9407
  }
9530
9408
  hasEffects(context) {
9531
9409
  if (this.test.hasEffects(context))
@@ -9536,29 +9414,13 @@ class ConditionalExpression extends NodeBase {
9536
9414
  }
9537
9415
  return usedBranch.hasEffects(context);
9538
9416
  }
9539
- hasEffectsWhenAccessedAtPath(path, context) {
9540
- const usedBranch = this.getUsedBranch();
9541
- if (!usedBranch) {
9542
- return (this.consequent.hasEffectsWhenAccessedAtPath(path, context) ||
9543
- this.alternate.hasEffectsWhenAccessedAtPath(path, context));
9544
- }
9545
- return usedBranch.hasEffectsWhenAccessedAtPath(path, context);
9546
- }
9547
- hasEffectsWhenAssignedAtPath(path, context) {
9548
- const usedBranch = this.getUsedBranch();
9549
- if (!usedBranch) {
9550
- return (this.consequent.hasEffectsWhenAssignedAtPath(path, context) ||
9551
- this.alternate.hasEffectsWhenAssignedAtPath(path, context));
9552
- }
9553
- return usedBranch.hasEffectsWhenAssignedAtPath(path, context);
9554
- }
9555
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
9417
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
9556
9418
  const usedBranch = this.getUsedBranch();
9557
9419
  if (!usedBranch) {
9558
- return (this.consequent.hasEffectsWhenCalledAtPath(path, callOptions, context) ||
9559
- this.alternate.hasEffectsWhenCalledAtPath(path, callOptions, context));
9420
+ return (this.consequent.hasEffectsOnInteractionAtPath(path, interaction, context) ||
9421
+ this.alternate.hasEffectsOnInteractionAtPath(path, interaction, context));
9560
9422
  }
9561
- return usedBranch.hasEffectsWhenCalledAtPath(path, callOptions, context);
9423
+ return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
9562
9424
  }
9563
9425
  include(context, includeChildrenRecursively) {
9564
9426
  this.included = true;
@@ -9686,13 +9548,11 @@ class ExportAllDeclaration extends NodeBase {
9686
9548
  render(code, _options, nodeRenderOptions) {
9687
9549
  code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
9688
9550
  }
9551
+ applyDeoptimizations() { }
9689
9552
  }
9690
9553
  ExportAllDeclaration.prototype.needsBoundaries = true;
9691
9554
 
9692
9555
  class FunctionDeclaration extends FunctionNode {
9693
- include(context, includeChildrenRecursively) {
9694
- super.include(context, includeChildrenRecursively, { includeWithoutParameterDefaults: true });
9695
- }
9696
9556
  initialise() {
9697
9557
  super.initialise();
9698
9558
  if (this.id !== null) {
@@ -9763,6 +9623,7 @@ class ExportDefaultDeclaration extends NodeBase {
9763
9623
  }
9764
9624
  this.declaration.render(code, options);
9765
9625
  }
9626
+ applyDeoptimizations() { }
9766
9627
  renderNamedDeclaration(code, declarationStart, declarationKeyword, endMarker, needsId, options) {
9767
9628
  const { exportNamesByVariable, format, snippets: { getPropertyAccess } } = options;
9768
9629
  const name = this.variable.getName(getPropertyAccess);
@@ -9817,27 +9678,23 @@ class ExportNamedDeclaration extends NodeBase {
9817
9678
  this.declaration.render(code, options, { end, start });
9818
9679
  }
9819
9680
  }
9681
+ applyDeoptimizations() { }
9820
9682
  }
9821
9683
  ExportNamedDeclaration.prototype.needsBoundaries = true;
9822
9684
 
9823
9685
  class ExportSpecifier extends NodeBase {
9686
+ applyDeoptimizations() { }
9824
9687
  }
9825
9688
 
9826
9689
  class ForInStatement extends NodeBase {
9827
- constructor() {
9828
- super(...arguments);
9829
- this.deoptimized = false;
9830
- }
9831
9690
  createScope(parentScope) {
9832
9691
  this.scope = new BlockScope(parentScope);
9833
9692
  }
9834
9693
  hasEffects(context) {
9835
- if (!this.deoptimized)
9694
+ const { deoptimized, left, right } = this;
9695
+ if (!deoptimized)
9836
9696
  this.applyDeoptimizations();
9837
- if ((this.left &&
9838
- (this.left.hasEffects(context) ||
9839
- this.left.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context))) ||
9840
- (this.right && this.right.hasEffects(context)))
9697
+ if (left.hasEffectsAsAssignmentTarget(context, false) || right.hasEffects(context))
9841
9698
  return true;
9842
9699
  const { brokenFlow, ignore: { breaks, continues } } = context;
9843
9700
  context.ignore.breaks = true;
@@ -9850,15 +9707,19 @@ class ForInStatement extends NodeBase {
9850
9707
  return false;
9851
9708
  }
9852
9709
  include(context, includeChildrenRecursively) {
9853
- if (!this.deoptimized)
9710
+ const { body, deoptimized, left, right } = this;
9711
+ if (!deoptimized)
9854
9712
  this.applyDeoptimizations();
9855
9713
  this.included = true;
9856
- this.left.include(context, includeChildrenRecursively || true);
9857
- this.right.include(context, includeChildrenRecursively);
9714
+ left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
9715
+ right.include(context, includeChildrenRecursively);
9858
9716
  const { brokenFlow } = context;
9859
- this.body.include(context, includeChildrenRecursively, { asSingleStatement: true });
9717
+ body.include(context, includeChildrenRecursively, { asSingleStatement: true });
9860
9718
  context.brokenFlow = brokenFlow;
9861
9719
  }
9720
+ initialise() {
9721
+ this.left.setAssignedValue(UNKNOWN_EXPRESSION);
9722
+ }
9862
9723
  render(code, options) {
9863
9724
  this.left.render(code, options, NO_SEMICOLON);
9864
9725
  this.right.render(code, options, NO_SEMICOLON);
@@ -9876,10 +9737,6 @@ class ForInStatement extends NodeBase {
9876
9737
  }
9877
9738
 
9878
9739
  class ForOfStatement extends NodeBase {
9879
- constructor() {
9880
- super(...arguments);
9881
- this.deoptimized = false;
9882
- }
9883
9740
  createScope(parentScope) {
9884
9741
  this.scope = new BlockScope(parentScope);
9885
9742
  }
@@ -9890,15 +9747,19 @@ class ForOfStatement extends NodeBase {
9890
9747
  return true;
9891
9748
  }
9892
9749
  include(context, includeChildrenRecursively) {
9893
- if (!this.deoptimized)
9750
+ const { body, deoptimized, left, right } = this;
9751
+ if (!deoptimized)
9894
9752
  this.applyDeoptimizations();
9895
9753
  this.included = true;
9896
- this.left.include(context, includeChildrenRecursively || true);
9897
- this.right.include(context, includeChildrenRecursively);
9754
+ left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false);
9755
+ right.include(context, includeChildrenRecursively);
9898
9756
  const { brokenFlow } = context;
9899
- this.body.include(context, includeChildrenRecursively, { asSingleStatement: true });
9757
+ body.include(context, includeChildrenRecursively, { asSingleStatement: true });
9900
9758
  context.brokenFlow = brokenFlow;
9901
9759
  }
9760
+ initialise() {
9761
+ this.left.setAssignedValue(UNKNOWN_EXPRESSION);
9762
+ }
9902
9763
  render(code, options) {
9903
9764
  this.left.render(code, options, NO_SEMICOLON);
9904
9765
  this.right.render(code, options, NO_SEMICOLON);
@@ -10074,6 +9935,7 @@ class IfStatement extends NodeBase {
10074
9935
  }
10075
9936
  this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess);
10076
9937
  }
9938
+ applyDeoptimizations() { }
10077
9939
  getTestValue() {
10078
9940
  if (this.testValue === unset) {
10079
9941
  return (this.testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this));
@@ -10159,10 +10021,12 @@ class ImportDeclaration extends NodeBase {
10159
10021
  render(code, _options, nodeRenderOptions) {
10160
10022
  code.remove(nodeRenderOptions.start, nodeRenderOptions.end);
10161
10023
  }
10024
+ applyDeoptimizations() { }
10162
10025
  }
10163
10026
  ImportDeclaration.prototype.needsBoundaries = true;
10164
10027
 
10165
10028
  class ImportDefaultSpecifier extends NodeBase {
10029
+ applyDeoptimizations() { }
10166
10030
  }
10167
10031
 
10168
10032
  const INTEROP_DEFAULT_VARIABLE = '_interopDefault';
@@ -10421,6 +10285,7 @@ class ImportExpression extends NodeBase {
10421
10285
  setInternalResolution(inlineNamespace) {
10422
10286
  this.inlineNamespace = inlineNamespace;
10423
10287
  }
10288
+ applyDeoptimizations() { }
10424
10289
  getDynamicImportMechanismAndHelper(resolution, exportMode, { compact, dynamicImportFunction, format, generatedCode: { arrowFunctions }, interop }, { _, getDirectReturnFunction, getDirectReturnIifeLeft }, pluginDriver) {
10425
10290
  const mechanism = pluginDriver.hookFirstSync('renderDynamicImport', [
10426
10291
  {
@@ -10529,9 +10394,11 @@ const accessedImportGlobals = {
10529
10394
  };
10530
10395
 
10531
10396
  class ImportNamespaceSpecifier extends NodeBase {
10397
+ applyDeoptimizations() { }
10532
10398
  }
10533
10399
 
10534
10400
  class ImportSpecifier extends NodeBase {
10401
+ applyDeoptimizations() { }
10535
10402
  }
10536
10403
 
10537
10404
  class LabeledStatement extends NodeBase {
@@ -10577,13 +10444,16 @@ class LogicalExpression extends NodeBase {
10577
10444
  this.usedBranch = null;
10578
10445
  }
10579
10446
  deoptimizeCache() {
10580
- if (this.usedBranch !== null) {
10447
+ if (this.usedBranch) {
10581
10448
  const unusedBranch = this.usedBranch === this.left ? this.right : this.left;
10582
10449
  this.usedBranch = null;
10583
10450
  unusedBranch.deoptimizePath(UNKNOWN_PATH);
10584
10451
  for (const expression of this.expressionsToBeDeoptimized) {
10585
10452
  expression.deoptimizeCache();
10586
10453
  }
10454
+ // Request another pass because we need to ensure "include" runs again if
10455
+ // it is rendered
10456
+ this.context.requestTreeshakingPass();
10587
10457
  }
10588
10458
  }
10589
10459
  deoptimizePath(path) {
@@ -10596,9 +10466,9 @@ class LogicalExpression extends NodeBase {
10596
10466
  usedBranch.deoptimizePath(path);
10597
10467
  }
10598
10468
  }
10599
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
10600
- this.left.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
10601
- this.right.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
10469
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
10470
+ this.left.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
10471
+ this.right.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
10602
10472
  }
10603
10473
  getLiteralValueAtPath(path, recursionTracker, origin) {
10604
10474
  const usedBranch = this.getUsedBranch();
@@ -10607,15 +10477,15 @@ class LogicalExpression extends NodeBase {
10607
10477
  this.expressionsToBeDeoptimized.push(origin);
10608
10478
  return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin);
10609
10479
  }
10610
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
10480
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
10611
10481
  const usedBranch = this.getUsedBranch();
10612
10482
  if (!usedBranch)
10613
10483
  return new MultiExpression([
10614
- this.left.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin),
10615
- this.right.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin)
10484
+ this.left.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin),
10485
+ this.right.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)
10616
10486
  ]);
10617
10487
  this.expressionsToBeDeoptimized.push(origin);
10618
- return usedBranch.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
10488
+ return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
10619
10489
  }
10620
10490
  hasEffects(context) {
10621
10491
  if (this.left.hasEffects(context)) {
@@ -10626,29 +10496,13 @@ class LogicalExpression extends NodeBase {
10626
10496
  }
10627
10497
  return false;
10628
10498
  }
10629
- hasEffectsWhenAccessedAtPath(path, context) {
10630
- const usedBranch = this.getUsedBranch();
10631
- if (!usedBranch) {
10632
- return (this.left.hasEffectsWhenAccessedAtPath(path, context) ||
10633
- this.right.hasEffectsWhenAccessedAtPath(path, context));
10634
- }
10635
- return usedBranch.hasEffectsWhenAccessedAtPath(path, context);
10636
- }
10637
- hasEffectsWhenAssignedAtPath(path, context) {
10638
- const usedBranch = this.getUsedBranch();
10639
- if (!usedBranch) {
10640
- return (this.left.hasEffectsWhenAssignedAtPath(path, context) ||
10641
- this.right.hasEffectsWhenAssignedAtPath(path, context));
10642
- }
10643
- return usedBranch.hasEffectsWhenAssignedAtPath(path, context);
10644
- }
10645
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
10499
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
10646
10500
  const usedBranch = this.getUsedBranch();
10647
10501
  if (!usedBranch) {
10648
- return (this.left.hasEffectsWhenCalledAtPath(path, callOptions, context) ||
10649
- this.right.hasEffectsWhenCalledAtPath(path, callOptions, context));
10502
+ return (this.left.hasEffectsOnInteractionAtPath(path, interaction, context) ||
10503
+ this.right.hasEffectsOnInteractionAtPath(path, interaction, context));
10650
10504
  }
10651
- return usedBranch.hasEffectsWhenCalledAtPath(path, callOptions, context);
10505
+ return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);
10652
10506
  }
10653
10507
  include(context, includeChildrenRecursively) {
10654
10508
  this.included = true;
@@ -10738,8 +10592,8 @@ class MetaProperty extends NodeBase {
10738
10592
  hasEffects() {
10739
10593
  return false;
10740
10594
  }
10741
- hasEffectsWhenAccessedAtPath(path) {
10742
- return path.length > 1;
10595
+ hasEffectsOnInteractionAtPath(path, { type }) {
10596
+ return path.length > 1 || type !== INTERACTION_ACCESSED;
10743
10597
  }
10744
10598
  include() {
10745
10599
  if (!this.included) {
@@ -10877,10 +10731,6 @@ const importMetaMechanisms = {
10877
10731
  };
10878
10732
 
10879
10733
  class NewExpression extends NodeBase {
10880
- constructor() {
10881
- super(...arguments);
10882
- this.deoptimized = false;
10883
- }
10884
10734
  hasEffects(context) {
10885
10735
  try {
10886
10736
  for (const argument of this.arguments) {
@@ -10891,15 +10741,15 @@ class NewExpression extends NodeBase {
10891
10741
  this.annotations)
10892
10742
  return false;
10893
10743
  return (this.callee.hasEffects(context) ||
10894
- this.callee.hasEffectsWhenCalledAtPath(EMPTY_PATH, this.callOptions, context));
10744
+ this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
10895
10745
  }
10896
10746
  finally {
10897
10747
  if (!this.deoptimized)
10898
10748
  this.applyDeoptimizations();
10899
10749
  }
10900
10750
  }
10901
- hasEffectsWhenAccessedAtPath(path) {
10902
- return path.length > 0;
10751
+ hasEffectsOnInteractionAtPath(path, { type }) {
10752
+ return path.length > 0 || type !== INTERACTION_ACCESSED;
10903
10753
  }
10904
10754
  include(context, includeChildrenRecursively) {
10905
10755
  if (!this.deoptimized)
@@ -10914,12 +10764,17 @@ class NewExpression extends NodeBase {
10914
10764
  this.callee.includeCallArguments(context, this.arguments);
10915
10765
  }
10916
10766
  initialise() {
10917
- this.callOptions = {
10767
+ this.interaction = {
10918
10768
  args: this.arguments,
10919
- thisParam: null,
10769
+ thisArg: null,
10770
+ type: INTERACTION_CALLED,
10920
10771
  withNew: true
10921
10772
  };
10922
10773
  }
10774
+ render(code, options) {
10775
+ this.callee.render(code, options);
10776
+ renderCallArguments(code, options, this);
10777
+ }
10923
10778
  applyDeoptimizations() {
10924
10779
  this.deoptimized = true;
10925
10780
  for (const argument of this.arguments) {
@@ -10941,23 +10796,17 @@ class ObjectExpression extends NodeBase {
10941
10796
  deoptimizePath(path) {
10942
10797
  this.getObjectEntity().deoptimizePath(path);
10943
10798
  }
10944
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
10945
- this.getObjectEntity().deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
10799
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
10800
+ this.getObjectEntity().deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
10946
10801
  }
10947
10802
  getLiteralValueAtPath(path, recursionTracker, origin) {
10948
10803
  return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);
10949
10804
  }
10950
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
10951
- return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
10952
- }
10953
- hasEffectsWhenAccessedAtPath(path, context) {
10954
- return this.getObjectEntity().hasEffectsWhenAccessedAtPath(path, context);
10805
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
10806
+ return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);
10955
10807
  }
10956
- hasEffectsWhenAssignedAtPath(path, context) {
10957
- return this.getObjectEntity().hasEffectsWhenAssignedAtPath(path, context);
10958
- }
10959
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
10960
- return this.getObjectEntity().hasEffectsWhenCalledAtPath(path, callOptions, context);
10808
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
10809
+ return this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);
10961
10810
  }
10962
10811
  render(code, options, { renderedSurroundingElement } = BLANK) {
10963
10812
  super.render(code, options);
@@ -10967,6 +10816,7 @@ class ObjectExpression extends NodeBase {
10967
10816
  code.prependLeft(this.end, ')');
10968
10817
  }
10969
10818
  }
10819
+ applyDeoptimizations() { }
10970
10820
  getObjectEntity() {
10971
10821
  if (this.objectEntity !== null) {
10972
10822
  return this.objectEntity;
@@ -11043,12 +10893,12 @@ class Program extends NodeBase {
11043
10893
  super.render(code, options);
11044
10894
  }
11045
10895
  }
10896
+ applyDeoptimizations() { }
11046
10897
  }
11047
10898
 
11048
10899
  class Property extends MethodBase {
11049
10900
  constructor() {
11050
10901
  super(...arguments);
11051
- this.deoptimized = false;
11052
10902
  this.declarationInit = null;
11053
10903
  }
11054
10904
  declare(kind, init) {
@@ -11087,33 +10937,28 @@ class PropertyDefinition extends NodeBase {
11087
10937
  var _a;
11088
10938
  (_a = this.value) === null || _a === void 0 ? void 0 : _a.deoptimizePath(path);
11089
10939
  }
11090
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
10940
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
11091
10941
  var _a;
11092
- (_a = this.value) === null || _a === void 0 ? void 0 : _a.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
10942
+ (_a = this.value) === null || _a === void 0 ? void 0 : _a.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
11093
10943
  }
11094
10944
  getLiteralValueAtPath(path, recursionTracker, origin) {
11095
10945
  return this.value
11096
10946
  ? this.value.getLiteralValueAtPath(path, recursionTracker, origin)
11097
10947
  : UnknownValue;
11098
10948
  }
11099
- getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
10949
+ getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {
11100
10950
  return this.value
11101
- ? this.value.getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin)
10951
+ ? this.value.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)
11102
10952
  : UNKNOWN_EXPRESSION;
11103
10953
  }
11104
10954
  hasEffects(context) {
11105
10955
  var _a;
11106
10956
  return this.key.hasEffects(context) || (this.static && !!((_a = this.value) === null || _a === void 0 ? void 0 : _a.hasEffects(context)));
11107
10957
  }
11108
- hasEffectsWhenAccessedAtPath(path, context) {
11109
- return !this.value || this.value.hasEffectsWhenAccessedAtPath(path, context);
11110
- }
11111
- hasEffectsWhenAssignedAtPath(path, context) {
11112
- return !this.value || this.value.hasEffectsWhenAssignedAtPath(path, context);
11113
- }
11114
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
11115
- return !this.value || this.value.hasEffectsWhenCalledAtPath(path, callOptions, context);
10958
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
10959
+ return !this.value || this.value.hasEffectsOnInteractionAtPath(path, interaction, context);
11116
10960
  }
10961
+ applyDeoptimizations() { }
11117
10962
  }
11118
10963
 
11119
10964
  class ReturnStatement extends NodeBase {
@@ -11147,8 +10992,8 @@ class SequenceExpression extends NodeBase {
11147
10992
  deoptimizePath(path) {
11148
10993
  this.expressions[this.expressions.length - 1].deoptimizePath(path);
11149
10994
  }
11150
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
11151
- this.expressions[this.expressions.length - 1].deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
10995
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
10996
+ this.expressions[this.expressions.length - 1].deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
11152
10997
  }
11153
10998
  getLiteralValueAtPath(path, recursionTracker, origin) {
11154
10999
  return this.expressions[this.expressions.length - 1].getLiteralValueAtPath(path, recursionTracker, origin);
@@ -11160,15 +11005,8 @@ class SequenceExpression extends NodeBase {
11160
11005
  }
11161
11006
  return false;
11162
11007
  }
11163
- hasEffectsWhenAccessedAtPath(path, context) {
11164
- return (path.length > 0 &&
11165
- this.expressions[this.expressions.length - 1].hasEffectsWhenAccessedAtPath(path, context));
11166
- }
11167
- hasEffectsWhenAssignedAtPath(path, context) {
11168
- return this.expressions[this.expressions.length - 1].hasEffectsWhenAssignedAtPath(path, context);
11169
- }
11170
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
11171
- return this.expressions[this.expressions.length - 1].hasEffectsWhenCalledAtPath(path, callOptions, context);
11008
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
11009
+ return this.expressions[this.expressions.length - 1].hasEffectsOnInteractionAtPath(path, interaction, context);
11172
11010
  }
11173
11011
  include(context, includeChildrenRecursively) {
11174
11012
  this.included = true;
@@ -11247,8 +11085,8 @@ class Super extends NodeBase {
11247
11085
  deoptimizePath(path) {
11248
11086
  this.variable.deoptimizePath(path);
11249
11087
  }
11250
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
11251
- this.variable.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
11088
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
11089
+ this.variable.deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker);
11252
11090
  }
11253
11091
  include() {
11254
11092
  if (!this.included) {
@@ -11388,7 +11226,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
11388
11226
  return true;
11389
11227
  }
11390
11228
  return (this.tag.hasEffects(context) ||
11391
- this.tag.hasEffectsWhenCalledAtPath(EMPTY_PATH, this.callOptions, context));
11229
+ this.tag.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));
11392
11230
  }
11393
11231
  finally {
11394
11232
  if (!this.deoptimized)
@@ -11406,16 +11244,17 @@ class TaggedTemplateExpression extends CallExpressionBase {
11406
11244
  this.tag.include(context, includeChildrenRecursively);
11407
11245
  this.quasi.include(context, includeChildrenRecursively);
11408
11246
  }
11409
- this.tag.includeCallArguments(context, this.callOptions.args);
11247
+ this.tag.includeCallArguments(context, this.interaction.args);
11410
11248
  const returnExpression = this.getReturnExpression();
11411
11249
  if (!returnExpression.included) {
11412
11250
  returnExpression.include(context, false);
11413
11251
  }
11414
11252
  }
11415
11253
  initialise() {
11416
- this.callOptions = {
11254
+ this.interaction = {
11417
11255
  args: [UNKNOWN_EXPRESSION, ...this.quasi.expressions],
11418
- thisParam: this.tag instanceof MemberExpression && !this.tag.variable ? this.tag.object : null,
11256
+ thisArg: this.tag instanceof MemberExpression && !this.tag.variable ? this.tag.object : null,
11257
+ type: INTERACTION_CALLED,
11419
11258
  withNew: false
11420
11259
  };
11421
11260
  }
@@ -11425,9 +11264,8 @@ class TaggedTemplateExpression extends CallExpressionBase {
11425
11264
  }
11426
11265
  applyDeoptimizations() {
11427
11266
  this.deoptimized = true;
11428
- const { thisParam } = this.callOptions;
11429
- if (thisParam) {
11430
- this.tag.deoptimizeThisOnEventAtPath(EVENT_CALLED, EMPTY_PATH, thisParam, SHARED_RECURSION_TRACKER);
11267
+ if (this.interaction.thisArg) {
11268
+ this.tag.deoptimizeThisOnInteractionAtPath(this.interaction, EMPTY_PATH, SHARED_RECURSION_TRACKER);
11431
11269
  }
11432
11270
  for (const argument of this.quasi.expressions) {
11433
11271
  // This will make sure all properties of parameters behave as "unknown"
@@ -11438,7 +11276,7 @@ class TaggedTemplateExpression extends CallExpressionBase {
11438
11276
  getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) {
11439
11277
  if (this.returnExpression === null) {
11440
11278
  this.returnExpression = UNKNOWN_EXPRESSION;
11441
- return (this.returnExpression = this.tag.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.callOptions, recursionTracker, this));
11279
+ return (this.returnExpression = this.tag.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this));
11442
11280
  }
11443
11281
  return this.returnExpression;
11444
11282
  }
@@ -11461,7 +11299,7 @@ class TemplateElement extends NodeBase {
11461
11299
  }
11462
11300
 
11463
11301
  class TemplateLiteral extends NodeBase {
11464
- deoptimizeThisOnEventAtPath() { }
11302
+ deoptimizeThisOnInteractionAtPath() { }
11465
11303
  getLiteralValueAtPath(path) {
11466
11304
  if (path.length > 0 || this.quasis.length !== 1) {
11467
11305
  return UnknownValue;
@@ -11474,12 +11312,12 @@ class TemplateLiteral extends NodeBase {
11474
11312
  }
11475
11313
  return getMemberReturnExpressionWhenCalled(literalStringMembers, path[0]);
11476
11314
  }
11477
- hasEffectsWhenAccessedAtPath(path) {
11478
- return path.length > 1;
11479
- }
11480
- hasEffectsWhenCalledAtPath(path, callOptions, context) {
11481
- if (path.length === 1) {
11482
- return hasMemberEffectWhenCalled(literalStringMembers, path[0], callOptions, context);
11315
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
11316
+ if (interaction.type === INTERACTION_ACCESSED) {
11317
+ return path.length > 1;
11318
+ }
11319
+ if (interaction.type === INTERACTION_CALLED && path.length === 1) {
11320
+ return hasMemberEffectWhenCalled(literalStringMembers, path[0], interaction, context);
11483
11321
  }
11484
11322
  return true;
11485
11323
  }
@@ -11607,16 +11445,15 @@ class ThisExpression extends NodeBase {
11607
11445
  deoptimizePath(path) {
11608
11446
  this.variable.deoptimizePath(path);
11609
11447
  }
11610
- deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
11611
- this.variable.deoptimizeThisOnEventAtPath(event, path,
11448
+ deoptimizeThisOnInteractionAtPath(interaction, path, recursionTracker) {
11612
11449
  // We rewrite the parameter so that a ThisVariable can detect self-mutations
11613
- thisParameter === this ? this.variable : thisParameter, recursionTracker);
11614
- }
11615
- hasEffectsWhenAccessedAtPath(path, context) {
11616
- return path.length > 0 && this.variable.hasEffectsWhenAccessedAtPath(path, context);
11450
+ this.variable.deoptimizeThisOnInteractionAtPath(interaction.thisArg === this ? { ...interaction, thisArg: this.variable } : interaction, path, recursionTracker);
11617
11451
  }
11618
- hasEffectsWhenAssignedAtPath(path, context) {
11619
- return this.variable.hasEffectsWhenAssignedAtPath(path, context);
11452
+ hasEffectsOnInteractionAtPath(path, interaction, context) {
11453
+ if (path.length === 0) {
11454
+ return interaction.type !== INTERACTION_ACCESSED;
11455
+ }
11456
+ return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);
11620
11457
  }
11621
11458
  include() {
11622
11459
  if (!this.included) {
@@ -11710,10 +11547,6 @@ const unaryOperators = {
11710
11547
  '~': value => ~value
11711
11548
  };
11712
11549
  class UnaryExpression extends NodeBase {
11713
- constructor() {
11714
- super(...arguments);
11715
- this.deoptimized = false;
11716
- }
11717
11550
  getLiteralValueAtPath(path, recursionTracker, origin) {
11718
11551
  if (path.length > 0)
11719
11552
  return UnknownValue;
@@ -11729,13 +11562,10 @@ class UnaryExpression extends NodeBase {
11729
11562
  return false;
11730
11563
  return (this.argument.hasEffects(context) ||
11731
11564
  (this.operator === 'delete' &&
11732
- this.argument.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context)));
11565
+ this.argument.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_ASSIGNMENT, context)));
11733
11566
  }
11734
- hasEffectsWhenAccessedAtPath(path) {
11735
- if (this.operator === 'void') {
11736
- return path.length > 0;
11737
- }
11738
- return path.length > 1;
11567
+ hasEffectsOnInteractionAtPath(path, { type }) {
11568
+ return type !== INTERACTION_ACCESSED || path.length > (this.operator === 'void' ? 0 : 1);
11739
11569
  }
11740
11570
  applyDeoptimizations() {
11741
11571
  this.deoptimized = true;
@@ -11756,18 +11586,22 @@ class UnknownNode extends NodeBase {
11756
11586
  }
11757
11587
 
11758
11588
  class UpdateExpression extends NodeBase {
11759
- constructor() {
11760
- super(...arguments);
11761
- this.deoptimized = false;
11762
- }
11763
11589
  hasEffects(context) {
11764
11590
  if (!this.deoptimized)
11765
11591
  this.applyDeoptimizations();
11766
- return (this.argument.hasEffects(context) ||
11767
- this.argument.hasEffectsWhenAssignedAtPath(EMPTY_PATH, context));
11592
+ return this.argument.hasEffectsAsAssignmentTarget(context, true);
11593
+ }
11594
+ hasEffectsOnInteractionAtPath(path, { type }) {
11595
+ return path.length > 1 || type !== INTERACTION_ACCESSED;
11596
+ }
11597
+ include(context, includeChildrenRecursively) {
11598
+ if (!this.deoptimized)
11599
+ this.applyDeoptimizations();
11600
+ this.included = true;
11601
+ this.argument.includeAsAssignmentTarget(context, includeChildrenRecursively, true);
11768
11602
  }
11769
- hasEffectsWhenAccessedAtPath(path) {
11770
- return path.length > 1;
11603
+ initialise() {
11604
+ this.argument.setAssignedValue(UNKNOWN_EXPRESSION);
11771
11605
  }
11772
11606
  render(code, options) {
11773
11607
  const { exportNamesByVariable, format, snippets: { _ } } = options;
@@ -11829,7 +11663,7 @@ class VariableDeclaration extends NodeBase {
11829
11663
  declarator.deoptimizePath(EMPTY_PATH);
11830
11664
  }
11831
11665
  }
11832
- hasEffectsWhenAssignedAtPath() {
11666
+ hasEffectsOnInteractionAtPath() {
11833
11667
  return false;
11834
11668
  }
11835
11669
  include(context, includeChildrenRecursively, { asSingleStatement } = BLANK) {
@@ -11861,6 +11695,7 @@ class VariableDeclaration extends NodeBase {
11861
11695
  this.renderReplacedDeclarations(code, options);
11862
11696
  }
11863
11697
  }
11698
+ applyDeoptimizations() { }
11864
11699
  renderDeclarationEnd(code, separatorString, lastSeparatorPos, actualContentEnd, renderedContentEnd, systemPatternExports, options) {
11865
11700
  if (code.original.charCodeAt(this.end - 1) === 59 /*";"*/) {
11866
11701
  code.remove(this.end - 1, this.end);
@@ -11991,9 +11826,7 @@ class VariableDeclarator extends NodeBase {
11991
11826
  include(context, includeChildrenRecursively) {
11992
11827
  var _a;
11993
11828
  this.included = true;
11994
- (_a = this.init) === null || _a === void 0 ? void 0 : _a.include(context, includeChildrenRecursively, {
11995
- includeWithoutParameterDefaults: true
11996
- });
11829
+ (_a = this.init) === null || _a === void 0 ? void 0 : _a.include(context, includeChildrenRecursively);
11997
11830
  this.id.markDeclarationReached();
11998
11831
  if (includeChildrenRecursively || this.id.shouldBeIncluded(context)) {
11999
11832
  this.id.include(context, includeChildrenRecursively);
@@ -12017,6 +11850,7 @@ class VariableDeclarator extends NodeBase {
12017
11850
  code.appendLeft(this.end, `${_}=${_}void 0`);
12018
11851
  }
12019
11852
  }
11853
+ applyDeoptimizations() { }
12020
11854
  }
12021
11855
 
12022
11856
  class WhileStatement extends NodeBase {
@@ -12043,15 +11877,11 @@ class WhileStatement extends NodeBase {
12043
11877
  }
12044
11878
 
12045
11879
  class YieldExpression extends NodeBase {
12046
- constructor() {
12047
- super(...arguments);
12048
- this.deoptimized = false;
12049
- }
12050
11880
  hasEffects(context) {
12051
11881
  var _a;
12052
11882
  if (!this.deoptimized)
12053
11883
  this.applyDeoptimizations();
12054
- return !context.ignore.returnYield || !!((_a = this.argument) === null || _a === void 0 ? void 0 : _a.hasEffects(context));
11884
+ return !(context.ignore.returnYield && !((_a = this.argument) === null || _a === void 0 ? void 0 : _a.hasEffects(context)));
12055
11885
  }
12056
11886
  render(code, options) {
12057
11887
  if (this.argument) {