[messages] Thoroughly test message text for wrongNumberOfTypeArguments errors.

Adds unit tests that validate the message text for the following
diagnostics:

- diag.wrongNumberOfTypeArguments
- diag.wrongNumberOfTypeArgumentsAnonymousFunction
- diag.wrongNumberOfTypeArgumentsConstructor
- diag.wrongNumberOfTypeArgumentsDotShorthandConstructor
- diag.wrongNumberOfTypeArgumentsEnum
- diag.wrongNumberOfTypeArgumentsExtension
- diag.wrongNumberOfTypeArgumentsFunction
- diag.wrongNumberOfTypeArgumentsMethod

I've tried to add enough tests to cover all the call sites that report
these diagnostics.

This paves the way for fixing
https://github.com/dart-lang/sdk/issues/62398 (Some message text
associated with "wrong number of type arguments" errors is confusing
or unclear.)

Change-Id: I6a6a696448c1c9bb914299d0f9496073d4cc1a28
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/472425
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
Paul Berry
2026-01-14 08:12:32 -08:00
committed by Commit Queue
parent dfd316f498
commit fc3ce5a24e
@@ -199,6 +199,405 @@ f(void Function<T>() foo, void Function<T, U>() bar) {
);
}
test_messageText_annotation() async {
await assertErrorsInCode(
r'''
class A {
const A();
}
@A<int>()
void f() {}
''',
[
error(
diag.wrongNumberOfTypeArguments,
28,
5,
messageContains: [
// TODO(paulberry): This message text could be better. See
// https://github.com/dart-lang/sdk/issues/62398.
"The type 'A Function()'",
'0 type parameters',
'1 type arguments',
],
),
],
);
}
test_messageText_constructorInvocationWithExplicitNew_noTypeParameters() async {
await assertErrorsInCode(
r'''
class Foo<X> {
Foo.bar();
}
main() {
new Foo.bar<int>();
}
''',
[
error(
diag.wrongNumberOfTypeArgumentsConstructor,
53,
5,
messageContains: [
"The constructor 'Foo.bar'",
"doesn't have type parameters",
],
),
],
);
}
test_messageText_constructorInvocationWithImplicitNew_noTypeParameters() async {
await assertErrorsInCode(
r'''
class Foo<X> {
Foo.bar();
}
main() {
Foo.bar<int>();
}
''',
[
error(
diag.wrongNumberOfTypeArgumentsConstructor,
49,
5,
messageContains: [
"The constructor 'Foo.bar'",
"doesn't have type parameters",
],
),
],
);
}
test_messageText_constructorTearoff_noTypeParametersExpected() async {
await assertErrorsInCode(
'''
class A<T> {
A.foo() {}
}
var x = A.foo<int>;
''',
[
error(
diag.wrongNumberOfTypeArgumentsConstructor,
42,
5,
messageContains: [
"The constructor 'A.foo'",
"doesn't have type parameters",
],
),
],
);
}
test_messageText_dotShorthand() async {
await assertErrorsInCode(
r'''
abstract class Foo<T> {
const factory Foo.a() = _Foo;
const Foo();
}
class _Foo<T> extends Foo<T> {
const _Foo();
}
Foo<int> bar<T>() => const .a<int>();
''',
[
error(
diag.wrongNumberOfTypeArgumentsDotShorthandConstructor,
154,
5,
messageContains: [
// TODO(paulberry): This message text could be better. See
// https://github.com/dart-lang/sdk/issues/62398.
"The constructor 'Foo<int>.a'",
"doesn't have type parameters",
],
),
],
);
}
test_messageText_enum() async {
await assertErrorsInCode(
r'''
enum E<T, U> {
v<int>()
}
''',
[
error(
diag.wrongNumberOfTypeArgumentsEnum,
18,
5,
messageContains: [
'The enum',
'2 type parameters',
'1 type arguments',
],
),
],
);
}
test_messageText_extension() async {
await assertErrorsInCode(
r'''
extension E on int {
void foo() {}
}
void f() {
E<int>(0).foo();
}
''',
[error(diag.wrongNumberOfTypeArgumentsExtension, 54, 5)],
);
}
test_messageText_functionInstantiation_duringConstEvaluation() async {
await assertErrorsInCode(
'''
void f<T>() {}
const dynamic x = f;
const y = (f)<int, String>;
''',
[
error(
diag.wrongNumberOfTypeArgumentsAnonymousFunction,
49,
13,
messageContains: [
'This function',
'1 type parameters',
'2 type arguments',
],
),
],
);
}
test_messageText_implicitCallTearoff() async {
await assertErrorsInCode(
'''
f(C c) {
c<int>;
}
class C {
void call<T, U>() {}
}
''',
[
error(
diag.wrongNumberOfTypeArgumentsFunction,
12,
5,
messageContains: [
// TODO(paulberry): This message text could be better. See
// https://github.com/dart-lang/sdk/issues/62398.
"The function 'call'",
'2 type parameters',
'1 type arguments',
],
),
],
);
}
test_messageText_instantiationOfFunctionTypedExpression() async {
await assertErrorsInCode(
'''
f(void Function<T, U>() foo, void Function<T, U>() bar) {
(1 == 2 ? foo : bar)<int>;
}
''',
[
error(
diag.wrongNumberOfTypeArgumentsAnonymousFunction,
80,
5,
messageContains: [
'This function',
'2 type parameters',
'1 type arguments',
],
),
],
);
}
test_messageText_localFunction() async {
await assertErrorsInCode(
'''
f() {
void foo<T, U>() {}
foo<int>;
}
''',
[
error(
diag.wrongNumberOfTypeArgumentsFunction,
33,
5,
messageContains: [
"The function 'foo'",
'2 type parameters',
'1 type arguments',
],
),
],
);
}
test_messageText_namedType() async {
await assertErrorsInCode(
r'''
class A<E, F> {}
A<A>? a;
''',
[
error(
diag.wrongNumberOfTypeArguments,
17,
5,
messageContains: [
"The type 'A'",
'2 type parameters',
'1 type arguments',
],
),
],
);
}
test_messageText_prefixedConstructorInvocation() async {
newFile('$testPackageLibPath/a.dart', '''
class Foo<X> {
Foo.bar();
}
''');
await assertErrorsInCode(
'''
import 'a.dart' as p;
main() {
p.Foo.bar<int>();
}
''',
[
error(
diag.wrongNumberOfTypeArgumentsConstructor,
43,
5,
messageContains: [
"The constructor 'p.Foo.bar'",
"doesn't have type parameters",
],
),
],
);
}
test_messageText_topLevelFunctionInvocation() async {
await assertErrorsInCode(
'''
void f() {
g<int>();
}
void g<T, U>() {}
''',
[
error(
diag.wrongNumberOfTypeArgumentsMethod,
14,
5,
messageContains: [
// TODO(paulberry): This message text could be better. See
// https://github.com/dart-lang/sdk/issues/62398.
"The method 'void Function<T, U>()'",
'2 type parameters',
'1 type arguments',
],
),
],
);
}
test_messageText_topLevelFunctionTearoff_const() async {
await assertErrorsInCode(
r'''
void foo<T, U>(T a, U b) {}
const g = foo<int>;
''',
[
error(
diag.wrongNumberOfTypeArgumentsFunction,
41,
5,
messageContains: [
"The function 'foo'",
'2 type parameters',
'1 type arguments',
],
),
],
);
}
test_messageText_typeInstantiation() async {
await assertErrorsInCode(
'''
class C<T, U> {}
var t = C<int>;
''',
[
error(
diag.wrongNumberOfTypeArguments,
26,
5,
messageContains: [
"The type 'C'",
'2 type parameters',
'1 type arguments',
],
),
],
);
}
test_messageText_typeInstantiation_typedef() async {
await assertErrorsInCode(
'''
typedef Fn<T, U> = void Function(T, U);
var t = Fn<int>;
''',
[
error(
diag.wrongNumberOfTypeArguments,
50,
5,
messageContains: [
"The type 'Fn'",
'2 type parameters',
'1 type arguments',
],
),
],
);
}
test_metadata_1of0() async {
await assertErrorsInCode(
r'''