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

[breaking] Remove TSParenthesizedType unless createParenthesizedExpressions is enabled #9546

Closed
nicolo-ribaudo opened this issue Feb 19, 2019 · 13 comments · Fixed by #12608
Closed
Assignees
Labels
area: typescript Has PR i: discussion outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: parser
Milestone

Comments

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Feb 19, 2019

I don't understand why we generate TSParenthesizedType nodes by default. Example: AST Explorer. It isn't needed (it isn't part of the AST, but more a CST thing) and we don't use it from Flow.

Also, we should add it to Flow when that option is enabled.

Ref: #8025

@smelukov
Copy link
Contributor

smelukov commented Mar 1, 2020

I want to try to deal with it

@smelukov
Copy link
Contributor

smelukov commented Mar 2, 2020

@nicolo-ribaudo
Seems like it breaks some cases:

Input: let x: [string, number?, (string | number)?]
Output: let x: [string, number?, string | number?]

It makes a different sense

Input: type Element<T> = T extends (infer U)[] ? U : T;
Output: type Element<T> = T extends infer U[] ? U : T;

Parsing error

@smelukov
Copy link
Contributor

smelukov commented Mar 3, 2020

Seems like we should create TSParenthesizedType nodes even if createParenthesizedExpressions is disabled because it breaks some cases.

@nicolo-ribaudo
Copy link
Member Author

The second one is like a @babel/generator bug: it should automatically add parentheses when needed, based on the AST structure.

Parentheses are handled by packages/babel-generator/src/node/parentheses.js: as you can see, there are many functions that, given a node and its parent, return true if the node should be parenthesized.

For example, to fix your first case we would need a function like this:

export function TSInferType(node: Object, parent: Object): boolean {
  return (
    t.isTSArrayType(parent) ||
    t.isTSOptionalType(parent)
  );
}

This is already a bug in Babel 7, because a plugin could create a TSArrayType node whose child is a TSInferType node, and it wouldn't be printed correctly. Would you like to fix it in a separate PR, so that we can release it in Babel 7?

On the other hand, I cannot reproduce the first case.
Here I wrote a small plugin which replaces TSParenthesizedType nodes with their children, as if they weren't generated by the parser in the first place. As you can see, it reproduces the second case but not the first one.

Maybe the AST generated by the parser is wrong? You need to manually check if it is correct, and if it isn't it's probably caused by some changes in the parser logic while disabling the TSParenthesizedType node.

I'd be happy to look at a "work in progress" PR if you need help.

@smelukov
Copy link
Contributor

smelukov commented Mar 3, 2020

I'd be happy to look at a "work in progress" PR if you need help.

@nicolo-ribaudo #11200 look at the failed tests

@smelukov
Copy link
Contributor

smelukov commented Mar 4, 2020

I think that I will fix babel 7 in a separated PR

@nicolo-ribaudo
Copy link
Member Author

Thanks! We will do like this:

  • Merge the Babel 7 PR to master
  • I will merge master into next-8-dev
    -You can then rebase your PR on the new next-8-dev

@smelukov
Copy link
Contributor

smelukov commented Mar 4, 2020

This is already a bug in Babel 7

It there an issue with a broken example for babel 7?

@smelukov
Copy link
Contributor

smelukov commented Mar 4, 2020

Now I can't reproduce the second case...
I suggest fix it for babel 8 for now

@nicolo-ribaudo
Copy link
Member Author

I will write a reproduction for Babel 7 in ~1 hour

@smelukov
Copy link
Contributor

smelukov commented Mar 5, 2020

@nicolo-ribaudo ☺️

@nicolo-ribaudo
Copy link
Member Author

Sorry for this super long hour! 😛

You can add this test to babel-generator/test/index.js (it has a section for TypeScript)

    it("wraps around infer inside an array type", () => {
      const type = t.tsArrayType(
        t.tsInferType(t.tsTypeParameter(null, null, "T")),
      );

      const output = generate(type).code;
      expect(output).toBe("(infer T)[]");
    });

@smelukov
Copy link
Contributor

#11227

@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 Apr 14, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: typescript Has PR i: discussion outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: parser
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants