Skip to content

Commit e7b2017

Browse files
Merge pull request microsoft#22744 from RyanCavanaugh/fixCacheInvalidation
Fix cache invalidation
2 parents 0736554 + a69adf2 commit e7b2017

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
lines changed

src/compiler/moduleNameResolver.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1118,7 +1118,7 @@ namespace ts {
11181118
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
11191119
return forEachAncestorDirectory(normalizeSlashes(directory), ancestorDirectory => {
11201120
if (getBaseFileName(ancestorDirectory) !== "node_modules") {
1121-
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state.traceEnabled, state.host);
1121+
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state.traceEnabled, state.host, failedLookupLocations);
11221122
if (resolutionFromCache) {
11231123
return resolutionFromCache;
11241124
}
@@ -1196,12 +1196,13 @@ namespace ts {
11961196
typesPackageName;
11971197
}
11981198

1199-
function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, traceEnabled: boolean, host: ModuleResolutionHost): SearchResult<Resolved> {
1199+
function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, traceEnabled: boolean, host: ModuleResolutionHost, failedLookupLocations: Push<string>): SearchResult<Resolved> {
12001200
const result = cache && cache.get(containingDirectory);
12011201
if (result) {
12021202
if (traceEnabled) {
12031203
trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
12041204
}
1205+
failedLookupLocations.push(...result.failedLookupLocations);
12051206
return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } };
12061207
}
12071208
}
@@ -1226,7 +1227,7 @@ namespace ts {
12261227
if (!isExternalModuleNameRelative(moduleName)) {
12271228
// Climb up parent directories looking for a module.
12281229
const resolved = forEachAncestorDirectory(containingDirectory, directory => {
1229-
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, traceEnabled, host);
1230+
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, traceEnabled, host, failedLookupLocations);
12301231
if (resolutionFromCache) {
12311232
return resolutionFromCache;
12321233
}

src/harness/unittests/moduleResolution.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace ts {
1616
export function checkResolvedModuleWithFailedLookupLocations(actual: ResolvedModuleWithFailedLookupLocations, expectedResolvedModule: ResolvedModuleFull, expectedFailedLookupLocations: string[]): void {
1717
assert.isTrue(actual.resolvedModule !== undefined, "module should be resolved");
1818
checkResolvedModule(actual.resolvedModule, expectedResolvedModule);
19-
assert.deepEqual(actual.failedLookupLocations, expectedFailedLookupLocations);
19+
assert.deepEqual(actual.failedLookupLocations, expectedFailedLookupLocations, `Failed lookup locations should match - expected has ${expectedFailedLookupLocations.length}, actual has ${actual.failedLookupLocations.length}`);
2020
}
2121

2222
export function createResolvedModule(resolvedFileName: string, isExternalLibraryImport = false): ResolvedModuleFull {

src/harness/unittests/tsserverProjectSystem.ts

+49
Original file line numberDiff line numberDiff line change
@@ -6128,6 +6128,55 @@ namespace ts.projectSystem {
61286128
});
61296129
});
61306130

6131+
describe("Subfolder invalidations correctly include parent folder failed lookup locations", () => {
6132+
function runFailedLookupTest(resolution: "Node" | "Classic") {
6133+
const projectLocation = "/proj";
6134+
const file1: FileOrFolder = {
6135+
path: `${projectLocation}/foo/boo/app.ts`,
6136+
content: `import * as debug from "debug"`
6137+
};
6138+
const file2: FileOrFolder = {
6139+
path: `${projectLocation}/foo/boo/moo/app.ts`,
6140+
content: `import * as debug from "debug"`
6141+
};
6142+
const tsconfig: FileOrFolder = {
6143+
path: `${projectLocation}/tsconfig.json`,
6144+
content: JSON.stringify({
6145+
files: ["foo/boo/app.ts", "foo/boo/moo/app.ts"],
6146+
moduleResolution: resolution
6147+
})
6148+
};
6149+
6150+
const files = [file1, file2, tsconfig, libFile];
6151+
const host = createServerHost(files);
6152+
const service = createProjectService(host);
6153+
service.openClientFile(file1.path);
6154+
6155+
const project = service.configuredProjects.get(tsconfig.path);
6156+
checkProjectActualFiles(project, files.map(f => f.path));
6157+
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file1.path).map(diag => diag.messageText), ["Cannot find module 'debug'."]);
6158+
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file2.path).map(diag => diag.messageText), ["Cannot find module 'debug'."]);
6159+
6160+
const debugTypesFile: FileOrFolder = {
6161+
path: `${projectLocation}/node_modules/debug/index.d.ts`,
6162+
content: "export {}"
6163+
};
6164+
files.push(debugTypesFile);
6165+
host.reloadFS(files);
6166+
host.runQueuedTimeoutCallbacks();
6167+
checkProjectActualFiles(project, files.map(f => f.path));
6168+
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file1.path).map(diag => diag.messageText), []);
6169+
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file2.path).map(diag => diag.messageText), []);
6170+
}
6171+
6172+
it("Includes the parent folder FLLs in node module resolution mode", () => {
6173+
runFailedLookupTest("Node");
6174+
});
6175+
it("Includes the parent folder FLLs in classic module resolution mode", () => {
6176+
runFailedLookupTest("Classic");
6177+
});
6178+
});
6179+
61316180
describe("Verify npm install in directory with tsconfig file works when", () => {
61326181
function verifyNpmInstall(timeoutDuringPartialInstallation: boolean) {
61336182
const root = "/user/username/rootfolder/otherfolder";

0 commit comments

Comments
 (0)