Track missing files

1. Expose missing files from the `Program`.
2. In `tsc --watch` and `tsserver`, add file watchers to missing files.
3. When missing files are created, schedule compilation (tsc) or refresh
the containing projects (tsserver).
This commit is contained in:
Andrew Casey
2017-06-20 15:54:43 -07:00
parent 587309d029
commit 4863ada22c
7 changed files with 102 additions and 5 deletions

View File

@@ -513,6 +513,8 @@ namespace ts {
}
}
const missingFilePaths = filesByName.getKeys().filter(p => !filesByName.get(p));
// unconditionally set moduleResolutionCache to undefined to avoid unnecessary leaks
moduleResolutionCache = undefined;
@@ -524,6 +526,7 @@ namespace ts {
getSourceFile,
getSourceFileByPath,
getSourceFiles: () => files,
getMissingFilePaths: () => missingFilePaths,
getCompilerOptions: () => options,
getSyntacticDiagnostics,
getOptionsDiagnostics,
@@ -862,11 +865,31 @@ namespace ts {
return oldProgram.structureIsReused;
}
// If a file has ceased to be missing, then we need to discard some of the old
// structure in order to pick it up.
// Caution: if the file has created and then deleted between since it was discovered to
// be missing, then the corresponding file watcher will have been closed and no new one
// will be created until we encounter a change that prevents complete structure reuse.
// During this interval, creation of the file will go unnoticed. We expect this to be
// both rare and low-impact.
if (oldProgram.getMissingFilePaths) {
const missingFilePaths: Path[] = oldProgram.getMissingFilePaths() || emptyArray;
for (const missingFilePath of missingFilePaths) {
if (host.fileExists(missingFilePath)) {
return oldProgram.structureIsReused = StructureIsReused.SafeModules;
}
}
}
// update fileName -> file mapping
for (let i = 0; i < newSourceFiles.length; i++) {
filesByName.set(filePaths[i], newSourceFiles[i]);
}
for (const p of oldProgram.getMissingFilePaths()) {
filesByName.set(p, undefined);
}
files = newSourceFiles;
fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();