rollup 0.49.1 → 0.50.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/rollup.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
- Rollup.js v0.49.1
3
- Mon Aug 28 2017 07:37:02 GMT-0400 (EDT) - commit 976043fa11a5cfd8aae10ac61dc51a511d837d06
2
+ Rollup.js v0.50.1
3
+ Wed Nov 08 2017 06:27:53 GMT+0100 (CET) - commit e773b589d9a05ba3d51ad44d3016ee6dfa2d2fd5
4
4
 
5
5
 
6
6
  https://github.com/rollup/rollup
@@ -1945,15 +1945,15 @@ var types = {
1945
1945
  eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
1946
1946
  assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
1947
1947
  incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
1948
- prefix: new TokenType("prefix", {beforeExpr: true, prefix: true, startsExpr: true}),
1948
+ prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}),
1949
1949
  logicalOR: binop("||", 1),
1950
1950
  logicalAND: binop("&&", 2),
1951
1951
  bitwiseOR: binop("|", 3),
1952
1952
  bitwiseXOR: binop("^", 4),
1953
1953
  bitwiseAND: binop("&", 5),
1954
- equality: binop("==/!=", 6),
1955
- relational: binop("</>", 7),
1956
- bitShift: binop("<</>>", 8),
1954
+ equality: binop("==/!=/===/!==", 6),
1955
+ relational: binop("</>/<=/>=", 7),
1956
+ bitShift: binop("<</>>/>>>", 8),
1957
1957
  plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
1958
1958
  modulo: binop("%", 10),
1959
1959
  star: binop("*", 10),
@@ -2303,7 +2303,7 @@ var pp = Parser.prototype;
2303
2303
 
2304
2304
  // ## Parser utilities
2305
2305
 
2306
- var literal = /^(?:'((?:[^']|\.)*)'|"((?:[^"]|\.)*)"|;)/;
2306
+ var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)"|;)/;
2307
2307
  pp.strictDirective = function(start) {
2308
2308
  var this$1 = this;
2309
2309
 
@@ -4017,7 +4017,7 @@ pp$3.parseTemplate = function(ref) {
4017
4017
 
4018
4018
  pp$3.isAsyncProp = function(prop) {
4019
4019
  return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
4020
- (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL) &&
4020
+ (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword) &&
4021
4021
  !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
4022
4022
  };
4023
4023
 
@@ -4893,7 +4893,7 @@ pp$8.readToken_caret = function() { // '^'
4893
4893
  pp$8.readToken_plus_min = function(code) { // '+-'
4894
4894
  var next = this.input.charCodeAt(this.pos + 1);
4895
4895
  if (next === code) {
4896
- if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 &&
4896
+ if (next == 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) == 62 &&
4897
4897
  (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {
4898
4898
  // A `-->` line comment
4899
4899
  this.skipLineComment(3);
@@ -4914,9 +4914,8 @@ pp$8.readToken_lt_gt = function(code) { // '<>'
4914
4914
  if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) }
4915
4915
  return this.finishOp(types.bitShift, size)
4916
4916
  }
4917
- if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 &&
4917
+ if (next == 33 && code == 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) == 45 &&
4918
4918
  this.input.charCodeAt(this.pos + 3) == 45) {
4919
- if (this.inModule) { this.unexpected(); }
4920
4919
  // `<!--`, an XML-style comment that should be interpreted as a line comment
4921
4920
  this.skipLineComment(4);
4922
4921
  this.skipSpace();
@@ -5522,19 +5521,39 @@ function relativeId ( id ) {
5522
5521
  return path.relative( process.cwd(), id );
5523
5522
  }
5524
5523
 
5525
- const UNKNOWN_VALUE = { toString: () => '[[UNKNOWN]]' };
5524
+ class Variable {
5525
+ constructor ( name ) {
5526
+ this.name = name;
5527
+ }
5526
5528
 
5527
- const UNKNOWN_ASSIGNMENT = {
5528
- type: 'UNKNOWN',
5529
- hasEffectsWhenMutated: () => true,
5530
- };
5529
+ addCall () {}
5530
+
5531
+ getName () {
5532
+ return this.name;
5533
+ }
5534
+
5535
+ hasEffectsWhenCalled () {
5536
+ return true;
5537
+ }
5538
+
5539
+ hasEffectsWhenMutated () {
5540
+ return true;
5541
+ }
5542
+
5543
+ includeVariable () {
5544
+ if ( this.included ) {
5545
+ return false;
5546
+ }
5547
+ this.included = true;
5548
+ return true;
5549
+ }
5550
+ }
5531
5551
 
5532
- class SyntheticNamespaceDeclaration {
5552
+ class NamespaceVariable extends Variable {
5533
5553
  constructor ( module ) {
5554
+ super( module.basename() );
5534
5555
  this.isNamespace = true;
5535
5556
  this.module = module;
5536
- this.name = module.basename();
5537
-
5538
5557
  this.needsNamespaceBlock = false;
5539
5558
 
5540
5559
  this.originals = blank();
@@ -5547,26 +5566,15 @@ class SyntheticNamespaceDeclaration {
5547
5566
  this.name = node.name;
5548
5567
  }
5549
5568
 
5550
- assignExpression () {
5551
- // This should probably not happen, but not defining this might prevent a more meaningful error message
5552
- }
5553
-
5554
- gatherPossibleValues ( values ) {
5555
- values.add( UNKNOWN_ASSIGNMENT );
5556
- }
5557
-
5558
- getName () {
5559
- return this.name;
5560
- }
5569
+ assignExpression () {}
5561
5570
 
5562
- includeDeclaration () {
5563
- if ( this.included ) {
5564
- return false;
5571
+ includeVariable () {
5572
+ const hasBeenIncluded = super.includeVariable();
5573
+ if ( hasBeenIncluded ) {
5574
+ this.needsNamespaceBlock = true;
5575
+ forOwn( this.originals, original => original.includeVariable() );
5565
5576
  }
5566
- this.included = true;
5567
- this.needsNamespaceBlock = true;
5568
- forOwn( this.originals, original => original.includeDeclaration() );
5569
- return true;
5577
+ return hasBeenIncluded;
5570
5578
  }
5571
5579
 
5572
5580
  renderBlock ( es, legacy, indentString ) {
@@ -5586,55 +5594,6 @@ class SyntheticNamespaceDeclaration {
5586
5594
  }
5587
5595
  }
5588
5596
 
5589
- class ExternalDeclaration {
5590
- constructor ( module, name ) {
5591
- this.module = module;
5592
- this.name = name;
5593
- this.safeName = null;
5594
- this.isExternal = true;
5595
- this.isNamespace = name === '*';
5596
- }
5597
-
5598
- addReference ( reference ) {
5599
- reference.declaration = this;
5600
-
5601
- if ( this.name === 'default' || this.name === '*' ) {
5602
- this.module.suggestName( reference.name );
5603
- }
5604
- }
5605
-
5606
- gatherPossibleValues ( values ) {
5607
- values.add( UNKNOWN_ASSIGNMENT );
5608
- }
5609
-
5610
- getName ( es ) {
5611
- if ( this.name === '*' ) {
5612
- return this.module.name;
5613
- }
5614
-
5615
- if ( this.name === 'default' ) {
5616
- return this.module.exportsNamespace || ( !es && this.module.exportsNames ) ?
5617
- `${this.module.name}__default` :
5618
- this.module.name;
5619
- }
5620
-
5621
- return es ? this.safeName : `${this.module.name}.${this.name}`;
5622
- }
5623
-
5624
- includeDeclaration () {
5625
- if ( this.included ) {
5626
- return false;
5627
- }
5628
- this.included = true;
5629
- this.module.used = true;
5630
- return true;
5631
- }
5632
-
5633
- setSafeName ( name ) {
5634
- this.safeName = name;
5635
- }
5636
- }
5637
-
5638
5597
  function extractNames ( param ) {
5639
5598
  const names = [];
5640
5599
  extractors[ param.type ]( names, param );
@@ -5667,13 +5626,216 @@ const extractors = {
5667
5626
  }
5668
5627
  };
5669
5628
 
5670
- class Node$1 {
5671
- assignExpression () {}
5629
+ const UNKNOWN_VALUE = { toString: () => '[[UNKNOWN]]' };
5630
+
5631
+ const UNKNOWN_ASSIGNMENT = {
5632
+ type: 'UNKNOWN',
5633
+ bindCall: () => {},
5634
+ hasEffectsWhenCalled: () => true,
5635
+ hasEffectsWhenMutated: () => true,
5636
+ };
5637
+
5638
+ const UNDEFINED_ASSIGNMENT = {
5639
+ type: 'UNDEFINED',
5640
+ bindCall: () => {},
5641
+ hasEffectsWhenCalled: () => true,
5642
+ hasEffectsWhenMutated: () => true,
5643
+ };
5644
+
5645
+ const UNKNOWN_OBJECT_LITERAL = {
5646
+ type: 'UNKNOWN_OBJECT_LITERAL',
5647
+ bindCall: () => {},
5648
+ hasEffectsWhenCalled: () => true,
5649
+ hasEffectsWhenMutated: () => false,
5650
+ };
5651
+
5652
+ const OPTION_IGNORE_BREAK_STATEMENTS = 'IGNORE_BREAK_STATEMENTS';
5653
+ const OPTION_IGNORE_RETURN_AWAIT_YIELD = 'IGNORE_RETURN_AWAIT_YIELD';
5654
+ const OPTION_IGNORE_SAFE_THIS_MUTATIONS = 'IGNORE_SAFE_THIS_MUTATIONS';
5655
+ const OPTION_CALLED_NODES = 'CALLED_NODES';
5656
+ const OPTION_MUTATED_NODES = 'MUTATED_NODES';
5657
+ const IGNORED_LABELS = 'IGNORED_LABELS';
5658
+
5659
+ /** Wrapper to ensure immutability */
5660
+ class ExecutionPathOptions {
5661
+ /**
5662
+ * @returns {ExecutionPathOptions}
5663
+ */
5664
+ static create () {
5665
+ return new this( {} );
5666
+ }
5667
+
5668
+ constructor ( optionValues ) {
5669
+ this._optionValues = optionValues;
5670
+ }
5671
+
5672
+ /**
5673
+ * Returns a new ExecutionPathOptions instance with the given option set to a new value.
5674
+ * Does not mutate the current instance. Also works in sub-classes.
5675
+ * @param {string} option - The name of an option
5676
+ * @param {*} value - The new value of the option
5677
+ * @returns {ExecutionPathOptions} A new options instance
5678
+ */
5679
+ set ( option, value ) {
5680
+ return new this.constructor( Object.assign( {}, this._optionValues, { [option]: value } ) );
5681
+ }
5682
+
5683
+ /**
5684
+ * @param {string} option - The name of an option
5685
+ * @returns {*} Its value
5686
+ */
5687
+ get ( option ) {
5688
+ return this._optionValues[ option ];
5689
+ }
5690
+
5691
+ /**
5692
+ * @return {boolean}
5693
+ */
5694
+ ignoreBreakStatements () {
5695
+ return this.get( OPTION_IGNORE_BREAK_STATEMENTS );
5696
+ }
5697
+
5698
+ /**
5699
+ * @param {boolean} [value=true]
5700
+ * @return {ExecutionPathOptions}
5701
+ */
5702
+ setIgnoreBreakStatements ( value ) {
5703
+ if ( value === void 0 ) value = true;
5672
5704
 
5705
+ return this.set( OPTION_IGNORE_BREAK_STATEMENTS, value );
5706
+ }
5707
+
5708
+ /**
5709
+ * @param {string} labelName
5710
+ * @return {boolean}
5711
+ */
5712
+ ignoreLabel ( labelName ) {
5713
+ const ignoredLabels = this.get( IGNORED_LABELS );
5714
+ return ignoredLabels && ignoredLabels.has( labelName );
5715
+ }
5716
+
5717
+ /**
5718
+ * @param {string} labelName
5719
+ * @return {ExecutionPathOptions}
5720
+ */
5721
+ setIgnoreLabel ( labelName ) {
5722
+ return this.set( IGNORED_LABELS, new Set( this.get( IGNORED_LABELS ) ).add( labelName ) );
5723
+ }
5724
+
5725
+ /**
5726
+ * @return {ExecutionPathOptions}
5727
+ */
5728
+ setIgnoreNoLabels () {
5729
+ return this.set( IGNORED_LABELS, null );
5730
+ }
5731
+
5732
+ /**
5733
+ * @return {boolean}
5734
+ */
5735
+ ignoreReturnAwaitYield () {
5736
+ return this.get( OPTION_IGNORE_RETURN_AWAIT_YIELD );
5737
+ }
5738
+
5739
+ /**
5740
+ * @param {boolean} [value=true]
5741
+ * @return {ExecutionPathOptions}
5742
+ */
5743
+ setIgnoreReturnAwaitYield ( value ) {
5744
+ if ( value === void 0 ) value = true;
5745
+
5746
+ return this.set( OPTION_IGNORE_RETURN_AWAIT_YIELD, value );
5747
+ }
5748
+
5749
+ /**
5750
+ * @return {boolean}
5751
+ */
5752
+ ignoreSafeThisMutations () {
5753
+ return this.get( OPTION_IGNORE_SAFE_THIS_MUTATIONS );
5754
+ }
5755
+
5756
+ /**
5757
+ * @param {boolean} [value=true]
5758
+ * @return {ExecutionPathOptions}
5759
+ */
5760
+ setIgnoreSafeThisMutations ( value ) {
5761
+ if ( value === void 0 ) value = true;
5762
+
5763
+ return this.set( OPTION_IGNORE_SAFE_THIS_MUTATIONS, value );
5764
+ }
5765
+
5766
+ /**
5767
+ * @param {Node} node
5768
+ * @return {ExecutionPathOptions}
5769
+ */
5770
+ addMutatedNode ( node ) {
5771
+ return this.set( OPTION_MUTATED_NODES, new Set( this.get( OPTION_MUTATED_NODES ) ).add( node ) );
5772
+ }
5773
+
5774
+ /**
5775
+ * @param {Node} node
5776
+ * @return {boolean}
5777
+ */
5778
+ hasNodeBeenMutated ( node ) {
5779
+ const mutatedNodes = this.get( OPTION_MUTATED_NODES );
5780
+ return mutatedNodes && mutatedNodes.has( node );
5781
+ }
5782
+
5783
+ /**
5784
+ * @param {Node} node
5785
+ * @return {ExecutionPathOptions}
5786
+ */
5787
+ addCalledNode ( node ) {
5788
+ return this.set( OPTION_CALLED_NODES, new Set( this.get( OPTION_CALLED_NODES ) ).add( node ) );
5789
+ }
5790
+
5791
+ /**
5792
+ * @param {Node} node
5793
+ * @return {boolean}
5794
+ */
5795
+ hasNodeBeenCalled ( node ) {
5796
+ const calledNodes = this.get( OPTION_CALLED_NODES );
5797
+ return calledNodes && calledNodes.has( node );
5798
+ }
5799
+
5800
+ /**
5801
+ * @param {Node} calledNode
5802
+ * @return {ExecutionPathOptions}
5803
+ */
5804
+ getHasEffectsWhenCalledOptions ( calledNode ) {
5805
+ return this
5806
+ .addCalledNode( calledNode )
5807
+ .setIgnoreReturnAwaitYield()
5808
+ .setIgnoreBreakStatements( false )
5809
+ .setIgnoreNoLabels();
5810
+ }
5811
+ }
5812
+
5813
+ class Node$1 {
5814
+ /**
5815
+ * Called once all nodes have been initialised and the scopes have been populated.
5816
+ * Use this to bind assignments and calls to variables.
5817
+ */
5673
5818
  bind () {
5674
5819
  this.eachChild( child => child.bind() );
5675
5820
  }
5676
5821
 
5822
+ /**
5823
+ * Bind an expression as an assignment to a node.
5824
+ * The default noop implementation is ok as long as hasEffectsWhenAssigned
5825
+ * always returns true for this node. Otherwise it should be overridden.
5826
+ * @param {Node} expression
5827
+ */
5828
+ bindAssignment () {}
5829
+
5830
+ /**
5831
+ * Binds ways a node is called to a node. Current options are:
5832
+ * - withNew: boolean - Did this call use the "new" operator
5833
+ * The default noop implementation is ok as long as hasEffectsWhenCalled
5834
+ * always returns true for this node. Otherwise it should be overridden.
5835
+ * @param callOptions
5836
+ */
5837
+ bindCall () {}
5838
+
5677
5839
  eachChild ( callback ) {
5678
5840
  this.keys.forEach( key => {
5679
5841
  const value = this[ key ];
@@ -5687,30 +5849,65 @@ class Node$1 {
5687
5849
  } );
5688
5850
  }
5689
5851
 
5690
- gatherPossibleValues ( values ) {
5691
- values.add( UNKNOWN_ASSIGNMENT );
5692
- }
5693
-
5694
5852
  getValue () {
5695
5853
  return UNKNOWN_VALUE;
5696
5854
  }
5697
5855
 
5856
+ /**
5857
+ * Determine if this Node would have an effect on the bundle.
5858
+ * This is usually true for already included nodes. Exceptions are e.g. break statements
5859
+ * which only have an effect if their surrounding loop or switch statement is included.
5860
+ * The options pass on information like this about the current execution path.
5861
+ * @param {ExecutionPathOptions} options
5862
+ * @return {boolean}
5863
+ */
5698
5864
  hasEffects ( options ) {
5699
5865
  return this.included || this.someChild( child => child.hasEffects( options ) );
5700
5866
  }
5701
5867
 
5868
+ /**
5869
+ * Special make-shift logic to treat cases where apparently side-effect free statements
5870
+ * are executed for side-effects. The most important case are getters with side-effects.
5871
+ * Once we can reliably handle this case in member expressions, this function should
5872
+ * probably be removed again.
5873
+ * @param {ExecutionPathOptions} options
5874
+ * @return {boolean}
5875
+ */
5876
+ hasEffectsAsExpressionStatement () {
5877
+ return true;
5878
+ }
5879
+
5880
+ /**
5881
+ * @param {ExecutionPathOptions} options
5882
+ * @return {boolean}
5883
+ */
5702
5884
  hasEffectsWhenAssigned () {
5703
- return false;
5885
+ return true;
5704
5886
  }
5705
5887
 
5706
- hasEffectsWhenMutated () {
5707
- return false;
5888
+ /**
5889
+ * @param {ExecutionPathOptions} options
5890
+ * @return {boolean}
5891
+ */
5892
+ hasEffectsWhenCalled () {
5893
+ return true;
5708
5894
  }
5709
5895
 
5710
- includeDeclaration () {
5711
- return this.includeInBundle();
5896
+ /**
5897
+ * @param {ExecutionPathOptions} options
5898
+ * @return {boolean}
5899
+ */
5900
+ hasEffectsWhenMutated () {
5901
+ return true;
5712
5902
  }
5713
5903
 
5904
+ /**
5905
+ * Includes the node in the bundle. Children are usually included if they are
5906
+ * necessary for this node (e.g. a function body) or if they have effects.
5907
+ * Necessary variables should be included as well. Should return true if any
5908
+ * nodes or variables have been added that were missing before.
5909
+ * @return {boolean}
5910
+ */
5714
5911
  includeInBundle () {
5715
5912
  if ( this.isFullyIncluded() ) { return false; }
5716
5913
  let addedNewNodes = false;
@@ -5726,21 +5923,49 @@ class Node$1 {
5726
5923
  return true;
5727
5924
  }
5728
5925
 
5926
+ /**
5927
+ * Alternative version of includeInBundle to override the default behaviour of
5928
+ * declarations to only include nodes for declarators that have an effect. Necessary
5929
+ * for for-loops that do not use a declared loop variable.
5930
+ * @return {boolean}
5931
+ */
5932
+ includeWithAllDeclarations () {
5933
+ return this.includeInBundle();
5934
+ }
5935
+
5936
+ /**
5937
+ * Assign a scope to this node and make sure all children have the right scopes.
5938
+ * Perform any additional initialisation that does not depend on the scope being
5939
+ * populated with variables.
5940
+ * Usually one should not override this function but override initialiseScope,
5941
+ * initialiseNode and/or initialiseChildren instead. BlockScopes have a special
5942
+ * alternative initialisation initialiseAndReplaceScope.
5943
+ * @param {Scope} parentScope
5944
+ */
5729
5945
  initialise ( parentScope ) {
5730
5946
  this.initialiseScope( parentScope );
5731
5947
  this.initialiseNode( parentScope );
5732
5948
  this.initialiseChildren( parentScope );
5733
5949
  }
5734
5950
 
5735
- // Override if e.g. some children need to be initialised with the parent scope
5951
+ /**
5952
+ * Override to change how and with what scopes children are initialised
5953
+ * @param {Scope} parentScope
5954
+ */
5736
5955
  initialiseChildren () {
5737
5956
  this.eachChild( child => child.initialise( this.scope ) );
5738
5957
  }
5739
5958
 
5740
- // Override to perform special initialisation steps after the scope is initialised
5959
+ /**
5960
+ * Override to perform special initialisation steps after the scope is initialised
5961
+ * @param {Scope} parentScope
5962
+ */
5741
5963
  initialiseNode () {}
5742
5964
 
5743
- // Overwrite to create a new scope
5965
+ /**
5966
+ * Override if this scope should receive a different scope than the parent scope.
5967
+ * @param {Scope} parentScope
5968
+ */
5744
5969
  initialiseScope ( parentScope ) {
5745
5970
  this.scope = parentScope;
5746
5971
  }
@@ -5751,6 +5976,11 @@ class Node$1 {
5751
5976
  }
5752
5977
  }
5753
5978
 
5979
+ /**
5980
+ * Shortcut to skip checking this node for effects when all children have already
5981
+ * been included.
5982
+ * @param {Scope} parentScope
5983
+ */
5754
5984
  isFullyIncluded () {
5755
5985
  if ( this._fullyIncluded ) {
5756
5986
  return true;
@@ -5771,8 +6001,15 @@ class Node$1 {
5771
6001
  this.eachChild( child => child.render( code, es ) );
5772
6002
  }
5773
6003
 
6004
+ /**
6005
+ * Start a new execution path to determine if this node has an effect on the bundle and
6006
+ * should therefore be included. Unless they are fully included, included nodes should
6007
+ * always be included again in subsequent visits as the inclusion of additional variables
6008
+ * may require the inclusion of more child nodes in e.g. block statements.
6009
+ * @return {boolean}
6010
+ */
5774
6011
  shouldBeIncluded () {
5775
- return this.hasEffects( {} );
6012
+ return this.hasEffects( ExecutionPathOptions.create() );
5776
6013
  }
5777
6014
 
5778
6015
  someChild ( callback ) {
@@ -5793,45 +6030,91 @@ class Node$1 {
5793
6030
  }
5794
6031
 
5795
6032
  class ArrayPattern extends Node$1 {
5796
- assignExpression () {
5797
- this.eachChild( child => child.assignExpression( UNKNOWN_ASSIGNMENT ) );
6033
+ bindAssignment () {
6034
+ this.eachChild( child => child.bindAssignment( UNKNOWN_ASSIGNMENT ) );
5798
6035
  }
5799
6036
 
5800
6037
  hasEffectsWhenAssigned ( options ) {
5801
6038
  return this.someChild( child => child.hasEffectsWhenAssigned( options ) );
5802
6039
  }
6040
+
6041
+ initialiseAndDeclare ( parentScope, kind ) {
6042
+ this.initialiseScope( parentScope );
6043
+ this.eachChild( child => child.initialiseAndDeclare( parentScope, kind, UNKNOWN_ASSIGNMENT ) );
6044
+ }
5803
6045
  }
5804
6046
 
5805
- class Parameter {
5806
- constructor ( name ) {
5807
- this.name = name;
5808
- this.isParam = true;
5809
- this.assignedExpressions = new Set( [ UNKNOWN_ASSIGNMENT ] );
6047
+ class LocalVariable extends Variable {
6048
+ constructor ( name, declarator, init ) {
6049
+ super( name );
6050
+ this.isReassigned = false;
6051
+ this.exportName = null;
6052
+ this.declarations = new Set( declarator ? [ declarator ] : null );
6053
+ this.assignedExpressions = new Set( init ? [ init ] : null );
6054
+ this.calls = new Set();
6055
+ }
6056
+
6057
+ addDeclaration ( identifier ) {
6058
+ this.declarations.add( identifier );
5810
6059
  }
5811
6060
 
5812
- addReference () {
5813
- // noop?
6061
+ addCall ( callOptions ) {
6062
+ // To prevent infinite loops
6063
+ if ( this.calls.has( callOptions ) ) { return; }
6064
+ this.calls.add( callOptions );
6065
+ Array.from( this.assignedExpressions ).forEach( expression => expression.bindCall( callOptions ) );
5814
6066
  }
5815
6067
 
6068
+ addReference () {}
6069
+
5816
6070
  assignExpression ( expression ) {
5817
6071
  this.assignedExpressions.add( expression );
5818
6072
  this.isReassigned = true;
6073
+ Array.from( this.calls ).forEach( callOptions => expression.bindCall( callOptions ) );
5819
6074
  }
5820
6075
 
5821
- gatherPossibleValues ( values ) {
5822
- values.add( UNKNOWN_ASSIGNMENT ); // TODO populate this at call time
6076
+ getName ( es ) {
6077
+ if ( es ) { return this.name; }
6078
+ if ( !this.isReassigned || !this.exportName ) { return this.name; }
6079
+
6080
+ return `exports.${this.exportName}`;
5823
6081
  }
5824
6082
 
5825
- getName () {
5826
- return this.name;
6083
+ hasEffectsWhenCalled ( options ) {
6084
+ return Array.from( this.assignedExpressions ).some( node =>
6085
+ !options.hasNodeBeenCalled( node )
6086
+ && node.hasEffectsWhenCalled( options.getHasEffectsWhenCalledOptions( node ) )
6087
+ );
5827
6088
  }
5828
6089
 
5829
- includeDeclaration () {
5830
- if ( this.included ) {
5831
- return false;
6090
+ hasEffectsWhenMutated ( options ) {
6091
+ return this.included
6092
+ || Array.from( this.assignedExpressions ).some( node =>
6093
+ !options.hasNodeBeenMutated( node ) &&
6094
+ node.hasEffectsWhenMutated( options.addMutatedNode( node ) )
6095
+ );
6096
+ }
6097
+
6098
+ includeVariable () {
6099
+ const hasBeenIncluded = super.includeVariable();
6100
+ if ( hasBeenIncluded ) {
6101
+ this.declarations.forEach( identifier => identifier.includeInBundle() );
5832
6102
  }
5833
- this.included = true;
5834
- return true;
6103
+ return hasBeenIncluded;
6104
+ }
6105
+
6106
+ toString () {
6107
+ return this.name;
6108
+ }
6109
+ }
6110
+
6111
+ class ParameterVariable extends LocalVariable {
6112
+ constructor ( name, declarator ) {
6113
+ super( name, declarator, UNKNOWN_ASSIGNMENT );
6114
+ }
6115
+
6116
+ getName () {
6117
+ return this.name;
5835
6118
  }
5836
6119
  }
5837
6120
 
@@ -5840,43 +6123,38 @@ class Scope {
5840
6123
  if ( options === void 0 ) options = {};
5841
6124
 
5842
6125
  this.parent = options.parent;
5843
- this.isBlockScope = !!options.isBlockScope;
5844
- this.isLexicalBoundary = !!options.isLexicalBoundary;
5845
6126
  this.isModuleScope = !!options.isModuleScope;
5846
6127
 
5847
6128
  this.children = [];
5848
6129
  if ( this.parent ) { this.parent.children.push( this ); }
5849
6130
 
5850
- this.declarations = blank();
5851
-
5852
- if ( this.isLexicalBoundary && !this.isModuleScope ) {
5853
- this.declarations.arguments = new Parameter( 'arguments' );
5854
- }
6131
+ this.variables = blank();
5855
6132
  }
5856
6133
 
5857
- addDeclaration ( name, declaration, isVar, isParam ) {
5858
- if ( isVar && this.isBlockScope ) {
5859
- this.parent.addDeclaration( name, declaration, isVar, isParam );
6134
+ addDeclaration ( identifier, isHoisted, init ) {
6135
+ const name = identifier.name;
6136
+ if ( this.variables[ name ] ) {
6137
+ const variable = this.variables[ name ];
6138
+ variable.addDeclaration( identifier );
6139
+ init && variable.assignExpression( init );
5860
6140
  } else {
5861
- const existingDeclaration = this.declarations[ name ];
5862
-
5863
- if ( existingDeclaration && existingDeclaration.duplicates ) {
5864
- // TODO warn/throw on duplicates?
5865
- existingDeclaration.duplicates.push( declaration );
5866
- } else {
5867
- this.declarations[ name ] = isParam ? new Parameter( name ) : declaration;
5868
- }
6141
+ this.variables[ name ] = new LocalVariable( identifier.name, identifier, init );
5869
6142
  }
5870
6143
  }
5871
6144
 
6145
+ addParameterDeclaration ( identifier ) {
6146
+ const name = identifier.name;
6147
+ this.variables[ name ] = new ParameterVariable( name, identifier );
6148
+ }
6149
+
5872
6150
  contains ( name ) {
5873
- return !!this.declarations[ name ] ||
6151
+ return !!this.variables[ name ] ||
5874
6152
  ( this.parent ? this.parent.contains( name ) : false );
5875
6153
  }
5876
6154
 
5877
6155
  deshadow ( names ) {
5878
- keys( this.declarations ).forEach( key => {
5879
- const declaration = this.declarations[ key ];
6156
+ keys( this.variables ).forEach( key => {
6157
+ const declaration = this.variables[ key ];
5880
6158
 
5881
6159
  // we can disregard exports.foo etc
5882
6160
  if ( declaration.exportName && declaration.isReassigned ) { return; }
@@ -5896,61 +6174,52 @@ class Scope {
5896
6174
  this.children.forEach( scope => scope.deshadow( names ) );
5897
6175
  }
5898
6176
 
5899
- findDeclaration ( name ) {
5900
- return this.declarations[ name ] ||
5901
- ( this.parent && this.parent.findDeclaration( name ) );
6177
+ findLexicalBoundary () {
6178
+ return this.parent.findLexicalBoundary();
5902
6179
  }
5903
6180
 
5904
- findLexicalBoundary () {
5905
- return this.isLexicalBoundary ? this : this.parent.findLexicalBoundary();
6181
+ findVariable ( name ) {
6182
+ return this.variables[ name ] ||
6183
+ ( this.parent && this.parent.findVariable( name ) );
5906
6184
  }
5907
6185
  }
5908
6186
 
5909
- class Function$1 extends Node$1 {
5910
- bind () {
5911
- if ( this.id ) { this.id.bind(); }
5912
- this.params.forEach( param => param.bind() );
5913
- this.body.bind();
5914
- }
6187
+ class ArrowFunctionExpression extends Node$1 {
6188
+ // Should receive an implementation once we start tracking parameter values
6189
+ bindCall () {}
5915
6190
 
5916
6191
  hasEffects () {
5917
6192
  return this.included;
5918
6193
  }
5919
6194
 
5920
- initialiseChildren () {
5921
- this.params.forEach( param => {
5922
- param.initialise( this.scope );
5923
- extractNames( param ).forEach( name => this.scope.addDeclaration( name, null, false, true ) );
5924
- } );
5925
- this.body.initialiseAndReplaceScope ?
5926
- this.body.initialiseAndReplaceScope( this.scope ) :
5927
- this.body.initialise( this.scope );
6195
+ hasEffectsWhenCalled ( options ) {
6196
+ return this.params.some( param => param.hasEffects( options ) )
6197
+ || this.body.hasEffects( options );
5928
6198
  }
5929
6199
 
5930
- initialiseScope ( parentScope ) {
5931
- this.scope = new Scope( {
5932
- parent: parentScope,
5933
- isBlockScope: false,
5934
- isLexicalBoundary: true
5935
- } );
6200
+ hasEffectsWhenMutated () {
6201
+ return this.included;
6202
+ }
6203
+
6204
+ initialiseChildren () {
6205
+ this.params.forEach( param => param.initialiseAndDeclare( this.scope, 'parameter' ) );
6206
+ if ( this.body.initialiseAndReplaceScope ) {
6207
+ this.body.initialiseAndReplaceScope( new Scope( { parent: this.scope } ) );
6208
+ } else {
6209
+ this.body.initialise( this.scope );
6210
+ }
5936
6211
  }
5937
- }
5938
6212
 
5939
- class ArrowFunctionExpression extends Function$1 {
5940
6213
  initialiseScope ( parentScope ) {
5941
- this.scope = new Scope( {
5942
- parent: parentScope,
5943
- isBlockScope: false,
5944
- isLexicalBoundary: false
5945
- } );
6214
+ this.scope = new Scope( { parent: parentScope } );
5946
6215
  }
5947
6216
  }
5948
6217
 
5949
6218
  // TODO tidy this up a bit (e.g. they can both use node.module.imports)
5950
6219
  function disallowIllegalReassignment ( scope, node ) {
5951
6220
  if ( node.type === 'MemberExpression' && node.object.type === 'Identifier' ) {
5952
- const declaration = scope.findDeclaration( node.object.name );
5953
- if ( declaration.isNamespace ) {
6221
+ const variable = scope.findVariable( node.object.name );
6222
+ if ( variable.isNamespace ) {
5954
6223
  node.module.error({
5955
6224
  code: 'ILLEGAL_NAMESPACE_REASSIGNMENT',
5956
6225
  message: `Illegal reassignment to import '${node.object.name}'`
@@ -5972,22 +6241,47 @@ class AssignmentExpression extends Node$1 {
5972
6241
  bind () {
5973
6242
  super.bind();
5974
6243
  disallowIllegalReassignment( this.scope, this.left );
5975
- this.left.assignExpression( this.right );
6244
+ this.left.bindAssignment( this.right );
5976
6245
  }
5977
6246
 
5978
6247
  hasEffects ( options ) {
5979
6248
  return super.hasEffects( options ) || this.left.hasEffectsWhenAssigned( options );
5980
6249
  }
5981
6250
 
5982
- hasEffectsWhenMutated () {
5983
- return true;
6251
+ hasEffectsAsExpressionStatement ( options ) {
6252
+ return this.hasEffects( options );
6253
+ }
6254
+ }
6255
+
6256
+ class AssignmentPattern extends Node$1 {
6257
+ bind () {
6258
+ super.bind();
6259
+ this.left.bindAssignment( this.right );
6260
+ }
6261
+
6262
+ bindAssignment ( expression ) {
6263
+ this.left.bindAssignment( expression );
6264
+ }
6265
+
6266
+ hasEffectsWhenAssigned ( options ) {
6267
+ return this.left.hasEffectsWhenAssigned( options );
6268
+ }
6269
+
6270
+ initialiseAndDeclare ( parentScope, kind, init ) {
6271
+ this.initialiseScope( parentScope );
6272
+ this.right.initialise( parentScope );
6273
+ this.left.initialiseAndDeclare( parentScope, kind, init );
5984
6274
  }
5985
6275
  }
5986
6276
 
5987
6277
  class AwaitExpression extends Node$1 {
5988
6278
  hasEffects ( options ) {
5989
6279
  return super.hasEffects( options )
5990
- || !options.inNestedFunctionCall;
6280
+ || !options.ignoreReturnAwaitYield();
6281
+ }
6282
+
6283
+ hasEffectsAsExpressionStatement ( options ) {
6284
+ return this.hasEffects( options );
5991
6285
  }
5992
6286
  }
5993
6287
 
@@ -6028,10 +6322,6 @@ class BinaryExpression extends Node$1 {
6028
6322
 
6029
6323
  return operators[ this.operator ]( leftValue, rightValue );
6030
6324
  }
6031
-
6032
- hasEffectsWhenMutated () {
6033
- return true;
6034
- }
6035
6325
  }
6036
6326
 
6037
6327
  class Statement extends Node$1 {
@@ -6044,11 +6334,26 @@ class Statement extends Node$1 {
6044
6334
  }
6045
6335
  }
6046
6336
 
6337
+ class BlockScope extends Scope {
6338
+ addDeclaration ( identifier, isHoisted, init ) {
6339
+ if ( isHoisted ) {
6340
+ this.parent.addDeclaration( identifier, isHoisted, init );
6341
+ } else {
6342
+ super.addDeclaration( identifier, false, init );
6343
+ }
6344
+ }
6345
+ }
6346
+
6047
6347
  class BlockStatement extends Statement {
6048
6348
  bind () {
6049
6349
  this.body.forEach( node => node.bind() );
6050
6350
  }
6051
6351
 
6352
+ hasEffects ( options ) {
6353
+ // Empty block statements do not have effects even though they may be included as e.g. function body
6354
+ return this.body.some( child => child.hasEffects( options ) );
6355
+ }
6356
+
6052
6357
  includeInBundle () {
6053
6358
  if ( this.isFullyIncluded() ) { return false; }
6054
6359
  let addedNewNodes = false;
@@ -6058,266 +6363,66 @@ class BlockStatement extends Statement {
6058
6363
  addedNewNodes = true;
6059
6364
  }
6060
6365
  }
6061
- } );
6062
- if ( !this.included || addedNewNodes ) {
6063
- this.included = true;
6064
- return true;
6065
- }
6066
- return false;
6067
- }
6068
-
6069
- initialiseAndReplaceScope ( scope ) {
6070
- this.scope = scope;
6071
- this.initialiseNode();
6072
- this.initialiseChildren( scope );
6073
- }
6074
-
6075
- initialiseChildren () {
6076
- let lastNode;
6077
- for ( const node of this.body ) {
6078
- node.initialise( this.scope );
6079
-
6080
- if ( lastNode ) { lastNode.next = node.start; }
6081
- lastNode = node;
6082
- }
6083
- }
6084
-
6085
- initialiseScope ( parentScope ) {
6086
- this.scope = new Scope( {
6087
- parent: parentScope,
6088
- isBlockScope: true,
6089
- isLexicalBoundary: false
6090
- } );
6091
- }
6092
-
6093
- render ( code, es ) {
6094
- if ( this.body.length ) {
6095
- for ( const node of this.body ) {
6096
- node.render( code, es );
6097
- }
6098
- } else {
6099
- Statement.prototype.render.call( this, code, es );
6100
- }
6101
- }
6102
- }
6103
-
6104
- class BreakStatement extends Node$1 {
6105
- hasEffects ( options ) {
6106
- return super.hasEffects( options )
6107
- || !options.inNestedBreakableStatement;
6108
- }
6109
-
6110
- shouldBeIncluded () {
6111
- return true;
6112
- }
6113
- }
6114
-
6115
- function isReference (node, parent) {
6116
- if (node.type === 'MemberExpression') {
6117
- return !node.computed && isReference(node.object, node);
6118
- }
6119
-
6120
- if (node.type === 'Identifier') {
6121
- // the only time we could have an identifier node without a parent is
6122
- // if it's the entire body of a function without a block statement –
6123
- // i.e. an arrow function expression like `a => a`
6124
- if (!parent) return true;
6125
-
6126
- // TODO is this right?
6127
- if (parent.type === 'MemberExpression' || parent.type === 'MethodDefinition') {
6128
- return parent.computed || node === parent.object;
6129
- }
6130
-
6131
- // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
6132
- if (parent.type === 'Property') return parent.computed || node === parent.value;
6133
-
6134
- // disregard the `bar` in `class Foo { bar () {...} }`
6135
- if (parent.type === 'MethodDefinition') return false;
6136
-
6137
- // disregard the `bar` in `export { foo as bar }`
6138
- if (parent.type === 'ExportSpecifier' && node !== parent.local) return false;
6139
-
6140
- return true;
6141
- }
6142
-
6143
- return false;
6144
- }
6145
-
6146
- function flatten ( node ) {
6147
- const parts = [];
6148
- while ( node.type === 'MemberExpression' ) {
6149
- if ( node.computed ) { return null; }
6150
- parts.unshift( node.property.name );
6151
-
6152
- node = node.object;
6153
- }
6154
-
6155
- if ( node.type !== 'Identifier' ) { return null; }
6156
-
6157
- const name = node.name;
6158
- parts.unshift( name );
6159
-
6160
- return { name, keypath: parts.join( '.' ) };
6161
- }
6162
-
6163
- const pureFunctions = {};
6164
-
6165
- const arrayTypes = 'Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split( ' ' );
6166
- const simdTypes = 'Int8x16 Int16x8 Int32x4 Float32x4 Float64x2'.split( ' ' );
6167
- 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( ' ' );
6168
- const allSimdMethods = [];
6169
- simdTypes.forEach( t => {
6170
- simdMethods.forEach( m => {
6171
- allSimdMethods.push( `SIMD.${t}.${m}` );
6172
- });
6173
- });
6174
-
6175
- [
6176
- 'Array.isArray',
6177
- 'Error', 'EvalError', 'InternalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError',
6178
- 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape', 'unescape',
6179
- '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',
6180
- 'Function', 'Boolean',
6181
- 'Number', 'Number.isFinite', 'Number.isInteger', 'Number.isNaN', 'Number.isSafeInteger', 'Number.parseFloat', 'Number.parseInt',
6182
- 'Symbol', 'Symbol.for', 'Symbol.keyFor',
6183
- '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',
6184
- 'Date', 'Date.UTC', 'Date.now', 'Date.parse',
6185
- 'String', 'String.fromCharCode', 'String.fromCodePoint', 'String.raw',
6186
- 'RegExp',
6187
- 'Map', 'Set', 'WeakMap', 'WeakSet',
6188
- 'ArrayBuffer', 'ArrayBuffer.isView',
6189
- 'DataView',
6190
- 'JSON.parse', 'JSON.stringify',
6191
- 'Promise', 'Promise.all', 'Promise.race', 'Promise.reject', 'Promise.resolve',
6192
- 'Intl.Collator', 'Intl.Collator.supportedLocalesOf', 'Intl.DateTimeFormat', 'Intl.DateTimeFormat.supportedLocalesOf', 'Intl.NumberFormat', 'Intl.NumberFormat.supportedLocalesOf'
6193
-
6194
- // TODO properties of e.g. window...
6195
- ].concat(
6196
- arrayTypes,
6197
- arrayTypes.map( t => `${t}.from` ),
6198
- arrayTypes.map( t => `${t}.of` ),
6199
- simdTypes.map( t => `SIMD.${t}` ),
6200
- allSimdMethods
6201
- ).forEach( name => pureFunctions[ name ] = true );
6202
-
6203
- const currentlyCalling = new Set();
6204
-
6205
- function isES5Function ( node ) {
6206
- return node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration';
6207
- }
6208
-
6209
- function hasEffectsNew ( node ) {
6210
- let inner = node;
6211
-
6212
- if ( inner.type === 'ExpressionStatement' ) {
6213
- inner = inner.expression;
6214
-
6215
- if ( inner.type === 'AssignmentExpression' ) {
6216
- if ( inner.right.hasEffects( { inNestedFunctionCall: true } ) ) {
6217
- return true;
6218
-
6219
- } else {
6220
- inner = inner.left;
6221
-
6222
- if ( inner.type === 'MemberExpression' ) {
6223
- if ( inner.computed && inner.property.hasEffects( { inNestedFunctionCall: true } ) ) {
6224
- return true;
6225
-
6226
- } else {
6227
- inner = inner.object;
6228
-
6229
- if ( inner.type === 'ThisExpression' ) {
6230
- return false;
6231
- }
6232
- }
6233
- }
6234
- }
6235
- }
6236
- }
6237
-
6238
- return node.hasEffects( { inNestedFunctionCall: true } );
6239
- }
6240
-
6241
- function fnHasEffects ( fn, isNew ) {
6242
- if ( currentlyCalling.has( fn ) ) { return false; } // prevent infinite loops... TODO there must be a better way
6243
- currentlyCalling.add( fn );
6244
-
6245
- // handle body-less arrow functions
6246
- const body = fn.body.type === 'BlockStatement' ? fn.body.body : [ fn.body ];
6247
-
6248
- for ( const node of body ) {
6249
- if ( isNew ? hasEffectsNew( node ) : node.hasEffects( { inNestedFunctionCall: true } ) ) {
6250
- currentlyCalling.delete( fn );
6251
- return true;
6252
- }
6253
- }
6254
-
6255
- currentlyCalling.delete( fn );
6256
- return false;
6257
- }
6258
-
6259
- function callHasEffects ( scope, callee, isNew ) {
6260
- const values = new Set( [ callee ] );
6261
-
6262
- for ( const node of values ) {
6263
- if ( node.type === 'UNKNOWN' ) { return true; } // err on side of caution
6264
-
6265
- if ( /Function/.test( node.type ) ) {
6266
- if ( fnHasEffects( node, isNew && isES5Function( node ) ) ) { return true; }
6267
- }
6268
-
6269
- else if ( /Class/.test( node.type ) ) {
6270
- // TODO find constructor (may belong to a superclass)
6271
- return true;
6272
- }
6273
-
6274
- else if ( isReference( node ) ) {
6275
- const flattened = flatten( node );
6276
- const declaration = scope.findDeclaration( flattened.name );
6277
-
6278
- if ( declaration.isGlobal ) {
6279
- if ( !pureFunctions[ flattened.keypath ] ) { return true; }
6280
- }
6281
-
6282
- else if ( declaration.isExternal ) {
6283
- return true; // TODO make this configurable? e.g. `path.[whatever]`
6284
- }
6285
-
6286
- else {
6287
- if ( node.declaration ) {
6288
- node.declaration.gatherPossibleValues( values );
6289
- } else {
6290
- return true;
6291
- }
6292
- }
6366
+ } );
6367
+ if ( !this.included || addedNewNodes ) {
6368
+ this.included = true;
6369
+ return true;
6293
6370
  }
6371
+ return false;
6372
+ }
6373
+
6374
+ initialiseAndReplaceScope ( scope ) {
6375
+ this.scope = scope;
6376
+ this.initialiseNode();
6377
+ this.initialiseChildren( scope );
6378
+ }
6379
+
6380
+ initialiseChildren () {
6381
+ let lastNode;
6382
+ for ( const node of this.body ) {
6383
+ node.initialise( this.scope );
6294
6384
 
6295
- else if ( node.gatherPossibleValues ) {
6296
- node.gatherPossibleValues( values );
6385
+ if ( lastNode ) { lastNode.next = node.start; }
6386
+ lastNode = node;
6297
6387
  }
6388
+ }
6298
6389
 
6299
- else {
6300
- // probably an error in the user's code — err on side of caution
6301
- return true;
6390
+ initialiseScope ( parentScope ) {
6391
+ this.scope = new BlockScope( { parent: parentScope } );
6392
+ }
6393
+
6394
+ render ( code, es ) {
6395
+ if ( this.body.length ) {
6396
+ for ( const node of this.body ) {
6397
+ node.render( code, es );
6398
+ }
6399
+ } else {
6400
+ Statement.prototype.render.call( this, code, es );
6302
6401
  }
6303
6402
  }
6403
+ }
6304
6404
 
6305
- return false;
6405
+ class BreakStatement extends Node$1 {
6406
+ hasEffects ( options ) {
6407
+ return super.hasEffects( options )
6408
+ || !options.ignoreBreakStatements()
6409
+ || (this.label && !options.ignoreLabel( this.label.name ));
6410
+ }
6306
6411
  }
6307
6412
 
6308
6413
  class CallExpression extends Node$1 {
6309
6414
  bind () {
6310
6415
  if ( this.callee.type === 'Identifier' ) {
6311
- const declaration = this.scope.findDeclaration( this.callee.name );
6416
+ const variable = this.scope.findVariable( this.callee.name );
6312
6417
 
6313
- if ( declaration.isNamespace ) {
6418
+ if ( variable.isNamespace ) {
6314
6419
  this.module.error( {
6315
6420
  code: 'CANNOT_CALL_NAMESPACE',
6316
6421
  message: `Cannot call a namespace ('${this.callee.name}')`
6317
6422
  }, this.start );
6318
6423
  }
6319
6424
 
6320
- if ( this.callee.name === 'eval' && declaration.isGlobal ) {
6425
+ if ( this.callee.name === 'eval' && variable.isGlobal ) {
6321
6426
  this.module.warn( {
6322
6427
  code: 'EVAL',
6323
6428
  message: `Use of eval is strongly discouraged, as it poses security risks and may cause issues with minification`,
@@ -6327,42 +6432,65 @@ class CallExpression extends Node$1 {
6327
6432
  }
6328
6433
 
6329
6434
  super.bind();
6435
+ this.callee.bindCall( { withNew: false } );
6330
6436
  }
6331
6437
 
6332
6438
  hasEffects ( options ) {
6333
6439
  return this.included
6334
6440
  || this.arguments.some( child => child.hasEffects( options ) )
6335
- || callHasEffects( this.scope, this.callee, false );
6441
+ || this.callee.hasEffectsWhenCalled( options.getHasEffectsWhenCalledOptions( this.callee ) );
6336
6442
  }
6337
6443
 
6338
- hasEffectsWhenMutated () {
6339
- return true;
6444
+ hasEffectsAsExpressionStatement ( options ) {
6445
+ return this.hasEffects( options );
6340
6446
  }
6341
6447
  }
6342
6448
 
6343
6449
  class CatchClause extends Node$1 {
6344
6450
  initialiseChildren () {
6345
- if ( this.param ) {
6346
- this.param.initialise( this.scope );
6347
- extractNames( this.param ).forEach( name => this.scope.addDeclaration( name, null, false, true ) );
6348
- }
6451
+ this.param && this.param.initialiseAndDeclare( this.scope, 'parameter' );
6349
6452
  this.body.initialiseAndReplaceScope( this.scope );
6350
6453
  }
6351
6454
 
6352
6455
  initialiseScope ( parentScope ) {
6353
- this.scope = new Scope( {
6354
- parent: parentScope,
6355
- isBlockScope: true,
6356
- isLexicalBoundary: false
6357
- } );
6456
+ this.scope = new BlockScope( { parent: parentScope } );
6358
6457
  }
6359
6458
  }
6360
6459
 
6361
- class Class extends Node$1 {
6362
- addReference () {}
6460
+ class ClassBody extends Node$1 {
6461
+ bindCall ( callOptions ) {
6462
+ if ( this.classConstructor ) {
6463
+ this.classConstructor.bindCall( callOptions );
6464
+ }
6465
+ }
6363
6466
 
6364
- getName () {
6365
- return this.name;
6467
+ hasEffectsWhenCalled ( options ) {
6468
+ if ( this.classConstructor ) {
6469
+ return this.classConstructor.hasEffectsWhenCalled( options );
6470
+ }
6471
+ return false;
6472
+ }
6473
+
6474
+ initialiseNode () {
6475
+ this.classConstructor = this.body.find( method => method.kind === 'constructor' );
6476
+ }
6477
+ }
6478
+
6479
+ class ClassNode extends Node$1 {
6480
+ bindCall ( callOptions ) {
6481
+ if ( this.superClass ) {
6482
+ this.superClass.bindCall( callOptions );
6483
+ }
6484
+ this.body.bindCall( callOptions );
6485
+ }
6486
+
6487
+ hasEffectsAsExpressionStatement ( options ) {
6488
+ return this.hasEffects( options );
6489
+ }
6490
+
6491
+ hasEffectsWhenCalled ( options ) {
6492
+ return this.body.hasEffectsWhenCalled( options )
6493
+ || ( this.superClass && this.superClass.hasEffectsWhenCalled( options ) );
6366
6494
  }
6367
6495
 
6368
6496
  initialiseChildren () {
@@ -6373,28 +6501,14 @@ class Class extends Node$1 {
6373
6501
  }
6374
6502
 
6375
6503
  initialiseScope ( parentScope ) {
6376
- this.scope = new Scope( {
6377
- parent: parentScope,
6378
- isBlockScope: true
6379
- } );
6504
+ this.scope = new Scope( { parent: parentScope } );
6380
6505
  }
6381
6506
  }
6382
6507
 
6383
- class ClassDeclaration extends Class {
6384
- gatherPossibleValues ( values ) {
6385
- values.add( this );
6386
- }
6387
-
6388
- hasEffects () {
6389
- return this.included;
6390
- }
6391
-
6508
+ class ClassDeclaration extends ClassNode {
6392
6509
  initialiseChildren ( parentScope ) {
6393
- if ( this.id ) {
6394
- this.name = this.id.name;
6395
- parentScope.addDeclaration( this.name, this, false, false );
6396
- this.id.initialise( parentScope );
6397
- }
6510
+ // Class declarations are like let declarations: Not hoisted, can be reassigned, cannot be redeclared
6511
+ this.id && this.id.initialiseAndDeclare( parentScope, 'class', this );
6398
6512
  super.initialiseChildren( parentScope );
6399
6513
  }
6400
6514
 
@@ -6407,14 +6521,10 @@ class ClassDeclaration extends Class {
6407
6521
  }
6408
6522
  }
6409
6523
 
6410
- class ClassExpression extends Class {
6411
- initialiseChildren (parentScope) {
6412
- if ( this.id ) {
6413
- this.name = this.id.name;
6414
- this.scope.addDeclaration( this.name, this, false, false );
6415
- this.id.initialise( this.scope );
6416
- }
6417
- super.initialiseChildren(parentScope);
6524
+ class ClassExpression extends ClassNode {
6525
+ initialiseChildren ( parentScope ) {
6526
+ this.id && this.id.initialiseAndDeclare( this.scope, 'class', this );
6527
+ super.initialiseChildren( parentScope );
6418
6528
  }
6419
6529
  }
6420
6530
 
@@ -6437,16 +6547,6 @@ class ConditionalExpression extends Node$1 {
6437
6547
  }
6438
6548
  }
6439
6549
 
6440
- gatherPossibleValues ( values ) {
6441
- const testValue = this.test.getValue();
6442
-
6443
- if ( testValue === UNKNOWN_VALUE ) {
6444
- values.add( this.consequent ).add( this.alternate );
6445
- } else {
6446
- values.add( testValue ? this.consequent : this.alternate );
6447
- }
6448
- }
6449
-
6450
6550
  getValue () {
6451
6551
  const testValue = this.test.getValue();
6452
6552
  if ( testValue === UNKNOWN_VALUE ) { return UNKNOWN_VALUE; }
@@ -6454,8 +6554,13 @@ class ConditionalExpression extends Node$1 {
6454
6554
  return testValue ? this.consequent.getValue() : this.alternate.getValue();
6455
6555
  }
6456
6556
 
6457
- hasEffectsWhenMutated () {
6458
- return true;
6557
+ hasEffects ( options ) {
6558
+ return (
6559
+ this.included
6560
+ || this.test.hasEffects( options )
6561
+ || (this.testValue === UNKNOWN_VALUE && (this.consequent.hasEffects( options ) || this.alternate.hasEffects( options )))
6562
+ || (this.testValue ? this.consequent.hasEffects( options ) : this.alternate.hasEffects( options ))
6563
+ );
6459
6564
  }
6460
6565
 
6461
6566
  render ( code, es ) {
@@ -6468,22 +6573,16 @@ class ConditionalExpression extends Node$1 {
6468
6573
  super.render( code, es );
6469
6574
  }
6470
6575
 
6471
- else if ( this.testValue ) {
6472
- code.remove( this.start, this.consequent.start );
6473
- code.remove( this.consequent.end, this.end );
6474
- if ( this.consequent.type === 'SequenceExpression' ) {
6475
- code.prependRight( this.consequent.start, '(' );
6476
- code.appendLeft( this.consequent.end, ')' );
6477
- }
6478
- this.consequent.render( code, es );
6479
- } else {
6480
- code.remove( this.start, this.alternate.start );
6481
- code.remove( this.alternate.end, this.end );
6482
- if ( this.alternate.type === 'SequenceExpression' ) {
6483
- code.prependRight( this.alternate.start, '(' );
6484
- code.appendLeft( this.alternate.end, ')' );
6576
+ else {
6577
+ const branchToRetain = this.testValue ? this.consequent : this.alternate;
6578
+
6579
+ code.remove( this.start, branchToRetain.start );
6580
+ code.remove( branchToRetain.end, this.end );
6581
+ if ( branchToRetain.type === 'SequenceExpression' ) {
6582
+ code.prependLeft( branchToRetain.start, '(' );
6583
+ code.appendRight( branchToRetain.end, ')' );
6485
6584
  }
6486
- this.alternate.render( code, es );
6585
+ branchToRetain.render( code, es );
6487
6586
  }
6488
6587
  }
6489
6588
  }
@@ -6494,7 +6593,7 @@ class DoWhileStatement extends Statement {
6494
6593
  return (
6495
6594
  this.included
6496
6595
  || this.test.hasEffects( options )
6497
- || this.body.hasEffects( Object.assign( {}, options, { inNestedBreakableStatement: true } ) )
6596
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
6498
6597
  );
6499
6598
  }
6500
6599
  }
@@ -6520,6 +6619,10 @@ class ExportAllDeclaration extends Node$1 {
6520
6619
  const functionOrClassDeclaration = /^(?:Function|Class)Declaration/;
6521
6620
 
6522
6621
  class ExportDefaultDeclaration extends Node$1 {
6622
+ addCall ( options ) {
6623
+ this.declaration.bindCall( options );
6624
+ }
6625
+
6523
6626
  addReference ( reference ) {
6524
6627
  this.name = reference.name;
6525
6628
  if ( this.original ) { this.original.addReference( reference ); }
@@ -6527,15 +6630,11 @@ class ExportDefaultDeclaration extends Node$1 {
6527
6630
 
6528
6631
  bind () {
6529
6632
  const name = ( this.declaration.id && this.declaration.id.name ) || this.declaration.name;
6530
- if ( name ) { this.original = this.scope.findDeclaration( name ); }
6633
+ if ( name ) { this.original = this.scope.findVariable( name ); }
6531
6634
 
6532
6635
  this.declaration.bind();
6533
6636
  }
6534
6637
 
6535
- gatherPossibleValues ( values ) {
6536
- this.declaration.gatherPossibleValues( values );
6537
- }
6538
-
6539
6638
  getName ( es ) {
6540
6639
  if ( this.original && !this.original.isReassigned ) {
6541
6640
  return this.original.getName( es );
@@ -6544,7 +6643,11 @@ class ExportDefaultDeclaration extends Node$1 {
6544
6643
  return this.name;
6545
6644
  }
6546
6645
 
6547
- includeDeclaration () {
6646
+ hasEffectsWhenCalled ( options ) {
6647
+ return this.declaration.hasEffectsWhenCalled( options );
6648
+ }
6649
+
6650
+ includeVariable () {
6548
6651
  if ( this.included ) {
6549
6652
  return false;
6550
6653
  }
@@ -6565,7 +6668,7 @@ class ExportDefaultDeclaration extends Node$1 {
6565
6668
  this.isDefault = true;
6566
6669
 
6567
6670
  this.name = ( this.declaration.id && this.declaration.id.name ) || this.declaration.name || this.module.basename();
6568
- this.scope.declarations.default = this;
6671
+ this.scope.variables.default = this;
6569
6672
  }
6570
6673
 
6571
6674
  // TODO this is total chaos, tidy it up
@@ -6613,7 +6716,7 @@ class ExportDefaultDeclaration extends Node$1 {
6613
6716
  if ( functionOrClassDeclaration.test( this.declaration.type ) ) {
6614
6717
  code.remove( this.leadingCommentStart || this.start, this.next || this.end );
6615
6718
  } else {
6616
- const hasEffects = this.declaration.hasEffects( {} );
6719
+ const hasEffects = this.declaration.hasEffects( ExecutionPathOptions.create() );
6617
6720
  code.remove( this.start, hasEffects ? declaration_start : this.next || this.end );
6618
6721
  }
6619
6722
  } else if ( name === this.declaration.name ) {
@@ -6628,11 +6731,12 @@ class ExportDefaultDeclaration extends Node$1 {
6628
6731
 
6629
6732
  class ExportNamedDeclaration extends Node$1 {
6630
6733
  bind () {
6734
+ // Do not bind specifiers
6631
6735
  if ( this.declaration ) { this.declaration.bind(); }
6632
6736
  }
6633
6737
 
6634
- hasEffects () {
6635
- return this.included || (this.declaration && this.declaration.hasEffects());
6738
+ hasEffects ( options ) {
6739
+ return this.included || (this.declaration && this.declaration.hasEffects( options ));
6636
6740
  }
6637
6741
 
6638
6742
  initialiseNode () {
@@ -6663,6 +6767,10 @@ class ExportNamedDeclaration extends Node$1 {
6663
6767
  }
6664
6768
 
6665
6769
  class ExpressionStatement extends Statement {
6770
+ hasEffects ( options ) {
6771
+ return super.hasEffects( options ) || this.expression.hasEffectsAsExpressionStatement(options);
6772
+ }
6773
+
6666
6774
  render ( code, es ) {
6667
6775
  super.render( code, es );
6668
6776
  if ( this.included ) { this.insertSemicolon( code ); }
@@ -6676,7 +6784,7 @@ class ForStatement extends Statement {
6676
6784
  || this.init && this.init.hasEffects( options )
6677
6785
  || this.test && this.test.hasEffects( options )
6678
6786
  || this.update && this.update.hasEffects( options )
6679
- || this.body.hasEffects( Object.assign( {}, options, { inNestedBreakableStatement: true } ) )
6787
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
6680
6788
  );
6681
6789
  }
6682
6790
 
@@ -6694,11 +6802,7 @@ class ForStatement extends Statement {
6694
6802
  }
6695
6803
 
6696
6804
  initialiseScope ( parentScope ) {
6697
- this.scope = new Scope( {
6698
- parent: parentScope,
6699
- isBlockScope: true,
6700
- isLexicalBoundary: false
6701
- } );
6805
+ this.scope = new BlockScope( { parent: parentScope } );
6702
6806
  }
6703
6807
  }
6704
6808
 
@@ -6706,9 +6810,9 @@ class ForInStatement extends Statement {
6706
6810
  hasEffects ( options ) {
6707
6811
  return (
6708
6812
  this.included
6709
- || this.left && this.left.hasEffects( options )
6813
+ || this.left && (this.left.hasEffects( options ) || this.left.hasEffectsWhenAssigned( options ))
6710
6814
  || this.right && this.right.hasEffects( options )
6711
- || this.body.hasEffects( Object.assign( {}, options, { inNestedBreakableStatement: true } ) )
6815
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
6712
6816
  );
6713
6817
  }
6714
6818
 
@@ -6722,39 +6826,35 @@ class ForInStatement extends Statement {
6722
6826
 
6723
6827
  includeInBundle () {
6724
6828
  let addedNewNodes = super.includeInBundle();
6725
- if ( this.left.includeDeclaration() ) {
6829
+ if ( this.left.includeWithAllDeclarations() ) {
6726
6830
  addedNewNodes = true;
6727
6831
  }
6728
6832
  return addedNewNodes;
6729
6833
  }
6730
6834
 
6731
6835
  initialiseScope ( parentScope ) {
6732
- this.scope = new Scope( {
6733
- parent: parentScope,
6734
- isBlockScope: true,
6735
- isLexicalBoundary: false
6736
- } );
6836
+ this.scope = new BlockScope( { parent: parentScope } );
6737
6837
  }
6738
6838
  }
6739
6839
 
6740
6840
  class ForOfStatement extends Statement {
6741
6841
  bind () {
6742
6842
  super.bind();
6743
- this.left.assignExpression( UNKNOWN_ASSIGNMENT );
6843
+ this.left.bindAssignment( UNKNOWN_ASSIGNMENT );
6744
6844
  }
6745
6845
 
6746
6846
  hasEffects ( options ) {
6747
6847
  return (
6748
6848
  this.included
6749
- || this.left && this.left.hasEffects( options )
6849
+ || this.left && (this.left.hasEffects( options ) || this.left.hasEffectsWhenAssigned( options ))
6750
6850
  || this.right && this.right.hasEffects( options )
6751
- || this.body.hasEffects( Object.assign( {}, options, { inNestedBreakableStatement: true } ) )
6851
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
6752
6852
  );
6753
6853
  }
6754
6854
 
6755
6855
  includeInBundle () {
6756
6856
  let addedNewNodes = super.includeInBundle();
6757
- if ( this.left.includeDeclaration() ) {
6857
+ if ( this.left.includeWithAllDeclarations() ) {
6758
6858
  addedNewNodes = true;
6759
6859
  }
6760
6860
  return addedNewNodes;
@@ -6769,45 +6869,65 @@ class ForOfStatement extends Statement {
6769
6869
  }
6770
6870
 
6771
6871
  initialiseScope ( parentScope ) {
6772
- this.scope = new Scope( {
6773
- parent: parentScope,
6774
- isBlockScope: true,
6775
- isLexicalBoundary: false
6776
- } );
6872
+ this.scope = new BlockScope( { parent: parentScope } );
6777
6873
  }
6778
6874
  }
6779
6875
 
6780
- class FunctionDeclaration extends Function$1 {
6781
- addReference () {}
6876
+ class FunctionScope extends Scope {
6877
+ constructor ( options ) {
6878
+ if ( options === void 0 ) options = {};
6782
6879
 
6783
- assignExpression ( expression ) {
6784
- this.assignedExpressions.add( expression );
6785
- this.isReassigned = true;
6880
+ super( options );
6881
+ this.variables.arguments = new ParameterVariable( 'arguments' );
6882
+ this.variables.this = new LocalVariable( 'this', null, null );
6883
+ }
6884
+
6885
+ findLexicalBoundary () {
6886
+ return this;
6786
6887
  }
6888
+ }
6889
+
6890
+ class FunctionNode extends Node$1 {
6891
+ bindCall ( ref ) {
6892
+ var withNew = ref.withNew;
6893
+
6894
+ const thisVariable = this.scope.findVariable( 'this' );
6787
6895
 
6788
- gatherPossibleValues ( values ) {
6789
- values.add( this );
6896
+ if ( withNew ) {
6897
+ thisVariable.assignExpression( UNKNOWN_OBJECT_LITERAL );
6898
+ } else {
6899
+ thisVariable.assignExpression( UNKNOWN_ASSIGNMENT );
6900
+ }
6790
6901
  }
6791
6902
 
6792
- getName () {
6793
- return this.name;
6903
+ hasEffects ( options ) {
6904
+ return this.included || (this.id && this.id.hasEffects( options ));
6794
6905
  }
6795
6906
 
6796
- initialiseChildren ( parentScope ) {
6797
- if ( this.id ) {
6798
- this.name = this.id.name; // may be overridden by bundle.deconflict
6799
- parentScope.addDeclaration( this.name, this, false, false );
6800
- this.id.initialise( parentScope );
6801
- }
6802
- super.initialiseChildren( parentScope );
6907
+ hasEffectsAsExpressionStatement ( options ) {
6908
+ return this.hasEffects( options );
6909
+ }
6910
+
6911
+ hasEffectsWhenCalled ( options ) {
6912
+ const innerOptions = options.setIgnoreSafeThisMutations();
6913
+ return this.params.some( param => param.hasEffects( innerOptions ) )
6914
+ || this.body.hasEffects( innerOptions );
6803
6915
  }
6804
6916
 
6805
6917
  hasEffectsWhenMutated () {
6806
6918
  return this.included;
6807
6919
  }
6808
6920
 
6809
- initialiseNode () {
6810
- this.assignedExpressions = new Set( [ this ] );
6921
+ initialiseScope ( parentScope ) {
6922
+ this.scope = new FunctionScope( { parent: parentScope } );
6923
+ }
6924
+ }
6925
+
6926
+ class FunctionDeclaration extends FunctionNode {
6927
+ initialiseChildren ( parentScope ) {
6928
+ this.id && this.id.initialiseAndDeclare( parentScope, 'function', this );
6929
+ this.params.forEach( param => param.initialiseAndDeclare( this.scope, 'parameter' ) );
6930
+ this.body.initialiseAndReplaceScope( new Scope( { parent: this.scope } ) );
6811
6931
  }
6812
6932
 
6813
6933
  render ( code, es ) {
@@ -6819,21 +6939,43 @@ class FunctionDeclaration extends Function$1 {
6819
6939
  }
6820
6940
  }
6821
6941
 
6822
- class FunctionExpression extends Function$1 {
6823
- addReference () {}
6942
+ class FunctionExpression extends FunctionNode {
6943
+ initialiseChildren () {
6944
+ this.id && this.id.initialiseAndDeclare( this.scope, 'function', this );
6945
+ this.params.forEach( param => param.initialiseAndDeclare( this.scope, 'parameter' ) );
6946
+ this.body.initialiseAndReplaceScope( new Scope( { parent: this.scope } ) );
6947
+ }
6948
+ }
6824
6949
 
6825
- getName () {
6826
- return this.name;
6950
+ function isReference (node, parent) {
6951
+ if (node.type === 'MemberExpression') {
6952
+ return !node.computed && isReference(node.object, node);
6827
6953
  }
6828
6954
 
6829
- initialiseChildren ( parentScope ) {
6830
- if ( this.id ) {
6831
- this.name = this.id.name; // may be overridden by bundle.deconflict
6832
- this.scope.addDeclaration( this.name, this, false, false );
6833
- this.id.initialise( this.scope );
6955
+ if (node.type === 'Identifier') {
6956
+ // the only time we could have an identifier node without a parent is
6957
+ // if it's the entire body of a function without a block statement –
6958
+ // i.e. an arrow function expression like `a => a`
6959
+ if (!parent) return true;
6960
+
6961
+ // TODO is this right?
6962
+ if (parent.type === 'MemberExpression' || parent.type === 'MethodDefinition') {
6963
+ return parent.computed || node === parent.object;
6834
6964
  }
6835
- super.initialiseChildren( parentScope );
6965
+
6966
+ // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
6967
+ if (parent.type === 'Property') return parent.computed || node === parent.value;
6968
+
6969
+ // disregard the `bar` in `class Foo { bar () {...} }`
6970
+ if (parent.type === 'MethodDefinition') return false;
6971
+
6972
+ // disregard the `bar` in `export { foo as bar }`
6973
+ if (parent.type === 'ExportSpecifier' && node !== parent.local) return false;
6974
+
6975
+ return true;
6836
6976
  }
6977
+
6978
+ return false;
6837
6979
  }
6838
6980
 
6839
6981
  function isAssignmentPatternLhs ( node, parent ) {
@@ -6852,49 +6994,74 @@ function isAssignmentPatternLhs ( node, parent ) {
6852
6994
  }
6853
6995
 
6854
6996
  class Identifier extends Node$1 {
6855
- assignExpression ( expression ) {
6856
- if ( this.declaration ) {
6857
- this.declaration.assignExpression( expression );
6997
+ bind () {
6998
+ if ( isReference( this, this.parent ) || isAssignmentPatternLhs( this, this.parent ) ) {
6999
+ this.variable = this.scope.findVariable( this.name );
7000
+ this.variable.addReference( this );
6858
7001
  }
6859
7002
  }
6860
7003
 
6861
- bind () {
6862
- if ( isReference( this, this.parent ) || isAssignmentPatternLhs( this, this.parent ) ) {
6863
- this.declaration = this.scope.findDeclaration( this.name );
6864
- this.declaration.addReference( this ); // TODO necessary?
7004
+ bindAssignment ( expression ) {
7005
+ if ( this.variable ) {
7006
+ this.variable.assignExpression( expression );
6865
7007
  }
6866
7008
  }
6867
7009
 
6868
- gatherPossibleValues ( values ) {
6869
- if ( isReference( this, this.parent ) ) {
6870
- values.add( this );
7010
+ bindCall ( callOptions ) {
7011
+ if ( this.variable ) {
7012
+ this.variable.addCall( callOptions );
6871
7013
  }
6872
7014
  }
6873
7015
 
7016
+ hasEffectsAsExpressionStatement ( options ) {
7017
+ return this.hasEffects( options ) || this.variable.isGlobal;
7018
+ }
7019
+
6874
7020
  hasEffectsWhenAssigned () {
6875
- return this.declaration && this.declaration.included;
7021
+ return this.variable && this.variable.included;
7022
+ }
7023
+
7024
+ hasEffectsWhenCalled ( options ) {
7025
+ if ( !this.variable ) {
7026
+ return true;
7027
+ }
7028
+ return this.variable.hasEffectsWhenCalled( options );
6876
7029
  }
6877
7030
 
6878
7031
  hasEffectsWhenMutated ( options ) {
6879
- return this.declaration &&
6880
- (this.declaration.included ||
6881
- this.declaration.isParam ||
6882
- this.declaration.isGlobal ||
6883
- this.declaration.isExternal ||
6884
- this.declaration.isNamespace ||
6885
- Array.from( this.declaration.assignedExpressions ).some( node => node.hasEffectsWhenMutated( options ) ));
7032
+ return this.variable && this.variable.hasEffectsWhenMutated( options );
6886
7033
  }
6887
7034
 
6888
7035
  includeInBundle () {
6889
7036
  if ( this.included ) { return false; }
6890
7037
  this.included = true;
6891
- this.declaration && this.declaration.includeDeclaration();
7038
+ this.variable && this.variable.includeVariable();
6892
7039
  return true;
6893
7040
  }
6894
7041
 
7042
+ initialiseAndDeclare ( parentScope, kind, init ) {
7043
+ this.initialiseScope( parentScope );
7044
+ switch ( kind ) {
7045
+ case 'var':
7046
+ case 'function':
7047
+ this.scope.addDeclaration( this, true, init );
7048
+ break;
7049
+ case 'let':
7050
+ case 'const':
7051
+ case 'class':
7052
+ this.scope.addDeclaration( this, false, init );
7053
+ break;
7054
+ case 'parameter':
7055
+ this.scope.addParameterDeclaration( this );
7056
+ break;
7057
+ default:
7058
+ throw new Error( 'Unexpected identifier kind', kind );
7059
+ }
7060
+ }
7061
+
6895
7062
  render ( code, es ) {
6896
- if ( this.declaration ) {
6897
- const name = this.declaration.getName( es );
7063
+ if ( this.variable ) {
7064
+ const name = this.variable.getName( es );
6898
7065
  if ( name !== this.name ) {
6899
7066
  code.overwrite( this.start, this.end, name, { storeName: true, contentOnly: false } );
6900
7067
 
@@ -6917,7 +7084,7 @@ const statementsWithIfStatements = new Set( [
6917
7084
  'WhileStatement'
6918
7085
  ] );
6919
7086
 
6920
- function handleVarDeclarations ( node, scope ) {
7087
+ function getHoistedVars ( node, scope ) {
6921
7088
  const hoistedVars = [];
6922
7089
 
6923
7090
  function visit ( node ) {
@@ -6927,7 +7094,7 @@ function handleVarDeclarations ( node, scope ) {
6927
7094
  declarator.initialise( scope );
6928
7095
 
6929
7096
  extractNames( declarator.id ).forEach( name => {
6930
- if ( !~hoistedVars.indexOf( name ) ) { hoistedVars.push( name ); }
7097
+ if ( hoistedVars.indexOf( name ) < 0 ) { hoistedVars.push( name ); }
6931
7098
  } );
6932
7099
  } );
6933
7100
  }
@@ -6942,29 +7109,24 @@ function handleVarDeclarations ( node, scope ) {
6942
7109
  return hoistedVars;
6943
7110
  }
6944
7111
 
6945
- // TODO DRY this out
6946
7112
  class IfStatement extends Statement {
6947
7113
  initialiseChildren ( parentScope ) {
7114
+ super.initialiseChildren( parentScope );
6948
7115
  if ( this.module.bundle.treeshake ) {
6949
7116
  this.testValue = this.test.getValue();
6950
7117
 
6951
7118
  if ( this.testValue === UNKNOWN_VALUE ) {
6952
- super.initialiseChildren( parentScope );
6953
- } else if ( this.testValue ) {
6954
- this.consequent.initialise( this.scope );
7119
+ return;
7120
+ }
7121
+ if ( this.testValue ) {
6955
7122
  if ( this.alternate ) {
6956
- this.hoistedVars = handleVarDeclarations( this.alternate, this.scope );
7123
+ this.hoistedVars = getHoistedVars( this.alternate, this.scope );
6957
7124
  this.alternate = null;
6958
7125
  }
6959
7126
  } else {
6960
- if ( this.alternate ) {
6961
- this.alternate.initialise( this.scope );
6962
- }
6963
- this.hoistedVars = handleVarDeclarations( this.consequent, this.scope );
7127
+ this.hoistedVars = getHoistedVars( this.consequent, this.scope );
6964
7128
  this.consequent = null;
6965
7129
  }
6966
- } else {
6967
- super.initialiseChildren( parentScope );
6968
7130
  }
6969
7131
  }
6970
7132
 
@@ -6983,8 +7145,8 @@ class IfStatement extends Statement {
6983
7145
  if ( this.hoistedVars ) {
6984
7146
  const names = this.hoistedVars
6985
7147
  .map( name => {
6986
- const declaration = this.scope.findDeclaration( name );
6987
- return declaration.included ? declaration.getName() : null;
7148
+ const variable = this.scope.findVariable( name );
7149
+ return variable.included ? variable.getName() : null;
6988
7150
  } )
6989
7151
  .filter( Boolean );
6990
7152
 
@@ -7034,13 +7196,23 @@ class ImportDeclaration extends Node$1 {
7034
7196
  }
7035
7197
  }
7036
7198
 
7199
+ class LabeledStatement extends Statement {
7200
+ hasEffects ( options ) {
7201
+ return this.body.hasEffects(
7202
+ options
7203
+ .setIgnoreLabel( this.label.name )
7204
+ .setIgnoreBreakStatements()
7205
+ );
7206
+ }
7207
+ }
7208
+
7037
7209
  class Literal extends Node$1 {
7038
7210
  getValue () {
7039
7211
  return this.value;
7040
7212
  }
7041
7213
 
7042
- gatherPossibleValues ( values ) {
7043
- values.add( this );
7214
+ hasEffectsWhenMutated () {
7215
+ return false;
7044
7216
  }
7045
7217
 
7046
7218
  render ( code ) {
@@ -7063,9 +7235,77 @@ class LogicalExpression extends Node$1 {
7063
7235
  const rightValue = this.right.getValue();
7064
7236
  if ( rightValue === UNKNOWN_VALUE ) { return UNKNOWN_VALUE; }
7065
7237
 
7066
- return operators$1[ this.operator ]( leftValue, rightValue );
7067
- }
7068
- }
7238
+ return operators$1[ this.operator ]( leftValue, rightValue );
7239
+ }
7240
+
7241
+ hasEffectsWhenMutated ( options ) {
7242
+ const leftValue = this.left.getValue();
7243
+ if ( leftValue === UNKNOWN_VALUE ) {
7244
+ return this.left.hasEffectsWhenMutated( options ) || this.right.hasEffectsWhenMutated( options );
7245
+ }
7246
+ if ((leftValue && this.operator === '||') || (!leftValue && this.operator === '&&')) {
7247
+ return this.left.hasEffectsWhenMutated( options );
7248
+ }
7249
+ return this.right.hasEffectsWhenMutated( options );
7250
+ }
7251
+ }
7252
+
7253
+ function flatten ( node ) {
7254
+ const parts = [];
7255
+ while ( node.type === 'MemberExpression' ) {
7256
+ if ( node.computed ) { return null; }
7257
+ parts.unshift( node.property.name );
7258
+
7259
+ node = node.object;
7260
+ }
7261
+
7262
+ if ( node.type !== 'Identifier' ) { return null; }
7263
+
7264
+ const name = node.name;
7265
+ parts.unshift( name );
7266
+
7267
+ return { name, keypath: parts.join( '.' ) };
7268
+ }
7269
+
7270
+ const pureFunctions = {};
7271
+
7272
+ const arrayTypes = 'Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split( ' ' );
7273
+ const simdTypes = 'Int8x16 Int16x8 Int32x4 Float32x4 Float64x2'.split( ' ' );
7274
+ 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( ' ' );
7275
+ const allSimdMethods = [];
7276
+ simdTypes.forEach( t => {
7277
+ simdMethods.forEach( m => {
7278
+ allSimdMethods.push( `SIMD.${t}.${m}` );
7279
+ });
7280
+ });
7281
+
7282
+ [
7283
+ 'Array.isArray',
7284
+ 'Error', 'EvalError', 'InternalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError',
7285
+ 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape', 'unescape',
7286
+ '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',
7287
+ 'Function', 'Boolean',
7288
+ 'Number', 'Number.isFinite', 'Number.isInteger', 'Number.isNaN', 'Number.isSafeInteger', 'Number.parseFloat', 'Number.parseInt',
7289
+ 'Symbol', 'Symbol.for', 'Symbol.keyFor',
7290
+ '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',
7291
+ 'Date', 'Date.UTC', 'Date.now', 'Date.parse',
7292
+ 'String', 'String.fromCharCode', 'String.fromCodePoint', 'String.raw',
7293
+ 'RegExp',
7294
+ 'Map', 'Set', 'WeakMap', 'WeakSet',
7295
+ 'ArrayBuffer', 'ArrayBuffer.isView',
7296
+ 'DataView',
7297
+ 'JSON.parse', 'JSON.stringify',
7298
+ 'Promise.all', 'Promise.race', 'Promise.resolve',
7299
+ 'Intl.Collator', 'Intl.Collator.supportedLocalesOf', 'Intl.DateTimeFormat', 'Intl.DateTimeFormat.supportedLocalesOf', 'Intl.NumberFormat', 'Intl.NumberFormat.supportedLocalesOf'
7300
+
7301
+ // TODO properties of e.g. window...
7302
+ ].concat(
7303
+ arrayTypes,
7304
+ arrayTypes.map( t => `${t}.from` ),
7305
+ arrayTypes.map( t => `${t}.of` ),
7306
+ simdTypes.map( t => `SIMD.${t}` ),
7307
+ allSimdMethods
7308
+ ).forEach( name => pureFunctions[ name ] = true );
7069
7309
 
7070
7310
  const validProp = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
7071
7311
 
@@ -7099,15 +7339,15 @@ class MemberExpression extends Node$1 {
7099
7339
  const keypath = new Keypath( this );
7100
7340
 
7101
7341
  if ( !keypath.computed && keypath.root.type === 'Identifier' ) {
7102
- let declaration = this.scope.findDeclaration( keypath.root.name );
7342
+ let variable = this.scope.findVariable( keypath.root.name );
7103
7343
 
7104
- while ( declaration.isNamespace && keypath.parts.length ) {
7105
- const exporterId = declaration.module.id;
7344
+ while ( variable.isNamespace && keypath.parts.length ) {
7345
+ const exporterId = variable.module.id;
7106
7346
 
7107
7347
  const part = keypath.parts[ 0 ];
7108
- declaration = declaration.module.traceExport( part.name || part.value );
7348
+ variable = variable.module.traceExport( part.name || part.value );
7109
7349
 
7110
- if ( !declaration ) {
7350
+ if ( !variable ) {
7111
7351
  this.module.warn( {
7112
7352
  code: 'MISSING_EXPORT',
7113
7353
  missing: part.name || part.value,
@@ -7128,10 +7368,10 @@ class MemberExpression extends Node$1 {
7128
7368
  return; // not a namespaced declaration
7129
7369
  }
7130
7370
 
7131
- this.declaration = declaration;
7371
+ this.variable = variable;
7132
7372
 
7133
- if ( declaration.isExternal ) {
7134
- declaration.module.suggestName( keypath.root.name );
7373
+ if ( variable.isExternal ) {
7374
+ variable.module.suggestName( keypath.root.name );
7135
7375
  }
7136
7376
  }
7137
7377
 
@@ -7140,30 +7380,39 @@ class MemberExpression extends Node$1 {
7140
7380
  }
7141
7381
  }
7142
7382
 
7143
- gatherPossibleValues ( values ) {
7144
- values.add( UNKNOWN_ASSIGNMENT ); // TODO
7383
+ bindCall ( callOptions ) {
7384
+ if ( this.variable ) {
7385
+ this.variable.addCall( callOptions );
7386
+ }
7145
7387
  }
7146
7388
 
7147
7389
  hasEffectsWhenAssigned ( options ) {
7148
7390
  return this.object.hasEffectsWhenMutated( options );
7149
7391
  }
7150
7392
 
7151
- hasEffectsWhenMutated () {
7152
- return true;
7153
- }
7154
-
7155
7393
  includeInBundle () {
7156
7394
  let addedNewNodes = super.includeInBundle();
7157
- if ( this.declaration && !this.declaration.included ) {
7158
- this.declaration.includeDeclaration();
7395
+ if ( this.variable && !this.variable.included ) {
7396
+ this.variable.includeVariable();
7159
7397
  addedNewNodes = true;
7160
7398
  }
7161
7399
  return addedNewNodes;
7162
7400
  }
7163
7401
 
7402
+ hasEffectsWhenCalled ( options ) {
7403
+ if ( this.variable ) {
7404
+ return this.variable.hasEffectsWhenCalled( options );
7405
+ }
7406
+ if ( !isReference( this ) ) {
7407
+ return true;
7408
+ }
7409
+ const flattenedNode = flatten( this );
7410
+ return !(this.scope.findVariable( flattenedNode.name ).isGlobal && pureFunctions[ flattenedNode.keypath ]);
7411
+ }
7412
+
7164
7413
  render ( code, es ) {
7165
- if ( this.declaration ) {
7166
- const name = this.declaration.getName( es );
7414
+ if ( this.variable ) {
7415
+ const name = this.variable.getName( es );
7167
7416
  if ( name !== this.name ) { code.overwrite( this.start, this.end, name, { storeName: true, contentOnly: false } ); }
7168
7417
  }
7169
7418
 
@@ -7175,31 +7424,69 @@ class MemberExpression extends Node$1 {
7175
7424
  }
7176
7425
  }
7177
7426
 
7427
+ class MethodDefinition extends Node$1 {
7428
+ bindCall ( callOptions ) {
7429
+ this.value.bindCall( callOptions );
7430
+ }
7431
+
7432
+ hasEffects ( options ) {
7433
+ return this.key.hasEffects( options );
7434
+ }
7435
+
7436
+ hasEffectsWhenCalled ( options ) {
7437
+ return this.value.hasEffectsWhenCalled( options );
7438
+ }
7439
+ }
7440
+
7178
7441
  class NewExpression extends Node$1 {
7179
- hasEffects () {
7180
- return this.included || callHasEffects( this.scope, this.callee, true );
7442
+ bind () {
7443
+ super.bind();
7444
+ this.callee.bindCall( { withNew: true } );
7445
+ }
7446
+
7447
+ hasEffects ( options ) {
7448
+ return this.included
7449
+ || this.arguments.some( child => child.hasEffects( options ) )
7450
+ || this.callee.hasEffectsWhenCalled( options.getHasEffectsWhenCalledOptions( this.callee ) );
7451
+ }
7452
+ }
7453
+
7454
+ class ObjectExpression extends Node$1 {
7455
+ hasEffectsWhenMutated () {
7456
+ return false;
7181
7457
  }
7182
7458
  }
7183
7459
 
7184
7460
  class ObjectPattern extends Node$1 {
7185
- assignExpression () {
7186
- this.eachChild( child => child.assignExpression( UNKNOWN_ASSIGNMENT ) );
7461
+ bindAssignment ( expression ) {
7462
+ this.properties.forEach( child => child.bindAssignment( expression ) );
7187
7463
  }
7188
7464
 
7189
7465
  hasEffectsWhenAssigned ( options ) {
7190
7466
  return this.someChild( child => child.hasEffectsWhenAssigned( options ) );
7191
7467
  }
7468
+
7469
+ initialiseAndDeclare ( parentScope, kind, init ) {
7470
+ this.initialiseScope( parentScope );
7471
+ this.properties.forEach( child => child.initialiseAndDeclare( parentScope, kind, init ) );
7472
+ }
7192
7473
  }
7193
7474
 
7194
7475
  class Property extends Node$1 {
7195
- assignExpression ( expression ) {
7196
- this.value.assignExpression( expression );
7476
+ bindAssignment () {
7477
+ this.value.bindAssignment( UNKNOWN_ASSIGNMENT );
7197
7478
  }
7198
7479
 
7199
7480
  hasEffectsWhenAssigned ( options ) {
7200
7481
  return this.value.hasEffectsWhenAssigned( options );
7201
7482
  }
7202
7483
 
7484
+ initialiseAndDeclare ( parentScope, kind, init ) {
7485
+ this.initialiseScope( parentScope );
7486
+ this.key.initialise( parentScope );
7487
+ this.value.initialiseAndDeclare( parentScope, kind, init && UNKNOWN_ASSIGNMENT );
7488
+ }
7489
+
7203
7490
  render ( code, es ) {
7204
7491
  if ( !this.shorthand ) {
7205
7492
  this.key.render( code, es );
@@ -7209,23 +7496,82 @@ class Property extends Node$1 {
7209
7496
  }
7210
7497
 
7211
7498
  class RestElement extends Node$1 {
7212
- assignExpression () {
7213
- this.argument.assignExpression( UNKNOWN_ASSIGNMENT );
7499
+ bindAssignment () {
7500
+ this.argument.bindAssignment( UNKNOWN_ASSIGNMENT );
7214
7501
  }
7215
7502
 
7216
7503
  hasEffectsWhenAssigned ( options ) {
7217
7504
  return this.argument.hasEffectsWhenAssigned( options );
7218
7505
  }
7506
+
7507
+ initialiseAndDeclare ( parentScope, kind ) {
7508
+ this.initialiseScope( parentScope );
7509
+ this.argument.initialiseAndDeclare( parentScope, kind, UNKNOWN_ASSIGNMENT );
7510
+ }
7219
7511
  }
7220
7512
 
7221
7513
  class ReturnStatement extends Statement {
7222
7514
  hasEffects ( options ) {
7223
7515
  return super.hasEffects( options )
7224
- || !options.inNestedFunctionCall;
7516
+ || !options.ignoreReturnAwaitYield();
7225
7517
  }
7518
+ }
7226
7519
 
7227
- shouldBeIncluded () {
7228
- return true;
7520
+ class SequenceExpression extends Node$1 {
7521
+ getValue () {
7522
+ return this.expressions[ this.expressions.length - 1 ].getValue();
7523
+ }
7524
+
7525
+ hasEffects ( options ) {
7526
+ return this.expressions.some( expression => expression.hasEffects( options ) );
7527
+ }
7528
+
7529
+ includeInBundle () {
7530
+ if ( this.isFullyIncluded() ) { return false; }
7531
+ let addedNewNodes = false;
7532
+ if ( this.expressions[ this.expressions.length - 1 ].includeInBundle() ) {
7533
+ addedNewNodes = true;
7534
+ }
7535
+ this.expressions.forEach( node => {
7536
+ if ( node.shouldBeIncluded() ) {
7537
+ if ( node.includeInBundle() ) {
7538
+ addedNewNodes = true;
7539
+ }
7540
+ }
7541
+ } );
7542
+ if ( !this.included || addedNewNodes ) {
7543
+ this.included = true;
7544
+ return true;
7545
+ }
7546
+ return false;
7547
+ }
7548
+
7549
+ render ( code, es ) {
7550
+ if ( !this.module.bundle.treeshake ) {
7551
+ super.render( code, es );
7552
+ }
7553
+
7554
+ else {
7555
+ const last = this.expressions[ this.expressions.length - 1 ];
7556
+ const included = this.expressions.slice( 0, this.expressions.length - 1 ).filter( expression => expression.included );
7557
+
7558
+ if ( included.length === 0 ) {
7559
+ code.remove( this.start, last.start );
7560
+ code.remove( last.end, this.end );
7561
+ }
7562
+
7563
+ else {
7564
+ let previousEnd = this.start;
7565
+ for ( const expression of included ) {
7566
+ code.remove( previousEnd, expression.start );
7567
+ code.appendLeft( expression.end, ', ' );
7568
+ previousEnd = expression.end;
7569
+ }
7570
+
7571
+ code.remove( previousEnd, last.start );
7572
+ code.remove( last.end, this.end );
7573
+ }
7574
+ }
7229
7575
  }
7230
7576
  }
7231
7577
 
@@ -7252,32 +7598,28 @@ class SwitchCase extends Node$1 {
7252
7598
  }
7253
7599
 
7254
7600
  class SwitchStatement extends Statement {
7255
- hasEffects(options) {
7256
- return super.hasEffects(Object.assign({}, options, {inNestedBreakableStatement: true}));
7601
+ hasEffects ( options ) {
7602
+ return super.hasEffects( options.setIgnoreBreakStatements() );
7257
7603
  }
7258
7604
 
7259
7605
  initialiseScope ( parentScope ) {
7260
- this.scope = new Scope( {
7261
- parent: parentScope,
7262
- isBlockScope: true,
7263
- isLexicalBoundary: false
7264
- } );
7606
+ this.scope = new BlockScope( { parent: parentScope } );
7265
7607
  }
7266
7608
  }
7267
7609
 
7268
7610
  class TaggedTemplateExpression extends Node$1 {
7269
7611
  bind () {
7270
7612
  if ( this.tag.type === 'Identifier' ) {
7271
- const declaration = this.scope.findDeclaration( this.tag.name );
7613
+ const variable = this.scope.findVariable( this.tag.name );
7272
7614
 
7273
- if ( declaration.isNamespace ) {
7615
+ if ( variable.isNamespace ) {
7274
7616
  this.module.error( {
7275
7617
  code: 'CANNOT_CALL_NAMESPACE',
7276
7618
  message: `Cannot call a namespace ('${this.tag.name}')`
7277
7619
  }, this.start );
7278
7620
  }
7279
7621
 
7280
- if ( this.tag.name === 'eval' && declaration.isGlobal ) {
7622
+ if ( this.tag.name === 'eval' && variable.isGlobal ) {
7281
7623
  this.module.warn( {
7282
7624
  code: 'EVAL',
7283
7625
  message: `Use of eval is strongly discouraged, as it poses security risks and may cause issues with minification`,
@@ -7287,10 +7629,12 @@ class TaggedTemplateExpression extends Node$1 {
7287
7629
  }
7288
7630
 
7289
7631
  super.bind();
7632
+ this.tag.bindCall( { withNew: false } );
7290
7633
  }
7291
7634
 
7292
7635
  hasEffects ( options ) {
7293
- return this.quasi.hasEffects( options ) || callHasEffects( this.scope, this.tag, false );
7636
+ return super.hasEffects( options )
7637
+ || this.tag.hasEffectsWhenCalled( options.getHasEffectsWhenCalledOptions( this.tag ) );
7294
7638
  }
7295
7639
  }
7296
7640
 
@@ -7308,10 +7652,6 @@ class TemplateLiteral extends Node$1 {
7308
7652
  }
7309
7653
 
7310
7654
  class ThisExpression extends Node$1 {
7311
- hasEffectsWhenMutated () {
7312
- return true;
7313
- }
7314
-
7315
7655
  initialiseNode () {
7316
7656
  const lexicalBoundary = this.scope.findLexicalBoundary();
7317
7657
 
@@ -7327,6 +7667,14 @@ class ThisExpression extends Node$1 {
7327
7667
  }
7328
7668
  }
7329
7669
 
7670
+ bind () {
7671
+ this.variable = this.scope.findVariable( 'this' );
7672
+ }
7673
+
7674
+ hasEffectsWhenMutated ( options ) {
7675
+ return !options.ignoreSafeThisMutations() || this.variable.hasEffectsWhenMutated( options );
7676
+ }
7677
+
7330
7678
  render ( code ) {
7331
7679
  if ( this.alias ) {
7332
7680
  code.overwrite( this.start, this.end, this.alias, { storeName: true, contentOnly: false } );
@@ -7371,6 +7719,10 @@ class UnaryExpression extends Node$1 {
7371
7719
  ));
7372
7720
  }
7373
7721
 
7722
+ hasEffectsAsExpressionStatement ( options ) {
7723
+ return this.hasEffects( options );
7724
+ }
7725
+
7374
7726
  initialiseNode () {
7375
7727
  this.value = this.getValue();
7376
7728
  }
@@ -7380,8 +7732,8 @@ class UpdateExpression extends Node$1 {
7380
7732
  bind () {
7381
7733
  disallowIllegalReassignment( this.scope, this.argument );
7382
7734
  if ( this.argument.type === 'Identifier' ) {
7383
- const declaration = this.scope.findDeclaration( this.argument.name );
7384
- declaration.isReassigned = true;
7735
+ const variable = this.scope.findVariable( this.argument.name );
7736
+ variable.isReassigned = true;
7385
7737
  }
7386
7738
  super.bind();
7387
7739
  }
@@ -7389,90 +7741,31 @@ class UpdateExpression extends Node$1 {
7389
7741
  hasEffects ( options ) {
7390
7742
  return this.included || this.argument.hasEffectsWhenAssigned( options );
7391
7743
  }
7392
- }
7393
-
7394
- class DeclaratorProxy {
7395
- constructor ( name, declarator, isTopLevel, init ) {
7396
- this.name = name;
7397
- this.declarator = declarator;
7398
-
7399
- this.isReassigned = false;
7400
- this.exportName = null;
7401
-
7402
- this.duplicates = [];
7403
- this.assignedExpressions = new Set( init ? [ init ] : null );
7404
- }
7405
-
7406
- addReference () {
7407
- /* noop? */
7408
- }
7409
-
7410
- assignExpression ( expression ) {
7411
- this.assignedExpressions.add( expression );
7412
- this.isReassigned = true;
7413
- }
7414
-
7415
- gatherPossibleValues ( values ) {
7416
- this.assignedExpressions.forEach( value => values.add( value ) );
7417
- }
7418
-
7419
- getName ( es ) {
7420
- // TODO destructuring...
7421
- if ( es ) { return this.name; }
7422
- if ( !this.isReassigned || !this.exportName ) { return this.name; }
7423
-
7424
- return `exports.${this.exportName}`;
7425
- }
7426
-
7427
- includeDeclaration () {
7428
- if ( this.included ) {
7429
- return false;
7430
- }
7431
- this.included = true;
7432
- this.declarator.includeDeclaration();
7433
- this.duplicates.forEach( duplicate => duplicate.includeDeclaration() );
7434
- return true;
7435
- }
7436
7744
 
7437
- toString () {
7438
- return this.name;
7745
+ hasEffectsAsExpressionStatement ( options ) {
7746
+ return this.hasEffects( options );
7439
7747
  }
7440
7748
  }
7441
7749
 
7442
7750
  class VariableDeclarator extends Node$1 {
7443
- assignExpression () {
7444
- for ( const proxy of this.proxies.values() ) {
7445
- proxy.assignExpression( UNKNOWN_ASSIGNMENT );
7446
- }
7447
- }
7448
-
7449
- hasEffects ( options ) {
7450
- return super.hasEffects( options )
7451
- || extractNames( this.id ).some( name => this.proxies.get( name ).included );
7751
+ bindAssignment ( expression ) {
7752
+ this.id.bindAssignment( expression );
7452
7753
  }
7453
7754
 
7454
- initialiseNode () {
7455
- this.proxies = new Map();
7456
- const lexicalBoundary = this.scope.findLexicalBoundary();
7457
- const init = this.init
7458
- ? ( this.id.type === 'Identifier' ? this.init : UNKNOWN_ASSIGNMENT )
7459
- : null;
7460
-
7461
- extractNames( this.id ).forEach( name => {
7462
- const proxy = new DeclaratorProxy( name, this, lexicalBoundary.isModuleScope, init );
7463
-
7464
- this.proxies.set( name, proxy );
7465
- this.scope.addDeclaration( name, proxy, this.parent.kind === 'var' );
7466
- } );
7755
+ initialiseDeclarator ( parentScope, kind ) {
7756
+ this.initialiseScope( parentScope );
7757
+ this.init && this.init.initialise( this.scope );
7758
+ this.id.initialiseAndDeclare( this.scope, kind, this.init );
7467
7759
  }
7468
7760
 
7761
+ // TODO Deleting this does not break any tests. Find meaningful test or delete.
7469
7762
  render ( code, es ) {
7470
7763
  extractNames( this.id ).forEach( name => {
7471
- const declaration = this.proxies.get( name );
7764
+ const variable = this.scope.findVariable( name );
7472
7765
 
7473
- if ( !es && declaration.exportName && declaration.isReassigned ) {
7766
+ if ( !es && variable.exportName && variable.isReassigned ) {
7474
7767
  if ( this.init ) {
7475
- code.overwrite( this.start, this.id.end, declaration.getName( es ) );
7768
+ code.overwrite( this.start, this.id.end, variable.getName( es ) );
7476
7769
  } else if ( this.module.bundle.treeshake ) {
7477
7770
  code.remove( this.start, this.end );
7478
7771
  }
@@ -7499,15 +7792,19 @@ function getSeparator ( code, start ) {
7499
7792
  const forStatement = /^For(?:Of|In)?Statement/;
7500
7793
 
7501
7794
  class VariableDeclaration extends Node$1 {
7502
- assignExpression () {
7503
- this.eachChild( child => child.assignExpression( UNKNOWN_ASSIGNMENT ) );
7795
+ bindAssignment () {
7796
+ this.eachChild( child => child.bindAssignment( UNKNOWN_ASSIGNMENT ) );
7504
7797
  }
7505
7798
 
7506
- includeDeclaration () {
7799
+ hasEffectsWhenAssigned () {
7800
+ return false;
7801
+ }
7802
+
7803
+ includeWithAllDeclarations () {
7507
7804
  if ( this.isFullyIncluded() ) { return false; }
7508
7805
  let addedNewNodes = false;
7509
7806
  this.declarations.forEach( declarator => {
7510
- if ( declarator.includeDeclaration() ) {
7807
+ if ( declarator.includeInBundle() ) {
7511
7808
  addedNewNodes = true;
7512
7809
  }
7513
7810
  } );
@@ -7535,6 +7832,10 @@ class VariableDeclaration extends Node$1 {
7535
7832
  return false;
7536
7833
  }
7537
7834
 
7835
+ initialiseChildren () {
7836
+ this.declarations.forEach( child => child.initialiseDeclarator( this.scope, this.kind ) );
7837
+ }
7838
+
7538
7839
  render ( code, es ) {
7539
7840
  const treeshake = this.module.bundle.treeshake;
7540
7841
 
@@ -7555,8 +7856,8 @@ class VariableDeclaration extends Node$1 {
7555
7856
  const prefix = empty ? '' : separator; // TODO indentation
7556
7857
 
7557
7858
  if ( declarator.id.type === 'Identifier' ) {
7558
- const proxy = declarator.proxies.get( declarator.id.name );
7559
- const isExportedAndReassigned = !es && proxy.exportName && proxy.isReassigned;
7859
+ const variable = this.scope.findVariable( declarator.id.name );
7860
+ const isExportedAndReassigned = !es && variable.exportName && variable.isReassigned;
7560
7861
 
7561
7862
  if ( isExportedAndReassigned ) {
7562
7863
  if ( declarator.init ) {
@@ -7564,7 +7865,7 @@ class VariableDeclaration extends Node$1 {
7564
7865
  c = declarator.end;
7565
7866
  empty = false;
7566
7867
  }
7567
- } else if ( !treeshake || proxy.included ) {
7868
+ } else if ( !treeshake || variable.included ) {
7568
7869
  if ( shouldSeparate ) { code.overwrite( c, declarator.start, `${prefix}${this.kind} ` ); } // TODO indentation
7569
7870
  c = declarator.end;
7570
7871
  empty = false;
@@ -7574,8 +7875,8 @@ class VariableDeclaration extends Node$1 {
7574
7875
  let isIncluded = false;
7575
7876
 
7576
7877
  extractNames( declarator.id ).forEach( name => {
7577
- const proxy = declarator.proxies.get( name );
7578
- const isExportedAndReassigned = !es && proxy.exportName && proxy.isReassigned;
7878
+ const variable = this.scope.findVariable( name );
7879
+ const isExportedAndReassigned = !es && variable.exportName && variable.isReassigned;
7579
7880
 
7580
7881
  if ( isExportedAndReassigned ) {
7581
7882
  // code.overwrite( c, declarator.start, prefix );
@@ -7622,23 +7923,35 @@ class WhileStatement extends Statement {
7622
7923
  return (
7623
7924
  this.included
7624
7925
  || this.test.hasEffects( options )
7625
- || this.body.hasEffects( Object.assign( {}, options, { inNestedBreakableStatement: true } ) )
7926
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
7626
7927
  );
7627
7928
  }
7628
7929
  }
7629
7930
 
7931
+ class YieldExpression extends Node$1 {
7932
+ hasEffects ( options ) {
7933
+ return super.hasEffects( options )
7934
+ || !options.ignoreReturnAwaitYield();
7935
+ }
7936
+
7937
+ hasEffectsAsExpressionStatement ( options ) {
7938
+ return this.hasEffects( options );
7939
+ }
7940
+ }
7941
+
7630
7942
  var nodes = {
7631
7943
  ArrayExpression: Node$1,
7632
7944
  ArrayPattern,
7633
7945
  ArrowFunctionExpression,
7634
7946
  AssignmentExpression,
7635
- AssignmentPattern: Node$1,
7947
+ AssignmentPattern,
7636
7948
  AwaitExpression,
7637
7949
  BinaryExpression,
7638
7950
  BlockStatement,
7639
7951
  BreakStatement,
7640
7952
  CallExpression,
7641
7953
  CatchClause,
7954
+ ClassBody,
7642
7955
  ClassDeclaration,
7643
7956
  ClassExpression,
7644
7957
  ConditionalExpression,
@@ -7656,15 +7969,18 @@ var nodes = {
7656
7969
  Identifier,
7657
7970
  IfStatement,
7658
7971
  ImportDeclaration,
7972
+ LabeledStatement,
7659
7973
  Literal,
7660
7974
  LogicalExpression,
7661
7975
  MemberExpression,
7976
+ MethodDefinition,
7662
7977
  NewExpression,
7663
- ObjectExpression: Node$1,
7978
+ ObjectExpression,
7664
7979
  ObjectPattern,
7665
7980
  Property,
7666
7981
  RestElement,
7667
7982
  ReturnStatement,
7983
+ SequenceExpression,
7668
7984
  SwitchCase,
7669
7985
  SwitchStatement,
7670
7986
  TaggedTemplateExpression,
@@ -7677,21 +7993,14 @@ var nodes = {
7677
7993
  UpdateExpression,
7678
7994
  VariableDeclarator,
7679
7995
  VariableDeclaration,
7680
- WhileStatement
7996
+ WhileStatement,
7997
+ YieldExpression
7681
7998
  };
7682
7999
 
7683
8000
  class UnknownNode extends Node$1 {
7684
8001
  hasEffects () {
7685
8002
  return true;
7686
8003
  }
7687
-
7688
- hasEffectsWhenAssigned () {
7689
- return true;
7690
- }
7691
-
7692
- hasEffectsWhenMutated () {
7693
- return true;
7694
- }
7695
8004
  }
7696
8005
 
7697
8006
  var keys$1 = {
@@ -7779,14 +8088,13 @@ function clone ( node ) {
7779
8088
 
7780
8089
  class ModuleScope extends Scope {
7781
8090
  constructor ( module ) {
7782
- super({
7783
- isBlockScope: false,
7784
- isLexicalBoundary: true,
8091
+ super( {
7785
8092
  isModuleScope: true,
7786
8093
  parent: module.bundle.scope
7787
- });
8094
+ } );
7788
8095
 
7789
8096
  this.module = module;
8097
+ this.variables.this = new LocalVariable( 'this', null, UNDEFINED_ASSIGNMENT );
7790
8098
  }
7791
8099
 
7792
8100
  deshadow ( names ) {
@@ -7798,21 +8106,21 @@ class ModuleScope extends Scope {
7798
8106
  const addDeclaration = declaration => {
7799
8107
  if ( declaration.isNamespace && !declaration.isExternal ) {
7800
8108
  declaration.module.getExports().forEach( name => {
7801
- addDeclaration( declaration.module.traceExport(name) );
7802
- });
8109
+ addDeclaration( declaration.module.traceExport( name ) );
8110
+ } );
7803
8111
  }
7804
8112
 
7805
8113
  names.add( declaration.name );
7806
8114
  };
7807
8115
 
7808
8116
  specifier.module.getExports().forEach( name => {
7809
- addDeclaration( specifier.module.traceExport(name) );
7810
- });
8117
+ addDeclaration( specifier.module.traceExport( name ) );
8118
+ } );
7811
8119
 
7812
8120
  if ( specifier.name !== '*' ) {
7813
8121
  const declaration = specifier.module.traceExport( specifier.name );
7814
8122
  if ( !declaration ) {
7815
- this.module.warn({
8123
+ this.module.warn( {
7816
8124
  code: 'NON_EXISTENT_EXPORT',
7817
8125
  name: specifier.name,
7818
8126
  source: specifier.module.id,
@@ -7830,22 +8138,22 @@ class ModuleScope extends Scope {
7830
8138
  names.add( specifier.specifier.imported.name );
7831
8139
  }
7832
8140
  }
7833
- });
8141
+ } );
7834
8142
 
7835
8143
  super.deshadow( names );
7836
8144
  }
7837
8145
 
7838
- findDeclaration ( name ) {
7839
- if ( this.declarations[ name ] ) {
7840
- return this.declarations[ name ];
7841
- }
7842
-
7843
- return this.module.trace( name ) || this.parent.findDeclaration( name );
7844
- }
7845
-
7846
8146
  findLexicalBoundary () {
7847
8147
  return this;
7848
8148
  }
8149
+
8150
+ findVariable ( name ) {
8151
+ if ( this.variables[ name ] ) {
8152
+ return this.variables[ name ];
8153
+ }
8154
+
8155
+ return this.module.trace( name ) || this.parent.findVariable( name );
8156
+ }
7849
8157
  }
7850
8158
 
7851
8159
  function tryParse ( module, acornOptions ) {
@@ -7864,6 +8172,11 @@ function tryParse ( module, acornOptions ) {
7864
8172
  }
7865
8173
  }
7866
8174
 
8175
+ function includeFully ( node ) {
8176
+ node.includeInBundle();
8177
+ node.eachChild( includeFully );
8178
+ }
8179
+
7867
8180
  class Module {
7868
8181
  constructor ( ref ) {
7869
8182
  var id = ref.id;
@@ -7998,9 +8311,6 @@ class Module {
7998
8311
  localName: 'default',
7999
8312
  identifier
8000
8313
  };
8001
-
8002
- // create a synthetic declaration
8003
- //this.declarations.default = new SyntheticDefaultDeclaration( node, identifier || this.basename() );
8004
8314
  }
8005
8315
 
8006
8316
  // export var { foo, bar } = ...
@@ -8167,6 +8477,10 @@ class Module {
8167
8477
  return keys( reexports );
8168
8478
  }
8169
8479
 
8480
+ includeAllInBundle () {
8481
+ this.ast.body.forEach( includeFully );
8482
+ }
8483
+
8170
8484
  includeInBundle () {
8171
8485
  let addedNewNodes = false;
8172
8486
  this.ast.body.forEach( node => {
@@ -8181,7 +8495,7 @@ class Module {
8181
8495
 
8182
8496
  namespace () {
8183
8497
  if ( !this.declarations[ '*' ] ) {
8184
- this.declarations[ '*' ] = new SyntheticNamespaceDeclaration( this );
8498
+ this.declarations[ '*' ] = new NamespaceVariable( this );
8185
8499
  }
8186
8500
 
8187
8501
  return this.declarations[ '*' ];
@@ -8217,8 +8531,8 @@ class Module {
8217
8531
 
8218
8532
  trace ( name ) {
8219
8533
  // TODO this is slightly circular
8220
- if ( name in this.scope.declarations ) {
8221
- return this.scope.declarations[ name ];
8534
+ if ( name in this.scope.variables ) {
8535
+ return this.scope.variables[ name ];
8222
8536
  }
8223
8537
 
8224
8538
  if ( name in this.imports ) {
@@ -8273,7 +8587,7 @@ class Module {
8273
8587
  const name = exportDeclaration.localName;
8274
8588
  const declaration = this.trace( name );
8275
8589
 
8276
- return declaration || this.bundle.scope.findDeclaration( name );
8590
+ return declaration || this.bundle.scope.findVariable( name );
8277
8591
  }
8278
8592
 
8279
8593
  if ( name === 'default' ) { return; }
@@ -8303,11 +8617,54 @@ class Module {
8303
8617
  }
8304
8618
  }
8305
8619
 
8620
+ class ExternalVariable extends Variable {
8621
+ constructor ( module, name ) {
8622
+ super( name );
8623
+ this.module = module;
8624
+ this.safeName = null;
8625
+ this.isExternal = true;
8626
+ this.isNamespace = name === '*';
8627
+ }
8628
+
8629
+ addReference ( reference ) {
8630
+ if ( this.name === 'default' || this.name === '*' ) {
8631
+ this.module.suggestName( reference.name );
8632
+ }
8633
+ }
8634
+
8635
+ getName ( es ) {
8636
+ if ( this.name === '*' ) {
8637
+ return this.module.name;
8638
+ }
8639
+
8640
+ if ( this.name === 'default' ) {
8641
+ return this.module.exportsNamespace || ( !es && this.module.exportsNames ) ?
8642
+ `${this.module.name}__default` :
8643
+ this.module.name;
8644
+ }
8645
+
8646
+ return es ? this.safeName : `${this.module.name}.${this.name}`;
8647
+ }
8648
+
8649
+ includeVariable () {
8650
+ if ( this.included ) {
8651
+ return false;
8652
+ }
8653
+ this.included = true;
8654
+ this.module.used = true;
8655
+ return true;
8656
+ }
8657
+
8658
+ setSafeName ( name ) {
8659
+ this.safeName = name;
8660
+ }
8661
+ }
8662
+
8306
8663
  class ExternalModule {
8307
8664
  constructor ( id ) {
8308
8665
  this.id = id;
8309
8666
 
8310
- const parts = id.split(/[\\/]/);
8667
+ const parts = id.split( /[\\/]/ );
8311
8668
  this.name = makeLegal( parts.pop() );
8312
8669
 
8313
8670
  this.nameSuggestions = blank();
@@ -8334,9 +8691,8 @@ class ExternalModule {
8334
8691
  if ( name !== 'default' && name !== '*' ) { this.exportsNames = true; }
8335
8692
  if ( name === '*' ) { this.exportsNamespace = true; }
8336
8693
 
8337
- return this.declarations[ name ] || (
8338
- this.declarations[ name ] = new ExternalDeclaration( this, name )
8339
- );
8694
+ return this.declarations[ name ]
8695
+ || (this.declarations[ name ] = new ExternalVariable( this, name ));
8340
8696
  }
8341
8697
  }
8342
8698
 
@@ -9378,9 +9734,9 @@ function callIfFunction ( thing ) {
9378
9734
  return typeof thing === 'function' ? thing() : thing;
9379
9735
  }
9380
9736
 
9381
- class SyntheticGlobalDeclaration {
9737
+ class GlobalVariable extends Variable {
9382
9738
  constructor ( name ) {
9383
- this.name = name;
9739
+ super( name );
9384
9740
  this.isExternal = true;
9385
9741
  this.isGlobal = true;
9386
9742
  this.isReassigned = false;
@@ -9388,33 +9744,23 @@ class SyntheticGlobalDeclaration {
9388
9744
  }
9389
9745
 
9390
9746
  addReference ( reference ) {
9391
- reference.declaration = this;
9392
9747
  if ( reference.isReassignment ) { this.isReassigned = true; }
9393
9748
  }
9394
9749
 
9395
9750
  assignExpression () {}
9396
9751
 
9397
- gatherPossibleValues ( values ) {
9398
- values.add( UNKNOWN_ASSIGNMENT );
9399
- }
9400
-
9401
- getName () {
9402
- return this.name;
9403
- }
9404
-
9405
- includeDeclaration () {
9406
- this.included = true;
9407
- return false;
9752
+ hasEffectsWhenCalled () {
9753
+ return !pureFunctions[ this.name ];
9408
9754
  }
9409
9755
  }
9410
9756
 
9411
9757
  class BundleScope extends Scope {
9412
- findDeclaration ( name ) {
9413
- if ( !this.declarations[ name ] ) {
9414
- this.declarations[ name ] = new SyntheticGlobalDeclaration( name );
9758
+ findVariable ( name ) {
9759
+ if ( !this.variables[ name ] ) {
9760
+ this.variables[ name ] = new GlobalVariable( name );
9415
9761
  }
9416
9762
 
9417
- return this.declarations[ name ];
9763
+ return this.variables[ name ];
9418
9764
  }
9419
9765
  }
9420
9766
 
@@ -9470,7 +9816,7 @@ class Bundle$$1 {
9470
9816
  this.scope = new BundleScope();
9471
9817
  // TODO strictly speaking, this only applies with non-ES6, non-default-only bundles
9472
9818
  [ 'module', 'exports', '_interopDefault' ].forEach( name => {
9473
- this.scope.findDeclaration( name ); // creates global declaration as side-effect
9819
+ this.scope.findVariable( name ); // creates global variable as side-effect
9474
9820
  } );
9475
9821
 
9476
9822
  this.moduleById = new Map();
@@ -9532,7 +9878,7 @@ class Bundle$$1 {
9532
9878
  .then( entryModule => {
9533
9879
  this.entryModule = entryModule;
9534
9880
 
9535
- // Phase 2 – binding. We link references to their declarations
9881
+ // Phase 2 – binding. We link references to their variables
9536
9882
  // to generate a complete picture of the bundle
9537
9883
 
9538
9884
  timeStart( 'phase 2' );
@@ -9542,31 +9888,30 @@ class Bundle$$1 {
9542
9888
 
9543
9889
  timeEnd( 'phase 2' );
9544
9890
 
9545
- // Phase 3 – marking. We 'run' each statement to see which ones
9546
- // need to be included in the generated bundle
9891
+ // Phase 3 – marking. We include all statements that should be included
9547
9892
 
9548
9893
  timeStart( 'phase 3' );
9549
9894
 
9550
9895
  // mark all export statements
9551
9896
  entryModule.getExports().forEach( name => {
9552
- const declaration = entryModule.traceExport( name );
9897
+ const variable = entryModule.traceExport( name );
9553
9898
 
9554
- declaration.exportName = name;
9555
- declaration.includeDeclaration();
9899
+ variable.exportName = name;
9900
+ variable.includeVariable();
9556
9901
 
9557
- if ( declaration.isNamespace ) {
9558
- declaration.needsNamespaceBlock = true;
9902
+ if ( variable.isNamespace ) {
9903
+ variable.needsNamespaceBlock = true;
9559
9904
  }
9560
9905
  } );
9561
9906
 
9562
9907
  entryModule.getReexports().forEach( name => {
9563
- const declaration = entryModule.traceExport( name );
9908
+ const variable = entryModule.traceExport( name );
9564
9909
 
9565
- if ( declaration.isExternal ) {
9566
- declaration.reexported = declaration.module.reexported = true;
9910
+ if ( variable.isExternal ) {
9911
+ variable.reexported = variable.module.reexported = true;
9567
9912
  } else {
9568
- declaration.exportName = name;
9569
- declaration.includeDeclaration();
9913
+ variable.exportName = name;
9914
+ variable.includeVariable();
9570
9915
  }
9571
9916
  } );
9572
9917
 
@@ -9581,6 +9926,9 @@ class Bundle$$1 {
9581
9926
  }
9582
9927
  } );
9583
9928
  } while ( addedNewNodes );
9929
+ } else {
9930
+ // Necessary to properly replace namespace imports
9931
+ this.modules.forEach( module => module.includeAllInBundle() );
9584
9932
  }
9585
9933
 
9586
9934
  timeEnd( 'phase 3' );
@@ -9627,7 +9975,7 @@ class Bundle$$1 {
9627
9975
  const used = blank();
9628
9976
 
9629
9977
  // ensure no conflicts with globals
9630
- keys( this.scope.declarations ).forEach( name => used[ name ] = 1 );
9978
+ keys( this.scope.variables ).forEach( name => used[ name ] = 1 );
9631
9979
 
9632
9980
  function getSafeName ( name ) {
9633
9981
  while ( used[ name ] ) {
@@ -9655,12 +10003,12 @@ class Bundle$$1 {
9655
10003
  } );
9656
10004
 
9657
10005
  this.modules.forEach( module => {
9658
- forOwn( module.scope.declarations, ( declaration ) => {
9659
- if ( declaration.isDefault && declaration.declaration.id ) {
10006
+ forOwn( module.scope.variables, variable => {
10007
+ if ( variable.isDefault && variable.declaration.id ) {
9660
10008
  return;
9661
10009
  }
9662
10010
 
9663
- declaration.name = getSafeName( declaration.name );
10011
+ variable.name = getSafeName( variable.name );
9664
10012
  } );
9665
10013
 
9666
10014
  // deconflict reified namespaces
@@ -9813,12 +10161,12 @@ class Bundle$$1 {
9813
10161
  // need to find the actual import declaration, so we can provide
9814
10162
  // a useful error message. Bit hoop-jumpy but what can you do
9815
10163
  const declaration = module.ast.body.find( node => {
9816
- return node.isImportDeclaration && node.source.value === source;
10164
+ return ( node.isImportDeclaration || node.isExportDeclaration ) && node.source.value === source;
9817
10165
  } );
9818
-
10166
+ const declarationType = /Export/.test( declaration.type ) ? 'export' : 'import';
9819
10167
  module.error( {
9820
10168
  code: 'CANNOT_IMPORT_SELF',
9821
- message: `A module cannot import itself`
10169
+ message: `A module cannot ${declarationType} itself`
9822
10170
  }, declaration.start );
9823
10171
  }
9824
10172
 
@@ -10299,7 +10647,7 @@ function createCommonjsModule(fn, module) {
10299
10647
  * Licensed under the MIT license.
10300
10648
  */
10301
10649
 
10302
- var index$2 = function filenameRegex() {
10650
+ var filenameRegex = function filenameRegex() {
10303
10651
  return /([^\\\/]+)$/;
10304
10652
  };
10305
10653
 
@@ -10310,7 +10658,7 @@ var index$2 = function filenameRegex() {
10310
10658
  * Released under the MIT License.
10311
10659
  */
10312
10660
 
10313
- var index$6 = function (arr) {
10661
+ var arrFlatten = function (arr) {
10314
10662
  return flat(arr, []);
10315
10663
  };
10316
10664
 
@@ -10356,7 +10704,7 @@ function diff(arr, arrays) {
10356
10704
  }
10357
10705
 
10358
10706
  if (argsLen > 2) {
10359
- arrays = index$6(slice.call(arguments, 1));
10707
+ arrays = arrFlatten(slice.call(arguments, 1));
10360
10708
  }
10361
10709
 
10362
10710
  while (++i < len) {
@@ -10371,7 +10719,7 @@ function diff(arr, arrays) {
10371
10719
  * Expose `diff`
10372
10720
  */
10373
10721
 
10374
- var index$4 = diff;
10722
+ var arrDiff = diff;
10375
10723
 
10376
10724
  /*!
10377
10725
  * array-unique <https://github.com/jonschlinkert/array-unique>
@@ -10380,7 +10728,7 @@ var index$4 = diff;
10380
10728
  * Licensed under the MIT License.
10381
10729
  */
10382
10730
 
10383
- var index$8 = function unique(arr) {
10731
+ var arrayUnique = function unique(arr) {
10384
10732
  if (!Array.isArray(arr)) {
10385
10733
  throw new TypeError('array-unique expects an array.');
10386
10734
  }
@@ -10402,12 +10750,12 @@ var index$8 = function unique(arr) {
10402
10750
 
10403
10751
  var toString$1$1 = {}.toString;
10404
10752
 
10405
- var index$18 = Array.isArray || function (arr) {
10753
+ var isarray = Array.isArray || function (arr) {
10406
10754
  return toString$1$1.call(arr) == '[object Array]';
10407
10755
  };
10408
10756
 
10409
- var index$16 = function isObject(val) {
10410
- return val != null && typeof val === 'object' && index$18(val) === false;
10757
+ var isobject = function isObject(val) {
10758
+ return val != null && typeof val === 'object' && isarray(val) === false;
10411
10759
  };
10412
10760
 
10413
10761
  /*!
@@ -10419,7 +10767,7 @@ var index$16 = function isObject(val) {
10419
10767
 
10420
10768
  // The _isBuffer check is for Safari 5-7 support, because it's missing
10421
10769
  // Object.prototype.constructor. Remove this eventually
10422
- var index$24 = function (obj) {
10770
+ var isBuffer_1 = function (obj) {
10423
10771
  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
10424
10772
  };
10425
10773
 
@@ -10441,7 +10789,7 @@ var toString$2 = Object.prototype.toString;
10441
10789
  * @return {*} Native javascript type
10442
10790
  */
10443
10791
 
10444
- var index$22 = function kindOf(val) {
10792
+ var kindOf = function kindOf(val) {
10445
10793
  // primitivies
10446
10794
  if (typeof val === 'undefined') {
10447
10795
  return 'undefined';
@@ -10494,7 +10842,7 @@ var index$22 = function kindOf(val) {
10494
10842
  }
10495
10843
 
10496
10844
  // buffer
10497
- if (index$24(val)) {
10845
+ if (isBuffer_1(val)) {
10498
10846
  return 'buffer';
10499
10847
  }
10500
10848
 
@@ -10548,8 +10896,8 @@ var index$22 = function kindOf(val) {
10548
10896
  return 'object';
10549
10897
  };
10550
10898
 
10551
- var index$20 = function isNumber(num) {
10552
- var type = index$22(num);
10899
+ var isNumber = function isNumber(num) {
10900
+ var type = kindOf(num);
10553
10901
  if (type !== 'number' && type !== 'string') {
10554
10902
  return false;
10555
10903
  }
@@ -10566,7 +10914,7 @@ var toString$3 = Object.prototype.toString;
10566
10914
  * @return {*} Native javascript type
10567
10915
  */
10568
10916
 
10569
- var index$30 = function kindOf(val) {
10917
+ var kindOf$2 = function kindOf(val) {
10570
10918
  // primitivies
10571
10919
  if (typeof val === 'undefined') {
10572
10920
  return 'undefined';
@@ -10619,7 +10967,7 @@ var index$30 = function kindOf(val) {
10619
10967
  }
10620
10968
 
10621
10969
  // buffer
10622
- if (index$24(val)) {
10970
+ if (isBuffer_1(val)) {
10623
10971
  return 'buffer';
10624
10972
  }
10625
10973
 
@@ -10673,8 +11021,8 @@ var index$30 = function kindOf(val) {
10673
11021
  return 'object';
10674
11022
  };
10675
11023
 
10676
- var index$28 = function isNumber(num) {
10677
- var type = index$30(num);
11024
+ var isNumber$2 = function isNumber(num) {
11025
+ var type = kindOf$2(num);
10678
11026
 
10679
11027
  if (type === 'string') {
10680
11028
  if (!num.trim()) return false;
@@ -10694,7 +11042,7 @@ var toString$4 = Object.prototype.toString;
10694
11042
  * @return {*} Native javascript type
10695
11043
  */
10696
11044
 
10697
- var index$32 = function kindOf(val) {
11045
+ var kindOf$4 = function kindOf(val) {
10698
11046
  // primitivies
10699
11047
  if (typeof val === 'undefined') {
10700
11048
  return 'undefined';
@@ -10750,7 +11098,7 @@ var index$32 = function kindOf(val) {
10750
11098
  }
10751
11099
 
10752
11100
  // buffer
10753
- if (index$24(val)) {
11101
+ if (isBuffer_1(val)) {
10754
11102
  return 'buffer';
10755
11103
  }
10756
11104
 
@@ -10808,7 +11156,7 @@ var index$32 = function kindOf(val) {
10808
11156
  * Expose `randomatic`
10809
11157
  */
10810
11158
 
10811
- var index$26 = randomatic;
11159
+ var randomatic_1 = randomatic;
10812
11160
 
10813
11161
  /**
10814
11162
  * Available mask characters
@@ -10844,12 +11192,12 @@ function randomatic(pattern, length, options) {
10844
11192
  if (typeof pattern === 'string') {
10845
11193
  length = pattern.length;
10846
11194
 
10847
- } else if (index$28(pattern)) {
11195
+ } else if (isNumber$2(pattern)) {
10848
11196
  options = {}; length = pattern; pattern = '*';
10849
11197
  }
10850
11198
  }
10851
11199
 
10852
- if (index$32(length) === 'object' && length.hasOwnProperty('chars')) {
11200
+ if (kindOf$4(length) === 'object' && length.hasOwnProperty('chars')) {
10853
11201
  options = length;
10854
11202
  pattern = options.chars;
10855
11203
  length = pattern.length;
@@ -10893,7 +11241,7 @@ var cache;
10893
11241
  * Expose `repeat`
10894
11242
  */
10895
11243
 
10896
- var index$34 = repeat;
11244
+ var repeatString = repeat;
10897
11245
 
10898
11246
  /**
10899
11247
  * Repeat the given `string` the specified `number`
@@ -10951,7 +11299,7 @@ function repeat(str, num) {
10951
11299
  * Licensed under the MIT license.
10952
11300
  */
10953
11301
 
10954
- var index$36 = function repeat(ele, num) {
11302
+ var repeatElement = function repeat(ele, num) {
10955
11303
  var arr = new Array(num);
10956
11304
 
10957
11305
  for (var i = 0; i < num; i++) {
@@ -10965,7 +11313,7 @@ var index$36 = function repeat(ele, num) {
10965
11313
  * Expose `fillRange`
10966
11314
  */
10967
11315
 
10968
- var index$14 = fillRange;
11316
+ var fillRange_1 = fillRange;
10969
11317
 
10970
11318
  /**
10971
11319
  * Return a range of numbers or letters.
@@ -10990,7 +11338,7 @@ function fillRange(a, b, step, options, fn) {
10990
11338
  fn = options; options = {};
10991
11339
  }
10992
11340
 
10993
- if (index$16(step)) {
11341
+ if (isobject(step)) {
10994
11342
  options = step; step = '';
10995
11343
  }
10996
11344
 
@@ -11025,11 +11373,11 @@ function fillRange(a, b, step, options, fn) {
11025
11373
 
11026
11374
  // repeat string
11027
11375
  if (m === '+') {
11028
- return index$36(a, b);
11376
+ return repeatElement(a, b);
11029
11377
 
11030
11378
  // randomize a, `b` times
11031
11379
  } else if (m === '?') {
11032
- return [index$26(a, b)];
11380
+ return [randomatic_1(a, b)];
11033
11381
 
11034
11382
  // expand right, no regex reduction
11035
11383
  } else if (m === '>') {
@@ -11052,7 +11400,7 @@ function fillRange(a, b, step, options, fn) {
11052
11400
  regex = true;
11053
11401
  sep$$1 = m;
11054
11402
  }
11055
- } else if (!index$20(step)) {
11403
+ } else if (!isNumber(step)) {
11056
11404
  if (!opts.silent) {
11057
11405
  throw new TypeError('fill-range: invalid step.');
11058
11406
  }
@@ -11077,8 +11425,8 @@ function fillRange(a, b, step, options, fn) {
11077
11425
  }
11078
11426
 
11079
11427
  // validate arguments
11080
- var isNumA = index$20(zeros(a));
11081
- var isNumB = index$20(zeros(b));
11428
+ var isNumA = isNumber(zeros(a));
11429
+ var isNumB = isNumber(zeros(b));
11082
11430
 
11083
11431
  if ((!isNumA && isNumB) || (isNumA && !isNumB)) {
11084
11432
  if (!opts.silent) {
@@ -11341,7 +11689,7 @@ function isPadded(origA, origB) {
11341
11689
  : blen;
11342
11690
 
11343
11691
  return function (a) {
11344
- return index$34('0', len - length(a));
11692
+ return repeatString('0', len - length(a));
11345
11693
  };
11346
11694
  }
11347
11695
  return false;
@@ -11355,7 +11703,7 @@ function length(val) {
11355
11703
  return val.toString().length;
11356
11704
  }
11357
11705
 
11358
- var index$12 = function expandRange(str, options, fn) {
11706
+ var expandRange = function expandRange(str, options, fn) {
11359
11707
  if (typeof str !== 'string') {
11360
11708
  throw new TypeError('expand-range expects a string.');
11361
11709
  }
@@ -11385,7 +11733,7 @@ var index$12 = function expandRange(str, options, fn) {
11385
11733
  }
11386
11734
 
11387
11735
  args.push(opts);
11388
- return index$14.apply(null, args.concat(fn));
11736
+ return fillRange_1.apply(null, args.concat(fn));
11389
11737
  };
11390
11738
 
11391
11739
  /*!
@@ -11441,7 +11789,7 @@ function randomize$1() {
11441
11789
 
11442
11790
  var cache$1 = {};
11443
11791
 
11444
- var index$38 = {
11792
+ var preserve = {
11445
11793
  before: before,
11446
11794
  after: after
11447
11795
  };
@@ -11458,7 +11806,7 @@ var index$38 = {
11458
11806
  * Expose `braces`
11459
11807
  */
11460
11808
 
11461
- var index$10 = function(str, options) {
11809
+ var braces_1 = function(str, options) {
11462
11810
  if (typeof str !== 'string') {
11463
11811
  throw new Error('braces expects a string');
11464
11812
  }
@@ -11528,7 +11876,7 @@ function braces(str, arr, options) {
11528
11876
  return arr.concat(str);
11529
11877
  } else {
11530
11878
  es6 = true;
11531
- str = index$38.before(str, es6Regex());
11879
+ str = preserve.before(str, es6Regex());
11532
11880
  }
11533
11881
  }
11534
11882
 
@@ -11548,7 +11896,7 @@ function braces(str, arr, options) {
11548
11896
  var segs, segsLength;
11549
11897
 
11550
11898
  if (inner.indexOf('..') !== -1) {
11551
- segs = index$12(inner, opts, fn) || inner.split(',');
11899
+ segs = expandRange(inner, opts, fn) || inner.split(',');
11552
11900
  segsLength = segs.length;
11553
11901
 
11554
11902
  } else if (inner[0] === '"' || inner[0] === '\'') {
@@ -11586,7 +11934,7 @@ function braces(str, arr, options) {
11586
11934
  arr = braces(val, arr, opts);
11587
11935
  } else if (val !== '') {
11588
11936
  if (opts.nodupes && arr.indexOf(val) !== -1) { continue; }
11589
- arr.push(es6 ? index$38.after(val) : val);
11937
+ arr.push(es6 ? preserve.after(val) : val);
11590
11938
  }
11591
11939
  }
11592
11940
 
@@ -11636,7 +11984,7 @@ function exponential(str, options, fn) {
11636
11984
 
11637
11985
  } else {
11638
11986
  var num = Math.pow(2, exp);
11639
- arr.push.apply(arr, index$36(ele, num));
11987
+ arr.push.apply(arr, repeatElement(ele, num));
11640
11988
  }
11641
11989
  }
11642
11990
  }
@@ -11844,7 +12192,7 @@ function filter$1(arr, cb) {
11844
12192
  * Licensed under the MIT License.
11845
12193
  */
11846
12194
 
11847
- var index$42 = function isPosixBracket(str) {
12195
+ var isPosixBracket = function isPosixBracket(str) {
11848
12196
  return typeof str === 'string' && /\[([:.=+])(?:[^\[\]]|)+\1\]/.test(str);
11849
12197
  };
11850
12198
 
@@ -11872,10 +12220,10 @@ var POSIX = {
11872
12220
  * Expose `brackets`
11873
12221
  */
11874
12222
 
11875
- var index$40 = brackets;
12223
+ var expandBrackets = brackets;
11876
12224
 
11877
12225
  function brackets(str) {
11878
- if (!index$42(str)) {
12226
+ if (!isPosixBracket(str)) {
11879
12227
  return str;
11880
12228
  }
11881
12229
 
@@ -12008,7 +12356,7 @@ brackets.match = function(arr, pattern) {
12008
12356
  * Licensed under the MIT License.
12009
12357
  */
12010
12358
 
12011
- var index$46 = function isExtglob(str) {
12359
+ var isExtglob = function isExtglob(str) {
12012
12360
  return typeof str === 'string'
12013
12361
  && /[@?!+*]\(/.test(str);
12014
12362
  };
@@ -12025,7 +12373,7 @@ var cache$2 = {};
12025
12373
  * Expose `extglob`
12026
12374
  */
12027
12375
 
12028
- var index$44 = extglob;
12376
+ var extglob_1 = extglob;
12029
12377
 
12030
12378
  /**
12031
12379
  * Convert the given extglob `string` to a regex-compatible
@@ -12193,15 +12541,15 @@ function toRegex$1(pattern, contains, isNegated) {
12193
12541
 
12194
12542
 
12195
12543
 
12196
- var index$48 = function isGlob(str) {
12544
+ var isGlob = function isGlob(str) {
12197
12545
  return typeof str === 'string'
12198
12546
  && (/[*!?{}(|)[\]]/.test(str)
12199
- || index$46(str));
12547
+ || isExtglob(str));
12200
12548
  };
12201
12549
 
12202
12550
  var isWin = process.platform === 'win32';
12203
12551
 
12204
- var index$52 = function (str) {
12552
+ var removeTrailingSeparator = function (str) {
12205
12553
  var i = str.length - 1;
12206
12554
  if (i < 2) {
12207
12555
  return str;
@@ -12226,13 +12574,13 @@ function isSeparator(str, i) {
12226
12574
 
12227
12575
 
12228
12576
 
12229
- var index$50 = function normalizePath(str, stripTrailing) {
12577
+ var normalizePath = function normalizePath(str, stripTrailing) {
12230
12578
  if (typeof str !== 'string') {
12231
12579
  throw new TypeError('expected a string');
12232
12580
  }
12233
12581
  str = str.replace(/[\\\/]+/g, '/');
12234
12582
  if (stripTrailing !== false) {
12235
- str = index$52(str);
12583
+ str = removeTrailingSeparator(str);
12236
12584
  }
12237
12585
  return str;
12238
12586
  };
@@ -12244,7 +12592,7 @@ var index$50 = function normalizePath(str, stripTrailing) {
12244
12592
  * Licensed under the MIT License.
12245
12593
  */
12246
12594
 
12247
- var index$56 = function isExtendable(val) {
12595
+ var isExtendable = function isExtendable(val) {
12248
12596
  return typeof val !== 'undefined' && val !== null
12249
12597
  && (typeof val === 'object' || typeof val === 'function');
12250
12598
  };
@@ -12256,7 +12604,7 @@ var index$56 = function isExtendable(val) {
12256
12604
  * Released under the MIT License.
12257
12605
  */
12258
12606
 
12259
- var index$60 = function forIn(obj, fn, thisArg) {
12607
+ var forIn = function forIn(obj, fn, thisArg) {
12260
12608
  for (var key in obj) {
12261
12609
  if (fn.call(thisArg, obj[key], key, obj) === false) {
12262
12610
  break;
@@ -12266,16 +12614,16 @@ var index$60 = function forIn(obj, fn, thisArg) {
12266
12614
 
12267
12615
  var hasOwn = Object.prototype.hasOwnProperty;
12268
12616
 
12269
- var index$58 = function forOwn(obj, fn, thisArg) {
12270
- index$60(obj, function(val, key) {
12617
+ var forOwn$1 = function forOwn(obj, fn, thisArg) {
12618
+ forIn(obj, function(val, key) {
12271
12619
  if (hasOwn.call(obj, key)) {
12272
12620
  return fn.call(thisArg, obj[key], key, obj);
12273
12621
  }
12274
12622
  });
12275
12623
  };
12276
12624
 
12277
- var index$54 = function omit(obj, keys) {
12278
- if (!index$56(obj)) return {};
12625
+ var object_omit = function omit(obj, keys) {
12626
+ if (!isExtendable(obj)) return {};
12279
12627
 
12280
12628
  keys = [].concat.apply([], [].slice.call(arguments, 1));
12281
12629
  var last = keys[keys.length - 1];
@@ -12290,7 +12638,7 @@ var index$54 = function omit(obj, keys) {
12290
12638
  return obj;
12291
12639
  }
12292
12640
 
12293
- index$58(obj, function(value, key) {
12641
+ forOwn$1(obj, function(value, key) {
12294
12642
  if (keys.indexOf(key) === -1) {
12295
12643
 
12296
12644
  if (!isFunction) {
@@ -12303,20 +12651,20 @@ var index$54 = function omit(obj, keys) {
12303
12651
  return res;
12304
12652
  };
12305
12653
 
12306
- var index$66 = function globParent(str) {
12654
+ var globParent = function globParent(str) {
12307
12655
  str += 'a'; // preserves full path in case of trailing path separator
12308
- do {str = path__default.dirname(str);} while (index$48(str));
12656
+ do {str = path__default.dirname(str);} while (isGlob(str));
12309
12657
  return str;
12310
12658
  };
12311
12659
 
12312
- var index$64 = function globBase(pattern) {
12660
+ var globBase = function globBase(pattern) {
12313
12661
  if (typeof pattern !== 'string') {
12314
12662
  throw new TypeError('glob-base expects a string.');
12315
12663
  }
12316
12664
 
12317
12665
  var res = {};
12318
- res.base = index$66(pattern);
12319
- res.isGlob = index$48(pattern);
12666
+ res.base = globParent(pattern);
12667
+ res.isGlob = isGlob(pattern);
12320
12668
 
12321
12669
  if (res.base !== '.') {
12322
12670
  res.glob = pattern.substr(res.base.length);
@@ -12355,7 +12703,7 @@ function dirname$1(glob) {
12355
12703
  * Released under the MIT License.
12356
12704
  */
12357
12705
 
12358
- var index$68 = function(str) {
12706
+ var isDotfile = function(str) {
12359
12707
  if (str.charCodeAt(0) === 46 /* . */ && str.indexOf('/', 1) === -1) {
12360
12708
  return true;
12361
12709
  }
@@ -12363,7 +12711,7 @@ var index$68 = function(str) {
12363
12711
  return slash !== -1 ? str.charCodeAt(slash + 1) === 46 /* . */ : false;
12364
12712
  };
12365
12713
 
12366
- var index$62 = createCommonjsModule(function (module) {
12714
+ var parseGlob = createCommonjsModule(function (module) {
12367
12715
  /*!
12368
12716
  * parse-glob <https://github.com/jonschlinkert/parse-glob>
12369
12717
  *
@@ -12408,7 +12756,7 @@ module.exports = function parseGlob(glob) {
12408
12756
  // unescape dots and slashes in braces/brackets
12409
12757
  glob = escape(glob);
12410
12758
 
12411
- var parsed = index$64(glob);
12759
+ var parsed = globBase(glob);
12412
12760
  tok.is.glob = parsed.isGlob;
12413
12761
 
12414
12762
  tok.glob = parsed.glob;
@@ -12424,7 +12772,7 @@ module.exports = function parseGlob(glob) {
12424
12772
  tok.path.extname = basename$$1.slice(1).join('.') || '';
12425
12773
  tok.path.ext = '';
12426
12774
 
12427
- if (index$48(tok.path.dirname) && !tok.path.basename) {
12775
+ if (isGlob(tok.path.dirname) && !tok.path.basename) {
12428
12776
  if (!/\/$/.test(tok.glob)) {
12429
12777
  tok.path.basename = tok.glob;
12430
12778
  }
@@ -12457,11 +12805,11 @@ module.exports = function parseGlob(glob) {
12457
12805
  // Booleans
12458
12806
  var is = (glob && tok.is.glob);
12459
12807
  tok.is.negated = glob && glob.charAt(0) === '!';
12460
- tok.is.extglob = glob && index$46(glob);
12808
+ tok.is.extglob = glob && isExtglob(glob);
12461
12809
  tok.is.braces = has(is, glob, '{');
12462
12810
  tok.is.brackets = has(is, glob, '[:');
12463
12811
  tok.is.globstar = has(is, glob, '**');
12464
- tok.is.dotfile = index$68(tok.path.basename) || index$68(tok.path.filename);
12812
+ tok.is.dotfile = isDotfile(tok.path.basename) || isDotfile(tok.path.filename);
12465
12813
  tok.is.dotdir = dotdir(tok.path.dirname);
12466
12814
  return (cache[glob] = tok);
12467
12815
  };
@@ -12530,18 +12878,18 @@ function unescape(str) {
12530
12878
  */
12531
12879
 
12532
12880
  // see http://jsperf.com/testing-value-is-primitive/7
12533
- var index$72 = function isPrimitive(value) {
12881
+ var isPrimitive = function isPrimitive(value) {
12534
12882
  return value == null || (typeof value !== 'function' && typeof value !== 'object');
12535
12883
  };
12536
12884
 
12537
- var index$74 = function isEqual(a, b) {
12885
+ var isEqualShallow = function isEqual(a, b) {
12538
12886
  if (!a && !b) { return true; }
12539
12887
  if (!a && b || a && !b) { return false; }
12540
12888
 
12541
12889
  var numKeysA = 0, numKeysB = 0, key;
12542
12890
  for (key in b) {
12543
12891
  numKeysB++;
12544
- if (!index$72(b[key]) || !a.hasOwnProperty(key) || (a[key] !== b[key])) {
12892
+ if (!isPrimitive(b[key]) || !a.hasOwnProperty(key) || (a[key] !== b[key])) {
12545
12893
  return false;
12546
12894
  }
12547
12895
  }
@@ -12558,7 +12906,7 @@ var cache$3 = {};
12558
12906
  * Expose `regexCache`
12559
12907
  */
12560
12908
 
12561
- var index$70 = regexCache;
12909
+ var regexCache_1 = regexCache;
12562
12910
 
12563
12911
  /**
12564
12912
  * Memoize the results of a call to the new RegExp constructor.
@@ -12591,7 +12939,7 @@ function regexCache(fn, str, opts) {
12591
12939
  }
12592
12940
 
12593
12941
  cached = cache$3[key];
12594
- if (cached && index$74(cached.opts, opts)) {
12942
+ if (cached && isEqualShallow(cached.opts, opts)) {
12595
12943
  return cached.regex;
12596
12944
  }
12597
12945
 
@@ -12610,8 +12958,8 @@ function memo(key, opts, regex) {
12610
12958
  var cache_1 = cache$3;
12611
12959
  var basic_1 = basic;
12612
12960
 
12613
- index$70.cache = cache_1;
12614
- index$70.basic = basic_1;
12961
+ regexCache_1.cache = cache_1;
12962
+ regexCache_1.basic = basic_1;
12615
12963
 
12616
12964
  var utils_1 = createCommonjsModule(function (module) {
12617
12965
  'use strict';
@@ -12625,18 +12973,18 @@ var utils = module.exports;
12625
12973
  * Module dependencies
12626
12974
  */
12627
12975
 
12628
- utils.diff = index$4;
12629
- utils.unique = index$8;
12630
- utils.braces = index$10;
12631
- utils.brackets = index$40;
12632
- utils.extglob = index$44;
12633
- utils.isExtglob = index$46;
12634
- utils.isGlob = index$48;
12635
- utils.typeOf = index$22;
12636
- utils.normalize = index$50;
12637
- utils.omit = index$54;
12638
- utils.parseGlob = index$62;
12639
- utils.cache = index$70;
12976
+ utils.diff = arrDiff;
12977
+ utils.unique = arrayUnique;
12978
+ utils.braces = braces_1;
12979
+ utils.brackets = expandBrackets;
12980
+ utils.extglob = extglob_1;
12981
+ utils.isExtglob = isExtglob;
12982
+ utils.isGlob = isGlob;
12983
+ utils.typeOf = kindOf;
12984
+ utils.normalize = normalizePath;
12985
+ utils.omit = object_omit;
12986
+ utils.parseGlob = parseGlob;
12987
+ utils.cache = regexCache_1;
12640
12988
 
12641
12989
  /**
12642
12990
  * Get the filename of a filepath
@@ -12646,7 +12994,7 @@ utils.cache = index$70;
12646
12994
  */
12647
12995
 
12648
12996
  utils.filename = function filename(fp) {
12649
- var seg = fp.match(index$2());
12997
+ var seg = fp.match(filenameRegex());
12650
12998
  return seg && seg[0];
12651
12999
  };
12652
13000
 
@@ -13740,7 +14088,7 @@ micromatch.matchKeys = matchKeys;
13740
14088
  * Expose `micromatch`
13741
14089
  */
13742
14090
 
13743
- var index$1 = micromatch;
14091
+ var micromatch_1 = micromatch;
13744
14092
 
13745
14093
  function ensureArray$1 ( thing ) {
13746
14094
  if ( Array.isArray( thing ) ) return thing;
@@ -13749,7 +14097,7 @@ function ensureArray$1 ( thing ) {
13749
14097
  }
13750
14098
 
13751
14099
  function createFilter ( include, exclude ) {
13752
- const getMatcher = id => ( isRegexp( id ) ? id : { test: index$1.matcher( path.resolve( id ) ) } );
14100
+ const getMatcher = id => ( isRegexp( id ) ? id : { test: micromatch_1.matcher( path.resolve( id ) ) } );
13753
14101
  include = ensureArray$1( include ).map( getMatcher );
13754
14102
  exclude = ensureArray$1( exclude ).map( getMatcher );
13755
14103
 
@@ -13803,12 +14151,12 @@ requireRelative.resolve = function(requested, relativeTo) {
13803
14151
  return module$1._resolveFilename(requested, root);
13804
14152
  };
13805
14153
 
13806
- var index$76 = requireRelative;
14154
+ var requireRelative_1$1 = requireRelative;
13807
14155
 
13808
14156
  let chokidar;
13809
14157
 
13810
14158
  try {
13811
- chokidar = index$76( 'chokidar', process.cwd() );
14159
+ chokidar = requireRelative_1$1( 'chokidar', process.cwd() );
13812
14160
  } catch (err) {
13813
14161
  chokidar = null;
13814
14162
  }
@@ -14144,7 +14492,7 @@ function watch$1(configs) {
14144
14492
  return new Watcher(configs);
14145
14493
  }
14146
14494
 
14147
- var version$1 = "0.49.1";
14495
+ var version$1 = "0.50.1";
14148
14496
 
14149
14497
  exports.rollup = rollup;
14150
14498
  exports.watch = watch$1;