Set old program build info as a location to look for from module resolution caches

This commit is contained in:
Sheetal Nandi
2022-12-09 14:49:25 -08:00
parent 207226a9c8
commit 591960edb0
20 changed files with 177 additions and 3046 deletions
+30 -4
View File
@@ -716,6 +716,12 @@ export interface PerDirectoryResolutionCache<T> {
* This updates the redirects map as well if needed so module resolutions are cached if they can across the projects
*/
update(options: CompilerOptions): void;
/** @internal */ setOldResolutionCache(cache: OldResolutionCache<T> | undefined): void;
}
/** @internal */
export interface OldResolutionCache<T> {
getResolved(name: string, mode: ResolutionMode, directory: Path, redirectedReference: ResolvedProjectReference | undefined): T | undefined;
}
export interface NonRelativeNameResolutionCache<T> {
@@ -729,6 +735,7 @@ export interface NonRelativeNameResolutionCache<T> {
* This updates the redirects map as well if needed so module resolutions are cached if they can across the projects
*/
update(options: CompilerOptions): void;
/** @internal */ setOldResolutionCache(cache: OldResolutionCache<T> | undefined): void;
}
export interface PerNonRelativeNameCache<T> {
@@ -906,6 +913,7 @@ function getOrCreateCache<K, V>(cacheWithRedirects: CacheWithRedirects<K, V>, re
function createPerDirectoryResolutionCache<T>(currentDirectory: string, getCanonicalFileName: GetCanonicalFileName, options: CompilerOptions | undefined): PerDirectoryResolutionCache<T> {
const perDirectoryMap = createCacheWithRedirects<Path, ModeAwareCache<T>>(options);
let oldResolutionCache: OldResolutionCache<T> | undefined;
return {
perDirectoryMap,
getFromDirectoryCache,
@@ -913,9 +921,11 @@ function createPerDirectoryResolutionCache<T>(currentDirectory: string, getCanon
getOrCreateCacheForDirectoryWithPath,
clear,
update,
setOldResolutionCache: cache => oldResolutionCache = cache,
};
function clear() {
oldResolutionCache = undefined;
perDirectoryMap.clear();
}
@@ -936,7 +946,11 @@ function createPerDirectoryResolutionCache<T>(currentDirectory: string, getCanon
}
function getFromDirectoryCacheWithPath(name: string, mode: ResolutionMode, directory: Path, redirectedReference: ResolvedProjectReference | undefined) {
return perDirectoryMap.getMapOfCacheRedirects(redirectedReference)?.get(directory)?.get(name, mode);
let result = perDirectoryMap.getMapOfCacheRedirects(redirectedReference)?.get(directory)?.get(name, mode);
if (result) return result;
result = oldResolutionCache?.getResolved(name, mode, directory, redirectedReference);
if (result) getOrCreateCacheForDirectoryWithPath(directory, redirectedReference).set(name, mode, result);
return result;
}
}
@@ -1019,6 +1033,7 @@ function createNonRelativeNameResolutionCache<T>(
getResolvedFileName: (result: T) => string | undefined,
): NonRelativeNameResolutionCache<T> {
const nonRelativeNameResolutionsMap = createCacheWithRedirects<ModeAwareCacheKey, PerNonRelativeNameCache<T>>(options);
let oldResolutionCache: OldResolutionCache<T> | undefined;
return {
nonRelativeNameResolutionsMap,
getFromNonRelativeNameCache,
@@ -1026,9 +1041,11 @@ function createNonRelativeNameResolutionCache<T>(
getOrCreateCacheForNonRelativeName,
clear,
update,
setOldResolutionCache: cache => oldResolutionCache = cache,
};
function clear() {
oldResolutionCache = undefined;
nonRelativeNameResolutionsMap.clear();
}
@@ -1037,13 +1054,16 @@ function createNonRelativeNameResolutionCache<T>(
}
function getFromNonRelativeNameCache(nonRelativeModuleName: string, mode: ResolutionMode, directoryName: string, redirectedReference?: ResolvedProjectReference): T | undefined {
Debug.assert(!isExternalModuleNameRelative(nonRelativeModuleName));
return nonRelativeNameResolutionsMap.getMapOfCacheRedirects(redirectedReference)?.get(createModeAwareCacheKey(nonRelativeModuleName, mode))?.get(directoryName);
return getFromNonRelativeNameCacheWithPath(nonRelativeModuleName, mode, toPath(directoryName, currentDirectory, getCanonicalFileName), redirectedReference);
}
function getFromNonRelativeNameCacheWithPath(nonRelativeModuleName: string, mode: ResolutionMode, dirPath: Path, redirectedReference?: ResolvedProjectReference): T | undefined {
Debug.assert(!isExternalModuleNameRelative(nonRelativeModuleName));
return nonRelativeNameResolutionsMap.getMapOfCacheRedirects(redirectedReference)?.get(createModeAwareCacheKey(nonRelativeModuleName, mode))?.getWithPath(dirPath);
let result = nonRelativeNameResolutionsMap.getMapOfCacheRedirects(redirectedReference)?.get(createModeAwareCacheKey(nonRelativeModuleName, mode))?.getWithPath(dirPath);
if (result) return result;
result = oldResolutionCache?.getResolved(nonRelativeModuleName, mode, dirPath, redirectedReference);
if (result) getOrCreateCacheForNonRelativeName(nonRelativeModuleName, mode, redirectedReference).setWithPath(dirPath, result, noop);
return result;
}
function getOrCreateCacheForNonRelativeName(nonRelativeModuleName: string, mode: ResolutionMode, redirectedReference?: ResolvedProjectReference): PerNonRelativeNameCache<T> {
@@ -1183,6 +1203,7 @@ function createModuleOrTypeReferenceResolutionCache<T>(
update,
getPackageJsonInfoCache: () => packageJsonInfoCache!,
clearAllExceptPackageJsonInfoCache,
setOldResolutionCache,
};
function clear() {
@@ -1199,6 +1220,11 @@ function createModuleOrTypeReferenceResolutionCache<T>(
perDirectory.update(options);
perNonRelativeName.update(options);
}
function setOldResolutionCache(cache: OldResolutionCache<T> | undefined) {
perDirectory.setOldResolutionCache(cache);
perNonRelativeName.setOldResolutionCache(cache);
}
}
export function createModuleResolutionCache(
+13 -1
View File
@@ -1538,6 +1538,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
);
}
let typeReferenceDirectiveResolutionCache: TypeReferenceDirectiveResolutionCache | undefined;
let actualResolveTypeReferenceDirectiveNamesWorker: <T extends FileReference | string>(
typeDirectiveNames: T[],
containingFile: string,
@@ -1548,6 +1549,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
) => readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[];
if (host.resolveTypeReferenceDirectiveReferences) {
actualResolveTypeReferenceDirectiveNamesWorker = host.resolveTypeReferenceDirectiveReferences.bind(host);
typeReferenceDirectiveResolutionCache = host.getTypeReferenceDirectiveResolutionCache?.();
}
else if (host.resolveTypeReferenceDirectives) {
actualResolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile, redirectedReference, options, containingSourceFile) =>
@@ -1558,9 +1560,10 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
options,
containingSourceFile?.impliedNodeFormat,
).map(resolvedTypeReferenceDirective => ({ resolvedTypeReferenceDirective }));
typeReferenceDirectiveResolutionCache = host.getTypeReferenceDirectiveResolutionCache?.();
}
else {
const typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache(currentDirectory, getCanonicalFileName, /*options*/ undefined, moduleResolutionCache?.getPackageJsonInfoCache());
typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache(currentDirectory, getCanonicalFileName, /*options*/ undefined, moduleResolutionCache?.getPackageJsonInfoCache());
actualResolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile, redirectedReference, options, containingSourceFile) =>
loadWithModeAwareCache(
typeDirectiveNames,
@@ -1581,6 +1584,14 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
fileExists: fileName => host.fileExists(fileName),
getCompilerOptions: () => options,
});
if (oldBuildInfoProgram) {
moduleResolutionCache?.setOldResolutionCache({
getResolved: (name, mode, dirPath, redirectedReference) => oldBuildInfoProgram?.getResolvedModule(name, mode, dirPath, redirectedReference)
});
typeReferenceDirectiveResolutionCache?.setOldResolutionCache({
getResolved: (name, mode, dirPath, redirectedReference) => oldBuildInfoProgram?.getResolvedTypeReferenceDirective(name, mode, dirPath, redirectedReference)
});
}
}
// Map from a stringified PackageId to the source file with that id.
@@ -1773,6 +1784,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
getSourceFiles: () => files,
getMissingFilePaths: () => missingFilePaths!, // TODO: GH#18217
getModuleResolutionCache: () => moduleResolutionCache,
getTypeReferenceDirectiveResolutionCache: () => typeReferenceDirectiveResolutionCache,
getFilesByNameMap: () => filesByName,
getCompilerOptions: () => options,
getSyntacticDiagnostics,
+3
View File
@@ -71,6 +71,7 @@ import {
stringContains,
StringLiteralLike,
trace,
TypeReferenceDirectiveResolutionCache,
updateResolutionField,
WatchDirectoryFlags,
} from "./_namespaces/ts";
@@ -123,6 +124,7 @@ export interface ResolutionCache {
closeTypeRootsWatch(): void;
getModuleResolutionCache(): ModuleResolutionCache;
getTypeReferenceDirectiveResolutionCache(): TypeReferenceDirectiveResolutionCache;
clear(): void;
}
@@ -319,6 +321,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
return {
getModuleResolutionCache: () => moduleResolutionCache,
getTypeReferenceDirectiveResolutionCache: () => typeReferenceDirectiveResolutionCache,
startRecordingFilesWithChangedResolutions,
finishRecordingFilesWithChangedResolutions,
// perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
+2
View File
@@ -433,6 +433,7 @@ function createSolutionBuilderState<T extends BuilderProgram>(watch: boolean, ho
compilerHost.resolveModuleNames = maybeBind(host, host.resolveModuleNames);
compilerHost.resolveTypeReferenceDirectives = maybeBind(host, host.resolveTypeReferenceDirectives);
compilerHost.getModuleResolutionCache = maybeBind(host, host.getModuleResolutionCache);
compilerHost.getTypeReferenceDirectiveResolutionCache = maybeBind(host, host.getTypeReferenceDirectiveResolutionCache);
let moduleResolutionCache: ModuleResolutionCache | undefined, typeReferenceDirectiveResolutionCache: TypeReferenceDirectiveResolutionCache | undefined;
if (!compilerHost.resolveModuleNameLiterals && !compilerHost.resolveModuleNames) {
moduleResolutionCache = createModuleResolutionCache(compilerHost.getCurrentDirectory(), compilerHost.getCanonicalFileName);
@@ -462,6 +463,7 @@ function createSolutionBuilderState<T extends BuilderProgram>(watch: boolean, ho
typeReferenceDirectiveResolutionCache,
createTypeReferenceResolutionLoader,
);
compilerHost.getTypeReferenceDirectiveResolutionCache = () => typeReferenceDirectiveResolutionCache;
}
compilerHost.getBuildInfo = (fileName, configFilePath) => getBuildInfo(state, fileName, toResolvedConfigFilePath(state, configFilePath as ResolvedConfigFileName), /*modifiedTime*/ undefined);
+4
View File
@@ -16,6 +16,7 @@ import {
ProgramBuildInfo,
Push,
SymlinkCache,
TypeReferenceDirectiveResolutionCache,
} from "./_namespaces/ts";
// branded string type used to store absolute, normalized and canonicalized paths
@@ -4444,6 +4445,8 @@ export interface Program extends ScriptReferenceHost {
/** @internal */
getModuleResolutionCache(): ModuleResolutionCache | undefined;
/** @internal */
getTypeReferenceDirectiveResolutionCache(): TypeReferenceDirectiveResolutionCache | undefined;
/** @internal */
getFilesByNameMap(): Map<string, SourceFile | false | undefined>;
/**
@@ -7367,6 +7370,7 @@ export interface CompilerHost extends ModuleResolutionHost {
* Returns the module resolution cache used by a provided `resolveModuleNames` implementation so that any non-name module resolution operations (eg, package.json lookup) can reuse it
*/
getModuleResolutionCache?(): ModuleResolutionCache | undefined;
/** @internal */ getTypeReferenceDirectiveResolutionCache?(): TypeReferenceDirectiveResolutionCache | undefined;
/**
* @deprecated supply resolveTypeReferenceDirectiveReferences instead for resolution that can handle newer resolution modes like nodenext
*
+5
View File
@@ -82,6 +82,7 @@ import {
sys,
System,
toPath,
TypeReferenceDirectiveResolutionCache,
updateErrorForNoInputFiles,
updateMissingFilePathsWatch,
updateSharedExtendedConfigFileWatcher,
@@ -242,6 +243,7 @@ export interface ProgramHost<T extends BuilderProgram> {
* Returns the module resolution cache used by a provided `resolveModuleNames` implementation so that any non-name module resolution operations (eg, package.json lookup) can reuse it
*/
getModuleResolutionCache?(): ModuleResolutionCache | undefined;
/** @internal */ getTypeReferenceDirectiveResolutionCache?(): TypeReferenceDirectiveResolutionCache | undefined;
}
/**
* Internal interface used to wire emit through same host
@@ -505,6 +507,9 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
compilerHost.getModuleResolutionCache = host.resolveModuleNameLiterals || host.resolveModuleNames ?
maybeBind(host, host.getModuleResolutionCache) :
(() => resolutionCache.getModuleResolutionCache());
compilerHost.getTypeReferenceDirectiveResolutionCache = host.resolveTypeReferenceDirectiveReferences || host.resolveTypeReferenceDirectives ?
maybeBind(host, host.getTypeReferenceDirectiveResolutionCache) :
(() => resolutionCache.getTypeReferenceDirectiveResolutionCache());
const userProvidedResolution = !!host.resolveModuleNameLiterals || !!host.resolveTypeReferenceDirectiveReferences ||
!!host.resolveModuleNames || !!host.resolveTypeReferenceDirectives;
// All resolutions are invalid if user provided resolutions and didnt supply hasInvalidatedResolutions
+11
View File
@@ -142,6 +142,7 @@ import {
toPath,
tracing,
TypeAcquisition,
TypeReferenceDirectiveResolutionCache,
updateErrorForNoInputFiles,
updateMissingFilePathsWatch,
WatchDirectoryFlags,
@@ -684,6 +685,11 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
);
}
/** @internal */
getTypeReferenceDirectiveResolutionCache(): TypeReferenceDirectiveResolutionCache | undefined {
return this.resolutionCache.getTypeReferenceDirectiveResolutionCache();
}
directoryExists(path: string): boolean {
return this.directoryStructureHost.directoryExists!(path); // TODO: GH#18217
}
@@ -2519,6 +2525,11 @@ export class AutoImportProviderProject extends Project {
getModuleResolutionCache() {
return this.hostProject.getCurrentProgram()?.getModuleResolutionCache();
}
/** @internal */
getTypeReferenceDirectiveResolutionCache() {
return this.hostProject.getCurrentProgram()?.getTypeReferenceDirectiveResolutionCache();
}
}
/**
+1
View File
@@ -1692,6 +1692,7 @@ export function createLanguageService(
trace: maybeBind(host, host.trace),
resolveModuleNames: maybeBind(host, host.resolveModuleNames),
getModuleResolutionCache: maybeBind(host, host.getModuleResolutionCache),
getTypeReferenceDirectiveResolutionCache: maybeBind(host, host.getTypeReferenceDirectiveResolutionCache),
createHash: maybeBind(host, host.createHash),
resolveTypeReferenceDirectives: maybeBind(host, host.resolveTypeReferenceDirectives),
resolveModuleNameLiterals: maybeBind(host, host.resolveModuleNameLiterals),
+2
View File
@@ -38,6 +38,7 @@ import {
textChanges,
TextRange,
TextSpan,
TypeReferenceDirectiveResolutionCache,
UserPreferences,
} from "./_namespaces/ts";
@@ -384,6 +385,7 @@ export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalR
/** @internal */ getSymlinkCache?(files?: readonly SourceFile[]): SymlinkCache;
/* Lets the Program from a AutoImportProviderProject use its host project's ModuleResolutionCache */
/** @internal */ getModuleResolutionCache?(): ModuleResolutionCache | undefined;
/** @internal */ getTypeReferenceDirectiveResolutionCache?(): TypeReferenceDirectiveResolutionCache | undefined;
/*
* Required for full import and type reference completions.
@@ -151,16 +151,10 @@ describe("unittests:: tsbuild:: cacheResolutions::", () => {
{
caption: "modify d/da/daa/daaa/x/y/z/randomFileForImport by adding import",
edit: fs => prependText(fs, "/src/project/d/da/daa/daaa/x/y/z/randomFileForImport.ts", `import type { ImportInterface0 } from "pkg0";\n`),
discrepancyExplanation: () => [
`Incremental is currently not reusing resolution so tsbuildinfo has two same resolutions instead of one TODO: (shkamat)`
]
},
{
caption: "modify e/ea/eaa/eaaa/x/y/z/randomFileForImport by adding import",
edit: fs => prependText(fs, "/src/project/e/ea/eaa/eaaa/x/y/z/randomFileForImport.ts", `import type { ImportInterface0 } from "pkg0";\n`),
discrepancyExplanation: () => [
`Incremental is currently not reusing resolution so tsbuildinfo has two same resolutions instead of one TODO: (shkamat)`
]
},
]
});
@@ -247,16 +247,10 @@ describe("unittests:: tsc:: cacheResolutions::", () => {
{
caption: "modify d/da/daa/daaa/x/y/z/randomFileForImport by adding import",
edit: fs => prependText(fs, "/src/project/d/da/daa/daaa/x/y/z/randomFileForImport.ts", `import type { ImportInterface0 } from "pkg0";\n`),
discrepancyExplanation: () => [
`Incremental is currently not reusing resolution so tsbuildinfo has two same resolutions instead of one TODO: (shkamat)`
]
},
{
caption: "modify e/ea/eaa/eaaa/x/y/z/randomFileForImport by adding import",
edit: fs => prependText(fs, "/src/project/e/ea/eaa/eaaa/x/y/z/randomFileForImport.ts", `import type { ImportInterface0 } from "pkg0";\n`),
discrepancyExplanation: () => [
`Incremental is currently not reusing resolution so tsbuildinfo has two same resolutions instead of one TODO: (shkamat)`
]
},
]
});