blob: e39e7e147e9a132fc669a7820bce03089919912c [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_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(TypeAliasCannotReferenceItselfTest);
});
}
@reflectiveTest
class TypeAliasCannotReferenceItselfTest extends PubPackageResolutionTest {
test_functionTypeAlias_typeParameterBounds() async {
await assertErrorsInCode('''
typedef A<T extends A<int>>();
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
test_functionTypedParameter_returnType() async {
await assertErrorsInCode('''
typedef A(A b());
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
test_generic() async {
await assertErrorsInCode(r'''
typedef F = void Function(List<G> l);
typedef G = void Function(List<F> l);
main() {
F? foo(G? g) => g;
foo(null);
}
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 46, 1),
]);
}
test_genericTypeAlias_typeParameterBounds() async {
await assertErrorsInCode('''
typedef A<T extends A<int>> = void Function();
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
test_infiniteParameterBoundCycle() async {
await assertErrorsInCode(r'''
typedef F<X extends F<X>> = F Function();
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
test_issue11987() async {
await assertErrorsInCode(r'''
typedef void F(List<G> l);
typedef void G(List<F> l);
main() {
F? foo(G? g) => g;
foo(null);
}
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 13, 1),
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 40, 1),
]);
}
test_issue19459() async {
// A complex example involving multiple classes. This is legal, since
// typedef F references itself only via a class.
await assertNoErrorsInCode(r'''
class A<B, C> {}
abstract class D {
f(E e);
}
abstract class E extends A<dynamic, F> {}
typedef D F();
''');
}
test_nonFunction_aliasedType_cycleOf2() async {
await assertErrorsInCode('''
typedef T1 = T2;
typedef T2 = T1;
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 2),
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 25, 2),
]);
}
test_nonFunction_aliasedType_directly_functionWithIt() async {
await assertErrorsInCode('''
typedef T = void Function(T);
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
test_nonFunction_aliasedType_directly_it_none() async {
await assertErrorsInCode('''
typedef T = T;
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
test_nonFunction_aliasedType_directly_it_question() async {
await assertErrorsInCode('''
typedef T = T?;
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
test_nonFunction_aliasedType_directly_ListOfIt() async {
await assertErrorsInCode('''
typedef T = List<T>;
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
test_nonFunction_typeParameterBounds() async {
await assertErrorsInCode('''
typedef T<X extends T<Never>> = List<X>;
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
test_parameterType_named() async {
await assertErrorsInCode('''
typedef A({A a});
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
test_parameterType_positional() async {
await assertErrorsInCode('''
typedef A([A a]);
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
test_parameterType_required() async {
await assertErrorsInCode('''
typedef A(A a);
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
test_parameterType_typeArgument() async {
await assertErrorsInCode('''
typedef A(List<A> a);
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
test_referencesReturnType_inTypeAlias() async {
await assertNoErrorsInCode(r'''
typedef B A();
class B {
A? a;
}
''');
}
test_returnClass_withTypeAlias() async {
// A typedef is allowed to indirectly reference itself via a class.
await assertNoErrorsInCode(r'''
typedef C A();
typedef A B();
class C {
B? a;
}
''');
}
test_returnType() async {
await assertErrorsInCode('''
typedef A A();
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 10, 1),
]);
}
test_returnType_indirect() async {
await assertErrorsInCode(r'''
typedef B A();
typedef A B();
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 10, 1),
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 25, 1),
]);
}
test_usingRecordType_directly() async {
await assertErrorsInCode(r'''
typedef F = (F, int) Function();
''', [
error(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1),
]);
}
}