From 95082e47432d4470190eeb6e76cee9c548be68f5 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Wed, 8 Aug 2018 20:29:59 +0200 Subject: [PATCH] make it work for root directory --- src/compiler/moduleNameResolver.ts | 32 +++++------ src/testRunner/unittests/moduleResolution.ts | 59 +++++++++++++++++++- 2 files changed, 73 insertions(+), 18 deletions(-) diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index b3ff0951166..5a288090e2f 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -407,7 +407,7 @@ namespace ts { // directory: /a/b/c/d/e // resolvedFileName: /a/b/foo.d.ts const commonPrefix = getCommonPrefix(path, resolvedFileName); - if (commonPrefix === undefined) { + if (!commonPrefix) { return; } let current = path; @@ -427,23 +427,21 @@ namespace ts { } const resolutionDirectory = toPath(getDirectoryPath(resolution), currentDirectory, getCanonicalFileName); - // find first position where directory and resolution differs - let i = 0; - while (i < Math.min(directory.length, resolutionDirectory.length) && directory.charCodeAt(i) === resolutionDirectory.charCodeAt(i)) { - i++; + let current = directory; + let parent = getDirectoryPath(current); + while ( + // keep going until we find a matching prefix + !startsWith(resolutionDirectory, current) || + // keep going if the prefix is not a complete directory segment, e.g. '/dir' as prefix of '/directory' + resolutionDirectory.length > current.length && resolutionDirectory[current.length] !== directorySeparator && current !== parent + ) { + if (current === parent) { + return undefined; + } + current = parent; + parent = getDirectoryPath(current); } - - if (i === directory.length && resolutionDirectory.length > i && resolutionDirectory[i] === directorySeparator) { - return directory; - } - - // find last directory separator before position i - const sep = directory.lastIndexOf(directorySeparator, i); - if (sep < 0) { - return undefined; - } - - return directory.substr(0, sep); + return current; } } } diff --git a/src/testRunner/unittests/moduleResolution.ts b/src/testRunner/unittests/moduleResolution.ts index 5f8251afb0a..a027f7215ed 100644 --- a/src/testRunner/unittests/moduleResolution.ts +++ b/src/testRunner/unittests/moduleResolution.ts @@ -195,7 +195,8 @@ namespace ts { describe("Node module resolution - non-relative paths", () => { it("computes correct commonPrefix for moduleName cache", () => { - const cache = createModuleResolutionCache("/", (f) => f).getOrCreateCacheForModuleName("a"); + const resolutionCache = createModuleResolutionCache("/", (f) => f); + let cache = resolutionCache.getOrCreateCacheForModuleName("a"); cache.set("/sub", { resolvedModule: { originalPath: undefined, @@ -207,6 +208,62 @@ namespace ts { }); assert.isDefined(cache.get("/sub")); assert.isUndefined(cache.get("/")); + + cache = resolutionCache.getOrCreateCacheForModuleName("b"); + cache.set("/sub/dir/foo", { + resolvedModule: { + originalPath: undefined, + resolvedFileName: "/sub/directory/node_modules/b/index.ts", + isExternalLibraryImport: true, + extension: Extension.Ts, + }, + failedLookupLocations: [], + }); + assert.isDefined(cache.get("/sub/dir/foo")); + assert.isDefined(cache.get("/sub/dir")); + assert.isDefined(cache.get("/sub")); + assert.isUndefined(cache.get("/")); + + cache = resolutionCache.getOrCreateCacheForModuleName("c"); + cache.set("/foo/bar", { + resolvedModule: { + originalPath: undefined, + resolvedFileName: "/bar/node_modules/c/index.ts", + isExternalLibraryImport: true, + extension: Extension.Ts, + }, + failedLookupLocations: [], + }); + assert.isDefined(cache.get("/foo/bar")); + assert.isDefined(cache.get("/foo")); + assert.isDefined(cache.get("/")); + + cache = resolutionCache.getOrCreateCacheForModuleName("d"); + cache.set("/foo", { + resolvedModule: { + originalPath: undefined, + resolvedFileName: "/foo/index.ts", + isExternalLibraryImport: true, + extension: Extension.Ts, + }, + failedLookupLocations: [], + }); + assert.isDefined(cache.get("/foo")); + assert.isUndefined(cache.get("/")); + + cache = resolutionCache.getOrCreateCacheForModuleName("e"); + cache.set("c:/foo", { + resolvedModule: { + originalPath: undefined, + resolvedFileName: "d:/bar/node_modules/e/index.ts", + isExternalLibraryImport: true, + extension: Extension.Ts, + }, + failedLookupLocations: [], + }); + assert.isDefined(cache.get("c:/foo")); + assert.isUndefined(cache.get("c:/")); + assert.isUndefined(cache.get("d:/")); }); it("load module as file - ts files not loaded", () => {