mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into tsbuildWatchImprovements
This commit is contained in:
+20
-3
@@ -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>) {
|
||||
|
||||
@@ -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) ?
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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 = `{
|
||||
}`;
|
||||
|
||||
Reference in New Issue
Block a user