Skip to content

Commit

Permalink
Add writeFile and customTransformers to build and buildReferences (#4…
Browse files Browse the repository at this point in the history
  • Loading branch information
sheetalkamat committed May 7, 2021
1 parent 4423871 commit e5395ef
Show file tree
Hide file tree
Showing 6 changed files with 352 additions and 11 deletions.
14 changes: 7 additions & 7 deletions src/compiler/tsbuildPublic.ts
Expand Up @@ -131,9 +131,9 @@ namespace ts {
}

export interface SolutionBuilder<T extends BuilderProgram> {
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
build(project?: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers): ExitStatus;
clean(project?: string): ExitStatus;
buildReferences(project: string, cancellationToken?: CancellationToken): ExitStatus;
buildReferences(project: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers): ExitStatus;
cleanReferences(project?: string): ExitStatus;
getNextInvalidatedProject(cancellationToken?: CancellationToken): InvalidatedProject<T> | undefined;

Expand Down Expand Up @@ -1125,7 +1125,7 @@ namespace ts {
break;

case BuildStep.BuildInvalidatedProjectOfBundle:
Debug.checkDefined(invalidatedProjectOfBundle).done(cancellationToken);
Debug.checkDefined(invalidatedProjectOfBundle).done(cancellationToken, writeFile, customTransformers);
step = BuildStep.Done;
break;

Expand Down Expand Up @@ -1649,7 +1649,7 @@ namespace ts {
}
}

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

Expand All @@ -1661,7 +1661,7 @@ namespace ts {
const invalidatedProject = getNextInvalidatedProject(state, buildOrder, reportQueue);
if (!invalidatedProject) break;
reportQueue = false;
invalidatedProject.done(cancellationToken);
invalidatedProject.done(cancellationToken, writeFile, getCustomTransformers?.(invalidatedProject.project));
if (!state.diagnostics.has(invalidatedProject.projectPath)) successfulProjects++;
}

Expand Down Expand Up @@ -1894,9 +1894,9 @@ namespace ts {
function createSolutionBuilderWorker<T extends BuilderProgram>(watch: boolean, hostOrHostWithWatch: SolutionBuilderHost<T> | SolutionBuilderWithWatchHost<T>, rootNames: readonly string[], options: BuildOptions, baseWatchOptions?: WatchOptions): SolutionBuilder<T> {
const state = createSolutionBuilderState(watch, hostOrHostWithWatch, rootNames, options, baseWatchOptions);
return {
build: (project, cancellationToken) => build(state, project, cancellationToken),
build: (project, cancellationToken, writeFile, getCustomTransformers) => build(state, project, cancellationToken, writeFile, getCustomTransformers),
clean: project => clean(state, project),
buildReferences: (project, cancellationToken) => build(state, project, cancellationToken, /*onlyReferences*/ true),
buildReferences: (project, cancellationToken, writeFile, getCustomTransformers) => build(state, project, cancellationToken, writeFile, getCustomTransformers, /*onlyReferences*/ true),
cleanReferences: project => clean(state, project, /*onlyReferences*/ true),
getNextInvalidatedProject: cancellationToken => {
setupInitialBuild(state, cancellationToken);
Expand Down
1 change: 1 addition & 0 deletions src/testRunner/tsconfig.json
Expand Up @@ -131,6 +131,7 @@
"unittests/tsbuild/noEmitOnError.ts",
"unittests/tsbuild/outFile.ts",
"unittests/tsbuild/outputPaths.ts",
"unittests/tsbuild/publicApi.ts",
"unittests/tsbuild/referencesWithRootDirInParent.ts",
"unittests/tsbuild/resolveJsonModule.ts",
"unittests/tsbuild/sample.ts",
Expand Down
124 changes: 124 additions & 0 deletions src/testRunner/unittests/tsbuild/publicApi.ts
@@ -0,0 +1,124 @@
namespace ts {
describe("unittests:: tsbuild:: Public API with custom transformers when passed to build", () => {
let sys: TscCompileSystem;
before(() => {
const initialFs = getFsWithTime(loadProjectFromFiles({
"/src/tsconfig.json": JSON.stringify({
references: [
{ path: "./shared/tsconfig.json" },
{ path: "./webpack/tsconfig.json" }
],
files: []
}),
"/src/shared/tsconfig.json": JSON.stringify({
compilerOptions: { composite: true },
}),
"/src/shared/index.ts": `export function f1() { }
export class c { }
export enum e { }
// leading
export function f2() { } // trailing`,
"/src/webpack/tsconfig.json": JSON.stringify({
compilerOptions: {
composite: true,
},
references: [{ path: "../shared/tsconfig.json" }]
}),
"/src/webpack/index.ts": `export function f2() { }
export class c2 { }
export enum e2 { }
// leading
export function f22() { } // trailing`,
})).fs.makeReadonly();
const inputFs = initialFs.shadow();
inputFs.makeReadonly();
const fs = inputFs.shadow();

// Create system
sys = new fakes.System(fs, { executingFilePath: "/lib/tsc" }) as TscCompileSystem;
fakes.patchHostForBuildInfoReadWrite(sys);
const commandLineArgs = ["--b", "/src/tsconfig.json"];
sys.write(`${sys.getExecutingFilePath()} ${commandLineArgs.join(" ")}\n`);
sys.exit = exitCode => sys.exitCode = exitCode;
const writtenFiles = sys.writtenFiles = new Set();
const originalWriteFile = sys.writeFile;
sys.writeFile = (fileName, content, writeByteOrderMark) => {
const path = toPathWithSystem(sys, fileName);
assert.isFalse(writtenFiles.has(path));
writtenFiles.add(path);
return originalWriteFile.call(sys, fileName, content, writeByteOrderMark);
};
const { cb, getPrograms } = commandLineCallbacks(sys, /*originalReadCall*/ undefined, originalWriteFile);
const buildHost = createSolutionBuilderHost(
sys,
/*createProgram*/ undefined,
createDiagnosticReporter(sys, /*pretty*/ true),
createBuilderStatusReporter(sys, /*pretty*/ true),
errorCount => sys.write(getErrorSummaryText(errorCount, sys.newLine))
);
buildHost.afterProgramEmitAndDiagnostics = cb;
buildHost.afterEmitBundle = cb;
const builder = createSolutionBuilder(buildHost, [commandLineArgs[1]], { verbose: true });
const exitStatus = builder.build(/*project*/ undefined, /*cancellationToken*/ undefined, /*writeFile*/ undefined, getCustomTransformers);
sys.exit(exitStatus);
sys.write(`exitCode:: ExitStatus.${ExitStatus[sys.exitCode as ExitStatus]}\n`);
const baseline: string[] = [];
tscWatch.baselinePrograms(baseline, getPrograms, emptyArray, /*baselineDependencies*/ false);
sys.write(baseline.join("\n"));
fs.makeReadonly();
sys.baseLine = () => {
const baseFsPatch = inputFs.diff(/*base*/ undefined, { baseIsNotShadowRoot: true });
const patch = fs.diff(inputFs, { includeChangedFileWithSameContent: true });
return {
file: `tsbuild/$publicAPI/${BuildKind.Initial}/${"build with custom transformers".split(" ").join("-")}.js`,
text: `Input::
${baseFsPatch ? vfs.formatPatch(baseFsPatch) : ""}
Output::
${sys.output.join("")}
${patch ? vfs.formatPatch(patch) : ""}`
};
};

function getCustomTransformers(project: string): CustomTransformers {
const before: TransformerFactory<SourceFile> = context => {
return file => visitEachChild(file, visit, context);
function visit(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.FunctionDeclaration:
return visitFunction(<FunctionDeclaration>node);
default:
return visitEachChild(node, visit, context);
}
}
function visitFunction(node: FunctionDeclaration) {
addSyntheticLeadingComment(node, SyntaxKind.MultiLineCommentTrivia, `@before${project}`, /*hasTrailingNewLine*/ true);
return node;
}
};

const after: TransformerFactory<SourceFile> = context => {
return file => visitEachChild(file, visit, context);
function visit(node: Node): VisitResult<Node> {
switch (node.kind) {
case SyntaxKind.VariableStatement:
return visitVariableStatement(<VariableStatement>node);
default:
return visitEachChild(node, visit, context);
}
}
function visitVariableStatement(node: VariableStatement) {
addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, `@after${project}`);
return node;
}
};
return { before: [before], after: [after] };
}
});
after(() => {
sys = undefined!;
});
verifyTscBaseline(() => sys);
});
}
4 changes: 2 additions & 2 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Expand Up @@ -5219,9 +5219,9 @@ declare namespace ts {
interface SolutionBuilderWithWatchHost<T extends BuilderProgram> extends SolutionBuilderHostBase<T>, WatchHost {
}
interface SolutionBuilder<T extends BuilderProgram> {
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
build(project?: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers): ExitStatus;
clean(project?: string): ExitStatus;
buildReferences(project: string, cancellationToken?: CancellationToken): ExitStatus;
buildReferences(project: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers): ExitStatus;
cleanReferences(project?: string): ExitStatus;
getNextInvalidatedProject(cancellationToken?: CancellationToken): InvalidatedProject<T> | undefined;
}
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/api/typescript.d.ts
Expand Up @@ -5219,9 +5219,9 @@ declare namespace ts {
interface SolutionBuilderWithWatchHost<T extends BuilderProgram> extends SolutionBuilderHostBase<T>, WatchHost {
}
interface SolutionBuilder<T extends BuilderProgram> {
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
build(project?: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers): ExitStatus;
clean(project?: string): ExitStatus;
buildReferences(project: string, cancellationToken?: CancellationToken): ExitStatus;
buildReferences(project: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers): ExitStatus;
cleanReferences(project?: string): ExitStatus;
getNextInvalidatedProject(cancellationToken?: CancellationToken): InvalidatedProject<T> | undefined;
}
Expand Down

0 comments on commit e5395ef

Please sign in to comment.