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 miss-reported node reuse in types. #58221

Merged
merged 3 commits into from
Apr 17, 2024

Conversation

dragomirtitian
Copy link
Contributor

Node reuse is not being reported correctly. When using a cached node builder result the original node was being set as a synthetic node (the node that was in the cache) rather than an original source node.

Ex:

var v = (a: ) => {
>v : (a: any) => void                         //<- correct, no node reuse
>  : ^ ^^^^^^^^^^^^^^
>(a: ) => {   } : (a: any) => void
>               :                        //<-  second time around nodes are reused?

@typescript-bot typescript-bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Apr 17, 2024
@typescript-bot
Copy link
Collaborator

This PR doesn't have any linked issues. Please open an issue that references this PR. From there we can discuss and prioritise.

@dragomirtitian
Copy link
Contributor Author

cc: @weswigham

if (!location) {
return range;
if (!location || nodeIsSynthesized(location)) {
return setOriginalNode(range, location?.original);
Copy link
Member

Choose a reason for hiding this comment

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

If range already has a .original set, this is going to unset it if location is undefined or lacks a .original of its own, which, while is what fixes the issue you witness, doesn't seem desirable. Unsetting .original on a copy is probably not a good thing. If this issue is that when we clone a node from the cache, we .original it, we should update the underlining requirements in nodeIsFullySynthetic in typeWriter.ts to instead of just checking for a .original, specifically look for a getParseTreeNode instead. So,

function nodeIsFullySynthetic(node: ts.Node) {
    return ts.nodeIsSynthesized(node) && !ts.getParseTreeNode(node);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That also works. My thought was that the node you get should be the same regardless of if it comes from the cache or from the original operation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to using the parse tree node.

Copy link
Member

@weswigham weswigham left a comment

Choose a reason for hiding this comment

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

I don't think we need the new nodeIsSynthesized check, either - all that's going to do is block setting .original on the range when the location has no position data, but it may still have a .original of its' own that is a parse tree node, and we wanna keep that 3 node chain (and is what getParseTreeNode looks up)

@weswigham
Copy link
Member

weswigham commented Apr 17, 2024

🤦 I meant the one just added in this PR in checker.ts - though that one is probably redundant, too (since we generally set original node now), I'd rather keep it, since a node made with a pos/end set, but no .original set to a parse node is probably still based enough on an input node, since it has concrete positions (which have to have come from one or more input nodes).

@weswigham weswigham merged commit 23e99c2 into microsoft:main Apr 17, 2024
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants