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,27 +1,106 @@
1
- /**
2
- * @fileoverview Rule to flag blocks with no reason to exist
3
- * @author Brandon Mills
4
- */
5
-
6
- "use strict";
7
-
8
- //------------------------------------------------------------------------------
9
- // Rule Definition
10
- //------------------------------------------------------------------------------
11
-
12
- module.exports = function(context) {
13
-
14
- return {
15
- "BlockStatement": function (node) {
16
- // Check for any occurrence of BlockStatement > BlockStatement or
17
- // Program > BlockStatement
18
- var parent = context.getAncestors().pop();
19
- if (parent.type === "BlockStatement" || parent.type === "Program") {
20
- context.report(node, "Block is nested inside another block.");
21
- }
22
- }
23
- };
24
-
25
- };
26
-
27
- module.exports.schema = [];
1
+ /**
2
+ * @fileoverview Rule to flag blocks with no reason to exist
3
+ * @author Brandon Mills
4
+ * @copyright 2015 Roberto Vidal. All rights reserved.
5
+ * @copyright 2014 Brandon Mills. All rights reserved.
6
+ */
7
+
8
+ "use strict";
9
+
10
+ //------------------------------------------------------------------------------
11
+ // Rule Definition
12
+ //------------------------------------------------------------------------------
13
+
14
+ module.exports = function(context) {
15
+
16
+ // A stack of lone blocks to be checked for block-level bindings
17
+ var loneBlocks = [],
18
+ ruleDef;
19
+
20
+ /**
21
+ * Reports a node as invalid.
22
+ * @param {ASTNode} node - The node to be reported.
23
+ * @returns {void}
24
+ */
25
+ function report(node) {
26
+ var parent = context.getAncestors().pop();
27
+ context.report(node, parent.type === "Program" ?
28
+ "Block is redundant." :
29
+ "Nested block is redundant."
30
+ );
31
+ }
32
+
33
+ /**
34
+ * Checks for any ocurrence of BlockStatement > BlockStatement or Program > BlockStatement
35
+ * @returns {boolean} True if the current node is a lone block.
36
+ */
37
+ function isLoneBlock() {
38
+ var parent = context.getAncestors().pop();
39
+ return parent.type === "BlockStatement" || parent.type === "Program";
40
+ }
41
+
42
+ /**
43
+ * Checks the enclosing block of the current node for block-level bindings,
44
+ * and "marks it" as valid if any.
45
+ * @returns {void}
46
+ */
47
+ function markLoneBlock() {
48
+ if (loneBlocks.length === 0) {
49
+ return;
50
+ }
51
+
52
+ var block = context.getAncestors().pop();
53
+
54
+ if (loneBlocks[loneBlocks.length - 1] === block) {
55
+ loneBlocks.pop();
56
+ }
57
+ }
58
+
59
+ // Default rule definition: report all lone blocks
60
+ ruleDef = {
61
+ BlockStatement: function(node) {
62
+ if (isLoneBlock(node)) {
63
+ report(node);
64
+ }
65
+ }
66
+ };
67
+
68
+ // ES6: report blocks without block-level bindings
69
+ if (context.ecmaFeatures.blockBindings || context.ecmaFeatures.classes) {
70
+ ruleDef = {
71
+ "BlockStatement": function(node) {
72
+ if (isLoneBlock(node)) {
73
+ loneBlocks.push(node);
74
+ }
75
+ },
76
+ "BlockStatement:exit": function(node) {
77
+ if (loneBlocks.length > 0 && loneBlocks[loneBlocks.length - 1] === node) {
78
+ loneBlocks.pop();
79
+ report(node);
80
+ }
81
+ }
82
+ };
83
+ }
84
+
85
+ if (context.ecmaFeatures.blockBindings) {
86
+ ruleDef.VariableDeclaration = function(node) {
87
+ if (node.kind === "let" || node.kind === "const") {
88
+ markLoneBlock(node);
89
+ }
90
+ };
91
+
92
+ ruleDef.FunctionDeclaration = function(node) {
93
+ if (context.getScope().isStrict) {
94
+ markLoneBlock(node);
95
+ }
96
+ };
97
+ }
98
+
99
+ if (context.ecmaFeatures.classes) {
100
+ ruleDef.ClassDeclaration = markLoneBlock;
101
+ }
102
+
103
+ return ruleDef;
104
+ };
105
+
106
+ module.exports.schema = [];
@@ -1,30 +1,30 @@
1
- /**
2
- * @fileoverview Rule to disallow if as the only statmenet in an else block
3
- * @author Brandon Mills
4
- */
5
- "use strict";
6
-
7
- //------------------------------------------------------------------------------
8
- // Rule Definition
9
- //------------------------------------------------------------------------------
10
-
11
- module.exports = function(context) {
12
-
13
- return {
14
- "IfStatement": function(node) {
15
- var ancestors = context.getAncestors(),
16
- parent = ancestors.pop(),
17
- grandparent = ancestors.pop();
18
-
19
- if (parent && parent.type === "BlockStatement" &&
20
- parent.body.length === 1 && grandparent &&
21
- grandparent.type === "IfStatement" &&
22
- parent === grandparent.alternate) {
23
- context.report(node, "Unexpected if as the only statement in an else block.");
24
- }
25
- }
26
- };
27
-
28
- };
29
-
30
- module.exports.schema = [];
1
+ /**
2
+ * @fileoverview Rule to disallow if as the only statmenet in an else block
3
+ * @author Brandon Mills
4
+ */
5
+ "use strict";
6
+
7
+ //------------------------------------------------------------------------------
8
+ // Rule Definition
9
+ //------------------------------------------------------------------------------
10
+
11
+ module.exports = function(context) {
12
+
13
+ return {
14
+ "IfStatement": function(node) {
15
+ var ancestors = context.getAncestors(),
16
+ parent = ancestors.pop(),
17
+ grandparent = ancestors.pop();
18
+
19
+ if (parent && parent.type === "BlockStatement" &&
20
+ parent.body.length === 1 && grandparent &&
21
+ grandparent.type === "IfStatement" &&
22
+ parent === grandparent.alternate) {
23
+ context.report(node, "Unexpected if as the only statement in an else block.");
24
+ }
25
+ }
26
+ };
27
+
28
+ };
29
+
30
+ module.exports.schema = [];
@@ -1,58 +1,58 @@
1
- /**
2
- * @fileoverview Rule to flag creation of function inside a loop
3
- * @author Ilya Volodin
4
- * @copyright 2013 Ilya Volodin. All rights reserved.
5
- */
6
-
7
- "use strict";
8
-
9
- //------------------------------------------------------------------------------
10
- // Rule Definition
11
- //------------------------------------------------------------------------------
12
-
13
- module.exports = function(context) {
14
- /**
15
- * Reports if the given node has an ancestor node which is a loop.
16
- * @param {ASTNode} node The AST node to check.
17
- * @returns {boolean} Whether or not the node is within a loop.
18
- */
19
- function checkForLoops(node) {
20
- var ancestors = context.getAncestors();
21
-
22
- /**
23
- * Checks if the given node is a loop and current context is in the loop.
24
- * @param {ASTNode} ancestor The AST node to check.
25
- * @param {number} index The index of ancestor in ancestors.
26
- * @returns {boolean} Whether or not the node is a loop and current context is in the loop.
27
- */
28
- function isInLoop(ancestor, index) {
29
- switch (ancestor.type) {
30
- case "ForStatement":
31
- return ancestor.init !== ancestors[index + 1];
32
-
33
- case "ForInStatement":
34
- case "ForOfStatement":
35
- return ancestor.right !== ancestors[index + 1];
36
-
37
- case "WhileStatement":
38
- case "DoWhileStatement":
39
- return true;
40
-
41
- default:
42
- return false;
43
- }
44
- }
45
-
46
- if (ancestors.some(isInLoop)) {
47
- context.report(node, "Don't make functions within a loop");
48
- }
49
- }
50
-
51
- return {
52
- "ArrowFunctionExpression": checkForLoops,
53
- "FunctionExpression": checkForLoops,
54
- "FunctionDeclaration": checkForLoops
55
- };
56
- };
57
-
58
- module.exports.schema = [];
1
+ /**
2
+ * @fileoverview Rule to flag creation of function inside a loop
3
+ * @author Ilya Volodin
4
+ * @copyright 2013 Ilya Volodin. All rights reserved.
5
+ */
6
+
7
+ "use strict";
8
+
9
+ //------------------------------------------------------------------------------
10
+ // Rule Definition
11
+ //------------------------------------------------------------------------------
12
+
13
+ module.exports = function(context) {
14
+ /**
15
+ * Reports if the given node has an ancestor node which is a loop.
16
+ * @param {ASTNode} node The AST node to check.
17
+ * @returns {boolean} Whether or not the node is within a loop.
18
+ */
19
+ function checkForLoops(node) {
20
+ var ancestors = context.getAncestors();
21
+
22
+ /**
23
+ * Checks if the given node is a loop and current context is in the loop.
24
+ * @param {ASTNode} ancestor The AST node to check.
25
+ * @param {number} index The index of ancestor in ancestors.
26
+ * @returns {boolean} Whether or not the node is a loop and current context is in the loop.
27
+ */
28
+ function isInLoop(ancestor, index) {
29
+ switch (ancestor.type) {
30
+ case "ForStatement":
31
+ return ancestor.init !== ancestors[index + 1];
32
+
33
+ case "ForInStatement":
34
+ case "ForOfStatement":
35
+ return ancestor.right !== ancestors[index + 1];
36
+
37
+ case "WhileStatement":
38
+ case "DoWhileStatement":
39
+ return true;
40
+
41
+ default:
42
+ return false;
43
+ }
44
+ }
45
+
46
+ if (ancestors.some(isInLoop)) {
47
+ context.report(node, "Don't make functions within a loop");
48
+ }
49
+ }
50
+
51
+ return {
52
+ "ArrowFunctionExpression": checkForLoops,
53
+ "FunctionExpression": checkForLoops,
54
+ "FunctionDeclaration": checkForLoops
55
+ };
56
+ };
57
+
58
+ module.exports.schema = [];
@@ -1,165 +1,165 @@
1
- /**
2
- * @fileoverview Rule to enforce grouped require statements for Node.JS
3
- * @author Raphael Pigulla
4
- */
5
-
6
- "use strict";
7
-
8
- //------------------------------------------------------------------------------
9
- // Rule Definition
10
- //------------------------------------------------------------------------------
11
-
12
- module.exports = function(context) {
13
-
14
- /**
15
- * Returns the list of built-in modules.
16
- *
17
- * @returns {string[]} An array of built-in Node.js modules.
18
- */
19
- function getBuiltinModules() {
20
- // This list is generated using `require("repl")._builtinLibs.concat('repl').sort()`
21
- // This particular list is as per nodejs v0.12.2 and iojs v0.7.1
22
- return [
23
- "assert", "buffer", "child_process", "cluster", "crypto",
24
- "dgram", "dns", "domain", "events", "fs", "http", "https",
25
- "net", "os", "path", "punycode", "querystring", "readline",
26
- "repl", "smalloc", "stream", "string_decoder", "tls", "tty",
27
- "url", "util", "v8", "vm", "zlib"
28
- ];
29
- }
30
-
31
- var BUILTIN_MODULES = getBuiltinModules();
32
-
33
- var DECL_REQUIRE = "require",
34
- DECL_UNINITIALIZED = "uninitialized",
35
- DECL_OTHER = "other";
36
-
37
- var REQ_CORE = "core",
38
- REQ_FILE = "file",
39
- REQ_MODULE = "module",
40
- REQ_COMPUTED = "computed";
41
-
42
- /**
43
- * Determines the type of a declaration statement.
44
- * @param {ASTNode} initExpression The init node of the VariableDeclarator.
45
- * @returns {string} The type of declaration represented by the expression.
46
- */
47
- function getDeclarationType(initExpression) {
48
- if (!initExpression) {
49
- // "var x;"
50
- return DECL_UNINITIALIZED;
51
- }
52
-
53
- if (initExpression.type === "CallExpression" &&
54
- initExpression.callee.type === "Identifier" &&
55
- initExpression.callee.name === "require"
56
- ) {
57
- // "var x = require('util');"
58
- return DECL_REQUIRE;
59
- } else if (initExpression.type === "MemberExpression") {
60
- // "var x = require('glob').Glob;"
61
- return getDeclarationType(initExpression.object);
62
- }
63
-
64
- // "var x = 42;"
65
- return DECL_OTHER;
66
- }
67
-
68
- /**
69
- * Determines the type of module that is loaded via require.
70
- * @param {ASTNode} initExpression The init node of the VariableDeclarator.
71
- * @returns {string} The module type.
72
- */
73
- function inferModuleType(initExpression) {
74
- if (initExpression.type === "MemberExpression") {
75
- // "var x = require('glob').Glob;"
76
- return inferModuleType(initExpression.object);
77
- } else if (initExpression.arguments.length === 0) {
78
- // "var x = require();"
79
- return REQ_COMPUTED;
80
- }
81
-
82
- var arg = initExpression.arguments[0];
83
-
84
- if (arg.type !== "Literal" || typeof arg.value !== "string") {
85
- // "var x = require(42);"
86
- return REQ_COMPUTED;
87
- }
88
-
89
- if (BUILTIN_MODULES.indexOf(arg.value) !== -1) {
90
- // "var fs = require('fs');"
91
- return REQ_CORE;
92
- } else if (/^\.{0,2}\//.test(arg.value)) {
93
- // "var utils = require('./utils');"
94
- return REQ_FILE;
95
- } else {
96
- // "var async = require('async');"
97
- return REQ_MODULE;
98
- }
99
- }
100
-
101
- /**
102
- * Check if the list of variable declarations is mixed, i.e. whether it
103
- * contains both require and other declarations.
104
- * @param {ASTNode} declarations The list of VariableDeclarators.
105
- * @returns {boolean} True if the declarations are mixed, false if not.
106
- */
107
- function isMixed(declarations) {
108
- var contains = {};
109
-
110
- declarations.forEach(function (declaration) {
111
- var type = getDeclarationType(declaration.init);
112
- contains[type] = true;
113
- });
114
-
115
- return !!(
116
- contains[DECL_REQUIRE] &&
117
- (contains[DECL_UNINITIALIZED] || contains[DECL_OTHER])
118
- );
119
- }
120
-
121
- /**
122
- * Check if all require declarations in the given list are of the same
123
- * type.
124
- * @param {ASTNode} declarations The list of VariableDeclarators.
125
- * @returns {boolean} True if the declarations are grouped, false if not.
126
- */
127
- function isGrouped(declarations) {
128
- var found = {};
129
-
130
- declarations.forEach(function (declaration) {
131
- if (getDeclarationType(declaration.init) === DECL_REQUIRE) {
132
- found[inferModuleType(declaration.init)] = true;
133
- }
134
- });
135
-
136
- return Object.keys(found).length <= 1;
137
- }
138
-
139
-
140
- return {
141
-
142
- "VariableDeclaration": function(node) {
143
- var grouping = !!context.options[0];
144
-
145
- if (isMixed(node.declarations)) {
146
- context.report(
147
- node,
148
- "Do not mix 'require' and other declarations."
149
- );
150
- } else if (grouping && !isGrouped(node.declarations)) {
151
- context.report(
152
- node,
153
- "Do not mix core, module, file and computed requires."
154
- );
155
- }
156
- }
157
- };
158
-
159
- };
160
-
161
- module.exports.schema = [
162
- {
163
- "type": "boolean"
164
- }
165
- ];
1
+ /**
2
+ * @fileoverview Rule to enforce grouped require statements for Node.JS
3
+ * @author Raphael Pigulla
4
+ */
5
+
6
+ "use strict";
7
+
8
+ //------------------------------------------------------------------------------
9
+ // Rule Definition
10
+ //------------------------------------------------------------------------------
11
+
12
+ module.exports = function(context) {
13
+
14
+ /**
15
+ * Returns the list of built-in modules.
16
+ *
17
+ * @returns {string[]} An array of built-in Node.js modules.
18
+ */
19
+ function getBuiltinModules() {
20
+ // This list is generated using `require("repl")._builtinLibs.concat('repl').sort()`
21
+ // This particular list is as per nodejs v0.12.2 and iojs v0.7.1
22
+ return [
23
+ "assert", "buffer", "child_process", "cluster", "crypto",
24
+ "dgram", "dns", "domain", "events", "fs", "http", "https",
25
+ "net", "os", "path", "punycode", "querystring", "readline",
26
+ "repl", "smalloc", "stream", "string_decoder", "tls", "tty",
27
+ "url", "util", "v8", "vm", "zlib"
28
+ ];
29
+ }
30
+
31
+ var BUILTIN_MODULES = getBuiltinModules();
32
+
33
+ var DECL_REQUIRE = "require",
34
+ DECL_UNINITIALIZED = "uninitialized",
35
+ DECL_OTHER = "other";
36
+
37
+ var REQ_CORE = "core",
38
+ REQ_FILE = "file",
39
+ REQ_MODULE = "module",
40
+ REQ_COMPUTED = "computed";
41
+
42
+ /**
43
+ * Determines the type of a declaration statement.
44
+ * @param {ASTNode} initExpression The init node of the VariableDeclarator.
45
+ * @returns {string} The type of declaration represented by the expression.
46
+ */
47
+ function getDeclarationType(initExpression) {
48
+ if (!initExpression) {
49
+ // "var x;"
50
+ return DECL_UNINITIALIZED;
51
+ }
52
+
53
+ if (initExpression.type === "CallExpression" &&
54
+ initExpression.callee.type === "Identifier" &&
55
+ initExpression.callee.name === "require"
56
+ ) {
57
+ // "var x = require('util');"
58
+ return DECL_REQUIRE;
59
+ } else if (initExpression.type === "MemberExpression") {
60
+ // "var x = require('glob').Glob;"
61
+ return getDeclarationType(initExpression.object);
62
+ }
63
+
64
+ // "var x = 42;"
65
+ return DECL_OTHER;
66
+ }
67
+
68
+ /**
69
+ * Determines the type of module that is loaded via require.
70
+ * @param {ASTNode} initExpression The init node of the VariableDeclarator.
71
+ * @returns {string} The module type.
72
+ */
73
+ function inferModuleType(initExpression) {
74
+ if (initExpression.type === "MemberExpression") {
75
+ // "var x = require('glob').Glob;"
76
+ return inferModuleType(initExpression.object);
77
+ } else if (initExpression.arguments.length === 0) {
78
+ // "var x = require();"
79
+ return REQ_COMPUTED;
80
+ }
81
+
82
+ var arg = initExpression.arguments[0];
83
+
84
+ if (arg.type !== "Literal" || typeof arg.value !== "string") {
85
+ // "var x = require(42);"
86
+ return REQ_COMPUTED;
87
+ }
88
+
89
+ if (BUILTIN_MODULES.indexOf(arg.value) !== -1) {
90
+ // "var fs = require('fs');"
91
+ return REQ_CORE;
92
+ } else if (/^\.{0,2}\//.test(arg.value)) {
93
+ // "var utils = require('./utils');"
94
+ return REQ_FILE;
95
+ } else {
96
+ // "var async = require('async');"
97
+ return REQ_MODULE;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Check if the list of variable declarations is mixed, i.e. whether it
103
+ * contains both require and other declarations.
104
+ * @param {ASTNode} declarations The list of VariableDeclarators.
105
+ * @returns {boolean} True if the declarations are mixed, false if not.
106
+ */
107
+ function isMixed(declarations) {
108
+ var contains = {};
109
+
110
+ declarations.forEach(function (declaration) {
111
+ var type = getDeclarationType(declaration.init);
112
+ contains[type] = true;
113
+ });
114
+
115
+ return !!(
116
+ contains[DECL_REQUIRE] &&
117
+ (contains[DECL_UNINITIALIZED] || contains[DECL_OTHER])
118
+ );
119
+ }
120
+
121
+ /**
122
+ * Check if all require declarations in the given list are of the same
123
+ * type.
124
+ * @param {ASTNode} declarations The list of VariableDeclarators.
125
+ * @returns {boolean} True if the declarations are grouped, false if not.
126
+ */
127
+ function isGrouped(declarations) {
128
+ var found = {};
129
+
130
+ declarations.forEach(function (declaration) {
131
+ if (getDeclarationType(declaration.init) === DECL_REQUIRE) {
132
+ found[inferModuleType(declaration.init)] = true;
133
+ }
134
+ });
135
+
136
+ return Object.keys(found).length <= 1;
137
+ }
138
+
139
+
140
+ return {
141
+
142
+ "VariableDeclaration": function(node) {
143
+ var grouping = !!context.options[0];
144
+
145
+ if (isMixed(node.declarations)) {
146
+ context.report(
147
+ node,
148
+ "Do not mix 'require' and other declarations."
149
+ );
150
+ } else if (grouping && !isGrouped(node.declarations)) {
151
+ context.report(
152
+ node,
153
+ "Do not mix core, module, file and computed requires."
154
+ );
155
+ }
156
+ }
157
+ };
158
+
159
+ };
160
+
161
+ module.exports.schema = [
162
+ {
163
+ "type": "boolean"
164
+ }
165
+ ];