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 suggestions to use-isnan in binary expressions #17996

Merged
merged 13 commits into from Jan 29, 2024

Conversation

StyleShit
Copy link
Contributor

@StyleShit StyleShit commented Jan 16, 2024

Partially handles #17978
This PR adds support for fix suggestions in use-isnan only in binary expressions, so this:

x === NaN;
y !== NaN;

will be fixed to this:

Number.isNaN(x);
! Number.isNaN(y);

Copy link

linux-foundation-easycla bot commented Jan 16, 2024

CLA Signed

The committers listed above are authorized under a signed CLA.

@eslint-github-bot eslint-github-bot bot added the feature This change adds a new feature to ESLint label Jan 16, 2024
Copy link

netlify bot commented Jan 16, 2024

Deploy Preview for docs-eslint canceled.

Name Link
🔨 Latest commit 0481f3d
🔍 Latest deploy log https://app.netlify.com/sites/docs-eslint/deploys/65b11f377e2e070008601fd4

Comment on lines 702 to 712
{
code: `/* just
adding */ x /* some */ === /* comments */ NaN; // here`,
errors: [{
...comparisonError,
suggestions: [{
messageId: "replaceWithIsNaN",
output: `/* just
adding */ Number.isNaN(x); // here`
}]
}]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wasn't sure what to do with the comments here, so I left the default behavior for now.
Any direction on what's the expected behavior here?

Copy link
Member

Choose a reason for hiding this comment

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

I think this looks okay to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is it OK to lose some comments when fixing?

Copy link
Member

Choose a reason for hiding this comment

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

Good question -- ideally we don't lose any comments, but since this is a suggestion, I think it's okay because people will manually need to accept it and can always undo it if it's a problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

I also think it's okay for suggestions to just remove comments that happen to be there. As @nzakas noted, if it's a problem in some cases, user can undo the change and manually fix the code.

@StyleShit StyleShit marked this pull request as ready for review January 16, 2024 19:08
@StyleShit StyleShit requested a review from a team as a code owner January 16, 2024 19:08
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.

Thanks for this. The functionality for the equality operators looks good.

We shouldn't supply suggestions for comparison operators like < and >. Because this isn't an equality operation, we can't use isNaN() as a replacement for those.

You say this partially handles #17978 but you didn't indicate what part you are addressing and what part(s) you're not. Can you please update the description of the PR to explain what specifically you are addressing from the issue?

Comment on lines 702 to 712
{
code: `/* just
adding */ x /* some */ === /* comments */ NaN; // here`,
errors: [{
...comparisonError,
suggestions: [{
messageId: "replaceWithIsNaN",
output: `/* just
adding */ Number.isNaN(x); // here`
}]
}]
Copy link
Member

Choose a reason for hiding this comment

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

I think this looks okay to me.

@Tanujkanti4441 Tanujkanti4441 added rule Relates to ESLint's core rules evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion labels Jan 17, 2024
@StyleShit
Copy link
Contributor Author

We shouldn't supply suggestions for comparison operators like < and >.

Done

update the description of the PR

Yeah, sure, sorry for that. Updated 😄

@StyleShit StyleShit requested a review from nzakas January 17, 2024 17:09
lib/rules/use-isnan.js Outdated Show resolved Hide resolved
@StyleShit StyleShit requested a review from nzakas January 18, 2024 06:09
@nzakas nzakas added accepted There is consensus among the team that this change meets the criteria for inclusion contributor pool labels Jan 19, 2024
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. Would like another approval before merging.

@mdjermanovic mdjermanovic removed the evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion label Jan 19, 2024
@mdjermanovic
Copy link
Member

foo == NaN looks like intent to convert the other operand to a number, so it might make more sense to suggest isNaN(foo) because, unlike Number.isNaN(), it converts the given value to a number, or maybe Number.IsNaN(Number(foo)) if we want to avoid isNaN()?

const foo = "bar";

Number.isNaN(foo); // false
isNaN(foo); // true
Number.isNaN(Number(foo)); // true

The same for foo != NaN.

@StyleShit
Copy link
Contributor Author

foo == NaN looks like intent to convert the other operand to a number, so it might make more sense to suggest isNaN(foo) because, unlike Number.isNaN(), it converts the given value to a number, or maybe Number.IsNaN(Number(foo)) if we want to avoid isNaN()?

const foo = "bar";

Number.isNaN(foo); // false
isNaN(foo); // true
Number.isNaN(Number(foo)); // true

The same for foo != NaN.

I'm not sure we can assume the user intent (Well... yeah, we basically assume the intent by giving those suggestions, so... 😅), but if I understand correctly, this makes sense.

Not sure though... Maybe we can suggest both and leave the choice to the user? WDYT?

@mdjermanovic
Copy link
Member

Maybe we can suggest both and leave the choice to the user?

By both, you mean Number.IsNaN(foo) as one suggestion, and one of isNaN(foo)/Number.isNaN(Number(foo)) as another suggestion?

@StyleShit
Copy link
Contributor Author

Maybe we can suggest both and leave the choice to the user?

By both, you mean Number.IsNaN(foo) as one suggestion, and one of isNaN(foo)/Number.isNaN(Number(foo)) as another suggestion?

Yup, exactly

@nzakas
Copy link
Member

nzakas commented Jan 22, 2024

I think it's fine to leave two suggestions, one for each, though I would put Number.isNaN() first.

@StyleShit
Copy link
Contributor Author

StyleShit commented Jan 23, 2024

Added 2 suggestions support.
I think it's kinda weird that we cast things like 123 to Number.
Is there any way to avoid that or we must have types for this?

@StyleShit StyleShit requested a review from nzakas January 23, 2024 18:38
Comment on lines 366 to 381
{
code: "123 === NaN;",
errors: [comparisonError]
errors: [{
...comparisonError,
suggestions: [
{
messageId: "replaceWithIsNaN",
output: "Number.isNaN(123);"
},
{
messageId: "replaceWithCastingAndIsNaN",
output: "Number.isNaN(Number(123));"
}
]
}]
},
Copy link
Member

Choose a reason for hiding this comment

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

For === or !==, I think there should be only one suggestion (without Number()).

Copy link
Contributor Author

@StyleShit StyleShit Jan 24, 2024

Choose a reason for hiding this comment

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

Ohh, yeah, this makes more sense. Now I get what you mean.
Done :)

@mdjermanovic
Copy link
Member

I think it's kinda weird that we cast things like 123 to Number.

I think it's fine because a code like 123 === NaN doesn't make sense anyway.

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.

LGTM, thanks! Leaving open for @nzakas to re-verify.

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. Nice work!

@nzakas nzakas merged commit 2d11d46 into eslint:main Jan 29, 2024
17 checks passed
@nzakas
Copy link
Member

nzakas commented Feb 8, 2024

@StyleShit we'd like to pay you for this contribution, but I couldn't find an email address to send you the details. Can you please contact us at contact (at) eslint (dot) org? Thanks.

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 contributor pool 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.

None yet

4 participants