ngannotate-rails 0.9.9 → 0.9.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/ngannotate/rails/version.rb +1 -1
- data/vendor/ngannotate.js +1074 -307
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MWE4NWU5NzAyODRkODQ3ZTE3Y2Q1NWM1ODBkMmIyYzkyZmYzMGY2MA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MWY2ZGNlZTEzZmUwYmZiYzA5MmMzYzIzOGVkMzBkNWVmZWY3NzA3OQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
N2I1NzE3YzQ2M2FmOGM4NjU4NDViZmQyYzMwZGQ3NDU4OTRlNmM1YTAxNTFk
|
10
|
+
MGM4MDRmOTBjZDQ1Zjc0M2I3OWI3NWRhYjRhZTU3NzRjMzI5ZTdhZjAzODg2
|
11
|
+
YmRjMTRlMDBmMTc3ZWI3YmFjMTIzOTMxYzJkNzcyZjU4ZjkyMmY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZDJkMGNjYTBkNjJlY2EyYWNhMmJhNzI2Y2UzNmZhZDQ1NjIzMGQzZjk3Yjli
|
14
|
+
ODNiNjQxYzNlZGQxZTUwY2MzNDEzZDY1MjIyMjQ0OWM2ZDg1NmM1MDc3NWE3
|
15
|
+
Y2YyMDkzZjJlOWFiNDE1NGRjN2IxN2Y1ZDlhZTU2NzVlOTQ4OTI=
|
data/vendor/ngannotate.js
CHANGED
@@ -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":
|
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
|
1425
|
+
var traverse = require("ordered-ast-traverse");
|
1426
|
+
var is = require("simple-is");
|
1422
1427
|
|
1423
|
-
|
1424
|
-
assert(this instanceof Heap);
|
1428
|
+
module.exports = Lut;
|
1425
1429
|
|
1426
|
-
|
1427
|
-
|
1428
|
-
});
|
1430
|
+
function Lut(ast, src) {
|
1431
|
+
assert(this instanceof Lut);
|
1429
1432
|
|
1430
|
-
|
1431
|
-
|
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
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
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
|
-
|
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
|
-
|
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
|
1467
|
-
var
|
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
|
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
|
-
|
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,"./
|
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
|
-
|
2223
|
+
inspectComments: inspectComments,
|
2224
|
+
inspectCallExpression: inspectCallExpression,
|
2007
2225
|
};
|
2008
2226
|
|
2009
|
-
function
|
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
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2019
|
-
|
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
|
-
|
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
|
2043
|
-
|
2044
|
-
|
2045
|
-
|
2046
|
-
|
2047
|
-
|
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
|
-
|
2051
|
-
|
2052
|
-
|
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
|
-
|
2058
|
-
|
2059
|
-
|
2060
|
-
|
2061
|
-
if (
|
2062
|
-
(
|
2063
|
-
|
2064
|
-
|
2065
|
-
|
2066
|
-
|
2067
|
-
|
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
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
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
|
-
|
2084
|
-
|
2085
|
-
|
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
|
-
|
2088
|
-
|
2089
|
-
|
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
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
var
|
2096
|
-
|
2097
|
-
|
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
|
-
|
2101
|
-
|
2102
|
-
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2109
|
-
|
2110
|
-
|
2111
|
-
|
2112
|
-
|
2113
|
-
|
2114
|
-
|
2115
|
-
|
2116
|
-
|
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
|
-
|
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":
|
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
|
-
},{}],
|
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
|
-
},{}],
|
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":
|
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
|
-
},{}],
|
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
|
-
},{}],
|
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":
|
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":
|
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":
|
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":
|
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":
|
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":
|
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":
|
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":
|
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":
|
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}],
|
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]);
|