Skip to content

Commit

Permalink
Use per directory cache for type reference directive resolution as well
Browse files Browse the repository at this point in the history
  • Loading branch information
sheetalkamat committed Apr 20, 2021
1 parent 55f0eec commit 116b9b3
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 106 deletions.
24 changes: 16 additions & 8 deletions src/compiler/diagnosticMessages.json
Expand Up @@ -4849,6 +4849,22 @@
"category": "Error",
"code": 6238
},
"Using cached result of 'package.json' at '{0}' that indicates it was found.": {
"category": "Message",
"code": 6239
},
"Using cached result of 'package.json' at '{0}' that indicates it was not found.": {
"category": "Message",
"code": 6240
},
"Resolution for type reference directive '{0}' was found in cache from location '{1}'.": {
"category": "Message",
"code": 6241
},
"======== Resolving type reference directive '{0}', containing file '{1}'. ========": {
"category": "Message",
"code": 6242
},

"Projects to reference": {
"category": "Message",
Expand Down Expand Up @@ -5041,14 +5057,6 @@
"code": 6387,
"reportsDeprecated": true
},
"Using cached result of 'package.json' at '{0}' that indicates it was found.": {
"category": "Message",
"code": 6388
},
"Using cached result of 'package.json' at '{0}' that indicates it was not found.": {
"category": "Message",
"code": 6389
},

"The expected type comes from property '{0}' which is declared here on type '{1}'": {
"category": "Message",
Expand Down
236 changes: 163 additions & 73 deletions src/compiler/moduleNameResolver.ts

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/compiler/program.ts
Expand Up @@ -843,7 +843,7 @@ namespace ts {
let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression | false | undefined;

let moduleResolutionCache: ModuleResolutionCache | undefined;
let packageJsonInfoCache: PackageJsonInfoCache | undefined;
let typeReferenceDirectiveResolutionCache: TypeReferenceDirectiveResolutionCache | undefined;
let actualResolveModuleNamesWorker: (moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference) => ResolvedModuleFull[];
const hasInvalidatedResolution = host.hasInvalidatedResolution || returnFalse;
if (host.resolveModuleNames) {
Expand All @@ -868,14 +868,14 @@ namespace ts {
actualResolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile, redirectedReference) => host.resolveTypeReferenceDirectives!(Debug.checkEachDefined(typeDirectiveNames), containingFile, redirectedReference, options);
}
else {
packageJsonInfoCache = moduleResolutionCache || createPackageJsonInfoCache(currentDirectory, getCanonicalFileName);
typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache(currentDirectory, getCanonicalFileName, /*options*/ undefined, moduleResolutionCache?.getPackageJsonInfoCache());
const loader = (typesRef: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveTypeReferenceDirective(
typesRef,
containingFile,
options,
host,
redirectedReference,
packageJsonInfoCache,
typeReferenceDirectiveResolutionCache,
).resolvedTypeReferenceDirective!; // TODO: GH#18217
actualResolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile, redirectedReference) => loadWithLocalCache<ResolvedTypeReferenceDirective>(Debug.checkEachDefined(typeReferenceDirectiveNames), containingFile, redirectedReference, loader);
}
Expand Down Expand Up @@ -1045,7 +1045,7 @@ namespace ts {
);
}

packageJsonInfoCache = undefined;
typeReferenceDirectiveResolutionCache = undefined;

// unconditionally set oldProgram to undefined to prevent it from being captured in closure
oldProgram = undefined;
Expand Down
18 changes: 13 additions & 5 deletions src/compiler/resolutionCache.ts
Expand Up @@ -166,15 +166,23 @@ namespace ts {
const resolvedModuleNames = new Map<Path, ESMap<string, CachedResolvedModuleWithFailedLookupLocations>>();
const perDirectoryResolvedModuleNames: CacheWithRedirects<ESMap<string, CachedResolvedModuleWithFailedLookupLocations>> = createCacheWithRedirects();
const nonRelativeModuleNameCache: CacheWithRedirects<PerModuleNameCache> = createCacheWithRedirects();
const moduleResolutionCache = createModuleResolutionCacheWithMaps(
const moduleResolutionCache = createModuleResolutionCache(
getCurrentDirectory(),
resolutionHost.getCanonicalFileName,
/*options*/ undefined,
perDirectoryResolvedModuleNames,
nonRelativeModuleNameCache,
getCurrentDirectory(),
resolutionHost.getCanonicalFileName
);

const resolvedTypeReferenceDirectives = new Map<Path, ESMap<string, CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
const perDirectoryResolvedTypeReferenceDirectives: CacheWithRedirects<ESMap<string, CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations>> = createCacheWithRedirects();
const typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache(
getCurrentDirectory(),
resolutionHost.getCanonicalFileName,
/*options*/ undefined,
moduleResolutionCache.getPackageJsonInfoCache(),
perDirectoryResolvedTypeReferenceDirectives
);

/**
* These are the extensions that failed lookup files will have by default,
Expand Down Expand Up @@ -285,7 +293,7 @@ namespace ts {

function clearPerDirectoryResolutions() {
moduleResolutionCache.clear();
perDirectoryResolvedTypeReferenceDirectives.clear();
typeReferenceDirectiveResolutionCache.clear();
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
nonRelativeExternalModuleResolutions.clear();
}
Expand Down Expand Up @@ -335,7 +343,7 @@ namespace ts {
}

function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference): CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations {
return ts.resolveTypeReferenceDirective(typeReferenceDirectiveName, containingFile, options, host, redirectedReference, moduleResolutionCache);
return ts.resolveTypeReferenceDirective(typeReferenceDirectiveName, containingFile, options, host, redirectedReference, typeReferenceDirectiveResolutionCache);
}

interface ResolveNamesWithLocalCacheInput<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName> {
Expand Down
12 changes: 6 additions & 6 deletions src/compiler/tsbuildPublic.ts
Expand Up @@ -238,7 +238,7 @@ namespace ts {

readonly compilerHost: CompilerHost;
readonly moduleResolutionCache: ModuleResolutionCache | undefined;
readonly packageJsonInfoCache: PackageJsonInfoCache | undefined;
readonly typeReferenceDirectiveResolutionCache: TypeReferenceDirectiveResolutionCache | undefined;

// Mutable state
buildOrder: AnyBuildOrder | undefined;
Expand Down Expand Up @@ -276,14 +276,14 @@ namespace ts {
compilerHost.resolveModuleNames = maybeBind(host, host.resolveModuleNames);
compilerHost.resolveTypeReferenceDirectives = maybeBind(host, host.resolveTypeReferenceDirectives);
const moduleResolutionCache = !compilerHost.resolveModuleNames ? createModuleResolutionCache(currentDirectory, getCanonicalFileName) : undefined;
const packageJsonInfoCache = !compilerHost.resolveTypeReferenceDirectives ? moduleResolutionCache || createPackageJsonInfoCache(currentDirectory, getCanonicalFileName) : undefined;
const typeReferenceDirectiveResolutionCache = !compilerHost.resolveTypeReferenceDirectives ? createTypeReferenceDirectiveResolutionCache(currentDirectory, getCanonicalFileName, /*options*/ undefined, moduleResolutionCache?.getPackageJsonInfoCache()) : undefined;
if (!compilerHost.resolveModuleNames) {
const loader = (moduleName: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveModuleName(moduleName, containingFile, state.projectCompilerOptions, compilerHost, moduleResolutionCache, redirectedReference).resolvedModule!;
compilerHost.resolveModuleNames = (moduleNames, containingFile, _reusedNames, redirectedReference) =>
loadWithLocalCache<ResolvedModuleFull>(Debug.checkEachDefined(moduleNames), containingFile, redirectedReference, loader);
}
if (!compilerHost.resolveTypeReferenceDirectives) {
const loader = (moduleName: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveTypeReferenceDirective(moduleName, containingFile, state.projectCompilerOptions, compilerHost, redirectedReference, state.packageJsonInfoCache).resolvedTypeReferenceDirective!;
const loader = (moduleName: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveTypeReferenceDirective(moduleName, containingFile, state.projectCompilerOptions, compilerHost, redirectedReference, state.typeReferenceDirectiveResolutionCache).resolvedTypeReferenceDirective!;
compilerHost.resolveTypeReferenceDirectives = (typeReferenceDirectiveNames, containingFile, redirectedReference) =>
loadWithLocalCache<ResolvedTypeReferenceDirective>(Debug.checkEachDefined(typeReferenceDirectiveNames), containingFile, redirectedReference, loader);
}
Expand Down Expand Up @@ -317,7 +317,7 @@ namespace ts {

compilerHost,
moduleResolutionCache,
packageJsonInfoCache,
typeReferenceDirectiveResolutionCache,

// Mutable state
buildOrder: undefined,
Expand Down Expand Up @@ -556,7 +556,7 @@ namespace ts {
function disableCache(state: SolutionBuilderState) {
if (!state.cache) return;

const { cache, host, compilerHost, extendedConfigCache, moduleResolutionCache, packageJsonInfoCache } = state;
const { cache, host, compilerHost, extendedConfigCache, moduleResolutionCache, typeReferenceDirectiveResolutionCache } = state;

host.readFile = cache.originalReadFile;
host.fileExists = cache.originalFileExists;
Expand All @@ -567,7 +567,7 @@ namespace ts {
state.readFileWithCache = cache.originalReadFileWithCache;
extendedConfigCache.clear();
moduleResolutionCache?.clear();
packageJsonInfoCache?.clear();
typeReferenceDirectiveResolutionCache?.clear();
state.cache = undefined;
}

Expand Down
15 changes: 10 additions & 5 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Expand Up @@ -4713,7 +4713,7 @@ declare namespace ts {
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
* is assumed to be the same as root directory of the project.
*/
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, packageJsonInfoCache?: PackageJsonInfoCache): ResolvedTypeReferenceDirectiveWithFailedLookupLocations;
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, cache?: TypeReferenceDirectiveResolutionCache): ResolvedTypeReferenceDirectiveWithFailedLookupLocations;
/**
* Given a set of options, returns the set of type directive names
* that should be included for this program automatically.
Expand All @@ -4723,19 +4723,24 @@ declare namespace ts {
* this list is only the set of defaults that are implicitly included.
*/
export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): string[];
export interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, PackageJsonInfoCache {
}
/**
* Cached module resolutions per containing directory.
* Cached resolutions per containing directory.
* This assumes that any module id will have the same resolution for sibling files located in the same folder.
*/
export interface ModuleResolutionCache extends NonRelativeModuleNameResolutionCache, PackageJsonInfoCache {
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map<ResolvedModuleWithFailedLookupLocations>;
export interface PerDirectoryResolutionCache<T> {
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map<T>;
clear(): void;
/**
* Updates with the current compilerOptions the cache will operate with.
* This updates the redirects map as well if needed so module resolutions are cached if they can across the projects
*/
update(options: CompilerOptions): void;
}
export interface ModuleResolutionCache extends PerDirectoryResolutionCache<ResolvedModuleWithFailedLookupLocations>, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache {
getPackageJsonInfoCache(): PackageJsonInfoCache;
}
/**
* Stored map from non-relative module name to a table: directory -> result of module lookup in this directory
* We support only non-relative module names because resolution of relative module names is usually more deterministic and thus less expensive.
Expand All @@ -4751,7 +4756,7 @@ declare namespace ts {
set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void;
}
export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string, options?: CompilerOptions): ModuleResolutionCache;
export function createPackageJsonInfoCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): PackageJsonInfoCache;
export function createTypeReferenceDirectiveResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string, options?: CompilerOptions, packageJsonInfoCache?: PackageJsonInfoCache): TypeReferenceDirectiveResolutionCache;
export function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations | undefined;
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
Expand Down
15 changes: 10 additions & 5 deletions tests/baselines/reference/api/typescript.d.ts
Expand Up @@ -4713,7 +4713,7 @@ declare namespace ts {
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
* is assumed to be the same as root directory of the project.
*/
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, packageJsonInfoCache?: PackageJsonInfoCache): ResolvedTypeReferenceDirectiveWithFailedLookupLocations;
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, cache?: TypeReferenceDirectiveResolutionCache): ResolvedTypeReferenceDirectiveWithFailedLookupLocations;
/**
* Given a set of options, returns the set of type directive names
* that should be included for this program automatically.
Expand All @@ -4723,19 +4723,24 @@ declare namespace ts {
* this list is only the set of defaults that are implicitly included.
*/
export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): string[];
export interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, PackageJsonInfoCache {
}
/**
* Cached module resolutions per containing directory.
* Cached resolutions per containing directory.
* This assumes that any module id will have the same resolution for sibling files located in the same folder.
*/
export interface ModuleResolutionCache extends NonRelativeModuleNameResolutionCache, PackageJsonInfoCache {
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map<ResolvedModuleWithFailedLookupLocations>;
export interface PerDirectoryResolutionCache<T> {
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map<T>;
clear(): void;
/**
* Updates with the current compilerOptions the cache will operate with.
* This updates the redirects map as well if needed so module resolutions are cached if they can across the projects
*/
update(options: CompilerOptions): void;
}
export interface ModuleResolutionCache extends PerDirectoryResolutionCache<ResolvedModuleWithFailedLookupLocations>, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache {
getPackageJsonInfoCache(): PackageJsonInfoCache;
}
/**
* Stored map from non-relative module name to a table: directory -> result of module lookup in this directory
* We support only non-relative module names because resolution of relative module names is usually more deterministic and thus less expensive.
Expand All @@ -4751,7 +4756,7 @@ declare namespace ts {
set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void;
}
export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string, options?: CompilerOptions): ModuleResolutionCache;
export function createPackageJsonInfoCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): PackageJsonInfoCache;
export function createTypeReferenceDirectiveResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string, options?: CompilerOptions, packageJsonInfoCache?: PackageJsonInfoCache): TypeReferenceDirectiveResolutionCache;
export function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations | undefined;
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
Expand Down

0 comments on commit 116b9b3

Please sign in to comment.