Skip to content

Commit af36a85

Browse files
authored
Fix the crash when affected file pending emit is not in program is being serialized into buildInfo (microsoft#51674)
Fixes microsoft#51641
1 parent 9f93c67 commit af36a85

File tree

3 files changed

+236
-2
lines changed

3 files changed

+236
-2
lines changed

src/compiler/builder.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1078,8 +1078,8 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
10781078
const seenFiles = new Set<Path>();
10791079
for (const path of arrayFrom(state.affectedFilesPendingEmit.keys()).sort(compareStringsCaseSensitive)) {
10801080
if (tryAddToSet(seenFiles, path)) {
1081-
const file = state.program!.getSourceFileByPath(path)!;
1082-
if (!sourceFileMayBeEmitted(file, state.program!)) continue;
1081+
const file = state.program!.getSourceFileByPath(path);
1082+
if (!file || !sourceFileMayBeEmitted(file, state.program!)) continue;
10831083
const fileId = toFileId(path), pendingEmit = state.affectedFilesPendingEmit.get(path)!;
10841084
(affectedFilesPendingEmit ||= []).push(
10851085
pendingEmit === fullEmitForOptions ?

src/testRunner/unittests/tsc/incremental.ts

+21
Original file line numberDiff line numberDiff line change
@@ -855,4 +855,25 @@ console.log(a);`,
855855
},
856856
]
857857
});
858+
859+
verifyTscWithEdits({
860+
scenario: "incremental",
861+
subScenario: "file deleted before fixing error with noEmitOnError",
862+
fs: () => loadProjectFromFiles({
863+
"/src/project/tsconfig.json": JSON.stringify({
864+
compilerOptions: {
865+
outDir: "outDir",
866+
noEmitOnError: true,
867+
},
868+
}),
869+
"/src/project/file1.ts": `export const x: 30 = "hello";`,
870+
"/src/project/file2.ts": `export class D { }`,
871+
}),
872+
commandLineArgs: ["--p", "/src/project", "-i"],
873+
edits: [{
874+
subScenario: "delete file without error",
875+
modifyFs: fs => fs.unlinkSync("/src/project/file2.ts"),
876+
}],
877+
baselinePrograms: true,
878+
});
858879
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
Input::
2+
//// [/lib/lib.d.ts]
3+
/// <reference no-default-lib="true"/>
4+
interface Boolean {}
5+
interface Function {}
6+
interface CallableFunction {}
7+
interface NewableFunction {}
8+
interface IArguments {}
9+
interface Number { toExponential: any; }
10+
interface Object {}
11+
interface RegExp {}
12+
interface String { charAt: any; }
13+
interface Array<T> { length: number; [n: number]: T; }
14+
interface ReadonlyArray<T> {}
15+
declare const console: { log(msg: any): void; };
16+
17+
//// [/src/project/file1.ts]
18+
export const x: 30 = "hello";
19+
20+
//// [/src/project/file2.ts]
21+
export class D { }
22+
23+
//// [/src/project/tsconfig.json]
24+
{"compilerOptions":{"outDir":"outDir","noEmitOnError":true}}
25+
26+
27+
28+
Output::
29+
/lib/tsc --p /src/project -i
30+
src/project/file1.ts:1:14 - error TS2322: Type '"hello"' is not assignable to type '30'.
31+
32+
1 export const x: 30 = "hello";
33+
   ~
34+
35+
36+
Found 1 error in src/project/file1.ts:1
37+
38+
exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped
39+
Program root files: ["/src/project/file1.ts","/src/project/file2.ts"]
40+
Program options: {"outDir":"/src/project/outDir","noEmitOnError":true,"project":"/src/project","incremental":true,"configFilePath":"/src/project/tsconfig.json"}
41+
Program structureReused: Not
42+
Program files::
43+
/lib/lib.d.ts
44+
/src/project/file1.ts
45+
/src/project/file2.ts
46+
47+
Semantic diagnostics in builder refreshed for::
48+
/lib/lib.d.ts
49+
/src/project/file1.ts
50+
/src/project/file2.ts
51+
52+
Shape signatures in builder refreshed for::
53+
/lib/lib.d.ts (used version)
54+
/src/project/file1.ts (used version)
55+
/src/project/file2.ts (used version)
56+
57+
58+
//// [/src/project/outDir/tsconfig.tsbuildinfo]
59+
{"program":{"fileNames":["../../../lib/lib.d.ts","../file1.ts","../file2.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},"-10927263693-export const x: 30 = \"hello\";","-7804761415-export class D { }"],"options":{"noEmitOnError":true,"outDir":"./"},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,[2,[{"file":"../file1.ts","start":13,"length":1,"code":2322,"category":1,"messageText":"Type '\"hello\"' is not assignable to type '30'."}]],3],"affectedFilesPendingEmit":[2,3]},"version":"FakeTSVersion"}
60+
61+
//// [/src/project/outDir/tsconfig.tsbuildinfo.readable.baseline.txt]
62+
{
63+
"program": {
64+
"fileNames": [
65+
"../../../lib/lib.d.ts",
66+
"../file1.ts",
67+
"../file2.ts"
68+
],
69+
"fileInfos": {
70+
"../../../lib/lib.d.ts": {
71+
"original": {
72+
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
73+
"affectsGlobalScope": true
74+
},
75+
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
76+
"signature": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
77+
"affectsGlobalScope": true
78+
},
79+
"../file1.ts": {
80+
"version": "-10927263693-export const x: 30 = \"hello\";",
81+
"signature": "-10927263693-export const x: 30 = \"hello\";"
82+
},
83+
"../file2.ts": {
84+
"version": "-7804761415-export class D { }",
85+
"signature": "-7804761415-export class D { }"
86+
}
87+
},
88+
"options": {
89+
"noEmitOnError": true,
90+
"outDir": "./"
91+
},
92+
"referencedMap": {},
93+
"exportedModulesMap": {},
94+
"semanticDiagnosticsPerFile": [
95+
"../../../lib/lib.d.ts",
96+
[
97+
"../file1.ts",
98+
[
99+
{
100+
"file": "../file1.ts",
101+
"start": 13,
102+
"length": 1,
103+
"code": 2322,
104+
"category": 1,
105+
"messageText": "Type '\"hello\"' is not assignable to type '30'."
106+
}
107+
]
108+
],
109+
"../file2.ts"
110+
],
111+
"affectedFilesPendingEmit": [
112+
[
113+
"../file1.ts",
114+
"Js"
115+
],
116+
[
117+
"../file2.ts",
118+
"Js"
119+
]
120+
]
121+
},
122+
"version": "FakeTSVersion",
123+
"size": 977
124+
}
125+
126+
127+
128+
Change:: delete file without error
129+
Input::
130+
//// [/src/project/file2.ts] unlink
131+
132+
133+
Output::
134+
/lib/tsc --p /src/project -i
135+
src/project/file1.ts:1:14 - error TS2322: Type '"hello"' is not assignable to type '30'.
136+
137+
1 export const x: 30 = "hello";
138+
   ~
139+
140+
141+
Found 1 error in src/project/file1.ts:1
142+
143+
exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped
144+
Program root files: ["/src/project/file1.ts"]
145+
Program options: {"outDir":"/src/project/outDir","noEmitOnError":true,"project":"/src/project","incremental":true,"configFilePath":"/src/project/tsconfig.json"}
146+
Program structureReused: Not
147+
Program files::
148+
/lib/lib.d.ts
149+
/src/project/file1.ts
150+
151+
Semantic diagnostics in builder refreshed for::
152+
153+
No shapes updated in the builder::
154+
155+
156+
//// [/src/project/outDir/tsconfig.tsbuildinfo]
157+
{"program":{"fileNames":["../../../lib/lib.d.ts","../file1.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},"-10927263693-export const x: 30 = \"hello\";"],"options":{"noEmitOnError":true,"outDir":"./"},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,[2,[{"file":"../file1.ts","start":13,"length":1,"code":2322,"category":1,"messageText":"Type '\"hello\"' is not assignable to type '30'."}]]],"affectedFilesPendingEmit":[2]},"version":"FakeTSVersion"}
158+
159+
//// [/src/project/outDir/tsconfig.tsbuildinfo.readable.baseline.txt]
160+
{
161+
"program": {
162+
"fileNames": [
163+
"../../../lib/lib.d.ts",
164+
"../file1.ts"
165+
],
166+
"fileInfos": {
167+
"../../../lib/lib.d.ts": {
168+
"original": {
169+
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
170+
"affectsGlobalScope": true
171+
},
172+
"version": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
173+
"signature": "3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };",
174+
"affectsGlobalScope": true
175+
},
176+
"../file1.ts": {
177+
"version": "-10927263693-export const x: 30 = \"hello\";",
178+
"signature": "-10927263693-export const x: 30 = \"hello\";"
179+
}
180+
},
181+
"options": {
182+
"noEmitOnError": true,
183+
"outDir": "./"
184+
},
185+
"referencedMap": {},
186+
"exportedModulesMap": {},
187+
"semanticDiagnosticsPerFile": [
188+
"../../../lib/lib.d.ts",
189+
[
190+
"../file1.ts",
191+
[
192+
{
193+
"file": "../file1.ts",
194+
"start": 13,
195+
"length": 1,
196+
"code": 2322,
197+
"category": 1,
198+
"messageText": "Type '\"hello\"' is not assignable to type '30'."
199+
}
200+
]
201+
]
202+
],
203+
"affectedFilesPendingEmit": [
204+
[
205+
"../file1.ts",
206+
"Js"
207+
]
208+
]
209+
},
210+
"version": "FakeTSVersion",
211+
"size": 926
212+
}
213+

0 commit comments

Comments
 (0)