Always include parent folder failed lookup locations

This commit is contained in:
Ryan Cavanaugh 2018-03-23 14:42:16 -07:00
parent 51edf13b3b
commit a507246ea9
3 changed files with 46 additions and 4 deletions

View File

@ -1118,7 +1118,7 @@ namespace ts {
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
return forEachAncestorDirectory(normalizeSlashes(directory), ancestorDirectory => {
if (getBaseFileName(ancestorDirectory) !== "node_modules") {
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state.traceEnabled, state.host);
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state.traceEnabled, state.host, failedLookupLocations);
if (resolutionFromCache) {
return resolutionFromCache;
}
@ -1196,12 +1196,13 @@ namespace ts {
typesPackageName;
}
function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, traceEnabled: boolean, host: ModuleResolutionHost): SearchResult<Resolved> {
function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, traceEnabled: boolean, host: ModuleResolutionHost, failedLookupLocations: Push<string>): SearchResult<Resolved> {
const result = cache && cache.get(containingDirectory);
if (result) {
if (traceEnabled) {
trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
}
failedLookupLocations.push(...result.failedLookupLocations);
return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } };
}
}
@ -1226,7 +1227,7 @@ namespace ts {
if (!isExternalModuleNameRelative(moduleName)) {
// Climb up parent directories looking for a module.
const resolved = forEachAncestorDirectory(containingDirectory, directory => {
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, traceEnabled, host);
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, traceEnabled, host, failedLookupLocations);
if (resolutionFromCache) {
return resolutionFromCache;
}

View File

@ -16,7 +16,7 @@ namespace ts {
export function checkResolvedModuleWithFailedLookupLocations(actual: ResolvedModuleWithFailedLookupLocations, expectedResolvedModule: ResolvedModuleFull, expectedFailedLookupLocations: string[]): void {
assert.isTrue(actual.resolvedModule !== undefined, "module should be resolved");
checkResolvedModule(actual.resolvedModule, expectedResolvedModule);
assert.deepEqual(actual.failedLookupLocations, expectedFailedLookupLocations);
assert.deepEqual(actual.failedLookupLocations, expectedFailedLookupLocations, `Failed lookup locations should match - expected has ${expectedFailedLookupLocations.length}, actual has ${actual.failedLookupLocations.length}`);
}
export function createResolvedModule(resolvedFileName: string, isExternalLibraryImport = false): ResolvedModuleFull {

View File

@ -6045,6 +6045,47 @@ namespace ts.projectSystem {
});
});
describe("Subfolder invalidations correctly include parent folder failed lookup locations", () => {
it("Includes the parent folder FLLs", () => {
const projectLocation = "/proj";
const file1: FileOrFolder = {
path: `${projectLocation}/foo/boo/app.ts`,
content: `import * as debug from "debug"`
};
const file2: FileOrFolder = {
path: `${projectLocation}/foo/boo/moo/app.ts`,
content: `import * as debug from "debug"`
};
const tsconfig: FileOrFolder = {
path: `${projectLocation}/tsconfig.json`,
content: JSON.stringify({
files: ["foo/boo/app.ts", "foo/boo/moo/app.ts"]
})
};
const files = [file1, file2, tsconfig, libFile];
const host = createServerHost(files);
const service = createProjectService(host);
service.openClientFile(file1.path);
const project = service.configuredProjects.get(tsconfig.path);
checkProjectActualFiles(project, files.map(f => f.path));
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file1.path).map(diag => diag.messageText), ["Cannot find module 'debug'."]);
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file2.path).map(diag => diag.messageText), ["Cannot find module 'debug'."]);
const debugTypesFile: FileOrFolder = {
path: `${projectLocation}/node_modules/debug/index.d.ts`,
content: "export {}"
};
files.push(debugTypesFile);
host.reloadFS(files);
host.runQueuedTimeoutCallbacks();
checkProjectActualFiles(project, files.map(f => f.path));
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file1.path).map(diag => diag.messageText), []);
assert.deepEqual(project.getLanguageService().getSemanticDiagnostics(file2.path).map(diag => diag.messageText), []);
});
});
describe("Verify npm install in directory with tsconfig file works when", () => {
function verifyNpmInstall(timeoutDuringPartialInstallation: boolean) {
const root = "/user/username/rootfolder/otherfolder";