2 * @fileoverview Rule to flag use of function declaration identifiers as variables.
3 * @author Ian Christian Myers
4 * @copyright 2013 Ian Christian Myers. All rights reserved.
9 //------------------------------------------------------------------------------
11 //------------------------------------------------------------------------------
13 module.exports = function(context) {
15 //--------------------------------------------------------------------------
17 //--------------------------------------------------------------------------
20 * Walk the scope chain looking for either a FunctionDeclaration or a
21 * VariableDeclaration with the same name as left-hand side of the
22 * AssignmentExpression. If we find the FunctionDeclaration first, then we
23 * warn, because a FunctionDeclaration is trying to become a Variable or a
24 * FunctionExpression. If we find a VariableDeclaration first, then we have
25 * a legitimate shadow variable.
27 function checkIfIdentifierIsFunction(scope, name) {
33 // Loop over all of the identifiers available in scope.
34 for (i = 0; i < scope.variables.length; i++) {
35 variable = scope.variables[i];
37 // For each identifier, see if it was defined in _this_ scope.
38 for (j = 0; j < variable.defs.length; j++) {
39 def = variable.defs[j];
41 // Identifier is a function and was declared in this scope
42 if (def.type === "FunctionName" && def.name.name === name) {
46 // Identifier is a variable and was declared in this scope. This
47 // is a legitimate shadow variable.
48 if (def.name && def.name.name === name) {
54 // Check the upper scope.
56 return checkIfIdentifierIsFunction(scope.upper, name);
59 // We've reached the global scope and haven't found anything.
63 //--------------------------------------------------------------------------
65 //--------------------------------------------------------------------------
69 "AssignmentExpression": function(node) {
70 var scope = context.getScope(),
71 name = node.left.name;
73 if (checkIfIdentifierIsFunction(scope, name)) {
74 context.report(node, "'{{name}}' is a function.", { name: name });