123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- "use strict";
- module.exports = {
- meta: {
- type: "suggestion",
- docs: {
- description: "enforce the use of variables within the scope they are defined",
- category: "Best Practices",
- recommended: false,
- url: "https://eslint.org/docs/rules/block-scoped-var"
- },
- schema: [],
- messages: {
- outOfScope: "'{{name}}' used outside of binding context."
- }
- },
- create(context) {
- let stack = [];
-
- function enterScope(node) {
- stack.push(node.range);
- }
-
- function exitScope() {
- stack.pop();
- }
-
- function report(reference) {
- const identifier = reference.identifier;
- context.report({ node: identifier, messageId: "outOfScope", data: { name: identifier.name } });
- }
-
- function checkForVariables(node) {
- if (node.kind !== "var") {
- return;
- }
-
- const scopeRange = stack[stack.length - 1];
-
- function isOutsideOfScope(reference) {
- const idRange = reference.identifier.range;
- return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1];
- }
-
- const variables = context.getDeclaredVariables(node);
- for (let i = 0; i < variables.length; ++i) {
-
- variables[i]
- .references
- .filter(isOutsideOfScope)
- .forEach(report);
- }
- }
- return {
- Program(node) {
- stack = [node.range];
- },
-
- BlockStatement: enterScope,
- "BlockStatement:exit": exitScope,
- ForStatement: enterScope,
- "ForStatement:exit": exitScope,
- ForInStatement: enterScope,
- "ForInStatement:exit": exitScope,
- ForOfStatement: enterScope,
- "ForOfStatement:exit": exitScope,
- SwitchStatement: enterScope,
- "SwitchStatement:exit": exitScope,
- CatchClause: enterScope,
- "CatchClause:exit": exitScope,
-
- VariableDeclaration: checkForVariables
- };
- }
- };
|