Skip to content

Commit cb61bfe

Browse files
committed
In preparation of sharing resolutions, watch the resolutions right away instead of defering external module reoslutions to watch all failed lookup locations
1 parent b3678ec commit cb61bfe

File tree

115 files changed

+480
-482
lines changed

Some content is hidden

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

115 files changed

+480
-482
lines changed

src/compiler/resolutionCache.ts

Lines changed: 33 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,10 @@ export interface ResolutionCache extends Required<CompilerHostSupportingResoluti
113113
countResolutionsResolvedWithGlobalCache(): number;
114114
countResolutionsResolvedWithoutGlobalCache(): number;
115115

116-
watchFailedLookupLocationsOfExternalModuleResolutions<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
117-
name: string,
116+
watchResolution<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
118117
resolution: T,
119118
filePath: Path,
120119
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
121-
deferWatchingNonRelativeResolution: boolean,
122120
): void;
123121

124122
resolveModuleNameLiterals(
@@ -179,10 +177,13 @@ export interface ResolutionCache extends Required<CompilerHostSupportingResoluti
179177
export interface ResolutionWithFailedLookupLocations {
180178
failedLookupLocations?: string[];
181179
affectingLocations?: string[];
180+
node10Result?: string;
182181
isInvalidated?: boolean;
183182
// Files that have this resolution using
184183
files?: Set<Path>;
185-
node10Result?: string;
184+
watchedFailed?: number;
185+
watchedAffected?: number;
186+
setAtRoot?: boolean;
186187
globalCacheResolution?: boolean;
187188
}
188189

@@ -553,7 +554,6 @@ export function createResolutionCache(
553554
rootDirForResolution: string,
554555
): ResolutionCache {
555556
let filesWithInvalidatedResolutions: Set<Path> | undefined;
556-
const nonRelativeExternalModuleResolutions = new Set<ResolutionWithFailedLookupLocations>();
557557

558558
const resolutionsWithFailedLookups = new Set<ResolutionWithFailedLookupLocations>();
559559
const resolutionsWithOnlyAffectingLocations = new Set<ResolutionWithFailedLookupLocations>();
@@ -625,7 +625,7 @@ export function createResolutionCache(
625625
fileWatchesOfAffectingLocations,
626626
countResolutionsResolvedWithGlobalCache: () => resolutionsResolvedWithGlobalCache,
627627
countResolutionsResolvedWithoutGlobalCache: () => resolutionsResolvedWithoutGlobalCache,
628-
watchFailedLookupLocationsOfExternalModuleResolutions,
628+
watchResolution,
629629
getModuleResolutionCache: () => moduleResolutionCache,
630630
// perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
631631
// (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
@@ -655,7 +655,6 @@ export function createResolutionCache(
655655
function clear() {
656656
clearMap(directoryWatchesOfFailedLookups, closeFileWatcherOf);
657657
clearMap(fileWatchesOfAffectingLocations, closeFileWatcherOf);
658-
nonRelativeExternalModuleResolutions.clear();
659658
closeTypeRootsWatch();
660659
resolvedModuleNames.clear();
661660
resolvedTypeReferenceDirectives.clear();
@@ -723,7 +722,6 @@ export function createResolutionCache(
723722
libraryResolutionCache.clearAllExceptPackageJsonInfoCache();
724723
// perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
725724
// (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
726-
watchFailedLookupLocationOfNonRelativeModuleResolutions();
727725
}
728726

729727
function cleanupLibResolutionWatching(newProgram: Program | undefined) {
@@ -744,7 +742,6 @@ export function createResolutionCache(
744742
resolutionsWithGlobalCachePassAreInvalidated = false;
745743
resolutionsWithoutGlobalCachePassAreInvalidated = false;
746744
unresolvedResolutionsWithGlobalCachePassAreInvalidated = false;
747-
watchFailedLookupLocationOfNonRelativeModuleResolutions();
748745
// Update file watches
749746
if (newProgram !== oldProgram) {
750747
cleanupLibResolutionWatching(newProgram);
@@ -810,7 +807,6 @@ export function createResolutionCache(
810807
perFileCache: Map<Path, ModeAwareCache<T>>;
811808
loader: ResolutionLoader<Entry, T, SourceFile>;
812809
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>;
813-
deferWatchingNonRelativeResolution: boolean;
814810
onNewResolution?: CallbackOnNewResolution<T>;
815811
}
816812
function resolveNamesWithLocalCache<Entry, SourceFile, T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>({
@@ -824,7 +820,6 @@ export function createResolutionCache(
824820
ambientEntries,
825821
loader,
826822
getResolutionWithResolvedFileName,
827-
deferWatchingNonRelativeResolution,
828823
onNewResolution,
829824
}: ResolveNamesWithLocalCacheInput<Entry, SourceFile, T, R>): readonly T[] {
830825
const path = resolutionHost.toPath(containingFile);
@@ -861,7 +856,7 @@ export function createResolutionCache(
861856
}
862857
resolutionsInFile.set(name, mode, resolution);
863858
if (resolution !== existingResolution) {
864-
watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution, path, getResolutionWithResolvedFileName, deferWatchingNonRelativeResolution);
859+
watchResolution(resolution, path, getResolutionWithResolvedFileName);
865860
if (existingResolution) {
866861
stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolutionWithResolvedFileName);
867862
}
@@ -1018,7 +1013,6 @@ export function createResolutionCache(
10181013
typeReferenceDirectiveResolutionCache,
10191014
),
10201015
getResolutionWithResolvedFileName: getResolvedTypeReferenceDirectiveFromResolution,
1021-
deferWatchingNonRelativeResolution: false,
10221016
});
10231017
}
10241018

@@ -1049,7 +1043,6 @@ export function createResolutionCache(
10491043
moduleResolutionCache,
10501044
),
10511045
getResolutionWithResolvedFileName: getResolvedModuleFromResolution,
1052-
deferWatchingNonRelativeResolution: true, // Defer non relative resolution watch because we could be using ambient modules
10531046
onNewResolution,
10541047
});
10551048
}
@@ -1066,7 +1059,7 @@ export function createResolutionCache(
10661059
const existingResolution = resolution;
10671060
resolution = ts_resolveLibrary(libraryName, resolveFrom, options, host, libraryResolutionCache);
10681061
const path = resolutionHost.toPath(resolveFrom);
1069-
watchFailedLookupLocationsOfExternalModuleResolutions(libraryName, resolution, path, getResolvedModuleFromResolution, /*deferWatchingNonRelativeResolution*/ false);
1062+
watchResolution(resolution, path, getResolvedModuleFromResolution);
10701063
resolvedLibraries.set(libFileName, resolution);
10711064
if (existingResolution) {
10721065
stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolvedModuleFromResolution);
@@ -1115,25 +1108,19 @@ export function createResolutionCache(
11151108
return endsWith(dirPath, "/node_modules/@types");
11161109
}
11171110

1118-
function watchFailedLookupLocationsOfExternalModuleResolutions<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
1119-
name: string,
1111+
function watchResolution<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
11201112
resolution: T,
11211113
filePath: Path,
11221114
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
1123-
deferWatchingNonRelativeResolution: boolean,
11241115
) {
11251116
(resolution.files ??= new Set()).add(filePath);
1117+
watchFailedLookupLocationOfResolution(resolution);
1118+
watchAffectingLocationsOfResolution(resolution);
11261119
if (resolution.files.size !== 1) return;
11271120

11281121
if (resolution.globalCacheResolution) resolutionsResolvedWithGlobalCache++;
11291122
else if (resolution.globalCacheResolution === false) resolutionsResolvedWithoutGlobalCache++;
11301123

1131-
if (!deferWatchingNonRelativeResolution || isExternalModuleNameRelative(name)) {
1132-
watchFailedLookupLocationOfResolution(resolution);
1133-
}
1134-
else {
1135-
nonRelativeExternalModuleResolutions.add(resolution);
1136-
}
11371124
const resolved = getResolutionWithResolvedFileName(resolution);
11381125
if (resolved && resolved.resolvedFileName) {
11391126
const key = resolutionHost.toPath(resolved.resolvedFileName);
@@ -1169,33 +1156,38 @@ export function createResolutionCache(
11691156
function watchFailedLookupLocationOfResolution(resolution: ResolutionWithFailedLookupLocations) {
11701157
Debug.assert(!!resolution.files?.size);
11711158

1172-
const { failedLookupLocations, affectingLocations, node10Result } = resolution;
1173-
if (!failedLookupLocations?.length && !affectingLocations?.length && !node10Result) return;
1174-
if (failedLookupLocations?.length || node10Result) resolutionsWithFailedLookups.add(resolution);
1159+
const { failedLookupLocations, node10Result, watchedFailed } = resolution;
1160+
// There have to be failed lookup locations if there is node10Result so storing failedLookupLocation length is good enough,
1161+
// node10Result doesnt change later only failed lookup locations get added on
1162+
if (watchedFailed === failedLookupLocations?.length) return;
1163+
if (!watchedFailed) {
1164+
resolutionsWithFailedLookups.add(resolution);
1165+
if (resolution.watchedAffected) resolutionsWithOnlyAffectingLocations.delete(resolution);
1166+
}
11751167

1176-
let setAtRoot = false;
1177-
if (failedLookupLocations) {
1178-
for (const failedLookupLocation of failedLookupLocations) {
1179-
setAtRoot = watchFailedLookupLocation(failedLookupLocation, setAtRoot);
1180-
}
1168+
let setAtRoot = !!resolution.setAtRoot;
1169+
for (let i = watchedFailed || 0; i < failedLookupLocations!.length; i++) {
1170+
setAtRoot = watchFailedLookupLocation(failedLookupLocations![i], setAtRoot);
11811171
}
1182-
if (node10Result) setAtRoot = watchFailedLookupLocation(node10Result, setAtRoot);
1183-
if (setAtRoot) {
1172+
if (!watchedFailed && node10Result) setAtRoot = watchFailedLookupLocation(node10Result, setAtRoot);
1173+
if (!resolution.setAtRoot && setAtRoot) {
11841174
// This is always non recursive
11851175
setDirectoryWatcher(rootDir, rootPath, /*nonRecursive*/ true);
11861176
}
1187-
watchAffectingLocationsOfResolution(resolution, !failedLookupLocations?.length && !node10Result);
1177+
resolution.watchedFailed = failedLookupLocations?.length;
1178+
resolution.setAtRoot = setAtRoot;
11881179
}
11891180

1190-
function watchAffectingLocationsOfResolution(resolution: ResolutionWithFailedLookupLocations, addToResolutionsWithOnlyAffectingLocations: boolean) {
1181+
function watchAffectingLocationsOfResolution(resolution: ResolutionWithFailedLookupLocations) {
11911182
Debug.assert(!!resolution.files?.size);
1192-
const { affectingLocations } = resolution;
1193-
if (!affectingLocations?.length) return;
1194-
if (addToResolutionsWithOnlyAffectingLocations) resolutionsWithOnlyAffectingLocations.add(resolution);
1183+
const { affectingLocations, watchedAffected } = resolution;
1184+
if (affectingLocations?.length === watchedAffected) return;
1185+
if (!watchedAffected && !resolution.watchedFailed) resolutionsWithOnlyAffectingLocations.add(resolution);
11951186
// Watch package json
1196-
for (const affectingLocation of affectingLocations) {
1197-
createFileWatcherOfAffectingLocation(affectingLocation, /*forResolution*/ true);
1187+
for (let i = watchedAffected || 0; i < affectingLocations!.length; i++) {
1188+
createFileWatcherOfAffectingLocation(affectingLocations![i], /*forResolution*/ true);
11981189
}
1190+
resolution.watchedAffected = affectingLocations?.length;
11991191
}
12001192

12011193
function createFileWatcherOfAffectingLocation(affectingLocation: string, forResolution: boolean) {
@@ -1263,11 +1255,6 @@ export function createResolutionCache(
12631255
packageJsonMap?.delete(resolutionHost.toPath(path));
12641256
}
12651257

1266-
function watchFailedLookupLocationOfNonRelativeModuleResolutions() {
1267-
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfResolution);
1268-
nonRelativeExternalModuleResolutions.clear();
1269-
}
1270-
12711258
function setDirectoryWatcher(dir: string, dirPath: Path, nonRecursive?: boolean) {
12721259
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
12731260
if (dirWatcher) {

src/harness/incrementalUtils.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,6 @@ export function verifyResolutionCache(
222222
path,
223223
resolutions,
224224
getResolvedModuleFileName,
225-
/*deferWatchingNonRelativeResolution*/ true,
226225
expected.resolvedModuleNames,
227226
(name, mode) => actualProgram.getResolvedModule(actualProgram.getSourceFileByPath(path)!, name, mode),
228227
)
@@ -233,7 +232,6 @@ export function verifyResolutionCache(
233232
path,
234233
resolutions,
235234
getResolvedTypeRefFileName,
236-
/*deferWatchingNonRelativeResolution*/ false,
237235
expected.resolvedTypeReferenceDirectives,
238236
(name, mode) =>
239237
path !== inferredTypesPath ?
@@ -251,7 +249,6 @@ export function verifyResolutionCache(
251249
getResolvedModuleFileName(resolved),
252250
ts.getLibraryNameFromLibFileName(libFileName),
253251
/*mode*/ undefined,
254-
/*deferWatchingNonRelativeResolution*/ false,
255252
);
256253
expected.resolvedLibraries.set(libFileName, expectedResolution);
257254
});
@@ -304,7 +301,20 @@ export function verifyResolutionCache(
304301
!resolution.isInvalidated,
305302
`${projectName}:: Resolution should not be invalidated`,
306303
);
307-
verifySet(resolutionToExpected.get(resolution)!.files, resolution.files, `${projectName}:: Resolution files`);
304+
const expected = resolutionToExpected.get(resolution)!;
305+
verifySet(expected.files, resolution.files, `${projectName}:: Resolution files`);
306+
ts.Debug.assert(
307+
expected.watchedFailed === resolution.watchedFailed,
308+
`${projectName}:: Expected watchedFailed of Resolution ${expected.watchedFailed} but got ${resolution.watchedFailed}`,
309+
);
310+
ts.Debug.assert(
311+
expected.watchedAffected === resolution.watchedAffected,
312+
`${projectName}:: Expected watchedAffected of Resolution ${expected.watchedAffected} but got ${resolution.watchedAffected}`,
313+
);
314+
ts.Debug.assert(
315+
expected.setAtRoot === resolution.setAtRoot,
316+
`${projectName}:: Expected setAtRoot of Resolution ${expected.setAtRoot} but got ${resolution.setAtRoot}`,
317+
);
308318
});
309319
verifyMapOfResolutionSet(expected.resolvedFileToResolution, actual.resolvedFileToResolution, `resolvedFileToResolution`);
310320
verifyResolutionSet(expected.resolutionsWithFailedLookups, actual.resolutionsWithFailedLookups, `resolutionsWithFailedLookups`);
@@ -364,7 +374,6 @@ export function verifyResolutionCache(
364374
fileName: ts.Path,
365375
cache: ts.ModeAwareCache<T> | undefined,
366376
getResolvedFileName: (resolution: T) => string | undefined,
367-
deferWatchingNonRelativeResolution: boolean,
368377
storeExpected: Map<ts.Path, ts.ModeAwareCache<ts.ResolutionWithFailedLookupLocations>>,
369378
getProgramResolutions: (name: string, mode: ts.ResolutionMode) => T | undefined,
370379
) {
@@ -375,7 +384,7 @@ export function verifyResolutionCache(
375384
let expectedCache: ts.ModeAwareCache<ts.ResolutionWithFailedLookupLocations> | undefined;
376385
cache?.forEach((resolved, name, mode) => {
377386
const resolvedFileName = getResolvedFileName(resolved);
378-
const expected = collectResolution(cacheType, fileName, resolved, resolvedFileName, name, mode, deferWatchingNonRelativeResolution);
387+
const expected = collectResolution(cacheType, fileName, resolved, resolvedFileName, name, mode);
379388
if (!expectedCache) storeExpected.set(fileName, expectedCache = ts.createModeAwareCache());
380389
expectedCache.set(name, mode, expected);
381390
// Resolution in cache should be same as that is in program
@@ -393,7 +402,6 @@ export function verifyResolutionCache(
393402
resolvedFileName: string | undefined,
394403
name: string,
395404
mode: ts.ResolutionMode,
396-
deferWatchingNonRelativeResolution: boolean,
397405
): ExpectedResolution {
398406
const existing = resolutionToRefs.get(resolved);
399407
let expectedResolution: ExpectedResolution;
@@ -414,7 +422,7 @@ export function verifyResolutionCache(
414422
expectedToResolution.set(expectedResolution, resolved);
415423
resolutionToExpected.set(resolved, expectedResolution);
416424
}
417-
expected.watchFailedLookupLocationsOfExternalModuleResolutions(name, expectedResolution, fileName, () => ({ resolvedFileName }), deferWatchingNonRelativeResolution);
425+
expected.watchResolution(expectedResolution, fileName, () => ({ resolvedFileName }));
418426
return expectedResolution;
419427
}
420428

0 commit comments

Comments
 (0)