Skip to content

Commit caff266

Browse files
committed
Notes on how to return errors from checkTypeRelatedTo
1 parent beddf9c commit caff266

File tree

1 file changed

+45
-13
lines changed

1 file changed

+45
-13
lines changed

src/compiler/checker.ts

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12341,7 +12341,26 @@ namespace ts {
1234112341
return getObjectFlags(source) & ObjectFlags.JsxAttributes && !isUnhyphenatedJsxName(sourceProp.escapedName);
1234212342
}
1234312343

12344-
/**
12344+
function checkTypeRelatedTo(
12345+
source: Type,
12346+
target: Type,
12347+
relation: Map<RelationComparisonResult>,
12348+
errorNode: Node | undefined,
12349+
headMessage?: DiagnosticMessage,
12350+
containingMessageChain?: () => DiagnosticMessageChain | undefined,
12351+
errorOutputContainer?: { error?: Diagnostic },
12352+
): boolean;
12353+
function checkTypeRelatedTo(
12354+
source: Type,
12355+
target: Type,
12356+
relation: Map<RelationComparisonResult>,
12357+
errorNode: Node | undefined,
12358+
headMessage?: DiagnosticMessage,
12359+
containingMessageChain?: () => DiagnosticMessageChain | undefined,
12360+
errorOutputContainer?: { error?: Diagnostic },
12361+
breakdown?: boolean
12362+
): [Node, DiagnosticMessageChain];
12363+
/**
1234512364
* Checks if 'source' is related to 'target' (e.g.: is a assignable to).
1234612365
* @param source The left-hand-side of the relation.
1234712366
* @param target The right-hand-side of the relation.
@@ -12358,9 +12377,9 @@ namespace ts {
1235812377
errorNode: Node | undefined,
1235912378
headMessage?: DiagnosticMessage,
1236012379
containingMessageChain?: () => DiagnosticMessageChain | undefined,
12361-
errorOutputContainer?: { error?: Diagnostic }
12362-
): boolean {
12363-
12380+
errorOutputContainer?: { error?: Diagnostic },
12381+
breakdown?: boolean
12382+
): boolean | [Node, DiagnosticMessageChain] {
1236412383
let errorInfo: DiagnosticMessageChain | undefined;
1236512384
let relatedInfo: [DiagnosticRelatedInformation, ...DiagnosticRelatedInformation[]] | undefined;
1236612385
let maybeKeys: string[];
@@ -12399,7 +12418,9 @@ namespace ts {
1239912418
}
1240012419
}
1240112420
}
12402-
12421+
if (breakdown) {
12422+
return [errorNode!, errorInfo];
12423+
}
1240312424
const diag = createDiagnosticForNodeFromMessageChain(errorNode!, errorInfo, relatedInformation);
1240412425
if (relatedInfo) {
1240512426
addRelatedInfo(diag, ...relatedInfo);
@@ -12409,6 +12430,7 @@ namespace ts {
1240912430
}
1241012431
diagnostics.add(diag); // TODO: GH#18217
1241112432
}
12433+
Debug.assert(!breakdown);
1241212434
return result !== Ternary.False;
1241312435

1241412436
function reportError(message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void {
@@ -21102,14 +21124,17 @@ namespace ts {
2110221124
return checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes);
2110321125
}
2110421126

21127+
// TODO: This function is only used in overload resolution; it should instead return a [errorNode, messageChain] pair if there is a failure and undefined if not
21128+
// The first-round callers can used undefined=pass and the second-round callers can build their own errors from the pair.
21129+
// TODO: Still need to thread BREAKDOWN through checkTypeRealtedToAndOptionallyElaborate and all other checkType calls
2110521130
function checkApplicableSignature(
2110621131
node: CallLikeExpression,
2110721132
args: ReadonlyArray<Expression>,
2110821133
signature: Signature,
2110921134
relation: Map<RelationComparisonResult>,
2111021135
checkMode: CheckMode,
2111121136
reportErrors: boolean,
21112-
containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined
21137+
containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
2111321138
) {
2111421139
if (isJsxOpeningLikeElement(node)) {
2111521140
// TODO: Maybe containingMessageChain too?
@@ -21478,14 +21503,21 @@ namespace ts {
2147821503
// skip the checkApplicableSignature check.
2147921504
if (reportErrors) {
2148021505
if (candidatesForArgumentError) {
21481-
// const related: DiagnosticRelatedInformation[] = [];
21482-
for (const c of candidatesForArgumentError) {
21483-
const chain = chainDiagnosticMessages(chainDiagnosticMessages(undefined, Diagnostics.Overload_0_gave_the_following_error, signatureToString(c)), Diagnostics.Failed_to_find_a_suitable_overload_for_this_call);
21506+
if (candidatesForArgumentError.length > 3) {
21507+
const c = candidatesForArgumentError[candidatesForArgumentError.length - 1];
21508+
const chain = chainDiagnosticMessages(undefined, Diagnostics.Failed_to_find_a_suitable_overload_for_this_call);
2148421509
checkApplicableSignature(node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain);
21485-
// related.push(argNode)
21486-
// This is not right; I want them to be siblings
21487-
// probably this is a new feature :(
21488-
// chain = chainDiagnosticMessages(chain, msg);
21510+
}
21511+
else {
21512+
// const related: DiagnosticRelatedInformation[] = [];
21513+
for (const c of candidatesForArgumentError) {
21514+
const chain = chainDiagnosticMessages(chainDiagnosticMessages(undefined, Diagnostics.Overload_0_gave_the_following_error, signatureToString(c)), Diagnostics.Failed_to_find_a_suitable_overload_for_this_call);
21515+
const [errorNode, msg] = checkApplicableSignature(node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain);
21516+
// related.push(argNode)
21517+
// This is not right; I want them to be siblings
21518+
// probably this is a new feature :(
21519+
// chain = chainDiagnosticMessages(chain, msg);
21520+
}
2148921521
}
2149021522
}
2149121523
else if (candidateForArgumentArityError) {

0 commit comments

Comments
 (0)