Api cleanup for Module and Type Reference directive resolution (#51546)

* Refactoring so CacheWithRedirects has Key and Value type parameters

* ModuleResolutionCache or TypeRefDirectiveCache will look in directory before solving, so ResolutionCache doesnt need this check

* Test showing module resolution is not shared because resolution cache doesnt update own options

* Enable traceResolution on some of the project reference tests

* Simplify CacheWithRedirects and ensure the options are set in all common scenarios so cache can be shared between redirects

* Make failedlookup etc optional in ResolvedModule/TypeRefefWithFailedLookupLocations
Also make accidental public failed lookup internal

* Add new API for module and type ref resolution

* Store auto type reference resolutions

* Modify test to show how using program partially doesnt report resolution diagnostics

* Ensure that resolution diagnostics are reported in filePreocessingDiagnostics so they can be reused when program is reused

* Some cleanup

* Remove the newly added ReoslutionInfo in favor of new APIs

* update
This commit is contained in:
Sheetal Nandi
2022-12-05 11:56:33 -08:00
committed by GitHub
parent c07f51242c
commit 9e845d2248
73 changed files with 2770 additions and 1438 deletions

View File

@@ -27,7 +27,6 @@ import {
extensionIsTS,
fileExtensionIs,
fileExtensionIsOneOf,
FileReference,
filter,
firstDefined,
forEach,
@@ -41,7 +40,6 @@ import {
GetEffectiveTypeRootsHost,
getEmitModuleKind,
getEmitModuleResolutionKind,
getModeForUsageLocation,
getNormalizedAbsolutePath,
getOwnKeys,
getPathComponents,
@@ -58,7 +56,6 @@ import {
isExternalModuleNameRelative,
isRootedDiskPath,
isString,
isStringLiteralLike,
lastOrUndefined,
length,
MapLike,
@@ -86,6 +83,7 @@ import {
removeFileExtension,
removePrefix,
ResolutionMode,
ResolutionNameAndModeGetter,
ResolvedModuleWithFailedLookupLocations,
ResolvedProjectReference,
ResolvedTypeReferenceDirective,
@@ -95,10 +93,8 @@ import {
SourceFile,
startsWith,
stringContains,
StringLiteralLike,
supportedDeclarationExtensions,
supportedTSImplementationExtensions,
toFileNameLowerCase,
toPath,
tryExtractTSExtension,
tryGetExtensionFromPath,
@@ -213,17 +209,28 @@ function createResolvedModuleWithFailedLookupLocations(
resultFromCache: ResolvedModuleWithFailedLookupLocations | undefined
): ResolvedModuleWithFailedLookupLocations {
if (resultFromCache) {
resultFromCache.failedLookupLocations.push(...failedLookupLocations);
resultFromCache.affectingLocations.push(...affectingLocations);
resultFromCache.failedLookupLocations = updateResolutionField(resultFromCache.failedLookupLocations, failedLookupLocations);
resultFromCache.affectingLocations = updateResolutionField(resultFromCache.affectingLocations, affectingLocations);
resultFromCache.resolutionDiagnostics = updateResolutionField(resultFromCache.resolutionDiagnostics, diagnostics);
return resultFromCache;
}
return {
resolvedModule: resolved && { resolvedFileName: resolved.path, originalPath: resolved.originalPath === true ? undefined : resolved.originalPath, extension: resolved.extension, isExternalLibraryImport, packageId: resolved.packageId },
failedLookupLocations,
affectingLocations,
resolutionDiagnostics: diagnostics,
failedLookupLocations: initializeResolutionField(failedLookupLocations),
affectingLocations: initializeResolutionField(affectingLocations),
resolutionDiagnostics: initializeResolutionField(diagnostics),
};
}
function initializeResolutionField<T>(value: T[]): T[] | undefined {
return value.length ? value : undefined;
}
/** @internal */
export function updateResolutionField<T>(to: T[] | undefined, value: T[] | undefined) {
if (!value?.length) return to;
if (!to?.length) return value;
to.push(...value);
return to;
}
/** @internal */
export interface ModuleResolutionState {
@@ -524,7 +531,12 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string
isExternalLibraryImport: pathContainsNodeModules(fileName),
};
}
result = { resolvedTypeReferenceDirective, failedLookupLocations, affectingLocations, resolutionDiagnostics: diagnostics };
result = {
resolvedTypeReferenceDirective,
failedLookupLocations: initializeResolutionField(failedLookupLocations),
affectingLocations: initializeResolutionField(affectingLocations),
resolutionDiagnostics: initializeResolutionField(diagnostics),
};
perFolderCache?.set(typeReferenceDirectiveName, /*mode*/ resolutionMode, result);
if (traceEnabled) traceResult(result);
return result;
@@ -911,23 +923,17 @@ export function createModeAwareCache<T>(): ModeAwareCache<T> {
}
/** @internal */
export function getResolutionName(entry: string | FileReference | StringLiteralLike) {
// We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
return !isString(entry) ? isStringLiteralLike(entry) ? entry.text : toFileNameLowerCase(entry.fileName) : entry;
}
/** @internal */
export function getResolutionMode(entry: FileReference | StringLiteralLike, file: SourceFile) {
return isStringLiteralLike(entry) ? getModeForUsageLocation(file, entry) : entry.resolutionMode || file.impliedNodeFormat;
}
/** @internal */
export function zipToModeAwareCache<V>(file: SourceFile, keys: readonly StringLiteralLike[] | readonly FileReference[], values: readonly V[]): ModeAwareCache<V> {
export function zipToModeAwareCache<K, V>(
file: SourceFile,
keys: readonly K[],
values: readonly V[],
nameAndModeGetter: ResolutionNameAndModeGetter<K, SourceFile>,
): ModeAwareCache<V> {
Debug.assert(keys.length === values.length);
const map = createModeAwareCache<V>();
for (let i = 0; i < keys.length; ++i) {
const entry = keys[i];
map.set(getResolutionName(entry), getResolutionMode(entry, file), values[i]);
map.set(nameAndModeGetter.getName(entry), nameAndModeGetter.getMode(entry, file), values[i]);
}
return map;
}
@@ -1373,7 +1379,7 @@ function tryLoadModuleUsingBaseUrl(extensions: Extensions, moduleName: string, l
export function resolveJSModule(moduleName: string, initialDir: string, host: ModuleResolutionHost): string {
const { resolvedModule, failedLookupLocations } = tryResolveJSModuleWorker(moduleName, initialDir, host);
if (!resolvedModule) {
throw new Error(`Could not resolve JS module '${moduleName}' starting at '${initialDir}'. Looked in: ${failedLookupLocations.join(", ")}`);
throw new Error(`Could not resolve JS module '${moduleName}' starting at '${initialDir}'. Looked in: ${failedLookupLocations?.join(", ")}`);
}
return resolvedModule.resolvedFileName;
}