Skip to content

Commit 83f02a4

Browse files
authored
Picking resolutions of module for sourceFile as method (#55818)
1 parent b47022b commit 83f02a4

File tree

45 files changed

+304
-544
lines changed

Some content is hidden

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

45 files changed

+304
-544
lines changed

src/compiler/builderState.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -238,18 +238,15 @@ export namespace BuilderState {
238238
}
239239

240240
// Handle type reference directives
241-
const resolvedTypeReferenceDirectiveNames = program.resolvedTypeReferenceDirectiveNames?.get(sourceFile.path);
242-
if (resolvedTypeReferenceDirectiveNames) {
243-
resolvedTypeReferenceDirectiveNames.forEach(({ resolvedTypeReferenceDirective }) => {
244-
if (!resolvedTypeReferenceDirective) {
245-
return;
246-
}
241+
program.forEachResolvedTypeReferenceDirective(({ resolvedTypeReferenceDirective }) => {
242+
if (!resolvedTypeReferenceDirective) {
243+
return;
244+
}
247245

248-
const fileName = resolvedTypeReferenceDirective.resolvedFileName!; // TODO: GH#18217
249-
const typeFilePath = getReferencedFileFromFileName(program, fileName, sourceFileDirectory, getCanonicalFileName);
250-
addReferencedFile(typeFilePath);
251-
});
252-
}
246+
const fileName = resolvedTypeReferenceDirective.resolvedFileName!; // TODO: GH#18217
247+
const typeFilePath = getReferencedFileFromFileName(program, fileName, sourceFileDirectory, getCanonicalFileName);
248+
addReferencedFile(typeFilePath);
249+
}, sourceFile);
253250

254251
// Add module augmentation as references
255252
if (sourceFile.moduleAugmentations.length) {

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4959,7 +4959,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
49594959
(isLiteralImportTypeNode(location) ? location : undefined)?.argument.literal;
49604960
const mode = contextSpecifier && isStringLiteralLike(contextSpecifier) ? getModeForUsageLocation(currentSourceFile, contextSpecifier) : currentSourceFile.impliedNodeFormat;
49614961
const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions);
4962-
const resolvedModule = host.resolvedModules?.get(currentSourceFile.path)?.get(moduleReference, mode)?.resolvedModule;
4962+
const resolvedModule = host.getResolvedModule(currentSourceFile, moduleReference, mode)?.resolvedModule;
49634963
const resolutionDiagnostic = resolvedModule && getResolutionDiagnostic(compilerOptions, resolvedModule, currentSourceFile);
49644964
const sourceFile = resolvedModule
49654965
&& (!resolutionDiagnostic || resolutionDiagnostic === Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set)

src/compiler/program.ts

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,7 @@ export function getReferencedFileLocation(program: Program, ref: ReferencedFile)
11751175
switch (kind) {
11761176
case FileIncludeKind.Import:
11771177
const importLiteral = getModuleNameStringLiteralAt(file, index);
1178-
packageId = program.resolvedModules?.get(file.path)?.get(importLiteral.text, getModeForResolutionAtIndex(file, index))?.resolvedModule?.packageId;
1178+
packageId = program.getResolvedModule(file, importLiteral.text, getModeForResolutionAtIndex(file, index))?.resolvedModule?.packageId;
11791179
if (importLiteral.pos === -1) return { file, packageId, text: importLiteral.text };
11801180
pos = skipTrivia(file.text, importLiteral.pos);
11811181
end = importLiteral.end;
@@ -1185,7 +1185,7 @@ export function getReferencedFileLocation(program: Program, ref: ReferencedFile)
11851185
break;
11861186
case FileIncludeKind.TypeReferenceDirective:
11871187
({ pos, end, resolutionMode } = file.typeReferenceDirectives[index]);
1188-
packageId = program.resolvedTypeReferenceDirectiveNames?.get(file.path)?.get(toFileNameLowerCase(file.typeReferenceDirectives[index].fileName), resolutionMode || file.impliedNodeFormat)?.resolvedTypeReferenceDirective?.packageId;
1188+
packageId = program.getResolvedTypeReferenceDirective(file, toFileNameLowerCase(file.typeReferenceDirectives[index].fileName), resolutionMode || file.impliedNodeFormat)?.resolvedTypeReferenceDirective?.packageId;
11891189
break;
11901190
case FileIncludeKind.LibReferenceDirective:
11911191
({ pos, end } = file.libReferenceDirectives[index]);
@@ -1886,6 +1886,10 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
18861886
resolvedModules,
18871887
resolvedTypeReferenceDirectiveNames,
18881888
resolvedLibReferences,
1889+
getResolvedModule,
1890+
getResolvedTypeReferenceDirective,
1891+
forEachResolvedModule,
1892+
forEachResolvedTypeReferenceDirective,
18891893
getCurrentPackagesMap: () => packageMap,
18901894
typesPackageExists,
18911895
packageBundlesTypes,
@@ -1935,18 +1939,47 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
19351939

19361940
return program;
19371941

1942+
function getResolvedModule(file: SourceFile, moduleName: string, mode: ResolutionMode) {
1943+
return resolvedModules?.get(file.path)?.get(moduleName, mode);
1944+
}
1945+
1946+
function getResolvedTypeReferenceDirective(file: SourceFile, typeDirectiveName: string, mode: ResolutionMode) {
1947+
return resolvedTypeReferenceDirectiveNames?.get(file.path)?.get(typeDirectiveName, mode);
1948+
}
1949+
1950+
function forEachResolvedModule(
1951+
callback: (resolution: ResolvedModuleWithFailedLookupLocations, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
1952+
file?: SourceFile,
1953+
) {
1954+
forEachResolution(resolvedModules, callback, file);
1955+
}
1956+
1957+
function forEachResolvedTypeReferenceDirective(
1958+
callback: (resolution: ResolvedTypeReferenceDirectiveWithFailedLookupLocations, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
1959+
file?: SourceFile,
1960+
): void {
1961+
forEachResolution(resolvedTypeReferenceDirectiveNames, callback, file);
1962+
}
1963+
1964+
function forEachResolution<T>(
1965+
resolutionCache: Map<Path, ModeAwareCache<T>> | undefined,
1966+
callback: (resolution: T, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
1967+
file: SourceFile | undefined,
1968+
) {
1969+
if (file) resolutionCache?.get(file.path)?.forEach((resolution, name, mode) => callback(resolution, name, mode, file.path));
1970+
else resolutionCache?.forEach((resolutions, filePath) => resolutions.forEach((resolution, name, mode) => callback(resolution, name, mode, filePath)));
1971+
}
1972+
19381973
function getPackagesMap() {
19391974
if (packageMap) return packageMap;
19401975
packageMap = new Map();
19411976
// A package name maps to true when we detect it has .d.ts files.
19421977
// This is useful as an approximation of whether a package bundles its own types.
19431978
// Note: we only look at files already found by module resolution,
19441979
// so there may be files we did not consider.
1945-
files.forEach(sf =>
1946-
resolvedModules?.get(sf.path)?.forEach(({ resolvedModule }) => {
1947-
if (resolvedModule?.packageId) packageMap!.set(resolvedModule.packageId.name, resolvedModule.extension === Extension.Dts || !!packageMap!.get(resolvedModule.packageId.name));
1948-
})
1949-
);
1980+
forEachResolvedModule(({ resolvedModule }) => {
1981+
if (resolvedModule?.packageId) packageMap!.set(resolvedModule.packageId.name, resolvedModule.extension === Extension.Dts || !!packageMap!.get(resolvedModule.packageId.name));
1982+
});
19501983
return packageMap;
19511984
}
19521985

@@ -2119,7 +2152,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
21192152
// If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions
21202153
if (file === oldSourceFile && !hasInvalidatedResolutions(file.path)) {
21212154
const mode = getModeForUsageLocation(file, moduleName);
2122-
const oldResolution = oldProgram?.resolvedModules?.get(file.path)?.get(moduleName.text, mode);
2155+
const oldResolution = oldProgram?.getResolvedModule(file, moduleName.text, mode);
21232156
if (oldResolution?.resolvedModule) {
21242157
if (isTraceEnabled(options, host)) {
21252158
trace(
@@ -2187,7 +2220,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
21872220
// If we change our policy of rechecking failed lookups on each program create,
21882221
// we should adjust the value returned here.
21892222
function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName: StringLiteralLike): boolean {
2190-
const resolutionToFile = oldProgram?.resolvedModules?.get(file.path)?.get(moduleName.text, getModeForUsageLocation(file, moduleName))?.resolvedModule;
2223+
const resolutionToFile = oldProgram?.getResolvedModule(file, moduleName.text, getModeForUsageLocation(file, moduleName))?.resolvedModule;
21912224
const resolvedFile = resolutionToFile && oldProgram!.getSourceFile(resolutionToFile.resolvedFileName);
21922225
if (resolutionToFile && resolvedFile) {
21932226
// In the old program, we resolved to an ambient module that was in the same
@@ -2234,7 +2267,9 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
22342267
if (canReuseResolutions) {
22352268
const typeDirectiveName = getTypeReferenceResolutionName(entry);
22362269
const mode = getModeForFileReference(entry, containingSourceFile?.impliedNodeFormat);
2237-
const oldResolution = (!isString(containingFile) ? oldProgram?.resolvedTypeReferenceDirectiveNames?.get(containingFile.path) : oldProgram?.getAutomaticTypeDirectiveResolutions())?.get(typeDirectiveName, mode);
2270+
const oldResolution = !isString(containingFile) ?
2271+
oldProgram?.getResolvedTypeReferenceDirective(containingFile, typeDirectiveName, mode) :
2272+
oldProgram?.getAutomaticTypeDirectiveResolutions()?.get(typeDirectiveName, mode);
22382273
if (oldResolution?.resolvedTypeReferenceDirective) {
22392274
if (isTraceEnabled(options, host)) {
22402275
trace(
@@ -2476,22 +2511,29 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
24762511
const moduleNames = getModuleNames(newSourceFile);
24772512
const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile);
24782513
(resolvedModulesProcessing ??= new Map()).set(newSourceFile.path, resolutions);
2479-
const oldResolutions = oldProgram.resolvedModules?.get(newSourceFile.path);
24802514
// ensure that module resolution results are still correct
2481-
const resolutionsChanged = hasChangesInResolutions(moduleNames, newSourceFile, resolutions, oldResolutions, moduleResolutionIsEqualTo, moduleResolutionNameAndModeGetter);
2515+
const resolutionsChanged = hasChangesInResolutions(
2516+
moduleNames,
2517+
newSourceFile,
2518+
resolutions,
2519+
(name, mode) => oldProgram!.getResolvedModule(newSourceFile, name, mode),
2520+
moduleResolutionIsEqualTo,
2521+
moduleResolutionNameAndModeGetter,
2522+
);
24822523
if (resolutionsChanged) structureIsReused = StructureIsReused.SafeModules;
24832524
const typesReferenceDirectives = newSourceFile.typeReferenceDirectives;
24842525
const typeReferenceResolutions = resolveTypeReferenceDirectiveNamesReusingOldState(typesReferenceDirectives, newSourceFile);
24852526
(resolvedTypeReferenceDirectiveNamesProcessing ??= new Map()).set(newSourceFile.path, typeReferenceResolutions);
24862527
// ensure that types resolutions are still correct
2487-
const oldTypeResolutions = oldProgram.resolvedTypeReferenceDirectiveNames?.get(newSourceFile.path);
2488-
const typeReferenceResolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, newSourceFile, typeReferenceResolutions, oldTypeResolutions, typeDirectiveIsEqualTo, typeReferenceResolutionNameAndModeGetter);
2489-
if (typeReferenceResolutionsChanged) {
2490-
structureIsReused = StructureIsReused.SafeModules;
2491-
}
2492-
else if (oldTypeResolutions) {
2493-
(resolvedTypeReferenceDirectiveNamesProcessing ??= new Map()).set(newSourceFile.path, oldTypeResolutions);
2494-
}
2528+
const typeReferenceResolutionsChanged = hasChangesInResolutions(
2529+
typesReferenceDirectives,
2530+
newSourceFile,
2531+
typeReferenceResolutions,
2532+
(name, mode) => oldProgram?.getResolvedTypeReferenceDirective(newSourceFile, name, mode),
2533+
typeDirectiveIsEqualTo,
2534+
typeReferenceResolutionNameAndModeGetter,
2535+
);
2536+
if (typeReferenceResolutionsChanged) structureIsReused = StructureIsReused.SafeModules;
24952537
}
24962538

24972539
if (structureIsReused !== StructureIsReused.Completely) {
@@ -4931,7 +4973,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
49314973
symlinks = createSymlinkCache(currentDirectory, getCanonicalFileName);
49324974
}
49334975
if (files && !symlinks.hasProcessedResolutions()) {
4934-
symlinks.setSymlinksFromResolutions(resolvedModules, resolvedTypeReferenceDirectiveNames, automaticTypeDirectiveResolutions);
4976+
symlinks.setSymlinksFromResolutions(forEachResolvedModule, forEachResolvedTypeReferenceDirective, automaticTypeDirectiveResolutions);
49354977
}
49364978
return symlinks;
49374979
}

src/compiler/types.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4651,6 +4651,20 @@ export interface Program extends ScriptReferenceHost {
46514651
resolvedModules: Map<Path, ModeAwareCache<ResolvedModuleWithFailedLookupLocations>> | undefined;
46524652
/** @internal */
46534653
resolvedTypeReferenceDirectiveNames: Map<Path, ModeAwareCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>> | undefined;
4654+
/** @internal */
4655+
getResolvedModule(f: SourceFile, moduleName: string, mode: ResolutionMode): ResolvedModuleWithFailedLookupLocations | undefined;
4656+
/** @internal */
4657+
getResolvedTypeReferenceDirective(f: SourceFile, typeDirectiveName: string, mode: ResolutionMode): ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined;
4658+
/** @internal */
4659+
forEachResolvedModule(
4660+
callback: (resolution: ResolvedModuleWithFailedLookupLocations, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
4661+
file?: SourceFile,
4662+
): void;
4663+
/** @internal */
4664+
forEachResolvedTypeReferenceDirective(
4665+
callback: (resolution: ResolvedTypeReferenceDirectiveWithFailedLookupLocations, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
4666+
file?: SourceFile,
4667+
): void;
46544668

46554669
/**
46564670
* Emits the JavaScript and declaration files. If targetSourceFile is not specified, then
@@ -4868,7 +4882,7 @@ export interface TypeCheckerHost extends ModuleSpecifierResolutionHost {
48684882
getProjectReferenceRedirect(fileName: string): string | undefined;
48694883
isSourceOfProjectReferenceRedirect(fileName: string): boolean;
48704884

4871-
resolvedModules: Map<Path, ModeAwareCache<ResolvedModuleWithFailedLookupLocations>> | undefined;
4885+
getResolvedModule(f: SourceFile, moduleName: string, mode: ResolutionMode): ResolvedModuleWithFailedLookupLocations | undefined;
48724886

48734887
readonly redirectTargetsMap: RedirectTargetsMap;
48744888

src/compiler/utilities.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ export function moduleResolutionIsEqualTo(oldResolution: ResolvedModuleWithFaile
766766

767767
/** @internal */
768768
export function createModuleNotFoundChain(sourceFile: SourceFile, host: TypeCheckerHost, moduleReference: string, mode: ResolutionMode, packageName: string) {
769-
const node10Result = host.resolvedModules?.get(sourceFile.path)?.get(moduleReference, mode)?.node10Result;
769+
const node10Result = host.getResolvedModule(sourceFile, moduleReference, mode)?.node10Result;
770770
const result = node10Result
771771
? chainDiagnosticMessages(
772772
/*details*/ undefined,
@@ -828,7 +828,7 @@ export function hasChangesInResolutions<K, V>(
828828
names: readonly K[],
829829
newSourceFile: SourceFile,
830830
newResolutions: readonly V[],
831-
oldResolutions: ModeAwareCache<V> | undefined,
831+
getOldResolution: (name: string, mode: ResolutionMode) => V | undefined,
832832
comparer: (oldResolution: V, newResolution: V) => boolean,
833833
nameAndModeGetter: ResolutionNameAndModeGetter<K, SourceFile>,
834834
): boolean {
@@ -839,7 +839,7 @@ export function hasChangesInResolutions<K, V>(
839839
const entry = names[i];
840840
const name = nameAndModeGetter.getName(entry);
841841
const mode = nameAndModeGetter.getMode(entry, newSourceFile);
842-
const oldResolution = oldResolutions && oldResolutions.get(name, mode);
842+
const oldResolution = getOldResolution(name, mode);
843843
const changed = oldResolution
844844
? !newResolution || !comparer(oldResolution, newResolution)
845845
: newResolution;
@@ -8825,8 +8825,12 @@ export interface SymlinkCache {
88258825
* `hasProcessedResolutions` returns false (once per cache instance).
88268826
*/
88278827
setSymlinksFromResolutions(
8828-
resolvedModules: Map<Path, ModeAwareCache<ResolvedModuleWithFailedLookupLocations>> | undefined,
8829-
resolvedTypeReferenceDirectiveNames: Map<Path, ModeAwareCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>> | undefined,
8828+
forEachResolvedModule: (
8829+
callback: (resolution: ResolvedModuleWithFailedLookupLocations, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
8830+
) => void,
8831+
forEachResolvedTypeReferenceDirective: (
8832+
callback: (resolution: ResolvedTypeReferenceDirectiveWithFailedLookupLocations, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
8833+
) => void,
88308834
typeReferenceDirectives: ModeAwareCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>,
88318835
): void;
88328836
/**
@@ -8860,11 +8864,11 @@ export function createSymlinkCache(cwd: string, getCanonicalFileName: GetCanonic
88608864
(symlinkedDirectories || (symlinkedDirectories = new Map())).set(symlinkPath, real);
88618865
}
88628866
},
8863-
setSymlinksFromResolutions(resolvedModules, resolvedTypeReferenceDirectiveNames, typeReferenceDirectives) {
8867+
setSymlinksFromResolutions(forEachResolvedModule, forEachResolvedTypeReferenceDirective, typeReferenceDirectives) {
88648868
Debug.assert(!hasProcessedResolutions);
88658869
hasProcessedResolutions = true;
8866-
resolvedModules?.forEach(cache => cache.forEach(resolution => processResolution(this, resolution.resolvedModule)));
8867-
resolvedTypeReferenceDirectiveNames?.forEach(cache => cache.forEach(resolution => processResolution(this, resolution.resolvedTypeReferenceDirective)));
8870+
forEachResolvedModule(resolution => processResolution(this, resolution.resolvedModule));
8871+
forEachResolvedTypeReferenceDirective(resolution => processResolution(this, resolution.resolvedTypeReferenceDirective));
88688872
typeReferenceDirectives.forEach(resolution => processResolution(this, resolution.resolvedTypeReferenceDirective));
88698873
},
88708874
hasProcessedResolutions: () => hasProcessedResolutions,

0 commit comments

Comments
 (0)