| // Copyright (c) 2020, 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:expect/expect.dart"; |
| |
| // Tests that inference can solve for T? ~ dynamic or void. |
| |
| class C<T extends Object> { |
| final T? value; |
| const C(this.value); |
| C.list(List<T?> list) : value = list.first; |
| void set nonNullValue(T value) {} |
| } |
| |
| List<T> foo<T extends Object>(T? value) => [value!]; |
| |
| List<T> bar<T extends Object>(List<T?> value) => [ |
| for (var element in value) |
| if (element != null) element |
| ]; |
| |
| extension Ext<T extends Object> on List<T?> { |
| List<T> whereNotNull() => [ |
| for (var element in this) |
| if (element != null) element |
| ]; |
| } |
| |
| main() { |
| { |
| // Testing for dynamic. |
| const dynamic o = 42; |
| |
| var c = const C(o); |
| var f = foo(o); |
| var l = [o].whereNotNull(); |
| |
| c.expectStaticType<Exactly<C<Object>>>(); |
| Expect.type<C<Object>>(c); // Run-time type is subtype of C<Object>. |
| c.nonNullValue = Object(); // And supertype. |
| |
| f.expectStaticType<Exactly<List<Object>>>(); |
| Expect.type<List<Object>>(f); // Run-time type is subtype of List<Object>. |
| f[0] = Object(); // And supertype. |
| |
| l.expectStaticType<Exactly<List<Object>>>(); |
| Expect.type<List<Object>>(l); // Run-time type is subtype of List<Object>. |
| l[0] = Object(); // And supertype. |
| } |
| |
| { |
| // Testing for void |
| List<void> o = <void>[42]; |
| |
| var c = C.list(o); |
| var f = bar(o); |
| var l = o.whereNotNull(); |
| |
| c.expectStaticType<Exactly<C<Object>>>(); |
| Expect.type<C<Object>>(c); // Run-time type is subtype of C<Object>. |
| c.nonNullValue = Object(); // And supertype. |
| |
| f.expectStaticType<Exactly<List<Object>>>(); |
| Expect.type<List<Object>>(f); // Run-time type is subtype of List<Object>. |
| f[0] = Object(); // And supertype. |
| |
| l.expectStaticType<Exactly<List<Object>>>(); |
| Expect.type<List<Object>>(l); // Run-time type is subtype of List<Object>. |
| l[0] = Object(); // And supertype. |
| } |
| } |
| |
| // Captures and checks static type of expression. |
| extension TypeCheck<T> on T { |
| T expectStaticType<R extends Exactly<T>>() { |
| return this; |
| } |
| } |
| |
| typedef Exactly<T> = T Function(T); |