eslint 1.4.1 → 1.5.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/README.md +1 -1
- package/bin/eslint.js +32 -3
- package/lib/ast-utils.js +17 -11
- package/lib/cli-engine.js +72 -11
- package/lib/config.js +54 -55
- package/lib/eslint.js +7 -56
- package/lib/options.js +7 -0
- package/lib/rules/array-bracket-spacing.js +6 -5
- package/lib/rules/block-spacing.js +4 -3
- package/lib/rules/comma-dangle.js +25 -10
- package/lib/rules/comma-spacing.js +4 -29
- package/lib/rules/computed-property-spacing.js +5 -4
- package/lib/rules/eol-last.js +8 -1
- package/lib/rules/func-style.js +29 -9
- package/lib/rules/id-length.js +3 -3
- package/lib/rules/indent.js +100 -47
- package/lib/rules/jsx-quotes.js +1 -1
- package/lib/rules/key-spacing.js +7 -1
- package/lib/rules/no-dupe-args.js +30 -46
- package/lib/rules/no-extra-semi.js +7 -1
- package/lib/rules/no-inline-comments.js +3 -1
- package/lib/rules/no-spaced-func.js +18 -5
- package/lib/rules/no-trailing-spaces.js +34 -6
- package/lib/rules/no-unused-vars.js +4 -4
- package/lib/rules/no-warning-comments.js +7 -0
- package/lib/rules/object-curly-spacing.js +7 -9
- package/lib/rules/semi-spacing.js +29 -4
- package/lib/rules/space-after-keywords.js +27 -5
- package/lib/rules/space-before-blocks.js +64 -7
- package/lib/rules/space-before-function-paren.js +19 -13
- package/lib/rules/space-before-keywords.js +45 -17
- package/lib/rules/space-infix-ops.js +22 -1
- package/lib/rules/space-return-throw-case.js +7 -1
- package/lib/testers/event-generator-tester.js +63 -0
- package/lib/util/comment-event-generator.js +116 -0
- package/lib/util/node-event-generator.js +55 -0
- package/lib/util/source-code.js +14 -7
- package/package.json +2 -2
@@ -111,10 +111,10 @@ module.exports = function(context) {
|
|
111
111
|
*/
|
112
112
|
function isUsedVariable(variable, references) {
|
113
113
|
var functionNodes = variable.defs.filter(function(def) {
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
114
|
+
return def.type === "FunctionName";
|
115
|
+
}).map(function(def) {
|
116
|
+
return def.node;
|
117
|
+
}),
|
118
118
|
isFunctionDefinition = functionNodes.length > 0;
|
119
119
|
|
120
120
|
return references.some(function(ref) {
|
@@ -5,6 +5,8 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
var astUtils = require("../ast-utils");
|
9
|
+
|
8
10
|
//------------------------------------------------------------------------------
|
9
11
|
// Rule Definition
|
10
12
|
//------------------------------------------------------------------------------
|
@@ -14,6 +16,7 @@ module.exports = function(context) {
|
|
14
16
|
var configuration = context.options[0] || {},
|
15
17
|
warningTerms = configuration.terms || ["todo", "fixme", "xxx"],
|
16
18
|
location = configuration.location || "start",
|
19
|
+
selfConfigRegEx = /\bno-warning-comments\b/,
|
17
20
|
warningRegExps;
|
18
21
|
|
19
22
|
/**
|
@@ -69,6 +72,10 @@ module.exports = function(context) {
|
|
69
72
|
* @returns {void} undefined.
|
70
73
|
*/
|
71
74
|
function checkComment(node) {
|
75
|
+
if (astUtils.isDirectiveComment(node) && selfConfigRegEx.test(node.value)) {
|
76
|
+
return;
|
77
|
+
}
|
78
|
+
|
72
79
|
var matches = commentContainsWarningTerm(node.value);
|
73
80
|
|
74
81
|
matches.forEach(function(matchedTerm) {
|
@@ -17,7 +17,8 @@ var astUtils = require("../ast-utils");
|
|
17
17
|
//------------------------------------------------------------------------------
|
18
18
|
|
19
19
|
module.exports = function(context) {
|
20
|
-
var spaced = context.options[0] === "always"
|
20
|
+
var spaced = context.options[0] === "always",
|
21
|
+
sourceCode = context.getSourceCode();
|
21
22
|
|
22
23
|
/**
|
23
24
|
* Determines whether an option is set, relative to the spacing option.
|
@@ -101,7 +102,7 @@ module.exports = function(context) {
|
|
101
102
|
firstSpaced, lastSpaced;
|
102
103
|
|
103
104
|
if (astUtils.isTokenOnSameLine(first, second)) {
|
104
|
-
firstSpaced =
|
105
|
+
firstSpaced = sourceCode.isSpaceBetweenTokens(first, second);
|
105
106
|
if (options.spaced && !firstSpaced) {
|
106
107
|
reportRequiredBeginningSpace(node, first);
|
107
108
|
}
|
@@ -111,7 +112,7 @@ module.exports = function(context) {
|
|
111
112
|
}
|
112
113
|
|
113
114
|
if (astUtils.isTokenOnSameLine(penultimate, last)) {
|
114
|
-
lastSpaced =
|
115
|
+
lastSpaced = sourceCode.isSpaceBetweenTokens(penultimate, last);
|
115
116
|
if (closingCurlyBraceMustBeSpaced && !lastSpaced) {
|
116
117
|
reportRequiredEndingSpace(node, last);
|
117
118
|
}
|
@@ -131,8 +132,7 @@ module.exports = function(context) {
|
|
131
132
|
return;
|
132
133
|
}
|
133
134
|
|
134
|
-
var
|
135
|
-
first = sourceCode.getFirstToken(node),
|
135
|
+
var first = sourceCode.getFirstToken(node),
|
136
136
|
last = sourceCode.getLastToken(node),
|
137
137
|
second = sourceCode.getTokenAfter(first),
|
138
138
|
penultimate = sourceCode.getTokenBefore(last);
|
@@ -150,8 +150,7 @@ module.exports = function(context) {
|
|
150
150
|
return;
|
151
151
|
}
|
152
152
|
|
153
|
-
var
|
154
|
-
firstSpecifier = node.specifiers[0],
|
153
|
+
var firstSpecifier = node.specifiers[0],
|
155
154
|
lastSpecifier = node.specifiers[node.specifiers.length - 1];
|
156
155
|
|
157
156
|
if (lastSpecifier.type !== "ImportSpecifier") {
|
@@ -185,8 +184,7 @@ module.exports = function(context) {
|
|
185
184
|
return;
|
186
185
|
}
|
187
186
|
|
188
|
-
var
|
189
|
-
firstSpecifier = node.specifiers[0],
|
187
|
+
var firstSpecifier = node.specifiers[0],
|
190
188
|
lastSpecifier = node.specifiers[node.specifiers.length - 1],
|
191
189
|
first = sourceCode.getTokenBefore(firstSpecifier),
|
192
190
|
last = sourceCode.getTokenAfter(lastSpecifier);
|
@@ -16,7 +16,8 @@ module.exports = function(context) {
|
|
16
16
|
|
17
17
|
var config = context.options[0],
|
18
18
|
requireSpaceBefore = false,
|
19
|
-
requireSpaceAfter = true
|
19
|
+
requireSpaceAfter = true,
|
20
|
+
sourceCode = context.getSourceCode();
|
20
21
|
|
21
22
|
if (typeof config === "object") {
|
22
23
|
if (config.hasOwnProperty("before")) {
|
@@ -34,7 +35,7 @@ module.exports = function(context) {
|
|
34
35
|
*/
|
35
36
|
function hasLeadingSpace(token) {
|
36
37
|
var tokenBefore = context.getTokenBefore(token);
|
37
|
-
return tokenBefore && astUtils.isTokenOnSameLine(tokenBefore, token) &&
|
38
|
+
return tokenBefore && astUtils.isTokenOnSameLine(tokenBefore, token) && sourceCode.isSpaceBetweenTokens(tokenBefore, token);
|
38
39
|
}
|
39
40
|
|
40
41
|
/**
|
@@ -44,7 +45,7 @@ module.exports = function(context) {
|
|
44
45
|
*/
|
45
46
|
function hasTrailingSpace(token) {
|
46
47
|
var tokenAfter = context.getTokenAfter(token);
|
47
|
-
return tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter) &&
|
48
|
+
return tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter) && sourceCode.isSpaceBetweenTokens(token, tokenAfter);
|
48
49
|
}
|
49
50
|
|
50
51
|
/**
|
@@ -57,6 +58,30 @@ module.exports = function(context) {
|
|
57
58
|
return !(tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter));
|
58
59
|
}
|
59
60
|
|
61
|
+
/**
|
62
|
+
* Checks if the given token is the first token in its line
|
63
|
+
* @param {Token} token The token to check.
|
64
|
+
* @returns {boolean} Whether or not the token is the first in its line.
|
65
|
+
*/
|
66
|
+
function isFirstTokenInCurrentLine(token) {
|
67
|
+
var tokenBefore = context.getTokenBefore(token);
|
68
|
+
return !(tokenBefore && astUtils.isTokenOnSameLine(token, tokenBefore));
|
69
|
+
}
|
70
|
+
|
71
|
+
/**
|
72
|
+
* Checks if the next token of a given token is a closing parenthesis.
|
73
|
+
* @param {Token} token The token to check.
|
74
|
+
* @returns {boolean} Whether or not the next token of a given token is a closing parenthesis.
|
75
|
+
*/
|
76
|
+
function isBeforeClosingParen(token) {
|
77
|
+
var nextToken = context.getTokenAfter(token);
|
78
|
+
return (
|
79
|
+
nextToken &&
|
80
|
+
nextToken.type === "Punctuator" &&
|
81
|
+
(nextToken.value === "}" || nextToken.value === ")")
|
82
|
+
);
|
83
|
+
}
|
84
|
+
|
60
85
|
/**
|
61
86
|
* Checks if the given token is a semicolon.
|
62
87
|
* @param {Token} token The token to check.
|
@@ -88,7 +113,7 @@ module.exports = function(context) {
|
|
88
113
|
}
|
89
114
|
}
|
90
115
|
|
91
|
-
if (!isLastTokenInCurrentLine(token)) {
|
116
|
+
if (!isFirstTokenInCurrentLine(token) && !isLastTokenInCurrentLine(token) && !isBeforeClosingParen(token)) {
|
92
117
|
if (hasTrailingSpace(token)) {
|
93
118
|
if (!requireSpaceAfter) {
|
94
119
|
context.report(node, location, "Unexpected whitespace after semicolon.");
|
@@ -31,13 +31,35 @@ module.exports = function(context) {
|
|
31
31
|
value = left.value;
|
32
32
|
|
33
33
|
if (hasSpace !== requiresSpace) {
|
34
|
-
context.report(
|
35
|
-
|
36
|
-
|
34
|
+
context.report({
|
35
|
+
node: node,
|
36
|
+
message: "Keyword \"{{value}}\" must {{not}}be followed by whitespace.",
|
37
|
+
data: {
|
38
|
+
value: value,
|
39
|
+
not: requiresSpace ? "" : "not "
|
40
|
+
},
|
41
|
+
fix: function(fixer) {
|
42
|
+
if (requiresSpace) {
|
43
|
+
return fixer.insertTextAfter(left, " ");
|
44
|
+
} else {
|
45
|
+
return fixer.removeRange([left.range[1], right.range[0]]);
|
46
|
+
}
|
47
|
+
}
|
37
48
|
});
|
38
49
|
} else if (left.loc.end.line !== right.loc.start.line) {
|
39
|
-
context.report(
|
40
|
-
|
50
|
+
context.report({
|
51
|
+
node: node,
|
52
|
+
message: "Keyword \"{{value}}\" must not be followed by a newline.",
|
53
|
+
data: {
|
54
|
+
value: value
|
55
|
+
},
|
56
|
+
fix: function(fixer) {
|
57
|
+
var text = "";
|
58
|
+
if (requiresSpace) {
|
59
|
+
text = " ";
|
60
|
+
}
|
61
|
+
return fixer.replaceTextRange([left.range[1], right.range[0]], text);
|
62
|
+
}
|
41
63
|
});
|
42
64
|
}
|
43
65
|
}
|
@@ -13,7 +13,28 @@ var astUtils = require("../ast-utils");
|
|
13
13
|
//------------------------------------------------------------------------------
|
14
14
|
|
15
15
|
module.exports = function(context) {
|
16
|
-
var
|
16
|
+
var config = context.options[0],
|
17
|
+
sourceCode = context.getSourceCode(),
|
18
|
+
checkFunctions = true,
|
19
|
+
checkKeywords = true;
|
20
|
+
|
21
|
+
if (typeof config === "object") {
|
22
|
+
checkFunctions = config.functions !== "never";
|
23
|
+
checkKeywords = config.keywords !== "never";
|
24
|
+
} else if (config === "never") {
|
25
|
+
checkFunctions = false;
|
26
|
+
checkKeywords = false;
|
27
|
+
}
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Checks whether or not a given token is an arrow operator (=>).
|
31
|
+
*
|
32
|
+
* @param {Token} token - A token to check.
|
33
|
+
* @returns {boolean} `true` if the token is an arrow operator.
|
34
|
+
*/
|
35
|
+
function isArrow(token) {
|
36
|
+
return token.type === "Punctuator" && token.value === "=>";
|
37
|
+
}
|
17
38
|
|
18
39
|
/**
|
19
40
|
* Checks the given BlockStatement node has a preceding space if it doesn’t start on a new line.
|
@@ -22,18 +43,38 @@ module.exports = function(context) {
|
|
22
43
|
*/
|
23
44
|
function checkPrecedingSpace(node) {
|
24
45
|
var precedingToken = context.getTokenBefore(node),
|
25
|
-
hasSpace
|
46
|
+
hasSpace,
|
47
|
+
parent,
|
48
|
+
requireSpace;
|
26
49
|
|
27
|
-
if (precedingToken && astUtils.isTokenOnSameLine(precedingToken, node)) {
|
28
|
-
hasSpace =
|
50
|
+
if (precedingToken && !isArrow(precedingToken) && astUtils.isTokenOnSameLine(precedingToken, node)) {
|
51
|
+
hasSpace = sourceCode.isSpaceBetweenTokens(precedingToken, node);
|
52
|
+
parent = context.getAncestors().pop();
|
53
|
+
if (parent.type === "FunctionExpression" || parent.type === "FunctionDeclaration") {
|
54
|
+
requireSpace = checkFunctions;
|
55
|
+
} else {
|
56
|
+
requireSpace = checkKeywords;
|
57
|
+
}
|
29
58
|
|
30
59
|
if (requireSpace) {
|
31
60
|
if (!hasSpace) {
|
32
|
-
context.report(
|
61
|
+
context.report({
|
62
|
+
node: node,
|
63
|
+
message: "Missing space before opening brace.",
|
64
|
+
fix: function(fixer) {
|
65
|
+
return fixer.insertTextBefore(node, " ");
|
66
|
+
}
|
67
|
+
});
|
33
68
|
}
|
34
69
|
} else {
|
35
70
|
if (hasSpace) {
|
36
|
-
context.report(
|
71
|
+
context.report({
|
72
|
+
node: node,
|
73
|
+
message: "Unexpected space before opening brace.",
|
74
|
+
fix: function(fixer) {
|
75
|
+
return fixer.removeRange([precedingToken.range[1], node.range[0]]);
|
76
|
+
}
|
77
|
+
});
|
37
78
|
}
|
38
79
|
}
|
39
80
|
}
|
@@ -69,6 +110,22 @@ module.exports = function(context) {
|
|
69
110
|
|
70
111
|
module.exports.schema = [
|
71
112
|
{
|
72
|
-
"
|
113
|
+
"oneOf": [
|
114
|
+
{
|
115
|
+
"enum": ["always", "never"]
|
116
|
+
},
|
117
|
+
{
|
118
|
+
"type": "object",
|
119
|
+
"properties": {
|
120
|
+
"keywords": {
|
121
|
+
"enum": ["always", "never"]
|
122
|
+
},
|
123
|
+
"functions": {
|
124
|
+
"enum": ["always", "never"]
|
125
|
+
}
|
126
|
+
},
|
127
|
+
"additionalProperties": false
|
128
|
+
}
|
129
|
+
]
|
73
130
|
}
|
74
131
|
];
|
@@ -2,6 +2,7 @@
|
|
2
2
|
* @fileoverview Rule to validate spacing before function paren.
|
3
3
|
* @author Mathias Schreck <https://github.com/lo1tuma>
|
4
4
|
* @copyright 2015 Mathias Schreck
|
5
|
+
* See LICENSE in root directory for full license.
|
5
6
|
*/
|
6
7
|
"use strict";
|
7
8
|
|
@@ -12,6 +13,7 @@
|
|
12
13
|
module.exports = function(context) {
|
13
14
|
|
14
15
|
var configuration = context.options[0],
|
16
|
+
sourceCode = context.getSourceCode(),
|
15
17
|
requireAnonymousFunctionSpacing = true,
|
16
18
|
requireNamedFunctionSpacing = true;
|
17
19
|
|
@@ -23,16 +25,6 @@ module.exports = function(context) {
|
|
23
25
|
requireNamedFunctionSpacing = false;
|
24
26
|
}
|
25
27
|
|
26
|
-
/**
|
27
|
-
* Determines whether two adjacent tokens are have whitespace between them.
|
28
|
-
* @param {Object} left - The left token object.
|
29
|
-
* @param {Object} right - The right token object.
|
30
|
-
* @returns {boolean} Whether or not there is space between the tokens.
|
31
|
-
*/
|
32
|
-
function isSpaced(left, right) {
|
33
|
-
return left.range[1] < right.range[0];
|
34
|
-
}
|
35
|
-
|
36
28
|
/**
|
37
29
|
* Determines whether a function has a name.
|
38
30
|
* @param {ASTNode} node The function node.
|
@@ -99,13 +91,27 @@ module.exports = function(context) {
|
|
99
91
|
|
100
92
|
location = leftToken.loc.end;
|
101
93
|
|
102
|
-
if (
|
94
|
+
if (sourceCode.isSpaceBetweenTokens(leftToken, rightToken)) {
|
103
95
|
if ((isNamed && !requireNamedFunctionSpacing) || (!isNamed && !requireAnonymousFunctionSpacing)) {
|
104
|
-
context.report(
|
96
|
+
context.report({
|
97
|
+
node: node,
|
98
|
+
loc: location,
|
99
|
+
message: "Unexpected space before function parentheses.",
|
100
|
+
fix: function(fixer) {
|
101
|
+
return fixer.removeRange([leftToken.range[1], rightToken.range[0]]);
|
102
|
+
}
|
103
|
+
});
|
105
104
|
}
|
106
105
|
} else {
|
107
106
|
if ((isNamed && requireNamedFunctionSpacing) || (!isNamed && requireAnonymousFunctionSpacing)) {
|
108
|
-
context.report(
|
107
|
+
context.report({
|
108
|
+
node: node,
|
109
|
+
loc: location,
|
110
|
+
message: "Missing space before function parentheses.",
|
111
|
+
fix: function(fixer) {
|
112
|
+
return fixer.insertTextAfter(leftToken, " ");
|
113
|
+
}
|
114
|
+
});
|
109
115
|
}
|
110
116
|
}
|
111
117
|
}
|
@@ -17,12 +17,37 @@ var ERROR_MSG_NO_SPACE_EXPECTED = "Unexpected space before keyword \"{{keyword}}
|
|
17
17
|
|
18
18
|
module.exports = function(context) {
|
19
19
|
|
20
|
+
var sourceCode = context.getSourceCode();
|
21
|
+
|
20
22
|
var SPACE_REQUIRED = context.options[0] !== "never";
|
21
23
|
|
22
24
|
//--------------------------------------------------------------------------
|
23
25
|
// Helpers
|
24
26
|
//--------------------------------------------------------------------------
|
25
27
|
|
28
|
+
/**
|
29
|
+
* Report the error message
|
30
|
+
* @param {ASTNode} node node to report
|
31
|
+
* @param {string} message Error message to be displayed
|
32
|
+
* @param {object} data Data object for the rule message
|
33
|
+
* @returns {void}
|
34
|
+
*/
|
35
|
+
function report(node, message, data) {
|
36
|
+
context.report({
|
37
|
+
node: node,
|
38
|
+
message: message,
|
39
|
+
data: data,
|
40
|
+
fix: function(fixer) {
|
41
|
+
if (SPACE_REQUIRED) {
|
42
|
+
return fixer.insertTextBefore(node, " ");
|
43
|
+
} else {
|
44
|
+
var tokenBefore = context.getTokenBefore(node);
|
45
|
+
return fixer.removeRange([tokenBefore.range[1], node.range[0]]);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
});
|
49
|
+
}
|
50
|
+
|
26
51
|
/**
|
27
52
|
* Check if a token meets the criteria
|
28
53
|
*
|
@@ -47,10 +72,10 @@ module.exports = function(context) {
|
|
47
72
|
}
|
48
73
|
|
49
74
|
options = options || {};
|
50
|
-
options.allowedPrecedingChars = options.allowedPrecedingChars || [];
|
75
|
+
options.allowedPrecedingChars = options.allowedPrecedingChars || [ "{" ];
|
51
76
|
options.requireSpace = typeof options.requireSpace === "undefined" ? SPACE_REQUIRED : options.requireSpace;
|
52
77
|
|
53
|
-
var hasSpace =
|
78
|
+
var hasSpace = sourceCode.isSpaceBetweenTokens(left, right);
|
54
79
|
var spaceOk = hasSpace === options.requireSpace;
|
55
80
|
|
56
81
|
if (spaceOk) {
|
@@ -59,13 +84,13 @@ module.exports = function(context) {
|
|
59
84
|
|
60
85
|
if (!astUtils.isTokenOnSameLine(left, right)) {
|
61
86
|
if (!options.requireSpace) {
|
62
|
-
|
87
|
+
report(node, ERROR_MSG_NO_SPACE_EXPECTED, { keyword: right.value });
|
63
88
|
}
|
64
89
|
return;
|
65
90
|
}
|
66
91
|
|
67
92
|
if (!options.requireSpace) {
|
68
|
-
|
93
|
+
report(node, ERROR_MSG_NO_SPACE_EXPECTED, { keyword: right.value });
|
69
94
|
return;
|
70
95
|
}
|
71
96
|
|
@@ -73,7 +98,7 @@ module.exports = function(context) {
|
|
73
98
|
return;
|
74
99
|
}
|
75
100
|
|
76
|
-
|
101
|
+
report(node, ERROR_MSG_SPACE_EXPECTED, { keyword: right.value });
|
77
102
|
|
78
103
|
}
|
79
104
|
|
@@ -130,7 +155,7 @@ module.exports = function(context) {
|
|
130
155
|
check(caseNode);
|
131
156
|
});
|
132
157
|
},
|
133
|
-
ThrowStatement: check,
|
158
|
+
"ThrowStatement": check,
|
134
159
|
"TryStatement": function(node) {
|
135
160
|
// try
|
136
161
|
check(node);
|
@@ -144,7 +169,7 @@ module.exports = function(context) {
|
|
144
169
|
},
|
145
170
|
"WithStatement": check,
|
146
171
|
"VariableDeclaration": function(node) {
|
147
|
-
check(node, { allowedPrecedingChars: [ "(" ] });
|
172
|
+
check(node, { allowedPrecedingChars: [ "(", "{" ] });
|
148
173
|
},
|
149
174
|
"ReturnStatement": check,
|
150
175
|
"BreakStatement": check,
|
@@ -152,25 +177,28 @@ module.exports = function(context) {
|
|
152
177
|
"ContinueStatement": check,
|
153
178
|
"FunctionDeclaration": check,
|
154
179
|
"FunctionExpression": function(node) {
|
155
|
-
|
156
180
|
var left = context.getTokenBefore(node);
|
157
|
-
var right =
|
181
|
+
var right = context.getFirstToken(node);
|
158
182
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
} else {
|
163
|
-
right = context.getFirstToken(node);
|
183
|
+
// If it's a method, a getter, or a setter, the first token is not the `function` keyword.
|
184
|
+
if (right.type !== "Keyword") {
|
185
|
+
return;
|
164
186
|
}
|
165
187
|
|
166
|
-
checkTokens(node, left, right, { allowedPrecedingChars: [ "(" ] });
|
188
|
+
checkTokens(node, left, right, { allowedPrecedingChars: [ "(", "{" ] });
|
167
189
|
},
|
168
190
|
"YieldExpression": function(node) {
|
169
|
-
check(node, { allowedPrecedingChars: [ "(" ] });
|
191
|
+
check(node, { allowedPrecedingChars: [ "(", "{" ] });
|
170
192
|
},
|
171
193
|
"ForOfStatement": check,
|
172
194
|
"ClassBody": function(node) {
|
173
|
-
|
195
|
+
|
196
|
+
// Find the 'class' token
|
197
|
+
while (node.value !== "class") {
|
198
|
+
node = context.getTokenBefore(node);
|
199
|
+
}
|
200
|
+
|
201
|
+
check(node);
|
174
202
|
},
|
175
203
|
"Super": check
|
176
204
|
|
@@ -48,7 +48,28 @@ module.exports = function(context) {
|
|
48
48
|
* @private
|
49
49
|
*/
|
50
50
|
function report(mainNode, culpritToken) {
|
51
|
-
context.report(
|
51
|
+
context.report({
|
52
|
+
node: mainNode,
|
53
|
+
loc: culpritToken.loc.start,
|
54
|
+
message: "Infix operators must be spaced.",
|
55
|
+
fix: function(fixer) {
|
56
|
+
var previousToken = context.getTokenBefore(culpritToken);
|
57
|
+
var afterToken = context.getTokenAfter(culpritToken);
|
58
|
+
var fixString = "";
|
59
|
+
|
60
|
+
if (culpritToken.range[0] - previousToken.range[1] === 0) {
|
61
|
+
fixString = " ";
|
62
|
+
}
|
63
|
+
|
64
|
+
fixString += culpritToken.value;
|
65
|
+
|
66
|
+
if (afterToken.range[0] - culpritToken.range[1] === 0) {
|
67
|
+
fixString += " ";
|
68
|
+
}
|
69
|
+
|
70
|
+
return fixer.replaceText(culpritToken, fixString);
|
71
|
+
}
|
72
|
+
});
|
52
73
|
}
|
53
74
|
|
54
75
|
/**
|
@@ -21,7 +21,13 @@ module.exports = function(context) {
|
|
21
21
|
value = tokens[0].value;
|
22
22
|
|
23
23
|
if (tokens[0].range[1] >= tokens[1].range[0]) {
|
24
|
-
context.report(
|
24
|
+
context.report({
|
25
|
+
node: node,
|
26
|
+
message: "Keyword \"" + value + "\" must be followed by whitespace.",
|
27
|
+
fix: function(fixer) {
|
28
|
+
return fixer.insertTextAfterRange(tokens[0].range, " ");
|
29
|
+
}
|
30
|
+
});
|
25
31
|
}
|
26
32
|
}
|
27
33
|
|
@@ -0,0 +1,63 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Helpers to test EventGenerator interface.
|
3
|
+
* @author Toru Nagashima
|
4
|
+
* @copyright 2015 Toru Nagashima. All rights reserved.
|
5
|
+
* See LICENSE file in root directory for full license.
|
6
|
+
*/
|
7
|
+
"use strict";
|
8
|
+
|
9
|
+
/* global describe, it */
|
10
|
+
|
11
|
+
//------------------------------------------------------------------------------
|
12
|
+
// Requirements
|
13
|
+
//------------------------------------------------------------------------------
|
14
|
+
|
15
|
+
var assert = require("assert");
|
16
|
+
|
17
|
+
//------------------------------------------------------------------------------
|
18
|
+
// Public Interface
|
19
|
+
//------------------------------------------------------------------------------
|
20
|
+
|
21
|
+
module.exports = {
|
22
|
+
/**
|
23
|
+
* Overrideable `describe` function to test.
|
24
|
+
* @param {string} text - A description.
|
25
|
+
* @param {function} method - A test logic.
|
26
|
+
* @returns {any} The returned value with the test logic.
|
27
|
+
*/
|
28
|
+
describe: (typeof describe === "function") ? describe : function(text, method) {
|
29
|
+
return method.apply(this);
|
30
|
+
},
|
31
|
+
|
32
|
+
/**
|
33
|
+
* Overrideable `it` function to test.
|
34
|
+
* @param {string} text - A description.
|
35
|
+
* @param {function} method - A test logic.
|
36
|
+
* @returns {any} The returned value with the test logic.
|
37
|
+
*/
|
38
|
+
it: (typeof it === "function") ? it : function(text, method) {
|
39
|
+
return method.apply(this);
|
40
|
+
},
|
41
|
+
|
42
|
+
/**
|
43
|
+
* Does some tests to check a given object implements the EventGenerator interface.
|
44
|
+
* @param {object} instance - An object to check.
|
45
|
+
* @returns {void}
|
46
|
+
*/
|
47
|
+
testEventGeneratorInterface: function(instance) {
|
48
|
+
this.describe("should implement EventGenerator interface", function() {
|
49
|
+
this.it("should have `emitter` property.", function() {
|
50
|
+
assert.equal(typeof instance.emitter, "object");
|
51
|
+
assert.equal(typeof instance.emitter.emit, "function");
|
52
|
+
});
|
53
|
+
|
54
|
+
this.it("should have `enterNode` property.", function() {
|
55
|
+
assert.equal(typeof instance.enterNode, "function");
|
56
|
+
});
|
57
|
+
|
58
|
+
this.it("should have `leaveNode` property.", function() {
|
59
|
+
assert.equal(typeof instance.leaveNode, "function");
|
60
|
+
});
|
61
|
+
}.bind(this));
|
62
|
+
}
|
63
|
+
};
|