| Index: packages/barback/lib/src/utils.dart
|
| diff --git a/packages/barback/lib/src/utils.dart b/packages/barback/lib/src/utils.dart
|
| index 7ce6724e17c31d67239f2754e61c1757c2532b1e..e991078bcc4b08010244fbdef1ab84caac4c4c2a 100644
|
| --- a/packages/barback/lib/src/utils.dart
|
| +++ b/packages/barback/lib/src/utils.dart
|
| @@ -7,6 +7,7 @@ library barback.utils;
|
| import 'dart:async';
|
| import 'dart:typed_data';
|
|
|
| +import 'package:async/async.dart';
|
| import 'package:stack_trace/stack_trace.dart';
|
|
|
| /// A class that represents a value or an error.
|
| @@ -129,8 +130,9 @@ Uint8List toUint8List(List<int> input) {
|
| ///
|
| /// This returns a map whose keys are the return values of [fn] and whose values
|
| /// are lists of each element in [iter] for which [fn] returned that key.
|
| -Map<Object, List> groupBy(Iterable iter, fn(element)) {
|
| - var map = {};
|
| +Map<Object/*=T*/, List/*<S>*/> groupBy/*<S, T>*/(Iterable/*<S>*/ iter,
|
| + /*=T*/ fn(/*=S*/ element)) {
|
| + var map = /*<T, List<S>>*/{};
|
| for (var element in iter) {
|
| var list = map.putIfAbsent(fn(element), () => []);
|
| list.add(element);
|
| @@ -156,27 +158,35 @@ List flatten(Iterable nested) {
|
| }
|
|
|
| /// Returns the union of all elements in each set in [sets].
|
| -Set unionAll(Iterable<Set> sets) =>
|
| +Set/*<T>*/ unionAll/*<T>*/(Iterable<Set/*<T>*/> sets) =>
|
| sets.fold(new Set(), (union, set) => union.union(set));
|
|
|
| /// Creates a new map from [map] with new keys and values.
|
| ///
|
| /// The return values of [keyFn] are used as the keys and the return values of
|
| /// [valueFn] are used as the values for the new map.
|
| -Map mapMap(Map map, keyFn(key, value), valueFn(key, value)) =>
|
| +Map/*<K2, V2>*/ mapMap/*<K1, V1, K2, V2>*/(Map/*<K1, V1>*/ map,
|
| + /*=K2*/ keyFn(/*=K1*/ key, /*=V1*/ value),
|
| + /*=V2*/ valueFn(/*=K1*/ key, /*=V1*/ value)) =>
|
| new Map.fromIterable(map.keys,
|
| - key: (key) => keyFn(key, map[key]),
|
| - value: (key) => valueFn(key, map[key]));
|
| + key: (key) => keyFn(key as dynamic/*=K1*/, map[key]),
|
| + value: (key) => valueFn(key as dynamic/*=K1*/, map[key]));
|
|
|
| /// Creates a new map from [map] with the same keys.
|
| ///
|
| /// The return values of [fn] are used as the values for the new map.
|
| -Map mapMapValues(Map map, fn(key, value)) => mapMap(map, (key, _) => key, fn);
|
| +Map/*<K, V2>*/ mapMapValues/*<K, V1, V2>*/(Map/*<K, V1>*/ map,
|
| + /*=V2*/ fn(/*=K*/ key, /*=V1*/ value)) =>
|
| + // TODO(nweiz): Don't explicitly type [key] when sdk#25490 is fixed.
|
| + mapMap(map, (/*=K*/ key, _) => key, fn);
|
|
|
| /// Creates a new map from [map] with the same keys.
|
| ///
|
| /// The return values of [fn] are used as the keys for the new map.
|
| -Map mapMapKeys(Map map, fn(key, value)) => mapMap(map, fn, (_, value) => value);
|
| +Map/*<K2, V>*/ mapMapKeys/*<K1, V, K2>*/(Map/*<K1, V>*/ map,
|
| + /*=K2*/ fn(/*=K1*/ key, /*=V*/ value)) =>
|
| + // TODO(nweiz): Don't explicitly type [value] when sdk#25490 is fixed.
|
| + mapMap(map, fn, (_, /*=V*/ value) => value);
|
|
|
| /// Returns whether [set1] has exactly the same elements as [set2].
|
| bool setEquals(Set set1, Set set2) =>
|
| @@ -186,15 +196,17 @@ bool setEquals(Set set1, Set set2) =>
|
| ///
|
| /// If [broadcast] is true, this will return a broadcast stream; otherwise, it
|
| /// will return a buffered stream.
|
| -Stream mergeStreams(Iterable<Stream> streams, {bool broadcast: false}) {
|
| +Stream/*<T>*/ mergeStreams/*<T>*/(Iterable<Stream/*<T>*/> streams,
|
| + {bool broadcast: false}) {
|
| streams = streams.toList();
|
| var doneCount = 0;
|
| // Use a sync stream to preserve the synchrony behavior of the input streams.
|
| // If the inputs are sync, then this will be sync as well; if the inputs are
|
| // async, then the events we receive will also be async, and forwarding them
|
| // sync won't change that.
|
| - var controller = broadcast ? new StreamController.broadcast(sync: true)
|
| - : new StreamController(sync: true);
|
| + var controller = broadcast
|
| + ? new StreamController/*<T>*/.broadcast(sync: true)
|
| + : new StreamController/*<T>*/(sync: true);
|
|
|
| for (var stream in streams) {
|
| stream.listen(
|
| @@ -235,13 +247,9 @@ Future pumpEventQueue([int times=20]) {
|
| return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1));
|
| }
|
|
|
| -/// Like `new Future`, but avoids issue 11911 by using `new Future.value` under
|
| +/// Like [new Future], but avoids dartbug.com/11911 by using async/await under
|
| /// the covers.
|
| -// TODO(jmesserly): doc comment changed to due 14601.
|
| -Future newFuture(callback()) => new Future.value().then((_) => callback());
|
| -
|
| -/// Like [Future.sync], but wraps the Future in [Chain.track] as well.
|
| -Future syncFuture(callback()) => Chain.track(new Future.sync(callback));
|
| +Future/*<T>*/ newFuture/*<T>*/(/*=T*/ callback()) async => await callback();
|
|
|
| /// Returns a buffered stream that will emit the same values as the stream
|
| /// returned by [future] once [future] completes.
|
| @@ -252,17 +260,18 @@ Future syncFuture(callback()) => Chain.track(new Future.sync(callback));
|
| /// If [broadcast] is true, a broadcast stream is returned. This assumes that
|
| /// the stream returned by [future] will be a broadcast stream as well.
|
| /// [broadcast] defaults to false.
|
| -Stream futureStream(Future<Stream> future, {bool broadcast: false}) {
|
| - var subscription;
|
| - var controller;
|
| +Stream/*<T>*/ futureStream/*<T>*/(Future<Stream/*<T>*/> future,
|
| + {bool broadcast: false}) {
|
| + StreamSubscription/*<T>*/ subscription;
|
| + StreamController/*<T>*/ controller;
|
|
|
| - future = future.catchError((e, stackTrace) {
|
| + future = DelegatingFuture.typed(future.catchError((e, stackTrace) {
|
| // Since [controller] is synchronous, it's likely that emitting an error
|
| // will cause it to be cancelled before we call close.
|
| if (controller != null) controller.addError(e, stackTrace);
|
| if (controller != null) controller.close();
|
| controller = null;
|
| - });
|
| + }));
|
|
|
| onListen() {
|
| future.then((stream) {
|
| @@ -281,10 +290,10 @@ Stream futureStream(Future<Stream> future, {bool broadcast: false}) {
|
| }
|
|
|
| if (broadcast) {
|
| - controller = new StreamController.broadcast(
|
| + controller = new StreamController/*<T>*/.broadcast(
|
| sync: true, onListen: onListen, onCancel: onCancel);
|
| } else {
|
| - controller = new StreamController(
|
| + controller = new StreamController/*<T>*/(
|
| sync: true, onListen: onListen, onCancel: onCancel);
|
| }
|
| return controller.stream;
|
| @@ -294,10 +303,10 @@ Stream futureStream(Future<Stream> future, {bool broadcast: false}) {
|
| /// [callback].
|
| ///
|
| /// [callback] will only be called when the returned [Stream] gets a subscriber.
|
| -Stream callbackStream(Stream callback()) {
|
| - var subscription;
|
| - var controller;
|
| - controller = new StreamController(onListen: () {
|
| +Stream/*<T>*/ callbackStream/*<T>*/(Stream/*<T>*/ callback()) {
|
| + StreamSubscription/*<T>*/ subscription;
|
| + StreamController/*<T>*/ controller;
|
| + controller = new StreamController/*<T>*/(onListen: () {
|
| subscription = callback().listen(controller.add,
|
| onError: controller.addError,
|
| onDone: controller.close);
|
| @@ -313,13 +322,14 @@ Stream callbackStream(Stream callback()) {
|
| ///
|
| /// The returned stream will enqueue events from [broadcast] until a listener is
|
| /// attached, then pipe events to that listener.
|
| -Stream broadcastToSingleSubscription(Stream broadcast) {
|
| +Stream/*<T>*/ broadcastToSingleSubscription/*<T>*/(Stream/*<T>*/ broadcast) {
|
| if (!broadcast.isBroadcast) return broadcast;
|
|
|
| // TODO(nweiz): Implement this using a transformer when issues 18588 and 18586
|
| // are fixed.
|
| var subscription;
|
| - var controller = new StreamController(onCancel: () => subscription.cancel());
|
| + var controller = new StreamController/*<T>*/(
|
| + onCancel: () => subscription.cancel());
|
| subscription = broadcast.listen(controller.add,
|
| onError: controller.addError,
|
| onDone: controller.close);
|
|
|