Skip to content

Commit 94a589b

Browse files
committed
Program cannot be reused if the missing file is now present
Also dont update filesByName array just to update missing file paths
1 parent 273569f commit 94a589b

2 files changed

Lines changed: 12 additions & 17 deletions

File tree

src/compiler/program.ts

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,7 @@ namespace ts {
473473
}
474474

475475
const filesByName = createMap<SourceFile | undefined>();
476+
let missingFilePaths: Path[];
476477
// stores 'filename -> file association' ignoring case
477478
// used to track cases when two file names differ only in casing
478479
const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? createMap<SourceFile>() : undefined;
@@ -511,9 +512,9 @@ namespace ts {
511512
});
512513
}
513514
}
514-
}
515515

516-
const missingFilePaths = arrayFrom(filesByName.keys(), p => <Path>p).filter(p => !filesByName.get(p));
516+
missingFilePaths = arrayFrom(filesByName.keys(), p => <Path>p).filter(p => !filesByName.get(p));
517+
}
517518

518519
// unconditionally set moduleResolutionCache to undefined to avoid unnecessary leaks
519520
moduleResolutionCache = undefined;
@@ -773,6 +774,13 @@ namespace ts {
773774
const modifiedSourceFiles: { oldFile: SourceFile, newFile: SourceFile }[] = [];
774775
oldProgram.structureIsReused = StructureIsReused.Completely;
775776

777+
// If the missing file paths are now present, it can change the progam structure,
778+
// and hence cant reuse the structure.
779+
// This is same as how we dont reuse the structure if one of the file from old program is now missing
780+
if (oldProgram.getMissingFilePaths().some(missingFilePath => host.fileExists(missingFilePath))) {
781+
return oldProgram.structureIsReused = StructureIsReused.Not;
782+
}
783+
776784
for (const oldSourceFile of oldProgram.getSourceFiles()) {
777785
const newSourceFile = host.getSourceFileByPath
778786
? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.path, options.target)
@@ -869,20 +877,7 @@ namespace ts {
869877
return oldProgram.structureIsReused;
870878
}
871879

872-
// If a file has ceased to be missing, then we need to discard some of the old
873-
// structure in order to pick it up.
874-
// Caution: if the file has created and then deleted between since it was discovered to
875-
// be missing, then the corresponding file watcher will have been closed and no new one
876-
// will be created until we encounter a change that prevents complete structure reuse.
877-
// During this interval, creation of the file will go unnoticed. We expect this to be
878-
// both rare and low-impact.
879-
if (oldProgram.getMissingFilePaths().some(missingFilePath => host.fileExists(missingFilePath))) {
880-
return oldProgram.structureIsReused = StructureIsReused.SafeModules;
881-
}
882-
883-
for (const p of oldProgram.getMissingFilePaths()) {
884-
filesByName.set(p, undefined);
885-
}
880+
missingFilePaths = oldProgram.getMissingFilePaths();
886881

887882
// update fileName -> file mapping
888883
for (let i = 0; i < newSourceFiles.length; i++) {

src/harness/unittests/reuseProgramStructure.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ namespace ts {
338338
const program_2 = updateProgram(program_1, ["a.ts"], options, noop, newTexts);
339339
assert.deepEqual(emptyArray, program_2.getMissingFilePaths());
340340

341-
assert.equal(StructureIsReused.SafeModules, program_1.structureIsReused);
341+
assert.equal(StructureIsReused.Not, program_1.structureIsReused);
342342
});
343343

344344
it("resolution cache follows imports", () => {

0 commit comments

Comments
 (0)