Skip to content

Commit

Permalink
Merge branch 'master' into directoryWatcherInsteadOfFileWatch
Browse files Browse the repository at this point in the history
  • Loading branch information
sheetalkamat committed Oct 17, 2017
2 parents a5861af + 314172a commit bd0c210
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 76 deletions.
72 changes: 58 additions & 14 deletions src/compiler/resolutionCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ namespace ts {
interface DirectoryOfFailedLookupWatch {
dir: string;
dirPath: Path;
ignore?: true;
}

export const maxNumberOfFilesToIterateForInvalidation = 256;
Expand Down Expand Up @@ -319,6 +320,33 @@ namespace ts {
return endsWith(dirPath, "/node_modules");
}

function isDirectoryAtleastAtLevelFromFSRoot(dirPath: Path, minLevels: number) {
for (let searchIndex = getRootLength(dirPath); minLevels > 0; minLevels--) {
searchIndex = dirPath.indexOf(directorySeparator, searchIndex) + 1;
if (searchIndex === 0) {
// Folder isnt at expected minimun levels
return false;
}
}
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;
}
return watchPath;
}

function getDirectoryToWatchFailedLookupLocation(failedLookupLocation: string, failedLookupLocationPath: Path): DirectoryOfFailedLookupWatch {
if (isInDirectoryPath(rootPath, failedLookupLocationPath)) {
return { dir: rootDir, dirPath: rootPath };
Expand All @@ -335,7 +363,7 @@ namespace ts {

// If the directory is node_modules use it to watch
if (isNodeModulesDirectory(dirPath)) {
return { dir, dirPath };
return filterFSRootDirectoriesToWatch({ dir, dirPath }, getDirectoryPath(dirPath));
}

// Use some ancestor of the root directory
Expand All @@ -350,7 +378,7 @@ namespace ts {
}
}

return { dir, dirPath };
return filterFSRootDirectoriesToWatch({ dir, dirPath }, dirPath);
}

function isPathWithDefaultFailedLookupExtension(path: Path) {
Expand Down Expand Up @@ -391,13 +419,15 @@ namespace ts {
const refCount = customFailedLookupPaths.get(failedLookupLocationPath) || 0;
customFailedLookupPaths.set(failedLookupLocationPath, refCount + 1);
}
const { dir, dirPath } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
if (dirWatcher) {
dirWatcher.refCount++;
}
else {
directoryWatchesOfFailedLookups.set(dirPath, { watcher: createDirectoryWatcher(dir, dirPath), refCount: 1 });
const { dir, dirPath, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
if (!ignore) {
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
if (dirWatcher) {
dirWatcher.refCount++;
}
else {
directoryWatchesOfFailedLookups.set(dirPath, { watcher: createDirectoryWatcher(dir, dirPath), refCount: 1 });
}
}
}
}
Expand All @@ -422,10 +452,12 @@ namespace ts {
customFailedLookupPaths.set(failedLookupLocationPath, refCount - 1);
}
}
const { dirPath } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
// Do not close the watcher yet since it might be needed by other failed lookup locations.
dirWatcher.refCount--;
const { dirPath, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
if (!ignore) {
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
// Do not close the watcher yet since it might be needed by other failed lookup locations.
dirWatcher.refCount--;
}
}
}

Expand Down Expand Up @@ -577,7 +609,8 @@ namespace ts {
}

// we need to assume the directories exist to ensure that we can get all the type root directories that get included
const typeRoots = getEffectiveTypeRoots(options, { directoryExists: returnTrue, getCurrentDirectory });
// But filter directories that are at root level to say directory doesnt exist, so that we arent watching them
const typeRoots = getEffectiveTypeRoots(options, { directoryExists: directoryExistsForTypeRootWatch, getCurrentDirectory });
if (typeRoots) {
mutateMap(
typeRootsWatches,
Expand All @@ -592,5 +625,16 @@ namespace ts {
closeTypeRootsWatch();
}
}

/**
* Use this function to return if directory exists to get type roots to watch
* If we return directory exists then only the paths will be added to type roots
* Hence return true for all directories except root directories which are filtered from watching
*/
function directoryExistsForTypeRootWatch(nodeTypesDirectory: string) {
const dir = getDirectoryPath(getDirectoryPath(nodeTypesDirectory));
const dirPath = resolutionHost.toPath(dir);
return dirPath === rootPath || canWatchDirectory(dirPath);
}
}
}
4 changes: 2 additions & 2 deletions src/harness/unittests/tscWatchMode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ namespace ts.tscWatch {
checkProgramRootFiles(watch(), [file1.path, file2.path]);
checkWatchedFiles(host, [configFile.path, file1.path, file2.path, libFile.path]);
const configDir = getDirectoryPath(configFile.path);
checkWatchedDirectories(host, projectSystem.getTypeRootsFromLocation(configDir).concat(configDir), /*recursive*/ true);
checkWatchedDirectories(host, [configDir, combinePaths(configDir, projectSystem.nodeModulesAtTypes)], /*recursive*/ true);
});

// TODO: if watching for config file creation
Expand All @@ -269,7 +269,7 @@ namespace ts.tscWatch {
const host = createWatchedSystem([commonFile1, libFile, configFile]);
const watch = createWatchModeWithConfigFile(configFile.path, host);
const configDir = getDirectoryPath(configFile.path);
checkWatchedDirectories(host, projectSystem.getTypeRootsFromLocation(configDir).concat(configDir), /*recursive*/ true);
checkWatchedDirectories(host, [configDir, combinePaths(configDir, projectSystem.nodeModulesAtTypes)], /*recursive*/ true);

checkProgramRootFiles(watch(), [commonFile1.path]);

Expand Down
Loading

0 comments on commit bd0c210

Please sign in to comment.