Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add no-useless-assignment rule #17625

Merged
merged 40 commits into from Jan 9, 2024

Conversation

ota-meshi
Copy link
Member

@ota-meshi ota-meshi commented Oct 7, 2023

Prerequisites checklist

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

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

What changes did you make? (Give an overview)

This PR adds a new no-useless-assignment rule which warns if a variable is not used after being assigned a value.

close #17559

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

This PR is still a draft as many test cases are missing.

@eslint-github-bot eslint-github-bot bot added the feature This change adds a new feature to ESLint label Oct 7, 2023
@netlify
Copy link

netlify bot commented Oct 7, 2023

Deploy Preview for docs-eslint ready!

Name Link
🔨 Latest commit f616420
🔍 Latest deploy log https://app.netlify.com/sites/docs-eslint/deploys/659d02b4404a2d0008f4050a
😎 Deploy Preview https://deploy-preview-17625--docs-eslint.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@fasttime fasttime added accepted There is consensus among the team that this change meets the criteria for inclusion rule Relates to ESLint's core rules labels Oct 7, 2023
@ota-meshi ota-meshi marked this pull request as ready for review October 9, 2023 05:43
@ota-meshi ota-meshi requested a review from a team as a code owner October 9, 2023 05:43
@ota-meshi ota-meshi marked this pull request as draft October 9, 2023 12:49
lib/rules/no-useless-assignment.js Outdated Show resolved Hide resolved
lib/rules/no-useless-assignment.js Outdated Show resolved Hide resolved
@ota-meshi ota-meshi marked this pull request as ready for review October 20, 2023 01:21
@ota-meshi
Copy link
Member Author

Hmm. I don't understand why it crashes in CI. I can't reproduce it well locally. If you know the cause, could you please advise?

@mdjermanovic
Copy link
Member

Hmm. I don't understand why it crashes in CI. I can't reproduce it well locally. If you know the cause, could you please advise?

The problem is fixed in dependencies now (#17664 (comment), fixed by humanwhocodes/object-schema@6ca80b0).

Comment on lines 246 to 247
// It is unused variable
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to avoid reporting on variables that are reported by no-unused-vars?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it shouldn't be reported in the new rule because it's not an unnecessary assignment, it's clearly an unnecessary variable. And it is reported by no-unused-vars.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add those details both as a comment here and in the documentation? I can see this being a bit confusing, but I agree with your rationale.

@mdjermanovic
Copy link
Member

I tried enabling this rule in the eslint codebase (this branch) and it found 46 errors:

C:\projects\tmp\ota-meshi-eslint\Makefile.js
  375:9  error  This assigned value is not used in subsequent statements  no-useless-assignment
  388:9  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\linter\code-path-analysis\code-path.js
  183:13  error  This assigned value is not used in subsequent statements  no-useless-assignment
  184:13  error  This assigned value is not used in subsequent statements  no-useless-assignment
  185:13  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\linter\config-comment-parser.js
   75:13  error  This assigned value is not used in subsequent statements  no-useless-assignment
  102:9   error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\linter\linter.js
  2062:13  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\linter\timing.js
  140:17  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\array-bracket-newline.js
  74:17  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\indent-legacy.js
  712:17  error  This assigned value is not used in subsequent statements  no-useless-assignment
  833:17  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\indent.js
  1407:21  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\key-spacing.js
  489:21  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\lines-around-comment.js
  156:17  error  This assigned value is not used in subsequent statements  no-useless-assignment
  166:13  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\max-len.js
  344:25  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\max-lines.js
  112:13  error  This assigned value is not used in subsequent statements  no-useless-assignment
  123:13  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\no-dupe-class-members.js
  85:21  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\no-dupe-else-if.js
  103:21  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\no-empty-function.js
  43:9  error  This assigned value is not used in subsequent statements  no-useless-assignment
  76:9  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\no-extra-parens.js
  497:17  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\no-loss-of-precision.js
  67:17  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\no-object-constructor.js
  64:9  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\no-trailing-spaces.js
  130:21  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\utils\ast-utils.js
  1804:13  error  This assigned value is not used in subsequent statements  no-useless-assignment
  1805:13  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\rules\yield-star-spacing.js
  79:21  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\lib\source-code\token-store\index.js
  40:9  error  This assigned value is not used in subsequent statements  no-useless-assignment
  41:9  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\tests\lib\cli-engine\cli-engine.js
  2510:21  error  This assigned value is not used in subsequent statements  no-useless-assignment
  2565:21  error  This assigned value is not used in subsequent statements  no-useless-assignment
  2622:21  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\tests\lib\eslint\eslint.js
  2464:21  error  This assigned value is not used in subsequent statements  no-useless-assignment
  2523:21  error  This assigned value is not used in subsequent statements  no-useless-assignment
  2583:21  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\tests\lib\eslint\flat-eslint.js
  2400:21  error  This assigned value is not used in subsequent statements  no-useless-assignment
  2465:21  error  This assigned value is not used in subsequent statements  no-useless-assignment
  2525:21  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\tests\lib\rule-tester\no-test-runners.js
  13:1  error  This assigned value is not used in subsequent statements  no-useless-assignment
  14:1  error  This assigned value is not used in subsequent statements  no-useless-assignment
  30:5  error  This assigned value is not used in subsequent statements  no-useless-assignment
  31:5  error  This assigned value is not used in subsequent statements  no-useless-assignment

C:\projects\tmp\ota-meshi-eslint\tools\update-readme.js
  152:9  error  This assigned value is not used in subsequent statements  no-useless-assignment

Most are initial assignments in declarations to default values like null, 0 or "". Perhaps these should be allowed in declarations (maybe optionally)?

There are also some that look to me like false positives for this rule, where the value is used on the right side of a subsequent assignment. For example:

eslint/Makefile.js

Lines 375 to 377 in 994596b

let commits = execSilent(`git rev-list HEAD -- ${filePath}`);
commits = splitCommandResultToLines(commits);

@mdjermanovic
Copy link
Member

mdjermanovic commented Oct 23, 2023

This is another kind of false positive, I believe:

items = {};
const normalizedString = string.replace(/([-a-zA-Z0-9/]+):/gu, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/u, "$1,");
try {
items = JSON.parse(`{${normalizedString}}`);
} catch (ex) {
debug("Manual parsing failed.");
return {
success: false,
error: {
ruleId: null,
fatal: true,
severity: 2,
message: `Failed to parse JSON from '${normalizedString}': ${ex.message}`,
line: location.start.line,
column: location.start.column + 1,
nodeType: null
}
};
}
return {
success: true,
config: items
};

The error is reported on line 102, but if JSON.parse() throws, that {} will be used as return value on line 127.

Edit: actually, this looks correct since catch always returns? Conclusion: this is not a false positive, the rule works fine in this case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you switch this to use FlatRuleTester instead? We are going through and updating all rule tests to do so. It should look like this:

const RuleTester = require("../../../lib/rule-tester/flat-rule-tester");

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the test case to use FlatRuleTester 👍

@nzakas
Copy link
Member

nzakas commented Dec 14, 2023

@mdjermanovic this is ready for you to check on your suggestions.

lib/rules/no-useless-assignment.js Outdated Show resolved Hide resolved
lib/rules/no-useless-assignment.js Outdated Show resolved Hide resolved
lib/rules/no-useless-assignment.js Outdated Show resolved Hide resolved
lib/rules/no-useless-assignment.js Outdated Show resolved Hide resolved
lib/rules/no-useless-assignment.js Outdated Show resolved Hide resolved
@ota-meshi
Copy link
Member Author

Thank you for your suggestions and also for finding the false positives. I fixed them.

Copy link
Member

@nzakas nzakas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Leaving open for @mdjermanovic to review.

@mdjermanovic
Copy link
Member

LGTM, I'll just close-reopen to check CI before merging.

@mdjermanovic mdjermanovic reopened this Jan 9, 2024
Copy link
Member

@mdjermanovic mdjermanovic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work, thanks!

Given the complexity of the problem and JS syntax, I wouldn't be surprised if some edge cases pop up in production, but can't see any at the moment.

Sorry for the delay in reviewing, there have been many tasks for the v9 release lately.

@mdjermanovic mdjermanovic merged commit b4e0503 into eslint:main Jan 9, 2024
15 checks passed
@ota-meshi ota-meshi deleted the no-useless-assignment branch January 9, 2024 08:48
bmish added a commit to bmish/eslint that referenced this pull request Jan 16, 2024
* main:
  chore: Split Docs CI from core CI (eslint#17897)
  fix: Ensure config keys are printed for config errors (eslint#17980)
  chore: delete relative-module-resolver.js (eslint#17981)
  docs: migration guide entry for `no-inner-declarations` (eslint#17977)
  docs: Update README
  feat: maintain latest ecma version in ESLint (eslint#17958)
  feat!: no-inner-declaration new default behaviour and option (eslint#17885)
  feat: add `no-useless-assignment` rule (eslint#17625)
  fix: `no-misleading-character-class` edge cases with granular errors (eslint#17970)
  feat: `no-misleading-character-class` granular errors (eslint#17515)
  docs: fix number of code-path events on custom rules page (eslint#17969)
  docs: reorder entries in v9 migration guide (eslint#17967)
  fix!: handle `--output-file` for empty output when saving to disk (eslint#17957)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion feature This change adds a new feature to ESLint rule Relates to ESLint's core rules
Projects
Status: Complete
Development

Successfully merging this pull request may close these issues.

New Rule: disallow useless assignments
4 participants