Skip to content

Commit 93b958e

Browse files
committed
Share module resolution cache among different program
1 parent 3264b64 commit 93b958e

File tree

3 files changed

+57
-4
lines changed

3 files changed

+57
-4
lines changed

src/compiler/moduleNameResolver.ts

+18-3
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ namespace ts {
421421
*/
422422
export interface ModuleResolutionCache extends NonRelativeModuleNameResolutionCache {
423423
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map<ResolvedModuleWithFailedLookupLocations>;
424+
/*@internal*/ directoryToModuleNameMap: CacheWithRedirects<Map<ResolvedModuleWithFailedLookupLocations>>;
424425
}
425426

426427
/**
@@ -429,6 +430,7 @@ namespace ts {
429430
*/
430431
export interface NonRelativeModuleNameResolutionCache {
431432
getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache;
433+
/*@internal*/ moduleNameToDirectoryMap: CacheWithRedirects<PerModuleNameCache>;
432434
}
433435

434436
export interface PerModuleNameCache {
@@ -445,25 +447,38 @@ namespace ts {
445447
);
446448
}
447449

450+
448451
/*@internal*/
449452
export interface CacheWithRedirects<T> {
450453
ownMap: Map<T>;
451454
redirectsMap: Map<Map<T>>;
452455
getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<T>;
453456
clear(): void;
457+
setOwnOptions(newOptions: CompilerOptions): void;
458+
setOwnMap(newOwnMap: Map<T>): void;
454459
}
455460

456461
/*@internal*/
457462
export function createCacheWithRedirects<T>(options?: CompilerOptions): CacheWithRedirects<T> {
458-
const ownMap: Map<T> = createMap();
463+
let ownMap: Map<T> = createMap();
459464
const redirectsMap: Map<Map<T>> = createMap();
460465
return {
461466
ownMap,
462467
redirectsMap,
463468
getOrCreateMapOfCacheRedirects,
464-
clear
469+
clear,
470+
setOwnOptions,
471+
setOwnMap
465472
};
466473

474+
function setOwnOptions(newOptions: CompilerOptions) {
475+
options = newOptions;
476+
}
477+
478+
function setOwnMap(newOwnMap: Map<T>) {
479+
ownMap = newOwnMap;
480+
}
481+
467482
function getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined) {
468483
if (!redirectedReference) {
469484
return ownMap;
@@ -491,7 +506,7 @@ namespace ts {
491506
currentDirectory: string,
492507
getCanonicalFileName: GetCanonicalFileName): ModuleResolutionCache {
493508

494-
return { getOrCreateCacheForDirectory, getOrCreateCacheForModuleName };
509+
return { getOrCreateCacheForDirectory, getOrCreateCacheForModuleName, directoryToModuleNameMap, moduleNameToDirectoryMap };
495510

496511
function getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference) {
497512
const path = toPath(directoryName, currentDirectory, getCanonicalFileName);

src/compiler/program.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,8 @@ namespace ts {
528528
}
529529
}
530530

531-
function loadWithLocalCache<T>(names: string[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, loader: (name: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => T): T[] {
531+
/* @internal */
532+
export function loadWithLocalCache<T>(names: string[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, loader: (name: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => T): T[] {
532533
if (names.length === 0) {
533534
return [];
534535
}

src/compiler/tsbuild.ts

+37
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ namespace ts {
400400
const compilerHost = createCompilerHostFromProgramHost(host, () => projectCompilerOptions);
401401
setGetSourceFileAsHashVersioned(compilerHost, host);
402402

403+
compilerHost.resolveModuleNames = maybeBind(host, host.resolveModuleNames);
404+
compilerHost.resolveTypeReferenceDirectives = maybeBind(host, host.resolveTypeReferenceDirectives);
405+
let moduleResolutionCache = !compilerHost.resolveModuleNames ? createModuleResolutionCache(currentDirectory, getCanonicalFileName) : undefined;
406+
403407
const buildInfoChecked = createFileMap<true>(toPath);
404408

405409
// Watch state
@@ -1097,6 +1101,30 @@ namespace ts {
10971101

10981102
// TODO: handle resolve module name to cache result in project reference redirect
10991103
projectCompilerOptions = configFile.options;
1104+
// Update module resolution cache if needed
1105+
if (moduleResolutionCache) {
1106+
const projPath = toPath(proj);
1107+
if (moduleResolutionCache.directoryToModuleNameMap.redirectsMap.size === 0) {
1108+
// The own map will be for projectCompilerOptions
1109+
Debug.assert(moduleResolutionCache.moduleNameToDirectoryMap.redirectsMap.size === 0);
1110+
moduleResolutionCache.directoryToModuleNameMap.redirectsMap.set(projPath, moduleResolutionCache.directoryToModuleNameMap.ownMap);
1111+
moduleResolutionCache.moduleNameToDirectoryMap.redirectsMap.set(projPath, moduleResolutionCache.moduleNameToDirectoryMap.ownMap);
1112+
}
1113+
else {
1114+
// Set correct own map
1115+
Debug.assert(moduleResolutionCache.moduleNameToDirectoryMap.redirectsMap.size > 0);
1116+
1117+
const ref: ResolvedProjectReference = {
1118+
sourceFile: projectCompilerOptions.configFile!,
1119+
commandLine: configFile
1120+
};
1121+
moduleResolutionCache.directoryToModuleNameMap.setOwnMap(moduleResolutionCache.directoryToModuleNameMap.getOrCreateMapOfCacheRedirects(ref));
1122+
moduleResolutionCache.moduleNameToDirectoryMap.setOwnMap(moduleResolutionCache.moduleNameToDirectoryMap.getOrCreateMapOfCacheRedirects(ref));
1123+
}
1124+
moduleResolutionCache.directoryToModuleNameMap.setOwnOptions(projectCompilerOptions);
1125+
moduleResolutionCache.moduleNameToDirectoryMap.setOwnOptions(projectCompilerOptions);
1126+
}
1127+
11001128
const program = host.createProgram(
11011129
configFile.fileNames,
11021130
configFile.options,
@@ -1368,6 +1396,13 @@ namespace ts {
13681396
readFileWithCache = newReadFileWithCache;
13691397
compilerHost.getSourceFile = getSourceFileWithCache!;
13701398

1399+
const originalResolveModuleNames = compilerHost.resolveModuleNames;
1400+
if (!compilerHost.resolveModuleNames) {
1401+
const loader = (moduleName: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveModuleName(moduleName, containingFile, projectCompilerOptions, compilerHost, moduleResolutionCache, redirectedReference).resolvedModule!;
1402+
compilerHost.resolveModuleNames = (moduleNames, containingFile, _reusedNames, redirectedReference) =>
1403+
loadWithLocalCache<ResolvedModuleFull>(Debug.assertEachDefined(moduleNames), containingFile, redirectedReference, loader);
1404+
}
1405+
13711406
const graph = getGlobalDependencyGraph();
13721407
reportBuildQueue(graph);
13731408
let anyFailed = false;
@@ -1428,6 +1463,8 @@ namespace ts {
14281463
host.writeFile = originalWriteFile;
14291464
compilerHost.getSourceFile = savedGetSourceFile;
14301465
readFileWithCache = savedReadFileWithCache;
1466+
compilerHost.resolveModuleNames = originalResolveModuleNames;
1467+
moduleResolutionCache = undefined;
14311468
return anyFailed ? ExitStatus.DiagnosticsPresent_OutputsSkipped : ExitStatus.Success;
14321469
}
14331470

0 commit comments

Comments
 (0)