Skip to content

Commit 1e66f07

Browse files
committed
Always include parent folder failed lookup locations
1 parent ab8233c commit 1e66f07

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-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

+41
Original file line numberDiff line numberDiff line change
@@ -6045,6 +6045,47 @@ namespace ts.projectSystem {
60456045
});
60466046
});
60476047

6048+
describe("Subfolder invalidations correctly include parent folder failed lookup locations QJWOP", () => {
6049+
it("Includes the parent folder FLLs", () => {
6050+
const projectLocation = "/proj";
6051+
const file1: FileOrFolder = {
6052+
path: `${projectLocation}/foo/boo/app.ts`,
6053+
content: `import * as debug from "debug"`
6054+
};
6055+
const file2: FileOrFolder = {
6056+
path: `${projectLocation}/foo/boo/moo/app.ts`,
6057+
content: `import * as debug from "debug"`
6058+
};
6059+
const tsconfig: FileOrFolder = {
6060+
path: `${projectLocation}/tsconfig.json`,
6061+
content: JSON.stringify({
6062+
files: ["foo/boo/app.ts", "foo/boo/moo/app.ts"]
6063+
})
6064+
};
6065+
6066+
const files = [file1, file2, tsconfig, libFile];
6067+
const host = createServerHost(files);
6068+
const service = createProjectService(host);
6069+
service.openClientFile(file1.path);
6070+
6071+
const project = service.configuredProjects.get(tsconfig.path);
6072+
checkProjectActualFiles(project, files.map(f => f.path));
6073+
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file1.path).map(diag => diag.messageText), ["Cannot find module 'debug'."]);
6074+
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file2.path).map(diag => diag.messageText), ["Cannot find module 'debug'."]);
6075+
6076+
const debugTypesFile: FileOrFolder = {
6077+
path: `${projectLocation}/node_modules/debug/index.d.ts`,
6078+
content: "export {}"
6079+
};
6080+
files.push(debugTypesFile);
6081+
host.reloadFS(files);
6082+
host.runQueuedTimeoutCallbacks();
6083+
checkProjectActualFiles(project, files.map(f => f.path));
6084+
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file1.path).map(diag => diag.messageText), []);
6085+
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file2.path).map(diag => diag.messageText), []);
6086+
});
6087+
});
6088+
60486089
describe("Verify npm install in directory with tsconfig file works when", () => {
60496090
function verifyNpmInstall(timeoutDuringPartialInstallation: boolean) {
60506091
const root = "/user/username/rootfolder/otherfolder";

0 commit comments

Comments
 (0)