Skip to content

Commit 02e93ca

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 0226520 commit 02e93ca

File tree

101 files changed

+362
-366
lines changed

Some content is hidden

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

101 files changed

+362
-366
lines changed

src/compiler/resolutionCache.ts

Lines changed: 34 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,10 @@ export interface ResolutionCache extends Required<CompilerHostSupportingResoluti
106106
startRecordingFilesWithChangedResolutions(): void;
107107
finishRecordingFilesWithChangedResolutions(): Path[] | undefined;
108108

109-
watchFailedLookupLocationsOfExternalModuleResolutions<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
110-
name: string,
109+
watchResolution<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
111110
resolution: T,
112111
filePath: Path,
113112
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
114-
deferWatchingNonRelativeResolution: boolean,
115113
): void;
116114

117115
resolveModuleNameLiterals(
@@ -171,10 +169,13 @@ export interface ResolutionCache extends Required<CompilerHostSupportingResoluti
171169
export interface ResolutionWithFailedLookupLocations {
172170
failedLookupLocations?: string[];
173171
affectingLocations?: string[];
172+
node10Result?: string;
174173
isInvalidated?: boolean;
175174
// Files that have this resolution using
176175
files?: Set<Path>;
177-
node10Result?: string;
176+
watchedFailed?: number;
177+
watchedAffected?: number;
178+
setAtRoot?: boolean;
178179
}
179180

180181
/** @internal */
@@ -501,7 +502,6 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
501502
let filesWithChangedSetOfUnresolvedImports: Path[] | undefined;
502503
let filesWithInvalidatedResolutions: Set<Path> | undefined;
503504
let filesWithInvalidatedNonRelativeUnresolvedImports: ReadonlyMap<Path, readonly string[]> | undefined;
504-
const nonRelativeExternalModuleResolutions = new Set<ResolutionWithFailedLookupLocations>();
505505

506506
const resolutionsWithFailedLookups = new Set<ResolutionWithFailedLookupLocations>();
507507
const resolutionsWithOnlyAffectingLocations = new Set<ResolutionWithFailedLookupLocations>();
@@ -564,7 +564,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
564564
resolutionsWithOnlyAffectingLocations,
565565
directoryWatchesOfFailedLookups,
566566
fileWatchesOfAffectingLocations,
567-
watchFailedLookupLocationsOfExternalModuleResolutions,
567+
watchResolution,
568568
getModuleResolutionCache: () => moduleResolutionCache,
569569
startRecordingFilesWithChangedResolutions,
570570
finishRecordingFilesWithChangedResolutions,
@@ -603,7 +603,6 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
603603
function clear() {
604604
clearMap(directoryWatchesOfFailedLookups, closeFileWatcherOf);
605605
clearMap(fileWatchesOfAffectingLocations, closeFileWatcherOf);
606-
nonRelativeExternalModuleResolutions.clear();
607606
closeTypeRootsWatch();
608607
resolvedModuleNames.clear();
609608
resolvedTypeReferenceDirectives.clear();
@@ -678,7 +677,6 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
678677
libraryResolutionCache.clearAllExceptPackageJsonInfoCache();
679678
// perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
680679
// (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
681-
watchFailedLookupLocationOfNonRelativeModuleResolutions();
682680
}
683681

684682
function cleanupLibResolutionWatching(newProgram: Program | undefined) {
@@ -697,7 +695,6 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
697695
function finishCachingPerDirectoryResolution(newProgram: Program | undefined, oldProgram: Program | undefined) {
698696
filesWithInvalidatedNonRelativeUnresolvedImports = undefined;
699697
allModuleAndTypeResolutionsAreInvalidated = false;
700-
watchFailedLookupLocationOfNonRelativeModuleResolutions();
701698
// Update file watches
702699
if (newProgram !== oldProgram) {
703700
cleanupLibResolutionWatching(newProgram);
@@ -754,12 +751,11 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
754751
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>;
755752
shouldRetryResolution: (t: T) => boolean;
756753
logChanges?: boolean;
757-
deferWatchingNonRelativeResolution: boolean;
758754
}
759755
function resolveNamesWithLocalCache<Entry, SourceFile, T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>({
760756
entries, containingFile, containingSourceFile, redirectedReference, options,
761757
perFileCache, reusedNames, ambientModuleNames,
762-
loader, getResolutionWithResolvedFileName, deferWatchingNonRelativeResolution,
758+
loader, getResolutionWithResolvedFileName,
763759
shouldRetryResolution, logChanges,
764760
}: ResolveNamesWithLocalCacheInput<Entry, SourceFile, T, R>): readonly T[] {
765761
const path = resolutionHost.toPath(containingFile);
@@ -791,7 +787,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
791787
}
792788
resolutionsInFile.set(name, mode, resolution);
793789
if (resolution !== existingResolution) {
794-
watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution, path, getResolutionWithResolvedFileName, deferWatchingNonRelativeResolution);
790+
watchResolution(resolution, path, getResolutionWithResolvedFileName);
795791
if (existingResolution) {
796792
stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolutionWithResolvedFileName);
797793
}
@@ -887,7 +883,6 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
887883
),
888884
getResolutionWithResolvedFileName: getResolvedTypeReferenceDirective,
889885
shouldRetryResolution: resolution => resolution.resolvedTypeReferenceDirective === undefined,
890-
deferWatchingNonRelativeResolution: false,
891886
});
892887
}
893888

@@ -919,7 +914,6 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
919914
getResolutionWithResolvedFileName: getResolvedModule,
920915
shouldRetryResolution: resolution => !resolution.resolvedModule || !resolutionExtensionIsTSOrJson(resolution.resolvedModule.extension),
921916
logChanges: logChangesWhenResolvingModule,
922-
deferWatchingNonRelativeResolution: true, // Defer non relative resolution watch because we could be using ambient modules
923917
});
924918
}
925919

@@ -935,7 +929,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
935929
const existingResolution = resolution;
936930
resolution = ts_resolveLibrary(libraryName, resolveFrom, options, host, libraryResolutionCache);
937931
const path = resolutionHost.toPath(resolveFrom);
938-
watchFailedLookupLocationsOfExternalModuleResolutions(libraryName, resolution, path, getResolvedModule, /*deferWatchingNonRelativeResolution*/ false);
932+
watchResolution(resolution, path, getResolvedModule);
939933
resolvedLibraries.set(libFileName, resolution);
940934
if (existingResolution) {
941935
stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolvedModule);
@@ -1066,21 +1060,15 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
10661060
return endsWith(dirPath, "/node_modules/@types");
10671061
}
10681062

1069-
function watchFailedLookupLocationsOfExternalModuleResolutions<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
1070-
name: string,
1063+
function watchResolution<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
10711064
resolution: T,
10721065
filePath: Path,
10731066
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
1074-
deferWatchingNonRelativeResolution: boolean,
10751067
) {
10761068
(resolution.files ??= new Set()).add(filePath);
1069+
watchFailedLookupLocationOfResolution(resolution);
1070+
watchAffectingLocationsOfResolution(resolution);
10771071
if (resolution.files.size !== 1) return;
1078-
if (!deferWatchingNonRelativeResolution || isExternalModuleNameRelative(name)) {
1079-
watchFailedLookupLocationOfResolution(resolution);
1080-
}
1081-
else {
1082-
nonRelativeExternalModuleResolutions.add(resolution);
1083-
}
10841072
const resolved = getResolutionWithResolvedFileName(resolution);
10851073
if (resolved && resolved.resolvedFileName) {
10861074
const key = resolutionHost.toPath(resolved.resolvedFileName);
@@ -1116,33 +1104,38 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
11161104
function watchFailedLookupLocationOfResolution(resolution: ResolutionWithFailedLookupLocations) {
11171105
Debug.assert(!!resolution.files?.size);
11181106

1119-
const { failedLookupLocations, affectingLocations, node10Result } = resolution;
1120-
if (!failedLookupLocations?.length && !affectingLocations?.length && !node10Result) return;
1121-
if (failedLookupLocations?.length || node10Result) resolutionsWithFailedLookups.add(resolution);
1107+
const { failedLookupLocations, node10Result, watchedFailed } = resolution;
1108+
// There have to be failed lookup locations if there is node10Result so storing failedLookupLocation length is good enough,
1109+
// node10Result doesnt change later only failed lookup locations get added on
1110+
if (watchedFailed === failedLookupLocations?.length) return;
1111+
if (!watchedFailed) {
1112+
resolutionsWithFailedLookups.add(resolution);
1113+
if (resolution.watchedAffected) resolutionsWithOnlyAffectingLocations.delete(resolution);
1114+
}
11221115

1123-
let setAtRoot = false;
1124-
if (failedLookupLocations) {
1125-
for (const failedLookupLocation of failedLookupLocations) {
1126-
setAtRoot = watchFailedLookupLocation(failedLookupLocation, setAtRoot);
1127-
}
1116+
let setAtRoot = !!resolution.setAtRoot;
1117+
for (let i = watchedFailed || 0; i < failedLookupLocations!.length; i++) {
1118+
setAtRoot = watchFailedLookupLocation(failedLookupLocations![i], setAtRoot);
11281119
}
1129-
if (node10Result) setAtRoot = watchFailedLookupLocation(node10Result, setAtRoot);
1130-
if (setAtRoot) {
1120+
if (!watchedFailed && node10Result) setAtRoot = watchFailedLookupLocation(node10Result, setAtRoot);
1121+
if (!resolution.setAtRoot && setAtRoot) {
11311122
// This is always non recursive
11321123
setDirectoryWatcher(rootDir, rootPath, /*nonRecursive*/ true);
11331124
}
1134-
watchAffectingLocationsOfResolution(resolution, !failedLookupLocations?.length && !node10Result);
1125+
resolution.watchedFailed = failedLookupLocations?.length;
1126+
resolution.setAtRoot = setAtRoot;
11351127
}
11361128

1137-
function watchAffectingLocationsOfResolution(resolution: ResolutionWithFailedLookupLocations, addToResolutionsWithOnlyAffectingLocations: boolean) {
1129+
function watchAffectingLocationsOfResolution(resolution: ResolutionWithFailedLookupLocations) {
11381130
Debug.assert(!!resolution.files?.size);
1139-
const { affectingLocations } = resolution;
1140-
if (!affectingLocations?.length) return;
1141-
if (addToResolutionsWithOnlyAffectingLocations) resolutionsWithOnlyAffectingLocations.add(resolution);
1131+
const { affectingLocations, watchedAffected } = resolution;
1132+
if (affectingLocations?.length === watchedAffected) return;
1133+
if (!watchedAffected && !resolution.watchedFailed) resolutionsWithOnlyAffectingLocations.add(resolution);
11421134
// Watch package json
1143-
for (const affectingLocation of affectingLocations) {
1144-
createFileWatcherOfAffectingLocation(affectingLocation, /*forResolution*/ true);
1135+
for (let i = watchedAffected || 0; i < affectingLocations!.length; i++) {
1136+
createFileWatcherOfAffectingLocation(affectingLocations![i], /*forResolution*/ true);
11451137
}
1138+
resolution.watchedAffected = affectingLocations?.length;
11461139
}
11471140

11481141
function createFileWatcherOfAffectingLocation(affectingLocation: string, forResolution: boolean) {
@@ -1210,11 +1203,6 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
12101203
packageJsonMap?.delete(resolutionHost.toPath(path));
12111204
}
12121205

1213-
function watchFailedLookupLocationOfNonRelativeModuleResolutions() {
1214-
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfResolution);
1215-
nonRelativeExternalModuleResolutions.clear();
1216-
}
1217-
12181206
function setDirectoryWatcher(dir: string, dirPath: Path, nonRecursive?: boolean) {
12191207
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
12201208
if (dirWatcher) {

src/harness/incrementalUtils.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,6 @@ export function verifyResolutionCache(
204204
path,
205205
resolutions,
206206
getResolvedModuleFileName,
207-
/*deferWatchingNonRelativeResolution*/ true,
208207
expected.resolvedModuleNames,
209208
actualProgram.getSourceFileByPath(path)!.resolvedModules,
210209
));
@@ -213,7 +212,6 @@ export function verifyResolutionCache(
213212
path,
214213
resolutions,
215214
getResolvedTypeRefFileName,
216-
/*deferWatchingNonRelativeResolution*/ false,
217215
expected.resolvedTypeReferenceDirectives,
218216
path !== inferredTypesPath ?
219217
actualProgram.getSourceFileByPath(path)!.resolvedTypeReferenceDirectiveNames :
@@ -229,7 +227,6 @@ export function verifyResolutionCache(
229227
getResolvedModuleFileName(resolved),
230228
ts.getLibraryNameFromLibFileName(libFileName),
231229
/*mode*/ undefined,
232-
/*deferWatchingNonRelativeResolution*/ false,
233230
);
234231
expected.resolvedLibraries.set(libFileName, expectedResolution);
235232
});
@@ -257,7 +254,20 @@ export function verifyResolutionCache(
257254
!resolution.isInvalidated,
258255
`${projectName}:: Resolution should not be invalidated`
259256
);
260-
verifySet(resolutionToExpected.get(resolution)!.files, resolution.files, `Resolution files`);
257+
const expected = resolutionToExpected.get(resolution)!;
258+
verifySet(expected.files, resolution.files, `Resolution files`);
259+
ts.Debug.assert(
260+
expected.watchedFailed === resolution.watchedFailed,
261+
`${projectName}:: Expected watchedFailed of Resolution ${expected.watchedFailed} but got ${resolution.watchedFailed}`
262+
);
263+
ts.Debug.assert(
264+
expected.watchedAffected === resolution.watchedAffected,
265+
`${projectName}:: Expected watchedAffected of Resolution ${expected.watchedAffected} but got ${resolution.watchedAffected}`
266+
);
267+
ts.Debug.assert(
268+
expected.setAtRoot === resolution.setAtRoot,
269+
`${projectName}:: Expected setAtRoot of Resolution ${expected.setAtRoot} but got ${resolution.setAtRoot}`
270+
);
261271
});
262272
verifyMapOfResolutionSet(expected.resolvedFileToResolution, actual.resolvedFileToResolution, `resolvedFileToResolution`);
263273
verifyResolutionSet(expected.resolutionsWithFailedLookups, actual.resolutionsWithFailedLookups, `resolutionsWithFailedLookups`);
@@ -299,7 +309,6 @@ export function verifyResolutionCache(
299309
fileName: ts.Path,
300310
cache: ts.ModeAwareCache<T> | undefined,
301311
getResolvedFileName: (resolution: T) => string | undefined,
302-
deferWatchingNonRelativeResolution: boolean,
303312
storeExpcted: Map<ts.Path, ts.ModeAwareCache<ts.ResolutionWithFailedLookupLocations>>,
304313
fromProgramResolutions: ts.ModeAwareCache<T> | undefined,
305314
) {
@@ -310,7 +319,7 @@ export function verifyResolutionCache(
310319
let expectedCache: ts.ModeAwareCache<ts.ResolutionWithFailedLookupLocations> | undefined;
311320
cache?.forEach((resolved, name, mode) => {
312321
const resolvedFileName = getResolvedFileName(resolved);
313-
const expected = collectResolution(cacheType, fileName, resolved, resolvedFileName, name, mode, deferWatchingNonRelativeResolution);
322+
const expected = collectResolution(cacheType, fileName, resolved, resolvedFileName, name, mode);
314323
if (!expectedCache) storeExpcted.set(fileName, expectedCache = ts.createModeAwareCache());
315324
expectedCache.set(name, mode, expected);
316325
// Resolution in program should be same as in resolution cache
@@ -326,7 +335,6 @@ export function verifyResolutionCache(
326335
resolvedFileName: string | undefined,
327336
name: string,
328337
mode: ts.ResolutionMode,
329-
deferWatchingNonRelativeResolution: boolean,
330338
): ExpectedResolution {
331339
const existing = resolutionToRefs.get(resolved);
332340
let expectedResolution: ExpectedResolution;
@@ -346,7 +354,7 @@ export function verifyResolutionCache(
346354
expectedToResolution.set(expectedResolution, resolved);
347355
resolutionToExpected.set(resolved, expectedResolution);
348356
}
349-
expected.watchFailedLookupLocationsOfExternalModuleResolutions(name, expectedResolution, fileName, () => ({ resolvedFileName }), deferWatchingNonRelativeResolution);
357+
expected.watchResolution(expectedResolution, fileName, () => ({ resolvedFileName }));
350358
return expectedResolution;
351359
}
352360

0 commit comments

Comments
 (0)