// 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. // Tests method signatures and return types for the `out` variance modifier. // SharedOptions=--enable-experiment=variance import "package:expect/expect.dart"; typedef Cov = T Function(); typedef Contra = void Function(T); Cov covFunction = () => 2; Contra contraFunction = (int val) {}; class Covariant {} class Contravariant {} class A { T? method1() => null; void method2(Contra x) {} Cov method3() { return () => null; } void method4(Contra> x) {} void method5(Cov> x) {} Contra> method6() { return (Contra x) { Expect.type>(x); }; } Cov> method7() { return () { return () => null; }; } void method8(Contravariant x) {} Covariant? method9() => null; void method10(Contravariant> x) {} Covariant>? method11() => null; void method12(Covariant> x) {} Contravariant>? method13() => null; void method14(covariant T x) {} void method15(covariant Contra x) {} void method16(covariant Cov x) {} void method17(covariant Contravariant x) {} void method18(covariant Covariant x) {} void method19({Contravariant? x}) {} void method20({Contra? x}) {} } mixin BMixin { T? method1() => null; void method2(Contra x) {} Cov method3() { return () => null; } void method4(Contra> x) {} void method5(Cov> x) {} Contra> method6() { return (Contra x) { Expect.type>(x); }; } Cov> method7() { return () { return () => null; }; } void method8(Contravariant x) {} Covariant? method9() => null; void method10(Contravariant> x) {} Covariant>? method11() => null; void method12(Covariant> x) {} Contravariant>? method13() => null; void method14(covariant T x) {} void method15(covariant Contra x) {} void method16(covariant Cov x) {} void method17(covariant Contravariant x) {} void method18(covariant Covariant x) {} void method19({Contravariant? x}) {} void method20({Contra? x}) {} } class B with BMixin {} class C { void method1(Contra> x) {} A method2() { return A(); } } class D { T? method() => null; void method2(T x) {} void method3(covariant T x) {} } class E extends D { @override T? method() => null; @override void method3(covariant T x) {} } void testClass() { A a = new A(); Expect.isNull(a.method1()); a.method2(contraFunction); Expect.type>(a.method3()); Cov method3Function = a.method3(); Expect.isNull(method3Function()); a.method4((Cov x) {}); a.method5(() { return contraFunction; }); Expect.type>>(a.method6()); Contra> method6Function = a.method6(); method6Function(contraFunction); Expect.type>>(a.method7()); Cov> method7Function = a.method7(); Expect.type>(method7Function()); Cov method7NestedFunction = method7Function(); Expect.isNull(method7NestedFunction()); a.method8(Contravariant()); Expect.isNull(a.method9()); a.method10(Contravariant>()); Expect.isNull(a.method11()); a.method12(Covariant>()); Expect.isNull(a.method13()); a.method14(3); a.method15(contraFunction); a.method16(covFunction); a.method17(Contravariant()); a.method18(Covariant()); a.method19(); a.method20(); } void testMixin() { B b = new B(); Expect.isNull(b.method1()); b.method2(contraFunction); Expect.type>(b.method3()); Cov method3Function = b.method3(); Expect.isNull(method3Function()); b.method4((Cov x) {}); b.method5(() { return contraFunction; }); Expect.type>>(b.method6()); Contra> method6Function = b.method6(); method6Function(contraFunction); Expect.type>>(b.method7()); Cov> method7Function = b.method7(); Expect.type>(method7Function()); Cov method7NestedFunction = method7Function(); Expect.isNull(method7NestedFunction()); b.method8(Contravariant()); Expect.isNull(b.method9()); b.method10(Contravariant>()); Expect.isNull(b.method11()); b.method12(Covariant>()); Expect.isNull(b.method13()); b.method14(3); b.method15(contraFunction); b.method16(covFunction); b.method17(Contravariant()); b.method18(Covariant()); b.method19(); b.method20(); } void testClassInMethods() { C c = new C(); c.method1((A x) {}); Expect.type>(c.method2()); } void testOverrideLegacyMethods() { E e = new E(); Expect.isNull(e.method()); e.method2(3); e.method3(3); D d = e; Expect.throws(() => d.method2("test")); Expect.throws(() => d.method3("test")); } main() { testClass(); testMixin(); testClassInMethods(); testOverrideLegacyMethods(); }