rollup 0.49.0 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/rollup.es.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
- Rollup.js v0.49.0
3
- Sun Aug 27 2017 17:42:39 GMT-0400 (EDT) - commit bed229c6691dbcf8113912461de6fc0625427220
2
+ Rollup.js v0.50.0
3
+ Sat Sep 16 2017 09:48:09 GMT-0400 (EDT) - commit b949eb08169115ff66648838cbc4833379bf9440
4
4
 
5
5
 
6
6
  https://github.com/rollup/rollup
@@ -1938,15 +1938,15 @@ var types = {
1938
1938
  eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
1939
1939
  assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
1940
1940
  incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
1941
- prefix: new TokenType("prefix", {beforeExpr: true, prefix: true, startsExpr: true}),
1941
+ prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}),
1942
1942
  logicalOR: binop("||", 1),
1943
1943
  logicalAND: binop("&&", 2),
1944
1944
  bitwiseOR: binop("|", 3),
1945
1945
  bitwiseXOR: binop("^", 4),
1946
1946
  bitwiseAND: binop("&", 5),
1947
- equality: binop("==/!=", 6),
1948
- relational: binop("</>", 7),
1949
- bitShift: binop("<</>>", 8),
1947
+ equality: binop("==/!=/===/!==", 6),
1948
+ relational: binop("</>/<=/>=", 7),
1949
+ bitShift: binop("<</>>/>>>", 8),
1950
1950
  plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
1951
1951
  modulo: binop("%", 10),
1952
1952
  star: binop("*", 10),
@@ -2296,7 +2296,7 @@ var pp = Parser.prototype;
2296
2296
 
2297
2297
  // ## Parser utilities
2298
2298
 
2299
- var literal = /^(?:'((?:[^']|\.)*)'|"((?:[^"]|\.)*)"|;)/;
2299
+ var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)"|;)/;
2300
2300
  pp.strictDirective = function(start) {
2301
2301
  var this$1 = this;
2302
2302
 
@@ -4010,7 +4010,7 @@ pp$3.parseTemplate = function(ref) {
4010
4010
 
4011
4011
  pp$3.isAsyncProp = function(prop) {
4012
4012
  return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
4013
- (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL) &&
4013
+ (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword) &&
4014
4014
  !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
4015
4015
  };
4016
4016
 
@@ -4886,7 +4886,7 @@ pp$8.readToken_caret = function() { // '^'
4886
4886
  pp$8.readToken_plus_min = function(code) { // '+-'
4887
4887
  var next = this.input.charCodeAt(this.pos + 1);
4888
4888
  if (next === code) {
4889
- if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 &&
4889
+ if (next == 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) == 62 &&
4890
4890
  (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {
4891
4891
  // A `-->` line comment
4892
4892
  this.skipLineComment(3);
@@ -4907,9 +4907,8 @@ pp$8.readToken_lt_gt = function(code) { // '<>'
4907
4907
  if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) }
4908
4908
  return this.finishOp(types.bitShift, size)
4909
4909
  }
4910
- if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 &&
4910
+ if (next == 33 && code == 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) == 45 &&
4911
4911
  this.input.charCodeAt(this.pos + 3) == 45) {
4912
- if (this.inModule) { this.unexpected(); }
4913
4912
  // `<!--`, an XML-style comment that should be interpreted as a line comment
4914
4913
  this.skipLineComment(4);
4915
4914
  this.skipSpace();
@@ -5515,19 +5514,39 @@ function relativeId ( id ) {
5515
5514
  return relative( process.cwd(), id );
5516
5515
  }
5517
5516
 
5518
- const UNKNOWN_VALUE = { toString: () => '[[UNKNOWN]]' };
5517
+ class Variable {
5518
+ constructor ( name ) {
5519
+ this.name = name;
5520
+ }
5519
5521
 
5520
- const UNKNOWN_ASSIGNMENT = {
5521
- type: 'UNKNOWN',
5522
- hasEffectsWhenMutated: () => true,
5523
- };
5522
+ addCall () {}
5523
+
5524
+ getName () {
5525
+ return this.name;
5526
+ }
5527
+
5528
+ hasEffectsWhenCalled () {
5529
+ return true;
5530
+ }
5531
+
5532
+ hasEffectsWhenMutated () {
5533
+ return true;
5534
+ }
5535
+
5536
+ includeVariable () {
5537
+ if ( this.included ) {
5538
+ return false;
5539
+ }
5540
+ this.included = true;
5541
+ return true;
5542
+ }
5543
+ }
5524
5544
 
5525
- class SyntheticNamespaceDeclaration {
5545
+ class NamespaceVariable extends Variable {
5526
5546
  constructor ( module ) {
5547
+ super( module.basename() );
5527
5548
  this.isNamespace = true;
5528
5549
  this.module = module;
5529
- this.name = module.basename();
5530
-
5531
5550
  this.needsNamespaceBlock = false;
5532
5551
 
5533
5552
  this.originals = blank();
@@ -5540,22 +5559,15 @@ class SyntheticNamespaceDeclaration {
5540
5559
  this.name = node.name;
5541
5560
  }
5542
5561
 
5543
- gatherPossibleValues ( values ) {
5544
- values.add( UNKNOWN_ASSIGNMENT );
5545
- }
5546
-
5547
- getName () {
5548
- return this.name;
5549
- }
5562
+ assignExpression () {}
5550
5563
 
5551
- includeDeclaration () {
5552
- if ( this.included ) {
5553
- return false;
5564
+ includeVariable () {
5565
+ const hasBeenIncluded = super.includeVariable();
5566
+ if ( hasBeenIncluded ) {
5567
+ this.needsNamespaceBlock = true;
5568
+ forOwn( this.originals, original => original.includeVariable() );
5554
5569
  }
5555
- this.included = true;
5556
- this.needsNamespaceBlock = true;
5557
- forOwn( this.originals, original => original.includeDeclaration() );
5558
- return true;
5570
+ return hasBeenIncluded;
5559
5571
  }
5560
5572
 
5561
5573
  renderBlock ( es, legacy, indentString ) {
@@ -5575,55 +5587,6 @@ class SyntheticNamespaceDeclaration {
5575
5587
  }
5576
5588
  }
5577
5589
 
5578
- class ExternalDeclaration {
5579
- constructor ( module, name ) {
5580
- this.module = module;
5581
- this.name = name;
5582
- this.safeName = null;
5583
- this.isExternal = true;
5584
- this.isNamespace = name === '*';
5585
- }
5586
-
5587
- addReference ( reference ) {
5588
- reference.declaration = this;
5589
-
5590
- if ( this.name === 'default' || this.name === '*' ) {
5591
- this.module.suggestName( reference.name );
5592
- }
5593
- }
5594
-
5595
- gatherPossibleValues ( values ) {
5596
- values.add( UNKNOWN_ASSIGNMENT );
5597
- }
5598
-
5599
- getName ( es ) {
5600
- if ( this.name === '*' ) {
5601
- return this.module.name;
5602
- }
5603
-
5604
- if ( this.name === 'default' ) {
5605
- return this.module.exportsNamespace || ( !es && this.module.exportsNames ) ?
5606
- `${this.module.name}__default` :
5607
- this.module.name;
5608
- }
5609
-
5610
- return es ? this.safeName : `${this.module.name}.${this.name}`;
5611
- }
5612
-
5613
- includeDeclaration () {
5614
- if ( this.included ) {
5615
- return false;
5616
- }
5617
- this.included = true;
5618
- this.module.used = true;
5619
- return true;
5620
- }
5621
-
5622
- setSafeName ( name ) {
5623
- this.safeName = name;
5624
- }
5625
- }
5626
-
5627
5590
  function extractNames ( param ) {
5628
5591
  const names = [];
5629
5592
  extractors[ param.type ]( names, param );
@@ -5656,13 +5619,216 @@ const extractors = {
5656
5619
  }
5657
5620
  };
5658
5621
 
5659
- class Node$1 {
5660
- assignExpression () {}
5622
+ const UNKNOWN_VALUE = { toString: () => '[[UNKNOWN]]' };
5623
+
5624
+ const UNKNOWN_ASSIGNMENT = {
5625
+ type: 'UNKNOWN',
5626
+ bindCall: () => {},
5627
+ hasEffectsWhenCalled: () => true,
5628
+ hasEffectsWhenMutated: () => true,
5629
+ };
5630
+
5631
+ const UNDEFINED_ASSIGNMENT = {
5632
+ type: 'UNDEFINED',
5633
+ bindCall: () => {},
5634
+ hasEffectsWhenCalled: () => true,
5635
+ hasEffectsWhenMutated: () => true,
5636
+ };
5637
+
5638
+ const UNKNOWN_OBJECT_LITERAL = {
5639
+ type: 'UNKNOWN_OBJECT_LITERAL',
5640
+ bindCall: () => {},
5641
+ hasEffectsWhenCalled: () => true,
5642
+ hasEffectsWhenMutated: () => false,
5643
+ };
5644
+
5645
+ const OPTION_IGNORE_BREAK_STATEMENTS = 'IGNORE_BREAK_STATEMENTS';
5646
+ const OPTION_IGNORE_RETURN_AWAIT_YIELD = 'IGNORE_RETURN_AWAIT_YIELD';
5647
+ const OPTION_IGNORE_SAFE_THIS_MUTATIONS = 'IGNORE_SAFE_THIS_MUTATIONS';
5648
+ const OPTION_CALLED_NODES = 'CALLED_NODES';
5649
+ const OPTION_MUTATED_NODES = 'MUTATED_NODES';
5650
+ const IGNORED_LABELS = 'IGNORED_LABELS';
5651
+
5652
+ /** Wrapper to ensure immutability */
5653
+ class ExecutionPathOptions {
5654
+ /**
5655
+ * @returns {ExecutionPathOptions}
5656
+ */
5657
+ static create () {
5658
+ return new this( {} );
5659
+ }
5660
+
5661
+ constructor ( optionValues ) {
5662
+ this._optionValues = optionValues;
5663
+ }
5664
+
5665
+ /**
5666
+ * Returns a new ExecutionPathOptions instance with the given option set to a new value.
5667
+ * Does not mutate the current instance. Also works in sub-classes.
5668
+ * @param {string} option - The name of an option
5669
+ * @param {*} value - The new value of the option
5670
+ * @returns {ExecutionPathOptions} A new options instance
5671
+ */
5672
+ set ( option, value ) {
5673
+ return new this.constructor( Object.assign( {}, this._optionValues, { [option]: value } ) );
5674
+ }
5675
+
5676
+ /**
5677
+ * @param {string} option - The name of an option
5678
+ * @returns {*} Its value
5679
+ */
5680
+ get ( option ) {
5681
+ return this._optionValues[ option ];
5682
+ }
5683
+
5684
+ /**
5685
+ * @return {boolean}
5686
+ */
5687
+ ignoreBreakStatements () {
5688
+ return this.get( OPTION_IGNORE_BREAK_STATEMENTS );
5689
+ }
5690
+
5691
+ /**
5692
+ * @param {boolean} [value=true]
5693
+ * @return {ExecutionPathOptions}
5694
+ */
5695
+ setIgnoreBreakStatements ( value ) {
5696
+ if ( value === void 0 ) value = true;
5697
+
5698
+ return this.set( OPTION_IGNORE_BREAK_STATEMENTS, value );
5699
+ }
5700
+
5701
+ /**
5702
+ * @param {string} labelName
5703
+ * @return {boolean}
5704
+ */
5705
+ ignoreLabel ( labelName ) {
5706
+ const ignoredLabels = this.get( IGNORED_LABELS );
5707
+ return ignoredLabels && ignoredLabels.has( labelName );
5708
+ }
5709
+
5710
+ /**
5711
+ * @param {string} labelName
5712
+ * @return {ExecutionPathOptions}
5713
+ */
5714
+ setIgnoreLabel ( labelName ) {
5715
+ return this.set( IGNORED_LABELS, new Set( this.get( IGNORED_LABELS ) ).add( labelName ) );
5716
+ }
5717
+
5718
+ /**
5719
+ * @return {ExecutionPathOptions}
5720
+ */
5721
+ setIgnoreNoLabels () {
5722
+ return this.set( IGNORED_LABELS, null );
5723
+ }
5724
+
5725
+ /**
5726
+ * @return {boolean}
5727
+ */
5728
+ ignoreReturnAwaitYield () {
5729
+ return this.get( OPTION_IGNORE_RETURN_AWAIT_YIELD );
5730
+ }
5731
+
5732
+ /**
5733
+ * @param {boolean} [value=true]
5734
+ * @return {ExecutionPathOptions}
5735
+ */
5736
+ setIgnoreReturnAwaitYield ( value ) {
5737
+ if ( value === void 0 ) value = true;
5738
+
5739
+ return this.set( OPTION_IGNORE_RETURN_AWAIT_YIELD, value );
5740
+ }
5741
+
5742
+ /**
5743
+ * @return {boolean}
5744
+ */
5745
+ ignoreSafeThisMutations () {
5746
+ return this.get( OPTION_IGNORE_SAFE_THIS_MUTATIONS );
5747
+ }
5748
+
5749
+ /**
5750
+ * @param {boolean} [value=true]
5751
+ * @return {ExecutionPathOptions}
5752
+ */
5753
+ setIgnoreSafeThisMutations ( value ) {
5754
+ if ( value === void 0 ) value = true;
5755
+
5756
+ return this.set( OPTION_IGNORE_SAFE_THIS_MUTATIONS, value );
5757
+ }
5758
+
5759
+ /**
5760
+ * @param {Node} node
5761
+ * @return {ExecutionPathOptions}
5762
+ */
5763
+ addMutatedNode ( node ) {
5764
+ return this.set( OPTION_MUTATED_NODES, new Set( this.get( OPTION_MUTATED_NODES ) ).add( node ) );
5765
+ }
5661
5766
 
5767
+ /**
5768
+ * @param {Node} node
5769
+ * @return {boolean}
5770
+ */
5771
+ hasNodeBeenMutated ( node ) {
5772
+ const mutatedNodes = this.get( OPTION_MUTATED_NODES );
5773
+ return mutatedNodes && mutatedNodes.has( node );
5774
+ }
5775
+
5776
+ /**
5777
+ * @param {Node} node
5778
+ * @return {ExecutionPathOptions}
5779
+ */
5780
+ addCalledNode ( node ) {
5781
+ return this.set( OPTION_CALLED_NODES, new Set( this.get( OPTION_CALLED_NODES ) ).add( node ) );
5782
+ }
5783
+
5784
+ /**
5785
+ * @param {Node} node
5786
+ * @return {boolean}
5787
+ */
5788
+ hasNodeBeenCalled ( node ) {
5789
+ const calledNodes = this.get( OPTION_CALLED_NODES );
5790
+ return calledNodes && calledNodes.has( node );
5791
+ }
5792
+
5793
+ /**
5794
+ * @param {Node} calledNode
5795
+ * @return {ExecutionPathOptions}
5796
+ */
5797
+ getHasEffectsWhenCalledOptions ( calledNode ) {
5798
+ return this
5799
+ .addCalledNode( calledNode )
5800
+ .setIgnoreReturnAwaitYield()
5801
+ .setIgnoreBreakStatements( false )
5802
+ .setIgnoreNoLabels();
5803
+ }
5804
+ }
5805
+
5806
+ class Node$1 {
5807
+ /**
5808
+ * Called once all nodes have been initialised and the scopes have been populated.
5809
+ * Use this to bind assignments and calls to variables.
5810
+ */
5662
5811
  bind () {
5663
5812
  this.eachChild( child => child.bind() );
5664
5813
  }
5665
5814
 
5815
+ /**
5816
+ * Bind an expression as an assignment to a node.
5817
+ * The default noop implementation is ok as long as hasEffectsWhenAssigned
5818
+ * always returns true for this node. Otherwise it should be overridden.
5819
+ * @param {Node} expression
5820
+ */
5821
+ bindAssignment () {}
5822
+
5823
+ /**
5824
+ * Binds ways a node is called to a node. Current options are:
5825
+ * - withNew: boolean - Did this call use the "new" operator
5826
+ * The default noop implementation is ok as long as hasEffectsWhenCalled
5827
+ * always returns true for this node. Otherwise it should be overridden.
5828
+ * @param callOptions
5829
+ */
5830
+ bindCall () {}
5831
+
5666
5832
  eachChild ( callback ) {
5667
5833
  this.keys.forEach( key => {
5668
5834
  const value = this[ key ];
@@ -5676,30 +5842,65 @@ class Node$1 {
5676
5842
  } );
5677
5843
  }
5678
5844
 
5679
- gatherPossibleValues ( values ) {
5680
- values.add( UNKNOWN_ASSIGNMENT );
5681
- }
5682
-
5683
5845
  getValue () {
5684
5846
  return UNKNOWN_VALUE;
5685
5847
  }
5686
5848
 
5687
- hasEffects () {
5688
- return this.included || this.someChild( child => child.hasEffects() );
5849
+ /**
5850
+ * Determine if this Node would have an effect on the bundle.
5851
+ * This is usually true for already included nodes. Exceptions are e.g. break statements
5852
+ * which only have an effect if their surrounding loop or switch statement is included.
5853
+ * The options pass on information like this about the current execution path.
5854
+ * @param {ExecutionPathOptions} options
5855
+ * @return {boolean}
5856
+ */
5857
+ hasEffects ( options ) {
5858
+ return this.included || this.someChild( child => child.hasEffects( options ) );
5859
+ }
5860
+
5861
+ /**
5862
+ * Special make-shift logic to treat cases where apparently side-effect free statements
5863
+ * are executed for side-effects. The most important case are getters with side-effects.
5864
+ * Once we can reliably handle this case in member expressions, this function should
5865
+ * probably be removed again.
5866
+ * @param {ExecutionPathOptions} options
5867
+ * @return {boolean}
5868
+ */
5869
+ hasEffectsAsExpressionStatement () {
5870
+ return true;
5689
5871
  }
5690
5872
 
5873
+ /**
5874
+ * @param {ExecutionPathOptions} options
5875
+ * @return {boolean}
5876
+ */
5691
5877
  hasEffectsWhenAssigned () {
5692
- return false;
5878
+ return true;
5693
5879
  }
5694
5880
 
5695
- hasEffectsWhenMutated () {
5696
- return false;
5881
+ /**
5882
+ * @param {ExecutionPathOptions} options
5883
+ * @return {boolean}
5884
+ */
5885
+ hasEffectsWhenCalled () {
5886
+ return true;
5697
5887
  }
5698
5888
 
5699
- includeDeclaration () {
5700
- return this.includeInBundle();
5889
+ /**
5890
+ * @param {ExecutionPathOptions} options
5891
+ * @return {boolean}
5892
+ */
5893
+ hasEffectsWhenMutated () {
5894
+ return true;
5701
5895
  }
5702
5896
 
5897
+ /**
5898
+ * Includes the node in the bundle. Children are usually included if they are
5899
+ * necessary for this node (e.g. a function body) or if they have effects.
5900
+ * Necessary variables should be included as well. Should return true if any
5901
+ * nodes or variables have been added that were missing before.
5902
+ * @return {boolean}
5903
+ */
5703
5904
  includeInBundle () {
5704
5905
  if ( this.isFullyIncluded() ) { return false; }
5705
5906
  let addedNewNodes = false;
@@ -5715,21 +5916,49 @@ class Node$1 {
5715
5916
  return true;
5716
5917
  }
5717
5918
 
5919
+ /**
5920
+ * Alternative version of includeInBundle to override the default behaviour of
5921
+ * declarations to only include nodes for declarators that have an effect. Necessary
5922
+ * for for-loops that do not use a declared loop variable.
5923
+ * @return {boolean}
5924
+ */
5925
+ includeWithAllDeclarations () {
5926
+ return this.includeInBundle();
5927
+ }
5928
+
5929
+ /**
5930
+ * Assign a scope to this node and make sure all children have the right scopes.
5931
+ * Perform any additional initialisation that does not depend on the scope being
5932
+ * populated with variables.
5933
+ * Usually one should not override this function but override initialiseScope,
5934
+ * initialiseNode and/or initialiseChildren instead. BlockScopes have a special
5935
+ * alternative initialisation initialiseAndReplaceScope.
5936
+ * @param {Scope} parentScope
5937
+ */
5718
5938
  initialise ( parentScope ) {
5719
5939
  this.initialiseScope( parentScope );
5720
5940
  this.initialiseNode( parentScope );
5721
5941
  this.initialiseChildren( parentScope );
5722
5942
  }
5723
5943
 
5724
- // Override if e.g. some children need to be initialised with the parent scope
5944
+ /**
5945
+ * Override to change how and with what scopes children are initialised
5946
+ * @param {Scope} parentScope
5947
+ */
5725
5948
  initialiseChildren () {
5726
5949
  this.eachChild( child => child.initialise( this.scope ) );
5727
5950
  }
5728
5951
 
5729
- // Override to perform special initialisation steps after the scope is initialised
5952
+ /**
5953
+ * Override to perform special initialisation steps after the scope is initialised
5954
+ * @param {Scope} parentScope
5955
+ */
5730
5956
  initialiseNode () {}
5731
5957
 
5732
- // Overwrite to create a new scope
5958
+ /**
5959
+ * Override if this scope should receive a different scope than the parent scope.
5960
+ * @param {Scope} parentScope
5961
+ */
5733
5962
  initialiseScope ( parentScope ) {
5734
5963
  this.scope = parentScope;
5735
5964
  }
@@ -5740,6 +5969,11 @@ class Node$1 {
5740
5969
  }
5741
5970
  }
5742
5971
 
5972
+ /**
5973
+ * Shortcut to skip checking this node for effects when all children have already
5974
+ * been included.
5975
+ * @param {Scope} parentScope
5976
+ */
5743
5977
  isFullyIncluded () {
5744
5978
  if ( this._fullyIncluded ) {
5745
5979
  return true;
@@ -5760,8 +5994,15 @@ class Node$1 {
5760
5994
  this.eachChild( child => child.render( code, es ) );
5761
5995
  }
5762
5996
 
5997
+ /**
5998
+ * Start a new execution path to determine if this node has an effect on the bundle and
5999
+ * should therefore be included. Unless they are fully included, included nodes should
6000
+ * always be included again in subsequent visits as the inclusion of additional variables
6001
+ * may require the inclusion of more child nodes in e.g. block statements.
6002
+ * @return {boolean}
6003
+ */
5763
6004
  shouldBeIncluded () {
5764
- return this.hasEffects();
6005
+ return this.hasEffects( ExecutionPathOptions.create() );
5765
6006
  }
5766
6007
 
5767
6008
  someChild ( callback ) {
@@ -5782,45 +6023,91 @@ class Node$1 {
5782
6023
  }
5783
6024
 
5784
6025
  class ArrayPattern extends Node$1 {
5785
- assignExpression () {
5786
- this.eachChild( child => child.assignExpression( UNKNOWN_ASSIGNMENT ) );
6026
+ bindAssignment () {
6027
+ this.eachChild( child => child.bindAssignment( UNKNOWN_ASSIGNMENT ) );
5787
6028
  }
5788
6029
 
5789
- hasEffectsWhenAssigned () {
5790
- return this.someChild( child => child.hasEffectsWhenAssigned() );
6030
+ hasEffectsWhenAssigned ( options ) {
6031
+ return this.someChild( child => child.hasEffectsWhenAssigned( options ) );
6032
+ }
6033
+
6034
+ initialiseAndDeclare ( parentScope, kind ) {
6035
+ this.initialiseScope( parentScope );
6036
+ this.eachChild( child => child.initialiseAndDeclare( parentScope, kind, UNKNOWN_ASSIGNMENT ) );
5791
6037
  }
5792
6038
  }
5793
6039
 
5794
- class Parameter {
5795
- constructor ( name ) {
5796
- this.name = name;
5797
- this.isParam = true;
5798
- this.assignedExpressions = new Set( [ UNKNOWN_ASSIGNMENT ] );
6040
+ class LocalVariable extends Variable {
6041
+ constructor ( name, declarator, init ) {
6042
+ super( name );
6043
+ this.isReassigned = false;
6044
+ this.exportName = null;
6045
+ this.declarations = new Set( declarator ? [ declarator ] : null );
6046
+ this.assignedExpressions = new Set( init ? [ init ] : null );
6047
+ this.calls = new Set();
6048
+ }
6049
+
6050
+ addDeclaration ( identifier ) {
6051
+ this.declarations.add( identifier );
5799
6052
  }
5800
6053
 
5801
- addReference () {
5802
- // noop?
6054
+ addCall ( callOptions ) {
6055
+ // To prevent infinite loops
6056
+ if ( this.calls.has( callOptions ) ) { return; }
6057
+ this.calls.add( callOptions );
6058
+ Array.from( this.assignedExpressions ).forEach( expression => expression.bindCall( callOptions ) );
5803
6059
  }
5804
6060
 
6061
+ addReference () {}
6062
+
5805
6063
  assignExpression ( expression ) {
5806
6064
  this.assignedExpressions.add( expression );
5807
6065
  this.isReassigned = true;
6066
+ Array.from( this.calls ).forEach( callOptions => expression.bindCall( callOptions ) );
5808
6067
  }
5809
6068
 
5810
- gatherPossibleValues ( values ) {
5811
- values.add( UNKNOWN_ASSIGNMENT ); // TODO populate this at call time
6069
+ getName ( es ) {
6070
+ if ( es ) { return this.name; }
6071
+ if ( !this.isReassigned || !this.exportName ) { return this.name; }
6072
+
6073
+ return `exports.${this.exportName}`;
5812
6074
  }
5813
6075
 
5814
- getName () {
5815
- return this.name;
6076
+ hasEffectsWhenCalled ( options ) {
6077
+ return Array.from( this.assignedExpressions ).some( node =>
6078
+ !options.hasNodeBeenCalled( node )
6079
+ && node.hasEffectsWhenCalled( options.getHasEffectsWhenCalledOptions( node ) )
6080
+ );
5816
6081
  }
5817
6082
 
5818
- includeDeclaration () {
5819
- if ( this.included ) {
5820
- return false;
6083
+ hasEffectsWhenMutated ( options ) {
6084
+ return this.included
6085
+ || Array.from( this.assignedExpressions ).some( node =>
6086
+ !options.hasNodeBeenMutated( node ) &&
6087
+ node.hasEffectsWhenMutated( options.addMutatedNode( node ) )
6088
+ );
6089
+ }
6090
+
6091
+ includeVariable () {
6092
+ const hasBeenIncluded = super.includeVariable();
6093
+ if ( hasBeenIncluded ) {
6094
+ this.declarations.forEach( identifier => identifier.includeInBundle() );
5821
6095
  }
5822
- this.included = true;
5823
- return true;
6096
+ return hasBeenIncluded;
6097
+ }
6098
+
6099
+ toString () {
6100
+ return this.name;
6101
+ }
6102
+ }
6103
+
6104
+ class ParameterVariable extends LocalVariable {
6105
+ constructor ( name, declarator ) {
6106
+ super( name, declarator, UNKNOWN_ASSIGNMENT );
6107
+ }
6108
+
6109
+ getName () {
6110
+ return this.name;
5824
6111
  }
5825
6112
  }
5826
6113
 
@@ -5829,43 +6116,38 @@ class Scope {
5829
6116
  if ( options === void 0 ) options = {};
5830
6117
 
5831
6118
  this.parent = options.parent;
5832
- this.isBlockScope = !!options.isBlockScope;
5833
- this.isLexicalBoundary = !!options.isLexicalBoundary;
5834
6119
  this.isModuleScope = !!options.isModuleScope;
5835
6120
 
5836
6121
  this.children = [];
5837
6122
  if ( this.parent ) { this.parent.children.push( this ); }
5838
6123
 
5839
- this.declarations = blank();
5840
-
5841
- if ( this.isLexicalBoundary && !this.isModuleScope ) {
5842
- this.declarations.arguments = new Parameter( 'arguments' );
5843
- }
6124
+ this.variables = blank();
5844
6125
  }
5845
6126
 
5846
- addDeclaration ( name, declaration, isVar, isParam ) {
5847
- if ( isVar && this.isBlockScope ) {
5848
- this.parent.addDeclaration( name, declaration, isVar, isParam );
6127
+ addDeclaration ( identifier, isHoisted, init ) {
6128
+ const name = identifier.name;
6129
+ if ( this.variables[ name ] ) {
6130
+ const variable = this.variables[ name ];
6131
+ variable.addDeclaration( identifier );
6132
+ init && variable.assignExpression( init );
5849
6133
  } else {
5850
- const existingDeclaration = this.declarations[ name ];
5851
-
5852
- if ( existingDeclaration && existingDeclaration.duplicates ) {
5853
- // TODO warn/throw on duplicates?
5854
- existingDeclaration.duplicates.push( declaration );
5855
- } else {
5856
- this.declarations[ name ] = isParam ? new Parameter( name ) : declaration;
5857
- }
6134
+ this.variables[ name ] = new LocalVariable( identifier.name, identifier, init );
5858
6135
  }
5859
6136
  }
5860
6137
 
6138
+ addParameterDeclaration ( identifier ) {
6139
+ const name = identifier.name;
6140
+ this.variables[ name ] = new ParameterVariable( name, identifier );
6141
+ }
6142
+
5861
6143
  contains ( name ) {
5862
- return !!this.declarations[ name ] ||
6144
+ return !!this.variables[ name ] ||
5863
6145
  ( this.parent ? this.parent.contains( name ) : false );
5864
6146
  }
5865
6147
 
5866
6148
  deshadow ( names ) {
5867
- keys( this.declarations ).forEach( key => {
5868
- const declaration = this.declarations[ key ];
6149
+ keys( this.variables ).forEach( key => {
6150
+ const declaration = this.variables[ key ];
5869
6151
 
5870
6152
  // we can disregard exports.foo etc
5871
6153
  if ( declaration.exportName && declaration.isReassigned ) { return; }
@@ -5885,61 +6167,52 @@ class Scope {
5885
6167
  this.children.forEach( scope => scope.deshadow( names ) );
5886
6168
  }
5887
6169
 
5888
- findDeclaration ( name ) {
5889
- return this.declarations[ name ] ||
5890
- ( this.parent && this.parent.findDeclaration( name ) );
6170
+ findLexicalBoundary () {
6171
+ return this.parent.findLexicalBoundary();
5891
6172
  }
5892
6173
 
5893
- findLexicalBoundary () {
5894
- return this.isLexicalBoundary ? this : this.parent.findLexicalBoundary();
6174
+ findVariable ( name ) {
6175
+ return this.variables[ name ] ||
6176
+ ( this.parent && this.parent.findVariable( name ) );
5895
6177
  }
5896
6178
  }
5897
6179
 
5898
- class Function$1 extends Node$1 {
5899
- bind () {
5900
- if ( this.id ) { this.id.bind(); }
5901
- this.params.forEach( param => param.bind() );
5902
- this.body.bind();
5903
- }
6180
+ class ArrowFunctionExpression extends Node$1 {
6181
+ // Should receive an implementation once we start tracking parameter values
6182
+ bindCall () {}
5904
6183
 
5905
6184
  hasEffects () {
5906
6185
  return this.included;
5907
6186
  }
5908
6187
 
5909
- initialiseChildren () {
5910
- this.params.forEach( param => {
5911
- param.initialise( this.scope );
5912
- extractNames( param ).forEach( name => this.scope.addDeclaration( name, null, false, true ) );
5913
- } );
5914
- this.body.initialiseAndReplaceScope ?
5915
- this.body.initialiseAndReplaceScope( this.scope ) :
5916
- this.body.initialise( this.scope );
6188
+ hasEffectsWhenCalled ( options ) {
6189
+ return this.params.some( param => param.hasEffects( options ) )
6190
+ || this.body.hasEffects( options );
5917
6191
  }
5918
6192
 
5919
- initialiseScope ( parentScope ) {
5920
- this.scope = new Scope( {
5921
- parent: parentScope,
5922
- isBlockScope: false,
5923
- isLexicalBoundary: true
5924
- } );
6193
+ hasEffectsWhenMutated () {
6194
+ return this.included;
6195
+ }
6196
+
6197
+ initialiseChildren () {
6198
+ this.params.forEach( param => param.initialiseAndDeclare( this.scope, 'parameter' ) );
6199
+ if ( this.body.initialiseAndReplaceScope ) {
6200
+ this.body.initialiseAndReplaceScope( new Scope( { parent: this.scope } ) );
6201
+ } else {
6202
+ this.body.initialise( this.scope );
6203
+ }
5925
6204
  }
5926
- }
5927
6205
 
5928
- class ArrowFunctionExpression extends Function$1 {
5929
6206
  initialiseScope ( parentScope ) {
5930
- this.scope = new Scope( {
5931
- parent: parentScope,
5932
- isBlockScope: false,
5933
- isLexicalBoundary: false
5934
- } );
6207
+ this.scope = new Scope( { parent: parentScope } );
5935
6208
  }
5936
6209
  }
5937
6210
 
5938
6211
  // TODO tidy this up a bit (e.g. they can both use node.module.imports)
5939
6212
  function disallowIllegalReassignment ( scope, node ) {
5940
6213
  if ( node.type === 'MemberExpression' && node.object.type === 'Identifier' ) {
5941
- const declaration = scope.findDeclaration( node.object.name );
5942
- if ( declaration.isNamespace ) {
6214
+ const variable = scope.findVariable( node.object.name );
6215
+ if ( variable.isNamespace ) {
5943
6216
  node.module.error({
5944
6217
  code: 'ILLEGAL_NAMESPACE_REASSIGNMENT',
5945
6218
  message: `Illegal reassignment to import '${node.object.name}'`
@@ -5961,15 +6234,47 @@ class AssignmentExpression extends Node$1 {
5961
6234
  bind () {
5962
6235
  super.bind();
5963
6236
  disallowIllegalReassignment( this.scope, this.left );
5964
- this.left.assignExpression( this.right );
6237
+ this.left.bindAssignment( this.right );
5965
6238
  }
5966
6239
 
5967
- hasEffects () {
5968
- return super.hasEffects() || this.left.hasEffectsWhenAssigned();
6240
+ hasEffects ( options ) {
6241
+ return super.hasEffects( options ) || this.left.hasEffectsWhenAssigned( options );
5969
6242
  }
5970
6243
 
5971
- hasEffectsWhenMutated () {
5972
- return true;
6244
+ hasEffectsAsExpressionStatement ( options ) {
6245
+ return this.hasEffects( options );
6246
+ }
6247
+ }
6248
+
6249
+ class AssignmentPattern extends Node$1 {
6250
+ bind () {
6251
+ super.bind();
6252
+ this.left.bindAssignment( this.right );
6253
+ }
6254
+
6255
+ bindAssignment ( expression ) {
6256
+ this.left.bindAssignment( expression );
6257
+ }
6258
+
6259
+ hasEffectsWhenAssigned ( options ) {
6260
+ return this.left.hasEffectsWhenAssigned( options );
6261
+ }
6262
+
6263
+ initialiseAndDeclare ( parentScope, kind, init ) {
6264
+ this.initialiseScope( parentScope );
6265
+ this.right.initialise( parentScope );
6266
+ this.left.initialiseAndDeclare( parentScope, kind, init );
6267
+ }
6268
+ }
6269
+
6270
+ class AwaitExpression extends Node$1 {
6271
+ hasEffects ( options ) {
6272
+ return super.hasEffects( options )
6273
+ || !options.ignoreReturnAwaitYield();
6274
+ }
6275
+
6276
+ hasEffectsAsExpressionStatement ( options ) {
6277
+ return this.hasEffects( options );
5973
6278
  }
5974
6279
  }
5975
6280
 
@@ -6010,10 +6315,6 @@ class BinaryExpression extends Node$1 {
6010
6315
 
6011
6316
  return operators[ this.operator ]( leftValue, rightValue );
6012
6317
  }
6013
-
6014
- hasEffectsWhenMutated () {
6015
- return true;
6016
- }
6017
6318
  }
6018
6319
 
6019
6320
  class Statement extends Node$1 {
@@ -6026,11 +6327,26 @@ class Statement extends Node$1 {
6026
6327
  }
6027
6328
  }
6028
6329
 
6330
+ class BlockScope extends Scope {
6331
+ addDeclaration ( identifier, isHoisted, init ) {
6332
+ if ( isHoisted ) {
6333
+ this.parent.addDeclaration( identifier, isHoisted, init );
6334
+ } else {
6335
+ super.addDeclaration( identifier, false, init );
6336
+ }
6337
+ }
6338
+ }
6339
+
6029
6340
  class BlockStatement extends Statement {
6030
6341
  bind () {
6031
6342
  this.body.forEach( node => node.bind() );
6032
6343
  }
6033
6344
 
6345
+ hasEffects ( options ) {
6346
+ // Empty block statements do not have effects even though they may be included as e.g. function body
6347
+ return this.body.some( child => child.hasEffects( options ) );
6348
+ }
6349
+
6034
6350
  includeInBundle () {
6035
6351
  if ( this.isFullyIncluded() ) { return false; }
6036
6352
  let addedNewNodes = false;
@@ -6059,236 +6375,47 @@ class BlockStatement extends Statement {
6059
6375
  for ( const node of this.body ) {
6060
6376
  node.initialise( this.scope );
6061
6377
 
6062
- if ( lastNode ) { lastNode.next = node.start; }
6063
- lastNode = node;
6064
- }
6065
- }
6066
-
6067
- initialiseScope ( parentScope ) {
6068
- this.scope = new Scope( {
6069
- parent: parentScope,
6070
- isBlockScope: true,
6071
- isLexicalBoundary: false
6072
- } );
6073
- }
6074
-
6075
- render ( code, es ) {
6076
- if ( this.body.length ) {
6077
- for ( const node of this.body ) {
6078
- node.render( code, es );
6079
- }
6080
- } else {
6081
- Statement.prototype.render.call( this, code, es );
6082
- }
6083
- }
6084
- }
6085
-
6086
- function isReference (node, parent) {
6087
- if (node.type === 'MemberExpression') {
6088
- return !node.computed && isReference(node.object, node);
6089
- }
6090
-
6091
- if (node.type === 'Identifier') {
6092
- // the only time we could have an identifier node without a parent is
6093
- // if it's the entire body of a function without a block statement –
6094
- // i.e. an arrow function expression like `a => a`
6095
- if (!parent) return true;
6096
-
6097
- // TODO is this right?
6098
- if (parent.type === 'MemberExpression' || parent.type === 'MethodDefinition') {
6099
- return parent.computed || node === parent.object;
6100
- }
6101
-
6102
- // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
6103
- if (parent.type === 'Property') return parent.computed || node === parent.value;
6104
-
6105
- // disregard the `bar` in `class Foo { bar () {...} }`
6106
- if (parent.type === 'MethodDefinition') return false;
6107
-
6108
- // disregard the `bar` in `export { foo as bar }`
6109
- if (parent.type === 'ExportSpecifier' && node !== parent.local) return false;
6110
-
6111
- return true;
6112
- }
6113
-
6114
- return false;
6115
- }
6116
-
6117
- function flatten ( node ) {
6118
- const parts = [];
6119
- while ( node.type === 'MemberExpression' ) {
6120
- if ( node.computed ) { return null; }
6121
- parts.unshift( node.property.name );
6122
-
6123
- node = node.object;
6124
- }
6125
-
6126
- if ( node.type !== 'Identifier' ) { return null; }
6127
-
6128
- const name = node.name;
6129
- parts.unshift( name );
6130
-
6131
- return { name, keypath: parts.join( '.' ) };
6132
- }
6133
-
6134
- const pureFunctions = {};
6135
-
6136
- const arrayTypes = 'Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split( ' ' );
6137
- const simdTypes = 'Int8x16 Int16x8 Int32x4 Float32x4 Float64x2'.split( ' ' );
6138
- const simdMethods = 'abs add and bool check div equal extractLane fromFloat32x4 fromFloat32x4Bits fromFloat64x2 fromFloat64x2Bits fromInt16x8Bits fromInt32x4 fromInt32x4Bits fromInt8x16Bits greaterThan greaterThanOrEqual lessThan lessThanOrEqual load max maxNum min minNum mul neg not notEqual or reciprocalApproximation reciprocalSqrtApproximation replaceLane select selectBits shiftLeftByScalar shiftRightArithmeticByScalar shiftRightLogicalByScalar shuffle splat sqrt store sub swizzle xor'.split( ' ' );
6139
- const allSimdMethods = [];
6140
- simdTypes.forEach( t => {
6141
- simdMethods.forEach( m => {
6142
- allSimdMethods.push( `SIMD.${t}.${m}` );
6143
- });
6144
- });
6145
-
6146
- [
6147
- 'Array.isArray',
6148
- 'Error', 'EvalError', 'InternalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError',
6149
- 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape', 'unescape',
6150
- 'Object', 'Object.create', 'Object.getNotifier', 'Object.getOwn', 'Object.getOwnPropertyDescriptor', 'Object.getOwnPropertyNames', 'Object.getOwnPropertySymbols', 'Object.getPrototypeOf', 'Object.is', 'Object.isExtensible', 'Object.isFrozen', 'Object.isSealed', 'Object.keys',
6151
- 'Function', 'Boolean',
6152
- 'Number', 'Number.isFinite', 'Number.isInteger', 'Number.isNaN', 'Number.isSafeInteger', 'Number.parseFloat', 'Number.parseInt',
6153
- 'Symbol', 'Symbol.for', 'Symbol.keyFor',
6154
- 'Math.abs', 'Math.acos', 'Math.acosh', 'Math.asin', 'Math.asinh', 'Math.atan', 'Math.atan2', 'Math.atanh', 'Math.cbrt', 'Math.ceil', 'Math.clz32', 'Math.cos', 'Math.cosh', 'Math.exp', 'Math.expm1', 'Math.floor', 'Math.fround', 'Math.hypot', 'Math.imul', 'Math.log', 'Math.log10', 'Math.log1p', 'Math.log2', 'Math.max', 'Math.min', 'Math.pow', 'Math.random', 'Math.round', 'Math.sign', 'Math.sin', 'Math.sinh', 'Math.sqrt', 'Math.tan', 'Math.tanh', 'Math.trunc',
6155
- 'Date', 'Date.UTC', 'Date.now', 'Date.parse',
6156
- 'String', 'String.fromCharCode', 'String.fromCodePoint', 'String.raw',
6157
- 'RegExp',
6158
- 'Map', 'Set', 'WeakMap', 'WeakSet',
6159
- 'ArrayBuffer', 'ArrayBuffer.isView',
6160
- 'DataView',
6161
- 'JSON.parse', 'JSON.stringify',
6162
- 'Promise', 'Promise.all', 'Promise.race', 'Promise.reject', 'Promise.resolve',
6163
- 'Intl.Collator', 'Intl.Collator.supportedLocalesOf', 'Intl.DateTimeFormat', 'Intl.DateTimeFormat.supportedLocalesOf', 'Intl.NumberFormat', 'Intl.NumberFormat.supportedLocalesOf'
6164
-
6165
- // TODO properties of e.g. window...
6166
- ].concat(
6167
- arrayTypes,
6168
- arrayTypes.map( t => `${t}.from` ),
6169
- arrayTypes.map( t => `${t}.of` ),
6170
- simdTypes.map( t => `SIMD.${t}` ),
6171
- allSimdMethods
6172
- ).forEach( name => pureFunctions[ name ] = true );
6173
-
6174
- const currentlyCalling = new Set();
6175
-
6176
- function isES5Function ( node ) {
6177
- return node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration';
6178
- }
6179
-
6180
- function hasEffectsNew ( node ) {
6181
- let inner = node;
6182
-
6183
- if ( inner.type === 'ExpressionStatement' ) {
6184
- inner = inner.expression;
6185
-
6186
- if ( inner.type === 'AssignmentExpression' ) {
6187
- if ( inner.right.hasEffects() ) {
6188
- return true;
6189
-
6190
- } else {
6191
- inner = inner.left;
6192
-
6193
- if ( inner.type === 'MemberExpression' ) {
6194
- if ( inner.computed && inner.property.hasEffects() ) {
6195
- return true;
6196
-
6197
- } else {
6198
- inner = inner.object;
6199
-
6200
- if ( inner.type === 'ThisExpression' ) {
6201
- return false;
6202
- }
6203
- }
6204
- }
6205
- }
6206
- }
6207
- }
6208
-
6209
- return node.hasEffects();
6210
- }
6211
-
6212
- function fnHasEffects ( fn, isNew ) {
6213
- if ( currentlyCalling.has( fn ) ) { return false; } // prevent infinite loops... TODO there must be a better way
6214
- currentlyCalling.add( fn );
6215
-
6216
- // handle body-less arrow functions
6217
- const body = fn.body.type === 'BlockStatement' ? fn.body.body : [ fn.body ];
6218
-
6219
- for ( const node of body ) {
6220
- if ( isNew ? hasEffectsNew( node ) : node.hasEffects() ) {
6221
- currentlyCalling.delete( fn );
6222
- return true;
6223
- }
6224
- }
6225
-
6226
- currentlyCalling.delete( fn );
6227
- return false;
6228
- }
6229
-
6230
- function callHasEffects ( scope, callee, isNew ) {
6231
- const values = new Set( [ callee ] );
6232
-
6233
- for ( const node of values ) {
6234
- if ( node.type === 'UNKNOWN' ) { return true; } // err on side of caution
6235
-
6236
- if ( /Function/.test( node.type ) ) {
6237
- if ( fnHasEffects( node, isNew && isES5Function( node ) ) ) { return true; }
6238
- }
6239
-
6240
- else if ( /Class/.test( node.type ) ) {
6241
- // TODO find constructor (may belong to a superclass)
6242
- return true;
6243
- }
6244
-
6245
- else if ( isReference( node ) ) {
6246
- const flattened = flatten( node );
6247
- const declaration = scope.findDeclaration( flattened.name );
6248
-
6249
- if ( declaration.isGlobal ) {
6250
- if ( !pureFunctions[ flattened.keypath ] ) { return true; }
6251
- }
6252
-
6253
- else if ( declaration.isExternal ) {
6254
- return true; // TODO make this configurable? e.g. `path.[whatever]`
6255
- }
6256
-
6257
- else {
6258
- if ( node.declaration ) {
6259
- node.declaration.gatherPossibleValues( values );
6260
- } else {
6261
- return true;
6262
- }
6263
- }
6264
- }
6265
-
6266
- else if ( node.gatherPossibleValues ) {
6267
- node.gatherPossibleValues( values );
6378
+ if ( lastNode ) { lastNode.next = node.start; }
6379
+ lastNode = node;
6268
6380
  }
6381
+ }
6269
6382
 
6270
- else {
6271
- // probably an error in the user's code — err on side of caution
6272
- return true;
6383
+ initialiseScope ( parentScope ) {
6384
+ this.scope = new BlockScope( { parent: parentScope } );
6385
+ }
6386
+
6387
+ render ( code, es ) {
6388
+ if ( this.body.length ) {
6389
+ for ( const node of this.body ) {
6390
+ node.render( code, es );
6391
+ }
6392
+ } else {
6393
+ Statement.prototype.render.call( this, code, es );
6273
6394
  }
6274
6395
  }
6396
+ }
6275
6397
 
6276
- return false;
6398
+ class BreakStatement extends Node$1 {
6399
+ hasEffects ( options ) {
6400
+ return super.hasEffects( options )
6401
+ || !options.ignoreBreakStatements()
6402
+ || (this.label && !options.ignoreLabel( this.label.name ));
6403
+ }
6277
6404
  }
6278
6405
 
6279
6406
  class CallExpression extends Node$1 {
6280
6407
  bind () {
6281
6408
  if ( this.callee.type === 'Identifier' ) {
6282
- const declaration = this.scope.findDeclaration( this.callee.name );
6409
+ const variable = this.scope.findVariable( this.callee.name );
6283
6410
 
6284
- if ( declaration.isNamespace ) {
6411
+ if ( variable.isNamespace ) {
6285
6412
  this.module.error( {
6286
6413
  code: 'CANNOT_CALL_NAMESPACE',
6287
6414
  message: `Cannot call a namespace ('${this.callee.name}')`
6288
6415
  }, this.start );
6289
6416
  }
6290
6417
 
6291
- if ( this.callee.name === 'eval' && declaration.isGlobal ) {
6418
+ if ( this.callee.name === 'eval' && variable.isGlobal ) {
6292
6419
  this.module.warn( {
6293
6420
  code: 'EVAL',
6294
6421
  message: `Use of eval is strongly discouraged, as it poses security risks and may cause issues with minification`,
@@ -6298,42 +6425,65 @@ class CallExpression extends Node$1 {
6298
6425
  }
6299
6426
 
6300
6427
  super.bind();
6428
+ this.callee.bindCall( { withNew: false } );
6301
6429
  }
6302
6430
 
6303
- hasEffects () {
6431
+ hasEffects ( options ) {
6304
6432
  return this.included
6305
- || this.arguments.some( child => child.hasEffects() )
6306
- || callHasEffects( this.scope, this.callee, false );
6433
+ || this.arguments.some( child => child.hasEffects( options ) )
6434
+ || this.callee.hasEffectsWhenCalled( options.getHasEffectsWhenCalledOptions( this.callee ) );
6307
6435
  }
6308
6436
 
6309
- hasEffectsWhenMutated () {
6310
- return true;
6437
+ hasEffectsAsExpressionStatement ( options ) {
6438
+ return this.hasEffects( options );
6311
6439
  }
6312
6440
  }
6313
6441
 
6314
6442
  class CatchClause extends Node$1 {
6315
6443
  initialiseChildren () {
6316
- if ( this.param ) {
6317
- this.param.initialise( this.scope );
6318
- extractNames( this.param ).forEach( name => this.scope.addDeclaration( name, null, false, true ) );
6319
- }
6444
+ this.param && this.param.initialiseAndDeclare( this.scope, 'parameter' );
6320
6445
  this.body.initialiseAndReplaceScope( this.scope );
6321
6446
  }
6322
6447
 
6323
6448
  initialiseScope ( parentScope ) {
6324
- this.scope = new Scope( {
6325
- parent: parentScope,
6326
- isBlockScope: true,
6327
- isLexicalBoundary: false
6328
- } );
6449
+ this.scope = new BlockScope( { parent: parentScope } );
6329
6450
  }
6330
6451
  }
6331
6452
 
6332
- class Class extends Node$1 {
6333
- addReference () {}
6453
+ class ClassBody extends Node$1 {
6454
+ bindCall ( callOptions ) {
6455
+ if ( this.classConstructor ) {
6456
+ this.classConstructor.bindCall( callOptions );
6457
+ }
6458
+ }
6334
6459
 
6335
- getName () {
6336
- return this.name;
6460
+ hasEffectsWhenCalled ( options ) {
6461
+ if ( this.classConstructor ) {
6462
+ return this.classConstructor.hasEffectsWhenCalled( options );
6463
+ }
6464
+ return false;
6465
+ }
6466
+
6467
+ initialiseNode () {
6468
+ this.classConstructor = this.body.find( method => method.kind === 'constructor' );
6469
+ }
6470
+ }
6471
+
6472
+ class ClassNode extends Node$1 {
6473
+ bindCall ( callOptions ) {
6474
+ if ( this.superClass ) {
6475
+ this.superClass.bindCall( callOptions );
6476
+ }
6477
+ this.body.bindCall( callOptions );
6478
+ }
6479
+
6480
+ hasEffectsAsExpressionStatement ( options ) {
6481
+ return this.hasEffects( options );
6482
+ }
6483
+
6484
+ hasEffectsWhenCalled ( options ) {
6485
+ return this.body.hasEffectsWhenCalled( options )
6486
+ || ( this.superClass && this.superClass.hasEffectsWhenCalled( options ) );
6337
6487
  }
6338
6488
 
6339
6489
  initialiseChildren () {
@@ -6344,28 +6494,14 @@ class Class extends Node$1 {
6344
6494
  }
6345
6495
 
6346
6496
  initialiseScope ( parentScope ) {
6347
- this.scope = new Scope( {
6348
- parent: parentScope,
6349
- isBlockScope: true
6350
- } );
6497
+ this.scope = new Scope( { parent: parentScope } );
6351
6498
  }
6352
6499
  }
6353
6500
 
6354
- class ClassDeclaration extends Class {
6355
- gatherPossibleValues ( values ) {
6356
- values.add( this );
6357
- }
6358
-
6359
- hasEffects () {
6360
- return this.included;
6361
- }
6362
-
6501
+ class ClassDeclaration extends ClassNode {
6363
6502
  initialiseChildren ( parentScope ) {
6364
- if ( this.id ) {
6365
- this.name = this.id.name;
6366
- parentScope.addDeclaration( this.name, this, false, false );
6367
- this.id.initialise( parentScope );
6368
- }
6503
+ // Class declarations are like let declarations: Not hoisted, can be reassigned, cannot be redeclared
6504
+ this.id && this.id.initialiseAndDeclare( parentScope, 'class', this );
6369
6505
  super.initialiseChildren( parentScope );
6370
6506
  }
6371
6507
 
@@ -6378,14 +6514,10 @@ class ClassDeclaration extends Class {
6378
6514
  }
6379
6515
  }
6380
6516
 
6381
- class ClassExpression extends Class {
6382
- initialiseChildren (parentScope) {
6383
- if ( this.id ) {
6384
- this.name = this.id.name;
6385
- this.scope.addDeclaration( this.name, this, false, false );
6386
- this.id.initialise( this.scope );
6387
- }
6388
- super.initialiseChildren(parentScope);
6517
+ class ClassExpression extends ClassNode {
6518
+ initialiseChildren ( parentScope ) {
6519
+ this.id && this.id.initialiseAndDeclare( this.scope, 'class', this );
6520
+ super.initialiseChildren( parentScope );
6389
6521
  }
6390
6522
  }
6391
6523
 
@@ -6408,16 +6540,6 @@ class ConditionalExpression extends Node$1 {
6408
6540
  }
6409
6541
  }
6410
6542
 
6411
- gatherPossibleValues ( values ) {
6412
- const testValue = this.test.getValue();
6413
-
6414
- if ( testValue === UNKNOWN_VALUE ) {
6415
- values.add( this.consequent ).add( this.alternate );
6416
- } else {
6417
- values.add( testValue ? this.consequent : this.alternate );
6418
- }
6419
- }
6420
-
6421
6543
  getValue () {
6422
6544
  const testValue = this.test.getValue();
6423
6545
  if ( testValue === UNKNOWN_VALUE ) { return UNKNOWN_VALUE; }
@@ -6425,10 +6547,6 @@ class ConditionalExpression extends Node$1 {
6425
6547
  return testValue ? this.consequent.getValue() : this.alternate.getValue();
6426
6548
  }
6427
6549
 
6428
- hasEffectsWhenMutated () {
6429
- return true;
6430
- }
6431
-
6432
6550
  render ( code, es ) {
6433
6551
  if ( !this.module.bundle.treeshake ) {
6434
6552
  super.render( code, es );
@@ -6460,6 +6578,16 @@ class ConditionalExpression extends Node$1 {
6460
6578
  }
6461
6579
  }
6462
6580
 
6581
+ class DoWhileStatement extends Statement {
6582
+ hasEffects ( options ) {
6583
+ return (
6584
+ this.included
6585
+ || this.test.hasEffects( options )
6586
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
6587
+ );
6588
+ }
6589
+ }
6590
+
6463
6591
  class EmptyStatement extends Statement {
6464
6592
  render ( code ) {
6465
6593
  if ( this.parent.type === 'BlockStatement' || this.parent.type === 'Program' ) {
@@ -6481,6 +6609,10 @@ class ExportAllDeclaration extends Node$1 {
6481
6609
  const functionOrClassDeclaration = /^(?:Function|Class)Declaration/;
6482
6610
 
6483
6611
  class ExportDefaultDeclaration extends Node$1 {
6612
+ addCall ( options ) {
6613
+ this.declaration.bindCall( options );
6614
+ }
6615
+
6484
6616
  addReference ( reference ) {
6485
6617
  this.name = reference.name;
6486
6618
  if ( this.original ) { this.original.addReference( reference ); }
@@ -6488,15 +6620,11 @@ class ExportDefaultDeclaration extends Node$1 {
6488
6620
 
6489
6621
  bind () {
6490
6622
  const name = ( this.declaration.id && this.declaration.id.name ) || this.declaration.name;
6491
- if ( name ) { this.original = this.scope.findDeclaration( name ); }
6623
+ if ( name ) { this.original = this.scope.findVariable( name ); }
6492
6624
 
6493
6625
  this.declaration.bind();
6494
6626
  }
6495
6627
 
6496
- gatherPossibleValues ( values ) {
6497
- this.declaration.gatherPossibleValues( values );
6498
- }
6499
-
6500
6628
  getName ( es ) {
6501
6629
  if ( this.original && !this.original.isReassigned ) {
6502
6630
  return this.original.getName( es );
@@ -6505,7 +6633,11 @@ class ExportDefaultDeclaration extends Node$1 {
6505
6633
  return this.name;
6506
6634
  }
6507
6635
 
6508
- includeDeclaration () {
6636
+ hasEffectsWhenCalled ( options ) {
6637
+ return this.declaration.hasEffectsWhenCalled( options );
6638
+ }
6639
+
6640
+ includeVariable () {
6509
6641
  if ( this.included ) {
6510
6642
  return false;
6511
6643
  }
@@ -6526,7 +6658,7 @@ class ExportDefaultDeclaration extends Node$1 {
6526
6658
  this.isDefault = true;
6527
6659
 
6528
6660
  this.name = ( this.declaration.id && this.declaration.id.name ) || this.declaration.name || this.module.basename();
6529
- this.scope.declarations.default = this;
6661
+ this.scope.variables.default = this;
6530
6662
  }
6531
6663
 
6532
6664
  // TODO this is total chaos, tidy it up
@@ -6574,7 +6706,7 @@ class ExportDefaultDeclaration extends Node$1 {
6574
6706
  if ( functionOrClassDeclaration.test( this.declaration.type ) ) {
6575
6707
  code.remove( this.leadingCommentStart || this.start, this.next || this.end );
6576
6708
  } else {
6577
- const hasEffects = this.declaration.hasEffects();
6709
+ const hasEffects = this.declaration.hasEffects( ExecutionPathOptions.create() );
6578
6710
  code.remove( this.start, hasEffects ? declaration_start : this.next || this.end );
6579
6711
  }
6580
6712
  } else if ( name === this.declaration.name ) {
@@ -6589,11 +6721,12 @@ class ExportDefaultDeclaration extends Node$1 {
6589
6721
 
6590
6722
  class ExportNamedDeclaration extends Node$1 {
6591
6723
  bind () {
6724
+ // Do not bind specifiers
6592
6725
  if ( this.declaration ) { this.declaration.bind(); }
6593
6726
  }
6594
6727
 
6595
- hasEffects () {
6596
- return this.included || (this.declaration && this.declaration.hasEffects());
6728
+ hasEffects ( options ) {
6729
+ return this.included || (this.declaration && this.declaration.hasEffects( options ));
6597
6730
  }
6598
6731
 
6599
6732
  initialiseNode () {
@@ -6624,6 +6757,10 @@ class ExportNamedDeclaration extends Node$1 {
6624
6757
  }
6625
6758
 
6626
6759
  class ExpressionStatement extends Statement {
6760
+ hasEffects ( options ) {
6761
+ return super.hasEffects( options ) || this.expression.hasEffectsAsExpressionStatement(options);
6762
+ }
6763
+
6627
6764
  render ( code, es ) {
6628
6765
  super.render( code, es );
6629
6766
  if ( this.included ) { this.insertSemicolon( code ); }
@@ -6631,6 +6768,16 @@ class ExpressionStatement extends Statement {
6631
6768
  }
6632
6769
 
6633
6770
  class ForStatement extends Statement {
6771
+ hasEffects ( options ) {
6772
+ return (
6773
+ this.included
6774
+ || this.init && this.init.hasEffects( options )
6775
+ || this.test && this.test.hasEffects( options )
6776
+ || this.update && this.update.hasEffects( options )
6777
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
6778
+ );
6779
+ }
6780
+
6634
6781
  initialiseChildren () {
6635
6782
  if ( this.init ) { this.init.initialise( this.scope ); }
6636
6783
  if ( this.test ) { this.test.initialise( this.scope ); }
@@ -6645,15 +6792,20 @@ class ForStatement extends Statement {
6645
6792
  }
6646
6793
 
6647
6794
  initialiseScope ( parentScope ) {
6648
- this.scope = new Scope( {
6649
- parent: parentScope,
6650
- isBlockScope: true,
6651
- isLexicalBoundary: false
6652
- } );
6795
+ this.scope = new BlockScope( { parent: parentScope } );
6653
6796
  }
6654
6797
  }
6655
6798
 
6656
6799
  class ForInStatement extends Statement {
6800
+ hasEffects ( options ) {
6801
+ return (
6802
+ this.included
6803
+ || this.left && (this.left.hasEffects( options ) || this.left.hasEffectsWhenAssigned( options ))
6804
+ || this.right && this.right.hasEffects( options )
6805
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
6806
+ );
6807
+ }
6808
+
6657
6809
  initialiseChildren () {
6658
6810
  this.left.initialise( this.scope );
6659
6811
  this.right.initialise( this.scope.parent );
@@ -6662,19 +6814,40 @@ class ForInStatement extends Statement {
6662
6814
  this.body.initialise( this.scope );
6663
6815
  }
6664
6816
 
6817
+ includeInBundle () {
6818
+ let addedNewNodes = super.includeInBundle();
6819
+ if ( this.left.includeWithAllDeclarations() ) {
6820
+ addedNewNodes = true;
6821
+ }
6822
+ return addedNewNodes;
6823
+ }
6824
+
6665
6825
  initialiseScope ( parentScope ) {
6666
- this.scope = new Scope({
6667
- parent: parentScope,
6668
- isBlockScope: true,
6669
- isLexicalBoundary: false
6670
- });
6826
+ this.scope = new BlockScope( { parent: parentScope } );
6671
6827
  }
6672
6828
  }
6673
6829
 
6674
6830
  class ForOfStatement extends Statement {
6675
6831
  bind () {
6676
6832
  super.bind();
6677
- this.left.assignExpression( UNKNOWN_ASSIGNMENT );
6833
+ this.left.bindAssignment( UNKNOWN_ASSIGNMENT );
6834
+ }
6835
+
6836
+ hasEffects ( options ) {
6837
+ return (
6838
+ this.included
6839
+ || this.left && (this.left.hasEffects( options ) || this.left.hasEffectsWhenAssigned( options ))
6840
+ || this.right && this.right.hasEffects( options )
6841
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
6842
+ );
6843
+ }
6844
+
6845
+ includeInBundle () {
6846
+ let addedNewNodes = super.includeInBundle();
6847
+ if ( this.left.includeWithAllDeclarations() ) {
6848
+ addedNewNodes = true;
6849
+ }
6850
+ return addedNewNodes;
6678
6851
  }
6679
6852
 
6680
6853
  initialiseChildren () {
@@ -6686,45 +6859,65 @@ class ForOfStatement extends Statement {
6686
6859
  }
6687
6860
 
6688
6861
  initialiseScope ( parentScope ) {
6689
- this.scope = new Scope( {
6690
- parent: parentScope,
6691
- isBlockScope: true,
6692
- isLexicalBoundary: false
6693
- } );
6862
+ this.scope = new BlockScope( { parent: parentScope } );
6694
6863
  }
6695
6864
  }
6696
6865
 
6697
- class FunctionDeclaration extends Function$1 {
6698
- addReference () {}
6866
+ class FunctionScope extends Scope {
6867
+ constructor ( options ) {
6868
+ if ( options === void 0 ) options = {};
6699
6869
 
6700
- assignExpression ( expression ) {
6701
- this.assignedExpressions.add( expression );
6702
- this.isReassigned = true;
6870
+ super( options );
6871
+ this.variables.arguments = new ParameterVariable( 'arguments' );
6872
+ this.variables.this = new LocalVariable( 'this', null, null );
6873
+ }
6874
+
6875
+ findLexicalBoundary () {
6876
+ return this;
6703
6877
  }
6878
+ }
6879
+
6880
+ class FunctionNode extends Node$1 {
6881
+ bindCall ( ref ) {
6882
+ var withNew = ref.withNew;
6883
+
6884
+ const thisVariable = this.scope.findVariable( 'this' );
6704
6885
 
6705
- gatherPossibleValues ( values ) {
6706
- values.add( this );
6886
+ if ( withNew ) {
6887
+ thisVariable.assignExpression( UNKNOWN_OBJECT_LITERAL );
6888
+ } else {
6889
+ thisVariable.assignExpression( UNKNOWN_ASSIGNMENT );
6890
+ }
6707
6891
  }
6708
6892
 
6709
- getName () {
6710
- return this.name;
6893
+ hasEffects ( options ) {
6894
+ return this.included || (this.id && this.id.hasEffects( options ));
6711
6895
  }
6712
6896
 
6713
- initialiseChildren ( parentScope ) {
6714
- if ( this.id ) {
6715
- this.name = this.id.name; // may be overridden by bundle.deconflict
6716
- parentScope.addDeclaration( this.name, this, false, false );
6717
- this.id.initialise( parentScope );
6718
- }
6719
- super.initialiseChildren( parentScope );
6897
+ hasEffectsAsExpressionStatement ( options ) {
6898
+ return this.hasEffects( options );
6899
+ }
6900
+
6901
+ hasEffectsWhenCalled ( options ) {
6902
+ const innerOptions = options.setIgnoreSafeThisMutations();
6903
+ return this.params.some( param => param.hasEffects( innerOptions ) )
6904
+ || this.body.hasEffects( innerOptions );
6720
6905
  }
6721
6906
 
6722
6907
  hasEffectsWhenMutated () {
6723
6908
  return this.included;
6724
6909
  }
6725
6910
 
6726
- initialiseNode () {
6727
- this.assignedExpressions = new Set( [ this ] );
6911
+ initialiseScope ( parentScope ) {
6912
+ this.scope = new FunctionScope( { parent: parentScope } );
6913
+ }
6914
+ }
6915
+
6916
+ class FunctionDeclaration extends FunctionNode {
6917
+ initialiseChildren ( parentScope ) {
6918
+ this.id && this.id.initialiseAndDeclare( parentScope, 'function', this );
6919
+ this.params.forEach( param => param.initialiseAndDeclare( this.scope, 'parameter' ) );
6920
+ this.body.initialiseAndReplaceScope( new Scope( { parent: this.scope } ) );
6728
6921
  }
6729
6922
 
6730
6923
  render ( code, es ) {
@@ -6736,21 +6929,43 @@ class FunctionDeclaration extends Function$1 {
6736
6929
  }
6737
6930
  }
6738
6931
 
6739
- class FunctionExpression extends Function$1 {
6740
- addReference () {}
6932
+ class FunctionExpression extends FunctionNode {
6933
+ initialiseChildren () {
6934
+ this.id && this.id.initialiseAndDeclare( this.scope, 'function', this );
6935
+ this.params.forEach( param => param.initialiseAndDeclare( this.scope, 'parameter' ) );
6936
+ this.body.initialiseAndReplaceScope( new Scope( { parent: this.scope } ) );
6937
+ }
6938
+ }
6741
6939
 
6742
- getName () {
6743
- return this.name;
6940
+ function isReference (node, parent) {
6941
+ if (node.type === 'MemberExpression') {
6942
+ return !node.computed && isReference(node.object, node);
6744
6943
  }
6745
6944
 
6746
- initialiseChildren ( parentScope ) {
6747
- if ( this.id ) {
6748
- this.name = this.id.name; // may be overridden by bundle.deconflict
6749
- this.scope.addDeclaration( this.name, this, false, false );
6750
- this.id.initialise( this.scope );
6945
+ if (node.type === 'Identifier') {
6946
+ // the only time we could have an identifier node without a parent is
6947
+ // if it's the entire body of a function without a block statement –
6948
+ // i.e. an arrow function expression like `a => a`
6949
+ if (!parent) return true;
6950
+
6951
+ // TODO is this right?
6952
+ if (parent.type === 'MemberExpression' || parent.type === 'MethodDefinition') {
6953
+ return parent.computed || node === parent.object;
6751
6954
  }
6752
- super.initialiseChildren( parentScope );
6955
+
6956
+ // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
6957
+ if (parent.type === 'Property') return parent.computed || node === parent.value;
6958
+
6959
+ // disregard the `bar` in `class Foo { bar () {...} }`
6960
+ if (parent.type === 'MethodDefinition') return false;
6961
+
6962
+ // disregard the `bar` in `export { foo as bar }`
6963
+ if (parent.type === 'ExportSpecifier' && node !== parent.local) return false;
6964
+
6965
+ return true;
6753
6966
  }
6967
+
6968
+ return false;
6754
6969
  }
6755
6970
 
6756
6971
  function isAssignmentPatternLhs ( node, parent ) {
@@ -6769,49 +6984,74 @@ function isAssignmentPatternLhs ( node, parent ) {
6769
6984
  }
6770
6985
 
6771
6986
  class Identifier extends Node$1 {
6772
- assignExpression ( expression ) {
6773
- if ( this.declaration ) {
6774
- this.declaration.assignExpression( expression );
6987
+ bind () {
6988
+ if ( isReference( this, this.parent ) || isAssignmentPatternLhs( this, this.parent ) ) {
6989
+ this.variable = this.scope.findVariable( this.name );
6990
+ this.variable.addReference( this );
6775
6991
  }
6776
6992
  }
6777
6993
 
6778
- bind () {
6779
- if ( isReference( this, this.parent ) || isAssignmentPatternLhs( this, this.parent ) ) {
6780
- this.declaration = this.scope.findDeclaration( this.name );
6781
- this.declaration.addReference( this ); // TODO necessary?
6994
+ bindAssignment ( expression ) {
6995
+ if ( this.variable ) {
6996
+ this.variable.assignExpression( expression );
6782
6997
  }
6783
6998
  }
6784
6999
 
6785
- gatherPossibleValues ( values ) {
6786
- if ( isReference( this, this.parent ) ) {
6787
- values.add( this );
7000
+ bindCall ( callOptions ) {
7001
+ if ( this.variable ) {
7002
+ this.variable.addCall( callOptions );
6788
7003
  }
6789
7004
  }
6790
7005
 
7006
+ hasEffectsAsExpressionStatement ( options ) {
7007
+ return this.hasEffects( options ) || this.variable.isGlobal;
7008
+ }
7009
+
6791
7010
  hasEffectsWhenAssigned () {
6792
- return this.declaration && this.declaration.included;
7011
+ return this.variable && this.variable.included;
6793
7012
  }
6794
7013
 
6795
- hasEffectsWhenMutated () {
6796
- return this.declaration &&
6797
- (this.declaration.included ||
6798
- this.declaration.isParam ||
6799
- this.declaration.isGlobal ||
6800
- this.declaration.isExternal ||
6801
- this.declaration.isNamespace ||
6802
- Array.from( this.declaration.assignedExpressions ).some( node => node.hasEffectsWhenMutated() ));
7014
+ hasEffectsWhenCalled ( options ) {
7015
+ if ( !this.variable ) {
7016
+ return true;
7017
+ }
7018
+ return this.variable.hasEffectsWhenCalled( options );
7019
+ }
7020
+
7021
+ hasEffectsWhenMutated ( options ) {
7022
+ return this.variable && this.variable.hasEffectsWhenMutated( options );
6803
7023
  }
6804
7024
 
6805
7025
  includeInBundle () {
6806
7026
  if ( this.included ) { return false; }
6807
7027
  this.included = true;
6808
- this.declaration && this.declaration.includeDeclaration();
7028
+ this.variable && this.variable.includeVariable();
6809
7029
  return true;
6810
7030
  }
6811
7031
 
7032
+ initialiseAndDeclare ( parentScope, kind, init ) {
7033
+ this.initialiseScope( parentScope );
7034
+ switch ( kind ) {
7035
+ case 'var':
7036
+ case 'function':
7037
+ this.scope.addDeclaration( this, true, init );
7038
+ break;
7039
+ case 'let':
7040
+ case 'const':
7041
+ case 'class':
7042
+ this.scope.addDeclaration( this, false, init );
7043
+ break;
7044
+ case 'parameter':
7045
+ this.scope.addParameterDeclaration( this );
7046
+ break;
7047
+ default:
7048
+ throw new Error( 'Unexpected identifier kind', kind );
7049
+ }
7050
+ }
7051
+
6812
7052
  render ( code, es ) {
6813
- if ( this.declaration ) {
6814
- const name = this.declaration.getName( es );
7053
+ if ( this.variable ) {
7054
+ const name = this.variable.getName( es );
6815
7055
  if ( name !== this.name ) {
6816
7056
  code.overwrite( this.start, this.end, name, { storeName: true, contentOnly: false } );
6817
7057
 
@@ -6834,7 +7074,7 @@ const statementsWithIfStatements = new Set( [
6834
7074
  'WhileStatement'
6835
7075
  ] );
6836
7076
 
6837
- function handleVarDeclarations ( node, scope ) {
7077
+ function getHoistedVars ( node, scope ) {
6838
7078
  const hoistedVars = [];
6839
7079
 
6840
7080
  function visit ( node ) {
@@ -6844,7 +7084,7 @@ function handleVarDeclarations ( node, scope ) {
6844
7084
  declarator.initialise( scope );
6845
7085
 
6846
7086
  extractNames( declarator.id ).forEach( name => {
6847
- if ( !~hoistedVars.indexOf( name ) ) { hoistedVars.push( name ); }
7087
+ if ( hoistedVars.indexOf( name ) < 0 ) { hoistedVars.push( name ); }
6848
7088
  } );
6849
7089
  } );
6850
7090
  }
@@ -6859,29 +7099,24 @@ function handleVarDeclarations ( node, scope ) {
6859
7099
  return hoistedVars;
6860
7100
  }
6861
7101
 
6862
- // TODO DRY this out
6863
7102
  class IfStatement extends Statement {
6864
7103
  initialiseChildren ( parentScope ) {
7104
+ super.initialiseChildren( parentScope );
6865
7105
  if ( this.module.bundle.treeshake ) {
6866
7106
  this.testValue = this.test.getValue();
6867
7107
 
6868
7108
  if ( this.testValue === UNKNOWN_VALUE ) {
6869
- super.initialiseChildren( parentScope );
6870
- } else if ( this.testValue ) {
6871
- this.consequent.initialise( this.scope );
7109
+ return;
7110
+ }
7111
+ if ( this.testValue ) {
6872
7112
  if ( this.alternate ) {
6873
- this.hoistedVars = handleVarDeclarations( this.alternate, this.scope );
7113
+ this.hoistedVars = getHoistedVars( this.alternate, this.scope );
6874
7114
  this.alternate = null;
6875
7115
  }
6876
7116
  } else {
6877
- if ( this.alternate ) {
6878
- this.alternate.initialise( this.scope );
6879
- }
6880
- this.hoistedVars = handleVarDeclarations( this.consequent, this.scope );
7117
+ this.hoistedVars = getHoistedVars( this.consequent, this.scope );
6881
7118
  this.consequent = null;
6882
7119
  }
6883
- } else {
6884
- super.initialiseChildren( parentScope );
6885
7120
  }
6886
7121
  }
6887
7122
 
@@ -6900,8 +7135,8 @@ class IfStatement extends Statement {
6900
7135
  if ( this.hoistedVars ) {
6901
7136
  const names = this.hoistedVars
6902
7137
  .map( name => {
6903
- const declaration = this.scope.findDeclaration( name );
6904
- return declaration.included ? declaration.getName() : null;
7138
+ const variable = this.scope.findVariable( name );
7139
+ return variable.included ? variable.getName() : null;
6905
7140
  } )
6906
7141
  .filter( Boolean );
6907
7142
 
@@ -6951,13 +7186,23 @@ class ImportDeclaration extends Node$1 {
6951
7186
  }
6952
7187
  }
6953
7188
 
7189
+ class LabeledStatement extends Statement {
7190
+ hasEffects ( options ) {
7191
+ return this.body.hasEffects(
7192
+ options
7193
+ .setIgnoreLabel( this.label.name )
7194
+ .setIgnoreBreakStatements()
7195
+ );
7196
+ }
7197
+ }
7198
+
6954
7199
  class Literal extends Node$1 {
6955
7200
  getValue () {
6956
7201
  return this.value;
6957
7202
  }
6958
7203
 
6959
- gatherPossibleValues ( values ) {
6960
- values.add( this );
7204
+ hasEffectsWhenMutated () {
7205
+ return false;
6961
7206
  }
6962
7207
 
6963
7208
  render ( code ) {
@@ -6980,9 +7225,77 @@ class LogicalExpression extends Node$1 {
6980
7225
  const rightValue = this.right.getValue();
6981
7226
  if ( rightValue === UNKNOWN_VALUE ) { return UNKNOWN_VALUE; }
6982
7227
 
6983
- return operators$1[ this.operator ]( leftValue, rightValue );
6984
- }
6985
- }
7228
+ return operators$1[ this.operator ]( leftValue, rightValue );
7229
+ }
7230
+
7231
+ hasEffectsWhenMutated ( options ) {
7232
+ const leftValue = this.left.getValue();
7233
+ if ( leftValue === UNKNOWN_VALUE ) {
7234
+ return this.left.hasEffectsWhenMutated( options ) || this.right.hasEffectsWhenMutated( options );
7235
+ }
7236
+ if ((leftValue && this.operator === '||') || (!leftValue && this.operator === '&&')) {
7237
+ return this.left.hasEffectsWhenMutated( options );
7238
+ }
7239
+ return this.right.hasEffectsWhenMutated( options );
7240
+ }
7241
+ }
7242
+
7243
+ function flatten ( node ) {
7244
+ const parts = [];
7245
+ while ( node.type === 'MemberExpression' ) {
7246
+ if ( node.computed ) { return null; }
7247
+ parts.unshift( node.property.name );
7248
+
7249
+ node = node.object;
7250
+ }
7251
+
7252
+ if ( node.type !== 'Identifier' ) { return null; }
7253
+
7254
+ const name = node.name;
7255
+ parts.unshift( name );
7256
+
7257
+ return { name, keypath: parts.join( '.' ) };
7258
+ }
7259
+
7260
+ const pureFunctions = {};
7261
+
7262
+ const arrayTypes = 'Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split( ' ' );
7263
+ const simdTypes = 'Int8x16 Int16x8 Int32x4 Float32x4 Float64x2'.split( ' ' );
7264
+ const simdMethods = 'abs add and bool check div equal extractLane fromFloat32x4 fromFloat32x4Bits fromFloat64x2 fromFloat64x2Bits fromInt16x8Bits fromInt32x4 fromInt32x4Bits fromInt8x16Bits greaterThan greaterThanOrEqual lessThan lessThanOrEqual load max maxNum min minNum mul neg not notEqual or reciprocalApproximation reciprocalSqrtApproximation replaceLane select selectBits shiftLeftByScalar shiftRightArithmeticByScalar shiftRightLogicalByScalar shuffle splat sqrt store sub swizzle xor'.split( ' ' );
7265
+ const allSimdMethods = [];
7266
+ simdTypes.forEach( t => {
7267
+ simdMethods.forEach( m => {
7268
+ allSimdMethods.push( `SIMD.${t}.${m}` );
7269
+ });
7270
+ });
7271
+
7272
+ [
7273
+ 'Array.isArray',
7274
+ 'Error', 'EvalError', 'InternalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError',
7275
+ 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape', 'unescape',
7276
+ 'Object', 'Object.create', 'Object.getNotifier', 'Object.getOwn', 'Object.getOwnPropertyDescriptor', 'Object.getOwnPropertyNames', 'Object.getOwnPropertySymbols', 'Object.getPrototypeOf', 'Object.is', 'Object.isExtensible', 'Object.isFrozen', 'Object.isSealed', 'Object.keys',
7277
+ 'Function', 'Boolean',
7278
+ 'Number', 'Number.isFinite', 'Number.isInteger', 'Number.isNaN', 'Number.isSafeInteger', 'Number.parseFloat', 'Number.parseInt',
7279
+ 'Symbol', 'Symbol.for', 'Symbol.keyFor',
7280
+ 'Math.abs', 'Math.acos', 'Math.acosh', 'Math.asin', 'Math.asinh', 'Math.atan', 'Math.atan2', 'Math.atanh', 'Math.cbrt', 'Math.ceil', 'Math.clz32', 'Math.cos', 'Math.cosh', 'Math.exp', 'Math.expm1', 'Math.floor', 'Math.fround', 'Math.hypot', 'Math.imul', 'Math.log', 'Math.log10', 'Math.log1p', 'Math.log2', 'Math.max', 'Math.min', 'Math.pow', 'Math.random', 'Math.round', 'Math.sign', 'Math.sin', 'Math.sinh', 'Math.sqrt', 'Math.tan', 'Math.tanh', 'Math.trunc',
7281
+ 'Date', 'Date.UTC', 'Date.now', 'Date.parse',
7282
+ 'String', 'String.fromCharCode', 'String.fromCodePoint', 'String.raw',
7283
+ 'RegExp',
7284
+ 'Map', 'Set', 'WeakMap', 'WeakSet',
7285
+ 'ArrayBuffer', 'ArrayBuffer.isView',
7286
+ 'DataView',
7287
+ 'JSON.parse', 'JSON.stringify',
7288
+ 'Promise.all', 'Promise.race', 'Promise.resolve',
7289
+ 'Intl.Collator', 'Intl.Collator.supportedLocalesOf', 'Intl.DateTimeFormat', 'Intl.DateTimeFormat.supportedLocalesOf', 'Intl.NumberFormat', 'Intl.NumberFormat.supportedLocalesOf'
7290
+
7291
+ // TODO properties of e.g. window...
7292
+ ].concat(
7293
+ arrayTypes,
7294
+ arrayTypes.map( t => `${t}.from` ),
7295
+ arrayTypes.map( t => `${t}.of` ),
7296
+ simdTypes.map( t => `SIMD.${t}` ),
7297
+ allSimdMethods
7298
+ ).forEach( name => pureFunctions[ name ] = true );
6986
7299
 
6987
7300
  const validProp = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
6988
7301
 
@@ -7016,15 +7329,15 @@ class MemberExpression extends Node$1 {
7016
7329
  const keypath = new Keypath( this );
7017
7330
 
7018
7331
  if ( !keypath.computed && keypath.root.type === 'Identifier' ) {
7019
- let declaration = this.scope.findDeclaration( keypath.root.name );
7332
+ let variable = this.scope.findVariable( keypath.root.name );
7020
7333
 
7021
- while ( declaration.isNamespace && keypath.parts.length ) {
7022
- const exporterId = declaration.module.id;
7334
+ while ( variable.isNamespace && keypath.parts.length ) {
7335
+ const exporterId = variable.module.id;
7023
7336
 
7024
7337
  const part = keypath.parts[ 0 ];
7025
- declaration = declaration.module.traceExport( part.name || part.value );
7338
+ variable = variable.module.traceExport( part.name || part.value );
7026
7339
 
7027
- if ( !declaration ) {
7340
+ if ( !variable ) {
7028
7341
  this.module.warn( {
7029
7342
  code: 'MISSING_EXPORT',
7030
7343
  missing: part.name || part.value,
@@ -7045,10 +7358,10 @@ class MemberExpression extends Node$1 {
7045
7358
  return; // not a namespaced declaration
7046
7359
  }
7047
7360
 
7048
- this.declaration = declaration;
7361
+ this.variable = variable;
7049
7362
 
7050
- if ( declaration.isExternal ) {
7051
- declaration.module.suggestName( keypath.root.name );
7363
+ if ( variable.isExternal ) {
7364
+ variable.module.suggestName( keypath.root.name );
7052
7365
  }
7053
7366
  }
7054
7367
 
@@ -7057,30 +7370,39 @@ class MemberExpression extends Node$1 {
7057
7370
  }
7058
7371
  }
7059
7372
 
7060
- gatherPossibleValues ( values ) {
7061
- values.add( UNKNOWN_ASSIGNMENT ); // TODO
7062
- }
7063
-
7064
- hasEffectsWhenAssigned () {
7065
- return this.object.hasEffectsWhenMutated();
7373
+ bindCall ( callOptions ) {
7374
+ if ( this.variable ) {
7375
+ this.variable.addCall( callOptions );
7376
+ }
7066
7377
  }
7067
7378
 
7068
- hasEffectsWhenMutated () {
7069
- return true;
7379
+ hasEffectsWhenAssigned ( options ) {
7380
+ return this.object.hasEffectsWhenMutated( options );
7070
7381
  }
7071
7382
 
7072
7383
  includeInBundle () {
7073
7384
  let addedNewNodes = super.includeInBundle();
7074
- if ( this.declaration && !this.declaration.included ) {
7075
- this.declaration.includeDeclaration();
7385
+ if ( this.variable && !this.variable.included ) {
7386
+ this.variable.includeVariable();
7076
7387
  addedNewNodes = true;
7077
7388
  }
7078
7389
  return addedNewNodes;
7079
7390
  }
7080
7391
 
7392
+ hasEffectsWhenCalled ( options ) {
7393
+ if ( this.variable ) {
7394
+ return this.variable.hasEffectsWhenCalled( options );
7395
+ }
7396
+ if ( !isReference( this ) ) {
7397
+ return true;
7398
+ }
7399
+ const flattenedNode = flatten( this );
7400
+ return !(this.scope.findVariable( flattenedNode.name ).isGlobal && pureFunctions[ flattenedNode.keypath ]);
7401
+ }
7402
+
7081
7403
  render ( code, es ) {
7082
- if ( this.declaration ) {
7083
- const name = this.declaration.getName( es );
7404
+ if ( this.variable ) {
7405
+ const name = this.variable.getName( es );
7084
7406
  if ( name !== this.name ) { code.overwrite( this.start, this.end, name, { storeName: true, contentOnly: false } ); }
7085
7407
  }
7086
7408
 
@@ -7092,29 +7414,67 @@ class MemberExpression extends Node$1 {
7092
7414
  }
7093
7415
  }
7094
7416
 
7417
+ class MethodDefinition extends Node$1 {
7418
+ bindCall ( callOptions ) {
7419
+ this.value.bindCall( callOptions );
7420
+ }
7421
+
7422
+ hasEffects ( options ) {
7423
+ return this.key.hasEffects( options );
7424
+ }
7425
+
7426
+ hasEffectsWhenCalled ( options ) {
7427
+ return this.value.hasEffectsWhenCalled( options );
7428
+ }
7429
+ }
7430
+
7095
7431
  class NewExpression extends Node$1 {
7096
- hasEffects () {
7097
- return this.included || callHasEffects( this.scope, this.callee, true );
7432
+ bind () {
7433
+ super.bind();
7434
+ this.callee.bindCall( { withNew: true } );
7435
+ }
7436
+
7437
+ hasEffects ( options ) {
7438
+ return this.included
7439
+ || this.arguments.some( child => child.hasEffects( options ) )
7440
+ || this.callee.hasEffectsWhenCalled( options.getHasEffectsWhenCalledOptions( this.callee ) );
7441
+ }
7442
+ }
7443
+
7444
+ class ObjectExpression extends Node$1 {
7445
+ hasEffectsWhenMutated () {
7446
+ return false;
7098
7447
  }
7099
7448
  }
7100
7449
 
7101
7450
  class ObjectPattern extends Node$1 {
7102
- assignExpression () {
7103
- this.eachChild( child => child.assignExpression( UNKNOWN_ASSIGNMENT ) );
7451
+ bindAssignment ( expression ) {
7452
+ this.properties.forEach( child => child.bindAssignment( expression ) );
7104
7453
  }
7105
7454
 
7106
- hasEffectsWhenAssigned () {
7107
- return this.someChild( child => child.hasEffectsWhenAssigned() );
7455
+ hasEffectsWhenAssigned ( options ) {
7456
+ return this.someChild( child => child.hasEffectsWhenAssigned( options ) );
7457
+ }
7458
+
7459
+ initialiseAndDeclare ( parentScope, kind, init ) {
7460
+ this.initialiseScope( parentScope );
7461
+ this.properties.forEach( child => child.initialiseAndDeclare( parentScope, kind, init ) );
7108
7462
  }
7109
7463
  }
7110
7464
 
7111
7465
  class Property extends Node$1 {
7112
- assignExpression ( expression ) {
7113
- this.value.assignExpression( expression );
7466
+ bindAssignment () {
7467
+ this.value.bindAssignment( UNKNOWN_ASSIGNMENT );
7114
7468
  }
7115
7469
 
7116
- hasEffectsWhenAssigned () {
7117
- return this.value.hasEffectsWhenAssigned();
7470
+ hasEffectsWhenAssigned ( options ) {
7471
+ return this.value.hasEffectsWhenAssigned( options );
7472
+ }
7473
+
7474
+ initialiseAndDeclare ( parentScope, kind, init ) {
7475
+ this.initialiseScope( parentScope );
7476
+ this.key.initialise( parentScope );
7477
+ this.value.initialiseAndDeclare( parentScope, kind, init && UNKNOWN_ASSIGNMENT );
7118
7478
  }
7119
7479
 
7120
7480
  render ( code, es ) {
@@ -7126,45 +7486,73 @@ class Property extends Node$1 {
7126
7486
  }
7127
7487
 
7128
7488
  class RestElement extends Node$1 {
7129
- assignExpression () {
7130
- this.argument.assignExpression( UNKNOWN_ASSIGNMENT );
7489
+ bindAssignment () {
7490
+ this.argument.bindAssignment( UNKNOWN_ASSIGNMENT );
7131
7491
  }
7132
7492
 
7133
- hasEffectsWhenAssigned () {
7134
- return this.argument.hasEffectsWhenAssigned();
7493
+ hasEffectsWhenAssigned ( options ) {
7494
+ return this.argument.hasEffectsWhenAssigned( options );
7495
+ }
7496
+
7497
+ initialiseAndDeclare ( parentScope, kind ) {
7498
+ this.initialiseScope( parentScope );
7499
+ this.argument.initialiseAndDeclare( parentScope, kind, UNKNOWN_ASSIGNMENT );
7135
7500
  }
7136
7501
  }
7137
7502
 
7138
7503
  class ReturnStatement extends Statement {
7139
- shouldBeIncluded () {
7140
- return true;
7504
+ hasEffects ( options ) {
7505
+ return super.hasEffects( options )
7506
+ || !options.ignoreReturnAwaitYield();
7507
+ }
7508
+ }
7509
+
7510
+ class SwitchCase extends Node$1 {
7511
+ includeInBundle () {
7512
+ if ( this.isFullyIncluded() ) { return false; }
7513
+ let addedNewNodes = false;
7514
+ if (this.test && this.test.includeInBundle()) {
7515
+ addedNewNodes = true;
7516
+ }
7517
+ this.consequent.forEach( node => {
7518
+ if ( node.shouldBeIncluded() ) {
7519
+ if ( node.includeInBundle() ) {
7520
+ addedNewNodes = true;
7521
+ }
7522
+ }
7523
+ } );
7524
+ if ( !this.included || addedNewNodes ) {
7525
+ this.included = true;
7526
+ return true;
7527
+ }
7528
+ return false;
7141
7529
  }
7142
7530
  }
7143
7531
 
7144
7532
  class SwitchStatement extends Statement {
7533
+ hasEffects ( options ) {
7534
+ return super.hasEffects( options.setIgnoreBreakStatements() );
7535
+ }
7536
+
7145
7537
  initialiseScope ( parentScope ) {
7146
- this.scope = new Scope( {
7147
- parent: parentScope,
7148
- isBlockScope: true,
7149
- isLexicalBoundary: false
7150
- } );
7538
+ this.scope = new BlockScope( { parent: parentScope } );
7151
7539
  }
7152
7540
  }
7153
7541
 
7154
7542
  class TaggedTemplateExpression extends Node$1 {
7155
7543
  bind () {
7156
7544
  if ( this.tag.type === 'Identifier' ) {
7157
- const declaration = this.scope.findDeclaration( this.tag.name );
7545
+ const variable = this.scope.findVariable( this.tag.name );
7158
7546
 
7159
- if ( declaration.isNamespace ) {
7160
- this.module.error({
7547
+ if ( variable.isNamespace ) {
7548
+ this.module.error( {
7161
7549
  code: 'CANNOT_CALL_NAMESPACE',
7162
7550
  message: `Cannot call a namespace ('${this.tag.name}')`
7163
7551
  }, this.start );
7164
7552
  }
7165
7553
 
7166
- if ( this.tag.name === 'eval' && declaration.isGlobal ) {
7167
- this.module.warn({
7554
+ if ( this.tag.name === 'eval' && variable.isGlobal ) {
7555
+ this.module.warn( {
7168
7556
  code: 'EVAL',
7169
7557
  message: `Use of eval is strongly discouraged, as it poses security risks and may cause issues with minification`,
7170
7558
  url: 'https://github.com/rollup/rollup/wiki/Troubleshooting#avoiding-eval'
@@ -7173,10 +7561,18 @@ class TaggedTemplateExpression extends Node$1 {
7173
7561
  }
7174
7562
 
7175
7563
  super.bind();
7564
+ this.tag.bindCall( { withNew: false } );
7176
7565
  }
7177
7566
 
7178
- hasEffects () {
7179
- return this.quasi.hasEffects() || callHasEffects( this.scope, this.tag, false );
7567
+ hasEffects ( options ) {
7568
+ return super.hasEffects( options )
7569
+ || this.tag.hasEffectsWhenCalled( options.getHasEffectsWhenCalledOptions( this.tag ) );
7570
+ }
7571
+ }
7572
+
7573
+ class TemplateElement extends Node$1 {
7574
+ hasEffects() {
7575
+ return false;
7180
7576
  }
7181
7577
  }
7182
7578
 
@@ -7188,10 +7584,6 @@ class TemplateLiteral extends Node$1 {
7188
7584
  }
7189
7585
 
7190
7586
  class ThisExpression extends Node$1 {
7191
- hasEffectsWhenMutated () {
7192
- return true;
7193
- }
7194
-
7195
7587
  initialiseNode () {
7196
7588
  const lexicalBoundary = this.scope.findLexicalBoundary();
7197
7589
 
@@ -7207,6 +7599,14 @@ class ThisExpression extends Node$1 {
7207
7599
  }
7208
7600
  }
7209
7601
 
7602
+ bind () {
7603
+ this.variable = this.scope.findVariable( 'this' );
7604
+ }
7605
+
7606
+ hasEffectsWhenMutated ( options ) {
7607
+ return !options.ignoreSafeThisMutations() || this.variable.hasEffectsWhenMutated( options );
7608
+ }
7609
+
7210
7610
  render ( code ) {
7211
7611
  if ( this.alias ) {
7212
7612
  code.overwrite( this.start, this.end, this.alias, { storeName: true, contentOnly: false } );
@@ -7242,15 +7642,19 @@ class UnaryExpression extends Node$1 {
7242
7642
  return operators$2[ this.operator ]( argumentValue );
7243
7643
  }
7244
7644
 
7245
- hasEffects () {
7645
+ hasEffects ( options ) {
7246
7646
  return this.included
7247
- || this.argument.hasEffects()
7647
+ || this.argument.hasEffects( options )
7248
7648
  || (this.operator === 'delete' && (
7249
7649
  this.argument.type !== 'MemberExpression'
7250
- || this.argument.object.hasEffectsWhenMutated()
7650
+ || this.argument.object.hasEffectsWhenMutated( options )
7251
7651
  ));
7252
7652
  }
7253
7653
 
7654
+ hasEffectsAsExpressionStatement ( options ) {
7655
+ return this.hasEffects( options );
7656
+ }
7657
+
7254
7658
  initialiseNode () {
7255
7659
  this.value = this.getValue();
7256
7660
  }
@@ -7260,99 +7664,40 @@ class UpdateExpression extends Node$1 {
7260
7664
  bind () {
7261
7665
  disallowIllegalReassignment( this.scope, this.argument );
7262
7666
  if ( this.argument.type === 'Identifier' ) {
7263
- const declaration = this.scope.findDeclaration( this.argument.name );
7264
- declaration.isReassigned = true;
7667
+ const variable = this.scope.findVariable( this.argument.name );
7668
+ variable.isReassigned = true;
7265
7669
  }
7266
7670
  super.bind();
7267
7671
  }
7268
7672
 
7269
- hasEffects () {
7270
- return this.included || this.argument.hasEffectsWhenAssigned();
7271
- }
7272
- }
7273
-
7274
- class DeclaratorProxy {
7275
- constructor ( name, declarator, isTopLevel, init ) {
7276
- this.name = name;
7277
- this.declarator = declarator;
7278
-
7279
- this.isReassigned = false;
7280
- this.exportName = null;
7281
-
7282
- this.duplicates = [];
7283
- this.assignedExpressions = new Set( init ? [ init ] : null );
7284
- }
7285
-
7286
- addReference () {
7287
- /* noop? */
7288
- }
7289
-
7290
- assignExpression ( expression ) {
7291
- this.assignedExpressions.add( expression );
7292
- this.isReassigned = true;
7293
- }
7294
-
7295
- gatherPossibleValues ( values ) {
7296
- this.assignedExpressions.forEach( value => values.add( value ) );
7297
- }
7298
-
7299
- getName ( es ) {
7300
- // TODO destructuring...
7301
- if ( es ) { return this.name; }
7302
- if ( !this.isReassigned || !this.exportName ) { return this.name; }
7303
-
7304
- return `exports.${this.exportName}`;
7305
- }
7306
-
7307
- includeDeclaration () {
7308
- if ( this.included ) {
7309
- return false;
7310
- }
7311
- this.included = true;
7312
- this.declarator.includeDeclaration();
7313
- this.duplicates.forEach( duplicate => duplicate.includeDeclaration() );
7314
- return true;
7673
+ hasEffects ( options ) {
7674
+ return this.included || this.argument.hasEffectsWhenAssigned( options );
7315
7675
  }
7316
7676
 
7317
- toString () {
7318
- return this.name;
7677
+ hasEffectsAsExpressionStatement ( options ) {
7678
+ return this.hasEffects( options );
7319
7679
  }
7320
7680
  }
7321
7681
 
7322
7682
  class VariableDeclarator extends Node$1 {
7323
- assignExpression () {
7324
- for ( const proxy of this.proxies.values() ) {
7325
- proxy.assignExpression( UNKNOWN_ASSIGNMENT );
7326
- }
7327
- }
7328
-
7329
- hasEffects () {
7330
- return super.hasEffects()
7331
- || extractNames( this.id ).some( name => this.proxies.get( name ).included );
7683
+ bindAssignment ( expression ) {
7684
+ this.id.bindAssignment( expression );
7332
7685
  }
7333
7686
 
7334
- initialiseNode () {
7335
- this.proxies = new Map();
7336
- const lexicalBoundary = this.scope.findLexicalBoundary();
7337
- const init = this.init
7338
- ? ( this.id.type === 'Identifier' ? this.init : UNKNOWN_ASSIGNMENT )
7339
- : null;
7340
-
7341
- extractNames( this.id ).forEach( name => {
7342
- const proxy = new DeclaratorProxy( name, this, lexicalBoundary.isModuleScope, init );
7343
-
7344
- this.proxies.set( name, proxy );
7345
- this.scope.addDeclaration( name, proxy, this.parent.kind === 'var' );
7346
- } );
7687
+ initialiseDeclarator ( parentScope, kind ) {
7688
+ this.initialiseScope( parentScope );
7689
+ this.init && this.init.initialise( this.scope );
7690
+ this.id.initialiseAndDeclare( this.scope, kind, this.init );
7347
7691
  }
7348
7692
 
7693
+ // TODO Deleting this does not break any tests. Find meaningful test or delete.
7349
7694
  render ( code, es ) {
7350
7695
  extractNames( this.id ).forEach( name => {
7351
- const declaration = this.proxies.get( name );
7696
+ const variable = this.scope.findVariable( name );
7352
7697
 
7353
- if ( !es && declaration.exportName && declaration.isReassigned ) {
7698
+ if ( !es && variable.exportName && variable.isReassigned ) {
7354
7699
  if ( this.init ) {
7355
- code.overwrite( this.start, this.id.end, declaration.getName( es ) );
7700
+ code.overwrite( this.start, this.id.end, variable.getName( es ) );
7356
7701
  } else if ( this.module.bundle.treeshake ) {
7357
7702
  code.remove( this.start, this.end );
7358
7703
  }
@@ -7379,8 +7724,27 @@ function getSeparator ( code, start ) {
7379
7724
  const forStatement = /^For(?:Of|In)?Statement/;
7380
7725
 
7381
7726
  class VariableDeclaration extends Node$1 {
7382
- assignExpression () {
7383
- this.eachChild( child => child.assignExpression( UNKNOWN_ASSIGNMENT ) );
7727
+ bindAssignment () {
7728
+ this.eachChild( child => child.bindAssignment( UNKNOWN_ASSIGNMENT ) );
7729
+ }
7730
+
7731
+ hasEffectsWhenAssigned () {
7732
+ return false;
7733
+ }
7734
+
7735
+ includeWithAllDeclarations () {
7736
+ if ( this.isFullyIncluded() ) { return false; }
7737
+ let addedNewNodes = false;
7738
+ this.declarations.forEach( declarator => {
7739
+ if ( declarator.includeInBundle() ) {
7740
+ addedNewNodes = true;
7741
+ }
7742
+ } );
7743
+ if ( !this.included || addedNewNodes ) {
7744
+ this.included = true;
7745
+ return true;
7746
+ }
7747
+ return false;
7384
7748
  }
7385
7749
 
7386
7750
  includeInBundle () {
@@ -7400,6 +7764,10 @@ class VariableDeclaration extends Node$1 {
7400
7764
  return false;
7401
7765
  }
7402
7766
 
7767
+ initialiseChildren () {
7768
+ this.declarations.forEach( child => child.initialiseDeclarator( this.scope, this.kind ) );
7769
+ }
7770
+
7403
7771
  render ( code, es ) {
7404
7772
  const treeshake = this.module.bundle.treeshake;
7405
7773
 
@@ -7420,8 +7788,8 @@ class VariableDeclaration extends Node$1 {
7420
7788
  const prefix = empty ? '' : separator; // TODO indentation
7421
7789
 
7422
7790
  if ( declarator.id.type === 'Identifier' ) {
7423
- const proxy = declarator.proxies.get( declarator.id.name );
7424
- const isExportedAndReassigned = !es && proxy.exportName && proxy.isReassigned;
7791
+ const variable = this.scope.findVariable( declarator.id.name );
7792
+ const isExportedAndReassigned = !es && variable.exportName && variable.isReassigned;
7425
7793
 
7426
7794
  if ( isExportedAndReassigned ) {
7427
7795
  if ( declarator.init ) {
@@ -7429,7 +7797,7 @@ class VariableDeclaration extends Node$1 {
7429
7797
  c = declarator.end;
7430
7798
  empty = false;
7431
7799
  }
7432
- } else if ( !treeshake || proxy.included ) {
7800
+ } else if ( !treeshake || variable.included ) {
7433
7801
  if ( shouldSeparate ) { code.overwrite( c, declarator.start, `${prefix}${this.kind} ` ); } // TODO indentation
7434
7802
  c = declarator.end;
7435
7803
  empty = false;
@@ -7439,8 +7807,8 @@ class VariableDeclaration extends Node$1 {
7439
7807
  let isIncluded = false;
7440
7808
 
7441
7809
  extractNames( declarator.id ).forEach( name => {
7442
- const proxy = declarator.proxies.get( name );
7443
- const isExportedAndReassigned = !es && proxy.exportName && proxy.isReassigned;
7810
+ const variable = this.scope.findVariable( name );
7811
+ const isExportedAndReassigned = !es && variable.exportName && variable.isReassigned;
7444
7812
 
7445
7813
  if ( isExportedAndReassigned ) {
7446
7814
  // code.overwrite( c, declarator.start, prefix );
@@ -7482,18 +7850,44 @@ class VariableDeclaration extends Node$1 {
7482
7850
  }
7483
7851
  }
7484
7852
 
7853
+ class WhileStatement extends Statement {
7854
+ hasEffects ( options ) {
7855
+ return (
7856
+ this.included
7857
+ || this.test.hasEffects( options )
7858
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
7859
+ );
7860
+ }
7861
+ }
7862
+
7863
+ class YieldExpression extends Node$1 {
7864
+ hasEffects ( options ) {
7865
+ return super.hasEffects( options )
7866
+ || !options.ignoreReturnAwaitYield();
7867
+ }
7868
+
7869
+ hasEffectsAsExpressionStatement ( options ) {
7870
+ return this.hasEffects( options );
7871
+ }
7872
+ }
7873
+
7485
7874
  var nodes = {
7875
+ ArrayExpression: Node$1,
7486
7876
  ArrayPattern,
7487
7877
  ArrowFunctionExpression,
7488
7878
  AssignmentExpression,
7879
+ AssignmentPattern,
7880
+ AwaitExpression,
7489
7881
  BinaryExpression,
7490
7882
  BlockStatement,
7883
+ BreakStatement,
7491
7884
  CallExpression,
7492
7885
  CatchClause,
7886
+ ClassBody,
7493
7887
  ClassDeclaration,
7494
7888
  ClassExpression,
7495
7889
  ConditionalExpression,
7496
- DoWhileStatement: Statement,
7890
+ DoWhileStatement,
7497
7891
  EmptyStatement,
7498
7892
  ExportAllDeclaration,
7499
7893
  ExportDefaultDeclaration,
@@ -7507,16 +7901,21 @@ var nodes = {
7507
7901
  Identifier,
7508
7902
  IfStatement,
7509
7903
  ImportDeclaration,
7904
+ LabeledStatement,
7510
7905
  Literal,
7511
7906
  LogicalExpression,
7512
7907
  MemberExpression,
7908
+ MethodDefinition,
7513
7909
  NewExpression,
7910
+ ObjectExpression,
7514
7911
  ObjectPattern,
7515
7912
  Property,
7516
7913
  RestElement,
7517
7914
  ReturnStatement,
7915
+ SwitchCase,
7518
7916
  SwitchStatement,
7519
7917
  TaggedTemplateExpression,
7918
+ TemplateElement,
7520
7919
  TemplateLiteral,
7521
7920
  ThisExpression,
7522
7921
  ThrowStatement,
@@ -7525,9 +7924,16 @@ var nodes = {
7525
7924
  UpdateExpression,
7526
7925
  VariableDeclarator,
7527
7926
  VariableDeclaration,
7528
- WhileStatement: Statement
7927
+ WhileStatement,
7928
+ YieldExpression
7529
7929
  };
7530
7930
 
7931
+ class UnknownNode extends Node$1 {
7932
+ hasEffects () {
7933
+ return true;
7934
+ }
7935
+ }
7936
+
7531
7937
  var keys$1 = {
7532
7938
  Program: [ 'body' ],
7533
7939
  Literal: []
@@ -7589,7 +7995,7 @@ function enhanceNode ( raw, parent, module, code ) {
7589
7995
  enhanceNode( raw[ key ], raw, module, code );
7590
7996
  }
7591
7997
 
7592
- const type = nodes[ raw.type ] || Node$1;
7998
+ const type = nodes[ raw.type ] || UnknownNode;
7593
7999
  raw.__proto__ = type.prototype;
7594
8000
  }
7595
8001
 
@@ -7613,14 +8019,13 @@ function clone ( node ) {
7613
8019
 
7614
8020
  class ModuleScope extends Scope {
7615
8021
  constructor ( module ) {
7616
- super({
7617
- isBlockScope: false,
7618
- isLexicalBoundary: true,
8022
+ super( {
7619
8023
  isModuleScope: true,
7620
8024
  parent: module.bundle.scope
7621
- });
8025
+ } );
7622
8026
 
7623
8027
  this.module = module;
8028
+ this.variables.this = new LocalVariable( 'this', null, UNDEFINED_ASSIGNMENT );
7624
8029
  }
7625
8030
 
7626
8031
  deshadow ( names ) {
@@ -7632,21 +8037,21 @@ class ModuleScope extends Scope {
7632
8037
  const addDeclaration = declaration => {
7633
8038
  if ( declaration.isNamespace && !declaration.isExternal ) {
7634
8039
  declaration.module.getExports().forEach( name => {
7635
- addDeclaration( declaration.module.traceExport(name) );
7636
- });
8040
+ addDeclaration( declaration.module.traceExport( name ) );
8041
+ } );
7637
8042
  }
7638
8043
 
7639
8044
  names.add( declaration.name );
7640
8045
  };
7641
8046
 
7642
8047
  specifier.module.getExports().forEach( name => {
7643
- addDeclaration( specifier.module.traceExport(name) );
7644
- });
8048
+ addDeclaration( specifier.module.traceExport( name ) );
8049
+ } );
7645
8050
 
7646
8051
  if ( specifier.name !== '*' ) {
7647
8052
  const declaration = specifier.module.traceExport( specifier.name );
7648
8053
  if ( !declaration ) {
7649
- this.module.warn({
8054
+ this.module.warn( {
7650
8055
  code: 'NON_EXISTENT_EXPORT',
7651
8056
  name: specifier.name,
7652
8057
  source: specifier.module.id,
@@ -7664,22 +8069,22 @@ class ModuleScope extends Scope {
7664
8069
  names.add( specifier.specifier.imported.name );
7665
8070
  }
7666
8071
  }
7667
- });
8072
+ } );
7668
8073
 
7669
8074
  super.deshadow( names );
7670
8075
  }
7671
8076
 
7672
- findDeclaration ( name ) {
7673
- if ( this.declarations[ name ] ) {
7674
- return this.declarations[ name ];
7675
- }
7676
-
7677
- return this.module.trace( name ) || this.parent.findDeclaration( name );
7678
- }
7679
-
7680
8077
  findLexicalBoundary () {
7681
8078
  return this;
7682
8079
  }
8080
+
8081
+ findVariable ( name ) {
8082
+ if ( this.variables[ name ] ) {
8083
+ return this.variables[ name ];
8084
+ }
8085
+
8086
+ return this.module.trace( name ) || this.parent.findVariable( name );
8087
+ }
7683
8088
  }
7684
8089
 
7685
8090
  function tryParse ( module, acornOptions ) {
@@ -7698,6 +8103,11 @@ function tryParse ( module, acornOptions ) {
7698
8103
  }
7699
8104
  }
7700
8105
 
8106
+ function includeFully ( node ) {
8107
+ node.includeInBundle();
8108
+ node.eachChild( includeFully );
8109
+ }
8110
+
7701
8111
  class Module {
7702
8112
  constructor ( ref ) {
7703
8113
  var id = ref.id;
@@ -7832,9 +8242,6 @@ class Module {
7832
8242
  localName: 'default',
7833
8243
  identifier
7834
8244
  };
7835
-
7836
- // create a synthetic declaration
7837
- //this.declarations.default = new SyntheticDefaultDeclaration( node, identifier || this.basename() );
7838
8245
  }
7839
8246
 
7840
8247
  // export var { foo, bar } = ...
@@ -8001,6 +8408,10 @@ class Module {
8001
8408
  return keys( reexports );
8002
8409
  }
8003
8410
 
8411
+ includeAllInBundle () {
8412
+ this.ast.body.forEach( includeFully );
8413
+ }
8414
+
8004
8415
  includeInBundle () {
8005
8416
  let addedNewNodes = false;
8006
8417
  this.ast.body.forEach( node => {
@@ -8015,7 +8426,7 @@ class Module {
8015
8426
 
8016
8427
  namespace () {
8017
8428
  if ( !this.declarations[ '*' ] ) {
8018
- this.declarations[ '*' ] = new SyntheticNamespaceDeclaration( this );
8429
+ this.declarations[ '*' ] = new NamespaceVariable( this );
8019
8430
  }
8020
8431
 
8021
8432
  return this.declarations[ '*' ];
@@ -8051,8 +8462,8 @@ class Module {
8051
8462
 
8052
8463
  trace ( name ) {
8053
8464
  // TODO this is slightly circular
8054
- if ( name in this.scope.declarations ) {
8055
- return this.scope.declarations[ name ];
8465
+ if ( name in this.scope.variables ) {
8466
+ return this.scope.variables[ name ];
8056
8467
  }
8057
8468
 
8058
8469
  if ( name in this.imports ) {
@@ -8107,7 +8518,7 @@ class Module {
8107
8518
  const name = exportDeclaration.localName;
8108
8519
  const declaration = this.trace( name );
8109
8520
 
8110
- return declaration || this.bundle.scope.findDeclaration( name );
8521
+ return declaration || this.bundle.scope.findVariable( name );
8111
8522
  }
8112
8523
 
8113
8524
  if ( name === 'default' ) { return; }
@@ -8137,11 +8548,54 @@ class Module {
8137
8548
  }
8138
8549
  }
8139
8550
 
8551
+ class ExternalVariable extends Variable {
8552
+ constructor ( module, name ) {
8553
+ super( name );
8554
+ this.module = module;
8555
+ this.safeName = null;
8556
+ this.isExternal = true;
8557
+ this.isNamespace = name === '*';
8558
+ }
8559
+
8560
+ addReference ( reference ) {
8561
+ if ( this.name === 'default' || this.name === '*' ) {
8562
+ this.module.suggestName( reference.name );
8563
+ }
8564
+ }
8565
+
8566
+ getName ( es ) {
8567
+ if ( this.name === '*' ) {
8568
+ return this.module.name;
8569
+ }
8570
+
8571
+ if ( this.name === 'default' ) {
8572
+ return this.module.exportsNamespace || ( !es && this.module.exportsNames ) ?
8573
+ `${this.module.name}__default` :
8574
+ this.module.name;
8575
+ }
8576
+
8577
+ return es ? this.safeName : `${this.module.name}.${this.name}`;
8578
+ }
8579
+
8580
+ includeDeclaration () {
8581
+ if ( this.included ) {
8582
+ return false;
8583
+ }
8584
+ this.included = true;
8585
+ this.module.used = true;
8586
+ return true;
8587
+ }
8588
+
8589
+ setSafeName ( name ) {
8590
+ this.safeName = name;
8591
+ }
8592
+ }
8593
+
8140
8594
  class ExternalModule {
8141
8595
  constructor ( id ) {
8142
8596
  this.id = id;
8143
8597
 
8144
- const parts = id.split(/[\\/]/);
8598
+ const parts = id.split( /[\\/]/ );
8145
8599
  this.name = makeLegal( parts.pop() );
8146
8600
 
8147
8601
  this.nameSuggestions = blank();
@@ -8168,9 +8622,8 @@ class ExternalModule {
8168
8622
  if ( name !== 'default' && name !== '*' ) { this.exportsNames = true; }
8169
8623
  if ( name === '*' ) { this.exportsNamespace = true; }
8170
8624
 
8171
- return this.declarations[ name ] || (
8172
- this.declarations[ name ] = new ExternalDeclaration( this, name )
8173
- );
8625
+ return this.declarations[ name ]
8626
+ || (this.declarations[ name ] = new ExternalVariable( this, name ));
8174
8627
  }
8175
8628
  }
8176
8629
 
@@ -9212,9 +9665,9 @@ function callIfFunction ( thing ) {
9212
9665
  return typeof thing === 'function' ? thing() : thing;
9213
9666
  }
9214
9667
 
9215
- class SyntheticGlobalDeclaration {
9668
+ class GlobalVariable extends Variable {
9216
9669
  constructor ( name ) {
9217
- this.name = name;
9670
+ super( name );
9218
9671
  this.isExternal = true;
9219
9672
  this.isGlobal = true;
9220
9673
  this.isReassigned = false;
@@ -9222,31 +9675,23 @@ class SyntheticGlobalDeclaration {
9222
9675
  }
9223
9676
 
9224
9677
  addReference ( reference ) {
9225
- reference.declaration = this;
9226
9678
  if ( reference.isReassignment ) { this.isReassigned = true; }
9227
9679
  }
9228
9680
 
9229
- gatherPossibleValues ( values ) {
9230
- values.add( UNKNOWN_ASSIGNMENT );
9231
- }
9232
-
9233
- getName () {
9234
- return this.name;
9235
- }
9681
+ assignExpression () {}
9236
9682
 
9237
- includeDeclaration() {
9238
- this.included = true;
9239
- return false;
9683
+ hasEffectsWhenCalled () {
9684
+ return !pureFunctions[ this.name ];
9240
9685
  }
9241
9686
  }
9242
9687
 
9243
9688
  class BundleScope extends Scope {
9244
- findDeclaration ( name ) {
9245
- if ( !this.declarations[ name ] ) {
9246
- this.declarations[ name ] = new SyntheticGlobalDeclaration( name );
9689
+ findVariable ( name ) {
9690
+ if ( !this.variables[ name ] ) {
9691
+ this.variables[ name ] = new GlobalVariable( name );
9247
9692
  }
9248
9693
 
9249
- return this.declarations[ name ];
9694
+ return this.variables[ name ];
9250
9695
  }
9251
9696
  }
9252
9697
 
@@ -9302,7 +9747,7 @@ class Bundle$$1 {
9302
9747
  this.scope = new BundleScope();
9303
9748
  // TODO strictly speaking, this only applies with non-ES6, non-default-only bundles
9304
9749
  [ 'module', 'exports', '_interopDefault' ].forEach( name => {
9305
- this.scope.findDeclaration( name ); // creates global declaration as side-effect
9750
+ this.scope.findVariable( name ); // creates global variable as side-effect
9306
9751
  } );
9307
9752
 
9308
9753
  this.moduleById = new Map();
@@ -9364,7 +9809,7 @@ class Bundle$$1 {
9364
9809
  .then( entryModule => {
9365
9810
  this.entryModule = entryModule;
9366
9811
 
9367
- // Phase 2 – binding. We link references to their declarations
9812
+ // Phase 2 – binding. We link references to their variables
9368
9813
  // to generate a complete picture of the bundle
9369
9814
 
9370
9815
  timeStart( 'phase 2' );
@@ -9374,31 +9819,30 @@ class Bundle$$1 {
9374
9819
 
9375
9820
  timeEnd( 'phase 2' );
9376
9821
 
9377
- // Phase 3 – marking. We 'run' each statement to see which ones
9378
- // need to be included in the generated bundle
9822
+ // Phase 3 – marking. We include all statements that should be included
9379
9823
 
9380
9824
  timeStart( 'phase 3' );
9381
9825
 
9382
9826
  // mark all export statements
9383
9827
  entryModule.getExports().forEach( name => {
9384
- const declaration = entryModule.traceExport( name );
9828
+ const variable = entryModule.traceExport( name );
9385
9829
 
9386
- declaration.exportName = name;
9387
- declaration.includeDeclaration();
9830
+ variable.exportName = name;
9831
+ variable.includeVariable();
9388
9832
 
9389
- if ( declaration.isNamespace ) {
9390
- declaration.needsNamespaceBlock = true;
9833
+ if ( variable.isNamespace ) {
9834
+ variable.needsNamespaceBlock = true;
9391
9835
  }
9392
9836
  } );
9393
9837
 
9394
9838
  entryModule.getReexports().forEach( name => {
9395
- const declaration = entryModule.traceExport( name );
9839
+ const variable = entryModule.traceExport( name );
9396
9840
 
9397
- if ( declaration.isExternal ) {
9398
- declaration.reexported = declaration.module.reexported = true;
9841
+ if ( variable.isExternal ) {
9842
+ variable.reexported = variable.module.reexported = true;
9399
9843
  } else {
9400
- declaration.exportName = name;
9401
- declaration.includeDeclaration();
9844
+ variable.exportName = name;
9845
+ variable.includeVariable();
9402
9846
  }
9403
9847
  } );
9404
9848
 
@@ -9413,6 +9857,9 @@ class Bundle$$1 {
9413
9857
  }
9414
9858
  } );
9415
9859
  } while ( addedNewNodes );
9860
+ } else {
9861
+ // Necessary to properly replace namespace imports
9862
+ this.modules.forEach( module => module.includeAllInBundle() );
9416
9863
  }
9417
9864
 
9418
9865
  timeEnd( 'phase 3' );
@@ -9459,7 +9906,7 @@ class Bundle$$1 {
9459
9906
  const used = blank();
9460
9907
 
9461
9908
  // ensure no conflicts with globals
9462
- keys( this.scope.declarations ).forEach( name => used[ name ] = 1 );
9909
+ keys( this.scope.variables ).forEach( name => used[ name ] = 1 );
9463
9910
 
9464
9911
  function getSafeName ( name ) {
9465
9912
  while ( used[ name ] ) {
@@ -9487,12 +9934,12 @@ class Bundle$$1 {
9487
9934
  } );
9488
9935
 
9489
9936
  this.modules.forEach( module => {
9490
- forOwn( module.scope.declarations, ( declaration ) => {
9491
- if ( declaration.isDefault && declaration.declaration.id ) {
9937
+ forOwn( module.scope.variables, variable => {
9938
+ if ( variable.isDefault && variable.declaration.id ) {
9492
9939
  return;
9493
9940
  }
9494
9941
 
9495
- declaration.name = getSafeName( declaration.name );
9942
+ variable.name = getSafeName( variable.name );
9496
9943
  } );
9497
9944
 
9498
9945
  // deconflict reified namespaces
@@ -9645,12 +10092,12 @@ class Bundle$$1 {
9645
10092
  // need to find the actual import declaration, so we can provide
9646
10093
  // a useful error message. Bit hoop-jumpy but what can you do
9647
10094
  const declaration = module.ast.body.find( node => {
9648
- return node.isImportDeclaration && node.source.value === source;
10095
+ return ( node.isImportDeclaration || node.isExportDeclaration ) && node.source.value === source;
9649
10096
  } );
9650
-
10097
+ const declarationType = /Export/.test( declaration.type ) ? 'export' : 'import';
9651
10098
  module.error( {
9652
10099
  code: 'CANNOT_IMPORT_SELF',
9653
- message: `A module cannot import itself`
10100
+ message: `A module cannot ${declarationType} itself`
9654
10101
  }, declaration.start );
9655
10102
  }
9656
10103
 
@@ -10131,7 +10578,7 @@ function createCommonjsModule(fn, module) {
10131
10578
  * Licensed under the MIT license.
10132
10579
  */
10133
10580
 
10134
- var index$2 = function filenameRegex() {
10581
+ var filenameRegex = function filenameRegex() {
10135
10582
  return /([^\\\/]+)$/;
10136
10583
  };
10137
10584
 
@@ -10142,7 +10589,7 @@ var index$2 = function filenameRegex() {
10142
10589
  * Released under the MIT License.
10143
10590
  */
10144
10591
 
10145
- var index$6 = function (arr) {
10592
+ var arrFlatten = function (arr) {
10146
10593
  return flat(arr, []);
10147
10594
  };
10148
10595
 
@@ -10188,7 +10635,7 @@ function diff(arr, arrays) {
10188
10635
  }
10189
10636
 
10190
10637
  if (argsLen > 2) {
10191
- arrays = index$6(slice.call(arguments, 1));
10638
+ arrays = arrFlatten(slice.call(arguments, 1));
10192
10639
  }
10193
10640
 
10194
10641
  while (++i < len) {
@@ -10203,7 +10650,7 @@ function diff(arr, arrays) {
10203
10650
  * Expose `diff`
10204
10651
  */
10205
10652
 
10206
- var index$4 = diff;
10653
+ var arrDiff = diff;
10207
10654
 
10208
10655
  /*!
10209
10656
  * array-unique <https://github.com/jonschlinkert/array-unique>
@@ -10212,7 +10659,7 @@ var index$4 = diff;
10212
10659
  * Licensed under the MIT License.
10213
10660
  */
10214
10661
 
10215
- var index$8 = function unique(arr) {
10662
+ var arrayUnique = function unique(arr) {
10216
10663
  if (!Array.isArray(arr)) {
10217
10664
  throw new TypeError('array-unique expects an array.');
10218
10665
  }
@@ -10234,12 +10681,12 @@ var index$8 = function unique(arr) {
10234
10681
 
10235
10682
  var toString$1$1 = {}.toString;
10236
10683
 
10237
- var index$18 = Array.isArray || function (arr) {
10684
+ var isarray = Array.isArray || function (arr) {
10238
10685
  return toString$1$1.call(arr) == '[object Array]';
10239
10686
  };
10240
10687
 
10241
- var index$16 = function isObject(val) {
10242
- return val != null && typeof val === 'object' && index$18(val) === false;
10688
+ var isobject = function isObject(val) {
10689
+ return val != null && typeof val === 'object' && isarray(val) === false;
10243
10690
  };
10244
10691
 
10245
10692
  /*!
@@ -10251,7 +10698,7 @@ var index$16 = function isObject(val) {
10251
10698
 
10252
10699
  // The _isBuffer check is for Safari 5-7 support, because it's missing
10253
10700
  // Object.prototype.constructor. Remove this eventually
10254
- var index$24 = function (obj) {
10701
+ var isBuffer_1 = function (obj) {
10255
10702
  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
10256
10703
  };
10257
10704
 
@@ -10273,7 +10720,7 @@ var toString$2 = Object.prototype.toString;
10273
10720
  * @return {*} Native javascript type
10274
10721
  */
10275
10722
 
10276
- var index$22 = function kindOf(val) {
10723
+ var kindOf = function kindOf(val) {
10277
10724
  // primitivies
10278
10725
  if (typeof val === 'undefined') {
10279
10726
  return 'undefined';
@@ -10326,7 +10773,7 @@ var index$22 = function kindOf(val) {
10326
10773
  }
10327
10774
 
10328
10775
  // buffer
10329
- if (index$24(val)) {
10776
+ if (isBuffer_1(val)) {
10330
10777
  return 'buffer';
10331
10778
  }
10332
10779
 
@@ -10380,8 +10827,8 @@ var index$22 = function kindOf(val) {
10380
10827
  return 'object';
10381
10828
  };
10382
10829
 
10383
- var index$20 = function isNumber(num) {
10384
- var type = index$22(num);
10830
+ var isNumber = function isNumber(num) {
10831
+ var type = kindOf(num);
10385
10832
  if (type !== 'number' && type !== 'string') {
10386
10833
  return false;
10387
10834
  }
@@ -10398,7 +10845,7 @@ var toString$3 = Object.prototype.toString;
10398
10845
  * @return {*} Native javascript type
10399
10846
  */
10400
10847
 
10401
- var index$30 = function kindOf(val) {
10848
+ var kindOf$2 = function kindOf(val) {
10402
10849
  // primitivies
10403
10850
  if (typeof val === 'undefined') {
10404
10851
  return 'undefined';
@@ -10451,7 +10898,7 @@ var index$30 = function kindOf(val) {
10451
10898
  }
10452
10899
 
10453
10900
  // buffer
10454
- if (index$24(val)) {
10901
+ if (isBuffer_1(val)) {
10455
10902
  return 'buffer';
10456
10903
  }
10457
10904
 
@@ -10505,8 +10952,8 @@ var index$30 = function kindOf(val) {
10505
10952
  return 'object';
10506
10953
  };
10507
10954
 
10508
- var index$28 = function isNumber(num) {
10509
- var type = index$30(num);
10955
+ var isNumber$2 = function isNumber(num) {
10956
+ var type = kindOf$2(num);
10510
10957
 
10511
10958
  if (type === 'string') {
10512
10959
  if (!num.trim()) return false;
@@ -10526,7 +10973,7 @@ var toString$4 = Object.prototype.toString;
10526
10973
  * @return {*} Native javascript type
10527
10974
  */
10528
10975
 
10529
- var index$32 = function kindOf(val) {
10976
+ var kindOf$4 = function kindOf(val) {
10530
10977
  // primitivies
10531
10978
  if (typeof val === 'undefined') {
10532
10979
  return 'undefined';
@@ -10582,7 +11029,7 @@ var index$32 = function kindOf(val) {
10582
11029
  }
10583
11030
 
10584
11031
  // buffer
10585
- if (index$24(val)) {
11032
+ if (isBuffer_1(val)) {
10586
11033
  return 'buffer';
10587
11034
  }
10588
11035
 
@@ -10640,7 +11087,7 @@ var index$32 = function kindOf(val) {
10640
11087
  * Expose `randomatic`
10641
11088
  */
10642
11089
 
10643
- var index$26 = randomatic;
11090
+ var randomatic_1 = randomatic;
10644
11091
 
10645
11092
  /**
10646
11093
  * Available mask characters
@@ -10676,12 +11123,12 @@ function randomatic(pattern, length, options) {
10676
11123
  if (typeof pattern === 'string') {
10677
11124
  length = pattern.length;
10678
11125
 
10679
- } else if (index$28(pattern)) {
11126
+ } else if (isNumber$2(pattern)) {
10680
11127
  options = {}; length = pattern; pattern = '*';
10681
11128
  }
10682
11129
  }
10683
11130
 
10684
- if (index$32(length) === 'object' && length.hasOwnProperty('chars')) {
11131
+ if (kindOf$4(length) === 'object' && length.hasOwnProperty('chars')) {
10685
11132
  options = length;
10686
11133
  pattern = options.chars;
10687
11134
  length = pattern.length;
@@ -10725,7 +11172,7 @@ var cache;
10725
11172
  * Expose `repeat`
10726
11173
  */
10727
11174
 
10728
- var index$34 = repeat;
11175
+ var repeatString = repeat;
10729
11176
 
10730
11177
  /**
10731
11178
  * Repeat the given `string` the specified `number`
@@ -10783,7 +11230,7 @@ function repeat(str, num) {
10783
11230
  * Licensed under the MIT license.
10784
11231
  */
10785
11232
 
10786
- var index$36 = function repeat(ele, num) {
11233
+ var repeatElement = function repeat(ele, num) {
10787
11234
  var arr = new Array(num);
10788
11235
 
10789
11236
  for (var i = 0; i < num; i++) {
@@ -10797,7 +11244,7 @@ var index$36 = function repeat(ele, num) {
10797
11244
  * Expose `fillRange`
10798
11245
  */
10799
11246
 
10800
- var index$14 = fillRange;
11247
+ var fillRange_1 = fillRange;
10801
11248
 
10802
11249
  /**
10803
11250
  * Return a range of numbers or letters.
@@ -10822,7 +11269,7 @@ function fillRange(a, b, step, options, fn) {
10822
11269
  fn = options; options = {};
10823
11270
  }
10824
11271
 
10825
- if (index$16(step)) {
11272
+ if (isobject(step)) {
10826
11273
  options = step; step = '';
10827
11274
  }
10828
11275
 
@@ -10857,11 +11304,11 @@ function fillRange(a, b, step, options, fn) {
10857
11304
 
10858
11305
  // repeat string
10859
11306
  if (m === '+') {
10860
- return index$36(a, b);
11307
+ return repeatElement(a, b);
10861
11308
 
10862
11309
  // randomize a, `b` times
10863
11310
  } else if (m === '?') {
10864
- return [index$26(a, b)];
11311
+ return [randomatic_1(a, b)];
10865
11312
 
10866
11313
  // expand right, no regex reduction
10867
11314
  } else if (m === '>') {
@@ -10884,7 +11331,7 @@ function fillRange(a, b, step, options, fn) {
10884
11331
  regex = true;
10885
11332
  sep$$1 = m;
10886
11333
  }
10887
- } else if (!index$20(step)) {
11334
+ } else if (!isNumber(step)) {
10888
11335
  if (!opts.silent) {
10889
11336
  throw new TypeError('fill-range: invalid step.');
10890
11337
  }
@@ -10909,8 +11356,8 @@ function fillRange(a, b, step, options, fn) {
10909
11356
  }
10910
11357
 
10911
11358
  // validate arguments
10912
- var isNumA = index$20(zeros(a));
10913
- var isNumB = index$20(zeros(b));
11359
+ var isNumA = isNumber(zeros(a));
11360
+ var isNumB = isNumber(zeros(b));
10914
11361
 
10915
11362
  if ((!isNumA && isNumB) || (isNumA && !isNumB)) {
10916
11363
  if (!opts.silent) {
@@ -11173,7 +11620,7 @@ function isPadded(origA, origB) {
11173
11620
  : blen;
11174
11621
 
11175
11622
  return function (a) {
11176
- return index$34('0', len - length(a));
11623
+ return repeatString('0', len - length(a));
11177
11624
  };
11178
11625
  }
11179
11626
  return false;
@@ -11187,7 +11634,7 @@ function length(val) {
11187
11634
  return val.toString().length;
11188
11635
  }
11189
11636
 
11190
- var index$12 = function expandRange(str, options, fn) {
11637
+ var expandRange = function expandRange(str, options, fn) {
11191
11638
  if (typeof str !== 'string') {
11192
11639
  throw new TypeError('expand-range expects a string.');
11193
11640
  }
@@ -11217,7 +11664,7 @@ var index$12 = function expandRange(str, options, fn) {
11217
11664
  }
11218
11665
 
11219
11666
  args.push(opts);
11220
- return index$14.apply(null, args.concat(fn));
11667
+ return fillRange_1.apply(null, args.concat(fn));
11221
11668
  };
11222
11669
 
11223
11670
  /*!
@@ -11273,7 +11720,7 @@ function randomize$1() {
11273
11720
 
11274
11721
  var cache$1 = {};
11275
11722
 
11276
- var index$38 = {
11723
+ var preserve = {
11277
11724
  before: before,
11278
11725
  after: after
11279
11726
  };
@@ -11290,7 +11737,7 @@ var index$38 = {
11290
11737
  * Expose `braces`
11291
11738
  */
11292
11739
 
11293
- var index$10 = function(str, options) {
11740
+ var braces_1 = function(str, options) {
11294
11741
  if (typeof str !== 'string') {
11295
11742
  throw new Error('braces expects a string');
11296
11743
  }
@@ -11360,7 +11807,7 @@ function braces(str, arr, options) {
11360
11807
  return arr.concat(str);
11361
11808
  } else {
11362
11809
  es6 = true;
11363
- str = index$38.before(str, es6Regex());
11810
+ str = preserve.before(str, es6Regex());
11364
11811
  }
11365
11812
  }
11366
11813
 
@@ -11380,7 +11827,7 @@ function braces(str, arr, options) {
11380
11827
  var segs, segsLength;
11381
11828
 
11382
11829
  if (inner.indexOf('..') !== -1) {
11383
- segs = index$12(inner, opts, fn) || inner.split(',');
11830
+ segs = expandRange(inner, opts, fn) || inner.split(',');
11384
11831
  segsLength = segs.length;
11385
11832
 
11386
11833
  } else if (inner[0] === '"' || inner[0] === '\'') {
@@ -11418,7 +11865,7 @@ function braces(str, arr, options) {
11418
11865
  arr = braces(val, arr, opts);
11419
11866
  } else if (val !== '') {
11420
11867
  if (opts.nodupes && arr.indexOf(val) !== -1) { continue; }
11421
- arr.push(es6 ? index$38.after(val) : val);
11868
+ arr.push(es6 ? preserve.after(val) : val);
11422
11869
  }
11423
11870
  }
11424
11871
 
@@ -11468,7 +11915,7 @@ function exponential(str, options, fn) {
11468
11915
 
11469
11916
  } else {
11470
11917
  var num = Math.pow(2, exp);
11471
- arr.push.apply(arr, index$36(ele, num));
11918
+ arr.push.apply(arr, repeatElement(ele, num));
11472
11919
  }
11473
11920
  }
11474
11921
  }
@@ -11676,7 +12123,7 @@ function filter$1(arr, cb) {
11676
12123
  * Licensed under the MIT License.
11677
12124
  */
11678
12125
 
11679
- var index$42 = function isPosixBracket(str) {
12126
+ var isPosixBracket = function isPosixBracket(str) {
11680
12127
  return typeof str === 'string' && /\[([:.=+])(?:[^\[\]]|)+\1\]/.test(str);
11681
12128
  };
11682
12129
 
@@ -11704,10 +12151,10 @@ var POSIX = {
11704
12151
  * Expose `brackets`
11705
12152
  */
11706
12153
 
11707
- var index$40 = brackets;
12154
+ var expandBrackets = brackets;
11708
12155
 
11709
12156
  function brackets(str) {
11710
- if (!index$42(str)) {
12157
+ if (!isPosixBracket(str)) {
11711
12158
  return str;
11712
12159
  }
11713
12160
 
@@ -11840,7 +12287,7 @@ brackets.match = function(arr, pattern) {
11840
12287
  * Licensed under the MIT License.
11841
12288
  */
11842
12289
 
11843
- var index$46 = function isExtglob(str) {
12290
+ var isExtglob = function isExtglob(str) {
11844
12291
  return typeof str === 'string'
11845
12292
  && /[@?!+*]\(/.test(str);
11846
12293
  };
@@ -11857,7 +12304,7 @@ var cache$2 = {};
11857
12304
  * Expose `extglob`
11858
12305
  */
11859
12306
 
11860
- var index$44 = extglob;
12307
+ var extglob_1 = extglob;
11861
12308
 
11862
12309
  /**
11863
12310
  * Convert the given extglob `string` to a regex-compatible
@@ -12025,15 +12472,15 @@ function toRegex$1(pattern, contains, isNegated) {
12025
12472
 
12026
12473
 
12027
12474
 
12028
- var index$48 = function isGlob(str) {
12475
+ var isGlob = function isGlob(str) {
12029
12476
  return typeof str === 'string'
12030
12477
  && (/[*!?{}(|)[\]]/.test(str)
12031
- || index$46(str));
12478
+ || isExtglob(str));
12032
12479
  };
12033
12480
 
12034
12481
  var isWin = process.platform === 'win32';
12035
12482
 
12036
- var index$52 = function (str) {
12483
+ var removeTrailingSeparator = function (str) {
12037
12484
  var i = str.length - 1;
12038
12485
  if (i < 2) {
12039
12486
  return str;
@@ -12058,13 +12505,13 @@ function isSeparator(str, i) {
12058
12505
 
12059
12506
 
12060
12507
 
12061
- var index$50 = function normalizePath(str, stripTrailing) {
12508
+ var normalizePath = function normalizePath(str, stripTrailing) {
12062
12509
  if (typeof str !== 'string') {
12063
12510
  throw new TypeError('expected a string');
12064
12511
  }
12065
12512
  str = str.replace(/[\\\/]+/g, '/');
12066
12513
  if (stripTrailing !== false) {
12067
- str = index$52(str);
12514
+ str = removeTrailingSeparator(str);
12068
12515
  }
12069
12516
  return str;
12070
12517
  };
@@ -12076,7 +12523,7 @@ var index$50 = function normalizePath(str, stripTrailing) {
12076
12523
  * Licensed under the MIT License.
12077
12524
  */
12078
12525
 
12079
- var index$56 = function isExtendable(val) {
12526
+ var isExtendable = function isExtendable(val) {
12080
12527
  return typeof val !== 'undefined' && val !== null
12081
12528
  && (typeof val === 'object' || typeof val === 'function');
12082
12529
  };
@@ -12088,7 +12535,7 @@ var index$56 = function isExtendable(val) {
12088
12535
  * Released under the MIT License.
12089
12536
  */
12090
12537
 
12091
- var index$60 = function forIn(obj, fn, thisArg) {
12538
+ var forIn = function forIn(obj, fn, thisArg) {
12092
12539
  for (var key in obj) {
12093
12540
  if (fn.call(thisArg, obj[key], key, obj) === false) {
12094
12541
  break;
@@ -12098,16 +12545,16 @@ var index$60 = function forIn(obj, fn, thisArg) {
12098
12545
 
12099
12546
  var hasOwn = Object.prototype.hasOwnProperty;
12100
12547
 
12101
- var index$58 = function forOwn(obj, fn, thisArg) {
12102
- index$60(obj, function(val, key) {
12548
+ var forOwn$1 = function forOwn(obj, fn, thisArg) {
12549
+ forIn(obj, function(val, key) {
12103
12550
  if (hasOwn.call(obj, key)) {
12104
12551
  return fn.call(thisArg, obj[key], key, obj);
12105
12552
  }
12106
12553
  });
12107
12554
  };
12108
12555
 
12109
- var index$54 = function omit(obj, keys) {
12110
- if (!index$56(obj)) return {};
12556
+ var object_omit = function omit(obj, keys) {
12557
+ if (!isExtendable(obj)) return {};
12111
12558
 
12112
12559
  keys = [].concat.apply([], [].slice.call(arguments, 1));
12113
12560
  var last = keys[keys.length - 1];
@@ -12122,7 +12569,7 @@ var index$54 = function omit(obj, keys) {
12122
12569
  return obj;
12123
12570
  }
12124
12571
 
12125
- index$58(obj, function(value, key) {
12572
+ forOwn$1(obj, function(value, key) {
12126
12573
  if (keys.indexOf(key) === -1) {
12127
12574
 
12128
12575
  if (!isFunction) {
@@ -12135,20 +12582,20 @@ var index$54 = function omit(obj, keys) {
12135
12582
  return res;
12136
12583
  };
12137
12584
 
12138
- var index$66 = function globParent(str) {
12585
+ var globParent = function globParent(str) {
12139
12586
  str += 'a'; // preserves full path in case of trailing path separator
12140
- do {str = path.dirname(str);} while (index$48(str));
12587
+ do {str = path.dirname(str);} while (isGlob(str));
12141
12588
  return str;
12142
12589
  };
12143
12590
 
12144
- var index$64 = function globBase(pattern) {
12591
+ var globBase = function globBase(pattern) {
12145
12592
  if (typeof pattern !== 'string') {
12146
12593
  throw new TypeError('glob-base expects a string.');
12147
12594
  }
12148
12595
 
12149
12596
  var res = {};
12150
- res.base = index$66(pattern);
12151
- res.isGlob = index$48(pattern);
12597
+ res.base = globParent(pattern);
12598
+ res.isGlob = isGlob(pattern);
12152
12599
 
12153
12600
  if (res.base !== '.') {
12154
12601
  res.glob = pattern.substr(res.base.length);
@@ -12187,7 +12634,7 @@ function dirname$1(glob) {
12187
12634
  * Released under the MIT License.
12188
12635
  */
12189
12636
 
12190
- var index$68 = function(str) {
12637
+ var isDotfile = function(str) {
12191
12638
  if (str.charCodeAt(0) === 46 /* . */ && str.indexOf('/', 1) === -1) {
12192
12639
  return true;
12193
12640
  }
@@ -12195,7 +12642,7 @@ var index$68 = function(str) {
12195
12642
  return slash !== -1 ? str.charCodeAt(slash + 1) === 46 /* . */ : false;
12196
12643
  };
12197
12644
 
12198
- var index$62 = createCommonjsModule(function (module) {
12645
+ var parseGlob = createCommonjsModule(function (module) {
12199
12646
  /*!
12200
12647
  * parse-glob <https://github.com/jonschlinkert/parse-glob>
12201
12648
  *
@@ -12240,7 +12687,7 @@ module.exports = function parseGlob(glob) {
12240
12687
  // unescape dots and slashes in braces/brackets
12241
12688
  glob = escape(glob);
12242
12689
 
12243
- var parsed = index$64(glob);
12690
+ var parsed = globBase(glob);
12244
12691
  tok.is.glob = parsed.isGlob;
12245
12692
 
12246
12693
  tok.glob = parsed.glob;
@@ -12256,7 +12703,7 @@ module.exports = function parseGlob(glob) {
12256
12703
  tok.path.extname = basename$$1.slice(1).join('.') || '';
12257
12704
  tok.path.ext = '';
12258
12705
 
12259
- if (index$48(tok.path.dirname) && !tok.path.basename) {
12706
+ if (isGlob(tok.path.dirname) && !tok.path.basename) {
12260
12707
  if (!/\/$/.test(tok.glob)) {
12261
12708
  tok.path.basename = tok.glob;
12262
12709
  }
@@ -12289,11 +12736,11 @@ module.exports = function parseGlob(glob) {
12289
12736
  // Booleans
12290
12737
  var is = (glob && tok.is.glob);
12291
12738
  tok.is.negated = glob && glob.charAt(0) === '!';
12292
- tok.is.extglob = glob && index$46(glob);
12739
+ tok.is.extglob = glob && isExtglob(glob);
12293
12740
  tok.is.braces = has(is, glob, '{');
12294
12741
  tok.is.brackets = has(is, glob, '[:');
12295
12742
  tok.is.globstar = has(is, glob, '**');
12296
- tok.is.dotfile = index$68(tok.path.basename) || index$68(tok.path.filename);
12743
+ tok.is.dotfile = isDotfile(tok.path.basename) || isDotfile(tok.path.filename);
12297
12744
  tok.is.dotdir = dotdir(tok.path.dirname);
12298
12745
  return (cache[glob] = tok);
12299
12746
  };
@@ -12362,18 +12809,18 @@ function unescape(str) {
12362
12809
  */
12363
12810
 
12364
12811
  // see http://jsperf.com/testing-value-is-primitive/7
12365
- var index$72 = function isPrimitive(value) {
12812
+ var isPrimitive = function isPrimitive(value) {
12366
12813
  return value == null || (typeof value !== 'function' && typeof value !== 'object');
12367
12814
  };
12368
12815
 
12369
- var index$74 = function isEqual(a, b) {
12816
+ var isEqualShallow = function isEqual(a, b) {
12370
12817
  if (!a && !b) { return true; }
12371
12818
  if (!a && b || a && !b) { return false; }
12372
12819
 
12373
12820
  var numKeysA = 0, numKeysB = 0, key;
12374
12821
  for (key in b) {
12375
12822
  numKeysB++;
12376
- if (!index$72(b[key]) || !a.hasOwnProperty(key) || (a[key] !== b[key])) {
12823
+ if (!isPrimitive(b[key]) || !a.hasOwnProperty(key) || (a[key] !== b[key])) {
12377
12824
  return false;
12378
12825
  }
12379
12826
  }
@@ -12390,7 +12837,7 @@ var cache$3 = {};
12390
12837
  * Expose `regexCache`
12391
12838
  */
12392
12839
 
12393
- var index$70 = regexCache;
12840
+ var regexCache_1 = regexCache;
12394
12841
 
12395
12842
  /**
12396
12843
  * Memoize the results of a call to the new RegExp constructor.
@@ -12423,7 +12870,7 @@ function regexCache(fn, str, opts) {
12423
12870
  }
12424
12871
 
12425
12872
  cached = cache$3[key];
12426
- if (cached && index$74(cached.opts, opts)) {
12873
+ if (cached && isEqualShallow(cached.opts, opts)) {
12427
12874
  return cached.regex;
12428
12875
  }
12429
12876
 
@@ -12442,8 +12889,8 @@ function memo(key, opts, regex) {
12442
12889
  var cache_1 = cache$3;
12443
12890
  var basic_1 = basic;
12444
12891
 
12445
- index$70.cache = cache_1;
12446
- index$70.basic = basic_1;
12892
+ regexCache_1.cache = cache_1;
12893
+ regexCache_1.basic = basic_1;
12447
12894
 
12448
12895
  var utils_1 = createCommonjsModule(function (module) {
12449
12896
  'use strict';
@@ -12457,18 +12904,18 @@ var utils = module.exports;
12457
12904
  * Module dependencies
12458
12905
  */
12459
12906
 
12460
- utils.diff = index$4;
12461
- utils.unique = index$8;
12462
- utils.braces = index$10;
12463
- utils.brackets = index$40;
12464
- utils.extglob = index$44;
12465
- utils.isExtglob = index$46;
12466
- utils.isGlob = index$48;
12467
- utils.typeOf = index$22;
12468
- utils.normalize = index$50;
12469
- utils.omit = index$54;
12470
- utils.parseGlob = index$62;
12471
- utils.cache = index$70;
12907
+ utils.diff = arrDiff;
12908
+ utils.unique = arrayUnique;
12909
+ utils.braces = braces_1;
12910
+ utils.brackets = expandBrackets;
12911
+ utils.extglob = extglob_1;
12912
+ utils.isExtglob = isExtglob;
12913
+ utils.isGlob = isGlob;
12914
+ utils.typeOf = kindOf;
12915
+ utils.normalize = normalizePath;
12916
+ utils.omit = object_omit;
12917
+ utils.parseGlob = parseGlob;
12918
+ utils.cache = regexCache_1;
12472
12919
 
12473
12920
  /**
12474
12921
  * Get the filename of a filepath
@@ -12478,7 +12925,7 @@ utils.cache = index$70;
12478
12925
  */
12479
12926
 
12480
12927
  utils.filename = function filename(fp) {
12481
- var seg = fp.match(index$2());
12928
+ var seg = fp.match(filenameRegex());
12482
12929
  return seg && seg[0];
12483
12930
  };
12484
12931
 
@@ -13572,7 +14019,7 @@ micromatch.matchKeys = matchKeys;
13572
14019
  * Expose `micromatch`
13573
14020
  */
13574
14021
 
13575
- var index$1 = micromatch;
14022
+ var micromatch_1 = micromatch;
13576
14023
 
13577
14024
  function ensureArray$1 ( thing ) {
13578
14025
  if ( Array.isArray( thing ) ) return thing;
@@ -13581,7 +14028,7 @@ function ensureArray$1 ( thing ) {
13581
14028
  }
13582
14029
 
13583
14030
  function createFilter ( include, exclude ) {
13584
- const getMatcher = id => ( isRegexp( id ) ? id : { test: index$1.matcher( resolve( id ) ) } );
14031
+ const getMatcher = id => ( isRegexp( id ) ? id : { test: micromatch_1.matcher( resolve( id ) ) } );
13585
14032
  include = ensureArray$1( include ).map( getMatcher );
13586
14033
  exclude = ensureArray$1( exclude ).map( getMatcher );
13587
14034
 
@@ -13635,12 +14082,12 @@ requireRelative.resolve = function(requested, relativeTo) {
13635
14082
  return module$1._resolveFilename(requested, root);
13636
14083
  };
13637
14084
 
13638
- var index$76 = requireRelative;
14085
+ var requireRelative_1$1 = requireRelative;
13639
14086
 
13640
14087
  let chokidar;
13641
14088
 
13642
14089
  try {
13643
- chokidar = index$76( 'chokidar', process.cwd() );
14090
+ chokidar = requireRelative_1$1( 'chokidar', process.cwd() );
13644
14091
  } catch (err) {
13645
14092
  chokidar = null;
13646
14093
  }
@@ -13976,7 +14423,7 @@ function watch$1(configs) {
13976
14423
  return new Watcher(configs);
13977
14424
  }
13978
14425
 
13979
- var version$1 = "0.49.0";
14426
+ var version$1 = "0.50.0";
13980
14427
 
13981
14428
  export { rollup, watch$1 as watch, version$1 as VERSION };
13982
14429
  //# sourceMappingURL=rollup.es.js.map