Skip to content

Commit 66049c3

Browse files
committed
Merge branch 'master' into noConstraint-is-unknown
2 parents 5dce990 + 025d826 commit 66049c3

File tree

38 files changed

+278
-31
lines changed

38 files changed

+278
-31
lines changed

src/compiler/builder.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ namespace ts {
792792
state,
793793
// When whole program is affected, do emit only once (eg when --out or --outFile is specified)
794794
// Otherwise just affected file
795-
affected.emitBuildInfo(writeFile || host.writeFile, cancellationToken),
795+
affected.emitBuildInfo(writeFile || maybeBind(host, host.writeFile), cancellationToken),
796796
affected,
797797
/*isPendingEmitFile*/ false,
798798
/*isBuildInfoEmit*/ true
@@ -820,7 +820,7 @@ namespace ts {
820820
state,
821821
// When whole program is affected, do emit only once (eg when --out or --outFile is specified)
822822
// Otherwise just affected file
823-
Debug.assertDefined(state.program).emit(affected === state.program ? undefined : affected as SourceFile, writeFile || host.writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers),
823+
Debug.assertDefined(state.program).emit(affected === state.program ? undefined : affected as SourceFile, writeFile || maybeBind(host, host.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers),
824824
affected,
825825
isPendingEmitFile
826826
);
@@ -862,7 +862,7 @@ namespace ts {
862862
};
863863
}
864864
}
865-
return Debug.assertDefined(state.program).emit(targetSourceFile, writeFile || host.writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
865+
return Debug.assertDefined(state.program).emit(targetSourceFile, writeFile || maybeBind(host, host.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers);
866866
}
867867

868868
/**

src/compiler/commandLineParser.ts

+7-8
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@ namespace ts {
136136
category: Diagnostics.Advanced_Options,
137137
description: Diagnostics.Show_verbose_diagnostic_information
138138
},
139+
{
140+
name: "incremental",
141+
shortName: "i",
142+
type: "boolean",
143+
category: Diagnostics.Basic_Options,
144+
description: Diagnostics.Enable_incremental_compilation,
145+
},
139146
];
140147

141148
/* @internal */
@@ -331,19 +338,11 @@ namespace ts {
331338
category: Diagnostics.Basic_Options,
332339
description: Diagnostics.Enable_project_compilation,
333340
},
334-
{
335-
name: "incremental",
336-
type: "boolean",
337-
isTSConfigOnly: true,
338-
category: Diagnostics.Basic_Options,
339-
description: Diagnostics.Enable_incremental_compilation,
340-
},
341341
{
342342
name: "tsBuildInfoFile",
343343
type: "string",
344344
isFilePath: true,
345345
paramType: Diagnostics.FILE,
346-
isTSConfigOnly: true,
347346
category: Diagnostics.Basic_Options,
348347
description: Diagnostics.Specify_file_to_store_incremental_compilation_information,
349348
},

src/compiler/diagnosticMessages.json

+4
Original file line numberDiff line numberDiff line change
@@ -3072,6 +3072,10 @@
30723072
"category": "Error",
30733073
"code": 5073
30743074
},
3075+
"Option '--incremental' can only be specified using tsconfig, emitting to single file or when option `--tsBuildInfoFile` is specified.": {
3076+
"category": "Error",
3077+
"code": 5074
3078+
},
30753079

30763080
"Generates a sourcemap for each corresponding '.d.ts' file.": {
30773081
"category": "Message",

src/compiler/emitter.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,15 @@ namespace ts {
5454
/*@internal*/
5555
export function getOutputPathForBuildInfo(options: CompilerOptions) {
5656
const configFile = options.configFilePath;
57-
if (!configFile || !isIncrementalCompilation(options)) return undefined;
57+
if (!isIncrementalCompilation(options)) return undefined;
5858
if (options.tsBuildInfoFile) return options.tsBuildInfoFile;
5959
const outPath = options.outFile || options.out;
6060
let buildInfoExtensionLess: string;
6161
if (outPath) {
6262
buildInfoExtensionLess = removeFileExtension(outPath);
6363
}
6464
else {
65+
if (!configFile) return undefined;
6566
const configFileExtensionLess = removeFileExtension(configFile);
6667
buildInfoExtensionLess = options.outDir ?
6768
options.rootDir ?

src/compiler/program.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,8 @@ namespace ts {
193193
getDirectories: (path: string) => system.getDirectories(path),
194194
realpath,
195195
readDirectory: (path, extensions, include, exclude, depth) => system.readDirectory(path, extensions, include, exclude, depth),
196-
createDirectory: d => system.createDirectory(d)
196+
createDirectory: d => system.createDirectory(d),
197+
createHash: maybeBind(system, system.createHash)
197198
};
198199
return compilerHost;
199200
}
@@ -315,7 +316,10 @@ namespace ts {
315316
};
316317
}
317318

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

331335
return sortAndDeduplicateDiagnostics(diagnostics);
332336
}
337+
// tslint:enable unified-signatures
333338

334339
export interface FormatDiagnosticsHost {
335340
getCurrentDirectory(): string;
@@ -2730,6 +2735,9 @@ namespace ts {
27302735
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "tsBuildInfoFile", "incremental", "composite");
27312736
}
27322737
}
2738+
else if (options.incremental && !options.outFile && !options.out && !options.configFilePath) {
2739+
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified));
2740+
}
27332741

27342742
verifyProjectReferences();
27352743

src/compiler/tsbuild.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace ts {
3030
listEmittedFiles?: boolean;
3131
listFiles?: boolean;
3232
pretty?: boolean;
33+
incremental?: boolean;
3334

3435
traceResolution?: boolean;
3536
/* @internal */ diagnostics?: boolean;
@@ -363,7 +364,7 @@ namespace ts {
363364
function getCompilerOptionsOfBuildOptions(buildOptions: BuildOptions): CompilerOptions {
364365
const result = {} as CompilerOptions;
365366
commonOptionsWithBuild.forEach(option => {
366-
result[option.name] = buildOptions[option.name];
367+
if (hasProperty(buildOptions, option.name)) result[option.name] = buildOptions[option.name];
367368
});
368369
return result;
369370
}

src/services/codefixes/fixAddMissingMember.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace ts.codefix {
1212
registerCodeFix({
1313
errorCodes,
1414
getCodeActions(context) {
15-
const info = getInfo(context.sourceFile, context.span.start, context.program.getTypeChecker());
15+
const info = getInfo(context.sourceFile, context.span.start, context.program.getTypeChecker(), context.program);
1616
if (!info) return undefined;
1717

1818
if (info.kind === InfoKind.Enum) {
@@ -37,7 +37,7 @@ namespace ts.codefix {
3737

3838
return createCombinedCodeActions(textChanges.ChangeTracker.with(context, changes => {
3939
eachDiagnostic(context, errorCodes, diag => {
40-
const info = getInfo(diag.file, diag.start, checker);
40+
const info = getInfo(diag.file, diag.start, checker, context.program);
4141
if (!info || !addToSeen(seen, getNodeId(info.parentDeclaration) + "#" + info.token.text)) {
4242
return;
4343
}
@@ -113,7 +113,7 @@ namespace ts.codefix {
113113
}
114114
type Info = EnumInfo | ClassOrInterfaceInfo;
115115

116-
function getInfo(tokenSourceFile: SourceFile, tokenPos: number, checker: TypeChecker): Info | undefined {
116+
function getInfo(tokenSourceFile: SourceFile, tokenPos: number, checker: TypeChecker, program: Program): Info | undefined {
117117
// The identifier of the missing property. eg:
118118
// this.missing = 1;
119119
// ^^^^^^^
@@ -131,15 +131,15 @@ namespace ts.codefix {
131131

132132
// Prefer to change the class instead of the interface if they are merged
133133
const classOrInterface = find(symbol.declarations, isClassLike) || find(symbol.declarations, isInterfaceDeclaration);
134-
if (classOrInterface) {
134+
if (classOrInterface && !program.isSourceFileFromExternalLibrary(classOrInterface.getSourceFile())) {
135135
const makeStatic = ((leftExpressionType as TypeReference).target || leftExpressionType) !== checker.getDeclaredTypeOfSymbol(symbol);
136136
const declSourceFile = classOrInterface.getSourceFile();
137137
const inJs = isSourceFileJS(declSourceFile);
138138
const call = tryCast(parent.parent, isCallExpression);
139139
return { kind: InfoKind.ClassOrInterface, token, parentDeclaration: classOrInterface, makeStatic, declSourceFile, inJs, call };
140140
}
141141
const enumDeclaration = find(symbol.declarations, isEnumDeclaration);
142-
if (enumDeclaration) {
142+
if (enumDeclaration && !program.isSourceFileFromExternalLibrary(enumDeclaration.getSourceFile())) {
143143
return { kind: InfoKind.Enum, token, parentDeclaration: enumDeclaration };
144144
}
145145
return undefined;

src/testRunner/unittests/config/commandLineParsing.ts

+47
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,26 @@ namespace ts {
365365
}
366366
});
367367
});
368+
369+
it("parse --incremental", () => {
370+
// --lib es6 0.ts
371+
assertParseResult(["--incremental", "0.ts"],
372+
{
373+
errors: [],
374+
fileNames: ["0.ts"],
375+
options: { incremental: true }
376+
});
377+
});
378+
379+
it("parse --tsBuildInfoFile", () => {
380+
// --lib es6 0.ts
381+
assertParseResult(["--tsBuildInfoFile", "build.tsbuildinfo", "0.ts"],
382+
{
383+
errors: [],
384+
fileNames: ["0.ts"],
385+
options: { tsBuildInfoFile: "build.tsbuildinfo" }
386+
});
387+
});
368388
});
369389

370390
describe("unittests:: config:: commandLineParsing:: parseBuildOptions", () => {
@@ -456,6 +476,33 @@ namespace ts {
456476
});
457477
});
458478

479+
it("parse build with --incremental", () => {
480+
// --lib es6 0.ts
481+
assertParseResult(["--incremental", "tests"],
482+
{
483+
errors: [],
484+
projects: ["tests"],
485+
buildOptions: { incremental: true }
486+
});
487+
});
488+
489+
it("parse build with --tsBuildInfoFile", () => {
490+
// --lib es6 0.ts
491+
assertParseResult(["--tsBuildInfoFile", "build.tsbuildinfo", "tests"],
492+
{
493+
errors: [{
494+
messageText: "Unknown build option '--tsBuildInfoFile'.",
495+
category: Diagnostics.Unknown_build_option_0.category,
496+
code: Diagnostics.Unknown_build_option_0.code,
497+
file: undefined,
498+
start: undefined,
499+
length: undefined
500+
}],
501+
projects: ["build.tsbuildinfo", "tests"],
502+
buildOptions: { }
503+
});
504+
});
505+
459506
describe("Combining options that make no sense together", () => {
460507
function verifyInvalidCombination(flag1: keyof BuildOptions, flag2: keyof BuildOptions) {
461508
it(`--${flag1} and --${flag2} together is invalid`, () => {

src/testRunner/unittests/tsbuild/outFile.ts

+45-2
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ namespace ts {
197197
dtsUnchangedExpectedReadFilesDependOrdered = undefined!;
198198
});
199199

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

204204
function getInitialExpectedReadFiles(additionalSourceFiles?: ReadonlyArray<string>) {
@@ -446,6 +446,49 @@ namespace ts {
446446
);
447447
});
448448

449+
it("rebuilds completely when command line incremental flag changes between non dts changes", () => {
450+
const fs = outFileFs.shadow();
451+
// Make non composite third project
452+
replaceText(fs, sources[project.third][source.config], `"composite": true,`, "");
453+
454+
// Build with command line incremental
455+
const host = new fakes.SolutionBuilderHost(fs);
456+
const builder = createSolutionBuilder(host, { incremental: true });
457+
builder.buildAllProjects();
458+
host.assertDiagnosticMessages(...initialExpectedDiagnostics);
459+
host.clearDiagnostics();
460+
tick();
461+
462+
// Make non incremental build with change in file that doesnt affect dts
463+
appendText(fs, relSources[project.first][source.ts][part.one], "console.log(s);");
464+
builder.resetBuildContext({ verbose: true });
465+
builder.buildAllProjects();
466+
host.assertDiagnosticMessages(getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]),
467+
[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]],
468+
[Diagnostics.Building_project_0, sources[project.first][source.config]],
469+
[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]],
470+
[Diagnostics.Project_0_is_out_of_date_because_output_of_its_dependency_1_has_changed, relSources[project.third][source.config], "src/first"],
471+
[Diagnostics.Building_project_0, sources[project.third][source.config]]
472+
);
473+
host.clearDiagnostics();
474+
tick();
475+
476+
// Make incremental build with change in file that doesnt affect dts
477+
appendText(fs, relSources[project.first][source.ts][part.one], "console.log(s);");
478+
builder.resetBuildContext({ verbose: true, incremental: true });
479+
builder.buildAllProjects();
480+
// Builds completely because tsbuildinfo is old.
481+
host.assertDiagnosticMessages(
482+
getExpectedDiagnosticForProjectsInBuild(relSources[project.first][source.config], relSources[project.second][source.config], relSources[project.third][source.config]),
483+
[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]],
484+
[Diagnostics.Building_project_0, sources[project.first][source.config]],
485+
[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]],
486+
[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"],
487+
[Diagnostics.Building_project_0, sources[project.third][source.config]]
488+
);
489+
host.clearDiagnostics();
490+
});
491+
449492
describe("Prepend output with .tsbuildinfo", () => {
450493
// Prologues
451494
describe("Prologues", () => {

src/tsc/tsc.ts

+3
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ namespace ts {
165165
reportWatchModeWithoutSysSupport();
166166
createWatchOfFilesAndCompilerOptions(commandLine.fileNames, commandLineOptions);
167167
}
168+
else if (isIncrementalCompilation(commandLineOptions)) {
169+
performIncrementalCompilation(commandLine);
170+
}
168171
else {
169172
performCompilation(commandLine.fileNames, /*references*/ undefined, commandLineOptions);
170173
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//// [a.ts]
2+
const x = 10;
3+
4+
5+
//// [a.js]
6+
var x = 10;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
=== /a.ts ===
2+
const x = 10;
3+
>x : Symbol(x, Decl(a.ts, 0, 5))
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
=== /a.ts ===
2+
const x = 10;
3+
>x : 10
4+
>10 : 10
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error TS5074: Option '--incremental' can only be specified using tsconfig, emitting to single file or when option `--tsBuildInfoFile` is specified.
2+
3+
4+
!!! error TS5074: Option '--incremental' can only be specified using tsconfig, emitting to single file or when option `--tsBuildInfoFile` is specified.
5+
==== tests/cases/compiler/incrementalInvalid.ts (0 errors) ====
6+
const x = 10;
7+
8+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//// [incrementalInvalid.ts]
2+
const x = 10;
3+
4+
5+
6+
//// [incrementalInvalid.js]
7+
var x = 10;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
=== tests/cases/compiler/incrementalInvalid.ts ===
2+
const x = 10;
3+
>x : Symbol(x, Decl(incrementalInvalid.ts, 0, 5))
4+
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
=== tests/cases/compiler/incrementalInvalid.ts ===
2+
const x = 10;
3+
>x : 10
4+
>10 : 10
5+
6+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//// [incrementalOut.ts]
2+
const x = 10;
3+
4+
5+
6+
//// [output.js]
7+
var x = 10;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
=== tests/cases/compiler/incrementalOut.ts ===
2+
const x = 10;
3+
>x : Symbol(x, Decl(incrementalOut.ts, 0, 5))
4+
5+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
=== tests/cases/compiler/incrementalOut.ts ===
2+
const x = 10;
3+
>x : 10
4+
>10 : 10
5+
6+

0 commit comments

Comments
 (0)