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.
- package/LICENSE +20 -20
- package/README.md +111 -95
- package/bin/eslint.js +41 -41
- package/conf/environments.js +87 -81
- package/conf/eslint.json +186 -179
- package/lib/api.js +13 -12
- package/lib/cli-engine.js +441 -451
- package/lib/cli.js +196 -196
- package/lib/config-initializer.js +145 -145
- package/lib/config-validator.js +110 -110
- package/lib/config.js +428 -416
- package/lib/eslint.js +1072 -1073
- package/lib/file-finder.js +167 -167
- package/lib/formatters/checkstyle.js +68 -68
- package/lib/formatters/compact.js +53 -53
- package/lib/formatters/jslint-xml.js +40 -40
- package/lib/formatters/junit.js +63 -63
- package/lib/formatters/stylish.js +90 -90
- package/lib/formatters/tap.js +86 -86
- package/lib/ignored-paths.js +137 -137
- package/lib/load-rules.js +39 -39
- package/lib/options.js +132 -126
- package/lib/rule-context.js +107 -107
- package/lib/rules/accessor-pairs.js +65 -65
- package/lib/rules/array-bracket-spacing.js +180 -0
- package/lib/rules/block-scoped-var.js +339 -320
- package/lib/rules/brace-style.js +228 -228
- package/lib/rules/camelcase.js +111 -111
- package/lib/rules/comma-dangle.js +67 -64
- package/lib/rules/comma-spacing.js +191 -191
- package/lib/rules/comma-style.js +195 -195
- package/lib/rules/complexity.js +94 -94
- package/lib/rules/computed-property-spacing.js +144 -0
- package/lib/rules/consistent-return.js +75 -75
- package/lib/rules/consistent-this.js +119 -119
- package/lib/rules/constructor-super.js +108 -0
- package/lib/rules/curly.js +109 -109
- package/lib/rules/default-case.js +66 -66
- package/lib/rules/dot-location.js +63 -63
- package/lib/rules/dot-notation.js +119 -119
- package/lib/rules/eol-last.js +38 -38
- package/lib/rules/eqeqeq.js +96 -96
- package/lib/rules/func-names.js +45 -45
- package/lib/rules/func-style.js +49 -49
- package/lib/rules/generator-star-spacing.js +104 -87
- package/lib/rules/generator-star.js +76 -76
- package/lib/rules/global-strict.js +49 -49
- package/lib/rules/guard-for-in.js +32 -32
- package/lib/rules/handle-callback-err.js +81 -124
- package/lib/rules/indent.js +486 -486
- package/lib/rules/key-spacing.js +325 -325
- package/lib/rules/linebreak-style.js +44 -44
- package/lib/rules/lines-around-comment.js +228 -160
- package/lib/rules/max-depth.js +89 -89
- package/lib/rules/max-len.js +76 -76
- package/lib/rules/max-nested-callbacks.js +73 -73
- package/lib/rules/max-params.js +45 -45
- package/lib/rules/max-statements.js +61 -61
- package/lib/rules/new-cap.js +224 -224
- package/lib/rules/new-parens.js +29 -29
- package/lib/rules/newline-after-var.js +127 -127
- package/lib/rules/no-alert.js +153 -153
- package/lib/rules/no-array-constructor.js +31 -31
- package/lib/rules/no-bitwise.js +57 -57
- package/lib/rules/no-caller.js +29 -29
- package/lib/rules/no-catch-shadow.js +52 -52
- package/lib/rules/no-comma-dangle.js +45 -45
- package/lib/rules/no-cond-assign.js +123 -123
- package/lib/rules/no-console.js +27 -27
- package/lib/rules/no-constant-condition.js +73 -73
- package/lib/rules/no-continue.js +23 -23
- package/lib/rules/no-control-regex.js +58 -58
- package/lib/rules/no-debugger.js +22 -22
- package/lib/rules/no-delete-var.js +25 -25
- package/lib/rules/no-div-regex.js +27 -27
- package/lib/rules/no-dupe-args.js +89 -85
- package/lib/rules/no-dupe-keys.js +43 -43
- package/lib/rules/no-duplicate-case.js +67 -67
- package/lib/rules/no-else-return.js +125 -125
- package/lib/rules/no-empty-character-class.js +43 -43
- package/lib/rules/no-empty-class.js +45 -45
- package/lib/rules/no-empty-label.js +27 -27
- package/lib/rules/no-empty.js +49 -49
- package/lib/rules/no-eq-null.js +29 -29
- package/lib/rules/no-eval.js +26 -26
- package/lib/rules/no-ex-assign.js +42 -42
- package/lib/rules/no-extend-native.js +103 -103
- package/lib/rules/no-extra-bind.js +81 -81
- package/lib/rules/no-extra-boolean-cast.js +71 -71
- package/lib/rules/no-extra-parens.js +368 -355
- package/lib/rules/no-extra-semi.js +70 -23
- package/lib/rules/no-extra-strict.js +86 -86
- package/lib/rules/no-fallthrough.js +97 -97
- package/lib/rules/no-floating-decimal.js +30 -30
- package/lib/rules/no-func-assign.js +83 -83
- package/lib/rules/no-implied-eval.js +76 -76
- package/lib/rules/no-inline-comments.js +49 -49
- package/lib/rules/no-inner-declarations.js +78 -78
- package/lib/rules/no-invalid-regexp.js +53 -53
- package/lib/rules/no-irregular-whitespace.js +135 -135
- package/lib/rules/no-iterator.js +28 -28
- package/lib/rules/no-label-var.js +64 -64
- package/lib/rules/no-labels.js +44 -44
- package/lib/rules/no-lone-blocks.js +106 -27
- package/lib/rules/no-lonely-if.js +30 -30
- package/lib/rules/no-loop-func.js +58 -58
- package/lib/rules/no-mixed-requires.js +165 -165
- package/lib/rules/no-mixed-spaces-and-tabs.js +74 -74
- package/lib/rules/no-multi-spaces.js +119 -119
- package/lib/rules/no-multi-str.js +43 -43
- package/lib/rules/no-multiple-empty-lines.js +98 -98
- package/lib/rules/no-native-reassign.js +62 -62
- package/lib/rules/no-negated-in-lhs.js +25 -25
- package/lib/rules/no-nested-ternary.js +24 -24
- package/lib/rules/no-new-func.js +25 -25
- package/lib/rules/no-new-object.js +25 -25
- package/lib/rules/no-new-require.js +25 -25
- package/lib/rules/no-new-wrappers.js +26 -26
- package/lib/rules/no-new.js +27 -27
- package/lib/rules/no-obj-calls.js +28 -28
- package/lib/rules/no-octal-escape.js +39 -39
- package/lib/rules/no-octal.js +25 -25
- package/lib/rules/no-param-reassign.js +87 -87
- package/lib/rules/no-path-concat.js +39 -39
- package/lib/rules/no-plusplus.js +24 -24
- package/lib/rules/no-process-env.js +30 -30
- package/lib/rules/no-process-exit.js +33 -33
- package/lib/rules/no-proto.js +28 -28
- package/lib/rules/no-redeclare.js +68 -68
- package/lib/rules/no-regex-spaces.js +35 -35
- package/lib/rules/no-reserved-keys.js +56 -56
- package/lib/rules/no-restricted-modules.js +85 -85
- package/lib/rules/no-return-assign.js +53 -24
- package/lib/rules/no-script-url.js +34 -34
- package/lib/rules/no-self-compare.js +29 -29
- package/lib/rules/no-sequences.js +94 -94
- package/lib/rules/no-shadow-restricted-names.js +51 -51
- package/lib/rules/no-shadow.js +181 -136
- package/lib/rules/no-space-before-semi.js +98 -98
- package/lib/rules/no-spaced-func.js +37 -37
- package/lib/rules/no-sparse-arrays.js +33 -33
- package/lib/rules/no-sync.js +30 -30
- package/lib/rules/no-ternary.js +24 -24
- package/lib/rules/no-this-before-super.js +144 -0
- package/lib/rules/no-throw-literal.js +33 -33
- package/lib/rules/no-trailing-spaces.js +74 -63
- package/lib/rules/no-undef-init.js +28 -28
- package/lib/rules/no-undef.js +92 -92
- package/lib/rules/no-undefined.js +27 -27
- package/lib/rules/no-underscore-dangle.js +73 -73
- package/lib/rules/no-unexpected-multiline.js +58 -0
- package/lib/rules/no-unneeded-ternary.js +48 -48
- package/lib/rules/no-unreachable.js +98 -98
- package/lib/rules/no-unused-expressions.js +76 -76
- package/lib/rules/no-unused-vars.js +252 -250
- package/lib/rules/no-use-before-define.js +105 -105
- package/lib/rules/no-var.js +26 -26
- package/lib/rules/no-void.js +28 -28
- package/lib/rules/no-warning-comments.js +102 -102
- package/lib/rules/no-with.js +22 -22
- package/lib/rules/no-wrap-func.js +65 -65
- package/lib/rules/object-curly-spacing.js +231 -206
- package/lib/rules/object-shorthand.js +74 -73
- package/lib/rules/one-var.js +311 -304
- package/lib/rules/operator-assignment.js +118 -118
- package/lib/rules/operator-linebreak.js +114 -114
- package/lib/rules/padded-blocks.js +98 -98
- package/lib/rules/prefer-const.js +91 -0
- package/lib/rules/quote-props.js +72 -72
- package/lib/rules/quotes.js +92 -92
- package/lib/rules/radix.js +41 -41
- package/lib/rules/semi-spacing.js +167 -167
- package/lib/rules/semi.js +136 -136
- package/lib/rules/sort-vars.js +49 -49
- package/lib/rules/space-after-function-name.js +49 -49
- package/lib/rules/space-after-keywords.js +82 -82
- package/lib/rules/space-before-blocks.js +91 -91
- package/lib/rules/space-before-function-paren.js +139 -139
- package/lib/rules/space-before-function-parentheses.js +139 -139
- package/lib/rules/space-in-brackets.js +305 -305
- package/lib/rules/space-in-parens.js +281 -281
- package/lib/rules/space-infix-ops.js +106 -106
- package/lib/rules/space-return-throw-case.js +38 -38
- package/lib/rules/space-unary-ops.js +124 -133
- package/lib/rules/spaced-comment.js +143 -0
- package/lib/rules/spaced-line-comment.js +89 -89
- package/lib/rules/strict.js +242 -242
- package/lib/rules/use-isnan.js +26 -26
- package/lib/rules/valid-jsdoc.js +215 -215
- package/lib/rules/valid-typeof.js +42 -42
- package/lib/rules/vars-on-top.js +115 -115
- package/lib/rules/wrap-iife.js +48 -48
- package/lib/rules/wrap-regex.js +38 -38
- package/lib/rules/yoda.js +242 -225
- package/lib/rules.js +88 -88
- package/lib/timing.js +109 -109
- package/lib/token-store.js +201 -201
- package/lib/util/traverse.js +105 -105
- package/lib/util.js +125 -85
- package/package.json +6 -6
- 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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
//------------------------------------------------------------------------------
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
+
];
|