Experiment with module resolution cache be the only one to store resolutions

This commit is contained in:
Sheetal Nandi 2023-09-22 10:55:41 -07:00
Родитель 55d8bed85c
Коммит e71e459faf
9 изменённых файлов: 210 добавлений и 43 удалений

Просмотреть файл

@ -609,7 +609,7 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string
affectingLocations: initializeResolutionField(affectingLocations),
resolutionDiagnostics: initializeResolutionField(diagnostics),
};
if (containingDirectory) {
if (containingDirectory !== undefined) {
cache?.getOrCreateCacheForDirectory(containingDirectory, redirectedReference).set(typeReferenceDirectiveName, /*mode*/ resolutionMode, result);
if (!isExternalModuleNameRelative(typeReferenceDirectiveName)) {
cache?.getOrCreateCacheForNonRelativeName(typeReferenceDirectiveName, resolutionMode, redirectedReference).set(containingDirectory, result);
@ -823,6 +823,7 @@ export interface ModeAwareCache<T> {
* This assumes that any module id will have the same resolution for sibling files located in the same folder.
*/
export interface PerDirectoryResolutionCache<T> {
/** @internal */ directoryToModuleNameMap: CacheWithRedirects<Path, ModeAwareCache<T>>;
getFromDirectoryCache(name: string, mode: ResolutionMode, directoryName: string, redirectedReference: ResolvedProjectReference | undefined): T | undefined;
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): ModeAwareCache<T>;
clear(): void;
@ -834,6 +835,7 @@ export interface PerDirectoryResolutionCache<T> {
}
export interface NonRelativeNameResolutionCache<T> {
/** @internal */ moduleNameToDirectoryMap: CacheWithRedirects<ModeAwareCacheKey, PerNonRelativeNameCache<T>>;
getFromNonRelativeNameCache(nonRelativeName: string, mode: ResolutionMode, directoryName: string, redirectedReference: ResolvedProjectReference | undefined): T | undefined;
getOrCreateCacheForNonRelativeName(nonRelativeName: string, mode: ResolutionMode, redirectedReference?: ResolvedProjectReference): PerNonRelativeNameCache<T>;
clear(): void;
@ -901,6 +903,13 @@ export interface CacheWithRedirects<K, V> {
getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<K, V>;
update(newOptions: CompilerOptions): void;
clear(): void;
getState(): {
ownOptions: CompilerOptions | undefined;
optionsToRedirectsKey: Map<CompilerOptions, RedirectsCacheKey>;
redirectsKeyToMap: Map<RedirectsCacheKey, Map<K, V>>;
ownMap: Map<K, V>;
redirectsMap: Map<CompilerOptions, Map<K, V>>;
};
}
/** @internal */
@ -917,6 +926,7 @@ export function createCacheWithRedirects<K, V>(ownOptions: CompilerOptions | und
getOrCreateMapOfCacheRedirects,
update,
clear,
getState: () => ({ ownOptions, optionsToRedirectsKey, redirectsKeyToMap, ownMap, redirectsMap }),
};
function getMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<K, V> | undefined {
@ -1019,6 +1029,7 @@ function createPerDirectoryResolutionCache<T>(
): PerDirectoryResolutionCache<T> {
const directoryToModuleNameMap = createCacheWithRedirects<Path, ModeAwareCache<T>>(options, optionsToRedirectsKey);
return {
directoryToModuleNameMap,
getFromDirectoryCache,
getOrCreateCacheForDirectory,
clear,
@ -1107,6 +1118,7 @@ function createNonRelativeNameResolutionCache<T>(
): NonRelativeNameResolutionCache<T> {
const moduleNameToDirectoryMap = createCacheWithRedirects<ModeAwareCacheKey, PerNonRelativeNameCache<T>>(options, optionsToRedirectsKey);
return {
moduleNameToDirectoryMap,
getFromNonRelativeNameCache,
getOrCreateCacheForNonRelativeName,
clear,

Просмотреть файл

@ -258,6 +258,7 @@ import {
Path,
pathIsAbsolute,
pathIsRelative,
PerDirectoryResolutionCache,
Program,
ProgramHost,
ProjectReference,
@ -271,6 +272,7 @@ import {
removeSuffix,
resolutionExtensionIsTSOrJson,
ResolutionMode,
ResolutionStorageCaches,
ResolutionWithFailedLookupLocations,
resolveConfigFileProjectName,
ResolvedConfigFileName,
@ -1558,6 +1560,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
const hasEmitBlockingDiagnostics = new Map<string, boolean>();
let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression | false | undefined;
let resolutionStorageCaches: ResolutionStorageCaches | undefined = host.getResolutionStorageCaches?.();
let moduleResolutionCache: ModuleResolutionCache | undefined;
let actualResolveModuleNamesWorker: (
moduleNames: readonly StringLiteralLike[],
@ -1604,6 +1607,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
moduleResolutionCache,
createModuleResolutionLoader,
);
(resolutionStorageCaches ??= {}).moduleResolutionCache = moduleResolutionCache;
}
let actualResolveTypeReferenceDirectiveNamesWorker: <T extends FileReference | string>(
@ -1646,6 +1650,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
typeReferenceDirectiveResolutionCache,
createTypeReferenceResolutionLoader,
);
(resolutionStorageCaches ??= {}).typeReferenceDirectiveResolutionCache = typeReferenceDirectiveResolutionCache;
}
const hasInvalidatedLibResolutions = host.hasInvalidatedLibResolutions || returnFalse;
@ -1886,6 +1891,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
usesUriStyleNodeCoreModules,
resolvedModules,
resolvedTypeReferenceDirectiveNames,
getResolutionStorageCaches: () => resolutionStorageCaches,
resolvedLibReferences,
getResolvedModule,
getResolvedTypeReferenceDirective,
@ -1941,34 +1947,121 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
return program;
function getResolvedModule(file: SourceFile, moduleName: string, mode: ResolutionMode) {
return resolvedModules?.get(file.path)?.get(moduleName, mode);
return getResolution(
file,
moduleName,
mode,
resolvedModules,
resolutionStorageCaches?.moduleResolutionCache,
getModuleNames,
moduleResolutionNameAndModeGetter,
);
}
function getResolvedTypeReferenceDirective(file: SourceFile, typeDirectiveName: string, mode: ResolutionMode) {
return resolvedTypeReferenceDirectiveNames?.get(file.path)?.get(typeDirectiveName, mode);
return getResolution(
file,
typeDirectiveName,
mode,
resolvedTypeReferenceDirectiveNames,
resolutionStorageCaches?.typeReferenceDirectiveResolutionCache,
file => file.typeReferenceDirectives,
typeReferenceResolutionNameAndModeGetter,
);
}
function getResolution<T, Entry>(
file: SourceFile,
name: string,
mode: ResolutionMode,
perFileCache: Map<Path, ModeAwareCache<T>> | undefined,
resolutionCache: PerDirectoryResolutionCache<T> | undefined,
getEntries: (file: SourceFile) => readonly Entry[],
nameAndMode: ResolutionNameAndModeGetter<Entry, SourceFile>,
) {
const result = perFileCache?.get(file.path)?.get(name, mode);
if (resolutionCache) {
const fileFromProgram = getSourceFileByPath(file.path);
if (
!fileFromProgram ||
fileFromProgram.path !== file.path ||
// There can be case where the resolution was resolved in directory with "mode" but not in file.
!forEach(getEntries(fileFromProgram), entry =>
nameAndMode.getName(entry) === name &&
nameAndMode.getMode(entry, fileFromProgram) === mode)
) {
Debug.assert(result === undefined);
return undefined;
}
const containingDirectory = getDirectoryPath(file.path);
const redirectedReference = getRedirectReferenceForResolution(file);
// May be we need to update ownOptions
const { ownOptions } = resolutionCache.directoryToModuleNameMap.getState();
if (ownOptions) resolutionCache.directoryToModuleNameMap.update(options);
const fromCache = resolutionCache.getFromDirectoryCache(name, mode, containingDirectory, redirectedReference);
Debug.assert(
result === fromCache ||
// Currently resolutionCache in tsserver or tsc-watch doesnt retain per directory resolutions through program update
// So cache might have different result than actual resolution - which will be fixed as part of sharing resolutions across projects
JSON.stringify((result as ResolvedModuleWithFailedLookupLocations)?.resolvedModule) === JSON.stringify((fromCache as ResolvedModuleWithFailedLookupLocations)?.resolvedModule) ||
JSON.stringify((result as ResolvedTypeReferenceDirectiveWithFailedLookupLocations)?.resolvedTypeReferenceDirective) === JSON.stringify((fromCache as ResolvedTypeReferenceDirectiveWithFailedLookupLocations)?.resolvedTypeReferenceDirective),
);
if (ownOptions) resolutionCache.directoryToModuleNameMap.update(ownOptions);
return fromCache;
}
return result;
}
function forEachResolvedModule(
callback: (resolution: ResolvedModuleWithFailedLookupLocations, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
file?: SourceFile,
) {
forEachResolution(resolvedModules, callback, file);
forEachResolution(
callback,
file,
resolvedModules,
resolutionStorageCaches?.moduleResolutionCache,
getModuleNames,
moduleResolutionNameAndModeGetter,
);
}
function forEachResolvedTypeReferenceDirective(
callback: (resolution: ResolvedTypeReferenceDirectiveWithFailedLookupLocations, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
file?: SourceFile,
): void {
forEachResolution(resolvedTypeReferenceDirectiveNames, callback, file);
forEachResolution(
callback,
file,
resolvedTypeReferenceDirectiveNames,
resolutionStorageCaches?.typeReferenceDirectiveResolutionCache,
file => file.typeReferenceDirectives,
typeReferenceResolutionNameAndModeGetter,
);
}
function forEachResolution<T>(
resolutionCache: Map<Path, ModeAwareCache<T>> | undefined,
function forEachResolution<T, Entry>(
callback: (resolution: T, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
file: SourceFile | undefined,
perFileCache: Map<Path, ModeAwareCache<T>> | undefined,
resolutionCache: PerDirectoryResolutionCache<T> | undefined,
getEntries: (file: SourceFile) => readonly Entry[],
nameAndMode: ResolutionNameAndModeGetter<Entry, SourceFile>,
) {
if (file) resolutionCache?.get(file.path)?.forEach((resolution, name, mode) => callback(resolution, name, mode, file.path));
else resolutionCache?.forEach((resolutions, filePath) => resolutions.forEach((resolution, name, mode) => callback(resolution, name, mode, filePath)));
if (file) {
perFileCache?.get(file.path)?.forEach((resolution, name, mode) => {
getResolution(file, name, mode, perFileCache, resolutionCache, getEntries, nameAndMode);
callback(resolution, name, mode, file.path);
});
}
else {
perFileCache?.forEach((resolutions, filePath) =>
resolutions.forEach((resolution, name, mode) => {
getResolution(getSourceFileByPath(filePath)!, name, mode, perFileCache, resolutionCache, getEntries, nameAndMode);
callback(resolution, name, mode, filePath);
})
);
}
}
function getPackagesMap() {
@ -2594,6 +2687,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
usesUriStyleNodeCoreModules = oldProgram.usesUriStyleNodeCoreModules;
resolvedModules = oldProgram.resolvedModules;
resolvedTypeReferenceDirectiveNames = oldProgram.resolvedTypeReferenceDirectiveNames;
resolutionStorageCaches = oldProgram.getResolutionStorageCaches();
resolvedLibReferences = oldProgram.resolvedLibReferences;
packageMap = oldProgram.getCurrentPackagesMap();
@ -3845,13 +3939,17 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
resolveTypeReferenceDirectiveNamesReusingOldState(typeDirectives, file);
const resolutionsInFile = createModeAwareCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>();
(resolvedTypeReferenceDirectiveNames ??= new Map()).set(file.path, resolutionsInFile);
const redirectedReference = getRedirectReferenceForResolution(file);
const resolutionsInCache = resolutionStorageCaches?.typeReferenceDirectiveResolutionCache?.getOrCreateCacheForDirectory(getDirectoryPath(file.path), redirectedReference);
for (let index = 0; index < typeDirectives.length; index++) {
const ref = file.typeReferenceDirectives[index];
const resolvedTypeReferenceDirective = resolutions[index];
// store resolved type directive on the file
const fileName = toFileNameLowerCase(ref.fileName);
resolutionsInFile.set(fileName, getModeForFileReference(ref, file.impliedNodeFormat), resolvedTypeReferenceDirective);
const mode = ref.resolutionMode || file.impliedNodeFormat;
const mode = getModeForFileReference(ref, file.impliedNodeFormat);
resolutionsInFile.set(fileName, mode, resolvedTypeReferenceDirective);
// We have to set this resolution if say this was done as part of reusing program where not every resolution is re-valudated
if (resolutionsInCache && !resolutionsInCache.has(fileName, mode)) resolutionsInCache.set(fileName, mode, resolutions[index]);
if (mode && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Node16 && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeNext) {
(fileProcessingDiagnostics ??= []).push({
kind: FilePreprocessingDiagnosticsKind.ResolutionDiagnostics,
@ -4021,14 +4119,18 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
const resolutions = resolvedModulesProcessing?.get(file.path) ||
resolveModuleNamesReusingOldState(moduleNames, file);
Debug.assert(resolutions.length === moduleNames.length);
const optionsForFile = (useSourceOfProjectReferenceRedirect ? getRedirectReferenceForResolution(file)?.commandLine.options : undefined) || options;
const redirectedReference = getRedirectReferenceForResolution(file);
const optionsForFile = (useSourceOfProjectReferenceRedirect ? redirectedReference?.commandLine.options : undefined) || options;
const resolutionsInFile = createModeAwareCache<ResolutionWithFailedLookupLocations>();
(resolvedModules ??= new Map()).set(file.path, resolutionsInFile);
const resolutionsInCache = resolutionStorageCaches?.moduleResolutionCache?.getOrCreateCacheForDirectory(getDirectoryPath(file.path), redirectedReference);
for (let index = 0; index < moduleNames.length; index++) {
const resolution = resolutions[index].resolvedModule;
const moduleName = moduleNames[index].text;
const mode = getModeForUsageLocation(file, moduleNames[index]);
resolutionsInFile.set(moduleName, mode, resolutions[index]);
// We have to set this resolution if say this was done as part of reusing program where not every resolution is re-valudated
if (resolutionsInCache && !resolutionsInCache.has(moduleName, mode)) resolutionsInCache.set(moduleName, mode, resolutions[index]);
addResolutionDiagnosticsFromResolutionOrCache(file, moduleName, resolutions[index], mode);
if (!resolution) {

Просмотреть файл

@ -75,6 +75,7 @@ import {
startsWith,
StringLiteralLike,
trace,
TypeReferenceDirectiveResolutionCache,
updateResolutionField,
WatchDirectoryFlags,
} from "./_namespaces/ts";
@ -156,6 +157,7 @@ export interface ResolutionCache {
closeTypeRootsWatch(): void;
getModuleResolutionCache(): ModuleResolutionCache;
getTypeReferenceDirectiveResolutionCache(): TypeReferenceDirectiveResolutionCache;
clear(): void;
onChangesAffectModuleResolution(): void;
@ -535,27 +537,18 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
// The key in the map is source file's path.
// The values are Map of resolutions with key being name lookedup.
const resolvedModuleNames = new Map<Path, ModeAwareCache<CachedResolvedModuleWithFailedLookupLocations>>();
const moduleResolutionCache = createModuleResolutionCache(
getCurrentDirectory(),
resolutionHost.getCanonicalFileName,
resolutionHost.getCompilationSettings(),
);
let moduleResolutionCache: ModuleResolutionCache;
const resolvedTypeReferenceDirectives = new Map<Path, ModeAwareCache<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
const typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache(
getCurrentDirectory(),
resolutionHost.getCanonicalFileName,
resolutionHost.getCompilationSettings(),
moduleResolutionCache.getPackageJsonInfoCache(),
moduleResolutionCache.optionsToRedirectsKey,
);
let typeReferenceDirectiveResolutionCache: TypeReferenceDirectiveResolutionCache;
createResolutionCaches();
const resolvedLibraries = new Map<string, CachedResolvedModuleWithFailedLookupLocations>();
const libraryResolutionCache = createModuleResolutionCache(
getCurrentDirectory(),
resolutionHost.getCanonicalFileName,
getOptionsForLibraryResolution(resolutionHost.getCompilationSettings()),
moduleResolutionCache.getPackageJsonInfoCache(),
moduleResolutionCache!.getPackageJsonInfoCache(),
);
const directoryWatchesOfFailedLookups = new Map<Path, DirectoryWatchesOfFailedLookup>();
@ -579,6 +572,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
fileWatchesOfAffectingLocations,
watchFailedLookupLocationsOfExternalModuleResolutions,
getModuleResolutionCache: () => moduleResolutionCache,
getTypeReferenceDirectiveResolutionCache: () => typeReferenceDirectiveResolutionCache,
startRecordingFilesWithChangedResolutions,
finishRecordingFilesWithChangedResolutions,
// perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
@ -603,6 +597,22 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
onChangesAffectModuleResolution,
};
function createResolutionCaches() {
moduleResolutionCache = createModuleResolutionCache(
getCurrentDirectory(),
resolutionHost.getCanonicalFileName,
resolutionHost.getCompilationSettings(),
moduleResolutionCache?.getPackageJsonInfoCache(),
);
typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache(
getCurrentDirectory(),
resolutionHost.getCanonicalFileName,
resolutionHost.getCompilationSettings(),
moduleResolutionCache.getPackageJsonInfoCache(),
moduleResolutionCache.optionsToRedirectsKey,
);
}
function getResolvedModule(resolution: CachedResolvedModuleWithFailedLookupLocations) {
return resolution.resolvedModule;
}
@ -627,10 +637,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
affectingPathChecks = undefined;
affectingPathChecksForFile = undefined;
allModuleAndTypeResolutionsAreInvalidated = false;
moduleResolutionCache.clear();
typeReferenceDirectiveResolutionCache.clear();
moduleResolutionCache.update(resolutionHost.getCompilationSettings());
typeReferenceDirectiveResolutionCache.update(resolutionHost.getCompilationSettings());
createResolutionCaches();
libraryResolutionCache.clear();
impliedFormatPackageJsons.clear();
resolvedLibraries.clear();
@ -639,10 +646,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
function onChangesAffectModuleResolution() {
allModuleAndTypeResolutionsAreInvalidated = true;
moduleResolutionCache.clearAllExceptPackageJsonInfoCache();
typeReferenceDirectiveResolutionCache.clearAllExceptPackageJsonInfoCache();
moduleResolutionCache.update(resolutionHost.getCompilationSettings());
typeReferenceDirectiveResolutionCache.update(resolutionHost.getCompilationSettings());
createResolutionCaches();
}
function startRecordingFilesWithChangedResolutions() {
@ -686,8 +690,8 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
}
function startCachingPerDirectoryResolution() {
moduleResolutionCache.clearAllExceptPackageJsonInfoCache();
typeReferenceDirectiveResolutionCache.clearAllExceptPackageJsonInfoCache();
// Not all resolutions are re-resolved so wont be in the cache. -- Hmm,
createResolutionCaches();
libraryResolutionCache.clearAllExceptPackageJsonInfoCache();
// perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
// (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)

Просмотреть файл

@ -393,8 +393,8 @@ interface SolutionBuilderState<T extends BuilderProgram> extends WatchFactory<Wa
readonly projectErrorsReported: Map<ResolvedConfigFilePath, true>;
readonly compilerHost: CompilerHost & ReadBuildProgramHost;
readonly moduleResolutionCache: ModuleResolutionCache | undefined;
readonly typeReferenceDirectiveResolutionCache: TypeReferenceDirectiveResolutionCache | undefined;
moduleResolutionCache: ModuleResolutionCache | undefined;
typeReferenceDirectiveResolutionCache: TypeReferenceDirectiveResolutionCache | undefined;
readonly libraryResolutionCache: ModuleResolutionCache | undefined;
// Mutable state
@ -449,10 +449,10 @@ function createSolutionBuilderState<T extends BuilderProgram>(watch: boolean, ho
options,
containingSourceFile,
host,
moduleResolutionCache,
state.moduleResolutionCache,
createModuleResolutionLoader,
);
compilerHost.getModuleResolutionCache = () => moduleResolutionCache;
compilerHost.getModuleResolutionCache = () => state.moduleResolutionCache;
}
if (!compilerHost.resolveTypeReferenceDirectiveReferences && !compilerHost.resolveTypeReferenceDirectives) {
typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache(
@ -470,10 +470,14 @@ function createSolutionBuilderState<T extends BuilderProgram>(watch: boolean, ho
options,
containingSourceFile,
host,
typeReferenceDirectiveResolutionCache,
state.typeReferenceDirectiveResolutionCache,
createTypeReferenceResolutionLoader,
);
}
compilerHost.getResolutionStorageCaches = () => ({
moduleResolutionCache: state.moduleResolutionCache,
typeReferenceDirectiveResolutionCache: state.typeReferenceDirectiveResolutionCache,
});
let libraryResolutionCache: ModuleResolutionCache | undefined;
if (!compilerHost.resolveLibrary) {
libraryResolutionCache = createModuleResolutionCache(compilerHost.getCurrentDirectory(), compilerHost.getCanonicalFileName, /*options*/ undefined, moduleResolutionCache?.getPackageJsonInfoCache());
@ -784,8 +788,24 @@ function disableCache<T extends BuilderProgram>(state: SolutionBuilderState<T>)
compilerHost.getSourceFile = cache.originalGetSourceFile;
state.readFileWithCache = cache.originalReadFileWithCache;
extendedConfigCache.clear();
moduleResolutionCache?.clear();
typeReferenceDirectiveResolutionCache?.clear();
if (moduleResolutionCache) {
moduleResolutionCache.getPackageJsonInfoCache().clear();
state.moduleResolutionCache = createModuleResolutionCache(
compilerHost.getCurrentDirectory(),
compilerHost.getCanonicalFileName,
/*options*/ undefined,
moduleResolutionCache.getPackageJsonInfoCache(),
);
}
if (typeReferenceDirectiveResolutionCache) {
state.typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache(
compilerHost.getCurrentDirectory(),
compilerHost.getCanonicalFileName,
/*options*/ undefined,
moduleResolutionCache?.getPackageJsonInfoCache(),
moduleResolutionCache?.optionsToRedirectsKey,
);
}
libraryResolutionCache?.clear();
state.cache = undefined;
}

Просмотреть файл

@ -17,6 +17,7 @@ import {
ProgramBuildInfo,
SymlinkCache,
ThisContainer,
TypeReferenceDirectiveResolutionCache,
} from "./_namespaces/ts";
// branded string type used to store absolute, normalized and canonicalized paths
@ -4623,6 +4624,12 @@ export interface LibResolution<T extends ResolvedModuleWithFailedLookupLocations
resolution: T;
actual: string;
}
/** @internal */
export interface ResolutionStorageCaches {
moduleResolutionCache?: ModuleResolutionCache;
typeReferenceDirectiveResolutionCache?: TypeReferenceDirectiveResolutionCache;
}
export interface Program extends ScriptReferenceHost {
getCurrentDirectory(): string;
/**
@ -4645,6 +4652,8 @@ export interface Program extends ScriptReferenceHost {
/** @internal */
getModuleResolutionCache(): ModuleResolutionCache | undefined;
/** @internal */
getResolutionStorageCaches(): ResolutionStorageCaches | undefined;
/** @internal */
getFilesByNameMap(): Map<string, SourceFile | false | undefined>;
/** @internal */
@ -7771,6 +7780,8 @@ export interface CompilerHost extends ModuleResolutionHost {
reusedNames: readonly T[] | undefined,
): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[];
/** @internal */
getResolutionStorageCaches?(): ResolutionStorageCaches | undefined;
/** @internal */
resolveLibrary?(
libraryName: string,
resolveFrom: string,

Просмотреть файл

@ -535,6 +535,12 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
compilerHost.getModuleResolutionCache = host.resolveModuleNameLiterals || host.resolveModuleNames ?
maybeBind(host, host.getModuleResolutionCache) :
(() => resolutionCache.getModuleResolutionCache());
compilerHost.getResolutionStorageCaches = () => ({
moduleResolutionCache: !host.resolveModuleNameLiterals && !host.resolveModuleNames ?
resolutionCache.getModuleResolutionCache() : undefined,
typeReferenceDirectiveResolutionCache: !host.resolveTypeReferenceDirectiveReferences && !host.resolveTypeReferenceDirectives ?
resolutionCache.getTypeReferenceDirectiveResolutionCache() : undefined,
});
const userProvidedResolution = !!host.resolveModuleNameLiterals || !!host.resolveTypeReferenceDirectiveReferences ||
!!host.resolveModuleNames || !!host.resolveTypeReferenceDirectives;
// All resolutions are invalid if user provided resolutions and didnt supply hasInvalidatedResolutions

Просмотреть файл

@ -102,6 +102,7 @@ import {
removeFileExtension,
ResolutionCache,
resolutionExtensionIsTSOrJson,
ResolutionStorageCaches,
ResolvedModuleWithFailedLookupLocations,
ResolvedProjectReference,
ResolvedTypeReferenceDirectiveWithFailedLookupLocations,
@ -730,6 +731,14 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
return this.resolutionCache.getModuleResolutionCache();
}
/** @internal */
getResolutionStorageCaches(): ResolutionStorageCaches {
return {
moduleResolutionCache: this.resolutionCache.getModuleResolutionCache(),
typeReferenceDirectiveResolutionCache: this.resolutionCache.getTypeReferenceDirectiveResolutionCache(),
};
}
/** @internal */
resolveTypeReferenceDirectiveReferences<T extends string | FileReference>(typeDirectiveReferences: readonly T[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, containingSourceFile: SourceFile | undefined, reusedNames: readonly T[] | undefined): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[] {
return this.resolutionCache.resolveTypeReferenceDirectiveReferences(
@ -2666,7 +2675,7 @@ export class AutoImportProviderProject extends Project {
}
/** @internal */
override getModuleResolutionCache() {
override getModuleResolutionCache() { // This will be wrong when program has its own module resolutionCache?
return this.hostProject.getCurrentProgram()?.getModuleResolutionCache();
}
}

Просмотреть файл

@ -1686,6 +1686,7 @@ export function createLanguageService(
trace: maybeBind(host, host.trace),
resolveModuleNames: maybeBind(host, host.resolveModuleNames),
getModuleResolutionCache: maybeBind(host, host.getModuleResolutionCache),
getResolutionStorageCaches: maybeBind(host, host.getResolutionStorageCaches),
createHash: maybeBind(host, host.createHash),
resolveTypeReferenceDirectives: maybeBind(host, host.resolveTypeReferenceDirectives),
resolveModuleNameLiterals: maybeBind(host, host.resolveModuleNameLiterals),

Просмотреть файл

@ -24,6 +24,7 @@ import {
Program,
ProjectReference,
ResolutionMode,
ResolutionStorageCaches,
ResolvedModule,
ResolvedModuleWithFailedLookupLocations,
ResolvedProjectReference,
@ -398,6 +399,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 */ getResolutionStorageCaches?(): ResolutionStorageCaches | undefined;
/*
* Required for full import and type reference completions.