|  | // 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 await for interacts with inference. | 
|  | import "package:async_helper/async_helper.dart"; | 
|  | import 'package:expect/expect.dart'; | 
|  |  | 
|  | import 'utils.dart'; | 
|  |  | 
|  | Stream<int> stream() => Stream.fromIterable([1]); | 
|  |  | 
|  | void main() { | 
|  | asyncTest(() async { | 
|  | await testBottomUpInference(); | 
|  | await testLoopVariableInference(); | 
|  | await testTopDownInference(); | 
|  | }); | 
|  | } | 
|  |  | 
|  | Future<void> testBottomUpInference() async { | 
|  | // Lists. | 
|  | Expect.type<List<int>>([await for (var i in stream()) 1]); | 
|  | Expect.type<List<int>>( | 
|  | [await for (var i in stream()) 1, await for (var i in stream()) 2]); | 
|  | Expect.type<List<num>>( | 
|  | [await for (var i in stream()) 1, await for (var i in stream()) 0.2]); | 
|  | Expect.type<List<int>>([await for (var i in stream()) 1, 2]); | 
|  | Expect.type<List<num>>([await for (var i in stream()) 1, 0.2]); | 
|  | Expect.type<List<dynamic>>([await for (var i in stream()) ...[]]); | 
|  | Expect.type<List<int>>([await for (var i in stream()) ...<int>[]]); | 
|  |  | 
|  | // Maps. | 
|  | Expect.type<Map<int, int>>({await for (var i in stream()) 1: 1}); | 
|  | Expect.type<Map<int, int>>( | 
|  | {await for (var i in stream()) 1: 1, await for (var i in stream()) 2: 2}); | 
|  | Expect.type<Map<num, num>>({ | 
|  | await for (var i in stream()) 1: 0.1, | 
|  | await for (var i in stream()) 0.2: 2 | 
|  | }); | 
|  | Expect.type<Map<int, int>>({await for (var i in stream()) 1: 1, 2: 2}); | 
|  | Expect.type<Map<num, num>>({await for (var i in stream()) 1: 0.1, 0.2: 2}); | 
|  | Expect.type<Map<dynamic, dynamic>>({await for (var i in stream()) ...{}}); | 
|  | Expect.type<Map<int, int>>({await for (var i in stream()) ...<int, int>{}}); | 
|  |  | 
|  | // Sets. | 
|  | Expect.type<Set<int>>({await for (var i in stream()) 1}); | 
|  | Expect.type<Set<int>>( | 
|  | {await for (var i in stream()) 1, await for (var i in stream()) 2}); | 
|  | Expect.type<Set<num>>( | 
|  | {await for (var i in stream()) 1, await for (var i in stream()) 0.2}); | 
|  | Expect.type<Set<int>>({await for (var i in stream()) 1, 2}); | 
|  | Expect.type<Set<num>>({await for (var i in stream()) 1, 0.2}); | 
|  | Expect.type<Set<dynamic>>({await for (var i in stream()) ...[]}); | 
|  | Expect.type<Set<int>>({await for (var i in stream()) ...<int>[]}); | 
|  |  | 
|  | // If a nested iterable's type is dynamic, the element type is dynamic. | 
|  | Expect.type<List<dynamic>>( | 
|  | [1, await for (var i in stream()) ...([] as dynamic)]); | 
|  | Expect.type<Set<dynamic>>( | 
|  | {1, await for (var i in stream()) ...([] as dynamic)}); | 
|  |  | 
|  | // If a nested maps's type is dynamic, the key and value types are dynamic. | 
|  | Expect.type<Map<dynamic, dynamic>>( | 
|  | {1: 1, await for (var i in stream()) ...({} as dynamic)}); | 
|  | } | 
|  |  | 
|  | Future<void> testLoopVariableInference() async { | 
|  | // Infers loop variable from stream. | 
|  | Expect.type<List<int>>([await for (var i in stream()) i]); | 
|  | Expect.type<List<String>>( | 
|  | [await for (var i in stream()) i.toRadixString(10)]); | 
|  |  | 
|  | // Loop variable type is pushed into stream. | 
|  | Expect.listEquals(<int>[1], [await for (int i in expectIntStream([1])) i]); | 
|  | } | 
|  |  | 
|  | Future<void> testTopDownInference() async { | 
|  | // Lists. | 
|  |  | 
|  | // The context element type is pushed into the body. | 
|  | Expect.listEquals(<int>[1], | 
|  | <int>[await for (var i in stream()) expectInt(1)]); | 
|  |  | 
|  | // Bottom up-inference from elements is not pushed back down into the body. | 
|  | Expect.listEquals(<int>[1, 2], | 
|  | [1, await for (var i in stream()) expectDynamic(2)]); | 
|  |  | 
|  | // Maps. | 
|  |  | 
|  | // The context element type is pushed into the body. | 
|  | Expect.mapEquals(<int, String>{1: "s"}, <int, String>{ | 
|  | await for (var i in stream()) expectInt(1): expectString("s") | 
|  | }); | 
|  |  | 
|  | // Bottom up-inference from elements is not pushed back down into the body. | 
|  | Expect.mapEquals(<int, String>{1: "s", 2: "t"}, { | 
|  | 1: "s", | 
|  | await for (var i in stream()) expectDynamic(2): expectDynamic("t") | 
|  | }); | 
|  |  | 
|  | // Sets. | 
|  |  | 
|  | // The context element type is pushed into the body. | 
|  | Expect.setEquals(<int>{1}, <int>{await for (var i in stream()) expectInt(1)}); | 
|  |  | 
|  | // Bottom up-inference from elements is not pushed back down into the body. | 
|  | Expect.setEquals(<int>{1, 2}, | 
|  | {1, await for (var i in stream()) expectDynamic(2)}); | 
|  | } |