eslint icon indicating copy to clipboard operation
eslint copied to clipboard

feat: Add `reportUsedIgnorePattern` option to `no-unused-vars` rule

Open Pearce-Ropion opened this issue 2 years ago • 20 comments

Prerequisites checklist

What is the purpose of this pull request? (put an "X" next to an item)

  • [x] Documentation update
  • [ ] Bug fix (template)
  • [ ] New rule (template)
  • [x] Changes an existing rule (template)
  • [ ] Add autofix to a rule
  • [ ] Add a CLI option
  • [ ] Add something to the core
  • [ ] Other, please explain:

What rule do you want to change?

no-unused-vars

What change do you want to make (place an "X" next to just one item)?

  • [x] Generate more warnings
  • [ ] Generate fewer warnings
  • [ ] Implement autofix
  • [ ] Implement suggestions

How will the change be implemented (place an "X" next to just one item)?

  • [x] A new option
  • [ ] A new default behavior
  • [ ] Other

Please provide some example code that this change will affect:

Example 1:

/* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^_" }] */

const _a = 5;
const _b = _a + 5

Example 2:

/* eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }] */

function foo(_a) {
  return _a + 5
}

Example 3:

/* eslint no-unused-vars: ["error", { "destructuredArrayIgnorePattern": "^_" }] */

const [ a, _b ] = items;
console.log(a + _b);

Example 4:

/* eslint no-unused-vars: ["error", { "caughtErrorsIgnorePattern": "^_" }] */

try {}
catch(_err) {
  console.error(_err);
}

What does the rule currently do for this code?

In all examples, no warnings are reported.

What will the rule do after it's changed?

When the new option reportUsedIgnorePattern is enabled, each of the examples above will report; indicating that a variable that has been marked as an ignored unused variable is being used.

What changes did you make? (Give an overview)

This change adds a new option reportUsedIgnorePattern to the no-unused-vars rule. When enabled, the rule will report any instances of variables that match any of the valid ignore pattern options when that variable is actually being used.

Resolves: #17568

Is there anything you'd like reviewers to focus on?

When finding all references in order to report on the correct nodes, it is also finding the variable declaration. So a question for the team would be which nodes should this option report on:

  • Should all references including the declaration be reported?
  • Should only the variable declaration be reported?
  • Should only references not including the declaration be reported

Pearce-Ropion avatar Oct 18 '23 18:10 Pearce-Ropion

CLA Signed

The committers listed above are authorized under a signed CLA.

  • :white_check_mark: login: Pearce-Ropion / name: Pearce Ropion (a364f2fa9c0d3ee0cb1ba8bd161a66a496bec51a, 12d57da97e916c6803fc4738c9c0937246a87177, 418a092720ae6ac80e559bbd6f0eb43d32c050ed, d97b7fd0f62b10579411b300f4f805427686d3a1, a91ea4fbdd213d39981d148a0e6ae95951cc1633, 1eefec568a8962247bb11533be89a4514a2fdccc, 9fa1956be5a998d084c52f4268f8ed41cfbb9873, 6a0b6b51d81f4f8815f6cd46ff29700687d39d6b)

Hi @Pearce-Ropion!, thanks for the Pull Request

The pull request title isn't properly formatted. We ask that you update the pull request title to match this format, as we use it to generate changelogs and automate releases.

  • The commit message tag wasn't recognized. Did you mean "docs", "fix", or "feat"?
  • There should be a space following the initial tag and colon, for example 'feat: Message'.
  • The first letter of the tag should be in lowercase

To Fix: You can fix this problem by clicking 'Edit' next to the pull request title at the top of this page.

Read more about contributing to ESLint here

eslint-github-bot[bot] avatar Oct 18 '23 18:10 eslint-github-bot[bot]

Deploy Preview for docs-eslint canceled.

Name Link
Latest commit 9fa1956be5a998d084c52f4268f8ed41cfbb9873
Latest deploy log https://app.netlify.com/sites/docs-eslint/deploys/660398e1192bd30008c67bd6

netlify[bot] avatar Oct 18 '23 18:10 netlify[bot]

  • Should all references including the declaration be reported?
  • Should only the variable declaration be reported?
  • Should only references not including the declaration be reported

Would it make sense to report only on the reasons the variable is considered used, which are usually its read references?

This is how it currently works:

/* eslint no-unused-vars: ["error", {
    varsIgnorePattern: "^_",
    reportUsedIgnorePattern: true
}] */

var _a; // not reported

_a = 1; // this is reported but doesn't seem relevant?

foo(_a); // this is also reported, ok

But this variable is considered used only because of the read reference so it might make sense to report like this:

/* eslint no-unused-vars: ["error", {
    varsIgnorePattern: "^_",
    reportUsedIgnorePattern: true
}] */

var _a; // not reported

_a = 1; // not reported

foo(_a); // reported

mdjermanovic avatar Oct 20 '23 19:10 mdjermanovic

  • Should all references including the declaration be reported?
  • Should only the variable declaration be reported?
  • Should only references not including the declaration be reported

Would it make sense to report only on the reasons the variable is considered used, which are usually its read references?

This is how it currently works:

/* eslint no-unused-vars: ["error", {
    varsIgnorePattern: "^_",
    reportUsedIgnorePattern: true
}] */

var _a; // not reported

_a = 1; // this is reported but doesn't seem relevant?

foo(_a); // this is also reported, ok

But this variable is considered used only because of the read reference so it might make sense to report like this:

/* eslint no-unused-vars: ["error", {
    varsIgnorePattern: "^_",
    reportUsedIgnorePattern: true
}] */

var _a; // not reported

_a = 1; // not reported

foo(_a); // reported

That makes sense to me. I couldn't entirely remember what counted as used. However, I would also expect that a user shouldn't be allowed to write to an ignored unused variable since it should be unused.

Pearce-Ropion avatar Oct 20 '23 20:10 Pearce-Ropion

Hi everyone, it looks like we lost track of this pull request. Please review and see what the next steps are. This pull request will auto-close in 7 days without an update.

github-actions[bot] avatar Nov 13 '23 22:11 github-actions[bot]

I changed it to skip all variable initializations but otherwise report on all references. I also doesn't check whether the variable scope matches anymore so it can handle variables defined in the outer scope which are used in an inner scope.

Pearce-Ropion avatar Nov 20 '23 06:11 Pearce-Ropion

@mdjermanovic I think this is working as expected now. Can you think of any other cases that I could test for? Otherwise, I think we are good to go.

Pearce-Ropion avatar Nov 30 '23 16:11 Pearce-Ropion

Hi everyone, it looks like we lost track of this pull request. Please review and see what the next steps are. This pull request will auto-close in 7 days without an update.

github-actions[bot] avatar Dec 10 '23 22:12 github-actions[bot]

@Pearce-Ropion apologies for the delay in reviewing this PR.

I changed it to skip all variable initializations but otherwise report on all references.

I'm not sure what the common use cases for the varsIgnorePattern option are, but if user has a code like the following where the rule doesn't report any errors:

/*eslint no-unused-vars: ["error", { varsIgnorePattern: "^_", reportUsedIgnorePattern: true }]*/

var _foo;

_foo = 5;

and then they add more code that causes the variable to be considered used, so that the rule now reports it:

/*eslint no-unused-vars: ["error", { varsIgnorePattern: "^_", reportUsedIgnorePattern: true }]*/

var _foo;

_foo = 5;

bar(_foo);

then, I think it makes the most sense to report only on the references where this rule considers the variable to be used: _foo in bar(_foo), because _foo = 5 has no effect on whether the variable is considered used, and it was valid before bar(_foo) was added.

Alternatively, we could report only the declaration assuming that the variable name is wrong because it was intended to be used (as opposed to reporting references, in which case the assumption is that the variable that wasn't intended to be used is mistakenly used).

Curious what others think about this.

mdjermanovic avatar Dec 15 '23 19:12 mdjermanovic

No worries, eslint is a massive project and I don't want to burden anyone.

then, I think it makes the most sense to report only on the references where this rule considers the variable to be used: _foo in bar(_foo), because _foo = 5 has no effect on whether the variable is considered used, and it was valid before bar(_foo) was added.

Alternatively, we could report only the declaration assuming that the variable name is wrong because it was intended to be used (as opposed to reporting references, in which case the assumption is that the variable that wasn't intended to be used is mistakenly used).

Using vscode's eslint extension as an example, on one hand it would be useful to see reported issues on the usages since that's what is considered invalid according to the new option. However, It would be more clear what the problem is and how to fix it at the declaration, so it'd probably be better to do it there.

Pearce-Ropion avatar Dec 18 '23 16:12 Pearce-Ropion

then, I think it makes the most sense to report only on the references where this rule considers the variable to be used: _foo in bar(_foo), because _foo = 5 has no effect on whether the variable is considered used, and it was valid before bar(_foo) was added.

I think this makes the most sense. :+1:

@Pearce-Ropion sorry for the delay, we've been busy working on v9. Can you please rebase and make any further changes? Thanks!

nzakas avatar Jan 02 '24 21:01 nzakas

Oops, accidentally hit "close"

nzakas avatar Jan 04 '24 18:01 nzakas

Oops, accidentally hit "close"

lol, I was going to reopen once I pushed the changes.

Pearce-Ropion avatar Jan 04 '24 21:01 Pearce-Ropion

Hi everyone, it looks like we lost track of this pull request. Please review and see what the next steps are. This pull request will auto-close in 7 days without an update.

github-actions[bot] avatar Jan 15 '24 22:01 github-actions[bot]

This is still active. Waiting for a review.

Pearce-Ropion avatar Jan 16 '24 01:01 Pearce-Ropion

In this case, the message seems misleading:

/*eslint no-unused-vars: ["error", {
    "reportUsedIgnorePattern": true,
    "destructuredArrayIgnorePattern": "^_",
    "varsIgnorePattern": "[iI]gnored"
}]*/

let _x; // '_x' is marked as ignored but is used. Used vars must not match /[iI]gnored/u.

[_x] = arr;

foo(_x);

mdjermanovic avatar Jan 25 '24 14:01 mdjermanovic

Hi @Pearce-Ropion, some changes are requested. you can check out.

Tanujkanti4441 avatar Feb 16 '24 07:02 Tanujkanti4441

In this case, the message seems misleading:

/*eslint no-unused-vars: ["error", {
    "reportUsedIgnorePattern": true,
    "destructuredArrayIgnorePattern": "^_",
    "varsIgnorePattern": "[iI]gnored"
}]*/

let _x; // '_x' is marked as ignored but is used. Used vars must not match /[iI]gnored/u.

[_x] = arr;

foo(_x);

I'm still getting the same error, looks like this case still hasn't been addressed?

mdjermanovic avatar Feb 22 '24 09:02 mdjermanovic

Here's a similar case that should also be fixed:

/*eslint no-unused-vars: ["error", {
    "reportUsedIgnorePattern": true,
    "destructuredArrayIgnorePattern": "^_",
    "varsIgnorePattern": "[iI]gnored"
}]*/

const [ignored] = arr; // 'ignored' is marked as ignored but is used. Used elements of array destructuring must not match /^_/u.

foo(ignored);

The message should be: 'ignored' is marked as ignored but is used. Used vars must not match /[iI]gnored/u.

mdjermanovic avatar Feb 22 '24 09:02 mdjermanovic

@Pearce-Ropion are you still working on this?

nzakas avatar Mar 22 '24 19:03 nzakas

@Pearce-Ropion are you still working on this?

Yes, apologies. I've been slammed with work. I'll get the proposed suggestions in this weekend

Pearce-Ropion avatar Mar 22 '24 23:03 Pearce-Ropion

Ok, I've applied @mdjermanovic's suggestions to report as soon as we detect the used ignored variable. I also explicitly added the test cases that @mdjermanovic used.

I've also updated the message data handling. I had already updated the other message data handlers as per previous comments, but I noticed that all 3 of the message data getters were doing basically the same thing. So I've added a getVariableDescription helper function to get the required info for the message data base on the type of the variable that is currently being reported.

Pearce-Ropion avatar Mar 27 '24 04:03 Pearce-Ropion