// 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 `in` 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 { void method1(T x) {} void method2(Cov x) {} Contra method3() { return (T val) { Expect.equals(2, val); }; } void method4(Cov> x) {} Contra> method5() { return (Cov method) { Expect.type>(method); }; } Cov> method6() { return () { return (T x) { Expect.equals(2, x); }; }; } void method7(Contra> x) {} void method8(Covariant x) {} Contravariant? method9() => null; void method10(Covariant> x) {} Contravariant>? method11() => null; void method12(Contravariant> x) {} Covariant>? 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({T? x}) {} void method20({Covariant? x}) {} void method21({Cov? x}) {} } mixin BMixin { void method1(T x) {} void method2(Cov x) {} Contra method3() { return (T val) { Expect.equals(2, val); }; } void method4(Cov> x) {} Contra> method5() { return (Cov method) { Expect.type>(method); }; } Cov> method6() { return () { return (T x) { Expect.equals(2, x); }; }; } void method7(Contra> x) {} void method8(Covariant x) {} Contravariant? method9() => null; void method10(Covariant> x) {} Contravariant>? method11() => null; void method12(Contravariant> x) {} Covariant>? 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({T? x}) {} void method20({Covariant? x}) {} void method21({Cov? x}) {} } class B with BMixin {} class C { void method1(Contra> x) {} A method2() { return A(); } } class D { late T x; T? method() => null; void method2(T x) {} void method3(covariant T x) {} } class E extends D { @override void Function(T) method() => (T x) {}; @override void method3(covariant void Function(T) x) {} } void testClass() { A a = new A(); a.method1(2); a.method2(covFunction); Expect.type>(a.method3()); Contra method3Function = a.method3(); method3Function(2); a.method4(() { return covFunction; }); Expect.type>>(a.method5()); Contra> method5Function = a.method5(); method5Function(covFunction); Expect.type>>(a.method6()); Cov> method6Function = a.method6(); Expect.type>(method6Function()); Contra method6NestedFunction = method6Function(); method6NestedFunction(2); a.method7((Contra x) {}); a.method8(Covariant()); Expect.isNull(a.method9()); a.method10(Covariant>()); Expect.isNull(a.method11()); a.method12(Contravariant>()); Expect.isNull(a.method13()); a.method14(3); a.method15(contraFunction); a.method16(covFunction); a.method17(Contravariant()); a.method18(Covariant()); a.method19(); a.method20(); a.method21(); } void testMixin() { B b = new B(); b.method1(2); b.method2(covFunction); Expect.type>(b.method3()); Contra method3Return = b.method3(); method3Return(2); b.method4(() { return covFunction; }); Expect.type>>(b.method5()); Contra> method5Return = b.method5(); method5Return(covFunction); Expect.type>>(b.method6()); Cov> method6Function = b.method6(); Expect.type>(method6Function()); Contra method6NestedFunction = method6Function(); method6NestedFunction(2); b.method7((Contra x) {}); b.method8(Covariant()); Expect.isNull(b.method9()); b.method10(Covariant>()); Expect.isNull(b.method11()); b.method12(Contravariant>()); Expect.isNull(b.method13()); b.method14(3); b.method15(contraFunction); b.method16(covFunction); b.method17(Contravariant()); b.method18(Covariant()); b.method19(); b.method20(); b.method21(); } void testClassInMethods() { C c = new C(); c.method1((A x) {}); Expect.type>(c.method2()); } void testOverrideLegacyMethods() { E e = new E(); Expect.isTrue(e.method() is Function); e.method2(contraFunction); e.method3(contraFunction); e.x = contraFunction; D d = e; Expect.throws(() => d.x = "test"); e = new E(); Expect.throws(() => e.method2(contraFunction)); Expect.throws(() => e.method3(contraFunction)); } main() { testClass(); testMixin(); testClassInMethods(); testOverrideLegacyMethods(); }