Partial implementation for invalidating the program (instead of source file as that would involve more work) so the files are picked up

This commit is contained in:
Sheetal Nandi
2017-08-07 11:31:13 -07:00
parent d55150cbd3
commit 8dc62484ec
5 changed files with 91 additions and 21 deletions
+41 -9
View File
@@ -255,6 +255,7 @@ namespace ts {
let timerToUpdateProgram: any; // timer callback to recompile the program
const sourceFilesCache = createMap<HostFileInfo | string>(); // Cache that stores the source file and version info
let missingFilePathsRequestedForRelease: Path[]; // These paths are held temparirly so that we can remove the entry from source file cache if the file is not tracked by missing files
watchingHost = watchingHost || createWatchingSystemHost(compilerOptions.pretty);
const { system, parseConfigFile, reportDiagnostic, reportWatchDiagnostic, beforeCompile, afterCompile } = watchingHost;
@@ -274,8 +275,7 @@ namespace ts {
const resolutionCache = createResolutionCache(
fileName => toPath(fileName),
() => compilerOptions,
() => clearExistingProgramAndScheduleProgramUpdate(),
(fileName, callback) => system.watchFile(fileName, callback),
watchFailedLookupLocation,
s => writeLog(s)
);
@@ -310,6 +310,19 @@ namespace ts {
// Update watches
missingFilesMap = updateMissingFilePathsWatch(program, missingFilesMap, watchMissingFilePath, closeMissingFilePathWatcher);
if (missingFilePathsRequestedForRelease) {
// These are the paths that program creater told us as not in use any more but were missing on the disk.
// We didnt remove the entry for them from sourceFiles cache so that we dont have to do File IO,
// if there is already watcher for it (for missing files)
// At that point our watches were updated, hence now we know that these paths are not tracked and need to be removed
// so that at later time we have correct result of their presence
for (const missingFilePath of missingFilePathsRequestedForRelease) {
if (!missingFilesMap.has(missingFilePath)) {
sourceFilesCache.delete(missingFilePath);
}
}
missingFilePathsRequestedForRelease = undefined;
}
afterCompile(host, program, builder);
reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes));
@@ -446,8 +459,14 @@ namespace ts {
// remove the cached entry.
// Note we arent deleting entry if file became missing in new program or
// there was version update and new source file was created.
if (hostSourceFileInfo && !isString(hostSourceFileInfo) && hostSourceFileInfo.sourceFile === oldSourceFile) {
sourceFilesCache.delete(oldSourceFile.path);
if (hostSourceFileInfo) {
// record the missing file paths so they can be removed later if watchers arent tracking them
if (isString(hostSourceFileInfo)) {
(missingFilePathsRequestedForRelease || (missingFilePathsRequestedForRelease = [])).push(oldSourceFile.path);
}
else if (hostSourceFileInfo.sourceFile === oldSourceFile) {
sourceFilesCache.delete(oldSourceFile.path);
}
}
}
@@ -471,11 +490,6 @@ namespace ts {
scheduleProgramUpdate();
}
function clearExistingProgramAndScheduleProgramUpdate() {
program = undefined;
scheduleProgramUpdate();
}
function updateProgram() {
timerToUpdateProgram = undefined;
reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.File_change_detected_Starting_incremental_compilation));
@@ -547,6 +561,24 @@ namespace ts {
}
}
function watchFailedLookupLocation(failedLookupLocation: string, containingFile: string, name: string) {
return host.watchFile(failedLookupLocation, (fileName, eventKind) => onFailedLookupLocationChange(fileName, eventKind, failedLookupLocation, containingFile, name));
}
function onFailedLookupLocationChange(fileName: string, eventKind: FileWatcherEventKind, failedLookupLocation: string, containingFile: string, name: string) {
writeLog(`Failed lookup location : ${failedLookupLocation} changed: ${FileWatcherEventKind[eventKind]}, fileName: ${fileName} containingFile: ${containingFile}, name: ${name}`);
const path = toPath(failedLookupLocation);
updateCachedSystem(failedLookupLocation, path);
// TODO: We need more intensive approach wherein we are able to comunicate to the program structure reuser that the even though the source file
// refering to this failed location hasnt changed, it needs to re-evaluate the module resolutions for the invalidated resolutions.
// For now just clear existing program, that should still reuse the source files but atleast compute the resolutions again.
// resolutionCache.invalidateResolutionOfChangedFailedLookupLocation(failedLookupLocation);
program = undefined;
scheduleProgramUpdate();
}
function watchMissingFilePath(missingFilePath: Path) {
return host.watchFile(missingFilePath, (fileName, eventKind) => onMissingFileChange(fileName, missingFilePath, eventKind));
}