UNPKG

2.64 kBJavaScriptView Raw
1/**
2 * @fileoverview Rule to flag use of function declaration identifiers as variables.
3 * @author Ian Christian Myers
4 */
5
6//------------------------------------------------------------------------------
7// Rule Definition
8//------------------------------------------------------------------------------
9
10module.exports = function(context) {
11
12 "use strict";
13
14 //--------------------------------------------------------------------------
15 // Helpers
16 //--------------------------------------------------------------------------
17
18 /*
19 * Walk the scope chain looking for either a FunctionDeclaration or a
20 * VariableDeclaration with the same name as left-hand side of the
21 * AssignmentExpression. If we find the FunctionDeclaration first, then we
22 * warn, because a FunctionDeclaration is trying to become a Variable or a
23 * FunctionExpression. If we find a VariableDeclaration first, then we have
24 * a legitimate shadow variable.
25 */
26 function checkIfIdentifierIsFunction(scope, name) {
27 var variable,
28 def,
29 i,
30 j;
31
32 // Loop over all of the identifiers available in scope.
33 for (i = 0; i < scope.variables.length; i++) {
34 variable = scope.variables[i];
35
36 // For each identifier, see if it was defined in _this_ scope.
37 for (j = 0; j < variable.defs.length; j++) {
38 def = variable.defs[j];
39
40 // Identifier is a function and was declared in this scope
41 if (def.name.name === name && def.type === "FunctionName") {
42 return true;
43 }
44
45 // Identifier is a variable and was declared in this scope. This
46 // is a legitimate shadow variable.
47 if (def.name.name === name) {
48 return false;
49 }
50 }
51 }
52
53 // Check the upper scope.
54 if (scope.upper) {
55 return checkIfIdentifierIsFunction(scope.upper, name);
56 }
57
58 // We've reached the global scope and haven't found anything.
59 return false;
60 }
61
62 //--------------------------------------------------------------------------
63 // Public API
64 //--------------------------------------------------------------------------
65
66 return {
67
68 "AssignmentExpression": function(node) {
69 var scope = context.getScope(),
70 name = node.left.name;
71
72 if (checkIfIdentifierIsFunction(scope, name)) {
73 context.report(node, "'{{name}}' is a function.", { name: name });
74 }
75
76 }
77
78 };
79
80};