diff options
Diffstat (limited to 'tools/eslint/lib/rules/no-shadow.js')
-rw-r--r-- | tools/eslint/lib/rules/no-shadow.js | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/tools/eslint/lib/rules/no-shadow.js b/tools/eslint/lib/rules/no-shadow.js new file mode 100644 index 0000000000..4906fa58f2 --- /dev/null +++ b/tools/eslint/lib/rules/no-shadow.js @@ -0,0 +1,72 @@ +/** + * @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 + }; + +}; |