Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1203)

Unified Diff: lib/src/utils.dart

Issue 2184303002: Make pub strong-mode clean. (Closed) Base URL: git@github.com:dart-lang/pub.git@master
Patch Set: Code review changes Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/src/system_cache.dart ('k') | lib/src/validator.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/utils.dart
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 5d35fd21505607b5f39c1c1c60f62e0ad951dda7..2bead98e47458e926c7cfae2970b725fba986bba 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -55,47 +55,6 @@ class Pair<E, F> {
int get hashCode => first.hashCode ^ last.hashCode;
}
-/// A completer that waits until all added [Future]s complete.
-// TODO(rnystrom): Copied from web_components. Remove from here when it gets
-// added to dart:core. (See #6626.)
-class FutureGroup<T> {
- int _pending = 0;
- Completer<List<T>> _completer = new Completer<List<T>>();
- final List<Future<T>> futures = <Future<T>>[];
- bool completed = false;
-
- final List<T> _values = <T>[];
-
- /// Wait for [task] to complete.
- Future<T> add(Future<T> task) {
- if (completed) {
- throw new StateError("The FutureGroup has already completed.");
- }
-
- _pending++;
- futures.add(task.then((value) {
- if (completed) return;
-
- _pending--;
- _values.add(value);
-
- if (_pending <= 0) {
- completed = true;
- _completer.complete(_values);
- }
- }).catchError((e, stackTrace) {
- if (completed) return;
-
- completed = true;
- _completer.completeError(e, stackTrace);
- }));
-
- return task;
- }
-
- Future<List> get future => _completer.future;
-}
-
/// Like [new Future], but avoids around issue 11911 by using [new Future.value]
/// under the covers.
Future newFuture(callback()) => new Future.value().then((_) => callback());
@@ -145,7 +104,7 @@ Future captureErrors(Future callback(), {bool captureStackChains: false}) {
/// only returns once all Futures have completed, successfully or not.
///
/// This will wrap the first error thrown in a [SilentException] and rethrow it.
-Future waitAndPrintErrors(Iterable<Future> futures) {
+Future<List/*<T>*/> waitAndPrintErrors/*<T>*/(Iterable<Future/*<T>*/> futures) {
return Future.wait(futures.map((future) {
return future.catchError((error, stackTrace) {
log.exception(error, stackTrace);
@@ -160,8 +119,8 @@ Future waitAndPrintErrors(Iterable<Future> futures) {
/// completes.
///
/// The stream will be passed through unchanged.
-StreamTransformer onDoneTransformer(void onDone()) {
- return new StreamTransformer.fromHandlers(handleDone: (sink) {
+StreamTransformer/*<T, T>*/ onDoneTransformer/*<T>*/(void onDone()) {
+ return new StreamTransformer/*<T, T>*/.fromHandlers(handleDone: (sink) {
onDone();
sink.close();
});
@@ -274,23 +233,6 @@ bool isLoopback(String host) {
}
}
-/// Flattens nested lists inside an iterable into a single list containing only
-/// non-list elements.
-List flatten(Iterable nested) {
- var result = [];
- helper(list) {
- for (var element in list) {
- if (element is List) {
- helper(element);
- } else {
- result.add(element);
- }
- }
- }
- helper(nested);
- return result;
-}
-
/// Randomly chooses a single element in [elements].
/*=T*/ choose/*<T>*/(List/*<T>*/ elements) =>
elements[random.nextInt(elements.length)];
@@ -312,7 +254,7 @@ bool overlaps(Set set1, Set set2) {
}
/// Returns a list containing the sorted elements of [iter].
-List ordered(Iterable<Comparable> iter) {
+List/*<T>*/ ordered/*<T extends Comparable<T>>*/(Iterable/*<T>*/ iter) {
var list = iter.toList();
list.sort();
return list;
@@ -346,84 +288,13 @@ Iterable<Pair> pairs(Iterable iter) {
});
}
-/// Creates a new map from [map] with new keys and values.
-///
-/// The return values of [key] are used as the keys and the return values of
-/// [value] are used as the values for the new map.
-///
-/// [key] defaults to returning the original key and [value] defaults to
-/// returning the original value.
-Map mapMap(Map map, {key(key, value), value(key, value)}) {
- if (key == null) key = (key, _) => key;
- if (value == null) value = (_, value) => value;
-
- var result = {};
- map.forEach((mapKey, mapValue) {
- result[key(mapKey, mapValue)] = value(mapKey, mapValue);
- });
- return result;
-}
-
-/// Like [Map.fromIterable], but [key] and [value] may return [Future]s.
-Future<Map> mapFromIterableAsync(Iterable iter, {key(element),
- value(element)}) {
- if (key == null) key = (element) => element;
- if (value == null) value = (element) => element;
-
- var map = new Map();
- return Future.wait(iter.map((element) {
- return Future.wait([
- new Future.sync(() => key(element)),
- new Future.sync(() => value(element))
- ]).then((results) {
- map[results[0]] = results[1];
- });
- })).then((_) => map);
-}
-
-/// Returns a new map with all entries in both [map1] and [map2].
-///
-/// If there are overlapping keys, [map2]'s value wins.
-Map mergeMaps(Map map1, Map map2) {
- var result = {};
- result.addAll(map1);
- result.addAll(map2);
- return result;
-}
-
-/// Returns the transitive closure of [graph].
-///
-/// This assumes [graph] represents a graph with a vertex for each key and an
-/// edge betweek each key and the values for that key.
-Map<dynamic, Set> transitiveClosure(Map<dynamic, Iterable> graph) {
- // This uses the Floyd-Warshall algorithm
- // (https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm).
- var result = {};
- graph.forEach((vertex, edges) {
- result[vertex] = new Set.from(edges)..add(vertex);
- });
-
- for (var vertex1 in graph.keys) {
- for (var vertex2 in graph.keys) {
- for (var vertex3 in graph.keys) {
- if (result[vertex2].contains(vertex1) &&
- result[vertex1].contains(vertex3)) {
- result[vertex2].add(vertex3);
- }
- }
- }
- }
-
- return result;
-}
-
/// Given a list of filenames, returns a set of patterns that can be used to
/// filter for those filenames.
///
/// For a given path, that path ends with some string in the returned set if
/// and only if that path's basename is in [files].
Set<String> createFileFilter(Iterable<String> files) {
- return files.expand((file) {
+ return files.expand/*<String>*/((file) {
var result = ["/$file"];
if (Platform.operatingSystem == 'windows') result.add("\\$file");
return result;
@@ -436,7 +307,7 @@ Set<String> createFileFilter(Iterable<String> files) {
/// For a given path, that path contains some string in the returned set if
/// and only if one of that path's components is in [dirs].
Set<String> createDirectoryFilter(Iterable<String> dirs) {
- return dirs.expand((dir) {
+ return dirs.expand/*<String>*/((dir) {
var result = ["/$dir/"];
if (Platform.operatingSystem == 'windows') {
result..add("/$dir\\")..add("\\$dir/")..add("\\$dir\\");
@@ -533,7 +404,7 @@ void chainToCompleter(Future future, Completer completer) {
/// emitting the same values and errors as [stream], but only if at least one
/// value can be read successfully. If an error occurs before any values are
/// emitted, the returned Future completes to that error.
-Future<Stream> validateStream(Stream stream) {
+Future<Stream/*<T>*/> validateStream/*<T>*/(Stream/*<T>*/ stream) {
var completer = new Completer<Stream>();
var controller = new StreamController(sync: true);
@@ -594,66 +465,6 @@ Pair<Stream, StreamSubscription> streamWithSubscription(Stream stream) {
return new Pair<Stream, StreamSubscription>(controller.stream, subscription);
}
-// TODO(nweiz): remove this when issue 7787 is fixed.
-/// Creates two single-subscription [Stream]s that each emit all values and
-/// errors from [stream].
-///
-/// This is useful if [stream] is single-subscription but multiple subscribers
-/// are necessary.
-Pair<Stream, Stream> tee(Stream stream) {
- var controller1 = new StreamController(sync: true);
- var controller2 = new StreamController(sync: true);
- stream.listen((value) {
- controller1.add(value);
- controller2.add(value);
- }, onError: (error, [stackTrace]) {
- controller1.addError(error, stackTrace);
- controller2.addError(error, stackTrace);
- }, onDone: () {
- controller1.close();
- controller2.close();
- });
- return new Pair<Stream, Stream>(controller1.stream, controller2.stream);
-}
-
-/// Merges [stream1] and [stream2] into a single stream that emits events from
-/// both sources.
-Stream mergeStreams(Stream stream1, Stream stream2) {
- var doneCount = 0;
- var controller = new StreamController(sync: true);
-
- for (var stream in [stream1, stream2]) {
- stream.listen(
- controller.add,
- onError: controller.addError,
- onDone: () {
- doneCount++;
- if (doneCount == 2) controller.close();
- });
- }
-
- return controller.stream;
-}
-
-/// Returns a [Stream] that will emit the same values as the stream returned by
-/// [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: () {
- subscription = callback().listen(controller.add,
- onError: controller.addError,
- onDone: controller.close);
- },
- onCancel: () => subscription.cancel(),
- onPause: () => subscription.pause(),
- onResume: () => subscription.resume(),
- sync: true);
- return controller.stream;
-}
-
/// A regular expression matching a trailing CR character.
final _trailingCR = new RegExp(r"\r$");
@@ -728,7 +539,7 @@ Uri addQueryParameters(Uri url, Map<String, String> parameters) {
/// Convert a URL query string (or `application/x-www-form-urlencoded` body)
/// into a [Map] from parameter names to values.
Map<String, String> queryToMap(String queryList) {
- var map = {};
+ var map = <String, String>{};
for (var pair in queryList.split("&")) {
var split = split1(pair, "=");
if (split.isEmpty) continue;
@@ -755,7 +566,7 @@ String mapToQuery(Map<String, String> map) {
}
/// 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));
// TODO(nweiz): remove this when issue 9068 has been fixed.
@@ -795,13 +606,12 @@ String niceDuration(Duration duration) {
// If we're using verbose logging, be more verbose but more accurate when
// reporting timing information.
- if (log.verbosity.isLevelVisible(log.Level.FINE)) {
- ms = padLeft(ms.toString(), 3, '0');
- } else {
- ms ~/= 100;
- }
+ var msString = log.verbosity.isLevelVisible(log.Level.FINE)
+ ? padLeft(ms.toString(), 3, '0')
+ : (ms ~/ 100).toString();
- return "$result${hasMinutes ? padLeft(s.toString(), 2, '0') : s}.${ms}s";
+ return "$result${hasMinutes ? padLeft(s.toString(), 2, '0') : s}"
+ ".${msString}s";
}
/// Decodes a URL-encoded string.
@@ -815,26 +625,27 @@ String urlDecode(String encoded) =>
/// within.
///
/// Completes with the fully resolved structure.
-Future awaitObject(object) {
+Future/*<T>*/ awaitObject/*<T>*/(/*=T*/ object) async {
// Unroll nested futures.
- if (object is Future) return object.then(awaitObject);
+ if (object is Future) return await awaitObject(await object);
+
if (object is Iterable) {
- return Future.wait(object.map(awaitObject).toList());
+ // TODO(nweiz): Remove the unnecessary as check when sdk#26965 is fixed.
+ return await Future.wait((object as Iterable).map(awaitObject))
+ as List/*=T*/;
}
- if (object is! Map) return new Future.value(object);
- var pairs = <Future<Pair>>[];
- object.forEach((key, value) {
- pairs.add(awaitObject(value)
- .then((resolved) => new Pair(key, resolved)));
- });
- return Future.wait(pairs).then((resolvedPairs) {
- var map = {};
- for (var pair in resolvedPairs) {
- map[pair.first] = pair.last;
- }
- return map;
- });
+ if (object is Map) {
+ // TODO(nweiz): Remove the unnecessary as check when sdk#26965 is fixed.
+ var oldMap = object as Map;
+ var newMap = {};
+ await Future.wait(oldMap.keys.map((key) async {
+ newMap[key] = await awaitObject(await oldMap[key]);
+ }));
+ return newMap as Map/*=T*/;
+ }
+
+ return object;
}
/// Whether "special" strings such as Unicode characters or color escapes are
« no previous file with comments | « lib/src/system_cache.dart ('k') | lib/src/validator.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698