From fb3af6549df6fc15847ae76183afa409d8f046f2 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 7 Jun 2018 13:36:24 -0700 Subject: [PATCH] Do not watch folders like "c:/users/username", "c:/users/username/folderAtRoot" Fixes Microsoft/vscode#51139 --- src/compiler/resolutionCache.ts | 37 +++++++++++++------ .../unittests/tsserverProjectSystem.ts | 22 ++++++++--- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index dea5463b2ffef..e3fd6b2d42c87 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -352,8 +352,32 @@ namespace ts { return endsWith(dirPath, "/node_modules/@types"); } - function isDirectoryAtleastAtLevelFromFSRoot(dirPath: Path, minLevels: number) { - for (let searchIndex = getRootLength(dirPath); minLevels > 0; minLevels--) { + /** + * Filter out paths like + * "/", "/user", "/user/username", "/user/username/folderAtRoot", + * "c:/", "c:/users", "c:/users/username", "c:/users/username/folderAtRoot", "c:/folderAtRoot" + * @param dirPath + */ + function canWatchDirectory(dirPath: Path) { + const rootLength = getRootLength(dirPath); + if (dirPath.length === rootLength) { + // Ignore "/", "c:/" + return false; + } + + const nextDirectorySeparator = dirPath.indexOf(directorySeparator, rootLength); + if (nextDirectorySeparator === -1) { + // ignore "/user", "c:/users" or "c:/folderAtRoot" + return false; + } + + if (dirPath.charCodeAt(0) !== CharacterCodes.slash && + dirPath.substr(rootLength, nextDirectorySeparator).search(/users/i) === -1) { + // Paths like c:/folderAtRoot/subFolder are allowed + return true; + } + + for (let searchIndex = nextDirectorySeparator + 1, searchLevels = 2; searchLevels > 0; searchLevels--) { searchIndex = dirPath.indexOf(directorySeparator, searchIndex) + 1; if (searchIndex === 0) { // Folder isnt at expected minimun levels @@ -363,15 +387,6 @@ namespace ts { return true; } - function canWatchDirectory(dirPath: Path) { - return isDirectoryAtleastAtLevelFromFSRoot(dirPath, - // When root is "/" do not watch directories like: - // "/", "/user", "/user/username", "/user/username/folderAtRoot" - // When root is "c:/" do not watch directories like: - // "c:/", "c:/folderAtRoot" - dirPath.charCodeAt(0) === CharacterCodes.slash ? 3 : 1); - } - function filterFSRootDirectoriesToWatch(watchPath: DirectoryOfFailedLookupWatch, dirPath: Path): DirectoryOfFailedLookupWatch { if (!canWatchDirectory(dirPath)) { watchPath.ignore = true; diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index f3bcbc4584553..e1c6fb3521b9f 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -7566,8 +7566,8 @@ namespace ts.projectSystem { }); describe("tsserverProjectSystem Watched recursive directories with windows style file system", () => { - function verifyWatchedDirectories(useProjectAtRoot: boolean) { - const root = useProjectAtRoot ? "c:/" : "c:/myfolder/allproject/"; + function verifyWatchedDirectories(rootedPath: string, useProjectAtRoot: boolean) { + const root = useProjectAtRoot ? rootedPath : `${rootedPath}myfolder/allproject/`; const configFile: File = { path: root + "project/tsconfig.json", content: "{}" @@ -7596,12 +7596,22 @@ namespace ts.projectSystem { ].concat(useProjectAtRoot ? [] : [root + nodeModulesAtTypes]), /*recursive*/ true); } - it("When project is in rootFolder", () => { - verifyWatchedDirectories(/*useProjectAtRoot*/ true); + function verifyRootedDirectoryWatch(rootedPath: string) { + it("When project is in rootFolder of style c:/", () => { + verifyWatchedDirectories(rootedPath, /*useProjectAtRoot*/ true); + }); + + it("When files at some folder other than root", () => { + verifyWatchedDirectories(rootedPath, /*useProjectAtRoot*/ false); + }); + } + + describe("for rootFolder of style c:/", () => { + verifyRootedDirectoryWatch("c:/"); }); - it("When files at some folder other than root", () => { - verifyWatchedDirectories(/*useProjectAtRoot*/ false); + describe("for rootFolder of style c:/users/username", () => { + verifyRootedDirectoryWatch("c:/users/username/"); }); });