rollup 2.72.1 → 2.74.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  @license
3
- Rollup.js v2.72.1
4
- Sat, 07 May 2022 19:04:43 GMT - commit 8c6e0f319b792ea52fe979888593b6523315ae93
3
+ Rollup.js v2.74.1
4
+ Thu, 19 May 2022 17:50:11 GMT - commit e823eded9920d6082cc8c1afcf591b716ab6b160
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.72.1";
17
+ var version$1 = "2.74.1";
18
18
 
19
19
  var charToInteger = {};
20
20
  var chars$1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
@@ -1521,9 +1521,16 @@ function getOrCreate(map, key, init) {
1521
1521
  }
1522
1522
 
1523
1523
  const UnknownKey = Symbol('Unknown Key');
1524
+ const UnknownNonAccessorKey = Symbol('Unknown Non-Accessor Key');
1524
1525
  const UnknownInteger = Symbol('Unknown Integer');
1525
1526
  const EMPTY_PATH = [];
1526
1527
  const UNKNOWN_PATH = [UnknownKey];
1528
+ // For deoptimizations, this means we are modifying an unknown property but did
1529
+ // not lose track of the object or are creating a setter/getter;
1530
+ // For assignment effects it means we do not check for setter/getter effects
1531
+ // but only if something is mutated that is included, which is relevant for
1532
+ // Object.defineProperty
1533
+ const UNKNOWN_NON_ACCESSOR_PATH = [UnknownNonAccessorKey];
1527
1534
  const UNKNOWN_INTEGER_PATH = [UnknownInteger];
1528
1535
  const EntitiesKey = Symbol('Entities');
1529
1536
  class PathTracker {
@@ -4580,7 +4587,7 @@ const UNDEFINED_EXPRESSION = new (class UndefinedExpression extends ExpressionEn
4580
4587
  })();
4581
4588
  const returnsUnknown = {
4582
4589
  value: {
4583
- callsArgs: null,
4590
+ hasEffectsWhenCalled: null,
4584
4591
  returns: UNKNOWN_EXPRESSION
4585
4592
  }
4586
4593
  };
@@ -4603,7 +4610,7 @@ const UNKNOWN_LITERAL_BOOLEAN = new (class UnknownBoolean extends ExpressionEnti
4603
4610
  })();
4604
4611
  const returnsBoolean = {
4605
4612
  value: {
4606
- callsArgs: null,
4613
+ hasEffectsWhenCalled: null,
4607
4614
  returns: UNKNOWN_LITERAL_BOOLEAN
4608
4615
  }
4609
4616
  };
@@ -4626,7 +4633,7 @@ const UNKNOWN_LITERAL_NUMBER = new (class UnknownNumber extends ExpressionEntity
4626
4633
  })();
4627
4634
  const returnsNumber = {
4628
4635
  value: {
4629
- callsArgs: null,
4636
+ hasEffectsWhenCalled: null,
4630
4637
  returns: UNKNOWN_LITERAL_NUMBER
4631
4638
  }
4632
4639
  };
@@ -4649,7 +4656,24 @@ const UNKNOWN_LITERAL_STRING = new (class UnknownString extends ExpressionEntity
4649
4656
  })();
4650
4657
  const returnsString = {
4651
4658
  value: {
4652
- callsArgs: null,
4659
+ hasEffectsWhenCalled: null,
4660
+ returns: UNKNOWN_LITERAL_STRING
4661
+ }
4662
+ };
4663
+ const stringReplace = {
4664
+ value: {
4665
+ hasEffectsWhenCalled(callOptions, context) {
4666
+ const arg1 = callOptions.args[1];
4667
+ return (callOptions.args.length < 2 ||
4668
+ (arg1.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, {
4669
+ deoptimizeCache() { }
4670
+ }) === UnknownValue &&
4671
+ arg1.hasEffectsWhenCalledAtPath(EMPTY_PATH, {
4672
+ args: NO_ARGS,
4673
+ thisParam: null,
4674
+ withNew: false
4675
+ }, context)));
4676
+ },
4653
4677
  returns: UNKNOWN_LITERAL_STRING
4654
4678
  }
4655
4679
  };
@@ -4697,18 +4721,8 @@ const literalStringMembers = assembleMemberDescriptions({
4697
4721
  padEnd: returnsString,
4698
4722
  padStart: returnsString,
4699
4723
  repeat: returnsString,
4700
- replace: {
4701
- value: {
4702
- callsArgs: [1],
4703
- returns: UNKNOWN_LITERAL_STRING
4704
- }
4705
- },
4706
- replaceAll: {
4707
- value: {
4708
- callsArgs: [1],
4709
- returns: UNKNOWN_LITERAL_STRING
4710
- }
4711
- },
4724
+ replace: stringReplace,
4725
+ replaceAll: stringReplace,
4712
4726
  search: returnsNumber,
4713
4727
  slice: returnsString,
4714
4728
  small: returnsString,
@@ -4743,21 +4757,11 @@ function getLiteralMembersForValue(value) {
4743
4757
  return Object.create(null);
4744
4758
  }
4745
4759
  function hasMemberEffectWhenCalled(members, memberName, callOptions, context) {
4760
+ var _a, _b;
4746
4761
  if (typeof memberName !== 'string' || !members[memberName]) {
4747
4762
  return true;
4748
4763
  }
4749
- if (!members[memberName].callsArgs)
4750
- return false;
4751
- for (const argIndex of members[memberName].callsArgs) {
4752
- if (callOptions.args[argIndex] &&
4753
- callOptions.args[argIndex].hasEffectsWhenCalledAtPath(EMPTY_PATH, {
4754
- args: NO_ARGS,
4755
- thisParam: null,
4756
- withNew: false
4757
- }, context))
4758
- return true;
4759
- }
4760
- return false;
4764
+ return ((_b = (_a = members[memberName]).hasEffectsWhenCalled) === null || _b === void 0 ? void 0 : _b.call(_a, callOptions, context)) || false;
4761
4765
  }
4762
4766
  function getMemberReturnExpressionWhenCalled(members, memberName) {
4763
4767
  if (typeof memberName !== 'string' || !members[memberName])
@@ -5464,6 +5468,7 @@ class ObjectEntity extends ExpressionEntity {
5464
5468
  this.deoptimizedPaths = Object.create(null);
5465
5469
  this.expressionsToBeDeoptimizedByKey = Object.create(null);
5466
5470
  this.gettersByKey = Object.create(null);
5471
+ this.hasLostTrack = false;
5467
5472
  this.hasUnknownDeoptimizedInteger = false;
5468
5473
  this.hasUnknownDeoptimizedProperty = false;
5469
5474
  this.propertiesAndGettersByKey = Object.create(null);
@@ -5484,12 +5489,18 @@ class ObjectEntity extends ExpressionEntity {
5484
5489
  }
5485
5490
  }
5486
5491
  }
5487
- deoptimizeAllProperties() {
5492
+ deoptimizeAllProperties(noAccessors) {
5488
5493
  var _a;
5489
- if (this.hasUnknownDeoptimizedProperty) {
5494
+ const isDeoptimized = this.hasLostTrack || this.hasUnknownDeoptimizedProperty;
5495
+ if (noAccessors) {
5496
+ this.hasUnknownDeoptimizedProperty = true;
5497
+ }
5498
+ else {
5499
+ this.hasLostTrack = true;
5500
+ }
5501
+ if (isDeoptimized) {
5490
5502
  return;
5491
5503
  }
5492
- this.hasUnknownDeoptimizedProperty = true;
5493
5504
  for (const properties of Object.values(this.propertiesAndGettersByKey).concat(Object.values(this.settersByKey))) {
5494
5505
  for (const property of properties) {
5495
5506
  property.deoptimizePath(UNKNOWN_PATH);
@@ -5500,7 +5511,9 @@ class ObjectEntity extends ExpressionEntity {
5500
5511
  this.deoptimizeCachedEntities();
5501
5512
  }
5502
5513
  deoptimizeIntegerProperties() {
5503
- if (this.hasUnknownDeoptimizedProperty || this.hasUnknownDeoptimizedInteger) {
5514
+ if (this.hasLostTrack ||
5515
+ this.hasUnknownDeoptimizedProperty ||
5516
+ this.hasUnknownDeoptimizedInteger) {
5504
5517
  return;
5505
5518
  }
5506
5519
  this.hasUnknownDeoptimizedInteger = true;
@@ -5513,17 +5526,19 @@ class ObjectEntity extends ExpressionEntity {
5513
5526
  }
5514
5527
  this.deoptimizeCachedIntegerEntities();
5515
5528
  }
5529
+ // Assumption: If only a specific path is deoptimized, no accessors are created
5516
5530
  deoptimizePath(path) {
5517
5531
  var _a;
5518
- if (this.hasUnknownDeoptimizedProperty || this.immutable)
5532
+ if (this.hasLostTrack || this.immutable) {
5519
5533
  return;
5534
+ }
5520
5535
  const key = path[0];
5521
5536
  if (path.length === 1) {
5522
5537
  if (typeof key !== 'string') {
5523
5538
  if (key === UnknownInteger) {
5524
5539
  return this.deoptimizeIntegerProperties();
5525
5540
  }
5526
- return this.deoptimizeAllProperties();
5541
+ return this.deoptimizeAllProperties(key === UnknownNonAccessorKey);
5527
5542
  }
5528
5543
  if (!this.deoptimizedPaths[key]) {
5529
5544
  this.deoptimizedPaths[key] = true;
@@ -5548,11 +5563,11 @@ class ObjectEntity extends ExpressionEntity {
5548
5563
  deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
5549
5564
  var _a;
5550
5565
  const [key, ...subPath] = path;
5551
- if (this.hasUnknownDeoptimizedProperty ||
5566
+ if (this.hasLostTrack ||
5552
5567
  // single paths that are deoptimized will not become getters or setters
5553
5568
  ((event === EVENT_CALLED || path.length > 1) &&
5554
- typeof key === 'string' &&
5555
- this.deoptimizedPaths[key])) {
5569
+ (this.hasUnknownDeoptimizedProperty ||
5570
+ (typeof key === 'string' && this.deoptimizedPaths[key])))) {
5556
5571
  thisParameter.deoptimizePath(UNKNOWN_PATH);
5557
5572
  return;
5558
5573
  }
@@ -5650,7 +5665,7 @@ class ObjectEntity extends ExpressionEntity {
5650
5665
  }
5651
5666
  return true;
5652
5667
  }
5653
- if (this.hasUnknownDeoptimizedProperty)
5668
+ if (this.hasLostTrack)
5654
5669
  return true;
5655
5670
  if (typeof key === 'string') {
5656
5671
  if (this.propertiesAndGettersByKey[key]) {
@@ -5697,9 +5712,10 @@ class ObjectEntity extends ExpressionEntity {
5697
5712
  }
5698
5713
  return true;
5699
5714
  }
5700
- if (this.hasUnknownDeoptimizedProperty)
5715
+ if (key === UnknownNonAccessorKey)
5716
+ return false;
5717
+ if (this.hasLostTrack)
5701
5718
  return true;
5702
- // We do not need to test for unknown properties as in that case, hasUnknownDeoptimizedProperty is true
5703
5719
  if (typeof key === 'string') {
5704
5720
  if (this.propertiesAndSettersByKey[key]) {
5705
5721
  const setters = this.settersByKey[key];
@@ -5717,6 +5733,14 @@ class ObjectEntity extends ExpressionEntity {
5717
5733
  }
5718
5734
  }
5719
5735
  }
5736
+ else {
5737
+ for (const setters of Object.values(this.settersByKey).concat([this.unmatchableSetters])) {
5738
+ for (const setter of setters) {
5739
+ if (setter.hasEffectsWhenAssignedAtPath(subPath, context))
5740
+ return true;
5741
+ }
5742
+ }
5743
+ }
5720
5744
  if (this.prototypeExpression) {
5721
5745
  return this.prototypeExpression.hasEffectsWhenAssignedAtPath(path, context);
5722
5746
  }
@@ -5800,7 +5824,8 @@ class ObjectEntity extends ExpressionEntity {
5800
5824
  }
5801
5825
  }
5802
5826
  getMemberExpression(key) {
5803
- if (this.hasUnknownDeoptimizedProperty ||
5827
+ if (this.hasLostTrack ||
5828
+ this.hasUnknownDeoptimizedProperty ||
5804
5829
  typeof key !== 'string' ||
5805
5830
  (this.hasUnknownDeoptimizedInteger && INTEGER_REG_EXP.test(key)) ||
5806
5831
  this.deoptimizedPaths[key]) {
@@ -6466,323 +6491,89 @@ class ReturnValueScope extends ParameterScope {
6466
6491
  }
6467
6492
  }
6468
6493
 
6469
- function treeshakeNode(node, code, start, end) {
6470
- code.remove(start, end);
6471
- if (node.annotations) {
6472
- for (const annotation of node.annotations) {
6473
- if (annotation.start < start) {
6474
- code.remove(annotation.start, annotation.end);
6475
- }
6476
- else {
6477
- return;
6478
- }
6479
- }
6480
- }
6481
- }
6482
- function removeAnnotations(node, code) {
6483
- if (!node.annotations && node.parent.type === ExpressionStatement$1) {
6484
- node = node.parent;
6485
- }
6486
- if (node.annotations) {
6487
- for (const annotation of node.annotations) {
6488
- code.remove(annotation.start, annotation.end);
6489
- }
6490
- }
6491
- }
6494
+ //@ts-check
6495
+ /** @typedef { import('estree').Node} Node */
6496
+ /** @typedef {Node | {
6497
+ * type: 'PropertyDefinition';
6498
+ * computed: boolean;
6499
+ * value: Node
6500
+ * }} NodeWithPropertyDefinition */
6492
6501
 
6493
- const NO_SEMICOLON = { isNoStatement: true };
6494
- // This assumes there are only white-space and comments between start and the string we are looking for
6495
- function findFirstOccurrenceOutsideComment(code, searchString, start = 0) {
6496
- let searchPos, charCodeAfterSlash;
6497
- searchPos = code.indexOf(searchString, start);
6498
- while (true) {
6499
- start = code.indexOf('/', start);
6500
- if (start === -1 || start >= searchPos)
6501
- return searchPos;
6502
- charCodeAfterSlash = code.charCodeAt(++start);
6503
- ++start;
6504
- // With our assumption, '/' always starts a comment. Determine comment type:
6505
- start =
6506
- charCodeAfterSlash === 47 /*"/"*/
6507
- ? code.indexOf('\n', start) + 1
6508
- : code.indexOf('*/', start) + 2;
6509
- if (start > searchPos) {
6510
- searchPos = code.indexOf(searchString, start);
6511
- }
6512
- }
6513
- }
6514
- const NON_WHITESPACE = /\S/g;
6515
- function findNonWhiteSpace(code, index) {
6516
- NON_WHITESPACE.lastIndex = index;
6517
- const result = NON_WHITESPACE.exec(code);
6518
- return result.index;
6519
- }
6520
- // This assumes "code" only contains white-space and comments
6521
- // Returns position of line-comment if applicable
6522
- function findFirstLineBreakOutsideComment(code) {
6523
- let lineBreakPos, charCodeAfterSlash, start = 0;
6524
- lineBreakPos = code.indexOf('\n', start);
6525
- while (true) {
6526
- start = code.indexOf('/', start);
6527
- if (start === -1 || start > lineBreakPos)
6528
- return [lineBreakPos, lineBreakPos + 1];
6529
- // With our assumption, '/' always starts a comment. Determine comment type:
6530
- charCodeAfterSlash = code.charCodeAt(start + 1);
6531
- if (charCodeAfterSlash === 47 /*"/"*/)
6532
- return [start, lineBreakPos + 1];
6533
- start = code.indexOf('*/', start + 3) + 2;
6534
- if (start > lineBreakPos) {
6535
- lineBreakPos = code.indexOf('\n', start);
6536
- }
6537
- }
6502
+ /**
6503
+ *
6504
+ * @param {NodeWithPropertyDefinition} node
6505
+ * @param {NodeWithPropertyDefinition} parent
6506
+ * @returns boolean
6507
+ */
6508
+ function is_reference (node, parent) {
6509
+ if (node.type === 'MemberExpression') {
6510
+ return !node.computed && is_reference(node.object, node);
6511
+ }
6512
+
6513
+ if (node.type === 'Identifier') {
6514
+ if (!parent) return true;
6515
+
6516
+ switch (parent.type) {
6517
+ // disregard `bar` in `foo.bar`
6518
+ case 'MemberExpression': return parent.computed || node === parent.object;
6519
+
6520
+ // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
6521
+ case 'MethodDefinition': return parent.computed;
6522
+
6523
+ // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
6524
+ case 'PropertyDefinition': return parent.computed || node === parent.value;
6525
+
6526
+ // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
6527
+ case 'Property': return parent.computed || node === parent.value;
6528
+
6529
+ // disregard the `bar` in `export { foo as bar }` or
6530
+ // the foo in `import { foo as bar }`
6531
+ case 'ExportSpecifier':
6532
+ case 'ImportSpecifier': return node === parent.local;
6533
+
6534
+ // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
6535
+ case 'LabeledStatement':
6536
+ case 'BreakStatement':
6537
+ case 'ContinueStatement': return false;
6538
+ default: return true;
6539
+ }
6540
+ }
6541
+
6542
+ return false;
6538
6543
  }
6539
- function renderStatementList(statements, code, start, end, options) {
6540
- let currentNode, currentNodeStart, currentNodeNeedsBoundaries, nextNodeStart;
6541
- let nextNode = statements[0];
6542
- let nextNodeNeedsBoundaries = !nextNode.included || nextNode.needsBoundaries;
6543
- if (nextNodeNeedsBoundaries) {
6544
- nextNodeStart =
6545
- start + findFirstLineBreakOutsideComment(code.original.slice(start, nextNode.start))[1];
6546
- }
6547
- for (let nextIndex = 1; nextIndex <= statements.length; nextIndex++) {
6548
- currentNode = nextNode;
6549
- currentNodeStart = nextNodeStart;
6550
- currentNodeNeedsBoundaries = nextNodeNeedsBoundaries;
6551
- nextNode = statements[nextIndex];
6552
- nextNodeNeedsBoundaries =
6553
- nextNode === undefined ? false : !nextNode.included || nextNode.needsBoundaries;
6554
- if (currentNodeNeedsBoundaries || nextNodeNeedsBoundaries) {
6555
- nextNodeStart =
6556
- currentNode.end +
6557
- findFirstLineBreakOutsideComment(code.original.slice(currentNode.end, nextNode === undefined ? end : nextNode.start))[1];
6558
- if (currentNode.included) {
6559
- currentNodeNeedsBoundaries
6560
- ? currentNode.render(code, options, {
6561
- end: nextNodeStart,
6562
- start: currentNodeStart
6563
- })
6564
- : currentNode.render(code, options);
6565
- }
6566
- else {
6567
- treeshakeNode(currentNode, code, currentNodeStart, nextNodeStart);
6568
- }
6569
- }
6570
- else {
6571
- currentNode.render(code, options);
6572
- }
6544
+
6545
+ /* eslint sort-keys: "off" */
6546
+ const ValueProperties = Symbol('Value Properties');
6547
+ const PURE = {
6548
+ hasEffectsWhenCalled() {
6549
+ return false;
6573
6550
  }
6574
- }
6575
- // This assumes that the first character is not part of the first node
6576
- function getCommaSeparatedNodesWithBoundaries(nodes, code, start, end) {
6577
- const splitUpNodes = [];
6578
- let node, nextNode, nextNodeStart, contentEnd, char;
6579
- let separator = start - 1;
6580
- for (let nextIndex = 0; nextIndex < nodes.length; nextIndex++) {
6581
- nextNode = nodes[nextIndex];
6582
- if (node !== undefined) {
6583
- separator =
6584
- node.end +
6585
- findFirstOccurrenceOutsideComment(code.original.slice(node.end, nextNode.start), ',');
6586
- }
6587
- nextNodeStart = contentEnd =
6588
- separator +
6589
- 1 +
6590
- findFirstLineBreakOutsideComment(code.original.slice(separator + 1, nextNode.start))[1];
6591
- while (((char = code.original.charCodeAt(nextNodeStart)),
6592
- char === 32 /*" "*/ || char === 9 /*"\t"*/ || char === 10 /*"\n"*/ || char === 13) /*"\r"*/)
6593
- nextNodeStart++;
6594
- if (node !== undefined) {
6595
- splitUpNodes.push({
6596
- contentEnd,
6597
- end: nextNodeStart,
6598
- node,
6599
- separator,
6600
- start
6601
- });
6602
- }
6603
- node = nextNode;
6604
- start = nextNodeStart;
6551
+ };
6552
+ const IMPURE = {
6553
+ hasEffectsWhenCalled() {
6554
+ return true;
6605
6555
  }
6606
- splitUpNodes.push({
6607
- contentEnd: end,
6608
- end,
6609
- node: node,
6610
- separator: null,
6611
- start
6612
- });
6613
- return splitUpNodes;
6614
- }
6615
- // This assumes there are only white-space and comments between start and end
6616
- function removeLineBreaks(code, start, end) {
6617
- while (true) {
6618
- const [removeStart, removeEnd] = findFirstLineBreakOutsideComment(code.original.slice(start, end));
6619
- if (removeStart === -1) {
6620
- break;
6556
+ };
6557
+ // We use shortened variables to reduce file size here
6558
+ /* OBJECT */
6559
+ const O = {
6560
+ __proto__: null,
6561
+ [ValueProperties]: IMPURE
6562
+ };
6563
+ /* PURE FUNCTION */
6564
+ const PF = {
6565
+ __proto__: null,
6566
+ [ValueProperties]: PURE
6567
+ };
6568
+ /* FUNCTION THAT MUTATES FIRST ARG WITHOUT TRIGGERING ACCESSORS */
6569
+ const MUTATES_ARG_WITHOUT_ACCESSOR = {
6570
+ __proto__: null,
6571
+ [ValueProperties]: {
6572
+ hasEffectsWhenCalled(callOptions, context) {
6573
+ return (!callOptions.args.length ||
6574
+ callOptions.args[0].hasEffectsWhenAssignedAtPath(UNKNOWN_NON_ACCESSOR_PATH, context));
6621
6575
  }
6622
- code.remove(start + removeStart, (start += removeEnd));
6623
6576
  }
6624
- }
6625
-
6626
- class BlockScope extends ChildScope {
6627
- addDeclaration(identifier, context, init, isHoisted) {
6628
- if (isHoisted) {
6629
- const variable = this.parent.addDeclaration(identifier, context, init, isHoisted);
6630
- // Necessary to make sure the init is deoptimized for conditional declarations.
6631
- // We cannot call deoptimizePath here.
6632
- variable.markInitializersForDeoptimization();
6633
- return variable;
6634
- }
6635
- else {
6636
- return super.addDeclaration(identifier, context, init, false);
6637
- }
6638
- }
6639
- }
6640
-
6641
- class ExpressionStatement extends NodeBase {
6642
- initialise() {
6643
- if (this.directive &&
6644
- this.directive !== 'use strict' &&
6645
- this.parent.type === Program$1) {
6646
- this.context.warn(
6647
- // This is necessary, because either way (deleting or not) can lead to errors.
6648
- {
6649
- code: 'MODULE_LEVEL_DIRECTIVE',
6650
- message: `Module level directives cause errors when bundled, '${this.directive}' was ignored.`
6651
- }, this.start);
6652
- }
6653
- }
6654
- render(code, options) {
6655
- super.render(code, options);
6656
- if (this.included)
6657
- this.insertSemicolon(code);
6658
- }
6659
- shouldBeIncluded(context) {
6660
- if (this.directive && this.directive !== 'use strict')
6661
- return this.parent.type !== Program$1;
6662
- return super.shouldBeIncluded(context);
6663
- }
6664
- }
6665
-
6666
- class BlockStatement extends NodeBase {
6667
- constructor() {
6668
- super(...arguments);
6669
- this.directlyIncluded = false;
6670
- }
6671
- addImplicitReturnExpressionToScope() {
6672
- const lastStatement = this.body[this.body.length - 1];
6673
- if (!lastStatement || lastStatement.type !== ReturnStatement$1) {
6674
- this.scope.addReturnExpression(UNKNOWN_EXPRESSION);
6675
- }
6676
- }
6677
- createScope(parentScope) {
6678
- this.scope = this.parent.preventChildBlockScope
6679
- ? parentScope
6680
- : new BlockScope(parentScope);
6681
- }
6682
- hasEffects(context) {
6683
- if (this.deoptimizeBody)
6684
- return true;
6685
- for (const node of this.body) {
6686
- if (context.brokenFlow)
6687
- break;
6688
- if (node.hasEffects(context))
6689
- return true;
6690
- }
6691
- return false;
6692
- }
6693
- include(context, includeChildrenRecursively) {
6694
- if (!(this.deoptimizeBody && this.directlyIncluded)) {
6695
- this.included = true;
6696
- this.directlyIncluded = true;
6697
- if (this.deoptimizeBody)
6698
- includeChildrenRecursively = true;
6699
- for (const node of this.body) {
6700
- if (includeChildrenRecursively || node.shouldBeIncluded(context))
6701
- node.include(context, includeChildrenRecursively);
6702
- }
6703
- }
6704
- }
6705
- initialise() {
6706
- const firstBodyStatement = this.body[0];
6707
- this.deoptimizeBody =
6708
- firstBodyStatement instanceof ExpressionStatement &&
6709
- firstBodyStatement.directive === 'use asm';
6710
- }
6711
- render(code, options) {
6712
- if (this.body.length) {
6713
- renderStatementList(this.body, code, this.start + 1, this.end - 1, options);
6714
- }
6715
- else {
6716
- super.render(code, options);
6717
- }
6718
- }
6719
- }
6720
-
6721
- //@ts-check
6722
- /** @typedef { import('estree').Node} Node */
6723
- /** @typedef {Node | {
6724
- * type: 'PropertyDefinition';
6725
- * computed: boolean;
6726
- * value: Node
6727
- * }} NodeWithPropertyDefinition */
6728
-
6729
- /**
6730
- *
6731
- * @param {NodeWithPropertyDefinition} node
6732
- * @param {NodeWithPropertyDefinition} parent
6733
- * @returns boolean
6734
- */
6735
- function is_reference (node, parent) {
6736
- if (node.type === 'MemberExpression') {
6737
- return !node.computed && is_reference(node.object, node);
6738
- }
6739
-
6740
- if (node.type === 'Identifier') {
6741
- if (!parent) return true;
6742
-
6743
- switch (parent.type) {
6744
- // disregard `bar` in `foo.bar`
6745
- case 'MemberExpression': return parent.computed || node === parent.object;
6746
-
6747
- // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
6748
- case 'MethodDefinition': return parent.computed;
6749
-
6750
- // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
6751
- case 'PropertyDefinition': return parent.computed || node === parent.value;
6752
-
6753
- // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
6754
- case 'Property': return parent.computed || node === parent.value;
6755
-
6756
- // disregard the `bar` in `export { foo as bar }` or
6757
- // the foo in `import { foo as bar }`
6758
- case 'ExportSpecifier':
6759
- case 'ImportSpecifier': return node === parent.local;
6760
-
6761
- // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
6762
- case 'LabeledStatement':
6763
- case 'BreakStatement':
6764
- case 'ContinueStatement': return false;
6765
- default: return true;
6766
- }
6767
- }
6768
-
6769
- return false;
6770
- }
6771
-
6772
- /* eslint sort-keys: "off" */
6773
- const ValueProperties = Symbol('Value Properties');
6774
- const PURE = { pure: true };
6775
- const IMPURE = { pure: false };
6776
- // We use shortened variables to reduce file size here
6777
- /* OBJECT */
6778
- const O = {
6779
- __proto__: null,
6780
- [ValueProperties]: IMPURE
6781
- };
6782
- /* PURE FUNCTION */
6783
- const PF = {
6784
- __proto__: null,
6785
- [ValueProperties]: PURE
6786
6577
  };
6787
6578
  /* CONSTRUCTOR */
6788
6579
  const C = {
@@ -6922,6 +6713,11 @@ const knownGlobals = {
6922
6713
  __proto__: null,
6923
6714
  [ValueProperties]: PURE,
6924
6715
  create: PF,
6716
+ // Technically those can throw in certain situations, but we ignore this as
6717
+ // code that relies on this will hopefully wrap this in a try-catch, which
6718
+ // deoptimizes everything anyway
6719
+ defineProperty: MUTATES_ARG_WITHOUT_ACCESSOR,
6720
+ defineProperties: MUTATES_ARG_WITHOUT_ACCESSOR,
6925
6721
  getOwnPropertyDescriptor: PF,
6926
6722
  getOwnPropertyNames: PF,
6927
6723
  getOwnPropertySymbols: PF,
@@ -7605,27 +7401,24 @@ function getGlobalAtPath(path) {
7605
7401
  }
7606
7402
  return currentGlobal[ValueProperties];
7607
7403
  }
7608
- function isPureGlobal(path) {
7609
- const globalAtPath = getGlobalAtPath(path);
7610
- return globalAtPath !== null && globalAtPath.pure;
7611
- }
7612
- function isGlobalMember(path) {
7613
- if (path.length === 1) {
7614
- return path[0] === 'undefined' || getGlobalAtPath(path) !== null;
7615
- }
7616
- return getGlobalAtPath(path.slice(0, -1)) !== null;
7617
- }
7618
7404
 
7619
7405
  class GlobalVariable extends Variable {
7620
7406
  constructor() {
7621
7407
  super(...arguments);
7408
+ // Ensure we use live-bindings for globals as we do not know if they have
7409
+ // been reassigned
7622
7410
  this.isReassigned = true;
7623
7411
  }
7624
7412
  hasEffectsWhenAccessedAtPath(path) {
7625
- return !isGlobalMember([this.name, ...path]);
7413
+ if (path.length === 0) {
7414
+ // Technically, "undefined" is a global variable of sorts
7415
+ return this.name !== 'undefined' && getGlobalAtPath([this.name]) === null;
7416
+ }
7417
+ return getGlobalAtPath([this.name, ...path].slice(0, -1)) === null;
7626
7418
  }
7627
- hasEffectsWhenCalledAtPath(path) {
7628
- return !isPureGlobal([this.name, ...path]);
7419
+ hasEffectsWhenCalledAtPath(path, callOptions, context) {
7420
+ const globalAtPath = getGlobalAtPath([this.name, ...path]);
7421
+ return globalAtPath === null || globalAtPath.hasEffectsWhenCalled(callOptions, context);
7629
7422
  }
7630
7423
  }
7631
7424
 
@@ -7761,57 +7554,309 @@ class Identifier extends NodeBase {
7761
7554
  // var use before declaration was encountered.
7762
7555
  return (this.isTDZAccess = true);
7763
7556
  }
7764
- return (this.isTDZAccess = false);
7557
+ return (this.isTDZAccess = false);
7558
+ }
7559
+ markDeclarationReached() {
7560
+ this.variable.initReached = true;
7561
+ }
7562
+ render(code, { snippets: { getPropertyAccess } }, { renderedParentType, isCalleeOfRenderedParent, isShorthandProperty } = BLANK) {
7563
+ if (this.variable) {
7564
+ const name = this.variable.getName(getPropertyAccess);
7565
+ if (name !== this.name) {
7566
+ code.overwrite(this.start, this.end, name, {
7567
+ contentOnly: true,
7568
+ storeName: true
7569
+ });
7570
+ if (isShorthandProperty) {
7571
+ code.prependRight(this.start, `${this.name}: `);
7572
+ }
7573
+ }
7574
+ // In strict mode, any variable named "eval" must be the actual "eval" function
7575
+ if (name === 'eval' &&
7576
+ renderedParentType === CallExpression$1 &&
7577
+ isCalleeOfRenderedParent) {
7578
+ code.appendRight(this.start, '0, ');
7579
+ }
7580
+ }
7581
+ }
7582
+ applyDeoptimizations() {
7583
+ this.deoptimized = true;
7584
+ if (this.variable !== null && this.variable instanceof LocalVariable) {
7585
+ this.variable.consolidateInitializers();
7586
+ this.context.requestTreeshakingPass();
7587
+ }
7588
+ }
7589
+ disallowImportReassignment() {
7590
+ return this.context.error({
7591
+ code: 'ILLEGAL_REASSIGNMENT',
7592
+ message: `Illegal reassignment to import '${this.name}'`
7593
+ }, this.start);
7594
+ }
7595
+ getVariableRespectingTDZ() {
7596
+ if (this.isPossibleTDZ()) {
7597
+ return UNKNOWN_EXPRESSION;
7598
+ }
7599
+ return this.variable;
7600
+ }
7601
+ }
7602
+ function closestParentFunctionOrProgram(node) {
7603
+ while (node && !/^Program|Function/.test(node.type)) {
7604
+ node = node.parent;
7605
+ }
7606
+ // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program
7607
+ return node;
7608
+ }
7609
+
7610
+ function treeshakeNode(node, code, start, end) {
7611
+ code.remove(start, end);
7612
+ if (node.annotations) {
7613
+ for (const annotation of node.annotations) {
7614
+ if (annotation.start < start) {
7615
+ code.remove(annotation.start, annotation.end);
7616
+ }
7617
+ else {
7618
+ return;
7619
+ }
7620
+ }
7621
+ }
7622
+ }
7623
+ function removeAnnotations(node, code) {
7624
+ if (!node.annotations && node.parent.type === ExpressionStatement$1) {
7625
+ node = node.parent;
7626
+ }
7627
+ if (node.annotations) {
7628
+ for (const annotation of node.annotations) {
7629
+ code.remove(annotation.start, annotation.end);
7630
+ }
7631
+ }
7632
+ }
7633
+
7634
+ const NO_SEMICOLON = { isNoStatement: true };
7635
+ // This assumes there are only white-space and comments between start and the string we are looking for
7636
+ function findFirstOccurrenceOutsideComment(code, searchString, start = 0) {
7637
+ let searchPos, charCodeAfterSlash;
7638
+ searchPos = code.indexOf(searchString, start);
7639
+ while (true) {
7640
+ start = code.indexOf('/', start);
7641
+ if (start === -1 || start >= searchPos)
7642
+ return searchPos;
7643
+ charCodeAfterSlash = code.charCodeAt(++start);
7644
+ ++start;
7645
+ // With our assumption, '/' always starts a comment. Determine comment type:
7646
+ start =
7647
+ charCodeAfterSlash === 47 /*"/"*/
7648
+ ? code.indexOf('\n', start) + 1
7649
+ : code.indexOf('*/', start) + 2;
7650
+ if (start > searchPos) {
7651
+ searchPos = code.indexOf(searchString, start);
7652
+ }
7653
+ }
7654
+ }
7655
+ const NON_WHITESPACE = /\S/g;
7656
+ function findNonWhiteSpace(code, index) {
7657
+ NON_WHITESPACE.lastIndex = index;
7658
+ const result = NON_WHITESPACE.exec(code);
7659
+ return result.index;
7660
+ }
7661
+ // This assumes "code" only contains white-space and comments
7662
+ // Returns position of line-comment if applicable
7663
+ function findFirstLineBreakOutsideComment(code) {
7664
+ let lineBreakPos, charCodeAfterSlash, start = 0;
7665
+ lineBreakPos = code.indexOf('\n', start);
7666
+ while (true) {
7667
+ start = code.indexOf('/', start);
7668
+ if (start === -1 || start > lineBreakPos)
7669
+ return [lineBreakPos, lineBreakPos + 1];
7670
+ // With our assumption, '/' always starts a comment. Determine comment type:
7671
+ charCodeAfterSlash = code.charCodeAt(start + 1);
7672
+ if (charCodeAfterSlash === 47 /*"/"*/)
7673
+ return [start, lineBreakPos + 1];
7674
+ start = code.indexOf('*/', start + 3) + 2;
7675
+ if (start > lineBreakPos) {
7676
+ lineBreakPos = code.indexOf('\n', start);
7677
+ }
7678
+ }
7679
+ }
7680
+ function renderStatementList(statements, code, start, end, options) {
7681
+ let currentNode, currentNodeStart, currentNodeNeedsBoundaries, nextNodeStart;
7682
+ let nextNode = statements[0];
7683
+ let nextNodeNeedsBoundaries = !nextNode.included || nextNode.needsBoundaries;
7684
+ if (nextNodeNeedsBoundaries) {
7685
+ nextNodeStart =
7686
+ start + findFirstLineBreakOutsideComment(code.original.slice(start, nextNode.start))[1];
7687
+ }
7688
+ for (let nextIndex = 1; nextIndex <= statements.length; nextIndex++) {
7689
+ currentNode = nextNode;
7690
+ currentNodeStart = nextNodeStart;
7691
+ currentNodeNeedsBoundaries = nextNodeNeedsBoundaries;
7692
+ nextNode = statements[nextIndex];
7693
+ nextNodeNeedsBoundaries =
7694
+ nextNode === undefined ? false : !nextNode.included || nextNode.needsBoundaries;
7695
+ if (currentNodeNeedsBoundaries || nextNodeNeedsBoundaries) {
7696
+ nextNodeStart =
7697
+ currentNode.end +
7698
+ findFirstLineBreakOutsideComment(code.original.slice(currentNode.end, nextNode === undefined ? end : nextNode.start))[1];
7699
+ if (currentNode.included) {
7700
+ currentNodeNeedsBoundaries
7701
+ ? currentNode.render(code, options, {
7702
+ end: nextNodeStart,
7703
+ start: currentNodeStart
7704
+ })
7705
+ : currentNode.render(code, options);
7706
+ }
7707
+ else {
7708
+ treeshakeNode(currentNode, code, currentNodeStart, nextNodeStart);
7709
+ }
7710
+ }
7711
+ else {
7712
+ currentNode.render(code, options);
7713
+ }
7714
+ }
7715
+ }
7716
+ // This assumes that the first character is not part of the first node
7717
+ function getCommaSeparatedNodesWithBoundaries(nodes, code, start, end) {
7718
+ const splitUpNodes = [];
7719
+ let node, nextNode, nextNodeStart, contentEnd, char;
7720
+ let separator = start - 1;
7721
+ for (let nextIndex = 0; nextIndex < nodes.length; nextIndex++) {
7722
+ nextNode = nodes[nextIndex];
7723
+ if (node !== undefined) {
7724
+ separator =
7725
+ node.end +
7726
+ findFirstOccurrenceOutsideComment(code.original.slice(node.end, nextNode.start), ',');
7727
+ }
7728
+ nextNodeStart = contentEnd =
7729
+ separator +
7730
+ 1 +
7731
+ findFirstLineBreakOutsideComment(code.original.slice(separator + 1, nextNode.start))[1];
7732
+ while (((char = code.original.charCodeAt(nextNodeStart)),
7733
+ char === 32 /*" "*/ || char === 9 /*"\t"*/ || char === 10 /*"\n"*/ || char === 13) /*"\r"*/)
7734
+ nextNodeStart++;
7735
+ if (node !== undefined) {
7736
+ splitUpNodes.push({
7737
+ contentEnd,
7738
+ end: nextNodeStart,
7739
+ node,
7740
+ separator,
7741
+ start
7742
+ });
7743
+ }
7744
+ node = nextNode;
7745
+ start = nextNodeStart;
7746
+ }
7747
+ splitUpNodes.push({
7748
+ contentEnd: end,
7749
+ end,
7750
+ node: node,
7751
+ separator: null,
7752
+ start
7753
+ });
7754
+ return splitUpNodes;
7755
+ }
7756
+ // This assumes there are only white-space and comments between start and end
7757
+ function removeLineBreaks(code, start, end) {
7758
+ while (true) {
7759
+ const [removeStart, removeEnd] = findFirstLineBreakOutsideComment(code.original.slice(start, end));
7760
+ if (removeStart === -1) {
7761
+ break;
7762
+ }
7763
+ code.remove(start + removeStart, (start += removeEnd));
7764
+ }
7765
+ }
7766
+
7767
+ class BlockScope extends ChildScope {
7768
+ addDeclaration(identifier, context, init, isHoisted) {
7769
+ if (isHoisted) {
7770
+ const variable = this.parent.addDeclaration(identifier, context, init, isHoisted);
7771
+ // Necessary to make sure the init is deoptimized for conditional declarations.
7772
+ // We cannot call deoptimizePath here.
7773
+ variable.markInitializersForDeoptimization();
7774
+ return variable;
7775
+ }
7776
+ else {
7777
+ return super.addDeclaration(identifier, context, init, false);
7778
+ }
7779
+ }
7780
+ }
7781
+
7782
+ class ExpressionStatement extends NodeBase {
7783
+ initialise() {
7784
+ if (this.directive &&
7785
+ this.directive !== 'use strict' &&
7786
+ this.parent.type === Program$1) {
7787
+ this.context.warn(
7788
+ // This is necessary, because either way (deleting or not) can lead to errors.
7789
+ {
7790
+ code: 'MODULE_LEVEL_DIRECTIVE',
7791
+ message: `Module level directives cause errors when bundled, '${this.directive}' was ignored.`
7792
+ }, this.start);
7793
+ }
7794
+ }
7795
+ render(code, options) {
7796
+ super.render(code, options);
7797
+ if (this.included)
7798
+ this.insertSemicolon(code);
7799
+ }
7800
+ shouldBeIncluded(context) {
7801
+ if (this.directive && this.directive !== 'use strict')
7802
+ return this.parent.type !== Program$1;
7803
+ return super.shouldBeIncluded(context);
7804
+ }
7805
+ }
7806
+
7807
+ class BlockStatement extends NodeBase {
7808
+ constructor() {
7809
+ super(...arguments);
7810
+ this.directlyIncluded = false;
7811
+ }
7812
+ addImplicitReturnExpressionToScope() {
7813
+ const lastStatement = this.body[this.body.length - 1];
7814
+ if (!lastStatement || lastStatement.type !== ReturnStatement$1) {
7815
+ this.scope.addReturnExpression(UNKNOWN_EXPRESSION);
7816
+ }
7765
7817
  }
7766
- markDeclarationReached() {
7767
- this.variable.initReached = true;
7818
+ createScope(parentScope) {
7819
+ this.scope = this.parent.preventChildBlockScope
7820
+ ? parentScope
7821
+ : new BlockScope(parentScope);
7768
7822
  }
7769
- render(code, { snippets: { getPropertyAccess } }, { renderedParentType, isCalleeOfRenderedParent, isShorthandProperty } = BLANK) {
7770
- if (this.variable) {
7771
- const name = this.variable.getName(getPropertyAccess);
7772
- if (name !== this.name) {
7773
- code.overwrite(this.start, this.end, name, {
7774
- contentOnly: true,
7775
- storeName: true
7776
- });
7777
- if (isShorthandProperty) {
7778
- code.prependRight(this.start, `${this.name}: `);
7779
- }
7780
- }
7781
- // In strict mode, any variable named "eval" must be the actual "eval" function
7782
- if (name === 'eval' &&
7783
- renderedParentType === CallExpression$1 &&
7784
- isCalleeOfRenderedParent) {
7785
- code.appendRight(this.start, '0, ');
7786
- }
7823
+ hasEffects(context) {
7824
+ if (this.deoptimizeBody)
7825
+ return true;
7826
+ for (const node of this.body) {
7827
+ if (context.brokenFlow)
7828
+ break;
7829
+ if (node.hasEffects(context))
7830
+ return true;
7787
7831
  }
7832
+ return false;
7788
7833
  }
7789
- applyDeoptimizations() {
7790
- this.deoptimized = true;
7791
- if (this.variable !== null && this.variable instanceof LocalVariable) {
7792
- this.variable.consolidateInitializers();
7793
- this.context.requestTreeshakingPass();
7834
+ include(context, includeChildrenRecursively) {
7835
+ if (!(this.deoptimizeBody && this.directlyIncluded)) {
7836
+ this.included = true;
7837
+ this.directlyIncluded = true;
7838
+ if (this.deoptimizeBody)
7839
+ includeChildrenRecursively = true;
7840
+ for (const node of this.body) {
7841
+ if (includeChildrenRecursively || node.shouldBeIncluded(context))
7842
+ node.include(context, includeChildrenRecursively);
7843
+ }
7794
7844
  }
7795
7845
  }
7796
- disallowImportReassignment() {
7797
- return this.context.error({
7798
- code: 'ILLEGAL_REASSIGNMENT',
7799
- message: `Illegal reassignment to import '${this.name}'`
7800
- }, this.start);
7846
+ initialise() {
7847
+ const firstBodyStatement = this.body[0];
7848
+ this.deoptimizeBody =
7849
+ firstBodyStatement instanceof ExpressionStatement &&
7850
+ firstBodyStatement.directive === 'use asm';
7801
7851
  }
7802
- getVariableRespectingTDZ() {
7803
- if (this.isPossibleTDZ()) {
7804
- return UNKNOWN_EXPRESSION;
7852
+ render(code, options) {
7853
+ if (this.body.length) {
7854
+ renderStatementList(this.body, code, this.start + 1, this.end - 1, options);
7855
+ }
7856
+ else {
7857
+ super.render(code, options);
7805
7858
  }
7806
- return this.variable;
7807
- }
7808
- }
7809
- function closestParentFunctionOrProgram(node) {
7810
- while (node && !/^Program|Function/.test(node.type)) {
7811
- node = node.parent;
7812
7859
  }
7813
- // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program
7814
- return node;
7815
7860
  }
7816
7861
 
7817
7862
  class RestElement extends NodeBase {
@@ -7845,26 +7890,31 @@ class RestElement extends NodeBase {
7845
7890
  }
7846
7891
  }
7847
7892
 
7848
- class ArrowFunctionExpression extends NodeBase {
7893
+ class FunctionBase extends NodeBase {
7849
7894
  constructor() {
7850
7895
  super(...arguments);
7896
+ this.objectEntity = null;
7851
7897
  this.deoptimizedReturn = false;
7852
7898
  }
7853
- createScope(parentScope) {
7854
- this.scope = new ReturnValueScope(parentScope, this.context);
7855
- }
7856
7899
  deoptimizePath(path) {
7857
- // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
7858
- // which means the return expression needs to be reassigned
7900
+ this.getObjectEntity().deoptimizePath(path);
7859
7901
  if (path.length === 1 && path[0] === UnknownKey) {
7902
+ // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
7903
+ // which means the return expression needs to be reassigned
7860
7904
  this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
7861
7905
  }
7862
7906
  }
7863
- // Arrow functions do not mutate their context
7864
- deoptimizeThisOnEventAtPath() { }
7865
- getReturnExpressionWhenCalledAtPath(path) {
7866
- if (path.length !== 0) {
7867
- return UNKNOWN_EXPRESSION;
7907
+ deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
7908
+ if (path.length > 0) {
7909
+ this.getObjectEntity().deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
7910
+ }
7911
+ }
7912
+ getLiteralValueAtPath(path, recursionTracker, origin) {
7913
+ return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);
7914
+ }
7915
+ getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin) {
7916
+ if (path.length > 0) {
7917
+ return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, callOptions, recursionTracker, origin);
7868
7918
  }
7869
7919
  if (this.async) {
7870
7920
  if (!this.deoptimizedReturn) {
@@ -7876,18 +7926,16 @@ class ArrowFunctionExpression extends NodeBase {
7876
7926
  }
7877
7927
  return this.scope.getReturnExpression();
7878
7928
  }
7879
- hasEffects() {
7880
- return false;
7881
- }
7882
- hasEffectsWhenAccessedAtPath(path) {
7883
- return path.length > 1;
7929
+ hasEffectsWhenAccessedAtPath(path, context) {
7930
+ return this.getObjectEntity().hasEffectsWhenAccessedAtPath(path, context);
7884
7931
  }
7885
- hasEffectsWhenAssignedAtPath(path) {
7886
- return path.length > 1;
7932
+ hasEffectsWhenAssignedAtPath(path, context) {
7933
+ return this.getObjectEntity().hasEffectsWhenAssignedAtPath(path, context);
7887
7934
  }
7888
- hasEffectsWhenCalledAtPath(path, _callOptions, context) {
7889
- if (path.length > 0)
7890
- return true;
7935
+ hasEffectsWhenCalledAtPath(path, callOptions, context) {
7936
+ if (path.length > 0) {
7937
+ return this.getObjectEntity().hasEffectsWhenCalledAtPath(path, callOptions, context);
7938
+ }
7891
7939
  if (this.async) {
7892
7940
  const { propertyReadSideEffects } = this.context.options
7893
7941
  .treeshake;
@@ -7903,26 +7951,10 @@ class ArrowFunctionExpression extends NodeBase {
7903
7951
  if (param.hasEffects(context))
7904
7952
  return true;
7905
7953
  }
7906
- const { ignore, brokenFlow } = context;
7907
- context.ignore = {
7908
- breaks: false,
7909
- continues: false,
7910
- labels: new Set(),
7911
- returnYield: true
7912
- };
7913
- if (this.body.hasEffects(context))
7914
- return true;
7915
- context.ignore = ignore;
7916
- context.brokenFlow = brokenFlow;
7917
7954
  return false;
7918
7955
  }
7919
7956
  include(context, includeChildrenRecursively) {
7920
7957
  this.included = true;
7921
- for (const param of this.params) {
7922
- if (!(param instanceof Identifier)) {
7923
- param.include(context, includeChildrenRecursively);
7924
- }
7925
- }
7926
7958
  const { brokenFlow } = context;
7927
7959
  context.brokenFlow = BROKEN_FLOW_NONE;
7928
7960
  this.body.include(context, includeChildrenRecursively);
@@ -7947,7 +7979,50 @@ class ArrowFunctionExpression extends NodeBase {
7947
7979
  super.parseNode(esTreeNode);
7948
7980
  }
7949
7981
  }
7950
- ArrowFunctionExpression.prototype.preventChildBlockScope = true;
7982
+ FunctionBase.prototype.preventChildBlockScope = true;
7983
+
7984
+ class ArrowFunctionExpression extends FunctionBase {
7985
+ constructor() {
7986
+ super(...arguments);
7987
+ this.objectEntity = null;
7988
+ }
7989
+ createScope(parentScope) {
7990
+ this.scope = new ReturnValueScope(parentScope, this.context);
7991
+ }
7992
+ hasEffects() {
7993
+ return false;
7994
+ }
7995
+ hasEffectsWhenCalledAtPath(path, callOptions, context) {
7996
+ if (super.hasEffectsWhenCalledAtPath(path, callOptions, context))
7997
+ return true;
7998
+ const { ignore, brokenFlow } = context;
7999
+ context.ignore = {
8000
+ breaks: false,
8001
+ continues: false,
8002
+ labels: new Set(),
8003
+ returnYield: true
8004
+ };
8005
+ if (this.body.hasEffects(context))
8006
+ return true;
8007
+ context.ignore = ignore;
8008
+ context.brokenFlow = brokenFlow;
8009
+ return false;
8010
+ }
8011
+ include(context, includeChildrenRecursively) {
8012
+ super.include(context, includeChildrenRecursively);
8013
+ for (const param of this.params) {
8014
+ if (!(param instanceof Identifier)) {
8015
+ param.include(context, includeChildrenRecursively);
8016
+ }
8017
+ }
8018
+ }
8019
+ getObjectEntity() {
8020
+ if (this.objectEntity !== null) {
8021
+ return this.objectEntity;
8022
+ }
8023
+ return (this.objectEntity = new ObjectEntity([], OBJECT_PROTOTYPE));
8024
+ }
8025
+ }
7951
8026
 
7952
8027
  function getSystemExportStatement(exportedVariables, { exportNamesByVariable, snippets: { _, getObject, getPropertyAccess } }, modifier = '') {
7953
8028
  if (exportedVariables.length === 1 &&
@@ -8241,85 +8316,26 @@ class FunctionScope extends ReturnValueScope {
8241
8316
  }
8242
8317
  }
8243
8318
 
8244
- class FunctionNode extends NodeBase {
8319
+ class FunctionNode extends FunctionBase {
8245
8320
  constructor() {
8246
8321
  super(...arguments);
8247
- this.deoptimizedReturn = false;
8248
- this.isPrototypeDeoptimized = false;
8322
+ this.objectEntity = null;
8249
8323
  }
8250
8324
  createScope(parentScope) {
8251
8325
  this.scope = new FunctionScope(parentScope, this.context);
8252
8326
  }
8253
- deoptimizePath(path) {
8254
- if (path.length === 1) {
8255
- if (path[0] === 'prototype') {
8256
- this.isPrototypeDeoptimized = true;
8257
- }
8258
- else if (path[0] === UnknownKey) {
8259
- this.isPrototypeDeoptimized = true;
8260
- // A reassignment of UNKNOWN_PATH is considered equivalent to having lost track
8261
- // which means the return expression needs to be reassigned as well
8262
- this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
8263
- }
8264
- }
8265
- }
8266
- // TODO for completeness, we should also track other events here
8267
- deoptimizeThisOnEventAtPath(event, path, thisParameter) {
8268
- if (event === EVENT_CALLED) {
8269
- if (path.length > 0) {
8270
- thisParameter.deoptimizePath(UNKNOWN_PATH);
8271
- }
8272
- else {
8273
- this.scope.thisVariable.addEntityToBeDeoptimized(thisParameter);
8274
- }
8275
- }
8276
- }
8277
- getReturnExpressionWhenCalledAtPath(path) {
8278
- if (path.length !== 0) {
8279
- return UNKNOWN_EXPRESSION;
8280
- }
8281
- if (this.async) {
8282
- if (!this.deoptimizedReturn) {
8283
- this.deoptimizedReturn = true;
8284
- this.scope.getReturnExpression().deoptimizePath(UNKNOWN_PATH);
8285
- this.context.requestTreeshakingPass();
8286
- }
8287
- return UNKNOWN_EXPRESSION;
8327
+ deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker) {
8328
+ super.deoptimizeThisOnEventAtPath(event, path, thisParameter, recursionTracker);
8329
+ if (event === EVENT_CALLED && path.length === 0) {
8330
+ this.scope.thisVariable.addEntityToBeDeoptimized(thisParameter);
8288
8331
  }
8289
- return this.scope.getReturnExpression();
8290
8332
  }
8291
8333
  hasEffects() {
8292
8334
  return this.id !== null && this.id.hasEffects();
8293
8335
  }
8294
- hasEffectsWhenAccessedAtPath(path) {
8295
- if (path.length <= 1)
8296
- return false;
8297
- return path.length > 2 || path[0] !== 'prototype' || this.isPrototypeDeoptimized;
8298
- }
8299
- hasEffectsWhenAssignedAtPath(path) {
8300
- if (path.length <= 1) {
8301
- return false;
8302
- }
8303
- return path.length > 2 || path[0] !== 'prototype' || this.isPrototypeDeoptimized;
8304
- }
8305
8336
  hasEffectsWhenCalledAtPath(path, callOptions, context) {
8306
- if (path.length > 0)
8337
+ if (super.hasEffectsWhenCalledAtPath(path, callOptions, context))
8307
8338
  return true;
8308
- if (this.async) {
8309
- const { propertyReadSideEffects } = this.context.options
8310
- .treeshake;
8311
- const returnExpression = this.scope.getReturnExpression();
8312
- if (returnExpression.hasEffectsWhenCalledAtPath(['then'], { args: NO_ARGS, thisParam: null, withNew: false }, context) ||
8313
- (propertyReadSideEffects &&
8314
- (propertyReadSideEffects === 'always' ||
8315
- returnExpression.hasEffectsWhenAccessedAtPath(['then'], context)))) {
8316
- return true;
8317
- }
8318
- }
8319
- for (const param of this.params) {
8320
- if (param.hasEffects(context))
8321
- return true;
8322
- }
8323
8339
  const thisInit = context.replacedVariableInits.get(this.scope.thisVariable);
8324
8340
  context.replacedVariableInits.set(this.scope.thisVariable, callOptions.withNew
8325
8341
  ? new ObjectEntity(Object.create(null), OBJECT_PROTOTYPE)
@@ -8344,7 +8360,7 @@ class FunctionNode extends NodeBase {
8344
8360
  return false;
8345
8361
  }
8346
8362
  include(context, includeChildrenRecursively) {
8347
- this.included = true;
8363
+ super.include(context, includeChildrenRecursively);
8348
8364
  if (this.id)
8349
8365
  this.id.include();
8350
8366
  const hasArguments = this.scope.argumentsVariable.included;
@@ -8353,27 +8369,25 @@ class FunctionNode extends NodeBase {
8353
8369
  param.include(context, includeChildrenRecursively);
8354
8370
  }
8355
8371
  }
8356
- const { brokenFlow } = context;
8357
- context.brokenFlow = BROKEN_FLOW_NONE;
8358
- this.body.include(context, includeChildrenRecursively);
8359
- context.brokenFlow = brokenFlow;
8360
- }
8361
- includeCallArguments(context, args) {
8362
- this.scope.includeCallArguments(context, args);
8363
8372
  }
8364
8373
  initialise() {
8365
- if (this.id !== null) {
8366
- this.id.declare('function', this);
8367
- }
8368
- this.scope.addParameterVariables(this.params.map(param => param.declare('parameter', UNKNOWN_EXPRESSION)), this.params[this.params.length - 1] instanceof RestElement);
8369
- this.body.addImplicitReturnExpressionToScope();
8374
+ var _a;
8375
+ super.initialise();
8376
+ (_a = this.id) === null || _a === void 0 ? void 0 : _a.declare('function', this);
8370
8377
  }
8371
- parseNode(esTreeNode) {
8372
- this.body = new BlockStatement(esTreeNode.body, this, this.scope.hoistedBodyVarScope);
8373
- super.parseNode(esTreeNode);
8378
+ getObjectEntity() {
8379
+ if (this.objectEntity !== null) {
8380
+ return this.objectEntity;
8381
+ }
8382
+ return (this.objectEntity = new ObjectEntity([
8383
+ {
8384
+ key: 'prototype',
8385
+ kind: 'init',
8386
+ property: new ObjectEntity([], OBJECT_PROTOTYPE)
8387
+ }
8388
+ ], OBJECT_PROTOTYPE));
8374
8389
  }
8375
8390
  }
8376
- FunctionNode.prototype.preventChildBlockScope = true;
8377
8391
 
8378
8392
  class AwaitExpression extends NodeBase {
8379
8393
  constructor() {
@@ -8623,7 +8637,11 @@ class MemberExpression extends NodeBase {
8623
8637
  }
8624
8638
  else if (!this.replacement) {
8625
8639
  if (path.length < MAX_PATH_DEPTH) {
8626
- this.object.deoptimizePath([this.getPropertyKey(), ...path]);
8640
+ const propertyKey = this.getPropertyKey();
8641
+ this.object.deoptimizePath([
8642
+ propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey,
8643
+ ...path
8644
+ ]);
8627
8645
  }
8628
8646
  }
8629
8647
  }
@@ -12303,8 +12321,8 @@ class Module {
12303
12321
  this.importMetas = [];
12304
12322
  this.importedFromNotTreeshaken = false;
12305
12323
  this.importers = [];
12306
- this.imports = new Set();
12307
12324
  this.includedDynamicImporters = [];
12325
+ this.includedImports = new Set();
12308
12326
  this.isExecuted = false;
12309
12327
  this.isUserDefinedEntryPoint = false;
12310
12328
  this.needsExportShim = false;
@@ -12433,7 +12451,7 @@ class Module {
12433
12451
  this.relevantDependencies = new Set();
12434
12452
  const necessaryDependencies = new Set();
12435
12453
  const alwaysCheckedDependencies = new Set();
12436
- const dependencyVariables = new Set(this.imports);
12454
+ const dependencyVariables = new Set(this.includedImports);
12437
12455
  if (this.info.isEntry ||
12438
12456
  this.includedDynamicImporters.length > 0 ||
12439
12457
  this.namespace.included ||
@@ -13011,13 +13029,13 @@ class Module {
13011
13029
  if (module instanceof ExternalModule) {
13012
13030
  const [externalVariable] = module.getVariableForExportName('*');
13013
13031
  externalVariable.include();
13014
- this.imports.add(externalVariable);
13032
+ this.includedImports.add(externalVariable);
13015
13033
  externalNamespaces.add(externalVariable);
13016
13034
  }
13017
13035
  else if (module.info.syntheticNamedExports) {
13018
13036
  const syntheticNamespace = module.getSyntheticNamespace();
13019
13037
  syntheticNamespace.include();
13020
- this.imports.add(syntheticNamespace);
13038
+ this.includedImports.add(syntheticNamespace);
13021
13039
  syntheticNamespaces.add(syntheticNamespace);
13022
13040
  }
13023
13041
  }
@@ -13054,7 +13072,7 @@ class Module {
13054
13072
  this.includeVariable(variable);
13055
13073
  const variableModule = variable.module;
13056
13074
  if (variableModule && variableModule !== this) {
13057
- this.imports.add(variable);
13075
+ this.includedImports.add(variable);
13058
13076
  }
13059
13077
  }
13060
13078
  shimMissingExport(name) {
@@ -14386,6 +14404,7 @@ class Chunk {
14386
14404
  this.implicitEntryModules = [];
14387
14405
  this.implicitlyLoadedBefore = new Set();
14388
14406
  this.imports = new Set();
14407
+ this.includedReexportsByModule = new Map();
14389
14408
  this.indentString = undefined;
14390
14409
  // This may only be updated in the constructor
14391
14410
  this.isEmpty = true;
@@ -14557,6 +14576,9 @@ class Chunk {
14557
14576
  this.exports.add(module.namespace);
14558
14577
  }
14559
14578
  }
14579
+ if (!this.outputOptions.preserveModules) {
14580
+ this.addNecessaryImportsForFacades();
14581
+ }
14560
14582
  return facades;
14561
14583
  }
14562
14584
  generateId(addons, options, existingNames, includeHash) {
@@ -14899,6 +14921,15 @@ class Chunk {
14899
14921
  }
14900
14922
  }
14901
14923
  }
14924
+ addNecessaryImportsForFacades() {
14925
+ for (const [module, variables] of this.includedReexportsByModule) {
14926
+ if (this.includedNamespaces.has(module)) {
14927
+ for (const variable of variables) {
14928
+ this.imports.add(variable);
14929
+ }
14930
+ }
14931
+ }
14932
+ }
14902
14933
  assignFacadeName({ fileName, name }, facadedModule) {
14903
14934
  if (fileName) {
14904
14935
  this.fileName = fileName;
@@ -14946,6 +14977,7 @@ class Chunk {
14946
14977
  return hash.digest('hex').substr(0, 8);
14947
14978
  }
14948
14979
  ensureReexportsAreAvailableForModule(module) {
14980
+ const includedReexports = [];
14949
14981
  const map = module.getExportNamesByVariable();
14950
14982
  for (const exportedVariable of map.keys()) {
14951
14983
  const isSynthetic = exportedVariable instanceof SyntheticNamedExportVariable;
@@ -14959,6 +14991,7 @@ class Chunk {
14959
14991
  const chunk = this.chunkByModule.get(exportingModule);
14960
14992
  if (chunk && chunk !== this) {
14961
14993
  chunk.exports.add(importedVariable);
14994
+ includedReexports.push(importedVariable);
14962
14995
  if (isSynthetic) {
14963
14996
  this.imports.add(importedVariable);
14964
14997
  }
@@ -14966,6 +14999,9 @@ class Chunk {
14966
14999
  }
14967
15000
  }
14968
15001
  }
15002
+ if (includedReexports.length) {
15003
+ this.includedReexportsByModule.set(module, includedReexports);
15004
+ }
14969
15005
  }
14970
15006
  finaliseDynamicImports(options, snippets) {
14971
15007
  const stripKnownJsExtensions = options.format === 'amd';
@@ -15321,7 +15357,7 @@ class Chunk {
15321
15357
  deconflictChunk(this.orderedModules, this.getDependenciesToBeDeconflicted(format !== 'es' && format !== 'system', format === 'amd' || format === 'umd' || format === 'iife', interop), this.imports, usedNames, format, interop, this.outputOptions.preserveModules, this.outputOptions.externalLiveBindings, this.chunkByModule, syntheticExports, this.exportNamesByVariable, this.accessedGlobalsByScope, this.includedNamespaces);
15322
15358
  }
15323
15359
  setUpChunkImportsAndExportsForModule(module) {
15324
- const moduleImports = new Set(module.imports);
15360
+ const moduleImports = new Set(module.includedImports);
15325
15361
  // when we are not preserving modules, we need to make all namespace variables available for
15326
15362
  // rendering the namespace object
15327
15363
  if (!this.outputOptions.preserveModules) {
@@ -22998,6 +23034,12 @@ function formatAction([pluginName, hookName, args]) {
22998
23034
  }
22999
23035
  return action;
23000
23036
  }
23037
+ // We do not directly listen on process to avoid max listeners warnings for
23038
+ // complicated build processes
23039
+ const beforeExitEvent = 'beforeExit';
23040
+ const beforeExitEmitter = new EventEmitter();
23041
+ beforeExitEmitter.setMaxListeners(0);
23042
+ process$1.on(beforeExitEvent, () => beforeExitEmitter.emit(beforeExitEvent));
23001
23043
  async function catchUnfinishedHookActions(pluginDriver, callback) {
23002
23044
  let handleEmptyEventLoop;
23003
23045
  const emptyEventLoopPromise = new Promise((_, reject) => {
@@ -23006,10 +23048,10 @@ async function catchUnfinishedHookActions(pluginDriver, callback) {
23006
23048
  reject(new Error(`Unexpected early exit. This happens when Promises returned by plugins cannot resolve. Unfinished hook action(s) on exit:\n` +
23007
23049
  [...unfulfilledActions].map(formatAction).join('\n')));
23008
23050
  };
23009
- process$1.once('beforeExit', handleEmptyEventLoop);
23051
+ beforeExitEmitter.once(beforeExitEvent, handleEmptyEventLoop);
23010
23052
  });
23011
23053
  const result = await Promise.race([callback(), emptyEventLoopPromise]);
23012
- process$1.off('beforeExit', handleEmptyEventLoop);
23054
+ beforeExitEmitter.off(beforeExitEvent, handleEmptyEventLoop);
23013
23055
  return result;
23014
23056
  }
23015
23057