Skip to content

Commit 0279cde

Browse files
committed
Clean resolutions from tsbuild info
1 parent a3fc17b commit 0279cde

File tree

6 files changed

+130
-0
lines changed

6 files changed

+130
-0
lines changed

src/compiler/tsbuildPublic.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,10 @@ namespace ts {
133133
export interface SolutionBuilder<T extends BuilderProgram> {
134134
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
135135
clean(project?: string): ExitStatus;
136+
cleanResolutions(project?: string): ExitStatus;
136137
buildReferences(project: string, cancellationToken?: CancellationToken): ExitStatus;
137138
cleanReferences(project?: string): ExitStatus;
139+
cleanResolutionsOfReferences(project?: string): ExitStatus;
138140
getNextInvalidatedProject(cancellationToken?: CancellationToken): InvalidatedProject<T> | undefined;
139141

140142
// Currently used for testing but can be made public if needed:
@@ -1726,6 +1728,38 @@ namespace ts {
17261728
return ExitStatus.Success;
17271729
}
17281730

1731+
function cleanResolutions(state: SolutionBuilderState, project?: string, onlyReferences?: boolean) {
1732+
const buildOrder = getBuildOrderFor(state, project, onlyReferences);
1733+
if (!buildOrder) return ExitStatus.InvalidProject_OutputsSkipped;
1734+
1735+
if (isCircularBuildOrder(buildOrder)) {
1736+
reportErrors(state, buildOrder.circularDiagnostics);
1737+
state.host.reportErrorSummary?.(getErrorCountForSummary(buildOrder.circularDiagnostics));
1738+
return ExitStatus.ProjectReferenceCycle_OutputsSkipped;
1739+
}
1740+
1741+
let diagnostics = 0;
1742+
for (const proj of buildOrder) {
1743+
const resolvedPath = toResolvedConfigFilePath(state, proj);
1744+
const parsed = parseConfigFile(state, proj, resolvedPath);
1745+
if (parsed) {
1746+
diagnostics += cleanResolutionsOfTsBuildInfoAndReportError(
1747+
parsed.options,
1748+
state.compilerHost,
1749+
err => state.host.reportDiagnostic(err),
1750+
state.writeFileName,
1751+
);
1752+
}
1753+
else {
1754+
// File has gone missing; fine to ignore here
1755+
reportParseConfigFileDiagnostic(state, resolvedPath);
1756+
}
1757+
}
1758+
1759+
state.host.reportErrorSummary?.(diagnostics);
1760+
return diagnostics ? ExitStatus.DiagnosticsPresent_OutputsGenerated : ExitStatus.Success;
1761+
}
1762+
17291763
function invalidateProject(state: SolutionBuilderState, resolved: ResolvedConfigFilePath, reloadLevel: ConfigFileProgramReloadLevel) {
17301764
// If host implements getParsedCommandLine, we cant get list of files from parseConfigFileHost
17311765
if (state.host.getParsedCommandLine && reloadLevel === ConfigFileProgramReloadLevel.Partial) {
@@ -1884,8 +1918,10 @@ namespace ts {
18841918
return {
18851919
build: (project, cancellationToken) => build(state, project, cancellationToken),
18861920
clean: project => clean(state, project),
1921+
cleanResolutions: project => cleanResolutions(state, project),
18871922
buildReferences: (project, cancellationToken) => build(state, project, cancellationToken, /*onlyReferences*/ true),
18881923
cleanReferences: project => clean(state, project, /*onlyReferences*/ true),
1924+
cleanResolutionsOfReferences: project => cleanResolutions(state, project, /*onlyReferences*/ true),
18891925
getNextInvalidatedProject: cancellationToken => {
18901926
setupInitialBuild(state, cancellationToken);
18911927
return getNextInvalidatedProject(state, getBuildOrder(state), /*reportQueue*/ false);

src/compiler/watch.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,29 @@ namespace ts {
233233
return ExitStatus.Success;
234234
}
235235

236+
export interface CleanResolutionsOfTsBuildInfoAndReportErrorHost extends CleanResolutionsOfTsBuildInfoHost {
237+
getCurrentDirectory(): string;
238+
}
239+
export function cleanResolutionsOfTsBuildInfoAndReportError(
240+
options: CompilerOptions,
241+
host: CleanResolutionsOfTsBuildInfoAndReportErrorHost,
242+
reportDiagnostic: DiagnosticReporter,
243+
writeFileName?: (s: string) => void,
244+
reportSummary?: ReportEmitErrorSummary,
245+
): number {
246+
const { emittedFiles, diagnostics } = cleanResolutionsOfTsBuildInfo(options, host);
247+
diagnostics.forEach(reportDiagnostic);
248+
if (writeFileName) {
249+
const currentDir = host.getCurrentDirectory();
250+
forEach(emittedFiles, file => {
251+
const filepath = getNormalizedAbsolutePath(file, currentDir);
252+
writeFileName(`TSFILE: ${filepath}`);
253+
});
254+
}
255+
reportSummary?.(diagnostics.length);
256+
return diagnostics.length;
257+
}
258+
236259
export const noopFileWatcher: FileWatcher = { close: noop };
237260
export const returnNoopFileWatcher = () => noopFileWatcher;
238261

src/compiler/watchPublic.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,32 @@ namespace ts {
1616
return createBuildProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);
1717
}
1818

19+
export interface CleanResolutionsOfTsBuildInfoHost {
20+
readFile(fileName: string): string | undefined;
21+
writeFile: WriteFileCallback;
22+
}
23+
export function cleanResolutionsOfTsBuildInfo(compilerOptions: CompilerOptions, host: CleanResolutionsOfTsBuildInfoHost): EmitResult {
24+
if (outFile(compilerOptions)) return emitSkippedWithNoDiagnostics;
25+
const buildInfoPath = getTsBuildInfoEmitOutputFilePath(compilerOptions);
26+
if (!buildInfoPath) return emitSkippedWithNoDiagnostics;
27+
const content = host.readFile(buildInfoPath);
28+
if (!content) return emitSkippedWithNoDiagnostics;
29+
const buildInfo = getBuildInfo(content);
30+
if (buildInfo.version !== version) return emitSkippedWithNoDiagnostics;
31+
if (!buildInfo.program) return emitSkippedWithNoDiagnostics;
32+
// TODO:: Clean the actual program
33+
let newContent = content;
34+
35+
// Actual writeFile with new program
36+
const emitDiagnostics = createDiagnosticCollection();
37+
writeFile(host, emitDiagnostics, buildInfoPath, newContent, /*writeByteOrderMark*/ false);
38+
return {
39+
emitSkipped: false,
40+
diagnostics: emitDiagnostics.getDiagnostics(),
41+
emittedFiles: compilerOptions.listEmittedFiles ? [buildInfoPath] : undefined
42+
};
43+
}
44+
1945
export function createIncrementalCompilerHost(options: CompilerOptions, system = sys): CompilerHost {
2046
const host = createCompilerHostWorker(options, /*setParentNodes*/ undefined, system);
2147
host.createHash = maybeBind(system, system.createHash);

src/executeCommandLine/executeCommandLine.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ namespace ts {
261261
reportDiagnostic,
262262
configParseResult.options
263263
);
264+
if (commandLineOptions.cleanResolutions) {
265+
configParseResult.errors.forEach(reportDiagnostic);
266+
return cleanResolutions(sys, configParseResult.options, reportDiagnostic);
267+
}
264268
if (isWatchSet(configParseResult.options)) {
265269
if (reportWatchModeWithoutSysSupport(sys, reportDiagnostic)) return;
266270
return createWatchOfConfigFile(
@@ -300,6 +304,9 @@ namespace ts {
300304
reportDiagnostic,
301305
commandLineOptions
302306
);
307+
if (commandLineOptions.cleanResolutions) {
308+
return cleanResolutions(sys, commandLineOptions, reportDiagnostic);
309+
}
303310
if (isWatchSet(commandLineOptions)) {
304311
if (reportWatchModeWithoutSysSupport(sys, reportDiagnostic)) return;
305312
return createWatchOfFilesAndCompilerOptions(
@@ -431,6 +438,19 @@ namespace ts {
431438
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
432439
}
433440

441+
if (buildOptions.cleanResolutions) {
442+
const buildHost = createSolutionBuilderHost(
443+
sys,
444+
/*createProgram*/ undefined,
445+
reportDiagnostic,
446+
createBuilderStatusReporter(sys, shouldBePretty(sys, buildOptions)),
447+
createReportErrorSummary(sys, buildOptions)
448+
);
449+
updateSolutionBuilderHost(sys, cb, buildHost);
450+
const builder = createSolutionBuilder(buildHost, projects, buildOptions);
451+
return sys.exit(builder.cleanResolutions());
452+
}
453+
434454
if (buildOptions.watch) {
435455
if (reportWatchModeWithoutSysSupport(sys, reportDiagnostic)) return;
436456
const buildHost = createSolutionBuilderWithWatchHost(
@@ -466,6 +486,17 @@ namespace ts {
466486
undefined;
467487
}
468488

489+
function cleanResolutions(sys: System, options: CompilerOptions, reportDiagnostic: DiagnosticReporter) {
490+
const diagnostics = cleanResolutionsOfTsBuildInfoAndReportError(
491+
options,
492+
sys,
493+
reportDiagnostic,
494+
s => sys.write(s + sys.newLine),
495+
createReportErrorSummary(sys, options)
496+
);
497+
return sys.exit(diagnostics ? ExitStatus.DiagnosticsPresent_OutputsGenerated : ExitStatus.Success);
498+
}
499+
469500
function performCompilation(
470501
sys: System,
471502
cb: ExecuteCommandLineCallbacks,

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4961,6 +4961,11 @@ declare namespace ts {
49614961
readFile(fileName: string): string | undefined;
49624962
}
49634963
function readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram | undefined;
4964+
interface CleanResolutionsOfTsBuildInfoHost {
4965+
readFile(fileName: string): string | undefined;
4966+
writeFile: WriteFileCallback;
4967+
}
4968+
function cleanResolutionsOfTsBuildInfo(compilerOptions: CompilerOptions, host: CleanResolutionsOfTsBuildInfoHost): EmitResult;
49644969
function createIncrementalCompilerHost(options: CompilerOptions, system?: System): CompilerHost;
49654970
interface IncrementalProgramOptions<T extends BuilderProgram> {
49664971
rootNames: readonly string[];
@@ -5125,8 +5130,10 @@ declare namespace ts {
51255130
interface SolutionBuilder<T extends BuilderProgram> {
51265131
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
51275132
clean(project?: string): ExitStatus;
5133+
cleanResolutions(project?: string): ExitStatus;
51285134
buildReferences(project: string, cancellationToken?: CancellationToken): ExitStatus;
51295135
cleanReferences(project?: string): ExitStatus;
5136+
cleanResolutionsOfReferences(project?: string): ExitStatus;
51305137
getNextInvalidatedProject(cancellationToken?: CancellationToken): InvalidatedProject<T> | undefined;
51315138
}
51325139
/**

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4961,6 +4961,11 @@ declare namespace ts {
49614961
readFile(fileName: string): string | undefined;
49624962
}
49634963
function readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram | undefined;
4964+
interface CleanResolutionsOfTsBuildInfoHost {
4965+
readFile(fileName: string): string | undefined;
4966+
writeFile: WriteFileCallback;
4967+
}
4968+
function cleanResolutionsOfTsBuildInfo(compilerOptions: CompilerOptions, host: CleanResolutionsOfTsBuildInfoHost): EmitResult;
49644969
function createIncrementalCompilerHost(options: CompilerOptions, system?: System): CompilerHost;
49654970
interface IncrementalProgramOptions<T extends BuilderProgram> {
49664971
rootNames: readonly string[];
@@ -5125,8 +5130,10 @@ declare namespace ts {
51255130
interface SolutionBuilder<T extends BuilderProgram> {
51265131
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
51275132
clean(project?: string): ExitStatus;
5133+
cleanResolutions(project?: string): ExitStatus;
51285134
buildReferences(project: string, cancellationToken?: CancellationToken): ExitStatus;
51295135
cleanReferences(project?: string): ExitStatus;
5136+
cleanResolutionsOfReferences(project?: string): ExitStatus;
51305137
getNextInvalidatedProject(cancellationToken?: CancellationToken): InvalidatedProject<T> | undefined;
51315138
}
51325139
/**

0 commit comments

Comments
 (0)