eslint 0.22.0 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/LICENSE +20 -20
  2. package/README.md +111 -95
  3. package/bin/eslint.js +41 -41
  4. package/conf/environments.js +87 -81
  5. package/conf/eslint.json +186 -179
  6. package/lib/api.js +13 -12
  7. package/lib/cli-engine.js +441 -451
  8. package/lib/cli.js +196 -196
  9. package/lib/config-initializer.js +145 -145
  10. package/lib/config-validator.js +110 -110
  11. package/lib/config.js +428 -416
  12. package/lib/eslint.js +1072 -1073
  13. package/lib/file-finder.js +167 -167
  14. package/lib/formatters/checkstyle.js +68 -68
  15. package/lib/formatters/compact.js +53 -53
  16. package/lib/formatters/jslint-xml.js +40 -40
  17. package/lib/formatters/junit.js +63 -63
  18. package/lib/formatters/stylish.js +90 -90
  19. package/lib/formatters/tap.js +86 -86
  20. package/lib/ignored-paths.js +137 -137
  21. package/lib/load-rules.js +39 -39
  22. package/lib/options.js +132 -126
  23. package/lib/rule-context.js +107 -107
  24. package/lib/rules/accessor-pairs.js +65 -65
  25. package/lib/rules/array-bracket-spacing.js +180 -0
  26. package/lib/rules/block-scoped-var.js +339 -320
  27. package/lib/rules/brace-style.js +228 -228
  28. package/lib/rules/camelcase.js +111 -111
  29. package/lib/rules/comma-dangle.js +67 -64
  30. package/lib/rules/comma-spacing.js +191 -191
  31. package/lib/rules/comma-style.js +195 -195
  32. package/lib/rules/complexity.js +94 -94
  33. package/lib/rules/computed-property-spacing.js +144 -0
  34. package/lib/rules/consistent-return.js +75 -75
  35. package/lib/rules/consistent-this.js +119 -119
  36. package/lib/rules/constructor-super.js +108 -0
  37. package/lib/rules/curly.js +109 -109
  38. package/lib/rules/default-case.js +66 -66
  39. package/lib/rules/dot-location.js +63 -63
  40. package/lib/rules/dot-notation.js +119 -119
  41. package/lib/rules/eol-last.js +38 -38
  42. package/lib/rules/eqeqeq.js +96 -96
  43. package/lib/rules/func-names.js +45 -45
  44. package/lib/rules/func-style.js +49 -49
  45. package/lib/rules/generator-star-spacing.js +104 -87
  46. package/lib/rules/generator-star.js +76 -76
  47. package/lib/rules/global-strict.js +49 -49
  48. package/lib/rules/guard-for-in.js +32 -32
  49. package/lib/rules/handle-callback-err.js +81 -124
  50. package/lib/rules/indent.js +486 -486
  51. package/lib/rules/key-spacing.js +325 -325
  52. package/lib/rules/linebreak-style.js +44 -44
  53. package/lib/rules/lines-around-comment.js +228 -160
  54. package/lib/rules/max-depth.js +89 -89
  55. package/lib/rules/max-len.js +76 -76
  56. package/lib/rules/max-nested-callbacks.js +73 -73
  57. package/lib/rules/max-params.js +45 -45
  58. package/lib/rules/max-statements.js +61 -61
  59. package/lib/rules/new-cap.js +224 -224
  60. package/lib/rules/new-parens.js +29 -29
  61. package/lib/rules/newline-after-var.js +127 -127
  62. package/lib/rules/no-alert.js +153 -153
  63. package/lib/rules/no-array-constructor.js +31 -31
  64. package/lib/rules/no-bitwise.js +57 -57
  65. package/lib/rules/no-caller.js +29 -29
  66. package/lib/rules/no-catch-shadow.js +52 -52
  67. package/lib/rules/no-comma-dangle.js +45 -45
  68. package/lib/rules/no-cond-assign.js +123 -123
  69. package/lib/rules/no-console.js +27 -27
  70. package/lib/rules/no-constant-condition.js +73 -73
  71. package/lib/rules/no-continue.js +23 -23
  72. package/lib/rules/no-control-regex.js +58 -58
  73. package/lib/rules/no-debugger.js +22 -22
  74. package/lib/rules/no-delete-var.js +25 -25
  75. package/lib/rules/no-div-regex.js +27 -27
  76. package/lib/rules/no-dupe-args.js +89 -85
  77. package/lib/rules/no-dupe-keys.js +43 -43
  78. package/lib/rules/no-duplicate-case.js +67 -67
  79. package/lib/rules/no-else-return.js +125 -125
  80. package/lib/rules/no-empty-character-class.js +43 -43
  81. package/lib/rules/no-empty-class.js +45 -45
  82. package/lib/rules/no-empty-label.js +27 -27
  83. package/lib/rules/no-empty.js +49 -49
  84. package/lib/rules/no-eq-null.js +29 -29
  85. package/lib/rules/no-eval.js +26 -26
  86. package/lib/rules/no-ex-assign.js +42 -42
  87. package/lib/rules/no-extend-native.js +103 -103
  88. package/lib/rules/no-extra-bind.js +81 -81
  89. package/lib/rules/no-extra-boolean-cast.js +71 -71
  90. package/lib/rules/no-extra-parens.js +368 -355
  91. package/lib/rules/no-extra-semi.js +70 -23
  92. package/lib/rules/no-extra-strict.js +86 -86
  93. package/lib/rules/no-fallthrough.js +97 -97
  94. package/lib/rules/no-floating-decimal.js +30 -30
  95. package/lib/rules/no-func-assign.js +83 -83
  96. package/lib/rules/no-implied-eval.js +76 -76
  97. package/lib/rules/no-inline-comments.js +49 -49
  98. package/lib/rules/no-inner-declarations.js +78 -78
  99. package/lib/rules/no-invalid-regexp.js +53 -53
  100. package/lib/rules/no-irregular-whitespace.js +135 -135
  101. package/lib/rules/no-iterator.js +28 -28
  102. package/lib/rules/no-label-var.js +64 -64
  103. package/lib/rules/no-labels.js +44 -44
  104. package/lib/rules/no-lone-blocks.js +106 -27
  105. package/lib/rules/no-lonely-if.js +30 -30
  106. package/lib/rules/no-loop-func.js +58 -58
  107. package/lib/rules/no-mixed-requires.js +165 -165
  108. package/lib/rules/no-mixed-spaces-and-tabs.js +74 -74
  109. package/lib/rules/no-multi-spaces.js +119 -119
  110. package/lib/rules/no-multi-str.js +43 -43
  111. package/lib/rules/no-multiple-empty-lines.js +98 -98
  112. package/lib/rules/no-native-reassign.js +62 -62
  113. package/lib/rules/no-negated-in-lhs.js +25 -25
  114. package/lib/rules/no-nested-ternary.js +24 -24
  115. package/lib/rules/no-new-func.js +25 -25
  116. package/lib/rules/no-new-object.js +25 -25
  117. package/lib/rules/no-new-require.js +25 -25
  118. package/lib/rules/no-new-wrappers.js +26 -26
  119. package/lib/rules/no-new.js +27 -27
  120. package/lib/rules/no-obj-calls.js +28 -28
  121. package/lib/rules/no-octal-escape.js +39 -39
  122. package/lib/rules/no-octal.js +25 -25
  123. package/lib/rules/no-param-reassign.js +87 -87
  124. package/lib/rules/no-path-concat.js +39 -39
  125. package/lib/rules/no-plusplus.js +24 -24
  126. package/lib/rules/no-process-env.js +30 -30
  127. package/lib/rules/no-process-exit.js +33 -33
  128. package/lib/rules/no-proto.js +28 -28
  129. package/lib/rules/no-redeclare.js +68 -68
  130. package/lib/rules/no-regex-spaces.js +35 -35
  131. package/lib/rules/no-reserved-keys.js +56 -56
  132. package/lib/rules/no-restricted-modules.js +85 -85
  133. package/lib/rules/no-return-assign.js +53 -24
  134. package/lib/rules/no-script-url.js +34 -34
  135. package/lib/rules/no-self-compare.js +29 -29
  136. package/lib/rules/no-sequences.js +94 -94
  137. package/lib/rules/no-shadow-restricted-names.js +51 -51
  138. package/lib/rules/no-shadow.js +181 -136
  139. package/lib/rules/no-space-before-semi.js +98 -98
  140. package/lib/rules/no-spaced-func.js +37 -37
  141. package/lib/rules/no-sparse-arrays.js +33 -33
  142. package/lib/rules/no-sync.js +30 -30
  143. package/lib/rules/no-ternary.js +24 -24
  144. package/lib/rules/no-this-before-super.js +144 -0
  145. package/lib/rules/no-throw-literal.js +33 -33
  146. package/lib/rules/no-trailing-spaces.js +74 -63
  147. package/lib/rules/no-undef-init.js +28 -28
  148. package/lib/rules/no-undef.js +92 -92
  149. package/lib/rules/no-undefined.js +27 -27
  150. package/lib/rules/no-underscore-dangle.js +73 -73
  151. package/lib/rules/no-unexpected-multiline.js +58 -0
  152. package/lib/rules/no-unneeded-ternary.js +48 -48
  153. package/lib/rules/no-unreachable.js +98 -98
  154. package/lib/rules/no-unused-expressions.js +76 -76
  155. package/lib/rules/no-unused-vars.js +252 -250
  156. package/lib/rules/no-use-before-define.js +105 -105
  157. package/lib/rules/no-var.js +26 -26
  158. package/lib/rules/no-void.js +28 -28
  159. package/lib/rules/no-warning-comments.js +102 -102
  160. package/lib/rules/no-with.js +22 -22
  161. package/lib/rules/no-wrap-func.js +65 -65
  162. package/lib/rules/object-curly-spacing.js +231 -206
  163. package/lib/rules/object-shorthand.js +74 -73
  164. package/lib/rules/one-var.js +311 -304
  165. package/lib/rules/operator-assignment.js +118 -118
  166. package/lib/rules/operator-linebreak.js +114 -114
  167. package/lib/rules/padded-blocks.js +98 -98
  168. package/lib/rules/prefer-const.js +91 -0
  169. package/lib/rules/quote-props.js +72 -72
  170. package/lib/rules/quotes.js +92 -92
  171. package/lib/rules/radix.js +41 -41
  172. package/lib/rules/semi-spacing.js +167 -167
  173. package/lib/rules/semi.js +136 -136
  174. package/lib/rules/sort-vars.js +49 -49
  175. package/lib/rules/space-after-function-name.js +49 -49
  176. package/lib/rules/space-after-keywords.js +82 -82
  177. package/lib/rules/space-before-blocks.js +91 -91
  178. package/lib/rules/space-before-function-paren.js +139 -139
  179. package/lib/rules/space-before-function-parentheses.js +139 -139
  180. package/lib/rules/space-in-brackets.js +305 -305
  181. package/lib/rules/space-in-parens.js +281 -281
  182. package/lib/rules/space-infix-ops.js +106 -106
  183. package/lib/rules/space-return-throw-case.js +38 -38
  184. package/lib/rules/space-unary-ops.js +124 -133
  185. package/lib/rules/spaced-comment.js +143 -0
  186. package/lib/rules/spaced-line-comment.js +89 -89
  187. package/lib/rules/strict.js +242 -242
  188. package/lib/rules/use-isnan.js +26 -26
  189. package/lib/rules/valid-jsdoc.js +215 -215
  190. package/lib/rules/valid-typeof.js +42 -42
  191. package/lib/rules/vars-on-top.js +115 -115
  192. package/lib/rules/wrap-iife.js +48 -48
  193. package/lib/rules/wrap-regex.js +38 -38
  194. package/lib/rules/yoda.js +242 -225
  195. package/lib/rules.js +88 -88
  196. package/lib/timing.js +109 -109
  197. package/lib/token-store.js +201 -201
  198. package/lib/util/traverse.js +105 -105
  199. package/lib/util.js +125 -85
  200. package/package.json +6 -6
  201. package/CHANGELOG.md +0 -1638
@@ -1,320 +1,339 @@
1
- /**
2
- * @fileoverview Rule to check for "block scoped" variables by binding context
3
- * @author Matt DuVall <http://www.mattduvall.com>
4
- */
5
- "use strict";
6
-
7
- //------------------------------------------------------------------------------
8
- // Rule Definition
9
- //------------------------------------------------------------------------------
10
-
11
- module.exports = function(context) {
12
-
13
- var scopeStack = [];
14
-
15
- //--------------------------------------------------------------------------
16
- // Helpers
17
- //--------------------------------------------------------------------------
18
-
19
- /**
20
- * Determines whether an identifier is in declaration position or is a non-declaration reference.
21
- * @param {ASTNode} id The identifier.
22
- * @param {ASTNode} parent The identifier's parent AST node.
23
- * @returns {Boolean} true when the identifier is in declaration position.
24
- */
25
- function isDeclaration(id, parent) {
26
- switch (parent.type) {
27
- case "FunctionDeclaration":
28
- case "FunctionExpression":
29
- return parent.params.indexOf(id) > -1 || id === parent.id;
30
-
31
- case "VariableDeclarator":
32
- return id === parent.id;
33
-
34
- case "CatchClause":
35
- return id === parent.param;
36
-
37
- default:
38
- return false;
39
- }
40
- }
41
-
42
- /**
43
- * Determines whether an identifier is in property position.
44
- * @param {ASTNode} id The identifier.
45
- * @param {ASTNode} parent The identifier's parent AST node.
46
- * @returns {Boolean} true when the identifier is in property position.
47
- */
48
- function isProperty(id, parent) {
49
- switch (parent.type) {
50
- case "MemberExpression":
51
- return id === parent.property && !parent.computed;
52
-
53
- case "Property":
54
- return id === parent.key;
55
-
56
- default:
57
- return false;
58
- }
59
- }
60
-
61
- /**
62
- * Pushes a new scope object on the scope stack.
63
- * @returns {void}
64
- */
65
- function pushScope() {
66
- scopeStack.push([]);
67
- }
68
-
69
- /**
70
- * Removes the topmost scope object from the scope stack.
71
- * @returns {void}
72
- */
73
- function popScope() {
74
- scopeStack.pop();
75
- }
76
-
77
- /**
78
- * Declares the given names in the topmost scope object.
79
- * @param {[String]} names A list of names to declare.
80
- * @returns {void}
81
- */
82
- function declare(names) {
83
- [].push.apply(scopeStack[scopeStack.length - 1], names);
84
- }
85
-
86
- //--------------------------------------------------------------------------
87
- // Public API
88
- //--------------------------------------------------------------------------
89
-
90
- /**
91
- * Declares all relevant identifiers for module imports.
92
- * @param {ASTNode} node The AST node representing an import.
93
- * @returns {void}
94
- * @private
95
- */
96
- function declareImports(node) {
97
- declare([node.local.name]);
98
-
99
- if (node.imported && node.imported.name !== node.local.name) {
100
- declare([node.imported.name]);
101
- }
102
- }
103
-
104
- /**
105
- * Declares all relevant identifiers for classes.
106
- * @param {ASTNode} node The AST node representing a class.
107
- * @returns {void}
108
- * @private
109
- */
110
- function declareClass(node) {
111
-
112
- if (node.id) {
113
- declare([node.id.name]);
114
- }
115
-
116
- pushScope();
117
- }
118
-
119
- /**
120
- * Declares all relevant identifiers for classes.
121
- * @param {ASTNode} node The AST node representing a class.
122
- * @returns {void}
123
- * @private
124
- */
125
- function declareClassMethod(node) {
126
- pushScope();
127
-
128
- declare([node.key.name]);
129
- }
130
-
131
- /**
132
- * Add declarations based on the type of node being passed.
133
- * @param {ASTNode} node The node containing declarations.
134
- * @returns {void}
135
- * @private
136
- */
137
- function declareByNodeType(node) {
138
-
139
- var declarations = [];
140
-
141
- switch (node.type) {
142
- case "Identifier":
143
- declarations.push(node.name);
144
- break;
145
-
146
- case "ObjectPattern":
147
- node.properties.forEach(function(property) {
148
- declarations.push(property.key.name);
149
- if (property.value) {
150
- declarations.push(property.value.name);
151
- }
152
- });
153
- break;
154
-
155
- case "ArrayPattern":
156
- node.elements.forEach(function(element) {
157
- if (element) {
158
- declarations.push(element.name);
159
- }
160
- });
161
- break;
162
-
163
- case "AssignmentPattern":
164
- declareByNodeType(node.left);
165
- break;
166
-
167
- case "RestElement":
168
- declareByNodeType(node.argument);
169
- break;
170
-
171
- // no default
172
- }
173
-
174
- declare(declarations);
175
-
176
- }
177
-
178
- /**
179
- * Adds declarations of the function parameters and pushes the scope
180
- * @param {ASTNode} node The node containing declarations.
181
- * @returns {void}
182
- * @private
183
- */
184
- function functionHandler(node) {
185
- pushScope();
186
-
187
- node.params.forEach(function(param) {
188
- declareByNodeType(param);
189
- });
190
-
191
- declare(node.rest ? [node.rest.name] : []);
192
- declare(["arguments"]);
193
- }
194
-
195
- /**
196
- * Adds declaration of the function name in its parent scope then process the function
197
- * @param {ASTNode} node The node containing declarations.
198
- * @returns {void}
199
- * @private
200
- */
201
- function functionDeclarationHandler(node) {
202
- declare(node.id ? [node.id.name] : []);
203
- functionHandler(node);
204
- }
205
-
206
- /**
207
- * Process function declarations and declares its name in its own scope
208
- * @param {ASTNode} node The node containing declarations.
209
- * @returns {void}
210
- * @private
211
- */
212
- function functionExpressionHandler(node) {
213
- functionHandler(node);
214
- declare(node.id ? [node.id.name] : []);
215
- }
216
-
217
- function variableDeclarationHandler(node) {
218
- node.declarations.forEach(function(declaration) {
219
- declareByNodeType(declaration.id);
220
- });
221
-
222
- }
223
-
224
- return {
225
- "Program": function() {
226
- var scope = context.getScope();
227
- scopeStack = [scope.variables.map(function(v) {
228
- return v.name;
229
- })];
230
-
231
- // global return creates another scope
232
- if (context.ecmaFeatures.globalReturn) {
233
- scope = scope.childScopes[0];
234
- scopeStack.push(scope.variables.map(function(v) {
235
- return v.name;
236
- }));
237
- }
238
- },
239
-
240
- "ImportSpecifier": declareImports,
241
- "ImportDefaultSpecifier": declareImports,
242
- "ImportNamespaceSpecifier": declareImports,
243
-
244
- "BlockStatement": function(node) {
245
- var statements = node.body;
246
- pushScope();
247
- statements.forEach(function(stmt) {
248
- if (stmt.type === "VariableDeclaration") {
249
- variableDeclarationHandler(stmt);
250
- } else if (stmt.type === "FunctionDeclaration") {
251
- declare([stmt.id.name]);
252
- }
253
- });
254
- },
255
-
256
- "VariableDeclaration": function (node) {
257
- variableDeclarationHandler(node);
258
- },
259
-
260
- "BlockStatement:exit": popScope,
261
-
262
- "CatchClause": function(node) {
263
- pushScope();
264
- declare([node.param.name]);
265
- },
266
- "CatchClause:exit": popScope,
267
-
268
- "FunctionDeclaration": functionDeclarationHandler,
269
- "FunctionDeclaration:exit": popScope,
270
-
271
- "ClassDeclaration": declareClass,
272
- "ClassDeclaration:exit": popScope,
273
-
274
- "ClassExpression": declareClass,
275
- "ClassExpression:exit": popScope,
276
-
277
- "MethodDefinition": declareClassMethod,
278
- "MethodDefinition:exit": popScope,
279
-
280
- "FunctionExpression": functionExpressionHandler,
281
- "FunctionExpression:exit": popScope,
282
-
283
- // Arrow functions cannot have names
284
- "ArrowFunctionExpression": functionHandler,
285
- "ArrowFunctionExpression:exit": popScope,
286
-
287
- "ForStatement": function() {
288
- pushScope();
289
- },
290
- "ForStatement:exit": popScope,
291
-
292
- "ForInStatement": function() {
293
- pushScope();
294
- },
295
- "ForInStatement:exit": popScope,
296
-
297
- "ForOfStatement": function() {
298
- pushScope();
299
- },
300
- "ForOfStatement:exit": popScope,
301
-
302
- "Identifier": function(node) {
303
- var ancestor = context.getAncestors().pop();
304
- if (isDeclaration(node, ancestor) || isProperty(node, ancestor) || ancestor.type === "LabeledStatement") {
305
- return;
306
- }
307
-
308
- for (var i = 0, l = scopeStack.length; i < l; i++) {
309
- if (scopeStack[i].indexOf(node.name) > -1) {
310
- return;
311
- }
312
- }
313
-
314
- context.report(node, "\"" + node.name + "\" used outside of binding context.");
315
- }
316
- };
317
-
318
- };
319
-
320
- module.exports.schema = [];
1
+ /**
2
+ * @fileoverview Rule to check for "block scoped" variables by binding context
3
+ * @author Matt DuVall <http://www.mattduvall.com>
4
+ * @copyright 2015 Mathieu M-Gosselin. All rights reserved.
5
+ */
6
+ "use strict";
7
+
8
+ //------------------------------------------------------------------------------
9
+ // Rule Definition
10
+ //------------------------------------------------------------------------------
11
+
12
+ module.exports = function(context) {
13
+
14
+ var scopeStack = [];
15
+
16
+ //--------------------------------------------------------------------------
17
+ // Helpers
18
+ //--------------------------------------------------------------------------
19
+
20
+ /**
21
+ * Determines whether an identifier is in declaration position or is a non-declaration reference.
22
+ * @param {ASTNode} id The identifier.
23
+ * @param {ASTNode} parent The identifier's parent AST node.
24
+ * @returns {Boolean} true when the identifier is in declaration position.
25
+ */
26
+ function isDeclaration(id, parent) {
27
+ switch (parent.type) {
28
+ case "FunctionDeclaration":
29
+ case "FunctionExpression":
30
+ return parent.params.indexOf(id) > -1 || id === parent.id;
31
+
32
+ case "VariableDeclarator":
33
+ return id === parent.id;
34
+
35
+ case "CatchClause":
36
+ return id === parent.param;
37
+
38
+ default:
39
+ return false;
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Determines whether an identifier is in property position.
45
+ * @param {ASTNode} id The identifier.
46
+ * @param {ASTNode} parent The identifier's parent AST node.
47
+ * @returns {Boolean} true when the identifier is in property position.
48
+ */
49
+ function isProperty(id, parent) {
50
+ switch (parent.type) {
51
+ case "MemberExpression":
52
+ return id === parent.property && !parent.computed;
53
+
54
+ case "Property":
55
+ return id === parent.key;
56
+
57
+ default:
58
+ return false;
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Pushes a new scope object on the scope stack.
64
+ * @returns {void}
65
+ */
66
+ function pushScope() {
67
+ scopeStack.push([]);
68
+ }
69
+
70
+ /**
71
+ * Removes the topmost scope object from the scope stack.
72
+ * @returns {void}
73
+ */
74
+ function popScope() {
75
+ scopeStack.pop();
76
+ }
77
+
78
+ /**
79
+ * Declares the given names in the topmost scope object.
80
+ * @param {[String]} names A list of names to declare.
81
+ * @returns {void}
82
+ */
83
+ function declare(names) {
84
+ [].push.apply(scopeStack[scopeStack.length - 1], names);
85
+ }
86
+
87
+ //--------------------------------------------------------------------------
88
+ // Public API
89
+ //--------------------------------------------------------------------------
90
+
91
+ /**
92
+ * Declares all relevant identifiers for module imports.
93
+ * @param {ASTNode} node The AST node representing an import.
94
+ * @returns {void}
95
+ * @private
96
+ */
97
+ function declareImports(node) {
98
+ declare([node.local.name]);
99
+
100
+ if (node.imported && node.imported.name !== node.local.name) {
101
+ declare([node.imported.name]);
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Declares all relevant identifiers for module exports.
107
+ * @param {ASTNode} node The AST node representing an export.
108
+ * @returns {void}
109
+ * @private
110
+ */
111
+ function declareExports(node) {
112
+ if (node.exported && node.exported.name) {
113
+ declare([node.exported.name]);
114
+
115
+ if (node.local) {
116
+ declare([node.local.name]);
117
+ }
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Declares all relevant identifiers for classes.
123
+ * @param {ASTNode} node The AST node representing a class.
124
+ * @returns {void}
125
+ * @private
126
+ */
127
+ function declareClass(node) {
128
+
129
+ if (node.id) {
130
+ declare([node.id.name]);
131
+ }
132
+
133
+ pushScope();
134
+ }
135
+
136
+ /**
137
+ * Declares all relevant identifiers for classes.
138
+ * @param {ASTNode} node The AST node representing a class.
139
+ * @returns {void}
140
+ * @private
141
+ */
142
+ function declareClassMethod(node) {
143
+ pushScope();
144
+
145
+ declare([node.key.name]);
146
+ }
147
+
148
+ /**
149
+ * Add declarations based on the type of node being passed.
150
+ * @param {ASTNode} node The node containing declarations.
151
+ * @returns {void}
152
+ * @private
153
+ */
154
+ function declareByNodeType(node) {
155
+
156
+ var declarations = [];
157
+
158
+ switch (node.type) {
159
+ case "Identifier":
160
+ declarations.push(node.name);
161
+ break;
162
+
163
+ case "ObjectPattern":
164
+ node.properties.forEach(function(property) {
165
+ declarations.push(property.key.name);
166
+ if (property.value) {
167
+ declarations.push(property.value.name);
168
+ }
169
+ });
170
+ break;
171
+
172
+ case "ArrayPattern":
173
+ node.elements.forEach(function(element) {
174
+ if (element) {
175
+ declarations.push(element.name);
176
+ }
177
+ });
178
+ break;
179
+
180
+ case "AssignmentPattern":
181
+ declareByNodeType(node.left);
182
+ break;
183
+
184
+ case "RestElement":
185
+ declareByNodeType(node.argument);
186
+ break;
187
+
188
+ // no default
189
+ }
190
+
191
+ declare(declarations);
192
+
193
+ }
194
+
195
+ /**
196
+ * Adds declarations of the function parameters and pushes the scope
197
+ * @param {ASTNode} node The node containing declarations.
198
+ * @returns {void}
199
+ * @private
200
+ */
201
+ function functionHandler(node) {
202
+ pushScope();
203
+
204
+ node.params.forEach(function(param) {
205
+ declareByNodeType(param);
206
+ });
207
+
208
+ declare(node.rest ? [node.rest.name] : []);
209
+ declare(["arguments"]);
210
+ }
211
+
212
+ /**
213
+ * Adds declaration of the function name in its parent scope then process the function
214
+ * @param {ASTNode} node The node containing declarations.
215
+ * @returns {void}
216
+ * @private
217
+ */
218
+ function functionDeclarationHandler(node) {
219
+ declare(node.id ? [node.id.name] : []);
220
+ functionHandler(node);
221
+ }
222
+
223
+ /**
224
+ * Process function declarations and declares its name in its own scope
225
+ * @param {ASTNode} node The node containing declarations.
226
+ * @returns {void}
227
+ * @private
228
+ */
229
+ function functionExpressionHandler(node) {
230
+ functionHandler(node);
231
+ declare(node.id ? [node.id.name] : []);
232
+ }
233
+
234
+ function variableDeclarationHandler(node) {
235
+ node.declarations.forEach(function(declaration) {
236
+ declareByNodeType(declaration.id);
237
+ });
238
+
239
+ }
240
+
241
+ return {
242
+ "Program": function() {
243
+ var scope = context.getScope();
244
+ scopeStack = [scope.variables.map(function(v) {
245
+ return v.name;
246
+ })];
247
+
248
+ // global return creates another scope
249
+ if (context.ecmaFeatures.globalReturn) {
250
+ scope = scope.childScopes[0];
251
+ scopeStack.push(scope.variables.map(function(v) {
252
+ return v.name;
253
+ }));
254
+ }
255
+ },
256
+
257
+ "ImportSpecifier": declareImports,
258
+ "ImportDefaultSpecifier": declareImports,
259
+ "ImportNamespaceSpecifier": declareImports,
260
+
261
+ "ExportSpecifier": declareExports,
262
+
263
+ "BlockStatement": function(node) {
264
+ var statements = node.body;
265
+ pushScope();
266
+ statements.forEach(function(stmt) {
267
+ if (stmt.type === "VariableDeclaration") {
268
+ variableDeclarationHandler(stmt);
269
+ } else if (stmt.type === "FunctionDeclaration") {
270
+ declare([stmt.id.name]);
271
+ }
272
+ });
273
+ },
274
+
275
+ "VariableDeclaration": function (node) {
276
+ variableDeclarationHandler(node);
277
+ },
278
+
279
+ "BlockStatement:exit": popScope,
280
+
281
+ "CatchClause": function(node) {
282
+ pushScope();
283
+ declare([node.param.name]);
284
+ },
285
+ "CatchClause:exit": popScope,
286
+
287
+ "FunctionDeclaration": functionDeclarationHandler,
288
+ "FunctionDeclaration:exit": popScope,
289
+
290
+ "ClassDeclaration": declareClass,
291
+ "ClassDeclaration:exit": popScope,
292
+
293
+ "ClassExpression": declareClass,
294
+ "ClassExpression:exit": popScope,
295
+
296
+ "MethodDefinition": declareClassMethod,
297
+ "MethodDefinition:exit": popScope,
298
+
299
+ "FunctionExpression": functionExpressionHandler,
300
+ "FunctionExpression:exit": popScope,
301
+
302
+ // Arrow functions cannot have names
303
+ "ArrowFunctionExpression": functionHandler,
304
+ "ArrowFunctionExpression:exit": popScope,
305
+
306
+ "ForStatement": function() {
307
+ pushScope();
308
+ },
309
+ "ForStatement:exit": popScope,
310
+
311
+ "ForInStatement": function() {
312
+ pushScope();
313
+ },
314
+ "ForInStatement:exit": popScope,
315
+
316
+ "ForOfStatement": function() {
317
+ pushScope();
318
+ },
319
+ "ForOfStatement:exit": popScope,
320
+
321
+ "Identifier": function(node) {
322
+ var ancestor = context.getAncestors().pop();
323
+ if (isDeclaration(node, ancestor) || isProperty(node, ancestor) || ancestor.type === "LabeledStatement") {
324
+ return;
325
+ }
326
+
327
+ for (var i = 0, l = scopeStack.length; i < l; i++) {
328
+ if (scopeStack[i].indexOf(node.name) > -1) {
329
+ return;
330
+ }
331
+ }
332
+
333
+ context.report(node, "\"" + node.name + "\" used outside of binding context.");
334
+ }
335
+ };
336
+
337
+ };
338
+
339
+ module.exports.schema = [];