blob: 2eeb8c899d9a011b332e9553b8ac2eae79e9e8d0 [file] [log] [blame]
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/src/error/codes.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ArgumentTypeNotAssignableTest);
defineReflectiveTests(ArgumentTypeNotAssignableWithStrictCastsTest);
});
}
@reflectiveTest
class ArgumentTypeNotAssignableTest extends PubPackageResolutionTest {
test_ambiguousClassName() async {
// See dartbug.com/19624
newFile('$testPackageLibPath/lib2.dart', '''
class _A {}
g(h(_A a)) {}''');
await assertErrorsInCode('''
import 'lib2.dart';
class _A {}
f() {
g((_A a) {});
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 42, 9),
]);
// The name _A is private to the library it's defined in, so this is a type
// mismatch. Furthermore, the error message should mention both _A and the
// filenames so the user can figure out what's going on.
String message = result.errors[0].message;
expect(message.contains("_A"), isTrue);
}
test_annotation_namedConstructor() async {
await assertErrorsInCode('''
class A {
const A.fromInt(int p);
}
@A.fromInt('0')
main() {}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 49, 3),
]);
}
test_annotation_namedConstructor_generic() async {
await assertErrorsInCode('''
class A<T> {
const A.fromInt(T p);
}
@A<int>.fromInt('0')
main() {
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 55, 3),
]);
}
test_annotation_type_arguments_inferred() async {
await assertNoErrorsInCode('''
@C([])
int i = 0;
class C<T> {
const C(List<List<T>> arg);
}
''');
}
test_annotation_unnamedConstructor() async {
await assertErrorsInCode('''
class A {
const A(int p);
}
@A('0')
main() {
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 33, 3),
]);
}
test_binary() async {
await assertErrorsInCode('''
class A {
operator +(int p) {}
}
f(A a) {
a + '0';
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 50, 3),
]);
}
test_binary_eqEq_covariantParameterType() async {
await assertErrorsInCode(r'''
class A {
bool operator==(covariant A other) => false;
}
void f(A a, A? aq) {
a == 0;
aq == 1;
aq == aq;
aq == null;
}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 88, 1),
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 99, 1),
]);
}
test_call() async {
await assertErrorsInCode('''
typedef bool Predicate<T>(T object);
Predicate<String> f() => (String s) => false;
void main() {
f().call(3);
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 110, 1),
]);
}
test_cascadeSecond() async {
await assertErrorsInCode('''
// filler filler filler filler filler filler filler filler filler filler
class A {
B ma() { return new B(); }
}
class B {
mb(String p) {}
}
main() {
A a = new A();
a.. ma().mb(0);
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 186, 1),
]);
}
test_const() async {
await assertErrorsInCode('''
class A {
const A(String p);
}
main() {
const A(42);
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 52, 2),
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 52, 2),
]);
}
test_const_super() async {
await assertErrorsInCode('''
class A {
const A(String p);
}
class B extends A {
const B() : super(42);
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 73, 2),
]);
}
test_downcast() async {
await assertErrorsInCode(r'''
m() {
num y = 1;
n(y);
}
n(int x) {}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 23, 1),
]);
}
test_downcast_nullableNonNullable() async {
await assertErrorsInCode(r'''
m() {
int? y;
n(y);
}
n(int x) {}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 20, 1),
]);
}
test_dynamicCast() async {
await assertNoErrorsInCode(r'''
m() {
dynamic i;
n(i);
}
n(int i) {}
''');
}
test_enumConstant() async {
await assertErrorsInCode(r'''
enum E {
v(0);
const E(String a);
}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 13, 1),
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 13, 1),
]);
}
test_enumConstant_implicitDouble() async {
await assertNoErrorsInCode(r'''
enum E {
v(0);
const E(double a);
}
''');
}
test_expressionFromConstructorTearoff_withoutTypeArgs() async {
await assertNoErrorsInCode('''
class C<T> {
C(T a);
}
var g = C.new;
var x = g('Hello');
''');
}
test_expressionFromConstructorTearoff_withTypeArgs_assignable() async {
await assertNoErrorsInCode('''
class C<T> {
C(T a);
}
var g = C<int>.new;
var x = g(0);
''');
}
test_expressionFromConstructorTearoff_withTypeArgs_notAssignable() async {
await assertErrorsInCode('''
class C<T> {
C(T a);
}
var g = C<int>.new;
var x = g('Hello');
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 56, 7),
]);
}
test_expressionFromFunctionTearoff_withoutTypeArgs() async {
await assertNoErrorsInCode('''
void f<T>(T a) {}
var g = f;
var x = g('Hello');
''');
}
test_expressionFromFunctionTearoff_withTypeArgs_assignable() async {
await assertNoErrorsInCode('''
void f<T>(T a) {}
var g = f<int>;
var x = g(0);
''');
}
test_expressionFromFunctionTearoff_withTypeArgs_notAssignable() async {
await assertErrorsInCode('''
void f<T>(T a) {}
var g = f<int>;
var x = g('Hello');
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 45, 7),
]);
}
test_for_element_type_inferred_from_rewritten_node() async {
// See https://github.com/dart-lang/sdk/issues/39171
await assertNoErrorsInCode('''
void f<T>(Iterable<T> Function() g, int Function(T) h) {
[for (var x in g()) if (x is String) h(x)];
}
''');
}
test_for_statement_type_inferred_from_rewritten_node() async {
// See https://github.com/dart-lang/sdk/issues/39171
await assertNoErrorsInCode('''
void f<T>(Iterable<T> Function() g, void Function(T) h) {
for (var x in g()) {
if (x is String) {
h(x);
}
}
}
''');
}
test_functionExpressionInvocation_required() async {
await assertErrorsInCode('''
main() {
(int x) {} ('');
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 23, 2),
]);
}
test_functionType() async {
await assertErrorsInCode(r'''
m() {
var a = new A();
a.n(() => 0);
}
class A {
n(void f(int i)) {}
}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 31, 7),
]);
}
test_implicitCallReference() async {
await assertNoErrorsInCode('''
class A {
void call(int p) {}
}
void f(void Function(int) a) {}
void g(A a) {
f(a);
}
''');
}
test_implicitCallReference_named() async {
await assertNoErrorsInCode('''
class A {
void call(int p) {}
}
void defaultFunc(int p) {}
void f({void Function(int) a = defaultFunc}) {}
void g(A a) {
f(a: a);
}
''');
}
test_implicitCallReference_namedAndRequired() async {
await assertNoErrorsInCode('''
class A {
void call(int p) {}
}
void f({required void Function(int) a}) {}
void g(A a) {
f(a: a);
}
''');
}
test_implicitCallReference_this() async {
await assertNoErrorsInCode('''
class A {
void call(int p) {}
void f(void Function(int) a) {}
void g() {
f(this);
}
}
''');
}
test_index_invalidRead() async {
await assertErrorsInCode('''
class A {
int operator [](int index) => 0;
}
f(A a) {
a['0'];
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 60, 3),
]);
}
test_index_invalidRead_validWrite() async {
await assertErrorsInCode('''
class A {
int operator [](int index) => 0;
operator []=(String index, int value) {}
}
f(A a) {
a['0'] += 0;
++a['0'];
a['0']++;
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 103, 3),
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 120, 3),
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 130, 3),
]);
}
test_index_invalidWrite() async {
await assertErrorsInCode('''
class A {
operator []=(int index, int value) {}
}
f(A a) {
a['0'] = 0;
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 65, 3),
]);
}
test_index_validRead_invalidWrite() async {
await assertErrorsInCode('''
class A {
int operator [](String index) => 0;
operator []=(int index, int value) {}
}
f(A a) {
a['0'] += 0;
++a['0'];
a['0']++;
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 103, 3),
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 120, 3),
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 130, 3),
]);
}
test_interfaceType() async {
await assertErrorsInCode(r'''
m() {
var i = '';
n(i);
}
n(int i) {}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 24, 1),
]);
}
test_invocation_callParameter() async {
await assertErrorsInCode('''
class A {
call(int p) {}
}
f(A a) {
a('0');
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 42, 3),
]);
}
test_invocation_callVariable() async {
await assertErrorsInCode('''
class A {
call(int p) {}
}
main() {
A a = new A();
a('0');
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 59, 3),
]);
}
test_invocation_functionParameter() async {
await assertErrorsInCode('''
a(b(int p)) {
b('0');
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 18, 3),
]);
}
test_invocation_functionParameter_generic() async {
await assertErrorsInCode('''
class A<K, V> {
m(f(K k), V v) {
f(v);
}
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 41, 1),
]);
}
test_invocation_functionTypes_optional() async {
await assertErrorsInCode('''
void acceptFunOptBool(void funNumOptBool([bool b])) {}
void funBool(bool b) {}
main() {
acceptFunOptBool(funBool);
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 107, 7),
]);
}
test_invocation_functionTypes_optional_method() async {
await assertErrorsInCode('''
void acceptFunOptBool(void funOptBool([bool b])) {}
class C {
static void funBool(bool b) {}
}
main() {
acceptFunOptBool(C.funBool);
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 125, 9),
]);
}
test_invocation_generic() async {
await assertErrorsInCode('''
class A<T> {
m(T t) {}
}
f(A<String> a) {
a.m(1);
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 50, 1),
]);
}
test_invocation_named() async {
await assertErrorsInCode('''
f({String p = ''}) {}
main() {
f(p: 42);
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 38, 2),
]);
}
test_invocation_optional() async {
await assertErrorsInCode('''
f([String p = '']) {}
main() {
f(42);
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 35, 2),
]);
}
test_invocation_required() async {
await assertErrorsInCode('''
f(String p) {}
main() {
f(42);
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 28, 2),
]);
}
test_invocation_typedef_generic() async {
await assertErrorsInCode('''
typedef A<T>(T p);
f(A<int> a) {
a('1');
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 37, 3),
]);
}
test_invocation_typedef_local() async {
await assertErrorsInCode('''
typedef A(int p);
A getA() => throw '';
main() {
A a = getA();
a('1');
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 69, 3),
]);
}
test_invocation_typedef_parameter() async {
await assertErrorsInCode('''
typedef A(int p);
f(A a) {
a('1');
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 31, 3),
]);
}
test_map_indexGet() async {
// Any type may be passed to Map.operator[].
await assertNoErrorsInCode('''
main() {
Map<int, int> m = <int, int>{};
m['x'];
}
''');
}
test_map_indexSet() async {
// The type passed to Map.operator[]= must match the key type.
await assertErrorsInCode('''
main() {
Map<int, int> m = <int, int>{};
m['x'] = 0;
}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 47, 3),
]);
}
test_map_indexSet_ifNull() async {
// The type passed to Map.operator[]= must match the key type.
await assertErrorsInCode('''
main() {
Map<int, int> m = <int, int>{};
m['x'] ??= 0;
}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 47, 3),
]);
}
test_new_generic() async {
await assertErrorsInCode('''
class A<T> {
A(T p) {}
}
main() {
new A<String>(42);
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 52, 2),
]);
}
test_new_optional() async {
await assertErrorsInCode('''
class A {
A([String p = '']) {}
}
main() {
new A(42);
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 53, 2),
]);
}
test_new_required() async {
await assertErrorsInCode('''
class A {
A(String p) {}
}
main() {
new A(42);
}''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 46, 2),
]);
}
void test_recordType() async {
await assertErrorsInCode('''
void f((int a, int b) r) {}
void g() {
f((a: 1, b: 2));
}
''', [
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.'
]),
]);
}
@failingTest
test_tearOff_required() async {
await assertErrorsInCode('''
class C {
Object/*=T*/ f/*<T>*/(Object/*=T*/ x) => x;
}
g(C c) {
var h = c.f/*<int>*/;
print(h('s'));
}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 99, 1),
]);
}
}
@reflectiveTest
class ArgumentTypeNotAssignableWithStrictCastsTest
extends PubPackageResolutionTest with WithStrictCastsMixin {
test_extensionTypePrimaryConstructor() async {
await assertErrorsWithStrictCasts('''
extension type E(int i) {}
dynamic a;
var e = E(a);
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 49, 1),
]);
}
test_functionCall() async {
await assertErrorsWithStrictCasts('''
void f(int i) {}
void foo(dynamic a) {
f(a);
}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 43, 1),
]);
}
test_operator() async {
await assertErrorsWithStrictCasts('''
void foo(int i, dynamic a) {
i + a;
}
''', [
error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 35, 1),
]);
}
}