Skip to content

Commit 1eec8b3

Browse files
TypeScript Botsheetalkamat
TypeScript Bot
andauthored
Cherry-pick PR #50617 into release-4.8 (#50618)
Component commits: 83a58b0 Check if its same buildinfo only for directly referenced projects and not recursively Fixes #50545 Co-authored-by: Sheetal Nandi <shkamat@microsoft.com>
1 parent 451b5ba commit 1eec8b3

File tree

3 files changed

+337
-19
lines changed

3 files changed

+337
-19
lines changed

src/compiler/tsbuildPublic.ts

+3-19
Original file line numberDiff line numberDiff line change
@@ -1694,10 +1694,7 @@ namespace ts {
16941694
}
16951695
}
16961696

1697-
const seenRefs = buildInfoPath ? new Set<ResolvedConfigFilePath>() : undefined;
16981697
const buildInfoCacheEntry = state.buildInfoCache.get(resolvedPath);
1699-
seenRefs?.add(resolvedPath);
1700-
17011698
/** Inputs are up-to-date, just need either timestamp update or bundle prepend manipulation to make it look up-to-date */
17021699
let pseudoUpToDate = false;
17031700
let usesPrepend = false;
@@ -1712,7 +1709,7 @@ namespace ts {
17121709
}
17131710

17141711
// Check if tsbuildinfo path is shared, then we need to rebuild
1715-
if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs!, resolvedConfig, resolvedRefPath)) {
1712+
if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath)) {
17161713
return {
17171714
type: UpToDateStatusType.OutOfDateWithUpstream,
17181715
outOfDateOutputFileName: buildInfoPath!,
@@ -1775,22 +1772,9 @@ namespace ts {
17751772
};
17761773
}
17771774

1778-
function hasSameBuildInfo(state: SolutionBuilderState, buildInfoCacheEntry: BuildInfoCacheEntry, seenRefs: Set<ResolvedConfigFilePath>, resolvedConfig: ParsedCommandLine, resolvedRefPath: ResolvedConfigFilePath) {
1779-
if (seenRefs.has(resolvedRefPath)) return false;
1780-
seenRefs.add(resolvedRefPath);
1775+
function hasSameBuildInfo(state: SolutionBuilderState, buildInfoCacheEntry: BuildInfoCacheEntry, resolvedRefPath: ResolvedConfigFilePath) {
17811776
const refBuildInfo = state.buildInfoCache.get(resolvedRefPath)!;
1782-
if (refBuildInfo.path === buildInfoCacheEntry.path) return true;
1783-
1784-
if (resolvedConfig.projectReferences) {
1785-
// Check references
1786-
for (const ref of resolvedConfig.projectReferences) {
1787-
const resolvedRef = resolveProjectReferencePath(ref);
1788-
const resolvedRefPath = toResolvedConfigFilePath(state, resolvedRef);
1789-
const resolvedConfig = parseConfigFile(state, resolvedRef, resolvedRefPath)!;
1790-
if (hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath)) return true;
1791-
}
1792-
}
1793-
return false;
1777+
return refBuildInfo.path === buildInfoCacheEntry.path;
17941778
}
17951779

17961780
function getUpToDateStatus(state: SolutionBuilderState, project: ParsedCommandLine | undefined, resolvedPath: ResolvedConfigFilePath): UpToDateStatus {

src/testRunner/unittests/tsbuild/containerOnlyReferenced.ts

+31
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,36 @@ namespace ts {
77
commandLineArgs: ["--b", "/src", "--verbose"],
88
edits: noChangeOnlyRuns
99
});
10+
11+
verifyTscWithEdits({
12+
scenario: "containerOnlyReferenced",
13+
subScenario: "when solution is referenced indirectly",
14+
fs: () => loadProjectFromFiles({
15+
"/src/project1/tsconfig.json": JSON.stringify({
16+
compilerOptions: { composite: true },
17+
references: [],
18+
}),
19+
"/src/project2/tsconfig.json": JSON.stringify({
20+
compilerOptions: { composite: true },
21+
references: [],
22+
}),
23+
"/src/project2/src/b.ts": "export const b = 10;",
24+
"/src/project3/tsconfig.json": JSON.stringify({
25+
compilerOptions: { composite: true },
26+
references: [{ path: "../project1", }, { path: "../project2" }],
27+
}),
28+
"/src/project3/src/c.ts": "export const c = 10;",
29+
"/src/project4/tsconfig.json": JSON.stringify({
30+
compilerOptions: { composite: true },
31+
references: [{ path: "../project3" }]
32+
}),
33+
"/src/project4/src/d.ts": "export const d = 10;",
34+
}),
35+
commandLineArgs: ["--b", "/src/project4", "--verbose", "--explainFiles"],
36+
edits: [{
37+
subScenario: "modify project3 file",
38+
modifyFs: fs => replaceText(fs, "/src/project3/src/c.ts", "c = ", "cc = "),
39+
}],
40+
});
1041
});
1142
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
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/project1/tsconfig.json]
18+
{"compilerOptions":{"composite":true},"references":[]}
19+
20+
//// [/src/project2/src/b.ts]
21+
export const b = 10;
22+
23+
//// [/src/project2/tsconfig.json]
24+
{"compilerOptions":{"composite":true},"references":[]}
25+
26+
//// [/src/project3/src/c.ts]
27+
export const c = 10;
28+
29+
//// [/src/project3/tsconfig.json]
30+
{"compilerOptions":{"composite":true},"references":[{"path":"../project1"},{"path":"../project2"}]}
31+
32+
//// [/src/project4/src/d.ts]
33+
export const d = 10;
34+
35+
//// [/src/project4/tsconfig.json]
36+
{"compilerOptions":{"composite":true},"references":[{"path":"../project3"}]}
37+
38+
39+
40+
Output::
41+
/lib/tsc --b /src/project4 --verbose --explainFiles
42+
[12:00:20 AM] Projects in this build:
43+
* src/project1/tsconfig.json
44+
* src/project2/tsconfig.json
45+
* src/project3/tsconfig.json
46+
* src/project4/tsconfig.json
47+
48+
[12:00:21 AM] Project 'src/project2/tsconfig.json' is out of date because output file 'src/project2/tsconfig.tsbuildinfo' does not exist
49+
50+
[12:00:22 AM] Building project '/src/project2/tsconfig.json'...
51+
52+
lib/lib.d.ts
53+
Default library for target 'es3'
54+
src/project2/src/b.ts
55+
Matched by default include pattern '**/*'
56+
[12:00:28 AM] Project 'src/project3/tsconfig.json' is out of date because output file 'src/project3/tsconfig.tsbuildinfo' does not exist
57+
58+
[12:00:29 AM] Building project '/src/project3/tsconfig.json'...
59+
60+
lib/lib.d.ts
61+
Default library for target 'es3'
62+
src/project3/src/c.ts
63+
Matched by default include pattern '**/*'
64+
[12:00:35 AM] Project 'src/project4/tsconfig.json' is out of date because output file 'src/project4/tsconfig.tsbuildinfo' does not exist
65+
66+
[12:00:36 AM] Building project '/src/project4/tsconfig.json'...
67+
68+
lib/lib.d.ts
69+
Default library for target 'es3'
70+
src/project4/src/d.ts
71+
Matched by default include pattern '**/*'
72+
exitCode:: ExitStatus.Success
73+
74+
75+
//// [/src/project2/src/b.d.ts]
76+
export declare const b = 10;
77+
78+
79+
//// [/src/project2/src/b.js]
80+
"use strict";
81+
exports.__esModule = true;
82+
exports.b = void 0;
83+
exports.b = 10;
84+
85+
86+
//// [/src/project2/tsconfig.tsbuildinfo]
87+
{"program":{"fileNames":["../../lib/lib.d.ts","./src/b.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":"-13368947479-export const b = 10;","signature":"-1807916688-export declare const b = 10;\r\n"}],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2],"latestChangedDtsFile":"./src/b.d.ts"},"version":"FakeTSVersion"}
88+
89+
//// [/src/project2/tsconfig.tsbuildinfo.readable.baseline.txt]
90+
{
91+
"program": {
92+
"fileNames": [
93+
"../../lib/lib.d.ts",
94+
"./src/b.ts"
95+
],
96+
"fileInfos": {
97+
"../../lib/lib.d.ts": {
98+
"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; };",
99+
"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; };",
100+
"affectsGlobalScope": true
101+
},
102+
"./src/b.ts": {
103+
"version": "-13368947479-export const b = 10;",
104+
"signature": "-1807916688-export declare const b = 10;\r\n"
105+
}
106+
},
107+
"options": {
108+
"composite": true
109+
},
110+
"referencedMap": {},
111+
"exportedModulesMap": {},
112+
"semanticDiagnosticsPerFile": [
113+
"../../lib/lib.d.ts",
114+
"./src/b.ts"
115+
],
116+
"latestChangedDtsFile": "./src/b.d.ts"
117+
},
118+
"version": "FakeTSVersion",
119+
"size": 832
120+
}
121+
122+
//// [/src/project3/src/c.d.ts]
123+
export declare const c = 10;
124+
125+
126+
//// [/src/project3/src/c.js]
127+
"use strict";
128+
exports.__esModule = true;
129+
exports.c = void 0;
130+
exports.c = 10;
131+
132+
133+
//// [/src/project3/tsconfig.tsbuildinfo]
134+
{"program":{"fileNames":["../../lib/lib.d.ts","./src/c.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":"-12077479510-export const c = 10;","signature":"-4148571535-export declare const c = 10;\r\n"}],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2],"latestChangedDtsFile":"./src/c.d.ts"},"version":"FakeTSVersion"}
135+
136+
//// [/src/project3/tsconfig.tsbuildinfo.readable.baseline.txt]
137+
{
138+
"program": {
139+
"fileNames": [
140+
"../../lib/lib.d.ts",
141+
"./src/c.ts"
142+
],
143+
"fileInfos": {
144+
"../../lib/lib.d.ts": {
145+
"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; };",
146+
"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; };",
147+
"affectsGlobalScope": true
148+
},
149+
"./src/c.ts": {
150+
"version": "-12077479510-export const c = 10;",
151+
"signature": "-4148571535-export declare const c = 10;\r\n"
152+
}
153+
},
154+
"options": {
155+
"composite": true
156+
},
157+
"referencedMap": {},
158+
"exportedModulesMap": {},
159+
"semanticDiagnosticsPerFile": [
160+
"../../lib/lib.d.ts",
161+
"./src/c.ts"
162+
],
163+
"latestChangedDtsFile": "./src/c.d.ts"
164+
},
165+
"version": "FakeTSVersion",
166+
"size": 832
167+
}
168+
169+
//// [/src/project4/src/d.d.ts]
170+
export declare const d = 10;
171+
172+
173+
//// [/src/project4/src/d.js]
174+
"use strict";
175+
exports.__esModule = true;
176+
exports.d = void 0;
177+
exports.d = 10;
178+
179+
180+
//// [/src/project4/tsconfig.tsbuildinfo]
181+
{"program":{"fileNames":["../../lib/lib.d.ts","./src/d.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":"-10786011541-export const d = 10;","signature":"-6489226382-export declare const d = 10;\r\n"}],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2],"latestChangedDtsFile":"./src/d.d.ts"},"version":"FakeTSVersion"}
182+
183+
//// [/src/project4/tsconfig.tsbuildinfo.readable.baseline.txt]
184+
{
185+
"program": {
186+
"fileNames": [
187+
"../../lib/lib.d.ts",
188+
"./src/d.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+
"./src/d.ts": {
197+
"version": "-10786011541-export const d = 10;",
198+
"signature": "-6489226382-export declare const d = 10;\r\n"
199+
}
200+
},
201+
"options": {
202+
"composite": true
203+
},
204+
"referencedMap": {},
205+
"exportedModulesMap": {},
206+
"semanticDiagnosticsPerFile": [
207+
"../../lib/lib.d.ts",
208+
"./src/d.ts"
209+
],
210+
"latestChangedDtsFile": "./src/d.d.ts"
211+
},
212+
"version": "FakeTSVersion",
213+
"size": 832
214+
}
215+
216+
217+
218+
Change:: modify project3 file
219+
Input::
220+
//// [/src/project3/src/c.ts]
221+
export const cc = 10;
222+
223+
224+
225+
Output::
226+
/lib/tsc --b /src/project4 --verbose --explainFiles
227+
[12:00:43 AM] Projects in this build:
228+
* src/project1/tsconfig.json
229+
* src/project2/tsconfig.json
230+
* src/project3/tsconfig.json
231+
* src/project4/tsconfig.json
232+
233+
[12:00:44 AM] Project 'src/project2/tsconfig.json' is up to date because newest input 'src/project2/src/b.ts' is older than output 'src/project2/tsconfig.tsbuildinfo'
234+
235+
[12:00:45 AM] Project 'src/project3/tsconfig.json' is out of date because output 'src/project3/tsconfig.tsbuildinfo' is older than input 'src/project3/src/c.ts'
236+
237+
[12:00:46 AM] Building project '/src/project3/tsconfig.json'...
238+
239+
lib/lib.d.ts
240+
Default library for target 'es3'
241+
src/project3/src/c.ts
242+
Matched by default include pattern '**/*'
243+
[12:00:52 AM] Project 'src/project4/tsconfig.json' is out of date because output 'src/project4/tsconfig.tsbuildinfo' is older than input 'src/project3'
244+
245+
[12:00:53 AM] Building project '/src/project4/tsconfig.json'...
246+
247+
[12:00:54 AM] Updating unchanged output timestamps of project '/src/project4/tsconfig.json'...
248+
249+
lib/lib.d.ts
250+
Default library for target 'es3'
251+
src/project4/src/d.ts
252+
Matched by default include pattern '**/*'
253+
exitCode:: ExitStatus.Success
254+
255+
256+
//// [/src/project3/src/c.d.ts]
257+
export declare const cc = 10;
258+
259+
260+
//// [/src/project3/src/c.js]
261+
"use strict";
262+
exports.__esModule = true;
263+
exports.cc = void 0;
264+
exports.cc = 10;
265+
266+
267+
//// [/src/project3/tsconfig.tsbuildinfo]
268+
{"program":{"fileNames":["../../lib/lib.d.ts","./src/c.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":"-12481904019-export const cc = 10;","signature":"-2519819788-export declare const cc = 10;\r\n"}],"options":{"composite":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2],"latestChangedDtsFile":"./src/c.d.ts"},"version":"FakeTSVersion"}
269+
270+
//// [/src/project3/tsconfig.tsbuildinfo.readable.baseline.txt]
271+
{
272+
"program": {
273+
"fileNames": [
274+
"../../lib/lib.d.ts",
275+
"./src/c.ts"
276+
],
277+
"fileInfos": {
278+
"../../lib/lib.d.ts": {
279+
"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; };",
280+
"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; };",
281+
"affectsGlobalScope": true
282+
},
283+
"./src/c.ts": {
284+
"version": "-12481904019-export const cc = 10;",
285+
"signature": "-2519819788-export declare const cc = 10;\r\n"
286+
}
287+
},
288+
"options": {
289+
"composite": true
290+
},
291+
"referencedMap": {},
292+
"exportedModulesMap": {},
293+
"semanticDiagnosticsPerFile": [
294+
"../../lib/lib.d.ts",
295+
"./src/c.ts"
296+
],
297+
"latestChangedDtsFile": "./src/c.d.ts"
298+
},
299+
"version": "FakeTSVersion",
300+
"size": 834
301+
}
302+
303+
//// [/src/project4/tsconfig.tsbuildinfo] file changed its modified time

0 commit comments

Comments
 (0)