eslint 6.6.0 → 6.8.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 +94 -0
- package/README.md +7 -8
- package/conf/config-schema.js +2 -0
- package/conf/default-cli-options.js +1 -1
- package/conf/eslint-recommended.js +0 -1
- package/lib/cli-engine/cascading-config-array-factory.js +38 -13
- package/lib/cli-engine/cli-engine.js +41 -14
- package/lib/cli-engine/config-array/config-array.js +13 -0
- package/lib/cli-engine/config-array/extracted-config.js +27 -0
- package/lib/cli-engine/config-array/ignore-pattern.js +231 -0
- package/lib/cli-engine/config-array/index.js +2 -0
- package/lib/cli-engine/config-array-factory.js +115 -1
- package/lib/cli-engine/file-enumerator.js +73 -40
- package/lib/cli-engine/lint-result-cache.js +2 -1
- package/lib/cli.js +2 -1
- package/lib/init/config-initializer.js +4 -3
- package/lib/linter/config-comment-parser.js +1 -1
- package/lib/linter/report-translator.js +73 -7
- package/lib/options.js +6 -0
- package/lib/rule-tester/rule-tester.js +42 -6
- package/lib/rules/array-bracket-spacing.js +8 -8
- package/lib/rules/camelcase.js +19 -6
- package/lib/rules/comma-dangle.js +5 -2
- package/lib/rules/computed-property-spacing.js +4 -4
- package/lib/rules/curly.js +9 -4
- package/lib/rules/function-call-argument-newline.js +3 -1
- package/lib/rules/grouped-accessor-pairs.js +224 -0
- package/lib/rules/indent.js +11 -0
- package/lib/rules/index.js +5 -0
- package/lib/rules/key-spacing.js +34 -15
- package/lib/rules/lines-between-class-members.js +42 -53
- package/lib/rules/multiline-comment-style.js +237 -106
- package/lib/rules/no-cond-assign.js +14 -4
- package/lib/rules/no-constructor-return.js +62 -0
- package/lib/rules/no-dupe-else-if.js +122 -0
- package/lib/rules/no-implicit-globals.js +90 -8
- package/lib/rules/no-inline-comments.js +25 -11
- package/lib/rules/no-invalid-this.js +16 -2
- package/lib/rules/no-multiple-empty-lines.js +1 -1
- package/lib/rules/no-octal-escape.js +1 -1
- package/lib/rules/no-restricted-imports.js +2 -2
- package/lib/rules/no-setter-return.js +227 -0
- package/lib/rules/no-underscore-dangle.js +23 -4
- package/lib/rules/no-unexpected-multiline.js +8 -0
- package/lib/rules/no-unsafe-negation.js +30 -5
- package/lib/rules/no-useless-computed-key.js +60 -33
- package/lib/rules/no-useless-escape.js +26 -3
- package/lib/rules/object-curly-spacing.js +8 -8
- package/lib/rules/operator-assignment.js +11 -2
- package/lib/rules/prefer-const.js +14 -7
- package/lib/rules/prefer-exponentiation-operator.js +189 -0
- package/lib/rules/prefer-numeric-literals.js +29 -28
- package/lib/rules/require-atomic-updates.js +1 -1
- package/lib/rules/require-await.js +8 -0
- package/lib/rules/semi.js +6 -3
- package/lib/rules/space-infix-ops.js +1 -1
- package/lib/rules/spaced-comment.js +5 -4
- package/lib/rules/utils/ast-utils.js +31 -4
- package/lib/shared/types.js +9 -0
- package/lib/source-code/source-code.js +87 -10
- package/package.json +4 -3
- package/lib/cli-engine/ignored-paths.js +0 -363
@@ -15,6 +15,12 @@ const astUtils = require("./utils/ast-utils");
|
|
15
15
|
// Helpers
|
16
16
|
//------------------------------------------------------------------------------
|
17
17
|
|
18
|
+
const radixMap = new Map([
|
19
|
+
[2, { system: "binary", literalPrefix: "0b" }],
|
20
|
+
[8, { system: "octal", literalPrefix: "0o" }],
|
21
|
+
[16, { system: "hexadecimal", literalPrefix: "0x" }]
|
22
|
+
]);
|
23
|
+
|
18
24
|
/**
|
19
25
|
* Checks to see if a CallExpression's callee node is `parseInt` or
|
20
26
|
* `Number.parseInt`.
|
@@ -54,49 +60,44 @@ module.exports = {
|
|
54
60
|
},
|
55
61
|
|
56
62
|
schema: [],
|
63
|
+
|
64
|
+
messages: {
|
65
|
+
useLiteral: "Use {{system}} literals instead of {{functionName}}()."
|
66
|
+
},
|
67
|
+
|
57
68
|
fixable: "code"
|
58
69
|
},
|
59
70
|
|
60
71
|
create(context) {
|
61
72
|
const sourceCode = context.getSourceCode();
|
62
73
|
|
63
|
-
const radixMap = {
|
64
|
-
2: "binary",
|
65
|
-
8: "octal",
|
66
|
-
16: "hexadecimal"
|
67
|
-
};
|
68
|
-
|
69
|
-
const prefixMap = {
|
70
|
-
2: "0b",
|
71
|
-
8: "0o",
|
72
|
-
16: "0x"
|
73
|
-
};
|
74
|
-
|
75
74
|
//----------------------------------------------------------------------
|
76
75
|
// Public
|
77
76
|
//----------------------------------------------------------------------
|
78
77
|
|
79
78
|
return {
|
80
79
|
|
81
|
-
CallExpression(node) {
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
80
|
+
"CallExpression[arguments.length=2]"(node) {
|
81
|
+
const [strNode, radixNode] = node.arguments,
|
82
|
+
str = strNode.value,
|
83
|
+
radix = radixNode.value;
|
84
|
+
|
85
|
+
if (
|
86
|
+
strNode.type === "Literal" &&
|
87
|
+
radixNode.type === "Literal" &&
|
88
|
+
typeof str === "string" &&
|
89
|
+
typeof radix === "number" &&
|
90
|
+
radixMap.has(radix) &&
|
91
|
+
isParseInt(node.callee)
|
92
|
+
) {
|
87
93
|
|
88
|
-
|
89
|
-
const radixName = radixMap[node.arguments[1].value];
|
94
|
+
const { system, literalPrefix } = radixMap.get(radix);
|
90
95
|
|
91
|
-
if (isParseInt(node.callee) &&
|
92
|
-
radixName &&
|
93
|
-
node.arguments[0].type === "Literal"
|
94
|
-
) {
|
95
96
|
context.report({
|
96
97
|
node,
|
97
|
-
|
98
|
+
messageId: "useLiteral",
|
98
99
|
data: {
|
99
|
-
|
100
|
+
system,
|
100
101
|
functionName: sourceCode.getText(node.callee)
|
101
102
|
},
|
102
103
|
fix(fixer) {
|
@@ -104,9 +105,9 @@ module.exports = {
|
|
104
105
|
return null;
|
105
106
|
}
|
106
107
|
|
107
|
-
const replacement = `${
|
108
|
+
const replacement = `${literalPrefix}${str}`;
|
108
109
|
|
109
|
-
if (+replacement !== parseInt(
|
110
|
+
if (+replacement !== parseInt(str, radix)) {
|
110
111
|
|
111
112
|
/*
|
112
113
|
* If the newly-produced literal would be invalid, (e.g. 0b1234),
|
@@ -162,7 +162,7 @@ module.exports = {
|
|
162
162
|
docs: {
|
163
163
|
description: "disallow assignments that can lead to race conditions due to usage of `await` or `yield`",
|
164
164
|
category: "Possible Errors",
|
165
|
-
recommended:
|
165
|
+
recommended: false,
|
166
166
|
url: "https://eslint.org/docs/rules/require-atomic-updates"
|
167
167
|
},
|
168
168
|
|
@@ -89,9 +89,17 @@ module.exports = {
|
|
89
89
|
"ArrowFunctionExpression:exit": exitFunction,
|
90
90
|
|
91
91
|
AwaitExpression() {
|
92
|
+
if (!scopeInfo) {
|
93
|
+
return;
|
94
|
+
}
|
95
|
+
|
92
96
|
scopeInfo.hasAwait = true;
|
93
97
|
},
|
94
98
|
ForOfStatement(node) {
|
99
|
+
if (!scopeInfo) {
|
100
|
+
return;
|
101
|
+
}
|
102
|
+
|
95
103
|
if (node.await) {
|
96
104
|
scopeInfo.hasAwait = true;
|
97
105
|
}
|
package/lib/rules/semi.js
CHANGED
@@ -93,17 +93,20 @@ module.exports = {
|
|
93
93
|
const lastToken = sourceCode.getLastToken(node);
|
94
94
|
let message,
|
95
95
|
fix,
|
96
|
-
loc
|
96
|
+
loc;
|
97
97
|
|
98
98
|
if (!missing) {
|
99
99
|
message = "Missing semicolon.";
|
100
|
-
loc =
|
100
|
+
loc = {
|
101
|
+
start: lastToken.loc.end,
|
102
|
+
end: astUtils.getNextLocation(sourceCode, lastToken.loc.end)
|
103
|
+
};
|
101
104
|
fix = function(fixer) {
|
102
105
|
return fixer.insertTextAfter(lastToken, ";");
|
103
106
|
};
|
104
107
|
} else {
|
105
108
|
message = "Extra semicolon.";
|
106
|
-
loc = loc
|
109
|
+
loc = lastToken.loc;
|
107
110
|
fix = function(fixer) {
|
108
111
|
|
109
112
|
/*
|
@@ -249,7 +249,8 @@ module.exports = {
|
|
249
249
|
beginRegex: requireSpace ? createAlwaysStylePattern(markers, exceptions) : createNeverStylePattern(markers),
|
250
250
|
endRegex: balanced && requireSpace ? new RegExp(`${createExceptionsPattern(exceptions)}$`, "u") : new RegExp(endNeverPattern, "u"),
|
251
251
|
hasExceptions: exceptions.length > 0,
|
252
|
-
|
252
|
+
captureMarker: new RegExp(`^(${markers.map(escape).join("|")})`, "u"),
|
253
|
+
markers: new Set(markers)
|
253
254
|
};
|
254
255
|
|
255
256
|
return rule;
|
@@ -322,8 +323,8 @@ module.exports = {
|
|
322
323
|
rule = styleRules[type],
|
323
324
|
commentIdentifier = type === "block" ? "/*" : "//";
|
324
325
|
|
325
|
-
// Ignores empty comments.
|
326
|
-
if (node.value.length === 0) {
|
326
|
+
// Ignores empty comments and comments that consist only of a marker.
|
327
|
+
if (node.value.length === 0 || rule.markers.has(node.value)) {
|
327
328
|
return;
|
328
329
|
}
|
329
330
|
|
@@ -333,7 +334,7 @@ module.exports = {
|
|
333
334
|
// Checks.
|
334
335
|
if (requireSpace) {
|
335
336
|
if (!beginMatch) {
|
336
|
-
const hasMarker = rule.
|
337
|
+
const hasMarker = rule.captureMarker.exec(node.value);
|
337
338
|
const marker = hasMarker ? commentIdentifier + hasMarker[0] : commentIdentifier;
|
338
339
|
|
339
340
|
if (rule.hasExceptions) {
|
@@ -581,23 +581,31 @@ module.exports = {
|
|
581
581
|
*
|
582
582
|
* First, this checks the node:
|
583
583
|
*
|
584
|
-
* - The function name does not start with uppercase
|
584
|
+
* - The function name does not start with uppercase. It's a convention to capitalize the names
|
585
|
+
* of constructor functions. This check is not performed if `capIsConstructor` is set to `false`.
|
585
586
|
* - The function does not have a JSDoc comment that has a @this tag.
|
586
587
|
*
|
587
588
|
* Next, this checks the location of the node.
|
588
589
|
* If the location is below, this judges `this` is valid.
|
589
590
|
*
|
590
591
|
* - The location is not on an object literal.
|
591
|
-
* - The location is not assigned to a variable which starts with an uppercase letter.
|
592
|
+
* - The location is not assigned to a variable which starts with an uppercase letter. Applies to anonymous
|
593
|
+
* functions only, as the name of the variable is considered to be the name of the function in this case.
|
594
|
+
* This check is not performed if `capIsConstructor` is set to `false`.
|
592
595
|
* - The location is not on an ES2015 class.
|
593
596
|
* - Its `bind`/`call`/`apply` method is not called directly.
|
594
597
|
* - The function is not a callback of array methods (such as `.forEach()`) if `thisArg` is given.
|
595
598
|
* @param {ASTNode} node A function node to check.
|
596
599
|
* @param {SourceCode} sourceCode A SourceCode instance to get comments.
|
600
|
+
* @param {boolean} [capIsConstructor = true] `false` disables the assumption that functions which name starts
|
601
|
+
* with an uppercase or are assigned to a variable which name starts with an uppercase are constructors.
|
597
602
|
* @returns {boolean} The function node is the default `this` binding.
|
598
603
|
*/
|
599
|
-
isDefaultThisBinding(node, sourceCode) {
|
600
|
-
if (
|
604
|
+
isDefaultThisBinding(node, sourceCode, { capIsConstructor = true } = {}) {
|
605
|
+
if (
|
606
|
+
(capIsConstructor && isES5Constructor(node)) ||
|
607
|
+
hasJSDocThisTag(node, sourceCode)
|
608
|
+
) {
|
601
609
|
return false;
|
602
610
|
}
|
603
611
|
const isAnonymous = node.id === null;
|
@@ -671,6 +679,7 @@ module.exports = {
|
|
671
679
|
return false;
|
672
680
|
}
|
673
681
|
if (
|
682
|
+
capIsConstructor &&
|
674
683
|
isAnonymous &&
|
675
684
|
parent.left.type === "Identifier" &&
|
676
685
|
startsWithUpperCase(parent.left.name)
|
@@ -685,6 +694,7 @@ module.exports = {
|
|
685
694
|
*/
|
686
695
|
case "VariableDeclarator":
|
687
696
|
return !(
|
697
|
+
capIsConstructor &&
|
688
698
|
isAnonymous &&
|
689
699
|
parent.init === currentNode &&
|
690
700
|
parent.id.type === "Identifier" &&
|
@@ -1200,6 +1210,23 @@ module.exports = {
|
|
1200
1210
|
};
|
1201
1211
|
},
|
1202
1212
|
|
1213
|
+
/**
|
1214
|
+
* Gets next location when the result is not out of bound, otherwise returns null.
|
1215
|
+
* @param {SourceCode} sourceCode The sourceCode
|
1216
|
+
* @param {{line: number, column: number}} location The location
|
1217
|
+
* @returns {{line: number, column: number} | null} Next location
|
1218
|
+
*/
|
1219
|
+
getNextLocation(sourceCode, location) {
|
1220
|
+
const index = sourceCode.getIndexFromLoc(location);
|
1221
|
+
|
1222
|
+
// Avoid out of bound location
|
1223
|
+
if (index + 1 > sourceCode.text.length) {
|
1224
|
+
return null;
|
1225
|
+
}
|
1226
|
+
|
1227
|
+
return sourceCode.getLocFromIndex(index + 1);
|
1228
|
+
},
|
1229
|
+
|
1203
1230
|
/**
|
1204
1231
|
* Gets the parenthesized text of a node. This is similar to sourceCode.getText(node), but it also includes any parentheses
|
1205
1232
|
* surrounding the node.
|
package/lib/shared/types.js
CHANGED
@@ -30,6 +30,7 @@ module.exports = {};
|
|
30
30
|
* @property {Record<string, boolean>} [env] The environment settings.
|
31
31
|
* @property {string | string[]} [extends] The path to other config files or the package name of shareable configs.
|
32
32
|
* @property {Record<string, GlobalConf>} [globals] The global variable settings.
|
33
|
+
* @property {string | string[]} [ignorePatterns] The glob patterns that ignore to lint.
|
33
34
|
* @property {boolean} [noInlineConfig] The flag that disables directive comments.
|
34
35
|
* @property {OverrideConfigData[]} [overrides] The override settings per kind of files.
|
35
36
|
* @property {string} [parser] The path to a parser or the package name of a parser.
|
@@ -91,6 +92,14 @@ module.exports = {};
|
|
91
92
|
* @property {string} message The error message.
|
92
93
|
* @property {string|null} ruleId The ID of the rule which makes this message.
|
93
94
|
* @property {0|1|2} severity The severity of this message.
|
95
|
+
* @property {Array<{desc?: string, messageId?: string, fix: {range: [number, number], text: string}}>} [suggestions] Information for suggestions.
|
96
|
+
*/
|
97
|
+
|
98
|
+
/**
|
99
|
+
* @typedef {Object} SuggestionResult
|
100
|
+
* @property {string} desc A short description.
|
101
|
+
* @property {string} [messageId] Id referencing a message for the description.
|
102
|
+
* @property {{ text: string, range: number[] }} fix fix result info
|
94
103
|
*/
|
95
104
|
|
96
105
|
/**
|
@@ -78,6 +78,68 @@ function sortedMerge(tokens, comments) {
|
|
78
78
|
return result;
|
79
79
|
}
|
80
80
|
|
81
|
+
/**
|
82
|
+
* Determines if two nodes or tokens overlap.
|
83
|
+
* @param {ASTNode|Token} first The first node or token to check.
|
84
|
+
* @param {ASTNode|Token} second The second node or token to check.
|
85
|
+
* @returns {boolean} True if the two nodes or tokens overlap.
|
86
|
+
* @private
|
87
|
+
*/
|
88
|
+
function nodesOrTokensOverlap(first, second) {
|
89
|
+
return (first.range[0] <= second.range[0] && first.range[1] >= second.range[0]) ||
|
90
|
+
(second.range[0] <= first.range[0] && second.range[1] >= first.range[0]);
|
91
|
+
}
|
92
|
+
|
93
|
+
/**
|
94
|
+
* Determines if two nodes or tokens have at least one whitespace character
|
95
|
+
* between them. Order does not matter. Returns false if the given nodes or
|
96
|
+
* tokens overlap.
|
97
|
+
* @param {SourceCode} sourceCode The source code object.
|
98
|
+
* @param {ASTNode|Token} first The first node or token to check between.
|
99
|
+
* @param {ASTNode|Token} second The second node or token to check between.
|
100
|
+
* @param {boolean} checkInsideOfJSXText If `true` is present, check inside of JSXText tokens for backward compatibility.
|
101
|
+
* @returns {boolean} True if there is a whitespace character between
|
102
|
+
* any of the tokens found between the two given nodes or tokens.
|
103
|
+
* @public
|
104
|
+
*/
|
105
|
+
function isSpaceBetween(sourceCode, first, second, checkInsideOfJSXText) {
|
106
|
+
if (nodesOrTokensOverlap(first, second)) {
|
107
|
+
return false;
|
108
|
+
}
|
109
|
+
|
110
|
+
const [startingNodeOrToken, endingNodeOrToken] = first.range[1] <= second.range[0]
|
111
|
+
? [first, second]
|
112
|
+
: [second, first];
|
113
|
+
const firstToken = sourceCode.getLastToken(startingNodeOrToken) || startingNodeOrToken;
|
114
|
+
const finalToken = sourceCode.getFirstToken(endingNodeOrToken) || endingNodeOrToken;
|
115
|
+
let currentToken = firstToken;
|
116
|
+
|
117
|
+
while (currentToken !== finalToken) {
|
118
|
+
const nextToken = sourceCode.getTokenAfter(currentToken, { includeComments: true });
|
119
|
+
|
120
|
+
if (
|
121
|
+
currentToken.range[1] !== nextToken.range[0] ||
|
122
|
+
|
123
|
+
/*
|
124
|
+
* For backward compatibility, check speces in JSXText.
|
125
|
+
* https://github.com/eslint/eslint/issues/12614
|
126
|
+
*/
|
127
|
+
(
|
128
|
+
checkInsideOfJSXText &&
|
129
|
+
nextToken !== finalToken &&
|
130
|
+
nextToken.type === "JSXText" &&
|
131
|
+
/\s/u.test(nextToken.value)
|
132
|
+
)
|
133
|
+
) {
|
134
|
+
return true;
|
135
|
+
}
|
136
|
+
|
137
|
+
currentToken = nextToken;
|
138
|
+
}
|
139
|
+
|
140
|
+
return false;
|
141
|
+
}
|
142
|
+
|
81
143
|
//------------------------------------------------------------------------------
|
82
144
|
// Public Interface
|
83
145
|
//------------------------------------------------------------------------------
|
@@ -411,19 +473,34 @@ class SourceCode extends TokenStore {
|
|
411
473
|
}
|
412
474
|
|
413
475
|
/**
|
414
|
-
* Determines if two tokens have at least one whitespace character
|
415
|
-
* between them.
|
416
|
-
*
|
417
|
-
* @param {Token} first The token to check
|
418
|
-
* @param {Token} second The token to check
|
419
|
-
* @returns {boolean} True if there is
|
420
|
-
*
|
476
|
+
* Determines if two nodes or tokens have at least one whitespace character
|
477
|
+
* between them. Order does not matter. Returns false if the given nodes or
|
478
|
+
* tokens overlap.
|
479
|
+
* @param {ASTNode|Token} first The first node or token to check between.
|
480
|
+
* @param {ASTNode|Token} second The second node or token to check between.
|
481
|
+
* @returns {boolean} True if there is a whitespace character between
|
482
|
+
* any of the tokens found between the two given nodes or tokens.
|
421
483
|
* @public
|
422
484
|
*/
|
423
|
-
|
424
|
-
|
485
|
+
isSpaceBetween(first, second) {
|
486
|
+
return isSpaceBetween(this, first, second, false);
|
487
|
+
}
|
425
488
|
|
426
|
-
|
489
|
+
/**
|
490
|
+
* Determines if two nodes or tokens have at least one whitespace character
|
491
|
+
* between them. Order does not matter. Returns false if the given nodes or
|
492
|
+
* tokens overlap.
|
493
|
+
* For backward compatibility, this method returns true if there are
|
494
|
+
* `JSXText` tokens that contain whitespaces between the two.
|
495
|
+
* @param {ASTNode|Token} first The first node or token to check between.
|
496
|
+
* @param {ASTNode|Token} second The second node or token to check between.
|
497
|
+
* @returns {boolean} True if there is a whitespace character between
|
498
|
+
* any of the tokens found between the two given nodes or tokens.
|
499
|
+
* @deprecated in favor of isSpaceBetween().
|
500
|
+
* @public
|
501
|
+
*/
|
502
|
+
isSpaceBetweenTokens(first, second) {
|
503
|
+
return isSpaceBetween(this, first, second, true);
|
427
504
|
}
|
428
505
|
|
429
506
|
/**
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "6.
|
3
|
+
"version": "6.8.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -42,6 +42,7 @@
|
|
42
42
|
"messages"
|
43
43
|
],
|
44
44
|
"repository": "eslint/eslint",
|
45
|
+
"funding": "https://opencollective.com/eslint",
|
45
46
|
"homepage": "https://eslint.org",
|
46
47
|
"bugs": "https://github.com/eslint/eslint/issues/",
|
47
48
|
"dependencies": {
|
@@ -60,7 +61,7 @@
|
|
60
61
|
"file-entry-cache": "^5.0.1",
|
61
62
|
"functional-red-black-tree": "^1.0.1",
|
62
63
|
"glob-parent": "^5.0.0",
|
63
|
-
"globals": "^
|
64
|
+
"globals": "^12.1.0",
|
64
65
|
"ignore": "^4.0.6",
|
65
66
|
"import-fresh": "^3.0.0",
|
66
67
|
"imurmurhash": "^0.1.4",
|
@@ -73,7 +74,7 @@
|
|
73
74
|
"minimatch": "^3.0.4",
|
74
75
|
"mkdirp": "^0.5.1",
|
75
76
|
"natural-compare": "^1.4.0",
|
76
|
-
"optionator": "^0.8.
|
77
|
+
"optionator": "^0.8.3",
|
77
78
|
"progress": "^2.0.0",
|
78
79
|
"regexpp": "^2.0.1",
|
79
80
|
"semver": "^6.1.2",
|