Skip to content

Commit 16faef1

Browse files
authoredSep 27, 2022
During uptodate ness check with buildInfo, check if there are errors explicitly with noEmit (#50974)
* Add test * During uptodate ness check, with buildInfo, check if there are errors in the program to determine uptodateness Fixes #50959 * Comment update
1 parent 63791f5 commit 16faef1

File tree

7 files changed

+811
-1
lines changed

7 files changed

+811
-1
lines changed
 

‎src/compiler/tsbuildPublic.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -1609,8 +1609,16 @@ namespace ts {
16091609

16101610
if (buildInfo.program) {
16111611
// If there are pending changes that are not emitted, project is out of date
1612+
// When there are syntax errors, changeFileSet will have list of files changed (irrespective of noEmit)
1613+
// But in case of semantic error we need special treatment.
1614+
// Checking presence of affectedFilesPendingEmit list is fast and good way to tell if there were semantic errors and file emit was blocked
1615+
// But if noEmit is true, affectedFilesPendingEmit will have file list even if there are no semantic errors to preserve list of files to be emitted when running with noEmit false
1616+
// So with noEmit set to true, check on semantic diagnostics needs to be explicit as oppose to when it is false when only files pending emit is sufficient
16121617
if ((buildInfo.program as ProgramMultiFileEmitBuildInfo).changeFileSet?.length ||
1613-
(!project.options.noEmit && (buildInfo.program as ProgramMultiFileEmitBuildInfo).affectedFilesPendingEmit?.length)) {
1618+
(!project.options.noEmit ?
1619+
(buildInfo.program as ProgramMultiFileEmitBuildInfo).affectedFilesPendingEmit?.length :
1620+
some((buildInfo.program as ProgramMultiFileEmitBuildInfo).semanticDiagnosticsPerFile, isArray))
1621+
) {
16141622
return {
16151623
type: UpToDateStatusType.OutOfDateBuildInfo,
16161624
buildInfoFile: buildInfoPath

‎src/testRunner/tsconfig.json

+1
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
"unittests/tsbuild/lateBoundSymbol.ts",
133133
"unittests/tsbuild/moduleResolution.ts",
134134
"unittests/tsbuild/moduleSpecifiers.ts",
135+
"unittests/tsbuild/noEmit.ts",
135136
"unittests/tsbuild/noEmitOnError.ts",
136137
"unittests/tsbuild/outFile.ts",
137138
"unittests/tsbuild/outputPaths.ts",
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
namespace ts {
2+
describe("unittests:: tsbuild:: noEmit", () => {
3+
function verifyNoEmitWorker(subScenario: string, aTsContent: string, commandLineArgs: readonly string[]) {
4+
verifyTscWithEdits({
5+
scenario: "noEmit",
6+
subScenario,
7+
fs: () => loadProjectFromFiles({
8+
"/src/a.ts": aTsContent,
9+
"/src/tsconfig.json": JSON.stringify({
10+
compilerOptions: { noEmit: true }
11+
})
12+
}),
13+
commandLineArgs,
14+
edits: [
15+
noChangeRun,
16+
{
17+
subScenario: "Fix error",
18+
modifyFs: fs => fs.writeFileSync("/src/a.ts", `const a = "hello"`),
19+
},
20+
noChangeRun,
21+
],
22+
baselinePrograms: true,
23+
});
24+
}
25+
26+
function verifyNoEmit(subScenario: string, aTsContent: string) {
27+
verifyNoEmitWorker(subScenario, aTsContent, ["--b", "/src/tsconfig.json", "-v"]);
28+
verifyNoEmitWorker(`${subScenario} with incremental`, aTsContent, ["--b", "/src/tsconfig.json", "-v", "--incremental"]);
29+
}
30+
31+
verifyNoEmit("syntax errors", `const a = "hello`);
32+
verifyNoEmit("semantic errors", `const a: number = "hello"`);
33+
});
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
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/a.ts]
18+
const a: number = "hello"
19+
20+
//// [/src/tsconfig.json]
21+
{"compilerOptions":{"noEmit":true}}
22+
23+
24+
25+
Output::
26+
/lib/tsc --b /src/tsconfig.json -v --incremental
27+
[12:00:08 AM] Projects in this build:
28+
* src/tsconfig.json
29+
30+
[12:00:09 AM] Project 'src/tsconfig.json' is out of date because output file 'src/tsconfig.tsbuildinfo' does not exist
31+
32+
[12:00:10 AM] Building project '/src/tsconfig.json'...
33+
34+
src/a.ts:1:7 - error TS2322: Type 'string' is not assignable to type 'number'.
35+
36+
1 const a: number = "hello"
37+
   ~
38+
39+
40+
Found 1 error.
41+
42+
exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped
43+
Program root files: ["/src/a.ts"]
44+
Program options: {"noEmit":true,"incremental":true,"configFilePath":"/src/tsconfig.json"}
45+
Program structureReused: Not
46+
Program files::
47+
/lib/lib.d.ts
48+
/src/a.ts
49+
50+
Semantic diagnostics in builder refreshed for::
51+
/lib/lib.d.ts
52+
/src/a.ts
53+
54+
Shape signatures in builder refreshed for::
55+
/lib/lib.d.ts (used version)
56+
/src/a.ts (used version)
57+
58+
59+
//// [/src/tsconfig.tsbuildinfo]
60+
{"program":{"fileNames":["../lib/lib.d.ts","./a.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},{"version":"1311033573-const a: number = \"hello\"","affectsGlobalScope":true}],"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,[2,[{"file":"./a.ts","start":6,"length":1,"code":2322,"category":1,"messageText":"Type 'string' is not assignable to type 'number'."}]]],"affectedFilesPendingEmit":[[2,1]]},"version":"FakeTSVersion"}
61+
62+
//// [/src/tsconfig.tsbuildinfo.readable.baseline.txt]
63+
{
64+
"program": {
65+
"fileNames": [
66+
"../lib/lib.d.ts",
67+
"./a.ts"
68+
],
69+
"fileInfos": {
70+
"../lib/lib.d.ts": {
71+
"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; };",
72+
"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; };",
73+
"affectsGlobalScope": true
74+
},
75+
"./a.ts": {
76+
"version": "1311033573-const a: number = \"hello\"",
77+
"signature": "1311033573-const a: number = \"hello\"",
78+
"affectsGlobalScope": true
79+
}
80+
},
81+
"referencedMap": {},
82+
"exportedModulesMap": {},
83+
"semanticDiagnosticsPerFile": [
84+
"../lib/lib.d.ts",
85+
[
86+
"./a.ts",
87+
[
88+
{
89+
"file": "./a.ts",
90+
"start": 6,
91+
"length": 1,
92+
"code": 2322,
93+
"category": 1,
94+
"messageText": "Type 'string' is not assignable to type 'number'."
95+
}
96+
]
97+
]
98+
],
99+
"affectedFilesPendingEmit": [
100+
[
101+
"./a.ts",
102+
"Full"
103+
]
104+
]
105+
},
106+
"version": "FakeTSVersion",
107+
"size": 899
108+
}
109+
110+
111+
112+
Change:: no-change-run
113+
Input::
114+
115+
116+
Output::
117+
/lib/tsc --b /src/tsconfig.json -v --incremental
118+
[12:00:14 AM] Projects in this build:
119+
* src/tsconfig.json
120+
121+
[12:00:15 AM] Project 'src/tsconfig.json' is out of date because buildinfo file 'src/tsconfig.tsbuildinfo' indicates that some of the changes were not emitted
122+
123+
[12:00:16 AM] Building project '/src/tsconfig.json'...
124+
125+
src/a.ts:1:7 - error TS2322: Type 'string' is not assignable to type 'number'.
126+
127+
1 const a: number = "hello"
128+
   ~
129+
130+
131+
Found 1 error.
132+
133+
exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped
134+
Program root files: ["/src/a.ts"]
135+
Program options: {"noEmit":true,"incremental":true,"configFilePath":"/src/tsconfig.json"}
136+
Program structureReused: Not
137+
Program files::
138+
/lib/lib.d.ts
139+
/src/a.ts
140+
141+
Semantic diagnostics in builder refreshed for::
142+
143+
No shapes updated in the builder::
144+
145+
146+
147+
148+
Change:: Fix error
149+
Input::
150+
//// [/src/a.ts]
151+
const a = "hello"
152+
153+
154+
155+
Output::
156+
/lib/tsc --b /src/tsconfig.json -v --incremental
157+
[12:00:18 AM] Projects in this build:
158+
* src/tsconfig.json
159+
160+
[12:00:19 AM] Project 'src/tsconfig.json' is out of date because buildinfo file 'src/tsconfig.tsbuildinfo' indicates that some of the changes were not emitted
161+
162+
[12:00:20 AM] Building project '/src/tsconfig.json'...
163+
164+
exitCode:: ExitStatus.Success
165+
Program root files: ["/src/a.ts"]
166+
Program options: {"noEmit":true,"incremental":true,"configFilePath":"/src/tsconfig.json"}
167+
Program structureReused: Not
168+
Program files::
169+
/lib/lib.d.ts
170+
/src/a.ts
171+
172+
Semantic diagnostics in builder refreshed for::
173+
/lib/lib.d.ts
174+
/src/a.ts
175+
176+
Shape signatures in builder refreshed for::
177+
/src/a.ts (computed .d.ts)
178+
179+
180+
//// [/src/tsconfig.tsbuildinfo]
181+
{"program":{"fileNames":["../lib/lib.d.ts","./a.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},{"version":"4011451714-const a = \"hello\"","signature":"-4100694204-declare const a = \"hello\";\r\n","affectsGlobalScope":true}],"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2],"affectedFilesPendingEmit":[[2,1]]},"version":"FakeTSVersion"}
182+
183+
//// [/src/tsconfig.tsbuildinfo.readable.baseline.txt]
184+
{
185+
"program": {
186+
"fileNames": [
187+
"../lib/lib.d.ts",
188+
"./a.ts"
189+
],
190+
"fileInfos": {
191+
"../lib/lib.d.ts": {
192+
"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; };",
193+
"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; };",
194+
"affectsGlobalScope": true
195+
},
196+
"./a.ts": {
197+
"version": "4011451714-const a = \"hello\"",
198+
"signature": "-4100694204-declare const a = \"hello\";\r\n",
199+
"affectsGlobalScope": true
200+
}
201+
},
202+
"referencedMap": {},
203+
"exportedModulesMap": {},
204+
"semanticDiagnosticsPerFile": [
205+
"../lib/lib.d.ts",
206+
"./a.ts"
207+
],
208+
"affectedFilesPendingEmit": [
209+
[
210+
"./a.ts",
211+
"Full"
212+
]
213+
]
214+
},
215+
"version": "FakeTSVersion",
216+
"size": 816
217+
}
218+
219+
220+
221+
Change:: no-change-run
222+
Input::
223+
224+
225+
Output::
226+
/lib/tsc --b /src/tsconfig.json -v --incremental
227+
[12:00:24 AM] Projects in this build:
228+
* src/tsconfig.json
229+
230+
[12:00:25 AM] Project 'src/tsconfig.json' is up to date because newest input 'src/a.ts' is older than output 'src/tsconfig.tsbuildinfo'
231+
232+
exitCode:: ExitStatus.Success
233+
234+

0 commit comments

Comments
 (0)
Please sign in to comment.