diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts
index a0ab1339bca19..1deeaf45ba275 100644
--- a/src/compiler/builder.ts
+++ b/src/compiler/builder.ts
@@ -313,7 +313,13 @@ function createBuilderProgramState(newProgram: Program, getCanonicalFileName: Ge
});
// If the global file is removed, add all files as changed
- if (useOldState && forEachEntry(oldState!.fileInfos, (info, sourceFilePath) => (outFilePath || info.affectsGlobalScope) && !state.fileInfos.has(sourceFilePath))) {
+ if (useOldState && forEachEntry(oldState!.fileInfos, (info, sourceFilePath) => {
+ if (state.fileInfos.has(sourceFilePath)) return false;
+ if (outFilePath || info.affectsGlobalScope) return true;
+ // if file is deleted we need to write buildInfo again
+ state.buildInfoEmitPending = true;
+ return false;
+ })) {
BuilderState.getAllFilesExcludingDefaultLibraryFile(state, newProgram, /*firstSourceFile*/ undefined)
.forEach(file => addFileToChangeSet(state, file.resolvedPath));
}
diff --git a/src/testRunner/unittests/tsc/incremental.ts b/src/testRunner/unittests/tsc/incremental.ts
index 9bd13a37fb64c..5bfe1a27c53e1 100644
--- a/src/testRunner/unittests/tsc/incremental.ts
+++ b/src/testRunner/unittests/tsc/incremental.ts
@@ -819,4 +819,26 @@ console.log(a);`,
baselinePrograms: true,
});
});
+
+ verifyTscWithEdits({
+ scenario: "incremental",
+ subScenario: "when file is deleted",
+ commandLineArgs: ["-p", `/src/project`],
+ fs: () => loadProjectFromFiles({
+ "/src/project/tsconfig.json": JSON.stringify({
+ compilerOptions: {
+ composite: true,
+ outDir: "outDir",
+ },
+ }),
+ "/src/project/file1.ts": `export class C { }`,
+ "/src/project/file2.ts": `export class D { }`,
+ }),
+ edits: [
+ {
+ subScenario: "delete file with imports",
+ modifyFs: fs => fs.unlinkSync("/src/project/file2.ts"),
+ },
+ ]
+ });
});
diff --git a/tests/baselines/reference/tsc/incremental/when-file-is-deleted.js b/tests/baselines/reference/tsc/incremental/when-file-is-deleted.js
new file mode 100644
index 0000000000000..9ee08e92a5412
--- /dev/null
+++ b/tests/baselines/reference/tsc/incremental/when-file-is-deleted.js
@@ -0,0 +1,178 @@
+Input::
+//// [/lib/lib.d.ts]
+///
+interface Boolean {}
+interface Function {}
+interface CallableFunction {}
+interface NewableFunction {}
+interface IArguments {}
+interface Number { toExponential: any; }
+interface Object {}
+interface RegExp {}
+interface String { charAt: any; }
+interface Array { length: number; [n: number]: T; }
+interface ReadonlyArray {}
+declare const console: { log(msg: any): void; };
+
+//// [/src/project/file1.ts]
+export class C { }
+
+//// [/src/project/file2.ts]
+export class D { }
+
+//// [/src/project/tsconfig.json]
+{"compilerOptions":{"composite":true,"outDir":"outDir"}}
+
+
+
+Output::
+/lib/tsc -p /src/project
+exitCode:: ExitStatus.Success
+
+
+//// [/src/project/outDir/file1.d.ts]
+export declare class C {
+}
+
+
+//// [/src/project/outDir/file1.js]
+"use strict";
+exports.__esModule = true;
+exports.C = void 0;
+var C = /** @class */ (function () {
+ function C() {
+ }
+ return C;
+}());
+exports.C = C;
+
+
+//// [/src/project/outDir/file2.d.ts]
+export declare class D {
+}
+
+
+//// [/src/project/outDir/file2.js]
+"use strict";
+exports.__esModule = true;
+exports.D = void 0;
+var D = /** @class */ (function () {
+ function D() {
+ }
+ return D;
+}());
+exports.D = D;
+
+
+//// [/src/project/outDir/tsconfig.tsbuildinfo]
+{"program":{"fileNames":["../../../lib/lib.d.ts","../file1.ts","../file2.ts"],"fileInfos":[{"version":"3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"-9819564552-export class C { }","signature":"-10192454122-export declare class C {\r\n}\r\n"},{"version":"-7804761415-export class D { }","signature":"-10523684105-export declare class D {\r\n}\r\n"}],"options":{"composite":true,"outDir":"./"},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2,3],"latestChangedDtsFile":"./file2.d.ts"},"version":"FakeTSVersion"}
+
+//// [/src/project/outDir/tsconfig.tsbuildinfo.readable.baseline.txt]
+{
+ "program": {
+ "fileNames": [
+ "../../../lib/lib.d.ts",
+ "../file1.ts",
+ "../file2.ts"
+ ],
+ "fileInfos": {
+ "../../../lib/lib.d.ts": {
+ "original": {
+ "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true
+ },
+ "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true
+ },
+ "../file1.ts": {
+ "original": {
+ "version": "-9819564552-export class C { }",
+ "signature": "-10192454122-export declare class C {\r\n}\r\n"
+ },
+ "version": "-9819564552-export class C { }",
+ "signature": "-10192454122-export declare class C {\r\n}\r\n"
+ },
+ "../file2.ts": {
+ "original": {
+ "version": "-7804761415-export class D { }",
+ "signature": "-10523684105-export declare class D {\r\n}\r\n"
+ },
+ "version": "-7804761415-export class D { }",
+ "signature": "-10523684105-export declare class D {\r\n}\r\n"
+ }
+ },
+ "options": {
+ "composite": true,
+ "outDir": "./"
+ },
+ "referencedMap": {},
+ "exportedModulesMap": {},
+ "semanticDiagnosticsPerFile": [
+ "../../../lib/lib.d.ts",
+ "../file1.ts",
+ "../file2.ts"
+ ],
+ "latestChangedDtsFile": "./file2.d.ts"
+ },
+ "version": "FakeTSVersion",
+ "size": 972
+}
+
+
+
+Change:: delete file with imports
+Input::
+//// [/src/project/file2.ts] unlink
+
+
+Output::
+/lib/tsc -p /src/project
+exitCode:: ExitStatus.Success
+
+
+//// [/src/project/outDir/tsconfig.tsbuildinfo]
+{"program":{"fileNames":["../../../lib/lib.d.ts","../file1.ts"],"fileInfos":[{"version":"3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"-9819564552-export class C { }","signature":"-10192454122-export declare class C {\r\n}\r\n"}],"options":{"composite":true,"outDir":"./"},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2],"latestChangedDtsFile":"./file2.d.ts"},"version":"FakeTSVersion"}
+
+//// [/src/project/outDir/tsconfig.tsbuildinfo.readable.baseline.txt]
+{
+ "program": {
+ "fileNames": [
+ "../../../lib/lib.d.ts",
+ "../file1.ts"
+ ],
+ "fileInfos": {
+ "../../../lib/lib.d.ts": {
+ "original": {
+ "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true
+ },
+ "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true
+ },
+ "../file1.ts": {
+ "original": {
+ "version": "-9819564552-export class C { }",
+ "signature": "-10192454122-export declare class C {\r\n}\r\n"
+ },
+ "version": "-9819564552-export class C { }",
+ "signature": "-10192454122-export declare class C {\r\n}\r\n"
+ }
+ },
+ "options": {
+ "composite": true,
+ "outDir": "./"
+ },
+ "referencedMap": {},
+ "exportedModulesMap": {},
+ "semanticDiagnosticsPerFile": [
+ "../../../lib/lib.d.ts",
+ "../file1.ts"
+ ],
+ "latestChangedDtsFile": "./file2.d.ts"
+ },
+ "version": "FakeTSVersion",
+ "size": 850
+}
+