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 | function hasShadowedGlobals(tokens, globalNames) {
|
30 | for (const token of tokens.tokens) {
|
31 | if (
|
32 | token.type === _types.TokenType.name &&
|
33 | _tokenizer.isDeclaration.call(void 0, token) &&
|
34 | globalNames.has(tokens.identifierNameForToken(token))
|
35 | ) {
|
36 | return true;
|
37 | }
|
38 | }
|
39 | return false;
|
40 | }
|
41 |
|
42 | function markShadowedGlobals(
|
43 | tokens,
|
44 | scopes,
|
45 | globalNames,
|
46 | ) {
|
47 | const scopeStack = [];
|
48 | let scopeIndex = scopes.length - 1;
|
49 |
|
50 |
|
51 | for (let i = tokens.tokens.length - 1; ; i--) {
|
52 | while (scopeStack.length > 0 && scopeStack[scopeStack.length - 1].startTokenIndex === i + 1) {
|
53 | scopeStack.pop();
|
54 | }
|
55 | while (scopeIndex >= 0 && scopes[scopeIndex].endTokenIndex === i + 1) {
|
56 | scopeStack.push(scopes[scopeIndex]);
|
57 | scopeIndex--;
|
58 | }
|
59 |
|
60 | if (i < 0) {
|
61 | break;
|
62 | }
|
63 |
|
64 | const token = tokens.tokens[i];
|
65 | const name = tokens.identifierNameForToken(token);
|
66 | if (scopeStack.length > 1 && token.type === _types.TokenType.name && globalNames.has(name)) {
|
67 | if (_tokenizer.isBlockScopedDeclaration.call(void 0, token)) {
|
68 | markShadowedForScope(scopeStack[scopeStack.length - 1], tokens, name);
|
69 | } else if (_tokenizer.isFunctionScopedDeclaration.call(void 0, token)) {
|
70 | let stackIndex = scopeStack.length - 1;
|
71 | while (stackIndex > 0 && !scopeStack[stackIndex].isFunctionScope) {
|
72 | stackIndex--;
|
73 | }
|
74 | if (stackIndex < 0) {
|
75 | throw new Error("Did not find parent function scope.");
|
76 | }
|
77 | markShadowedForScope(scopeStack[stackIndex], tokens, name);
|
78 | }
|
79 | }
|
80 | }
|
81 | if (scopeStack.length > 0) {
|
82 | throw new Error("Expected empty scope stack after processing file.");
|
83 | }
|
84 | }
|
85 |
|
86 | function markShadowedForScope(scope, tokens, name) {
|
87 | for (let i = scope.startTokenIndex; i < scope.endTokenIndex; i++) {
|
88 | const token = tokens.tokens[i];
|
89 | if (token.type === _types.TokenType.name && tokens.identifierNameForToken(token) === name) {
|
90 | token.shadowsGlobal = true;
|
91 | }
|
92 | }
|
93 | }
|