mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-19 20:37:00 -05:00
Fix auto-imports from auto type acquisition definitions (#33766)
* Fix auto-imports from ATA typings * Compare canonical filenames in isImportablePath
This commit is contained in:
@@ -317,9 +317,13 @@ namespace ts.moduleSpecifiers {
|
||||
|
||||
// If the module could be imported by a directory name, use that directory's name
|
||||
const moduleSpecifier = packageNameOnly ? moduleFileName : getDirectoryOrExtensionlessFileName(moduleFileName);
|
||||
const globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
|
||||
// Get a path that's relative to node_modules or the importing file's path
|
||||
// if node_modules folder is in this folder or any of its parent folders, no need to keep it.
|
||||
if (!startsWith(sourceDirectory, getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex)))) return undefined;
|
||||
const pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
|
||||
if (!(startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// If the module was found in @types, get the actual Node package name
|
||||
const nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
|
||||
|
||||
@@ -6170,6 +6170,8 @@ namespace ts {
|
||||
readFile?(path: string): string | undefined;
|
||||
/* @internal */
|
||||
getProbableSymlinks?(files: readonly SourceFile[]): ReadonlyMap<string>;
|
||||
/* @internal */
|
||||
getGlobalTypingsCacheLocation?(): string | undefined;
|
||||
}
|
||||
|
||||
// Note: this used to be deprecated in our public API, but is still used internally
|
||||
|
||||
@@ -220,6 +220,10 @@ namespace Harness.LanguageService {
|
||||
return !!this.typesRegistry && this.typesRegistry.has(name);
|
||||
}
|
||||
|
||||
getGlobalTypingsCacheLocation() {
|
||||
return "/Library/Caches/typescript";
|
||||
}
|
||||
|
||||
installPackage = ts.notImplemented;
|
||||
|
||||
getCompilationSettings() { return this.settings; }
|
||||
|
||||
@@ -307,6 +307,11 @@ namespace ts.server {
|
||||
return this.typingsCache.installPackage({ ...options, projectName: this.projectName, projectRootPath: this.toPath(this.currentDirectory) });
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
getGlobalTypingsCacheLocation() {
|
||||
return this.getGlobalCache();
|
||||
}
|
||||
|
||||
private get typingsCache(): TypingsCache {
|
||||
return this.projectService.typingsCache;
|
||||
}
|
||||
|
||||
@@ -631,6 +631,7 @@ namespace ts.codefix {
|
||||
let filteredCount = 0;
|
||||
const packageJson = filterByPackageJson && createAutoImportFilter(from, program, host);
|
||||
const allSourceFiles = program.getSourceFiles();
|
||||
const globalTypingsCache = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
|
||||
forEachExternalModule(program.getTypeChecker(), allSourceFiles, (module, sourceFile) => {
|
||||
if (sourceFile === undefined) {
|
||||
if (!packageJson || packageJson.allowsImportingAmbientModule(module, allSourceFiles)) {
|
||||
@@ -640,7 +641,10 @@ namespace ts.codefix {
|
||||
filteredCount++;
|
||||
}
|
||||
}
|
||||
else if (sourceFile && sourceFile !== from && isImportablePath(from.fileName, sourceFile.fileName)) {
|
||||
else if (sourceFile &&
|
||||
sourceFile !== from &&
|
||||
isImportablePath(from.fileName, sourceFile.fileName, hostGetCanonicalFileName(host), globalTypingsCache)
|
||||
) {
|
||||
if (!packageJson || packageJson.allowsImportingSourceFile(sourceFile, allSourceFiles)) {
|
||||
cb(module);
|
||||
}
|
||||
@@ -669,10 +673,13 @@ namespace ts.codefix {
|
||||
* Don't include something from a `node_modules` that isn't actually reachable by a global import.
|
||||
* A relative import to node_modules is usually a bad idea.
|
||||
*/
|
||||
function isImportablePath(fromPath: string, toPath: string): boolean {
|
||||
function isImportablePath(fromPath: string, toPath: string, getCanonicalFileName: GetCanonicalFileName, globalCachePath?: string): boolean {
|
||||
// If it's in a `node_modules` but is not reachable from here via a global import, don't bother.
|
||||
const toNodeModules = forEachAncestorDirectory(toPath, ancestor => getBaseFileName(ancestor) === "node_modules" ? ancestor : undefined);
|
||||
return toNodeModules === undefined || startsWith(fromPath, getDirectoryPath(toNodeModules));
|
||||
const toNodeModulesParent = toNodeModules && getDirectoryPath(getCanonicalFileName(toNodeModules));
|
||||
return toNodeModulesParent === undefined
|
||||
|| startsWith(getCanonicalFileName(fromPath), toNodeModulesParent)
|
||||
|| (!!globalCachePath && startsWith(getCanonicalFileName(globalCachePath), toNodeModulesParent));
|
||||
}
|
||||
|
||||
export function moduleSymbolToValidIdentifier(moduleSymbol: Symbol, target: ScriptTarget): string {
|
||||
@@ -718,6 +725,7 @@ namespace ts.codefix {
|
||||
readFile: maybeBind(host, host.readFile),
|
||||
useCaseSensitiveFileNames: maybeBind(host, host.useCaseSensitiveFileNames),
|
||||
getProbableSymlinks: maybeBind(host, host.getProbableSymlinks) || program.getProbableSymlinks,
|
||||
getGlobalTypingsCacheLocation: maybeBind(host, host.getGlobalTypingsCacheLocation),
|
||||
};
|
||||
|
||||
let usesNodeCoreModules: boolean | undefined;
|
||||
|
||||
@@ -243,6 +243,8 @@ namespace ts {
|
||||
resolveTypeReferenceDirectives?(typeDirectiveNames: string[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions): (ResolvedTypeReferenceDirective | undefined)[];
|
||||
/* @internal */ hasInvalidatedResolution?: HasInvalidatedResolution;
|
||||
/* @internal */ hasChangedAutomaticTypeDirectiveNames?: boolean;
|
||||
/* @internal */
|
||||
getGlobalTypingsCacheLocation?(): string | undefined;
|
||||
|
||||
/*
|
||||
* Required for full import and type reference completions.
|
||||
|
||||
Reference in New Issue
Block a user