rollup 0.49.3 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/rollup.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
- Rollup.js v0.49.3
3
- Thu Sep 07 2017 21:02:36 GMT-0400 (EDT) - commit 0d20ed12e069b4fc445faecf221ffe5b40fbf90a
2
+ Rollup.js v0.50.0
3
+ Sat Sep 16 2017 09:48:09 GMT-0400 (EDT) - commit b949eb08169115ff66648838cbc4833379bf9440
4
4
 
5
5
 
6
6
  https://github.com/rollup/rollup
@@ -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
+ }
5672
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;
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,34 +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
+ */
5702
5876
  hasEffectsAsExpressionStatement () {
5703
5877
  return true;
5704
5878
  }
5705
5879
 
5880
+ /**
5881
+ * @param {ExecutionPathOptions} options
5882
+ * @return {boolean}
5883
+ */
5706
5884
  hasEffectsWhenAssigned () {
5707
5885
  return true;
5708
5886
  }
5709
5887
 
5710
- hasEffectsWhenMutated () {
5888
+ /**
5889
+ * @param {ExecutionPathOptions} options
5890
+ * @return {boolean}
5891
+ */
5892
+ hasEffectsWhenCalled () {
5711
5893
  return true;
5712
5894
  }
5713
5895
 
5714
- includeDeclaration () {
5715
- return this.includeInBundle();
5896
+ /**
5897
+ * @param {ExecutionPathOptions} options
5898
+ * @return {boolean}
5899
+ */
5900
+ hasEffectsWhenMutated () {
5901
+ return true;
5716
5902
  }
5717
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
+ */
5718
5911
  includeInBundle () {
5719
5912
  if ( this.isFullyIncluded() ) { return false; }
5720
5913
  let addedNewNodes = false;
@@ -5730,21 +5923,49 @@ class Node$1 {
5730
5923
  return true;
5731
5924
  }
5732
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
+ */
5733
5945
  initialise ( parentScope ) {
5734
5946
  this.initialiseScope( parentScope );
5735
5947
  this.initialiseNode( parentScope );
5736
5948
  this.initialiseChildren( parentScope );
5737
5949
  }
5738
5950
 
5739
- // 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
+ */
5740
5955
  initialiseChildren () {
5741
5956
  this.eachChild( child => child.initialise( this.scope ) );
5742
5957
  }
5743
5958
 
5744
- // 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
+ */
5745
5963
  initialiseNode () {}
5746
5964
 
5747
- // 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
+ */
5748
5969
  initialiseScope ( parentScope ) {
5749
5970
  this.scope = parentScope;
5750
5971
  }
@@ -5755,6 +5976,11 @@ class Node$1 {
5755
5976
  }
5756
5977
  }
5757
5978
 
5979
+ /**
5980
+ * Shortcut to skip checking this node for effects when all children have already
5981
+ * been included.
5982
+ * @param {Scope} parentScope
5983
+ */
5758
5984
  isFullyIncluded () {
5759
5985
  if ( this._fullyIncluded ) {
5760
5986
  return true;
@@ -5775,8 +6001,15 @@ class Node$1 {
5775
6001
  this.eachChild( child => child.render( code, es ) );
5776
6002
  }
5777
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
+ */
5778
6011
  shouldBeIncluded () {
5779
- return this.hasEffects( {} );
6012
+ return this.hasEffects( ExecutionPathOptions.create() );
5780
6013
  }
5781
6014
 
5782
6015
  someChild ( callback ) {
@@ -5797,45 +6030,91 @@ class Node$1 {
5797
6030
  }
5798
6031
 
5799
6032
  class ArrayPattern extends Node$1 {
5800
- assignExpression () {
5801
- this.eachChild( child => child.assignExpression( UNKNOWN_ASSIGNMENT ) );
6033
+ bindAssignment () {
6034
+ this.eachChild( child => child.bindAssignment( UNKNOWN_ASSIGNMENT ) );
5802
6035
  }
5803
6036
 
5804
6037
  hasEffectsWhenAssigned ( options ) {
5805
6038
  return this.someChild( child => child.hasEffectsWhenAssigned( options ) );
5806
6039
  }
6040
+
6041
+ initialiseAndDeclare ( parentScope, kind ) {
6042
+ this.initialiseScope( parentScope );
6043
+ this.eachChild( child => child.initialiseAndDeclare( parentScope, kind, UNKNOWN_ASSIGNMENT ) );
6044
+ }
5807
6045
  }
5808
6046
 
5809
- class Parameter {
5810
- constructor ( name ) {
5811
- this.name = name;
5812
- this.isParam = true;
5813
- 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 );
5814
6059
  }
5815
6060
 
5816
- addReference () {
5817
- // 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 ) );
5818
6066
  }
5819
6067
 
6068
+ addReference () {}
6069
+
5820
6070
  assignExpression ( expression ) {
5821
6071
  this.assignedExpressions.add( expression );
5822
6072
  this.isReassigned = true;
6073
+ Array.from( this.calls ).forEach( callOptions => expression.bindCall( callOptions ) );
5823
6074
  }
5824
6075
 
5825
- gatherPossibleValues ( values ) {
5826
- 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}`;
5827
6081
  }
5828
6082
 
5829
- getName () {
5830
- 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
+ );
5831
6088
  }
5832
6089
 
5833
- includeDeclaration () {
5834
- if ( this.included ) {
5835
- 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() );
5836
6102
  }
5837
- this.included = true;
5838
- 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;
5839
6118
  }
5840
6119
  }
5841
6120
 
@@ -5844,43 +6123,38 @@ class Scope {
5844
6123
  if ( options === void 0 ) options = {};
5845
6124
 
5846
6125
  this.parent = options.parent;
5847
- this.isBlockScope = !!options.isBlockScope;
5848
- this.isLexicalBoundary = !!options.isLexicalBoundary;
5849
6126
  this.isModuleScope = !!options.isModuleScope;
5850
6127
 
5851
6128
  this.children = [];
5852
6129
  if ( this.parent ) { this.parent.children.push( this ); }
5853
6130
 
5854
- this.declarations = blank();
5855
-
5856
- if ( this.isLexicalBoundary && !this.isModuleScope ) {
5857
- this.declarations.arguments = new Parameter( 'arguments' );
5858
- }
6131
+ this.variables = blank();
5859
6132
  }
5860
6133
 
5861
- addDeclaration ( name, declaration, isVar, isParam ) {
5862
- if ( isVar && this.isBlockScope ) {
5863
- 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 );
5864
6140
  } else {
5865
- const existingDeclaration = this.declarations[ name ];
5866
-
5867
- if ( existingDeclaration && existingDeclaration.duplicates ) {
5868
- // TODO warn/throw on duplicates?
5869
- existingDeclaration.duplicates.push( declaration );
5870
- } else {
5871
- this.declarations[ name ] = isParam ? new Parameter( name ) : declaration;
5872
- }
6141
+ this.variables[ name ] = new LocalVariable( identifier.name, identifier, init );
5873
6142
  }
5874
6143
  }
5875
6144
 
6145
+ addParameterDeclaration ( identifier ) {
6146
+ const name = identifier.name;
6147
+ this.variables[ name ] = new ParameterVariable( name, identifier );
6148
+ }
6149
+
5876
6150
  contains ( name ) {
5877
- return !!this.declarations[ name ] ||
6151
+ return !!this.variables[ name ] ||
5878
6152
  ( this.parent ? this.parent.contains( name ) : false );
5879
6153
  }
5880
6154
 
5881
6155
  deshadow ( names ) {
5882
- keys( this.declarations ).forEach( key => {
5883
- const declaration = this.declarations[ key ];
6156
+ keys( this.variables ).forEach( key => {
6157
+ const declaration = this.variables[ key ];
5884
6158
 
5885
6159
  // we can disregard exports.foo etc
5886
6160
  if ( declaration.exportName && declaration.isReassigned ) { return; }
@@ -5900,61 +6174,52 @@ class Scope {
5900
6174
  this.children.forEach( scope => scope.deshadow( names ) );
5901
6175
  }
5902
6176
 
5903
- findDeclaration ( name ) {
5904
- return this.declarations[ name ] ||
5905
- ( this.parent && this.parent.findDeclaration( name ) );
6177
+ findLexicalBoundary () {
6178
+ return this.parent.findLexicalBoundary();
5906
6179
  }
5907
6180
 
5908
- findLexicalBoundary () {
5909
- return this.isLexicalBoundary ? this : this.parent.findLexicalBoundary();
6181
+ findVariable ( name ) {
6182
+ return this.variables[ name ] ||
6183
+ ( this.parent && this.parent.findVariable( name ) );
5910
6184
  }
5911
6185
  }
5912
6186
 
5913
- class Function$1 extends Node$1 {
5914
- bind () {
5915
- if ( this.id ) { this.id.bind(); }
5916
- this.params.forEach( param => param.bind() );
5917
- this.body.bind();
5918
- }
6187
+ class ArrowFunctionExpression extends Node$1 {
6188
+ // Should receive an implementation once we start tracking parameter values
6189
+ bindCall () {}
5919
6190
 
5920
6191
  hasEffects () {
5921
6192
  return this.included;
5922
6193
  }
5923
6194
 
5924
- initialiseChildren () {
5925
- this.params.forEach( param => {
5926
- param.initialise( this.scope );
5927
- extractNames( param ).forEach( name => this.scope.addDeclaration( name, null, false, true ) );
5928
- } );
5929
- this.body.initialiseAndReplaceScope ?
5930
- this.body.initialiseAndReplaceScope( this.scope ) :
5931
- this.body.initialise( this.scope );
6195
+ hasEffectsWhenCalled ( options ) {
6196
+ return this.params.some( param => param.hasEffects( options ) )
6197
+ || this.body.hasEffects( options );
5932
6198
  }
5933
6199
 
5934
- initialiseScope ( parentScope ) {
5935
- this.scope = new Scope( {
5936
- parent: parentScope,
5937
- isBlockScope: false,
5938
- isLexicalBoundary: true
5939
- } );
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
+ }
5940
6211
  }
5941
- }
5942
6212
 
5943
- class ArrowFunctionExpression extends Function$1 {
5944
6213
  initialiseScope ( parentScope ) {
5945
- this.scope = new Scope( {
5946
- parent: parentScope,
5947
- isBlockScope: false,
5948
- isLexicalBoundary: false
5949
- } );
6214
+ this.scope = new Scope( { parent: parentScope } );
5950
6215
  }
5951
6216
  }
5952
6217
 
5953
6218
  // TODO tidy this up a bit (e.g. they can both use node.module.imports)
5954
6219
  function disallowIllegalReassignment ( scope, node ) {
5955
6220
  if ( node.type === 'MemberExpression' && node.object.type === 'Identifier' ) {
5956
- const declaration = scope.findDeclaration( node.object.name );
5957
- if ( declaration.isNamespace ) {
6221
+ const variable = scope.findVariable( node.object.name );
6222
+ if ( variable.isNamespace ) {
5958
6223
  node.module.error({
5959
6224
  code: 'ILLEGAL_NAMESPACE_REASSIGNMENT',
5960
6225
  message: `Illegal reassignment to import '${node.object.name}'`
@@ -5976,7 +6241,7 @@ class AssignmentExpression extends Node$1 {
5976
6241
  bind () {
5977
6242
  super.bind();
5978
6243
  disallowIllegalReassignment( this.scope, this.left );
5979
- this.left.assignExpression( this.right );
6244
+ this.left.bindAssignment( this.right );
5980
6245
  }
5981
6246
 
5982
6247
  hasEffects ( options ) {
@@ -5989,345 +6254,175 @@ class AssignmentExpression extends Node$1 {
5989
6254
  }
5990
6255
 
5991
6256
  class AssignmentPattern extends Node$1 {
5992
- hasEffectsWhenAssigned ( options ) {
5993
- return this.left.hasEffectsWhenAssigned( options );
5994
- }
5995
- }
5996
-
5997
- class AwaitExpression extends Node$1 {
5998
- hasEffects ( options ) {
5999
- return super.hasEffects( options )
6000
- || !options.inNestedFunctionCall;
6001
- }
6002
-
6003
- hasEffectsAsExpressionStatement ( options ) {
6004
- return this.hasEffects( options );
6005
- }
6006
- }
6007
-
6008
- const operators = {
6009
- '==': ( left, right ) => left == right,
6010
- '!=': ( left, right ) => left != right,
6011
- '===': ( left, right ) => left === right,
6012
- '!==': ( left, right ) => left !== right,
6013
- '<': ( left, right ) => left < right,
6014
- '<=': ( left, right ) => left <= right,
6015
- '>': ( left, right ) => left > right,
6016
- '>=': ( left, right ) => left >= right,
6017
- '<<': ( left, right ) => left << right,
6018
- '>>': ( left, right ) => left >> right,
6019
- '>>>': ( left, right ) => left >>> right,
6020
- '+': ( left, right ) => left + right,
6021
- '-': ( left, right ) => left - right,
6022
- '*': ( left, right ) => left * right,
6023
- '/': ( left, right ) => left / right,
6024
- '%': ( left, right ) => left % right,
6025
- '|': ( left, right ) => left | right,
6026
- '^': ( left, right ) => left ^ right,
6027
- '&': ( left, right ) => left & right,
6028
- '**': ( left, right ) => Math.pow( left, right ),
6029
- in: ( left, right ) => left in right,
6030
- instanceof: ( left, right ) => left instanceof right
6031
- };
6032
-
6033
- class BinaryExpression extends Node$1 {
6034
- getValue () {
6035
- const leftValue = this.left.getValue();
6036
- if ( leftValue === UNKNOWN_VALUE ) { return UNKNOWN_VALUE; }
6037
-
6038
- const rightValue = this.right.getValue();
6039
- if ( rightValue === UNKNOWN_VALUE ) { return UNKNOWN_VALUE; }
6040
-
6041
- if ( !operators[ this.operator ] ) { return UNKNOWN_VALUE; }
6042
-
6043
- return operators[ this.operator ]( leftValue, rightValue );
6044
- }
6045
- }
6046
-
6047
- class Statement extends Node$1 {
6048
- render ( code, es ) {
6049
- if ( !this.module.bundle.treeshake || this.included ) {
6050
- super.render( code, es );
6051
- } else {
6052
- code.remove( this.leadingCommentStart || this.start, this.next || this.end );
6053
- }
6054
- }
6055
- }
6056
-
6057
- class BlockStatement extends Statement {
6058
6257
  bind () {
6059
- this.body.forEach( node => node.bind() );
6060
- }
6061
-
6062
- includeInBundle () {
6063
- if ( this.isFullyIncluded() ) { return false; }
6064
- let addedNewNodes = false;
6065
- this.body.forEach( node => {
6066
- if ( node.shouldBeIncluded() ) {
6067
- if ( node.includeInBundle() ) {
6068
- addedNewNodes = true;
6069
- }
6070
- }
6071
- } );
6072
- if ( !this.included || addedNewNodes ) {
6073
- this.included = true;
6074
- return true;
6075
- }
6076
- return false;
6077
- }
6078
-
6079
- initialiseAndReplaceScope ( scope ) {
6080
- this.scope = scope;
6081
- this.initialiseNode();
6082
- this.initialiseChildren( scope );
6258
+ super.bind();
6259
+ this.left.bindAssignment( this.right );
6083
6260
  }
6084
6261
 
6085
- initialiseChildren () {
6086
- let lastNode;
6087
- for ( const node of this.body ) {
6088
- node.initialise( this.scope );
6089
-
6090
- if ( lastNode ) { lastNode.next = node.start; }
6091
- lastNode = node;
6092
- }
6262
+ bindAssignment ( expression ) {
6263
+ this.left.bindAssignment( expression );
6093
6264
  }
6094
6265
 
6095
- initialiseScope ( parentScope ) {
6096
- this.scope = new Scope( {
6097
- parent: parentScope,
6098
- isBlockScope: true,
6099
- isLexicalBoundary: false
6100
- } );
6266
+ hasEffectsWhenAssigned ( options ) {
6267
+ return this.left.hasEffectsWhenAssigned( options );
6101
6268
  }
6102
6269
 
6103
- render ( code, es ) {
6104
- if ( this.body.length ) {
6105
- for ( const node of this.body ) {
6106
- node.render( code, es );
6107
- }
6108
- } else {
6109
- Statement.prototype.render.call( this, code, es );
6110
- }
6270
+ initialiseAndDeclare ( parentScope, kind, init ) {
6271
+ this.initialiseScope( parentScope );
6272
+ this.right.initialise( parentScope );
6273
+ this.left.initialiseAndDeclare( parentScope, kind, init );
6111
6274
  }
6112
6275
  }
6113
6276
 
6114
- class BreakStatement extends Node$1 {
6277
+ class AwaitExpression extends Node$1 {
6115
6278
  hasEffects ( options ) {
6116
6279
  return super.hasEffects( options )
6117
- || !options.inNestedBreakableStatement;
6118
- }
6119
-
6120
- shouldBeIncluded () {
6121
- return true;
6122
- }
6123
- }
6124
-
6125
- function isReference (node, parent) {
6126
- if (node.type === 'MemberExpression') {
6127
- return !node.computed && isReference(node.object, node);
6128
- }
6129
-
6130
- if (node.type === 'Identifier') {
6131
- // the only time we could have an identifier node without a parent is
6132
- // if it's the entire body of a function without a block statement –
6133
- // i.e. an arrow function expression like `a => a`
6134
- if (!parent) return true;
6135
-
6136
- // TODO is this right?
6137
- if (parent.type === 'MemberExpression' || parent.type === 'MethodDefinition') {
6138
- return parent.computed || node === parent.object;
6139
- }
6140
-
6141
- // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
6142
- if (parent.type === 'Property') return parent.computed || node === parent.value;
6143
-
6144
- // disregard the `bar` in `class Foo { bar () {...} }`
6145
- if (parent.type === 'MethodDefinition') return false;
6146
-
6147
- // disregard the `bar` in `export { foo as bar }`
6148
- if (parent.type === 'ExportSpecifier' && node !== parent.local) return false;
6149
-
6150
- return true;
6151
- }
6152
-
6153
- return false;
6154
- }
6155
-
6156
- function flatten ( node ) {
6157
- const parts = [];
6158
- while ( node.type === 'MemberExpression' ) {
6159
- if ( node.computed ) { return null; }
6160
- parts.unshift( node.property.name );
6161
-
6162
- node = node.object;
6280
+ || !options.ignoreReturnAwaitYield();
6163
6281
  }
6164
6282
 
6165
- if ( node.type !== 'Identifier' ) { return null; }
6166
-
6167
- const name = node.name;
6168
- parts.unshift( name );
6169
-
6170
- return { name, keypath: parts.join( '.' ) };
6171
- }
6172
-
6173
- const pureFunctions = {};
6174
-
6175
- const arrayTypes = 'Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split( ' ' );
6176
- const simdTypes = 'Int8x16 Int16x8 Int32x4 Float32x4 Float64x2'.split( ' ' );
6177
- 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( ' ' );
6178
- const allSimdMethods = [];
6179
- simdTypes.forEach( t => {
6180
- simdMethods.forEach( m => {
6181
- allSimdMethods.push( `SIMD.${t}.${m}` );
6182
- });
6183
- });
6184
-
6185
- [
6186
- 'Array.isArray',
6187
- 'Error', 'EvalError', 'InternalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError',
6188
- 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape', 'unescape',
6189
- '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',
6190
- 'Function', 'Boolean',
6191
- 'Number', 'Number.isFinite', 'Number.isInteger', 'Number.isNaN', 'Number.isSafeInteger', 'Number.parseFloat', 'Number.parseInt',
6192
- 'Symbol', 'Symbol.for', 'Symbol.keyFor',
6193
- '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',
6194
- 'Date', 'Date.UTC', 'Date.now', 'Date.parse',
6195
- 'String', 'String.fromCharCode', 'String.fromCodePoint', 'String.raw',
6196
- 'RegExp',
6197
- 'Map', 'Set', 'WeakMap', 'WeakSet',
6198
- 'ArrayBuffer', 'ArrayBuffer.isView',
6199
- 'DataView',
6200
- 'JSON.parse', 'JSON.stringify',
6201
- 'Promise.all', 'Promise.race', 'Promise.resolve',
6202
- 'Intl.Collator', 'Intl.Collator.supportedLocalesOf', 'Intl.DateTimeFormat', 'Intl.DateTimeFormat.supportedLocalesOf', 'Intl.NumberFormat', 'Intl.NumberFormat.supportedLocalesOf'
6203
-
6204
- // TODO properties of e.g. window...
6205
- ].concat(
6206
- arrayTypes,
6207
- arrayTypes.map( t => `${t}.from` ),
6208
- arrayTypes.map( t => `${t}.of` ),
6209
- simdTypes.map( t => `SIMD.${t}` ),
6210
- allSimdMethods
6211
- ).forEach( name => pureFunctions[ name ] = true );
6212
-
6213
- const currentlyCalling = new Set();
6214
-
6215
- function isES5Function ( node ) {
6216
- return node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration';
6283
+ hasEffectsAsExpressionStatement ( options ) {
6284
+ return this.hasEffects( options );
6285
+ }
6217
6286
  }
6218
6287
 
6219
- function hasEffectsNew ( node ) {
6220
- let inner = node;
6221
-
6222
- if ( inner.type === 'ExpressionStatement' ) {
6223
- inner = inner.expression;
6288
+ const operators = {
6289
+ '==': ( left, right ) => left == right,
6290
+ '!=': ( left, right ) => left != right,
6291
+ '===': ( left, right ) => left === right,
6292
+ '!==': ( left, right ) => left !== right,
6293
+ '<': ( left, right ) => left < right,
6294
+ '<=': ( left, right ) => left <= right,
6295
+ '>': ( left, right ) => left > right,
6296
+ '>=': ( left, right ) => left >= right,
6297
+ '<<': ( left, right ) => left << right,
6298
+ '>>': ( left, right ) => left >> right,
6299
+ '>>>': ( left, right ) => left >>> right,
6300
+ '+': ( left, right ) => left + right,
6301
+ '-': ( left, right ) => left - right,
6302
+ '*': ( left, right ) => left * right,
6303
+ '/': ( left, right ) => left / right,
6304
+ '%': ( left, right ) => left % right,
6305
+ '|': ( left, right ) => left | right,
6306
+ '^': ( left, right ) => left ^ right,
6307
+ '&': ( left, right ) => left & right,
6308
+ '**': ( left, right ) => Math.pow( left, right ),
6309
+ in: ( left, right ) => left in right,
6310
+ instanceof: ( left, right ) => left instanceof right
6311
+ };
6224
6312
 
6225
- if ( inner.type === 'AssignmentExpression' ) {
6226
- if ( inner.right.hasEffects( { inNestedFunctionCall: true } ) ) {
6227
- return true;
6313
+ class BinaryExpression extends Node$1 {
6314
+ getValue () {
6315
+ const leftValue = this.left.getValue();
6316
+ if ( leftValue === UNKNOWN_VALUE ) { return UNKNOWN_VALUE; }
6228
6317
 
6229
- } else {
6230
- inner = inner.left;
6318
+ const rightValue = this.right.getValue();
6319
+ if ( rightValue === UNKNOWN_VALUE ) { return UNKNOWN_VALUE; }
6231
6320
 
6232
- if ( inner.type === 'MemberExpression' ) {
6233
- if ( inner.computed && inner.property.hasEffects( { inNestedFunctionCall: true } ) ) {
6234
- return true;
6321
+ if ( !operators[ this.operator ] ) { return UNKNOWN_VALUE; }
6235
6322
 
6236
- } else {
6237
- inner = inner.object;
6323
+ return operators[ this.operator ]( leftValue, rightValue );
6324
+ }
6325
+ }
6238
6326
 
6239
- if ( inner.type === 'ThisExpression' ) {
6240
- return false;
6241
- }
6242
- }
6243
- }
6244
- }
6327
+ class Statement extends Node$1 {
6328
+ render ( code, es ) {
6329
+ if ( !this.module.bundle.treeshake || this.included ) {
6330
+ super.render( code, es );
6331
+ } else {
6332
+ code.remove( this.leadingCommentStart || this.start, this.next || this.end );
6245
6333
  }
6246
6334
  }
6247
-
6248
- return node.hasEffects( { inNestedFunctionCall: true } );
6249
6335
  }
6250
6336
 
6251
- function fnHasEffects ( fn, isNew ) {
6252
- if ( currentlyCalling.has( fn ) ) { return false; } // prevent infinite loops... TODO there must be a better way
6253
- currentlyCalling.add( fn );
6254
-
6255
- // handle body-less arrow functions
6256
- const body = fn.body.type === 'BlockStatement' ? fn.body.body : [ fn.body ];
6257
-
6258
- for ( const node of body ) {
6259
- if ( isNew ? hasEffectsNew( node ) : node.hasEffects( { inNestedFunctionCall: true } ) ) {
6260
- currentlyCalling.delete( fn );
6261
- return true;
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 );
6262
6343
  }
6263
6344
  }
6264
-
6265
- currentlyCalling.delete( fn );
6266
- return false;
6267
6345
  }
6268
6346
 
6269
- function callHasEffects ( scope, callee, isNew ) {
6270
- const values = new Set( [ callee ] );
6271
-
6272
- for ( const node of values ) {
6273
- if ( node.type === 'UNKNOWN' ) { return true; } // err on side of caution
6347
+ class BlockStatement extends Statement {
6348
+ bind () {
6349
+ this.body.forEach( node => node.bind() );
6350
+ }
6274
6351
 
6275
- if ( /Function/.test( node.type ) ) {
6276
- if ( fnHasEffects( node, isNew && isES5Function( node ) ) ) { return true; }
6277
- }
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
+ }
6278
6356
 
6279
- else if ( /Class/.test( node.type ) ) {
6280
- // TODO find constructor (may belong to a superclass)
6357
+ includeInBundle () {
6358
+ if ( this.isFullyIncluded() ) { return false; }
6359
+ let addedNewNodes = false;
6360
+ this.body.forEach( node => {
6361
+ if ( node.shouldBeIncluded() ) {
6362
+ if ( node.includeInBundle() ) {
6363
+ addedNewNodes = true;
6364
+ }
6365
+ }
6366
+ } );
6367
+ if ( !this.included || addedNewNodes ) {
6368
+ this.included = true;
6281
6369
  return true;
6282
6370
  }
6371
+ return false;
6372
+ }
6283
6373
 
6284
- else if ( isReference( node ) ) {
6285
- const flattened = flatten( node );
6286
- const declaration = scope.findDeclaration( flattened.name );
6287
-
6288
- if ( declaration.isGlobal ) {
6289
- if ( !pureFunctions[ flattened.keypath ] ) { return true; }
6290
- }
6374
+ initialiseAndReplaceScope ( scope ) {
6375
+ this.scope = scope;
6376
+ this.initialiseNode();
6377
+ this.initialiseChildren( scope );
6378
+ }
6291
6379
 
6292
- else if ( declaration.isExternal ) {
6293
- return true; // TODO make this configurable? e.g. `path.[whatever]`
6294
- }
6380
+ initialiseChildren () {
6381
+ let lastNode;
6382
+ for ( const node of this.body ) {
6383
+ node.initialise( this.scope );
6295
6384
 
6296
- else {
6297
- if ( node.declaration ) {
6298
- node.declaration.gatherPossibleValues( values );
6299
- } else {
6300
- return true;
6301
- }
6302
- }
6385
+ if ( lastNode ) { lastNode.next = node.start; }
6386
+ lastNode = node;
6303
6387
  }
6388
+ }
6304
6389
 
6305
- else if ( node.gatherPossibleValues ) {
6306
- node.gatherPossibleValues( values );
6307
- }
6390
+ initialiseScope ( parentScope ) {
6391
+ this.scope = new BlockScope( { parent: parentScope } );
6392
+ }
6308
6393
 
6309
- else {
6310
- // probably an error in the user's code — err on side of caution
6311
- return true;
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 );
6312
6401
  }
6313
6402
  }
6403
+ }
6314
6404
 
6315
- 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
+ }
6316
6411
  }
6317
6412
 
6318
6413
  class CallExpression extends Node$1 {
6319
6414
  bind () {
6320
6415
  if ( this.callee.type === 'Identifier' ) {
6321
- const declaration = this.scope.findDeclaration( this.callee.name );
6416
+ const variable = this.scope.findVariable( this.callee.name );
6322
6417
 
6323
- if ( declaration.isNamespace ) {
6418
+ if ( variable.isNamespace ) {
6324
6419
  this.module.error( {
6325
6420
  code: 'CANNOT_CALL_NAMESPACE',
6326
6421
  message: `Cannot call a namespace ('${this.callee.name}')`
6327
6422
  }, this.start );
6328
6423
  }
6329
6424
 
6330
- if ( this.callee.name === 'eval' && declaration.isGlobal ) {
6425
+ if ( this.callee.name === 'eval' && variable.isGlobal ) {
6331
6426
  this.module.warn( {
6332
6427
  code: 'EVAL',
6333
6428
  message: `Use of eval is strongly discouraged, as it poses security risks and may cause issues with minification`,
@@ -6337,12 +6432,13 @@ class CallExpression extends Node$1 {
6337
6432
  }
6338
6433
 
6339
6434
  super.bind();
6435
+ this.callee.bindCall( { withNew: false } );
6340
6436
  }
6341
6437
 
6342
6438
  hasEffects ( options ) {
6343
6439
  return this.included
6344
6440
  || this.arguments.some( child => child.hasEffects( options ) )
6345
- || callHasEffects( this.scope, this.callee, false );
6441
+ || this.callee.hasEffectsWhenCalled( options.getHasEffectsWhenCalledOptions( this.callee ) );
6346
6442
  }
6347
6443
 
6348
6444
  hasEffectsAsExpressionStatement ( options ) {
@@ -6352,27 +6448,49 @@ class CallExpression extends Node$1 {
6352
6448
 
6353
6449
  class CatchClause extends Node$1 {
6354
6450
  initialiseChildren () {
6355
- if ( this.param ) {
6356
- this.param.initialise( this.scope );
6357
- extractNames( this.param ).forEach( name => this.scope.addDeclaration( name, null, false, true ) );
6358
- }
6451
+ this.param && this.param.initialiseAndDeclare( this.scope, 'parameter' );
6359
6452
  this.body.initialiseAndReplaceScope( this.scope );
6360
6453
  }
6361
6454
 
6362
6455
  initialiseScope ( parentScope ) {
6363
- this.scope = new Scope( {
6364
- parent: parentScope,
6365
- isBlockScope: true,
6366
- isLexicalBoundary: false
6367
- } );
6456
+ this.scope = new BlockScope( { parent: parentScope } );
6368
6457
  }
6369
6458
  }
6370
6459
 
6371
- class Class extends Node$1 {
6372
- addReference () {}
6460
+ class ClassBody extends Node$1 {
6461
+ bindCall ( callOptions ) {
6462
+ if ( this.classConstructor ) {
6463
+ this.classConstructor.bindCall( callOptions );
6464
+ }
6465
+ }
6373
6466
 
6374
- getName () {
6375
- 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 ) );
6376
6494
  }
6377
6495
 
6378
6496
  initialiseChildren () {
@@ -6383,28 +6501,14 @@ class Class extends Node$1 {
6383
6501
  }
6384
6502
 
6385
6503
  initialiseScope ( parentScope ) {
6386
- this.scope = new Scope( {
6387
- parent: parentScope,
6388
- isBlockScope: true
6389
- } );
6504
+ this.scope = new Scope( { parent: parentScope } );
6390
6505
  }
6391
6506
  }
6392
6507
 
6393
- class ClassDeclaration extends Class {
6394
- gatherPossibleValues ( values ) {
6395
- values.add( this );
6396
- }
6397
-
6398
- hasEffects () {
6399
- return this.included;
6400
- }
6401
-
6508
+ class ClassDeclaration extends ClassNode {
6402
6509
  initialiseChildren ( parentScope ) {
6403
- if ( this.id ) {
6404
- this.name = this.id.name;
6405
- parentScope.addDeclaration( this.name, this, false, false );
6406
- this.id.initialise( parentScope );
6407
- }
6510
+ // Class declarations are like let declarations: Not hoisted, can be reassigned, cannot be redeclared
6511
+ this.id && this.id.initialiseAndDeclare( parentScope, 'class', this );
6408
6512
  super.initialiseChildren( parentScope );
6409
6513
  }
6410
6514
 
@@ -6417,14 +6521,10 @@ class ClassDeclaration extends Class {
6417
6521
  }
6418
6522
  }
6419
6523
 
6420
- class ClassExpression extends Class {
6421
- initialiseChildren (parentScope) {
6422
- if ( this.id ) {
6423
- this.name = this.id.name;
6424
- this.scope.addDeclaration( this.name, this, false, false );
6425
- this.id.initialise( this.scope );
6426
- }
6427
- 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 );
6428
6528
  }
6429
6529
  }
6430
6530
 
@@ -6447,16 +6547,6 @@ class ConditionalExpression extends Node$1 {
6447
6547
  }
6448
6548
  }
6449
6549
 
6450
- gatherPossibleValues ( values ) {
6451
- const testValue = this.test.getValue();
6452
-
6453
- if ( testValue === UNKNOWN_VALUE ) {
6454
- values.add( this.consequent ).add( this.alternate );
6455
- } else {
6456
- values.add( testValue ? this.consequent : this.alternate );
6457
- }
6458
- }
6459
-
6460
6550
  getValue () {
6461
6551
  const testValue = this.test.getValue();
6462
6552
  if ( testValue === UNKNOWN_VALUE ) { return UNKNOWN_VALUE; }
@@ -6500,7 +6590,7 @@ class DoWhileStatement extends Statement {
6500
6590
  return (
6501
6591
  this.included
6502
6592
  || this.test.hasEffects( options )
6503
- || this.body.hasEffects( Object.assign( {}, options, { inNestedBreakableStatement: true } ) )
6593
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
6504
6594
  );
6505
6595
  }
6506
6596
  }
@@ -6526,6 +6616,10 @@ class ExportAllDeclaration extends Node$1 {
6526
6616
  const functionOrClassDeclaration = /^(?:Function|Class)Declaration/;
6527
6617
 
6528
6618
  class ExportDefaultDeclaration extends Node$1 {
6619
+ addCall ( options ) {
6620
+ this.declaration.bindCall( options );
6621
+ }
6622
+
6529
6623
  addReference ( reference ) {
6530
6624
  this.name = reference.name;
6531
6625
  if ( this.original ) { this.original.addReference( reference ); }
@@ -6533,15 +6627,11 @@ class ExportDefaultDeclaration extends Node$1 {
6533
6627
 
6534
6628
  bind () {
6535
6629
  const name = ( this.declaration.id && this.declaration.id.name ) || this.declaration.name;
6536
- if ( name ) { this.original = this.scope.findDeclaration( name ); }
6630
+ if ( name ) { this.original = this.scope.findVariable( name ); }
6537
6631
 
6538
6632
  this.declaration.bind();
6539
6633
  }
6540
6634
 
6541
- gatherPossibleValues ( values ) {
6542
- this.declaration.gatherPossibleValues( values );
6543
- }
6544
-
6545
6635
  getName ( es ) {
6546
6636
  if ( this.original && !this.original.isReassigned ) {
6547
6637
  return this.original.getName( es );
@@ -6550,7 +6640,11 @@ class ExportDefaultDeclaration extends Node$1 {
6550
6640
  return this.name;
6551
6641
  }
6552
6642
 
6553
- includeDeclaration () {
6643
+ hasEffectsWhenCalled ( options ) {
6644
+ return this.declaration.hasEffectsWhenCalled( options );
6645
+ }
6646
+
6647
+ includeVariable () {
6554
6648
  if ( this.included ) {
6555
6649
  return false;
6556
6650
  }
@@ -6571,7 +6665,7 @@ class ExportDefaultDeclaration extends Node$1 {
6571
6665
  this.isDefault = true;
6572
6666
 
6573
6667
  this.name = ( this.declaration.id && this.declaration.id.name ) || this.declaration.name || this.module.basename();
6574
- this.scope.declarations.default = this;
6668
+ this.scope.variables.default = this;
6575
6669
  }
6576
6670
 
6577
6671
  // TODO this is total chaos, tidy it up
@@ -6619,7 +6713,7 @@ class ExportDefaultDeclaration extends Node$1 {
6619
6713
  if ( functionOrClassDeclaration.test( this.declaration.type ) ) {
6620
6714
  code.remove( this.leadingCommentStart || this.start, this.next || this.end );
6621
6715
  } else {
6622
- const hasEffects = this.declaration.hasEffects( {} );
6716
+ const hasEffects = this.declaration.hasEffects( ExecutionPathOptions.create() );
6623
6717
  code.remove( this.start, hasEffects ? declaration_start : this.next || this.end );
6624
6718
  }
6625
6719
  } else if ( name === this.declaration.name ) {
@@ -6634,11 +6728,12 @@ class ExportDefaultDeclaration extends Node$1 {
6634
6728
 
6635
6729
  class ExportNamedDeclaration extends Node$1 {
6636
6730
  bind () {
6731
+ // Do not bind specifiers
6637
6732
  if ( this.declaration ) { this.declaration.bind(); }
6638
6733
  }
6639
6734
 
6640
- hasEffects () {
6641
- return this.included || (this.declaration && this.declaration.hasEffects());
6735
+ hasEffects ( options ) {
6736
+ return this.included || (this.declaration && this.declaration.hasEffects( options ));
6642
6737
  }
6643
6738
 
6644
6739
  initialiseNode () {
@@ -6686,7 +6781,7 @@ class ForStatement extends Statement {
6686
6781
  || this.init && this.init.hasEffects( options )
6687
6782
  || this.test && this.test.hasEffects( options )
6688
6783
  || this.update && this.update.hasEffects( options )
6689
- || this.body.hasEffects( Object.assign( {}, options, { inNestedBreakableStatement: true } ) )
6784
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
6690
6785
  );
6691
6786
  }
6692
6787
 
@@ -6704,11 +6799,7 @@ class ForStatement extends Statement {
6704
6799
  }
6705
6800
 
6706
6801
  initialiseScope ( parentScope ) {
6707
- this.scope = new Scope( {
6708
- parent: parentScope,
6709
- isBlockScope: true,
6710
- isLexicalBoundary: false
6711
- } );
6802
+ this.scope = new BlockScope( { parent: parentScope } );
6712
6803
  }
6713
6804
  }
6714
6805
 
@@ -6716,9 +6807,9 @@ class ForInStatement extends Statement {
6716
6807
  hasEffects ( options ) {
6717
6808
  return (
6718
6809
  this.included
6719
- || this.left && this.left.hasEffects( options )
6810
+ || this.left && (this.left.hasEffects( options ) || this.left.hasEffectsWhenAssigned( options ))
6720
6811
  || this.right && this.right.hasEffects( options )
6721
- || this.body.hasEffects( Object.assign( {}, options, { inNestedBreakableStatement: true } ) )
6812
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
6722
6813
  );
6723
6814
  }
6724
6815
 
@@ -6732,39 +6823,35 @@ class ForInStatement extends Statement {
6732
6823
 
6733
6824
  includeInBundle () {
6734
6825
  let addedNewNodes = super.includeInBundle();
6735
- if ( this.left.includeDeclaration() ) {
6826
+ if ( this.left.includeWithAllDeclarations() ) {
6736
6827
  addedNewNodes = true;
6737
6828
  }
6738
6829
  return addedNewNodes;
6739
6830
  }
6740
6831
 
6741
6832
  initialiseScope ( parentScope ) {
6742
- this.scope = new Scope( {
6743
- parent: parentScope,
6744
- isBlockScope: true,
6745
- isLexicalBoundary: false
6746
- } );
6833
+ this.scope = new BlockScope( { parent: parentScope } );
6747
6834
  }
6748
6835
  }
6749
6836
 
6750
6837
  class ForOfStatement extends Statement {
6751
6838
  bind () {
6752
6839
  super.bind();
6753
- this.left.assignExpression( UNKNOWN_ASSIGNMENT );
6840
+ this.left.bindAssignment( UNKNOWN_ASSIGNMENT );
6754
6841
  }
6755
6842
 
6756
6843
  hasEffects ( options ) {
6757
6844
  return (
6758
6845
  this.included
6759
- || this.left && this.left.hasEffects( options )
6846
+ || this.left && (this.left.hasEffects( options ) || this.left.hasEffectsWhenAssigned( options ))
6760
6847
  || this.right && this.right.hasEffects( options )
6761
- || this.body.hasEffects( Object.assign( {}, options, { inNestedBreakableStatement: true } ) )
6848
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
6762
6849
  );
6763
6850
  }
6764
6851
 
6765
6852
  includeInBundle () {
6766
6853
  let addedNewNodes = super.includeInBundle();
6767
- if ( this.left.includeDeclaration() ) {
6854
+ if ( this.left.includeWithAllDeclarations() ) {
6768
6855
  addedNewNodes = true;
6769
6856
  }
6770
6857
  return addedNewNodes;
@@ -6779,45 +6866,65 @@ class ForOfStatement extends Statement {
6779
6866
  }
6780
6867
 
6781
6868
  initialiseScope ( parentScope ) {
6782
- this.scope = new Scope( {
6783
- parent: parentScope,
6784
- isBlockScope: true,
6785
- isLexicalBoundary: false
6786
- } );
6869
+ this.scope = new BlockScope( { parent: parentScope } );
6787
6870
  }
6788
6871
  }
6789
6872
 
6790
- class FunctionDeclaration extends Function$1 {
6791
- addReference () {}
6873
+ class FunctionScope extends Scope {
6874
+ constructor ( options ) {
6875
+ if ( options === void 0 ) options = {};
6792
6876
 
6793
- assignExpression ( expression ) {
6794
- this.assignedExpressions.add( expression );
6795
- this.isReassigned = true;
6877
+ super( options );
6878
+ this.variables.arguments = new ParameterVariable( 'arguments' );
6879
+ this.variables.this = new LocalVariable( 'this', null, null );
6796
6880
  }
6797
6881
 
6798
- gatherPossibleValues ( values ) {
6799
- values.add( this );
6882
+ findLexicalBoundary () {
6883
+ return this;
6800
6884
  }
6885
+ }
6801
6886
 
6802
- getName () {
6803
- return this.name;
6804
- }
6887
+ class FunctionNode extends Node$1 {
6888
+ bindCall ( ref ) {
6889
+ var withNew = ref.withNew;
6805
6890
 
6806
- initialiseChildren ( parentScope ) {
6807
- if ( this.id ) {
6808
- this.name = this.id.name; // may be overridden by bundle.deconflict
6809
- parentScope.addDeclaration( this.name, this, false, false );
6810
- this.id.initialise( parentScope );
6891
+ const thisVariable = this.scope.findVariable( 'this' );
6892
+
6893
+ if ( withNew ) {
6894
+ thisVariable.assignExpression( UNKNOWN_OBJECT_LITERAL );
6895
+ } else {
6896
+ thisVariable.assignExpression( UNKNOWN_ASSIGNMENT );
6811
6897
  }
6812
- super.initialiseChildren( parentScope );
6898
+ }
6899
+
6900
+ hasEffects ( options ) {
6901
+ return this.included || (this.id && this.id.hasEffects( options ));
6902
+ }
6903
+
6904
+ hasEffectsAsExpressionStatement ( options ) {
6905
+ return this.hasEffects( options );
6906
+ }
6907
+
6908
+ hasEffectsWhenCalled ( options ) {
6909
+ const innerOptions = options.setIgnoreSafeThisMutations();
6910
+ return this.params.some( param => param.hasEffects( innerOptions ) )
6911
+ || this.body.hasEffects( innerOptions );
6813
6912
  }
6814
6913
 
6815
6914
  hasEffectsWhenMutated () {
6816
6915
  return this.included;
6817
6916
  }
6818
6917
 
6819
- initialiseNode () {
6820
- this.assignedExpressions = new Set( [ this ] );
6918
+ initialiseScope ( parentScope ) {
6919
+ this.scope = new FunctionScope( { parent: parentScope } );
6920
+ }
6921
+ }
6922
+
6923
+ class FunctionDeclaration extends FunctionNode {
6924
+ initialiseChildren ( parentScope ) {
6925
+ this.id && this.id.initialiseAndDeclare( parentScope, 'function', this );
6926
+ this.params.forEach( param => param.initialiseAndDeclare( this.scope, 'parameter' ) );
6927
+ this.body.initialiseAndReplaceScope( new Scope( { parent: this.scope } ) );
6821
6928
  }
6822
6929
 
6823
6930
  render ( code, es ) {
@@ -6829,21 +6936,43 @@ class FunctionDeclaration extends Function$1 {
6829
6936
  }
6830
6937
  }
6831
6938
 
6832
- class FunctionExpression extends Function$1 {
6833
- addReference () {}
6939
+ class FunctionExpression extends FunctionNode {
6940
+ initialiseChildren () {
6941
+ this.id && this.id.initialiseAndDeclare( this.scope, 'function', this );
6942
+ this.params.forEach( param => param.initialiseAndDeclare( this.scope, 'parameter' ) );
6943
+ this.body.initialiseAndReplaceScope( new Scope( { parent: this.scope } ) );
6944
+ }
6945
+ }
6834
6946
 
6835
- getName () {
6836
- return this.name;
6947
+ function isReference (node, parent) {
6948
+ if (node.type === 'MemberExpression') {
6949
+ return !node.computed && isReference(node.object, node);
6837
6950
  }
6838
6951
 
6839
- initialiseChildren ( parentScope ) {
6840
- if ( this.id ) {
6841
- this.name = this.id.name; // may be overridden by bundle.deconflict
6842
- this.scope.addDeclaration( this.name, this, false, false );
6843
- this.id.initialise( this.scope );
6952
+ if (node.type === 'Identifier') {
6953
+ // the only time we could have an identifier node without a parent is
6954
+ // if it's the entire body of a function without a block statement –
6955
+ // i.e. an arrow function expression like `a => a`
6956
+ if (!parent) return true;
6957
+
6958
+ // TODO is this right?
6959
+ if (parent.type === 'MemberExpression' || parent.type === 'MethodDefinition') {
6960
+ return parent.computed || node === parent.object;
6844
6961
  }
6845
- super.initialiseChildren( parentScope );
6962
+
6963
+ // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
6964
+ if (parent.type === 'Property') return parent.computed || node === parent.value;
6965
+
6966
+ // disregard the `bar` in `class Foo { bar () {...} }`
6967
+ if (parent.type === 'MethodDefinition') return false;
6968
+
6969
+ // disregard the `bar` in `export { foo as bar }`
6970
+ if (parent.type === 'ExportSpecifier' && node !== parent.local) return false;
6971
+
6972
+ return true;
6846
6973
  }
6974
+
6975
+ return false;
6847
6976
  }
6848
6977
 
6849
6978
  function isAssignmentPatternLhs ( node, parent ) {
@@ -6862,54 +6991,74 @@ function isAssignmentPatternLhs ( node, parent ) {
6862
6991
  }
6863
6992
 
6864
6993
  class Identifier extends Node$1 {
6865
- assignExpression ( expression ) {
6866
- if ( this.declaration ) {
6867
- this.declaration.assignExpression( expression );
6994
+ bind () {
6995
+ if ( isReference( this, this.parent ) || isAssignmentPatternLhs( this, this.parent ) ) {
6996
+ this.variable = this.scope.findVariable( this.name );
6997
+ this.variable.addReference( this );
6868
6998
  }
6869
6999
  }
6870
7000
 
6871
- bind () {
6872
- if ( isReference( this, this.parent ) || isAssignmentPatternLhs( this, this.parent ) ) {
6873
- this.declaration = this.scope.findDeclaration( this.name );
6874
- this.declaration.addReference( this ); // TODO necessary?
7001
+ bindAssignment ( expression ) {
7002
+ if ( this.variable ) {
7003
+ this.variable.assignExpression( expression );
6875
7004
  }
6876
7005
  }
6877
7006
 
6878
- gatherPossibleValues ( values ) {
6879
- if ( isReference( this, this.parent ) ) {
6880
- values.add( this );
7007
+ bindCall ( callOptions ) {
7008
+ if ( this.variable ) {
7009
+ this.variable.addCall( callOptions );
6881
7010
  }
6882
7011
  }
6883
7012
 
6884
7013
  hasEffectsAsExpressionStatement ( options ) {
6885
- return this.hasEffects( options ) || this.declaration.isGlobal;
7014
+ return this.hasEffects( options ) || this.variable.isGlobal;
6886
7015
  }
6887
7016
 
6888
7017
  hasEffectsWhenAssigned () {
6889
- return this.declaration && this.declaration.included;
7018
+ return this.variable && this.variable.included;
7019
+ }
7020
+
7021
+ hasEffectsWhenCalled ( options ) {
7022
+ if ( !this.variable ) {
7023
+ return true;
7024
+ }
7025
+ return this.variable.hasEffectsWhenCalled( options );
6890
7026
  }
6891
7027
 
6892
7028
  hasEffectsWhenMutated ( options ) {
6893
- return this.declaration &&
6894
- (this.declaration.included ||
6895
- this.declaration.isParam ||
6896
- this.declaration.isGlobal ||
6897
- this.declaration.isExternal ||
6898
- this.declaration.isNamespace ||
6899
- !this.declaration.assignedExpressions ||
6900
- Array.from( this.declaration.assignedExpressions ).some( node => node.hasEffectsWhenMutated( options ) ));
7029
+ return this.variable && this.variable.hasEffectsWhenMutated( options );
6901
7030
  }
6902
7031
 
6903
7032
  includeInBundle () {
6904
7033
  if ( this.included ) { return false; }
6905
7034
  this.included = true;
6906
- this.declaration && this.declaration.includeDeclaration();
7035
+ this.variable && this.variable.includeVariable();
6907
7036
  return true;
6908
7037
  }
6909
7038
 
7039
+ initialiseAndDeclare ( parentScope, kind, init ) {
7040
+ this.initialiseScope( parentScope );
7041
+ switch ( kind ) {
7042
+ case 'var':
7043
+ case 'function':
7044
+ this.scope.addDeclaration( this, true, init );
7045
+ break;
7046
+ case 'let':
7047
+ case 'const':
7048
+ case 'class':
7049
+ this.scope.addDeclaration( this, false, init );
7050
+ break;
7051
+ case 'parameter':
7052
+ this.scope.addParameterDeclaration( this );
7053
+ break;
7054
+ default:
7055
+ throw new Error( 'Unexpected identifier kind', kind );
7056
+ }
7057
+ }
7058
+
6910
7059
  render ( code, es ) {
6911
- if ( this.declaration ) {
6912
- const name = this.declaration.getName( es );
7060
+ if ( this.variable ) {
7061
+ const name = this.variable.getName( es );
6913
7062
  if ( name !== this.name ) {
6914
7063
  code.overwrite( this.start, this.end, name, { storeName: true, contentOnly: false } );
6915
7064
 
@@ -6932,7 +7081,7 @@ const statementsWithIfStatements = new Set( [
6932
7081
  'WhileStatement'
6933
7082
  ] );
6934
7083
 
6935
- function handleVarDeclarations ( node, scope ) {
7084
+ function getHoistedVars ( node, scope ) {
6936
7085
  const hoistedVars = [];
6937
7086
 
6938
7087
  function visit ( node ) {
@@ -6942,7 +7091,7 @@ function handleVarDeclarations ( node, scope ) {
6942
7091
  declarator.initialise( scope );
6943
7092
 
6944
7093
  extractNames( declarator.id ).forEach( name => {
6945
- if ( !~hoistedVars.indexOf( name ) ) { hoistedVars.push( name ); }
7094
+ if ( hoistedVars.indexOf( name ) < 0 ) { hoistedVars.push( name ); }
6946
7095
  } );
6947
7096
  } );
6948
7097
  }
@@ -6957,29 +7106,24 @@ function handleVarDeclarations ( node, scope ) {
6957
7106
  return hoistedVars;
6958
7107
  }
6959
7108
 
6960
- // TODO DRY this out
6961
7109
  class IfStatement extends Statement {
6962
7110
  initialiseChildren ( parentScope ) {
7111
+ super.initialiseChildren( parentScope );
6963
7112
  if ( this.module.bundle.treeshake ) {
6964
7113
  this.testValue = this.test.getValue();
6965
7114
 
6966
7115
  if ( this.testValue === UNKNOWN_VALUE ) {
6967
- super.initialiseChildren( parentScope );
6968
- } else if ( this.testValue ) {
6969
- this.consequent.initialise( this.scope );
7116
+ return;
7117
+ }
7118
+ if ( this.testValue ) {
6970
7119
  if ( this.alternate ) {
6971
- this.hoistedVars = handleVarDeclarations( this.alternate, this.scope );
7120
+ this.hoistedVars = getHoistedVars( this.alternate, this.scope );
6972
7121
  this.alternate = null;
6973
7122
  }
6974
7123
  } else {
6975
- if ( this.alternate ) {
6976
- this.alternate.initialise( this.scope );
6977
- }
6978
- this.hoistedVars = handleVarDeclarations( this.consequent, this.scope );
7124
+ this.hoistedVars = getHoistedVars( this.consequent, this.scope );
6979
7125
  this.consequent = null;
6980
7126
  }
6981
- } else {
6982
- super.initialiseChildren( parentScope );
6983
7127
  }
6984
7128
  }
6985
7129
 
@@ -6998,8 +7142,8 @@ class IfStatement extends Statement {
6998
7142
  if ( this.hoistedVars ) {
6999
7143
  const names = this.hoistedVars
7000
7144
  .map( name => {
7001
- const declaration = this.scope.findDeclaration( name );
7002
- return declaration.included ? declaration.getName() : null;
7145
+ const variable = this.scope.findVariable( name );
7146
+ return variable.included ? variable.getName() : null;
7003
7147
  } )
7004
7148
  .filter( Boolean );
7005
7149
 
@@ -7049,15 +7193,21 @@ class ImportDeclaration extends Node$1 {
7049
7193
  }
7050
7194
  }
7051
7195
 
7196
+ class LabeledStatement extends Statement {
7197
+ hasEffects ( options ) {
7198
+ return this.body.hasEffects(
7199
+ options
7200
+ .setIgnoreLabel( this.label.name )
7201
+ .setIgnoreBreakStatements()
7202
+ );
7203
+ }
7204
+ }
7205
+
7052
7206
  class Literal extends Node$1 {
7053
7207
  getValue () {
7054
7208
  return this.value;
7055
7209
  }
7056
7210
 
7057
- gatherPossibleValues ( values ) {
7058
- values.add( this );
7059
- }
7060
-
7061
7211
  hasEffectsWhenMutated () {
7062
7212
  return false;
7063
7213
  }
@@ -7097,6 +7247,63 @@ class LogicalExpression extends Node$1 {
7097
7247
  }
7098
7248
  }
7099
7249
 
7250
+ function flatten ( node ) {
7251
+ const parts = [];
7252
+ while ( node.type === 'MemberExpression' ) {
7253
+ if ( node.computed ) { return null; }
7254
+ parts.unshift( node.property.name );
7255
+
7256
+ node = node.object;
7257
+ }
7258
+
7259
+ if ( node.type !== 'Identifier' ) { return null; }
7260
+
7261
+ const name = node.name;
7262
+ parts.unshift( name );
7263
+
7264
+ return { name, keypath: parts.join( '.' ) };
7265
+ }
7266
+
7267
+ const pureFunctions = {};
7268
+
7269
+ const arrayTypes = 'Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array'.split( ' ' );
7270
+ const simdTypes = 'Int8x16 Int16x8 Int32x4 Float32x4 Float64x2'.split( ' ' );
7271
+ 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( ' ' );
7272
+ const allSimdMethods = [];
7273
+ simdTypes.forEach( t => {
7274
+ simdMethods.forEach( m => {
7275
+ allSimdMethods.push( `SIMD.${t}.${m}` );
7276
+ });
7277
+ });
7278
+
7279
+ [
7280
+ 'Array.isArray',
7281
+ 'Error', 'EvalError', 'InternalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError',
7282
+ 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape', 'unescape',
7283
+ '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',
7284
+ 'Function', 'Boolean',
7285
+ 'Number', 'Number.isFinite', 'Number.isInteger', 'Number.isNaN', 'Number.isSafeInteger', 'Number.parseFloat', 'Number.parseInt',
7286
+ 'Symbol', 'Symbol.for', 'Symbol.keyFor',
7287
+ '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',
7288
+ 'Date', 'Date.UTC', 'Date.now', 'Date.parse',
7289
+ 'String', 'String.fromCharCode', 'String.fromCodePoint', 'String.raw',
7290
+ 'RegExp',
7291
+ 'Map', 'Set', 'WeakMap', 'WeakSet',
7292
+ 'ArrayBuffer', 'ArrayBuffer.isView',
7293
+ 'DataView',
7294
+ 'JSON.parse', 'JSON.stringify',
7295
+ 'Promise.all', 'Promise.race', 'Promise.resolve',
7296
+ 'Intl.Collator', 'Intl.Collator.supportedLocalesOf', 'Intl.DateTimeFormat', 'Intl.DateTimeFormat.supportedLocalesOf', 'Intl.NumberFormat', 'Intl.NumberFormat.supportedLocalesOf'
7297
+
7298
+ // TODO properties of e.g. window...
7299
+ ].concat(
7300
+ arrayTypes,
7301
+ arrayTypes.map( t => `${t}.from` ),
7302
+ arrayTypes.map( t => `${t}.of` ),
7303
+ simdTypes.map( t => `SIMD.${t}` ),
7304
+ allSimdMethods
7305
+ ).forEach( name => pureFunctions[ name ] = true );
7306
+
7100
7307
  const validProp = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
7101
7308
 
7102
7309
  class Keypath {
@@ -7129,15 +7336,15 @@ class MemberExpression extends Node$1 {
7129
7336
  const keypath = new Keypath( this );
7130
7337
 
7131
7338
  if ( !keypath.computed && keypath.root.type === 'Identifier' ) {
7132
- let declaration = this.scope.findDeclaration( keypath.root.name );
7339
+ let variable = this.scope.findVariable( keypath.root.name );
7133
7340
 
7134
- while ( declaration.isNamespace && keypath.parts.length ) {
7135
- const exporterId = declaration.module.id;
7341
+ while ( variable.isNamespace && keypath.parts.length ) {
7342
+ const exporterId = variable.module.id;
7136
7343
 
7137
7344
  const part = keypath.parts[ 0 ];
7138
- declaration = declaration.module.traceExport( part.name || part.value );
7345
+ variable = variable.module.traceExport( part.name || part.value );
7139
7346
 
7140
- if ( !declaration ) {
7347
+ if ( !variable ) {
7141
7348
  this.module.warn( {
7142
7349
  code: 'MISSING_EXPORT',
7143
7350
  missing: part.name || part.value,
@@ -7158,10 +7365,10 @@ class MemberExpression extends Node$1 {
7158
7365
  return; // not a namespaced declaration
7159
7366
  }
7160
7367
 
7161
- this.declaration = declaration;
7368
+ this.variable = variable;
7162
7369
 
7163
- if ( declaration.isExternal ) {
7164
- declaration.module.suggestName( keypath.root.name );
7370
+ if ( variable.isExternal ) {
7371
+ variable.module.suggestName( keypath.root.name );
7165
7372
  }
7166
7373
  }
7167
7374
 
@@ -7170,8 +7377,10 @@ class MemberExpression extends Node$1 {
7170
7377
  }
7171
7378
  }
7172
7379
 
7173
- gatherPossibleValues ( values ) {
7174
- values.add( UNKNOWN_ASSIGNMENT ); // TODO
7380
+ bindCall ( callOptions ) {
7381
+ if ( this.variable ) {
7382
+ this.variable.addCall( callOptions );
7383
+ }
7175
7384
  }
7176
7385
 
7177
7386
  hasEffectsWhenAssigned ( options ) {
@@ -7180,16 +7389,27 @@ class MemberExpression extends Node$1 {
7180
7389
 
7181
7390
  includeInBundle () {
7182
7391
  let addedNewNodes = super.includeInBundle();
7183
- if ( this.declaration && !this.declaration.included ) {
7184
- this.declaration.includeDeclaration();
7392
+ if ( this.variable && !this.variable.included ) {
7393
+ this.variable.includeVariable();
7185
7394
  addedNewNodes = true;
7186
7395
  }
7187
7396
  return addedNewNodes;
7188
7397
  }
7189
7398
 
7399
+ hasEffectsWhenCalled ( options ) {
7400
+ if ( this.variable ) {
7401
+ return this.variable.hasEffectsWhenCalled( options );
7402
+ }
7403
+ if ( !isReference( this ) ) {
7404
+ return true;
7405
+ }
7406
+ const flattenedNode = flatten( this );
7407
+ return !(this.scope.findVariable( flattenedNode.name ).isGlobal && pureFunctions[ flattenedNode.keypath ]);
7408
+ }
7409
+
7190
7410
  render ( code, es ) {
7191
- if ( this.declaration ) {
7192
- const name = this.declaration.getName( es );
7411
+ if ( this.variable ) {
7412
+ const name = this.variable.getName( es );
7193
7413
  if ( name !== this.name ) { code.overwrite( this.start, this.end, name, { storeName: true, contentOnly: false } ); }
7194
7414
  }
7195
7415
 
@@ -7201,9 +7421,30 @@ class MemberExpression extends Node$1 {
7201
7421
  }
7202
7422
  }
7203
7423
 
7424
+ class MethodDefinition extends Node$1 {
7425
+ bindCall ( callOptions ) {
7426
+ this.value.bindCall( callOptions );
7427
+ }
7428
+
7429
+ hasEffects ( options ) {
7430
+ return this.key.hasEffects( options );
7431
+ }
7432
+
7433
+ hasEffectsWhenCalled ( options ) {
7434
+ return this.value.hasEffectsWhenCalled( options );
7435
+ }
7436
+ }
7437
+
7204
7438
  class NewExpression extends Node$1 {
7205
- hasEffects () {
7206
- return this.included || callHasEffects( this.scope, this.callee, true );
7439
+ bind () {
7440
+ super.bind();
7441
+ this.callee.bindCall( { withNew: true } );
7442
+ }
7443
+
7444
+ hasEffects ( options ) {
7445
+ return this.included
7446
+ || this.arguments.some( child => child.hasEffects( options ) )
7447
+ || this.callee.hasEffectsWhenCalled( options.getHasEffectsWhenCalledOptions( this.callee ) );
7207
7448
  }
7208
7449
  }
7209
7450
 
@@ -7214,24 +7455,35 @@ class ObjectExpression extends Node$1 {
7214
7455
  }
7215
7456
 
7216
7457
  class ObjectPattern extends Node$1 {
7217
- assignExpression () {
7218
- this.eachChild( child => child.assignExpression( UNKNOWN_ASSIGNMENT ) );
7458
+ bindAssignment ( expression ) {
7459
+ this.properties.forEach( child => child.bindAssignment( expression ) );
7219
7460
  }
7220
7461
 
7221
7462
  hasEffectsWhenAssigned ( options ) {
7222
7463
  return this.someChild( child => child.hasEffectsWhenAssigned( options ) );
7223
7464
  }
7465
+
7466
+ initialiseAndDeclare ( parentScope, kind, init ) {
7467
+ this.initialiseScope( parentScope );
7468
+ this.properties.forEach( child => child.initialiseAndDeclare( parentScope, kind, init ) );
7469
+ }
7224
7470
  }
7225
7471
 
7226
7472
  class Property extends Node$1 {
7227
- assignExpression ( expression ) {
7228
- this.value.assignExpression( expression );
7473
+ bindAssignment () {
7474
+ this.value.bindAssignment( UNKNOWN_ASSIGNMENT );
7229
7475
  }
7230
7476
 
7231
7477
  hasEffectsWhenAssigned ( options ) {
7232
7478
  return this.value.hasEffectsWhenAssigned( options );
7233
7479
  }
7234
7480
 
7481
+ initialiseAndDeclare ( parentScope, kind, init ) {
7482
+ this.initialiseScope( parentScope );
7483
+ this.key.initialise( parentScope );
7484
+ this.value.initialiseAndDeclare( parentScope, kind, init && UNKNOWN_ASSIGNMENT );
7485
+ }
7486
+
7235
7487
  render ( code, es ) {
7236
7488
  if ( !this.shorthand ) {
7237
7489
  this.key.render( code, es );
@@ -7241,23 +7493,24 @@ class Property extends Node$1 {
7241
7493
  }
7242
7494
 
7243
7495
  class RestElement extends Node$1 {
7244
- assignExpression () {
7245
- this.argument.assignExpression( UNKNOWN_ASSIGNMENT );
7496
+ bindAssignment () {
7497
+ this.argument.bindAssignment( UNKNOWN_ASSIGNMENT );
7246
7498
  }
7247
7499
 
7248
7500
  hasEffectsWhenAssigned ( options ) {
7249
7501
  return this.argument.hasEffectsWhenAssigned( options );
7250
7502
  }
7503
+
7504
+ initialiseAndDeclare ( parentScope, kind ) {
7505
+ this.initialiseScope( parentScope );
7506
+ this.argument.initialiseAndDeclare( parentScope, kind, UNKNOWN_ASSIGNMENT );
7507
+ }
7251
7508
  }
7252
7509
 
7253
7510
  class ReturnStatement extends Statement {
7254
7511
  hasEffects ( options ) {
7255
7512
  return super.hasEffects( options )
7256
- || !options.inNestedFunctionCall;
7257
- }
7258
-
7259
- shouldBeIncluded () {
7260
- return true;
7513
+ || !options.ignoreReturnAwaitYield();
7261
7514
  }
7262
7515
  }
7263
7516
 
@@ -7284,32 +7537,28 @@ class SwitchCase extends Node$1 {
7284
7537
  }
7285
7538
 
7286
7539
  class SwitchStatement extends Statement {
7287
- hasEffects(options) {
7288
- return super.hasEffects(Object.assign({}, options, {inNestedBreakableStatement: true}));
7540
+ hasEffects ( options ) {
7541
+ return super.hasEffects( options.setIgnoreBreakStatements() );
7289
7542
  }
7290
7543
 
7291
7544
  initialiseScope ( parentScope ) {
7292
- this.scope = new Scope( {
7293
- parent: parentScope,
7294
- isBlockScope: true,
7295
- isLexicalBoundary: false
7296
- } );
7545
+ this.scope = new BlockScope( { parent: parentScope } );
7297
7546
  }
7298
7547
  }
7299
7548
 
7300
7549
  class TaggedTemplateExpression extends Node$1 {
7301
7550
  bind () {
7302
7551
  if ( this.tag.type === 'Identifier' ) {
7303
- const declaration = this.scope.findDeclaration( this.tag.name );
7552
+ const variable = this.scope.findVariable( this.tag.name );
7304
7553
 
7305
- if ( declaration.isNamespace ) {
7554
+ if ( variable.isNamespace ) {
7306
7555
  this.module.error( {
7307
7556
  code: 'CANNOT_CALL_NAMESPACE',
7308
7557
  message: `Cannot call a namespace ('${this.tag.name}')`
7309
7558
  }, this.start );
7310
7559
  }
7311
7560
 
7312
- if ( this.tag.name === 'eval' && declaration.isGlobal ) {
7561
+ if ( this.tag.name === 'eval' && variable.isGlobal ) {
7313
7562
  this.module.warn( {
7314
7563
  code: 'EVAL',
7315
7564
  message: `Use of eval is strongly discouraged, as it poses security risks and may cause issues with minification`,
@@ -7319,10 +7568,12 @@ class TaggedTemplateExpression extends Node$1 {
7319
7568
  }
7320
7569
 
7321
7570
  super.bind();
7571
+ this.tag.bindCall( { withNew: false } );
7322
7572
  }
7323
7573
 
7324
7574
  hasEffects ( options ) {
7325
- return this.quasi.hasEffects( options ) || callHasEffects( this.scope, this.tag, false );
7575
+ return super.hasEffects( options )
7576
+ || this.tag.hasEffectsWhenCalled( options.getHasEffectsWhenCalledOptions( this.tag ) );
7326
7577
  }
7327
7578
  }
7328
7579
 
@@ -7355,6 +7606,14 @@ class ThisExpression extends Node$1 {
7355
7606
  }
7356
7607
  }
7357
7608
 
7609
+ bind () {
7610
+ this.variable = this.scope.findVariable( 'this' );
7611
+ }
7612
+
7613
+ hasEffectsWhenMutated ( options ) {
7614
+ return !options.ignoreSafeThisMutations() || this.variable.hasEffectsWhenMutated( options );
7615
+ }
7616
+
7358
7617
  render ( code ) {
7359
7618
  if ( this.alias ) {
7360
7619
  code.overwrite( this.start, this.end, this.alias, { storeName: true, contentOnly: false } );
@@ -7412,8 +7671,8 @@ class UpdateExpression extends Node$1 {
7412
7671
  bind () {
7413
7672
  disallowIllegalReassignment( this.scope, this.argument );
7414
7673
  if ( this.argument.type === 'Identifier' ) {
7415
- const declaration = this.scope.findDeclaration( this.argument.name );
7416
- declaration.isReassigned = true;
7674
+ const variable = this.scope.findVariable( this.argument.name );
7675
+ variable.isReassigned = true;
7417
7676
  }
7418
7677
  super.bind();
7419
7678
  }
@@ -7427,88 +7686,25 @@ class UpdateExpression extends Node$1 {
7427
7686
  }
7428
7687
  }
7429
7688
 
7430
- class DeclaratorProxy {
7431
- constructor ( name, declarator, isTopLevel, init ) {
7432
- this.name = name;
7433
- this.declarator = declarator;
7434
-
7435
- this.isReassigned = false;
7436
- this.exportName = null;
7437
-
7438
- this.duplicates = [];
7439
- this.assignedExpressions = new Set( init ? [ init ] : null );
7440
- }
7441
-
7442
- addReference () {
7443
- /* noop? */
7444
- }
7445
-
7446
- assignExpression ( expression ) {
7447
- this.assignedExpressions.add( expression );
7448
- this.isReassigned = true;
7449
- }
7450
-
7451
- gatherPossibleValues ( values ) {
7452
- this.assignedExpressions.forEach( value => values.add( value ) );
7453
- }
7454
-
7455
- getName ( es ) {
7456
- // TODO destructuring...
7457
- if ( es ) { return this.name; }
7458
- if ( !this.isReassigned || !this.exportName ) { return this.name; }
7459
-
7460
- return `exports.${this.exportName}`;
7461
- }
7462
-
7463
- includeDeclaration () {
7464
- if ( this.included ) {
7465
- return false;
7466
- }
7467
- this.included = true;
7468
- this.declarator.includeDeclaration();
7469
- this.duplicates.forEach( duplicate => duplicate.includeDeclaration() );
7470
- return true;
7471
- }
7472
-
7473
- toString () {
7474
- return this.name;
7475
- }
7476
- }
7477
-
7478
7689
  class VariableDeclarator extends Node$1 {
7479
- assignExpression () {
7480
- for ( const proxy of this.proxies.values() ) {
7481
- proxy.assignExpression( UNKNOWN_ASSIGNMENT );
7482
- }
7690
+ bindAssignment ( expression ) {
7691
+ this.id.bindAssignment( expression );
7483
7692
  }
7484
7693
 
7485
- hasEffects ( options ) {
7486
- return super.hasEffects( options )
7487
- || extractNames( this.id ).some( name => this.proxies.get( name ).included );
7488
- }
7489
-
7490
- initialiseNode () {
7491
- this.proxies = new Map();
7492
- const lexicalBoundary = this.scope.findLexicalBoundary();
7493
- const init = this.init
7494
- ? ( this.id.type === 'Identifier' ? this.init : UNKNOWN_ASSIGNMENT )
7495
- : null;
7496
-
7497
- extractNames( this.id ).forEach( name => {
7498
- const proxy = new DeclaratorProxy( name, this, lexicalBoundary.isModuleScope, init );
7499
-
7500
- this.proxies.set( name, proxy );
7501
- this.scope.addDeclaration( name, proxy, this.parent.kind === 'var' );
7502
- } );
7694
+ initialiseDeclarator ( parentScope, kind ) {
7695
+ this.initialiseScope( parentScope );
7696
+ this.init && this.init.initialise( this.scope );
7697
+ this.id.initialiseAndDeclare( this.scope, kind, this.init );
7503
7698
  }
7504
7699
 
7700
+ // TODO Deleting this does not break any tests. Find meaningful test or delete.
7505
7701
  render ( code, es ) {
7506
7702
  extractNames( this.id ).forEach( name => {
7507
- const declaration = this.proxies.get( name );
7703
+ const variable = this.scope.findVariable( name );
7508
7704
 
7509
- if ( !es && declaration.exportName && declaration.isReassigned ) {
7705
+ if ( !es && variable.exportName && variable.isReassigned ) {
7510
7706
  if ( this.init ) {
7511
- code.overwrite( this.start, this.id.end, declaration.getName( es ) );
7707
+ code.overwrite( this.start, this.id.end, variable.getName( es ) );
7512
7708
  } else if ( this.module.bundle.treeshake ) {
7513
7709
  code.remove( this.start, this.end );
7514
7710
  }
@@ -7535,15 +7731,19 @@ function getSeparator ( code, start ) {
7535
7731
  const forStatement = /^For(?:Of|In)?Statement/;
7536
7732
 
7537
7733
  class VariableDeclaration extends Node$1 {
7538
- assignExpression () {
7539
- this.eachChild( child => child.assignExpression( UNKNOWN_ASSIGNMENT ) );
7734
+ bindAssignment () {
7735
+ this.eachChild( child => child.bindAssignment( UNKNOWN_ASSIGNMENT ) );
7540
7736
  }
7541
7737
 
7542
- includeDeclaration () {
7738
+ hasEffectsWhenAssigned () {
7739
+ return false;
7740
+ }
7741
+
7742
+ includeWithAllDeclarations () {
7543
7743
  if ( this.isFullyIncluded() ) { return false; }
7544
7744
  let addedNewNodes = false;
7545
7745
  this.declarations.forEach( declarator => {
7546
- if ( declarator.includeDeclaration() ) {
7746
+ if ( declarator.includeInBundle() ) {
7547
7747
  addedNewNodes = true;
7548
7748
  }
7549
7749
  } );
@@ -7571,6 +7771,10 @@ class VariableDeclaration extends Node$1 {
7571
7771
  return false;
7572
7772
  }
7573
7773
 
7774
+ initialiseChildren () {
7775
+ this.declarations.forEach( child => child.initialiseDeclarator( this.scope, this.kind ) );
7776
+ }
7777
+
7574
7778
  render ( code, es ) {
7575
7779
  const treeshake = this.module.bundle.treeshake;
7576
7780
 
@@ -7591,8 +7795,8 @@ class VariableDeclaration extends Node$1 {
7591
7795
  const prefix = empty ? '' : separator; // TODO indentation
7592
7796
 
7593
7797
  if ( declarator.id.type === 'Identifier' ) {
7594
- const proxy = declarator.proxies.get( declarator.id.name );
7595
- const isExportedAndReassigned = !es && proxy.exportName && proxy.isReassigned;
7798
+ const variable = this.scope.findVariable( declarator.id.name );
7799
+ const isExportedAndReassigned = !es && variable.exportName && variable.isReassigned;
7596
7800
 
7597
7801
  if ( isExportedAndReassigned ) {
7598
7802
  if ( declarator.init ) {
@@ -7600,7 +7804,7 @@ class VariableDeclaration extends Node$1 {
7600
7804
  c = declarator.end;
7601
7805
  empty = false;
7602
7806
  }
7603
- } else if ( !treeshake || proxy.included ) {
7807
+ } else if ( !treeshake || variable.included ) {
7604
7808
  if ( shouldSeparate ) { code.overwrite( c, declarator.start, `${prefix}${this.kind} ` ); } // TODO indentation
7605
7809
  c = declarator.end;
7606
7810
  empty = false;
@@ -7610,8 +7814,8 @@ class VariableDeclaration extends Node$1 {
7610
7814
  let isIncluded = false;
7611
7815
 
7612
7816
  extractNames( declarator.id ).forEach( name => {
7613
- const proxy = declarator.proxies.get( name );
7614
- const isExportedAndReassigned = !es && proxy.exportName && proxy.isReassigned;
7817
+ const variable = this.scope.findVariable( name );
7818
+ const isExportedAndReassigned = !es && variable.exportName && variable.isReassigned;
7615
7819
 
7616
7820
  if ( isExportedAndReassigned ) {
7617
7821
  // code.overwrite( c, declarator.start, prefix );
@@ -7658,11 +7862,22 @@ class WhileStatement extends Statement {
7658
7862
  return (
7659
7863
  this.included
7660
7864
  || this.test.hasEffects( options )
7661
- || this.body.hasEffects( Object.assign( {}, options, { inNestedBreakableStatement: true } ) )
7865
+ || this.body.hasEffects( options.setIgnoreBreakStatements() )
7662
7866
  );
7663
7867
  }
7664
7868
  }
7665
7869
 
7870
+ class YieldExpression extends Node$1 {
7871
+ hasEffects ( options ) {
7872
+ return super.hasEffects( options )
7873
+ || !options.ignoreReturnAwaitYield();
7874
+ }
7875
+
7876
+ hasEffectsAsExpressionStatement ( options ) {
7877
+ return this.hasEffects( options );
7878
+ }
7879
+ }
7880
+
7666
7881
  var nodes = {
7667
7882
  ArrayExpression: Node$1,
7668
7883
  ArrayPattern,
@@ -7675,6 +7890,7 @@ var nodes = {
7675
7890
  BreakStatement,
7676
7891
  CallExpression,
7677
7892
  CatchClause,
7893
+ ClassBody,
7678
7894
  ClassDeclaration,
7679
7895
  ClassExpression,
7680
7896
  ConditionalExpression,
@@ -7692,9 +7908,11 @@ var nodes = {
7692
7908
  Identifier,
7693
7909
  IfStatement,
7694
7910
  ImportDeclaration,
7911
+ LabeledStatement,
7695
7912
  Literal,
7696
7913
  LogicalExpression,
7697
7914
  MemberExpression,
7915
+ MethodDefinition,
7698
7916
  NewExpression,
7699
7917
  ObjectExpression,
7700
7918
  ObjectPattern,
@@ -7713,7 +7931,8 @@ var nodes = {
7713
7931
  UpdateExpression,
7714
7932
  VariableDeclarator,
7715
7933
  VariableDeclaration,
7716
- WhileStatement
7934
+ WhileStatement,
7935
+ YieldExpression
7717
7936
  };
7718
7937
 
7719
7938
  class UnknownNode extends Node$1 {
@@ -7807,14 +8026,13 @@ function clone ( node ) {
7807
8026
 
7808
8027
  class ModuleScope extends Scope {
7809
8028
  constructor ( module ) {
7810
- super({
7811
- isBlockScope: false,
7812
- isLexicalBoundary: true,
8029
+ super( {
7813
8030
  isModuleScope: true,
7814
8031
  parent: module.bundle.scope
7815
- });
8032
+ } );
7816
8033
 
7817
8034
  this.module = module;
8035
+ this.variables.this = new LocalVariable( 'this', null, UNDEFINED_ASSIGNMENT );
7818
8036
  }
7819
8037
 
7820
8038
  deshadow ( names ) {
@@ -7826,21 +8044,21 @@ class ModuleScope extends Scope {
7826
8044
  const addDeclaration = declaration => {
7827
8045
  if ( declaration.isNamespace && !declaration.isExternal ) {
7828
8046
  declaration.module.getExports().forEach( name => {
7829
- addDeclaration( declaration.module.traceExport(name) );
7830
- });
8047
+ addDeclaration( declaration.module.traceExport( name ) );
8048
+ } );
7831
8049
  }
7832
8050
 
7833
8051
  names.add( declaration.name );
7834
8052
  };
7835
8053
 
7836
8054
  specifier.module.getExports().forEach( name => {
7837
- addDeclaration( specifier.module.traceExport(name) );
7838
- });
8055
+ addDeclaration( specifier.module.traceExport( name ) );
8056
+ } );
7839
8057
 
7840
8058
  if ( specifier.name !== '*' ) {
7841
8059
  const declaration = specifier.module.traceExport( specifier.name );
7842
8060
  if ( !declaration ) {
7843
- this.module.warn({
8061
+ this.module.warn( {
7844
8062
  code: 'NON_EXISTENT_EXPORT',
7845
8063
  name: specifier.name,
7846
8064
  source: specifier.module.id,
@@ -7858,22 +8076,22 @@ class ModuleScope extends Scope {
7858
8076
  names.add( specifier.specifier.imported.name );
7859
8077
  }
7860
8078
  }
7861
- });
8079
+ } );
7862
8080
 
7863
8081
  super.deshadow( names );
7864
8082
  }
7865
8083
 
7866
- findDeclaration ( name ) {
7867
- if ( this.declarations[ name ] ) {
7868
- return this.declarations[ name ];
7869
- }
7870
-
7871
- return this.module.trace( name ) || this.parent.findDeclaration( name );
7872
- }
7873
-
7874
8084
  findLexicalBoundary () {
7875
8085
  return this;
7876
8086
  }
8087
+
8088
+ findVariable ( name ) {
8089
+ if ( this.variables[ name ] ) {
8090
+ return this.variables[ name ];
8091
+ }
8092
+
8093
+ return this.module.trace( name ) || this.parent.findVariable( name );
8094
+ }
7877
8095
  }
7878
8096
 
7879
8097
  function tryParse ( module, acornOptions ) {
@@ -7892,6 +8110,11 @@ function tryParse ( module, acornOptions ) {
7892
8110
  }
7893
8111
  }
7894
8112
 
8113
+ function includeFully ( node ) {
8114
+ node.includeInBundle();
8115
+ node.eachChild( includeFully );
8116
+ }
8117
+
7895
8118
  class Module {
7896
8119
  constructor ( ref ) {
7897
8120
  var id = ref.id;
@@ -8026,9 +8249,6 @@ class Module {
8026
8249
  localName: 'default',
8027
8250
  identifier
8028
8251
  };
8029
-
8030
- // create a synthetic declaration
8031
- //this.declarations.default = new SyntheticDefaultDeclaration( node, identifier || this.basename() );
8032
8252
  }
8033
8253
 
8034
8254
  // export var { foo, bar } = ...
@@ -8195,6 +8415,10 @@ class Module {
8195
8415
  return keys( reexports );
8196
8416
  }
8197
8417
 
8418
+ includeAllInBundle () {
8419
+ this.ast.body.forEach( includeFully );
8420
+ }
8421
+
8198
8422
  includeInBundle () {
8199
8423
  let addedNewNodes = false;
8200
8424
  this.ast.body.forEach( node => {
@@ -8209,7 +8433,7 @@ class Module {
8209
8433
 
8210
8434
  namespace () {
8211
8435
  if ( !this.declarations[ '*' ] ) {
8212
- this.declarations[ '*' ] = new SyntheticNamespaceDeclaration( this );
8436
+ this.declarations[ '*' ] = new NamespaceVariable( this );
8213
8437
  }
8214
8438
 
8215
8439
  return this.declarations[ '*' ];
@@ -8245,8 +8469,8 @@ class Module {
8245
8469
 
8246
8470
  trace ( name ) {
8247
8471
  // TODO this is slightly circular
8248
- if ( name in this.scope.declarations ) {
8249
- return this.scope.declarations[ name ];
8472
+ if ( name in this.scope.variables ) {
8473
+ return this.scope.variables[ name ];
8250
8474
  }
8251
8475
 
8252
8476
  if ( name in this.imports ) {
@@ -8301,7 +8525,7 @@ class Module {
8301
8525
  const name = exportDeclaration.localName;
8302
8526
  const declaration = this.trace( name );
8303
8527
 
8304
- return declaration || this.bundle.scope.findDeclaration( name );
8528
+ return declaration || this.bundle.scope.findVariable( name );
8305
8529
  }
8306
8530
 
8307
8531
  if ( name === 'default' ) { return; }
@@ -8331,11 +8555,54 @@ class Module {
8331
8555
  }
8332
8556
  }
8333
8557
 
8558
+ class ExternalVariable extends Variable {
8559
+ constructor ( module, name ) {
8560
+ super( name );
8561
+ this.module = module;
8562
+ this.safeName = null;
8563
+ this.isExternal = true;
8564
+ this.isNamespace = name === '*';
8565
+ }
8566
+
8567
+ addReference ( reference ) {
8568
+ if ( this.name === 'default' || this.name === '*' ) {
8569
+ this.module.suggestName( reference.name );
8570
+ }
8571
+ }
8572
+
8573
+ getName ( es ) {
8574
+ if ( this.name === '*' ) {
8575
+ return this.module.name;
8576
+ }
8577
+
8578
+ if ( this.name === 'default' ) {
8579
+ return this.module.exportsNamespace || ( !es && this.module.exportsNames ) ?
8580
+ `${this.module.name}__default` :
8581
+ this.module.name;
8582
+ }
8583
+
8584
+ return es ? this.safeName : `${this.module.name}.${this.name}`;
8585
+ }
8586
+
8587
+ includeDeclaration () {
8588
+ if ( this.included ) {
8589
+ return false;
8590
+ }
8591
+ this.included = true;
8592
+ this.module.used = true;
8593
+ return true;
8594
+ }
8595
+
8596
+ setSafeName ( name ) {
8597
+ this.safeName = name;
8598
+ }
8599
+ }
8600
+
8334
8601
  class ExternalModule {
8335
8602
  constructor ( id ) {
8336
8603
  this.id = id;
8337
8604
 
8338
- const parts = id.split(/[\\/]/);
8605
+ const parts = id.split( /[\\/]/ );
8339
8606
  this.name = makeLegal( parts.pop() );
8340
8607
 
8341
8608
  this.nameSuggestions = blank();
@@ -8362,9 +8629,8 @@ class ExternalModule {
8362
8629
  if ( name !== 'default' && name !== '*' ) { this.exportsNames = true; }
8363
8630
  if ( name === '*' ) { this.exportsNamespace = true; }
8364
8631
 
8365
- return this.declarations[ name ] || (
8366
- this.declarations[ name ] = new ExternalDeclaration( this, name )
8367
- );
8632
+ return this.declarations[ name ]
8633
+ || (this.declarations[ name ] = new ExternalVariable( this, name ));
8368
8634
  }
8369
8635
  }
8370
8636
 
@@ -9406,9 +9672,9 @@ function callIfFunction ( thing ) {
9406
9672
  return typeof thing === 'function' ? thing() : thing;
9407
9673
  }
9408
9674
 
9409
- class SyntheticGlobalDeclaration {
9675
+ class GlobalVariable extends Variable {
9410
9676
  constructor ( name ) {
9411
- this.name = name;
9677
+ super( name );
9412
9678
  this.isExternal = true;
9413
9679
  this.isGlobal = true;
9414
9680
  this.isReassigned = false;
@@ -9416,33 +9682,23 @@ class SyntheticGlobalDeclaration {
9416
9682
  }
9417
9683
 
9418
9684
  addReference ( reference ) {
9419
- reference.declaration = this;
9420
9685
  if ( reference.isReassignment ) { this.isReassigned = true; }
9421
9686
  }
9422
9687
 
9423
9688
  assignExpression () {}
9424
9689
 
9425
- gatherPossibleValues ( values ) {
9426
- values.add( UNKNOWN_ASSIGNMENT );
9427
- }
9428
-
9429
- getName () {
9430
- return this.name;
9431
- }
9432
-
9433
- includeDeclaration () {
9434
- this.included = true;
9435
- return false;
9690
+ hasEffectsWhenCalled () {
9691
+ return !pureFunctions[ this.name ];
9436
9692
  }
9437
9693
  }
9438
9694
 
9439
9695
  class BundleScope extends Scope {
9440
- findDeclaration ( name ) {
9441
- if ( !this.declarations[ name ] ) {
9442
- this.declarations[ name ] = new SyntheticGlobalDeclaration( name );
9696
+ findVariable ( name ) {
9697
+ if ( !this.variables[ name ] ) {
9698
+ this.variables[ name ] = new GlobalVariable( name );
9443
9699
  }
9444
9700
 
9445
- return this.declarations[ name ];
9701
+ return this.variables[ name ];
9446
9702
  }
9447
9703
  }
9448
9704
 
@@ -9498,7 +9754,7 @@ class Bundle$$1 {
9498
9754
  this.scope = new BundleScope();
9499
9755
  // TODO strictly speaking, this only applies with non-ES6, non-default-only bundles
9500
9756
  [ 'module', 'exports', '_interopDefault' ].forEach( name => {
9501
- this.scope.findDeclaration( name ); // creates global declaration as side-effect
9757
+ this.scope.findVariable( name ); // creates global variable as side-effect
9502
9758
  } );
9503
9759
 
9504
9760
  this.moduleById = new Map();
@@ -9560,7 +9816,7 @@ class Bundle$$1 {
9560
9816
  .then( entryModule => {
9561
9817
  this.entryModule = entryModule;
9562
9818
 
9563
- // Phase 2 – binding. We link references to their declarations
9819
+ // Phase 2 – binding. We link references to their variables
9564
9820
  // to generate a complete picture of the bundle
9565
9821
 
9566
9822
  timeStart( 'phase 2' );
@@ -9570,31 +9826,30 @@ class Bundle$$1 {
9570
9826
 
9571
9827
  timeEnd( 'phase 2' );
9572
9828
 
9573
- // Phase 3 – marking. We 'run' each statement to see which ones
9574
- // need to be included in the generated bundle
9829
+ // Phase 3 – marking. We include all statements that should be included
9575
9830
 
9576
9831
  timeStart( 'phase 3' );
9577
9832
 
9578
9833
  // mark all export statements
9579
9834
  entryModule.getExports().forEach( name => {
9580
- const declaration = entryModule.traceExport( name );
9835
+ const variable = entryModule.traceExport( name );
9581
9836
 
9582
- declaration.exportName = name;
9583
- declaration.includeDeclaration();
9837
+ variable.exportName = name;
9838
+ variable.includeVariable();
9584
9839
 
9585
- if ( declaration.isNamespace ) {
9586
- declaration.needsNamespaceBlock = true;
9840
+ if ( variable.isNamespace ) {
9841
+ variable.needsNamespaceBlock = true;
9587
9842
  }
9588
9843
  } );
9589
9844
 
9590
9845
  entryModule.getReexports().forEach( name => {
9591
- const declaration = entryModule.traceExport( name );
9846
+ const variable = entryModule.traceExport( name );
9592
9847
 
9593
- if ( declaration.isExternal ) {
9594
- declaration.reexported = declaration.module.reexported = true;
9848
+ if ( variable.isExternal ) {
9849
+ variable.reexported = variable.module.reexported = true;
9595
9850
  } else {
9596
- declaration.exportName = name;
9597
- declaration.includeDeclaration();
9851
+ variable.exportName = name;
9852
+ variable.includeVariable();
9598
9853
  }
9599
9854
  } );
9600
9855
 
@@ -9609,6 +9864,9 @@ class Bundle$$1 {
9609
9864
  }
9610
9865
  } );
9611
9866
  } while ( addedNewNodes );
9867
+ } else {
9868
+ // Necessary to properly replace namespace imports
9869
+ this.modules.forEach( module => module.includeAllInBundle() );
9612
9870
  }
9613
9871
 
9614
9872
  timeEnd( 'phase 3' );
@@ -9655,7 +9913,7 @@ class Bundle$$1 {
9655
9913
  const used = blank();
9656
9914
 
9657
9915
  // ensure no conflicts with globals
9658
- keys( this.scope.declarations ).forEach( name => used[ name ] = 1 );
9916
+ keys( this.scope.variables ).forEach( name => used[ name ] = 1 );
9659
9917
 
9660
9918
  function getSafeName ( name ) {
9661
9919
  while ( used[ name ] ) {
@@ -9683,12 +9941,12 @@ class Bundle$$1 {
9683
9941
  } );
9684
9942
 
9685
9943
  this.modules.forEach( module => {
9686
- forOwn( module.scope.declarations, ( declaration ) => {
9687
- if ( declaration.isDefault && declaration.declaration.id ) {
9944
+ forOwn( module.scope.variables, variable => {
9945
+ if ( variable.isDefault && variable.declaration.id ) {
9688
9946
  return;
9689
9947
  }
9690
9948
 
9691
- declaration.name = getSafeName( declaration.name );
9949
+ variable.name = getSafeName( variable.name );
9692
9950
  } );
9693
9951
 
9694
9952
  // deconflict reified namespaces
@@ -9841,12 +10099,12 @@ class Bundle$$1 {
9841
10099
  // need to find the actual import declaration, so we can provide
9842
10100
  // a useful error message. Bit hoop-jumpy but what can you do
9843
10101
  const declaration = module.ast.body.find( node => {
9844
- return node.isImportDeclaration && node.source.value === source;
10102
+ return ( node.isImportDeclaration || node.isExportDeclaration ) && node.source.value === source;
9845
10103
  } );
9846
-
10104
+ const declarationType = /Export/.test( declaration.type ) ? 'export' : 'import';
9847
10105
  module.error( {
9848
10106
  code: 'CANNOT_IMPORT_SELF',
9849
- message: `A module cannot import itself`
10107
+ message: `A module cannot ${declarationType} itself`
9850
10108
  }, declaration.start );
9851
10109
  }
9852
10110
 
@@ -10327,7 +10585,7 @@ function createCommonjsModule(fn, module) {
10327
10585
  * Licensed under the MIT license.
10328
10586
  */
10329
10587
 
10330
- var index$2 = function filenameRegex() {
10588
+ var filenameRegex = function filenameRegex() {
10331
10589
  return /([^\\\/]+)$/;
10332
10590
  };
10333
10591
 
@@ -10338,7 +10596,7 @@ var index$2 = function filenameRegex() {
10338
10596
  * Released under the MIT License.
10339
10597
  */
10340
10598
 
10341
- var index$6 = function (arr) {
10599
+ var arrFlatten = function (arr) {
10342
10600
  return flat(arr, []);
10343
10601
  };
10344
10602
 
@@ -10384,7 +10642,7 @@ function diff(arr, arrays) {
10384
10642
  }
10385
10643
 
10386
10644
  if (argsLen > 2) {
10387
- arrays = index$6(slice.call(arguments, 1));
10645
+ arrays = arrFlatten(slice.call(arguments, 1));
10388
10646
  }
10389
10647
 
10390
10648
  while (++i < len) {
@@ -10399,7 +10657,7 @@ function diff(arr, arrays) {
10399
10657
  * Expose `diff`
10400
10658
  */
10401
10659
 
10402
- var index$4 = diff;
10660
+ var arrDiff = diff;
10403
10661
 
10404
10662
  /*!
10405
10663
  * array-unique <https://github.com/jonschlinkert/array-unique>
@@ -10408,7 +10666,7 @@ var index$4 = diff;
10408
10666
  * Licensed under the MIT License.
10409
10667
  */
10410
10668
 
10411
- var index$8 = function unique(arr) {
10669
+ var arrayUnique = function unique(arr) {
10412
10670
  if (!Array.isArray(arr)) {
10413
10671
  throw new TypeError('array-unique expects an array.');
10414
10672
  }
@@ -10430,12 +10688,12 @@ var index$8 = function unique(arr) {
10430
10688
 
10431
10689
  var toString$1$1 = {}.toString;
10432
10690
 
10433
- var index$18 = Array.isArray || function (arr) {
10691
+ var isarray = Array.isArray || function (arr) {
10434
10692
  return toString$1$1.call(arr) == '[object Array]';
10435
10693
  };
10436
10694
 
10437
- var index$16 = function isObject(val) {
10438
- return val != null && typeof val === 'object' && index$18(val) === false;
10695
+ var isobject = function isObject(val) {
10696
+ return val != null && typeof val === 'object' && isarray(val) === false;
10439
10697
  };
10440
10698
 
10441
10699
  /*!
@@ -10447,7 +10705,7 @@ var index$16 = function isObject(val) {
10447
10705
 
10448
10706
  // The _isBuffer check is for Safari 5-7 support, because it's missing
10449
10707
  // Object.prototype.constructor. Remove this eventually
10450
- var index$24 = function (obj) {
10708
+ var isBuffer_1 = function (obj) {
10451
10709
  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
10452
10710
  };
10453
10711
 
@@ -10469,7 +10727,7 @@ var toString$2 = Object.prototype.toString;
10469
10727
  * @return {*} Native javascript type
10470
10728
  */
10471
10729
 
10472
- var index$22 = function kindOf(val) {
10730
+ var kindOf = function kindOf(val) {
10473
10731
  // primitivies
10474
10732
  if (typeof val === 'undefined') {
10475
10733
  return 'undefined';
@@ -10522,7 +10780,7 @@ var index$22 = function kindOf(val) {
10522
10780
  }
10523
10781
 
10524
10782
  // buffer
10525
- if (index$24(val)) {
10783
+ if (isBuffer_1(val)) {
10526
10784
  return 'buffer';
10527
10785
  }
10528
10786
 
@@ -10576,8 +10834,8 @@ var index$22 = function kindOf(val) {
10576
10834
  return 'object';
10577
10835
  };
10578
10836
 
10579
- var index$20 = function isNumber(num) {
10580
- var type = index$22(num);
10837
+ var isNumber = function isNumber(num) {
10838
+ var type = kindOf(num);
10581
10839
  if (type !== 'number' && type !== 'string') {
10582
10840
  return false;
10583
10841
  }
@@ -10594,7 +10852,7 @@ var toString$3 = Object.prototype.toString;
10594
10852
  * @return {*} Native javascript type
10595
10853
  */
10596
10854
 
10597
- var index$30 = function kindOf(val) {
10855
+ var kindOf$2 = function kindOf(val) {
10598
10856
  // primitivies
10599
10857
  if (typeof val === 'undefined') {
10600
10858
  return 'undefined';
@@ -10647,7 +10905,7 @@ var index$30 = function kindOf(val) {
10647
10905
  }
10648
10906
 
10649
10907
  // buffer
10650
- if (index$24(val)) {
10908
+ if (isBuffer_1(val)) {
10651
10909
  return 'buffer';
10652
10910
  }
10653
10911
 
@@ -10701,8 +10959,8 @@ var index$30 = function kindOf(val) {
10701
10959
  return 'object';
10702
10960
  };
10703
10961
 
10704
- var index$28 = function isNumber(num) {
10705
- var type = index$30(num);
10962
+ var isNumber$2 = function isNumber(num) {
10963
+ var type = kindOf$2(num);
10706
10964
 
10707
10965
  if (type === 'string') {
10708
10966
  if (!num.trim()) return false;
@@ -10722,7 +10980,7 @@ var toString$4 = Object.prototype.toString;
10722
10980
  * @return {*} Native javascript type
10723
10981
  */
10724
10982
 
10725
- var index$32 = function kindOf(val) {
10983
+ var kindOf$4 = function kindOf(val) {
10726
10984
  // primitivies
10727
10985
  if (typeof val === 'undefined') {
10728
10986
  return 'undefined';
@@ -10778,7 +11036,7 @@ var index$32 = function kindOf(val) {
10778
11036
  }
10779
11037
 
10780
11038
  // buffer
10781
- if (index$24(val)) {
11039
+ if (isBuffer_1(val)) {
10782
11040
  return 'buffer';
10783
11041
  }
10784
11042
 
@@ -10836,7 +11094,7 @@ var index$32 = function kindOf(val) {
10836
11094
  * Expose `randomatic`
10837
11095
  */
10838
11096
 
10839
- var index$26 = randomatic;
11097
+ var randomatic_1 = randomatic;
10840
11098
 
10841
11099
  /**
10842
11100
  * Available mask characters
@@ -10872,12 +11130,12 @@ function randomatic(pattern, length, options) {
10872
11130
  if (typeof pattern === 'string') {
10873
11131
  length = pattern.length;
10874
11132
 
10875
- } else if (index$28(pattern)) {
11133
+ } else if (isNumber$2(pattern)) {
10876
11134
  options = {}; length = pattern; pattern = '*';
10877
11135
  }
10878
11136
  }
10879
11137
 
10880
- if (index$32(length) === 'object' && length.hasOwnProperty('chars')) {
11138
+ if (kindOf$4(length) === 'object' && length.hasOwnProperty('chars')) {
10881
11139
  options = length;
10882
11140
  pattern = options.chars;
10883
11141
  length = pattern.length;
@@ -10921,7 +11179,7 @@ var cache;
10921
11179
  * Expose `repeat`
10922
11180
  */
10923
11181
 
10924
- var index$34 = repeat;
11182
+ var repeatString = repeat;
10925
11183
 
10926
11184
  /**
10927
11185
  * Repeat the given `string` the specified `number`
@@ -10979,7 +11237,7 @@ function repeat(str, num) {
10979
11237
  * Licensed under the MIT license.
10980
11238
  */
10981
11239
 
10982
- var index$36 = function repeat(ele, num) {
11240
+ var repeatElement = function repeat(ele, num) {
10983
11241
  var arr = new Array(num);
10984
11242
 
10985
11243
  for (var i = 0; i < num; i++) {
@@ -10993,7 +11251,7 @@ var index$36 = function repeat(ele, num) {
10993
11251
  * Expose `fillRange`
10994
11252
  */
10995
11253
 
10996
- var index$14 = fillRange;
11254
+ var fillRange_1 = fillRange;
10997
11255
 
10998
11256
  /**
10999
11257
  * Return a range of numbers or letters.
@@ -11018,7 +11276,7 @@ function fillRange(a, b, step, options, fn) {
11018
11276
  fn = options; options = {};
11019
11277
  }
11020
11278
 
11021
- if (index$16(step)) {
11279
+ if (isobject(step)) {
11022
11280
  options = step; step = '';
11023
11281
  }
11024
11282
 
@@ -11053,11 +11311,11 @@ function fillRange(a, b, step, options, fn) {
11053
11311
 
11054
11312
  // repeat string
11055
11313
  if (m === '+') {
11056
- return index$36(a, b);
11314
+ return repeatElement(a, b);
11057
11315
 
11058
11316
  // randomize a, `b` times
11059
11317
  } else if (m === '?') {
11060
- return [index$26(a, b)];
11318
+ return [randomatic_1(a, b)];
11061
11319
 
11062
11320
  // expand right, no regex reduction
11063
11321
  } else if (m === '>') {
@@ -11080,7 +11338,7 @@ function fillRange(a, b, step, options, fn) {
11080
11338
  regex = true;
11081
11339
  sep$$1 = m;
11082
11340
  }
11083
- } else if (!index$20(step)) {
11341
+ } else if (!isNumber(step)) {
11084
11342
  if (!opts.silent) {
11085
11343
  throw new TypeError('fill-range: invalid step.');
11086
11344
  }
@@ -11105,8 +11363,8 @@ function fillRange(a, b, step, options, fn) {
11105
11363
  }
11106
11364
 
11107
11365
  // validate arguments
11108
- var isNumA = index$20(zeros(a));
11109
- var isNumB = index$20(zeros(b));
11366
+ var isNumA = isNumber(zeros(a));
11367
+ var isNumB = isNumber(zeros(b));
11110
11368
 
11111
11369
  if ((!isNumA && isNumB) || (isNumA && !isNumB)) {
11112
11370
  if (!opts.silent) {
@@ -11369,7 +11627,7 @@ function isPadded(origA, origB) {
11369
11627
  : blen;
11370
11628
 
11371
11629
  return function (a) {
11372
- return index$34('0', len - length(a));
11630
+ return repeatString('0', len - length(a));
11373
11631
  };
11374
11632
  }
11375
11633
  return false;
@@ -11383,7 +11641,7 @@ function length(val) {
11383
11641
  return val.toString().length;
11384
11642
  }
11385
11643
 
11386
- var index$12 = function expandRange(str, options, fn) {
11644
+ var expandRange = function expandRange(str, options, fn) {
11387
11645
  if (typeof str !== 'string') {
11388
11646
  throw new TypeError('expand-range expects a string.');
11389
11647
  }
@@ -11413,7 +11671,7 @@ var index$12 = function expandRange(str, options, fn) {
11413
11671
  }
11414
11672
 
11415
11673
  args.push(opts);
11416
- return index$14.apply(null, args.concat(fn));
11674
+ return fillRange_1.apply(null, args.concat(fn));
11417
11675
  };
11418
11676
 
11419
11677
  /*!
@@ -11469,7 +11727,7 @@ function randomize$1() {
11469
11727
 
11470
11728
  var cache$1 = {};
11471
11729
 
11472
- var index$38 = {
11730
+ var preserve = {
11473
11731
  before: before,
11474
11732
  after: after
11475
11733
  };
@@ -11486,7 +11744,7 @@ var index$38 = {
11486
11744
  * Expose `braces`
11487
11745
  */
11488
11746
 
11489
- var index$10 = function(str, options) {
11747
+ var braces_1 = function(str, options) {
11490
11748
  if (typeof str !== 'string') {
11491
11749
  throw new Error('braces expects a string');
11492
11750
  }
@@ -11556,7 +11814,7 @@ function braces(str, arr, options) {
11556
11814
  return arr.concat(str);
11557
11815
  } else {
11558
11816
  es6 = true;
11559
- str = index$38.before(str, es6Regex());
11817
+ str = preserve.before(str, es6Regex());
11560
11818
  }
11561
11819
  }
11562
11820
 
@@ -11576,7 +11834,7 @@ function braces(str, arr, options) {
11576
11834
  var segs, segsLength;
11577
11835
 
11578
11836
  if (inner.indexOf('..') !== -1) {
11579
- segs = index$12(inner, opts, fn) || inner.split(',');
11837
+ segs = expandRange(inner, opts, fn) || inner.split(',');
11580
11838
  segsLength = segs.length;
11581
11839
 
11582
11840
  } else if (inner[0] === '"' || inner[0] === '\'') {
@@ -11614,7 +11872,7 @@ function braces(str, arr, options) {
11614
11872
  arr = braces(val, arr, opts);
11615
11873
  } else if (val !== '') {
11616
11874
  if (opts.nodupes && arr.indexOf(val) !== -1) { continue; }
11617
- arr.push(es6 ? index$38.after(val) : val);
11875
+ arr.push(es6 ? preserve.after(val) : val);
11618
11876
  }
11619
11877
  }
11620
11878
 
@@ -11664,7 +11922,7 @@ function exponential(str, options, fn) {
11664
11922
 
11665
11923
  } else {
11666
11924
  var num = Math.pow(2, exp);
11667
- arr.push.apply(arr, index$36(ele, num));
11925
+ arr.push.apply(arr, repeatElement(ele, num));
11668
11926
  }
11669
11927
  }
11670
11928
  }
@@ -11872,7 +12130,7 @@ function filter$1(arr, cb) {
11872
12130
  * Licensed under the MIT License.
11873
12131
  */
11874
12132
 
11875
- var index$42 = function isPosixBracket(str) {
12133
+ var isPosixBracket = function isPosixBracket(str) {
11876
12134
  return typeof str === 'string' && /\[([:.=+])(?:[^\[\]]|)+\1\]/.test(str);
11877
12135
  };
11878
12136
 
@@ -11900,10 +12158,10 @@ var POSIX = {
11900
12158
  * Expose `brackets`
11901
12159
  */
11902
12160
 
11903
- var index$40 = brackets;
12161
+ var expandBrackets = brackets;
11904
12162
 
11905
12163
  function brackets(str) {
11906
- if (!index$42(str)) {
12164
+ if (!isPosixBracket(str)) {
11907
12165
  return str;
11908
12166
  }
11909
12167
 
@@ -12036,7 +12294,7 @@ brackets.match = function(arr, pattern) {
12036
12294
  * Licensed under the MIT License.
12037
12295
  */
12038
12296
 
12039
- var index$46 = function isExtglob(str) {
12297
+ var isExtglob = function isExtglob(str) {
12040
12298
  return typeof str === 'string'
12041
12299
  && /[@?!+*]\(/.test(str);
12042
12300
  };
@@ -12053,7 +12311,7 @@ var cache$2 = {};
12053
12311
  * Expose `extglob`
12054
12312
  */
12055
12313
 
12056
- var index$44 = extglob;
12314
+ var extglob_1 = extglob;
12057
12315
 
12058
12316
  /**
12059
12317
  * Convert the given extglob `string` to a regex-compatible
@@ -12221,15 +12479,15 @@ function toRegex$1(pattern, contains, isNegated) {
12221
12479
 
12222
12480
 
12223
12481
 
12224
- var index$48 = function isGlob(str) {
12482
+ var isGlob = function isGlob(str) {
12225
12483
  return typeof str === 'string'
12226
12484
  && (/[*!?{}(|)[\]]/.test(str)
12227
- || index$46(str));
12485
+ || isExtglob(str));
12228
12486
  };
12229
12487
 
12230
12488
  var isWin = process.platform === 'win32';
12231
12489
 
12232
- var index$52 = function (str) {
12490
+ var removeTrailingSeparator = function (str) {
12233
12491
  var i = str.length - 1;
12234
12492
  if (i < 2) {
12235
12493
  return str;
@@ -12254,13 +12512,13 @@ function isSeparator(str, i) {
12254
12512
 
12255
12513
 
12256
12514
 
12257
- var index$50 = function normalizePath(str, stripTrailing) {
12515
+ var normalizePath = function normalizePath(str, stripTrailing) {
12258
12516
  if (typeof str !== 'string') {
12259
12517
  throw new TypeError('expected a string');
12260
12518
  }
12261
12519
  str = str.replace(/[\\\/]+/g, '/');
12262
12520
  if (stripTrailing !== false) {
12263
- str = index$52(str);
12521
+ str = removeTrailingSeparator(str);
12264
12522
  }
12265
12523
  return str;
12266
12524
  };
@@ -12272,7 +12530,7 @@ var index$50 = function normalizePath(str, stripTrailing) {
12272
12530
  * Licensed under the MIT License.
12273
12531
  */
12274
12532
 
12275
- var index$56 = function isExtendable(val) {
12533
+ var isExtendable = function isExtendable(val) {
12276
12534
  return typeof val !== 'undefined' && val !== null
12277
12535
  && (typeof val === 'object' || typeof val === 'function');
12278
12536
  };
@@ -12284,7 +12542,7 @@ var index$56 = function isExtendable(val) {
12284
12542
  * Released under the MIT License.
12285
12543
  */
12286
12544
 
12287
- var index$60 = function forIn(obj, fn, thisArg) {
12545
+ var forIn = function forIn(obj, fn, thisArg) {
12288
12546
  for (var key in obj) {
12289
12547
  if (fn.call(thisArg, obj[key], key, obj) === false) {
12290
12548
  break;
@@ -12294,16 +12552,16 @@ var index$60 = function forIn(obj, fn, thisArg) {
12294
12552
 
12295
12553
  var hasOwn = Object.prototype.hasOwnProperty;
12296
12554
 
12297
- var index$58 = function forOwn(obj, fn, thisArg) {
12298
- index$60(obj, function(val, key) {
12555
+ var forOwn$1 = function forOwn(obj, fn, thisArg) {
12556
+ forIn(obj, function(val, key) {
12299
12557
  if (hasOwn.call(obj, key)) {
12300
12558
  return fn.call(thisArg, obj[key], key, obj);
12301
12559
  }
12302
12560
  });
12303
12561
  };
12304
12562
 
12305
- var index$54 = function omit(obj, keys) {
12306
- if (!index$56(obj)) return {};
12563
+ var object_omit = function omit(obj, keys) {
12564
+ if (!isExtendable(obj)) return {};
12307
12565
 
12308
12566
  keys = [].concat.apply([], [].slice.call(arguments, 1));
12309
12567
  var last = keys[keys.length - 1];
@@ -12318,7 +12576,7 @@ var index$54 = function omit(obj, keys) {
12318
12576
  return obj;
12319
12577
  }
12320
12578
 
12321
- index$58(obj, function(value, key) {
12579
+ forOwn$1(obj, function(value, key) {
12322
12580
  if (keys.indexOf(key) === -1) {
12323
12581
 
12324
12582
  if (!isFunction) {
@@ -12331,20 +12589,20 @@ var index$54 = function omit(obj, keys) {
12331
12589
  return res;
12332
12590
  };
12333
12591
 
12334
- var index$66 = function globParent(str) {
12592
+ var globParent = function globParent(str) {
12335
12593
  str += 'a'; // preserves full path in case of trailing path separator
12336
- do {str = path__default.dirname(str);} while (index$48(str));
12594
+ do {str = path__default.dirname(str);} while (isGlob(str));
12337
12595
  return str;
12338
12596
  };
12339
12597
 
12340
- var index$64 = function globBase(pattern) {
12598
+ var globBase = function globBase(pattern) {
12341
12599
  if (typeof pattern !== 'string') {
12342
12600
  throw new TypeError('glob-base expects a string.');
12343
12601
  }
12344
12602
 
12345
12603
  var res = {};
12346
- res.base = index$66(pattern);
12347
- res.isGlob = index$48(pattern);
12604
+ res.base = globParent(pattern);
12605
+ res.isGlob = isGlob(pattern);
12348
12606
 
12349
12607
  if (res.base !== '.') {
12350
12608
  res.glob = pattern.substr(res.base.length);
@@ -12383,7 +12641,7 @@ function dirname$1(glob) {
12383
12641
  * Released under the MIT License.
12384
12642
  */
12385
12643
 
12386
- var index$68 = function(str) {
12644
+ var isDotfile = function(str) {
12387
12645
  if (str.charCodeAt(0) === 46 /* . */ && str.indexOf('/', 1) === -1) {
12388
12646
  return true;
12389
12647
  }
@@ -12391,7 +12649,7 @@ var index$68 = function(str) {
12391
12649
  return slash !== -1 ? str.charCodeAt(slash + 1) === 46 /* . */ : false;
12392
12650
  };
12393
12651
 
12394
- var index$62 = createCommonjsModule(function (module) {
12652
+ var parseGlob = createCommonjsModule(function (module) {
12395
12653
  /*!
12396
12654
  * parse-glob <https://github.com/jonschlinkert/parse-glob>
12397
12655
  *
@@ -12436,7 +12694,7 @@ module.exports = function parseGlob(glob) {
12436
12694
  // unescape dots and slashes in braces/brackets
12437
12695
  glob = escape(glob);
12438
12696
 
12439
- var parsed = index$64(glob);
12697
+ var parsed = globBase(glob);
12440
12698
  tok.is.glob = parsed.isGlob;
12441
12699
 
12442
12700
  tok.glob = parsed.glob;
@@ -12452,7 +12710,7 @@ module.exports = function parseGlob(glob) {
12452
12710
  tok.path.extname = basename$$1.slice(1).join('.') || '';
12453
12711
  tok.path.ext = '';
12454
12712
 
12455
- if (index$48(tok.path.dirname) && !tok.path.basename) {
12713
+ if (isGlob(tok.path.dirname) && !tok.path.basename) {
12456
12714
  if (!/\/$/.test(tok.glob)) {
12457
12715
  tok.path.basename = tok.glob;
12458
12716
  }
@@ -12485,11 +12743,11 @@ module.exports = function parseGlob(glob) {
12485
12743
  // Booleans
12486
12744
  var is = (glob && tok.is.glob);
12487
12745
  tok.is.negated = glob && glob.charAt(0) === '!';
12488
- tok.is.extglob = glob && index$46(glob);
12746
+ tok.is.extglob = glob && isExtglob(glob);
12489
12747
  tok.is.braces = has(is, glob, '{');
12490
12748
  tok.is.brackets = has(is, glob, '[:');
12491
12749
  tok.is.globstar = has(is, glob, '**');
12492
- tok.is.dotfile = index$68(tok.path.basename) || index$68(tok.path.filename);
12750
+ tok.is.dotfile = isDotfile(tok.path.basename) || isDotfile(tok.path.filename);
12493
12751
  tok.is.dotdir = dotdir(tok.path.dirname);
12494
12752
  return (cache[glob] = tok);
12495
12753
  };
@@ -12558,18 +12816,18 @@ function unescape(str) {
12558
12816
  */
12559
12817
 
12560
12818
  // see http://jsperf.com/testing-value-is-primitive/7
12561
- var index$72 = function isPrimitive(value) {
12819
+ var isPrimitive = function isPrimitive(value) {
12562
12820
  return value == null || (typeof value !== 'function' && typeof value !== 'object');
12563
12821
  };
12564
12822
 
12565
- var index$74 = function isEqual(a, b) {
12823
+ var isEqualShallow = function isEqual(a, b) {
12566
12824
  if (!a && !b) { return true; }
12567
12825
  if (!a && b || a && !b) { return false; }
12568
12826
 
12569
12827
  var numKeysA = 0, numKeysB = 0, key;
12570
12828
  for (key in b) {
12571
12829
  numKeysB++;
12572
- if (!index$72(b[key]) || !a.hasOwnProperty(key) || (a[key] !== b[key])) {
12830
+ if (!isPrimitive(b[key]) || !a.hasOwnProperty(key) || (a[key] !== b[key])) {
12573
12831
  return false;
12574
12832
  }
12575
12833
  }
@@ -12586,7 +12844,7 @@ var cache$3 = {};
12586
12844
  * Expose `regexCache`
12587
12845
  */
12588
12846
 
12589
- var index$70 = regexCache;
12847
+ var regexCache_1 = regexCache;
12590
12848
 
12591
12849
  /**
12592
12850
  * Memoize the results of a call to the new RegExp constructor.
@@ -12619,7 +12877,7 @@ function regexCache(fn, str, opts) {
12619
12877
  }
12620
12878
 
12621
12879
  cached = cache$3[key];
12622
- if (cached && index$74(cached.opts, opts)) {
12880
+ if (cached && isEqualShallow(cached.opts, opts)) {
12623
12881
  return cached.regex;
12624
12882
  }
12625
12883
 
@@ -12638,8 +12896,8 @@ function memo(key, opts, regex) {
12638
12896
  var cache_1 = cache$3;
12639
12897
  var basic_1 = basic;
12640
12898
 
12641
- index$70.cache = cache_1;
12642
- index$70.basic = basic_1;
12899
+ regexCache_1.cache = cache_1;
12900
+ regexCache_1.basic = basic_1;
12643
12901
 
12644
12902
  var utils_1 = createCommonjsModule(function (module) {
12645
12903
  'use strict';
@@ -12653,18 +12911,18 @@ var utils = module.exports;
12653
12911
  * Module dependencies
12654
12912
  */
12655
12913
 
12656
- utils.diff = index$4;
12657
- utils.unique = index$8;
12658
- utils.braces = index$10;
12659
- utils.brackets = index$40;
12660
- utils.extglob = index$44;
12661
- utils.isExtglob = index$46;
12662
- utils.isGlob = index$48;
12663
- utils.typeOf = index$22;
12664
- utils.normalize = index$50;
12665
- utils.omit = index$54;
12666
- utils.parseGlob = index$62;
12667
- utils.cache = index$70;
12914
+ utils.diff = arrDiff;
12915
+ utils.unique = arrayUnique;
12916
+ utils.braces = braces_1;
12917
+ utils.brackets = expandBrackets;
12918
+ utils.extglob = extglob_1;
12919
+ utils.isExtglob = isExtglob;
12920
+ utils.isGlob = isGlob;
12921
+ utils.typeOf = kindOf;
12922
+ utils.normalize = normalizePath;
12923
+ utils.omit = object_omit;
12924
+ utils.parseGlob = parseGlob;
12925
+ utils.cache = regexCache_1;
12668
12926
 
12669
12927
  /**
12670
12928
  * Get the filename of a filepath
@@ -12674,7 +12932,7 @@ utils.cache = index$70;
12674
12932
  */
12675
12933
 
12676
12934
  utils.filename = function filename(fp) {
12677
- var seg = fp.match(index$2());
12935
+ var seg = fp.match(filenameRegex());
12678
12936
  return seg && seg[0];
12679
12937
  };
12680
12938
 
@@ -13768,7 +14026,7 @@ micromatch.matchKeys = matchKeys;
13768
14026
  * Expose `micromatch`
13769
14027
  */
13770
14028
 
13771
- var index$1 = micromatch;
14029
+ var micromatch_1 = micromatch;
13772
14030
 
13773
14031
  function ensureArray$1 ( thing ) {
13774
14032
  if ( Array.isArray( thing ) ) return thing;
@@ -13777,7 +14035,7 @@ function ensureArray$1 ( thing ) {
13777
14035
  }
13778
14036
 
13779
14037
  function createFilter ( include, exclude ) {
13780
- const getMatcher = id => ( isRegexp( id ) ? id : { test: index$1.matcher( path.resolve( id ) ) } );
14038
+ const getMatcher = id => ( isRegexp( id ) ? id : { test: micromatch_1.matcher( path.resolve( id ) ) } );
13781
14039
  include = ensureArray$1( include ).map( getMatcher );
13782
14040
  exclude = ensureArray$1( exclude ).map( getMatcher );
13783
14041
 
@@ -13831,12 +14089,12 @@ requireRelative.resolve = function(requested, relativeTo) {
13831
14089
  return module$1._resolveFilename(requested, root);
13832
14090
  };
13833
14091
 
13834
- var index$76 = requireRelative;
14092
+ var requireRelative_1$1 = requireRelative;
13835
14093
 
13836
14094
  let chokidar;
13837
14095
 
13838
14096
  try {
13839
- chokidar = index$76( 'chokidar', process.cwd() );
14097
+ chokidar = requireRelative_1$1( 'chokidar', process.cwd() );
13840
14098
  } catch (err) {
13841
14099
  chokidar = null;
13842
14100
  }
@@ -14172,7 +14430,7 @@ function watch$1(configs) {
14172
14430
  return new Watcher(configs);
14173
14431
  }
14174
14432
 
14175
- var version$1 = "0.49.3";
14433
+ var version$1 = "0.50.0";
14176
14434
 
14177
14435
  exports.rollup = rollup;
14178
14436
  exports.watch = watch$1;