Skip to content

Commit e8033dc

Browse files
author
Andy Hanson
committed
Add importModuleSpecifierPreference option
1 parent c0e2d52 commit e8033dc

File tree

5 files changed

+35
-9
lines changed

5 files changed

+35
-9
lines changed

src/services/codefixes/importFixes.ts

+16-9
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ namespace ts.codefix {
102102
const exportInfos = getAllReExportingModules(exportedSymbol, checker, allSourceFiles);
103103
Debug.assert(exportInfos.some(info => info.moduleSymbol === moduleSymbol));
104104
// We sort the best codefixes first, so taking `first` is best for completions.
105-
const moduleSpecifier = first(getNewImportInfos(program, sourceFile, exportInfos, compilerOptions, getCanonicalFileName, host)).moduleSpecifier;
105+
const moduleSpecifier = first(getNewImportInfos(program, sourceFile, exportInfos, compilerOptions, getCanonicalFileName, host, options)).moduleSpecifier;
106106
const ctx: ImportCodeFixContext = { host, program, checker, compilerOptions, sourceFile, formatContext, symbolName, getCanonicalFileName, symbolToken, options };
107107
return { moduleSpecifier, codeAction: first(getCodeActionsForImport(exportInfos, ctx)) };
108108
}
@@ -254,25 +254,26 @@ namespace ts.codefix {
254254
program: Program,
255255
sourceFile: SourceFile,
256256
moduleSymbols: ReadonlyArray<SymbolExportInfo>,
257-
options: CompilerOptions,
257+
compilerOptions: CompilerOptions,
258258
getCanonicalFileName: (file: string) => string,
259259
host: LanguageServiceHost,
260+
options: Options,
260261
): ReadonlyArray<NewImportInfo> {
261-
const { baseUrl, paths, rootDirs } = options;
262+
const { baseUrl, paths, rootDirs } = compilerOptions;
262263
const addJsExtension = usesJsExtensionOnImports(sourceFile);
263264
const choicesForEachExportingModule = flatMap<SymbolExportInfo, NewImportInfo[]>(moduleSymbols, ({ moduleSymbol, importKind }) => {
264265
const modulePathsGroups = getAllModulePaths(program, moduleSymbol.valueDeclaration.getSourceFile()).map(moduleFileName => {
265266
const sourceDirectory = getDirectoryPath(sourceFile.fileName);
266267
const global = tryGetModuleNameFromAmbientModule(moduleSymbol)
267-
|| tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName, addJsExtension)
268-
|| tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory)
268+
|| tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension)
269+
|| tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory)
269270
|| rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName);
270271
if (global) {
271272
return [global];
272273
}
273274

274-
const relativePath = removeExtensionAndIndexPostFix(getRelativePath(moduleFileName, sourceDirectory, getCanonicalFileName), options, addJsExtension);
275-
if (!baseUrl) {
275+
const relativePath = removeExtensionAndIndexPostFix(getRelativePath(moduleFileName, sourceDirectory, getCanonicalFileName), compilerOptions, addJsExtension);
276+
if (!baseUrl || options.importModuleSpecifierPreference == "relative") {
276277
return [relativePath];
277278
}
278279

@@ -281,14 +282,20 @@ namespace ts.codefix {
281282
return [relativePath];
282283
}
283284

284-
const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, options, addJsExtension);
285+
const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, compilerOptions, addJsExtension);
285286
if (paths) {
286287
const fromPaths = tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths);
287288
if (fromPaths) {
288289
return [fromPaths];
289290
}
290291
}
291292

293+
if (options.importModuleSpecifierPreference === "baseUrl") {
294+
return [importRelativeToBaseUrl];
295+
}
296+
297+
if (options.importModuleSpecifierPreference !== undefined) Debug.assertNever(options.importModuleSpecifierPreference);
298+
292299
if (isPathRelativeToParent(relativeToBaseUrl)) {
293300
return [relativePath];
294301
}
@@ -584,7 +591,7 @@ namespace ts.codefix {
584591
const existingDeclaration = firstDefined(existingImports, newImportInfoFromExistingSpecifier);
585592
const newImportInfos = existingDeclaration
586593
? [existingDeclaration]
587-
: getNewImportInfos(ctx.program, ctx.sourceFile, exportInfos, ctx.compilerOptions, ctx.getCanonicalFileName, ctx.host);
594+
: getNewImportInfos(ctx.program, ctx.sourceFile, exportInfos, ctx.compilerOptions, ctx.getCanonicalFileName, ctx.host, ctx.options);
588595
return newImportInfos.map(info => getCodeActionForNewImport(ctx, info));
589596
}
590597

src/services/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ namespace ts {
218218
readonly quote?: "double" | "single";
219219
readonly includeCompletionsForModuleExports?: boolean;
220220
readonly includeCompletionsWithInsertText?: boolean;
221+
readonly importModuleSpecifierPreference?: "relative" | "baseUrl";
221222
}
222223
/* @internal */
223224
export const defaultOptions: Options = {};

tests/cases/fourslash/fourslash.ts

+1
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ declare namespace FourSlashInterface {
527527
quote?: "double" | "single";
528528
includeCompletionsForModuleExports?: boolean;
529529
includeInsertTextCompletions?: boolean;
530+
importModuleSpecifierPreference?: "relative" | "baseUrl";
530531
}
531532
interface CompletionsAtOptions extends Options {
532533
isNewIdentifierLocation?: boolean;

tests/cases/fourslash/importNameCodeFixNewImportBaseUrl1.ts

+8
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,11 @@ f1();`,
2323
2424
f1();`
2525
]);
26+
27+
verify.importFixAtPosition([
28+
`import { f1 } from "b/x";
29+
30+
f1();`,
31+
], /*errorCode*/ undefined, {
32+
importModuleSpecifierPreference: "baseUrl",
33+
});

tests/cases/fourslash/importNameCodeFixNewImportBaseUrl2.ts

+9
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,12 @@ f1();`,
2323
2424
f1();`
2525
]);
26+
27+
verify.importFixAtPosition([
28+
`import { f1 } from "../b/x";
29+
30+
f1();`,
31+
], /*errorCode*/ undefined, {
32+
importModuleSpecifierPreference: "relative",
33+
});
34+

0 commit comments

Comments
 (0)