From 116b9b33ccac72aac65f25cbd9615ea42644b007 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 19 Apr 2021 15:24:49 -0700 Subject: [PATCH] Use per directory cache for type reference directive resolution as well --- src/compiler/diagnosticMessages.json | 24 +- src/compiler/moduleNameResolver.ts | 236 ++++++++++++------ src/compiler/program.ts | 8 +- src/compiler/resolutionCache.ts | 18 +- src/compiler/tsbuildPublic.ts | 12 +- .../reference/api/tsserverlibrary.d.ts | 15 +- tests/baselines/reference/api/typescript.d.ts | 15 +- 7 files changed, 222 insertions(+), 106 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index a25a5510f9e2e..5fa04cff3bcf9 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -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", @@ -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", diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 8e6838b793b86..f59b265652ad7 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -284,13 +284,24 @@ 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 { const traceEnabled = isTraceEnabled(options, host); if (redirectedReference) { options = redirectedReference.commandLine.options; } - const failedLookupLocations: string[] = []; - const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled, failedLookupLocations, packageJsonInfoCache }; + + const containingDirectory = containingFile ? getDirectoryPath(containingFile) : undefined; + const perFolderCache = containingDirectory ? cache && cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference) : undefined; + let result = perFolderCache && perFolderCache.get(typeReferenceDirectiveName); + if (result) { + if (traceEnabled) { + trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_1, typeReferenceDirectiveName, containingFile); + if (redirectedReference) trace(host, Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName); + trace(host, Diagnostics.Resolution_for_type_reference_directive_0_was_found_in_cache_from_location_1, typeReferenceDirectiveName, containingDirectory); + traceResult(result); + } + return result; + } const typeRoots = getEffectiveTypeRoots(options, host); if (traceEnabled) { @@ -315,6 +326,8 @@ namespace ts { } } + const failedLookupLocations: string[] = []; + const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled, failedLookupLocations, packageJsonInfoCache: cache }; let resolved = primaryLookup(); let primary = true; if (!resolved) { @@ -326,18 +339,24 @@ namespace ts { if (resolved) { const { fileName, packageId } = resolved; const resolvedFileName = options.preserveSymlinks ? fileName : realPath(fileName, host, traceEnabled); - if (traceEnabled) { - if (packageId) { - trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3, typeReferenceDirectiveName, resolvedFileName, packageIdToString(packageId), primary); - } - else { - trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFileName, primary); - } - } resolvedTypeReferenceDirective = { primary, resolvedFileName, packageId, isExternalLibraryImport: pathContainsNodeModules(fileName) }; } + result = { resolvedTypeReferenceDirective, failedLookupLocations }; + perFolderCache?.set(typeReferenceDirectiveName, result); + if (traceEnabled) traceResult(result); + return result; - return { resolvedTypeReferenceDirective, failedLookupLocations }; + function traceResult(result: ResolvedTypeReferenceDirectiveWithFailedLookupLocations) { + if (!result.resolvedTypeReferenceDirective?.resolvedFileName) { + trace(host, Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName); + } + else if (result.resolvedTypeReferenceDirective.packageId) { + trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3, typeReferenceDirectiveName, result.resolvedTypeReferenceDirective.resolvedFileName, packageIdToString(result.resolvedTypeReferenceDirective.packageId), result.resolvedTypeReferenceDirective.primary); + } + else { + trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, result.resolvedTypeReferenceDirective.resolvedFileName, result.resolvedTypeReferenceDirective.primary); + } + } function primaryLookup(): PathAndPackageId | undefined { // Check primary library paths @@ -381,11 +400,7 @@ namespace ts { const { path: candidate } = normalizePathAndParts(combinePaths(initialLocationForSecondaryLookup, typeReferenceDirectiveName)); result = nodeLoadModuleByRelativeName(Extensions.DtsOnly, candidate, /*onlyRecordFailures*/ false, moduleResolutionState, /*considerPackageJson*/ true); } - const resolvedFile = resolvedTypeScriptOnly(result); - if (!resolvedFile && traceEnabled) { - trace(host, Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName); - } - return resolvedFile; + return resolvedTypeScriptOnly(result); } else { if (traceEnabled) { @@ -440,12 +455,15 @@ namespace ts { return result; } + export interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache, 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; + export interface PerDirectoryResolutionCache { + getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map; clear(): void; /** * Updates with the current compilerOptions the cache will operate with. @@ -454,6 +472,10 @@ namespace ts { update(options: CompilerOptions): void; } + export interface ModuleResolutionCache extends PerDirectoryResolutionCache, 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. @@ -473,16 +495,6 @@ namespace ts { set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void; } - export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string, options?: CompilerOptions): ModuleResolutionCache { - return createModuleResolutionCacheWithMaps( - createCacheWithRedirects(options), - createCacheWithRedirects(options), - currentDirectory, - getCanonicalFileName - ); - } - - /*@internal*/ export interface CacheWithRedirects { ownMap: ESMap; @@ -534,7 +546,7 @@ namespace ts { } } - export function createPackageJsonInfoCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): PackageJsonInfoCache { + function createPackageJsonInfoCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): PackageJsonInfoCache { let cache: ESMap | undefined; return { getPackageJsonInfo, setPackageJsonInfo, clear }; function getPackageJsonInfo(packageJsonPath: string) { @@ -548,69 +560,111 @@ namespace ts { } } + function getOrCreateCache(cacheWithRedirects: CacheWithRedirects, redirectedReference: ResolvedProjectReference | undefined, key: string, create: () => T): T { + const cache = cacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference); + let result = cache.get(key); + if (!result) { + result = create(); + cache.set(key, result); + } + return result; + } + + function updateRedirectsMap( + options: CompilerOptions, + directoryToModuleNameMap: CacheWithRedirects>, + moduleNameToDirectoryMap?: CacheWithRedirects + ) { + if (!options.configFile) return; + if (directoryToModuleNameMap.redirectsMap.size === 0) { + // The own map will be for projectCompilerOptions + Debug.assert(!moduleNameToDirectoryMap || moduleNameToDirectoryMap.redirectsMap.size === 0); + Debug.assert(directoryToModuleNameMap.ownMap.size === 0); + Debug.assert(!moduleNameToDirectoryMap || moduleNameToDirectoryMap.ownMap.size === 0); + directoryToModuleNameMap.redirectsMap.set(options.configFile.path, directoryToModuleNameMap.ownMap); + moduleNameToDirectoryMap?.redirectsMap.set(options.configFile.path, moduleNameToDirectoryMap.ownMap); + } + else { + // Set correct own map + Debug.assert(!moduleNameToDirectoryMap || moduleNameToDirectoryMap.redirectsMap.size > 0); + const ref: ResolvedProjectReference = { + sourceFile: options.configFile, + commandLine: { options } as ParsedCommandLine + }; + directoryToModuleNameMap.setOwnMap(directoryToModuleNameMap.getOrCreateMapOfCacheRedirects(ref)); + moduleNameToDirectoryMap?.setOwnMap(moduleNameToDirectoryMap.getOrCreateMapOfCacheRedirects(ref)); + } + directoryToModuleNameMap.setOwnOptions(options); + moduleNameToDirectoryMap?.setOwnOptions(options); + } + + function createPerDirectoryResolutionCache(currentDirectory: string, getCanonicalFileName: GetCanonicalFileName, directoryToModuleNameMap: CacheWithRedirects>): PerDirectoryResolutionCache { + return { + getOrCreateCacheForDirectory, + clear, + update, + }; + + function clear() { + directoryToModuleNameMap.clear(); + } + + function update(options: CompilerOptions) { + updateRedirectsMap(options, directoryToModuleNameMap); + } + + function getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference) { + const path = toPath(directoryName, currentDirectory, getCanonicalFileName); + return getOrCreateCache>(directoryToModuleNameMap, redirectedReference, path, () => new Map()); + } + } + + export function createModuleResolutionCache( + currentDirectory: string, + getCanonicalFileName: (s: string) => string, + options?: CompilerOptions + ): ModuleResolutionCache; /*@internal*/ - export function createModuleResolutionCacheWithMaps( + export function createModuleResolutionCache( + currentDirectory: string, + getCanonicalFileName: GetCanonicalFileName, + options: undefined, directoryToModuleNameMap: CacheWithRedirects>, moduleNameToDirectoryMap: CacheWithRedirects, + ): ModuleResolutionCache; + export function createModuleResolutionCache( currentDirectory: string, - getCanonicalFileName: GetCanonicalFileName): ModuleResolutionCache { + getCanonicalFileName: GetCanonicalFileName, + options?: CompilerOptions, + directoryToModuleNameMap?: CacheWithRedirects>, + moduleNameToDirectoryMap?: CacheWithRedirects, + ): ModuleResolutionCache { + const preDirectoryResolutionCache = createPerDirectoryResolutionCache(currentDirectory, getCanonicalFileName, directoryToModuleNameMap ||= createCacheWithRedirects(options)); + moduleNameToDirectoryMap ||= createCacheWithRedirects(options); const packageJsonInfoCache = createPackageJsonInfoCache(currentDirectory, getCanonicalFileName); + return { ...packageJsonInfoCache, - getOrCreateCacheForDirectory, + ...preDirectoryResolutionCache, getOrCreateCacheForModuleName, clear, update, + getPackageJsonInfoCache: () => packageJsonInfoCache, }; function clear() { - directoryToModuleNameMap.clear(); - moduleNameToDirectoryMap.clear(); + preDirectoryResolutionCache.clear(); + moduleNameToDirectoryMap!.clear(); packageJsonInfoCache.clear(); } function update(options: CompilerOptions) { - if (!options.configFile) return; - if (directoryToModuleNameMap.redirectsMap.size === 0) { - // The own map will be for projectCompilerOptions - Debug.assert(moduleNameToDirectoryMap.redirectsMap.size === 0); - Debug.assert(directoryToModuleNameMap.ownMap.size === 0); - Debug.assert(moduleNameToDirectoryMap.ownMap.size === 0); - directoryToModuleNameMap.redirectsMap.set(options.configFile.path, directoryToModuleNameMap.ownMap); - moduleNameToDirectoryMap.redirectsMap.set(options.configFile.path, moduleNameToDirectoryMap.ownMap); - } - else { - // Set correct own map - Debug.assert(moduleNameToDirectoryMap.redirectsMap.size > 0); - const ref: ResolvedProjectReference = { - sourceFile: options.configFile, - commandLine: { options } as ParsedCommandLine - }; - directoryToModuleNameMap.setOwnMap(directoryToModuleNameMap.getOrCreateMapOfCacheRedirects(ref)); - moduleNameToDirectoryMap.setOwnMap(moduleNameToDirectoryMap.getOrCreateMapOfCacheRedirects(ref)); - } - directoryToModuleNameMap.setOwnOptions(options); - moduleNameToDirectoryMap.setOwnOptions(options); - } - - function getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference) { - const path = toPath(directoryName, currentDirectory, getCanonicalFileName); - return getOrCreateCache>(directoryToModuleNameMap, redirectedReference, path, () => new Map()); + updateRedirectsMap(options, directoryToModuleNameMap!, moduleNameToDirectoryMap); } function getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache { Debug.assert(!isExternalModuleNameRelative(nonRelativeModuleName)); - return getOrCreateCache(moduleNameToDirectoryMap, redirectedReference, nonRelativeModuleName, createPerModuleNameCache); - } - - function getOrCreateCache(cacheWithRedirects: CacheWithRedirects, redirectedReference: ResolvedProjectReference | undefined, key: string, create: () => T): T { - const cache = cacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference); - let result = cache.get(key); - if (!result) { - result = create(); - cache.set(key, result); - } - return result; + return getOrCreateCache(moduleNameToDirectoryMap!, redirectedReference, nonRelativeModuleName, createPerModuleNameCache); } function createPerModuleNameCache(): PerModuleNameCache { @@ -686,6 +740,42 @@ namespace ts { } } + export function createTypeReferenceDirectiveResolutionCache( + currentDirectory: string, + getCanonicalFileName: (s: string) => string, + options?: CompilerOptions, + packageJsonInfoCache?: PackageJsonInfoCache, + ): TypeReferenceDirectiveResolutionCache; + /*@internal*/ + export function createTypeReferenceDirectiveResolutionCache( + currentDirectory: string, + getCanonicalFileName: GetCanonicalFileName, + options: undefined, + packageJsonInfoCache: PackageJsonInfoCache | undefined, + directoryToModuleNameMap: CacheWithRedirects>, + ): TypeReferenceDirectiveResolutionCache; + export function createTypeReferenceDirectiveResolutionCache( + currentDirectory: string, + getCanonicalFileName: GetCanonicalFileName, + options?: CompilerOptions, + packageJsonInfoCache?: PackageJsonInfoCache | undefined, + directoryToModuleNameMap?: CacheWithRedirects>, + ): TypeReferenceDirectiveResolutionCache { + const preDirectoryResolutionCache = createPerDirectoryResolutionCache(currentDirectory, getCanonicalFileName, directoryToModuleNameMap ||= createCacheWithRedirects(options)); + packageJsonInfoCache ||= createPackageJsonInfoCache(currentDirectory, getCanonicalFileName); + + return { + ...packageJsonInfoCache, + ...preDirectoryResolutionCache, + clear, + }; + + function clear() { + preDirectoryResolutionCache.clear(); + packageJsonInfoCache!.clear(); + } + } + export function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations | undefined { const containingDirectory = getDirectoryPath(containingFile); const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 6f3fb4eeb1092..869202fe2ed5c 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -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) { @@ -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(Debug.checkEachDefined(typeReferenceDirectiveNames), containingFile, redirectedReference, loader); } @@ -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; diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index 28ebf28e52739..cb7de929e70f9 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -166,15 +166,23 @@ namespace ts { const resolvedModuleNames = new Map>(); const perDirectoryResolvedModuleNames: CacheWithRedirects> = createCacheWithRedirects(); const nonRelativeModuleNameCache: CacheWithRedirects = createCacheWithRedirects(); - const moduleResolutionCache = createModuleResolutionCacheWithMaps( + const moduleResolutionCache = createModuleResolutionCache( + getCurrentDirectory(), + resolutionHost.getCanonicalFileName, + /*options*/ undefined, perDirectoryResolvedModuleNames, nonRelativeModuleNameCache, - getCurrentDirectory(), - resolutionHost.getCanonicalFileName ); const resolvedTypeReferenceDirectives = new Map>(); const perDirectoryResolvedTypeReferenceDirectives: CacheWithRedirects> = createCacheWithRedirects(); + const typeReferenceDirectiveResolutionCache = createTypeReferenceDirectiveResolutionCache( + getCurrentDirectory(), + resolutionHost.getCanonicalFileName, + /*options*/ undefined, + moduleResolutionCache.getPackageJsonInfoCache(), + perDirectoryResolvedTypeReferenceDirectives + ); /** * These are the extensions that failed lookup files will have by default, @@ -285,7 +293,7 @@ namespace ts { function clearPerDirectoryResolutions() { moduleResolutionCache.clear(); - perDirectoryResolvedTypeReferenceDirectives.clear(); + typeReferenceDirectiveResolutionCache.clear(); nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions); nonRelativeExternalModuleResolutions.clear(); } @@ -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 { diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 65a889cc277f8..1e9c5ec23a6a9 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -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; @@ -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(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(Debug.checkEachDefined(typeReferenceDirectiveNames), containingFile, redirectedReference, loader); } @@ -317,7 +317,7 @@ namespace ts { compilerHost, moduleResolutionCache, - packageJsonInfoCache, + typeReferenceDirectiveResolutionCache, // Mutable state buildOrder: undefined, @@ -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; @@ -567,7 +567,7 @@ namespace ts { state.readFileWithCache = cache.originalReadFileWithCache; extendedConfigCache.clear(); moduleResolutionCache?.clear(); - packageJsonInfoCache?.clear(); + typeReferenceDirectiveResolutionCache?.clear(); state.cache = undefined; } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index f5edd8edc5330..9fe75059b2590 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -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. @@ -4723,12 +4723,14 @@ 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, 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; + export interface PerDirectoryResolutionCache { + getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map; clear(): void; /** * Updates with the current compilerOptions the cache will operate with. @@ -4736,6 +4738,9 @@ declare namespace ts { */ update(options: CompilerOptions): void; } + export interface ModuleResolutionCache extends PerDirectoryResolutionCache, 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. @@ -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; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index f409cccf55149..44f89d9061b35 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -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. @@ -4723,12 +4723,14 @@ 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, 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; + export interface PerDirectoryResolutionCache { + getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map; clear(): void; /** * Updates with the current compilerOptions the cache will operate with. @@ -4736,6 +4738,9 @@ declare namespace ts { */ update(options: CompilerOptions): void; } + export interface ModuleResolutionCache extends PerDirectoryResolutionCache, 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. @@ -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;