Skip to content

Commit 8518c04

Browse files
committed
feat: Support custom severity when reporting unused disable directives
1 parent 7a2a0be commit 8518c04

File tree

16 files changed

+182
-24
lines changed

16 files changed

+182
-24
lines changed

conf/default-cli-options.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@ module.exports = {
2828
fix: false,
2929
allowInlineConfig: true,
3030
reportUnusedDisableDirectives: void 0,
31+
reportUnusedDisableDirectivesSeverity: void 0,
3132
globInputPaths: true
3233
};

docs/src/use/command-line-interface.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ Output:
9898
Inline configuration comments:
9999
--no-inline-config Prevent comments from changing config or rules
100100
--report-unused-disable-directives Adds reported errors for unused eslint-disable directives
101+
--report-unused-disable-directives-severity String Choose what severity level that eslint-disable directives should be reported as
101102
102103
Caching:
103104
--cache Only check changed files - default: false
@@ -572,7 +573,7 @@ npx eslint --no-inline-config file.js
572573

573574
#### `--report-unused-disable-directives`
574575

575-
This option causes ESLint to report directive comments like `// eslint-disable-line` when no errors would have been reported on that line anyway.
576+
This option causes ESLint to report disable directive comments like `// eslint-disable-line` as errors when there are no violations present.
576577

577578
* **Argument Type**: No argument.
578579

@@ -581,7 +582,7 @@ This can be useful to prevent future errors from unexpectedly being suppressed,
581582
::: warning
582583
When using this option, it is possible that new errors start being reported whenever ESLint or custom rules are upgraded.
583584

584-
For example, suppose a rule has a bug that causes it to report a false positive, and an `eslint-disable` comment is added to suppress the incorrect report. If the bug is then fixed in a patch release of ESLint, the `eslint-disable` comment becomes unused since ESLint is no longer generating an incorrect report. This results in a new reported error for the unused directive if the `report-unused-disable-directives` option is used.
585+
For example, suppose a rule has a bug that causes it to report a false positive, and an `eslint-disable` comment is added to suppress the incorrect report. If the bug is then fixed in a patch release of ESLint, the `eslint-disable` comment becomes unused since ESLint is no longer generating an incorrect report. This results in a new reported error for the unused directive if the `--report-unused-disable-directives` option is used.
585586
:::
586587

587588
##### `--report-unused-disable-directives` example
@@ -590,6 +591,16 @@ For example, suppose a rule has a bug that causes it to report a false positive,
590591
npx eslint --report-unused-disable-directives file.js
591592
```
592593

594+
#### `--report-unused-disable-directives-severity`
595+
596+
Same as [`--report-unused-disable-directives`](#--report-unused-disable-directives), but allows you to specify the severity level (`error`, `warn`, `off`) of the reported errors. Only one of these two options can be used at a time.
597+
598+
##### `--report-unused-disable-directives-severity` example
599+
600+
```shell
601+
npx eslint --report-unused-disable-directives-severity warn file.js
602+
```
603+
593604
### Caching
594605

595606
#### `--cache`

docs/src/use/configure/configuration-files-new.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Each configuration object contains all of the information ESLint needs to execut
4545
* `parserOptions` - An object specifying additional options that are passed directly to the `parse()` or `parseForESLint()` method on the parser. The available options are parser-dependent.
4646
* `linterOptions` - An object containing settings related to the linting process.
4747
* `noInlineConfig` - A Boolean value indicating if inline configuration is allowed.
48-
* `reportUnusedDisableDirectives` - A Boolean value indicating if unused disable directives should be tracked and reported.
48+
* `reportUnusedDisableDirectives` - A severity string indicating if and how unused disable directives should be tracked and reported. For legacy compatibility, `true` is equivalent to `"warn"` and `false` is equivalent to `"off"`. (default: `"off"`)
4949
* `processor` - Either an object containing `preprocess()` and `postprocess()` methods or a string indicating the name of a processor inside of a plugin (i.e., `"pluginName/processorName"`).
5050
* `plugins` - An object containing a name-value mapping of plugin names to plugin objects. When `files` is specified, these plugins are only available to the matching files.
5151
* `rules` - An object containing the configured rules. When `files` or `ignores` are specified, these rule configurations are only available to the matching files.
@@ -208,20 +208,22 @@ export default [
208208

209209
#### Reporting unused disable directives
210210

211-
Disable directives such as `/*eslint-disable*/` and `/*eslint-disable-next-line*/` are used to disable ESLint rules around certain portions of code. As code changes, it's possible for these directives to no longer be needed because the code has changed in such a way that the rule is no longer triggered. You can enable reporting of these unused disable directives by setting the `reportUnusedDisableDirectives` option to `true`, as in this example:
211+
Disable directives such as `/*eslint-disable*/` and `/*eslint-disable-next-line*/` are used to disable ESLint rules around certain portions of code. As code changes, it's possible for these directives to no longer be needed because the code has changed in such a way that the rule is no longer triggered. You can enable reporting of these unused disable directives by setting the `reportUnusedDisableDirectives` option to a severity string, as in this example:
212212

213213
```js
214214
export default [
215215
{
216216
files: ["**/*.js"],
217217
linterOptions: {
218-
reportUnusedDisableDirectives: true
218+
reportUnusedDisableDirectives: "error"
219219
}
220220
}
221221
];
222222
```
223223

224-
By default, unused disable directives are reported as warnings. You can change this setting using the `--report-unused-disable-directives` command line option.
224+
You can override this setting using the [`--report-unused-disable-directives`](../command-line-interface#--report-unused-disable-directives) or the [`--report-unused-disable-directives-severity`](../command-line-interface#--report-unused-disable-directives-severity) command line options.
225+
226+
For legacy compatibility, `true` is equivalent to `"warn"` and `false` is equivalent to `"off"`.
225227

226228
### Configuring language options
227229

docs/src/use/configure/rules.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,8 @@ To report unused `eslint-disable` comments, use the `reportUnusedDisableDirectiv
302302
```json
303303
{
304304
"rules": {...},
305-
"reportUnusedDisableDirectives": true
305+
"reportUnusedDisableDirectives": "error"
306306
}
307307
```
308308

309-
This setting is similar to [--report-unused-disable-directives](../command-line-interface#--report-unused-disable-directives) CLI option, but doesn't fail linting (reports as `"warn"` severity).
309+
This setting is similar to [--report-unused-disable-directives](../command-line-interface#--report-unused-disable-directives) and [--report-unused-disable-directives-severity](../command-line-interface#--report-unused-disable-directives-severity) CLI options.

lib/cli-engine/cli-engine.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ const validFixTypes = new Set(["directive", "problem", "suggestion", "layout"]);
8383
* @property {string[]} [plugins] An array of plugins to load.
8484
* @property {Record<string,RuleConf>} [rules] An object of rules to use.
8585
* @property {string[]} [rulePaths] An array of directories to load custom rules from.
86-
* @property {boolean} [reportUnusedDisableDirectives] `true` adds reports for unused eslint-disable directives
86+
* @property {boolean|string} [reportUnusedDisableDirectives] `true` or `error` adds reports for unused eslint-disable directives
8787
* @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file.
8888
* @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD
8989
*/
@@ -215,7 +215,7 @@ function calculateStatsPerRun(results) {
215215
* @param {ConfigArray} config.config The config.
216216
* @param {boolean} config.fix If `true` then it does fix.
217217
* @param {boolean} config.allowInlineConfig If `true` then it uses directive comments.
218-
* @param {boolean} config.reportUnusedDisableDirectives If `true` then it reports unused `eslint-disable` comments.
218+
* @param {boolean|string} config.reportUnusedDisableDirectives If `true` or `error`, then it reports unused `eslint-disable` comments.
219219
* @param {FileEnumerator} config.fileEnumerator The file enumerator to check if a path is a target or not.
220220
* @param {Linter} config.linter The linter instance to verify.
221221
* @returns {LintResult} The result of linting.

lib/cli.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ async function translateOptions({
8989
plugin,
9090
quiet,
9191
reportUnusedDisableDirectives,
92+
reportUnusedDisableDirectivesSeverity,
9293
resolvePluginsRelativeTo,
9394
rule,
9495
rulesdir
@@ -177,7 +178,7 @@ async function translateOptions({
177178
ignore,
178179
overrideConfig,
179180
overrideConfigFile,
180-
reportUnusedDisableDirectives: reportUnusedDisableDirectives ? "error" : void 0
181+
reportUnusedDisableDirectives: reportUnusedDisableDirectivesSeverity || (reportUnusedDisableDirectives ? "error" : void 0)
181182
};
182183

183184
if (configType === "flat") {
@@ -377,6 +378,11 @@ const cli = {
377378
return 2;
378379
}
379380

381+
if (options.reportUnusedDisableDirectives && options.reportUnusedDisableDirectivesSeverity) {
382+
log.error("The --report-unused-disable-directives option and the --report-unused-disable-directives-severity option cannot be used together.");
383+
return 2;
384+
}
385+
380386
const ActiveESLint = usingFlatConfig ? FlatESLint : ESLint;
381387

382388
const engine = new ActiveESLint(await translateOptions(options, usingFlatConfig ? "flat" : "eslintrc"));

lib/config/flat-config-schema.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,16 @@ const booleanSchema = {
222222
validate: "boolean"
223223
};
224224

225+
/** @type {ObjectPropertySchema} */
226+
const booleanOrStringSchema = {
227+
merge: "replace",
228+
validate(value) {
229+
if (typeof value !== "string" && typeof value !== "boolean") {
230+
throw new TypeError("Expected a string or a boolean.");
231+
}
232+
}
233+
};
234+
225235
/** @type {ObjectPropertySchema} */
226236
const deepObjectAssignSchema = {
227237
merge(first = {}, second = {}) {
@@ -447,7 +457,7 @@ exports.flatConfigSchema = {
447457
linterOptions: {
448458
schema: {
449459
noInlineConfig: booleanSchema,
450-
reportUnusedDisableDirectives: booleanSchema
460+
reportUnusedDisableDirectives: booleanOrStringSchema
451461
}
452462
},
453463
languageOptions: {

lib/eslint/eslint-helpers.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ function processOptions({
675675
overrideConfig = null,
676676
overrideConfigFile = null,
677677
plugins = {},
678-
reportUnusedDisableDirectives = null, // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that.
678+
reportUnusedDisableDirectives = null, // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that. TODO: should anything change based on this comment?
679679
...unknownOptions
680680
}) {
681681
const errors = [];

lib/eslint/eslint.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ function processOptions({
165165
overrideConfig = null,
166166
overrideConfigFile = null,
167167
plugins = {},
168-
reportUnusedDisableDirectives = null, // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that.
168+
reportUnusedDisableDirectives = null, // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that. TODO: should anything change based on this comment?
169169
resolvePluginsRelativeTo = null, // ← should be null by default because if it's a string then it suppresses RFC47 feature.
170170
rulePaths = [],
171171
useEslintrc = true,

lib/eslint/flat-eslint.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ async function calculateConfigArray(eslint, {
466466
* @param {FlatConfigArray} config.configs The config.
467467
* @param {boolean} config.fix If `true` then it does fix.
468468
* @param {boolean} config.allowInlineConfig If `true` then it uses directive comments.
469-
* @param {boolean} config.reportUnusedDisableDirectives If `true` then it reports unused `eslint-disable` comments.
469+
* @param {boolean|string} config.reportUnusedDisableDirectives If `true` or `error`, then it reports unused `eslint-disable` comments.
470470
* @param {Linter} config.linter The linter instance to verify.
471471
* @returns {LintResult} The result of linting.
472472
* @private

0 commit comments

Comments
 (0)