summaryrefslogtreecommitdiff
path: root/tools/eslint/lib/rules/no-shadow.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/eslint/lib/rules/no-shadow.js')
-rw-r--r--tools/eslint/lib/rules/no-shadow.js72
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
+ };
+
+};