ngannotate-rails 0.10.1 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NzcwNWRjZWVkYzE0OGFiZmI2MzY0NmJiOTMxM2EzMjZkODllOGY3Ng==
5
- data.tar.gz: !binary |-
6
- MWMwZjQzNzkyMWY5YjRlOTYxY2Y2MzI5MDM0MWZjMDA2MWU0NGY1Mw==
2
+ SHA1:
3
+ metadata.gz: 6eb1737fcf0afa5ea00f1e82a330c7ab64770225
4
+ data.tar.gz: fcfe26fd09d2ac827928d8474dc75dc89b4b6f44
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ODg3YTVjOWIxNjk4MmQ0OWEyYzIzN2RlNjNiMDI4NTk0ZjJmNjI4MTdiYWQ2
10
- MTczMTU2NDRiZWI3MzRjOWM1ZTY0MTQxMWM1NTAwYWY1MjViZTZhODFiYWRi
11
- MmM2M2MzNWE2YWVlYzc0NDVhYTczMzY4ZGVlNjlmZDc5NDY5MzY=
12
- data.tar.gz: !binary |-
13
- N2Y4YTA4NGY5MzM4MmU3MDk4ZjBkMjUzZDFmNWU2YTc5NDkyZmUxMGFhMGM4
14
- YTQ0MjMxMmFlZDQ3NDAwNDhiMjQ5ODhhNzBjOTY0MzY5ZDMzM2Q3ODgyODUx
15
- YWZmMTBmMDE3ODM1MWJmNzNmZjI1ODY0MzQ0NjZjOThjMjE5ZWY=
6
+ metadata.gz: 732565bc3e8b91bf37ef22829345cb1c1543ae7cdca342dcd3983d696d17947728cbeddaf71a82b8e84cc5fbce1a9ffb38c5526c08bd19a304ae511718e69d25
7
+ data.tar.gz: 136e610aaa587d154244d5ec10d40398081d34d1e1988c4a7ed89ef611c25a327ad7bbc7fae44c2ba9cd2e50830bf831a2aea407e1bbd4f82d825d497027336a
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-1.9.3-p484
1
+ ruby-2.1.5
@@ -1,5 +1,5 @@
1
1
  module Ngannotate
2
2
  module Rails
3
- VERSION = "0.10.1"
3
+ VERSION = "0.12.1"
4
4
  end
5
5
  end
data/vendor/ngannotate.js CHANGED
@@ -668,6 +668,8 @@ var process = module.exports = {};
668
668
  process.nextTick = (function () {
669
669
  var canSetImmediate = typeof window !== 'undefined'
670
670
  && window.setImmediate;
671
+ var canMutationObserver = typeof window !== 'undefined'
672
+ && window.MutationObserver;
671
673
  var canPost = typeof window !== 'undefined'
672
674
  && window.postMessage && window.addEventListener
673
675
  ;
@@ -676,8 +678,29 @@ process.nextTick = (function () {
676
678
  return function (f) { return window.setImmediate(f) };
677
679
  }
678
680
 
681
+ var queue = [];
682
+
683
+ if (canMutationObserver) {
684
+ var hiddenDiv = document.createElement("div");
685
+ var observer = new MutationObserver(function () {
686
+ var queueList = queue.slice();
687
+ queue.length = 0;
688
+ queueList.forEach(function (fn) {
689
+ fn();
690
+ });
691
+ });
692
+
693
+ observer.observe(hiddenDiv, { attributes: true });
694
+
695
+ return function nextTick(fn) {
696
+ if (!queue.length) {
697
+ hiddenDiv.setAttribute('yes', 'no');
698
+ }
699
+ queue.push(fn);
700
+ };
701
+ }
702
+
679
703
  if (canPost) {
680
- var queue = [];
681
704
  window.addEventListener('message', function (ev) {
682
705
  var source = ev.source;
683
706
  if ((source === window || source === null) && ev.data === 'process-tick') {
@@ -717,7 +740,7 @@ process.emit = noop;
717
740
 
718
741
  process.binding = function (name) {
719
742
  throw new Error('process.binding is not supported');
720
- }
743
+ };
721
744
 
722
745
  // TODO(shtylman)
723
746
  process.cwd = function () { return '/' };
@@ -1414,7 +1437,7 @@ module.exports = function generateSourcemap(src, fragments, inFile, sourceRoot)
1414
1437
  return new SourceMapper(src, fragments, inFile, sourceRoot).generate();
1415
1438
  }
1416
1439
 
1417
- },{"source-map":20,"stable":30}],9:[function(require,module,exports){
1440
+ },{"source-map":21,"stable":31}],9:[function(require,module,exports){
1418
1441
  // lut.js
1419
1442
  // MIT licensed, see LICENSE file
1420
1443
  // Copyright (c) 2013-2014 Olov Lassus <olov.lassus@gmail.com>
@@ -1542,15 +1565,12 @@ function last(arr) {
1542
1565
  return arr[arr.length - 1];
1543
1566
  }
1544
1567
 
1545
- },{"assert":1,"ordered-ast-traverse":17,"simple-is":19}],10:[function(require,module,exports){
1568
+ },{"assert":1,"ordered-ast-traverse":18,"simple-is":20}],10:[function(require,module,exports){
1546
1569
  // ng-annotate-main.js
1547
1570
  // MIT licensed, see LICENSE file
1548
1571
  // Copyright (c) 2013-2014 Olov Lassus <olov.lassus@gmail.com>
1549
1572
 
1550
1573
  "use strict";
1551
- var esprima_require_t0 = Date.now();
1552
- var esprima = require("esprima").parse;
1553
- var esprima_require_t1 = Date.now();
1554
1574
  var fmt = require("simple-fmt");
1555
1575
  var is = require("simple-is");
1556
1576
  var alter = require("alter");
@@ -1562,6 +1582,7 @@ var generateSourcemap = require("./generate-sourcemap");
1562
1582
  var Lut = require("./lut");
1563
1583
  var scopeTools = require("./scopetools");
1564
1584
  var stringmap = require("stringmap");
1585
+ var parser = null; // will be lazy-loaded to esprima or acorn
1565
1586
 
1566
1587
  var chainedRouteProvider = 1;
1567
1588
  var chainedUrlRouterProvider = 2;
@@ -1575,8 +1596,10 @@ function match(node, ctx, matchPlugins) {
1575
1596
  node.callee.computed === false
1576
1597
  );
1577
1598
 
1599
+ // matchInjectorInvoke must happen before matchRegular
1600
+ // to prevent false positive ($injector.invoke() outside module)
1578
1601
  var matchMethodCalls = (isMethodCall &&
1579
- (matchRegular(node, ctx) || matchNgRoute(node) || matchNgUi(node) || matchHttpProvider(node)));
1602
+ (matchInjectorInvoke(node) || matchRegular(node, ctx) || matchNgRoute(node) || matchNgUi(node) || matchHttpProvider(node)));
1580
1603
 
1581
1604
  return matchMethodCalls ||
1582
1605
  (matchPlugins && matchPlugins(node)) ||
@@ -1769,6 +1792,19 @@ function matchNgUi(node) {
1769
1792
  }
1770
1793
  }
1771
1794
 
1795
+ function matchInjectorInvoke(node) {
1796
+ // $injector.invoke(function($compile) { ... });
1797
+
1798
+ // we already know that node is a (non-computed) method call
1799
+ var callee = node.callee;
1800
+ var obj = callee.object; // identifier or expression
1801
+ var method = callee.property; // identifier
1802
+
1803
+ return method.name === "invoke" &&
1804
+ obj.type === "Identifier" && obj.name === "$injector" &&
1805
+ node.arguments.length >= 1 && node.arguments;
1806
+ }
1807
+
1772
1808
  function matchHttpProvider(node) {
1773
1809
  // $httpProvider.interceptors.push(function($scope) {});
1774
1810
  // $httpProvider.responseInterceptors.push(function($scope) {});
@@ -1849,7 +1885,8 @@ function last(arr) {
1849
1885
  function matchProp(name, props) {
1850
1886
  for (var i = 0; i < props.length; i++) {
1851
1887
  var prop = props[i];
1852
- if (prop.key.type === "Identifier" && prop.key.name === name) {
1888
+ if ((prop.key.type === "Identifier" && prop.key.name === name) ||
1889
+ (prop.key.type === "Literal" && prop.key.value === name)) {
1853
1890
  return prop.value; // FunctionExpression or ArrayExpression
1854
1891
  }
1855
1892
  }
@@ -1879,10 +1916,59 @@ function stringify(ctx, arr, quot) {
1879
1916
  }).join(", ") + "]";
1880
1917
  }
1881
1918
 
1919
+ function parseExpressionOfType(str, type) {
1920
+ var node = parser(str).body[0].expression;
1921
+ assert(node.type === type);
1922
+ return node;
1923
+ }
1924
+
1925
+ // stand-in for not having a jsshaper-style ref's
1926
+ function replaceNodeWith(node, newNode) {
1927
+ var done = false;
1928
+ var parent = node.$parent;
1929
+ var keys = Object.keys(parent);
1930
+ keys.forEach(function(key) {
1931
+ if (parent[key] === node) {
1932
+ parent[key] = newNode;
1933
+ done = true;
1934
+ }
1935
+ });
1936
+
1937
+ if (done) {
1938
+ return;
1939
+ }
1940
+
1941
+ // second pass, now check arrays
1942
+ keys.forEach(function(key) {
1943
+ if (Array.isArray(parent[key])) {
1944
+ var arr = parent[key];
1945
+ for (var i = 0; i < arr.length; i++) {
1946
+ if (arr[i] === node) {
1947
+ arr[i] = newNode;
1948
+ done = true;
1949
+ }
1950
+ }
1951
+ }
1952
+ });
1953
+
1954
+ assert(done);
1955
+ }
1956
+
1882
1957
  function insertArray(ctx, functionExpression, fragments, quot) {
1883
1958
  var range = functionExpression.range;
1884
1959
 
1885
1960
  var args = stringify(ctx, functionExpression.params, quot);
1961
+
1962
+ // modify the AST
1963
+ /*
1964
+ const arrayExpression = parseExpressionOfType(args, "ArrayExpression");
1965
+ const parent = functionExpression.$parent;
1966
+ replaceNodeWith(functionExpression, arrayExpression);
1967
+ arrayExpression.$parent = parent;
1968
+ arrayExpression.elements.push(functionExpression)
1969
+ functionExpression.$parent = arrayExpression;
1970
+ */
1971
+
1886
1972
  fragments.push({
1887
1973
  start: range[0],
1888
1974
  end: range[0],
@@ -2066,9 +2152,15 @@ function followReference(node) {
2066
2152
 
2067
2153
  if (is.someof(kind, ["const", "let", "var"])) {
2068
2154
  assert(ptype === "VariableDeclarator");
2069
- return parent.init;
2155
+ // {type: "VariableDeclarator", id: {type: "Identifier", name: "foo"}, init: ..}
2156
+ return parent;
2070
2157
  } else if (kind === "fun") {
2071
2158
  assert(ptype === "FunctionDeclaration" || ptype === "FunctionExpression")
2159
+ // FunctionDeclaration is the common case, i.e.
2160
+ // function foo(a, b) {}
2161
+
2162
+ // FunctionExpression is only applicable for cases similar to
2163
+ // var f = function asdf(a,b) { mymod.controller("asdf", asdf) };
2072
2164
  return parent;
2073
2165
  }
2074
2166
 
@@ -2098,31 +2190,72 @@ function posToLine(pos, src) {
2098
2190
  }
2099
2191
 
2100
2192
  function judgeInjectArraySuspect(node, ctx) {
2101
- // /*@ngInject*/ var foo = function($scope) {} and
2102
- // /*@ngInject*/ function foo($scope) {} and
2103
- // /*@ngInject*/ foo.bar[0] = function($scope) {}
2193
+ if (node.type === "VariableDeclaration") {
2194
+ // suspect can only be a VariableDeclaration (statement) in case of
2195
+ // explicitly marked via ngInject, not via references because
2196
+ // references follow to VariableDeclarator (child)
2197
+
2198
+ // /*@ngInject*/ var foo = function($scope) {} and
2199
+
2200
+ if (node.declarations.length !== 1) {
2201
+ // more than one declarator => exit
2202
+ return;
2203
+ }
2204
+
2205
+ // one declarator => jump over declaration into declarator
2206
+ // rest of code will treat it as any (referenced) declarator
2207
+ node = node.declarations[0];
2208
+ }
2209
+
2210
+ // onode is a top-level node (inside function block), later verified
2211
+ // node is inner match, descent in multiple steps
2212
+ var onode = null;
2213
+ var declaratorName = null;
2214
+ if (node.type === "VariableDeclarator") {
2215
+ onode = node.$parent;
2216
+ declaratorName = node.id.name;
2217
+ node = node.init; // var foo = ___;
2218
+ } else {
2219
+ onode = node;
2220
+ }
2104
2221
 
2105
2222
  // suspect must be inside of a block or at the top-level (i.e. inside of node.$parent.body[])
2106
- if (!node.$parent || is.noneof(node.$parent.type, ["Program", "BlockStatement"])) {
2223
+ if (!node || !onode.$parent || is.noneof(onode.$parent.type, ["Program", "BlockStatement"])) {
2107
2224
  return;
2108
2225
  }
2109
2226
 
2110
- var d0 = null;
2111
- var nr0 = node.range[0];
2112
- var nr1 = node.range[1];
2113
- if (node.type === "VariableDeclaration" && node.declarations.length === 1 &&
2114
- (d0 = node.declarations[0]).init && ctx.isFunctionExpressionWithArgs(d0.init)) {
2115
- var isSemicolonTerminated = (ctx.src[nr1 - 1] === ";");
2116
- addRemoveInjectArray(d0.init.params, nr0, isSemicolonTerminated ? nr1 : d0.init.range[1], d0.id.name);
2227
+ var insertPos = onode.range[1];
2228
+ var isSemicolonTerminated = (ctx.src[insertPos - 1] === ";");
2229
+
2230
+ node = jumpOverIife(node);
2231
+
2232
+ if (ctx.isFunctionExpressionWithArgs(node)) {
2233
+ // var x = 1, y = function(a,b) {}, z;
2234
+
2235
+ assert(declaratorName);
2236
+ addRemoveInjectArray(node.params, isSemicolonTerminated ? insertPos : node.range[1], declaratorName);
2237
+
2117
2238
  } else if (ctx.isFunctionDeclarationWithArgs(node)) {
2118
- addRemoveInjectArray(node.params, nr0, nr1, node.id.name);
2239
+ // /*@ngInject*/ function foo($scope) {}
2240
+
2241
+ addRemoveInjectArray(node.params, insertPos, node.id.name);
2242
+
2119
2243
  } else if (node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" &&
2120
2244
  ctx.isFunctionExpressionWithArgs(node.expression.right)) {
2121
- var isSemicolonTerminated$0 = (ctx.src[nr1 - 1] === ";");
2245
+ // /*@ngInject*/ foo.bar[0] = function($scope) {}
2246
+
2122
2247
  var name = ctx.srcForRange(node.expression.left.range);
2123
- addRemoveInjectArray(node.expression.right.params, nr0, isSemicolonTerminated$0 ? nr1 : node.expression.right.range[1], name);
2248
+ addRemoveInjectArray(node.expression.right.params, isSemicolonTerminated ? insertPos : node.expression.right.range[1], name);
2249
+
2250
+ } else if (node = followReference(node)) {
2251
+ // node was a reference and followed node now is either a
2252
+ // FunctionDeclaration or a VariableDeclarator
2253
+ // => recurse
2254
+
2255
+ judgeInjectArraySuspect(node, ctx);
2124
2256
  }
2125
2257
 
2258
+
2126
2259
  function getIndent(pos) {
2127
2260
  var src = ctx.src;
2128
2261
  var lineStart = src.lastIndexOf("\n", pos - 1) + 1;
@@ -2132,7 +2265,7 @@ function judgeInjectArraySuspect(node, ctx) {
2132
2265
  return src.slice(lineStart, i);
2133
2266
  }
2134
2267
 
2135
- function addRemoveInjectArray(params, posAtFunctionDeclaration, posAfterFunctionDeclaration, name) {
2268
+ function addRemoveInjectArray(params, posAfterFunctionDeclaration, name) {
2136
2269
  // if an existing something.$inject = [..] exists then is will always be recycled when rebuilding
2137
2270
 
2138
2271
  var indent = getIndent(posAfterFunctionDeclaration);
@@ -2140,8 +2273,8 @@ function judgeInjectArraySuspect(node, ctx) {
2140
2273
  var foundSuspectInBody = false;
2141
2274
  var existingExpressionStatementWithArray = null;
2142
2275
  var troublesomeReturn = false;
2143
- node.$parent.body.forEach(function(bnode) {
2144
- if (bnode === node) {
2276
+ onode.$parent.body.forEach(function(bnode) {
2277
+ if (bnode === onode) {
2145
2278
  foundSuspectInBody = true;
2146
2279
  }
2147
2280
 
@@ -2175,15 +2308,6 @@ function judgeInjectArraySuspect(node, ctx) {
2175
2308
  (lvalue.computed === true && ctx.srcForRange(lvalue.object.range) === name && lvalue.property.type === "Literal" && lvalue.property.value === "$inject")));
2176
2309
  }
2177
2310
 
2178
- function skipNewline(pos) {
2179
- if (ctx.src[pos] === "\n") {
2180
- return pos + 1;
2181
- } else if (ctx.src.slice(pos, pos + 2) === "\r\n") {
2182
- return pos + 2;
2183
- }
2184
- return pos;
2185
- }
2186
-
2187
2311
  function skipPrevNewline(pos) {
2188
2312
  var prevLF = ctx.src.lastIndexOf("\n", pos);
2189
2313
  if (prevLF === -1) {
@@ -2226,13 +2350,18 @@ function judgeInjectArraySuspect(node, ctx) {
2226
2350
 
2227
2351
  function jumpOverIife(node) {
2228
2352
  var outerfn;
2229
- var outerbody;
2230
- if (node.type === "CallExpression" &&
2231
- (outerfn = node.callee).type === "FunctionExpression" &&
2232
- (outerbody = outerfn.body.body).length === 1 &&
2233
- outerbody[0].type === "ReturnStatement" && outerbody[0].argument) {
2234
- return outerbody[0].argument;
2353
+ if (!(node.type === "CallExpression" && (outerfn = node.callee).type === "FunctionExpression")) {
2354
+ return node;
2355
+ }
2356
+
2357
+ var outerbody = outerfn.body.body;
2358
+ for (var i = 0; i < outerbody.length; i++) {
2359
+ var statement = outerbody[i];
2360
+ if (statement.type === "ReturnStatement") {
2361
+ return statement.argument;
2362
+ }
2235
2363
  }
2364
+
2236
2365
  return node;
2237
2366
  }
2238
2367
 
@@ -2277,37 +2406,58 @@ window.annotate = function ngAnnotate(src, options) {
2277
2406
  }
2278
2407
  var ast;
2279
2408
  var stats = {};
2409
+
2410
+ // [{type: "Block"|"Line", value: str, range: [from,to]}, ..]
2411
+ var comments = [];
2412
+
2413
+ stats.parser_require_t0 = Date.now();
2414
+ if (!options.es6) {
2415
+ parser = require("esprima").parse;
2416
+ } else {
2417
+ parser = require("acorn").parse;
2418
+ }
2419
+ stats.parser_require_t1 = Date.now();
2420
+
2280
2421
  try {
2281
- stats.esprima_require_t0 = esprima_require_t0;
2282
- stats.esprima_require_t1 = esprima_require_t1;
2283
- stats.esprima_parse_t0 = Date.now();
2422
+ stats.parser_parse_t0 = Date.now();
2284
2423
 
2285
- ast = esprima(src, {
2286
- range: true,
2287
- comment: true,
2288
- });
2424
+ if (!options.es6) {
2425
+ // esprima
2426
+ ast = parser(src, {
2427
+ range: true,
2428
+ comment: true,
2429
+ });
2430
+
2431
+ // Fix Program node range (https://code.google.com/p/esprima/issues/detail?id=541)
2432
+ ast.range[0] = 0;
2433
+
2434
+ // detach comments from ast
2435
+ comments = ast.comments;
2436
+ ast.comments = null;
2437
+
2438
+ } else {
2439
+ // acorn
2440
+ ast = parser(src, {
2441
+ ecmaVersion: 6,
2442
+ locations: true,
2443
+ ranges: true,
2444
+ onComment: comments,
2445
+ });
2446
+ }
2289
2447
 
2290
- stats.esprima_parse_t1 = Date.now();
2448
+ stats.parser_parse_t1 = Date.now();
2291
2449
  } catch(e) {
2292
2450
  return {
2293
2451
  errors: ["error: couldn't process source due to parse error", e.message],
2294
2452
  };
2295
2453
  }
2296
2454
 
2297
- // Fix Program node range (https://code.google.com/p/esprima/issues/detail?id=541)
2298
- ast.range[0] = 0;
2299
-
2300
2455
  // append a dummy-node to ast so that lut.findNodeFromPos(lastPos) returns something
2301
2456
  ast.body.push({
2302
2457
  type: "DebuggerStatement",
2303
2458
  range: [ast.range[1], ast.range[1]],
2304
2459
  });
2305
2460
 
2306
- // detach comments from ast
2307
- // [{type: "Block"|"Line", value: str, range: [from,to]}, ..]
2308
- var comments = ast.comments;
2309
- ast.comments = null;
2310
-
2311
2461
  // all source modifications are built up as operations in the
2312
2462
  // fragments array, later sent to alter in one shot
2313
2463
  var fragments = [];
@@ -2403,7 +2553,7 @@ window.annotate = function ngAnnotate(src, options) {
2403
2553
  return result;
2404
2554
  }
2405
2555
 
2406
- },{"./generate-sourcemap":8,"./lut":9,"./nginject":11,"./scopetools":13,"alter":14,"assert":1,"esprima":15,"ordered-ast-traverse":17,"os":3,"simple-fmt":18,"simple-is":19,"stringmap":31}],11:[function(require,module,exports){
2556
+ },{"./generate-sourcemap":8,"./lut":9,"./nginject":11,"./scopetools":13,"acorn":14,"alter":15,"assert":1,"esprima":16,"ordered-ast-traverse":18,"os":3,"simple-fmt":19,"simple-is":20,"stringmap":32}],11:[function(require,module,exports){
2407
2557
  // nginject-comments.js
2408
2558
  // MIT licensed, see LICENSE file
2409
2559
  // Copyright (c) 2013-2014 Olov Lassus <olov.lassus@gmail.com>
@@ -2485,7 +2635,7 @@ function nestedObjectValues(node, res) {
2485
2635
  return res;
2486
2636
  }
2487
2637
 
2488
- },{"simple-fmt":18,"simple-is":19}],12:[function(require,module,exports){
2638
+ },{"simple-fmt":19,"simple-is":20}],12:[function(require,module,exports){
2489
2639
  // scope.js
2490
2640
  // MIT licensed, see LICENSE file
2491
2641
  // Copyright (c) 2013-2014 Olov Lassus <olov.lassus@gmail.com>
@@ -2608,226 +2758,2815 @@ Scope.prototype.getFromPos = function(name) {
2608
2758
  return decl ? decl.from : null;
2609
2759
  };
2610
2760
 
2611
- Scope.prototype.hasOwn = function(name) {
2612
- return this.decls.has(name);
2613
- };
2761
+ Scope.prototype.hasOwn = function(name) {
2762
+ return this.decls.has(name);
2763
+ };
2764
+
2765
+ Scope.prototype.remove = function(name) {
2766
+ return this.decls.remove(name);
2767
+ };
2768
+
2769
+ Scope.prototype.doesPropagate = function(name) {
2770
+ return this.propagates.has(name);
2771
+ };
2772
+
2773
+ Scope.prototype.markPropagates = function(name) {
2774
+ this.propagates.add(name);
2775
+ };
2776
+
2777
+ Scope.prototype.closestHoistScope = function() {
2778
+ var scope = this;
2779
+ while (scope.kind !== "hoist") {
2780
+ scope = scope.parent;
2781
+ }
2782
+ return scope;
2783
+ };
2784
+
2785
+ Scope.prototype.lookup = function(name) {
2786
+ for (var scope = this; scope; scope = scope.parent) {
2787
+ if (scope.decls.has(name)) {
2788
+ return scope;
2789
+ } else if (scope.kind === "hoist") {
2790
+ scope.propagates.add(name);
2791
+ }
2792
+ }
2793
+ return null;
2794
+ };
2795
+
2796
+ module.exports = Scope;
2797
+
2798
+ },{"assert":1,"simple-fmt":19,"simple-is":20,"stringmap":32,"stringset":33}],13:[function(require,module,exports){
2799
+ // scopetools.js
2800
+ // MIT licensed, see LICENSE file
2801
+ // Copyright (c) 2013-2014 Olov Lassus <olov.lassus@gmail.com>
2802
+
2803
+ "use strict";
2804
+
2805
+ var assert = require("assert");
2806
+ var traverse = require("ordered-ast-traverse");
2807
+ var Scope = require("./scope");
2808
+ var is = require("simple-is");
2809
+
2810
+ module.exports = {
2811
+ setupScopeAndReferences: setupScopeAndReferences,
2812
+ isReference: isReference,
2813
+ };
2814
+
2815
+ function setupScopeAndReferences(root) {
2816
+ traverse(root, {pre: createScopes});
2817
+ createTopScope(root.$scope);
2818
+ }
2819
+
2820
+ function createScopes(node, parent) {
2821
+ node.$parent = parent;
2822
+ node.$scope = parent ? parent.$scope : null; // may be overridden
2823
+
2824
+ if (isNonFunctionBlock(node, parent)) {
2825
+ // A block node is a scope unless parent is a function
2826
+ node.$scope = new Scope({
2827
+ kind: "block",
2828
+ node: node,
2829
+ parent: parent.$scope,
2830
+ });
2831
+
2832
+ } else if (node.type === "VariableDeclaration") {
2833
+ // Variable declarations names goes in current scope
2834
+ node.declarations.forEach(function(declarator) {
2835
+ var name = declarator.id.name;
2836
+ node.$scope.add(name, node.kind, declarator.id, declarator.range[1]);
2837
+ });
2838
+
2839
+ } else if (isFunction(node)) {
2840
+ // Function is a scope, with params in it
2841
+ // There's no block-scope under it
2842
+
2843
+ node.$scope = new Scope({
2844
+ kind: "hoist",
2845
+ node: node,
2846
+ parent: parent.$scope,
2847
+ });
2848
+
2849
+ // function has a name
2850
+ if (node.id) {
2851
+ if (node.type === "FunctionDeclaration") {
2852
+ // Function name goes in parent scope for declared functions
2853
+ parent.$scope.add(node.id.name, "fun", node.id, null);
2854
+ } else if (node.type === "FunctionExpression") {
2855
+ // Function name goes in function's scope for named function expressions
2856
+ node.$scope.add(node.id.name, "fun", node.id, null);
2857
+ } else {
2858
+ assert(false);
2859
+ }
2860
+ }
2861
+
2862
+ node.params.forEach(function(param) {
2863
+ node.$scope.add(param.name, "param", param, null);
2864
+ });
2865
+
2866
+ } else if (isForWithConstLet(node) || isForInOfWithConstLet(node)) {
2867
+ // For(In/Of) loop with const|let declaration is a scope, with declaration in it
2868
+ // There may be a block-scope under it
2869
+ node.$scope = new Scope({
2870
+ kind: "block",
2871
+ node: node,
2872
+ parent: parent.$scope,
2873
+ });
2874
+
2875
+ } else if (node.type === "CatchClause") {
2876
+ var identifier = node.param;
2877
+
2878
+ node.$scope = new Scope({
2879
+ kind: "catch-block",
2880
+ node: node,
2881
+ parent: parent.$scope,
2882
+ });
2883
+ node.$scope.add(identifier.name, "caught", identifier, null);
2884
+
2885
+ // All hoist-scope keeps track of which variables that are propagated through,
2886
+ // i.e. an reference inside the scope points to a declaration outside the scope.
2887
+ // This is used to mark "taint" the name since adding a new variable in the scope,
2888
+ // with a propagated name, would change the meaning of the existing references.
2889
+ //
2890
+ // catch(e) is special because even though e is a variable in its own scope,
2891
+ // we want to make sure that catch(e){let e} is never transformed to
2892
+ // catch(e){var e} (but rather var e$0). For that reason we taint the use of e
2893
+ // in the closest hoist-scope, i.e. where var e$0 belongs.
2894
+ node.$scope.closestHoistScope().markPropagates(identifier.name);
2895
+
2896
+ } else if (node.type === "Program") {
2897
+ // Top-level program is a scope
2898
+ // There's no block-scope under it
2899
+ node.$scope = new Scope({
2900
+ kind: "hoist",
2901
+ node: node,
2902
+ parent: null,
2903
+ });
2904
+ }
2905
+ }
2906
+
2907
+ function createTopScope(programScope) {
2908
+ function inject(obj) {
2909
+ for (var name in obj) {
2910
+ var writeable = obj[name];
2911
+ var kind = (writeable ? "var" : "const");
2912
+ if (topScope.hasOwn(name)) {
2913
+ topScope.remove(name);
2914
+ }
2915
+ topScope.add(name, kind, {loc: {start: {line: -1}}}, -1);
2916
+ }
2917
+ }
2918
+
2919
+ var topScope = new Scope({
2920
+ kind: "hoist",
2921
+ node: {},
2922
+ parent: null,
2923
+ });
2924
+
2925
+ var complementary = {
2926
+ undefined: false,
2927
+ Infinity: false,
2928
+ console: false,
2929
+ };
2930
+
2931
+ inject(complementary);
2932
+ // inject(jshint_vars.reservedVars);
2933
+ // inject(jshint_vars.ecmaIdentifiers);
2934
+
2935
+ // link it in
2936
+ programScope.parent = topScope;
2937
+ topScope.children.push(programScope);
2938
+
2939
+ return topScope;
2940
+ }
2941
+
2942
+ function isConstLet(kind) {
2943
+ return kind === "const" || kind === "let";
2944
+ }
2945
+
2946
+ function isNonFunctionBlock(node, parent) {
2947
+ return node.type === "BlockStatement" && parent.type !== "FunctionDeclaration" && parent.type !== "FunctionExpression";
2948
+ }
2949
+
2950
+ function isForWithConstLet(node) {
2951
+ return node.type === "ForStatement" && node.init && node.init.type === "VariableDeclaration" && isConstLet(node.init.kind);
2952
+ }
2953
+
2954
+ function isForInOfWithConstLet(node) {
2955
+ return isForInOf(node) && node.left.type === "VariableDeclaration" && isConstLet(node.left.kind);
2956
+ }
2957
+
2958
+ function isForInOf(node) {
2959
+ return node.type === "ForInStatement" || node.type === "ForOfStatement";
2960
+ }
2961
+
2962
+ function isFunction(node) {
2963
+ return node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
2964
+ }
2965
+
2966
+ function isReference(node) {
2967
+ var parent = node.$parent;
2968
+ return node.$refToScope ||
2969
+ node.type === "Identifier" &&
2970
+ !(parent.type === "VariableDeclarator" && parent.id === node) && // var|let|const $
2971
+ !(parent.type === "MemberExpression" && parent.computed === false && parent.property === node) && // obj.$
2972
+ !(parent.type === "Property" && parent.key === node) && // {$: ...}
2973
+ !(parent.type === "LabeledStatement" && parent.label === node) && // $: ...
2974
+ !(parent.type === "CatchClause" && parent.param === node) && // catch($)
2975
+ !(isFunction(parent) && parent.id === node) && // function $(..
2976
+ !(isFunction(parent) && is.someof(node, parent.params)) && // function f($)..
2977
+ true;
2978
+ }
2979
+
2980
+ },{"./scope":12,"assert":1,"ordered-ast-traverse":18,"simple-is":20}],14:[function(require,module,exports){
2981
+ // Acorn is a tiny, fast JavaScript parser written in JavaScript.
2982
+ //
2983
+ // Acorn was written by Marijn Haverbeke and various contributors and
2984
+ // released under an MIT license. The Unicode regexps (for identifiers
2985
+ // and whitespace) were taken from [Esprima](http://esprima.org) by
2986
+ // Ariya Hidayat.
2987
+ //
2988
+ // Git repositories for Acorn are available at
2989
+ //
2990
+ // http://marijnhaverbeke.nl/git/acorn
2991
+ // https://github.com/marijnh/acorn.git
2992
+ //
2993
+ // Please use the [github bug tracker][ghbt] to report issues.
2994
+ //
2995
+ // [ghbt]: https://github.com/marijnh/acorn/issues
2996
+ //
2997
+ // This file defines the main parser interface. The library also comes
2998
+ // with a [error-tolerant parser][dammit] and an
2999
+ // [abstract syntax tree walker][walk], defined in other files.
3000
+ //
3001
+ // [dammit]: acorn_loose.js
3002
+ // [walk]: util/walk.js
3003
+
3004
+ (function(root, mod) {
3005
+ if (typeof exports == "object" && typeof module == "object") return mod(exports); // CommonJS
3006
+ if (typeof define == "function" && define.amd) return define(["exports"], mod); // AMD
3007
+ mod(root.acorn || (root.acorn = {})); // Plain browser env
3008
+ })(this, function(exports) {
3009
+ "use strict";
3010
+
3011
+ exports.version = "0.9.0";
3012
+
3013
+ // The main exported interface (under `self.acorn` when in the
3014
+ // browser) is a `parse` function that takes a code string and
3015
+ // returns an abstract syntax tree as specified by [Mozilla parser
3016
+ // API][api], with the caveat that inline XML is not recognized.
3017
+ //
3018
+ // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
3019
+
3020
+ var options, input, inputLen, sourceFile;
3021
+
3022
+ exports.parse = function(inpt, opts) {
3023
+ input = String(inpt); inputLen = input.length;
3024
+ setOptions(opts);
3025
+ initTokenState();
3026
+ initParserState();
3027
+ return parseTopLevel(options.program);
3028
+ };
3029
+
3030
+ // A second optional argument can be given to further configure
3031
+ // the parser process. These options are recognized:
3032
+
3033
+ var defaultOptions = exports.defaultOptions = {
3034
+ // `ecmaVersion` indicates the ECMAScript version to parse. Must
3035
+ // be either 3, or 5, or 6. This influences support for strict
3036
+ // mode, the set of reserved words, support for getters and
3037
+ // setters and other features.
3038
+ ecmaVersion: 5,
3039
+ // Turn on `strictSemicolons` to prevent the parser from doing
3040
+ // automatic semicolon insertion.
3041
+ strictSemicolons: false,
3042
+ // When `allowTrailingCommas` is false, the parser will not allow
3043
+ // trailing commas in array and object literals.
3044
+ allowTrailingCommas: true,
3045
+ // By default, reserved words are not enforced. Enable
3046
+ // `forbidReserved` to enforce them. When this option has the
3047
+ // value "everywhere", reserved words and keywords can also not be
3048
+ // used as property names.
3049
+ forbidReserved: false,
3050
+ // When enabled, a return at the top level is not considered an
3051
+ // error.
3052
+ allowReturnOutsideFunction: false,
3053
+ // When `locations` is on, `loc` properties holding objects with
3054
+ // `start` and `end` properties in `{line, column}` form (with
3055
+ // line being 1-based and column 0-based) will be attached to the
3056
+ // nodes.
3057
+ locations: false,
3058
+ // A function can be passed as `onToken` option, which will
3059
+ // cause Acorn to call that function with object in the same
3060
+ // format as tokenize() returns. Note that you are not
3061
+ // allowed to call the parser from the callback—that will
3062
+ // corrupt its internal state.
3063
+ onToken: null,
3064
+ // A function can be passed as `onComment` option, which will
3065
+ // cause Acorn to call that function with `(block, text, start,
3066
+ // end)` parameters whenever a comment is skipped. `block` is a
3067
+ // boolean indicating whether this is a block (`/* */`) comment,
3068
+ // `text` is the content of the comment, and `start` and `end` are
3069
+ // character offsets that denote the start and end of the comment.
3070
+ // When the `locations` option is on, two more parameters are
3071
+ // passed, the full `{line, column}` locations of the start and
3072
+ // end of the comments. Note that you are not allowed to call the
3073
+ // parser from the callback—that will corrupt its internal state.
3074
+ onComment: null,
3075
+ // Nodes have their start and end characters offsets recorded in
3076
+ // `start` and `end` properties (directly on the node, rather than
3077
+ // the `loc` object, which holds line/column data. To also add a
3078
+ // [semi-standardized][range] `range` property holding a `[start,
3079
+ // end]` array with the same numbers, set the `ranges` option to
3080
+ // `true`.
3081
+ //
3082
+ // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
3083
+ ranges: false,
3084
+ // It is possible to parse multiple files into a single AST by
3085
+ // passing the tree produced by parsing the first file as
3086
+ // `program` option in subsequent parses. This will add the
3087
+ // toplevel forms of the parsed file to the `Program` (top) node
3088
+ // of an existing parse tree.
3089
+ program: null,
3090
+ // When `locations` is on, you can pass this to record the source
3091
+ // file in every node's `loc` object.
3092
+ sourceFile: null,
3093
+ // This value, if given, is stored in every node, whether
3094
+ // `locations` is on or off.
3095
+ directSourceFile: null
3096
+ };
3097
+
3098
+ // This function tries to parse a single expression at a given
3099
+ // offset in a string. Useful for parsing mixed-language formats
3100
+ // that embed JavaScript expressions.
3101
+
3102
+ exports.parseExpressionAt = function(inpt, pos, opts) {
3103
+ input = String(inpt); inputLen = input.length;
3104
+ setOptions(opts);
3105
+ initTokenState(pos);
3106
+ initParserState();
3107
+ return parseExpression();
3108
+ };
3109
+
3110
+ var isArray = function (obj) {
3111
+ return Object.prototype.toString.call(obj) === "[object Array]";
3112
+ };
3113
+
3114
+ function setOptions(opts) {
3115
+ options = opts || {};
3116
+ for (var opt in defaultOptions) if (!has(options, opt))
3117
+ options[opt] = defaultOptions[opt];
3118
+ sourceFile = options.sourceFile || null;
3119
+ if (isArray(options.onToken)) {
3120
+ var tokens = options.onToken;
3121
+ options.onToken = function (token) {
3122
+ tokens.push(token);
3123
+ };
3124
+ }
3125
+ if (isArray(options.onComment)) {
3126
+ var comments = options.onComment;
3127
+ options.onComment = function (block, text, start, end, startLoc, endLoc) {
3128
+ var comment = {
3129
+ type: block ? 'Block' : 'Line',
3130
+ value: text,
3131
+ start: start,
3132
+ end: end
3133
+ };
3134
+ if (options.locations) {
3135
+ comment.loc = new SourceLocation();
3136
+ comment.loc.start = startLoc;
3137
+ comment.loc.end = endLoc;
3138
+ }
3139
+ if (options.ranges)
3140
+ comment.range = [start, end];
3141
+ comments.push(comment);
3142
+ };
3143
+ }
3144
+ isKeyword = options.ecmaVersion >= 6 ? isEcma6Keyword : isEcma5AndLessKeyword;
3145
+ }
3146
+
3147
+ // The `getLineInfo` function is mostly useful when the
3148
+ // `locations` option is off (for performance reasons) and you
3149
+ // want to find the line/column position for a given character
3150
+ // offset. `input` should be the code string that the offset refers
3151
+ // into.
3152
+
3153
+ var getLineInfo = exports.getLineInfo = function(input, offset) {
3154
+ for (var line = 1, cur = 0;;) {
3155
+ lineBreak.lastIndex = cur;
3156
+ var match = lineBreak.exec(input);
3157
+ if (match && match.index < offset) {
3158
+ ++line;
3159
+ cur = match.index + match[0].length;
3160
+ } else break;
3161
+ }
3162
+ return {line: line, column: offset - cur};
3163
+ };
3164
+
3165
+ function Token() {
3166
+ this.type = tokType;
3167
+ this.value = tokVal;
3168
+ this.start = tokStart;
3169
+ this.end = tokEnd;
3170
+ if (options.locations) {
3171
+ this.loc = new SourceLocation();
3172
+ this.loc.end = tokEndLoc;
3173
+ // TODO: remove in next major release
3174
+ this.startLoc = tokStartLoc;
3175
+ this.endLoc = tokEndLoc;
3176
+ }
3177
+ if (options.ranges)
3178
+ this.range = [tokStart, tokEnd];
3179
+ }
3180
+
3181
+ exports.Token = Token;
3182
+
3183
+ // Acorn is organized as a tokenizer and a recursive-descent parser.
3184
+ // The `tokenize` export provides an interface to the tokenizer.
3185
+ // Because the tokenizer is optimized for being efficiently used by
3186
+ // the Acorn parser itself, this interface is somewhat crude and not
3187
+ // very modular. Performing another parse or call to `tokenize` will
3188
+ // reset the internal state, and invalidate existing tokenizers.
3189
+
3190
+ exports.tokenize = function(inpt, opts) {
3191
+ input = String(inpt); inputLen = input.length;
3192
+ setOptions(opts);
3193
+ initTokenState();
3194
+
3195
+ function getToken(forceRegexp) {
3196
+ lastEnd = tokEnd;
3197
+ readToken(forceRegexp);
3198
+ return new Token();
3199
+ }
3200
+ getToken.jumpTo = function(pos, reAllowed) {
3201
+ tokPos = pos;
3202
+ if (options.locations) {
3203
+ tokCurLine = 1;
3204
+ tokLineStart = lineBreak.lastIndex = 0;
3205
+ var match;
3206
+ while ((match = lineBreak.exec(input)) && match.index < pos) {
3207
+ ++tokCurLine;
3208
+ tokLineStart = match.index + match[0].length;
3209
+ }
3210
+ }
3211
+ tokRegexpAllowed = reAllowed;
3212
+ skipSpace();
3213
+ };
3214
+ return getToken;
3215
+ };
3216
+
3217
+ // State is kept in (closure-)global variables. We already saw the
3218
+ // `options`, `input`, and `inputLen` variables above.
3219
+
3220
+ // The current position of the tokenizer in the input.
3221
+
3222
+ var tokPos;
3223
+
3224
+ // The start and end offsets of the current token.
3225
+
3226
+ var tokStart, tokEnd;
3227
+
3228
+ // When `options.locations` is true, these hold objects
3229
+ // containing the tokens start and end line/column pairs.
3230
+
3231
+ var tokStartLoc, tokEndLoc;
3232
+
3233
+ // The type and value of the current token. Token types are objects,
3234
+ // named by variables against which they can be compared, and
3235
+ // holding properties that describe them (indicating, for example,
3236
+ // the precedence of an infix operator, and the original name of a
3237
+ // keyword token). The kind of value that's held in `tokVal` depends
3238
+ // on the type of the token. For literals, it is the literal value,
3239
+ // for operators, the operator name, and so on.
3240
+
3241
+ var tokType, tokVal;
3242
+
3243
+ // Internal state for the tokenizer. To distinguish between division
3244
+ // operators and regular expressions, it remembers whether the last
3245
+ // token was one that is allowed to be followed by an expression.
3246
+ // (If it is, a slash is probably a regexp, if it isn't it's a
3247
+ // division operator. See the `parseStatement` function for a
3248
+ // caveat.)
3249
+
3250
+ var tokRegexpAllowed;
3251
+
3252
+ // When `options.locations` is true, these are used to keep
3253
+ // track of the current line, and know when a new line has been
3254
+ // entered.
3255
+
3256
+ var tokCurLine, tokLineStart;
3257
+
3258
+ // These store the position of the previous token, which is useful
3259
+ // when finishing a node and assigning its `end` position.
3260
+
3261
+ var lastStart, lastEnd, lastEndLoc;
3262
+
3263
+ // This is the parser's state. `inFunction` is used to reject
3264
+ // `return` statements outside of functions, `inGenerator` to
3265
+ // reject `yield`s outside of generators, `labels` to verify
3266
+ // that `break` and `continue` have somewhere to jump to, and
3267
+ // `strict` indicates whether strict mode is on.
3268
+
3269
+ var inFunction, inGenerator, labels, strict;
3270
+
3271
+ // This counter is used for checking that arrow expressions did
3272
+ // not contain nested parentheses in argument list.
3273
+
3274
+ var metParenL;
3275
+
3276
+ // This is used by parser for detecting if it's inside ES6
3277
+ // Template String. If it is, it should treat '$' as prefix before
3278
+ // '{expression}' and everything else as string literals.
3279
+
3280
+ var inTemplate;
3281
+
3282
+ function initParserState() {
3283
+ lastStart = lastEnd = tokPos;
3284
+ if (options.locations) lastEndLoc = new Position;
3285
+ inFunction = inGenerator = strict = false;
3286
+ labels = [];
3287
+ readToken();
3288
+ }
3289
+
3290
+ // This function is used to raise exceptions on parse errors. It
3291
+ // takes an offset integer (into the current `input`) to indicate
3292
+ // the location of the error, attaches the position to the end
3293
+ // of the error message, and then raises a `SyntaxError` with that
3294
+ // message.
3295
+
3296
+ function raise(pos, message) {
3297
+ var loc = getLineInfo(input, pos);
3298
+ message += " (" + loc.line + ":" + loc.column + ")";
3299
+ var err = new SyntaxError(message);
3300
+ err.pos = pos; err.loc = loc; err.raisedAt = tokPos;
3301
+ throw err;
3302
+ }
3303
+
3304
+ // Reused empty array added for node fields that are always empty.
3305
+
3306
+ var empty = [];
3307
+
3308
+ // ## Token types
3309
+
3310
+ // The assignment of fine-grained, information-carrying type objects
3311
+ // allows the tokenizer to store the information it has about a
3312
+ // token in a way that is very cheap for the parser to look up.
3313
+
3314
+ // All token type variables start with an underscore, to make them
3315
+ // easy to recognize.
3316
+
3317
+ // These are the general types. The `type` property is only used to
3318
+ // make them recognizeable when debugging.
3319
+
3320
+ var _num = {type: "num"}, _regexp = {type: "regexp"}, _string = {type: "string"};
3321
+ var _name = {type: "name"}, _eof = {type: "eof"};
3322
+
3323
+ // Keyword tokens. The `keyword` property (also used in keyword-like
3324
+ // operators) indicates that the token originated from an
3325
+ // identifier-like word, which is used when parsing property names.
3326
+ //
3327
+ // The `beforeExpr` property is used to disambiguate between regular
3328
+ // expressions and divisions. It is set on all token types that can
3329
+ // be followed by an expression (thus, a slash after them would be a
3330
+ // regular expression).
3331
+ //
3332
+ // `isLoop` marks a keyword as starting a loop, which is important
3333
+ // to know when parsing a label, in order to allow or disallow
3334
+ // continue jumps to that label.
3335
+
3336
+ var _break = {keyword: "break"}, _case = {keyword: "case", beforeExpr: true}, _catch = {keyword: "catch"};
3337
+ var _continue = {keyword: "continue"}, _debugger = {keyword: "debugger"}, _default = {keyword: "default"};
3338
+ var _do = {keyword: "do", isLoop: true}, _else = {keyword: "else", beforeExpr: true};
3339
+ var _finally = {keyword: "finally"}, _for = {keyword: "for", isLoop: true}, _function = {keyword: "function"};
3340
+ var _if = {keyword: "if"}, _return = {keyword: "return", beforeExpr: true}, _switch = {keyword: "switch"};
3341
+ var _throw = {keyword: "throw", beforeExpr: true}, _try = {keyword: "try"}, _var = {keyword: "var"};
3342
+ var _let = {keyword: "let"}, _const = {keyword: "const"};
3343
+ var _while = {keyword: "while", isLoop: true}, _with = {keyword: "with"}, _new = {keyword: "new", beforeExpr: true};
3344
+ var _this = {keyword: "this"};
3345
+ var _class = {keyword: "class"}, _extends = {keyword: "extends", beforeExpr: true};
3346
+ var _export = {keyword: "export"}, _import = {keyword: "import"};
3347
+ var _yield = {keyword: "yield", beforeExpr: true};
3348
+
3349
+ // The keywords that denote values.
3350
+
3351
+ var _null = {keyword: "null", atomValue: null}, _true = {keyword: "true", atomValue: true};
3352
+ var _false = {keyword: "false", atomValue: false};
3353
+
3354
+ // Some keywords are treated as regular operators. `in` sometimes
3355
+ // (when parsing `for`) needs to be tested against specifically, so
3356
+ // we assign a variable name to it for quick comparing.
3357
+
3358
+ var _in = {keyword: "in", binop: 7, beforeExpr: true};
3359
+
3360
+ // Map keyword names to token types.
3361
+
3362
+ var keywordTypes = {"break": _break, "case": _case, "catch": _catch,
3363
+ "continue": _continue, "debugger": _debugger, "default": _default,
3364
+ "do": _do, "else": _else, "finally": _finally, "for": _for,
3365
+ "function": _function, "if": _if, "return": _return, "switch": _switch,
3366
+ "throw": _throw, "try": _try, "var": _var, "let": _let, "const": _const,
3367
+ "while": _while, "with": _with,
3368
+ "null": _null, "true": _true, "false": _false, "new": _new, "in": _in,
3369
+ "instanceof": {keyword: "instanceof", binop: 7, beforeExpr: true}, "this": _this,
3370
+ "typeof": {keyword: "typeof", prefix: true, beforeExpr: true},
3371
+ "void": {keyword: "void", prefix: true, beforeExpr: true},
3372
+ "delete": {keyword: "delete", prefix: true, beforeExpr: true},
3373
+ "class": _class, "extends": _extends,
3374
+ "export": _export, "import": _import, "yield": _yield};
3375
+
3376
+ // Punctuation token types. Again, the `type` property is purely for debugging.
3377
+
3378
+ var _bracketL = {type: "[", beforeExpr: true}, _bracketR = {type: "]"}, _braceL = {type: "{", beforeExpr: true};
3379
+ var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"};
3380
+ var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true};
3381
+ var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _ellipsis = {type: "..."}, _question = {type: "?", beforeExpr: true};
3382
+ var _arrow = {type: "=>", beforeExpr: true}, _bquote = {type: "`"}, _dollarBraceL = {type: "${", beforeExpr: true};
3383
+
3384
+ // Operators. These carry several kinds of properties to help the
3385
+ // parser use them properly (the presence of these properties is
3386
+ // what categorizes them as operators).
3387
+ //
3388
+ // `binop`, when present, specifies that this operator is a binary
3389
+ // operator, and will refer to its precedence.
3390
+ //
3391
+ // `prefix` and `postfix` mark the operator as a prefix or postfix
3392
+ // unary operator. `isUpdate` specifies that the node produced by
3393
+ // the operator should be of type UpdateExpression rather than
3394
+ // simply UnaryExpression (`++` and `--`).
3395
+ //
3396
+ // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
3397
+ // binary operators with a very low precedence, that should result
3398
+ // in AssignmentExpression nodes.
3399
+
3400
+ var _slash = {binop: 10, beforeExpr: true}, _eq = {isAssign: true, beforeExpr: true};
3401
+ var _assign = {isAssign: true, beforeExpr: true};
3402
+ var _incDec = {postfix: true, prefix: true, isUpdate: true}, _prefix = {prefix: true, beforeExpr: true};
3403
+ var _logicalOR = {binop: 1, beforeExpr: true};
3404
+ var _logicalAND = {binop: 2, beforeExpr: true};
3405
+ var _bitwiseOR = {binop: 3, beforeExpr: true};
3406
+ var _bitwiseXOR = {binop: 4, beforeExpr: true};
3407
+ var _bitwiseAND = {binop: 5, beforeExpr: true};
3408
+ var _equality = {binop: 6, beforeExpr: true};
3409
+ var _relational = {binop: 7, beforeExpr: true};
3410
+ var _bitShift = {binop: 8, beforeExpr: true};
3411
+ var _plusMin = {binop: 9, prefix: true, beforeExpr: true};
3412
+ var _modulo = {binop: 10, beforeExpr: true};
3413
+
3414
+ // '*' may be multiply or have special meaning in ES6
3415
+ var _star = {binop: 10, beforeExpr: true};
3416
+
3417
+ // Provide access to the token types for external users of the
3418
+ // tokenizer.
3419
+
3420
+ exports.tokTypes = {bracketL: _bracketL, bracketR: _bracketR, braceL: _braceL, braceR: _braceR,
3421
+ parenL: _parenL, parenR: _parenR, comma: _comma, semi: _semi, colon: _colon,
3422
+ dot: _dot, ellipsis: _ellipsis, question: _question, slash: _slash, eq: _eq,
3423
+ name: _name, eof: _eof, num: _num, regexp: _regexp, string: _string,
3424
+ arrow: _arrow, bquote: _bquote, dollarBraceL: _dollarBraceL};
3425
+ for (var kw in keywordTypes) exports.tokTypes["_" + kw] = keywordTypes[kw];
3426
+
3427
+ // This is a trick taken from Esprima. It turns out that, on
3428
+ // non-Chrome browsers, to check whether a string is in a set, a
3429
+ // predicate containing a big ugly `switch` statement is faster than
3430
+ // a regular expression, and on Chrome the two are about on par.
3431
+ // This function uses `eval` (non-lexical) to produce such a
3432
+ // predicate from a space-separated string of words.
3433
+ //
3434
+ // It starts by sorting the words by length.
3435
+
3436
+ function makePredicate(words) {
3437
+ words = words.split(" ");
3438
+ var f = "", cats = [];
3439
+ out: for (var i = 0; i < words.length; ++i) {
3440
+ for (var j = 0; j < cats.length; ++j)
3441
+ if (cats[j][0].length == words[i].length) {
3442
+ cats[j].push(words[i]);
3443
+ continue out;
3444
+ }
3445
+ cats.push([words[i]]);
3446
+ }
3447
+ function compareTo(arr) {
3448
+ if (arr.length == 1) return f += "return str === " + JSON.stringify(arr[0]) + ";";
3449
+ f += "switch(str){";
3450
+ for (var i = 0; i < arr.length; ++i) f += "case " + JSON.stringify(arr[i]) + ":";
3451
+ f += "return true}return false;";
3452
+ }
3453
+
3454
+ // When there are more than three length categories, an outer
3455
+ // switch first dispatches on the lengths, to save on comparisons.
3456
+
3457
+ if (cats.length > 3) {
3458
+ cats.sort(function(a, b) {return b.length - a.length;});
3459
+ f += "switch(str.length){";
3460
+ for (var i = 0; i < cats.length; ++i) {
3461
+ var cat = cats[i];
3462
+ f += "case " + cat[0].length + ":";
3463
+ compareTo(cat);
3464
+ }
3465
+ f += "}";
3466
+
3467
+ // Otherwise, simply generate a flat `switch` statement.
3468
+
3469
+ } else {
3470
+ compareTo(words);
3471
+ }
3472
+ return new Function("str", f);
3473
+ }
3474
+
3475
+ // The ECMAScript 3 reserved word list.
3476
+
3477
+ var isReservedWord3 = makePredicate("abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile");
3478
+
3479
+ // ECMAScript 5 reserved words.
3480
+
3481
+ var isReservedWord5 = makePredicate("class enum extends super const export import");
3482
+
3483
+ // The additional reserved words in strict mode.
3484
+
3485
+ var isStrictReservedWord = makePredicate("implements interface let package private protected public static yield");
3486
+
3487
+ // The forbidden variable names in strict mode.
3488
+
3489
+ var isStrictBadIdWord = makePredicate("eval arguments");
3490
+
3491
+ // And the keywords.
3492
+
3493
+ var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";
3494
+
3495
+ var isEcma5AndLessKeyword = makePredicate(ecma5AndLessKeywords);
3496
+
3497
+ var isEcma6Keyword = makePredicate(ecma5AndLessKeywords + " let const class extends export import yield");
3498
+
3499
+ var isKeyword = isEcma5AndLessKeyword;
3500
+
3501
+ // ## Character categories
3502
+
3503
+ // Big ugly regular expressions that match characters in the
3504
+ // whitespace, identifier, and identifier-start categories. These
3505
+ // are only applied when a character is found to actually have a
3506
+ // code point above 128.
3507
+ // Generated by `tools/generate-identifier-regex.js`.
3508
+
3509
+ var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
3510
+ var nonASCIIidentifierStartChars = "\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC";
3511
+ var nonASCIIidentifierChars = "\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u0669\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07C0-\u07C9\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0966-\u096F\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09E6-\u09EF\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A66-\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B66-\u0B6F\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0CE6-\u0CEF\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D66-\u0D6F\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0E50-\u0E59\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0ED0-\u0ED9\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1040-\u1049\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u18A9\u1920-\u192B\u1930-\u193B\u1946-\u194F\u19B0-\u19C0\u19C8\u19C9\u19D0-\u19D9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AB0-\u1ABD\u1B00-\u1B04\u1B34-\u1B44\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BB0-\u1BB9\u1BE6-\u1BF3\u1C24-\u1C37\u1C40-\u1C49\u1C50-\u1C59\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u200C\u200D\u203F\u2040\u2054\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA620-\uA629\uA66F\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F1\uA900-\uA909\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9D0-\uA9D9\uA9E5\uA9F0-\uA9F9\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA50-\uAA59\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uABF0-\uABF9\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFF10-\uFF19\uFF3F";
3512
+ var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
3513
+ var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
3514
+
3515
+ // Whether a single character denotes a newline.
3516
+
3517
+ var newline = /[\n\r\u2028\u2029]/;
3518
+
3519
+ // Matches a whole line break (where CRLF is considered a single
3520
+ // line break). Used to count lines.
3521
+
3522
+ var lineBreak = /\r\n|[\n\r\u2028\u2029]/g;
3523
+
3524
+ // Test whether a given character code starts an identifier.
3525
+
3526
+ var isIdentifierStart = exports.isIdentifierStart = function(code) {
3527
+ if (code < 65) return code === 36;
3528
+ if (code < 91) return true;
3529
+ if (code < 97) return code === 95;
3530
+ if (code < 123)return true;
3531
+ return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
3532
+ };
3533
+
3534
+ // Test whether a given character is part of an identifier.
3535
+
3536
+ var isIdentifierChar = exports.isIdentifierChar = function(code) {
3537
+ if (code < 48) return code === 36;
3538
+ if (code < 58) return true;
3539
+ if (code < 65) return false;
3540
+ if (code < 91) return true;
3541
+ if (code < 97) return code === 95;
3542
+ if (code < 123)return true;
3543
+ return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
3544
+ };
3545
+
3546
+ // ## Tokenizer
3547
+
3548
+ // These are used when `options.locations` is on, for the
3549
+ // `tokStartLoc` and `tokEndLoc` properties.
3550
+
3551
+ function Position() {
3552
+ this.line = tokCurLine;
3553
+ this.column = tokPos - tokLineStart;
3554
+ }
3555
+
3556
+ // Reset the token state. Used at the start of a parse.
3557
+
3558
+ function initTokenState(pos) {
3559
+ if (pos) {
3560
+ tokPos = pos;
3561
+ tokLineStart = Math.max(0, input.lastIndexOf("\n", pos));
3562
+ tokCurLine = input.slice(0, tokLineStart).split(newline).length;
3563
+ } else {
3564
+ tokCurLine = 1;
3565
+ tokPos = tokLineStart = 0;
3566
+ }
3567
+ tokRegexpAllowed = true;
3568
+ metParenL = 0;
3569
+ inTemplate = false;
3570
+ skipSpace();
3571
+ }
3572
+
3573
+ // Called at the end of every token. Sets `tokEnd`, `tokVal`, and
3574
+ // `tokRegexpAllowed`, and skips the space after the token, so that
3575
+ // the next one's `tokStart` will point at the right position.
3576
+
3577
+ function finishToken(type, val, shouldSkipSpace) {
3578
+ tokEnd = tokPos;
3579
+ if (options.locations) tokEndLoc = new Position;
3580
+ tokType = type;
3581
+ if (shouldSkipSpace !== false) skipSpace();
3582
+ tokVal = val;
3583
+ tokRegexpAllowed = type.beforeExpr;
3584
+ if (options.onToken) {
3585
+ options.onToken(new Token());
3586
+ }
3587
+ }
3588
+
3589
+ function skipBlockComment() {
3590
+ var startLoc = options.onComment && options.locations && new Position;
3591
+ var start = tokPos, end = input.indexOf("*/", tokPos += 2);
3592
+ if (end === -1) raise(tokPos - 2, "Unterminated comment");
3593
+ tokPos = end + 2;
3594
+ if (options.locations) {
3595
+ lineBreak.lastIndex = start;
3596
+ var match;
3597
+ while ((match = lineBreak.exec(input)) && match.index < tokPos) {
3598
+ ++tokCurLine;
3599
+ tokLineStart = match.index + match[0].length;
3600
+ }
3601
+ }
3602
+ if (options.onComment)
3603
+ options.onComment(true, input.slice(start + 2, end), start, tokPos,
3604
+ startLoc, options.locations && new Position);
3605
+ }
3606
+
3607
+ function skipLineComment(startSkip) {
3608
+ var start = tokPos;
3609
+ var startLoc = options.onComment && options.locations && new Position;
3610
+ var ch = input.charCodeAt(tokPos+=startSkip);
3611
+ while (tokPos < inputLen && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
3612
+ ++tokPos;
3613
+ ch = input.charCodeAt(tokPos);
3614
+ }
3615
+ if (options.onComment)
3616
+ options.onComment(false, input.slice(start + startSkip, tokPos), start, tokPos,
3617
+ startLoc, options.locations && new Position);
3618
+ }
3619
+
3620
+ // Called at the start of the parse and after every token. Skips
3621
+ // whitespace and comments, and.
3622
+
3623
+ function skipSpace() {
3624
+ while (tokPos < inputLen) {
3625
+ var ch = input.charCodeAt(tokPos);
3626
+ if (ch === 32) { // ' '
3627
+ ++tokPos;
3628
+ } else if (ch === 13) {
3629
+ ++tokPos;
3630
+ var next = input.charCodeAt(tokPos);
3631
+ if (next === 10) {
3632
+ ++tokPos;
3633
+ }
3634
+ if (options.locations) {
3635
+ ++tokCurLine;
3636
+ tokLineStart = tokPos;
3637
+ }
3638
+ } else if (ch === 10 || ch === 8232 || ch === 8233) {
3639
+ ++tokPos;
3640
+ if (options.locations) {
3641
+ ++tokCurLine;
3642
+ tokLineStart = tokPos;
3643
+ }
3644
+ } else if (ch > 8 && ch < 14) {
3645
+ ++tokPos;
3646
+ } else if (ch === 47) { // '/'
3647
+ var next = input.charCodeAt(tokPos + 1);
3648
+ if (next === 42) { // '*'
3649
+ skipBlockComment();
3650
+ } else if (next === 47) { // '/'
3651
+ skipLineComment(2);
3652
+ } else break;
3653
+ } else if (ch === 160) { // '\xa0'
3654
+ ++tokPos;
3655
+ } else if (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
3656
+ ++tokPos;
3657
+ } else {
3658
+ break;
3659
+ }
3660
+ }
3661
+ }
3662
+
3663
+ // ### Token reading
3664
+
3665
+ // This is the function that is called to fetch the next token. It
3666
+ // is somewhat obscure, because it works in character codes rather
3667
+ // than characters, and because operator parsing has been inlined
3668
+ // into it.
3669
+ //
3670
+ // All in the name of speed.
3671
+ //
3672
+ // The `forceRegexp` parameter is used in the one case where the
3673
+ // `tokRegexpAllowed` trick does not work. See `parseStatement`.
3674
+
3675
+ function readToken_dot() {
3676
+ var next = input.charCodeAt(tokPos + 1);
3677
+ if (next >= 48 && next <= 57) return readNumber(true);
3678
+ var next2 = input.charCodeAt(tokPos + 2);
3679
+ if (options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
3680
+ tokPos += 3;
3681
+ return finishToken(_ellipsis);
3682
+ } else {
3683
+ ++tokPos;
3684
+ return finishToken(_dot);
3685
+ }
3686
+ }
3687
+
3688
+ function readToken_slash() { // '/'
3689
+ var next = input.charCodeAt(tokPos + 1);
3690
+ if (tokRegexpAllowed) {++tokPos; return readRegexp();}
3691
+ if (next === 61) return finishOp(_assign, 2);
3692
+ return finishOp(_slash, 1);
3693
+ }
3694
+
3695
+ function readToken_mult_modulo(code) { // '%*'
3696
+ var next = input.charCodeAt(tokPos + 1);
3697
+ if (next === 61) return finishOp(_assign, 2);
3698
+ return finishOp(code === 42 ? _star : _modulo, 1);
3699
+ }
3700
+
3701
+ function readToken_pipe_amp(code) { // '|&'
3702
+ var next = input.charCodeAt(tokPos + 1);
3703
+ if (next === code) return finishOp(code === 124 ? _logicalOR : _logicalAND, 2);
3704
+ if (next === 61) return finishOp(_assign, 2);
3705
+ return finishOp(code === 124 ? _bitwiseOR : _bitwiseAND, 1);
3706
+ }
3707
+
3708
+ function readToken_caret() { // '^'
3709
+ var next = input.charCodeAt(tokPos + 1);
3710
+ if (next === 61) return finishOp(_assign, 2);
3711
+ return finishOp(_bitwiseXOR, 1);
3712
+ }
3713
+
3714
+ function readToken_plus_min(code) { // '+-'
3715
+ var next = input.charCodeAt(tokPos + 1);
3716
+ if (next === code) {
3717
+ if (next == 45 && input.charCodeAt(tokPos + 2) == 62 &&
3718
+ newline.test(input.slice(lastEnd, tokPos))) {
3719
+ // A `-->` line comment
3720
+ skipLineComment(3);
3721
+ skipSpace();
3722
+ return readToken();
3723
+ }
3724
+ return finishOp(_incDec, 2);
3725
+ }
3726
+ if (next === 61) return finishOp(_assign, 2);
3727
+ return finishOp(_plusMin, 1);
3728
+ }
3729
+
3730
+ function readToken_lt_gt(code) { // '<>'
3731
+ var next = input.charCodeAt(tokPos + 1);
3732
+ var size = 1;
3733
+ if (next === code) {
3734
+ size = code === 62 && input.charCodeAt(tokPos + 2) === 62 ? 3 : 2;
3735
+ if (input.charCodeAt(tokPos + size) === 61) return finishOp(_assign, size + 1);
3736
+ return finishOp(_bitShift, size);
3737
+ }
3738
+ if (next == 33 && code == 60 && input.charCodeAt(tokPos + 2) == 45 &&
3739
+ input.charCodeAt(tokPos + 3) == 45) {
3740
+ // `<!--`, an XML-style comment that should be interpreted as a line comment
3741
+ skipLineComment(4);
3742
+ skipSpace();
3743
+ return readToken();
3744
+ }
3745
+ if (next === 61)
3746
+ size = input.charCodeAt(tokPos + 2) === 61 ? 3 : 2;
3747
+ return finishOp(_relational, size);
3748
+ }
3749
+
3750
+ function readToken_eq_excl(code) { // '=!', '=>'
3751
+ var next = input.charCodeAt(tokPos + 1);
3752
+ if (next === 61) return finishOp(_equality, input.charCodeAt(tokPos + 2) === 61 ? 3 : 2);
3753
+ if (code === 61 && next === 62 && options.ecmaVersion >= 6) { // '=>'
3754
+ tokPos += 2;
3755
+ return finishToken(_arrow);
3756
+ }
3757
+ return finishOp(code === 61 ? _eq : _prefix, 1);
3758
+ }
3759
+
3760
+ // Get token inside ES6 template (special rules work there).
3761
+
3762
+ function getTemplateToken(code) {
3763
+ // '`' and '${' have special meanings, but they should follow
3764
+ // string (can be empty)
3765
+ if (tokType === _string) {
3766
+ if (code === 96) { // '`'
3767
+ ++tokPos;
3768
+ return finishToken(_bquote);
3769
+ } else
3770
+ if (code === 36 && input.charCodeAt(tokPos + 1) === 123) { // '${'
3771
+ tokPos += 2;
3772
+ return finishToken(_dollarBraceL);
3773
+ }
3774
+ }
3775
+
3776
+ if (code === 125) { // '}'
3777
+ ++tokPos;
3778
+ return finishToken(_braceR, undefined, false);
3779
+ }
3780
+
3781
+ // anything else is considered string literal
3782
+ return readTmplString();
3783
+ }
3784
+
3785
+ function getTokenFromCode(code) {
3786
+ switch (code) {
3787
+ // The interpretation of a dot depends on whether it is followed
3788
+ // by a digit or another two dots.
3789
+ case 46: // '.'
3790
+ return readToken_dot();
3791
+
3792
+ // Punctuation tokens.
3793
+ case 40: ++tokPos; return finishToken(_parenL);
3794
+ case 41: ++tokPos; return finishToken(_parenR);
3795
+ case 59: ++tokPos; return finishToken(_semi);
3796
+ case 44: ++tokPos; return finishToken(_comma);
3797
+ case 91: ++tokPos; return finishToken(_bracketL);
3798
+ case 93: ++tokPos; return finishToken(_bracketR);
3799
+ case 123: ++tokPos; return finishToken(_braceL);
3800
+ case 125: ++tokPos; return finishToken(_braceR);
3801
+ case 58: ++tokPos; return finishToken(_colon);
3802
+ case 63: ++tokPos; return finishToken(_question);
3803
+
3804
+ case 96: // '`'
3805
+ if (options.ecmaVersion >= 6) {
3806
+ ++tokPos;
3807
+ return finishToken(_bquote, undefined, false);
3808
+ }
3809
+
3810
+ case 48: // '0'
3811
+ var next = input.charCodeAt(tokPos + 1);
3812
+ if (next === 120 || next === 88) return readRadixNumber(16); // '0x', '0X' - hex number
3813
+ if (options.ecmaVersion >= 6) {
3814
+ if (next === 111 || next === 79) return readRadixNumber(8); // '0o', '0O' - octal number
3815
+ if (next === 98 || next === 66) return readRadixNumber(2); // '0b', '0B' - binary number
3816
+ }
3817
+ // Anything else beginning with a digit is an integer, octal
3818
+ // number, or float.
3819
+ case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
3820
+ return readNumber(false);
3821
+
3822
+ // Quotes produce strings.
3823
+ case 34: case 39: // '"', "'"
3824
+ return readString(code);
3825
+
3826
+ // Operators are parsed inline in tiny state machines. '=' (61) is
3827
+ // often referred to. `finishOp` simply skips the amount of
3828
+ // characters it is given as second argument, and returns a token
3829
+ // of the type given by its first argument.
3830
+
3831
+ case 47: // '/'
3832
+ return readToken_slash();
3833
+
3834
+ case 37: case 42: // '%*'
3835
+ return readToken_mult_modulo(code);
3836
+
3837
+ case 124: case 38: // '|&'
3838
+ return readToken_pipe_amp(code);
3839
+
3840
+ case 94: // '^'
3841
+ return readToken_caret();
3842
+
3843
+ case 43: case 45: // '+-'
3844
+ return readToken_plus_min(code);
3845
+
3846
+ case 60: case 62: // '<>'
3847
+ return readToken_lt_gt(code);
3848
+
3849
+ case 61: case 33: // '=!'
3850
+ return readToken_eq_excl(code);
3851
+
3852
+ case 126: // '~'
3853
+ return finishOp(_prefix, 1);
3854
+ }
3855
+
3856
+ return false;
3857
+ }
3858
+
3859
+ function readToken(forceRegexp) {
3860
+ if (!forceRegexp) tokStart = tokPos;
3861
+ else tokPos = tokStart + 1;
3862
+ if (options.locations) tokStartLoc = new Position;
3863
+ if (forceRegexp) return readRegexp();
3864
+ if (tokPos >= inputLen) return finishToken(_eof);
3865
+
3866
+ var code = input.charCodeAt(tokPos);
3867
+
3868
+ if (inTemplate) return getTemplateToken(code);
3869
+
3870
+ // Identifier or keyword. '\uXXXX' sequences are allowed in
3871
+ // identifiers, so '\' also dispatches to that.
3872
+ if (isIdentifierStart(code) || code === 92 /* '\' */) return readWord();
3873
+
3874
+ var tok = getTokenFromCode(code);
3875
+
3876
+ if (tok === false) {
3877
+ // If we are here, we either found a non-ASCII identifier
3878
+ // character, or something that's entirely disallowed.
3879
+ var ch = String.fromCharCode(code);
3880
+ if (ch === "\\" || nonASCIIidentifierStart.test(ch)) return readWord();
3881
+ raise(tokPos, "Unexpected character '" + ch + "'");
3882
+ }
3883
+ return tok;
3884
+ }
3885
+
3886
+ function finishOp(type, size) {
3887
+ var str = input.slice(tokPos, tokPos + size);
3888
+ tokPos += size;
3889
+ finishToken(type, str);
3890
+ }
3891
+
3892
+ // Parse a regular expression. Some context-awareness is necessary,
3893
+ // since a '/' inside a '[]' set does not end the expression.
3894
+
3895
+ function readRegexp() {
3896
+ var content = "", escaped, inClass, start = tokPos;
3897
+ for (;;) {
3898
+ if (tokPos >= inputLen) raise(start, "Unterminated regular expression");
3899
+ var ch = input.charAt(tokPos);
3900
+ if (newline.test(ch)) raise(start, "Unterminated regular expression");
3901
+ if (!escaped) {
3902
+ if (ch === "[") inClass = true;
3903
+ else if (ch === "]" && inClass) inClass = false;
3904
+ else if (ch === "/" && !inClass) break;
3905
+ escaped = ch === "\\";
3906
+ } else escaped = false;
3907
+ ++tokPos;
3908
+ }
3909
+ var content = input.slice(start, tokPos);
3910
+ ++tokPos;
3911
+ // Need to use `readWord1` because '\uXXXX' sequences are allowed
3912
+ // here (don't ask).
3913
+ var mods = readWord1();
3914
+ if (mods && !/^[gmsiy]*$/.test(mods)) raise(start, "Invalid regular expression flag");
3915
+ try {
3916
+ var value = new RegExp(content, mods);
3917
+ } catch (e) {
3918
+ if (e instanceof SyntaxError) raise(start, "Error parsing regular expression: " + e.message);
3919
+ raise(e);
3920
+ }
3921
+ return finishToken(_regexp, value);
3922
+ }
3923
+
3924
+ // Read an integer in the given radix. Return null if zero digits
3925
+ // were read, the integer value otherwise. When `len` is given, this
3926
+ // will return `null` unless the integer has exactly `len` digits.
3927
+
3928
+ function readInt(radix, len) {
3929
+ var start = tokPos, total = 0;
3930
+ for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
3931
+ var code = input.charCodeAt(tokPos), val;
3932
+ if (code >= 97) val = code - 97 + 10; // a
3933
+ else if (code >= 65) val = code - 65 + 10; // A
3934
+ else if (code >= 48 && code <= 57) val = code - 48; // 0-9
3935
+ else val = Infinity;
3936
+ if (val >= radix) break;
3937
+ ++tokPos;
3938
+ total = total * radix + val;
3939
+ }
3940
+ if (tokPos === start || len != null && tokPos - start !== len) return null;
3941
+
3942
+ return total;
3943
+ }
3944
+
3945
+ function readRadixNumber(radix) {
3946
+ tokPos += 2; // 0x
3947
+ var val = readInt(radix);
3948
+ if (val == null) raise(tokStart + 2, "Expected number in radix " + radix);
3949
+ if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number");
3950
+ return finishToken(_num, val);
3951
+ }
3952
+
3953
+ // Read an integer, octal integer, or floating-point number.
3954
+
3955
+ function readNumber(startsWithDot) {
3956
+ var start = tokPos, isFloat = false, octal = input.charCodeAt(tokPos) === 48;
3957
+ if (!startsWithDot && readInt(10) === null) raise(start, "Invalid number");
3958
+ if (input.charCodeAt(tokPos) === 46) {
3959
+ ++tokPos;
3960
+ readInt(10);
3961
+ isFloat = true;
3962
+ }
3963
+ var next = input.charCodeAt(tokPos);
3964
+ if (next === 69 || next === 101) { // 'eE'
3965
+ next = input.charCodeAt(++tokPos);
3966
+ if (next === 43 || next === 45) ++tokPos; // '+-'
3967
+ if (readInt(10) === null) raise(start, "Invalid number");
3968
+ isFloat = true;
3969
+ }
3970
+ if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number");
3971
+
3972
+ var str = input.slice(start, tokPos), val;
3973
+ if (isFloat) val = parseFloat(str);
3974
+ else if (!octal || str.length === 1) val = parseInt(str, 10);
3975
+ else if (/[89]/.test(str) || strict) raise(start, "Invalid number");
3976
+ else val = parseInt(str, 8);
3977
+ return finishToken(_num, val);
3978
+ }
3979
+
3980
+ // Read a string value, interpreting backslash-escapes.
3981
+
3982
+ function readCodePoint() {
3983
+ var ch = input.charCodeAt(tokPos), code;
3984
+
3985
+ if (ch === 123) {
3986
+ if (options.ecmaVersion < 6) unexpected();
3987
+ ++tokPos;
3988
+ code = readHexChar(input.indexOf('}', tokPos) - tokPos);
3989
+ ++tokPos;
3990
+ if (code > 0x10FFFF) unexpected();
3991
+ } else {
3992
+ code = readHexChar(4);
3993
+ }
3994
+
3995
+ // UTF-16 Encoding
3996
+ if (code <= 0xFFFF) {
3997
+ return String.fromCharCode(code);
3998
+ }
3999
+ var cu1 = ((code - 0x10000) >> 10) + 0xD800;
4000
+ var cu2 = ((code - 0x10000) & 1023) + 0xDC00;
4001
+ return String.fromCharCode(cu1, cu2);
4002
+ }
4003
+
4004
+ function readString(quote) {
4005
+ ++tokPos;
4006
+ var out = "";
4007
+ for (;;) {
4008
+ if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant");
4009
+ var ch = input.charCodeAt(tokPos);
4010
+ if (ch === quote) {
4011
+ ++tokPos;
4012
+ return finishToken(_string, out);
4013
+ }
4014
+ if (ch === 92) { // '\'
4015
+ out += readEscapedChar();
4016
+ } else {
4017
+ ++tokPos;
4018
+ if (newline.test(String.fromCharCode(ch))) {
4019
+ raise(tokStart, "Unterminated string constant");
4020
+ }
4021
+ out += String.fromCharCode(ch); // '\'
4022
+ }
4023
+ }
4024
+ }
4025
+
4026
+ function readTmplString() {
4027
+ var out = "";
4028
+ for (;;) {
4029
+ if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant");
4030
+ var ch = input.charCodeAt(tokPos);
4031
+ if (ch === 96 || ch === 36 && input.charCodeAt(tokPos + 1) === 123) // '`', '${'
4032
+ return finishToken(_string, out);
4033
+ if (ch === 92) { // '\'
4034
+ out += readEscapedChar();
4035
+ } else {
4036
+ ++tokPos;
4037
+ if (newline.test(String.fromCharCode(ch))) {
4038
+ if (ch === 13 && input.charCodeAt(tokPos) === 10) {
4039
+ ++tokPos;
4040
+ ch = 10;
4041
+ }
4042
+ if (options.locations) {
4043
+ ++tokCurLine;
4044
+ tokLineStart = tokPos;
4045
+ }
4046
+ }
4047
+ out += String.fromCharCode(ch); // '\'
4048
+ }
4049
+ }
4050
+ }
4051
+
4052
+ // Used to read escaped characters
4053
+
4054
+ function readEscapedChar() {
4055
+ var ch = input.charCodeAt(++tokPos);
4056
+ var octal = /^[0-7]+/.exec(input.slice(tokPos, tokPos + 3));
4057
+ if (octal) octal = octal[0];
4058
+ while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, -1);
4059
+ if (octal === "0") octal = null;
4060
+ ++tokPos;
4061
+ if (octal) {
4062
+ if (strict) raise(tokPos - 2, "Octal literal in strict mode");
4063
+ tokPos += octal.length - 1;
4064
+ return String.fromCharCode(parseInt(octal, 8));
4065
+ } else {
4066
+ switch (ch) {
4067
+ case 110: return "\n"; // 'n' -> '\n'
4068
+ case 114: return "\r"; // 'r' -> '\r'
4069
+ case 120: return String.fromCharCode(readHexChar(2)); // 'x'
4070
+ case 117: return readCodePoint(); // 'u'
4071
+ case 85: return String.fromCharCode(readHexChar(8)); // 'U'
4072
+ case 116: return "\t"; // 't' -> '\t'
4073
+ case 98: return "\b"; // 'b' -> '\b'
4074
+ case 118: return "\u000b"; // 'v' -> '\u000b'
4075
+ case 102: return "\f"; // 'f' -> '\f'
4076
+ case 48: return "\0"; // 0 -> '\0'
4077
+ case 13: if (input.charCodeAt(tokPos) === 10) ++tokPos; // '\r\n'
4078
+ case 10: // ' \n'
4079
+ if (options.locations) { tokLineStart = tokPos; ++tokCurLine; }
4080
+ return "";
4081
+ default: return String.fromCharCode(ch);
4082
+ }
4083
+ }
4084
+ }
4085
+
4086
+ // Used to read character escape sequences ('\x', '\u', '\U').
4087
+
4088
+ function readHexChar(len) {
4089
+ var n = readInt(16, len);
4090
+ if (n === null) raise(tokStart, "Bad character escape sequence");
4091
+ return n;
4092
+ }
4093
+
4094
+ // Used to signal to callers of `readWord1` whether the word
4095
+ // contained any escape sequences. This is needed because words with
4096
+ // escape sequences must not be interpreted as keywords.
4097
+
4098
+ var containsEsc;
4099
+
4100
+ // Read an identifier, and return it as a string. Sets `containsEsc`
4101
+ // to whether the word contained a '\u' escape.
4102
+ //
4103
+ // Only builds up the word character-by-character when it actually
4104
+ // containeds an escape, as a micro-optimization.
4105
+
4106
+ function readWord1() {
4107
+ containsEsc = false;
4108
+ var word, first = true, start = tokPos;
4109
+ for (;;) {
4110
+ var ch = input.charCodeAt(tokPos);
4111
+ if (isIdentifierChar(ch)) {
4112
+ if (containsEsc) word += input.charAt(tokPos);
4113
+ ++tokPos;
4114
+ } else if (ch === 92) { // "\"
4115
+ if (!containsEsc) word = input.slice(start, tokPos);
4116
+ containsEsc = true;
4117
+ if (input.charCodeAt(++tokPos) != 117) // "u"
4118
+ raise(tokPos, "Expecting Unicode escape sequence \\uXXXX");
4119
+ ++tokPos;
4120
+ var esc = readHexChar(4);
4121
+ var escStr = String.fromCharCode(esc);
4122
+ if (!escStr) raise(tokPos - 1, "Invalid Unicode escape");
4123
+ if (!(first ? isIdentifierStart(esc) : isIdentifierChar(esc)))
4124
+ raise(tokPos - 4, "Invalid Unicode escape");
4125
+ word += escStr;
4126
+ } else {
4127
+ break;
4128
+ }
4129
+ first = false;
4130
+ }
4131
+ return containsEsc ? word : input.slice(start, tokPos);
4132
+ }
4133
+
4134
+ // Read an identifier or keyword token. Will check for reserved
4135
+ // words when necessary.
4136
+
4137
+ function readWord() {
4138
+ var word = readWord1();
4139
+ var type = _name;
4140
+ if (!containsEsc && isKeyword(word))
4141
+ type = keywordTypes[word];
4142
+ return finishToken(type, word);
4143
+ }
4144
+
4145
+ // ## Parser
4146
+
4147
+ // A recursive descent parser operates by defining functions for all
4148
+ // syntactic elements, and recursively calling those, each function
4149
+ // advancing the input stream and returning an AST node. Precedence
4150
+ // of constructs (for example, the fact that `!x[1]` means `!(x[1])`
4151
+ // instead of `(!x)[1]` is handled by the fact that the parser
4152
+ // function that parses unary prefix operators is called first, and
4153
+ // in turn calls the function that parses `[]` subscripts — that
4154
+ // way, it'll receive the node for `x[1]` already parsed, and wraps
4155
+ // *that* in the unary operator node.
4156
+ //
4157
+ // Acorn uses an [operator precedence parser][opp] to handle binary
4158
+ // operator precedence, because it is much more compact than using
4159
+ // the technique outlined above, which uses different, nesting
4160
+ // functions to specify precedence, for all of the ten binary
4161
+ // precedence levels that JavaScript defines.
4162
+ //
4163
+ // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
4164
+
4165
+ // ### Parser utilities
4166
+
4167
+ // Continue to the next token.
4168
+
4169
+ function next() {
4170
+ lastStart = tokStart;
4171
+ lastEnd = tokEnd;
4172
+ lastEndLoc = tokEndLoc;
4173
+ readToken();
4174
+ }
4175
+
4176
+ // Enter strict mode. Re-reads the next token to please pedantic
4177
+ // tests ("use strict"; 010; -- should fail).
4178
+
4179
+ function setStrict(strct) {
4180
+ strict = strct;
4181
+ tokPos = tokStart;
4182
+ if (options.locations) {
4183
+ while (tokPos < tokLineStart) {
4184
+ tokLineStart = input.lastIndexOf("\n", tokLineStart - 2) + 1;
4185
+ --tokCurLine;
4186
+ }
4187
+ }
4188
+ skipSpace();
4189
+ readToken();
4190
+ }
4191
+
4192
+ // Start an AST node, attaching a start offset.
4193
+
4194
+ function Node() {
4195
+ this.type = null;
4196
+ this.start = tokStart;
4197
+ this.end = null;
4198
+ }
4199
+
4200
+ exports.Node = Node;
4201
+
4202
+ function SourceLocation() {
4203
+ this.start = tokStartLoc;
4204
+ this.end = null;
4205
+ if (sourceFile !== null) this.source = sourceFile;
4206
+ }
4207
+
4208
+ function startNode() {
4209
+ var node = new Node();
4210
+ if (options.locations)
4211
+ node.loc = new SourceLocation();
4212
+ if (options.directSourceFile)
4213
+ node.sourceFile = options.directSourceFile;
4214
+ if (options.ranges)
4215
+ node.range = [tokStart, 0];
4216
+ return node;
4217
+ }
4218
+
4219
+ // Start a node whose start offset information should be based on
4220
+ // the start of another node. For example, a binary operator node is
4221
+ // only started after its left-hand side has already been parsed.
4222
+
4223
+ function startNodeFrom(other) {
4224
+ var node = new Node();
4225
+ node.start = other.start;
4226
+ if (options.locations) {
4227
+ node.loc = new SourceLocation();
4228
+ node.loc.start = other.loc.start;
4229
+ }
4230
+ if (options.ranges)
4231
+ node.range = [other.range[0], 0];
4232
+
4233
+ return node;
4234
+ }
4235
+
4236
+ // Finish an AST node, adding `type` and `end` properties.
4237
+
4238
+ function finishNode(node, type) {
4239
+ node.type = type;
4240
+ node.end = lastEnd;
4241
+ if (options.locations)
4242
+ node.loc.end = lastEndLoc;
4243
+ if (options.ranges)
4244
+ node.range[1] = lastEnd;
4245
+ return node;
4246
+ }
4247
+
4248
+ // Test whether a statement node is the string literal `"use strict"`.
4249
+
4250
+ function isUseStrict(stmt) {
4251
+ return options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" &&
4252
+ stmt.expression.type === "Literal" && stmt.expression.value === "use strict";
4253
+ }
4254
+
4255
+ // Predicate that tests whether the next token is of the given
4256
+ // type, and if yes, consumes it as a side effect.
4257
+
4258
+ function eat(type) {
4259
+ if (tokType === type) {
4260
+ next();
4261
+ return true;
4262
+ } else {
4263
+ return false;
4264
+ }
4265
+ }
4266
+
4267
+ // Test whether a semicolon can be inserted at the current position.
4268
+
4269
+ function canInsertSemicolon() {
4270
+ return !options.strictSemicolons &&
4271
+ (tokType === _eof || tokType === _braceR || newline.test(input.slice(lastEnd, tokStart)));
4272
+ }
4273
+
4274
+ // Consume a semicolon, or, failing that, see if we are allowed to
4275
+ // pretend that there is a semicolon at this position.
4276
+
4277
+ function semicolon() {
4278
+ if (!eat(_semi) && !canInsertSemicolon()) unexpected();
4279
+ }
4280
+
4281
+ // Expect a token of a given type. If found, consume it, otherwise,
4282
+ // raise an unexpected token error.
4283
+
4284
+ function expect(type) {
4285
+ eat(type) || unexpected();
4286
+ }
4287
+
4288
+ // Raise an unexpected token error.
4289
+
4290
+ function unexpected(pos) {
4291
+ raise(pos != null ? pos : tokStart, "Unexpected token");
4292
+ }
4293
+
4294
+ // Checks if hash object has a property.
4295
+
4296
+ function has(obj, propName) {
4297
+ return Object.prototype.hasOwnProperty.call(obj, propName);
4298
+ }
4299
+ // Convert existing expression atom to assignable pattern
4300
+ // if possible.
4301
+
4302
+ function toAssignable(node, allowSpread, checkType) {
4303
+ if (options.ecmaVersion >= 6 && node) {
4304
+ switch (node.type) {
4305
+ case "Identifier":
4306
+ case "MemberExpression":
4307
+ break;
4308
+
4309
+ case "ObjectExpression":
4310
+ node.type = "ObjectPattern";
4311
+ for (var i = 0; i < node.properties.length; i++) {
4312
+ var prop = node.properties[i];
4313
+ if (prop.kind !== "init") unexpected(prop.key.start);
4314
+ toAssignable(prop.value, false, checkType);
4315
+ }
4316
+ break;
4317
+
4318
+ case "ArrayExpression":
4319
+ node.type = "ArrayPattern";
4320
+ for (var i = 0, lastI = node.elements.length - 1; i <= lastI; i++) {
4321
+ toAssignable(node.elements[i], i === lastI, checkType);
4322
+ }
4323
+ break;
4324
+
4325
+ case "SpreadElement":
4326
+ if (allowSpread) {
4327
+ toAssignable(node.argument, false, checkType);
4328
+ checkSpreadAssign(node.argument);
4329
+ } else {
4330
+ unexpected(node.start);
4331
+ }
4332
+ break;
4333
+
4334
+ default:
4335
+ if (checkType) unexpected(node.start);
4336
+ }
4337
+ }
4338
+ return node;
4339
+ }
4340
+
4341
+ // Checks if node can be assignable spread argument.
4342
+
4343
+ function checkSpreadAssign(node) {
4344
+ if (node.type !== "Identifier" && node.type !== "ArrayPattern")
4345
+ unexpected(node.start);
4346
+ }
4347
+
4348
+ // Verify that argument names are not repeated, and it does not
4349
+ // try to bind the words `eval` or `arguments`.
4350
+
4351
+ function checkFunctionParam(param, nameHash) {
4352
+ switch (param.type) {
4353
+ case "Identifier":
4354
+ if (isStrictReservedWord(param.name) || isStrictBadIdWord(param.name))
4355
+ raise(param.start, "Defining '" + param.name + "' in strict mode");
4356
+ if (has(nameHash, param.name))
4357
+ raise(param.start, "Argument name clash in strict mode");
4358
+ nameHash[param.name] = true;
4359
+ break;
4360
+
4361
+ case "ObjectPattern":
4362
+ for (var i = 0; i < param.properties.length; i++)
4363
+ checkFunctionParam(param.properties[i].value, nameHash);
4364
+ break;
4365
+
4366
+ case "ArrayPattern":
4367
+ for (var i = 0; i < param.elements.length; i++)
4368
+ checkFunctionParam(param.elements[i], nameHash);
4369
+ break;
4370
+ }
4371
+ }
4372
+
4373
+ // Check if property name clashes with already added.
4374
+ // Object/class getters and setters are not allowed to clash —
4375
+ // either with each other or with an init property — and in
4376
+ // strict mode, init properties are also not allowed to be repeated.
4377
+
4378
+ function checkPropClash(prop, propHash) {
4379
+ if (prop.computed) return;
4380
+ var key = prop.key, name;
4381
+ switch (key.type) {
4382
+ case "Identifier": name = key.name; break;
4383
+ case "Literal": name = String(key.value); break;
4384
+ default: return;
4385
+ }
4386
+ var kind = prop.kind || "init", other;
4387
+ if (has(propHash, name)) {
4388
+ other = propHash[name];
4389
+ var isGetSet = kind !== "init";
4390
+ if ((strict || isGetSet) && other[kind] || !(isGetSet ^ other.init))
4391
+ raise(key.start, "Redefinition of property");
4392
+ } else {
4393
+ other = propHash[name] = {
4394
+ init: false,
4395
+ get: false,
4396
+ set: false
4397
+ };
4398
+ }
4399
+ other[kind] = true;
4400
+ }
4401
+
4402
+ // Verify that a node is an lval — something that can be assigned
4403
+ // to.
4404
+
4405
+ function checkLVal(expr, isBinding) {
4406
+ switch (expr.type) {
4407
+ case "Identifier":
4408
+ if (strict && (isStrictBadIdWord(expr.name) || isStrictReservedWord(expr.name)))
4409
+ raise(expr.start, isBinding
4410
+ ? "Binding " + expr.name + " in strict mode"
4411
+ : "Assigning to " + expr.name + " in strict mode"
4412
+ );
4413
+ break;
4414
+
4415
+ case "MemberExpression":
4416
+ if (!isBinding) break;
4417
+
4418
+ case "ObjectPattern":
4419
+ for (var i = 0; i < expr.properties.length; i++)
4420
+ checkLVal(expr.properties[i].value, isBinding);
4421
+ break;
4422
+
4423
+ case "ArrayPattern":
4424
+ for (var i = 0; i < expr.elements.length; i++) {
4425
+ var elem = expr.elements[i];
4426
+ if (elem) checkLVal(elem, isBinding);
4427
+ }
4428
+ break;
4429
+
4430
+ case "SpreadElement":
4431
+ break;
4432
+
4433
+ default:
4434
+ raise(expr.start, "Assigning to rvalue");
4435
+ }
4436
+ }
4437
+
4438
+ // ### Statement parsing
4439
+
4440
+ // Parse a program. Initializes the parser, reads any number of
4441
+ // statements, and wraps them in a Program node. Optionally takes a
4442
+ // `program` argument. If present, the statements will be appended
4443
+ // to its body instead of creating a new node.
4444
+
4445
+ function parseTopLevel(program) {
4446
+ var node = program || startNode(), first = true;
4447
+ if (!program) node.body = [];
4448
+ while (tokType !== _eof) {
4449
+ var stmt = parseStatement();
4450
+ node.body.push(stmt);
4451
+ if (first && isUseStrict(stmt)) setStrict(true);
4452
+ first = false;
4453
+ }
4454
+ return finishNode(node, "Program");
4455
+ }
4456
+
4457
+ var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};
4458
+
4459
+ // Parse a single statement.
4460
+ //
4461
+ // If expecting a statement and finding a slash operator, parse a
4462
+ // regular expression literal. This is to handle cases like
4463
+ // `if (foo) /blah/.exec(foo);`, where looking at the previous token
4464
+ // does not help.
4465
+
4466
+ function parseStatement() {
4467
+ if (tokType === _slash || tokType === _assign && tokVal == "/=")
4468
+ readToken(true);
4469
+
4470
+ var starttype = tokType, node = startNode();
4471
+
4472
+ // Most types of statements are recognized by the keyword they
4473
+ // start with. Many are trivial to parse, some require a bit of
4474
+ // complexity.
4475
+
4476
+ switch (starttype) {
4477
+ case _break: case _continue: return parseBreakContinueStatement(node, starttype.keyword);
4478
+ case _debugger: return parseDebuggerStatement(node);
4479
+ case _do: return parseDoStatement(node);
4480
+ case _for: return parseForStatement(node);
4481
+ case _function: return parseFunctionStatement(node);
4482
+ case _class: return parseClass(node, true);
4483
+ case _if: return parseIfStatement(node);
4484
+ case _return: return parseReturnStatement(node);
4485
+ case _switch: return parseSwitchStatement(node);
4486
+ case _throw: return parseThrowStatement(node);
4487
+ case _try: return parseTryStatement(node);
4488
+ case _var: case _let: case _const: return parseVarStatement(node, starttype.keyword);
4489
+ case _while: return parseWhileStatement(node);
4490
+ case _with: return parseWithStatement(node);
4491
+ case _braceL: return parseBlock(); // no point creating a function for this
4492
+ case _semi: return parseEmptyStatement(node);
4493
+ case _export: return parseExport(node);
4494
+ case _import: return parseImport(node);
4495
+
4496
+ // If the statement does not start with a statement keyword or a
4497
+ // brace, it's an ExpressionStatement or LabeledStatement. We
4498
+ // simply start parsing an expression, and afterwards, if the
4499
+ // next token is a colon and the expression was a simple
4500
+ // Identifier node, we switch to interpreting it as a label.
4501
+ default:
4502
+ var maybeName = tokVal, expr = parseExpression();
4503
+ if (starttype === _name && expr.type === "Identifier" && eat(_colon))
4504
+ return parseLabeledStatement(node, maybeName, expr);
4505
+ else return parseExpressionStatement(node, expr);
4506
+ }
4507
+ }
4508
+
4509
+ function parseBreakContinueStatement(node, keyword) {
4510
+ var isBreak = keyword == "break";
4511
+ next();
4512
+ if (eat(_semi) || canInsertSemicolon()) node.label = null;
4513
+ else if (tokType !== _name) unexpected();
4514
+ else {
4515
+ node.label = parseIdent();
4516
+ semicolon();
4517
+ }
4518
+
4519
+ // Verify that there is an actual destination to break or
4520
+ // continue to.
4521
+ for (var i = 0; i < labels.length; ++i) {
4522
+ var lab = labels[i];
4523
+ if (node.label == null || lab.name === node.label.name) {
4524
+ if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
4525
+ if (node.label && isBreak) break;
4526
+ }
4527
+ }
4528
+ if (i === labels.length) raise(node.start, "Unsyntactic " + keyword);
4529
+ return finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
4530
+ }
4531
+
4532
+ function parseDebuggerStatement(node) {
4533
+ next();
4534
+ semicolon();
4535
+ return finishNode(node, "DebuggerStatement");
4536
+ }
4537
+
4538
+ function parseDoStatement(node) {
4539
+ next();
4540
+ labels.push(loopLabel);
4541
+ node.body = parseStatement();
4542
+ labels.pop();
4543
+ expect(_while);
4544
+ node.test = parseParenExpression();
4545
+ semicolon();
4546
+ return finishNode(node, "DoWhileStatement");
4547
+ }
4548
+
4549
+ // Disambiguating between a `for` and a `for`/`in` or `for`/`of`
4550
+ // loop is non-trivial. Basically, we have to parse the init `var`
4551
+ // statement or expression, disallowing the `in` operator (see
4552
+ // the second parameter to `parseExpression`), and then check
4553
+ // whether the next token is `in` or `of`. When there is no init
4554
+ // part (semicolon immediately after the opening parenthesis), it
4555
+ // is a regular `for` loop.
4556
+
4557
+ function parseForStatement(node) {
4558
+ next();
4559
+ labels.push(loopLabel);
4560
+ expect(_parenL);
4561
+ if (tokType === _semi) return parseFor(node, null);
4562
+ if (tokType === _var || tokType === _let) {
4563
+ var init = startNode(), varKind = tokType.keyword, isLet = tokType === _let;
4564
+ next();
4565
+ parseVar(init, true, varKind);
4566
+ finishNode(init, "VariableDeclaration");
4567
+ if ((tokType === _in || (options.ecmaVersion >= 6 && tokType === _name && tokVal === "of")) && init.declarations.length === 1 &&
4568
+ !(isLet && init.declarations[0].init))
4569
+ return parseForIn(node, init);
4570
+ return parseFor(node, init);
4571
+ }
4572
+ var init = parseExpression(false, true);
4573
+ if (tokType === _in || (options.ecmaVersion >= 6 && tokType === _name && tokVal === "of")) {
4574
+ checkLVal(init);
4575
+ return parseForIn(node, init);
4576
+ }
4577
+ return parseFor(node, init);
4578
+ }
4579
+
4580
+ function parseFunctionStatement(node) {
4581
+ next();
4582
+ return parseFunction(node, true);
4583
+ }
4584
+
4585
+ function parseIfStatement(node) {
4586
+ next();
4587
+ node.test = parseParenExpression();
4588
+ node.consequent = parseStatement();
4589
+ node.alternate = eat(_else) ? parseStatement() : null;
4590
+ return finishNode(node, "IfStatement");
4591
+ }
4592
+
4593
+ function parseReturnStatement(node) {
4594
+ if (!inFunction && !options.allowReturnOutsideFunction)
4595
+ raise(tokStart, "'return' outside of function");
4596
+ next();
4597
+
4598
+ // In `return` (and `break`/`continue`), the keywords with
4599
+ // optional arguments, we eagerly look for a semicolon or the
4600
+ // possibility to insert one.
4601
+
4602
+ if (eat(_semi) || canInsertSemicolon()) node.argument = null;
4603
+ else { node.argument = parseExpression(); semicolon(); }
4604
+ return finishNode(node, "ReturnStatement");
4605
+ }
4606
+
4607
+ function parseSwitchStatement(node) {
4608
+ next();
4609
+ node.discriminant = parseParenExpression();
4610
+ node.cases = [];
4611
+ expect(_braceL);
4612
+ labels.push(switchLabel);
4613
+
4614
+ // Statements under must be grouped (by label) in SwitchCase
4615
+ // nodes. `cur` is used to keep the node that we are currently
4616
+ // adding statements to.
4617
+
4618
+ for (var cur, sawDefault; tokType != _braceR;) {
4619
+ if (tokType === _case || tokType === _default) {
4620
+ var isCase = tokType === _case;
4621
+ if (cur) finishNode(cur, "SwitchCase");
4622
+ node.cases.push(cur = startNode());
4623
+ cur.consequent = [];
4624
+ next();
4625
+ if (isCase) cur.test = parseExpression();
4626
+ else {
4627
+ if (sawDefault) raise(lastStart, "Multiple default clauses"); sawDefault = true;
4628
+ cur.test = null;
4629
+ }
4630
+ expect(_colon);
4631
+ } else {
4632
+ if (!cur) unexpected();
4633
+ cur.consequent.push(parseStatement());
4634
+ }
4635
+ }
4636
+ if (cur) finishNode(cur, "SwitchCase");
4637
+ next(); // Closing brace
4638
+ labels.pop();
4639
+ return finishNode(node, "SwitchStatement");
4640
+ }
4641
+
4642
+ function parseThrowStatement(node) {
4643
+ next();
4644
+ if (newline.test(input.slice(lastEnd, tokStart)))
4645
+ raise(lastEnd, "Illegal newline after throw");
4646
+ node.argument = parseExpression();
4647
+ semicolon();
4648
+ return finishNode(node, "ThrowStatement");
4649
+ }
4650
+
4651
+ function parseTryStatement(node) {
4652
+ next();
4653
+ node.block = parseBlock();
4654
+ node.handler = null;
4655
+ if (tokType === _catch) {
4656
+ var clause = startNode();
4657
+ next();
4658
+ expect(_parenL);
4659
+ clause.param = parseIdent();
4660
+ if (strict && isStrictBadIdWord(clause.param.name))
4661
+ raise(clause.param.start, "Binding " + clause.param.name + " in strict mode");
4662
+ expect(_parenR);
4663
+ clause.guard = null;
4664
+ clause.body = parseBlock();
4665
+ node.handler = finishNode(clause, "CatchClause");
4666
+ }
4667
+ node.guardedHandlers = empty;
4668
+ node.finalizer = eat(_finally) ? parseBlock() : null;
4669
+ if (!node.handler && !node.finalizer)
4670
+ raise(node.start, "Missing catch or finally clause");
4671
+ return finishNode(node, "TryStatement");
4672
+ }
4673
+
4674
+ function parseVarStatement(node, kind) {
4675
+ next();
4676
+ parseVar(node, false, kind);
4677
+ semicolon();
4678
+ return finishNode(node, "VariableDeclaration");
4679
+ }
4680
+
4681
+ function parseWhileStatement(node) {
4682
+ next();
4683
+ node.test = parseParenExpression();
4684
+ labels.push(loopLabel);
4685
+ node.body = parseStatement();
4686
+ labels.pop();
4687
+ return finishNode(node, "WhileStatement");
4688
+ }
4689
+
4690
+ function parseWithStatement(node) {
4691
+ if (strict) raise(tokStart, "'with' in strict mode");
4692
+ next();
4693
+ node.object = parseParenExpression();
4694
+ node.body = parseStatement();
4695
+ return finishNode(node, "WithStatement");
4696
+ }
4697
+
4698
+ function parseEmptyStatement(node) {
4699
+ next();
4700
+ return finishNode(node, "EmptyStatement");
4701
+ }
4702
+
4703
+ function parseLabeledStatement(node, maybeName, expr) {
4704
+ for (var i = 0; i < labels.length; ++i)
4705
+ if (labels[i].name === maybeName) raise(expr.start, "Label '" + maybeName + "' is already declared");
4706
+ var kind = tokType.isLoop ? "loop" : tokType === _switch ? "switch" : null;
4707
+ labels.push({name: maybeName, kind: kind});
4708
+ node.body = parseStatement();
4709
+ labels.pop();
4710
+ node.label = expr;
4711
+ return finishNode(node, "LabeledStatement");
4712
+ }
4713
+
4714
+ function parseExpressionStatement(node, expr) {
4715
+ node.expression = expr;
4716
+ semicolon();
4717
+ return finishNode(node, "ExpressionStatement");
4718
+ }
4719
+
4720
+ // Used for constructs like `switch` and `if` that insist on
4721
+ // parentheses around their expression.
4722
+
4723
+ function parseParenExpression() {
4724
+ expect(_parenL);
4725
+ var val = parseExpression();
4726
+ expect(_parenR);
4727
+ return val;
4728
+ }
4729
+
4730
+ // Parse a semicolon-enclosed block of statements, handling `"use
4731
+ // strict"` declarations when `allowStrict` is true (used for
4732
+ // function bodies).
4733
+
4734
+ function parseBlock(allowStrict) {
4735
+ var node = startNode(), first = true, oldStrict;
4736
+ node.body = [];
4737
+ expect(_braceL);
4738
+ while (!eat(_braceR)) {
4739
+ var stmt = parseStatement();
4740
+ node.body.push(stmt);
4741
+ if (first && allowStrict && isUseStrict(stmt)) {
4742
+ oldStrict = strict;
4743
+ setStrict(strict = true);
4744
+ }
4745
+ first = false;
4746
+ }
4747
+ if (oldStrict === false) setStrict(false);
4748
+ return finishNode(node, "BlockStatement");
4749
+ }
4750
+
4751
+ // Parse a regular `for` loop. The disambiguation code in
4752
+ // `parseStatement` will already have parsed the init statement or
4753
+ // expression.
4754
+
4755
+ function parseFor(node, init) {
4756
+ node.init = init;
4757
+ expect(_semi);
4758
+ node.test = tokType === _semi ? null : parseExpression();
4759
+ expect(_semi);
4760
+ node.update = tokType === _parenR ? null : parseExpression();
4761
+ expect(_parenR);
4762
+ node.body = parseStatement();
4763
+ labels.pop();
4764
+ return finishNode(node, "ForStatement");
4765
+ }
4766
+
4767
+ // Parse a `for`/`in` and `for`/`of` loop, which are almost
4768
+ // same from parser's perspective.
4769
+
4770
+ function parseForIn(node, init) {
4771
+ var type = tokType === _in ? "ForInStatement" : "ForOfStatement";
4772
+ next();
4773
+ node.left = init;
4774
+ node.right = parseExpression();
4775
+ expect(_parenR);
4776
+ node.body = parseStatement();
4777
+ labels.pop();
4778
+ return finishNode(node, type);
4779
+ }
4780
+
4781
+ // Parse a list of variable declarations.
4782
+
4783
+ function parseVar(node, noIn, kind) {
4784
+ node.declarations = [];
4785
+ node.kind = kind;
4786
+ for (;;) {
4787
+ var decl = startNode();
4788
+ decl.id = options.ecmaVersion >= 6 ? toAssignable(parseExprAtom()) : parseIdent();
4789
+ checkLVal(decl.id, true);
4790
+ decl.init = eat(_eq) ? parseExpression(true, noIn) : (kind === _const.keyword ? unexpected() : null);
4791
+ node.declarations.push(finishNode(decl, "VariableDeclarator"));
4792
+ if (!eat(_comma)) break;
4793
+ }
4794
+ return node;
4795
+ }
4796
+
4797
+ // ### Expression parsing
4798
+
4799
+ // These nest, from the most general expression type at the top to
4800
+ // 'atomic', nondivisible expression types at the bottom. Most of
4801
+ // the functions will simply let the function(s) below them parse,
4802
+ // and, *if* the syntactic construct they handle is present, wrap
4803
+ // the AST node that the inner parser gave them in another node.
4804
+
4805
+ // Parse a full expression. The arguments are used to forbid comma
4806
+ // sequences (in argument lists, array literals, or object literals)
4807
+ // or the `in` operator (in for loops initalization expressions).
4808
+
4809
+ function parseExpression(noComma, noIn) {
4810
+ var expr = parseMaybeAssign(noIn);
4811
+ if (!noComma && tokType === _comma) {
4812
+ var node = startNodeFrom(expr);
4813
+ node.expressions = [expr];
4814
+ while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn));
4815
+ return finishNode(node, "SequenceExpression");
4816
+ }
4817
+ return expr;
4818
+ }
4819
+
4820
+ // Parse an assignment expression. This includes applications of
4821
+ // operators like `+=`.
4822
+
4823
+ function parseMaybeAssign(noIn) {
4824
+ var left = parseMaybeConditional(noIn);
4825
+ if (tokType.isAssign) {
4826
+ var node = startNodeFrom(left);
4827
+ node.operator = tokVal;
4828
+ node.left = tokType === _eq ? toAssignable(left) : left;
4829
+ checkLVal(left);
4830
+ next();
4831
+ node.right = parseMaybeAssign(noIn);
4832
+ return finishNode(node, "AssignmentExpression");
4833
+ }
4834
+ return left;
4835
+ }
4836
+
4837
+ // Parse a ternary conditional (`?:`) operator.
4838
+
4839
+ function parseMaybeConditional(noIn) {
4840
+ var expr = parseExprOps(noIn);
4841
+ if (eat(_question)) {
4842
+ var node = startNodeFrom(expr);
4843
+ node.test = expr;
4844
+ node.consequent = parseExpression(true);
4845
+ expect(_colon);
4846
+ node.alternate = parseExpression(true, noIn);
4847
+ return finishNode(node, "ConditionalExpression");
4848
+ }
4849
+ return expr;
4850
+ }
4851
+
4852
+ // Start the precedence parser.
4853
+
4854
+ function parseExprOps(noIn) {
4855
+ return parseExprOp(parseMaybeUnary(), -1, noIn);
4856
+ }
4857
+
4858
+ // Parse binary operators with the operator precedence parsing
4859
+ // algorithm. `left` is the left-hand side of the operator.
4860
+ // `minPrec` provides context that allows the function to stop and
4861
+ // defer further parser to one of its callers when it encounters an
4862
+ // operator that has a lower precedence than the set it is parsing.
4863
+
4864
+ function parseExprOp(left, minPrec, noIn) {
4865
+ var prec = tokType.binop;
4866
+ if (prec != null && (!noIn || tokType !== _in)) {
4867
+ if (prec > minPrec) {
4868
+ var node = startNodeFrom(left);
4869
+ node.left = left;
4870
+ node.operator = tokVal;
4871
+ var op = tokType;
4872
+ next();
4873
+ node.right = parseExprOp(parseMaybeUnary(), prec, noIn);
4874
+ var exprNode = finishNode(node, (op === _logicalOR || op === _logicalAND) ? "LogicalExpression" : "BinaryExpression");
4875
+ return parseExprOp(exprNode, minPrec, noIn);
4876
+ }
4877
+ }
4878
+ return left;
4879
+ }
4880
+
4881
+ // Parse unary operators, both prefix and postfix.
4882
+
4883
+ function parseMaybeUnary() {
4884
+ if (tokType.prefix) {
4885
+ var node = startNode(), update = tokType.isUpdate;
4886
+ node.operator = tokVal;
4887
+ node.prefix = true;
4888
+ tokRegexpAllowed = true;
4889
+ next();
4890
+ node.argument = parseMaybeUnary();
4891
+ if (update) checkLVal(node.argument);
4892
+ else if (strict && node.operator === "delete" &&
4893
+ node.argument.type === "Identifier")
4894
+ raise(node.start, "Deleting local variable in strict mode");
4895
+ return finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
4896
+ }
4897
+ var expr = parseExprSubscripts();
4898
+ while (tokType.postfix && !canInsertSemicolon()) {
4899
+ var node = startNodeFrom(expr);
4900
+ node.operator = tokVal;
4901
+ node.prefix = false;
4902
+ node.argument = expr;
4903
+ checkLVal(expr);
4904
+ next();
4905
+ expr = finishNode(node, "UpdateExpression");
4906
+ }
4907
+ return expr;
4908
+ }
4909
+
4910
+ // Parse call, dot, and `[]`-subscript expressions.
4911
+
4912
+ function parseExprSubscripts() {
4913
+ return parseSubscripts(parseExprAtom());
4914
+ }
4915
+
4916
+ function parseSubscripts(base, noCalls) {
4917
+ if (eat(_dot)) {
4918
+ var node = startNodeFrom(base);
4919
+ node.object = base;
4920
+ node.property = parseIdent(true);
4921
+ node.computed = false;
4922
+ return parseSubscripts(finishNode(node, "MemberExpression"), noCalls);
4923
+ } else if (eat(_bracketL)) {
4924
+ var node = startNodeFrom(base);
4925
+ node.object = base;
4926
+ node.property = parseExpression();
4927
+ node.computed = true;
4928
+ expect(_bracketR);
4929
+ return parseSubscripts(finishNode(node, "MemberExpression"), noCalls);
4930
+ } else if (!noCalls && eat(_parenL)) {
4931
+ var node = startNodeFrom(base);
4932
+ node.callee = base;
4933
+ node.arguments = parseExprList(_parenR, false);
4934
+ return parseSubscripts(finishNode(node, "CallExpression"), noCalls);
4935
+ } else if (tokType === _bquote) {
4936
+ var node = startNodeFrom(base);
4937
+ node.tag = base;
4938
+ node.quasi = parseTemplate();
4939
+ return parseSubscripts(finishNode(node, "TaggedTemplateExpression"), noCalls);
4940
+ } return base;
4941
+ }
4942
+
4943
+ // Parse an atomic expression — either a single token that is an
4944
+ // expression, an expression started by a keyword like `function` or
4945
+ // `new`, or an expression wrapped in punctuation like `()`, `[]`,
4946
+ // or `{}`.
4947
+
4948
+ function parseExprAtom() {
4949
+ switch (tokType) {
4950
+ case _this:
4951
+ var node = startNode();
4952
+ next();
4953
+ return finishNode(node, "ThisExpression");
4954
+
4955
+ case _yield:
4956
+ if (inGenerator) return parseYield();
4957
+
4958
+ case _name:
4959
+ var id = parseIdent(tokType !== _name);
4960
+ if (eat(_arrow)) {
4961
+ return parseArrowExpression(startNodeFrom(id), [id]);
4962
+ }
4963
+ return id;
4964
+
4965
+ case _num: case _string: case _regexp:
4966
+ var node = startNode();
4967
+ node.value = tokVal;
4968
+ node.raw = input.slice(tokStart, tokEnd);
4969
+ next();
4970
+ return finishNode(node, "Literal");
4971
+
4972
+ case _null: case _true: case _false:
4973
+ var node = startNode();
4974
+ node.value = tokType.atomValue;
4975
+ node.raw = tokType.keyword;
4976
+ next();
4977
+ return finishNode(node, "Literal");
4978
+
4979
+ case _parenL:
4980
+ var tokStartLoc1 = tokStartLoc, tokStart1 = tokStart, val, exprList;
4981
+ next();
4982
+ // check whether this is generator comprehension or regular expression
4983
+ if (options.ecmaVersion >= 6 && tokType === _for) {
4984
+ val = parseComprehension(startNode(), true);
4985
+ } else {
4986
+ var oldParenL = ++metParenL;
4987
+ if (tokType !== _parenR) {
4988
+ val = parseExpression();
4989
+ exprList = val.type === "SequenceExpression" ? val.expressions : [val];
4990
+ } else {
4991
+ exprList = [];
4992
+ }
4993
+ expect(_parenR);
4994
+ // if '=>' follows '(...)', convert contents to arguments
4995
+ if (metParenL === oldParenL && eat(_arrow)) {
4996
+ val = parseArrowExpression(startNode(), exprList);
4997
+ } else {
4998
+ // forbid '()' before everything but '=>'
4999
+ if (!val) unexpected(lastStart);
5000
+ // forbid '...' in sequence expressions
5001
+ if (options.ecmaVersion >= 6) {
5002
+ for (var i = 0; i < exprList.length; i++) {
5003
+ if (exprList[i].type === "SpreadElement") unexpected();
5004
+ }
5005
+ }
5006
+ }
5007
+ }
5008
+ val.start = tokStart1;
5009
+ val.end = lastEnd;
5010
+ if (options.locations) {
5011
+ val.loc.start = tokStartLoc1;
5012
+ val.loc.end = lastEndLoc;
5013
+ }
5014
+ if (options.ranges) {
5015
+ val.range = [tokStart1, lastEnd];
5016
+ }
5017
+ return val;
5018
+
5019
+ case _bracketL:
5020
+ var node = startNode();
5021
+ next();
5022
+ // check whether this is array comprehension or regular array
5023
+ if (options.ecmaVersion >= 6 && tokType === _for) {
5024
+ return parseComprehension(node, false);
5025
+ }
5026
+ node.elements = parseExprList(_bracketR, true, true);
5027
+ return finishNode(node, "ArrayExpression");
5028
+
5029
+ case _braceL:
5030
+ return parseObj();
5031
+
5032
+ case _function:
5033
+ var node = startNode();
5034
+ next();
5035
+ return parseFunction(node, false);
5036
+
5037
+ case _class:
5038
+ return parseClass(startNode(), false);
5039
+
5040
+ case _new:
5041
+ return parseNew();
5042
+
5043
+ case _ellipsis:
5044
+ return parseSpread();
5045
+
5046
+ case _bquote:
5047
+ return parseTemplate();
5048
+
5049
+ default:
5050
+ unexpected();
5051
+ }
5052
+ }
5053
+
5054
+ // New's precedence is slightly tricky. It must allow its argument
5055
+ // to be a `[]` or dot subscript expression, but not a call — at
5056
+ // least, not without wrapping it in parentheses. Thus, it uses the
5057
+
5058
+ function parseNew() {
5059
+ var node = startNode();
5060
+ next();
5061
+ node.callee = parseSubscripts(parseExprAtom(), true);
5062
+ if (eat(_parenL)) node.arguments = parseExprList(_parenR, false);
5063
+ else node.arguments = empty;
5064
+ return finishNode(node, "NewExpression");
5065
+ }
5066
+
5067
+ // Parse spread element '...expr'
2614
5068
 
2615
- Scope.prototype.remove = function(name) {
2616
- return this.decls.remove(name);
2617
- };
5069
+ function parseSpread() {
5070
+ var node = startNode();
5071
+ next();
5072
+ node.argument = parseExpression(true);
5073
+ return finishNode(node, "SpreadElement");
5074
+ }
2618
5075
 
2619
- Scope.prototype.doesPropagate = function(name) {
2620
- return this.propagates.has(name);
2621
- };
5076
+ // Parse template expression.
5077
+
5078
+ function parseTemplate() {
5079
+ var node = startNode();
5080
+ node.expressions = [];
5081
+ node.quasis = [];
5082
+ inTemplate = true;
5083
+ next();
5084
+ for (;;) {
5085
+ var elem = startNode();
5086
+ elem.value = {cooked: tokVal, raw: input.slice(tokStart, tokEnd)};
5087
+ elem.tail = false;
5088
+ next();
5089
+ node.quasis.push(finishNode(elem, "TemplateElement"));
5090
+ if (tokType === _bquote) { // '`', end of template
5091
+ elem.tail = true;
5092
+ break;
5093
+ }
5094
+ inTemplate = false;
5095
+ expect(_dollarBraceL);
5096
+ node.expressions.push(parseExpression());
5097
+ inTemplate = true;
5098
+ // hack to include previously skipped space
5099
+ tokPos = tokEnd;
5100
+ expect(_braceR);
5101
+ }
5102
+ inTemplate = false;
5103
+ next();
5104
+ return finishNode(node, "TemplateLiteral");
5105
+ }
2622
5106
 
2623
- Scope.prototype.markPropagates = function(name) {
2624
- this.propagates.add(name);
2625
- };
5107
+ // Parse an object literal.
5108
+
5109
+ function parseObj() {
5110
+ var node = startNode(), first = true, propHash = {};
5111
+ node.properties = [];
5112
+ next();
5113
+ while (!eat(_braceR)) {
5114
+ if (!first) {
5115
+ expect(_comma);
5116
+ if (options.allowTrailingCommas && eat(_braceR)) break;
5117
+ } else first = false;
5118
+
5119
+ var prop = startNode(), isGenerator;
5120
+ if (options.ecmaVersion >= 6) {
5121
+ prop.method = false;
5122
+ prop.shorthand = false;
5123
+ isGenerator = eat(_star);
5124
+ }
5125
+ parsePropertyName(prop);
5126
+ if (eat(_colon)) {
5127
+ prop.value = parseExpression(true);
5128
+ prop.kind = "init";
5129
+ } else if (options.ecmaVersion >= 6 && tokType === _parenL) {
5130
+ prop.kind = "init";
5131
+ prop.method = true;
5132
+ prop.value = parseMethod(isGenerator);
5133
+ } else if (options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
5134
+ (prop.key.name === "get" || prop.key.name === "set")) {
5135
+ if (isGenerator) unexpected();
5136
+ prop.kind = prop.key.name;
5137
+ parsePropertyName(prop);
5138
+ prop.value = parseMethod(false);
5139
+ } else if (options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
5140
+ prop.kind = "init";
5141
+ prop.value = prop.key;
5142
+ prop.shorthand = true;
5143
+ } else unexpected();
5144
+
5145
+ checkPropClash(prop, propHash);
5146
+ node.properties.push(finishNode(prop, "Property"));
5147
+ }
5148
+ return finishNode(node, "ObjectExpression");
5149
+ }
2626
5150
 
2627
- Scope.prototype.closestHoistScope = function() {
2628
- var scope = this;
2629
- while (scope.kind !== "hoist") {
2630
- scope = scope.parent;
5151
+ function parsePropertyName(prop) {
5152
+ if (options.ecmaVersion >= 6) {
5153
+ if (eat(_bracketL)) {
5154
+ prop.computed = true;
5155
+ prop.key = parseExpression();
5156
+ expect(_bracketR);
5157
+ return;
5158
+ } else {
5159
+ prop.computed = false;
5160
+ }
2631
5161
  }
2632
- return scope;
2633
- };
5162
+ prop.key = (tokType === _num || tokType === _string) ? parseExprAtom() : parseIdent(true);
5163
+ }
2634
5164
 
2635
- Scope.prototype.lookup = function(name) {
2636
- for (var scope = this; scope; scope = scope.parent) {
2637
- if (scope.decls.has(name)) {
2638
- return scope;
2639
- } else if (scope.kind === "hoist") {
2640
- scope.propagates.add(name);
2641
- }
5165
+ // Initialize empty function node.
5166
+
5167
+ function initFunction(node) {
5168
+ node.id = null;
5169
+ node.params = [];
5170
+ if (options.ecmaVersion >= 6) {
5171
+ node.defaults = [];
5172
+ node.rest = null;
5173
+ node.generator = false;
2642
5174
  }
2643
- return null;
2644
- };
5175
+ }
2645
5176
 
2646
- module.exports = Scope;
5177
+ // Parse a function declaration or literal (depending on the
5178
+ // `isStatement` parameter).
2647
5179
 
2648
- },{"assert":1,"simple-fmt":18,"simple-is":19,"stringmap":31,"stringset":32}],13:[function(require,module,exports){
2649
- // scopetools.js
2650
- // MIT licensed, see LICENSE file
2651
- // Copyright (c) 2013-2014 Olov Lassus <olov.lassus@gmail.com>
5180
+ function parseFunction(node, isStatement, allowExpressionBody) {
5181
+ initFunction(node);
5182
+ if (options.ecmaVersion >= 6) {
5183
+ node.generator = eat(_star);
5184
+ }
5185
+ if (isStatement || tokType === _name) {
5186
+ node.id = parseIdent();
5187
+ }
5188
+ parseFunctionParams(node);
5189
+ parseFunctionBody(node, allowExpressionBody);
5190
+ return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
5191
+ }
2652
5192
 
2653
- "use strict";
5193
+ // Parse object or class method.
2654
5194
 
2655
- var assert = require("assert");
2656
- var traverse = require("ordered-ast-traverse");
2657
- var Scope = require("./scope");
2658
- var is = require("simple-is");
5195
+ function parseMethod(isGenerator) {
5196
+ var node = startNode();
5197
+ initFunction(node);
5198
+ parseFunctionParams(node);
5199
+ var allowExpressionBody;
5200
+ if (options.ecmaVersion >= 6) {
5201
+ node.generator = isGenerator;
5202
+ allowExpressionBody = true;
5203
+ } else {
5204
+ allowExpressionBody = false;
5205
+ }
5206
+ parseFunctionBody(node, allowExpressionBody);
5207
+ return finishNode(node, "FunctionExpression");
5208
+ }
2659
5209
 
2660
- module.exports = {
2661
- setupScopeAndReferences: setupScopeAndReferences,
2662
- isReference: isReference,
2663
- };
5210
+ // Parse arrow function expression with given parameters.
2664
5211
 
2665
- function setupScopeAndReferences(root) {
2666
- traverse(root, {pre: createScopes});
2667
- createTopScope(root.$scope);
2668
- }
5212
+ function parseArrowExpression(node, params) {
5213
+ initFunction(node);
2669
5214
 
2670
- function createScopes(node, parent) {
2671
- node.$parent = parent;
2672
- node.$scope = parent ? parent.$scope : null; // may be overridden
5215
+ var defaults = node.defaults, hasDefaults = false;
2673
5216
 
2674
- if (isNonFunctionBlock(node, parent)) {
2675
- // A block node is a scope unless parent is a function
2676
- node.$scope = new Scope({
2677
- kind: "block",
2678
- node: node,
2679
- parent: parent.$scope,
2680
- });
5217
+ for (var i = 0, lastI = params.length - 1; i <= lastI; i++) {
5218
+ var param = params[i];
2681
5219
 
2682
- } else if (node.type === "VariableDeclaration") {
2683
- // Variable declarations names goes in current scope
2684
- node.declarations.forEach(function(declarator) {
2685
- var name = declarator.id.name;
2686
- node.$scope.add(name, node.kind, declarator.id, declarator.range[1]);
2687
- });
5220
+ if (param.type === "AssignmentExpression" && param.operator === "=") {
5221
+ hasDefaults = true;
5222
+ params[i] = param.left;
5223
+ defaults.push(param.right);
5224
+ } else {
5225
+ toAssignable(param, i === lastI, true);
5226
+ defaults.push(null);
5227
+ if (param.type === "SpreadElement") {
5228
+ params.length--;
5229
+ node.rest = param.argument;
5230
+ break;
5231
+ }
5232
+ }
5233
+ }
2688
5234
 
2689
- } else if (isFunction(node)) {
2690
- // Function is a scope, with params in it
2691
- // There's no block-scope under it
5235
+ node.params = params;
5236
+ if (!hasDefaults) node.defaults = [];
2692
5237
 
2693
- node.$scope = new Scope({
2694
- kind: "hoist",
2695
- node: node,
2696
- parent: parent.$scope,
2697
- });
5238
+ parseFunctionBody(node, true);
5239
+ return finishNode(node, "ArrowFunctionExpression");
5240
+ }
2698
5241
 
2699
- // function has a name
2700
- if (node.id) {
2701
- if (node.type === "FunctionDeclaration") {
2702
- // Function name goes in parent scope for declared functions
2703
- parent.$scope.add(node.id.name, "fun", node.id, null);
2704
- } else if (node.type === "FunctionExpression") {
2705
- // Function name goes in function's scope for named function expressions
2706
- node.$scope.add(node.id.name, "fun", node.id, null);
2707
- } else {
2708
- assert(false);
2709
- }
2710
- }
5242
+ // Parse function parameters.
2711
5243
 
2712
- node.params.forEach(function(param) {
2713
- node.$scope.add(param.name, "param", param, null);
2714
- });
5244
+ function parseFunctionParams(node) {
5245
+ var defaults = [], hasDefaults = false;
2715
5246
 
2716
- } else if (isForWithConstLet(node) || isForInOfWithConstLet(node)) {
2717
- // For(In/Of) loop with const|let declaration is a scope, with declaration in it
2718
- // There may be a block-scope under it
2719
- node.$scope = new Scope({
2720
- kind: "block",
2721
- node: node,
2722
- parent: parent.$scope,
2723
- });
5247
+ expect(_parenL);
5248
+ for (;;) {
5249
+ if (eat(_parenR)) {
5250
+ break;
5251
+ } else if (options.ecmaVersion >= 6 && eat(_ellipsis)) {
5252
+ node.rest = toAssignable(parseExprAtom(), false, true);
5253
+ checkSpreadAssign(node.rest);
5254
+ expect(_parenR);
5255
+ defaults.push(null);
5256
+ break;
5257
+ } else {
5258
+ node.params.push(options.ecmaVersion >= 6 ? toAssignable(parseExprAtom(), false, true) : parseIdent());
5259
+ if (options.ecmaVersion >= 6) {
5260
+ if (eat(_eq)) {
5261
+ hasDefaults = true;
5262
+ defaults.push(parseExpression(true));
5263
+ } else {
5264
+ defaults.push(null);
5265
+ }
5266
+ }
5267
+ if (!eat(_comma)) {
5268
+ expect(_parenR);
5269
+ break;
5270
+ }
5271
+ }
5272
+ }
2724
5273
 
2725
- } else if (node.type === "CatchClause") {
2726
- var identifier = node.param;
5274
+ if (hasDefaults) node.defaults = defaults;
5275
+ }
2727
5276
 
2728
- node.$scope = new Scope({
2729
- kind: "catch-block",
2730
- node: node,
2731
- parent: parent.$scope,
2732
- });
2733
- node.$scope.add(identifier.name, "caught", identifier, null);
5277
+ // Parse function body and check parameters.
2734
5278
 
2735
- // All hoist-scope keeps track of which variables that are propagated through,
2736
- // i.e. an reference inside the scope points to a declaration outside the scope.
2737
- // This is used to mark "taint" the name since adding a new variable in the scope,
2738
- // with a propagated name, would change the meaning of the existing references.
2739
- //
2740
- // catch(e) is special because even though e is a variable in its own scope,
2741
- // we want to make sure that catch(e){let e} is never transformed to
2742
- // catch(e){var e} (but rather var e$0). For that reason we taint the use of e
2743
- // in the closest hoist-scope, i.e. where var e$0 belongs.
2744
- node.$scope.closestHoistScope().markPropagates(identifier.name);
5279
+ function parseFunctionBody(node, allowExpression) {
5280
+ var isExpression = allowExpression && tokType !== _braceL;
2745
5281
 
2746
- } else if (node.type === "Program") {
2747
- // Top-level program is a scope
2748
- // There's no block-scope under it
2749
- node.$scope = new Scope({
2750
- kind: "hoist",
2751
- node: node,
2752
- parent: null,
2753
- });
5282
+ if (isExpression) {
5283
+ node.body = parseExpression(true);
5284
+ node.expression = true;
5285
+ } else {
5286
+ // Start a new scope with regard to labels and the `inFunction`
5287
+ // flag (restore them to their old value afterwards).
5288
+ var oldInFunc = inFunction, oldInGen = inGenerator, oldLabels = labels;
5289
+ inFunction = true; inGenerator = node.generator; labels = [];
5290
+ node.body = parseBlock(true);
5291
+ node.expression = false;
5292
+ inFunction = oldInFunc; inGenerator = oldInGen; labels = oldLabels;
5293
+ }
5294
+
5295
+ // If this is a strict mode function, verify that argument names
5296
+ // are not repeated, and it does not try to bind the words `eval`
5297
+ // or `arguments`.
5298
+ if (strict || !isExpression && node.body.body.length && isUseStrict(node.body.body[0])) {
5299
+ var nameHash = {};
5300
+ if (node.id)
5301
+ checkFunctionParam(node.id, {});
5302
+ for (var i = 0; i < node.params.length; i++)
5303
+ checkFunctionParam(node.params[i], nameHash);
5304
+ if (node.rest)
5305
+ checkFunctionParam(node.rest, nameHash);
2754
5306
  }
2755
- }
5307
+ }
2756
5308
 
2757
- function createTopScope(programScope) {
2758
- function inject(obj) {
2759
- for (var name in obj) {
2760
- var writeable = obj[name];
2761
- var kind = (writeable ? "var" : "const");
2762
- if (topScope.hasOwn(name)) {
2763
- topScope.remove(name);
2764
- }
2765
- topScope.add(name, kind, {loc: {start: {line: -1}}}, -1);
2766
- }
5309
+ // Parse a class declaration or literal (depending on the
5310
+ // `isStatement` parameter).
5311
+
5312
+ function parseClass(node, isStatement) {
5313
+ next();
5314
+ node.id = tokType === _name ? parseIdent() : isStatement ? unexpected() : null;
5315
+ node.superClass = eat(_extends) ? parseExpression() : null;
5316
+ var classBody = startNode(), methodHash = {}, staticMethodHash = {};
5317
+ classBody.body = [];
5318
+ expect(_braceL);
5319
+ while (!eat(_braceR)) {
5320
+ var method = startNode();
5321
+ if (tokType === _name && tokVal === "static") {
5322
+ next();
5323
+ method['static'] = true;
5324
+ } else {
5325
+ method['static'] = false;
5326
+ }
5327
+ var isGenerator = eat(_star);
5328
+ parsePropertyName(method);
5329
+ if (tokType === _name && !method.computed && method.key.type === "Identifier" &&
5330
+ (method.key.name === "get" || method.key.name === "set")) {
5331
+ if (isGenerator) unexpected();
5332
+ method.kind = method.key.name;
5333
+ parsePropertyName(method);
5334
+ } else {
5335
+ method.kind = "";
5336
+ }
5337
+ method.value = parseMethod(isGenerator);
5338
+ checkPropClash(method, method['static'] ? staticMethodHash : methodHash);
5339
+ classBody.body.push(finishNode(method, "MethodDefinition"));
5340
+ eat(_semi);
2767
5341
  }
5342
+ node.body = finishNode(classBody, "ClassBody");
5343
+ return finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
5344
+ }
2768
5345
 
2769
- var topScope = new Scope({
2770
- kind: "hoist",
2771
- node: {},
2772
- parent: null,
2773
- });
5346
+ // Parses a comma-separated list of expressions, and returns them as
5347
+ // an array. `close` is the token type that ends the list, and
5348
+ // `allowEmpty` can be turned on to allow subsequent commas with
5349
+ // nothing in between them to be parsed as `null` (which is needed
5350
+ // for array literals).
2774
5351
 
2775
- var complementary = {
2776
- undefined: false,
2777
- Infinity: false,
2778
- console: false,
2779
- };
5352
+ function parseExprList(close, allowTrailingComma, allowEmpty) {
5353
+ var elts = [], first = true;
5354
+ while (!eat(close)) {
5355
+ if (!first) {
5356
+ expect(_comma);
5357
+ if (allowTrailingComma && options.allowTrailingCommas && eat(close)) break;
5358
+ } else first = false;
2780
5359
 
2781
- inject(complementary);
2782
- // inject(jshint_vars.reservedVars);
2783
- // inject(jshint_vars.ecmaIdentifiers);
5360
+ if (allowEmpty && tokType === _comma) elts.push(null);
5361
+ else elts.push(parseExpression(true));
5362
+ }
5363
+ return elts;
5364
+ }
2784
5365
 
2785
- // link it in
2786
- programScope.parent = topScope;
2787
- topScope.children.push(programScope);
5366
+ // Parse the next token as an identifier. If `liberal` is true (used
5367
+ // when parsing properties), it will also convert keywords into
5368
+ // identifiers.
5369
+
5370
+ function parseIdent(liberal) {
5371
+ var node = startNode();
5372
+ if (liberal && options.forbidReserved == "everywhere") liberal = false;
5373
+ if (tokType === _name) {
5374
+ if (!liberal &&
5375
+ (options.forbidReserved &&
5376
+ (options.ecmaVersion === 3 ? isReservedWord3 : isReservedWord5)(tokVal) ||
5377
+ strict && isStrictReservedWord(tokVal)) &&
5378
+ input.slice(tokStart, tokEnd).indexOf("\\") == -1)
5379
+ raise(tokStart, "The keyword '" + tokVal + "' is reserved");
5380
+ node.name = tokVal;
5381
+ } else if (liberal && tokType.keyword) {
5382
+ node.name = tokType.keyword;
5383
+ } else {
5384
+ unexpected();
5385
+ }
5386
+ tokRegexpAllowed = false;
5387
+ next();
5388
+ return finishNode(node, "Identifier");
5389
+ }
2788
5390
 
2789
- return topScope;
2790
- }
5391
+ // Parses module export declaration.
5392
+
5393
+ function parseExport(node) {
5394
+ next();
5395
+ // export var|const|let|function|class ...;
5396
+ if (tokType === _var || tokType === _const || tokType === _let || tokType === _function || tokType === _class) {
5397
+ node.declaration = parseStatement();
5398
+ node['default'] = false;
5399
+ node.specifiers = null;
5400
+ node.source = null;
5401
+ } else
5402
+ // export default ...;
5403
+ if (eat(_default)) {
5404
+ node.declaration = parseExpression(true);
5405
+ node['default'] = true;
5406
+ node.specifiers = null;
5407
+ node.source = null;
5408
+ semicolon();
5409
+ } else {
5410
+ // export * from '...'
5411
+ // export { x, y as z } [from '...']
5412
+ var isBatch = tokType === _star;
5413
+ node.declaration = null;
5414
+ node['default'] = false;
5415
+ node.specifiers = parseExportSpecifiers();
5416
+ if (tokType === _name && tokVal === "from") {
5417
+ next();
5418
+ node.source = tokType === _string ? parseExprAtom() : unexpected();
5419
+ } else {
5420
+ if (isBatch) unexpected();
5421
+ node.source = null;
5422
+ }
5423
+ }
5424
+ return finishNode(node, "ExportDeclaration");
5425
+ }
2791
5426
 
2792
- function isConstLet(kind) {
2793
- return kind === "const" || kind === "let";
2794
- }
5427
+ // Parses a comma-separated list of module exports.
2795
5428
 
2796
- function isNonFunctionBlock(node, parent) {
2797
- return node.type === "BlockStatement" && parent.type !== "FunctionDeclaration" && parent.type !== "FunctionExpression";
2798
- }
5429
+ function parseExportSpecifiers() {
5430
+ var nodes = [], first = true;
5431
+ if (tokType === _star) {
5432
+ // export * from '...'
5433
+ var node = startNode();
5434
+ next();
5435
+ nodes.push(finishNode(node, "ExportBatchSpecifier"));
5436
+ } else {
5437
+ // export { x, y as z } [from '...']
5438
+ expect(_braceL);
5439
+ while (!eat(_braceR)) {
5440
+ if (!first) {
5441
+ expect(_comma);
5442
+ if (options.allowTrailingCommas && eat(_braceR)) break;
5443
+ } else first = false;
5444
+
5445
+ var node = startNode();
5446
+ node.id = parseIdent();
5447
+ if (tokType === _name && tokVal === "as") {
5448
+ next();
5449
+ node.name = parseIdent(true);
5450
+ } else {
5451
+ node.name = null;
5452
+ }
5453
+ nodes.push(finishNode(node, "ExportSpecifier"));
5454
+ }
5455
+ }
5456
+ return nodes;
5457
+ }
2799
5458
 
2800
- function isForWithConstLet(node) {
2801
- return node.type === "ForStatement" && node.init && node.init.type === "VariableDeclaration" && isConstLet(node.init.kind);
2802
- }
5459
+ // Parses import declaration.
2803
5460
 
2804
- function isForInOfWithConstLet(node) {
2805
- return isForInOf(node) && node.left.type === "VariableDeclaration" && isConstLet(node.left.kind);
2806
- }
5461
+ function parseImport(node) {
5462
+ next();
5463
+ // import '...';
5464
+ if (tokType === _string) {
5465
+ node.specifiers = [];
5466
+ node.source = parseExprAtom();
5467
+ node.kind = "";
5468
+ } else {
5469
+ node.specifiers = parseImportSpecifiers();
5470
+ if (tokType !== _name || tokVal !== "from") unexpected();
5471
+ next();
5472
+ node.source = tokType === _string ? parseExprAtom() : unexpected();
5473
+ // only for backward compatibility with Esprima's AST
5474
+ // (it doesn't support mixed default + named yet)
5475
+ node.kind = node.specifiers[0]['default'] ? "default" : "named";
5476
+ }
5477
+ return finishNode(node, "ImportDeclaration");
5478
+ }
2807
5479
 
2808
- function isForInOf(node) {
2809
- return node.type === "ForInStatement" || node.type === "ForOfStatement";
2810
- }
5480
+ // Parses a comma-separated list of module imports.
5481
+
5482
+ function parseImportSpecifiers() {
5483
+ var nodes = [], first = true;
5484
+ if (tokType === _star) {
5485
+ var node = startNode();
5486
+ next();
5487
+ if (tokType !== _name || tokVal !== "as") unexpected();
5488
+ next();
5489
+ node.name = parseIdent();
5490
+ checkLVal(node.name, true);
5491
+ nodes.push(finishNode(node, "ImportBatchSpecifier"));
5492
+ return nodes;
5493
+ }
5494
+ if (tokType === _name) {
5495
+ // import defaultObj, { x, y as z } from '...'
5496
+ var node = startNode();
5497
+ node.id = parseIdent();
5498
+ checkLVal(node.id, true);
5499
+ node.name = null;
5500
+ node['default'] = true;
5501
+ nodes.push(finishNode(node, "ImportSpecifier"));
5502
+ if (!eat(_comma)) return nodes;
5503
+ }
5504
+ expect(_braceL);
5505
+ while (!eat(_braceR)) {
5506
+ if (!first) {
5507
+ expect(_comma);
5508
+ if (options.allowTrailingCommas && eat(_braceR)) break;
5509
+ } else first = false;
5510
+
5511
+ var node = startNode();
5512
+ node.id = parseIdent(true);
5513
+ if (tokType === _name && tokVal === "as") {
5514
+ next();
5515
+ node.name = parseIdent();
5516
+ } else {
5517
+ node.name = null;
5518
+ }
5519
+ checkLVal(node.name || node.id, true);
5520
+ node['default'] = false;
5521
+ nodes.push(finishNode(node, "ImportSpecifier"));
5522
+ }
5523
+ return nodes;
5524
+ }
2811
5525
 
2812
- function isFunction(node) {
2813
- return node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
2814
- }
5526
+ // Parses yield expression inside generator.
2815
5527
 
2816
- function isReference(node) {
2817
- var parent = node.$parent;
2818
- return node.$refToScope ||
2819
- node.type === "Identifier" &&
2820
- !(parent.type === "VariableDeclarator" && parent.id === node) && // var|let|const $
2821
- !(parent.type === "MemberExpression" && parent.computed === false && parent.property === node) && // obj.$
2822
- !(parent.type === "Property" && parent.key === node) && // {$: ...}
2823
- !(parent.type === "LabeledStatement" && parent.label === node) && // $: ...
2824
- !(parent.type === "CatchClause" && parent.param === node) && // catch($)
2825
- !(isFunction(parent) && parent.id === node) && // function $(..
2826
- !(isFunction(parent) && is.someof(node, parent.params)) && // function f($)..
2827
- true;
2828
- }
5528
+ function parseYield() {
5529
+ var node = startNode();
5530
+ next();
5531
+ if (eat(_semi) || canInsertSemicolon()) {
5532
+ node.delegate = false;
5533
+ node.argument = null;
5534
+ } else {
5535
+ node.delegate = eat(_star);
5536
+ node.argument = parseExpression(true);
5537
+ }
5538
+ return finishNode(node, "YieldExpression");
5539
+ }
5540
+
5541
+ // Parses array and generator comprehensions.
5542
+
5543
+ function parseComprehension(node, isGenerator) {
5544
+ node.blocks = [];
5545
+ while (tokType === _for) {
5546
+ var block = startNode();
5547
+ next();
5548
+ expect(_parenL);
5549
+ block.left = toAssignable(parseExprAtom());
5550
+ checkLVal(block.left, true);
5551
+ if (tokType !== _name || tokVal !== "of") unexpected();
5552
+ next();
5553
+ // `of` property is here for compatibility with Esprima's AST
5554
+ // which also supports deprecated [for (... in ...) expr]
5555
+ block.of = true;
5556
+ block.right = parseExpression();
5557
+ expect(_parenR);
5558
+ node.blocks.push(finishNode(block, "ComprehensionBlock"));
5559
+ }
5560
+ node.filter = eat(_if) ? parseParenExpression() : null;
5561
+ node.body = parseExpression();
5562
+ expect(isGenerator ? _parenR : _bracketR);
5563
+ node.generator = isGenerator;
5564
+ return finishNode(node, "ComprehensionExpression");
5565
+ }
2829
5566
 
2830
- },{"./scope":12,"assert":1,"ordered-ast-traverse":17,"simple-is":19}],14:[function(require,module,exports){
5567
+ });
5568
+
5569
+ },{}],15:[function(require,module,exports){
2831
5570
  // alter.js
2832
5571
  // MIT licensed, see LICENSE file
2833
5572
  // Copyright (c) 2013 Olov Lassus <olov.lassus@gmail.com>
@@ -2874,7 +5613,7 @@ if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
2874
5613
  module.exports = alter;
2875
5614
  }
2876
5615
 
2877
- },{"assert":1,"stable":30}],15:[function(require,module,exports){
5616
+ },{"assert":1,"stable":31}],16:[function(require,module,exports){
2878
5617
  /*
2879
5618
  Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com>
2880
5619
  Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>
@@ -6632,7 +9371,7 @@ parseStatement: true, parseSourceElement: true */
6632
9371
  }));
6633
9372
  /* vim: set sw=4 ts=4 et tw=80 : */
6634
9373
 
6635
- },{}],16:[function(require,module,exports){
9374
+ },{}],17:[function(require,module,exports){
6636
9375
  // ordered-esprima-props.js
6637
9376
  // MIT licensed, see LICENSE file
6638
9377
  // Copyright (c) 2014 Olov Lassus <olov.lassus@gmail.com>
@@ -6711,7 +9450,7 @@ module.exports = (function() {
6711
9450
  };
6712
9451
  })();
6713
9452
 
6714
- },{}],17:[function(require,module,exports){
9453
+ },{}],18:[function(require,module,exports){
6715
9454
  // ordered-ast-traverse.js
6716
9455
  // MIT licensed, see LICENSE file
6717
9456
  // Copyright (c) 2014 Olov Lassus <olov.lassus@gmail.com>
@@ -6772,7 +9511,7 @@ if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
6772
9511
  module.exports = traverse;
6773
9512
  }
6774
9513
 
6775
- },{"ordered-esprima-props":16}],18:[function(require,module,exports){
9514
+ },{"ordered-esprima-props":17}],19:[function(require,module,exports){
6776
9515
  // simple-fmt.js
6777
9516
  // MIT licensed, see LICENSE file
6778
9517
  // Copyright (c) 2013 Olov Lassus <olov.lassus@gmail.com>
@@ -6807,7 +9546,7 @@ if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
6807
9546
  module.exports = fmt;
6808
9547
  }
6809
9548
 
6810
- },{}],19:[function(require,module,exports){
9549
+ },{}],20:[function(require,module,exports){
6811
9550
  // simple-is.js
6812
9551
  // MIT licensed, see LICENSE file
6813
9552
  // Copyright (c) 2013 Olov Lassus <olov.lassus@gmail.com>
@@ -6865,7 +9604,7 @@ if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
6865
9604
  module.exports = is;
6866
9605
  }
6867
9606
 
6868
- },{}],20:[function(require,module,exports){
9607
+ },{}],21:[function(require,module,exports){
6869
9608
  /*
6870
9609
  * Copyright 2009-2011 Mozilla Foundation and contributors
6871
9610
  * Licensed under the New BSD license. See LICENSE.txt or:
@@ -6875,7 +9614,7 @@ exports.SourceMapGenerator = require('./source-map/source-map-generator').Source
6875
9614
  exports.SourceMapConsumer = require('./source-map/source-map-consumer').SourceMapConsumer;
6876
9615
  exports.SourceNode = require('./source-map/source-node').SourceNode;
6877
9616
 
6878
- },{"./source-map/source-map-consumer":25,"./source-map/source-map-generator":26,"./source-map/source-node":27}],21:[function(require,module,exports){
9617
+ },{"./source-map/source-map-consumer":26,"./source-map/source-map-generator":27,"./source-map/source-node":28}],22:[function(require,module,exports){
6879
9618
  /* -*- Mode: js; js-indent-level: 2; -*- */
6880
9619
  /*
6881
9620
  * Copyright 2011 Mozilla Foundation and contributors
@@ -6974,7 +9713,7 @@ define(function (require, exports, module) {
6974
9713
 
6975
9714
  });
6976
9715
 
6977
- },{"./util":28,"amdefine":29}],22:[function(require,module,exports){
9716
+ },{"./util":29,"amdefine":30}],23:[function(require,module,exports){
6978
9717
  /* -*- Mode: js; js-indent-level: 2; -*- */
6979
9718
  /*
6980
9719
  * Copyright 2011 Mozilla Foundation and contributors
@@ -7092,9 +9831,9 @@ define(function (require, exports, module) {
7092
9831
 
7093
9832
  /**
7094
9833
  * Decodes the next base 64 VLQ value from the given string and returns the
7095
- * value and the rest of the string.
9834
+ * value and the rest of the string via the out parameter.
7096
9835
  */
7097
- exports.decode = function base64VLQ_decode(aStr) {
9836
+ exports.decode = function base64VLQ_decode(aStr, aOutParam) {
7098
9837
  var i = 0;
7099
9838
  var strLen = aStr.length;
7100
9839
  var result = 0;
@@ -7112,15 +9851,13 @@ define(function (require, exports, module) {
7112
9851
  shift += VLQ_BASE_SHIFT;
7113
9852
  } while (continuation);
7114
9853
 
7115
- return {
7116
- value: fromVLQSigned(result),
7117
- rest: aStr.slice(i)
7118
- };
9854
+ aOutParam.value = fromVLQSigned(result);
9855
+ aOutParam.rest = aStr.slice(i);
7119
9856
  };
7120
9857
 
7121
9858
  });
7122
9859
 
7123
- },{"./base64":23,"amdefine":29}],23:[function(require,module,exports){
9860
+ },{"./base64":24,"amdefine":30}],24:[function(require,module,exports){
7124
9861
  /* -*- Mode: js; js-indent-level: 2; -*- */
7125
9862
  /*
7126
9863
  * Copyright 2011 Mozilla Foundation and contributors
@@ -7164,7 +9901,7 @@ define(function (require, exports, module) {
7164
9901
 
7165
9902
  });
7166
9903
 
7167
- },{"amdefine":29}],24:[function(require,module,exports){
9904
+ },{"amdefine":30}],25:[function(require,module,exports){
7168
9905
  /* -*- Mode: js; js-indent-level: 2; -*- */
7169
9906
  /*
7170
9907
  * Copyright 2011 Mozilla Foundation and contributors
@@ -7247,7 +9984,7 @@ define(function (require, exports, module) {
7247
9984
 
7248
9985
  });
7249
9986
 
7250
- },{"amdefine":29}],25:[function(require,module,exports){
9987
+ },{"amdefine":30}],26:[function(require,module,exports){
7251
9988
  /* -*- Mode: js; js-indent-level: 2; -*- */
7252
9989
  /*
7253
9990
  * Copyright 2011 Mozilla Foundation and contributors
@@ -7427,6 +10164,12 @@ define(function (require, exports, module) {
7427
10164
  }
7428
10165
  });
7429
10166
 
10167
+ SourceMapConsumer.prototype._nextCharIsMappingSeparator =
10168
+ function SourceMapConsumer_nextCharIsMappingSeparator(aStr) {
10169
+ var c = aStr.charAt(0);
10170
+ return c === ";" || c === ",";
10171
+ };
10172
+
7430
10173
  /**
7431
10174
  * Parse the mappings in a string in to a data structure which we can easily
7432
10175
  * query (the ordered arrays in the `this.__generatedMappings` and
@@ -7440,10 +10183,9 @@ define(function (require, exports, module) {
7440
10183
  var previousOriginalColumn = 0;
7441
10184
  var previousSource = 0;
7442
10185
  var previousName = 0;
7443
- var mappingSeparator = /^[,;]/;
7444
10186
  var str = aStr;
10187
+ var temp = {};
7445
10188
  var mapping;
7446
- var temp;
7447
10189
 
7448
10190
  while (str.length > 0) {
7449
10191
  if (str.charAt(0) === ';') {
@@ -7459,41 +10201,41 @@ define(function (require, exports, module) {
7459
10201
  mapping.generatedLine = generatedLine;
7460
10202
 
7461
10203
  // Generated column.
7462
- temp = base64VLQ.decode(str);
10204
+ base64VLQ.decode(str, temp);
7463
10205
  mapping.generatedColumn = previousGeneratedColumn + temp.value;
7464
10206
  previousGeneratedColumn = mapping.generatedColumn;
7465
10207
  str = temp.rest;
7466
10208
 
7467
- if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {
10209
+ if (str.length > 0 && !this._nextCharIsMappingSeparator(str)) {
7468
10210
  // Original source.
7469
- temp = base64VLQ.decode(str);
10211
+ base64VLQ.decode(str, temp);
7470
10212
  mapping.source = this._sources.at(previousSource + temp.value);
7471
10213
  previousSource += temp.value;
7472
10214
  str = temp.rest;
7473
- if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {
10215
+ if (str.length === 0 || this._nextCharIsMappingSeparator(str)) {
7474
10216
  throw new Error('Found a source, but no line and column');
7475
10217
  }
7476
10218
 
7477
10219
  // Original line.
7478
- temp = base64VLQ.decode(str);
10220
+ base64VLQ.decode(str, temp);
7479
10221
  mapping.originalLine = previousOriginalLine + temp.value;
7480
10222
  previousOriginalLine = mapping.originalLine;
7481
10223
  // Lines are stored 0-based
7482
10224
  mapping.originalLine += 1;
7483
10225
  str = temp.rest;
7484
- if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {
10226
+ if (str.length === 0 || this._nextCharIsMappingSeparator(str)) {
7485
10227
  throw new Error('Found a source and line, but no column');
7486
10228
  }
7487
10229
 
7488
10230
  // Original column.
7489
- temp = base64VLQ.decode(str);
10231
+ base64VLQ.decode(str, temp);
7490
10232
  mapping.originalColumn = previousOriginalColumn + temp.value;
7491
10233
  previousOriginalColumn = mapping.originalColumn;
7492
10234
  str = temp.rest;
7493
10235
 
7494
- if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {
10236
+ if (str.length > 0 && !this._nextCharIsMappingSeparator(str)) {
7495
10237
  // Original name.
7496
- temp = base64VLQ.decode(str);
10238
+ base64VLQ.decode(str, temp);
7497
10239
  mapping.name = this._names.at(previousName + temp.value);
7498
10240
  previousName += temp.value;
7499
10241
  str = temp.rest;
@@ -7727,7 +10469,7 @@ define(function (require, exports, module) {
7727
10469
 
7728
10470
  });
7729
10471
 
7730
- },{"./array-set":21,"./base64-vlq":22,"./binary-search":24,"./util":28,"amdefine":29}],26:[function(require,module,exports){
10472
+ },{"./array-set":22,"./base64-vlq":23,"./binary-search":25,"./util":29,"amdefine":30}],27:[function(require,module,exports){
7731
10473
  /* -*- Mode: js; js-indent-level: 2; -*- */
7732
10474
  /*
7733
10475
  * Copyright 2011 Mozilla Foundation and contributors
@@ -7934,9 +10676,7 @@ define(function (require, exports, module) {
7934
10676
  }
7935
10677
  mapping.originalLine = original.line;
7936
10678
  mapping.originalColumn = original.column;
7937
- if (original.name != null && mapping.name != null) {
7938
- // Only use the identifier name if it's an identifier
7939
- // in both SourceMaps
10679
+ if (original.name != null) {
7940
10680
  mapping.name = original.name;
7941
10681
  }
7942
10682
  }
@@ -8132,7 +10872,7 @@ define(function (require, exports, module) {
8132
10872
 
8133
10873
  });
8134
10874
 
8135
- },{"./array-set":21,"./base64-vlq":22,"./util":28,"amdefine":29}],27:[function(require,module,exports){
10875
+ },{"./array-set":22,"./base64-vlq":23,"./util":29,"amdefine":30}],28:[function(require,module,exports){
8136
10876
  /* -*- Mode: js; js-indent-level: 2; -*- */
8137
10877
  /*
8138
10878
  * Copyright 2011 Mozilla Foundation and contributors
@@ -8542,7 +11282,7 @@ define(function (require, exports, module) {
8542
11282
 
8543
11283
  });
8544
11284
 
8545
- },{"./source-map-generator":26,"./util":28,"amdefine":29}],28:[function(require,module,exports){
11285
+ },{"./source-map-generator":27,"./util":29,"amdefine":30}],29:[function(require,module,exports){
8546
11286
  /* -*- Mode: js; js-indent-level: 2; -*- */
8547
11287
  /*
8548
11288
  * Copyright 2011 Mozilla Foundation and contributors
@@ -8863,7 +11603,7 @@ define(function (require, exports, module) {
8863
11603
 
8864
11604
  });
8865
11605
 
8866
- },{"amdefine":29}],29:[function(require,module,exports){
11606
+ },{"amdefine":30}],30:[function(require,module,exports){
8867
11607
  (function (process,__filename){
8868
11608
  /** vim: et:ts=4:sw=4:sts=4
8869
11609
  * @license amdefine 0.1.0 Copyright (c) 2011, The Dojo Foundation All Rights Reserved.
@@ -9166,7 +11906,7 @@ function amdefine(module, requireFn) {
9166
11906
  module.exports = amdefine;
9167
11907
 
9168
11908
  }).call(this,require('_process'),"/node_modules/ng-annotate/node_modules/source-map/node_modules/amdefine/amdefine.js")
9169
- },{"_process":5,"path":4}],30:[function(require,module,exports){
11909
+ },{"_process":5,"path":4}],31:[function(require,module,exports){
9170
11910
  //! stable.js 0.1.5, https://github.com/Two-Screen/stable
9171
11911
  //! © 2014 Angry Bytes and contributors. MIT licensed.
9172
11912
 
@@ -9279,7 +12019,7 @@ else {
9279
12019
 
9280
12020
  })();
9281
12021
 
9282
- },{}],31:[function(require,module,exports){
12022
+ },{}],32:[function(require,module,exports){
9283
12023
  // stringmap.js
9284
12024
  // MIT licensed, see LICENSE file
9285
12025
  // Copyright (c) 2013 Olov Lassus <olov.lassus@gmail.com>
@@ -9525,7 +12265,7 @@ if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
9525
12265
  module.exports = StringMap;
9526
12266
  }
9527
12267
 
9528
- },{}],32:[function(require,module,exports){
12268
+ },{}],33:[function(require,module,exports){
9529
12269
  // stringset.js
9530
12270
  // MIT licensed, see LICENSE file
9531
12271
  // Copyright (c) 2013 Olov Lassus <olov.lassus@gmail.com>