Skip to content

Commit bdcc57a

Browse files
authored
feat: set reportDiagnostic to solution builder (#58)
1 parent f1c20c6 commit bdcc57a

File tree

7 files changed

+98
-7
lines changed

7 files changed

+98
-7
lines changed

src/typescript/worker/lib/program/solution-builder.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ let solutionBuilderHost:
1212
| ts.SolutionBuilderWithWatchHost<ts.SemanticDiagnosticsBuilderProgram>
1313
| undefined;
1414
let solutionBuilder: ts.SolutionBuilder<ts.SemanticDiagnosticsBuilderProgram> | undefined;
15+
let hostDiagnostics: ts.Diagnostic[] = [];
1516

1617
export function useSolutionBuilder() {
1718
if (!solutionBuilderHost) {
@@ -25,7 +26,7 @@ export function useSolutionBuilder() {
2526
host,
2627
oldProgram,
2728
configFileParsingDiagnostics,
28-
projectReferences
29+
projectReferences,
2930
) => {
3031
if (compilerOptions) {
3132
startTracingIfNeeded(compilerOptions);
@@ -36,28 +37,38 @@ export function useSolutionBuilder() {
3637
host,
3738
oldProgram,
3839
configFileParsingDiagnostics,
39-
projectReferences
40+
projectReferences,
4041
);
4142
},
42-
undefined,
43+
(diagnostic) => {
44+
// SolutionBuilder can emit graph-level diagnostics while building the project graph
45+
// (e.g. invalid/cyclic project references) — i.e. before any Program/BuilderProgram exists.
46+
hostDiagnostics.push(diagnostic);
47+
updateDiagnostics(config.configFile, hostDiagnostics);
48+
},
4349
undefined,
4450
undefined,
4551
undefined,
4652
(builderProgram) => {
53+
const programConfigFile = getConfigFilePathFromBuilderProgram(builderProgram);
54+
const programDiagnostics = getDiagnosticsOfProgram(builderProgram);
55+
4756
updateDiagnostics(
48-
getConfigFilePathFromBuilderProgram(builderProgram),
49-
getDiagnosticsOfProgram(builderProgram)
57+
programConfigFile,
58+
programConfigFile === config.configFile
59+
? [...programDiagnostics, ...hostDiagnostics]
60+
: programDiagnostics,
5061
);
5162
emitTsBuildInfoIfNeeded(builderProgram);
5263
stopTracingIfNeeded(builderProgram);
53-
}
64+
},
5465
);
5566
}
5667
if (!solutionBuilder) {
5768
solutionBuilder = typescript.createSolutionBuilderWithWatch(
5869
solutionBuilderHost,
5970
[config.configFile],
60-
{ watch: true }
71+
{ watch: true },
6172
);
6273
solutionBuilder.build();
6374
}
@@ -68,4 +79,5 @@ export function invalidateSolutionBuilder(withHost = false) {
6879
solutionBuilderHost = undefined;
6980
}
7081
solutionBuilder = undefined;
82+
hostDiagnostics = [];
7183
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const a = 1;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"composite": true,
4+
"declaration": true,
5+
"outDir": "./dist",
6+
"target": "ES2021",
7+
"module": "ES2020",
8+
"moduleResolution": "node",
9+
"strict": true,
10+
"types": []
11+
},
12+
"include": [
13+
"src"
14+
],
15+
"references": [
16+
{
17+
"path": "../b"
18+
}
19+
]
20+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const b = 2;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"composite": true,
4+
"declaration": true,
5+
"outDir": "./dist",
6+
"target": "ES2021",
7+
"module": "ES2020",
8+
"moduleResolution": "node",
9+
"strict": true,
10+
"types": []
11+
},
12+
"include": [
13+
"src"
14+
],
15+
"references": [
16+
{
17+
"path": "../a"
18+
}
19+
]
20+
}

test/e2e/with-rsbuild/index.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,29 @@ test('should not throw error when the file is excluded by code', async () => {
165165

166166
await expect(rsbuild.build()).resolves.toBeTruthy();
167167
});
168+
169+
test('should host diagnostics in SolutionBuilder (e.g. TS6202 for circular project references)', async () => {
170+
const { logs, restore } = proxyConsole();
171+
172+
const rsbuild = await createRsbuild({
173+
rsbuildConfig: {
174+
tools: {
175+
rspack: {
176+
plugins: [
177+
new TsCheckerRspackPlugin({
178+
typescript: {
179+
build: true,
180+
configFile: './tsconfig.circular.json',
181+
},
182+
}),
183+
],
184+
},
185+
},
186+
},
187+
});
188+
189+
await expect(rsbuild.build()).rejects.toThrowError('build failed!');
190+
expect(logs.find((log) => log.includes('TS6202'))).toBeTruthy();
191+
192+
restore();
193+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"files": [],
3+
"references": [
4+
{
5+
"path": "./__fixtures__/solution-builder/a"
6+
},
7+
{
8+
"path": "./__fixtures__/solution-builder/b"
9+
}
10+
]
11+
}

0 commit comments

Comments
 (0)