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

Print trailing comma after a single TS generic in arrow fns #14113

Merged
merged 5 commits into from Jan 10, 2022
Merged

Print trailing comma after a single TS generic in arrow fns #14113

merged 5 commits into from Jan 10, 2022

Conversation

ozanhonamlioglu
Copy link
Contributor

@ozanhonamlioglu ozanhonamlioglu commented Jan 7, 2022

Q                       A
Fixed Issues? Fixes #13778
Patch: Bug Fix? Yes
Major: Breaking Change?
Minor: New Feature?
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT

From now on, any project which uses typescript plugin, will unconditionally print the last comma inside type parameter angle brackets.

Here is a demo code

// ****** INPUTS
<T>(a: T): T => a; 
<T,>(a: T): T => a;

// ****** OUTPUTS
<T>(a: T): T => a; 
<T,>(a: T): T => a;

@babel-bot
Copy link
Collaborator

babel-bot commented Jan 7, 2022

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/50639/

@@ -15,6 +15,7 @@ export function TSTypeParameterInstantiation(
): void {
this.token("<");
this.printList(node.params, node, {});
if(node.extra?.trailingComma) this.token(",");
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for that PR!
I think it would be safer to always print the comma if node.params.length === 1, so that it also works when the node has been modified/generated by a plugin. For example:
https://astexplorer.net/#/gist/ef9b1bdad45421b25b826a06f3a707e1/latest

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I do it like that, now generator starts adding comma end of every conditional node.params.length === 1 type inside every angle bracket. But some of those usages are not compatible with typescript, such as this one.

// IN
// *****************************************************

const useState = <T>(x: T): T => x;

const foo = <T>(a: T) => {
  const x = useState<number>(2);
};


// OUT
// *****************************************************

const useState = <T,>(x: T): T => x;

const foo = <T,>(a: T) => {
  const x = useState<number,>(2); // now this becomes incompatible due to <number,>
};

Or am I missing something?

Copy link
Member

Choose a reason for hiding this comment

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

Oh true. TSTypeParameterInstantiation is called with an additional argument, parent: t.Node: you can check if parent.type === "ArrowFunctionExpression".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We also need to find the type of FunctionDeclaration right?

function foo<T>(a: T) {} // AST says this is ArrowFunctionExpression (init type)
const foo= <T>(x: T): T => x; // and says this is FunctionDeclaration (type)

They both should be generated with at least one comma inside their angle brackets.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think the first one needs a trailing comma, because it's not ambiguous with JSX.

Copy link
Member

Choose a reason for hiding this comment

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

If you are interested, I have another bug for you which can be fixed after that this PR is merged (we first need a second review)!

We currently parse <T>() => {} without problems even when both the JSX and TypeScript plugins are enabled. If there is a single type parameter and there isn't a trailing comma, we should report a parser error. It can probably be reported in

parseMaybeAssign(...args): N.Expression {
, using this.raise (see how it's used in other parts of that file). OVERWRITE=true yarn jest parser will then probably update some existing (wrong) tests: I would be surprised if we need new tests for this.

(Note: that function is probably one of the most complex parser functions 😬)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Absolutely, I want to work on this case. please assign it to me.
When do you think other reviewer can review this PR?

Copy link
Member

Choose a reason for hiding this comment

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

Probably @JLHwung or @existentialism can review this tomorrow or on Monday.

I haven't created an issue for that bug; feel free to consider it assigned to you and just link my comment in the new PR 🙂

Btw, you don't need to wait for this to be merged because it's a parser bug, but you will then need to rebase your new PR after that this is merged to check if any related @babel/generator tests need to be merged.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Absolutely, will start to work on it ASAP. Thanks @nicolo-ribaudo

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you are interested, I have another bug for you which can be fixed after that this PR is merged (we first need a second review)!

We currently parse <T>() => {} without problems even when both the JSX and TypeScript plugins are enabled. If there is a single type parameter and there isn't a trailing comma, we should report a parser error. It can probably be reported in

parseMaybeAssign(...args): N.Expression {

, using this.raise (see how it's used in other parts of that file). OVERWRITE=true yarn jest parser will then probably update some existing (wrong) tests: I would be surprised if we need new tests for this.
(Note: that function is probably one of the most complex parser functions 😬)

Hi @nicolo-ribaudo
I start to work on this bug today, will quote reply once I create a PR

@nicolo-ribaudo nicolo-ribaudo added area: typescript pkg: generator PR: Bug Fix 🐛 A type of pull request used for our changelog categories labels Jan 8, 2022
Copy link
Member

@nicolo-ribaudo nicolo-ribaudo left a comment

Choose a reason for hiding this comment

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

Thanks!

While reviewing this PR I found a TS bug: microsoft/TypeScript#47355

@nicolo-ribaudo nicolo-ribaudo changed the title solved last comma end of separated generic types Print trailing comma after a single TS generic in arrow fns Jan 10, 2022
@nicolo-ribaudo nicolo-ribaudo merged commit 1c32b67 into babel:main Jan 10, 2022
@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label May 6, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: typescript outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: generator PR: Bug Fix 🐛 A type of pull request used for our changelog categories
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: Edge case in TSX: <T,>(t: T) => t
4 participants