Skip to content

Commit 9e845d2

Browse files
authored
Api cleanup for Module and Type Reference directive resolution (microsoft#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
1 parent c07f512 commit 9e845d2

73 files changed

Lines changed: 2772 additions & 1440 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/compiler/builderState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ export namespace BuilderState {
233233

234234
// Handle type reference directives
235235
if (sourceFile.resolvedTypeReferenceDirectiveNames) {
236-
sourceFile.resolvedTypeReferenceDirectiveNames.forEach((resolvedTypeReferenceDirective) => {
236+
sourceFile.resolvedTypeReferenceDirectiveNames.forEach(({ resolvedTypeReferenceDirective }) => {
237237
if (!resolvedTypeReferenceDirective) {
238238
return;
239239
}

src/compiler/checker.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,8 +1333,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
13331333
host.getSourceFiles().forEach(sf => {
13341334
if (!sf.resolvedModules) return;
13351335

1336-
sf.resolvedModules.forEach(r => {
1337-
if (r && r.packageId) map.set(r.packageId.name, r.extension === Extension.Dts || !!map.get(r.packageId.name));
1336+
sf.resolvedModules.forEach(({ resolvedModule }) => {
1337+
if (resolvedModule?.packageId) map.set(resolvedModule.packageId.name, resolvedModule.extension === Extension.Dts || !!map.get(resolvedModule.packageId.name));
13381338
});
13391339
});
13401340
return map;
@@ -44897,15 +44897,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4489744897
// this variable and functions that use it are deliberately moved here from the outer scope
4489844898
// to avoid scope pollution
4489944899
const resolvedTypeReferenceDirectives = host.getResolvedTypeReferenceDirectives();
44900-
let fileToDirective: Map<string, [specifier: string, mode: ResolutionMode | undefined]>;
44900+
let fileToDirective: Map<string, [specifier: string, mode: ResolutionMode]>;
4490144901
if (resolvedTypeReferenceDirectives) {
4490244902
// populate reverse mapping: file path -> type reference directive that was resolved to this file
44903-
fileToDirective = new Map<string, [specifier: string, mode: ResolutionMode | undefined]>();
44904-
resolvedTypeReferenceDirectives.forEach((resolvedDirective, key, mode) => {
44905-
if (!resolvedDirective || !resolvedDirective.resolvedFileName) {
44903+
fileToDirective = new Map<string, [specifier: string, mode: ResolutionMode]>();
44904+
resolvedTypeReferenceDirectives.forEach(({ resolvedTypeReferenceDirective }, key, mode) => {
44905+
if (!resolvedTypeReferenceDirective?.resolvedFileName) {
4490644906
return;
4490744907
}
44908-
const file = host.getSourceFile(resolvedDirective.resolvedFileName);
44908+
const file = host.getSourceFile(resolvedTypeReferenceDirective.resolvedFileName);
4490944909
if (file) {
4491044910
// Add the transitive closure of path references loaded by this file (as long as they are not)
4491144911
// part of an existing type reference.
@@ -45032,7 +45032,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4503245032
}
4503345033

4503445034
// defined here to avoid outer scope pollution
45035-
function getTypeReferenceDirectivesForEntityName(node: EntityNameOrEntityNameExpression): [specifier: string, mode: ResolutionMode | undefined][] | undefined {
45035+
function getTypeReferenceDirectivesForEntityName(node: EntityNameOrEntityNameExpression): [specifier: string, mode: ResolutionMode][] | undefined {
4503645036
// program does not have any files with type reference directives - bail out
4503745037
if (!fileToDirective) {
4503845038
return undefined;
@@ -45057,13 +45057,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4505745057
}
4505845058

4505945059
// defined here to avoid outer scope pollution
45060-
function getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): [specifier: string, mode: ResolutionMode | undefined][] | undefined {
45060+
function getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: SymbolFlags): [specifier: string, mode: ResolutionMode][] | undefined {
4506145061
// program does not have any files with type reference directives - bail out
4506245062
if (!fileToDirective || !isSymbolFromTypeDeclarationFile(symbol)) {
4506345063
return undefined;
4506445064
}
4506545065
// check what declarations in the symbol can contribute to the target meaning
45066-
let typeReferenceDirectives: [specifier: string, mode: ResolutionMode | undefined][] | undefined;
45066+
let typeReferenceDirectives: [specifier: string, mode: ResolutionMode][] | undefined;
4506745067
for (const decl of symbol.declarations!) {
4506845068
// check meaning of the local symbol to see if declaration needs to be analyzed further
4506945069
if (decl.symbol && decl.symbol.flags & meaning!) {
@@ -45114,7 +45114,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4511445114
return false;
4511545115
}
4511645116

45117-
function addReferencedFilesToTypeDirective(file: SourceFile, key: string, mode: ResolutionMode | undefined) {
45117+
function addReferencedFilesToTypeDirective(file: SourceFile, key: string, mode: ResolutionMode) {
4511845118
if (fileToDirective.has(file.path)) return;
4511945119
fileToDirective.set(file.path, [key, mode]);
4512045120
for (const { fileName, resolutionMode } of file.referencedFiles) {

src/compiler/moduleNameResolver.ts

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
extensionIsTS,
2828
fileExtensionIs,
2929
fileExtensionIsOneOf,
30-
FileReference,
3130
filter,
3231
firstDefined,
3332
forEach,
@@ -41,7 +40,6 @@ import {
4140
GetEffectiveTypeRootsHost,
4241
getEmitModuleKind,
4342
getEmitModuleResolutionKind,
44-
getModeForUsageLocation,
4543
getNormalizedAbsolutePath,
4644
getOwnKeys,
4745
getPathComponents,
@@ -58,7 +56,6 @@ import {
5856
isExternalModuleNameRelative,
5957
isRootedDiskPath,
6058
isString,
61-
isStringLiteralLike,
6259
lastOrUndefined,
6360
length,
6461
MapLike,
@@ -86,6 +83,7 @@ import {
8683
removeFileExtension,
8784
removePrefix,
8885
ResolutionMode,
86+
ResolutionNameAndModeGetter,
8987
ResolvedModuleWithFailedLookupLocations,
9088
ResolvedProjectReference,
9189
ResolvedTypeReferenceDirective,
@@ -95,10 +93,8 @@ import {
9593
SourceFile,
9694
startsWith,
9795
stringContains,
98-
StringLiteralLike,
9996
supportedDeclarationExtensions,
10097
supportedTSImplementationExtensions,
101-
toFileNameLowerCase,
10298
toPath,
10399
tryExtractTSExtension,
104100
tryGetExtensionFromPath,
@@ -213,17 +209,28 @@ function createResolvedModuleWithFailedLookupLocations(
213209
resultFromCache: ResolvedModuleWithFailedLookupLocations | undefined
214210
): ResolvedModuleWithFailedLookupLocations {
215211
if (resultFromCache) {
216-
resultFromCache.failedLookupLocations.push(...failedLookupLocations);
217-
resultFromCache.affectingLocations.push(...affectingLocations);
212+
resultFromCache.failedLookupLocations = updateResolutionField(resultFromCache.failedLookupLocations, failedLookupLocations);
213+
resultFromCache.affectingLocations = updateResolutionField(resultFromCache.affectingLocations, affectingLocations);
214+
resultFromCache.resolutionDiagnostics = updateResolutionField(resultFromCache.resolutionDiagnostics, diagnostics);
218215
return resultFromCache;
219216
}
220217
return {
221218
resolvedModule: resolved && { resolvedFileName: resolved.path, originalPath: resolved.originalPath === true ? undefined : resolved.originalPath, extension: resolved.extension, isExternalLibraryImport, packageId: resolved.packageId },
222-
failedLookupLocations,
223-
affectingLocations,
224-
resolutionDiagnostics: diagnostics,
219+
failedLookupLocations: initializeResolutionField(failedLookupLocations),
220+
affectingLocations: initializeResolutionField(affectingLocations),
221+
resolutionDiagnostics: initializeResolutionField(diagnostics),
225222
};
226223
}
224+
function initializeResolutionField<T>(value: T[]): T[] | undefined {
225+
return value.length ? value : undefined;
226+
}
227+
/** @internal */
228+
export function updateResolutionField<T>(to: T[] | undefined, value: T[] | undefined) {
229+
if (!value?.length) return to;
230+
if (!to?.length) return value;
231+
to.push(...value);
232+
return to;
233+
}
227234

228235
/** @internal */
229236
export interface ModuleResolutionState {
@@ -524,7 +531,12 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string
524531
isExternalLibraryImport: pathContainsNodeModules(fileName),
525532
};
526533
}
527-
result = { resolvedTypeReferenceDirective, failedLookupLocations, affectingLocations, resolutionDiagnostics: diagnostics };
534+
result = {
535+
resolvedTypeReferenceDirective,
536+
failedLookupLocations: initializeResolutionField(failedLookupLocations),
537+
affectingLocations: initializeResolutionField(affectingLocations),
538+
resolutionDiagnostics: initializeResolutionField(diagnostics),
539+
};
528540
perFolderCache?.set(typeReferenceDirectiveName, /*mode*/ resolutionMode, result);
529541
if (traceEnabled) traceResult(result);
530542
return result;
@@ -911,23 +923,17 @@ export function createModeAwareCache<T>(): ModeAwareCache<T> {
911923
}
912924

913925
/** @internal */
914-
export function getResolutionName(entry: string | FileReference | StringLiteralLike) {
915-
// We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
916-
return !isString(entry) ? isStringLiteralLike(entry) ? entry.text : toFileNameLowerCase(entry.fileName) : entry;
917-
}
918-
919-
/** @internal */
920-
export function getResolutionMode(entry: FileReference | StringLiteralLike, file: SourceFile) {
921-
return isStringLiteralLike(entry) ? getModeForUsageLocation(file, entry) : entry.resolutionMode || file.impliedNodeFormat;
922-
}
923-
924-
/** @internal */
925-
export function zipToModeAwareCache<V>(file: SourceFile, keys: readonly StringLiteralLike[] | readonly FileReference[], values: readonly V[]): ModeAwareCache<V> {
926+
export function zipToModeAwareCache<K, V>(
927+
file: SourceFile,
928+
keys: readonly K[],
929+
values: readonly V[],
930+
nameAndModeGetter: ResolutionNameAndModeGetter<K, SourceFile>,
931+
): ModeAwareCache<V> {
926932
Debug.assert(keys.length === values.length);
927933
const map = createModeAwareCache<V>();
928934
for (let i = 0; i < keys.length; ++i) {
929935
const entry = keys[i];
930-
map.set(getResolutionName(entry), getResolutionMode(entry, file), values[i]);
936+
map.set(nameAndModeGetter.getName(entry), nameAndModeGetter.getMode(entry, file), values[i]);
931937
}
932938
return map;
933939
}
@@ -1373,7 +1379,7 @@ function tryLoadModuleUsingBaseUrl(extensions: Extensions, moduleName: string, l
13731379
export function resolveJSModule(moduleName: string, initialDir: string, host: ModuleResolutionHost): string {
13741380
const { resolvedModule, failedLookupLocations } = tryResolveJSModuleWorker(moduleName, initialDir, host);
13751381
if (!resolvedModule) {
1376-
throw new Error(`Could not resolve JS module '${moduleName}' starting at '${initialDir}'. Looked in: ${failedLookupLocations.join(", ")}`);
1382+
throw new Error(`Could not resolve JS module '${moduleName}' starting at '${initialDir}'. Looked in: ${failedLookupLocations?.join(", ")}`);
13771383
}
13781384
return resolvedModule.resolvedFileName;
13791385
}

0 commit comments

Comments
 (0)