convertToEs6Module: Avoid replacing entire function#22507
Conversation
3fde583 to
9e99f5d
Compare
9e99f5d to
5c13eaf
Compare
|
|
||
| verify.codeFix({ | ||
| description: "Convert to ES6 module", | ||
| // TODO: GH#22492 |
There was a problem hiding this comment.
Isn't this the bug that this change fixes?
| if (lparen) { | ||
| // `() => {}` --> `function f() {}` | ||
| this.insertNodesAt(sourceFile, lparen.getStart(sourceFile), [createToken(SyntaxKind.FunctionKeyword), createIdentifier(name)], { joiner: " " }); | ||
| this.deleteNode(sourceFile, arrow); |
There was a problem hiding this comment.
Will this destroy any trivia? Does it matter?
| const arrow = findChildOfKind(node, SyntaxKind.EqualsGreaterThanToken, sourceFile)!; | ||
| const lparen = findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile); | ||
| if (lparen) { | ||
| // `() => {}` --> `function f() {}` |
There was a problem hiding this comment.
(Or is there some reason that's impossible here?)
There was a problem hiding this comment.
See if (node.body.kind !== SyntaxKind.Block) below
src/services/textChanges.ts
Outdated
| } | ||
| else { | ||
| // `x => {}` -> `function f(x) {}` | ||
| this.insertNodesAt(sourceFile, first(node.parameters).getStart(sourceFile), [createToken(SyntaxKind.FunctionKeyword), createIdentifier(name + "(")], { joiner: " " }); |
There was a problem hiding this comment.
The lparen is in the identifier because we don't want a space between them? If we're going to do that, why not just insert raw text?
There was a problem hiding this comment.
Good idea, when I first wrote this we didn't have insertText.
src/services/textChanges.ts
Outdated
| else { | ||
| // `x => {}` -> `function f(x) {}` | ||
| this.insertNodesAt(sourceFile, first(node.parameters).getStart(sourceFile), [createToken(SyntaxKind.FunctionKeyword), createIdentifier(name + "(")], { joiner: " " }); | ||
| // Replaceing full range of arrow to get rid of the leading space -- replace ` =>` with `)` |
| // `x => {}` -> `function f(x) {}` | ||
| this.insertNodesAt(sourceFile, first(node.parameters).getStart(sourceFile), [createToken(SyntaxKind.FunctionKeyword), createIdentifier(name + "(")], { joiner: " " }); | ||
| // Replaceing full range of arrow to get rid of the leading space -- replace ` =>` with `)` | ||
| this.replaceRange(sourceFile, arrow, createToken(SyntaxKind.CloseParenToken)); |
There was a problem hiding this comment.
This will definitely clobber trivia.
| } | ||
|
|
||
| function convertExportsDotXEquals(name: string | undefined, exported: Expression): Statement { | ||
| function convertExportsDotXEquals({ left, right, parent }: BinaryExpression & { left: PropertyAccessExpression }, sourceFile: SourceFile, changes: textChanges.ChangeTracker): void { |
There was a problem hiding this comment.
Could "ExportsDotXEquals" be rephrased as "ExportsPropertyAssignment"?
| const name = left.name.text; | ||
| if ((isFunctionExpression(right) || isArrowFunction(right) || isClassExpression(right)) && (!right.name || right.name.text === name)) { | ||
| // `exports.f = function() {}` -> `export function f() {}` -- Replace `exports.f = ` with `export `, and insert the name after `function`. | ||
| changes.replaceRange(sourceFile, { pos: left.getStart(sourceFile), end: right.getStart(sourceFile) }, createToken(SyntaxKind.ExportKeyword), { suffix: " " }); |
There was a problem hiding this comment.
Will this clobber trivia on the LHS of the assignment?
| if (!right.name) changes.insertName(sourceFile, right, name); | ||
|
|
||
| const semi = findChildOfKind(parent, SyntaxKind.SemicolonToken, sourceFile); | ||
| if (semi) changes.deleteNode(sourceFile, semi, { useNonAdjustedEndPosition: true }); |
There was a problem hiding this comment.
Will this clobber trailing trivia on the semicolon?
Fixes #22492
Will rebase once #22361 is in.