eslint 1.7.1 → 1.9.0
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/README.md +1 -0
- package/conf/eslint.json +3 -0
- package/lib/cli-engine.js +74 -74
- package/lib/cli.js +12 -10
- package/lib/eslint.js +15 -26
- package/lib/logging.js +25 -0
- package/lib/options.js +7 -2
- package/lib/rules/array-bracket-spacing.js +2 -2
- package/lib/rules/arrow-body-style.js +71 -0
- package/lib/rules/comma-dangle.js +26 -10
- package/lib/rules/comma-spacing.js +72 -36
- package/lib/rules/eol-last.js +10 -4
- package/lib/rules/indent.js +8 -7
- package/lib/rules/key-spacing.js +13 -25
- package/lib/rules/linebreak-style.js +45 -10
- package/lib/rules/max-nested-callbacks.js +1 -1
- package/lib/rules/no-arrow-condition.js +88 -0
- package/lib/rules/no-case-declarations.js +47 -0
- package/lib/rules/no-extend-native.js +3 -3
- package/lib/rules/no-magic-numbers.js +22 -5
- package/lib/rules/no-mixed-spaces-and-tabs.js +23 -19
- package/lib/rules/no-multiple-empty-lines.js +39 -13
- package/lib/rules/no-plusplus.js +22 -1
- package/lib/rules/no-shadow.js +22 -4
- package/lib/rules/no-use-before-define.js +1 -1
- package/lib/rules/no-warning-comments.js +1 -1
- package/lib/rules/radix.js +36 -6
- package/lib/rules/space-in-parens.js +148 -199
- package/lib/rules/spaced-comment.js +3 -3
- package/lib/rules/valid-jsdoc.js +36 -19
- package/lib/rules.js +13 -9
- package/lib/testers/rule-tester.js +62 -7
- package/lib/util/estraverse.js +54 -0
- package/lib/util/glob-util.js +149 -0
- package/lib/util/source-code-fixer.js +1 -1
- package/lib/util/source-code.js +11 -1
- package/lib/util.js +15 -9
- package/package.json +21 -21
@@ -13,13 +13,15 @@
|
|
13
13
|
module.exports = function(context) {
|
14
14
|
|
15
15
|
// Use options.max or 2 as default
|
16
|
-
var
|
16
|
+
var max = 2,
|
17
|
+
maxEOF;
|
17
18
|
|
18
19
|
// store lines that appear empty but really aren't
|
19
20
|
var notEmpty = [];
|
20
21
|
|
21
22
|
if (context.options.length) {
|
22
|
-
|
23
|
+
max = context.options[0].max;
|
24
|
+
maxEOF = context.options[0].maxEOF;
|
23
25
|
}
|
24
26
|
|
25
27
|
//--------------------------------------------------------------------------
|
@@ -45,17 +47,28 @@ module.exports = function(context) {
|
|
45
47
|
location,
|
46
48
|
trimmedLines = lines.map(function(str) {
|
47
49
|
return str.trim();
|
48
|
-
})
|
50
|
+
}),
|
51
|
+
firstOfEndingBlankLines;
|
49
52
|
|
50
53
|
// add the notEmpty lines in there with a placeholder
|
51
54
|
notEmpty.forEach(function(x, i) {
|
52
55
|
trimmedLines[i] = x;
|
53
56
|
});
|
54
57
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
58
|
+
if (typeof maxEOF === "undefined") {
|
59
|
+
// swallow the final newline, as some editors add it
|
60
|
+
// automatically and we don't want it to cause an issue
|
61
|
+
if (trimmedLines[trimmedLines.length - 1] === "") {
|
62
|
+
trimmedLines = trimmedLines.slice(0, -1);
|
63
|
+
}
|
64
|
+
firstOfEndingBlankLines = trimmedLines.length;
|
65
|
+
} else {
|
66
|
+
// save the number of the first of the last blank lines
|
67
|
+
firstOfEndingBlankLines = trimmedLines.length;
|
68
|
+
while (trimmedLines[firstOfEndingBlankLines - 1] === ""
|
69
|
+
&& firstOfEndingBlankLines > 0) {
|
70
|
+
firstOfEndingBlankLines--;
|
71
|
+
}
|
59
72
|
}
|
60
73
|
|
61
74
|
// Aggregate and count blank lines
|
@@ -67,12 +80,22 @@ module.exports = function(context) {
|
|
67
80
|
if (lastLocation === currentLocation - 1) {
|
68
81
|
blankCounter++;
|
69
82
|
} else {
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
83
|
+
location = {
|
84
|
+
line: lastLocation + 1,
|
85
|
+
column: 1
|
86
|
+
};
|
87
|
+
if (lastLocation < firstOfEndingBlankLines) {
|
88
|
+
// within the file, not at the end
|
89
|
+
if (blankCounter >= max) {
|
90
|
+
context.report(node, location,
|
91
|
+
"More than " + max + " blank lines not allowed.");
|
92
|
+
}
|
93
|
+
} else {
|
94
|
+
// inside the last blank lines
|
95
|
+
if (blankCounter >= maxEOF) {
|
96
|
+
context.report(node, location,
|
97
|
+
"Too many blank lines at the end of file. Max of " + maxEOF + " allowed.");
|
98
|
+
}
|
76
99
|
}
|
77
100
|
|
78
101
|
// Finally, reset the blank counter
|
@@ -90,6 +113,9 @@ module.exports.schema = [
|
|
90
113
|
"properties": {
|
91
114
|
"max": {
|
92
115
|
"type": "integer"
|
116
|
+
},
|
117
|
+
"maxEOF": {
|
118
|
+
"type": "integer"
|
93
119
|
}
|
94
120
|
},
|
95
121
|
"required": ["max"],
|
package/lib/rules/no-plusplus.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview Rule to flag use of unary increment and decrement operators.
|
3
3
|
* @author Ian Christian Myers
|
4
|
+
* @author Brody McKee (github.com/mrmckeb)
|
4
5
|
*/
|
5
6
|
|
6
7
|
"use strict";
|
@@ -11,9 +12,19 @@
|
|
11
12
|
|
12
13
|
module.exports = function(context) {
|
13
14
|
|
15
|
+
var config = context.options[0],
|
16
|
+
allowInForAfterthought = false;
|
17
|
+
|
18
|
+
if (typeof config === "object") {
|
19
|
+
allowInForAfterthought = config.allowForLoopAfterthoughts === true;
|
20
|
+
}
|
21
|
+
|
14
22
|
return {
|
15
23
|
|
16
24
|
"UpdateExpression": function(node) {
|
25
|
+
if (allowInForAfterthought && node.parent.type === "ForStatement") {
|
26
|
+
return;
|
27
|
+
}
|
17
28
|
context.report(node, "Unary operator '" + node.operator + "' used.");
|
18
29
|
}
|
19
30
|
|
@@ -21,4 +32,14 @@ module.exports = function(context) {
|
|
21
32
|
|
22
33
|
};
|
23
34
|
|
24
|
-
module.exports.schema = [
|
35
|
+
module.exports.schema = [
|
36
|
+
{
|
37
|
+
"type": "object",
|
38
|
+
"properties": {
|
39
|
+
"allowForLoopAfterthoughts": {
|
40
|
+
"type": "boolean"
|
41
|
+
}
|
42
|
+
},
|
43
|
+
"additionalProperties": false
|
44
|
+
}
|
45
|
+
];
|
package/lib/rules/no-shadow.js
CHANGED
@@ -14,9 +14,20 @@ module.exports = function(context) {
|
|
14
14
|
|
15
15
|
var options = {
|
16
16
|
builtinGlobals: Boolean(context.options[0] && context.options[0].builtinGlobals),
|
17
|
-
hoist: (context.options[0] && context.options[0].hoist) || "functions"
|
17
|
+
hoist: (context.options[0] && context.options[0].hoist) || "functions",
|
18
|
+
allow: (context.options[0] && context.options[0].allow) || []
|
18
19
|
};
|
19
20
|
|
21
|
+
/**
|
22
|
+
* Check if variable name is allowed.
|
23
|
+
*
|
24
|
+
* @param {ASTNode} variable The variable to check.
|
25
|
+
* @returns {boolean} Whether or not the variable name is allowed.
|
26
|
+
*/
|
27
|
+
function isAllowed(variable) {
|
28
|
+
return options.allow.indexOf(variable.name) !== -1;
|
29
|
+
}
|
30
|
+
|
20
31
|
/**
|
21
32
|
* Checks if a variable of the class name in the class scope of ClassDeclaration.
|
22
33
|
*
|
@@ -121,7 +132,7 @@ module.exports = function(context) {
|
|
121
132
|
if (variable.identifiers.length > 0 && isContainedInScopeVars(variable, scope.variables)) {
|
122
133
|
context.report(
|
123
134
|
variable.identifiers[0],
|
124
|
-
"{{name}} is already declared in the upper scope.",
|
135
|
+
"\"{{name}}\" is already declared in the upper scope.",
|
125
136
|
{name: variable.name});
|
126
137
|
} else {
|
127
138
|
passedVars.push(variable);
|
@@ -142,7 +153,8 @@ module.exports = function(context) {
|
|
142
153
|
// Skip "arguments".
|
143
154
|
variable.identifiers.length > 0 &&
|
144
155
|
// Skip variables of a class name in the class scope of ClassDeclaration.
|
145
|
-
!isDuplicatedClassNameVariable(variable)
|
156
|
+
!isDuplicatedClassNameVariable(variable) &&
|
157
|
+
!isAllowed(variable)
|
146
158
|
);
|
147
159
|
});
|
148
160
|
|
@@ -175,7 +187,13 @@ module.exports.schema = [
|
|
175
187
|
"type": "object",
|
176
188
|
"properties": {
|
177
189
|
"builtinGlobals": {"type": "boolean"},
|
178
|
-
"hoist": {"enum": ["all", "functions", "never"]}
|
190
|
+
"hoist": {"enum": ["all", "functions", "never"]},
|
191
|
+
"allow": {
|
192
|
+
"type": "array",
|
193
|
+
"items": {
|
194
|
+
"type": "string"
|
195
|
+
}
|
196
|
+
}
|
179
197
|
},
|
180
198
|
"additionalProperties": false
|
181
199
|
}
|
@@ -57,7 +57,7 @@ module.exports = function(context) {
|
|
57
57
|
function checkLocationAndReport(reference, declaration) {
|
58
58
|
if (typeOption !== NO_FUNC || declaration.defs[0].type !== "FunctionName") {
|
59
59
|
if (declaration.identifiers[0].range[1] > reference.identifier.range[1]) {
|
60
|
-
context.report(reference.identifier, "{{a}} was used before it was defined", {a: reference.identifier.name});
|
60
|
+
context.report(reference.identifier, "\"{{a}}\" was used before it was defined", {a: reference.identifier.name});
|
61
61
|
}
|
62
62
|
}
|
63
63
|
}
|
@@ -79,7 +79,7 @@ module.exports = function(context) {
|
|
79
79
|
var matches = commentContainsWarningTerm(node.value);
|
80
80
|
|
81
81
|
matches.forEach(function(matchedTerm) {
|
82
|
-
context.report(node, "Unexpected " + matchedTerm + " comment.");
|
82
|
+
context.report(node, "Unexpected \"" + matchedTerm + "\" comment.");
|
83
83
|
});
|
84
84
|
}
|
85
85
|
|
package/lib/rules/radix.js
CHANGED
@@ -11,6 +11,11 @@
|
|
11
11
|
|
12
12
|
module.exports = function(context) {
|
13
13
|
|
14
|
+
var MODE_ALWAYS = "always",
|
15
|
+
MODE_AS_NEEDED = "as-needed";
|
16
|
+
|
17
|
+
var mode = context.options[0] || MODE_ALWAYS;
|
18
|
+
|
14
19
|
return {
|
15
20
|
"CallExpression": function(node) {
|
16
21
|
|
@@ -25,17 +30,37 @@ module.exports = function(context) {
|
|
25
30
|
return;
|
26
31
|
}
|
27
32
|
|
28
|
-
if (node.arguments.length
|
29
|
-
context.report(
|
33
|
+
if (node.arguments.length === 0) {
|
34
|
+
context.report({
|
35
|
+
node: node,
|
36
|
+
message: "Missing parameters."
|
37
|
+
});
|
38
|
+
} else if (node.arguments.length < 2 && mode === MODE_ALWAYS) {
|
39
|
+
context.report({
|
40
|
+
node: node,
|
41
|
+
message: "Missing radix parameter."
|
42
|
+
});
|
43
|
+
} else if (node.arguments.length > 1 && mode === MODE_AS_NEEDED &&
|
44
|
+
(node.arguments[1] && node.arguments[1].type === "Literal" &&
|
45
|
+
node.arguments[1].value === 10)
|
46
|
+
) {
|
47
|
+
context.report({
|
48
|
+
node: node,
|
49
|
+
message: "Redundant radix parameter."
|
50
|
+
});
|
30
51
|
} else {
|
31
52
|
|
32
53
|
radix = node.arguments[1];
|
33
54
|
|
34
55
|
// don't allow non-numeric literals or undefined
|
35
|
-
if (
|
36
|
-
(radix.type === "
|
56
|
+
if (radix &&
|
57
|
+
((radix.type === "Literal" && typeof radix.value !== "number") ||
|
58
|
+
(radix.type === "Identifier" && radix.name === "undefined"))
|
37
59
|
) {
|
38
|
-
context.report(
|
60
|
+
context.report({
|
61
|
+
node: node,
|
62
|
+
message: "Invalid radix parameter."
|
63
|
+
});
|
39
64
|
}
|
40
65
|
}
|
41
66
|
|
@@ -44,4 +69,9 @@ module.exports = function(context) {
|
|
44
69
|
|
45
70
|
};
|
46
71
|
|
47
|
-
module.exports.schema = [
|
72
|
+
module.exports.schema = [
|
73
|
+
{
|
74
|
+
"enum": ["always", "as-needed"]
|
75
|
+
}
|
76
|
+
];
|
77
|
+
|