mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.0 KiB
106 lines
3.0 KiB
/**
|
|
* @fileoverview Rule to check for "block scoped" variables by binding context
|
|
* @author Matt DuVall <http://www.mattduvall.com>
|
|
* @copyright 2015 Toru Nagashima. All rights reserved.
|
|
* @copyright 2015 Mathieu M-Gosselin. All rights reserved.
|
|
*/
|
|
"use strict";
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Rule Definition
|
|
//------------------------------------------------------------------------------
|
|
|
|
module.exports = function(context) {
|
|
var stack = [];
|
|
|
|
/**
|
|
* Makes a block scope.
|
|
* @param {ASTNode} node - A node of a scope.
|
|
* @returns {void}
|
|
*/
|
|
function enterScope(node) {
|
|
stack.push(node.range);
|
|
}
|
|
|
|
/**
|
|
* Pops the last block scope.
|
|
* @returns {void}
|
|
*/
|
|
function exitScope() {
|
|
stack.pop();
|
|
}
|
|
|
|
/**
|
|
* Reports a given reference.
|
|
* @param {escope.Reference} reference - A reference to report.
|
|
* @returns {void}
|
|
*/
|
|
function report(reference) {
|
|
var identifier = reference.identifier;
|
|
context.report(
|
|
identifier,
|
|
"'{{name}}' used outside of binding context.",
|
|
{name: identifier.name});
|
|
}
|
|
|
|
/**
|
|
* Finds and reports references which are outside of valid scopes.
|
|
* @param {ASTNode} node - A node to get variables.
|
|
* @returns {void}
|
|
*/
|
|
function checkForVariables(node) {
|
|
if (node.kind !== "var") {
|
|
return;
|
|
}
|
|
|
|
// Defines a predicate to check whether or not a given reference is outside of valid scope.
|
|
var scopeRange = stack[stack.length - 1];
|
|
|
|
/**
|
|
* Check if a reference is out of scope
|
|
* @param {ASTNode} reference node to examine
|
|
* @returns {boolean} True is its outside the scope
|
|
* @private
|
|
*/
|
|
function isOutsideOfScope(reference) {
|
|
var idRange = reference.identifier.range;
|
|
return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1];
|
|
}
|
|
|
|
// Gets declared variables, and checks its references.
|
|
var variables = context.getDeclaredVariables(node);
|
|
for (var i = 0; i < variables.length; ++i) {
|
|
// Reports.
|
|
variables[i]
|
|
.references
|
|
.filter(isOutsideOfScope)
|
|
.forEach(report);
|
|
}
|
|
}
|
|
|
|
return {
|
|
"Program": function(node) {
|
|
stack = [node.range];
|
|
},
|
|
|
|
// Manages scopes.
|
|
"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,
|
|
|
|
// Finds and reports references which are outside of valid scope.
|
|
"VariableDeclaration": checkForVariables
|
|
};
|
|
|
|
};
|
|
|
|
module.exports.schema = [];
|
|
|