Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0fefaf2

Browse filesBrowse files
author
Andy
authored
moveToNewFile: Infer quote preference (microsoft#24652)
1 parent 83c58a4 commit 0fefaf2
Copy full SHA for 0fefaf2

7 files changed

+85-49Lines changed: 85 additions & 49 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/services/codefixes/convertToEs6Module.ts‎

Copy file name to clipboardExpand all lines: src/services/codefixes/convertToEs6Module.ts
+32-24Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ namespace ts.codefix {
55
getCodeActions(context) {
66
const { sourceFile, program, preferences } = context;
77
const changes = textChanges.ChangeTracker.with(context, changes => {
8-
const moduleExportsChangedToDefault = convertFileToEs6Module(sourceFile, program.getTypeChecker(), changes, program.getCompilerOptions().target!, preferences);
8+
const moduleExportsChangedToDefault = convertFileToEs6Module(sourceFile, program.getTypeChecker(), changes, program.getCompilerOptions().target!, getQuotePreference(sourceFile, preferences));
99
if (moduleExportsChangedToDefault) {
1010
for (const importingFile of program.getSourceFiles()) {
11-
fixImportOfModuleExports(importingFile, sourceFile, changes, preferences);
11+
fixImportOfModuleExports(importingFile, sourceFile, changes, getQuotePreference(importingFile, preferences));
1212
}
1313
}
1414
});
@@ -17,7 +17,7 @@ namespace ts.codefix {
1717
},
1818
});
1919

20-
function fixImportOfModuleExports(importingFile: SourceFile, exportingFile: SourceFile, changes: textChanges.ChangeTracker, preferences: UserPreferences) {
20+
function fixImportOfModuleExports(importingFile: SourceFile, exportingFile: SourceFile, changes: textChanges.ChangeTracker, quotePreference: QuotePreference) {
2121
for (const moduleSpecifier of importingFile.imports) {
2222
const imported = getResolvedModule(importingFile, moduleSpecifier.text);
2323
if (!imported || imported.resolvedFileName !== exportingFile.fileName) {
@@ -27,7 +27,7 @@ namespace ts.codefix {
2727
const importNode = importFromModuleSpecifier(moduleSpecifier);
2828
switch (importNode.kind) {
2929
case SyntaxKind.ImportEqualsDeclaration:
30-
changes.replaceNode(importingFile, importNode, makeImport(importNode.name, /*namedImports*/ undefined, moduleSpecifier, preferences));
30+
changes.replaceNode(importingFile, importNode, makeImport(importNode.name, /*namedImports*/ undefined, moduleSpecifier, quotePreference));
3131
break;
3232
case SyntaxKind.CallExpression:
3333
if (isRequireCall(importNode, /*checkArgumentIsStringLiteralLike*/ false)) {
@@ -39,13 +39,13 @@ namespace ts.codefix {
3939
}
4040

4141
/** @returns Whether we converted a `module.exports =` to a default export. */
42-
function convertFileToEs6Module(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, target: ScriptTarget, preferences: UserPreferences): ModuleExportsChanged {
42+
function convertFileToEs6Module(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, target: ScriptTarget, quotePreference: QuotePreference): ModuleExportsChanged {
4343
const identifiers: Identifiers = { original: collectFreeIdentifiers(sourceFile), additional: createMap<true>() };
4444
const exports = collectExportRenames(sourceFile, checker, identifiers);
4545
convertExportsAccesses(sourceFile, exports, changes);
4646
let moduleExportsChangedToDefault = false;
4747
for (const statement of sourceFile.statements) {
48-
const moduleExportsChanged = convertStatement(sourceFile, statement, checker, changes, identifiers, target, exports, preferences);
48+
const moduleExportsChanged = convertStatement(sourceFile, statement, checker, changes, identifiers, target, exports, quotePreference);
4949
moduleExportsChangedToDefault = moduleExportsChangedToDefault || moduleExportsChanged;
5050
}
5151
return moduleExportsChangedToDefault;
@@ -98,18 +98,18 @@ namespace ts.codefix {
9898
/** Whether `module.exports =` was changed to `export default` */
9999
type ModuleExportsChanged = boolean;
100100

101-
function convertStatement(sourceFile: SourceFile, statement: Statement, checker: TypeChecker, changes: textChanges.ChangeTracker, identifiers: Identifiers, target: ScriptTarget, exports: ExportRenames, preferences: UserPreferences): ModuleExportsChanged {
101+
function convertStatement(sourceFile: SourceFile, statement: Statement, checker: TypeChecker, changes: textChanges.ChangeTracker, identifiers: Identifiers, target: ScriptTarget, exports: ExportRenames, quotePreference: QuotePreference): ModuleExportsChanged {
102102
switch (statement.kind) {
103103
case SyntaxKind.VariableStatement:
104-
convertVariableStatement(sourceFile, statement as VariableStatement, changes, checker, identifiers, target, preferences);
104+
convertVariableStatement(sourceFile, statement as VariableStatement, changes, checker, identifiers, target, quotePreference);
105105
return false;
106106
case SyntaxKind.ExpressionStatement: {
107107
const { expression } = statement as ExpressionStatement;
108108
switch (expression.kind) {
109109
case SyntaxKind.CallExpression: {
110110
if (isRequireCall(expression, /*checkArgumentIsStringLiteralLike*/ true)) {
111111
// For side-effecting require() call, just make a side-effecting import.
112-
changes.replaceNode(sourceFile, statement, makeImport(/*name*/ undefined, /*namedImports*/ undefined, expression.arguments[0], preferences));
112+
changes.replaceNode(sourceFile, statement, makeImport(/*name*/ undefined, /*namedImports*/ undefined, expression.arguments[0], quotePreference));
113113
}
114114
return false;
115115
}
@@ -125,7 +125,15 @@ namespace ts.codefix {
125125
}
126126
}
127127

128-
function convertVariableStatement(sourceFile: SourceFile, statement: VariableStatement, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers, target: ScriptTarget, preferences: UserPreferences): void {
128+
function convertVariableStatement(
129+
sourceFile: SourceFile,
130+
statement: VariableStatement,
131+
changes: textChanges.ChangeTracker,
132+
checker: TypeChecker,
133+
identifiers: Identifiers,
134+
target: ScriptTarget,
135+
quotePreference: QuotePreference,
136+
): void {
129137
const { declarationList } = statement;
130138
let foundImport = false;
131139
const newNodes = flatMap(declarationList.declarations, decl => {
@@ -138,11 +146,11 @@ namespace ts.codefix {
138146
}
139147
else if (isRequireCall(initializer, /*checkArgumentIsStringLiteralLike*/ true)) {
140148
foundImport = true;
141-
return convertSingleImport(sourceFile, name, initializer.arguments[0], changes, checker, identifiers, target, preferences);
149+
return convertSingleImport(sourceFile, name, initializer.arguments[0], changes, checker, identifiers, target, quotePreference);
142150
}
143151
else if (isPropertyAccessExpression(initializer) && isRequireCall(initializer.expression, /*checkArgumentIsStringLiteralLike*/ true)) {
144152
foundImport = true;
145-
return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0], identifiers, preferences);
153+
return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0], identifiers, quotePreference);
146154
}
147155
}
148156
// Move it out to its own variable statement. (This will not be used if `!foundImport`)
@@ -155,20 +163,20 @@ namespace ts.codefix {
155163
}
156164

157165
/** Converts `const name = require("moduleSpecifier").propertyName` */
158-
function convertPropertyAccessImport(name: BindingName, propertyName: string, moduleSpecifier: StringLiteralLike, identifiers: Identifiers, preferences: UserPreferences): ReadonlyArray<Node> {
166+
function convertPropertyAccessImport(name: BindingName, propertyName: string, moduleSpecifier: StringLiteralLike, identifiers: Identifiers, quotePreference: QuotePreference): ReadonlyArray<Node> {
159167
switch (name.kind) {
160168
case SyntaxKind.ObjectBindingPattern:
161169
case SyntaxKind.ArrayBindingPattern: {
162170
// `const [a, b] = require("c").d` --> `import { d } from "c"; const [a, b] = d;`
163171
const tmp = makeUniqueName(propertyName, identifiers);
164172
return [
165-
makeSingleImport(tmp, propertyName, moduleSpecifier, preferences),
173+
makeSingleImport(tmp, propertyName, moduleSpecifier, quotePreference),
166174
makeConst(/*modifiers*/ undefined, name, createIdentifier(tmp)),
167175
];
168176
}
169177
case SyntaxKind.Identifier:
170178
// `const a = require("b").c` --> `import { c as a } from "./b";
171-
return [makeSingleImport(name.text, propertyName, moduleSpecifier, preferences)];
179+
return [makeSingleImport(name.text, propertyName, moduleSpecifier, quotePreference)];
172180
default:
173181
return Debug.assertNever(name);
174182
}
@@ -340,7 +348,7 @@ namespace ts.codefix {
340348
checker: TypeChecker,
341349
identifiers: Identifiers,
342350
target: ScriptTarget,
343-
preferences: UserPreferences,
351+
quotePreference: QuotePreference,
344352
): ReadonlyArray<Node> {
345353
switch (name.kind) {
346354
case SyntaxKind.ObjectBindingPattern: {
@@ -349,7 +357,7 @@ namespace ts.codefix {
349357
? undefined
350358
: makeImportSpecifier(e.propertyName && (e.propertyName as Identifier).text, e.name.text)); // tslint:disable-line no-unnecessary-type-assertion (TODO: GH#18217)
351359
if (importSpecifiers) {
352-
return [makeImport(/*name*/ undefined, importSpecifiers, moduleSpecifier, preferences)];
360+
return [makeImport(/*name*/ undefined, importSpecifiers, moduleSpecifier, quotePreference)];
353361
}
354362
}
355363
// falls through -- object destructuring has an interesting pattern and must be a variable declaration
@@ -360,12 +368,12 @@ namespace ts.codefix {
360368
*/
361369
const tmp = makeUniqueName(moduleSpecifierToValidIdentifier(moduleSpecifier.text, target), identifiers);
362370
return [
363-
makeImport(createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier, preferences),
371+
makeImport(createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier, quotePreference),
364372
makeConst(/*modifiers*/ undefined, getSynthesizedDeepClone(name), createIdentifier(tmp)),
365373
];
366374
}
367375
case SyntaxKind.Identifier:
368-
return convertSingleIdentifierImport(file, name, moduleSpecifier, changes, checker, identifiers, preferences);
376+
return convertSingleIdentifierImport(file, name, moduleSpecifier, changes, checker, identifiers, quotePreference);
369377
default:
370378
return Debug.assertNever(name);
371379
}
@@ -375,7 +383,7 @@ namespace ts.codefix {
375383
* Convert `import x = require("x").`
376384
* Also converts uses like `x.y()` to `y()` and uses a named import.
377385
*/
378-
function convertSingleIdentifierImport(file: SourceFile, name: Identifier, moduleSpecifier: StringLiteralLike, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers, preferences: UserPreferences): ReadonlyArray<Node> {
386+
function convertSingleIdentifierImport(file: SourceFile, name: Identifier, moduleSpecifier: StringLiteralLike, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers, quotePreference: QuotePreference): ReadonlyArray<Node> {
379387
const nameSymbol = checker.getSymbolAtLocation(name);
380388
// Maps from module property name to name actually used. (The same if there isn't shadowing.)
381389
const namedBindingsNames = createMap<string>();
@@ -410,7 +418,7 @@ namespace ts.codefix {
410418
// If it was unused, ensure that we at least import *something*.
411419
needDefaultImport = true;
412420
}
413-
return [makeImport(needDefaultImport ? getSynthesizedDeepClone(name) : undefined, namedBindings, moduleSpecifier, preferences)];
421+
return [makeImport(needDefaultImport ? getSynthesizedDeepClone(name) : undefined, namedBindings, moduleSpecifier, quotePreference)];
414422
}
415423

416424
// Identifiers helpers
@@ -488,10 +496,10 @@ namespace ts.codefix {
488496
getSynthesizedDeepClones(cls.members));
489497
}
490498

491-
function makeSingleImport(localName: string, propertyName: string, moduleSpecifier: StringLiteralLike, preferences: UserPreferences): ImportDeclaration {
499+
function makeSingleImport(localName: string, propertyName: string, moduleSpecifier: StringLiteralLike, quotePreference: QuotePreference): ImportDeclaration {
492500
return propertyName === "default"
493-
? makeImport(createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier, preferences)
494-
: makeImport(/*name*/ undefined, [makeImportSpecifier(propertyName, localName)], moduleSpecifier, preferences);
501+
? makeImport(createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier, quotePreference)
502+
: makeImport(/*name*/ undefined, [makeImportSpecifier(propertyName, localName)], moduleSpecifier, quotePreference);
495503
}
496504

497505
function makeImportSpecifier(propertyName: string | undefined, name: string): ImportSpecifier {
Collapse file

‎src/services/codefixes/fixInvalidImportSyntax.ts‎

Copy file name to clipboardExpand all lines: src/services/codefixes/fixInvalidImportSyntax.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace ts.codefix {
2828
const variations: CodeFixAction[] = [];
2929

3030
// import Bluebird from "bluebird";
31-
variations.push(createAction(context, sourceFile, node, makeImport(namespace.name, /*namedImports*/ undefined, node.moduleSpecifier, context.preferences)));
31+
variations.push(createAction(context, sourceFile, node, makeImport(namespace.name, /*namedImports*/ undefined, node.moduleSpecifier, getQuotePreference(sourceFile, context.preferences))));
3232

3333
if (getEmitModuleKind(opts) === ModuleKind.CommonJS) {
3434
// import Bluebird = require("bluebird");
Collapse file

‎src/services/codefixes/importFixes.ts‎

Copy file name to clipboardExpand all lines: src/services/codefixes/importFixes.ts
+1-11Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ namespace ts.codefix {
197197
const lastImportDeclaration = findLast(sourceFile.statements, isAnyImportSyntax);
198198

199199
const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier);
200-
const quotedModuleSpecifier = createLiteral(moduleSpecifierWithoutQuotes, shouldUseSingleQuote(sourceFile, preferences));
200+
const quotedModuleSpecifier = makeStringLiteral(moduleSpecifierWithoutQuotes, getQuotePreference(sourceFile, preferences));
201201
const importDecl = importKind !== ImportKind.Equals
202202
? createImportDeclaration(
203203
/*decorators*/ undefined,
@@ -225,16 +225,6 @@ namespace ts.codefix {
225225
return createCodeAction(Diagnostics.Import_0_from_module_1, [symbolName, moduleSpecifierWithoutQuotes], changes);
226226
}
227227

228-
function shouldUseSingleQuote(sourceFile: SourceFile, preferences: UserPreferences): boolean {
229-
if (preferences.quotePreference) {
230-
return preferences.quotePreference === "single";
231-
}
232-
else {
233-
const firstModuleSpecifier = firstOrUndefined(sourceFile.imports);
234-
return !!firstModuleSpecifier && !isStringDoubleQuoted(firstModuleSpecifier, sourceFile);
235-
}
236-
}
237-
238228
function createImportClauseOfKind(kind: ImportKind.Default | ImportKind.Named | ImportKind.Namespace, symbolName: string) {
239229
const id = createIdentifier(symbolName);
240230
switch (kind) {
Collapse file

‎src/services/codefixes/useDefaultImport.ts‎

Copy file name to clipboardExpand all lines: src/services/codefixes/useDefaultImport.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,6 @@ namespace ts.codefix {
3737
}
3838

3939
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, info: Info, preferences: UserPreferences): void {
40-
changes.replaceNode(sourceFile, info.importNode, makeImport(info.name, /*namedImports*/ undefined, info.moduleSpecifier, preferences));
40+
changes.replaceNode(sourceFile, info.importNode, makeImport(info.name, /*namedImports*/ undefined, info.moduleSpecifier, getQuotePreference(sourceFile, preferences)));
4141
}
4242
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.