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

Rule Change: [no-extra-parens] assume unknown node types need to be parenthesised if they are parenthesised #17173

Closed
1 task done
bradzacher opened this issue May 11, 2023 · 11 comments · Fixed by #17302
Closed
1 task done
Assignees
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 enhancement This change enhances an existing feature of ESLint rule Relates to ESLint's core rules

Comments

@bradzacher
Copy link
Contributor

bradzacher commented May 11, 2023

What rule do you want to change?

no-extra-parens

What change to do you want to make?

Generate fewer warnings

How do you think the change should be implemented?

A new default behavior

Example code

const x = (1 satisfies number).toFixed();
const y = (1 as number).toFixed();

What does the rule currently do for this code?

The rule currently errors on this TypeScript code because it doesn't understand that TSAsExpression and TSSatisfiesExpression have a lower precedence than MemberExpression.

This occurs because the precedence of "unknown" node types is automatically set to the maximum precedence:

default:
return 20;

So whenever the rule compares precedence it assumes the unknown node doesn't need parens

What will the rule do after it's changed?

For existing JS code - no change at all.
For non-JS code (eg TS) that has new AST node types - the rule will assume that these new nodes must be wrapped in parentheses and will not report.

Participation

  • I am willing to submit a pull request to implement this change.

Additional comments

We do have an extension rule, but some users do use the base rule (either because they choose to or accidentally).
This change would stop annoying false positives which will make users' lives better.

@bradzacher bradzacher added enhancement This change enhances an existing feature of ESLint rule Relates to ESLint's core rules labels May 11, 2023
@sam3k
Copy link
Contributor

sam3k commented May 11, 2023

Considering that const z = (2).toFixed(); is perfectly okay and it passes; I think this is a good rule change. You got my +1. 👍

@mdjermanovic
Copy link
Member

assume unknown node types need to be parenthesised if they are parenthesised

Makes sense to me 👍

@nzakas what do you think?

@bradzacher
Copy link
Contributor Author

My proposal for the change is essentially this:

 default:
-  return 20;
+  return node.type in eslintVisitorKeys ? 20 : -1;

WDYT?

@mdjermanovic
Copy link
Member

My proposal for the change is essentially this:

 default:
-  return 20;
+  return node.type in eslintVisitorKeys ? 20 : -1;

WDYT?

I think this will make sense for most places where astUtils.getPrecedence is used, but we should check each to see if the current assumption that unknown nodes have higher precedence seems better and in that case handle the -1 return value separately. For example, in prefer-exponentiation-operator here where we check if a ** b should be parenthesized based on its parent.

@bradzacher
Copy link
Contributor Author

bradzacher commented May 14, 2023

Maybe instead parameterise it so the usecases can choose?

function getPrecedence(node, useLowestForUnknownNodes = true) {
  switch (node.type) {
    // ...

    default:
      return !useLowestForUnknownNodes || node.type in eslintVisitorKeys ? 20 : -1;
  }
}

@mdjermanovic
Copy link
Member

Maybe instead parameterise it so the usecases can choose?

function getPrecedence(node, useLowestForUnknownNodes = true) {
  case (node.type) {
    // ...

    default:
     return !useLowestForUnknownNodes || node.type in eslintVisitorKeys ? 20 : -1;
  }
}

I think it's simpler and more flexible to always return -1 for unknown nodes and let the caller handle it as a special case if needed for the use case.

@github-actions
Copy link

Oops! It looks like we lost track of this issue. What do we want to do here? This issue will auto-close in 7 days without an update.

@github-actions github-actions bot added the Stale label Jun 15, 2023
@fasttime
Copy link
Member

@nzakas I think your feedback is wanted: #17173 (comment)

@fasttime fasttime removed the Stale label Jun 16, 2023
@nzakas
Copy link
Member

nzakas commented Jun 16, 2023

assume unknown node types need to be parenthesised if they are parenthesised

Makes sense to me. 👍

Thanks for the ping @fasttime -- still catching up after missing a couple weeks.

@nzakas nzakas added the accepted There is consensus among the team that this change meets the criteria for inclusion label Jun 16, 2023
@fasttime
Copy link
Member

This change request has been accepted. @bradzacher would you like to submit a PR?

@bradzacher
Copy link
Contributor Author

Sure - I'll look into it!

@mdjermanovic mdjermanovic linked a pull request Jun 26, 2023 that will close this issue
1 task
@eslint-github-bot eslint-github-bot bot locked and limited conversation to collaborators Dec 26, 2023
@eslint-github-bot eslint-github-bot bot added the archived due to age This issue has been archived; please open a new issue for any further discussion label Dec 26, 2023
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 enhancement This change enhances an existing feature of ESLint rule Relates to ESLint's core rules
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

5 participants