1 | "use strict"; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }Object.defineProperty(exports, "__esModule", {value: true});
|
2 |
|
3 |
|
4 |
|
5 | var _tokenizer = require('./parser/tokenizer');
|
6 |
|
7 | var _types = require('./parser/tokenizer/types');
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | function identifyShadowedGlobals(
|
15 | tokens,
|
16 | scopes,
|
17 | globalNames,
|
18 | ) {
|
19 | if (!hasShadowedGlobals(tokens, globalNames)) {
|
20 | return;
|
21 | }
|
22 | markShadowedGlobals(tokens, scopes, globalNames);
|
23 | } exports.default = identifyShadowedGlobals;
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 | function hasShadowedGlobals(tokens, globalNames) {
|
31 | for (const token of tokens.tokens) {
|
32 | if (
|
33 | token.type === _types.TokenType.name &&
|
34 | _tokenizer.isNonTopLevelDeclaration.call(void 0, token) &&
|
35 | globalNames.has(tokens.identifierNameForToken(token))
|
36 | ) {
|
37 | return true;
|
38 | }
|
39 | }
|
40 | return false;
|
41 | } exports.hasShadowedGlobals = hasShadowedGlobals;
|
42 |
|
43 | function markShadowedGlobals(
|
44 | tokens,
|
45 | scopes,
|
46 | globalNames,
|
47 | ) {
|
48 | const scopeStack = [];
|
49 | let scopeIndex = scopes.length - 1;
|
50 |
|
51 |
|
52 | for (let i = tokens.tokens.length - 1; ; i--) {
|
53 | while (scopeStack.length > 0 && scopeStack[scopeStack.length - 1].startTokenIndex === i + 1) {
|
54 | scopeStack.pop();
|
55 | }
|
56 | while (scopeIndex >= 0 && scopes[scopeIndex].endTokenIndex === i + 1) {
|
57 | scopeStack.push(scopes[scopeIndex]);
|
58 | scopeIndex--;
|
59 | }
|
60 |
|
61 | if (i < 0) {
|
62 | break;
|
63 | }
|
64 |
|
65 | const token = tokens.tokens[i];
|
66 | const name = tokens.identifierNameForToken(token);
|
67 | if (scopeStack.length > 1 && token.type === _types.TokenType.name && globalNames.has(name)) {
|
68 | if (_tokenizer.isBlockScopedDeclaration.call(void 0, token)) {
|
69 | markShadowedForScope(scopeStack[scopeStack.length - 1], tokens, name);
|
70 | } else if (_tokenizer.isFunctionScopedDeclaration.call(void 0, token)) {
|
71 | let stackIndex = scopeStack.length - 1;
|
72 | while (stackIndex > 0 && !scopeStack[stackIndex].isFunctionScope) {
|
73 | stackIndex--;
|
74 | }
|
75 | if (stackIndex < 0) {
|
76 | throw new Error("Did not find parent function scope.");
|
77 | }
|
78 | markShadowedForScope(scopeStack[stackIndex], tokens, name);
|
79 | }
|
80 | }
|
81 | }
|
82 | if (scopeStack.length > 0) {
|
83 | throw new Error("Expected empty scope stack after processing file.");
|
84 | }
|
85 | }
|
86 |
|
87 | function markShadowedForScope(scope, tokens, name) {
|
88 | for (let i = scope.startTokenIndex; i < scope.endTokenIndex; i++) {
|
89 | const token = tokens.tokens[i];
|
90 | if (token.type === _types.TokenType.name && tokens.identifierNameForToken(token) === name) {
|
91 | token.shadowsGlobal = true;
|
92 | }
|
93 | }
|
94 | }
|