Index: sdk/lib/async/future.dart |
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart |
index ed0f1b74abaf315dd3c335efc1831531eab1e2e7..5240bf8d5d707207210f6f980946e7e6b3459d93 100644 |
--- a/sdk/lib/async/future.dart |
+++ b/sdk/lib/async/future.dart |
@@ -37,7 +37,7 @@ part of dart.async; |
/// `FutureOr<FutureOr<Object>>`, `FutureOr<Future<Object>> is equivalent to |
/// `Future<Object>`. |
abstract class FutureOr<T> { |
- // Private constructor, so that it is not subclassable, mixable, or |
+ // Private generative constructor, so that it is not subclassable, mixable, or |
// instantiable. |
FutureOr._() { |
throw new UnsupportedError("FutureOr can't be instantiated"); |
@@ -151,7 +151,7 @@ abstract class Future<T> { |
* If a non-future value is returned, the returned future is completed |
* with that value. |
*/ |
- factory Future(computation()) { |
+ factory Future(FutureOr<T> computation()) { |
_Future<T> result = new _Future<T>(); |
Timer.run(() { |
try { |
@@ -177,7 +177,7 @@ abstract class Future<T> { |
* If calling [computation] returns a non-future value, |
* the returned future is completed with that value. |
*/ |
- factory Future.microtask(computation()) { |
+ factory Future.microtask(FutureOr<T> computation()) { |
_Future<T> result = new _Future<T>(); |
scheduleMicrotask(() { |
try { |
@@ -190,38 +190,51 @@ abstract class Future<T> { |
} |
/** |
- * Creates a future containing the result of immediately calling |
+ * Returns a future containing the result of immediately calling |
* [computation]. |
* |
* If calling [computation] throws, the returned future is completed with the |
* error. |
* |
- * If calling [computation] returns a [Future], completion of |
- * the created future will wait until the returned future completes, |
- * and will then complete with the same result. |
+ * If calling [computation] returns a `Future<T>`, that future is returned. |
* |
* If calling [computation] returns a non-future value, |
- * the returned future is completed with that value. |
+ * a future is returned which has been completed with that value. |
*/ |
- factory Future.sync(computation()) { |
+ factory Future.sync(FutureOr<T> computation()) { |
try { |
var result = computation(); |
- return new Future<T>.value(result); |
+ if (result is Future<T>) { |
+ return result; |
+ } else if (result is Future) { |
+ // TODO(lrn): Remove this case for Dart 2.0. |
+ return new _Future<T>.immediate(result); |
+ } else { |
+ return new _Future<T>.value(result); |
+ } |
} catch (error, stackTrace) { |
- return new Future<T>.error(error, stackTrace); |
+ var future = new _Future<T>(); |
+ AsyncError replacement = Zone.current.errorCallback(error, stackTrace); |
+ if (replacement != null) { |
+ future._asyncCompleteError( |
+ _nonNullError(replacement.error), replacement.stackTrace); |
+ } else { |
+ future._asyncCompleteError(error, stackTrace); |
+ } |
+ return future; |
} |
} |
/** |
* A future whose value is available in the next event-loop iteration. |
* |
- * If [value] is not a [Future], using this constructor is equivalent |
- * to [:new Future<T>.sync(() => value):]. |
+ * If [result] is not a [Future], using this constructor is equivalent |
+ * to `new Future<T>.sync(() => result)`. |
* |
- * Use [Completer] to create a Future and complete it later. |
+ * Use [Completer] to create a future and complete it later. |
*/ |
- factory Future.value([value]) { |
- return new _Future<T>.immediate(value); |
+ factory Future.value([FutureOr<T> result]) { |
+ return new _Future<T>.immediate(result); |
} |
/** |
@@ -422,7 +435,7 @@ abstract class Future<T> { |
* If [f] returns a non-[Future], iteration continues immediately. Otherwise |
* it waits for the returned [Future] to complete. |
*/ |
- static Future forEach<T>(Iterable<T> input, dynamic f(T element)) { |
+ static Future forEach<T>(Iterable<T> input, FutureOr f(T element)) { |
var iterator = input.iterator; |
return doWhile(() { |
if (!iterator.moveNext()) return false; |
@@ -437,13 +450,12 @@ abstract class Future<T> { |
* value `true` or a [Future] which completes with the value `true`. |
* |
* If a call to [f] returns `false` or a [Future] that completes to `false`, |
- * iteration ends and the future returned by [doWhile] is completed. |
- * |
- * If a future returned by [f] completes with an error, iteration ends and |
- * the future returned by [doWhile] completes with the same error. |
+ * iteration ends and the future returned by [doWhile] is completed with |
+ * a `null` value. |
* |
- * The [f] function must return either a `bool` value or a [Future] completing |
- * with a `bool` value. |
+ * If a call to [f] throws or a future returned by [f] completes with |
+ * an error, iteration ends and the future returned by [doWhile] |
+ * completes with the same error. |
*/ |
static Future doWhile(FutureOr<bool> f()) { |
_Future doneSignal = new _Future(); |
@@ -609,7 +621,7 @@ abstract class Future<T> { |
* }); |
* } |
*/ |
- Future<T> whenComplete(dynamic action()); |
+ Future<T> whenComplete(FutureOr action()); |
/** |
* Creates a [Stream] containing the result of this future. |