UNPKG

2.81 kBJavaScriptView Raw
1/**
2 * @fileoverview Rule to flag when the same variable is declared more then once.
3 * @author Ilya Volodin
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Rule Definition
10//------------------------------------------------------------------------------
11
12module.exports = function(context) {
13 var options = {
14 builtinGlobals: Boolean(context.options[0] && context.options[0].builtinGlobals)
15 };
16
17 /**
18 * Find variables in a given scope and flag redeclared ones.
19 * @param {Scope} scope - An escope scope object.
20 * @returns {void}
21 * @private
22 */
23 function findVariablesInScope(scope) {
24 scope.variables.forEach(function(variable) {
25 var hasBuiltin = options.builtinGlobals && "writeable" in variable;
26 var count = (hasBuiltin ? 1 : 0) + variable.identifiers.length;
27
28 if (count >= 2) {
29 variable.identifiers.sort(function(a, b) {
30 return a.range[1] - b.range[1];
31 });
32
33 for (var i = (hasBuiltin ? 0 : 1), l = variable.identifiers.length; i < l; i++) {
34 context.report(
35 variable.identifiers[i],
36 "'{{a}}' is already defined",
37 {a: variable.name});
38 }
39 }
40 });
41
42 }
43
44 /**
45 * Find variables in the current scope.
46 * @param {ASTNode} node - The Program node.
47 * @returns {void}
48 * @private
49 */
50 function checkForGlobal(node) {
51 var scope = context.getScope(),
52 parserOptions = context.parserOptions,
53 ecmaFeatures = parserOptions.ecmaFeatures || {};
54
55 // Nodejs env or modules has a special scope.
56 if (ecmaFeatures.globalReturn || node.sourceType === "module") {
57 findVariablesInScope(scope.childScopes[0]);
58 } else {
59 findVariablesInScope(scope);
60 }
61 }
62
63 /**
64 * Find variables in the current scope.
65 * @returns {void}
66 * @private
67 */
68 function checkForBlock() {
69 findVariablesInScope(context.getScope());
70 }
71
72 if (context.parserOptions.ecmaVersion >= 6) {
73 return {
74 "Program": checkForGlobal,
75 "BlockStatement": checkForBlock,
76 "SwitchStatement": checkForBlock
77 };
78 } else {
79 return {
80 "Program": checkForGlobal,
81 "FunctionDeclaration": checkForBlock,
82 "FunctionExpression": checkForBlock,
83 "ArrowFunctionExpression": checkForBlock
84 };
85 }
86};
87
88module.exports.schema = [
89 {
90 "type": "object",
91 "properties": {
92 "builtinGlobals": {"type": "boolean"}
93 },
94 "additionalProperties": false
95 }
96];