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 better TS generic support for arrow-parens (fixes #12570) #12587
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for contributing!
I have modified the rule to handle better typescript Generics, please have another look @kaicataldo @platinumazure |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this change! I left a couple of notes/questions for the start.
@matmalkowski Friendly ping |
@kaicataldo Just came back from leave, will try to take a look at the comments tomorrow / Monday 👍 |
@mdjermanovic @kaicataldo Hey, finally I had a moment to take a look at the change and do some fixes. Apart from making the fixer more generic, I've also added |
That part looks good, thanks for fixing the fixer :) |
@@ -111,15 +141,17 @@ module.exports = { | |||
node.params.length === 1 && | |||
node.params[0].type === "Identifier" && | |||
!node.params[0].typeAnnotation && | |||
!node.typeParameters && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works, but we shouldn't use node.typeParameters
because it isn't defined in estree extensions.
There is a simple alternative using the tokens only: Once we have openingParenToken
, we could take the first token of the function (the second if the function is async
) and check by reference whether it is the openingParenToken
. If it isn't, then the rule should not warn to remove parens. That way, we are not using undocumented AST properties. It's a simple check, though it doesn't make sense for JS-only input so the rule becomes aware that there can be something unknown before the params (I don't think there is a way to avoid that).
@platinumazure @kaicataldo would this be acceptable? This is to avoid removing necessary parens in cases such as this:
/* eslint arrow-parens: ["error", "as-needed"] */
<T>(x) => {};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm no longer on the team, but I would be okay with this approach. @kaicataldo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed!
const arrowToken = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken); | ||
|
||
const openingParenToken = node.params.length >= 1 && node.params[0].type === "Identifier" | ||
? sourceCode.getTokenBefore(node.params[0], t => isTokenPartOfNode(t, node) && astUtils.isOpeningParenToken(t)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is no opening paren for params (e.g., x => x
), I think this would go through all tokens before the param until it reaches the beginning of the source code.
Maybe we could just unconditionally get the first token before params[0]
and then check if it is an opening paren that is part of the node.
Also, I think there is no need to check node.params[0].type === "Identifier"
here.
|
||
const openingParenToken = node.params.length >= 1 && node.params[0].type === "Identifier" | ||
? sourceCode.getTokenBefore(node.params[0], t => isTokenPartOfNode(t, node) && astUtils.isOpeningParenToken(t)) | ||
: sourceCode.getTokenBefore(arrowToken, t => isTokenPartOfNode(t, node) && astUtils.isOpeningParenToken(t)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could find an opening paren in default values for params.
Maybe we should just always get the first token before params[0]
, and make sure that the rule works only on single-param arrow function by changing the ArrowFunctionExpression
selector to:
"ArrowFunctionExpression[params.length=1]"
@mdjermanovic @platinumazure @kaicataldo Hey, I would like to get back to this issue, there is still one question unanswered, could you please help with it? I would get back on fixes after it |
@matmalkowski Thanks for the ping. I'm no longer on the team, but I have left my own comment on what I think is the open question and asked Kai to follow up as well. Thank you for your patience! |
@matmalkowski Is there anything else we can do to help you land this? |
@matmalkowski are you still working on this? Is there anything you were waiting on? |
@nzakas Hey, unfortunately I didn't have much time to take a look at it - right now I'm unable to commit on any timeline. As for progress - I believe PR is missing some cleanup / refactor, as the main functionality/fix is already there in place - maybe someone would be interested in picking it up? |
@matmalkowski No worries. I think we should go ahead and close this PR so folks know they can work on this. If someone else ends up working on this and wants to finish it up, please feel free (including @matmalkowski, if things change 😄). |
What is the purpose of this pull request? (put an "X" next to item)
[ ] Documentation update
[ ] Bug fix (template)
[ ] New rule (template)
[ ] Changes an existing rule (template)
[ ] Add autofixing to a rule
[ ] Add a CLI option
[ ] Add something to the core
[x] Other, please explain:
Extend test coverage to include typescript generics as params with constrains
What changes did you make? (Give an overview)
I've added additional test cases for
arrow-parens
rule that that include usage of Typescript generics - refactored the rule itself so that new scenarios with generics are working correctly, by changing how param tokens are being picked. This fixes #12570Is there anything you'd like reviewers to focus on?