blob: 9d2253f584f5a1dd3f0a0b1981001950aa6a153a [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/dart/analysis/experiments.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/driver_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ArgumentTypeNotAssignableTest);
defineReflectiveTests(ArgumentTypeNotAssignableTest_NNBD);
});
}
@reflectiveTest
class ArgumentTypeNotAssignableTest extends DriverResolutionTest {
test_ambiguousClassName() async {
// See dartbug.com/19624
newFile("/test/lib/lib2.dart", content: '''
class _A {}
g(h(_A a)) {}''');
await assertErrorsInCode('''
import 'lib2.dart';
class _A {}
f() {
g((_A a) {});
}''', [
error(StaticWarningCode.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.indexOf("_A") >= 0, isTrue);
}
test_annotation_namedConstructor() async {
await assertErrorsInCode('''
class A {
const A.fromInt(int p);
}
@A.fromInt('0')
main() {
}''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 49, 3),
]);
}
test_annotation_unnamedConstructor() async {
await assertErrorsInCode('''
class A {
const A(int p);
}
@A('0')
main() {
}''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 33, 3),
]);
}
test_binary() async {
await assertErrorsInCode('''
class A {
operator +(int p) {}
}
f(A a) {
a + '0';
}''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 50, 3),
]);
}
test_call() async {
await assertErrorsInCode('''
typedef bool Predicate<T>(T object);
Predicate<String> f() => (String s) => false;
void main() {
f().call(3);
}''', [
error(StaticWarningCode.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(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 186, 1),
]);
}
test_const() async {
await assertErrorsInCode('''
class A {
const A(String p);
}
main() {
const A(42);
}''', [
error(
CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
52,
2),
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 52, 2),
]);
}
test_const_super() async {
await assertErrorsInCode('''
class A {
const A(String p);
}
class B extends A {
const B() : super(42);
}''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 73, 2),
]);
}
test_functionExpressionInvocation_required() async {
await assertErrorsInCode('''
main() {
(int x) {} ('');
}''', [
error(StaticWarningCode.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(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 31, 7),
]);
}
test_index() async {
await assertErrorsInCode('''
class A {
operator [](int index) {}
}
f(A a) {
a['0'];
}''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 53, 3),
]);
}
test_interfaceType() async {
await assertErrorsInCode(r'''
m() {
var i = '';
n(i);
}
n(int i) {}
''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 24, 1),
]);
}
test_invocation_callParameter() async {
await assertErrorsInCode('''
class A {
call(int p) {}
}
f(A a) {
a('0');
}''', [
error(StaticWarningCode.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(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 59, 3),
]);
}
test_invocation_functionParameter() async {
await assertErrorsInCode('''
a(b(int p)) {
b('0');
}''', [
error(StaticWarningCode.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(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 41, 1),
]);
}
test_invocation_functionTypes_optional() async {
await assertErrorsInCode('''
void acceptFunNumOptBool(void funNumOptBool([bool b])) {}
void funNumBool(bool b) {}
main() {
acceptFunNumOptBool(funNumBool);
}''', [
error(StrongModeCode.INVALID_CAST_FUNCTION, 116, 10),
]);
}
test_invocation_generic() async {
await assertErrorsInCode('''
class A<T> {
m(T t) {}
}
f(A<String> a) {
a.m(1);
}''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 50, 1),
]);
}
test_invocation_named() async {
await assertErrorsInCode('''
f({String p = ''}) {}
main() {
f(p: 42);
}''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 35, 5),
]);
}
test_invocation_optional() async {
await assertErrorsInCode('''
f([String p = '']) {}
main() {
f(42);
}''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 35, 2),
]);
}
test_invocation_required() async {
await assertErrorsInCode('''
f(String p) {}
main() {
f(42);
}''', [
error(StaticWarningCode.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(StaticWarningCode.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(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 69, 3),
]);
}
test_invocation_typedef_parameter() async {
await assertErrorsInCode('''
typedef A(int p);
f(A a) {
a('1');
}''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 31, 3),
]);
}
test_new_generic() async {
await assertErrorsInCode('''
class A<T> {
A(T p) {}
}
main() {
new A<String>(42);
}''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 52, 2),
]);
}
test_new_optional() async {
await assertErrorsInCode('''
class A {
A([String p = '']) {}
}
main() {
new A(42);
}''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 53, 2),
]);
}
test_new_required() async {
await assertErrorsInCode('''
class A {
A(String p) {}
}
main() {
new A(42);
}''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 46, 2),
]);
}
@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(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 99, 1),
]);
}
}
@reflectiveTest
class ArgumentTypeNotAssignableTest_NNBD extends ArgumentTypeNotAssignableTest {
@override
AnalysisOptionsImpl get analysisOptions =>
AnalysisOptionsImpl()..enabledExperiments = [EnableString.non_nullable];
test_downcast() async {
await assertErrorsInCode(r'''
m() {
num y = 1;
n(y);
}
n(int x) {}
''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 23, 1),
]);
}
@failingTest
test_downcast_nullableNonNullable() async {
await assertErrorsInCode(r'''
m() {
int? y;
n(y);
}
n(int x) {}
''', [
error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 24, 1),
]);
}
test_dynamicCast() async {
await assertNoErrorsInCode(r'''
m() {
dynamic i;
n(i);
}
n(int i) {}
''');
}
@failingTest
test_invocation_functionTypes_optional() async {
// The test is currently generating an error where none is expected.
await super.test_invocation_functionTypes_optional();
}
}