From 5b361c8497d2cc25d0e25f97c11e5c2394429a2a Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 2 May 2019 13:27:36 -0700 Subject: [PATCH] Make API to build project and wire cancellation token --- src/compiler/tsbuild.ts | 153 ++++++++++++------ src/compiler/types.ts | 3 + src/compiler/watch.ts | 29 ++-- .../unittests/tsbuild/emptyFiles.ts | 4 +- src/testRunner/unittests/tsbuild/helpers.ts | 2 +- .../unittests/tsbuild/missingExtendedFile.ts | 2 +- src/testRunner/unittests/tsbuild/outFile.ts | 37 +++-- .../tsbuild/referencesWithRootDirInParent.ts | 8 +- .../unittests/tsbuild/resolveJsonModule.ts | 14 +- src/testRunner/unittests/tsbuild/sample.ts | 80 +++++---- .../unittests/tsbuild/transitiveReferences.ts | 2 +- src/testRunner/unittests/tsbuildWatchMode.ts | 12 +- .../unittests/tsserver/projectReferences.ts | 2 +- src/tsc/tsc.ts | 4 +- 14 files changed, 234 insertions(+), 118 deletions(-) diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index dd9b62edd7a..4fb2edf6801 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -255,7 +255,7 @@ namespace ts { } export interface SolutionBuilder { - buildAllProjects(): ExitStatus; + build(project?: string, cancellationToken?: CancellationToken): ExitStatus; cleanAllProjects(): ExitStatus; // Currently used for testing but can be made public if needed: @@ -264,14 +264,21 @@ namespace ts { // Testing only /*@internal*/ getUpToDateStatusOfProject(project: string): UpToDateStatus; /*@internal*/ invalidateProject(configFileName: string, reloadLevel?: ConfigFileProgramReloadLevel): void; - /*@internal*/ buildInvalidatedProject(): void; + /*@internal*/ buildNextInvalidatedProject(): void; } export interface SolutionBuilderWithWatch { - buildAllProjects(): ExitStatus; + build(project?: string, cancellationToken?: CancellationToken): ExitStatus; /*@internal*/ startWatching(): void; } + interface InvalidatedProject { + project: ResolvedConfigFileName; + projectPath: ResolvedConfigFilePath; + reloadLevel: ConfigFileProgramReloadLevel; + projectIndex: number; + } + /** * Create a function that reports watch status by writing to the system and handles the formating of the diagnostic */ @@ -386,18 +393,22 @@ namespace ts { const allWatchedInputFiles = createMap() as ConfigFileMap>; const allWatchedConfigFiles = createMap() as ConfigFileMap; + let allProjectBuildPending = true; + let needsSummary = true; + // let watchAllProjectsPending = watch; + return watch ? { - buildAllProjects, + build, startWatching } : { - buildAllProjects, + build, cleanAllProjects, getBuildOrder, getUpToDateStatusOfProject, invalidateProject, - buildInvalidatedProject, + buildNextInvalidatedProject, }; function toPath(fileName: string) { @@ -800,6 +811,7 @@ namespace ts { configFileCache.delete(resolved); buildOrder = undefined; } + needsSummary = true; clearProjectStatus(resolved); addProjToQueue(resolved, reloadLevel); enableCache(); @@ -823,16 +835,16 @@ namespace ts { } } - function getNextInvalidatedProject() { - Debug.assert(hasPendingInvalidatedProjects()); - return forEach(getBuildOrder(), (project, projectIndex) => { - const projectPath = toResolvedConfigFilePath(project); - const reloadLevel = projectPendingBuild.get(projectPath); - if (reloadLevel !== undefined) { - projectPendingBuild.delete(projectPath); - return { project, projectPath, reloadLevel, projectIndex }; - } - }); + function getNextInvalidatedProject(buildOrder: readonly ResolvedConfigFileName[]): InvalidatedProject | undefined { + return hasPendingInvalidatedProjects() ? + forEach(buildOrder, (project, projectIndex) => { + const projectPath = toResolvedConfigFilePath(project); + const reloadLevel = projectPendingBuild.get(projectPath); + if (reloadLevel !== undefined) { + return { project, projectPath, reloadLevel, projectIndex }; + } + }) : + undefined; } function hasPendingInvalidatedProjects() { @@ -846,18 +858,19 @@ namespace ts { if (timerToBuildInvalidatedProject) { hostWithWatch.clearTimeout(timerToBuildInvalidatedProject); } - timerToBuildInvalidatedProject = hostWithWatch.setTimeout(buildInvalidatedProject, 250); + timerToBuildInvalidatedProject = hostWithWatch.setTimeout(buildNextInvalidatedProject, 250); } - function buildInvalidatedProject() { + function buildNextInvalidatedProject() { timerToBuildInvalidatedProject = undefined; if (reportFileChangeDetected) { reportFileChangeDetected = false; projectErrorsReported.clear(); reportWatchStatus(Diagnostics.File_change_detected_Starting_incremental_compilation); } - if (hasPendingInvalidatedProjects()) { - buildNextInvalidatedProject(); + const invalidatedProject = getNextInvalidatedProject(getBuildOrder()); + if (invalidatedProject) { + buildInvalidatedProject(invalidatedProject); if (hasPendingInvalidatedProjects()) { if (watch && !timerToBuildInvalidatedProject) { scheduleBuildInvalidatedProject(); @@ -872,6 +885,7 @@ namespace ts { function reportErrorSummary() { if (watch || host.reportErrorSummary) { + needsSummary = false; // Report errors from the other projects getBuildOrder().forEach(project => { const projectPath = toResolvedConfigFilePath(project); @@ -890,11 +904,11 @@ namespace ts { } } - function buildNextInvalidatedProject() { - const { project, projectPath, reloadLevel, projectIndex } = getNextInvalidatedProject()!; + function buildInvalidatedProject({ project, projectPath, reloadLevel, projectIndex }: InvalidatedProject, cancellationToken?: CancellationToken) { const config = parseConfigFile(project, projectPath); if (!config) { reportParseConfigFileDiagnostic(projectPath); + projectPendingBuild.delete(projectPath); return; } @@ -920,6 +934,7 @@ namespace ts { // In a dry build, inform the user of this fact reportStatus(Diagnostics.Project_0_is_up_to_date, project); } + projectPendingBuild.delete(projectPath); return; } @@ -927,24 +942,28 @@ namespace ts { reportAndStoreErrors(projectPath, config.errors); // Fake that files have been built by updating output file stamps updateOutputTimestamps(config, projectPath); + projectPendingBuild.delete(projectPath); return; } if (status.type === UpToDateStatusType.UpstreamBlocked) { reportAndStoreErrors(projectPath, config.errors); if (options.verbose) reportStatus(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, project, status.upstreamProjectName); + projectPendingBuild.delete(projectPath); return; } if (status.type === UpToDateStatusType.ContainerOnly) { reportAndStoreErrors(projectPath, config.errors); // Do nothing + projectPendingBuild.delete(projectPath); return; } const buildResult = needsBuild(status, config) ? - buildSingleProject(project, projectPath) : // Actual build - updateBundle(project, projectPath); // Fake that files have been built by manipulating prepend and existing output + buildSingleProject(project, projectPath, cancellationToken) : // Actual build + updateBundle(project, projectPath, cancellationToken); // Fake that files have been built by manipulating prepend and existing output + projectPendingBuild.delete(projectPath); // Only composite projects can be referenced by other projects if (!(buildResult & BuildResultFlags.AnyErrors) && config.options.composite) { queueReferencingProjects(project, projectPath, projectIndex, !(buildResult & BuildResultFlags.DeclarationOutputUnchanged)); @@ -1050,7 +1069,7 @@ namespace ts { } } - function buildSingleProject(proj: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath): BuildResultFlags { + function buildSingleProject(proj: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, cancellationToken: CancellationToken | undefined): BuildResultFlags { if (options.dry) { reportStatus(Diagnostics.A_non_dry_build_would_build_project_0, proj); return BuildResultFlags.Success; @@ -1112,15 +1131,15 @@ namespace ts { // Don't emit anything in the presence of syntactic errors or options diagnostics const syntaxDiagnostics = [ ...program.getConfigFileParsingDiagnostics(), - ...program.getOptionsDiagnostics(), - ...program.getGlobalDiagnostics(), - ...program.getSyntacticDiagnostics()]; + ...program.getOptionsDiagnostics(cancellationToken), + ...program.getGlobalDiagnostics(cancellationToken), + ...program.getSyntacticDiagnostics(/*sourceFile*/ undefined, cancellationToken)]; if (syntaxDiagnostics.length) { return buildErrors(syntaxDiagnostics, BuildResultFlags.SyntaxErrors, "Syntactic"); } // Same as above but now for semantic diagnostics - const semanticDiagnostics = program.getSemanticDiagnostics(); + const semanticDiagnostics = program.getSemanticDiagnostics(/*sourceFile*/ undefined, cancellationToken); if (semanticDiagnostics.length) { return buildErrors(semanticDiagnostics, BuildResultFlags.TypeErrors, "Semantic"); } @@ -1132,7 +1151,14 @@ namespace ts { let declDiagnostics: Diagnostic[] | undefined; const reportDeclarationDiagnostics = (d: Diagnostic) => (declDiagnostics || (declDiagnostics = [])).push(d); const outputFiles: OutputFile[] = []; - emitFilesAndReportErrors(program, reportDeclarationDiagnostics, /*writeFileName*/ undefined, /*reportSummary*/ undefined, (name, text, writeByteOrderMark) => outputFiles.push({ name, text, writeByteOrderMark })); + emitFilesAndReportErrors( + program, + reportDeclarationDiagnostics, + /*writeFileName*/ undefined, + /*reportSummary*/ undefined, + (name, text, writeByteOrderMark) => outputFiles.push({ name, text, writeByteOrderMark }), + cancellationToken + ); // Don't emit .d.ts if there are decl file errors if (declDiagnostics) { program.restoreState(); @@ -1221,7 +1247,7 @@ namespace ts { return readBuilderProgram(parsed.options, readFileWithCache) as any as T; } - function updateBundle(proj: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath): BuildResultFlags { + function updateBundle(proj: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, cancellationToken: CancellationToken | undefined): BuildResultFlags { if (options.dry) { reportStatus(Diagnostics.A_non_dry_build_would_update_output_of_project_0, proj); return BuildResultFlags.Success; @@ -1241,7 +1267,7 @@ namespace ts { }); if (isString(outputFiles)) { reportStatus(Diagnostics.Cannot_update_output_of_project_0_because_there_was_error_reading_file_1, proj, relName(outputFiles)); - return buildSingleProject(proj, resolvedPath); + return buildSingleProject(proj, resolvedPath, cancellationToken); } // Actual Emit @@ -1403,21 +1429,58 @@ namespace ts { cacheState = undefined; } - function buildAllProjects(): ExitStatus { - if (options.watch) { reportWatchStatus(Diagnostics.Starting_compilation_in_watch_mode); } - enableCache(); + function build(project?: string, cancellationToken?: CancellationToken): ExitStatus { + // Set initial build if not already built + if (allProjectBuildPending) { + allProjectBuildPending = false; + if (options.watch) { reportWatchStatus(Diagnostics.Starting_compilation_in_watch_mode); } + enableCache(); + const buildOrder = getBuildOrder(); + reportBuildQueue(buildOrder); + buildOrder.forEach(configFileName => + projectPendingBuild.set(toResolvedConfigFilePath(configFileName), ConfigFileProgramReloadLevel.None)); - const buildOrder = getBuildOrder(); - reportBuildQueue(buildOrder); - buildOrder.forEach(configFileName => - projectPendingBuild.set(toResolvedConfigFilePath(configFileName), ConfigFileProgramReloadLevel.None)); - - while (hasPendingInvalidatedProjects()) { - buildNextInvalidatedProject(); + if (cancellationToken) { + cancellationToken.throwIfCancellationRequested(); + } } - reportErrorSummary(); - disableCache(); - return diagnostics.size ? ExitStatus.DiagnosticsPresent_OutputsSkipped : ExitStatus.Success; + + let successfulProjects = 0; + let errorProjects = 0; + const resolvedProject = project && resolveProjectName(project); + if (resolvedProject) { + const projectPath = toResolvedConfigFilePath(resolvedProject); + const projectIndex = findIndex( + getBuildOrder(), + configFileName => toResolvedConfigFilePath(configFileName) === projectPath + ); + if (projectIndex === -1) return ExitStatus.InvalidProject_OutputsSkipped; + } + const buildOrder = resolvedProject ? createBuildOrder([resolvedProject]) : getBuildOrder(); + while (true) { + const invalidatedProject = getNextInvalidatedProject(buildOrder); + if (!invalidatedProject) { + if (needsSummary) { + disableCache(); + reportErrorSummary(); + } + break; + } + + buildInvalidatedProject(invalidatedProject, cancellationToken); + if (diagnostics.has(invalidatedProject.projectPath)) { + errorProjects++; + } + else { + successfulProjects++; + } + } + + return errorProjects ? + successfulProjects ? + ExitStatus.DiagnosticsPresent_OutputsGenerated : + ExitStatus.DiagnosticsPresent_OutputsSkipped : + ExitStatus.Success; } function needsBuild(status: UpToDateStatus, config: ParsedCommandLine) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 5e2d6aba474..791b26ab572 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3053,6 +3053,9 @@ namespace ts { // Diagnostics were produced and outputs were generated in spite of them. DiagnosticsPresent_OutputsGenerated = 2, + + // When build skipped because passed in project is invalid + InvalidProject_OutputsSkipped = 3, } export interface EmitResult { diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index f9bf2a8468d..d6a856cfe9f 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -113,12 +113,12 @@ namespace ts { getCurrentDirectory(): string; getCompilerOptions(): CompilerOptions; getSourceFiles(): ReadonlyArray; - getSyntacticDiagnostics(): ReadonlyArray; - getOptionsDiagnostics(): ReadonlyArray; - getGlobalDiagnostics(): ReadonlyArray; - getSemanticDiagnostics(): ReadonlyArray; + getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; + getOptionsDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; + getGlobalDiagnostics(cancellationToken?: CancellationToken): ReadonlyArray; + getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; getConfigFileParsingDiagnostics(): ReadonlyArray; - emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback): EmitResult; + emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken): EmitResult; } export function listFiles(program: ProgramToEmitFilesAndReportErrors, writeFileName: (s: string) => void) { @@ -132,25 +132,32 @@ namespace ts { /** * Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options */ - export function emitFilesAndReportErrors(program: ProgramToEmitFilesAndReportErrors, reportDiagnostic: DiagnosticReporter, writeFileName?: (s: string) => void, reportSummary?: ReportEmitErrorSummary, writeFile?: WriteFileCallback) { + export function emitFilesAndReportErrors( + program: ProgramToEmitFilesAndReportErrors, + reportDiagnostic: DiagnosticReporter, + writeFileName?: (s: string) => void, + reportSummary?: ReportEmitErrorSummary, + writeFile?: WriteFileCallback, + cancellationToken?: CancellationToken + ) { // First get and report any syntactic errors. const diagnostics = program.getConfigFileParsingDiagnostics().slice(); const configFileParsingDiagnosticsLength = diagnostics.length; - addRange(diagnostics, program.getSyntacticDiagnostics()); + addRange(diagnostics, program.getSyntacticDiagnostics(/*sourceFile*/ undefined, cancellationToken)); // If we didn't have any syntactic errors, then also try getting the global and // semantic errors. if (diagnostics.length === configFileParsingDiagnosticsLength) { - addRange(diagnostics, program.getOptionsDiagnostics()); - addRange(diagnostics, program.getGlobalDiagnostics()); + addRange(diagnostics, program.getOptionsDiagnostics(cancellationToken)); + addRange(diagnostics, program.getGlobalDiagnostics(cancellationToken)); if (diagnostics.length === configFileParsingDiagnosticsLength) { - addRange(diagnostics, program.getSemanticDiagnostics()); + addRange(diagnostics, program.getSemanticDiagnostics(/*sourceFile*/ undefined, cancellationToken)); } } // Emit and report any errors we ran into. - const { emittedFiles, emitSkipped, diagnostics: emitDiagnostics } = program.emit(/*targetSourceFile*/ undefined, writeFile); + const { emittedFiles, emitSkipped, diagnostics: emitDiagnostics } = program.emit(/*targetSourceFile*/ undefined, writeFile, cancellationToken); addRange(diagnostics, emitDiagnostics); sortAndDeduplicateDiagnostics(diagnostics).forEach(reportDiagnostic); diff --git a/src/testRunner/unittests/tsbuild/emptyFiles.ts b/src/testRunner/unittests/tsbuild/emptyFiles.ts index 17c6644ccc6..badad8f3377 100644 --- a/src/testRunner/unittests/tsbuild/emptyFiles.ts +++ b/src/testRunner/unittests/tsbuild/emptyFiles.ts @@ -14,7 +14,7 @@ namespace ts { const builder = createSolutionBuilder(host, ["/src/no-references"], { dry: false, force: false, verbose: false }); host.clearDiagnostics(); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages([Diagnostics.The_files_list_in_config_file_0_is_empty, "/src/no-references/tsconfig.json"]); // Check for outputs to not be written. @@ -29,7 +29,7 @@ namespace ts { const builder = createSolutionBuilder(host, ["/src/with-references"], { dry: false, force: false, verbose: false }); host.clearDiagnostics(); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(/*empty*/); // Check for outputs to be written. diff --git a/src/testRunner/unittests/tsbuild/helpers.ts b/src/testRunner/unittests/tsbuild/helpers.ts index 579573a876e..33a7afb181a 100644 --- a/src/testRunner/unittests/tsbuild/helpers.ts +++ b/src/testRunner/unittests/tsbuild/helpers.ts @@ -172,7 +172,7 @@ declare const console: { log(msg: any): void; };`; } return originalReadFile.call(host, path); }; - builder.buildAllProjects(); + builder.build(); generateSourceMapBaselineFiles(fs, expectedMapFileNames); generateBuildInfoSectionBaselineFiles(fs, expectedBuildInfoFilesForSectionBaselines || emptyArray); fs.makeReadonly(); diff --git a/src/testRunner/unittests/tsbuild/missingExtendedFile.ts b/src/testRunner/unittests/tsbuild/missingExtendedFile.ts index 00e8bfec1e3..881f3fbc030 100644 --- a/src/testRunner/unittests/tsbuild/missingExtendedFile.ts +++ b/src/testRunner/unittests/tsbuild/missingExtendedFile.ts @@ -5,7 +5,7 @@ namespace ts { const fs = projFs.shadow(); const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/tsconfig.json"], {}); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( [Diagnostics.The_specified_path_does_not_exist_Colon_0, "/src/foobar.json"], [Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, "/src/tsconfig.first.json", "[\"**/*\"]", "[]"], diff --git a/src/testRunner/unittests/tsbuild/outFile.ts b/src/testRunner/unittests/tsbuild/outFile.ts index 20061c86a7b..ea56c7f511d 100644 --- a/src/testRunner/unittests/tsbuild/outFile.ts +++ b/src/testRunner/unittests/tsbuild/outFile.ts @@ -363,7 +363,7 @@ namespace ts { ]; const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(...initialExpectedDiagnostics); // Verify they exist for (const output of expectedOutputs) { @@ -389,7 +389,7 @@ namespace ts { ]; const host = new fakes.SolutionBuilderHost(fs); let builder = createSolutionBuilder(host); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(...initialExpectedDiagnostics); // Verify they exist for (const output of expectedOutputs) { @@ -399,7 +399,7 @@ namespace ts { host.clearDiagnostics(); host.deleteFile(outputFiles[project.first][ext.buildinfo]); builder = createSolutionBuilder(host); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]), [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, relSources[project.first][source.config], relOutputFiles[project.first][ext.buildinfo]], @@ -416,7 +416,7 @@ namespace ts { const host = new fakes.SolutionBuilderHost(fs); replaceText(fs, sources[project.third][source.config], `"composite": true,`, ""); const builder = createSolutionBuilder(host); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(...initialExpectedDiagnostics); // Verify they exist - without tsbuildinfo for third project for (const output of expectedOutputFiles.slice(0, expectedOutputFiles.length - 2)) { @@ -429,12 +429,12 @@ namespace ts { const fs = outFileFs.shadow(); const host = new fakes.SolutionBuilderHost(fs); let builder = createSolutionBuilder(host); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(...initialExpectedDiagnostics); host.clearDiagnostics(); builder = createSolutionBuilder(host); changeCompilerVersion(host); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]), [Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2, relSources[project.first][source.config], fakes.version, version], @@ -454,7 +454,7 @@ namespace ts { // Build with command line incremental const host = new fakes.SolutionBuilderHost(fs); let builder = createSolutionBuilder(host, { incremental: true }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(...initialExpectedDiagnostics); host.clearDiagnostics(); tick(); @@ -462,7 +462,7 @@ namespace ts { // Make non incremental build with change in file that doesnt affect dts appendText(fs, relSources[project.first][source.ts][part.one], "console.log(s);"); builder = createSolutionBuilder(host, { verbose: true }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]), [Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, relSources[project.first][source.config], relOutputFiles[project.first][ext.js], relSources[project.first][source.ts][part.one]], [Diagnostics.Building_project_0, sources[project.first][source.config]], @@ -476,7 +476,7 @@ namespace ts { // Make incremental build with change in file that doesnt affect dts appendText(fs, relSources[project.first][source.ts][part.one], "console.log(s);"); builder = createSolutionBuilder(host, { verbose: true, incremental: true }); - builder.buildAllProjects(); + builder.build(); // Builds completely because tsbuildinfo is old. host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]), @@ -489,6 +489,23 @@ namespace ts { host.clearDiagnostics(); }); + it("builds till project specified", () => { + const fs = outFileFs.shadow(); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, { verbose: false }); + const result = builder.build(sources[project.second][source.config]); + host.assertDiagnosticMessages(/*empty*/); + // First and Third is not built + for (const output of [...outputFiles[project.first], ...outputFiles[project.third]]) { + assert.isFalse(fs.existsSync(output), `Expect file ${output} to not exist`); + } + // second is built + for (const output of outputFiles[project.second]) { + assert(fs.existsSync(output), `Expect file ${output} to exist`); + } + assert.equal(result, ExitStatus.Success); + }); + describe("Prepend output with .tsbuildinfo", () => { // Prologues describe("Prologues", () => { @@ -904,7 +921,7 @@ ${internal} enum internalEnum { a, b, c }`); const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]), [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, relSources[project.first][source.config], "src/first/first_PART1.js"], diff --git a/src/testRunner/unittests/tsbuild/referencesWithRootDirInParent.ts b/src/testRunner/unittests/tsbuild/referencesWithRootDirInParent.ts index 630cd8575ec..c965eb73067 100644 --- a/src/testRunner/unittests/tsbuild/referencesWithRootDirInParent.ts +++ b/src/testRunner/unittests/tsbuild/referencesWithRootDirInParent.ts @@ -19,7 +19,7 @@ namespace ts { const fs = projFs.shadow(); const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/src/main", "/src/src/other"], {}); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(/*empty*/); for (const output of allExpectedOutputs) { assert(fs.existsSync(output), `Expect file ${output} to exist`); @@ -39,7 +39,7 @@ namespace ts { replaceText(fs, "/src/tsconfig.base.json", `"rootDir": "./src/",`, ""); const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/src/main"], { verbose: true }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/src/other/tsconfig.json", "src/src/main/tsconfig.json"), [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/src/other/tsconfig.json", "src/dist/other.js"], @@ -75,7 +75,7 @@ namespace ts { })); const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/src/main"], { verbose: true }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/src/other/tsconfig.json", "src/src/main/tsconfig.json"), [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/src/other/tsconfig.json", "src/dist/other.js"], @@ -112,7 +112,7 @@ namespace ts { })); const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/src/main/tsconfig.main.json"], { verbose: true }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/src/other/tsconfig.other.json", "src/src/main/tsconfig.main.json"), [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/src/other/tsconfig.other.json", "src/dist/other.js"], diff --git a/src/testRunner/unittests/tsbuild/resolveJsonModule.ts b/src/testRunner/unittests/tsbuild/resolveJsonModule.ts index d2555a730a2..f1a40c050f9 100644 --- a/src/testRunner/unittests/tsbuild/resolveJsonModule.ts +++ b/src/testRunner/unittests/tsbuild/resolveJsonModule.ts @@ -19,7 +19,7 @@ namespace ts { function verifyProjectWithResolveJsonModuleWithFs(fs: vfs.FileSystem, configFile: string, allExpectedOutputs: ReadonlyArray, ...expectedDiagnosticMessages: fakes.ExpectedDiagnostic[]) { const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, [configFile], { dry: false, force: false, verbose: false }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(...expectedDiagnosticMessages); if (!expectedDiagnosticMessages.length) { // Check for outputs. Not an exhaustive list @@ -65,7 +65,7 @@ export default hello.hello`); replaceText(fs, configFile, `"composite": true,`, `"composite": true, "sourceMap": true,`); const host = new fakes.SolutionBuilderHost(fs); let builder = createSolutionBuilder(host, [configFile], { verbose: true }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild(configFile), [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, configFile, "src/dist/src/index.js"], @@ -77,7 +77,7 @@ export default hello.hello`); host.clearDiagnostics(); builder = createSolutionBuilder(host, [configFile], { verbose: true }); tick(); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild(configFile), [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, configFile, "src/src/index.ts", "src/dist/src/index.js"] @@ -90,7 +90,7 @@ export default hello.hello`); replaceText(fs, configFile, `"outDir": "dist",`, ""); const host = new fakes.SolutionBuilderHost(fs); let builder = createSolutionBuilder(host, [configFile], { verbose: true }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild(configFile), [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, configFile, "src/src/index.js"], @@ -102,7 +102,7 @@ export default hello.hello`); host.clearDiagnostics(); builder = createSolutionBuilder(host, [configFile], { verbose: true }); tick(); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild(configFile), [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, configFile, "src/src/index.ts", "src/src/index.js"] @@ -129,7 +129,7 @@ export default hello.hello`); const mainConfigFile = "src/main/tsconfig.json"; const host = new fakes.SolutionBuilderHost(fs); let builder = createSolutionBuilder(host, [configFile], { verbose: true }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild(stringsConfigFile, mainConfigFile, configFile), [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, stringsConfigFile, "src/strings/tsconfig.tsbuildinfo"], @@ -141,7 +141,7 @@ export default hello.hello`); host.clearDiagnostics(); builder = createSolutionBuilder(host, [configFile], { verbose: true }); tick(); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild(stringsConfigFile, mainConfigFile, configFile), [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, stringsConfigFile, "src/strings/foo.json", "src/strings/tsconfig.tsbuildinfo"], diff --git a/src/testRunner/unittests/tsbuild/sample.ts b/src/testRunner/unittests/tsbuild/sample.ts index 9119fd2fb96..3ad2b2e3eec 100644 --- a/src/testRunner/unittests/tsbuild/sample.ts +++ b/src/testRunner/unittests/tsbuild/sample.ts @@ -21,7 +21,7 @@ namespace ts { const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: false }); host.clearDiagnostics(); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(/*empty*/); // Check for outputs. Not an exhaustive list @@ -39,7 +39,7 @@ namespace ts { const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/tests"], {}); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(/*empty*/); const expectedOutputs = allExpectedOutputs.map(f => f.replace("/logic/", "/logic/outDir/")); // Check for outputs. Not an exhaustive list @@ -57,7 +57,7 @@ namespace ts { const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/tests"], {}); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(/*empty*/); const expectedOutputs = allExpectedOutputs.map(f => f.replace("/logic/index.d.ts", "/logic/out/decls/index.d.ts")); // Check for outputs. Not an exhaustive list @@ -71,7 +71,7 @@ namespace ts { replaceText(fs, "/src/core/tsconfig.json", `"composite": true,`, ""); const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/core"], { verbose: true }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json"), [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"], @@ -88,7 +88,7 @@ namespace ts { const fs = projFs.shadow(); const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/tests"], { dry: true, force: false, verbose: false }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( [Diagnostics.A_non_dry_build_would_build_project_0, "/src/core/tsconfig.json"], [Diagnostics.A_non_dry_build_would_build_project_0, "/src/logic/tsconfig.json"], @@ -106,12 +106,12 @@ namespace ts { const host = new fakes.SolutionBuilderHost(fs); let builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: false }); - builder.buildAllProjects(); + builder.build(); tick(); host.clearDiagnostics(); builder = createSolutionBuilder(host, ["/src/tests"], { dry: true, force: false, verbose: false }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( [Diagnostics.Project_0_is_up_to_date, "/src/core/tsconfig.json"], [Diagnostics.Project_0_is_up_to_date, "/src/logic/tsconfig.json"], @@ -126,7 +126,7 @@ namespace ts { const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: false }); - builder.buildAllProjects(); + builder.build(); // Verify they exist for (const output of allExpectedOutputs) { assert(fs.existsSync(output), `Expect file ${output} to exist`); @@ -146,15 +146,16 @@ namespace ts { const fs = projFs.shadow(); const host = new fakes.SolutionBuilderHost(fs); - const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: true, verbose: false }); - builder.buildAllProjects(); + let builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: true, verbose: false }); + builder.build(); let currentTime = time(); checkOutputTimestamps(currentTime); tick(); Debug.assert(time() !== currentTime, "Time moves on"); currentTime = time(); - builder.buildAllProjects(); + builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: true, verbose: false }); + builder.build(); checkOutputTimestamps(currentTime); function checkOutputTimestamps(expected: number) { @@ -172,7 +173,7 @@ namespace ts { const fs = projFs.shadow(); const host = new fakes.SolutionBuilderHost(fs); let builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true }); - builder.buildAllProjects(); + builder.build(); host.clearDiagnostics(); tick(); builder = createSolutionBuilder(host, ["/src/tests"], { ...(opts || {}), verbose: true }); @@ -183,7 +184,7 @@ namespace ts { const fs = projFs.shadow(); const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"], @@ -198,7 +199,7 @@ namespace ts { // All three projects are up to date it("Detects that all projects are up to date", () => { const { host, builder } = initializeWithBuild(); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/core/tsconfig.json", "src/core/anotherModule.ts", "src/core/anotherModule.js"], @@ -211,7 +212,7 @@ namespace ts { it("Only builds the leaf node project", () => { const { fs, host, builder } = initializeWithBuild(); fs.writeFileSync("/src/tests/index.ts", "const m = 10;"); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/core/tsconfig.json", "src/core/anotherModule.ts", "src/core/anotherModule.js"], @@ -225,7 +226,7 @@ namespace ts { it("Detects type-only changes in upstream projects", () => { const { fs, host, builder } = initializeWithBuild(); replaceText(fs, "/src/core/index.ts", "HELLO WORLD", "WELCOME PLANET"); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), @@ -242,7 +243,7 @@ namespace ts { it("rebuilds completely when version in tsbuildinfo doesnt match ts version", () => { const { host, builder } = initializeWithBuild(); changeCompilerVersion(host); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), [Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2, "src/core/tsconfig.json", fakes.version, version], @@ -256,7 +257,7 @@ namespace ts { it("rebuilds from start if --f is passed", () => { const { host, builder } = initializeWithBuild({ force: true }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/core/tsconfig.json", "src/core/anotherModule.ts", "src/core/anotherModule.js"], @@ -271,7 +272,7 @@ namespace ts { it("rebuilds when tsconfig changes", () => { const { fs, host, builder } = initializeWithBuild(); replaceText(fs, "/src/tests/tsconfig.json", `"composite": true`, `"composite": true, "target": "es3"`); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/core/tsconfig.json", "src/core/anotherModule.ts", "src/core/anotherModule.js"], @@ -287,7 +288,7 @@ namespace ts { replaceText(fs, "/src/tests/tsconfig.json", `"references": [`, `"extends": "./tsconfig.base.json", "references": [`); const host = new fakes.SolutionBuilderHost(fs); let builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"], @@ -301,7 +302,7 @@ namespace ts { tick(); builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true }); fs.writeFileSync("/src/tests/tsconfig.base.json", JSON.stringify({ compilerOptions: {} })); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/core/tsconfig.json", "src/core/anotherModule.ts", "src/core/anotherModule.js"], @@ -310,6 +311,31 @@ namespace ts { [Diagnostics.Building_project_0, "/src/tests/tsconfig.json"] ); }); + + it("builds till project specified", () => { + const fs = projFs.shadow(); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, ["/src/tests"], {}); + const result = builder.build("/src/logic"); + host.assertDiagnosticMessages(/*empty*/); + assert.isFalse(fs.existsSync(allExpectedOutputs[0]), `Expect file ${allExpectedOutputs[0]} to not exist`); + for (const output of allExpectedOutputs.slice(1)) { + assert(fs.existsSync(output), `Expect file ${output} to exist`); + } + assert.equal(result, ExitStatus.Success); + }); + + it("building project in not build order doesnt throw error", () => { + const fs = projFs.shadow(); + const host = new fakes.SolutionBuilderHost(fs); + const builder = createSolutionBuilder(host, ["/src/tests"], {}); + const result = builder.build("/src/logic2"); + host.assertDiagnosticMessages(/*empty*/); + for (const output of allExpectedOutputs) { + assert.isFalse(fs.existsSync(output), `Expect file ${output} to not exist`); + } + assert.equal(result, ExitStatus.InvalidProject_OutputsSkipped); + }); }); describe("downstream-blocked compilations", () => { @@ -320,7 +346,7 @@ namespace ts { // Induce an error in the middle project replaceText(fs, "/src/logic/index.ts", "c.multiply(10, 15)", `c.muitply()`); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages( getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"], @@ -340,7 +366,7 @@ namespace ts { const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/tests"], { dry: false, force: false, verbose: false }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(/*empty*/); // Update a timestamp in the middle project @@ -366,7 +392,7 @@ export class cNew {}`); // Rebuild this project tick(); builder.invalidateProject("/src/logic"); - builder.buildInvalidatedProject(); + builder.buildNextInvalidatedProject(); // The file should be updated assert.isTrue(writtenFiles.has("/src/logic/index.js"), "JS file should have been rebuilt"); assert.equal(fs.statSync("/src/logic/index.js").mtimeMs, time(), "JS file should have been rebuilt"); @@ -376,7 +402,7 @@ export class cNew {}`); // Build downstream projects should update 'tests', but not 'core' tick(); - builder.buildInvalidatedProject(); + builder.buildNextInvalidatedProject(); if (expectedToWriteTests) { assert.isTrue(writtenFiles.has("/src/tests/index.js"), "Downstream JS file should have been rebuilt"); } @@ -394,7 +420,7 @@ export class cNew {}`); const fs = projFs.shadow(); const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/tests"], { listFiles: true }); - builder.buildAllProjects(); + builder.build(); assert.deepEqual(host.traces, [ "/lib/lib.d.ts", "/src/core/anotherModule.ts", @@ -421,7 +447,7 @@ export class cNew {}`); const fs = projFs.shadow(); const host = new fakes.SolutionBuilderHost(fs); const builder = createSolutionBuilder(host, ["/src/tests"], { listEmittedFiles: true }); - builder.buildAllProjects(); + builder.build(); assert.deepEqual(host.traces, [ "TSFILE: /src/core/anotherModule.js", "TSFILE: /src/core/anotherModule.d.ts.map", diff --git a/src/testRunner/unittests/tsbuild/transitiveReferences.ts b/src/testRunner/unittests/tsbuild/transitiveReferences.ts index 30e28de8cde..94f364ddec0 100644 --- a/src/testRunner/unittests/tsbuild/transitiveReferences.ts +++ b/src/testRunner/unittests/tsbuild/transitiveReferences.ts @@ -30,7 +30,7 @@ namespace ts { const host = new fakes.SolutionBuilderHost(fs); modifyDiskLayout(fs); const builder = createSolutionBuilder(host, ["/src/tsconfig.c.json"], { listFiles: true }); - builder.buildAllProjects(); + builder.build(); host.assertDiagnosticMessages(...expectedDiagnostics); for (const output of allExpectedOutputs) { assert(fs.existsSync(output), `Expect file ${output} to exist`); diff --git a/src/testRunner/unittests/tsbuildWatchMode.ts b/src/testRunner/unittests/tsbuildWatchMode.ts index ef87aa1f9cb..ad00145db52 100644 --- a/src/testRunner/unittests/tsbuildWatchMode.ts +++ b/src/testRunner/unittests/tsbuildWatchMode.ts @@ -24,7 +24,7 @@ namespace ts.tscWatch { function createSolutionBuilderWithWatch(system: TsBuildWatchSystem, rootNames: ReadonlyArray, defaultOptions?: BuildOptions) { const host = createSolutionBuilderWithWatchHost(system); const solutionBuilder = ts.createSolutionBuilderWithWatch(host, rootNames, defaultOptions || { watch: true }); - solutionBuilder.buildAllProjects(); + solutionBuilder.build(); solutionBuilder.startWatching(); return solutionBuilder; } @@ -608,7 +608,7 @@ let x: string = 10;`); // Build the composite project const host = createTsBuildWatchSystem(allFiles, { currentDirectory }); const solutionBuilder = createSolutionBuilder(host, [solutionBuilderconfig], {}); - solutionBuilder.buildAllProjects(); + solutionBuilder.build(); const outputFileStamps = getOutputFileStamps(host); for (const stamp of outputFileStamps) { assert.isDefined(stamp[1], `${stamp[0]} expected to be present`); @@ -723,7 +723,7 @@ let x: string = 10;`); function foo() { }`); solutionBuilder.invalidateProject(`${project}/${SubProject.logic}`); - solutionBuilder.buildInvalidatedProject(); + solutionBuilder.buildNextInvalidatedProject(); // not ideal, but currently because of d.ts but no new file is written // There will be timeout queued even though file contents are same @@ -736,7 +736,7 @@ function foo() { export function gfoo() { }`); solutionBuilder.invalidateProject(logic[0].path); - solutionBuilder.buildInvalidatedProject(); + solutionBuilder.buildNextInvalidatedProject(); }, expectedProgramFiles); }); @@ -747,7 +747,7 @@ export function gfoo() { references: [{ path: "../core" }] })); solutionBuilder.invalidateProject(logic[0].path, ConfigFileProgramReloadLevel.Full); - solutionBuilder.buildInvalidatedProject(); + solutionBuilder.buildNextInvalidatedProject(); }, [tests[1].path, libFile.path, coreIndexDts, coreAnotherModuleDts, projectFilePath(SubProject.logic, "decls/index.d.ts")]); }); }); @@ -967,7 +967,7 @@ export function gfoo() { export function gfoo() { }`); solutionBuilder.invalidateProject(bTsconfig.path); - solutionBuilder.buildInvalidatedProject(); + solutionBuilder.buildNextInvalidatedProject(); }, emptyArray, expectedProgramFiles, diff --git a/src/testRunner/unittests/tsserver/projectReferences.ts b/src/testRunner/unittests/tsserver/projectReferences.ts index e39c510216d..f07774cd43c 100644 --- a/src/testRunner/unittests/tsserver/projectReferences.ts +++ b/src/testRunner/unittests/tsserver/projectReferences.ts @@ -5,7 +5,7 @@ namespace ts.projectSystem { // ts build should succeed const solutionBuilder = tscWatch.createSolutionBuilder(host, rootNames, {}); - solutionBuilder.buildAllProjects(); + solutionBuilder.build(); assert.equal(host.getOutput().length, 0); return host; diff --git a/src/tsc/tsc.ts b/src/tsc/tsc.ts index 35bd29ea774..fc5559be023 100644 --- a/src/tsc/tsc.ts +++ b/src/tsc/tsc.ts @@ -216,7 +216,7 @@ namespace ts { updateCreateProgram(buildHost); buildHost.afterProgramEmitAndDiagnostics = program => reportStatistics(program.getProgram()); const builder = createSolutionBuilderWithWatch(buildHost, projects, buildOptions); - builder.buildAllProjects(); + builder.build(); return builder.startWatching(); } else { @@ -224,7 +224,7 @@ namespace ts { updateCreateProgram(buildHost); buildHost.afterProgramEmitAndDiagnostics = program => reportStatistics(program.getProgram()); const builder = createSolutionBuilder(buildHost, projects, buildOptions); - return sys.exit(buildOptions.clean ? builder.cleanAllProjects() : builder.buildAllProjects()); + return sys.exit(buildOptions.clean ? builder.cleanAllProjects() : builder.build()); } }