Skip to content

Commit 6d8fd79

Browse files
authored
Add SolutionBuilderHostBase.getCustomTransformers to be used when emitting. (#44496)
This allows not having to specify the transformers during normal watch scneario Builds on top of #43984
1 parent 14231af commit 6d8fd79

File tree

6 files changed

+505
-3
lines changed

6 files changed

+505
-3
lines changed

src/compiler/tsbuildPublic.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ namespace ts {
8585
* writeFileCallback
8686
*/
8787
writeFile?(path: string, data: string, writeByteOrderMark?: boolean): void;
88+
getCustomTransformers?: (project: string) => CustomTransformers | undefined;
8889

8990
getModifiedTime(fileName: string): Date | undefined;
9091
setModifiedTime(fileName: string, date: Date): void;
@@ -785,7 +786,7 @@ namespace ts {
785786
emit: (targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) => {
786787
if (targetSourceFile || emitOnlyDtsFiles) {
787788
return withProgramOrUndefined(
788-
program => program.emit(targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers)
789+
program => program.emit(targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers || state.host.getCustomTransformers?.(project))
789790
);
790791
}
791792
executeSteps(BuildStep.SemanticDiagnostics, cancellationToken);
@@ -921,7 +922,7 @@ namespace ts {
921922
(name, text, writeByteOrderMark) => outputFiles.push({ name, text, writeByteOrderMark }),
922923
cancellationToken,
923924
/*emitOnlyDts*/ false,
924-
customTransformers
925+
customTransformers || state.host.getCustomTransformers?.(project)
925926
);
926927
// Don't emit .d.ts if there are decl file errors
927928
if (declDiagnostics) {
@@ -1060,7 +1061,7 @@ namespace ts {
10601061
const refName = resolveProjectName(state, ref.path);
10611062
return parseConfigFile(state, refName, toResolvedConfigFilePath(state, refName));
10621063
},
1063-
customTransformers
1064+
customTransformers || state.host.getCustomTransformers?.(project)
10641065
);
10651066

10661067
if (isString(outputFiles)) {

src/testRunner/tsconfig.json

+1
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
"unittests/tsbuild/transitiveReferences.ts",
138138
"unittests/tsbuild/watchEnvironment.ts",
139139
"unittests/tsbuild/watchMode.ts",
140+
"unittests/tsbuildWatch/publicApi.ts",
140141
"unittests/tsc/composite.ts",
141142
"unittests/tsc/declarationEmit.ts",
142143
"unittests/tsc/incremental.ts",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
namespace ts.tscWatch {
2+
it("unittests:: tsbuildWatch:: watchMode:: Public API with custom transformers", () => {
3+
const solution: File = {
4+
path: `${projectRoot}/tsconfig.json`,
5+
content: JSON.stringify({
6+
references: [
7+
{ path: "./shared/tsconfig.json" },
8+
{ path: "./webpack/tsconfig.json" }
9+
],
10+
files: []
11+
})
12+
};
13+
const sharedConfig: File = {
14+
path: `${projectRoot}/shared/tsconfig.json`,
15+
content: JSON.stringify({
16+
compilerOptions: { composite: true },
17+
})
18+
};
19+
const sharedIndex: File = {
20+
path: `${projectRoot}/shared/index.ts`,
21+
content: `export function f1() { }
22+
export class c { }
23+
export enum e { }
24+
// leading
25+
export function f2() { } // trailing`
26+
};
27+
const webpackConfig: File = {
28+
path: `${projectRoot}/webpack/tsconfig.json`,
29+
content: JSON.stringify({
30+
compilerOptions: { composite: true, },
31+
references: [{ path: "../shared/tsconfig.json" }]
32+
})
33+
};
34+
const webpackIndex: File = {
35+
path: `${projectRoot}/webpack/index.ts`,
36+
content: `export function f2() { }
37+
export class c2 { }
38+
export enum e2 { }
39+
// leading
40+
export function f22() { } // trailing`
41+
};
42+
const commandLineArgs = ["--b", "--w"];
43+
const { sys, baseline, oldSnap } = createBaseline(createWatchedSystem([libFile, solution, sharedConfig, sharedIndex, webpackConfig, webpackIndex], { currentDirectory: projectRoot }));
44+
const { cb, getPrograms } = commandLineCallbacks(sys);
45+
const buildHost = createSolutionBuilderWithWatchHost(
46+
sys,
47+
/*createProgram*/ undefined,
48+
createDiagnosticReporter(sys, /*pretty*/ true),
49+
createBuilderStatusReporter(sys, /*pretty*/ true),
50+
createWatchStatusReporter(sys, /*pretty*/ true)
51+
);
52+
buildHost.afterProgramEmitAndDiagnostics = cb;
53+
buildHost.afterEmitBundle = cb;
54+
buildHost.getCustomTransformers = getCustomTransformers;
55+
const builder = createSolutionBuilderWithWatch(buildHost, [solution.path], { verbose: true });
56+
builder.build();
57+
runWatchBaseline({
58+
scenario: "publicApi",
59+
subScenario: "with custom transformers",
60+
commandLineArgs,
61+
sys,
62+
baseline,
63+
oldSnap,
64+
getPrograms,
65+
changes: [
66+
{
67+
caption: "change to shared",
68+
change: sys => sys.prependFile(sharedIndex.path, "export function fooBar() {}"),
69+
timeouts: sys => {
70+
sys.checkTimeoutQueueLengthAndRun(1); // Shared
71+
sys.checkTimeoutQueueLengthAndRun(1); // webpack
72+
sys.checkTimeoutQueueLengthAndRun(1); // solution
73+
sys.checkTimeoutQueueLength(0);
74+
}
75+
}
76+
],
77+
watchOrSolution: builder
78+
});
79+
80+
function getCustomTransformers(project: string): CustomTransformers {
81+
const before: TransformerFactory<SourceFile> = context => {
82+
return file => visitEachChild(file, visit, context);
83+
function visit(node: Node): VisitResult<Node> {
84+
switch (node.kind) {
85+
case SyntaxKind.FunctionDeclaration:
86+
return visitFunction(node as FunctionDeclaration);
87+
default:
88+
return visitEachChild(node, visit, context);
89+
}
90+
}
91+
function visitFunction(node: FunctionDeclaration) {
92+
addSyntheticLeadingComment(node, SyntaxKind.MultiLineCommentTrivia, `@before${project}`, /*hasTrailingNewLine*/ true);
93+
return node;
94+
}
95+
};
96+
97+
const after: TransformerFactory<SourceFile> = context => {
98+
return file => visitEachChild(file, visit, context);
99+
function visit(node: Node): VisitResult<Node> {
100+
switch (node.kind) {
101+
case SyntaxKind.VariableStatement:
102+
return visitVariableStatement(node as VariableStatement);
103+
default:
104+
return visitEachChild(node, visit, context);
105+
}
106+
}
107+
function visitVariableStatement(node: VariableStatement) {
108+
addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, `@after${project}`);
109+
return node;
110+
}
111+
};
112+
return { before: [before], after: [after] };
113+
}
114+
});
115+
}

tests/baselines/reference/api/tsserverlibrary.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5205,6 +5205,7 @@ declare namespace ts {
52055205
* writeFileCallback
52065206
*/
52075207
writeFile?(path: string, data: string, writeByteOrderMark?: boolean): void;
5208+
getCustomTransformers?: (project: string) => CustomTransformers | undefined;
52085209
getModifiedTime(fileName: string): Date | undefined;
52095210
setModifiedTime(fileName: string, date: Date): void;
52105211
deleteFile(fileName: string): void;

tests/baselines/reference/api/typescript.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5205,6 +5205,7 @@ declare namespace ts {
52055205
* writeFileCallback
52065206
*/
52075207
writeFile?(path: string, data: string, writeByteOrderMark?: boolean): void;
5208+
getCustomTransformers?: (project: string) => CustomTransformers | undefined;
52085209
getModifiedTime(fileName: string): Date | undefined;
52095210
setModifiedTime(fileName: string, date: Date): void;
52105211
deleteFile(fileName: string): void;

0 commit comments

Comments
 (0)