node/tools/eslint/lib/rules/no-shadow.js
Yosuke Furukawa f9dd34d301 tools: replace closure-linter with eslint
PR-URL: https://github.com/iojs/io.js/pull/1539
Fixes: https://github.com/iojs/io.js/issues/1253
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
Reviewed-By: Johan Bergström <bugs@bergstroem.nu>
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
2015-05-09 12:09:52 +09:00

73 lines
2.4 KiB
JavaScript

/**
* @fileoverview Rule to flag on declaring variables already declared in the outer scope
* @author Ilya Volodin
* @copyright 2013 Ilya Volodin. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
/**
* Checks if a variable is contained in the list of given scope variables.
* @param {Object} variable The variable to check.
* @param {Array} scopeVars The scope variables to look for.
* @returns {boolean} Whether or not the variable is contains in the list of scope variables.
*/
function isContainedInScopeVars(variable, scopeVars) {
return scopeVars.some(function (scopeVar) {
if (scopeVar.identifiers.length > 0) {
return variable.name === scopeVar.name;
}
return false;
});
}
/**
* Checks if the given variables are shadowed in the given scope.
* @param {Array} variables The variables to look for
* @param {Object} scope The scope to be checked.
* @returns {void}
*/
function checkShadowsInScope(variables, scope) {
variables.forEach(function (variable) {
if (isContainedInScopeVars(variable, scope.variables) &&
// "arguments" is a special case that has no identifiers (#1759)
variable.identifiers.length > 0 &&
// function names are exempt
variable.defs.length && variable.defs[0].type !== "FunctionName"
) {
context.report(variable.identifiers[0], "{{a}} is already declared in the upper scope.", {a: variable.name});
}
});
}
/**
* Checks the current context for shadowed variables.
* @returns {void}
*/
function checkForShadows() {
var scope = context.getScope(),
variables = scope.variables;
// iterate through the array of variables and find duplicates with the upper scope
var upper = scope.upper;
while (upper) {
checkShadowsInScope(variables, upper);
upper = upper.upper;
}
}
return {
"FunctionDeclaration": checkForShadows,
"FunctionExpression": checkForShadows,
"ArrowFunctionExpression": checkForShadows
};
};