/
index.js
52 lines (42 loc) · 1.03 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
"use strict";
const EVAL_SCOPE_MARKER = "evalInScope";
module.exports = {
EVAL_SCOPE_MARKER,
getEvalScopes,
markEvalScopes,
isMarked,
hasEval,
};
function getEvalScopes(path) {
const evalScopes = new Set;
function add(scope) {
let evalScope = scope;
do {
evalScopes.add(evalScope);
} while (evalScope = evalScope.parent);
}
path.traverse({
CallExpression(evalPath) {
const callee = evalPath.get("callee");
if (callee.isIdentifier() && callee.node.name === "eval" && !callee.scope.getBinding("eval")) {
add(callee.scope);
}
}
});
return evalScopes;
}
function markEvalScopes(path, key = EVAL_SCOPE_MARKER) {
const evalScopes = getEvalScopes(path);
[...evalScopes].forEach((scope) => {
scope[key] = true;
});
}
function isMarked(scope, key = EVAL_SCOPE_MARKER) {
return Object.prototype.hasOwnProperty.call(scope, key);
}
function hasEval(scope, key = EVAL_SCOPE_MARKER) {
if (!isMarked(scope, key)) {
markEvalScopes(scope, key);
}
return scope[key];
}