mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:57:35 +00:00
Improve message when generating error ARGUMENT_TYPE_NOT_ASSIGNABLE for records.
Fixes BUG: #53580 Change-Id: I4c5a7b5147875ced2319ba36a396067a5ce1a657 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/330668 Commit-Queue: Keerti Parthasarathy <keertip@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
parent
4f438f287d
commit
c31be01bbe
|
@ -118,10 +118,12 @@ class CompileTimeErrorCode extends AnalyzerErrorCode {
|
|||
/// Parameters:
|
||||
/// 0: the name of the actual argument type
|
||||
/// 1: the name of the expected type
|
||||
/// 2: additional information, if any, when problem is associated with records
|
||||
static const CompileTimeErrorCode ARGUMENT_TYPE_NOT_ASSIGNABLE =
|
||||
CompileTimeErrorCode(
|
||||
'ARGUMENT_TYPE_NOT_ASSIGNABLE',
|
||||
"The argument type '{0}' can't be assigned to the parameter type '{1}'.",
|
||||
"The argument type '{0}' can't be assigned to the parameter type '{1}'. "
|
||||
"{2}",
|
||||
hasPublishedDocs: true,
|
||||
);
|
||||
|
||||
|
|
|
@ -98,7 +98,44 @@ mixin ErrorDetectionHelpers {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (errorCode == CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE) {
|
||||
var additionalInfo = <String>[];
|
||||
if (expectedStaticType is RecordType &&
|
||||
actualStaticType is RecordType) {
|
||||
var actualPositionalFields = actualStaticType.positionalFields.length;
|
||||
var expectedPositionalFields =
|
||||
expectedStaticType.positionalFields.length;
|
||||
if (expectedPositionalFields != 0 &&
|
||||
actualPositionalFields != expectedPositionalFields) {
|
||||
additionalInfo.add(
|
||||
'Expected $expectedPositionalFields positional arguments, but got $actualPositionalFields instead.');
|
||||
}
|
||||
var actualNamedFieldsLength = actualStaticType.namedFields.length;
|
||||
var expectedNamedFieldsLength = expectedStaticType.namedFields.length;
|
||||
if (expectedNamedFieldsLength != 0 &&
|
||||
actualNamedFieldsLength != expectedNamedFieldsLength) {
|
||||
additionalInfo.add(
|
||||
'Expected $expectedNamedFieldsLength named arguments, but got $actualNamedFieldsLength instead.');
|
||||
}
|
||||
var namedFields = expectedStaticType.namedFields;
|
||||
if (namedFields.isNotEmpty) {
|
||||
for (var field in actualStaticType.namedFields) {
|
||||
if (!namedFields.any((element) =>
|
||||
element.name == field.name && field.type == element.type)) {
|
||||
additionalInfo.add(
|
||||
'Unexpected named argument `${field.name}` with type `${field.type.getDisplayString(withNullability: true)}`.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
errorReporter.reportErrorForNode(
|
||||
errorCode,
|
||||
getErrorNode(expression),
|
||||
[actualStaticType, expectedStaticType, additionalInfo.join(' ')],
|
||||
computeWhyNotPromotedMessages(expression, whyNotPromoted?.call()),
|
||||
);
|
||||
return;
|
||||
}
|
||||
errorReporter.reportErrorForNode(
|
||||
errorCode,
|
||||
getErrorNode(expression),
|
||||
|
|
|
@ -644,12 +644,13 @@ CompileTimeErrorCode:
|
|||
}
|
||||
```
|
||||
ARGUMENT_TYPE_NOT_ASSIGNABLE:
|
||||
problemMessage: "The argument type '{0}' can't be assigned to the parameter type '{1}'."
|
||||
problemMessage: "The argument type '{0}' can't be assigned to the parameter type '{1}'. {2}"
|
||||
hasPublishedDocs: true
|
||||
comment: |-
|
||||
Parameters:
|
||||
0: the name of the actual argument type
|
||||
1: the name of the expected type
|
||||
2: additional information, if any, when problem is associated with records
|
||||
documentation: |-
|
||||
#### Description
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ main() {
|
|||
reporter.reportErrorForNode(
|
||||
CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
|
||||
findNode.simple('x'),
|
||||
[firstType, secondType],
|
||||
[firstType, secondType, ''],
|
||||
);
|
||||
|
||||
var error = listener.errors[0];
|
||||
|
@ -142,7 +142,7 @@ main() {
|
|||
reporter.reportErrorForNode(
|
||||
CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
|
||||
findNode.simple('x'),
|
||||
[firstType, secondType],
|
||||
[firstType, secondType, ''],
|
||||
);
|
||||
|
||||
var error = listener.errors[0];
|
||||
|
@ -175,7 +175,7 @@ main() {
|
|||
reporter.reportErrorForNode(
|
||||
CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
|
||||
findNode.simple('x'),
|
||||
[fa.variables.type!.type!, fb.variables.type!.type!],
|
||||
[fa.variables.type!.type!, fb.variables.type!.type!, ''],
|
||||
);
|
||||
|
||||
var error = listener.errors[0];
|
||||
|
@ -210,7 +210,7 @@ main() {
|
|||
reporter.reportErrorForNode(
|
||||
CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
|
||||
findNode.simple('x'),
|
||||
[ba.variables.type!.type!, bb.variables.type!.type!],
|
||||
[ba.variables.type!.type!, bb.variables.type!.type!, ''],
|
||||
);
|
||||
|
||||
var error = listener.errors[0];
|
||||
|
|
|
@ -225,7 +225,76 @@ void g() {
|
|||
f((a: 1, b: 2));
|
||||
}
|
||||
''', [
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 44, 12),
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 44, 12,
|
||||
messageContains: [
|
||||
'Expected 2 positional arguments, but got 0 instead.'
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
void test_recordType_namedArguments() async {
|
||||
await assertErrorsInCode('''
|
||||
typedef A = ({
|
||||
int b,
|
||||
int c,
|
||||
});
|
||||
|
||||
void f(A a){print(a);}
|
||||
|
||||
main() {
|
||||
f((bb:2, c:3));
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
|
||||
74,
|
||||
11,
|
||||
messageContains: ['Unexpected named argument `bb` with type `int`.'],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
void test_recordType_namedArguments_missing() async {
|
||||
await assertErrorsInCode('''
|
||||
typedef A = ({
|
||||
int b,
|
||||
int c,
|
||||
});
|
||||
|
||||
void f(A a){print(a);}
|
||||
|
||||
main() {
|
||||
f((b:2));
|
||||
}
|
||||
''', [
|
||||
error(
|
||||
CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
|
||||
74,
|
||||
5,
|
||||
messageContains: [
|
||||
'Expected 2 named arguments, but got 1 instead.',
|
||||
],
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
void test_recordType_positionalArguments() async {
|
||||
await assertErrorsInCode('''
|
||||
typedef A = (
|
||||
int b,
|
||||
int c,
|
||||
);
|
||||
|
||||
void f(A a){print(a);}
|
||||
|
||||
main() {
|
||||
f((3, 2, 1));
|
||||
}
|
||||
''', [
|
||||
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 72, 9,
|
||||
messageContains: [
|
||||
'Expected 2 positional arguments, but got 3 instead.'
|
||||
]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -773,7 +773,7 @@ int Function(int) fromPointer(Pointer<NativeFunction<Int8 Function(Int8)>> p) {
|
|||
|
||||
### argument_type_not_assignable
|
||||
|
||||
_The argument type '{0}' can't be assigned to the parameter type '{1}'._
|
||||
_The argument type '{0}' can't be assigned to the parameter type '{1}'. {2}_
|
||||
|
||||
#### Description
|
||||
|
||||
|
|
Loading…
Reference in a new issue