eslint 3.13.1 → 3.16.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/CHANGELOG.md +81 -0
- package/README.md +1 -1
- package/conf/{eslint.json → eslint-recommended.js} +88 -71
- package/lib/ast-utils.js +247 -28
- package/lib/cli.js +2 -2
- package/lib/code-path-analysis/code-path-state.js +2 -2
- package/lib/config/autoconfig.js +24 -20
- package/lib/config/config-file.js +31 -24
- package/lib/config/config-initializer.js +2 -2
- package/lib/config/config-rule.js +15 -16
- package/lib/config/config-validator.js +6 -6
- package/lib/config.js +3 -2
- package/lib/eslint.js +18 -18
- package/lib/formatters/checkstyle.js +2 -2
- package/lib/formatters/codeframe.js +1 -1
- package/lib/formatters/compact.js +2 -2
- package/lib/formatters/junit.js +2 -2
- package/lib/formatters/tap.js +2 -2
- package/lib/formatters/unix.js +2 -2
- package/lib/formatters/visualstudio.js +2 -2
- package/lib/internal-rules/internal-consistent-docs-description.js +1 -1
- package/lib/rule-context.js +2 -2
- package/lib/rules/arrow-body-style.js +7 -4
- package/lib/rules/arrow-spacing.js +7 -6
- package/lib/rules/block-spacing.js +2 -2
- package/lib/rules/brace-style.js +93 -202
- package/lib/rules/capitalized-comments.js +6 -6
- package/lib/rules/comma-dangle.js +6 -6
- package/lib/rules/comma-spacing.js +16 -16
- package/lib/rules/comma-style.js +1 -1
- package/lib/rules/consistent-return.js +1 -1
- package/lib/rules/constructor-super.js +3 -3
- package/lib/rules/curly.js +11 -7
- package/lib/rules/default-case.js +3 -3
- package/lib/rules/eqeqeq.js +15 -6
- package/lib/rules/func-call-spacing.js +12 -15
- package/lib/rules/func-name-matching.js +1 -1
- package/lib/rules/generator-star-spacing.js +18 -19
- package/lib/rules/global-require.js +2 -2
- package/lib/rules/id-blacklist.js +2 -2
- package/lib/rules/id-length.js +3 -3
- package/lib/rules/id-match.js +2 -2
- package/lib/rules/indent.js +21 -20
- package/lib/rules/key-spacing.js +20 -23
- package/lib/rules/keyword-spacing.js +2 -13
- package/lib/rules/line-comment-position.js +1 -1
- package/lib/rules/linebreak-style.js +7 -1
- package/lib/rules/lines-around-comment.js +4 -4
- package/lib/rules/lines-around-directive.js +4 -4
- package/lib/rules/max-lines.js +3 -3
- package/lib/rules/max-statements-per-line.js +8 -7
- package/lib/rules/new-cap.js +2 -2
- package/lib/rules/newline-after-var.js +7 -2
- package/lib/rules/newline-before-return.js +2 -2
- package/lib/rules/newline-per-chained-call.js +3 -1
- package/lib/rules/no-await-in-loop.js +5 -5
- package/lib/rules/no-cond-assign.js +3 -3
- package/lib/rules/no-dupe-keys.js +1 -1
- package/lib/rules/no-else-return.js +88 -25
- package/lib/rules/no-extend-native.js +3 -3
- package/lib/rules/no-extra-bind.js +3 -4
- package/lib/rules/no-extra-boolean-cast.js +22 -1
- package/lib/rules/no-extra-parens.js +57 -9
- package/lib/rules/no-inner-declarations.js +4 -4
- package/lib/rules/no-irregular-whitespace.js +7 -1
- package/lib/rules/no-lone-blocks.js +10 -10
- package/lib/rules/no-mixed-operators.js +1 -7
- package/lib/rules/no-mixed-requires.js +4 -4
- package/lib/rules/no-multi-assign.js +41 -0
- package/lib/rules/no-multi-spaces.js +4 -1
- package/lib/rules/no-multi-str.js +7 -3
- package/lib/rules/no-redeclare.js +7 -7
- package/lib/rules/no-return-assign.js +7 -14
- package/lib/rules/no-return-await.js +2 -2
- package/lib/rules/no-sequences.js +7 -6
- package/lib/rules/no-throw-literal.js +2 -39
- package/lib/rules/no-trailing-spaces.js +8 -2
- package/lib/rules/no-undefined.js +45 -6
- package/lib/rules/no-unexpected-multiline.js +9 -8
- package/lib/rules/no-unneeded-ternary.js +5 -1
- package/lib/rules/no-unused-labels.js +17 -2
- package/lib/rules/no-unused-vars.js +34 -19
- package/lib/rules/no-use-before-define.js +33 -29
- package/lib/rules/no-useless-computed-key.js +9 -4
- package/lib/rules/no-useless-concat.js +10 -7
- package/lib/rules/no-useless-escape.js +1 -1
- package/lib/rules/no-useless-return.js +5 -11
- package/lib/rules/no-var.js +69 -3
- package/lib/rules/no-whitespace-before-property.js +5 -16
- package/lib/rules/object-curly-newline.js +2 -2
- package/lib/rules/object-curly-spacing.js +7 -25
- package/lib/rules/object-property-newline.js +3 -3
- package/lib/rules/object-shorthand.js +10 -10
- package/lib/rules/operator-assignment.js +2 -2
- package/lib/rules/operator-linebreak.js +8 -10
- package/lib/rules/padded-blocks.js +4 -4
- package/lib/rules/prefer-promise-reject-errors.js +124 -0
- package/lib/rules/prefer-spread.js +1 -1
- package/lib/rules/prefer-template.js +1 -1
- package/lib/rules/quotes.js +11 -7
- package/lib/rules/require-await.js +1 -1
- package/lib/rules/semi-spacing.js +4 -0
- package/lib/rules/sort-imports.js +4 -4
- package/lib/rules/sort-keys.js +2 -2
- package/lib/rules/sort-vars.js +2 -2
- package/lib/rules/space-before-function-paren.js +9 -6
- package/lib/rules/space-in-parens.js +8 -8
- package/lib/rules/spaced-comment.js +10 -10
- package/lib/rules/strict.js +2 -2
- package/lib/rules/template-tag-spacing.js +77 -0
- package/lib/rules/unicode-bom.js +1 -1
- package/lib/rules/wrap-iife.js +5 -5
- package/lib/rules/yoda.js +2 -7
- package/lib/rules.js +2 -2
- package/lib/testers/rule-tester.js +28 -21
- package/lib/token-store/backward-token-comment-cursor.js +57 -0
- package/lib/token-store/backward-token-cursor.js +56 -0
- package/lib/token-store/cursor.js +76 -0
- package/lib/token-store/cursors.js +92 -0
- package/lib/token-store/decorative-cursor.js +39 -0
- package/lib/token-store/filter-cursor.js +43 -0
- package/lib/token-store/forward-token-comment-cursor.js +57 -0
- package/lib/token-store/forward-token-cursor.js +61 -0
- package/lib/token-store/index.js +604 -0
- package/lib/token-store/limit-cursor.js +40 -0
- package/lib/token-store/padded-token-cursor.js +38 -0
- package/lib/token-store/skip-cursor.js +42 -0
- package/lib/token-store/utils.js +100 -0
- package/lib/util/comment-event-generator.js +17 -16
- package/lib/util/glob-util.js +1 -1
- package/lib/util/glob.js +1 -1
- package/lib/util/rule-fixer.js +3 -8
- package/lib/util/source-code-fixer.js +41 -45
- package/lib/util/source-code.js +35 -19
- package/messages/extend-config-missing.txt +3 -0
- package/package.json +3 -3
- package/lib/token-store.js +0 -203
package/lib/rules/brace-style.js
CHANGED
@@ -5,6 +5,8 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
const astUtils = require("../ast-utils");
|
9
|
+
|
8
10
|
//------------------------------------------------------------------------------
|
9
11
|
// Rule Definition
|
10
12
|
//------------------------------------------------------------------------------
|
@@ -52,215 +54,86 @@ module.exports = {
|
|
52
54
|
//--------------------------------------------------------------------------
|
53
55
|
|
54
56
|
/**
|
55
|
-
|
56
|
-
* @param {ASTNode} node The node to check.
|
57
|
-
* @returns {boolean} True if the node is a block statement, false if not.
|
58
|
-
* @private
|
59
|
-
*/
|
60
|
-
function isBlock(node) {
|
61
|
-
return node && node.type === "BlockStatement";
|
62
|
-
}
|
63
|
-
|
64
|
-
/**
|
65
|
-
* Check if the token is an punctuator with a value of curly brace
|
66
|
-
* @param {Object} token - Token to check
|
67
|
-
* @returns {boolean} true if its a curly punctuator
|
68
|
-
* @private
|
69
|
-
*/
|
70
|
-
function isCurlyPunctuator(token) {
|
71
|
-
return token.value === "{" || token.value === "}";
|
72
|
-
}
|
73
|
-
|
74
|
-
/**
|
75
|
-
* Reports a place where a newline unexpectedly appears
|
76
|
-
* @param {ASTNode} node The node to report
|
77
|
-
* @param {string} message The message to report
|
57
|
+
* Fixes a place where a newline unexpectedly appears
|
78
58
|
* @param {Token} firstToken The token before the unexpected newline
|
79
|
-
* @
|
59
|
+
* @param {Token} secondToken The token after the unexpected newline
|
60
|
+
* @returns {Function} A fixer function to remove the newlines between the tokens
|
80
61
|
*/
|
81
|
-
function
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
fix(fixer) {
|
86
|
-
const secondToken = sourceCode.getTokenAfter(firstToken);
|
87
|
-
const textBetween = sourceCode.getText().slice(firstToken.range[1], secondToken.range[0]);
|
88
|
-
const NEWLINE_REGEX = /\r\n|\r|\n|\u2028|\u2029/g;
|
62
|
+
function removeNewlineBetween(firstToken, secondToken) {
|
63
|
+
const textRange = [firstToken.range[1], secondToken.range[0]];
|
64
|
+
const textBetween = sourceCode.text.slice(textRange[0], textRange[1]);
|
65
|
+
const NEWLINE_REGEX = astUtils.createGlobalLinebreakMatcher();
|
89
66
|
|
90
|
-
|
91
|
-
|
92
|
-
}
|
93
|
-
});
|
67
|
+
// Don't do a fix if there is a comment between the tokens
|
68
|
+
return fixer => fixer.replaceTextRange(textRange, textBetween.trim() ? null : textBetween.replace(NEWLINE_REGEX, ""));
|
94
69
|
}
|
95
70
|
|
96
71
|
/**
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
const
|
106
|
-
|
107
|
-
return function(node) {
|
108
|
-
Array.prototype.forEach.call(blockProperties, blockProp => {
|
109
|
-
const block = node[blockProp];
|
110
|
-
|
111
|
-
if (!isBlock(block)) {
|
112
|
-
return;
|
113
|
-
}
|
114
|
-
|
115
|
-
const previousToken = sourceCode.getTokenBefore(block);
|
116
|
-
const curlyToken = sourceCode.getFirstToken(block);
|
117
|
-
const curlyTokenEnd = sourceCode.getLastToken(block);
|
118
|
-
const allOnSameLine = previousToken.loc.start.line === curlyTokenEnd.loc.start.line;
|
119
|
-
|
120
|
-
if (allOnSameLine && params.allowSingleLine) {
|
121
|
-
return;
|
122
|
-
}
|
123
|
-
|
124
|
-
if (style !== "allman" && previousToken.loc.start.line !== curlyToken.loc.start.line) {
|
125
|
-
reportExtraNewline(node, OPEN_MESSAGE, previousToken);
|
126
|
-
} else if (style === "allman" && previousToken.loc.start.line === curlyToken.loc.start.line) {
|
127
|
-
context.report({
|
128
|
-
node,
|
129
|
-
message: OPEN_MESSAGE_ALLMAN,
|
130
|
-
fix: fixer => fixer.insertTextBefore(curlyToken, "\n")
|
131
|
-
});
|
132
|
-
}
|
133
|
-
|
134
|
-
if (!block.body.length) {
|
135
|
-
return;
|
136
|
-
}
|
137
|
-
|
138
|
-
if (curlyToken.loc.start.line === block.body[0].loc.start.line) {
|
139
|
-
context.report({
|
140
|
-
node: block.body[0],
|
141
|
-
message: BODY_MESSAGE,
|
142
|
-
fix: fixer => fixer.insertTextAfter(curlyToken, "\n")
|
143
|
-
});
|
144
|
-
}
|
72
|
+
* Validates a pair of curly brackets based on the user's config
|
73
|
+
* @param {Token} openingCurly The opening curly bracket
|
74
|
+
* @param {Token} closingCurly The closing curly bracket
|
75
|
+
* @returns {void}
|
76
|
+
*/
|
77
|
+
function validateCurlyPair(openingCurly, closingCurly) {
|
78
|
+
const tokenBeforeOpeningCurly = sourceCode.getTokenBefore(openingCurly);
|
79
|
+
const tokenAfterOpeningCurly = sourceCode.getTokenAfter(openingCurly);
|
80
|
+
const tokenBeforeClosingCurly = sourceCode.getTokenBefore(closingCurly);
|
81
|
+
const singleLineException = params.allowSingleLine && astUtils.isTokenOnSameLine(openingCurly, closingCurly);
|
145
82
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
});
|
152
|
-
}
|
83
|
+
if (style !== "allman" && !astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly)) {
|
84
|
+
context.report({
|
85
|
+
node: openingCurly,
|
86
|
+
message: OPEN_MESSAGE,
|
87
|
+
fix: removeNewlineBetween(tokenBeforeOpeningCurly, openingCurly)
|
153
88
|
});
|
154
|
-
};
|
155
|
-
}
|
156
|
-
|
157
|
-
/**
|
158
|
-
* Enforces the configured brace style on IfStatements
|
159
|
-
* @param {ASTNode} node An IfStatement node.
|
160
|
-
* @returns {void}
|
161
|
-
* @private
|
162
|
-
*/
|
163
|
-
function checkIfStatement(node) {
|
164
|
-
checkBlock("consequent", "alternate")(node);
|
165
|
-
|
166
|
-
if (node.alternate) {
|
167
|
-
|
168
|
-
const tokens = sourceCode.getTokensBefore(node.alternate, 2);
|
169
|
-
|
170
|
-
if (style === "1tbs") {
|
171
|
-
if (tokens[0].loc.start.line !== tokens[1].loc.start.line &&
|
172
|
-
node.consequent.type === "BlockStatement" &&
|
173
|
-
isCurlyPunctuator(tokens[0])) {
|
174
|
-
reportExtraNewline(node.alternate, CLOSE_MESSAGE, tokens[0]);
|
175
|
-
}
|
176
|
-
} else if (tokens[0].loc.start.line === tokens[1].loc.start.line) {
|
177
|
-
context.report({
|
178
|
-
node: node.alternate,
|
179
|
-
message: CLOSE_MESSAGE_STROUSTRUP_ALLMAN,
|
180
|
-
fix: fixer => fixer.insertTextAfter(tokens[0], "\n")
|
181
|
-
});
|
182
|
-
}
|
183
|
-
|
184
89
|
}
|
185
|
-
}
|
186
|
-
|
187
|
-
/**
|
188
|
-
* Enforces the configured brace style on TryStatements
|
189
|
-
* @param {ASTNode} node A TryStatement node.
|
190
|
-
* @returns {void}
|
191
|
-
* @private
|
192
|
-
*/
|
193
|
-
function checkTryStatement(node) {
|
194
|
-
checkBlock("block", "finalizer")(node);
|
195
90
|
|
196
|
-
if (
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
}
|
203
|
-
} else if (tokens[0].loc.start.line === tokens[1].loc.start.line) {
|
204
|
-
context.report({
|
205
|
-
node: node.finalizer,
|
206
|
-
message: CLOSE_MESSAGE_STROUSTRUP_ALLMAN,
|
207
|
-
fix: fixer => fixer.insertTextAfter(tokens[0], "\n")
|
208
|
-
});
|
209
|
-
}
|
91
|
+
if (style === "allman" && astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly) && !singleLineException) {
|
92
|
+
context.report({
|
93
|
+
node: openingCurly,
|
94
|
+
message: OPEN_MESSAGE_ALLMAN,
|
95
|
+
fix: fixer => fixer.insertTextBefore(openingCurly, "\n")
|
96
|
+
});
|
210
97
|
}
|
211
|
-
}
|
212
|
-
|
213
|
-
/**
|
214
|
-
* Enforces the configured brace style on CatchClauses
|
215
|
-
* @param {ASTNode} node A CatchClause node.
|
216
|
-
* @returns {void}
|
217
|
-
* @private
|
218
|
-
*/
|
219
|
-
function checkCatchClause(node) {
|
220
|
-
const previousToken = sourceCode.getTokenBefore(node),
|
221
|
-
firstToken = sourceCode.getFirstToken(node);
|
222
98
|
|
223
|
-
|
99
|
+
if (astUtils.isTokenOnSameLine(openingCurly, tokenAfterOpeningCurly) && tokenAfterOpeningCurly !== closingCurly && !singleLineException) {
|
100
|
+
context.report({
|
101
|
+
node: openingCurly,
|
102
|
+
message: BODY_MESSAGE,
|
103
|
+
fix: fixer => fixer.insertTextAfter(openingCurly, "\n")
|
104
|
+
});
|
105
|
+
}
|
224
106
|
|
225
|
-
if (
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
}
|
231
|
-
if (previousToken.loc.start.line === firstToken.loc.start.line) {
|
232
|
-
context.report({
|
233
|
-
node,
|
234
|
-
message: CLOSE_MESSAGE_STROUSTRUP_ALLMAN,
|
235
|
-
fix: fixer => fixer.insertTextAfter(previousToken, "\n")
|
236
|
-
});
|
237
|
-
}
|
238
|
-
}
|
107
|
+
if (tokenBeforeClosingCurly !== openingCurly && !singleLineException && astUtils.isTokenOnSameLine(tokenBeforeClosingCurly, closingCurly)) {
|
108
|
+
context.report({
|
109
|
+
node: closingCurly,
|
110
|
+
message: CLOSE_MESSAGE_SINGLE,
|
111
|
+
fix: fixer => fixer.insertTextBefore(closingCurly, "\n")
|
112
|
+
});
|
239
113
|
}
|
240
114
|
}
|
241
115
|
|
242
116
|
/**
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
let tokens;
|
117
|
+
* Validates the location of a token that appears before a keyword (e.g. a newline before `else`)
|
118
|
+
* @param {Token} curlyToken The closing curly token. This is assumed to precede a keyword token (such as `else` or `finally`).
|
119
|
+
* @returns {void}
|
120
|
+
*/
|
121
|
+
function validateCurlyBeforeKeyword(curlyToken) {
|
122
|
+
const keywordToken = sourceCode.getTokenAfter(curlyToken);
|
250
123
|
|
251
|
-
if (
|
252
|
-
|
253
|
-
|
254
|
-
|
124
|
+
if (style === "1tbs" && !astUtils.isTokenOnSameLine(curlyToken, keywordToken)) {
|
125
|
+
context.report({
|
126
|
+
node: curlyToken,
|
127
|
+
message: CLOSE_MESSAGE,
|
128
|
+
fix: removeNewlineBetween(curlyToken, keywordToken)
|
129
|
+
});
|
255
130
|
}
|
256
131
|
|
257
|
-
if (style !== "
|
258
|
-
reportExtraNewline(node, OPEN_MESSAGE, tokens[0]);
|
259
|
-
} else if (style === "allman" && tokens[0].loc.start.line === tokens[1].loc.start.line) {
|
132
|
+
if (style !== "1tbs" && astUtils.isTokenOnSameLine(curlyToken, keywordToken)) {
|
260
133
|
context.report({
|
261
|
-
node,
|
262
|
-
message:
|
263
|
-
fix: fixer => fixer.
|
134
|
+
node: curlyToken,
|
135
|
+
message: CLOSE_MESSAGE_STROUSTRUP_ALLMAN,
|
136
|
+
fix: fixer => fixer.insertTextAfter(curlyToken, "\n")
|
264
137
|
});
|
265
138
|
}
|
266
139
|
}
|
@@ -270,20 +143,38 @@ module.exports = {
|
|
270
143
|
//--------------------------------------------------------------------------
|
271
144
|
|
272
145
|
return {
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
146
|
+
BlockStatement(node) {
|
147
|
+
if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) {
|
148
|
+
validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node));
|
149
|
+
}
|
150
|
+
},
|
151
|
+
ClassBody(node) {
|
152
|
+
validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node));
|
153
|
+
},
|
154
|
+
SwitchStatement(node) {
|
155
|
+
const closingCurly = sourceCode.getLastToken(node);
|
156
|
+
const openingCurly = sourceCode.getTokenBefore(node.cases.length ? node.cases[0] : closingCurly);
|
157
|
+
|
158
|
+
validateCurlyPair(openingCurly, closingCurly);
|
159
|
+
},
|
160
|
+
IfStatement(node) {
|
161
|
+
if (node.consequent.type === "BlockStatement" && node.alternate) {
|
162
|
+
|
163
|
+
// Handle the keyword after the `if` block (before `else`)
|
164
|
+
validateCurlyBeforeKeyword(sourceCode.getLastToken(node.consequent));
|
165
|
+
}
|
166
|
+
},
|
167
|
+
TryStatement(node) {
|
168
|
+
|
169
|
+
// Handle the keyword after the `try` block (before `catch` or `finally`)
|
170
|
+
validateCurlyBeforeKeyword(sourceCode.getLastToken(node.block));
|
287
171
|
|
172
|
+
if (node.handler && node.finalizer) {
|
173
|
+
|
174
|
+
// Handle the keyword after the `catch` block (before `finally`)
|
175
|
+
validateCurlyBeforeKeyword(sourceCode.getLastToken(node.handler.body));
|
176
|
+
}
|
177
|
+
}
|
178
|
+
};
|
288
179
|
}
|
289
180
|
};
|
@@ -163,8 +163,8 @@ module.exports = {
|
|
163
163
|
* otherwise.
|
164
164
|
*/
|
165
165
|
function isInlineComment(comment) {
|
166
|
-
const previousToken = sourceCode.
|
167
|
-
nextToken = sourceCode.
|
166
|
+
const previousToken = sourceCode.getTokenBefore(comment, { includeComments: true }),
|
167
|
+
nextToken = sourceCode.getTokenAfter(comment, { includeComments: true });
|
168
168
|
|
169
169
|
return Boolean(
|
170
170
|
previousToken &&
|
@@ -181,7 +181,7 @@ module.exports = {
|
|
181
181
|
* @returns {boolean} True if the comment follows a valid comment.
|
182
182
|
*/
|
183
183
|
function isConsecutiveComment(comment) {
|
184
|
-
const previousTokenOrComment = sourceCode.
|
184
|
+
const previousTokenOrComment = sourceCode.getTokenBefore(comment, { includeComments: true });
|
185
185
|
|
186
186
|
return Boolean(
|
187
187
|
previousTokenOrComment &&
|
@@ -264,9 +264,9 @@ module.exports = {
|
|
264
264
|
commentValid = isCommentValid(comment, options);
|
265
265
|
|
266
266
|
if (!commentValid) {
|
267
|
-
const message = capitalize === "always"
|
268
|
-
ALWAYS_MESSAGE
|
269
|
-
NEVER_MESSAGE;
|
267
|
+
const message = capitalize === "always"
|
268
|
+
? ALWAYS_MESSAGE
|
269
|
+
: NEVER_MESSAGE;
|
270
270
|
|
271
271
|
context.report({
|
272
272
|
node: null, // Intentionally using loc instead
|
@@ -20,7 +20,7 @@ const DEFAULT_OPTIONS = Object.freeze({
|
|
20
20
|
objects: "never",
|
21
21
|
imports: "never",
|
22
22
|
exports: "never",
|
23
|
-
functions: "ignore"
|
23
|
+
functions: "ignore"
|
24
24
|
});
|
25
25
|
|
26
26
|
/**
|
@@ -53,7 +53,7 @@ function normalizeOptions(optionValue) {
|
|
53
53
|
exports: optionValue,
|
54
54
|
|
55
55
|
// For backward compatibility, always ignore functions.
|
56
|
-
functions: "ignore"
|
56
|
+
functions: "ignore"
|
57
57
|
};
|
58
58
|
}
|
59
59
|
if (typeof optionValue === "object" && optionValue !== null) {
|
@@ -62,7 +62,7 @@ function normalizeOptions(optionValue) {
|
|
62
62
|
objects: optionValue.objects || DEFAULT_OPTIONS.objects,
|
63
63
|
imports: optionValue.imports || DEFAULT_OPTIONS.imports,
|
64
64
|
exports: optionValue.exports || DEFAULT_OPTIONS.exports,
|
65
|
-
functions: optionValue.functions || DEFAULT_OPTIONS.functions
|
65
|
+
functions: optionValue.functions || DEFAULT_OPTIONS.functions
|
66
66
|
};
|
67
67
|
}
|
68
68
|
|
@@ -121,7 +121,7 @@ module.exports = {
|
|
121
121
|
additionalProperties: false
|
122
122
|
}
|
123
123
|
]
|
124
|
-
}
|
124
|
+
}
|
125
125
|
]
|
126
126
|
},
|
127
127
|
|
@@ -312,7 +312,7 @@ module.exports = {
|
|
312
312
|
"always-multiline": forceTrailingCommaIfMultiline,
|
313
313
|
"only-multiline": allowTrailingCommaIfMultiline,
|
314
314
|
never: forbidTrailingComma,
|
315
|
-
ignore: lodash.noop
|
315
|
+
ignore: lodash.noop
|
316
316
|
};
|
317
317
|
|
318
318
|
return {
|
@@ -330,7 +330,7 @@ module.exports = {
|
|
330
330
|
FunctionExpression: predicate[options.functions],
|
331
331
|
ArrowFunctionExpression: predicate[options.functions],
|
332
332
|
CallExpression: predicate[options.functions],
|
333
|
-
NewExpression: predicate[options.functions]
|
333
|
+
NewExpression: predicate[options.functions]
|
334
334
|
};
|
335
335
|
}
|
336
336
|
};
|
@@ -78,27 +78,27 @@ module.exports = {
|
|
78
78
|
if (options[dir]) {
|
79
79
|
if (dir === "before") {
|
80
80
|
return fixer.insertTextBefore(node, " ");
|
81
|
-
} else {
|
82
|
-
return fixer.insertTextAfter(node, " ");
|
83
81
|
}
|
84
|
-
|
85
|
-
let start, end;
|
86
|
-
const newText = "";
|
82
|
+
return fixer.insertTextAfter(node, " ");
|
87
83
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
} else {
|
92
|
-
start = node.range[1];
|
93
|
-
end = otherNode.range[0];
|
94
|
-
}
|
84
|
+
}
|
85
|
+
let start, end;
|
86
|
+
const newText = "";
|
95
87
|
|
96
|
-
|
88
|
+
if (dir === "before") {
|
89
|
+
start = otherNode.range[1];
|
90
|
+
end = node.range[0];
|
91
|
+
} else {
|
92
|
+
start = node.range[1];
|
93
|
+
end = otherNode.range[0];
|
97
94
|
}
|
95
|
+
|
96
|
+
return fixer.replaceTextRange([start, end], newText);
|
97
|
+
|
98
98
|
},
|
99
|
-
message: options[dir]
|
100
|
-
"A space is required {{dir}} ','."
|
101
|
-
"There should be no space {{dir}} ','.",
|
99
|
+
message: options[dir]
|
100
|
+
? "A space is required {{dir}} ','."
|
101
|
+
: "There should be no space {{dir}} ','.",
|
102
102
|
data: {
|
103
103
|
dir
|
104
104
|
}
|
package/lib/rules/comma-style.js
CHANGED
@@ -104,7 +104,7 @@ module.exports = {
|
|
104
104
|
} else if (node.type === "ArrowFunctionExpression") {
|
105
105
|
|
106
106
|
// `=>` token
|
107
|
-
loc = context.getSourceCode().getTokenBefore(node.body).loc.start;
|
107
|
+
loc = context.getSourceCode().getTokenBefore(node.body, astUtils.isArrowToken).loc.start;
|
108
108
|
type = "function";
|
109
109
|
} else if (
|
110
110
|
node.parent.type === "MethodDefinition" ||
|
@@ -209,9 +209,9 @@ module.exports = {
|
|
209
209
|
|
210
210
|
if (!calledInEveryPaths) {
|
211
211
|
context.report({
|
212
|
-
message: calledInSomePaths
|
213
|
-
"Lacked a call of 'super()' in some code paths."
|
214
|
-
"Expected to call 'super()'.",
|
212
|
+
message: calledInSomePaths
|
213
|
+
? "Lacked a call of 'super()' in some code paths."
|
214
|
+
: "Expected to call 'super()'.",
|
215
215
|
node: node.parent
|
216
216
|
});
|
217
217
|
}
|
package/lib/rules/curly.js
CHANGED
@@ -94,19 +94,23 @@ module.exports = {
|
|
94
94
|
return first.loc.start.line === last.loc.end.line;
|
95
95
|
}
|
96
96
|
|
97
|
+
/**
|
98
|
+
* Checks if the given token is an `else` token or not.
|
99
|
+
*
|
100
|
+
* @param {Token} token - The token to check.
|
101
|
+
* @returns {boolean} `true` if the token is an `else` token.
|
102
|
+
*/
|
103
|
+
function isElseKeywordToken(token) {
|
104
|
+
return token.value === "else" && token.type === "Keyword";
|
105
|
+
}
|
106
|
+
|
97
107
|
/**
|
98
108
|
* Gets the `else` keyword token of a given `IfStatement` node.
|
99
109
|
* @param {ASTNode} node - A `IfStatement` node to get.
|
100
110
|
* @returns {Token} The `else` keyword token.
|
101
111
|
*/
|
102
112
|
function getElseKeyword(node) {
|
103
|
-
|
104
|
-
|
105
|
-
while (token.type !== "Keyword" || token.value !== "else") {
|
106
|
-
token = sourceCode.getTokenAfter(token);
|
107
|
-
}
|
108
|
-
|
109
|
-
return token;
|
113
|
+
return node.alternate && sourceCode.getFirstTokenBetween(node.consequent, node.alternate, isElseKeywordToken);
|
110
114
|
}
|
111
115
|
|
112
116
|
/**
|
@@ -31,9 +31,9 @@ module.exports = {
|
|
31
31
|
|
32
32
|
create(context) {
|
33
33
|
const options = context.options[0] || {};
|
34
|
-
const commentPattern = options.commentPattern
|
35
|
-
new RegExp(options.commentPattern)
|
36
|
-
DEFAULT_COMMENT_PATTERN;
|
34
|
+
const commentPattern = options.commentPattern
|
35
|
+
? new RegExp(options.commentPattern)
|
36
|
+
: DEFAULT_COMMENT_PATTERN;
|
37
37
|
|
38
38
|
const sourceCode = context.getSourceCode();
|
39
39
|
|
package/lib/rules/eqeqeq.js
CHANGED
@@ -5,6 +5,12 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Requirements
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
const astUtils = require("../ast-utils");
|
13
|
+
|
8
14
|
//------------------------------------------------------------------------------
|
9
15
|
// Rule Definition
|
10
16
|
//------------------------------------------------------------------------------
|
@@ -57,9 +63,9 @@ module.exports = {
|
|
57
63
|
const options = context.options[1] || {};
|
58
64
|
const sourceCode = context.getSourceCode();
|
59
65
|
|
60
|
-
const nullOption = (config === "always")
|
61
|
-
options.null || "always"
|
62
|
-
"ignore";
|
66
|
+
const nullOption = (config === "always")
|
67
|
+
? options.null || "always"
|
68
|
+
: "ignore";
|
63
69
|
const enforceRuleForNull = (nullOption === "always");
|
64
70
|
const enforceInverseRuleForNull = (nullOption === "never");
|
65
71
|
|
@@ -100,8 +106,7 @@ module.exports = {
|
|
100
106
|
* @private
|
101
107
|
*/
|
102
108
|
function isNullCheck(node) {
|
103
|
-
return (node.right
|
104
|
-
(node.left.type === "Literal" && node.left.value === null);
|
109
|
+
return astUtils.isNullLiteral(node.right) || astUtils.isNullLiteral(node.left);
|
105
110
|
}
|
106
111
|
|
107
112
|
/**
|
@@ -134,7 +139,11 @@ module.exports = {
|
|
134
139
|
|
135
140
|
// If the comparison is a `typeof` comparison or both sides are literals with the same type, then it's safe to fix.
|
136
141
|
if (isTypeOfBinary(node) || areLiteralsAndSameType(node)) {
|
137
|
-
const operatorToken = sourceCode.
|
142
|
+
const operatorToken = sourceCode.getFirstTokenBetween(
|
143
|
+
node.left,
|
144
|
+
node.right,
|
145
|
+
token => token.value === node.operator
|
146
|
+
);
|
138
147
|
|
139
148
|
return fixer.replaceText(operatorToken, expectedOperator);
|
140
149
|
}
|
@@ -5,6 +5,12 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Requirements
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
const astUtils = require("../ast-utils");
|
13
|
+
|
8
14
|
//------------------------------------------------------------------------------
|
9
15
|
// Rule Definition
|
10
16
|
//------------------------------------------------------------------------------
|
@@ -67,28 +73,19 @@ module.exports = {
|
|
67
73
|
* @private
|
68
74
|
*/
|
69
75
|
function checkSpacing(node) {
|
76
|
+
const lastToken = sourceCode.getLastToken(node);
|
70
77
|
const lastCalleeToken = sourceCode.getLastToken(node.callee);
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
// advances to an open parenthesis.
|
75
|
-
while (
|
76
|
-
parenToken &&
|
77
|
-
parenToken.range[1] < node.range[1] &&
|
78
|
-
parenToken.value !== "("
|
79
|
-
) {
|
80
|
-
prevToken = parenToken;
|
81
|
-
parenToken = sourceCode.getTokenAfter(parenToken);
|
82
|
-
}
|
78
|
+
const parenToken = sourceCode.getFirstTokenBetween(lastCalleeToken, lastToken, astUtils.isOpeningParenToken);
|
79
|
+
const prevToken = parenToken && sourceCode.getTokenBefore(parenToken);
|
83
80
|
|
84
81
|
// Parens in NewExpression are optional
|
85
82
|
if (!(parenToken && parenToken.range[1] < node.range[1])) {
|
86
83
|
return;
|
87
84
|
}
|
88
85
|
|
89
|
-
const
|
90
|
-
const
|
91
|
-
|
86
|
+
const textBetweenTokens = text.slice(prevToken.range[1], parenToken.range[0]).replace(/\/\*.*?\*\//g, "");
|
87
|
+
const hasWhitespace = /\s/.test(textBetweenTokens);
|
88
|
+
const hasNewline = hasWhitespace && astUtils.LINEBREAK_MATCHER.test(textBetweenTokens);
|
92
89
|
|
93
90
|
/*
|
94
91
|
* never allowNewlines hasWhitespace hasNewline message
|
@@ -155,7 +155,7 @@ module.exports = {
|
|
155
155
|
return;
|
156
156
|
}
|
157
157
|
|
158
|
-
const isProp = node.left.type === "MemberExpression"
|
158
|
+
const isProp = node.left.type === "MemberExpression";
|
159
159
|
const name = isProp ? astUtils.getStaticPropertyName(node.left) : node.left.name;
|
160
160
|
|
161
161
|
if (node.right.id && isIdentifier(name) && shouldWarn(name, node.right.id.name)) {
|