ngannotate-rails 0.9.9 → 0.9.11

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,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ODQ2NmUwNTEwZDE5MTA2YzUwZTg2ZGM0NWVlMjM2NzcxYzdhMWM3YQ==
4
+ MWE4NWU5NzAyODRkODQ3ZTE3Y2Q1NWM1ODBkMmIyYzkyZmYzMGY2MA==
5
5
  data.tar.gz: !binary |-
6
- MWNhYWZlMTQ3NzZmYmEzYmYzNzIzNmNjZmI0OThlMGVjYzg5YmJkMw==
6
+ MWY2ZGNlZTEzZmUwYmZiYzA5MmMzYzIzOGVkMzBkNWVmZWY3NzA3OQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YmE0MDM1MGYyNjI2NzEzMzlmNWZiYWE1NGMxNDRiZTk1MzYzMTA4ODYyNzRh
10
- M2VmODNiMzhiOGFhNWVlNTY2MzAyNjY4MjM1OTZmOGFjN2VhMmI1NmFiYzk3
11
- NGQxNzlhZDg1M2ZhMzhkODE4YTUxMmRmOGRhNWYxYTA5NzhkN2M=
9
+ N2I1NzE3YzQ2M2FmOGM4NjU4NDViZmQyYzMwZGQ3NDU4OTRlNmM1YTAxNTFk
10
+ MGM4MDRmOTBjZDQ1Zjc0M2I3OWI3NWRhYjRhZTU3NzRjMzI5ZTdhZjAzODg2
11
+ YmRjMTRlMDBmMTc3ZWI3YmFjMTIzOTMxYzJkNzcyZjU4ZjkyMmY=
12
12
  data.tar.gz: !binary |-
13
- MTkzNDQxZjc3OWFlMmE1MTdkYjcwYjU5OGE3OTAwNmQ5YWQ2ZmY3ZDMzNTZl
14
- MGZiNzlkMzMyNTYwYWNiNjMzMzA4ZWVjZWM5Njc3YTU2NjcyZWJlNmViNWRh
15
- MWI4Mzc1ODk4MzQwODExM2NiMjRmODM3ZjY1NjZlMTNkMThkNTM=
13
+ ZDJkMGNjYTBkNjJlY2EyYWNhMmJhNzI2Y2UzNmZhZDQ1NjIzMGQzZjk3Yjli
14
+ ODNiNjQxYzNlZGQxZTUwY2MzNDEzZDY1MjIyMjQ0OWM2ZDg1NmM1MDc3NWE3
15
+ Y2YyMDkzZjJlOWFiNDE1NGRjN2IxN2Y1ZDlhZTU2NzVlOTQ4OTI=
@@ -1,5 +1,5 @@
1
1
  module Ngannotate
2
2
  module Rails
3
- VERSION = "0.9.9"
3
+ VERSION = "0.9.11"
4
4
  end
5
5
  end
@@ -1414,44 +1414,135 @@ module.exports = function generateSourcemap(src, fragments, inFile, sourceRoot)
1414
1414
  return new SourceMapper(src, fragments, inFile, sourceRoot).generate();
1415
1415
  }
1416
1416
 
1417
- },{"source-map":19,"stable":29}],9:[function(require,module,exports){
1417
+ },{"source-map":20,"stable":30}],9:[function(require,module,exports){
1418
+ // lut.js
1419
+ // MIT licensed, see LICENSE file
1420
+ // Copyright (c) 2013-2014 Olov Lassus <olov.lassus@gmail.com>
1421
+
1418
1422
  "use strict";
1419
1423
 
1420
1424
  var assert = require("assert");
1421
- var PriorityQueue = require("priorityqueuejs");
1425
+ var traverse = require("ordered-ast-traverse");
1426
+ var is = require("simple-is");
1422
1427
 
1423
- function Heap() {
1424
- assert(this instanceof Heap);
1428
+ module.exports = Lut;
1425
1429
 
1426
- var q = new PriorityQueue(function(a, b) {
1427
- return b.pos - a.pos;
1428
- });
1430
+ function Lut(ast, src) {
1431
+ assert(this instanceof Lut);
1429
1432
 
1430
- function nextPos() {
1431
- return (q.size() >= 1 ? q.peek().pos : (1 << 30));
1433
+ var sparseBegins = new Array(src.length);
1434
+ var begins = [];
1435
+ var sparseEnds = new Array(src.length);
1436
+ var ends = [];
1437
+ var p = 0;
1438
+ var t0 = Date.now();
1439
+ traverse(ast, {pre: function(node) {
1440
+ // assert (node.range[0] >= p);
1441
+ if (node.type === "Program") {
1442
+ return;
1443
+ }
1444
+ p = node.range[0];
1445
+ if (!sparseBegins[p]) {
1446
+ sparseBegins[p] = node;
1447
+ }
1448
+ p = node.range[1];
1449
+ if (!sparseEnds[p]) {
1450
+ sparseEnds[p] = node;
1451
+ }
1452
+ }});
1453
+ for (var i in sparseBegins) {
1454
+ begins.push(sparseBegins[i]);
1432
1455
  }
1456
+ for (var i$0 in sparseEnds) {
1457
+ ends.push(sparseEnds[i$0]);
1458
+ }
1459
+ var t1 = Date.now();
1460
+ // console.error(t1-t0)
1433
1461
 
1434
- this.pos = (1 << 30);
1435
- this.addMany = function(arr) {
1436
- arr.forEach(function(e) {
1437
- q.enq(e);
1438
- });
1439
- this.pos = nextPos();
1440
- };
1441
- this.add = function(e) {
1442
- q.enq(e);
1443
- this.pos = nextPos();
1444
- };
1445
- this.getAndRemoveNext = function() {
1446
- var e = q.deq();
1447
- this.pos = nextPos();
1448
- return e;
1449
- };
1462
+ // begins and ends are compact arrays with nodes,
1463
+ // sorted on node.range[0/1] (unique)
1464
+ this.begins = begins;
1465
+ this.ends = ends;
1466
+ }
1467
+
1468
+ Lut.prototype.findNodeFromPos = findNodeFromPos;
1469
+ Lut.prototype.findNodeBeforePos = findNodeBeforePos;
1470
+
1471
+ // binary search lut to find node beginning at pos
1472
+ // or as close after pos as possible. null if none
1473
+ function findNodeFromPos(pos) {
1474
+ var lut = this.begins;
1475
+ assert(is.finitenumber(pos) && pos >= 0);
1476
+
1477
+ var left = 0;
1478
+ var right = lut.length - 1;
1479
+ while (left < right) {
1480
+ var mid = Math.floor((left + right) / 2);
1481
+ assert(mid >= 0 && mid < lut.length);
1482
+ if (pos > lut[mid].range[0]) {
1483
+ left = mid + 1;
1484
+ }
1485
+ else {
1486
+ right = mid;
1487
+ }
1488
+ }
1489
+ if (left > right) {
1490
+ assert(last(lut).range[0] < pos);
1491
+ return null;
1492
+ }
1493
+
1494
+ var found = left;
1495
+ var foundPos = lut[found].range[0];
1496
+ assert(foundPos >= pos);
1497
+ if (found >= 1) {
1498
+ var prevPos = lut[found - 1].range[0];
1499
+ assert(prevPos < pos);
1500
+ }
1501
+
1502
+ return lut[found];
1450
1503
  }
1451
1504
 
1452
- module.exports = Heap;
1505
+ // binary search lut to find node ending (as in range[1]
1506
+ // at or before pos. null if none
1507
+ function findNodeBeforePos(pos) {
1508
+ var lut = this.ends;
1509
+ assert(is.finitenumber(pos) && pos >= 0);
1453
1510
 
1454
- },{"assert":1,"priorityqueuejs":16}],10:[function(require,module,exports){
1511
+ var left = 0;
1512
+ var right = lut.length - 1;
1513
+ while (left < right) {
1514
+ var mid = Math.ceil((left + right) / 2);
1515
+ assert(mid >= 0 && mid < lut.length);
1516
+ if (pos < lut[mid].range[1]) {
1517
+ right = mid - 1;
1518
+ }
1519
+ else {
1520
+ left = mid;
1521
+ }
1522
+ }
1523
+ if (left > right) {
1524
+ assert(lut[0].range[1] > pos);
1525
+ return null;
1526
+ }
1527
+
1528
+ var found = left;
1529
+ var foundPos = lut[found].range[1];
1530
+ if(foundPos > pos) {
1531
+ return null;
1532
+ }
1533
+ if (found <= lut.length - 2) {
1534
+ var nextPos = lut[found + 1].range[1];
1535
+ assert(nextPos > pos);
1536
+ }
1537
+
1538
+ return lut[found];
1539
+ }
1540
+
1541
+ function last(arr) {
1542
+ return arr[arr.length - 1];
1543
+ }
1544
+
1545
+ },{"assert":1,"ordered-ast-traverse":17,"simple-is":19}],10:[function(require,module,exports){
1455
1546
  // ng-annotate-main.js
1456
1547
  // MIT licensed, see LICENSE file
1457
1548
  // Copyright (c) 2013-2014 Olov Lassus <olov.lassus@gmail.com>
@@ -1460,12 +1551,16 @@ module.exports = Heap;
1460
1551
  var esprima_require_t0 = Date.now();
1461
1552
  var esprima = require("esprima").parse;
1462
1553
  var esprima_require_t1 = Date.now();
1554
+ var fmt = require("simple-fmt");
1463
1555
  var is = require("simple-is");
1464
1556
  var alter = require("alter");
1465
1557
  var traverse = require("ordered-ast-traverse");
1466
- var Heap = require("./heap");
1467
- var ngInjectComments = require("./nginject-comments");
1558
+ var EOL = require("os").EOL;
1559
+ var assert = require("assert");
1560
+ var ngInject = require("./nginject");
1468
1561
  var generateSourcemap = require("./generate-sourcemap");
1562
+ var Lut = require("./lut");
1563
+ var scopeTools = require("./scopetools");
1469
1564
 
1470
1565
  var chainedRouteProvider = 1;
1471
1566
  var chainedUrlRouterProvider = 2;
@@ -1806,6 +1901,14 @@ function judgeSuspects(ctx) {
1806
1901
  }
1807
1902
 
1808
1903
  target = jumpOverIife(target);
1904
+ var followedTarget = followReference(target);
1905
+ if (followedTarget) {
1906
+ if (followedTarget.$once) {
1907
+ continue;
1908
+ }
1909
+ followedTarget.$once = true;
1910
+ target = followedTarget;
1911
+ }
1809
1912
 
1810
1913
  if (mode === "rebuild" && isAnnotatedArray(target)) {
1811
1914
  replaceArray(target, fragments, quot);
@@ -1813,6 +1916,121 @@ function judgeSuspects(ctx) {
1813
1916
  removeArray(target, fragments);
1814
1917
  } else if (is.someof(mode, ["add", "rebuild"]) && isFunctionExpressionWithArgs(target)) {
1815
1918
  insertArray(target, fragments, quot);
1919
+ } else {
1920
+ // if it's not array or function-expression, then it's a candidate for foo.$inject = [..]
1921
+ judgeInjectArraySuspect(target, ctx);
1922
+ }
1923
+ }
1924
+ }
1925
+
1926
+ function followReference(node) {
1927
+ if (!scopeTools.isReference(node)) {
1928
+ return null;
1929
+ }
1930
+
1931
+ var scope = node.$scope.lookup(node.name);
1932
+ if (!scope) {
1933
+ return null;
1934
+ }
1935
+
1936
+ var parent = scope.getNode(node.name).$parent;
1937
+ var kind = scope.getKind(node.name);
1938
+ var ptype = parent.type;
1939
+
1940
+ if (is.someof(kind, ["const", "let", "var"])) {
1941
+ assert(ptype === "VariableDeclarator");
1942
+ return parent.init;
1943
+ } else if (kind === "fun") {
1944
+ assert(ptype === "FunctionDeclaration" || ptype === "FunctionExpression")
1945
+ return parent;
1946
+ }
1947
+
1948
+ // other kinds should not be handled ("param", "caught")
1949
+
1950
+ return null;
1951
+ }
1952
+
1953
+ function judgeInjectArraySuspect(node, ctx) {
1954
+ // /*@ngInject*/ var foo = function($scope) {} and
1955
+ // /*@ngInject*/ function foo($scope) {} and
1956
+ // /*@ngInject*/ foo.bar[0] = function($scope) {}
1957
+ var d0 = null;
1958
+ var nr0 = node.range[0];
1959
+ var nr1 = node.range[1];
1960
+ if (node.type === "VariableDeclaration" && node.declarations.length === 1 &&
1961
+ (d0 = node.declarations[0]).init && ctx.isFunctionExpressionWithArgs(d0.init)) {
1962
+ var isSemicolonTerminated = (ctx.src[nr1 - 1] === ";");
1963
+ addRemoveInjectArray(d0.init.params, nr0, isSemicolonTerminated ? nr1 : d0.init.range[1], d0.id.name);
1964
+ } else if (ctx.isFunctionDeclarationWithArgs(node)) {
1965
+ addRemoveInjectArray(node.params, nr0, nr1, node.id.name);
1966
+ } else if (node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" &&
1967
+ ctx.isFunctionExpressionWithArgs(node.expression.right)) {
1968
+ var isSemicolonTerminated$0 = (ctx.src[nr1 - 1] === ";");
1969
+ var name = ctx.srcForRange(node.expression.left.range);
1970
+ addRemoveInjectArray(node.expression.right.params, nr0, isSemicolonTerminated$0 ? nr1 : node.expression.right.range[1], name);
1971
+ }
1972
+
1973
+ function getIndent(pos) {
1974
+ var src = ctx.src;
1975
+ var lineStart = src.lastIndexOf("\n", pos - 1) + 1;
1976
+ var i = lineStart;
1977
+ for (; src[i] === " " || src[i] === "\t"; i++) {
1978
+ }
1979
+ return src.slice(lineStart, i);
1980
+ }
1981
+
1982
+ function addRemoveInjectArray(params, posBeforeFunctionDeclaration, posAfterFunctionDeclaration, name) {
1983
+ var indent = getIndent(posAfterFunctionDeclaration);
1984
+
1985
+ var nextNode = ctx.lut.findNodeFromPos(posAfterFunctionDeclaration);
1986
+ var prevNode = ctx.lut.findNodeBeforePos(posBeforeFunctionDeclaration);
1987
+
1988
+ function hasInjectArray(node) {
1989
+ var lvalue;
1990
+ var assignment;
1991
+ return (node && node.type === "ExpressionStatement" && (assignment = node.expression).type === "AssignmentExpression" &&
1992
+ assignment.operator === "=" &&
1993
+ (lvalue = assignment.left).type === "MemberExpression" &&
1994
+ ((lvalue.computed === false && ctx.srcForRange(lvalue.object.range) === name && lvalue.property.name === "$inject") ||
1995
+ (lvalue.computed === true && ctx.srcForRange(lvalue.object.range) === name && lvalue.property.type === "Literal" && lvalue.property.value === "$inject")));
1996
+ }
1997
+
1998
+ function skipNewline(pos) {
1999
+ if (ctx.src[pos] === "\n") {
2000
+ return pos + 1;
2001
+ } else if (ctx.src.slice(pos, pos + 2) === "\r\n") {
2002
+ return pos + 2;
2003
+ }
2004
+ return pos;
2005
+ }
2006
+
2007
+ var hasArrayBefore = hasInjectArray(prevNode);
2008
+ var hasArrayAfter = hasInjectArray(nextNode);
2009
+
2010
+ var hasArray = hasArrayBefore || hasArrayAfter;
2011
+ var start = hasArrayBefore ? prevNode.range[0]: posAfterFunctionDeclaration;
2012
+ var end = hasArrayBefore ? skipNewline(prevNode.range[1]) : nextNode.range[1];
2013
+
2014
+ var str = fmt("{0}{1}{2}.$inject = {3};", EOL, indent, name, ctx.stringify(params, ctx.quot));
2015
+
2016
+ if (ctx.mode === "rebuild" && hasArray) {
2017
+ ctx.fragments.push({
2018
+ start: start,
2019
+ end: end,
2020
+ str: str,
2021
+ });
2022
+ } else if (ctx.mode === "remove" && hasArray) {
2023
+ ctx.fragments.push({
2024
+ start: start,
2025
+ end: end,
2026
+ str: "",
2027
+ });
2028
+ } else if (is.someof(ctx.mode, ["add", "rebuild"]) && !hasArray) {
2029
+ ctx.fragments.push({
2030
+ start: posAfterFunctionDeclaration,
2031
+ end: posAfterFunctionDeclaration,
2032
+ str: str,
2033
+ });
1816
2034
  }
1817
2035
  }
1818
2036
  }
@@ -1881,7 +2099,7 @@ window.annotate = function ngAnnotate(src, options) {
1881
2099
  // Fix Program node range (https://code.google.com/p/esprima/issues/detail?id=541)
1882
2100
  ast.range[0] = 0;
1883
2101
 
1884
- // append a dummy-node to ast to catch any remaining triggers
2102
+ // append a dummy-node to ast so that lut.findNodeFromPos(lastPos) returns something
1885
2103
  ast.body.push({
1886
2104
  type: "DebuggerStatement",
1887
2105
  range: [ast.range[1], ast.range[1]],
@@ -1896,10 +2114,6 @@ window.annotate = function ngAnnotate(src, options) {
1896
2114
  // fragments array, later sent to alter in one shot
1897
2115
  var fragments = [];
1898
2116
 
1899
- // triggers contains functions to trigger when traverse hits the
1900
- // first node at (or after) a certain pos
1901
- var triggers = new Heap();
1902
-
1903
2117
  // suspects is built up with suspect nodes by match.
1904
2118
  // A suspect node will get annotations added / removed if it
1905
2119
  // fulfills the arrayexpression or functionexpression look,
@@ -1908,6 +2122,10 @@ window.annotate = function ngAnnotate(src, options) {
1908
2122
  // context with node.$always = true
1909
2123
  var suspects = [];
1910
2124
 
2125
+ var lut = new Lut(ast, src);
2126
+
2127
+ scopeTools.setupScopeAndReferences(ast);
2128
+
1911
2129
  var ctx = {
1912
2130
  mode: mode,
1913
2131
  quot: quot,
@@ -1918,8 +2136,8 @@ window.annotate = function ngAnnotate(src, options) {
1918
2136
  re: re,
1919
2137
  comments: comments,
1920
2138
  fragments: fragments,
1921
- triggers: triggers,
1922
2139
  suspects: suspects,
2140
+ lut: lut,
1923
2141
  isFunctionExpressionWithArgs: isFunctionExpressionWithArgs,
1924
2142
  isFunctionDeclarationWithArgs: isFunctionDeclarationWithArgs,
1925
2143
  isAnnotatedArray: isAnnotatedArray,
@@ -1940,7 +2158,7 @@ window.annotate = function ngAnnotate(src, options) {
1940
2158
  }
1941
2159
  var matchPluginsOrNull = (plugins.length === 0 ? null : matchPlugins);
1942
2160
 
1943
- ngInjectComments.init(ctx);
2161
+ ngInject.inspectComments(ctx);
1944
2162
  plugins.forEach(function(plugin) {
1945
2163
  plugin.init(ctx);
1946
2164
  });
@@ -1952,13 +2170,9 @@ window.annotate = function ngAnnotate(src, options) {
1952
2170
  if (node.type === "CallExpression") {
1953
2171
  callerIds.push(node);
1954
2172
  recentCaller = node;
2173
+ ngInject.inspectCallExpression(node, ctx);
1955
2174
  }
1956
2175
 
1957
- var pos = node.range[0];
1958
- while (pos >= triggers.pos) {
1959
- var trigger = triggers.getAndRemoveNext();
1960
- trigger.fn.call(null, node, trigger.ctx);
1961
- }
1962
2176
  }, post: function(node) {
1963
2177
  if (node === recentCaller) {
1964
2178
  callerIds.pop();
@@ -1995,33 +2209,71 @@ window.annotate = function ngAnnotate(src, options) {
1995
2209
  return result;
1996
2210
  }
1997
2211
 
1998
- },{"./generate-sourcemap":8,"./heap":9,"./nginject-comments":11,"alter":12,"esprima":13,"ordered-ast-traverse":15,"simple-is":18}],11:[function(require,module,exports){
2212
+ },{"./generate-sourcemap":8,"./lut":9,"./nginject":11,"./scopetools":13,"alter":14,"assert":1,"esprima":15,"ordered-ast-traverse":17,"os":5,"simple-fmt":18,"simple-is":19}],11:[function(require,module,exports){
2213
+ // nginject-comments.js
2214
+ // MIT licensed, see LICENSE file
2215
+ // Copyright (c) 2013-2014 Olov Lassus <olov.lassus@gmail.com>
2216
+
1999
2217
  "use strict";
2000
2218
 
2001
- var os = require("os");
2002
2219
  var is = require("simple-is");
2003
2220
  var fmt = require("simple-fmt");
2004
2221
 
2005
2222
  module.exports = {
2006
- init: ngInjectCommentsInit,
2223
+ inspectComments: inspectComments,
2224
+ inspectCallExpression: inspectCallExpression,
2007
2225
  };
2008
2226
 
2009
- function ngInjectCommentsInit(ctx) {
2227
+ function inspectCallExpression(node, ctx) {
2228
+ if (node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "ngInject" && node.arguments.length === 1) {
2229
+ addSuspect(node.arguments[0], ctx);
2230
+ }
2231
+ }
2232
+
2233
+ function inspectComments(ctx) {
2010
2234
  var comments = ctx.comments;
2011
- var triggers = [];
2012
2235
  for (var i = 0; i < comments.length; i++) {
2013
2236
  var comment = comments[i];
2014
2237
  var pos = comment.value.indexOf("@ngInject");
2015
- if (pos >= 0) {
2016
- triggers.push({
2017
- pos: comment.range[1],
2018
- fn: visitNodeFollowingNgInjectComment,
2019
- ctx: ctx,
2020
- });
2238
+ if (pos === -1) {
2239
+ continue;
2240
+ }
2241
+
2242
+ var target = ctx.lut.findNodeFromPos(comment.range[1]);
2243
+ if (!target) {
2244
+ continue;
2021
2245
  }
2246
+
2247
+ addSuspect(target, ctx);
2248
+ }
2249
+ }
2250
+
2251
+ function addSuspect(target, ctx) {
2252
+ if (target.type === "ObjectExpression") {
2253
+ // /*@ngInject*/ {f1: function(a), .., {f2: function(b)}}
2254
+ addObjectExpression(target, ctx);
2255
+ } else if (target.type === "AssignmentExpression" && target.right.type === "ObjectExpression") {
2256
+ // /*@ngInject*/ f(x.y = {f1: function(a), .., {f2: function(b)}})
2257
+ addObjectExpression(target.right, ctx);
2258
+ } else if (target.type === "ExpressionStatement" && target.expression.type === "AssignmentExpression" && target.expression.right.type === "ObjectExpression") {
2259
+ // /*@ngInject*/ x.y = {f1: function(a), .., {f2: function(b)}}
2260
+ addObjectExpression(target.expression.right, ctx);
2261
+ } else if (target.type === "VariableDeclaration" && target.declarations.length === 1 && target.declarations[0].init && target.declarations[0].init.type === "ObjectExpression") {
2262
+ // /*@ngInject*/ var x = {f1: function(a), .., {f2: function(b)}}
2263
+ addObjectExpression(target.declarations[0].init, ctx);
2264
+ } else if (target.type === "Property") {
2265
+ // {/*@ngInject*/ justthisone: function(a), ..}
2266
+ ctx.addModuleContextIndependentSuspect(target.value, ctx);
2267
+ } else {
2268
+ // /*@ngInject*/ function(a) {}
2269
+ ctx.addModuleContextIndependentSuspect(target, ctx);
2022
2270
  }
2271
+ }
2023
2272
 
2024
- ctx.triggers.addMany(triggers);
2273
+ function addObjectExpression(node, ctx) {
2274
+ nestedObjectValues(node).forEach(function(n) {
2275
+ ctx.addModuleContextIndependentSuspect(n, ctx);
2276
+ });
2025
2277
  }
2026
2278
 
2027
2279
  function nestedObjectValues(node, res) {
@@ -2039,89 +2291,349 @@ function nestedObjectValues(node, res) {
2039
2291
  return res;
2040
2292
  }
2041
2293
 
2042
- function visitNodeFollowingNgInjectComment(node, ctx) {
2043
- // handle most common case: /*@ngInject*/ prepended to an array or function expression
2044
- // (or call expression, in case of IIFE jumping)
2045
- if (node.type === "ArrayExpression" || node.type === "FunctionExpression" || node.type === "CallExpression") {
2046
- ctx.addModuleContextIndependentSuspect(node, ctx);
2047
- return;
2294
+ },{"simple-fmt":18,"simple-is":19}],12:[function(require,module,exports){
2295
+ // scope.js
2296
+ // MIT licensed, see LICENSE file
2297
+ // Copyright (c) 2013-2014 Olov Lassus <olov.lassus@gmail.com>
2298
+
2299
+ "use strict";
2300
+
2301
+ var assert = require("assert");
2302
+ var stringmap = require("stringmap");
2303
+ var stringset = require("stringset");
2304
+ var is = require("simple-is");
2305
+ var fmt = require("simple-fmt");
2306
+
2307
+ function Scope(args) {
2308
+ assert(is.someof(args.kind, ["hoist", "block", "catch-block"]));
2309
+ assert(is.object(args.node));
2310
+ assert(args.parent === null || is.object(args.parent));
2311
+
2312
+ // kind === "hoist": function scopes, program scope, injected globals
2313
+ // kind === "block": ES6 block scopes
2314
+ // kind === "catch-block": catch block scopes
2315
+ this.kind = args.kind;
2316
+
2317
+ // the AST node the block corresponds to
2318
+ this.node = args.node;
2319
+
2320
+ // parent scope
2321
+ this.parent = args.parent;
2322
+
2323
+ // children scopes for easier traversal (populated internally)
2324
+ this.children = [];
2325
+
2326
+ // scope declarations. decls[variable_name] = {
2327
+ // kind: "fun" for functions,
2328
+ // "param" for function parameters,
2329
+ // "caught" for catch parameter
2330
+ // "var",
2331
+ // "const",
2332
+ // "let"
2333
+ // node: the AST node the declaration corresponds to
2334
+ // from: source code index from which it is visible at earliest
2335
+ // (only stored for "const", "let" [and "var"] nodes)
2336
+ // }
2337
+ this.decls = stringmap();
2338
+
2339
+ // names of all variables declared outside this hoist scope but
2340
+ // referenced in this scope (immediately or in child).
2341
+ // only stored on hoist scopes for efficiency
2342
+ // (because we currently generate lots of empty block scopes)
2343
+ this.propagates = (this.kind === "hoist" ? stringset() : null);
2344
+
2345
+ // scopes register themselves with their parents for easier traversal
2346
+ if (this.parent) {
2347
+ this.parent.children.push(this);
2048
2348
  }
2349
+ }
2049
2350
 
2050
- if (node.type === "ObjectExpression") {
2051
- nestedObjectValues(node).forEach(function(n) {
2052
- ctx.addModuleContextIndependentSuspect(n, ctx);
2053
- });
2054
- return;
2351
+ Scope.prototype.print = function(indent) {
2352
+ indent = indent || 0;
2353
+ var scope = this;
2354
+ var names = this.decls.keys().map(function(name) {
2355
+ return fmt("{0} [{1}]", name, scope.decls.get(name).kind);
2356
+ }).join(", ");
2357
+ var propagates = this.propagates ? this.propagates.items().join(", ") : "";
2358
+ console.log(fmt("{0}{1}: {2}. propagates: {3}", fmt.repeat(" ", indent), this.node.type, names, propagates));
2359
+ this.children.forEach(function(c) {
2360
+ c.print(indent + 2);
2361
+ });
2362
+ };
2363
+
2364
+ Scope.prototype.add = function(name, kind, node, referableFromPos) {
2365
+ assert(is.someof(kind, ["fun", "param", "var", "caught", "const", "let"]));
2366
+
2367
+ function isConstLet(kind) {
2368
+ return is.someof(kind, ["const", "let"]);
2055
2369
  }
2056
2370
 
2057
- // /*@ngInject*/ var foo = function($scope) {} and
2058
- // /*@ngInject*/ function foo($scope) {}
2059
- var d0 = null;
2060
- var nr1 = node.range[1];
2061
- if (node.type === "VariableDeclaration" && node.declarations.length === 1 &&
2062
- (d0 = node.declarations[0]).init && ctx.isFunctionExpressionWithArgs(d0.init)) {
2063
- var isSemicolonTerminated = (ctx.src[nr1 - 1] === ";");
2064
- addRemoveInjectArray(d0.init.params, isSemicolonTerminated ? nr1 : d0.init.range[1], d0.id.name);
2065
- } else if (ctx.isFunctionDeclarationWithArgs(node)) {
2066
- addRemoveInjectArray(node.params, nr1, node.id.name);
2067
- } else if (node.type === "ExpressionStatement" && node.expression.type === "AssignmentExpression" &&
2068
- ctx.isFunctionExpressionWithArgs(node.expression.right)) {
2069
- var isSemicolonTerminated$0 = (ctx.src[nr1 - 1] === ";");
2070
- var name = ctx.srcForRange(node.expression.left.range);
2071
- addRemoveInjectArray(node.expression.right.params, isSemicolonTerminated$0 ? nr1 : node.expression.right.range[1], name);
2371
+ var scope = this;
2372
+
2373
+ // search nearest hoist-scope for fun, param and var's
2374
+ // const, let and caught variables go directly in the scope (which may be hoist, block or catch-block)
2375
+ if (is.someof(kind, ["fun", "param", "var"])) {
2376
+ while (scope.kind !== "hoist") {
2377
+ // if (scope.decls.has(name) && isConstLet(scope.decls.get(name).kind)) { // could be caught
2378
+ // return error(getline(node), "{0} is already declared", name);
2379
+ // }
2380
+ scope = scope.parent;
2381
+ }
2072
2382
  }
2383
+ // name exists in scope and either new or existing kind is const|let => error
2384
+ // if (scope.decls.has(name) && (isConstLet(scope.decls.get(name).kind) || isConstLet(kind))) {
2385
+ // return error(getline(node), "{0} is already declared", name);
2386
+ // }
2073
2387
 
2074
- function getIndent(pos) {
2075
- var src = ctx.src;
2076
- var lineStart = src.lastIndexOf("\n", pos - 1) + 1;
2077
- var i = lineStart;
2078
- for (; src[i] === " " || src[i] === "\t"; i++) {
2388
+ var declaration = {
2389
+ kind: kind,
2390
+ node: node,
2391
+ };
2392
+ if (referableFromPos) {
2393
+ assert(is.someof(kind, ["var", "const", "let"]));
2394
+ declaration.from = referableFromPos;
2395
+ }
2396
+ scope.decls.set(name, declaration);
2397
+ };
2398
+
2399
+ Scope.prototype.getKind = function(name) {
2400
+ assert(is.string(name));
2401
+ var decl = this.decls.get(name);
2402
+ return decl ? decl.kind : null;
2403
+ };
2404
+
2405
+ Scope.prototype.getNode = function(name) {
2406
+ assert(is.string(name));
2407
+ var decl = this.decls.get(name);
2408
+ return decl ? decl.node : null;
2409
+ };
2410
+
2411
+ Scope.prototype.getFromPos = function(name) {
2412
+ assert(is.string(name));
2413
+ var decl = this.decls.get(name);
2414
+ return decl ? decl.from : null;
2415
+ };
2416
+
2417
+ Scope.prototype.hasOwn = function(name) {
2418
+ return this.decls.has(name);
2419
+ };
2420
+
2421
+ Scope.prototype.remove = function(name) {
2422
+ return this.decls.remove(name);
2423
+ };
2424
+
2425
+ Scope.prototype.doesPropagate = function(name) {
2426
+ return this.propagates.has(name);
2427
+ };
2428
+
2429
+ Scope.prototype.markPropagates = function(name) {
2430
+ this.propagates.add(name);
2431
+ };
2432
+
2433
+ Scope.prototype.closestHoistScope = function() {
2434
+ var scope = this;
2435
+ while (scope.kind !== "hoist") {
2436
+ scope = scope.parent;
2437
+ }
2438
+ return scope;
2439
+ };
2440
+
2441
+ Scope.prototype.lookup = function(name) {
2442
+ for (var scope = this; scope; scope = scope.parent) {
2443
+ if (scope.decls.has(name)) {
2444
+ return scope;
2445
+ } else if (scope.kind === "hoist") {
2446
+ scope.propagates.add(name);
2079
2447
  }
2080
- return src.slice(lineStart, i);
2081
2448
  }
2449
+ return null;
2450
+ };
2082
2451
 
2083
- function addRemoveInjectArray(params, posAfterFunctionDeclaration, name) {
2084
- var indent = getIndent(posAfterFunctionDeclaration);
2085
- var str = fmt("{0}{1}{2}.$inject = {3};", os.EOL, indent, name, ctx.stringify(params, ctx.quot));
2452
+ module.exports = Scope;
2453
+
2454
+ },{"assert":1,"simple-fmt":18,"simple-is":19,"stringmap":31,"stringset":32}],13:[function(require,module,exports){
2455
+ // scopetools.js
2456
+ // MIT licensed, see LICENSE file
2457
+ // Copyright (c) 2013-2014 Olov Lassus <olov.lassus@gmail.com>
2458
+
2459
+ "use strict";
2086
2460
 
2087
- ctx.triggers.add({
2088
- pos: posAfterFunctionDeclaration,
2089
- fn: visitNodeFollowingFunctionDeclaration,
2461
+ var assert = require("assert");
2462
+ var traverse = require("ordered-ast-traverse");
2463
+ var Scope = require("./scope");
2464
+ var is = require("simple-is");
2465
+
2466
+ module.exports = {
2467
+ setupScopeAndReferences: setupScopeAndReferences,
2468
+ isReference: isReference,
2469
+ };
2470
+
2471
+ function setupScopeAndReferences(root) {
2472
+ traverse(root, {pre: createScopes});
2473
+ createTopScope(root.$scope);
2474
+ }
2475
+
2476
+ function createScopes(node, parent) {
2477
+ node.$parent = parent;
2478
+ node.$scope = parent ? parent.$scope : null; // may be overridden
2479
+
2480
+ if (isNonFunctionBlock(node, parent)) {
2481
+ // A block node is a scope unless parent is a function
2482
+ node.$scope = new Scope({
2483
+ kind: "block",
2484
+ node: node,
2485
+ parent: parent.$scope,
2090
2486
  });
2091
2487
 
2092
- function visitNodeFollowingFunctionDeclaration(nextNode) {
2093
- var assignment = nextNode.expression;
2094
- var lvalue;
2095
- var hasInjectArray = (nextNode.type === "ExpressionStatement" && assignment.type === "AssignmentExpression" &&
2096
- assignment.operator === "=" &&
2097
- (lvalue = assignment.left).type === "MemberExpression" &&
2098
- lvalue.computed === false && ctx.srcForRange(lvalue.object.range) === name && lvalue.property.name === "$inject");
2488
+ } else if (node.type === "VariableDeclaration") {
2489
+ // Variable declarations names goes in current scope
2490
+ node.declarations.forEach(function(declarator) {
2491
+ var name = declarator.id.name;
2492
+ node.$scope.add(name, node.kind, declarator.id, declarator.range[1]);
2493
+ });
2099
2494
 
2100
- if (ctx.mode === "rebuild" && hasInjectArray) {
2101
- ctx.fragments.push({
2102
- start: posAfterFunctionDeclaration,
2103
- end: nextNode.range[1],
2104
- str: str,
2105
- });
2106
- } else if (ctx.mode === "remove" && hasInjectArray) {
2107
- ctx.fragments.push({
2108
- start: posAfterFunctionDeclaration,
2109
- end: nextNode.range[1],
2110
- str: "",
2111
- });
2112
- } else if (is.someof(ctx.mode, ["add", "rebuild"]) && !hasInjectArray) {
2113
- ctx.fragments.push({
2114
- start: posAfterFunctionDeclaration,
2115
- end: posAfterFunctionDeclaration,
2116
- str: str,
2117
- });
2495
+ } else if (isFunction(node)) {
2496
+ // Function is a scope, with params in it
2497
+ // There's no block-scope under it
2498
+
2499
+ node.$scope = new Scope({
2500
+ kind: "hoist",
2501
+ node: node,
2502
+ parent: parent.$scope,
2503
+ });
2504
+
2505
+ // function has a name
2506
+ if (node.id) {
2507
+ if (node.type === "FunctionDeclaration") {
2508
+ // Function name goes in parent scope for declared functions
2509
+ parent.$scope.add(node.id.name, "fun", node.id, null);
2510
+ } else if (node.type === "FunctionExpression") {
2511
+ // Function name goes in function's scope for named function expressions
2512
+ node.$scope.add(node.id.name, "fun", node.id, null);
2513
+ } else {
2514
+ assert(false);
2118
2515
  }
2119
2516
  }
2517
+
2518
+ node.params.forEach(function(param) {
2519
+ node.$scope.add(param.name, "param", param, null);
2520
+ });
2521
+
2522
+ } else if (isForWithConstLet(node) || isForInOfWithConstLet(node)) {
2523
+ // For(In/Of) loop with const|let declaration is a scope, with declaration in it
2524
+ // There may be a block-scope under it
2525
+ node.$scope = new Scope({
2526
+ kind: "block",
2527
+ node: node,
2528
+ parent: parent.$scope,
2529
+ });
2530
+
2531
+ } else if (node.type === "CatchClause") {
2532
+ var identifier = node.param;
2533
+
2534
+ node.$scope = new Scope({
2535
+ kind: "catch-block",
2536
+ node: node,
2537
+ parent: parent.$scope,
2538
+ });
2539
+ node.$scope.add(identifier.name, "caught", identifier, null);
2540
+
2541
+ // All hoist-scope keeps track of which variables that are propagated through,
2542
+ // i.e. an reference inside the scope points to a declaration outside the scope.
2543
+ // This is used to mark "taint" the name since adding a new variable in the scope,
2544
+ // with a propagated name, would change the meaning of the existing references.
2545
+ //
2546
+ // catch(e) is special because even though e is a variable in its own scope,
2547
+ // we want to make sure that catch(e){let e} is never transformed to
2548
+ // catch(e){var e} (but rather var e$0). For that reason we taint the use of e
2549
+ // in the closest hoist-scope, i.e. where var e$0 belongs.
2550
+ node.$scope.closestHoistScope().markPropagates(identifier.name);
2551
+
2552
+ } else if (node.type === "Program") {
2553
+ // Top-level program is a scope
2554
+ // There's no block-scope under it
2555
+ node.$scope = new Scope({
2556
+ kind: "hoist",
2557
+ node: node,
2558
+ parent: null,
2559
+ });
2120
2560
  }
2121
2561
  }
2122
2562
 
2563
+ function createTopScope(programScope) {
2564
+ function inject(obj) {
2565
+ for (var name in obj) {
2566
+ var writeable = obj[name];
2567
+ var kind = (writeable ? "var" : "const");
2568
+ if (topScope.hasOwn(name)) {
2569
+ topScope.remove(name);
2570
+ }
2571
+ topScope.add(name, kind, {loc: {start: {line: -1}}}, -1);
2572
+ }
2573
+ }
2123
2574
 
2124
- },{"os":5,"simple-fmt":17,"simple-is":18}],12:[function(require,module,exports){
2575
+ var topScope = new Scope({
2576
+ kind: "hoist",
2577
+ node: {},
2578
+ parent: null,
2579
+ });
2580
+
2581
+ var complementary = {
2582
+ undefined: false,
2583
+ Infinity: false,
2584
+ console: false,
2585
+ };
2586
+
2587
+ inject(complementary);
2588
+ // inject(jshint_vars.reservedVars);
2589
+ // inject(jshint_vars.ecmaIdentifiers);
2590
+
2591
+ // link it in
2592
+ programScope.parent = topScope;
2593
+ topScope.children.push(programScope);
2594
+
2595
+ return topScope;
2596
+ }
2597
+
2598
+ function isConstLet(kind) {
2599
+ return kind === "const" || kind === "let";
2600
+ }
2601
+
2602
+ function isNonFunctionBlock(node, parent) {
2603
+ return node.type === "BlockStatement" && parent.type !== "FunctionDeclaration" && parent.type !== "FunctionExpression";
2604
+ }
2605
+
2606
+ function isForWithConstLet(node) {
2607
+ return node.type === "ForStatement" && node.init && node.init.type === "VariableDeclaration" && isConstLet(node.init.kind);
2608
+ }
2609
+
2610
+ function isForInOfWithConstLet(node) {
2611
+ return isForInOf(node) && node.left.type === "VariableDeclaration" && isConstLet(node.left.kind);
2612
+ }
2613
+
2614
+ function isForInOf(node) {
2615
+ return node.type === "ForInStatement" || node.type === "ForOfStatement";
2616
+ }
2617
+
2618
+ function isFunction(node) {
2619
+ return node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
2620
+ }
2621
+
2622
+ function isReference(node) {
2623
+ var parent = node.$parent;
2624
+ return node.$refToScope ||
2625
+ node.type === "Identifier" &&
2626
+ !(parent.type === "VariableDeclarator" && parent.id === node) && // var|let|const $
2627
+ !(parent.type === "MemberExpression" && parent.computed === false && parent.property === node) && // obj.$
2628
+ !(parent.type === "Property" && parent.key === node) && // {$: ...}
2629
+ !(parent.type === "LabeledStatement" && parent.label === node) && // $: ...
2630
+ !(parent.type === "CatchClause" && parent.param === node) && // catch($)
2631
+ !(isFunction(parent) && parent.id === node) && // function $(..
2632
+ !(isFunction(parent) && is.someof(node, parent.params)) && // function f($)..
2633
+ true;
2634
+ }
2635
+
2636
+ },{"./scope":12,"assert":1,"ordered-ast-traverse":17,"simple-is":19}],14:[function(require,module,exports){
2125
2637
  // alter.js
2126
2638
  // MIT licensed, see LICENSE file
2127
2639
  // Copyright (c) 2013 Olov Lassus <olov.lassus@gmail.com>
@@ -2168,7 +2680,7 @@ if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
2168
2680
  module.exports = alter;
2169
2681
  }
2170
2682
 
2171
- },{"assert":1,"stable":29}],13:[function(require,module,exports){
2683
+ },{"assert":1,"stable":30}],15:[function(require,module,exports){
2172
2684
  /*
2173
2685
  Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com>
2174
2686
  Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>
@@ -5926,7 +6438,7 @@ parseStatement: true, parseSourceElement: true */
5926
6438
  }));
5927
6439
  /* vim: set sw=4 ts=4 et tw=80 : */
5928
6440
 
5929
- },{}],14:[function(require,module,exports){
6441
+ },{}],16:[function(require,module,exports){
5930
6442
  // ordered-esprima-props.js
5931
6443
  // MIT licensed, see LICENSE file
5932
6444
  // Copyright (c) 2014 Olov Lassus <olov.lassus@gmail.com>
@@ -6005,7 +6517,7 @@ module.exports = (function() {
6005
6517
  };
6006
6518
  })();
6007
6519
 
6008
- },{}],15:[function(require,module,exports){
6520
+ },{}],17:[function(require,module,exports){
6009
6521
  // ordered-ast-traverse.js
6010
6522
  // MIT licensed, see LICENSE file
6011
6523
  // Copyright (c) 2014 Olov Lassus <olov.lassus@gmail.com>
@@ -6066,181 +6578,7 @@ if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
6066
6578
  module.exports = traverse;
6067
6579
  }
6068
6580
 
6069
- },{"ordered-esprima-props":14}],16:[function(require,module,exports){
6070
- /**
6071
- * Expose `PriorityQueue`.
6072
- */
6073
- module.exports = PriorityQueue;
6074
-
6075
- /**
6076
- * Initializes a new empty `PriorityQueue` with the given `comparator(a, b)`
6077
- * function, uses `.DEFAULT_COMPARATOR()` when no function is provided.
6078
- *
6079
- * The comparator function must return a positive number when `a > b`, 0 when
6080
- * `a == b` and a negative number when `a < b`.
6081
- *
6082
- * @param {Function}
6083
- * @return {PriorityQueue}
6084
- * @api public
6085
- */
6086
- function PriorityQueue(comparator) {
6087
- this._comparator = comparator || PriorityQueue.DEFAULT_COMPARATOR;
6088
- this._elements = [];
6089
- }
6090
-
6091
- /**
6092
- * Compares `a` and `b`, when `a > b` it returns a positive number, when
6093
- * it returns 0 and when `a < b` it returns a negative number.
6094
- *
6095
- * @param {String|Number} a
6096
- * @param {String|Number} b
6097
- * @return {Number}
6098
- * @api public
6099
- */
6100
- PriorityQueue.DEFAULT_COMPARATOR = function(a, b) {
6101
- if (a instanceof Number && b instanceof Number) {
6102
- return a - b;
6103
- } else {
6104
- a = a.toString();
6105
- b = b.toString();
6106
-
6107
- if (a == b) return 0;
6108
-
6109
- return (a > b) ? 1 : -1;
6110
- }
6111
- };
6112
-
6113
- /**
6114
- * Returns whether the priority queue is empty or not.
6115
- *
6116
- * @return {Boolean}
6117
- * @api public
6118
- */
6119
- PriorityQueue.prototype.isEmpty = function() {
6120
- return this.size() === 0;
6121
- };
6122
-
6123
- /**
6124
- * Peeks at the top element of the priority queue.
6125
- *
6126
- * @return {Object}
6127
- * @throws {Error} when the queue is empty.
6128
- * @api public
6129
- */
6130
- PriorityQueue.prototype.peek = function() {
6131
- if (this.isEmpty()) throw new Error('PriorityQueue is empty');
6132
-
6133
- return this._elements[0];
6134
- };
6135
-
6136
- /**
6137
- * Dequeues the top element of the priority queue.
6138
- *
6139
- * @return {Object}
6140
- * @throws {Error} when the queue is empty.
6141
- * @api public
6142
- */
6143
- PriorityQueue.prototype.deq = function() {
6144
- var first = this.peek();
6145
- var last = this._elements.pop();
6146
- var size = this.size();
6147
-
6148
- if (size === 0) return first;
6149
-
6150
- this._elements[0] = last;
6151
- var current = 0;
6152
-
6153
- while (current < size) {
6154
- var largest = current;
6155
- var left = (2 * current) + 1;
6156
- var right = (2 * current) + 2;
6157
-
6158
- if (left < size && this._compare(left, largest) > 0) {
6159
- largest = left;
6160
- }
6161
-
6162
- if (right < size && this._compare(right, largest) > 0) {
6163
- largest = right;
6164
- }
6165
-
6166
- if (largest === current) break;
6167
-
6168
- this._swap(largest, current);
6169
- current = largest;
6170
- }
6171
-
6172
- return first;
6173
- };
6174
-
6175
- /**
6176
- * Enqueues the `element` at the priority queue and returns its new size.
6177
- *
6178
- * @param {Object} element
6179
- * @return {Number}
6180
- * @api public
6181
- */
6182
- PriorityQueue.prototype.enq = function(element) {
6183
- var size = this._elements.push(element);
6184
- var current = size - 1;
6185
-
6186
- while (current > 0) {
6187
- var parent = Math.floor((current - 1) / 2);
6188
-
6189
- if (this._compare(current, parent) < 0) break;
6190
-
6191
- this._swap(parent, current);
6192
- current = parent;
6193
- }
6194
-
6195
- return size;
6196
- };
6197
-
6198
- /**
6199
- * Returns the size of the priority queue.
6200
- *
6201
- * @return {Number}
6202
- * @api public
6203
- */
6204
- PriorityQueue.prototype.size = function() {
6205
- return this._elements.length;
6206
- };
6207
-
6208
- /**
6209
- * Iterates over queue elements
6210
- *
6211
- * @param {Function} fn
6212
- */
6213
- PriorityQueue.prototype.forEach = function(fn) {
6214
- return this._elements.forEach(fn);
6215
- };
6216
-
6217
- /**
6218
- * Compares the values at position `a` and `b` in the priority queue using its
6219
- * comparator function.
6220
- *
6221
- * @param {Number} a
6222
- * @param {Number} b
6223
- * @return {Number}
6224
- * @api private
6225
- */
6226
- PriorityQueue.prototype._compare = function(a, b) {
6227
- return this._comparator(this._elements[a], this._elements[b]);
6228
- };
6229
-
6230
- /**
6231
- * Swaps the values at position `a` and `b` in the priority queue.
6232
- *
6233
- * @param {Number} a
6234
- * @param {Number} b
6235
- * @api private
6236
- */
6237
- PriorityQueue.prototype._swap = function(a, b) {
6238
- var aux = this._elements[a];
6239
- this._elements[a] = this._elements[b];
6240
- this._elements[b] = aux;
6241
- };
6242
-
6243
- },{}],17:[function(require,module,exports){
6581
+ },{"ordered-esprima-props":16}],18:[function(require,module,exports){
6244
6582
  // simple-fmt.js
6245
6583
  // MIT licensed, see LICENSE file
6246
6584
  // Copyright (c) 2013 Olov Lassus <olov.lassus@gmail.com>
@@ -6275,7 +6613,7 @@ if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
6275
6613
  module.exports = fmt;
6276
6614
  }
6277
6615
 
6278
- },{}],18:[function(require,module,exports){
6616
+ },{}],19:[function(require,module,exports){
6279
6617
  // simple-is.js
6280
6618
  // MIT licensed, see LICENSE file
6281
6619
  // Copyright (c) 2013 Olov Lassus <olov.lassus@gmail.com>
@@ -6333,7 +6671,7 @@ if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
6333
6671
  module.exports = is;
6334
6672
  }
6335
6673
 
6336
- },{}],19:[function(require,module,exports){
6674
+ },{}],20:[function(require,module,exports){
6337
6675
  /*
6338
6676
  * Copyright 2009-2011 Mozilla Foundation and contributors
6339
6677
  * Licensed under the New BSD license. See LICENSE.txt or:
@@ -6343,7 +6681,7 @@ exports.SourceMapGenerator = require('./source-map/source-map-generator').Source
6343
6681
  exports.SourceMapConsumer = require('./source-map/source-map-consumer').SourceMapConsumer;
6344
6682
  exports.SourceNode = require('./source-map/source-node').SourceNode;
6345
6683
 
6346
- },{"./source-map/source-map-consumer":24,"./source-map/source-map-generator":25,"./source-map/source-node":26}],20:[function(require,module,exports){
6684
+ },{"./source-map/source-map-consumer":25,"./source-map/source-map-generator":26,"./source-map/source-node":27}],21:[function(require,module,exports){
6347
6685
  /* -*- Mode: js; js-indent-level: 2; -*- */
6348
6686
  /*
6349
6687
  * Copyright 2011 Mozilla Foundation and contributors
@@ -6442,7 +6780,7 @@ define(function (require, exports, module) {
6442
6780
 
6443
6781
  });
6444
6782
 
6445
- },{"./util":27,"amdefine":28}],21:[function(require,module,exports){
6783
+ },{"./util":28,"amdefine":29}],22:[function(require,module,exports){
6446
6784
  /* -*- Mode: js; js-indent-level: 2; -*- */
6447
6785
  /*
6448
6786
  * Copyright 2011 Mozilla Foundation and contributors
@@ -6588,7 +6926,7 @@ define(function (require, exports, module) {
6588
6926
 
6589
6927
  });
6590
6928
 
6591
- },{"./base64":22,"amdefine":28}],22:[function(require,module,exports){
6929
+ },{"./base64":23,"amdefine":29}],23:[function(require,module,exports){
6592
6930
  /* -*- Mode: js; js-indent-level: 2; -*- */
6593
6931
  /*
6594
6932
  * Copyright 2011 Mozilla Foundation and contributors
@@ -6632,7 +6970,7 @@ define(function (require, exports, module) {
6632
6970
 
6633
6971
  });
6634
6972
 
6635
- },{"amdefine":28}],23:[function(require,module,exports){
6973
+ },{"amdefine":29}],24:[function(require,module,exports){
6636
6974
  /* -*- Mode: js; js-indent-level: 2; -*- */
6637
6975
  /*
6638
6976
  * Copyright 2011 Mozilla Foundation and contributors
@@ -6715,7 +7053,7 @@ define(function (require, exports, module) {
6715
7053
 
6716
7054
  });
6717
7055
 
6718
- },{"amdefine":28}],24:[function(require,module,exports){
7056
+ },{"amdefine":29}],25:[function(require,module,exports){
6719
7057
  /* -*- Mode: js; js-indent-level: 2; -*- */
6720
7058
  /*
6721
7059
  * Copyright 2011 Mozilla Foundation and contributors
@@ -7195,7 +7533,7 @@ define(function (require, exports, module) {
7195
7533
 
7196
7534
  });
7197
7535
 
7198
- },{"./array-set":20,"./base64-vlq":21,"./binary-search":23,"./util":27,"amdefine":28}],25:[function(require,module,exports){
7536
+ },{"./array-set":21,"./base64-vlq":22,"./binary-search":24,"./util":28,"amdefine":29}],26:[function(require,module,exports){
7199
7537
  /* -*- Mode: js; js-indent-level: 2; -*- */
7200
7538
  /*
7201
7539
  * Copyright 2011 Mozilla Foundation and contributors
@@ -7600,7 +7938,7 @@ define(function (require, exports, module) {
7600
7938
 
7601
7939
  });
7602
7940
 
7603
- },{"./array-set":20,"./base64-vlq":21,"./util":27,"amdefine":28}],26:[function(require,module,exports){
7941
+ },{"./array-set":21,"./base64-vlq":22,"./util":28,"amdefine":29}],27:[function(require,module,exports){
7604
7942
  /* -*- Mode: js; js-indent-level: 2; -*- */
7605
7943
  /*
7606
7944
  * Copyright 2011 Mozilla Foundation and contributors
@@ -8010,7 +8348,7 @@ define(function (require, exports, module) {
8010
8348
 
8011
8349
  });
8012
8350
 
8013
- },{"./source-map-generator":25,"./util":27,"amdefine":28}],27:[function(require,module,exports){
8351
+ },{"./source-map-generator":26,"./util":28,"amdefine":29}],28:[function(require,module,exports){
8014
8352
  /* -*- Mode: js; js-indent-level: 2; -*- */
8015
8353
  /*
8016
8354
  * Copyright 2011 Mozilla Foundation and contributors
@@ -8331,7 +8669,7 @@ define(function (require, exports, module) {
8331
8669
 
8332
8670
  });
8333
8671
 
8334
- },{"amdefine":28}],28:[function(require,module,exports){
8672
+ },{"amdefine":29}],29:[function(require,module,exports){
8335
8673
  (function (process,__filename){
8336
8674
  /** vim: et:ts=4:sw=4:sts=4
8337
8675
  * @license amdefine 0.1.0 Copyright (c) 2011, The Dojo Foundation All Rights Reserved.
@@ -8634,7 +8972,7 @@ function amdefine(module, requireFn) {
8634
8972
  module.exports = amdefine;
8635
8973
 
8636
8974
  }).call(this,require('_process'),"/node_modules/ng-annotate/node_modules/source-map/node_modules/amdefine/amdefine.js")
8637
- },{"_process":7,"path":6}],29:[function(require,module,exports){
8975
+ },{"_process":7,"path":6}],30:[function(require,module,exports){
8638
8976
  //! stable.js 0.1.5, https://github.com/Two-Screen/stable
8639
8977
  //! © 2014 Angry Bytes and contributors. MIT licensed.
8640
8978
 
@@ -8747,4 +9085,433 @@ else {
8747
9085
 
8748
9086
  })();
8749
9087
 
9088
+ },{}],31:[function(require,module,exports){
9089
+ // stringmap.js
9090
+ // MIT licensed, see LICENSE file
9091
+ // Copyright (c) 2013 Olov Lassus <olov.lassus@gmail.com>
9092
+
9093
+ var StringMap = (function() {
9094
+ "use strict";
9095
+
9096
+ // to save us a few characters
9097
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
9098
+
9099
+ var create = (function() {
9100
+ function hasOwnEnumerableProps(obj) {
9101
+ for (var prop in obj) {
9102
+ if (hasOwnProperty.call(obj, prop)) {
9103
+ return true;
9104
+ }
9105
+ }
9106
+ return false;
9107
+ }
9108
+ // FF <= 3.6:
9109
+ // o = {}; o.hasOwnProperty("__proto__" or "__count__" or "__parent__") => true
9110
+ // o = {"__proto__": null}; Object.prototype.hasOwnProperty.call(o, "__proto__" or "__count__" or "__parent__") => false
9111
+ function hasOwnPollutedProps(obj) {
9112
+ return hasOwnProperty.call(obj, "__count__") || hasOwnProperty.call(obj, "__parent__");
9113
+ }
9114
+
9115
+ var useObjectCreate = false;
9116
+ if (typeof Object.create === "function") {
9117
+ if (!hasOwnEnumerableProps(Object.create(null))) {
9118
+ useObjectCreate = true;
9119
+ }
9120
+ }
9121
+ if (useObjectCreate === false) {
9122
+ if (hasOwnEnumerableProps({})) {
9123
+ throw new Error("StringMap environment error 0, please file a bug at https://github.com/olov/stringmap/issues");
9124
+ }
9125
+ }
9126
+ // no throw yet means we can create objects without own enumerable props (safe-guard against VMs and shims)
9127
+
9128
+ var o = (useObjectCreate ? Object.create(null) : {});
9129
+ var useProtoClear = false;
9130
+ if (hasOwnPollutedProps(o)) {
9131
+ o.__proto__ = null;
9132
+ if (hasOwnEnumerableProps(o) || hasOwnPollutedProps(o)) {
9133
+ throw new Error("StringMap environment error 1, please file a bug at https://github.com/olov/stringmap/issues");
9134
+ }
9135
+ useProtoClear = true;
9136
+ }
9137
+ // no throw yet means we can create objects without own polluted props (safe-guard against VMs and shims)
9138
+
9139
+ return function() {
9140
+ var o = (useObjectCreate ? Object.create(null) : {});
9141
+ if (useProtoClear) {
9142
+ o.__proto__ = null;
9143
+ }
9144
+ return o;
9145
+ };
9146
+ })();
9147
+
9148
+ // stringmap ctor
9149
+ function stringmap(optional_object) {
9150
+ // use with or without new
9151
+ if (!(this instanceof stringmap)) {
9152
+ return new stringmap(optional_object);
9153
+ }
9154
+ this.obj = create();
9155
+ this.hasProto = false; // false (no __proto__ key) or true (has __proto__ key)
9156
+ this.proto = undefined; // value for __proto__ key when hasProto is true, undefined otherwise
9157
+
9158
+ if (optional_object) {
9159
+ this.setMany(optional_object);
9160
+ }
9161
+ };
9162
+
9163
+ // primitive methods that deals with data representation
9164
+ stringmap.prototype.has = function(key) {
9165
+ // The type-check of key in has, get, set and delete is important because otherwise an object
9166
+ // {toString: function() { return "__proto__"; }} can avoid the key === "__proto__" test.
9167
+ // The alternative to type-checking would be to force string conversion, i.e. key = String(key);
9168
+ if (typeof key !== "string") {
9169
+ throw new Error("StringMap expected string key");
9170
+ }
9171
+ return (key === "__proto__" ?
9172
+ this.hasProto :
9173
+ hasOwnProperty.call(this.obj, key));
9174
+ };
9175
+
9176
+ stringmap.prototype.get = function(key) {
9177
+ if (typeof key !== "string") {
9178
+ throw new Error("StringMap expected string key");
9179
+ }
9180
+ return (key === "__proto__" ?
9181
+ this.proto :
9182
+ (hasOwnProperty.call(this.obj, key) ? this.obj[key] : undefined));
9183
+ };
9184
+
9185
+ stringmap.prototype.set = function(key, value) {
9186
+ if (typeof key !== "string") {
9187
+ throw new Error("StringMap expected string key");
9188
+ }
9189
+ if (key === "__proto__") {
9190
+ this.hasProto = true;
9191
+ this.proto = value;
9192
+ } else {
9193
+ this.obj[key] = value;
9194
+ }
9195
+ };
9196
+
9197
+ stringmap.prototype.remove = function(key) {
9198
+ if (typeof key !== "string") {
9199
+ throw new Error("StringMap expected string key");
9200
+ }
9201
+ var didExist = this.has(key);
9202
+ if (key === "__proto__") {
9203
+ this.hasProto = false;
9204
+ this.proto = undefined;
9205
+ } else {
9206
+ delete this.obj[key];
9207
+ }
9208
+ return didExist;
9209
+ };
9210
+
9211
+ // alias remove to delete but beware:
9212
+ // sm.delete("key"); // OK in ES5 and later
9213
+ // sm['delete']("key"); // OK in all ES versions
9214
+ // sm.remove("key"); // OK in all ES versions
9215
+ stringmap.prototype['delete'] = stringmap.prototype.remove;
9216
+
9217
+ stringmap.prototype.isEmpty = function() {
9218
+ for (var key in this.obj) {
9219
+ if (hasOwnProperty.call(this.obj, key)) {
9220
+ return false;
9221
+ }
9222
+ }
9223
+ return !this.hasProto;
9224
+ };
9225
+
9226
+ stringmap.prototype.size = function() {
9227
+ var len = 0;
9228
+ for (var key in this.obj) {
9229
+ if (hasOwnProperty.call(this.obj, key)) {
9230
+ ++len;
9231
+ }
9232
+ }
9233
+ return (this.hasProto ? len + 1 : len);
9234
+ };
9235
+
9236
+ stringmap.prototype.keys = function() {
9237
+ var keys = [];
9238
+ for (var key in this.obj) {
9239
+ if (hasOwnProperty.call(this.obj, key)) {
9240
+ keys.push(key);
9241
+ }
9242
+ }
9243
+ if (this.hasProto) {
9244
+ keys.push("__proto__");
9245
+ }
9246
+ return keys;
9247
+ };
9248
+
9249
+ stringmap.prototype.values = function() {
9250
+ var values = [];
9251
+ for (var key in this.obj) {
9252
+ if (hasOwnProperty.call(this.obj, key)) {
9253
+ values.push(this.obj[key]);
9254
+ }
9255
+ }
9256
+ if (this.hasProto) {
9257
+ values.push(this.proto);
9258
+ }
9259
+ return values;
9260
+ };
9261
+
9262
+ stringmap.prototype.items = function() {
9263
+ var items = [];
9264
+ for (var key in this.obj) {
9265
+ if (hasOwnProperty.call(this.obj, key)) {
9266
+ items.push([key, this.obj[key]]);
9267
+ }
9268
+ }
9269
+ if (this.hasProto) {
9270
+ items.push(["__proto__", this.proto]);
9271
+ }
9272
+ return items;
9273
+ };
9274
+
9275
+
9276
+ // methods that rely on the above primitives
9277
+ stringmap.prototype.setMany = function(object) {
9278
+ if (object === null || (typeof object !== "object" && typeof object !== "function")) {
9279
+ throw new Error("StringMap expected Object");
9280
+ }
9281
+ for (var key in object) {
9282
+ if (hasOwnProperty.call(object, key)) {
9283
+ this.set(key, object[key]);
9284
+ }
9285
+ }
9286
+ return this;
9287
+ };
9288
+
9289
+ stringmap.prototype.merge = function(other) {
9290
+ var keys = other.keys();
9291
+ for (var i = 0; i < keys.length; i++) {
9292
+ var key = keys[i];
9293
+ this.set(key, other.get(key));
9294
+ }
9295
+ return this;
9296
+ };
9297
+
9298
+ stringmap.prototype.map = function(fn) {
9299
+ var keys = this.keys();
9300
+ for (var i = 0; i < keys.length; i++) {
9301
+ var key = keys[i];
9302
+ keys[i] = fn(this.get(key), key); // re-use keys array for results
9303
+ }
9304
+ return keys;
9305
+ };
9306
+
9307
+ stringmap.prototype.forEach = function(fn) {
9308
+ var keys = this.keys();
9309
+ for (var i = 0; i < keys.length; i++) {
9310
+ var key = keys[i];
9311
+ fn(this.get(key), key);
9312
+ }
9313
+ };
9314
+
9315
+ stringmap.prototype.clone = function() {
9316
+ var other = stringmap();
9317
+ return other.merge(this);
9318
+ };
9319
+
9320
+ stringmap.prototype.toString = function() {
9321
+ var self = this;
9322
+ return "{" + this.keys().map(function(key) {
9323
+ return JSON.stringify(key) + ":" + JSON.stringify(self.get(key));
9324
+ }).join(",") + "}";
9325
+ };
9326
+
9327
+ return stringmap;
9328
+ })();
9329
+
9330
+ if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
9331
+ module.exports = StringMap;
9332
+ }
9333
+
9334
+ },{}],32:[function(require,module,exports){
9335
+ // stringset.js
9336
+ // MIT licensed, see LICENSE file
9337
+ // Copyright (c) 2013 Olov Lassus <olov.lassus@gmail.com>
9338
+
9339
+ var StringSet = (function() {
9340
+ "use strict";
9341
+
9342
+ // to save us a few characters
9343
+ var hasOwnProperty = Object.prototype.hasOwnProperty;
9344
+
9345
+ var create = (function() {
9346
+ function hasOwnEnumerableProps(obj) {
9347
+ for (var prop in obj) {
9348
+ if (hasOwnProperty.call(obj, prop)) {
9349
+ return true;
9350
+ }
9351
+ }
9352
+ return false;
9353
+ }
9354
+
9355
+ // FF <= 3.6:
9356
+ // o = {}; o.hasOwnProperty("__proto__" or "__count__" or "__parent__") => true
9357
+ // o = {"__proto__": null}; Object.prototype.hasOwnProperty.call(o, "__proto__" or "__count__" or "__parent__") => false
9358
+ function hasOwnPollutedProps(obj) {
9359
+ return hasOwnProperty.call(obj, "__count__") || hasOwnProperty.call(obj, "__parent__");
9360
+ }
9361
+
9362
+ var useObjectCreate = false;
9363
+ if (typeof Object.create === "function") {
9364
+ if (!hasOwnEnumerableProps(Object.create(null))) {
9365
+ useObjectCreate = true;
9366
+ }
9367
+ }
9368
+ if (useObjectCreate === false) {
9369
+ if (hasOwnEnumerableProps({})) {
9370
+ throw new Error("StringSet environment error 0, please file a bug at https://github.com/olov/stringset/issues");
9371
+ }
9372
+ }
9373
+ // no throw yet means we can create objects without own enumerable props (safe-guard against VMs and shims)
9374
+
9375
+ var o = (useObjectCreate ? Object.create(null) : {});
9376
+ var useProtoClear = false;
9377
+ if (hasOwnPollutedProps(o)) {
9378
+ o.__proto__ = null;
9379
+ if (hasOwnEnumerableProps(o) || hasOwnPollutedProps(o)) {
9380
+ throw new Error("StringSet environment error 1, please file a bug at https://github.com/olov/stringset/issues");
9381
+ }
9382
+ useProtoClear = true;
9383
+ }
9384
+ // no throw yet means we can create objects without own polluted props (safe-guard against VMs and shims)
9385
+
9386
+ return function() {
9387
+ var o = (useObjectCreate ? Object.create(null) : {});
9388
+ if (useProtoClear) {
9389
+ o.__proto__ = null;
9390
+ }
9391
+ return o;
9392
+ };
9393
+ })();
9394
+
9395
+ // stringset ctor
9396
+ function stringset(optional_array) {
9397
+ // use with or without new
9398
+ if (!(this instanceof stringset)) {
9399
+ return new stringset(optional_array);
9400
+ }
9401
+ this.obj = create();
9402
+ this.hasProto = false; // false (no __proto__ item) or true (has __proto__ item)
9403
+
9404
+ if (optional_array) {
9405
+ this.addMany(optional_array);
9406
+ }
9407
+ };
9408
+
9409
+ // primitive methods that deals with data representation
9410
+ stringset.prototype.has = function(item) {
9411
+ // The type-check of item in has, get, set and delete is important because otherwise an object
9412
+ // {toString: function() { return "__proto__"; }} can avoid the item === "__proto__" test.
9413
+ // The alternative to type-checking would be to force string conversion, i.e. item = String(item);
9414
+ if (typeof item !== "string") {
9415
+ throw new Error("StringSet expected string item");
9416
+ }
9417
+ return (item === "__proto__" ?
9418
+ this.hasProto :
9419
+ hasOwnProperty.call(this.obj, item));
9420
+ };
9421
+
9422
+ stringset.prototype.add = function(item) {
9423
+ if (typeof item !== "string") {
9424
+ throw new Error("StringSet expected string item");
9425
+ }
9426
+ if (item === "__proto__") {
9427
+ this.hasProto = true;
9428
+ } else {
9429
+ this.obj[item] = true;
9430
+ }
9431
+ };
9432
+
9433
+ stringset.prototype.remove = function(item) {
9434
+ if (typeof item !== "string") {
9435
+ throw new Error("StringSet expected string item");
9436
+ }
9437
+ var didExist = this.has(item);
9438
+ if (item === "__proto__") {
9439
+ this.hasProto = false;
9440
+ } else {
9441
+ delete this.obj[item];
9442
+ }
9443
+ return didExist;
9444
+ };
9445
+
9446
+ // alias remove to delete but beware:
9447
+ // ss.delete("key"); // OK in ES5 and later
9448
+ // ss['delete']("key"); // OK in all ES versions
9449
+ // ss.remove("key"); // OK in all ES versions
9450
+ stringset.prototype['delete'] = stringset.prototype.remove;
9451
+
9452
+ stringset.prototype.isEmpty = function() {
9453
+ for (var item in this.obj) {
9454
+ if (hasOwnProperty.call(this.obj, item)) {
9455
+ return false;
9456
+ }
9457
+ }
9458
+ return !this.hasProto;
9459
+ };
9460
+
9461
+ stringset.prototype.size = function() {
9462
+ var len = 0;
9463
+ for (var item in this.obj) {
9464
+ if (hasOwnProperty.call(this.obj, item)) {
9465
+ ++len;
9466
+ }
9467
+ }
9468
+ return (this.hasProto ? len + 1 : len);
9469
+ };
9470
+
9471
+ stringset.prototype.items = function() {
9472
+ var items = [];
9473
+ for (var item in this.obj) {
9474
+ if (hasOwnProperty.call(this.obj, item)) {
9475
+ items.push(item);
9476
+ }
9477
+ }
9478
+ if (this.hasProto) {
9479
+ items.push("__proto__");
9480
+ }
9481
+ return items;
9482
+ };
9483
+
9484
+
9485
+ // methods that rely on the above primitives
9486
+ stringset.prototype.addMany = function(items) {
9487
+ if (!Array.isArray(items)) {
9488
+ throw new Error("StringSet expected array");
9489
+ }
9490
+ for (var i = 0; i < items.length; i++) {
9491
+ this.add(items[i]);
9492
+ }
9493
+ return this;
9494
+ };
9495
+
9496
+ stringset.prototype.merge = function(other) {
9497
+ this.addMany(other.items());
9498
+ return this;
9499
+ };
9500
+
9501
+ stringset.prototype.clone = function() {
9502
+ var other = stringset();
9503
+ return other.merge(this);
9504
+ };
9505
+
9506
+ stringset.prototype.toString = function() {
9507
+ return "{" + this.items().map(JSON.stringify).join(",") + "}";
9508
+ };
9509
+
9510
+ return stringset;
9511
+ })();
9512
+
9513
+ if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
9514
+ module.exports = StringSet;
9515
+ }
9516
+
8750
9517
  },{}]},{},[10]);