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.

73 lines
2.4 KiB

/**
* @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
};
};