source: frontend/node_modules/sucrase/dist/identifyShadowedGlobals.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 3.0 KB
Line 
1"use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
3
4
5var _tokenizer = require('./parser/tokenizer');
6
7var _types = require('./parser/tokenizer/types');
8
9
10/**
11 * Traverse the given tokens and modify them if necessary to indicate that some names shadow global
12 * variables.
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 * We can do a fast up-front check to see if there are any declarations to global names. If not,
27 * then there's no point in computing scope assignments.
28 */
29// Exported for testing.
30 function hasShadowedGlobals(tokens, globalNames) {
31 for (const token of tokens.tokens) {
32 if (
33 token.type === _types.TokenType.name &&
34 !token.isType &&
35 _tokenizer.isNonTopLevelDeclaration.call(void 0, token) &&
36 globalNames.has(tokens.identifierNameForToken(token))
37 ) {
38 return true;
39 }
40 }
41 return false;
42} exports.hasShadowedGlobals = hasShadowedGlobals;
43
44function markShadowedGlobals(
45 tokens,
46 scopes,
47 globalNames,
48) {
49 const scopeStack = [];
50 let scopeIndex = scopes.length - 1;
51 // Scopes were generated at completion time, so they're sorted by end index, so we can maintain a
52 // good stack by going backwards through them.
53 for (let i = tokens.tokens.length - 1; ; i--) {
54 while (scopeStack.length > 0 && scopeStack[scopeStack.length - 1].startTokenIndex === i + 1) {
55 scopeStack.pop();
56 }
57 while (scopeIndex >= 0 && scopes[scopeIndex].endTokenIndex === i + 1) {
58 scopeStack.push(scopes[scopeIndex]);
59 scopeIndex--;
60 }
61 // Process scopes after the last iteration so we can make sure we pop all of them.
62 if (i < 0) {
63 break;
64 }
65
66 const token = tokens.tokens[i];
67 const name = tokens.identifierNameForToken(token);
68 if (scopeStack.length > 1 && !token.isType && token.type === _types.TokenType.name && globalNames.has(name)) {
69 if (_tokenizer.isBlockScopedDeclaration.call(void 0, token)) {
70 markShadowedForScope(scopeStack[scopeStack.length - 1], tokens, name);
71 } else if (_tokenizer.isFunctionScopedDeclaration.call(void 0, token)) {
72 let stackIndex = scopeStack.length - 1;
73 while (stackIndex > 0 && !scopeStack[stackIndex].isFunctionScope) {
74 stackIndex--;
75 }
76 if (stackIndex < 0) {
77 throw new Error("Did not find parent function scope.");
78 }
79 markShadowedForScope(scopeStack[stackIndex], tokens, name);
80 }
81 }
82 }
83 if (scopeStack.length > 0) {
84 throw new Error("Expected empty scope stack after processing file.");
85 }
86}
87
88function markShadowedForScope(scope, tokens, name) {
89 for (let i = scope.startTokenIndex; i < scope.endTokenIndex; i++) {
90 const token = tokens.tokens[i];
91 if (
92 (token.type === _types.TokenType.name || token.type === _types.TokenType.jsxName) &&
93 tokens.identifierNameForToken(token) === name
94 ) {
95 token.shadowsGlobal = true;
96 }
97 }
98}
Note: See TracBrowser for help on using the repository browser.