mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-30 01:04:49 -05:00
Add writeFile and customTransformers to build and buildReferences (#43984)
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
|
||||
124
src/testRunner/unittests/tsbuild/publicApi.ts
Normal file
124
src/testRunner/unittests/tsbuild/publicApi.ts
Normal file
@@ -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);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user