Skip to content

Commit

Permalink
Merge pull request #30513 from Microsoft/incrementalFromCommandLine
Browse files Browse the repository at this point in the history
Allow --incremental from command line
  • Loading branch information
sheetalkamat authored Mar 29, 2019
2 parents 17cedda + cf8b308 commit 025d826
Show file tree
Hide file tree
Showing 35 changed files with 237 additions and 26 deletions.
6 changes: 3 additions & 3 deletions src/compiler/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ namespace ts {
state,
// When whole program is affected, do emit only once (eg when --out or --outFile is specified)
// Otherwise just affected file
affected.emitBuildInfo(writeFile || host.writeFile, cancellationToken),
affected.emitBuildInfo(writeFile || maybeBind(host, host.writeFile), cancellationToken),
affected,
/*isPendingEmitFile*/ false,
/*isBuildInfoEmit*/ true
Expand Down Expand Up @@ -820,7 +820,7 @@ namespace ts {
state,
// When whole program is affected, do emit only once (eg when --out or --outFile is specified)
// Otherwise just affected file
Debug.assertDefined(state.program).emit(affected === state.program ? undefined : affected as SourceFile, writeFile || host.writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers),
Debug.assertDefined(state.program).emit(affected === state.program ? undefined : affected as SourceFile, writeFile || maybeBind(host, host.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers),
affected,
isPendingEmitFile
);
Expand Down Expand Up @@ -862,7 +862,7 @@ namespace ts {
};
}
}
return Debug.assertDefined(state.program).emit(targetSourceFile, writeFile || host.writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
return Debug.assertDefined(state.program).emit(targetSourceFile, writeFile || maybeBind(host, host.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers);
}

/**
Expand Down
15 changes: 7 additions & 8 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ namespace ts {
category: Diagnostics.Advanced_Options,
description: Diagnostics.Show_verbose_diagnostic_information
},
{
name: "incremental",
shortName: "i",
type: "boolean",
category: Diagnostics.Basic_Options,
description: Diagnostics.Enable_incremental_compilation,
},
];

/* @internal */
Expand Down Expand Up @@ -331,19 +338,11 @@ namespace ts {
category: Diagnostics.Basic_Options,
description: Diagnostics.Enable_project_compilation,
},
{
name: "incremental",
type: "boolean",
isTSConfigOnly: true,
category: Diagnostics.Basic_Options,
description: Diagnostics.Enable_incremental_compilation,
},
{
name: "tsBuildInfoFile",
type: "string",
isFilePath: true,
paramType: Diagnostics.FILE,
isTSConfigOnly: true,
category: Diagnostics.Basic_Options,
description: Diagnostics.Specify_file_to_store_incremental_compilation_information,
},
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3072,6 +3072,10 @@
"category": "Error",
"code": 5073
},
"Option '--incremental' can only be specified using tsconfig, emitting to single file or when option `--tsBuildInfoFile` is specified.": {
"category": "Error",
"code": 5074
},

"Generates a sourcemap for each corresponding '.d.ts' file.": {
"category": "Message",
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,15 @@ namespace ts {
/*@internal*/
export function getOutputPathForBuildInfo(options: CompilerOptions) {
const configFile = options.configFilePath;
if (!configFile || !isIncrementalCompilation(options)) return undefined;
if (!isIncrementalCompilation(options)) return undefined;
if (options.tsBuildInfoFile) return options.tsBuildInfoFile;
const outPath = options.outFile || options.out;
let buildInfoExtensionLess: string;
if (outPath) {
buildInfoExtensionLess = removeFileExtension(outPath);
}
else {
if (!configFile) return undefined;
const configFileExtensionLess = removeFileExtension(configFile);
buildInfoExtensionLess = options.outDir ?
options.rootDir ?
Expand Down
12 changes: 10 additions & 2 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ namespace ts {
getDirectories: (path: string) => system.getDirectories(path),
realpath,
readDirectory: (path, extensions, include, exclude, depth) => system.readDirectory(path, extensions, include, exclude, depth),
createDirectory: d => system.createDirectory(d)
createDirectory: d => system.createDirectory(d),
createHash: maybeBind(system, system.createHash)
};
return compilerHost;
}
Expand Down Expand Up @@ -315,7 +316,10 @@ namespace ts {
};
}

export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic> {
// tslint:disable unified-signatures
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
/*@internal*/ export function getPreEmitDiagnostics(program: BuilderProgram, sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
export function getPreEmitDiagnostics(program: Program | BuilderProgram, sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic> {
const diagnostics = [
...program.getConfigFileParsingDiagnostics(),
...program.getOptionsDiagnostics(cancellationToken),
Expand All @@ -330,6 +334,7 @@ namespace ts {

return sortAndDeduplicateDiagnostics(diagnostics);
}
// tslint:enable unified-signatures

export interface FormatDiagnosticsHost {
getCurrentDirectory(): string;
Expand Down Expand Up @@ -2730,6 +2735,9 @@ namespace ts {
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "tsBuildInfoFile", "incremental", "composite");
}
}
else if (options.incremental && !options.outFile && !options.out && !options.configFilePath) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified));
}

verifyProjectReferences();

Expand Down
3 changes: 2 additions & 1 deletion src/compiler/tsbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace ts {
listEmittedFiles?: boolean;
listFiles?: boolean;
pretty?: boolean;
incremental?: boolean;

traceResolution?: boolean;
/* @internal */ diagnostics?: boolean;
Expand Down Expand Up @@ -363,7 +364,7 @@ namespace ts {
function getCompilerOptionsOfBuildOptions(buildOptions: BuildOptions): CompilerOptions {
const result = {} as CompilerOptions;
commonOptionsWithBuild.forEach(option => {
result[option.name] = buildOptions[option.name];
if (hasProperty(buildOptions, option.name)) result[option.name] = buildOptions[option.name];
});
return result;
}
Expand Down
47 changes: 47 additions & 0 deletions src/testRunner/unittests/config/commandLineParsing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,26 @@ namespace ts {
}
});
});

it("parse --incremental", () => {
// --lib es6 0.ts
assertParseResult(["--incremental", "0.ts"],
{
errors: [],
fileNames: ["0.ts"],
options: { incremental: true }
});
});

it("parse --tsBuildInfoFile", () => {
// --lib es6 0.ts
assertParseResult(["--tsBuildInfoFile", "build.tsbuildinfo", "0.ts"],
{
errors: [],
fileNames: ["0.ts"],
options: { tsBuildInfoFile: "build.tsbuildinfo" }
});
});
});

describe("unittests:: config:: commandLineParsing:: parseBuildOptions", () => {
Expand Down Expand Up @@ -456,6 +476,33 @@ namespace ts {
});
});

it("parse build with --incremental", () => {
// --lib es6 0.ts
assertParseResult(["--incremental", "tests"],
{
errors: [],
projects: ["tests"],
buildOptions: { incremental: true }
});
});

it("parse build with --tsBuildInfoFile", () => {
// --lib es6 0.ts
assertParseResult(["--tsBuildInfoFile", "build.tsbuildinfo", "tests"],
{
errors: [{
messageText: "Unknown build option '--tsBuildInfoFile'.",
category: Diagnostics.Unknown_build_option_0.category,
code: Diagnostics.Unknown_build_option_0.code,
file: undefined,
start: undefined,
length: undefined
}],
projects: ["build.tsbuildinfo", "tests"],
buildOptions: { }
});
});

describe("Combining options that make no sense together", () => {
function verifyInvalidCombination(flag1: keyof BuildOptions, flag2: keyof BuildOptions) {
it(`--${flag1} and --${flag2} together is invalid`, () => {
Expand Down
47 changes: 45 additions & 2 deletions src/testRunner/unittests/tsbuild/outFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ namespace ts {
dtsUnchangedExpectedReadFilesDependOrdered = undefined!;
});

function createSolutionBuilder(host: fakes.SolutionBuilderHost) {
return ts.createSolutionBuilder(host, ["/src/third"], { dry: false, force: false, verbose: true });
function createSolutionBuilder(host: fakes.SolutionBuilderHost, baseOptions?: BuildOptions) {
return ts.createSolutionBuilder(host, ["/src/third"], { dry: false, force: false, verbose: true, ...(baseOptions || {}) });
}

function getInitialExpectedReadFiles(additionalSourceFiles?: ReadonlyArray<string>) {
Expand Down Expand Up @@ -446,6 +446,49 @@ namespace ts {
);
});

it("rebuilds completely when command line incremental flag changes between non dts changes", () => {
const fs = outFileFs.shadow();
// Make non composite third project
replaceText(fs, sources[project.third][source.config], `"composite": true,`, "");

// Build with command line incremental
const host = new fakes.SolutionBuilderHost(fs);
const builder = createSolutionBuilder(host, { incremental: true });
builder.buildAllProjects();
host.assertDiagnosticMessages(...initialExpectedDiagnostics);
host.clearDiagnostics();
tick();

// 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.resetBuildContext({ verbose: true });
builder.buildAllProjects();
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]],
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, relSources[project.second][source.config], relSources[project.second][source.ts][part.one], relOutputFiles[project.second][ext.js]],
[Diagnostics.Project_0_is_out_of_date_because_output_of_its_dependency_1_has_changed, relSources[project.third][source.config], "src/first"],
[Diagnostics.Building_project_0, sources[project.third][source.config]]
);
host.clearDiagnostics();
tick();

// Make incremental build with change in file that doesnt affect dts
appendText(fs, relSources[project.first][source.ts][part.one], "console.log(s);");
builder.resetBuildContext({ verbose: true, incremental: true });
builder.buildAllProjects();
// Builds completely because tsbuildinfo is old.
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]],
[Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, relSources[project.second][source.config], relSources[project.second][source.ts][part.one], relOutputFiles[project.second][ext.js]],
[Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, relSources[project.third][source.config], relOutputFiles[project.third][ext.buildinfo], "src/first"],
[Diagnostics.Building_project_0, sources[project.third][source.config]]
);
host.clearDiagnostics();
});

describe("Prepend output with .tsbuildinfo", () => {
// Prologues
describe("Prologues", () => {
Expand Down
3 changes: 3 additions & 0 deletions src/tsc/tsc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ namespace ts {
reportWatchModeWithoutSysSupport();
createWatchOfFilesAndCompilerOptions(commandLine.fileNames, commandLineOptions);
}
else if (isIncrementalCompilation(commandLineOptions)) {
performIncrementalCompilation(commandLine);
}
else {
performCompilation(commandLine.fileNames, /*references*/ undefined, commandLineOptions);
}
Expand Down
6 changes: 6 additions & 0 deletions tests/baselines/reference/incrementalConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//// [a.ts]
const x = 10;


//// [a.js]
var x = 10;
4 changes: 4 additions & 0 deletions tests/baselines/reference/incrementalConfig.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
=== /a.ts ===
const x = 10;
>x : Symbol(x, Decl(a.ts, 0, 5))

5 changes: 5 additions & 0 deletions tests/baselines/reference/incrementalConfig.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
=== /a.ts ===
const x = 10;
>x : 10
>10 : 10

8 changes: 8 additions & 0 deletions tests/baselines/reference/incrementalInvalid.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error TS5074: Option '--incremental' can only be specified using tsconfig, emitting to single file or when option `--tsBuildInfoFile` is specified.


!!! error TS5074: Option '--incremental' can only be specified using tsconfig, emitting to single file or when option `--tsBuildInfoFile` is specified.
==== tests/cases/compiler/incrementalInvalid.ts (0 errors) ====
const x = 10;


7 changes: 7 additions & 0 deletions tests/baselines/reference/incrementalInvalid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//// [incrementalInvalid.ts]
const x = 10;



//// [incrementalInvalid.js]
var x = 10;
5 changes: 5 additions & 0 deletions tests/baselines/reference/incrementalInvalid.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
=== tests/cases/compiler/incrementalInvalid.ts ===
const x = 10;
>x : Symbol(x, Decl(incrementalInvalid.ts, 0, 5))


6 changes: 6 additions & 0 deletions tests/baselines/reference/incrementalInvalid.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
=== tests/cases/compiler/incrementalInvalid.ts ===
const x = 10;
>x : 10
>10 : 10


7 changes: 7 additions & 0 deletions tests/baselines/reference/incrementalOut.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//// [incrementalOut.ts]
const x = 10;



//// [output.js]
var x = 10;
5 changes: 5 additions & 0 deletions tests/baselines/reference/incrementalOut.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
=== tests/cases/compiler/incrementalOut.ts ===
const x = 10;
>x : Symbol(x, Decl(incrementalOut.ts, 0, 5))


6 changes: 6 additions & 0 deletions tests/baselines/reference/incrementalOut.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
=== tests/cases/compiler/incrementalOut.ts ===
const x = 10;
>x : 10
>10 : 10


8 changes: 8 additions & 0 deletions tests/baselines/reference/incrementalTsBuildInfoFile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//// [a.ts]
const x = 10;




//// [a.js]
var x = 10;
6 changes: 6 additions & 0 deletions tests/baselines/reference/incrementalTsBuildInfoFile.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
=== /a.ts ===
const x = 10;
>x : Symbol(x, Decl(a.ts, 0, 5))



7 changes: 7 additions & 0 deletions tests/baselines/reference/incrementalTsBuildInfoFile.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
=== /a.ts ===
const x = 10;
>x : 10
>10 : 10



Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"compilerOptions": {
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
Expand All @@ -14,7 +15,6 @@
// "outDir": "./", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "incremental": true, /* Enable incremental compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
Expand Down
Loading

0 comments on commit 025d826

Please sign in to comment.