diff options
Diffstat (limited to 'tools/eslint/lib/rules/no-param-reassign.js')
-rw-r--r-- | tools/eslint/lib/rules/no-param-reassign.js | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/tools/eslint/lib/rules/no-param-reassign.js b/tools/eslint/lib/rules/no-param-reassign.js new file mode 100644 index 0000000000..c38f0ef6f4 --- /dev/null +++ b/tools/eslint/lib/rules/no-param-reassign.js @@ -0,0 +1,85 @@ +/** + * @fileoverview Disallow reassignment of function parameters. + * @author Nat Burns + * @copyright 2014 Nat Burns. All rights reserved. + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = function(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Finds the declaration for a given variable by name, searching up the scope tree. + * @param {Scope} scope The scope in which to search. + * @param {String} name The name of the variable. + * @returns {Variable} The declaration information for the given variable, or null if no declaration was found. + */ + function findDeclaration(scope, name) { + var variables = scope.variables; + + for (var i = 0; i < variables.length; i++) { + if (variables[i].name === name) { + return variables[i]; + } + } + + if (scope.upper) { + return findDeclaration(scope.upper, name); + } else { + return null; + } + } + + /** + * Determines if a given variable is declared as a function parameter. + * @param {Variable} variable The variable declaration. + * @returns {boolean} True if the variable is a function parameter, false otherwise. + */ + function isParameter(variable) { + var defs = variable.defs; + + for (var i = 0; i < defs.length; i++) { + if (defs[i].type === "Parameter") { + return true; + } + } + + return false; + } + + /** + * Checks whether a given node is an assignment to a function parameter. + * If so, a linting error will be reported. + * @param {ASTNode} node The node to check. + * @param {String} name The name of the variable being assigned to. + * @returns {void} + */ + function checkParameter(node, name) { + var declaration = findDeclaration(context.getScope(), name); + + if (declaration && isParameter(declaration)) { + context.report(node, "Assignment to function parameter '{{name}}'.", { name: name }); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + "AssignmentExpression": function(node) { + checkParameter(node, node.left.name); + }, + + "UpdateExpression": function(node) { + checkParameter(node, node.argument.name); + } + }; +}; |