mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
moveToNewFile: Infer quote preference (#24652)
This commit is contained in:
parent
83c58a4fb5
commit
0fefaf286d
@ -5,10 +5,10 @@ namespace ts.codefix {
|
||||
getCodeActions(context) {
|
||||
const { sourceFile, program, preferences } = context;
|
||||
const changes = textChanges.ChangeTracker.with(context, changes => {
|
||||
const moduleExportsChangedToDefault = convertFileToEs6Module(sourceFile, program.getTypeChecker(), changes, program.getCompilerOptions().target!, preferences);
|
||||
const moduleExportsChangedToDefault = convertFileToEs6Module(sourceFile, program.getTypeChecker(), changes, program.getCompilerOptions().target!, getQuotePreference(sourceFile, preferences));
|
||||
if (moduleExportsChangedToDefault) {
|
||||
for (const importingFile of program.getSourceFiles()) {
|
||||
fixImportOfModuleExports(importingFile, sourceFile, changes, preferences);
|
||||
fixImportOfModuleExports(importingFile, sourceFile, changes, getQuotePreference(importingFile, preferences));
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -17,7 +17,7 @@ namespace ts.codefix {
|
||||
},
|
||||
});
|
||||
|
||||
function fixImportOfModuleExports(importingFile: SourceFile, exportingFile: SourceFile, changes: textChanges.ChangeTracker, preferences: UserPreferences) {
|
||||
function fixImportOfModuleExports(importingFile: SourceFile, exportingFile: SourceFile, changes: textChanges.ChangeTracker, quotePreference: QuotePreference) {
|
||||
for (const moduleSpecifier of importingFile.imports) {
|
||||
const imported = getResolvedModule(importingFile, moduleSpecifier.text);
|
||||
if (!imported || imported.resolvedFileName !== exportingFile.fileName) {
|
||||
@ -27,7 +27,7 @@ namespace ts.codefix {
|
||||
const importNode = importFromModuleSpecifier(moduleSpecifier);
|
||||
switch (importNode.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
changes.replaceNode(importingFile, importNode, makeImport(importNode.name, /*namedImports*/ undefined, moduleSpecifier, preferences));
|
||||
changes.replaceNode(importingFile, importNode, makeImport(importNode.name, /*namedImports*/ undefined, moduleSpecifier, quotePreference));
|
||||
break;
|
||||
case SyntaxKind.CallExpression:
|
||||
if (isRequireCall(importNode, /*checkArgumentIsStringLiteralLike*/ false)) {
|
||||
@ -39,13 +39,13 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
/** @returns Whether we converted a `module.exports =` to a default export. */
|
||||
function convertFileToEs6Module(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, target: ScriptTarget, preferences: UserPreferences): ModuleExportsChanged {
|
||||
function convertFileToEs6Module(sourceFile: SourceFile, checker: TypeChecker, changes: textChanges.ChangeTracker, target: ScriptTarget, quotePreference: QuotePreference): ModuleExportsChanged {
|
||||
const identifiers: Identifiers = { original: collectFreeIdentifiers(sourceFile), additional: createMap<true>() };
|
||||
const exports = collectExportRenames(sourceFile, checker, identifiers);
|
||||
convertExportsAccesses(sourceFile, exports, changes);
|
||||
let moduleExportsChangedToDefault = false;
|
||||
for (const statement of sourceFile.statements) {
|
||||
const moduleExportsChanged = convertStatement(sourceFile, statement, checker, changes, identifiers, target, exports, preferences);
|
||||
const moduleExportsChanged = convertStatement(sourceFile, statement, checker, changes, identifiers, target, exports, quotePreference);
|
||||
moduleExportsChangedToDefault = moduleExportsChangedToDefault || moduleExportsChanged;
|
||||
}
|
||||
return moduleExportsChangedToDefault;
|
||||
@ -98,10 +98,10 @@ namespace ts.codefix {
|
||||
/** Whether `module.exports =` was changed to `export default` */
|
||||
type ModuleExportsChanged = boolean;
|
||||
|
||||
function convertStatement(sourceFile: SourceFile, statement: Statement, checker: TypeChecker, changes: textChanges.ChangeTracker, identifiers: Identifiers, target: ScriptTarget, exports: ExportRenames, preferences: UserPreferences): ModuleExportsChanged {
|
||||
function convertStatement(sourceFile: SourceFile, statement: Statement, checker: TypeChecker, changes: textChanges.ChangeTracker, identifiers: Identifiers, target: ScriptTarget, exports: ExportRenames, quotePreference: QuotePreference): ModuleExportsChanged {
|
||||
switch (statement.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
convertVariableStatement(sourceFile, statement as VariableStatement, changes, checker, identifiers, target, preferences);
|
||||
convertVariableStatement(sourceFile, statement as VariableStatement, changes, checker, identifiers, target, quotePreference);
|
||||
return false;
|
||||
case SyntaxKind.ExpressionStatement: {
|
||||
const { expression } = statement as ExpressionStatement;
|
||||
@ -109,7 +109,7 @@ namespace ts.codefix {
|
||||
case SyntaxKind.CallExpression: {
|
||||
if (isRequireCall(expression, /*checkArgumentIsStringLiteralLike*/ true)) {
|
||||
// For side-effecting require() call, just make a side-effecting import.
|
||||
changes.replaceNode(sourceFile, statement, makeImport(/*name*/ undefined, /*namedImports*/ undefined, expression.arguments[0], preferences));
|
||||
changes.replaceNode(sourceFile, statement, makeImport(/*name*/ undefined, /*namedImports*/ undefined, expression.arguments[0], quotePreference));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -125,7 +125,15 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
function convertVariableStatement(sourceFile: SourceFile, statement: VariableStatement, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers, target: ScriptTarget, preferences: UserPreferences): void {
|
||||
function convertVariableStatement(
|
||||
sourceFile: SourceFile,
|
||||
statement: VariableStatement,
|
||||
changes: textChanges.ChangeTracker,
|
||||
checker: TypeChecker,
|
||||
identifiers: Identifiers,
|
||||
target: ScriptTarget,
|
||||
quotePreference: QuotePreference,
|
||||
): void {
|
||||
const { declarationList } = statement;
|
||||
let foundImport = false;
|
||||
const newNodes = flatMap(declarationList.declarations, decl => {
|
||||
@ -138,11 +146,11 @@ namespace ts.codefix {
|
||||
}
|
||||
else if (isRequireCall(initializer, /*checkArgumentIsStringLiteralLike*/ true)) {
|
||||
foundImport = true;
|
||||
return convertSingleImport(sourceFile, name, initializer.arguments[0], changes, checker, identifiers, target, preferences);
|
||||
return convertSingleImport(sourceFile, name, initializer.arguments[0], changes, checker, identifiers, target, quotePreference);
|
||||
}
|
||||
else if (isPropertyAccessExpression(initializer) && isRequireCall(initializer.expression, /*checkArgumentIsStringLiteralLike*/ true)) {
|
||||
foundImport = true;
|
||||
return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0], identifiers, preferences);
|
||||
return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0], identifiers, quotePreference);
|
||||
}
|
||||
}
|
||||
// Move it out to its own variable statement. (This will not be used if `!foundImport`)
|
||||
@ -155,20 +163,20 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
/** Converts `const name = require("moduleSpecifier").propertyName` */
|
||||
function convertPropertyAccessImport(name: BindingName, propertyName: string, moduleSpecifier: StringLiteralLike, identifiers: Identifiers, preferences: UserPreferences): ReadonlyArray<Node> {
|
||||
function convertPropertyAccessImport(name: BindingName, propertyName: string, moduleSpecifier: StringLiteralLike, identifiers: Identifiers, quotePreference: QuotePreference): ReadonlyArray<Node> {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
case SyntaxKind.ArrayBindingPattern: {
|
||||
// `const [a, b] = require("c").d` --> `import { d } from "c"; const [a, b] = d;`
|
||||
const tmp = makeUniqueName(propertyName, identifiers);
|
||||
return [
|
||||
makeSingleImport(tmp, propertyName, moduleSpecifier, preferences),
|
||||
makeSingleImport(tmp, propertyName, moduleSpecifier, quotePreference),
|
||||
makeConst(/*modifiers*/ undefined, name, createIdentifier(tmp)),
|
||||
];
|
||||
}
|
||||
case SyntaxKind.Identifier:
|
||||
// `const a = require("b").c` --> `import { c as a } from "./b";
|
||||
return [makeSingleImport(name.text, propertyName, moduleSpecifier, preferences)];
|
||||
return [makeSingleImport(name.text, propertyName, moduleSpecifier, quotePreference)];
|
||||
default:
|
||||
return Debug.assertNever(name);
|
||||
}
|
||||
@ -340,7 +348,7 @@ namespace ts.codefix {
|
||||
checker: TypeChecker,
|
||||
identifiers: Identifiers,
|
||||
target: ScriptTarget,
|
||||
preferences: UserPreferences,
|
||||
quotePreference: QuotePreference,
|
||||
): ReadonlyArray<Node> {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.ObjectBindingPattern: {
|
||||
@ -349,7 +357,7 @@ namespace ts.codefix {
|
||||
? undefined
|
||||
: makeImportSpecifier(e.propertyName && (e.propertyName as Identifier).text, e.name.text)); // tslint:disable-line no-unnecessary-type-assertion (TODO: GH#18217)
|
||||
if (importSpecifiers) {
|
||||
return [makeImport(/*name*/ undefined, importSpecifiers, moduleSpecifier, preferences)];
|
||||
return [makeImport(/*name*/ undefined, importSpecifiers, moduleSpecifier, quotePreference)];
|
||||
}
|
||||
}
|
||||
// falls through -- object destructuring has an interesting pattern and must be a variable declaration
|
||||
@ -360,12 +368,12 @@ namespace ts.codefix {
|
||||
*/
|
||||
const tmp = makeUniqueName(moduleSpecifierToValidIdentifier(moduleSpecifier.text, target), identifiers);
|
||||
return [
|
||||
makeImport(createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier, preferences),
|
||||
makeImport(createIdentifier(tmp), /*namedImports*/ undefined, moduleSpecifier, quotePreference),
|
||||
makeConst(/*modifiers*/ undefined, getSynthesizedDeepClone(name), createIdentifier(tmp)),
|
||||
];
|
||||
}
|
||||
case SyntaxKind.Identifier:
|
||||
return convertSingleIdentifierImport(file, name, moduleSpecifier, changes, checker, identifiers, preferences);
|
||||
return convertSingleIdentifierImport(file, name, moduleSpecifier, changes, checker, identifiers, quotePreference);
|
||||
default:
|
||||
return Debug.assertNever(name);
|
||||
}
|
||||
@ -375,7 +383,7 @@ namespace ts.codefix {
|
||||
* Convert `import x = require("x").`
|
||||
* Also converts uses like `x.y()` to `y()` and uses a named import.
|
||||
*/
|
||||
function convertSingleIdentifierImport(file: SourceFile, name: Identifier, moduleSpecifier: StringLiteralLike, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers, preferences: UserPreferences): ReadonlyArray<Node> {
|
||||
function convertSingleIdentifierImport(file: SourceFile, name: Identifier, moduleSpecifier: StringLiteralLike, changes: textChanges.ChangeTracker, checker: TypeChecker, identifiers: Identifiers, quotePreference: QuotePreference): ReadonlyArray<Node> {
|
||||
const nameSymbol = checker.getSymbolAtLocation(name);
|
||||
// Maps from module property name to name actually used. (The same if there isn't shadowing.)
|
||||
const namedBindingsNames = createMap<string>();
|
||||
@ -410,7 +418,7 @@ namespace ts.codefix {
|
||||
// If it was unused, ensure that we at least import *something*.
|
||||
needDefaultImport = true;
|
||||
}
|
||||
return [makeImport(needDefaultImport ? getSynthesizedDeepClone(name) : undefined, namedBindings, moduleSpecifier, preferences)];
|
||||
return [makeImport(needDefaultImport ? getSynthesizedDeepClone(name) : undefined, namedBindings, moduleSpecifier, quotePreference)];
|
||||
}
|
||||
|
||||
// Identifiers helpers
|
||||
@ -488,10 +496,10 @@ namespace ts.codefix {
|
||||
getSynthesizedDeepClones(cls.members));
|
||||
}
|
||||
|
||||
function makeSingleImport(localName: string, propertyName: string, moduleSpecifier: StringLiteralLike, preferences: UserPreferences): ImportDeclaration {
|
||||
function makeSingleImport(localName: string, propertyName: string, moduleSpecifier: StringLiteralLike, quotePreference: QuotePreference): ImportDeclaration {
|
||||
return propertyName === "default"
|
||||
? makeImport(createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier, preferences)
|
||||
: makeImport(/*name*/ undefined, [makeImportSpecifier(propertyName, localName)], moduleSpecifier, preferences);
|
||||
? makeImport(createIdentifier(localName), /*namedImports*/ undefined, moduleSpecifier, quotePreference)
|
||||
: makeImport(/*name*/ undefined, [makeImportSpecifier(propertyName, localName)], moduleSpecifier, quotePreference);
|
||||
}
|
||||
|
||||
function makeImportSpecifier(propertyName: string | undefined, name: string): ImportSpecifier {
|
||||
|
||||
@ -28,7 +28,7 @@ namespace ts.codefix {
|
||||
const variations: CodeFixAction[] = [];
|
||||
|
||||
// import Bluebird from "bluebird";
|
||||
variations.push(createAction(context, sourceFile, node, makeImport(namespace.name, /*namedImports*/ undefined, node.moduleSpecifier, context.preferences)));
|
||||
variations.push(createAction(context, sourceFile, node, makeImport(namespace.name, /*namedImports*/ undefined, node.moduleSpecifier, getQuotePreference(sourceFile, context.preferences))));
|
||||
|
||||
if (getEmitModuleKind(opts) === ModuleKind.CommonJS) {
|
||||
// import Bluebird = require("bluebird");
|
||||
|
||||
@ -197,7 +197,7 @@ namespace ts.codefix {
|
||||
const lastImportDeclaration = findLast(sourceFile.statements, isAnyImportSyntax);
|
||||
|
||||
const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier);
|
||||
const quotedModuleSpecifier = createLiteral(moduleSpecifierWithoutQuotes, shouldUseSingleQuote(sourceFile, preferences));
|
||||
const quotedModuleSpecifier = makeStringLiteral(moduleSpecifierWithoutQuotes, getQuotePreference(sourceFile, preferences));
|
||||
const importDecl = importKind !== ImportKind.Equals
|
||||
? createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
@ -225,16 +225,6 @@ namespace ts.codefix {
|
||||
return createCodeAction(Diagnostics.Import_0_from_module_1, [symbolName, moduleSpecifierWithoutQuotes], changes);
|
||||
}
|
||||
|
||||
function shouldUseSingleQuote(sourceFile: SourceFile, preferences: UserPreferences): boolean {
|
||||
if (preferences.quotePreference) {
|
||||
return preferences.quotePreference === "single";
|
||||
}
|
||||
else {
|
||||
const firstModuleSpecifier = firstOrUndefined(sourceFile.imports);
|
||||
return !!firstModuleSpecifier && !isStringDoubleQuoted(firstModuleSpecifier, sourceFile);
|
||||
}
|
||||
}
|
||||
|
||||
function createImportClauseOfKind(kind: ImportKind.Default | ImportKind.Named | ImportKind.Namespace, symbolName: string) {
|
||||
const id = createIdentifier(symbolName);
|
||||
switch (kind) {
|
||||
|
||||
@ -37,6 +37,6 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, info: Info, preferences: UserPreferences): void {
|
||||
changes.replaceNode(sourceFile, info.importNode, makeImport(info.name, /*namedImports*/ undefined, info.moduleSpecifier, preferences));
|
||||
changes.replaceNode(sourceFile, info.importNode, makeImport(info.name, /*namedImports*/ undefined, info.moduleSpecifier, getQuotePreference(sourceFile, preferences)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,7 +118,8 @@ namespace ts.refactor {
|
||||
}
|
||||
|
||||
const useEs6ModuleSyntax = !!oldFile.externalModuleIndicator;
|
||||
const importsFromNewFile = createOldFileImportsFromNewFile(usage.oldFileImportsFromNewFile, newModuleName, useEs6ModuleSyntax, preferences);
|
||||
const quotePreference = getQuotePreference(oldFile, preferences);
|
||||
const importsFromNewFile = createOldFileImportsFromNewFile(usage.oldFileImportsFromNewFile, newModuleName, useEs6ModuleSyntax, quotePreference);
|
||||
if (importsFromNewFile) {
|
||||
changes.insertNodeBefore(oldFile, oldFile.statements[0], importsFromNewFile, /*blankLineBetween*/ true);
|
||||
}
|
||||
@ -129,7 +130,7 @@ namespace ts.refactor {
|
||||
updateImportsInOtherFiles(changes, program, oldFile, usage.movedSymbols, newModuleName);
|
||||
|
||||
return [
|
||||
...getNewFileImportsAndAddExportInOldFile(oldFile, usage.oldImportsNeededByNewFile, usage.newFileImportsFromOldFile, changes, checker, useEs6ModuleSyntax, preferences),
|
||||
...getNewFileImportsAndAddExportInOldFile(oldFile, usage.oldImportsNeededByNewFile, usage.newFileImportsFromOldFile, changes, checker, useEs6ModuleSyntax, quotePreference),
|
||||
...addExports(oldFile, toMove.all, usage.oldFileImportsFromNewFile, useEs6ModuleSyntax),
|
||||
];
|
||||
}
|
||||
@ -268,7 +269,7 @@ namespace ts.refactor {
|
||||
| ImportEqualsDeclaration
|
||||
| VariableStatement;
|
||||
|
||||
function createOldFileImportsFromNewFile(newFileNeedExport: ReadonlySymbolSet, newFileNameWithExtension: string, useEs6Imports: boolean, preferences: UserPreferences): Statement | undefined {
|
||||
function createOldFileImportsFromNewFile(newFileNeedExport: ReadonlySymbolSet, newFileNameWithExtension: string, useEs6Imports: boolean, quotePreference: QuotePreference): Statement | undefined {
|
||||
let defaultImport: Identifier | undefined;
|
||||
const imports: string[] = [];
|
||||
newFileNeedExport.forEach(symbol => {
|
||||
@ -279,14 +280,14 @@ namespace ts.refactor {
|
||||
imports.push(symbol.name);
|
||||
}
|
||||
});
|
||||
return makeImportOrRequire(defaultImport, imports, newFileNameWithExtension, useEs6Imports, preferences);
|
||||
return makeImportOrRequire(defaultImport, imports, newFileNameWithExtension, useEs6Imports, quotePreference);
|
||||
}
|
||||
|
||||
function makeImportOrRequire(defaultImport: Identifier | undefined, imports: ReadonlyArray<string>, path: string, useEs6Imports: boolean, preferences: UserPreferences): Statement | undefined {
|
||||
function makeImportOrRequire(defaultImport: Identifier | undefined, imports: ReadonlyArray<string>, path: string, useEs6Imports: boolean, quotePreference: QuotePreference): Statement | undefined {
|
||||
path = ensurePathIsNonModuleName(path);
|
||||
if (useEs6Imports) {
|
||||
const specifiers = imports.map(i => createImportSpecifier(/*propertyName*/ undefined, createIdentifier(i)));
|
||||
return makeImportIfNecessary(defaultImport, specifiers, path, preferences);
|
||||
return makeImportIfNecessary(defaultImport, specifiers, path, quotePreference);
|
||||
}
|
||||
else {
|
||||
Debug.assert(!defaultImport); // If there's a default export, it should have been an es6 module.
|
||||
@ -392,7 +393,7 @@ namespace ts.refactor {
|
||||
changes: textChanges.ChangeTracker,
|
||||
checker: TypeChecker,
|
||||
useEs6ModuleSyntax: boolean,
|
||||
preferences: UserPreferences,
|
||||
quotePreference: QuotePreference,
|
||||
): ReadonlyArray<SupportedImportStatement> {
|
||||
const copiedOldImports: SupportedImportStatement[] = [];
|
||||
for (const oldStatement of oldFile.statements) {
|
||||
@ -424,7 +425,7 @@ namespace ts.refactor {
|
||||
}
|
||||
});
|
||||
|
||||
append(copiedOldImports, makeImportOrRequire(oldFileDefault, oldFileNamedImports, removeFileExtension(getBaseFileName(oldFile.fileName)), useEs6ModuleSyntax, preferences));
|
||||
append(copiedOldImports, makeImportOrRequire(oldFileDefault, oldFileNamedImports, removeFileExtension(getBaseFileName(oldFile.fileName)), useEs6ModuleSyntax, quotePreference));
|
||||
return copiedOldImports;
|
||||
}
|
||||
|
||||
|
||||
@ -1257,18 +1257,34 @@ namespace ts {
|
||||
return createGetCanonicalFileName(hostUsesCaseSensitiveFileNames(host));
|
||||
}
|
||||
|
||||
export function makeImportIfNecessary(defaultImport: Identifier | undefined, namedImports: ReadonlyArray<ImportSpecifier> | undefined, moduleSpecifier: string, preferences: UserPreferences): ImportDeclaration | undefined {
|
||||
return defaultImport || namedImports && namedImports.length ? makeImport(defaultImport, namedImports, moduleSpecifier, preferences) : undefined;
|
||||
export function makeImportIfNecessary(defaultImport: Identifier | undefined, namedImports: ReadonlyArray<ImportSpecifier> | undefined, moduleSpecifier: string, quotePreference: QuotePreference): ImportDeclaration | undefined {
|
||||
return defaultImport || namedImports && namedImports.length ? makeImport(defaultImport, namedImports, moduleSpecifier, quotePreference) : undefined;
|
||||
}
|
||||
|
||||
export function makeImport(defaultImport: Identifier | undefined, namedImports: ReadonlyArray<ImportSpecifier> | undefined, moduleSpecifier: string | Expression, preferences: UserPreferences): ImportDeclaration {
|
||||
export function makeImport(defaultImport: Identifier | undefined, namedImports: ReadonlyArray<ImportSpecifier> | undefined, moduleSpecifier: string | Expression, quotePreference: QuotePreference): ImportDeclaration {
|
||||
return createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
defaultImport || namedImports
|
||||
? createImportClause(defaultImport, namedImports && namedImports.length ? createNamedImports(namedImports) : undefined)
|
||||
: undefined,
|
||||
typeof moduleSpecifier === "string" ? createLiteral(moduleSpecifier, preferences.quotePreference === "single") : moduleSpecifier);
|
||||
typeof moduleSpecifier === "string" ? makeStringLiteral(moduleSpecifier, quotePreference) : moduleSpecifier);
|
||||
}
|
||||
|
||||
export function makeStringLiteral(text: string, quotePreference: QuotePreference): StringLiteral {
|
||||
return createLiteral(text, quotePreference === QuotePreference.Single);
|
||||
}
|
||||
|
||||
export const enum QuotePreference { Single, Double }
|
||||
|
||||
export function getQuotePreference(sourceFile: SourceFile, preferences: UserPreferences): QuotePreference {
|
||||
if (preferences.quotePreference) {
|
||||
return preferences.quotePreference === "single" ? QuotePreference.Single : QuotePreference.Double;
|
||||
}
|
||||
else {
|
||||
const firstModuleSpecifier = firstOrUndefined(sourceFile.imports);
|
||||
return !!firstModuleSpecifier && !isStringDoubleQuoted(firstModuleSpecifier, sourceFile) ? QuotePreference.Single : QuotePreference.Double;
|
||||
}
|
||||
}
|
||||
|
||||
export function symbolNameNoDefault(symbol: Symbol): string | undefined {
|
||||
|
||||
21
tests/cases/fourslash/moveToNewFile_inferQuoteStyle.ts
Normal file
21
tests/cases/fourslash/moveToNewFile_inferQuoteStyle.ts
Normal file
@ -0,0 +1,21 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: /a.ts
|
||||
////import 'unrelated';
|
||||
////
|
||||
////[|const x = 0;|]
|
||||
////x;
|
||||
|
||||
verify.moveToNewFile({
|
||||
newFileContents: {
|
||||
"/a.ts":
|
||||
`import { x } from './x';
|
||||
|
||||
import 'unrelated';
|
||||
|
||||
x;`,
|
||||
|
||||
"/x.ts":
|
||||
`export const x = 0;`,
|
||||
},
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user