Skip to content

Commit 1722bd2

Browse files
committed
Refactor to use related info everywhere
1 parent a994d43 commit 1722bd2

File tree

4 files changed

+96
-140
lines changed

4 files changed

+96
-140
lines changed

src/compiler/checker.ts

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -839,15 +839,16 @@ namespace ts {
839839
}
840840

841841
function errorAndMaybeSuggestAwait(
842-
location: Node | undefined,
842+
location: Node,
843843
maybeMissingAwait: boolean,
844-
defaultMessage: DiagnosticMessage,
845-
missingAwaitMessage: DiagnosticMessage,
844+
message: DiagnosticMessage,
846845
arg0?: string | number | undefined, arg1?: string | number | undefined, arg2?: string | number | undefined, arg3?: string | number | undefined): Diagnostic {
846+
const diagnostic = error(location, message, arg0, arg1, arg2, arg3);
847847
if (maybeMissingAwait) {
848-
return error(location, missingAwaitMessage, arg0, arg1, arg2, arg3);
848+
const related = createDiagnosticForNode(location, Diagnostics.Did_you_forget_to_use_await);
849+
addRelatedInfo(diagnostic, related);
849850
}
850-
return error(location, defaultMessage, arg0, arg1, arg2, arg3);
851+
return diagnostic;
851852
}
852853

853854
function createSymbol(flags: SymbolFlags, name: __String, checkFlags?: CheckFlags) {
@@ -22068,11 +22069,11 @@ namespace ts {
2206822069
return true;
2206922070
}
2207022071

22071-
function invocationErrorDetails(apparentType: Type, kind: SignatureKind): DiagnosticMessageChain {
22072+
function invocationErrorDetails(apparentType: Type, kind: SignatureKind): { messageChain: DiagnosticMessageChain, relatedMessage: DiagnosticMessage | undefined } {
2207222073
let errorInfo: DiagnosticMessageChain | undefined;
2207322074
const isCall = kind === SignatureKind.Call;
2207422075
const awaitedType = getAwaitedType(apparentType);
22075-
const mightWorkWithAwait = awaitedType && getSignaturesOfType(awaitedType, kind).length > 0;
22076+
const maybeMissingAwait = awaitedType && getSignaturesOfType(awaitedType, kind).length > 0;
2207622077
if (apparentType.flags & TypeFlags.Union) {
2207722078
const types = (apparentType as UnionType).types;
2207822079
let hasSignatures = false;
@@ -22137,15 +22138,20 @@ namespace ts {
2213722138
typeToString(apparentType)
2213822139
);
2213922140
}
22140-
return chainDiagnosticMessages(
22141-
errorInfo,
22142-
mightWorkWithAwait
22143-
? isCall ? Diagnostics.This_expression_is_not_callable_Did_you_forget_to_use_await : Diagnostics.This_expression_is_not_constructable_Did_you_forget_to_use_await
22144-
: isCall ? Diagnostics.This_expression_is_not_callable : Diagnostics.This_expression_is_not_constructable
22145-
);
22141+
return {
22142+
messageChain: chainDiagnosticMessages(
22143+
errorInfo,
22144+
isCall ? Diagnostics.This_expression_is_not_callable : Diagnostics.This_expression_is_not_constructable
22145+
),
22146+
relatedMessage: maybeMissingAwait ? Diagnostics.Did_you_forget_to_use_await : undefined,
22147+
};
2214622148
}
2214722149
function invocationError(errorTarget: Node, apparentType: Type, kind: SignatureKind, relatedInformation?: DiagnosticRelatedInformation) {
22148-
const diagnostic = createDiagnosticForNodeFromMessageChain(errorTarget, invocationErrorDetails(apparentType, kind));
22150+
const { messageChain, relatedMessage: relatedInfo } = invocationErrorDetails(apparentType, kind);
22151+
const diagnostic = createDiagnosticForNodeFromMessageChain(errorTarget, messageChain);
22152+
if (relatedInfo) {
22153+
addRelatedInfo(diagnostic, createDiagnosticForNode(errorTarget, relatedInfo));
22154+
}
2214922155
if (isCallExpression(errorTarget.parent)) {
2215022156
const { start, length } = getDiagnosticSpanForCallNode(errorTarget.parent, /* doNotIncludeArguments */ true);
2215122157
diagnostic.start = start;
@@ -22245,9 +22251,12 @@ namespace ts {
2224522251

2224622252
const headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
2224722253
if (!callSignatures.length) {
22248-
let errorInfo = invocationErrorDetails(apparentType, SignatureKind.Call);
22249-
errorInfo = chainDiagnosticMessages(errorInfo, headMessage);
22250-
const diag = createDiagnosticForNodeFromMessageChain(node.expression, errorInfo);
22254+
const errorDetails = invocationErrorDetails(apparentType, SignatureKind.Call);
22255+
const messageChain = chainDiagnosticMessages(errorDetails.messageChain, headMessage);
22256+
const diag = createDiagnosticForNodeFromMessageChain(node.expression, messageChain);
22257+
if (errorDetails.relatedMessage) {
22258+
addRelatedInfo(diag, createDiagnosticForNode(node.expression, errorDetails.relatedMessage));
22259+
}
2225122260
diagnostics.add(diag);
2225222261
invocationErrorRecovery(apparentType, SignatureKind.Call, diag);
2225322262
return resolveErrorCall(node);
@@ -23381,14 +23390,13 @@ namespace ts {
2338123390
}
2338223391
}
2338323392

23384-
function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage, missingAwaitDiagnostic: DiagnosticMessage): boolean {
23393+
function checkArithmeticOperandType(operand: Node, type: Type, diagnostic: DiagnosticMessage): boolean {
2338523394
if (!isTypeAssignableTo(type, numberOrBigIntType)) {
2338623395
const awaitedType = getAwaitedType(type);
2338723396
errorAndMaybeSuggestAwait(
2338823397
operand,
2338923398
!!awaitedType && isTypeAssignableTo(awaitedType, numberOrBigIntType),
23390-
diagnostic,
23391-
missingAwaitDiagnostic);
23399+
diagnostic);
2339223400
return false;
2339323401
}
2339423402
return true;
@@ -23586,8 +23594,7 @@ namespace ts {
2358623594
case SyntaxKind.PlusPlusToken:
2358723595
case SyntaxKind.MinusMinusToken:
2358823596
const ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand),
23589-
Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type,
23590-
Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type_Did_you_forget_to_use_await);
23597+
Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type);
2359123598
if (ok) {
2359223599
// run check only if former checks succeeded to avoid reporting cascading errors
2359323600
checkReferenceExpression(node.operand, Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access);
@@ -23605,8 +23612,7 @@ namespace ts {
2360523612
const ok = checkArithmeticOperandType(
2360623613
node.operand,
2360723614
checkNonNullType(operandType, node.operand),
23608-
Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type,
23609-
Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type_Did_you_forget_to_use_await);
23615+
Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type);
2361023616
if (ok) {
2361123617
// run check only if former checks succeeded to avoid reporting cascading errors
2361223618
checkReferenceExpression(node.operand, Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access);
@@ -23996,8 +24002,8 @@ namespace ts {
2399624002
}
2399724003
else {
2399824004
// otherwise just check each operand separately and report errors as normal
23999-
const leftOk = checkArithmeticOperandType(left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_Did_you_forget_to_use_await);
24000-
const rightOk = checkArithmeticOperandType(right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_Did_you_forget_to_use_await);
24005+
const leftOk = checkArithmeticOperandType(left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type);
24006+
const rightOk = checkArithmeticOperandType(right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type);
2400124007
let resultType: Type;
2400224008
// If both are any or unknown, allow operation; assume it will resolve to number
2400324009
if ((isTypeAssignableToKind(leftType, TypeFlags.AnyOrUnknown) && isTypeAssignableToKind(rightType, TypeFlags.AnyOrUnknown)) ||
@@ -24250,7 +24256,6 @@ namespace ts {
2425024256
errNode,
2425124257
wouldWorkWithAwait,
2425224258
Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2,
24253-
Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2_Did_you_forget_to_use_await,
2425424259
tokenToString(operatorToken.kind),
2425524260
leftStr,
2425624261
rightStr,
@@ -24275,7 +24280,6 @@ namespace ts {
2427524280
errNode,
2427624281
maybeMissingAwait,
2427724282
Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap,
24278-
Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap_Did_you_forget_to_use_await,
2427924283
typeName, leftStr, rightStr);
2428024284
}
2428124285

@@ -27588,28 +27592,22 @@ namespace ts {
2758827592
// number and string input is allowed, we want to say that number is not an
2758927593
// array type or a string type.
2759027594
const isIterable = !!getIteratedTypeOfIterable(inputType, /* errorNode */ undefined, allowAsyncIterables, /*allowSyncIterables*/ true, checkAssignability);
27591-
const [defaultDiagnostic, missingAwaitDiagnostic]: [DiagnosticMessage, DiagnosticMessage | undefined] = !allowStringInput || hasStringConstituent
27595+
const [defaultDiagnostic, maybeMissingAwait]: [DiagnosticMessage, boolean] = !allowStringInput || hasStringConstituent
2759227596
? downlevelIteration
27593-
? [Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_Did_you_forget_to_use_await]
27597+
? [Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, true]
2759427598
: isIterable
27595-
? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, undefined]
27596-
: [Diagnostics.Type_0_is_not_an_array_type, Diagnostics.Type_0_is_not_an_array_type_Did_you_forget_to_use_await]
27599+
? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, false]
27600+
: [Diagnostics.Type_0_is_not_an_array_type, true]
2759727601
: downlevelIteration
27598-
? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_Did_you_forget_to_use_await]
27602+
? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, true]
2759927603
: isIterable
27600-
? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, undefined]
27601-
: [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type, Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Did_you_forget_to_use_await];
27602-
if (missingAwaitDiagnostic) {
27603-
errorAndMaybeSuggestAwait(
27604-
errorNode,
27605-
!!getAwaitedTypeOfPromise(arrayType),
27606-
defaultDiagnostic,
27607-
missingAwaitDiagnostic,
27608-
typeToString(arrayType));
27609-
}
27610-
else {
27611-
error(errorNode, defaultDiagnostic, typeToString(arrayType));
27612-
}
27604+
? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, false]
27605+
: [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type, true];
27606+
errorAndMaybeSuggestAwait(
27607+
errorNode,
27608+
maybeMissingAwait && !!getAwaitedTypeOfPromise(arrayType),
27609+
defaultDiagnostic,
27610+
typeToString(arrayType));
2761327611
}
2761427612
return hasStringConstituent ? stringType : undefined;
2761527613
}
@@ -27740,10 +27738,10 @@ namespace ts {
2774027738
}
2774127739

2774227740
function reportTypeNotIterableError(errorNode: Node, type: Type, allowAsyncIterables: boolean): void {
27743-
const [defaultDiagnostic, missingAwaitDiagnostic] = allowAsyncIterables
27744-
? [Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator, Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator_Did_you_forget_to_use_await]
27745-
: [Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator, Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator_Did_you_forget_to_use_await];
27746-
errorAndMaybeSuggestAwait(errorNode, !!getAwaitedTypeOfPromise(type), defaultDiagnostic, missingAwaitDiagnostic, typeToString(type));
27741+
const message = allowAsyncIterables
27742+
? Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator
27743+
: Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator;
27744+
errorAndMaybeSuggestAwait(errorNode, !!getAwaitedTypeOfPromise(type), message, typeToString(type));
2774727745
}
2774827746

2774927747
/**

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2653,65 +2653,9 @@
26532653
"category": "Error",
26542654
"code": 2762
26552655
},
2656-
"Operator '{0}' cannot be applied to types '{1}' and '{2}'. Did you forget to use 'await'?": {
2657-
"category": "Error",
2658-
"code": 2763
2659-
},
2660-
"An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'?": {
2661-
"category": "Error",
2662-
"code": 2764
2663-
},
2664-
"The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'?": {
2665-
"category": "Error",
2666-
"code": 2765
2667-
},
2668-
"The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. Did you forget to use 'await'?": {
2669-
"category": "Error",
2670-
"code": 2766
2671-
},
2672-
"Type '{0}' must have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": {
2673-
"category": "Error",
2674-
"code": 2767
2675-
},
2676-
"Type '{0}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator. Did you forget to use 'await'?": {
2677-
"category": "Error",
2678-
"code": 2768
2679-
},
2680-
"Type '{0}' is not an array type. Did you forget to use 'await'?": {
2681-
"category": "Error",
2682-
"code": 2769
2683-
},
2684-
"Type '{0}' is not an array type or a string type. Did you forget to use 'await'?": {
2685-
"category": "Error",
2686-
"code": 2770
2687-
},
2688-
"Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": {
2689-
"category": "Error",
2690-
"code": 2771
2691-
},
2692-
"Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator. Did you forget to use 'await'?": {
2693-
"category": "Error",
2694-
"code": 2772
2695-
},
2696-
"Argument of type '{0}' is not assignable to parameter of type '{1}'. Did you forget to use 'await'?": {
2697-
"category": "Error",
2698-
"code": 2773
2699-
},
2700-
"This expression is not callable. Did you forget to use 'await'?": {
2701-
"category": "Error",
2702-
"code": 2774
2703-
},
2704-
"This expression is not constructable. Did you forget to use 'await'?": {
2705-
"category": "Error",
2706-
"code": 2775
2707-
},
2708-
"This condition will always return '{0}' since the types '{1}' and '{2}' have no overlap. Did you forget to use 'await'?": {
2709-
"category": "Error",
2710-
"code": 2776
2711-
},
27122656
"Did you forget to use 'await'?": {
27132657
"category": "Error",
2714-
"code": 2777
2658+
"code": 2763
27152659
},
27162660

27172661
"Import declaration '{0}' is using private name '{1}'.": {

0 commit comments

Comments
 (0)