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

Fix: add parentheses in no-extra-boolean-cast autofixer (fixes #7912) #7914

Merged
merged 1 commit into from
Jan 14, 2017

Conversation

sprzybylski
Copy link
Contributor

What is the purpose of this pull request? (put an "X" next to item)
[X] Bug fix for #7912

What changes did you make? (Give an overview)
I've change autofixer in no-extra-boolean-cast rule for "Redundant Boolean call" to include brackets if the inner part is an expression.

@jsf-clabot
Copy link

jsf-clabot commented Jan 12, 2017

CLA assistant check
All committers have signed the CLA.

@mention-bot
Copy link

@sprzybylski, thanks for your PR! By analyzing the history of the files in this pull request, we identified @not-an-aardvark, @btmills and @vitorbal to be potential reviewers.

@eslintbot
Copy link

Thanks for the pull request, @sprzybylski! I took a look to make sure it's ready for merging and found some changes are needed:

  • The commit summary needs to begin with a tag (such as Fix: or Update:). Please check out our guide for how to properly format your commit summary and update it on this pull request.

Can you please update the pull request to address these?

(More information can be found in our pull request guide.)

@eslintbot
Copy link

Thanks for the pull request, @sprzybylski! I took a look to make sure it's ready for merging and found some changes are needed:

  • The commit summary must be 72 characters or shorter. Please check out our guide for how to properly format your commit summary and update it on this pull request.

Can you please update the pull request to address these?

(More information can be found in our pull request guide.)

@not-an-aardvark not-an-aardvark added accepted There is consensus among the team that this change meets the criteria for inclusion bug ESLint is working incorrectly rule Relates to ESLint's core rules labels Jan 12, 2017
Copy link
Member

@not-an-aardvark not-an-aardvark 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 the pull request! I have a suggestion for how the fix can be improved.

fix: fixer => {
const argument = node.arguments[0];

if (argument.type === "LogicalExpression") {
Copy link
Member

Choose a reason for hiding this comment

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

This will resolve the specific case in the bug report, but I think the problem will still exist for arguments that aren't LogicalExpression nodes. For example, this fix would still be incorrect:

!Boolean(1 + 2);

// gets fixed to:

!1 + 2;

I think best solution would be to check the precedence of the argument. The fixer should only add parentheses if the argument has lower precedence than the !(...) node, which is a UnaryExpression. (If the argument has higher precedence, the ! operator will get applied to the entire argument anyway.)

For example, a UnaryExpression has a higher precedence than a LogicalExpression, so !foo && bar gets parsed as (!foo) && bar. On the other hand, a CallExpression has lower precedence than a UnaryExpression, so !foo() will get parsed as !(foo()) rather than (!foo)().

A function to get the precedence of a node can be found here in ast-utils.js.

@sprzybylski sprzybylski changed the title Fixes #7912; adds brackets for expressions in no-extra-boolean-cast autofixer Fix: add parentheses in no-extra-boolean-cast autofixer (fixes #7912) Jan 12, 2017
@eslintbot
Copy link

LGTM

fix: fixer => {
const argument = node.arguments[0];

if (astUtils.getPrecedence(argument) < astUtils.getPrecedence(node)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @not-an-aardvark for the suggestion! I'm not 100% sure if I get it right.
In this case node precedence will always be the same because its CallExpression every time. So parentheses will be skipped only for NewExpressions.

Copy link
Member

Choose a reason for hiding this comment

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

It looks like this is using the precedence of the Boolean() call expression, but remember that the call expression won't exist anymore when Boolean is removed. Instead, I think we want to compare it to node.parent, which is a UnaryExpression.

To double-check, I think it would be a good idea to add cases like these to the tests:

!Boolean(foo + bar);

// fixed to

!(foo + bar);

// ---

!Boolean(+foo);

// fixed to

!+foo;

// ---

!Boolean(foo());

// fixed to

!foo();

// ---

!Boolean(foo = bar);

// fixed to

!(foo = bar);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated PR. Thank you!

@eslintbot
Copy link

LGTM

Copy link
Member

@not-an-aardvark not-an-aardvark 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!

Copy link
Member

@platinumazure platinumazure left a comment

Choose a reason for hiding this comment

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

Awesome! LGTM, thanks for contributing!

Copy link
Member

@vitorbal vitorbal 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 a lot!

@nzakas nzakas merged commit 6448ba0 into eslint:master Jan 14, 2017
@eslint-deprecated eslint-deprecated bot locked and limited conversation to collaborators Feb 6, 2018
@eslint-deprecated eslint-deprecated bot added the archived due to age This issue has been archived; please open a new issue for any further discussion label Feb 6, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion archived due to age This issue has been archived; please open a new issue for any further discussion bug ESLint is working incorrectly rule Relates to ESLint's core rules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants