Merge branch 'master' into tsbuildWatchImprovements

This commit is contained in:
Sheetal Nandi
2018-09-11 11:45:57 -07:00
88 changed files with 715 additions and 392 deletions
+20 -3
View File
@@ -19208,12 +19208,16 @@ namespace ts {
let aboveArgCount = Number.POSITIVE_INFINITY;
let argCount = args.length;
let closestSignature: Signature | undefined;
for (const sig of signatures) {
const minCount = getMinArgumentCount(sig);
const maxCount = getParameterCount(sig);
if (minCount < argCount && minCount > belowArgCount) belowArgCount = minCount;
if (argCount < maxCount && maxCount < aboveArgCount) aboveArgCount = maxCount;
min = Math.min(min, minCount);
if (minCount < min) {
min = minCount;
closestSignature = sig;
}
max = Math.max(max, maxCount);
}
@@ -19226,16 +19230,29 @@ namespace ts {
argCount--;
}
let related: DiagnosticWithLocation | undefined;
if (closestSignature && getMinArgumentCount(closestSignature) > argCount && closestSignature.declaration) {
const paramDecl = closestSignature.declaration.parameters[closestSignature.thisParameter ? argCount + 1 : argCount];
if (paramDecl) {
related = createDiagnosticForNode(
paramDecl,
isBindingPattern(paramDecl.name) ? Diagnostics.An_argument_matching_this_binding_pattern_was_not_provided : Diagnostics.An_argument_for_0_was_not_provided,
!paramDecl.name ? argCount : !isBindingPattern(paramDecl.name) ? idText(getFirstIdentifier(paramDecl.name)) : undefined
);
}
}
if (hasRestParameter || hasSpreadArgument) {
const error = hasRestParameter && hasSpreadArgument ? Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more :
hasRestParameter ? Diagnostics.Expected_at_least_0_arguments_but_got_1 :
Diagnostics.Expected_0_arguments_but_got_1_or_more;
return createDiagnosticForNode(node, error, paramRange, argCount);
const diagnostic = createDiagnosticForNode(node, error, paramRange, argCount);
return related ? addRelatedInfo(diagnostic, related) : diagnostic;
}
if (min < argCount && argCount < max) {
return createDiagnosticForNode(node, Diagnostics.No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments, argCount, belowArgCount, aboveArgCount);
}
return createDiagnosticForNode(node, Diagnostics.Expected_0_arguments_but_got_1, paramRange, argCount);
const diagnostic = createDiagnosticForNode(node, Diagnostics.Expected_0_arguments_but_got_1, paramRange, argCount);
return related ? addRelatedInfo(diagnostic, related) : diagnostic;
}
function getTypeArgumentArityError(node: Node, signatures: ReadonlyArray<Signature>, typeArguments: NodeArray<TypeNode>) {
+16 -7
View File
@@ -1844,8 +1844,21 @@ namespace ts {
if (hasProperty(raw, "files") && !isNullOrUndefined(raw.files)) {
if (isArray(raw.files)) {
filesSpecs = <ReadonlyArray<string>>raw.files;
if (filesSpecs.length === 0) {
createCompilerDiagnosticOnlyIfJson(Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json");
const hasReferences = hasProperty(raw, "references") && !isNullOrUndefined(raw.references);
const hasZeroOrNoReferences = !hasReferences || raw.references.length === 0;
if (filesSpecs.length === 0 && hasZeroOrNoReferences) {
if (sourceFile) {
const fileName = configFileName || "tsconfig.json";
const diagnosticMessage = Diagnostics.The_files_list_in_config_file_0_is_empty;
const nodeValue = firstDefined(getTsConfigPropArray(sourceFile, "files"), property => property.initializer);
const error = nodeValue
? createDiagnosticForNodeInSourceFile(sourceFile, nodeValue, diagnosticMessage, fileName)
: createCompilerDiagnostic(diagnosticMessage, fileName);
errors.push(error);
}
else {
createCompilerDiagnosticOnlyIfJson(Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json");
}
}
}
else {
@@ -2066,11 +2079,6 @@ namespace ts {
createDiagnosticForNodeInSourceFile(sourceFile, valueNode, message, arg0)
);
return;
case "files":
if ((<ReadonlyArray<string>>value).length === 0) {
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, valueNode, Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json"));
}
return;
}
},
onSetUnknownOptionKeyValueInRoot(key: string, keyNode: PropertyName, _value: CompilerOptionsValue, _valueNode: Expression) {
@@ -2080,6 +2088,7 @@ namespace ts {
}
};
const json = convertToObjectWorker(sourceFile, errors, /*returnValue*/ true, getTsconfigRootOptionsMap(), optionsIterator);
if (!typeAcquisition) {
if (typingOptionstypeAcquisition) {
typeAcquisition = (typingOptionstypeAcquisition.enableAutoDiscovery !== undefined) ?
+8
View File
@@ -3708,6 +3708,14 @@
"category": "Message",
"code": 6209
},
"An argument for '{0}' was not provided.": {
"category": "Message",
"code": 6210
},
"An argument matching this binding pattern was not provided.": {
"category": "Message",
"code": 6211
},
"Projects to reference": {
"category": "Message",
+2 -1
View File
@@ -2818,7 +2818,8 @@ namespace ts {
const parameter = singleOrUndefined(parameters);
return parameter
&& parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter
&& !(isArrowFunction(parentNode) && parentNode.type) // arrow function may not have return type annotation
&& isArrowFunction(parentNode) // only arrow functions may have simple arrow head
&& !parentNode.type // arrow function may not have return type annotation
&& !some(parentNode.decorators) // parent may not have decorators
&& !some(parentNode.modifiers) // parent may not have modifiers
&& !some(parentNode.typeParameters) // parent may not have type parameters
+1 -1
View File
@@ -250,7 +250,7 @@ namespace ts {
Blue = "\u001b[94m",
Cyan = "\u001b[96m"
}
const gutterStyleSequence = "\u001b[30;47m";
const gutterStyleSequence = "\u001b[7m";
const gutterSeparator = " ";
const resetEscapeSequence = "\u001b[0m";
const ellipsis = "...";
+11 -2
View File
@@ -1017,7 +1017,6 @@ namespace ts {
projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Config file errors" });
return resultFlags;
}
if (configFile.fileNames.length === 0) {
// Nothing to build - must be a solution file, basically
return BuildResultFlags.None;
@@ -1221,7 +1220,6 @@ namespace ts {
const queue = graph.buildQueue;
reportBuildQueue(graph);
let anyFailed = false;
for (const next of queue) {
const proj = parseConfigFile(next);
@@ -1229,11 +1227,15 @@ namespace ts {
anyFailed = true;
break;
}
// report errors early when using continue or break statements
const errors = proj.errors;
const status = getUpToDateStatus(proj);
verboseReportProjectStatus(next, status);
const projName = proj.options.configFilePath!;
if (status.type === UpToDateStatusType.UpToDate && !options.force) {
reportErrors(errors);
// Up to date, skip
if (defaultOptions.dry) {
// In a dry build, inform the user of this fact
@@ -1243,17 +1245,20 @@ namespace ts {
}
if (status.type === UpToDateStatusType.UpToDateWithUpstreamTypes && !options.force) {
reportErrors(errors);
// Fake build
updateOutputTimestamps(proj);
continue;
}
if (status.type === UpToDateStatusType.UpstreamBlocked) {
reportErrors(errors);
if (options.verbose) reportStatus(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, projName, status.upstreamProjectName);
continue;
}
if (status.type === UpToDateStatusType.ContainerOnly) {
reportErrors(errors);
// Do nothing
continue;
}
@@ -1265,6 +1270,10 @@ namespace ts {
return anyFailed ? ExitStatus.DiagnosticsPresent_OutputsSkipped : ExitStatus.Success;
}
function reportErrors(errors: Diagnostic[]) {
errors.forEach((err) => host.reportDiagnostic(err));
}
/**
* Report the build ordering inferred from the current project graph if we're in verbose mode
*/
+42
View File
@@ -292,6 +292,48 @@ namespace ts {
});
}
export namespace EmptyFiles {
const projFs = loadProjectFromDisk("tests/projects/empty-files");
const allExpectedOutputs = [
"/src/core/index.js",
"/src/core/index.d.ts",
"/src/core/index.d.ts.map",
];
describe("tsbuild - empty files option in tsconfig", () => {
it("has empty files diagnostic when files is empty and no references are provided", () => {
const fs = projFs.shadow();
const host = new fakes.SolutionBuilderHost(fs);
const builder = createSolutionBuilder(host, ["/src/no-references"], { dry: false, force: false, verbose: false });
host.clearDiagnostics();
builder.buildAllProjects();
host.assertDiagnosticMessages(Diagnostics.The_files_list_in_config_file_0_is_empty);
// Check for outputs to not be written.
for (const output of allExpectedOutputs) {
assert(!fs.existsSync(output), `Expect file ${output} to not exist`);
}
});
it("does not have empty files diagnostic when files is empty and references are provided", () => {
const fs = projFs.shadow();
const host = new fakes.SolutionBuilderHost(fs);
const builder = createSolutionBuilder(host, ["/src/with-references"], { dry: false, force: false, verbose: false });
host.clearDiagnostics();
builder.buildAllProjects();
host.assertDiagnosticMessages(/*empty*/);
// Check for outputs to be written.
for (const output of allExpectedOutputs) {
assert(fs.existsSync(output), `Expect file ${output} to exist`);
}
});
});
}
describe("tsbuild - graph-ordering", () => {
let host: fakes.SolutionBuilderHost | undefined;
const deps: [string, string][] = [
@@ -61,6 +61,19 @@ namespace ts {
}
}
function assertParseFileDiagnosticsExclusion(jsonText: string, configFileName: string, basePath: string, allFileList: string[], expectedExcludedDiagnosticCode: number) {
{
const parsed = getParsedCommandJson(jsonText, configFileName, basePath, allFileList);
assert.isTrue(parsed.errors.length >= 0);
assert.isTrue(parsed.errors.findIndex(e => e.code === expectedExcludedDiagnosticCode) === -1, `Expected error code ${expectedExcludedDiagnosticCode} to not be in ${JSON.stringify(parsed.errors)}`);
}
{
const parsed = getParsedCommandJsonNode(jsonText, configFileName, basePath, allFileList);
assert.isTrue(parsed.errors.length >= 0);
assert.isTrue(parsed.errors.findIndex(e => e.code === expectedExcludedDiagnosticCode) === -1, `Expected error code ${expectedExcludedDiagnosticCode} to not be in ${JSON.stringify(parsed.errors)}`);
}
}
it("returns empty config for file with only whitespaces", () => {
assertParseResult("", { config : {} });
assertParseResult(" ", { config : {} });
@@ -280,6 +293,30 @@ namespace ts {
Diagnostics.The_files_list_in_config_file_0_is_empty.code);
});
it("generates errors for empty files list when no references are provided", () => {
const content = `{
"files": [],
"references": []
}`;
assertParseFileDiagnostics(content,
"/apath/tsconfig.json",
"tests/cases/unittests",
["/apath/a.ts"],
Diagnostics.The_files_list_in_config_file_0_is_empty.code);
});
it("does not generate errors for empty files list when one or more references are provided", () => {
const content = `{
"files": [],
"references": [{ "path": "/apath" }]
}`;
assertParseFileDiagnosticsExclusion(content,
"/apath/tsconfig.json",
"tests/cases/unittests",
["/apath/a.ts"],
Diagnostics.The_files_list_in_config_file_0_is_empty.code);
});
it("generates errors for directory with no .ts files", () => {
const content = `{
}`;