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/ast-utils.js
CHANGED
@@ -24,6 +24,12 @@ const bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/;
|
|
24
24
|
const breakableTypePattern = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/;
|
25
25
|
const thisTagPattern = /^[\s*]*@this/m;
|
26
26
|
|
27
|
+
const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]);
|
28
|
+
const LINEBREAK_MATCHER = /\r\n|[\r\n\u2028\u2029]/;
|
29
|
+
|
30
|
+
// A set of node types that can contain a list of statements
|
31
|
+
const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "SwitchCase"]);
|
32
|
+
|
27
33
|
/**
|
28
34
|
* Checks reference if is non initializer and writable.
|
29
35
|
* @param {Reference} reference - A reference to check.
|
@@ -142,7 +148,7 @@ function isInLoop(node) {
|
|
142
148
|
*/
|
143
149
|
function isNullOrUndefined(node) {
|
144
150
|
return (
|
145
|
-
(node
|
151
|
+
module.exports.isNullLiteral(node) ||
|
146
152
|
(node.type === "Identifier" && node.name === "undefined") ||
|
147
153
|
(node.type === "UnaryExpression" && node.operator === "void")
|
148
154
|
);
|
@@ -158,9 +164,9 @@ function isCallee(node) {
|
|
158
164
|
}
|
159
165
|
|
160
166
|
/**
|
161
|
-
* Checks whether or not a node is `
|
167
|
+
* Checks whether or not a node is `Reflect.apply`.
|
162
168
|
* @param {ASTNode} node - A node to check.
|
163
|
-
* @returns {boolean} Whether or not the node is a `
|
169
|
+
* @returns {boolean} Whether or not the node is a `Reflect.apply`.
|
164
170
|
*/
|
165
171
|
function isReflectApply(node) {
|
166
172
|
return (
|
@@ -210,6 +216,15 @@ function isMethodWhichHasThisArg(node) {
|
|
210
216
|
return false;
|
211
217
|
}
|
212
218
|
|
219
|
+
/**
|
220
|
+
* Creates the negate function of the given function.
|
221
|
+
* @param {Function} f - The function to negate.
|
222
|
+
* @returns {Function} Negated function.
|
223
|
+
*/
|
224
|
+
function negate(f) {
|
225
|
+
return token => !f(token);
|
226
|
+
}
|
227
|
+
|
213
228
|
/**
|
214
229
|
* Checks whether or not a node has a `@this` tag in its comments.
|
215
230
|
* @param {ASTNode} node - A node to check.
|
@@ -247,20 +262,123 @@ function isParenthesised(sourceCode, node) {
|
|
247
262
|
}
|
248
263
|
|
249
264
|
/**
|
250
|
-
*
|
265
|
+
* Checks if the given token is an arrow token or not.
|
251
266
|
*
|
252
|
-
* @param {
|
253
|
-
* @
|
254
|
-
* @returns {Token} `=>` token.
|
267
|
+
* @param {Token} token - The token to check.
|
268
|
+
* @returns {boolean} `true` if the token is an arrow token.
|
255
269
|
*/
|
256
|
-
function
|
257
|
-
|
270
|
+
function isArrowToken(token) {
|
271
|
+
return token.value === "=>" && token.type === "Punctuator";
|
272
|
+
}
|
258
273
|
|
259
|
-
|
260
|
-
|
261
|
-
|
274
|
+
/**
|
275
|
+
* Checks if the given token is a comma token or not.
|
276
|
+
*
|
277
|
+
* @param {Token} token - The token to check.
|
278
|
+
* @returns {boolean} `true` if the token is a comma token.
|
279
|
+
*/
|
280
|
+
function isCommaToken(token) {
|
281
|
+
return token.value === "," && token.type === "Punctuator";
|
282
|
+
}
|
283
|
+
|
284
|
+
/**
|
285
|
+
* Checks if the given token is a semicolon token or not.
|
286
|
+
*
|
287
|
+
* @param {Token} token - The token to check.
|
288
|
+
* @returns {boolean} `true` if the token is a semicolon token.
|
289
|
+
*/
|
290
|
+
function isSemicolonToken(token) {
|
291
|
+
return token.value === ";" && token.type === "Punctuator";
|
292
|
+
}
|
293
|
+
|
294
|
+
/**
|
295
|
+
* Checks if the given token is a colon token or not.
|
296
|
+
*
|
297
|
+
* @param {Token} token - The token to check.
|
298
|
+
* @returns {boolean} `true` if the token is a colon token.
|
299
|
+
*/
|
300
|
+
function isColonToken(token) {
|
301
|
+
return token.value === ":" && token.type === "Punctuator";
|
302
|
+
}
|
303
|
+
|
304
|
+
/**
|
305
|
+
* Checks if the given token is an opening parenthesis token or not.
|
306
|
+
*
|
307
|
+
* @param {Token} token - The token to check.
|
308
|
+
* @returns {boolean} `true` if the token is an opening parenthesis token.
|
309
|
+
*/
|
310
|
+
function isOpeningParenToken(token) {
|
311
|
+
return token.value === "(" && token.type === "Punctuator";
|
312
|
+
}
|
313
|
+
|
314
|
+
/**
|
315
|
+
* Checks if the given token is a closing parenthesis token or not.
|
316
|
+
*
|
317
|
+
* @param {Token} token - The token to check.
|
318
|
+
* @returns {boolean} `true` if the token is a closing parenthesis token.
|
319
|
+
*/
|
320
|
+
function isClosingParenToken(token) {
|
321
|
+
return token.value === ")" && token.type === "Punctuator";
|
322
|
+
}
|
323
|
+
|
324
|
+
/**
|
325
|
+
* Checks if the given token is an opening square bracket token or not.
|
326
|
+
*
|
327
|
+
* @param {Token} token - The token to check.
|
328
|
+
* @returns {boolean} `true` if the token is an opening square bracket token.
|
329
|
+
*/
|
330
|
+
function isOpeningBracketToken(token) {
|
331
|
+
return token.value === "[" && token.type === "Punctuator";
|
332
|
+
}
|
333
|
+
|
334
|
+
/**
|
335
|
+
* Checks if the given token is a closing square bracket token or not.
|
336
|
+
*
|
337
|
+
* @param {Token} token - The token to check.
|
338
|
+
* @returns {boolean} `true` if the token is a closing square bracket token.
|
339
|
+
*/
|
340
|
+
function isClosingBracketToken(token) {
|
341
|
+
return token.value === "]" && token.type === "Punctuator";
|
342
|
+
}
|
343
|
+
|
344
|
+
/**
|
345
|
+
* Checks if the given token is an opening brace token or not.
|
346
|
+
*
|
347
|
+
* @param {Token} token - The token to check.
|
348
|
+
* @returns {boolean} `true` if the token is an opening brace token.
|
349
|
+
*/
|
350
|
+
function isOpeningBraceToken(token) {
|
351
|
+
return token.value === "{" && token.type === "Punctuator";
|
352
|
+
}
|
353
|
+
|
354
|
+
/**
|
355
|
+
* Checks if the given token is a closing brace token or not.
|
356
|
+
*
|
357
|
+
* @param {Token} token - The token to check.
|
358
|
+
* @returns {boolean} `true` if the token is a closing brace token.
|
359
|
+
*/
|
360
|
+
function isClosingBraceToken(token) {
|
361
|
+
return token.value === "}" && token.type === "Punctuator";
|
362
|
+
}
|
262
363
|
|
263
|
-
|
364
|
+
/**
|
365
|
+
* Checks if the given token is a comment token or not.
|
366
|
+
*
|
367
|
+
* @param {Token} token - The token to check.
|
368
|
+
* @returns {boolean} `true` if the token is a comment token.
|
369
|
+
*/
|
370
|
+
function isCommentToken(token) {
|
371
|
+
return token.type === "Line" || token.type === "Block" || token.type === "Shebang";
|
372
|
+
}
|
373
|
+
|
374
|
+
/**
|
375
|
+
* Checks if the given token is a keyword token or not.
|
376
|
+
*
|
377
|
+
* @param {Token} token - The token to check.
|
378
|
+
* @returns {boolean} `true` if the token is a keyword token.
|
379
|
+
*/
|
380
|
+
function isKeywordToken(token) {
|
381
|
+
return token.type === "Keyword";
|
264
382
|
}
|
265
383
|
|
266
384
|
/**
|
@@ -271,13 +389,18 @@ function getArrowToken(node, sourceCode) {
|
|
271
389
|
* @returns {Token} `(` token.
|
272
390
|
*/
|
273
391
|
function getOpeningParenOfParams(node, sourceCode) {
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
}
|
392
|
+
return node.id
|
393
|
+
? sourceCode.getTokenAfter(node.id, isOpeningParenToken)
|
394
|
+
: sourceCode.getFirstToken(node, isOpeningParenToken);
|
395
|
+
}
|
279
396
|
|
280
|
-
|
397
|
+
/**
|
398
|
+
* Creates a version of the LINEBREAK_MATCHER regex with the global flag.
|
399
|
+
* Global regexes are mutable, so this needs to be a function instead of a constant.
|
400
|
+
* @returns {RegExp} A global regular expression that matches line terminators
|
401
|
+
*/
|
402
|
+
function createGlobalLinebreakMatcher() {
|
403
|
+
return new RegExp(LINEBREAK_MATCHER.source, "g");
|
281
404
|
}
|
282
405
|
|
283
406
|
const lineIndexCache = new WeakMap();
|
@@ -290,8 +413,23 @@ const lineIndexCache = new WeakMap();
|
|
290
413
|
function getLineIndices(sourceCode) {
|
291
414
|
|
292
415
|
if (!lineIndexCache.has(sourceCode)) {
|
293
|
-
const lineIndices =
|
294
|
-
|
416
|
+
const lineIndices = [0];
|
417
|
+
const lineEndingPattern = createGlobalLinebreakMatcher();
|
418
|
+
let match;
|
419
|
+
|
420
|
+
/*
|
421
|
+
* Previously, this function was implemented using a regex that
|
422
|
+
* matched a sequence of non-linebreak characters followed by a
|
423
|
+
* linebreak, then adding the lengths of the matches. However,
|
424
|
+
* this caused a catastrophic backtracking issue when the end
|
425
|
+
* of a file contained a large number of non-newline characters.
|
426
|
+
* To avoid this, the current implementation just matches newlines
|
427
|
+
* and uses match.index to get the correct line start indices.
|
428
|
+
*/
|
429
|
+
|
430
|
+
while ((match = lineEndingPattern.exec(sourceCode.text))) {
|
431
|
+
lineIndices.push(match.index + match[0].length);
|
432
|
+
}
|
295
433
|
|
296
434
|
// Store the sourceCode object in a WeakMap to avoid iterating over all of the lines every time a sourceCode object is passed in.
|
297
435
|
lineIndexCache.set(sourceCode, lineIndices);
|
@@ -304,6 +442,9 @@ function getLineIndices(sourceCode) {
|
|
304
442
|
//------------------------------------------------------------------------------
|
305
443
|
|
306
444
|
module.exports = {
|
445
|
+
LINEBREAKS,
|
446
|
+
LINEBREAK_MATCHER,
|
447
|
+
STATEMENT_LIST_PARENTS,
|
307
448
|
|
308
449
|
/**
|
309
450
|
* Determines whether two adjacent tokens are on the same line.
|
@@ -325,6 +466,29 @@ module.exports = {
|
|
325
466
|
isInLoop,
|
326
467
|
isArrayFromMethod,
|
327
468
|
isParenthesised,
|
469
|
+
createGlobalLinebreakMatcher,
|
470
|
+
|
471
|
+
isArrowToken,
|
472
|
+
isClosingBraceToken,
|
473
|
+
isClosingBracketToken,
|
474
|
+
isClosingParenToken,
|
475
|
+
isColonToken,
|
476
|
+
isCommaToken,
|
477
|
+
isCommentToken,
|
478
|
+
isKeywordToken,
|
479
|
+
isNotClosingBraceToken: negate(isClosingBraceToken),
|
480
|
+
isNotClosingBracketToken: negate(isClosingBracketToken),
|
481
|
+
isNotClosingParenToken: negate(isClosingParenToken),
|
482
|
+
isNotColonToken: negate(isColonToken),
|
483
|
+
isNotCommaToken: negate(isCommaToken),
|
484
|
+
isNotOpeningBraceToken: negate(isOpeningBraceToken),
|
485
|
+
isNotOpeningBracketToken: negate(isOpeningBracketToken),
|
486
|
+
isNotOpeningParenToken: negate(isOpeningParenToken),
|
487
|
+
isNotSemicolonToken: negate(isSemicolonToken),
|
488
|
+
isOpeningBraceToken,
|
489
|
+
isOpeningBracketToken,
|
490
|
+
isOpeningParenToken,
|
491
|
+
isSemicolonToken,
|
328
492
|
|
329
493
|
/**
|
330
494
|
* Checks whether or not a given node is a string literal.
|
@@ -658,6 +822,8 @@ module.exports = {
|
|
658
822
|
case "/":
|
659
823
|
case "%":
|
660
824
|
return 13;
|
825
|
+
case "**":
|
826
|
+
return 15;
|
661
827
|
|
662
828
|
// no default
|
663
829
|
}
|
@@ -666,10 +832,10 @@ module.exports = {
|
|
666
832
|
|
667
833
|
case "UnaryExpression":
|
668
834
|
case "AwaitExpression":
|
669
|
-
return
|
835
|
+
return 16;
|
670
836
|
|
671
837
|
case "UpdateExpression":
|
672
|
-
return
|
838
|
+
return 17;
|
673
839
|
|
674
840
|
case "CallExpression":
|
675
841
|
|
@@ -677,14 +843,14 @@ module.exports = {
|
|
677
843
|
if (node.callee.type === "FunctionExpression") {
|
678
844
|
return -1;
|
679
845
|
}
|
680
|
-
return
|
846
|
+
return 18;
|
681
847
|
|
682
848
|
case "NewExpression":
|
683
|
-
return
|
849
|
+
return 19;
|
684
850
|
|
685
851
|
// no default
|
686
852
|
}
|
687
|
-
return
|
853
|
+
return 20;
|
688
854
|
},
|
689
855
|
|
690
856
|
/**
|
@@ -1023,7 +1189,7 @@ module.exports = {
|
|
1023
1189
|
let end = null;
|
1024
1190
|
|
1025
1191
|
if (node.type === "ArrowFunctionExpression") {
|
1026
|
-
const arrowToken =
|
1192
|
+
const arrowToken = sourceCode.getTokenBefore(node.body, isArrowToken);
|
1027
1193
|
|
1028
1194
|
start = arrowToken.loc.start;
|
1029
1195
|
end = arrowToken.loc.end;
|
@@ -1037,7 +1203,7 @@ module.exports = {
|
|
1037
1203
|
|
1038
1204
|
return {
|
1039
1205
|
start: Object.assign({}, start),
|
1040
|
-
end: Object.assign({}, end)
|
1206
|
+
end: Object.assign({}, end)
|
1041
1207
|
};
|
1042
1208
|
},
|
1043
1209
|
|
@@ -1097,5 +1263,58 @@ module.exports = {
|
|
1097
1263
|
}
|
1098
1264
|
|
1099
1265
|
return sourceCode.getText().slice(leftToken.range[0], rightToken.range[1]);
|
1266
|
+
},
|
1267
|
+
|
1268
|
+
/*
|
1269
|
+
* Determine if a node has a possiblity to be an Error object
|
1270
|
+
* @param {ASTNode} node ASTNode to check
|
1271
|
+
* @returns {boolean} True if there is a chance it contains an Error obj
|
1272
|
+
*/
|
1273
|
+
couldBeError(node) {
|
1274
|
+
switch (node.type) {
|
1275
|
+
case "Identifier":
|
1276
|
+
case "CallExpression":
|
1277
|
+
case "NewExpression":
|
1278
|
+
case "MemberExpression":
|
1279
|
+
case "TaggedTemplateExpression":
|
1280
|
+
case "YieldExpression":
|
1281
|
+
case "AwaitExpression":
|
1282
|
+
return true; // possibly an error object.
|
1283
|
+
|
1284
|
+
case "AssignmentExpression":
|
1285
|
+
return module.exports.couldBeError(node.right);
|
1286
|
+
|
1287
|
+
case "SequenceExpression": {
|
1288
|
+
const exprs = node.expressions;
|
1289
|
+
|
1290
|
+
return exprs.length !== 0 && module.exports.couldBeError(exprs[exprs.length - 1]);
|
1291
|
+
}
|
1292
|
+
|
1293
|
+
case "LogicalExpression":
|
1294
|
+
return module.exports.couldBeError(node.left) || module.exports.couldBeError(node.right);
|
1295
|
+
|
1296
|
+
case "ConditionalExpression":
|
1297
|
+
return module.exports.couldBeError(node.consequent) || module.exports.couldBeError(node.alternate);
|
1298
|
+
|
1299
|
+
default:
|
1300
|
+
return false;
|
1301
|
+
}
|
1302
|
+
},
|
1303
|
+
|
1304
|
+
/**
|
1305
|
+
* Determines whether the given node is a `null` literal.
|
1306
|
+
* @param {ASTNode} node The node to check
|
1307
|
+
* @returns {boolean} `true` if the node is a `null` literal
|
1308
|
+
*/
|
1309
|
+
isNullLiteral(node) {
|
1310
|
+
|
1311
|
+
/*
|
1312
|
+
* Checking `node.value === null` does not guarantee that a literal is a null literal.
|
1313
|
+
* When parsing values that cannot be represented in the current environment (e.g. unicode
|
1314
|
+
* regexes in Node 4), `node.value` is set to `null` because it wouldn't be possible to
|
1315
|
+
* set `node.value` to a unicode regex. To make sure a literal is actually `null`, check
|
1316
|
+
* `node.regex` instead. Also see: https://github.com/eslint/eslint/issues/8020
|
1317
|
+
*/
|
1318
|
+
return node.type === "Literal" && node.value === null && !node.regex;
|
1100
1319
|
}
|
1101
1320
|
};
|
package/lib/cli.js
CHANGED
@@ -467,8 +467,8 @@ class CodePathState {
|
|
467
467
|
* Creates the next path from own true/false fork context.
|
468
468
|
*/
|
469
469
|
const prevForkContext =
|
470
|
-
context.kind === "&&" ? context.trueForkContext
|
471
|
-
/* kind === "||" */ context.falseForkContext;
|
470
|
+
context.kind === "&&" ? context.trueForkContext
|
471
|
+
/* kind === "||" */ : context.falseForkContext;
|
472
472
|
|
473
473
|
forkContext.replaceHead(prevForkContext.makeNext(0, -1));
|
474
474
|
prevForkContext.clear();
|
package/lib/config/autoconfig.js
CHANGED
@@ -13,7 +13,7 @@ const lodash = require("lodash"),
|
|
13
13
|
eslint = require("../eslint"),
|
14
14
|
configRule = require("./config-rule"),
|
15
15
|
ConfigOps = require("./config-ops"),
|
16
|
-
recConfig = require("../../conf/eslint
|
16
|
+
recConfig = require("../../conf/eslint-recommended");
|
17
17
|
|
18
18
|
const debug = require("debug")("eslint:autoconfig");
|
19
19
|
|
@@ -65,17 +65,16 @@ function makeRegistryItems(rulesConfig) {
|
|
65
65
|
* Unless a rulesConfig is provided at construction, the registry will not contain
|
66
66
|
* any rules, only methods. This will be useful for building up registries manually.
|
67
67
|
*
|
68
|
-
*
|
69
|
-
* @class Registry
|
70
|
-
* @param {rulesConfig} [rulesConfig] Hash of rule names and arrays of possible configurations
|
68
|
+
* Registry class
|
71
69
|
*/
|
72
|
-
|
73
|
-
this.rules = (rulesConfig) ? makeRegistryItems(rulesConfig) : {};
|
74
|
-
}
|
75
|
-
|
76
|
-
Registry.prototype = {
|
70
|
+
class Registry {
|
77
71
|
|
78
|
-
|
72
|
+
/**
|
73
|
+
* @param {rulesConfig} [rulesConfig] Hash of rule names and arrays of possible configurations
|
74
|
+
*/
|
75
|
+
constructor(rulesConfig) {
|
76
|
+
this.rules = (rulesConfig) ? makeRegistryItems(rulesConfig) : {};
|
77
|
+
}
|
79
78
|
|
80
79
|
/**
|
81
80
|
* Populate the registry with core rule configs.
|
@@ -89,7 +88,7 @@ Registry.prototype = {
|
|
89
88
|
const rulesConfig = configRule.createCoreRuleConfigs();
|
90
89
|
|
91
90
|
this.rules = makeRegistryItems(rulesConfig);
|
92
|
-
}
|
91
|
+
}
|
93
92
|
|
94
93
|
/**
|
95
94
|
* Creates sets of rule configurations which can be used for linting
|
@@ -156,7 +155,7 @@ Registry.prototype = {
|
|
156
155
|
}
|
157
156
|
|
158
157
|
return ruleSets;
|
159
|
-
}
|
158
|
+
}
|
160
159
|
|
161
160
|
/**
|
162
161
|
* Remove all items from the registry with a non-zero number of errors
|
@@ -182,7 +181,7 @@ Registry.prototype = {
|
|
182
181
|
});
|
183
182
|
|
184
183
|
return newRegistry;
|
185
|
-
}
|
184
|
+
}
|
186
185
|
|
187
186
|
/**
|
188
187
|
* Removes rule configurations which were not included in a ruleSet
|
@@ -199,7 +198,7 @@ Registry.prototype = {
|
|
199
198
|
});
|
200
199
|
|
201
200
|
return newRegistry;
|
202
|
-
}
|
201
|
+
}
|
203
202
|
|
204
203
|
/**
|
205
204
|
* Creates a registry of rules which had no error-free configs.
|
@@ -221,7 +220,7 @@ Registry.prototype = {
|
|
221
220
|
});
|
222
221
|
|
223
222
|
return failingRegistry;
|
224
|
-
}
|
223
|
+
}
|
225
224
|
|
226
225
|
/**
|
227
226
|
* Create an eslint config for any rules which only have one configuration
|
@@ -240,7 +239,7 @@ Registry.prototype = {
|
|
240
239
|
});
|
241
240
|
|
242
241
|
return config;
|
243
|
-
}
|
242
|
+
}
|
244
243
|
|
245
244
|
/**
|
246
245
|
* Return a cloned registry containing only configs with a desired specificity
|
@@ -258,7 +257,7 @@ Registry.prototype = {
|
|
258
257
|
});
|
259
258
|
|
260
259
|
return newRegistry;
|
261
|
-
}
|
260
|
+
}
|
262
261
|
|
263
262
|
/**
|
264
263
|
* Lint SourceCodes against all configurations in the registry, and record results
|
@@ -297,8 +296,13 @@ Registry.prototype = {
|
|
297
296
|
|
298
297
|
// It is possible that the error is from a configuration comment
|
299
298
|
// in a linted file, in which case there may not be a config
|
300
|
-
// set in this ruleSetIdx.
|
301
|
-
|
299
|
+
// set in this ruleSetIdx.
|
300
|
+
// (https://github.com/eslint/eslint/issues/5992)
|
301
|
+
// (https://github.com/eslint/eslint/issues/7860)
|
302
|
+
if (
|
303
|
+
lintedRegistry.rules[result.ruleId] &&
|
304
|
+
lintedRegistry.rules[result.ruleId][ruleSetIdx]
|
305
|
+
) {
|
302
306
|
lintedRegistry.rules[result.ruleId][ruleSetIdx].errorCount += 1;
|
303
307
|
}
|
304
308
|
});
|
@@ -316,7 +320,7 @@ Registry.prototype = {
|
|
316
320
|
|
317
321
|
return lintedRegistry;
|
318
322
|
}
|
319
|
-
}
|
323
|
+
}
|
320
324
|
|
321
325
|
/**
|
322
326
|
* Extract rule configuration into eslint:recommended where possible.
|
@@ -23,7 +23,7 @@ const fs = require("fs"),
|
|
23
23
|
stripBom = require("strip-bom"),
|
24
24
|
stripComments = require("strip-json-comments"),
|
25
25
|
stringify = require("json-stable-stringify"),
|
26
|
-
defaultOptions = require("../../conf/eslint
|
26
|
+
defaultOptions = require("../../conf/eslint-recommended"),
|
27
27
|
requireUncached = require("require-uncached");
|
28
28
|
|
29
29
|
const debug = require("debug")("eslint:config-file");
|
@@ -364,10 +364,10 @@ function applyExtends(config, filePath, relativeTo) {
|
|
364
364
|
if (parentPath === "eslint:recommended") {
|
365
365
|
|
366
366
|
/*
|
367
|
-
* Add an explicit substitution for eslint:recommended to
|
368
|
-
*
|
367
|
+
* Add an explicit substitution for eslint:recommended to
|
368
|
+
* conf/eslint-recommended.js.
|
369
369
|
*/
|
370
|
-
parentPath = path.resolve(__dirname, "../../conf/eslint.
|
370
|
+
parentPath = path.resolve(__dirname, "../../conf/eslint-recommended.js");
|
371
371
|
} else if (parentPath === "eslint:all") {
|
372
372
|
|
373
373
|
/*
|
@@ -380,9 +380,9 @@ function applyExtends(config, filePath, relativeTo) {
|
|
380
380
|
* If the `extends` path is relative, use the directory of the current configuration
|
381
381
|
* file as the reference point. Otherwise, use as-is.
|
382
382
|
*/
|
383
|
-
parentPath = (!path.isAbsolute(parentPath)
|
384
|
-
path.join(relativeTo || path.dirname(filePath), parentPath)
|
385
|
-
parentPath
|
383
|
+
parentPath = (!path.isAbsolute(parentPath)
|
384
|
+
? path.join(relativeTo || path.dirname(filePath), parentPath)
|
385
|
+
: parentPath
|
386
386
|
);
|
387
387
|
}
|
388
388
|
|
@@ -390,6 +390,13 @@ function applyExtends(config, filePath, relativeTo) {
|
|
390
390
|
debug(`Loading ${parentPath}`);
|
391
391
|
return ConfigOps.merge(load(parentPath, false, relativeTo), previousValue);
|
392
392
|
} catch (e) {
|
393
|
+
if (parentPath.indexOf("plugin:") === 0 || parentPath.indexOf("eslint:") === 0) {
|
394
|
+
e.message = `Failed to load config "${parentPath}" to extend from.`;
|
395
|
+
e.messageTemplate = "extend-config-missing";
|
396
|
+
e.messageData = {
|
397
|
+
configName: parentPath
|
398
|
+
};
|
399
|
+
}
|
393
400
|
|
394
401
|
/*
|
395
402
|
* If the file referenced by `extends` failed to load, add the path
|
@@ -461,24 +468,24 @@ function normalizePackageName(name, prefix) {
|
|
461
468
|
function resolve(filePath, relativeTo) {
|
462
469
|
if (isFilePath(filePath)) {
|
463
470
|
return { filePath: path.resolve(relativeTo || "", filePath) };
|
464
|
-
} else {
|
465
|
-
let normalizedPackageName;
|
466
|
-
|
467
|
-
if (filePath.indexOf("plugin:") === 0) {
|
468
|
-
const packagePath = filePath.substr(7, filePath.lastIndexOf("/") - 7);
|
469
|
-
const configName = filePath.substr(filePath.lastIndexOf("/") + 1, filePath.length - filePath.lastIndexOf("/") - 1);
|
470
|
-
|
471
|
-
normalizedPackageName = normalizePackageName(packagePath, "eslint-plugin");
|
472
|
-
debug(`Attempting to resolve ${normalizedPackageName}`);
|
473
|
-
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
|
474
|
-
return { filePath, configName };
|
475
|
-
} else {
|
476
|
-
normalizedPackageName = normalizePackageName(filePath, "eslint-config");
|
477
|
-
debug(`Attempting to resolve ${normalizedPackageName}`);
|
478
|
-
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
|
479
|
-
return { filePath };
|
480
|
-
}
|
481
471
|
}
|
472
|
+
let normalizedPackageName;
|
473
|
+
|
474
|
+
if (filePath.indexOf("plugin:") === 0) {
|
475
|
+
const packagePath = filePath.substr(7, filePath.lastIndexOf("/") - 7);
|
476
|
+
const configName = filePath.substr(filePath.lastIndexOf("/") + 1, filePath.length - filePath.lastIndexOf("/") - 1);
|
477
|
+
|
478
|
+
normalizedPackageName = normalizePackageName(packagePath, "eslint-plugin");
|
479
|
+
debug(`Attempting to resolve ${normalizedPackageName}`);
|
480
|
+
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
|
481
|
+
return { filePath, configName };
|
482
|
+
}
|
483
|
+
normalizedPackageName = normalizePackageName(filePath, "eslint-config");
|
484
|
+
debug(`Attempting to resolve ${normalizedPackageName}`);
|
485
|
+
filePath = resolver.resolve(normalizedPackageName, getLookupPath(relativeTo));
|
486
|
+
return { filePath };
|
487
|
+
|
488
|
+
|
482
489
|
|
483
490
|
}
|
484
491
|
|
@@ -17,7 +17,7 @@ const util = require("util"),
|
|
17
17
|
ConfigOps = require("./config-ops"),
|
18
18
|
getSourceCodeOfFiles = require("../util/source-code-util").getSourceCodeOfFiles,
|
19
19
|
npmUtil = require("../util/npm-util"),
|
20
|
-
recConfig = require("../../conf/eslint
|
20
|
+
recConfig = require("../../conf/eslint-recommended"),
|
21
21
|
log = require("../logging");
|
22
22
|
|
23
23
|
const debug = require("debug")("eslint:config-initializer");
|
@@ -317,7 +317,7 @@ function promptUser(callback) {
|
|
317
317
|
default: false,
|
318
318
|
when(answers) {
|
319
319
|
return answers.styleguide === "airbnb";
|
320
|
-
}
|
320
|
+
}
|
321
321
|
},
|
322
322
|
{
|
323
323
|
type: "input",
|