Skip to content

Commit 8bdf98e

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 e98d6ec commit 8bdf98e

File tree

113 files changed

+456
-458
lines changed

Some content is hidden

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

113 files changed

+456
-458
lines changed

src/compiler/resolutionCache.ts

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

117-
watchFailedLookupLocationsOfExternalModuleResolutions<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
118-
name: string,
117+
watchResolution<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
119118
resolution: T,
120119
filePath: Path,
121120
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
122-
deferWatchingNonRelativeResolution: boolean,
123121
): void;
124122

125123
resolveModuleNameLiterals(
@@ -180,10 +178,13 @@ export interface ResolutionCache extends Required<CompilerHostSupportingResoluti
180178
export interface ResolutionWithFailedLookupLocations {
181179
failedLookupLocations?: string[];
182180
affectingLocations?: string[];
181+
node10Result?: string;
183182
isInvalidated?: boolean;
184183
// Files that have this resolution using
185184
files?: Set<Path>;
186-
node10Result?: string;
185+
watchedFailed?: number;
186+
watchedAffected?: number;
187+
setAtRoot?: boolean;
187188
globalCacheResolution?: boolean;
188189
}
189190

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

559559
const resolutionsWithFailedLookups = new Set<ResolutionWithFailedLookupLocations>();
560560
const resolutionsWithOnlyAffectingLocations = new Set<ResolutionWithFailedLookupLocations>();
@@ -626,7 +626,7 @@ export function createResolutionCache(
626626
fileWatchesOfAffectingLocations,
627627
countResolutionsResolvedWithGlobalCache: () => resolutionsResolvedWithGlobalCache,
628628
countResolutionsResolvedWithoutGlobalCache: () => resolutionsResolvedWithoutGlobalCache,
629-
watchFailedLookupLocationsOfExternalModuleResolutions,
629+
watchResolution,
630630
getModuleResolutionCache: () => moduleResolutionCache,
631631
// perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
632632
// (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
@@ -656,7 +656,6 @@ export function createResolutionCache(
656656
function clear() {
657657
clearMap(directoryWatchesOfFailedLookups, closeFileWatcherOf);
658658
clearMap(fileWatchesOfAffectingLocations, closeFileWatcherOf);
659-
nonRelativeExternalModuleResolutions.clear();
660659
closeTypeRootsWatch();
661660
resolvedModuleNames.clear();
662661
resolvedTypeReferenceDirectives.clear();
@@ -724,7 +723,6 @@ export function createResolutionCache(
724723
libraryResolutionCache.clearAllExceptPackageJsonInfoCache();
725724
// perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
726725
// (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
727-
watchFailedLookupLocationOfNonRelativeModuleResolutions();
728726
}
729727

730728
function cleanupLibResolutionWatching(newProgram: Program | undefined) {
@@ -745,7 +743,6 @@ export function createResolutionCache(
745743
resolutionsWithGlobalCachePassAreInvalidated = false;
746744
resolutionsWithoutGlobalCachePassAreInvalidated = false;
747745
unresolvedResolutionsWithGlobalCachePassAreInvalidated = false;
748-
watchFailedLookupLocationOfNonRelativeModuleResolutions();
749746
// Update file watches
750747
if (newProgram !== oldProgram) {
751748
cleanupLibResolutionWatching(newProgram);
@@ -811,7 +808,6 @@ export function createResolutionCache(
811808
perFileCache: Map<Path, ModeAwareCache<T>>;
812809
loader: ResolutionLoader<Entry, T, SourceFile>;
813810
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>;
814-
deferWatchingNonRelativeResolution: boolean;
815811
onNewResolution?: CallbackOnNewResolution<T>;
816812
}
817813
function resolveNamesWithLocalCache<Entry, SourceFile, T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>({
@@ -825,7 +821,6 @@ export function createResolutionCache(
825821
ambientEntries,
826822
loader,
827823
getResolutionWithResolvedFileName,
828-
deferWatchingNonRelativeResolution,
829824
onNewResolution,
830825
}: ResolveNamesWithLocalCacheInput<Entry, SourceFile, T, R>): readonly T[] {
831826
const path = resolutionHost.toPath(containingFile);
@@ -862,7 +857,7 @@ export function createResolutionCache(
862857
}
863858
resolutionsInFile.set(name, mode, resolution);
864859
if (resolution !== existingResolution) {
865-
watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution, path, getResolutionWithResolvedFileName, deferWatchingNonRelativeResolution);
860+
watchResolution(resolution, path, getResolutionWithResolvedFileName);
866861
if (existingResolution) {
867862
stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolutionWithResolvedFileName);
868863
}
@@ -1019,7 +1014,6 @@ export function createResolutionCache(
10191014
typeReferenceDirectiveResolutionCache,
10201015
),
10211016
getResolutionWithResolvedFileName: getResolvedTypeReferenceDirectiveFromResolution,
1022-
deferWatchingNonRelativeResolution: false,
10231017
});
10241018
}
10251019

@@ -1050,7 +1044,6 @@ export function createResolutionCache(
10501044
moduleResolutionCache,
10511045
),
10521046
getResolutionWithResolvedFileName: getResolvedModuleFromResolution,
1053-
deferWatchingNonRelativeResolution: true, // Defer non relative resolution watch because we could be using ambient modules
10541047
onNewResolution,
10551048
});
10561049
}
@@ -1067,7 +1060,7 @@ export function createResolutionCache(
10671060
const existingResolution = resolution;
10681061
resolution = ts_resolveLibrary(libraryName, resolveFrom, options, host, libraryResolutionCache);
10691062
const path = resolutionHost.toPath(resolveFrom);
1070-
watchFailedLookupLocationsOfExternalModuleResolutions(libraryName, resolution, path, getResolvedModuleFromResolution, /*deferWatchingNonRelativeResolution*/ false);
1063+
watchResolution(resolution, path, getResolvedModuleFromResolution);
10711064
resolvedLibraries.set(libFileName, resolution);
10721065
if (existingResolution) {
10731066
stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolvedModuleFromResolution);
@@ -1116,25 +1109,19 @@ export function createResolutionCache(
11161109
return endsWith(dirPath, "/node_modules/@types");
11171110
}
11181111

1119-
function watchFailedLookupLocationsOfExternalModuleResolutions<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
1120-
name: string,
1112+
function watchResolution<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
11211113
resolution: T,
11221114
filePath: Path,
11231115
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
1124-
deferWatchingNonRelativeResolution: boolean,
11251116
) {
11261117
(resolution.files ??= new Set()).add(filePath);
1118+
watchFailedLookupLocationOfResolution(resolution);
1119+
watchAffectingLocationsOfResolution(resolution);
11271120
if (resolution.files.size !== 1) return;
11281121

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

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

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

1177-
let setAtRoot = false;
1178-
if (failedLookupLocations) {
1179-
for (const failedLookupLocation of failedLookupLocations) {
1180-
setAtRoot = watchFailedLookupLocation(failedLookupLocation, setAtRoot);
1181-
}
1169+
let setAtRoot = !!resolution.setAtRoot;
1170+
for (let i = watchedFailed || 0; i < failedLookupLocations!.length; i++) {
1171+
setAtRoot = watchFailedLookupLocation(failedLookupLocations![i], setAtRoot);
11821172
}
1183-
if (node10Result) setAtRoot = watchFailedLookupLocation(node10Result, setAtRoot);
1184-
if (setAtRoot) {
1173+
if (!watchedFailed && node10Result) setAtRoot = watchFailedLookupLocation(node10Result, setAtRoot);
1174+
if (!resolution.setAtRoot && setAtRoot) {
11851175
// This is always non recursive
11861176
setDirectoryWatcher(rootDir, rootPath, /*nonRecursive*/ true);
11871177
}
1188-
watchAffectingLocationsOfResolution(resolution, !failedLookupLocations?.length && !node10Result);
1178+
resolution.watchedFailed = failedLookupLocations?.length;
1179+
resolution.setAtRoot = setAtRoot;
11891180
}
11901181

1191-
function watchAffectingLocationsOfResolution(resolution: ResolutionWithFailedLookupLocations, addToResolutionsWithOnlyAffectingLocations: boolean) {
1182+
function watchAffectingLocationsOfResolution(resolution: ResolutionWithFailedLookupLocations) {
11921183
Debug.assert(!!resolution.files?.size);
1193-
const { affectingLocations } = resolution;
1194-
if (!affectingLocations?.length) return;
1195-
if (addToResolutionsWithOnlyAffectingLocations) resolutionsWithOnlyAffectingLocations.add(resolution);
1184+
const { affectingLocations, watchedAffected } = resolution;
1185+
if (affectingLocations?.length === watchedAffected) return;
1186+
if (!watchedAffected && !resolution.watchedFailed) resolutionsWithOnlyAffectingLocations.add(resolution);
11961187
// Watch package json
1197-
for (const affectingLocation of affectingLocations) {
1198-
createFileWatcherOfAffectingLocation(affectingLocation, /*forResolution*/ true);
1188+
for (let i = watchedAffected || 0; i < affectingLocations!.length; i++) {
1189+
createFileWatcherOfAffectingLocation(affectingLocations![i], /*forResolution*/ true);
11991190
}
1191+
resolution.watchedAffected = affectingLocations?.length;
12001192
}
12011193

12021194
function createFileWatcherOfAffectingLocation(affectingLocation: string, forResolution: boolean) {
@@ -1264,11 +1256,6 @@ export function createResolutionCache(
12641256
packageJsonMap?.delete(resolutionHost.toPath(path));
12651257
}
12661258

1267-
function watchFailedLookupLocationOfNonRelativeModuleResolutions() {
1268-
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfResolution);
1269-
nonRelativeExternalModuleResolutions.clear();
1270-
}
1271-
12721259
function setDirectoryWatcher(dir: string, dirPath: Path, nonRecursive?: boolean) {
12731260
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
12741261
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)