Skip to content

Commit e5395ef

Browse files
authored
Add writeFile and customTransformers to build and buildReferences (#43984)
1 parent 4423871 commit e5395ef

File tree

6 files changed

+352
-11
lines changed

6 files changed

+352
-11
lines changed

Diff for: src/compiler/tsbuildPublic.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ namespace ts {
131131
}
132132

133133
export interface SolutionBuilder<T extends BuilderProgram> {
134-
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
134+
build(project?: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers): ExitStatus;
135135
clean(project?: string): ExitStatus;
136-
buildReferences(project: string, cancellationToken?: CancellationToken): ExitStatus;
136+
buildReferences(project: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers): ExitStatus;
137137
cleanReferences(project?: string): ExitStatus;
138138
getNextInvalidatedProject(cancellationToken?: CancellationToken): InvalidatedProject<T> | undefined;
139139

@@ -1125,7 +1125,7 @@ namespace ts {
11251125
break;
11261126

11271127
case BuildStep.BuildInvalidatedProjectOfBundle:
1128-
Debug.checkDefined(invalidatedProjectOfBundle).done(cancellationToken);
1128+
Debug.checkDefined(invalidatedProjectOfBundle).done(cancellationToken, writeFile, customTransformers);
11291129
step = BuildStep.Done;
11301130
break;
11311131

@@ -1649,7 +1649,7 @@ namespace ts {
16491649
}
16501650
}
16511651

1652-
function build(state: SolutionBuilderState, project?: string, cancellationToken?: CancellationToken, onlyReferences?: boolean): ExitStatus {
1652+
function build(state: SolutionBuilderState, project?: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers, onlyReferences?: boolean): ExitStatus {
16531653
const buildOrder = getBuildOrderFor(state, project, onlyReferences);
16541654
if (!buildOrder) return ExitStatus.InvalidProject_OutputsSkipped;
16551655

@@ -1661,7 +1661,7 @@ namespace ts {
16611661
const invalidatedProject = getNextInvalidatedProject(state, buildOrder, reportQueue);
16621662
if (!invalidatedProject) break;
16631663
reportQueue = false;
1664-
invalidatedProject.done(cancellationToken);
1664+
invalidatedProject.done(cancellationToken, writeFile, getCustomTransformers?.(invalidatedProject.project));
16651665
if (!state.diagnostics.has(invalidatedProject.projectPath)) successfulProjects++;
16661666
}
16671667

@@ -1894,9 +1894,9 @@ namespace ts {
18941894
function createSolutionBuilderWorker<T extends BuilderProgram>(watch: boolean, hostOrHostWithWatch: SolutionBuilderHost<T> | SolutionBuilderWithWatchHost<T>, rootNames: readonly string[], options: BuildOptions, baseWatchOptions?: WatchOptions): SolutionBuilder<T> {
18951895
const state = createSolutionBuilderState(watch, hostOrHostWithWatch, rootNames, options, baseWatchOptions);
18961896
return {
1897-
build: (project, cancellationToken) => build(state, project, cancellationToken),
1897+
build: (project, cancellationToken, writeFile, getCustomTransformers) => build(state, project, cancellationToken, writeFile, getCustomTransformers),
18981898
clean: project => clean(state, project),
1899-
buildReferences: (project, cancellationToken) => build(state, project, cancellationToken, /*onlyReferences*/ true),
1899+
buildReferences: (project, cancellationToken, writeFile, getCustomTransformers) => build(state, project, cancellationToken, writeFile, getCustomTransformers, /*onlyReferences*/ true),
19001900
cleanReferences: project => clean(state, project, /*onlyReferences*/ true),
19011901
getNextInvalidatedProject: cancellationToken => {
19021902
setupInitialBuild(state, cancellationToken);

Diff for: src/testRunner/tsconfig.json

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@
131131
"unittests/tsbuild/noEmitOnError.ts",
132132
"unittests/tsbuild/outFile.ts",
133133
"unittests/tsbuild/outputPaths.ts",
134+
"unittests/tsbuild/publicApi.ts",
134135
"unittests/tsbuild/referencesWithRootDirInParent.ts",
135136
"unittests/tsbuild/resolveJsonModule.ts",
136137
"unittests/tsbuild/sample.ts",

Diff for: src/testRunner/unittests/tsbuild/publicApi.ts

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
namespace ts {
2+
describe("unittests:: tsbuild:: Public API with custom transformers when passed to build", () => {
3+
let sys: TscCompileSystem;
4+
before(() => {
5+
const initialFs = getFsWithTime(loadProjectFromFiles({
6+
"/src/tsconfig.json": JSON.stringify({
7+
references: [
8+
{ path: "./shared/tsconfig.json" },
9+
{ path: "./webpack/tsconfig.json" }
10+
],
11+
files: []
12+
}),
13+
"/src/shared/tsconfig.json": JSON.stringify({
14+
compilerOptions: { composite: true },
15+
}),
16+
"/src/shared/index.ts": `export function f1() { }
17+
export class c { }
18+
export enum e { }
19+
// leading
20+
export function f2() { } // trailing`,
21+
"/src/webpack/tsconfig.json": JSON.stringify({
22+
compilerOptions: {
23+
composite: true,
24+
},
25+
references: [{ path: "../shared/tsconfig.json" }]
26+
}),
27+
"/src/webpack/index.ts": `export function f2() { }
28+
export class c2 { }
29+
export enum e2 { }
30+
// leading
31+
export function f22() { } // trailing`,
32+
})).fs.makeReadonly();
33+
const inputFs = initialFs.shadow();
34+
inputFs.makeReadonly();
35+
const fs = inputFs.shadow();
36+
37+
// Create system
38+
sys = new fakes.System(fs, { executingFilePath: "/lib/tsc" }) as TscCompileSystem;
39+
fakes.patchHostForBuildInfoReadWrite(sys);
40+
const commandLineArgs = ["--b", "/src/tsconfig.json"];
41+
sys.write(`${sys.getExecutingFilePath()} ${commandLineArgs.join(" ")}\n`);
42+
sys.exit = exitCode => sys.exitCode = exitCode;
43+
const writtenFiles = sys.writtenFiles = new Set();
44+
const originalWriteFile = sys.writeFile;
45+
sys.writeFile = (fileName, content, writeByteOrderMark) => {
46+
const path = toPathWithSystem(sys, fileName);
47+
assert.isFalse(writtenFiles.has(path));
48+
writtenFiles.add(path);
49+
return originalWriteFile.call(sys, fileName, content, writeByteOrderMark);
50+
};
51+
const { cb, getPrograms } = commandLineCallbacks(sys, /*originalReadCall*/ undefined, originalWriteFile);
52+
const buildHost = createSolutionBuilderHost(
53+
sys,
54+
/*createProgram*/ undefined,
55+
createDiagnosticReporter(sys, /*pretty*/ true),
56+
createBuilderStatusReporter(sys, /*pretty*/ true),
57+
errorCount => sys.write(getErrorSummaryText(errorCount, sys.newLine))
58+
);
59+
buildHost.afterProgramEmitAndDiagnostics = cb;
60+
buildHost.afterEmitBundle = cb;
61+
const builder = createSolutionBuilder(buildHost, [commandLineArgs[1]], { verbose: true });
62+
const exitStatus = builder.build(/*project*/ undefined, /*cancellationToken*/ undefined, /*writeFile*/ undefined, getCustomTransformers);
63+
sys.exit(exitStatus);
64+
sys.write(`exitCode:: ExitStatus.${ExitStatus[sys.exitCode as ExitStatus]}\n`);
65+
const baseline: string[] = [];
66+
tscWatch.baselinePrograms(baseline, getPrograms, emptyArray, /*baselineDependencies*/ false);
67+
sys.write(baseline.join("\n"));
68+
fs.makeReadonly();
69+
sys.baseLine = () => {
70+
const baseFsPatch = inputFs.diff(/*base*/ undefined, { baseIsNotShadowRoot: true });
71+
const patch = fs.diff(inputFs, { includeChangedFileWithSameContent: true });
72+
return {
73+
file: `tsbuild/$publicAPI/${BuildKind.Initial}/${"build with custom transformers".split(" ").join("-")}.js`,
74+
text: `Input::
75+
${baseFsPatch ? vfs.formatPatch(baseFsPatch) : ""}
76+
77+
Output::
78+
${sys.output.join("")}
79+
80+
${patch ? vfs.formatPatch(patch) : ""}`
81+
};
82+
};
83+
84+
function getCustomTransformers(project: string): CustomTransformers {
85+
const before: TransformerFactory<SourceFile> = context => {
86+
return file => visitEachChild(file, visit, context);
87+
function visit(node: Node): VisitResult<Node> {
88+
switch (node.kind) {
89+
case SyntaxKind.FunctionDeclaration:
90+
return visitFunction(<FunctionDeclaration>node);
91+
default:
92+
return visitEachChild(node, visit, context);
93+
}
94+
}
95+
function visitFunction(node: FunctionDeclaration) {
96+
addSyntheticLeadingComment(node, SyntaxKind.MultiLineCommentTrivia, `@before${project}`, /*hasTrailingNewLine*/ true);
97+
return node;
98+
}
99+
};
100+
101+
const after: TransformerFactory<SourceFile> = context => {
102+
return file => visitEachChild(file, visit, context);
103+
function visit(node: Node): VisitResult<Node> {
104+
switch (node.kind) {
105+
case SyntaxKind.VariableStatement:
106+
return visitVariableStatement(<VariableStatement>node);
107+
default:
108+
return visitEachChild(node, visit, context);
109+
}
110+
}
111+
function visitVariableStatement(node: VariableStatement) {
112+
addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, `@after${project}`);
113+
return node;
114+
}
115+
};
116+
return { before: [before], after: [after] };
117+
}
118+
});
119+
after(() => {
120+
sys = undefined!;
121+
});
122+
verifyTscBaseline(() => sys);
123+
});
124+
}

Diff for: tests/baselines/reference/api/tsserverlibrary.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -5219,9 +5219,9 @@ declare namespace ts {
52195219
interface SolutionBuilderWithWatchHost<T extends BuilderProgram> extends SolutionBuilderHostBase<T>, WatchHost {
52205220
}
52215221
interface SolutionBuilder<T extends BuilderProgram> {
5222-
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
5222+
build(project?: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers): ExitStatus;
52235223
clean(project?: string): ExitStatus;
5224-
buildReferences(project: string, cancellationToken?: CancellationToken): ExitStatus;
5224+
buildReferences(project: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers): ExitStatus;
52255225
cleanReferences(project?: string): ExitStatus;
52265226
getNextInvalidatedProject(cancellationToken?: CancellationToken): InvalidatedProject<T> | undefined;
52275227
}

Diff for: tests/baselines/reference/api/typescript.d.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -5219,9 +5219,9 @@ declare namespace ts {
52195219
interface SolutionBuilderWithWatchHost<T extends BuilderProgram> extends SolutionBuilderHostBase<T>, WatchHost {
52205220
}
52215221
interface SolutionBuilder<T extends BuilderProgram> {
5222-
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
5222+
build(project?: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers): ExitStatus;
52235223
clean(project?: string): ExitStatus;
5224-
buildReferences(project: string, cancellationToken?: CancellationToken): ExitStatus;
5224+
buildReferences(project: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers): ExitStatus;
52255225
cleanReferences(project?: string): ExitStatus;
52265226
getNextInvalidatedProject(cancellationToken?: CancellationToken): InvalidatedProject<T> | undefined;
52275227
}

0 commit comments

Comments
 (0)