]> git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/block-scoped-var.js
d98250b062bcb22a2ef9aeec78e62eed7e6255a5
[pve-eslint.git] / eslint / lib / rules / block-scoped-var.js
1 /**
2 * @fileoverview Rule to check for "block scoped" variables by binding context
3 * @author Matt DuVall <http://www.mattduvall.com>
4 */
5 "use strict";
6
7 //------------------------------------------------------------------------------
8 // Rule Definition
9 //------------------------------------------------------------------------------
10
11 module.exports = {
12 meta: {
13 type: "suggestion",
14
15 docs: {
16 description: "enforce the use of variables within the scope they are defined",
17 recommended: false,
18 url: "https://eslint.org/docs/rules/block-scoped-var"
19 },
20
21 schema: [],
22
23 messages: {
24 outOfScope: "'{{name}}' used outside of binding context."
25 }
26 },
27
28 create(context) {
29 let stack = [];
30
31 /**
32 * Makes a block scope.
33 * @param {ASTNode} node A node of a scope.
34 * @returns {void}
35 */
36 function enterScope(node) {
37 stack.push(node.range);
38 }
39
40 /**
41 * Pops the last block scope.
42 * @returns {void}
43 */
44 function exitScope() {
45 stack.pop();
46 }
47
48 /**
49 * Reports a given reference.
50 * @param {eslint-scope.Reference} reference A reference to report.
51 * @returns {void}
52 */
53 function report(reference) {
54 const identifier = reference.identifier;
55
56 context.report({ node: identifier, messageId: "outOfScope", data: { name: identifier.name } });
57 }
58
59 /**
60 * Finds and reports references which are outside of valid scopes.
61 * @param {ASTNode} node A node to get variables.
62 * @returns {void}
63 */
64 function checkForVariables(node) {
65 if (node.kind !== "var") {
66 return;
67 }
68
69 // Defines a predicate to check whether or not a given reference is outside of valid scope.
70 const scopeRange = stack[stack.length - 1];
71
72 /**
73 * Check if a reference is out of scope
74 * @param {ASTNode} reference node to examine
75 * @returns {boolean} True is its outside the scope
76 * @private
77 */
78 function isOutsideOfScope(reference) {
79 const idRange = reference.identifier.range;
80
81 return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1];
82 }
83
84 // Gets declared variables, and checks its references.
85 const variables = context.getDeclaredVariables(node);
86
87 for (let i = 0; i < variables.length; ++i) {
88
89 // Reports.
90 variables[i]
91 .references
92 .filter(isOutsideOfScope)
93 .forEach(report);
94 }
95 }
96
97 return {
98 Program(node) {
99 stack = [node.range];
100 },
101
102 // Manages scopes.
103 BlockStatement: enterScope,
104 "BlockStatement:exit": exitScope,
105 ForStatement: enterScope,
106 "ForStatement:exit": exitScope,
107 ForInStatement: enterScope,
108 "ForInStatement:exit": exitScope,
109 ForOfStatement: enterScope,
110 "ForOfStatement:exit": exitScope,
111 SwitchStatement: enterScope,
112 "SwitchStatement:exit": exitScope,
113 CatchClause: enterScope,
114 "CatchClause:exit": exitScope,
115 StaticBlock: enterScope,
116 "StaticBlock:exit": exitScope,
117
118 // Finds and reports references which are outside of valid scope.
119 VariableDeclaration: checkForVariables
120 };
121
122 }
123 };