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 better TS generic support for arrow-parens (fixes #12570) #12587

Closed
wants to merge 6 commits into from
Closed

Fix: add better TS generic support for arrow-parens (fixes #12570) #12587

wants to merge 6 commits into from

Conversation

matmalkowski
Copy link

@matmalkowski matmalkowski commented Nov 21, 2019

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 #12570
Is there anything you'd like reviewers to focus on?

@eslint-deprecated eslint-deprecated bot added the triage An ESLint team member will look at this issue soon label Nov 21, 2019
@matmalkowski matmalkowski changed the title Chore: Adds more typescript test coverage for arrow-parens rule refs #12570 Chore: Adds typescript generics tests for arrow-parens (refs #12570) Nov 21, 2019
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.

Thanks for contributing!

@platinumazure platinumazure added chore This change is not user-facing rule Relates to ESLint's core rules and removed triage An ESLint team member will look at this issue soon labels Nov 21, 2019
@matmalkowski
Copy link
Author

I have modified the rule to handle better typescript Generics, please have another look @kaicataldo @platinumazure

@matmalkowski matmalkowski changed the title Chore: Adds typescript generics tests for arrow-parens (refs #12570) Fix: add better TS generic support for arrow-parens (fixes #12570) Nov 23, 2019
@mdjermanovic mdjermanovic added accepted There is consensus among the team that this change meets the criteria for inclusion bug ESLint is working incorrectly 3rd party plugin This is an issue related to a 3rd party plugin, config, or parser and removed chore This change is not user-facing labels Dec 8, 2019
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.

Thanks for this change! I left a couple of notes/questions for the start.

lib/rules/arrow-parens.js Outdated Show resolved Hide resolved
lib/rules/arrow-parens.js Outdated Show resolved Hide resolved
lib/rules/arrow-parens.js Outdated Show resolved Hide resolved
@kaicataldo
Copy link
Member

@matmalkowski Friendly ping

@matmalkowski
Copy link
Author

@kaicataldo Just came back from leave, will try to take a look at the comments tomorrow / Monday 👍

@matmalkowski
Copy link
Author

@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 yield test case to the suite.

@mdjermanovic
Copy link
Member

Apart from making the fixer more generic, I've also added yield test case to the suite.

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 &&
Copy link
Member

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) => {};

Copy link
Member

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?

Copy link
Member

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))
Copy link
Member

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));
Copy link
Member

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]"

@matmalkowski
Copy link
Author

@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

@platinumazure
Copy link
Member

@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!

@kaicataldo kaicataldo requested review from mdjermanovic and removed request for platinumazure March 2, 2020 18:17
@kaicataldo
Copy link
Member

@matmalkowski Is there anything else we can do to help you land this?

@nzakas
Copy link
Member

nzakas commented Jun 11, 2020

@matmalkowski are you still working on this? Is there anything you were waiting on?

@matmalkowski
Copy link
Author

@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?

@kaicataldo
Copy link
Member

@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 😄).

@kaicataldo kaicataldo closed this Jun 26, 2020
@eslint-deprecated eslint-deprecated bot locked and limited conversation to collaborators Dec 24, 2020
@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 Dec 24, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
3rd party plugin This is an issue related to a 3rd party plugin, config, or parser 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.

arrow-parens crashes when parsing typescript function with generics
5 participants