mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 12:32:08 -06:00
Use non relative name cache for type reference resolutions and API updates (#51732)
* Make the non relative name resolution cache generic * Add cache for non relative type reference resolution * Add getter only methods so we can use these in future for sharing resolutions across the projects * Mark existing non relative module name cache getOrCreate as deprecated * Prefer getters for getting directory results
This commit is contained in:
parent
703652cebf
commit
38f33ade06
@ -447,8 +447,11 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string
|
||||
}
|
||||
|
||||
const containingDirectory = containingFile ? getDirectoryPath(containingFile) : undefined;
|
||||
const perFolderCache = containingDirectory ? cache && cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference) : undefined;
|
||||
let result = perFolderCache && perFolderCache.get(typeReferenceDirectiveName, /*mode*/ resolutionMode);
|
||||
let result = containingDirectory ? cache?.getFromDirectoryCache(typeReferenceDirectiveName, resolutionMode, containingDirectory, redirectedReference) : undefined;
|
||||
if (!result && containingDirectory && !isExternalModuleNameRelative(typeReferenceDirectiveName)) {
|
||||
result = cache?.getFromNonRelativeNameCache(typeReferenceDirectiveName, resolutionMode, containingDirectory, redirectedReference);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_1, typeReferenceDirectiveName, containingFile);
|
||||
@ -459,6 +462,7 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
const typeRoots = getEffectiveTypeRoots(options, host);
|
||||
if (traceEnabled) {
|
||||
if (containingFile === undefined) {
|
||||
@ -537,7 +541,12 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string
|
||||
affectingLocations: initializeResolutionField(affectingLocations),
|
||||
resolutionDiagnostics: initializeResolutionField(diagnostics),
|
||||
};
|
||||
perFolderCache?.set(typeReferenceDirectiveName, /*mode*/ resolutionMode, result);
|
||||
if (containingDirectory) {
|
||||
cache?.getOrCreateCacheForDirectory(containingDirectory, redirectedReference).set(typeReferenceDirectiveName, /*mode*/ resolutionMode, result);
|
||||
if (!isExternalModuleNameRelative(typeReferenceDirectiveName)) {
|
||||
cache?.getOrCreateCacheForNonRelativeName(typeReferenceDirectiveName, resolutionMode, redirectedReference).set(containingDirectory, result);
|
||||
}
|
||||
}
|
||||
if (traceEnabled) traceResult(result);
|
||||
return result;
|
||||
|
||||
@ -678,7 +687,7 @@ export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: M
|
||||
return result;
|
||||
}
|
||||
|
||||
export interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, PackageJsonInfoCache {
|
||||
export interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, NonRelativeNameResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, PackageJsonInfoCache {
|
||||
/** @internal */ clearAllExceptPackageJsonInfoCache(): void;
|
||||
}
|
||||
|
||||
@ -696,6 +705,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> {
|
||||
getFromDirectoryCache(name: string, mode: ResolutionMode, directoryName: string, redirectedReference: ResolvedProjectReference | undefined): T | undefined;
|
||||
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): ModeAwareCache<T>;
|
||||
clear(): void;
|
||||
/**
|
||||
@ -705,6 +715,22 @@ export interface PerDirectoryResolutionCache<T> {
|
||||
update(options: CompilerOptions): void;
|
||||
}
|
||||
|
||||
export interface NonRelativeNameResolutionCache<T> {
|
||||
getFromNonRelativeNameCache(nonRelativeName: string, mode: ResolutionMode, directoryName: string, redirectedReference: ResolvedProjectReference | undefined): T | undefined;
|
||||
getOrCreateCacheForNonRelativeName(nonRelativeName: string, mode: ResolutionMode, redirectedReference?: ResolvedProjectReference): PerNonRelativeNameCache<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 PerNonRelativeNameCache<T> {
|
||||
get(directory: string): T | undefined;
|
||||
set(directory: string, result: T): void;
|
||||
}
|
||||
|
||||
export interface ModuleResolutionCache extends PerDirectoryResolutionCache<ResolvedModuleWithFailedLookupLocations>, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache {
|
||||
getPackageJsonInfoCache(): PackageJsonInfoCache;
|
||||
/** @internal */ clearAllExceptPackageJsonInfoCache(): void;
|
||||
@ -714,7 +740,8 @@ export interface ModuleResolutionCache extends PerDirectoryResolutionCache<Resol
|
||||
* 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.
|
||||
*/
|
||||
export interface NonRelativeModuleNameResolutionCache extends PackageJsonInfoCache {
|
||||
export interface NonRelativeModuleNameResolutionCache extends NonRelativeNameResolutionCache<ResolvedModuleWithFailedLookupLocations>, PackageJsonInfoCache {
|
||||
/** @deprecated Use getOrCreateCacheForNonRelativeName */
|
||||
getOrCreateCacheForModuleName(nonRelativeModuleName: string, mode: ResolutionMode, redirectedReference?: ResolvedProjectReference): PerModuleNameCache;
|
||||
}
|
||||
|
||||
@ -726,10 +753,7 @@ export interface PackageJsonInfoCache {
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
export interface PerModuleNameCache {
|
||||
get(directory: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void;
|
||||
}
|
||||
export type PerModuleNameCache = PerNonRelativeNameCache<ResolvedModuleWithFailedLookupLocations>;
|
||||
|
||||
function compilerOptionValueToString(value: unknown): string {
|
||||
if (value === null || typeof value !== "object") { // eslint-disable-line no-null/no-null
|
||||
@ -754,6 +778,7 @@ export function getKeyForCompilerOptions(options: CompilerOptions, affectingOpti
|
||||
|
||||
/** @internal */
|
||||
export interface CacheWithRedirects<K, V> {
|
||||
getMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<K, V> | undefined;
|
||||
getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<K, V>;
|
||||
update(newOptions: CompilerOptions): void;
|
||||
clear(): void;
|
||||
@ -768,26 +793,35 @@ export function createCacheWithRedirects<K, V>(ownOptions: CompilerOptions | und
|
||||
let ownMap = new Map<K, V>();
|
||||
if (ownOptions) redirectsMap.set(ownOptions, ownMap);
|
||||
return {
|
||||
getMapOfCacheRedirects,
|
||||
getOrCreateMapOfCacheRedirects,
|
||||
update,
|
||||
clear,
|
||||
};
|
||||
|
||||
function getMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<K, V> | undefined {
|
||||
return redirectedReference ?
|
||||
getOrCreateMap(redirectedReference.commandLine.options, /*create*/ false) :
|
||||
ownMap;
|
||||
}
|
||||
|
||||
function getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<K, V> {
|
||||
return redirectedReference ?
|
||||
getOrCreateMap(redirectedReference.commandLine.options) :
|
||||
getOrCreateMap(redirectedReference.commandLine.options, /*create*/ true) :
|
||||
ownMap;
|
||||
}
|
||||
|
||||
function update(newOptions: CompilerOptions) {
|
||||
if (ownOptions !== newOptions) {
|
||||
if (ownOptions) ownMap = getOrCreateMap(newOptions); // set new map for new options as ownMap
|
||||
if (ownOptions) ownMap = getOrCreateMap(newOptions, /*create*/ true); // set new map for new options as ownMap
|
||||
else redirectsMap.set(newOptions, ownMap); // Use existing map if oldOptions = undefined
|
||||
ownOptions = newOptions;
|
||||
}
|
||||
}
|
||||
|
||||
function getOrCreateMap(redirectOptions: CompilerOptions): Map<K, V> {
|
||||
function getOrCreateMap(redirectOptions: CompilerOptions, create: true): Map<K, V>;
|
||||
function getOrCreateMap(redirectOptions: CompilerOptions, create: false): Map<K, V> | undefined;
|
||||
function getOrCreateMap(redirectOptions: CompilerOptions, create: boolean): Map<K, V> | undefined {
|
||||
let result = redirectsMap.get(redirectOptions);
|
||||
if (result) return result;
|
||||
const key = getRedirectsCacheKey(redirectOptions);
|
||||
@ -798,9 +832,10 @@ export function createCacheWithRedirects<K, V>(ownOptions: CompilerOptions | und
|
||||
if (ownKey === key) result = ownMap;
|
||||
else if (!redirectsKeyToMap.has(ownKey)) redirectsKeyToMap.set(ownKey, ownMap);
|
||||
}
|
||||
redirectsKeyToMap.set(key, result ??= new Map());
|
||||
if (create) result ??= new Map();
|
||||
if (result) redirectsKeyToMap.set(key, result);
|
||||
}
|
||||
redirectsMap.set(redirectOptions, result);
|
||||
if (result) redirectsMap.set(redirectOptions, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -856,8 +891,10 @@ function getOrCreateCache<K, V>(cacheWithRedirects: CacheWithRedirects<K, V>, re
|
||||
return result;
|
||||
}
|
||||
|
||||
function createPerDirectoryResolutionCache<T>(currentDirectory: string, getCanonicalFileName: GetCanonicalFileName, directoryToModuleNameMap: CacheWithRedirects<Path, ModeAwareCache<T>>): PerDirectoryResolutionCache<T> {
|
||||
function createPerDirectoryResolutionCache<T>(currentDirectory: string, getCanonicalFileName: GetCanonicalFileName, options: CompilerOptions | undefined): PerDirectoryResolutionCache<T> {
|
||||
const directoryToModuleNameMap = createCacheWithRedirects<Path, ModeAwareCache<T>>(options);
|
||||
return {
|
||||
getFromDirectoryCache,
|
||||
getOrCreateCacheForDirectory,
|
||||
clear,
|
||||
update,
|
||||
@ -875,6 +912,11 @@ function createPerDirectoryResolutionCache<T>(currentDirectory: string, getCanon
|
||||
const path = toPath(directoryName, currentDirectory, getCanonicalFileName);
|
||||
return getOrCreateCache(directoryToModuleNameMap, redirectedReference, path, () => createModeAwareCache());
|
||||
}
|
||||
|
||||
function getFromDirectoryCache(name: string, mode: ResolutionMode, directoryName: string, redirectedReference: ResolvedProjectReference | undefined) {
|
||||
const path = toPath(directoryName, currentDirectory, getCanonicalFileName);
|
||||
return directoryToModuleNameMap.getMapOfCacheRedirects(redirectedReference)?.get(path)?.get(name, mode);
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@ -938,52 +980,53 @@ export function zipToModeAwareCache<K, V>(
|
||||
return map;
|
||||
}
|
||||
|
||||
export function createModuleResolutionCache(
|
||||
function getOriginalOrResolvedModuleFileName(result: ResolvedModuleWithFailedLookupLocations) {
|
||||
return result.resolvedModule && (result.resolvedModule.originalPath || result.resolvedModule.resolvedFileName);
|
||||
}
|
||||
|
||||
function getOriginalOrResolvedTypeReferenceFileName(result: ResolvedTypeReferenceDirectiveWithFailedLookupLocations) {
|
||||
return result.resolvedTypeReferenceDirective &&
|
||||
(result.resolvedTypeReferenceDirective.originalPath || result.resolvedTypeReferenceDirective.resolvedFileName);
|
||||
}
|
||||
|
||||
function createNonRelativeNameResolutionCache<T>(
|
||||
currentDirectory: string,
|
||||
getCanonicalFileName: (s: string) => string,
|
||||
options?: CompilerOptions
|
||||
): ModuleResolutionCache {
|
||||
const directoryToModuleNameMap = createCacheWithRedirects<Path, ModeAwareCache<ResolvedModuleWithFailedLookupLocations>>(options);
|
||||
const perDirectoryResolutionCache = createPerDirectoryResolutionCache(currentDirectory, getCanonicalFileName, directoryToModuleNameMap);
|
||||
const moduleNameToDirectoryMap = createCacheWithRedirects<ModeAwareCacheKey, PerModuleNameCache>(options);
|
||||
const packageJsonInfoCache = createPackageJsonInfoCache(currentDirectory, getCanonicalFileName);
|
||||
|
||||
options: CompilerOptions | undefined,
|
||||
getResolvedFileName: (result: T) => string | undefined,
|
||||
): NonRelativeNameResolutionCache<T> {
|
||||
const moduleNameToDirectoryMap = createCacheWithRedirects<ModeAwareCacheKey, PerNonRelativeNameCache<T>>(options);
|
||||
return {
|
||||
...packageJsonInfoCache,
|
||||
...perDirectoryResolutionCache,
|
||||
getOrCreateCacheForModuleName,
|
||||
getFromNonRelativeNameCache,
|
||||
getOrCreateCacheForNonRelativeName,
|
||||
clear,
|
||||
update,
|
||||
getPackageJsonInfoCache: () => packageJsonInfoCache,
|
||||
clearAllExceptPackageJsonInfoCache,
|
||||
};
|
||||
|
||||
function clear() {
|
||||
clearAllExceptPackageJsonInfoCache();
|
||||
packageJsonInfoCache.clear();
|
||||
}
|
||||
|
||||
function clearAllExceptPackageJsonInfoCache() {
|
||||
perDirectoryResolutionCache.clear();
|
||||
moduleNameToDirectoryMap.clear();
|
||||
}
|
||||
|
||||
function update(options: CompilerOptions) {
|
||||
directoryToModuleNameMap.update(options);
|
||||
moduleNameToDirectoryMap.update(options);
|
||||
}
|
||||
|
||||
function getOrCreateCacheForModuleName(nonRelativeModuleName: string, mode: ResolutionMode, redirectedReference?: ResolvedProjectReference): PerModuleNameCache {
|
||||
function getFromNonRelativeNameCache(nonRelativeModuleName: string, mode: ResolutionMode, directoryName: string, redirectedReference?: ResolvedProjectReference): T | undefined {
|
||||
Debug.assert(!isExternalModuleNameRelative(nonRelativeModuleName));
|
||||
return moduleNameToDirectoryMap.getMapOfCacheRedirects(redirectedReference)?.get(createModeAwareCacheKey(nonRelativeModuleName, mode))?.get(directoryName);
|
||||
}
|
||||
|
||||
function getOrCreateCacheForNonRelativeName(nonRelativeModuleName: string, mode: ResolutionMode, redirectedReference?: ResolvedProjectReference): PerNonRelativeNameCache<T> {
|
||||
Debug.assert(!isExternalModuleNameRelative(nonRelativeModuleName));
|
||||
return getOrCreateCache(moduleNameToDirectoryMap, redirectedReference, createModeAwareCacheKey(nonRelativeModuleName, mode), createPerModuleNameCache);
|
||||
}
|
||||
|
||||
function createPerModuleNameCache(): PerModuleNameCache {
|
||||
const directoryPathMap = new Map<Path, ResolvedModuleWithFailedLookupLocations>();
|
||||
function createPerModuleNameCache(): PerNonRelativeNameCache<T> {
|
||||
const directoryPathMap = new Map<Path, T>();
|
||||
|
||||
return { get, set };
|
||||
|
||||
function get(directory: string): ResolvedModuleWithFailedLookupLocations | undefined {
|
||||
function get(directory: string): T | undefined {
|
||||
return directoryPathMap.get(toPath(directory, currentDirectory, getCanonicalFileName));
|
||||
}
|
||||
|
||||
@ -998,7 +1041,7 @@ export function createModuleResolutionCache(
|
||||
* ]
|
||||
* this means that request for module resolution from file in any of these folder will be immediately found in cache.
|
||||
*/
|
||||
function set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void {
|
||||
function set(directory: string, result: T): void {
|
||||
const path = toPath(directory, currentDirectory, getCanonicalFileName);
|
||||
// if entry is already in cache do nothing
|
||||
if (directoryPathMap.has(path)) {
|
||||
@ -1006,8 +1049,7 @@ export function createModuleResolutionCache(
|
||||
}
|
||||
directoryPathMap.set(path, result);
|
||||
|
||||
const resolvedFileName = result.resolvedModule &&
|
||||
(result.resolvedModule.originalPath || result.resolvedModule.resolvedFileName);
|
||||
const resolvedFileName = getResolvedFileName(result);
|
||||
// find common prefix between directory and resolved file name
|
||||
// this common prefix should be the shortest path that has the same resolution
|
||||
// directory: /a/b/c/d/e
|
||||
@ -1051,20 +1093,33 @@ export function createModuleResolutionCache(
|
||||
}
|
||||
}
|
||||
|
||||
export function createTypeReferenceDirectiveResolutionCache(
|
||||
interface ModuleOrTypeReferenceResolutionCache<T> extends PerDirectoryResolutionCache<T>, NonRelativeNameResolutionCache<T>, PackageJsonInfoCache {
|
||||
getPackageJsonInfoCache(): PackageJsonInfoCache;
|
||||
clearAllExceptPackageJsonInfoCache(): void;
|
||||
}
|
||||
function createModuleOrTypeReferenceResolutionCache<T>(
|
||||
currentDirectory: string,
|
||||
getCanonicalFileName: (s: string) => string,
|
||||
options?: CompilerOptions,
|
||||
packageJsonInfoCache?: PackageJsonInfoCache,
|
||||
): TypeReferenceDirectiveResolutionCache {
|
||||
const directoryToModuleNameMap = createCacheWithRedirects<Path, ModeAwareCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>(options);
|
||||
const perDirectoryResolutionCache = createPerDirectoryResolutionCache(currentDirectory, getCanonicalFileName, directoryToModuleNameMap);
|
||||
packageJsonInfoCache ||= createPackageJsonInfoCache(currentDirectory, getCanonicalFileName);
|
||||
options: CompilerOptions | undefined,
|
||||
packageJsonInfoCache: PackageJsonInfoCache | undefined,
|
||||
getResolvedFileName: (result: T) => string | undefined,
|
||||
): ModuleOrTypeReferenceResolutionCache<T> {
|
||||
const perDirectoryResolutionCache = createPerDirectoryResolutionCache<T>(currentDirectory, getCanonicalFileName, options);
|
||||
const nonRelativeNameResolutionCache = createNonRelativeNameResolutionCache(
|
||||
currentDirectory,
|
||||
getCanonicalFileName,
|
||||
options,
|
||||
getResolvedFileName,
|
||||
);
|
||||
packageJsonInfoCache ??= createPackageJsonInfoCache(currentDirectory, getCanonicalFileName);
|
||||
|
||||
return {
|
||||
...packageJsonInfoCache,
|
||||
...perDirectoryResolutionCache,
|
||||
...nonRelativeNameResolutionCache,
|
||||
clear,
|
||||
update,
|
||||
getPackageJsonInfoCache: () => packageJsonInfoCache!,
|
||||
clearAllExceptPackageJsonInfoCache,
|
||||
};
|
||||
|
||||
@ -1075,14 +1130,49 @@ export function createTypeReferenceDirectiveResolutionCache(
|
||||
|
||||
function clearAllExceptPackageJsonInfoCache() {
|
||||
perDirectoryResolutionCache.clear();
|
||||
nonRelativeNameResolutionCache.clear();
|
||||
}
|
||||
|
||||
function update(options: CompilerOptions) {
|
||||
perDirectoryResolutionCache.update(options);
|
||||
nonRelativeNameResolutionCache.update(options);
|
||||
}
|
||||
}
|
||||
|
||||
export function createModuleResolutionCache(
|
||||
currentDirectory: string,
|
||||
getCanonicalFileName: (s: string) => string,
|
||||
options?: CompilerOptions
|
||||
): ModuleResolutionCache {
|
||||
const result = createModuleOrTypeReferenceResolutionCache(
|
||||
currentDirectory,
|
||||
getCanonicalFileName,
|
||||
options,
|
||||
/*packageJsonInfoCache*/ undefined,
|
||||
getOriginalOrResolvedModuleFileName,
|
||||
) as ModuleResolutionCache;
|
||||
result.getOrCreateCacheForModuleName = (nonRelativeName, mode, redirectedReference) => result.getOrCreateCacheForNonRelativeName(nonRelativeName, mode, redirectedReference);
|
||||
return result;
|
||||
}
|
||||
|
||||
export function createTypeReferenceDirectiveResolutionCache(
|
||||
currentDirectory: string,
|
||||
getCanonicalFileName: (s: string) => string,
|
||||
options?: CompilerOptions,
|
||||
packageJsonInfoCache?: PackageJsonInfoCache,
|
||||
): TypeReferenceDirectiveResolutionCache {
|
||||
return createModuleOrTypeReferenceResolutionCache(
|
||||
currentDirectory,
|
||||
getCanonicalFileName,
|
||||
options,
|
||||
packageJsonInfoCache,
|
||||
getOriginalOrResolvedTypeReferenceFileName
|
||||
);
|
||||
}
|
||||
|
||||
export function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache, mode?: ResolutionMode): ResolvedModuleWithFailedLookupLocations | undefined {
|
||||
const containingDirectory = getDirectoryPath(containingFile);
|
||||
const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);
|
||||
if (!perFolderCache) return undefined;
|
||||
return perFolderCache.get(moduleName, mode);
|
||||
return cache.getFromDirectoryCache(moduleName, mode, containingDirectory, /*redirectedReference*/ undefined);
|
||||
}
|
||||
|
||||
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, resolutionMode?: ResolutionMode): ResolvedModuleWithFailedLookupLocations {
|
||||
@ -1097,8 +1187,7 @@ export function resolveModuleName(moduleName: string, containingFile: string, co
|
||||
}
|
||||
}
|
||||
const containingDirectory = getDirectoryPath(containingFile);
|
||||
const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference);
|
||||
let result = perFolderCache && perFolderCache.get(moduleName, resolutionMode);
|
||||
let result = cache?.getFromDirectoryCache(moduleName, resolutionMode, containingDirectory, redirectedReference);
|
||||
|
||||
if (result) {
|
||||
if (traceEnabled) {
|
||||
@ -1152,12 +1241,10 @@ export function resolveModuleName(moduleName: string, containingFile: string, co
|
||||
if (result && result.resolvedModule) perfLogger.logInfoEvent(`Module "${moduleName}" resolved to "${result.resolvedModule.resolvedFileName}"`);
|
||||
perfLogger.logStopResolveModule((result && result.resolvedModule) ? "" + result.resolvedModule.resolvedFileName : "null");
|
||||
|
||||
if (perFolderCache) {
|
||||
perFolderCache.set(moduleName, resolutionMode, result);
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
// put result in per-module name cache
|
||||
cache.getOrCreateCacheForModuleName(moduleName, resolutionMode, redirectedReference).set(containingDirectory, result);
|
||||
}
|
||||
cache?.getOrCreateCacheForDirectory(containingDirectory, redirectedReference).set(moduleName, resolutionMode, result);
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
// put result in per-module name cache
|
||||
cache?.getOrCreateCacheForNonRelativeName(moduleName, resolutionMode, redirectedReference).set(containingDirectory, result);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2512,7 +2599,7 @@ function loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName: string,
|
||||
}
|
||||
|
||||
function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult<Resolved> {
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, state.features === 0 ? undefined : state.features & NodeResolutionFeatures.EsmMode ? ModuleKind.ESNext : ModuleKind.CommonJS, redirectedReference);
|
||||
const mode = state.features === 0 ? undefined : state.features & NodeResolutionFeatures.EsmMode ? ModuleKind.ESNext : ModuleKind.CommonJS;
|
||||
// Do (up to) two passes through node_modules:
|
||||
// 1. For each ancestor node_modules directory, try to find:
|
||||
// i. TS/DTS files in the implementation package
|
||||
@ -2534,7 +2621,7 @@ function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions,
|
||||
function lookup(extensions: Extensions) {
|
||||
return forEachAncestorDirectory(normalizeSlashes(directory), ancestorDirectory => {
|
||||
if (getBaseFileName(ancestorDirectory) !== "node_modules") {
|
||||
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state);
|
||||
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(cache, moduleName, mode, ancestorDirectory, redirectedReference, state);
|
||||
if (resolutionFromCache) {
|
||||
return resolutionFromCache;
|
||||
}
|
||||
@ -2719,8 +2806,8 @@ export function unmangleScopedPackageName(typesPackageName: string): string {
|
||||
typesPackageName;
|
||||
}
|
||||
|
||||
function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, state: ModuleResolutionState): SearchResult<Resolved> {
|
||||
const result = cache && cache.get(containingDirectory);
|
||||
function tryFindNonRelativeModuleNameInCache(cache: NonRelativeModuleNameResolutionCache | undefined, moduleName: string, mode: ResolutionMode, containingDirectory: string, redirectedReference: ResolvedProjectReference | undefined, state: ModuleResolutionState): SearchResult<Resolved> {
|
||||
const result = cache && cache.getFromNonRelativeNameCache(moduleName, mode, containingDirectory, redirectedReference);
|
||||
if (result) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
|
||||
@ -2769,10 +2856,9 @@ export function classicNameResolver(moduleName: string, containingFile: string,
|
||||
}
|
||||
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, /*mode*/ undefined, redirectedReference);
|
||||
// Climb up parent directories looking for a module.
|
||||
const resolved = forEachAncestorDirectory(containingDirectory, directory => {
|
||||
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, state);
|
||||
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(cache, moduleName, /*mode*/ undefined, directory, redirectedReference, state);
|
||||
if (resolutionFromCache) {
|
||||
return resolutionFromCache;
|
||||
}
|
||||
|
||||
@ -1855,7 +1855,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
// This may totally change if/when the issue of output paths not mapping to input files is fixed in a broader context
|
||||
// When it is, how we extract diagnostics from the module name resolver will have the be refined - the current cache
|
||||
// APIs wrapping the underlying resolver make it almost impossible to smuggle the diagnostics out in a generalized way
|
||||
const fromCache = moduleResolutionCache.getOrCreateCacheForModuleName(name, mode, redirectedReference).get(containingDir);
|
||||
const fromCache = moduleResolutionCache.getFromNonRelativeNameCache(name, mode, containingDir, redirectedReference);
|
||||
if (fromCache) addResolutionDiagnostics(fromCache);
|
||||
}
|
||||
|
||||
|
||||
@ -162,7 +162,7 @@ describe("unittests:: moduleResolution:: Node module resolution - relative paths
|
||||
describe("unittests:: moduleResolution:: Node module resolution - non-relative paths", () => {
|
||||
it("computes correct commonPrefix for moduleName cache", () => {
|
||||
const resolutionCache = ts.createModuleResolutionCache("/", (f) => f);
|
||||
let cache = resolutionCache.getOrCreateCacheForModuleName("a", /*mode*/ undefined);
|
||||
let cache = resolutionCache.getOrCreateCacheForNonRelativeName("a", /*mode*/ undefined);
|
||||
cache.set("/sub", {
|
||||
resolvedModule: {
|
||||
originalPath: undefined,
|
||||
@ -177,7 +177,7 @@ describe("unittests:: moduleResolution:: Node module resolution - non-relative p
|
||||
assert.isDefined(cache.get("/sub"));
|
||||
assert.isUndefined(cache.get("/"));
|
||||
|
||||
cache = resolutionCache.getOrCreateCacheForModuleName("b", /*mode*/ undefined);
|
||||
cache = resolutionCache.getOrCreateCacheForNonRelativeName("b", /*mode*/ undefined);
|
||||
cache.set("/sub/dir/foo", {
|
||||
resolvedModule: {
|
||||
originalPath: undefined,
|
||||
@ -194,7 +194,7 @@ describe("unittests:: moduleResolution:: Node module resolution - non-relative p
|
||||
assert.isDefined(cache.get("/sub"));
|
||||
assert.isUndefined(cache.get("/"));
|
||||
|
||||
cache = resolutionCache.getOrCreateCacheForModuleName("c", /*mode*/ undefined);
|
||||
cache = resolutionCache.getOrCreateCacheForNonRelativeName("c", /*mode*/ undefined);
|
||||
cache.set("/foo/bar", {
|
||||
resolvedModule: {
|
||||
originalPath: undefined,
|
||||
@ -210,7 +210,7 @@ describe("unittests:: moduleResolution:: Node module resolution - non-relative p
|
||||
assert.isDefined(cache.get("/foo"));
|
||||
assert.isDefined(cache.get("/"));
|
||||
|
||||
cache = resolutionCache.getOrCreateCacheForModuleName("d", /*mode*/ undefined);
|
||||
cache = resolutionCache.getOrCreateCacheForNonRelativeName("d", /*mode*/ undefined);
|
||||
cache.set("/foo", {
|
||||
resolvedModule: {
|
||||
originalPath: undefined,
|
||||
@ -225,7 +225,7 @@ describe("unittests:: moduleResolution:: Node module resolution - non-relative p
|
||||
assert.isDefined(cache.get("/foo"));
|
||||
assert.isUndefined(cache.get("/"));
|
||||
|
||||
cache = resolutionCache.getOrCreateCacheForModuleName("e", /*mode*/ undefined);
|
||||
cache = resolutionCache.getOrCreateCacheForNonRelativeName("e", /*mode*/ undefined);
|
||||
cache.set("c:/foo", {
|
||||
resolvedModule: {
|
||||
originalPath: undefined,
|
||||
@ -241,7 +241,7 @@ describe("unittests:: moduleResolution:: Node module resolution - non-relative p
|
||||
assert.isDefined(cache.get("c:/"));
|
||||
assert.isUndefined(cache.get("d:/"));
|
||||
|
||||
cache = resolutionCache.getOrCreateCacheForModuleName("f", /*mode*/ undefined);
|
||||
cache = resolutionCache.getOrCreateCacheForNonRelativeName("f", /*mode*/ undefined);
|
||||
cache.set("/foo/bar/baz", {
|
||||
resolvedModule: undefined,
|
||||
failedLookupLocations: [],
|
||||
|
||||
@ -42,7 +42,7 @@ describe("unittests:: tsserver:: getEditsForFileRename", () => {
|
||||
readFile: path => host.readFile(path),
|
||||
fileExists: path => host.fileExists(path),
|
||||
resolveModuleNames: (moduleNames, containingFile) => moduleNames.map(name => ts.resolveModuleName(name, containingFile, options, lsHost, moduleResolutionCache).resolvedModule),
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache: (moduleName, containingFile, mode) => moduleResolutionCache.getOrCreateCacheForDirectory(ts.getDirectoryPath(containingFile)).get(moduleName, mode),
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache: (moduleName, containingFile, mode) => moduleResolutionCache.getFromDirectoryCache(moduleName, mode, ts.getDirectoryPath(containingFile), /*redirectedReference*/ undefined),
|
||||
};
|
||||
const service = ts.createLanguageService(lsHost);
|
||||
const edits = service.getEditsForFileRename("/old.ts", "/new.ts", ts.testFormatSettings, ts.emptyOptions);
|
||||
|
||||
@ -9187,7 +9187,7 @@ declare namespace ts {
|
||||
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, resolutionMode?: ResolutionMode): ResolvedModuleWithFailedLookupLocations;
|
||||
function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
|
||||
function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
|
||||
interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, PackageJsonInfoCache {
|
||||
interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, NonRelativeNameResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, PackageJsonInfoCache {
|
||||
}
|
||||
interface ModeAwareCache<T> {
|
||||
get(key: string, mode: ResolutionMode): T | undefined;
|
||||
@ -9202,6 +9202,7 @@ declare namespace ts {
|
||||
* This assumes that any module id will have the same resolution for sibling files located in the same folder.
|
||||
*/
|
||||
interface PerDirectoryResolutionCache<T> {
|
||||
getFromDirectoryCache(name: string, mode: ResolutionMode, directoryName: string, redirectedReference: ResolvedProjectReference | undefined): T | undefined;
|
||||
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): ModeAwareCache<T>;
|
||||
clear(): void;
|
||||
/**
|
||||
@ -9210,6 +9211,20 @@ declare namespace ts {
|
||||
*/
|
||||
update(options: CompilerOptions): void;
|
||||
}
|
||||
interface NonRelativeNameResolutionCache<T> {
|
||||
getFromNonRelativeNameCache(nonRelativeName: string, mode: ResolutionMode, directoryName: string, redirectedReference: ResolvedProjectReference | undefined): T | undefined;
|
||||
getOrCreateCacheForNonRelativeName(nonRelativeName: string, mode: ResolutionMode, redirectedReference?: ResolvedProjectReference): PerNonRelativeNameCache<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;
|
||||
}
|
||||
interface PerNonRelativeNameCache<T> {
|
||||
get(directory: string): T | undefined;
|
||||
set(directory: string, result: T): void;
|
||||
}
|
||||
interface ModuleResolutionCache extends PerDirectoryResolutionCache<ResolvedModuleWithFailedLookupLocations>, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache {
|
||||
getPackageJsonInfoCache(): PackageJsonInfoCache;
|
||||
}
|
||||
@ -9217,16 +9232,14 @@ declare namespace ts {
|
||||
* 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.
|
||||
*/
|
||||
interface NonRelativeModuleNameResolutionCache extends PackageJsonInfoCache {
|
||||
interface NonRelativeModuleNameResolutionCache extends NonRelativeNameResolutionCache<ResolvedModuleWithFailedLookupLocations>, PackageJsonInfoCache {
|
||||
/** @deprecated Use getOrCreateCacheForNonRelativeName */
|
||||
getOrCreateCacheForModuleName(nonRelativeModuleName: string, mode: ResolutionMode, redirectedReference?: ResolvedProjectReference): PerModuleNameCache;
|
||||
}
|
||||
interface PackageJsonInfoCache {
|
||||
clear(): void;
|
||||
}
|
||||
interface PerModuleNameCache {
|
||||
get(directory: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void;
|
||||
}
|
||||
type PerModuleNameCache = PerNonRelativeNameCache<ResolvedModuleWithFailedLookupLocations>;
|
||||
/**
|
||||
* Visits a Node using the supplied visitor, possibly returning a new Node in its place.
|
||||
*
|
||||
|
||||
25
tests/baselines/reference/api/typescript.d.ts
vendored
25
tests/baselines/reference/api/typescript.d.ts
vendored
@ -5254,7 +5254,7 @@ declare namespace ts {
|
||||
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, resolutionMode?: ResolutionMode): ResolvedModuleWithFailedLookupLocations;
|
||||
function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
|
||||
function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
|
||||
interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, PackageJsonInfoCache {
|
||||
interface TypeReferenceDirectiveResolutionCache extends PerDirectoryResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, NonRelativeNameResolutionCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>, PackageJsonInfoCache {
|
||||
}
|
||||
interface ModeAwareCache<T> {
|
||||
get(key: string, mode: ResolutionMode): T | undefined;
|
||||
@ -5269,6 +5269,7 @@ declare namespace ts {
|
||||
* This assumes that any module id will have the same resolution for sibling files located in the same folder.
|
||||
*/
|
||||
interface PerDirectoryResolutionCache<T> {
|
||||
getFromDirectoryCache(name: string, mode: ResolutionMode, directoryName: string, redirectedReference: ResolvedProjectReference | undefined): T | undefined;
|
||||
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): ModeAwareCache<T>;
|
||||
clear(): void;
|
||||
/**
|
||||
@ -5277,6 +5278,20 @@ declare namespace ts {
|
||||
*/
|
||||
update(options: CompilerOptions): void;
|
||||
}
|
||||
interface NonRelativeNameResolutionCache<T> {
|
||||
getFromNonRelativeNameCache(nonRelativeName: string, mode: ResolutionMode, directoryName: string, redirectedReference: ResolvedProjectReference | undefined): T | undefined;
|
||||
getOrCreateCacheForNonRelativeName(nonRelativeName: string, mode: ResolutionMode, redirectedReference?: ResolvedProjectReference): PerNonRelativeNameCache<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;
|
||||
}
|
||||
interface PerNonRelativeNameCache<T> {
|
||||
get(directory: string): T | undefined;
|
||||
set(directory: string, result: T): void;
|
||||
}
|
||||
interface ModuleResolutionCache extends PerDirectoryResolutionCache<ResolvedModuleWithFailedLookupLocations>, NonRelativeModuleNameResolutionCache, PackageJsonInfoCache {
|
||||
getPackageJsonInfoCache(): PackageJsonInfoCache;
|
||||
}
|
||||
@ -5284,16 +5299,14 @@ declare namespace ts {
|
||||
* 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.
|
||||
*/
|
||||
interface NonRelativeModuleNameResolutionCache extends PackageJsonInfoCache {
|
||||
interface NonRelativeModuleNameResolutionCache extends NonRelativeNameResolutionCache<ResolvedModuleWithFailedLookupLocations>, PackageJsonInfoCache {
|
||||
/** @deprecated Use getOrCreateCacheForNonRelativeName */
|
||||
getOrCreateCacheForModuleName(nonRelativeModuleName: string, mode: ResolutionMode, redirectedReference?: ResolvedProjectReference): PerModuleNameCache;
|
||||
}
|
||||
interface PackageJsonInfoCache {
|
||||
clear(): void;
|
||||
}
|
||||
interface PerModuleNameCache {
|
||||
get(directory: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void;
|
||||
}
|
||||
type PerModuleNameCache = PerNonRelativeNameCache<ResolvedModuleWithFailedLookupLocations>;
|
||||
/**
|
||||
* Visits a Node using the supplied visitor, possibly returning a new Node in its place.
|
||||
*
|
||||
|
||||
@ -5,10 +5,7 @@
|
||||
"File '/node_modules/@types/alpha/index.d.ts' exist - use it as a name resolution result.",
|
||||
"Resolving real path for '/node_modules/@types/alpha/index.d.ts', result '/node_modules/@types/alpha/index.d.ts'.",
|
||||
"======== Type reference directive 'alpha' was successfully resolved to '/node_modules/@types/alpha/index.d.ts', primary: true. ========",
|
||||
"======== Resolving type reference directive 'alpha', containing file '/__inferred type names__.ts', root directory '/node_modules/@types'. ========",
|
||||
"Resolving with primary search path '/node_modules/@types'.",
|
||||
"File '/node_modules/@types/alpha/package.json' does not exist according to earlier cached lookups.",
|
||||
"File '/node_modules/@types/alpha/index.d.ts' exist - use it as a name resolution result.",
|
||||
"Resolving real path for '/node_modules/@types/alpha/index.d.ts', result '/node_modules/@types/alpha/index.d.ts'.",
|
||||
"======== Resolving type reference directive 'alpha', containing file '/__inferred type names__.ts'. ========",
|
||||
"Resolution for type reference directive 'alpha' was found in cache from location '/'.",
|
||||
"======== Type reference directive 'alpha' was successfully resolved to '/node_modules/@types/alpha/index.d.ts', primary: true. ========"
|
||||
]
|
||||
Loading…
x
Reference in New Issue
Block a user