Skip to content

Fix overlapping changes when un-qualifying import use site within transformed export #40987

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

Merged
merged 2 commits into from
Oct 9, 2020

Conversation

andrewbranch
Copy link
Member

Fixes #40983

Can’t believe we didn’t get this one before now 🤔

@typescript-bot typescript-bot added Author: Team For Milestone Bug PRs that fix a bug with a specific milestone labels Oct 8, 2020
@@ -199,7 +199,26 @@ namespace ts.codefix {
}
});

return getSynthesizedDeepCloneWithRenames(nodeToRename, /*includeTrivia*/ true, identsToRenameMap, checker);
return getSynthesizedDeepCloneWithReplacements(nodeToRename, /*includeTrivia*/ true, original => {
Copy link
Member Author

Choose a reason for hiding this comment

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

This was, until now, the only consumer of getSynthesizedDeepCloneWithRenames, so I moved the bits that had poor reusability out to here.

Copy link
Member

Choose a reason for hiding this comment

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

weird that it had an unused optional callback parameter

Copy link
Member Author

Choose a reason for hiding this comment

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

It was used originally, but I stopped using it a few months back when I greatly simplified convertToAsyncFunction.

Copy link
Member

@sandersn sandersn left a comment

Choose a reason for hiding this comment

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

Looks reasonable. A few non-blocking questions; probably the most important is whether convertAssignment already took a set of use sites to unqualify.

@@ -199,7 +199,26 @@ namespace ts.codefix {
}
});

return getSynthesizedDeepCloneWithRenames(nodeToRename, /*includeTrivia*/ true, identsToRenameMap, checker);
return getSynthesizedDeepCloneWithReplacements(nodeToRename, /*includeTrivia*/ true, original => {
Copy link
Member

Choose a reason for hiding this comment

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

weird that it had an unused optional callback parameter

@@ -115,7 +129,7 @@ namespace ts.codefix {
}
case SyntaxKind.BinaryExpression: {
const { operatorToken } = expression as BinaryExpression;
return operatorToken.kind === SyntaxKind.EqualsToken && convertAssignment(sourceFile, checker, expression as BinaryExpression, changes, exports);
return operatorToken.kind === SyntaxKind.EqualsToken && convertAssignment(sourceFile, checker, expression as BinaryExpression, changes, exports, useSitesToUnqualify);
Copy link
Member

Choose a reason for hiding this comment

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

is a change to convertAssignment already in this PR? Or did it already take a map of use sites to unqualify?

Copy link
Member Author

Choose a reason for hiding this comment

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

useSitesToUnqualify?: ESMap<Node, Node>;
}

function convertedImports(newImports: readonly Node[], useSitesToUnqualify?: ESMap<Node, Node>): ConvertedImports {
Copy link
Member

Choose a reason for hiding this comment

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

This function seems a bit superfluous to me; there's only one call with a second argument.
I guess it lets you avoid writing casts or explicit return types in some places?

Copy link
Member Author

Choose a reason for hiding this comment

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

It was because of all the places that didn’t have the second argument that I added this; all those were one-liner returns that would have become four lines in order to add the object literal with useSitesToUnqualify: undefined on a line.

@@ -200,7 +223,7 @@ namespace ts.codefix {
changes.delete(sourceFile, assignment.parent);
}
else {
const replacement = isObjectLiteralExpression(right) ? tryChangeModuleExportsObject(right)
const replacement = isObjectLiteralExpression(right) ? tryChangeModuleExportsObject(right, useSitesToUnqualify)
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 know this code at all, but it seems like there are a lot of potential places that need to be threaded through with useSitesToUnqualify. Are you confident you didn't miss any?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep, pretty confident. I had never seen this code before either, but I ended up reading pretty much all the parts that actually perform text changes.

@andrewbranch andrewbranch merged commit 4766a2e into microsoft:master Oct 9, 2020
@andrewbranch andrewbranch deleted the bug/40983 branch October 9, 2020 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Author: Team For Milestone Bug PRs that fix a bug with a specific milestone
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Error: Debug Failure. False expression: Changes overlap
3 participants