Skip to content

Commit b9f48c1

Browse files
author
Andy
authored
refactorConvertToEs6Module: Preserve quote style of imports (#22929)
1 parent 07a890d commit b9f48c1

File tree

3 files changed

+23
-14
lines changed

3 files changed

+23
-14
lines changed

src/services/codefixes/convertToEs6Module.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,15 @@ namespace ts.codefix {
2020

2121
function fixImportOfModuleExports(importingFile: SourceFile, exportingFile: SourceFile, changes: textChanges.ChangeTracker) {
2222
for (const moduleSpecifier of importingFile.imports) {
23-
const { text } = moduleSpecifier;
24-
const imported = getResolvedModule(importingFile, text);
23+
const imported = getResolvedModule(importingFile, moduleSpecifier.text);
2524
if (!imported || imported.resolvedFileName !== exportingFile.fileName) {
2625
continue;
2726
}
2827

2928
const importNode = importFromModuleSpecifier(moduleSpecifier);
3029
switch (importNode.kind) {
3130
case SyntaxKind.ImportEqualsDeclaration:
32-
changes.replaceNode(importingFile, importNode, makeImport(importNode.name, /*namedImports*/ undefined, text));
31+
changes.replaceNode(importingFile, importNode, makeImport(importNode.name, /*namedImports*/ undefined, moduleSpecifier));
3332
break;
3433
case SyntaxKind.CallExpression:
3534
if (isRequireCall(importNode, /*checkArgumentIsStringLiteralLike*/ false)) {
@@ -111,7 +110,7 @@ namespace ts.codefix {
111110
case SyntaxKind.CallExpression: {
112111
if (isRequireCall(expression, /*checkArgumentIsStringLiteralLike*/ true)) {
113112
// For side-effecting require() call, just make a side-effecting import.
114-
changes.replaceNode(sourceFile, statement, makeImport(/*name*/ undefined, /*namedImports*/ undefined, expression.arguments[0].text));
113+
changes.replaceNode(sourceFile, statement, makeImport(/*name*/ undefined, /*namedImports*/ undefined, expression.arguments[0]));
115114
}
116115
return false;
117116
}
@@ -139,11 +138,11 @@ namespace ts.codefix {
139138
}
140139
if (isRequireCall(initializer, /*checkArgumentIsStringLiteralLike*/ true)) {
141140
foundImport = true;
142-
return convertSingleImport(sourceFile, name, initializer.arguments[0].text, changes, checker, identifiers, target);
141+
return convertSingleImport(sourceFile, name, initializer.arguments[0], changes, checker, identifiers, target);
143142
}
144143
else if (isPropertyAccessExpression(initializer) && isRequireCall(initializer.expression, /*checkArgumentIsStringLiteralLike*/ true)) {
145144
foundImport = true;
146-
return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0].text, identifiers);
145+
return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0], identifiers);
147146
}
148147
else {
149148
// Move it out to its own variable statement.
@@ -157,7 +156,7 @@ namespace ts.codefix {
157156
}
158157

159158
/** Converts `const name = require("moduleSpecifier").propertyName` */
160-
function convertPropertyAccessImport(name: BindingName, propertyName: string, moduleSpecifier: string, identifiers: Identifiers): ReadonlyArray<Node> {
159+
function convertPropertyAccessImport(name: BindingName, propertyName: string, moduleSpecifier: StringLiteralLike, identifiers: Identifiers): ReadonlyArray<Node> {
161160
switch (name.kind) {
162161
case SyntaxKind.ObjectBindingPattern:
163162
case SyntaxKind.ArrayBindingPattern: {
@@ -340,7 +339,7 @@ namespace ts.codefix {
340339
function convertSingleImport(
341340
file: SourceFile,
342341
name: BindingName,
343-
moduleSpecifier: string,
342+
moduleSpecifier: StringLiteralLike,
344343
changes: textChanges.ChangeTracker,
345344
checker: TypeChecker,
346345
identifiers: Identifiers,
@@ -362,7 +361,7 @@ namespace ts.codefix {
362361
import x from "x";
363362
const [a, b, c] = x;
364363
*/
365-
const tmp = makeUniqueName(moduleSpecifierToValidIdentifier(moduleSpecifier, target), identifiers);
364+
const tmp = makeUniqueName(moduleSpecifierToValidIdentifier(moduleSpecifier.text, target), identifiers);
366365
return [
367366
makeImport(createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier),
368367
makeConst(/*modifiers*/ undefined, getSynthesizedDeepClone(name), createIdentifier(tmp)),
@@ -379,7 +378,7 @@ namespace ts.codefix {
379378
* Convert `import x = require("x").`
380379
* Also converts uses like `x.y()` to `y()` and uses a named import.
381380
*/
382-
function convertSingleIdentifierImport(file: SourceFile, name: Identifier, moduleSpecifier: string, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers): ReadonlyArray<Node> {
381+
function convertSingleIdentifierImport(file: SourceFile, name: Identifier, moduleSpecifier: StringLiteralLike, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers): ReadonlyArray<Node> {
383382
const nameSymbol = checker.getSymbolAtLocation(name);
384383
// Maps from module property name to name actually used. (The same if there isn't shadowing.)
385384
const namedBindingsNames = createMap<string>();
@@ -486,14 +485,14 @@ namespace ts.codefix {
486485
getSynthesizedDeepClones(cls.members));
487486
}
488487

489-
function makeSingleImport(localName: string, propertyName: string, moduleSpecifier: string): ImportDeclaration {
488+
function makeSingleImport(localName: string, propertyName: string, moduleSpecifier: StringLiteralLike): ImportDeclaration {
490489
return propertyName === "default"
491490
? makeImport(createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier)
492491
: makeImport(/*name*/ undefined, [makeImportSpecifier(propertyName, localName)], moduleSpecifier);
493492
}
494493

495-
function makeImport(name: Identifier | undefined, namedImports: ReadonlyArray<ImportSpecifier> | undefined, moduleSpecifier: string): ImportDeclaration {
496-
return makeImportDeclaration(name, namedImports, createLiteral(moduleSpecifier));
494+
function makeImport(name: Identifier | undefined, namedImports: ReadonlyArray<ImportSpecifier> | undefined, moduleSpecifier: StringLiteralLike): ImportDeclaration {
495+
return makeImportDeclaration(name, namedImports, moduleSpecifier);
497496
}
498497

499498
export function makeImportDeclaration(name: Identifier, namedImports: ReadonlyArray<ImportSpecifier> | undefined, moduleSpecifier: Expression) {

tests/cases/fourslash/refactorConvertToEs6Module_import_sideEffect.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// @allowJs: true
66

77
// @Filename: /a.js
8-
/////*a*/require/*b*/("foo");
8+
////require("foo");
99

1010
verify.codeFix({
1111
description: "Convert to ES6 module",
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @allowJs: true
4+
// @Filename: /a.js
5+
////const a = require('a');
6+
7+
verify.codeFix({
8+
description: "Convert to ES6 module",
9+
newFileContent: "import a from 'a';",
10+
});

0 commit comments

Comments
 (0)