eslint 8.51.0 → 8.53.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/README.md +7 -2
- package/bin/eslint.js +24 -2
- package/conf/rule-type-list.json +25 -33
- package/lib/cli.js +8 -1
- package/lib/config/flat-config-schema.js +55 -36
- package/lib/linter/apply-disable-directives.js +126 -12
- package/lib/options.js +2 -2
- package/lib/rules/array-bracket-newline.js +3 -0
- package/lib/rules/array-bracket-spacing.js +3 -0
- package/lib/rules/array-element-newline.js +3 -0
- package/lib/rules/arrow-parens.js +3 -0
- package/lib/rules/arrow-spacing.js +3 -0
- package/lib/rules/block-spacing.js +3 -0
- package/lib/rules/brace-style.js +3 -0
- package/lib/rules/comma-dangle.js +3 -0
- package/lib/rules/comma-spacing.js +3 -0
- package/lib/rules/comma-style.js +3 -0
- package/lib/rules/computed-property-spacing.js +3 -0
- package/lib/rules/dot-location.js +3 -0
- package/lib/rules/eol-last.js +3 -0
- package/lib/rules/func-call-spacing.js +3 -0
- package/lib/rules/function-call-argument-newline.js +3 -0
- package/lib/rules/function-paren-newline.js +3 -0
- package/lib/rules/generator-star-spacing.js +3 -0
- package/lib/rules/implicit-arrow-linebreak.js +3 -0
- package/lib/rules/indent.js +3 -0
- package/lib/rules/jsx-quotes.js +3 -0
- package/lib/rules/key-spacing.js +3 -0
- package/lib/rules/keyword-spacing.js +3 -0
- package/lib/rules/linebreak-style.js +3 -0
- package/lib/rules/lines-around-comment.js +3 -0
- package/lib/rules/lines-between-class-members.js +3 -0
- package/lib/rules/max-len.js +3 -0
- package/lib/rules/max-statements-per-line.js +3 -0
- package/lib/rules/multiline-ternary.js +3 -0
- package/lib/rules/new-parens.js +3 -0
- package/lib/rules/newline-per-chained-call.js +3 -0
- package/lib/rules/no-confusing-arrow.js +3 -0
- package/lib/rules/no-extra-parens.js +3 -0
- package/lib/rules/no-extra-semi.js +3 -0
- package/lib/rules/no-floating-decimal.js +3 -0
- package/lib/rules/no-mixed-operators.js +3 -0
- package/lib/rules/no-mixed-spaces-and-tabs.js +3 -0
- package/lib/rules/no-multi-spaces.js +3 -0
- package/lib/rules/no-multiple-empty-lines.js +3 -0
- package/lib/rules/no-object-constructor.js +103 -5
- package/lib/rules/no-prototype-builtins.js +90 -2
- package/lib/rules/no-tabs.js +3 -0
- package/lib/rules/no-trailing-spaces.js +3 -0
- package/lib/rules/no-whitespace-before-property.js +3 -0
- package/lib/rules/nonblock-statement-body-position.js +3 -0
- package/lib/rules/object-curly-newline.js +3 -0
- package/lib/rules/object-curly-spacing.js +3 -0
- package/lib/rules/object-property-newline.js +3 -0
- package/lib/rules/one-var-declaration-per-line.js +3 -0
- package/lib/rules/operator-linebreak.js +3 -0
- package/lib/rules/padded-blocks.js +3 -0
- package/lib/rules/padding-line-between-statements.js +3 -0
- package/lib/rules/quote-props.js +3 -0
- package/lib/rules/quotes.js +3 -0
- package/lib/rules/rest-spread-spacing.js +3 -0
- package/lib/rules/semi-spacing.js +3 -0
- package/lib/rules/semi-style.js +3 -0
- package/lib/rules/semi.js +3 -0
- package/lib/rules/space-before-blocks.js +3 -0
- package/lib/rules/space-before-function-paren.js +3 -0
- package/lib/rules/space-in-parens.js +3 -0
- package/lib/rules/space-infix-ops.js +3 -0
- package/lib/rules/space-unary-ops.js +3 -0
- package/lib/rules/spaced-comment.js +3 -0
- package/lib/rules/switch-colon-spacing.js +3 -0
- package/lib/rules/template-curly-spacing.js +3 -0
- package/lib/rules/template-tag-spacing.js +3 -0
- package/lib/rules/wrap-iife.js +3 -0
- package/lib/rules/wrap-regex.js +3 -0
- package/lib/rules/yield-star-spacing.js +3 -0
- package/package.json +5 -14
package/README.md
CHANGED
@@ -254,6 +254,11 @@ Francesco Trotta
|
|
254
254
|
<img src="https://github.com/ota-meshi.png?s=75" width="75" height="75"><br />
|
255
255
|
Yosuke Ota
|
256
256
|
</a>
|
257
|
+
</td><td align="center" valign="top" width="11%">
|
258
|
+
<a href="https://github.com/Tanujkanti4441">
|
259
|
+
<img src="https://github.com/Tanujkanti4441.png?s=75" width="75" height="75"><br />
|
260
|
+
Tanuj Kanti
|
261
|
+
</a>
|
257
262
|
</td></tr></tbody></table>
|
258
263
|
|
259
264
|
### Website Team
|
@@ -288,8 +293,8 @@ The following companies, organizations, and individuals support ESLint's ongoing
|
|
288
293
|
<h3>Platinum Sponsors</h3>
|
289
294
|
<p><a href="#"><img src="https://images.opencollective.com/2021-frameworks-fund/logo.png" alt="Chrome Frameworks Fund" height="undefined"></a> <a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
|
290
295
|
<p><a href="https://engineering.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a></p><h3>Silver Sponsors</h3>
|
291
|
-
<p><a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://
|
292
|
-
<p><a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://transloadit.com/"><img src="https://avatars.githubusercontent.com/u/125754?v=4" alt="Transloadit" height="32"></a> <a href="https://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a
|
296
|
+
<p><a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="64"></a></p><h3>Bronze Sponsors</h3>
|
297
|
+
<p><a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://transloadit.com/"><img src="https://avatars.githubusercontent.com/u/125754?v=4" alt="Transloadit" height="32"></a> <a href="https://www.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a></p>
|
293
298
|
<!--sponsorsend-->
|
294
299
|
|
295
300
|
## Technology Sponsors
|
package/bin/eslint.js
CHANGED
@@ -97,9 +97,14 @@ function getErrorMessage(error) {
|
|
97
97
|
* same message once.
|
98
98
|
* @type {Set<string>}
|
99
99
|
*/
|
100
|
-
|
101
100
|
const displayedErrors = new Set();
|
102
101
|
|
102
|
+
/**
|
103
|
+
* Tracks whether an unexpected error was caught
|
104
|
+
* @type {boolean}
|
105
|
+
*/
|
106
|
+
let hadFatalError = false;
|
107
|
+
|
103
108
|
/**
|
104
109
|
* Catch and report unexpected error.
|
105
110
|
* @param {any} error The thrown error object.
|
@@ -107,6 +112,7 @@ const displayedErrors = new Set();
|
|
107
112
|
*/
|
108
113
|
function onFatalError(error) {
|
109
114
|
process.exitCode = 2;
|
115
|
+
hadFatalError = true;
|
110
116
|
|
111
117
|
const { version } = require("../package.json");
|
112
118
|
const message = `
|
@@ -143,9 +149,25 @@ ${getErrorMessage(error)}`;
|
|
143
149
|
}
|
144
150
|
|
145
151
|
// Otherwise, call the CLI.
|
146
|
-
|
152
|
+
const exitCode = await require("../lib/cli").execute(
|
147
153
|
process.argv,
|
148
154
|
process.argv.includes("--stdin") ? await readStdin() : null,
|
149
155
|
true
|
150
156
|
);
|
157
|
+
|
158
|
+
/*
|
159
|
+
* If an uncaught exception or unhandled rejection was detected in the meantime,
|
160
|
+
* keep the fatal exit code 2 that is already assigned to `process.exitCode`.
|
161
|
+
* Without this condition, exit code 2 (unsuccessful execution) could be overwritten with
|
162
|
+
* 1 (successful execution, lint problems found) or even 0 (successful execution, no lint problems found).
|
163
|
+
* This ensures that unexpected errors that seemingly don't affect the success
|
164
|
+
* of the execution will still cause a non-zero exit code, as it's a common
|
165
|
+
* practice and the default behavior of Node.js to exit with non-zero
|
166
|
+
* in case of an uncaught exception or unhandled rejection.
|
167
|
+
*
|
168
|
+
* Otherwise, assign the exit code returned from CLI.
|
169
|
+
*/
|
170
|
+
if (!hadFatalError) {
|
171
|
+
process.exitCode = exitCode;
|
172
|
+
}
|
151
173
|
}()).catch(onFatalError);
|
package/conf/rule-type-list.json
CHANGED
@@ -1,36 +1,28 @@
|
|
1
1
|
{
|
2
|
-
"types":
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
],
|
7
|
-
"deprecated": {
|
8
|
-
"name": "Deprecated",
|
9
|
-
"description": "These rules have been deprecated in accordance with the <a href=\"{{ '/use/rule-deprecation' | url }}\">deprecation policy</a>, and replaced by newer rules:",
|
10
|
-
"rules": []
|
2
|
+
"types": {
|
3
|
+
"problem": [],
|
4
|
+
"suggestion": [],
|
5
|
+
"layout": []
|
11
6
|
},
|
12
|
-
"
|
13
|
-
|
14
|
-
"
|
15
|
-
"
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
{ "removed": "spaced-line-comment", "replacedBy": ["spaced-comment"] }
|
34
|
-
]
|
35
|
-
}
|
7
|
+
"deprecated": [],
|
8
|
+
"removed": [
|
9
|
+
{ "removed": "generator-star", "replacedBy": ["generator-star-spacing"] },
|
10
|
+
{ "removed": "global-strict", "replacedBy": ["strict"] },
|
11
|
+
{ "removed": "no-arrow-condition", "replacedBy": ["no-confusing-arrow", "no-constant-condition"] },
|
12
|
+
{ "removed": "no-comma-dangle", "replacedBy": ["comma-dangle"] },
|
13
|
+
{ "removed": "no-empty-class", "replacedBy": ["no-empty-character-class"] },
|
14
|
+
{ "removed": "no-empty-label", "replacedBy": ["no-labels"] },
|
15
|
+
{ "removed": "no-extra-strict", "replacedBy": ["strict"] },
|
16
|
+
{ "removed": "no-reserved-keys", "replacedBy": ["quote-props"] },
|
17
|
+
{ "removed": "no-space-before-semi", "replacedBy": ["semi-spacing"] },
|
18
|
+
{ "removed": "no-wrap-func", "replacedBy": ["no-extra-parens"] },
|
19
|
+
{ "removed": "space-after-function-name", "replacedBy": ["space-before-function-paren"] },
|
20
|
+
{ "removed": "space-after-keywords", "replacedBy": ["keyword-spacing"] },
|
21
|
+
{ "removed": "space-before-function-parentheses", "replacedBy": ["space-before-function-paren"] },
|
22
|
+
{ "removed": "space-before-keywords", "replacedBy": ["keyword-spacing"] },
|
23
|
+
{ "removed": "space-in-brackets", "replacedBy": ["object-curly-spacing", "array-bracket-spacing"] },
|
24
|
+
{ "removed": "space-return-throw-case", "replacedBy": ["keyword-spacing"] },
|
25
|
+
{ "removed": "space-unary-word-ops", "replacedBy": ["space-unary-ops"] },
|
26
|
+
{ "removed": "spaced-line-comment", "replacedBy": ["spaced-comment"] }
|
27
|
+
]
|
36
28
|
}
|
package/lib/cli.js
CHANGED
@@ -318,7 +318,14 @@ const cli = {
|
|
318
318
|
options = CLIOptions.parse(args);
|
319
319
|
} catch (error) {
|
320
320
|
debug("Error parsing CLI options:", error.message);
|
321
|
-
|
321
|
+
|
322
|
+
let errorMessage = error.message;
|
323
|
+
|
324
|
+
if (usingFlatConfig) {
|
325
|
+
errorMessage += "\nYou're using eslint.config.js, some command line flags are no longer available. Please see https://eslint.org/docs/latest/use/command-line-interface for details.";
|
326
|
+
}
|
327
|
+
|
328
|
+
log.error(errorMessage);
|
322
329
|
return 2;
|
323
330
|
}
|
324
331
|
|
@@ -5,6 +5,16 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
//-----------------------------------------------------------------------------
|
9
|
+
// Requirements
|
10
|
+
//-----------------------------------------------------------------------------
|
11
|
+
|
12
|
+
/*
|
13
|
+
* Note: This can be removed in ESLint v9 because structuredClone is available globally
|
14
|
+
* starting in Node.js v17.
|
15
|
+
*/
|
16
|
+
const structuredClone = require("@ungap/structured-clone").default;
|
17
|
+
|
8
18
|
//-----------------------------------------------------------------------------
|
9
19
|
// Type Definitions
|
10
20
|
//-----------------------------------------------------------------------------
|
@@ -119,7 +129,7 @@ function normalizeRuleOptions(ruleOptions) {
|
|
119
129
|
: [ruleOptions];
|
120
130
|
|
121
131
|
finalOptions[0] = ruleSeverities.get(finalOptions[0]);
|
122
|
-
return finalOptions;
|
132
|
+
return structuredClone(finalOptions);
|
123
133
|
}
|
124
134
|
|
125
135
|
//-----------------------------------------------------------------------------
|
@@ -378,48 +388,57 @@ const rulesSchema = {
|
|
378
388
|
...second
|
379
389
|
};
|
380
390
|
|
381
|
-
for (const ruleId of Object.keys(result)) {
|
382
|
-
|
383
|
-
// avoid hairy edge case
|
384
|
-
if (ruleId === "__proto__") {
|
385
|
-
|
386
|
-
/* eslint-disable-next-line no-proto -- Though deprecated, may still be present */
|
387
|
-
delete result.__proto__;
|
388
|
-
continue;
|
389
|
-
}
|
390
|
-
|
391
|
-
result[ruleId] = normalizeRuleOptions(result[ruleId]);
|
392
|
-
|
393
|
-
/*
|
394
|
-
* If either rule config is missing, then the correct
|
395
|
-
* config is already present and we just need to normalize
|
396
|
-
* the severity.
|
397
|
-
*/
|
398
|
-
if (!(ruleId in first) || !(ruleId in second)) {
|
399
|
-
continue;
|
400
|
-
}
|
401
391
|
|
402
|
-
|
403
|
-
const secondRuleOptions = normalizeRuleOptions(second[ruleId]);
|
392
|
+
for (const ruleId of Object.keys(result)) {
|
404
393
|
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
394
|
+
try {
|
395
|
+
|
396
|
+
// avoid hairy edge case
|
397
|
+
if (ruleId === "__proto__") {
|
398
|
+
|
399
|
+
/* eslint-disable-next-line no-proto -- Though deprecated, may still be present */
|
400
|
+
delete result.__proto__;
|
401
|
+
continue;
|
402
|
+
}
|
403
|
+
|
404
|
+
result[ruleId] = normalizeRuleOptions(result[ruleId]);
|
405
|
+
|
406
|
+
/*
|
407
|
+
* If either rule config is missing, then the correct
|
408
|
+
* config is already present and we just need to normalize
|
409
|
+
* the severity.
|
410
|
+
*/
|
411
|
+
if (!(ruleId in first) || !(ruleId in second)) {
|
412
|
+
continue;
|
413
|
+
}
|
414
|
+
|
415
|
+
const firstRuleOptions = normalizeRuleOptions(first[ruleId]);
|
416
|
+
const secondRuleOptions = normalizeRuleOptions(second[ruleId]);
|
417
|
+
|
418
|
+
/*
|
419
|
+
* If the second rule config only has a severity (length of 1),
|
420
|
+
* then use that severity and keep the rest of the options from
|
421
|
+
* the first rule config.
|
422
|
+
*/
|
423
|
+
if (secondRuleOptions.length === 1) {
|
424
|
+
result[ruleId] = [secondRuleOptions[0], ...firstRuleOptions.slice(1)];
|
425
|
+
continue;
|
426
|
+
}
|
427
|
+
|
428
|
+
/*
|
429
|
+
* In any other situation, then the second rule config takes
|
430
|
+
* precedence. That means the value at `result[ruleId]` is
|
431
|
+
* already correct and no further work is necessary.
|
432
|
+
*/
|
433
|
+
} catch (ex) {
|
434
|
+
throw new Error(`Key "${ruleId}": ${ex.message}`, { cause: ex });
|
413
435
|
}
|
414
436
|
|
415
|
-
/*
|
416
|
-
* In any other situation, then the second rule config takes
|
417
|
-
* precedence. That means the value at `result[ruleId]` is
|
418
|
-
* already correct and no further work is necessary.
|
419
|
-
*/
|
420
437
|
}
|
421
438
|
|
422
439
|
return result;
|
440
|
+
|
441
|
+
|
423
442
|
},
|
424
443
|
|
425
444
|
validate(value) {
|
@@ -30,7 +30,7 @@ function compareLocations(itemA, itemB) {
|
|
30
30
|
|
31
31
|
/**
|
32
32
|
* Groups a set of directives into sub-arrays by their parent comment.
|
33
|
-
* @param {Directive
|
33
|
+
* @param {Iterable<Directive>} directives Unused directives to be removed.
|
34
34
|
* @returns {Directive[][]} Directives grouped by their parent comment.
|
35
35
|
*/
|
36
36
|
function groupByParentComment(directives) {
|
@@ -177,10 +177,10 @@ function createCommentRemoval(directives, commentToken) {
|
|
177
177
|
|
178
178
|
/**
|
179
179
|
* Parses details from directives to create output Problems.
|
180
|
-
* @param {Directive
|
180
|
+
* @param {Iterable<Directive>} allDirectives Unused directives to be removed.
|
181
181
|
* @returns {{ description, fix, unprocessedDirective }[]} Details for later creation of output Problems.
|
182
182
|
*/
|
183
|
-
function
|
183
|
+
function processUnusedDirectives(allDirectives) {
|
184
184
|
const directiveGroups = groupByParentComment(allDirectives);
|
185
185
|
|
186
186
|
return directiveGroups.flatMap(
|
@@ -199,6 +199,95 @@ function processUnusedDisableDirectives(allDirectives) {
|
|
199
199
|
);
|
200
200
|
}
|
201
201
|
|
202
|
+
/**
|
203
|
+
* Collect eslint-enable comments that are removing suppressions by eslint-disable comments.
|
204
|
+
* @param {Directive[]} directives The directives to check.
|
205
|
+
* @returns {Set<Directive>} The used eslint-enable comments
|
206
|
+
*/
|
207
|
+
function collectUsedEnableDirectives(directives) {
|
208
|
+
|
209
|
+
/**
|
210
|
+
* A Map of `eslint-enable` keyed by ruleIds that may be marked as used.
|
211
|
+
* If `eslint-enable` does not have a ruleId, the key will be `null`.
|
212
|
+
* @type {Map<string|null, Directive>}
|
213
|
+
*/
|
214
|
+
const enabledRules = new Map();
|
215
|
+
|
216
|
+
/**
|
217
|
+
* A Set of `eslint-enable` marked as used.
|
218
|
+
* It is also the return value of `collectUsedEnableDirectives` function.
|
219
|
+
* @type {Set<Directive>}
|
220
|
+
*/
|
221
|
+
const usedEnableDirectives = new Set();
|
222
|
+
|
223
|
+
/*
|
224
|
+
* Checks the directives backwards to see if the encountered `eslint-enable` is used by the previous `eslint-disable`,
|
225
|
+
* and if so, stores the `eslint-enable` in `usedEnableDirectives`.
|
226
|
+
*/
|
227
|
+
for (let index = directives.length - 1; index >= 0; index--) {
|
228
|
+
const directive = directives[index];
|
229
|
+
|
230
|
+
if (directive.type === "disable") {
|
231
|
+
if (enabledRules.size === 0) {
|
232
|
+
continue;
|
233
|
+
}
|
234
|
+
if (directive.ruleId === null) {
|
235
|
+
|
236
|
+
// If encounter `eslint-disable` without ruleId,
|
237
|
+
// mark all `eslint-enable` currently held in enabledRules as used.
|
238
|
+
// e.g.
|
239
|
+
// /* eslint-disable */ <- current directive
|
240
|
+
// /* eslint-enable rule-id1 */ <- used
|
241
|
+
// /* eslint-enable rule-id2 */ <- used
|
242
|
+
// /* eslint-enable */ <- used
|
243
|
+
for (const enableDirective of enabledRules.values()) {
|
244
|
+
usedEnableDirectives.add(enableDirective);
|
245
|
+
}
|
246
|
+
enabledRules.clear();
|
247
|
+
} else {
|
248
|
+
const enableDirective = enabledRules.get(directive.ruleId);
|
249
|
+
|
250
|
+
if (enableDirective) {
|
251
|
+
|
252
|
+
// If encounter `eslint-disable` with ruleId, and there is an `eslint-enable` with the same ruleId in enabledRules,
|
253
|
+
// mark `eslint-enable` with ruleId as used.
|
254
|
+
// e.g.
|
255
|
+
// /* eslint-disable rule-id */ <- current directive
|
256
|
+
// /* eslint-enable rule-id */ <- used
|
257
|
+
usedEnableDirectives.add(enableDirective);
|
258
|
+
} else {
|
259
|
+
const enabledDirectiveWithoutRuleId = enabledRules.get(null);
|
260
|
+
|
261
|
+
if (enabledDirectiveWithoutRuleId) {
|
262
|
+
|
263
|
+
// If encounter `eslint-disable` with ruleId, and there is no `eslint-enable` with the same ruleId in enabledRules,
|
264
|
+
// mark `eslint-enable` without ruleId as used.
|
265
|
+
// e.g.
|
266
|
+
// /* eslint-disable rule-id */ <- current directive
|
267
|
+
// /* eslint-enable */ <- used
|
268
|
+
usedEnableDirectives.add(enabledDirectiveWithoutRuleId);
|
269
|
+
}
|
270
|
+
}
|
271
|
+
}
|
272
|
+
} else if (directive.type === "enable") {
|
273
|
+
if (directive.ruleId === null) {
|
274
|
+
|
275
|
+
// If encounter `eslint-enable` without ruleId, the `eslint-enable` that follows it are unused.
|
276
|
+
// So clear enabledRules.
|
277
|
+
// e.g.
|
278
|
+
// /* eslint-enable */ <- current directive
|
279
|
+
// /* eslint-enable rule-id *// <- unused
|
280
|
+
// /* eslint-enable */ <- unused
|
281
|
+
enabledRules.clear();
|
282
|
+
enabledRules.set(null, directive);
|
283
|
+
} else {
|
284
|
+
enabledRules.set(directive.ruleId, directive);
|
285
|
+
}
|
286
|
+
}
|
287
|
+
}
|
288
|
+
return usedEnableDirectives;
|
289
|
+
}
|
290
|
+
|
202
291
|
/**
|
203
292
|
* This is the same as the exported function, except that it
|
204
293
|
* doesn't handle disable-line and disable-next-line directives, and it always reports unused
|
@@ -206,7 +295,7 @@ function processUnusedDisableDirectives(allDirectives) {
|
|
206
295
|
* @param {Object} options options for applying directives. This is the same as the options
|
207
296
|
* for the exported function, except that `reportUnusedDisableDirectives` is not supported
|
208
297
|
* (this function always reports unused disable directives).
|
209
|
-
* @returns {{problems: LintMessage[],
|
298
|
+
* @returns {{problems: LintMessage[], unusedDirectives: LintMessage[]}} An object with a list
|
210
299
|
* of problems (including suppressed ones) and unused eslint-disable directives
|
211
300
|
*/
|
212
301
|
function applyDirectives(options) {
|
@@ -258,17 +347,42 @@ function applyDirectives(options) {
|
|
258
347
|
const unusedDisableDirectivesToReport = options.directives
|
259
348
|
.filter(directive => directive.type === "disable" && !usedDisableDirectives.has(directive));
|
260
349
|
|
261
|
-
const processed = processUnusedDisableDirectives(unusedDisableDirectivesToReport);
|
262
350
|
|
263
|
-
const
|
351
|
+
const unusedEnableDirectivesToReport = new Set(
|
352
|
+
options.directives.filter(directive => directive.unprocessedDirective.type === "enable")
|
353
|
+
);
|
354
|
+
|
355
|
+
/*
|
356
|
+
* If directives has the eslint-enable directive,
|
357
|
+
* check whether the eslint-enable comment is used.
|
358
|
+
*/
|
359
|
+
if (unusedEnableDirectivesToReport.size > 0) {
|
360
|
+
for (const directive of collectUsedEnableDirectives(options.directives)) {
|
361
|
+
unusedEnableDirectivesToReport.delete(directive);
|
362
|
+
}
|
363
|
+
}
|
364
|
+
|
365
|
+
const processed = processUnusedDirectives(unusedDisableDirectivesToReport)
|
366
|
+
.concat(processUnusedDirectives(unusedEnableDirectivesToReport));
|
367
|
+
|
368
|
+
const unusedDirectives = processed
|
264
369
|
.map(({ description, fix, unprocessedDirective }) => {
|
265
370
|
const { parentComment, type, line, column } = unprocessedDirective;
|
266
371
|
|
372
|
+
let message;
|
373
|
+
|
374
|
+
if (type === "enable") {
|
375
|
+
message = description
|
376
|
+
? `Unused eslint-enable directive (no matching eslint-disable directives were found for ${description}).`
|
377
|
+
: "Unused eslint-enable directive (no matching eslint-disable directives were found).";
|
378
|
+
} else {
|
379
|
+
message = description
|
380
|
+
? `Unused eslint-disable directive (no problems were reported from ${description}).`
|
381
|
+
: "Unused eslint-disable directive (no problems were reported).";
|
382
|
+
}
|
267
383
|
return {
|
268
384
|
ruleId: null,
|
269
|
-
message
|
270
|
-
? `Unused eslint-disable directive (no problems were reported from ${description}).`
|
271
|
-
: "Unused eslint-disable directive (no problems were reported).",
|
385
|
+
message,
|
272
386
|
line: type === "disable-next-line" ? parentComment.commentToken.loc.start.line : line,
|
273
387
|
column: type === "disable-next-line" ? parentComment.commentToken.loc.start.column + 1 : column,
|
274
388
|
severity: options.reportUnusedDisableDirectives === "warn" ? 1 : 2,
|
@@ -277,7 +391,7 @@ function applyDirectives(options) {
|
|
277
391
|
};
|
278
392
|
});
|
279
393
|
|
280
|
-
return { problems,
|
394
|
+
return { problems, unusedDirectives };
|
281
395
|
}
|
282
396
|
|
283
397
|
/**
|
@@ -344,8 +458,8 @@ module.exports = ({ directives, disableFixes, problems, reportUnusedDisableDirec
|
|
344
458
|
|
345
459
|
return reportUnusedDisableDirectives !== "off"
|
346
460
|
? lineDirectivesResult.problems
|
347
|
-
.concat(blockDirectivesResult.
|
348
|
-
.concat(lineDirectivesResult.
|
461
|
+
.concat(blockDirectivesResult.unusedDirectives)
|
462
|
+
.concat(lineDirectivesResult.unusedDirectives)
|
349
463
|
.sort(compareLocations)
|
350
464
|
: lineDirectivesResult.problems;
|
351
465
|
};
|
package/lib/options.js
CHANGED
@@ -47,7 +47,7 @@ const optionator = require("optionator");
|
|
47
47
|
* @property {Object} [parserOptions] Specify parser options
|
48
48
|
* @property {string[]} [plugin] Specify plugins
|
49
49
|
* @property {string} [printConfig] Print the configuration for the given file
|
50
|
-
* @property {boolean | undefined} reportUnusedDisableDirectives Adds reported errors for unused eslint-disable directives
|
50
|
+
* @property {boolean | undefined} reportUnusedDisableDirectives Adds reported errors for unused eslint-disable and eslint-enable directives
|
51
51
|
* @property {string} [resolvePluginsRelativeTo] A folder where plugins should be resolved from, CWD by default
|
52
52
|
* @property {Object} [rule] Specify rules
|
53
53
|
* @property {string[]} [rulesdir] Load additional rules from this directory. Deprecated: Use rules from plugins
|
@@ -304,7 +304,7 @@ module.exports = function(usingFlatConfig) {
|
|
304
304
|
option: "report-unused-disable-directives",
|
305
305
|
type: "Boolean",
|
306
306
|
default: void 0,
|
307
|
-
description: "Adds reported errors for unused eslint-disable directives"
|
307
|
+
description: "Adds reported errors for unused eslint-disable and eslint-enable directives"
|
308
308
|
},
|
309
309
|
{
|
310
310
|
heading: "Caching"
|
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview Rule to enforce linebreaks after open and before close array brackets
|
3
3
|
* @author Jan Peer Stöcklmair <https://github.com/JPeer264>
|
4
|
+
* @deprecated in ESLint v8.53.0
|
4
5
|
*/
|
5
6
|
|
6
7
|
"use strict";
|
@@ -14,6 +15,8 @@ const astUtils = require("./utils/ast-utils");
|
|
14
15
|
/** @type {import('../shared/types').Rule} */
|
15
16
|
module.exports = {
|
16
17
|
meta: {
|
18
|
+
deprecated: true,
|
19
|
+
replacedBy: [],
|
17
20
|
type: "layout",
|
18
21
|
|
19
22
|
docs: {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview Disallows or enforces spaces inside of array brackets.
|
3
3
|
* @author Jamund Ferguson
|
4
|
+
* @deprecated in ESLint v8.53.0
|
4
5
|
*/
|
5
6
|
"use strict";
|
6
7
|
|
@@ -13,6 +14,8 @@ const astUtils = require("./utils/ast-utils");
|
|
13
14
|
/** @type {import('../shared/types').Rule} */
|
14
15
|
module.exports = {
|
15
16
|
meta: {
|
17
|
+
deprecated: true,
|
18
|
+
replacedBy: [],
|
16
19
|
type: "layout",
|
17
20
|
|
18
21
|
docs: {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview Rule to enforce line breaks after each array element
|
3
3
|
* @author Jan Peer Stöcklmair <https://github.com/JPeer264>
|
4
|
+
* @deprecated in ESLint v8.53.0
|
4
5
|
*/
|
5
6
|
|
6
7
|
"use strict";
|
@@ -14,6 +15,8 @@ const astUtils = require("./utils/ast-utils");
|
|
14
15
|
/** @type {import('../shared/types').Rule} */
|
15
16
|
module.exports = {
|
16
17
|
meta: {
|
18
|
+
deprecated: true,
|
19
|
+
replacedBy: [],
|
17
20
|
type: "layout",
|
18
21
|
|
19
22
|
docs: {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview Rule to require parens in arrow function arguments.
|
3
3
|
* @author Jxck
|
4
|
+
* @deprecated in ESLint v8.53.0
|
4
5
|
*/
|
5
6
|
"use strict";
|
6
7
|
|
@@ -30,6 +31,8 @@ function hasBlockBody(node) {
|
|
30
31
|
/** @type {import('../shared/types').Rule} */
|
31
32
|
module.exports = {
|
32
33
|
meta: {
|
34
|
+
deprecated: true,
|
35
|
+
replacedBy: [],
|
33
36
|
type: "layout",
|
34
37
|
|
35
38
|
docs: {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview Rule to define spacing before/after arrow function's arrow.
|
3
3
|
* @author Jxck
|
4
|
+
* @deprecated in ESLint v8.53.0
|
4
5
|
*/
|
5
6
|
"use strict";
|
6
7
|
|
@@ -17,6 +18,8 @@ const astUtils = require("./utils/ast-utils");
|
|
17
18
|
/** @type {import('../shared/types').Rule} */
|
18
19
|
module.exports = {
|
19
20
|
meta: {
|
21
|
+
deprecated: true,
|
22
|
+
replacedBy: [],
|
20
23
|
type: "layout",
|
21
24
|
|
22
25
|
docs: {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview A rule to disallow or enforce spaces inside of single line blocks.
|
3
3
|
* @author Toru Nagashima
|
4
|
+
* @deprecated in ESLint v8.53.0
|
4
5
|
*/
|
5
6
|
|
6
7
|
"use strict";
|
@@ -14,6 +15,8 @@ const util = require("./utils/ast-utils");
|
|
14
15
|
/** @type {import('../shared/types').Rule} */
|
15
16
|
module.exports = {
|
16
17
|
meta: {
|
18
|
+
deprecated: true,
|
19
|
+
replacedBy: [],
|
17
20
|
type: "layout",
|
18
21
|
|
19
22
|
docs: {
|
package/lib/rules/brace-style.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview Rule to flag block statements that do not use the one true brace style
|
3
3
|
* @author Ian Christian Myers
|
4
|
+
* @deprecated in ESLint v8.53.0
|
4
5
|
*/
|
5
6
|
|
6
7
|
"use strict";
|
@@ -14,6 +15,8 @@ const astUtils = require("./utils/ast-utils");
|
|
14
15
|
/** @type {import('../shared/types').Rule} */
|
15
16
|
module.exports = {
|
16
17
|
meta: {
|
18
|
+
deprecated: true,
|
19
|
+
replacedBy: [],
|
17
20
|
type: "layout",
|
18
21
|
|
19
22
|
docs: {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview Rule to forbid or enforce dangling commas.
|
3
3
|
* @author Ian Christian Myers
|
4
|
+
* @deprecated in ESLint v8.53.0
|
4
5
|
*/
|
5
6
|
|
6
7
|
"use strict";
|
@@ -73,6 +74,8 @@ function normalizeOptions(optionValue, ecmaVersion) {
|
|
73
74
|
/** @type {import('../shared/types').Rule} */
|
74
75
|
module.exports = {
|
75
76
|
meta: {
|
77
|
+
deprecated: true,
|
78
|
+
replacedBy: [],
|
76
79
|
type: "layout",
|
77
80
|
|
78
81
|
docs: {
|
@@ -1,6 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @fileoverview Comma spacing - validates spacing before and after comma
|
3
3
|
* @author Vignesh Anand aka vegetableman.
|
4
|
+
* @deprecated in ESLint v8.53.0
|
4
5
|
*/
|
5
6
|
"use strict";
|
6
7
|
|
@@ -13,6 +14,8 @@ const astUtils = require("./utils/ast-utils");
|
|
13
14
|
/** @type {import('../shared/types').Rule} */
|
14
15
|
module.exports = {
|
15
16
|
meta: {
|
17
|
+
deprecated: true,
|
18
|
+
replacedBy: [],
|
16
19
|
type: "layout",
|
17
20
|
|
18
21
|
docs: {
|