eslint 7.27.0 → 7.31.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 +58 -0
- package/README.md +7 -7
- package/lib/config/default-config.js +52 -0
- package/lib/config/flat-config-array.js +125 -0
- package/lib/config/flat-config-schema.js +452 -0
- package/lib/config/rule-validator.js +169 -0
- package/lib/eslint/eslint.js +38 -2
- package/lib/init/npm-utils.js +1 -2
- package/lib/linter/linter.js +25 -17
- package/lib/rule-tester/rule-tester.js +75 -13
- package/lib/rules/arrow-body-style.js +21 -11
- package/lib/rules/comma-style.js +1 -2
- package/lib/rules/consistent-return.js +3 -3
- package/lib/rules/dot-notation.js +3 -3
- package/lib/rules/indent.js +2 -4
- package/lib/rules/no-duplicate-imports.js +214 -66
- package/lib/rules/no-fallthrough.js +17 -6
- package/lib/rules/no-implicit-coercion.js +21 -2
- package/lib/rules/no-mixed-operators.js +1 -1
- package/lib/rules/no-unused-vars.js +15 -9
- package/lib/rules/operator-assignment.js +6 -3
- package/lib/rules/prefer-arrow-callback.js +4 -4
- package/lib/rules/use-isnan.js +4 -1
- package/lib/source-code/source-code.js +2 -2
- package/package.json +6 -5
@@ -4,92 +4,225 @@
|
|
4
4
|
*/
|
5
5
|
"use strict";
|
6
6
|
|
7
|
+
//------------------------------------------------------------------------------
|
8
|
+
// Helpers
|
9
|
+
//------------------------------------------------------------------------------
|
10
|
+
|
11
|
+
const NAMED_TYPES = ["ImportSpecifier", "ExportSpecifier"];
|
12
|
+
const NAMESPACE_TYPES = [
|
13
|
+
"ImportNamespaceSpecifier",
|
14
|
+
"ExportNamespaceSpecifier"
|
15
|
+
];
|
16
|
+
|
7
17
|
//------------------------------------------------------------------------------
|
8
18
|
// Rule Definition
|
9
19
|
//------------------------------------------------------------------------------
|
10
20
|
|
11
21
|
/**
|
12
|
-
*
|
22
|
+
* Check if an import/export type belongs to (ImportSpecifier|ExportSpecifier) or (ImportNamespaceSpecifier|ExportNamespaceSpecifier).
|
23
|
+
* @param {string} importExportType An import/export type to check.
|
24
|
+
* @param {string} type Can be "named" or "namespace"
|
25
|
+
* @returns {boolean} True if import/export type belongs to (ImportSpecifier|ExportSpecifier) or (ImportNamespaceSpecifier|ExportNamespaceSpecifier) and false if it doesn't.
|
26
|
+
*/
|
27
|
+
function isImportExportSpecifier(importExportType, type) {
|
28
|
+
const arrayToCheck = type === "named" ? NAMED_TYPES : NAMESPACE_TYPES;
|
29
|
+
|
30
|
+
return arrayToCheck.includes(importExportType);
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Return the type of (import|export).
|
13
35
|
* @param {ASTNode} node A node to get.
|
14
|
-
* @returns {string}
|
36
|
+
* @returns {string} The type of the (import|export).
|
15
37
|
*/
|
16
|
-
function
|
17
|
-
if (node && node.
|
18
|
-
|
38
|
+
function getImportExportType(node) {
|
39
|
+
if (node.specifiers && node.specifiers.length > 0) {
|
40
|
+
const nodeSpecifiers = node.specifiers;
|
41
|
+
const index = nodeSpecifiers.findIndex(
|
42
|
+
({ type }) =>
|
43
|
+
isImportExportSpecifier(type, "named") ||
|
44
|
+
isImportExportSpecifier(type, "namespace")
|
45
|
+
);
|
46
|
+
const i = index > -1 ? index : 0;
|
47
|
+
|
48
|
+
return nodeSpecifiers[i].type;
|
19
49
|
}
|
50
|
+
if (node.type === "ExportAllDeclaration") {
|
51
|
+
if (node.exported) {
|
52
|
+
return "ExportNamespaceSpecifier";
|
53
|
+
}
|
54
|
+
return "ExportAll";
|
55
|
+
}
|
56
|
+
return "SideEffectImport";
|
57
|
+
}
|
20
58
|
|
21
|
-
|
59
|
+
/**
|
60
|
+
* Returns a boolean indicates if two (import|export) can be merged
|
61
|
+
* @param {ASTNode} node1 A node to check.
|
62
|
+
* @param {ASTNode} node2 A node to check.
|
63
|
+
* @returns {boolean} True if two (import|export) can be merged, false if they can't.
|
64
|
+
*/
|
65
|
+
function isImportExportCanBeMerged(node1, node2) {
|
66
|
+
const importExportType1 = getImportExportType(node1);
|
67
|
+
const importExportType2 = getImportExportType(node2);
|
68
|
+
|
69
|
+
if (
|
70
|
+
(importExportType1 === "ExportAll" &&
|
71
|
+
importExportType2 !== "ExportAll" &&
|
72
|
+
importExportType2 !== "SideEffectImport") ||
|
73
|
+
(importExportType1 !== "ExportAll" &&
|
74
|
+
importExportType1 !== "SideEffectImport" &&
|
75
|
+
importExportType2 === "ExportAll")
|
76
|
+
) {
|
77
|
+
return false;
|
78
|
+
}
|
79
|
+
if (
|
80
|
+
(isImportExportSpecifier(importExportType1, "namespace") &&
|
81
|
+
isImportExportSpecifier(importExportType2, "named")) ||
|
82
|
+
(isImportExportSpecifier(importExportType2, "namespace") &&
|
83
|
+
isImportExportSpecifier(importExportType1, "named"))
|
84
|
+
) {
|
85
|
+
return false;
|
86
|
+
}
|
87
|
+
return true;
|
22
88
|
}
|
23
89
|
|
24
90
|
/**
|
25
|
-
*
|
26
|
-
* @param {
|
27
|
-
* @param {ASTNode}
|
28
|
-
* @
|
29
|
-
* @param {string[]} array The array containing other imports or exports in the file.
|
30
|
-
* @param {string} messageId A messageId to be reported after the name of the module
|
31
|
-
*
|
32
|
-
* @returns {void} No return value
|
91
|
+
* Returns a boolean if we should report (import|export).
|
92
|
+
* @param {ASTNode} node A node to be reported or not.
|
93
|
+
* @param {[ASTNode]} previousNodes An array contains previous nodes of the module imported or exported.
|
94
|
+
* @returns {boolean} True if the (import|export) should be reported.
|
33
95
|
*/
|
34
|
-
function
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
});
|
96
|
+
function shouldReportImportExport(node, previousNodes) {
|
97
|
+
let i = 0;
|
98
|
+
|
99
|
+
while (i < previousNodes.length) {
|
100
|
+
if (isImportExportCanBeMerged(node, previousNodes[i])) {
|
101
|
+
return true;
|
102
|
+
}
|
103
|
+
i++;
|
43
104
|
}
|
105
|
+
return false;
|
44
106
|
}
|
45
107
|
|
46
108
|
/**
|
47
|
-
*
|
48
|
-
* @param {ASTNode}
|
109
|
+
* Returns array contains only nodes with declarations types equal to type.
|
110
|
+
* @param {[{node: ASTNode, declarationType: string}]} nodes An array contains objects, each object contains a node and a declaration type.
|
111
|
+
* @param {string} type Declaration type.
|
112
|
+
* @returns {[ASTNode]} An array contains only nodes with declarations types equal to type.
|
113
|
+
*/
|
114
|
+
function getNodesByDeclarationType(nodes, type) {
|
115
|
+
return nodes
|
116
|
+
.filter(({ declarationType }) => declarationType === type)
|
117
|
+
.map(({ node }) => node);
|
118
|
+
}
|
119
|
+
|
120
|
+
/**
|
121
|
+
* Returns the name of the module imported or re-exported.
|
122
|
+
* @param {ASTNode} node A node to get.
|
123
|
+
* @returns {string} The name of the module, or empty string if no name.
|
49
124
|
*/
|
125
|
+
function getModule(node) {
|
126
|
+
if (node && node.source && node.source.value) {
|
127
|
+
return node.source.value.trim();
|
128
|
+
}
|
129
|
+
return "";
|
130
|
+
}
|
50
131
|
|
51
132
|
/**
|
52
|
-
*
|
133
|
+
* Checks if the (import|export) can be merged with at least one import or one export, and reports if so.
|
53
134
|
* @param {RuleContext} context The ESLint rule context object.
|
135
|
+
* @param {ASTNode} node A node to get.
|
136
|
+
* @param {Map} modules A Map object contains as a key a module name and as value an array contains objects, each object contains a node and a declaration type.
|
137
|
+
* @param {string} declarationType A declaration type can be an import or export.
|
54
138
|
* @param {boolean} includeExports Whether or not to check for exports in addition to imports.
|
55
|
-
* @
|
56
|
-
* @param {string[]} exportsInFile The array containing other exports in the file.
|
57
|
-
*
|
58
|
-
* @returns {nodeCallback} A function passed to ESLint to handle the statement.
|
139
|
+
* @returns {void} No return value.
|
59
140
|
*/
|
60
|
-
function
|
61
|
-
|
62
|
-
|
141
|
+
function checkAndReport(
|
142
|
+
context,
|
143
|
+
node,
|
144
|
+
modules,
|
145
|
+
declarationType,
|
146
|
+
includeExports
|
147
|
+
) {
|
148
|
+
const module = getModule(node);
|
63
149
|
|
64
|
-
|
65
|
-
|
150
|
+
if (modules.has(module)) {
|
151
|
+
const previousNodes = modules.get(module);
|
152
|
+
const messagesIds = [];
|
153
|
+
const importNodes = getNodesByDeclarationType(previousNodes, "import");
|
154
|
+
let exportNodes;
|
66
155
|
|
156
|
+
if (includeExports) {
|
157
|
+
exportNodes = getNodesByDeclarationType(previousNodes, "export");
|
158
|
+
}
|
159
|
+
if (declarationType === "import") {
|
160
|
+
if (shouldReportImportExport(node, importNodes)) {
|
161
|
+
messagesIds.push("import");
|
162
|
+
}
|
67
163
|
if (includeExports) {
|
68
|
-
|
164
|
+
if (shouldReportImportExport(node, exportNodes)) {
|
165
|
+
messagesIds.push("importAs");
|
166
|
+
}
|
167
|
+
}
|
168
|
+
} else if (declarationType === "export") {
|
169
|
+
if (shouldReportImportExport(node, exportNodes)) {
|
170
|
+
messagesIds.push("export");
|
171
|
+
}
|
172
|
+
if (shouldReportImportExport(node, importNodes)) {
|
173
|
+
messagesIds.push("exportAs");
|
69
174
|
}
|
70
|
-
|
71
|
-
importsInFile.push(value);
|
72
175
|
}
|
73
|
-
|
176
|
+
messagesIds.forEach(messageId =>
|
177
|
+
context.report({
|
178
|
+
node,
|
179
|
+
messageId,
|
180
|
+
data: {
|
181
|
+
module
|
182
|
+
}
|
183
|
+
}));
|
184
|
+
}
|
74
185
|
}
|
75
186
|
|
76
187
|
/**
|
77
|
-
*
|
188
|
+
* @callback nodeCallback
|
189
|
+
* @param {ASTNode} node A node to handle.
|
190
|
+
*/
|
191
|
+
|
192
|
+
/**
|
193
|
+
* Returns a function handling the (imports|exports) of a given file
|
78
194
|
* @param {RuleContext} context The ESLint rule context object.
|
79
|
-
* @param {
|
80
|
-
* @param {string
|
81
|
-
*
|
195
|
+
* @param {Map} modules A Map object contains as a key a module name and as value an array contains objects, each object contains a node and a declaration type.
|
196
|
+
* @param {string} declarationType A declaration type can be an import or export.
|
197
|
+
* @param {boolean} includeExports Whether or not to check for exports in addition to imports.
|
82
198
|
* @returns {nodeCallback} A function passed to ESLint to handle the statement.
|
83
199
|
*/
|
84
|
-
function
|
200
|
+
function handleImportsExports(
|
201
|
+
context,
|
202
|
+
modules,
|
203
|
+
declarationType,
|
204
|
+
includeExports
|
205
|
+
) {
|
85
206
|
return function(node) {
|
86
|
-
const
|
207
|
+
const module = getModule(node);
|
208
|
+
|
209
|
+
if (module) {
|
210
|
+
checkAndReport(
|
211
|
+
context,
|
212
|
+
node,
|
213
|
+
modules,
|
214
|
+
declarationType,
|
215
|
+
includeExports
|
216
|
+
);
|
217
|
+
const currentNode = { node, declarationType };
|
218
|
+
let nodes = [currentNode];
|
87
219
|
|
88
|
-
|
89
|
-
|
90
|
-
checkAndReport(context, node, value, importsInFile, "exportAs");
|
220
|
+
if (modules.has(module)) {
|
221
|
+
const previousNodes = modules.get(module);
|
91
222
|
|
92
|
-
|
223
|
+
nodes = [...previousNodes, currentNode];
|
224
|
+
}
|
225
|
+
modules.set(module, nodes);
|
93
226
|
}
|
94
227
|
};
|
95
228
|
}
|
@@ -105,16 +238,19 @@ module.exports = {
|
|
105
238
|
url: "https://eslint.org/docs/rules/no-duplicate-imports"
|
106
239
|
},
|
107
240
|
|
108
|
-
schema: [
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
241
|
+
schema: [
|
242
|
+
{
|
243
|
+
type: "object",
|
244
|
+
properties: {
|
245
|
+
includeExports: {
|
246
|
+
type: "boolean",
|
247
|
+
default: false
|
248
|
+
}
|
249
|
+
},
|
250
|
+
additionalProperties: false
|
251
|
+
}
|
252
|
+
],
|
253
|
+
|
118
254
|
messages: {
|
119
255
|
import: "'{{module}}' import is duplicated.",
|
120
256
|
importAs: "'{{module}}' import is duplicated as export.",
|
@@ -125,18 +261,30 @@ module.exports = {
|
|
125
261
|
|
126
262
|
create(context) {
|
127
263
|
const includeExports = (context.options[0] || {}).includeExports,
|
128
|
-
|
129
|
-
exportsInFile = [];
|
130
|
-
|
264
|
+
modules = new Map();
|
131
265
|
const handlers = {
|
132
|
-
ImportDeclaration:
|
266
|
+
ImportDeclaration: handleImportsExports(
|
267
|
+
context,
|
268
|
+
modules,
|
269
|
+
"import",
|
270
|
+
includeExports
|
271
|
+
)
|
133
272
|
};
|
134
273
|
|
135
274
|
if (includeExports) {
|
136
|
-
handlers.ExportNamedDeclaration =
|
137
|
-
|
275
|
+
handlers.ExportNamedDeclaration = handleImportsExports(
|
276
|
+
context,
|
277
|
+
modules,
|
278
|
+
"export",
|
279
|
+
includeExports
|
280
|
+
);
|
281
|
+
handlers.ExportAllDeclaration = handleImportsExports(
|
282
|
+
context,
|
283
|
+
modules,
|
284
|
+
"export",
|
285
|
+
includeExports
|
286
|
+
);
|
138
287
|
}
|
139
|
-
|
140
288
|
return handlers;
|
141
289
|
}
|
142
290
|
};
|
@@ -11,15 +11,26 @@
|
|
11
11
|
const DEFAULT_FALLTHROUGH_COMMENT = /falls?\s?through/iu;
|
12
12
|
|
13
13
|
/**
|
14
|
-
* Checks whether or not a given
|
15
|
-
* @param {ASTNode}
|
14
|
+
* Checks whether or not a given case has a fallthrough comment.
|
15
|
+
* @param {ASTNode} caseWhichFallsThrough SwitchCase node which falls through.
|
16
|
+
* @param {ASTNode} subsequentCase The case after caseWhichFallsThrough.
|
16
17
|
* @param {RuleContext} context A rule context which stores comments.
|
17
18
|
* @param {RegExp} fallthroughCommentPattern A pattern to match comment to.
|
18
|
-
* @returns {boolean} `true` if the
|
19
|
+
* @returns {boolean} `true` if the case has a valid fallthrough comment.
|
19
20
|
*/
|
20
|
-
function hasFallthroughComment(
|
21
|
+
function hasFallthroughComment(caseWhichFallsThrough, subsequentCase, context, fallthroughCommentPattern) {
|
21
22
|
const sourceCode = context.getSourceCode();
|
22
|
-
|
23
|
+
|
24
|
+
if (caseWhichFallsThrough.consequent.length === 1 && caseWhichFallsThrough.consequent[0].type === "BlockStatement") {
|
25
|
+
const trailingCloseBrace = sourceCode.getLastToken(caseWhichFallsThrough.consequent[0]);
|
26
|
+
const commentInBlock = sourceCode.getCommentsBefore(trailingCloseBrace).pop();
|
27
|
+
|
28
|
+
if (commentInBlock && fallthroughCommentPattern.test(commentInBlock.value)) {
|
29
|
+
return true;
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
const comment = sourceCode.getCommentsBefore(subsequentCase).pop();
|
23
34
|
|
24
35
|
return Boolean(comment && fallthroughCommentPattern.test(comment.value));
|
25
36
|
}
|
@@ -108,7 +119,7 @@ module.exports = {
|
|
108
119
|
* Checks whether or not there is a fallthrough comment.
|
109
120
|
* And reports the previous fallthrough node if that does not exist.
|
110
121
|
*/
|
111
|
-
if (fallthroughCase && !hasFallthroughComment(node, context, fallthroughCommentPattern)) {
|
122
|
+
if (fallthroughCase && !hasFallthroughComment(fallthroughCase, node, context, fallthroughCommentPattern)) {
|
112
123
|
context.report({
|
113
124
|
messageId: node.test ? "case" : "default",
|
114
125
|
node
|
@@ -109,6 +109,20 @@ function getNonNumericOperand(node) {
|
|
109
109
|
return null;
|
110
110
|
}
|
111
111
|
|
112
|
+
/**
|
113
|
+
* Checks whether an expression evaluates to a string.
|
114
|
+
* @param {ASTNode} node node that represents the expression to check.
|
115
|
+
* @returns {boolean} Whether or not the expression evaluates to a string.
|
116
|
+
*/
|
117
|
+
function isStringType(node) {
|
118
|
+
return astUtils.isStringLiteral(node) ||
|
119
|
+
(
|
120
|
+
node.type === "CallExpression" &&
|
121
|
+
node.callee.type === "Identifier" &&
|
122
|
+
node.callee.name === "String"
|
123
|
+
);
|
124
|
+
}
|
125
|
+
|
112
126
|
/**
|
113
127
|
* Checks whether a node is an empty string literal or not.
|
114
128
|
* @param {ASTNode} node The node to check.
|
@@ -126,8 +140,8 @@ function isEmptyString(node) {
|
|
126
140
|
*/
|
127
141
|
function isConcatWithEmptyString(node) {
|
128
142
|
return node.operator === "+" && (
|
129
|
-
(isEmptyString(node.left) && !
|
130
|
-
(isEmptyString(node.right) && !
|
143
|
+
(isEmptyString(node.left) && !isStringType(node.right)) ||
|
144
|
+
(isEmptyString(node.right) && !isStringType(node.left))
|
131
145
|
);
|
132
146
|
}
|
133
147
|
|
@@ -332,6 +346,11 @@ module.exports = {
|
|
332
346
|
return;
|
333
347
|
}
|
334
348
|
|
349
|
+
// if the expression is already a string, then this isn't a coercion
|
350
|
+
if (isStringType(node.expressions[0])) {
|
351
|
+
return;
|
352
|
+
}
|
353
|
+
|
335
354
|
const code = sourceCode.getText(node.expressions[0]);
|
336
355
|
const recommendation = `String(${code})`;
|
337
356
|
|
@@ -117,7 +117,7 @@ module.exports = {
|
|
117
117
|
],
|
118
118
|
|
119
119
|
messages: {
|
120
|
-
unexpectedMixedOperator: "Unexpected mix of '{{leftOperator}}' and '{{rightOperator}}'."
|
120
|
+
unexpectedMixedOperator: "Unexpected mix of '{{leftOperator}}' and '{{rightOperator}}'. Use parentheses to clarify the intended order of operations."
|
121
121
|
}
|
122
122
|
},
|
123
123
|
|
@@ -449,18 +449,24 @@ module.exports = {
|
|
449
449
|
return ref.isRead() && (
|
450
450
|
|
451
451
|
// self update. e.g. `a += 1`, `a++`
|
452
|
-
(
|
453
|
-
(
|
452
|
+
(
|
453
|
+
(
|
454
454
|
parent.type === "AssignmentExpression" &&
|
455
|
-
|
456
|
-
|
455
|
+
parent.left === id &&
|
456
|
+
isUnusedExpression(parent)
|
457
457
|
) ||
|
458
|
+
(
|
459
|
+
parent.type === "UpdateExpression" &&
|
460
|
+
isUnusedExpression(parent)
|
461
|
+
)
|
462
|
+
) ||
|
463
|
+
|
464
|
+
// in RHS of an assignment for itself. e.g. `a = a + 1`
|
458
465
|
(
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
!isInsideOfStorableFunction(id, rhsNode)))
|
466
|
+
rhsNode &&
|
467
|
+
isInside(id, rhsNode) &&
|
468
|
+
!isInsideOfStorableFunction(id, rhsNode)
|
469
|
+
)
|
464
470
|
);
|
465
471
|
}
|
466
472
|
|
@@ -76,8 +76,8 @@ module.exports = {
|
|
76
76
|
|
77
77
|
fixable: "code",
|
78
78
|
messages: {
|
79
|
-
replaced: "Assignment can be replaced with operator assignment.",
|
80
|
-
unexpected: "Unexpected operator assignment shorthand."
|
79
|
+
replaced: "Assignment (=) can be replaced with operator assignment ({{operator}}=).",
|
80
|
+
unexpected: "Unexpected operator assignment ({{operator}}=) shorthand."
|
81
81
|
}
|
82
82
|
},
|
83
83
|
|
@@ -113,6 +113,7 @@ module.exports = {
|
|
113
113
|
context.report({
|
114
114
|
node,
|
115
115
|
messageId: "replaced",
|
116
|
+
data: { operator },
|
116
117
|
fix(fixer) {
|
117
118
|
if (canBeFixed(left) && canBeFixed(expr.left)) {
|
118
119
|
const equalsToken = getOperatorToken(node);
|
@@ -139,7 +140,8 @@ module.exports = {
|
|
139
140
|
*/
|
140
141
|
context.report({
|
141
142
|
node,
|
142
|
-
messageId: "replaced"
|
143
|
+
messageId: "replaced",
|
144
|
+
data: { operator }
|
143
145
|
});
|
144
146
|
}
|
145
147
|
}
|
@@ -155,6 +157,7 @@ module.exports = {
|
|
155
157
|
context.report({
|
156
158
|
node,
|
157
159
|
messageId: "unexpected",
|
160
|
+
data: { operator: node.operator },
|
158
161
|
fix(fixer) {
|
159
162
|
if (canBeFixed(node.left)) {
|
160
163
|
const firstToken = sourceCode.getFirstToken(node);
|
@@ -295,7 +295,7 @@ module.exports = {
|
|
295
295
|
* If the callback function has duplicates in its list of parameters (possible in sloppy mode),
|
296
296
|
* don't replace it with an arrow function, because this is a SyntaxError with arrow functions.
|
297
297
|
*/
|
298
|
-
return;
|
298
|
+
return;
|
299
299
|
}
|
300
300
|
|
301
301
|
// Remove `.bind(this)` if exists.
|
@@ -307,7 +307,7 @@ module.exports = {
|
|
307
307
|
* E.g. `(foo || function(){}).bind(this)`
|
308
308
|
*/
|
309
309
|
if (memberNode.type !== "MemberExpression") {
|
310
|
-
return;
|
310
|
+
return;
|
311
311
|
}
|
312
312
|
|
313
313
|
const callNode = memberNode.parent;
|
@@ -320,12 +320,12 @@ module.exports = {
|
|
320
320
|
* ^^^^^^^^^^^^
|
321
321
|
*/
|
322
322
|
if (astUtils.isParenthesised(sourceCode, memberNode)) {
|
323
|
-
return;
|
323
|
+
return;
|
324
324
|
}
|
325
325
|
|
326
326
|
// If comments exist in the `.bind(this)`, don't remove those.
|
327
327
|
if (sourceCode.commentsExistBetween(firstTokenToRemove, lastTokenToRemove)) {
|
328
|
-
return;
|
328
|
+
return;
|
329
329
|
}
|
330
330
|
|
331
331
|
yield fixer.removeRange([firstTokenToRemove.range[0], lastTokenToRemove.range[1]]);
|
package/lib/rules/use-isnan.js
CHANGED
@@ -21,7 +21,10 @@ const astUtils = require("./utils/ast-utils");
|
|
21
21
|
* @returns {boolean} `true` if the node is 'NaN' identifier.
|
22
22
|
*/
|
23
23
|
function isNaNIdentifier(node) {
|
24
|
-
return Boolean(node) &&
|
24
|
+
return Boolean(node) && (
|
25
|
+
astUtils.isSpecificId(node, "NaN") ||
|
26
|
+
astUtils.isSpecificMemberAccess(node, "Number", "NaN")
|
27
|
+
);
|
25
28
|
}
|
26
29
|
|
27
30
|
//------------------------------------------------------------------------------
|
@@ -349,7 +349,7 @@ class SourceCode extends TokenStore {
|
|
349
349
|
let currentToken = this.getTokenBefore(node, { includeComments: true });
|
350
350
|
|
351
351
|
while (currentToken && isCommentToken(currentToken)) {
|
352
|
-
if (node.parent && (currentToken.start < node.parent.start)) {
|
352
|
+
if (node.parent && node.parent.type !== "Program" && (currentToken.start < node.parent.start)) {
|
353
353
|
break;
|
354
354
|
}
|
355
355
|
comments.leading.push(currentToken);
|
@@ -361,7 +361,7 @@ class SourceCode extends TokenStore {
|
|
361
361
|
currentToken = this.getTokenAfter(node, { includeComments: true });
|
362
362
|
|
363
363
|
while (currentToken && isCommentToken(currentToken)) {
|
364
|
-
if (node.parent && (currentToken.end > node.parent.end)) {
|
364
|
+
if (node.parent && node.parent.type !== "Program" && (currentToken.end > node.parent.end)) {
|
365
365
|
break;
|
366
366
|
}
|
367
367
|
comments.trailing.push(currentToken);
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "7.
|
3
|
+
"version": "7.31.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -44,7 +44,8 @@
|
|
44
44
|
"bugs": "https://github.com/eslint/eslint/issues/",
|
45
45
|
"dependencies": {
|
46
46
|
"@babel/code-frame": "7.12.11",
|
47
|
-
"@eslint/eslintrc": "^0.4.
|
47
|
+
"@eslint/eslintrc": "^0.4.3",
|
48
|
+
"@humanwhocodes/config-array": "^0.5.0",
|
48
49
|
"ajv": "^6.10.0",
|
49
50
|
"chalk": "^4.0.0",
|
50
51
|
"cross-spawn": "^7.0.2",
|
@@ -61,7 +62,7 @@
|
|
61
62
|
"fast-deep-equal": "^3.1.3",
|
62
63
|
"file-entry-cache": "^6.0.1",
|
63
64
|
"functional-red-black-tree": "^1.0.1",
|
64
|
-
"glob-parent": "^5.
|
65
|
+
"glob-parent": "^5.1.2",
|
65
66
|
"globals": "^13.6.0",
|
66
67
|
"ignore": "^4.0.6",
|
67
68
|
"import-fresh": "^3.0.0",
|
@@ -95,14 +96,14 @@
|
|
95
96
|
"ejs": "^3.0.2",
|
96
97
|
"eslint": "file:.",
|
97
98
|
"eslint-config-eslint": "file:packages/eslint-config-eslint",
|
98
|
-
"eslint-plugin-eslint-plugin": "^
|
99
|
+
"eslint-plugin-eslint-plugin": "^3.2.0",
|
99
100
|
"eslint-plugin-internal-rules": "file:tools/internal-rules",
|
100
101
|
"eslint-plugin-jsdoc": "^25.4.3",
|
101
102
|
"eslint-plugin-node": "^11.1.0",
|
102
103
|
"eslint-release": "^2.0.0",
|
103
104
|
"eslump": "^3.0.0",
|
104
105
|
"esprima": "^4.0.1",
|
105
|
-
"fs-teardown": "
|
106
|
+
"fs-teardown": "0.1.1",
|
106
107
|
"glob": "^7.1.6",
|
107
108
|
"jsdoc": "^3.5.5",
|
108
109
|
"karma": "^6.1.1",
|