mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Fix auto-import when paths points to project reference redirect (#51492)
* Fix auto-import when `paths` points to project reference redirect * Put paths specifiers to redirects in lower priority bucket
This commit is contained in:
@@ -275,6 +275,7 @@ function computeModuleSpecifiers(
|
||||
// 4. Relative paths
|
||||
let nodeModulesSpecifiers: string[] | undefined;
|
||||
let pathsSpecifiers: string[] | undefined;
|
||||
let redirectPathsSpecifiers: string[] | undefined;
|
||||
let relativeSpecifiers: string[] | undefined;
|
||||
for (const modulePath of modulePaths) {
|
||||
const specifier = tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, userPreferences, /*packageNameOnly*/ undefined, options.overrideImportMode);
|
||||
@@ -285,9 +286,23 @@ function computeModuleSpecifiers(
|
||||
return nodeModulesSpecifiers!;
|
||||
}
|
||||
|
||||
if (!specifier && !modulePath.isRedirect) {
|
||||
const local = getLocalModuleSpecifier(modulePath.path, info, compilerOptions, host, options.overrideImportMode || importingSourceFile.impliedNodeFormat, preferences);
|
||||
if (pathIsBareSpecifier(local)) {
|
||||
if (!specifier) {
|
||||
const local = getLocalModuleSpecifier(
|
||||
modulePath.path,
|
||||
info,
|
||||
compilerOptions,
|
||||
host,
|
||||
options.overrideImportMode || importingSourceFile.impliedNodeFormat,
|
||||
preferences,
|
||||
/*pathsOnly*/ modulePath.isRedirect,
|
||||
);
|
||||
if (!local) {
|
||||
continue;
|
||||
}
|
||||
if (modulePath.isRedirect) {
|
||||
redirectPathsSpecifiers = append(redirectPathsSpecifiers, local);
|
||||
}
|
||||
else if (pathIsBareSpecifier(local)) {
|
||||
pathsSpecifiers = append(pathsSpecifiers, local);
|
||||
}
|
||||
else if (!importedFileIsInNodeModules || modulePath.isInNodeModules) {
|
||||
@@ -306,6 +321,7 @@ function computeModuleSpecifiers(
|
||||
}
|
||||
|
||||
return pathsSpecifiers?.length ? pathsSpecifiers :
|
||||
redirectPathsSpecifiers?.length ? redirectPathsSpecifiers :
|
||||
nodeModulesSpecifiers?.length ? nodeModulesSpecifiers :
|
||||
Debug.checkDefined(relativeSpecifiers);
|
||||
}
|
||||
@@ -322,32 +338,42 @@ function getInfo(importingSourceFileName: Path, host: ModuleSpecifierResolutionH
|
||||
return { getCanonicalFileName, importingSourceFileName, sourceDirectory };
|
||||
}
|
||||
|
||||
function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, { ending, relativePreference }: Preferences): string {
|
||||
function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, { ending, relativePreference }: Preferences): string;
|
||||
function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, { ending, relativePreference }: Preferences, pathsOnly?: boolean): string | undefined;
|
||||
function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, { ending, relativePreference }: Preferences, pathsOnly?: boolean): string | undefined {
|
||||
const { baseUrl, paths, rootDirs } = compilerOptions;
|
||||
if (pathsOnly && !paths) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { sourceDirectory, getCanonicalFileName } = info;
|
||||
const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, ending, compilerOptions) ||
|
||||
removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions);
|
||||
if (!baseUrl && !paths || relativePreference === RelativePreference.Relative) {
|
||||
return relativePath;
|
||||
return pathsOnly ? undefined : relativePath;
|
||||
}
|
||||
|
||||
const baseDirectory = getNormalizedAbsolutePath(getPathsBasePath(compilerOptions, host) || baseUrl!, host.getCurrentDirectory());
|
||||
const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseDirectory, getCanonicalFileName);
|
||||
if (!relativeToBaseUrl) {
|
||||
return relativePath;
|
||||
return pathsOnly ? undefined : relativePath;
|
||||
}
|
||||
|
||||
const fromPaths = paths && tryGetModuleNameFromPaths(relativeToBaseUrl, paths, getAllowedEndings(ending, compilerOptions, importMode), host, compilerOptions);
|
||||
const nonRelative = fromPaths === undefined && baseUrl !== undefined ? removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions) : fromPaths;
|
||||
if (!nonRelative) {
|
||||
if (pathsOnly) {
|
||||
return fromPaths;
|
||||
}
|
||||
|
||||
const maybeNonRelative = fromPaths === undefined && baseUrl !== undefined ? removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions) : fromPaths;
|
||||
if (!maybeNonRelative) {
|
||||
return relativePath;
|
||||
}
|
||||
|
||||
if (relativePreference === RelativePreference.NonRelative) {
|
||||
return nonRelative;
|
||||
if (relativePreference === RelativePreference.NonRelative && !pathIsRelative(maybeNonRelative)) {
|
||||
return maybeNonRelative;
|
||||
}
|
||||
|
||||
if (relativePreference === RelativePreference.ExternalNonRelative) {
|
||||
if (relativePreference === RelativePreference.ExternalNonRelative && !pathIsRelative(maybeNonRelative)) {
|
||||
const projectDirectory = compilerOptions.configFilePath ?
|
||||
toPath(getDirectoryPath(compilerOptions.configFilePath), host.getCurrentDirectory(), info.getCanonicalFileName) :
|
||||
info.getCanonicalFileName(host.getCurrentDirectory());
|
||||
@@ -363,7 +389,7 @@ function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOpt
|
||||
// lib/ | (path crosses tsconfig.json)
|
||||
// imported.ts <---
|
||||
//
|
||||
return nonRelative;
|
||||
return maybeNonRelative;
|
||||
}
|
||||
|
||||
const nearestTargetPackageJson = getNearestAncestorDirectoryWithPackageJson(host, getDirectoryPath(modulePath));
|
||||
@@ -378,16 +404,14 @@ function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOpt
|
||||
// package.json |
|
||||
// component.ts <---
|
||||
//
|
||||
return nonRelative;
|
||||
return maybeNonRelative;
|
||||
}
|
||||
|
||||
return relativePath;
|
||||
}
|
||||
|
||||
if (relativePreference !== RelativePreference.Shortest) Debug.assertNever(relativePreference);
|
||||
|
||||
// Prefer a relative import over a baseUrl import if it has fewer components.
|
||||
return isPathRelativeToParent(nonRelative) || countPathComponents(relativePath) < countPathComponents(nonRelative) ? relativePath : nonRelative;
|
||||
return isPathRelativeToParent(maybeNonRelative) || countPathComponents(relativePath) < countPathComponents(maybeNonRelative) ? relativePath : maybeNonRelative;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
||||
@@ -3041,6 +3041,10 @@ export class TestState {
|
||||
* @param fileName Path to file where error should be retrieved from.
|
||||
*/
|
||||
private getCodeFixes(fileName: string, errorCode?: number, preferences: ts.UserPreferences = ts.emptyOptions, position?: number): readonly ts.CodeFixAction[] {
|
||||
if (this.testType === FourSlashTestType.Server) {
|
||||
this.configure(preferences);
|
||||
}
|
||||
|
||||
const diagnosticsForCodeFix = this.getDiagnostics(fileName, /*includeSuggestions*/ true).map(diagnostic => ({
|
||||
start: diagnostic.start,
|
||||
length: diagnostic.length,
|
||||
|
||||
Reference in New Issue
Block a user