mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06: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:
parent
3fcd1b51a1
commit
89ce16ccfd
@ -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,
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
/// <reference path="../fourslash.ts" />
|
||||
|
||||
// @Filename: /common/tsconfig.json
|
||||
//// {
|
||||
//// "compilerOptions": {
|
||||
//// "module": "commonjs",
|
||||
//// "outDir": "dist",
|
||||
//// "composite": true
|
||||
//// },
|
||||
//// "include": ["src"]
|
||||
//// }
|
||||
|
||||
// @Filename: /common/src/MyModule.ts
|
||||
//// export function square(n: number) {
|
||||
//// return n * 2;
|
||||
//// }
|
||||
|
||||
// @Filename: /web/tsconfig.json
|
||||
//// {
|
||||
//// "compilerOptions": {
|
||||
//// "module": "esnext",
|
||||
//// "moduleResolution": "node",
|
||||
//// "noEmit": true,
|
||||
//// "baseUrl": "."
|
||||
//// },
|
||||
//// "include": ["src"],
|
||||
//// "references": [{ "path": "../common" }]
|
||||
//// }
|
||||
|
||||
// @Filename: /web/src/MyApp.ts
|
||||
//// import { square } from "../../common/dist/src/MyModule";
|
||||
|
||||
// @Filename: /web/src/Helper.ts
|
||||
//// export function saveMe() {
|
||||
//// square/**/(2);
|
||||
//// }
|
||||
|
||||
goTo.file("/web/src/Helper.ts");
|
||||
verify.importFixModuleSpecifiers("", ["../../common/src/MyModule"], {
|
||||
importModuleSpecifierPreference: "non-relative"
|
||||
});
|
||||
@ -0,0 +1,43 @@
|
||||
/// <reference path="../fourslash.ts" />
|
||||
|
||||
// @Filename: /common/tsconfig.json
|
||||
//// {
|
||||
//// "compilerOptions": {
|
||||
//// "module": "commonjs",
|
||||
//// "outDir": "dist",
|
||||
//// "composite": true
|
||||
//// },
|
||||
//// "include": ["src"]
|
||||
//// }
|
||||
|
||||
// @Filename: /common/src/MyModule.ts
|
||||
//// export function square(n: number) {
|
||||
//// return n * 2;
|
||||
//// }
|
||||
|
||||
// @Filename: /web/tsconfig.json
|
||||
//// {
|
||||
//// "compilerOptions": {
|
||||
//// "module": "esnext",
|
||||
//// "moduleResolution": "node",
|
||||
//// "noEmit": true,
|
||||
//// "paths": {
|
||||
//// "@common/*": ["../common/dist/src/*"]
|
||||
//// }
|
||||
//// },
|
||||
//// "include": ["src"],
|
||||
//// "references": [{ "path": "../common" }]
|
||||
//// }
|
||||
|
||||
// @Filename: /web/src/MyApp.ts
|
||||
//// import { square } from "@common/MyModule";
|
||||
|
||||
// @Filename: /web/src/Helper.ts
|
||||
//// export function saveMe() {
|
||||
//// square/**/(2);
|
||||
//// }
|
||||
|
||||
goTo.file("/web/src/Helper.ts");
|
||||
verify.importFixModuleSpecifiers("", ["@common/MyModule"], {
|
||||
importModuleSpecifierPreference: "non-relative"
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user