| // 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. |
| |
| // Test how spread interacts with inference. |
| import 'package:expect/expect.dart'; |
| |
| void main() { |
| testBottomUpInference(); |
| testTopDownInference(); |
| } |
| |
| void testBottomUpInference() { |
| // Lists. |
| Expect.type<List<dynamic>>([...[]]); |
| Expect.type<List<int>>([...<int>[]]); |
| Expect.type<List<int>>([...[1]]); |
| Expect.type<List<int>>([1, ...[2]]); |
| Expect.type<List<num>>([1, ...[0.2]]); |
| Expect.type<List<int>>([...[1, 2]]); |
| Expect.type<List<num>>([...[1, 0.2]]); |
| Expect.type<List<int>>([...[1], ...[2]]); |
| Expect.type<List<num>>([...[1], ...[0.2]]); |
| |
| // Maps. |
| Expect.type<Map<dynamic, dynamic>>({...{}}); |
| Expect.type<Map<int, int>>({...<int, int>{}}); |
| Expect.type<Map<int, int>>({...{1: 1}}); |
| Expect.type<Map<int, int>>({1: 1, ...{2: 2}}); |
| Expect.type<Map<num, num>>({1: 1, ...{0.2: 0.2}}); |
| Expect.type<Map<int, int>>({...{1: 1, 2: 2}}); |
| Expect.type<Map<num, num>>({...{1: 1, 0.2: 0.2}}); |
| Expect.type<Map<int, int>>({...{1: 1}, ...{2: 2}}); |
| Expect.type<Map<num, num>>({...{1: 1}, ...{0.2: 0.2}}); |
| |
| // Sets. |
| Expect.type<Set<dynamic>>({...[]}); |
| Expect.type<Set<int>>({...<int>[]}); |
| Expect.type<Set<int>>({...[1]}); |
| Expect.type<Set<int>>({1, ...[2]}); |
| Expect.type<Set<num>>({1, ...[0.2]}); |
| Expect.type<Set<int>>({...[1, 2]}); |
| Expect.type<Set<num>>({...[1, 0.2]}); |
| Expect.type<Set<int>>({...[1], ...[2]}); |
| Expect.type<Set<num>>({...[1], ...[0.2]}); |
| Expect.type<Set<num>>({...{1}, ...[0.2]}); |
| Expect.type<Set<num>>({...{1}, ...{0.2}}); |
| |
| // If the iterable's type is dynamic, the element type is inferred as dynamic. |
| Expect.type<List<dynamic>>([...([] as dynamic)]); |
| Expect.type<Set<dynamic>>({1, ...([] as dynamic)}); |
| |
| // If the iterable's type is dynamic, the key and value types are inferred as |
| // dynamic. |
| Expect.type<Map<dynamic, dynamic>>({1: 1, ...({} as dynamic)}); |
| } |
| |
| void testTopDownInference() { |
| // Lists. |
| Iterable<T> expectIntIterable<T>() { |
| Expect.equals(int, T); |
| return []; |
| } |
| |
| Iterable<T> expectDynamicIterable<T>() { |
| Expect.equals(dynamic, T); |
| return []; |
| } |
| |
| // The context element type is pushed into the spread expression if it is |
| // Iterable<T>. |
| Expect.listEquals(<int>[], <int>[...expectIntIterable()]); |
| |
| // Bottom up-inference from elements is not pushed back down into spread. |
| Expect.listEquals(<int>[1], [1, ...expectDynamicIterable()]); |
| |
| // Maps. |
| Map<K, V> expectIntStringMap<K, V>() { |
| Expect.equals(int, K); |
| Expect.equals(String, V); |
| return {}; |
| } |
| |
| Map<K, V> expectDynamicDynamicMap<K, V>() { |
| Expect.equals(dynamic, K); |
| Expect.equals(dynamic, V); |
| return {}; |
| } |
| |
| // The context element type is pushed into the spread expression if it is |
| // Map<K, V>. |
| Expect.mapEquals(<int, String>{}, <int, String>{...expectIntStringMap()}); |
| |
| // Bottom up-inference from elements is not pushed back down into spread. |
| Expect.mapEquals(<int, String>{1: "s"}, |
| {1: "s", ...expectDynamicDynamicMap()}); |
| |
| // Sets. |
| Set<T> expectIntSet<T>() { |
| Expect.equals(int, T); |
| return Set(); |
| } |
| |
| Set<T> expectDynamicSet<T>() { |
| Expect.equals(dynamic, T); |
| return Set(); |
| } |
| |
| // The context element type is pushed into the spread expression if it is |
| // Iterable<T>. |
| Expect.setEquals(<int>{}, <int>{...expectIntSet()}); |
| |
| // Bottom up-inference from elements is not pushed back down into spread. |
| Expect.setEquals(<int>{1}, {1, ...expectDynamicSet()}); |
| } |