Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart.async; | 5 part of dart.async; |
| 6 | 6 |
| 7 /** The onValue and onError handlers return either a value or a future */ | 7 /** The onValue and onError handlers return either a value or a future */ |
| 8 typedef dynamic _FutureOnValue<T>(T value); | 8 typedef dynamic _FutureOnValue<T>(T value); |
| 9 /** Test used by [Future.catchError] to handle skip some errors. */ | 9 /** Test used by [Future.catchError] to handle skip some errors. */ |
| 10 typedef bool _FutureErrorTest(var error); | 10 typedef bool _FutureErrorTest(var error); |
| 11 /** Used by [WhenFuture]. */ | 11 /** Used by [WhenFuture]. */ |
| 12 typedef _FutureAction(); | 12 typedef _FutureAction(); |
| 13 | 13 |
| 14 abstract class _Completer<T> implements Completer<T> { | 14 abstract class _Completer<T> implements Completer<T> { |
| 15 final _Future<T> future = new _Future<T>(); | 15 final _Future<T> future = new _Future<T>(); |
| 16 | 16 |
| 17 void complete([T value]); | 17 void complete([value]); |
| 18 | 18 |
| 19 void completeError(Object error, [StackTrace stackTrace]); | 19 void completeError(Object error, [StackTrace stackTrace]); |
| 20 | 20 |
| 21 // The future's _isComplete doesn't take into account pending completions. | 21 // The future's _isComplete doesn't take into account pending completions. |
| 22 // We therefore use _mayComplete. | 22 // We therefore use _mayComplete. |
| 23 bool get isCompleted => !future._mayComplete; | 23 bool get isCompleted => !future._mayComplete; |
| 24 } | 24 } |
| 25 | 25 |
| 26 class _AsyncCompleter<T> extends _Completer<T> { | 26 class _AsyncCompleter<T> extends _Completer<T> { |
| 27 | 27 |
| 28 void complete([T value]) { | 28 void complete([value]) { |
| 29 if (!future._mayComplete) throw new StateError("Future already completed"); | 29 if (!future._mayComplete) throw new StateError("Future already completed"); |
| 30 future._asyncComplete(value); | 30 future._asyncComplete(value); |
| 31 } | 31 } |
| 32 | 32 |
| 33 void completeError(Object error, [StackTrace stackTrace]) { | 33 void completeError(Object error, [StackTrace stackTrace]) { |
| 34 if (error is Future) { | |
|
floitsch
2013/10/29 18:13:35
ditto. I don't think this restriction is necessary
Lasse Reichstein Nielsen
2013/10/30 09:22:17
Removing.
| |
| 35 throw new ArgumentError("Cannot use completeError with a future - " | |
| 36 "use complete instead"); | |
| 37 } | |
| 38 if (error == null) throw new ArgumentError("Error must not be null"); | |
| 34 if (!future._mayComplete) throw new StateError("Future already completed"); | 39 if (!future._mayComplete) throw new StateError("Future already completed"); |
| 35 future._asyncCompleteError(error, stackTrace); | 40 future._asyncCompleteError(error, stackTrace); |
| 36 } | 41 } |
| 37 } | 42 } |
| 38 | 43 |
| 39 class _SyncCompleter<T> extends _Completer<T> { | 44 class _SyncCompleter<T> extends _Completer<T> { |
| 40 | 45 |
| 41 void complete([T value]) { | 46 void complete([value]) { |
| 42 if (!future._mayComplete) throw new StateError("Future already completed"); | 47 if (!future._mayComplete) throw new StateError("Future already completed"); |
| 43 future._complete(value); | 48 future._complete(value); |
| 44 } | 49 } |
| 45 | 50 |
| 46 void completeError(Object error, [StackTrace stackTrace]) { | 51 void completeError(Object error, [StackTrace stackTrace]) { |
| 52 if (error is Future) { | |
|
floitsch
2013/10/29 18:13:35
ditto
Lasse Reichstein Nielsen
2013/10/30 09:22:17
ditto too.
| |
| 53 throw new ArgumentError("Cannot use completeError with a future. " | |
| 54 "Use complete instead."); | |
| 55 } | |
| 47 if (!future._mayComplete) throw new StateError("Future already completed"); | 56 if (!future._mayComplete) throw new StateError("Future already completed"); |
| 48 future._completeError(error, stackTrace); | 57 future._completeError(error, stackTrace); |
| 49 } | 58 } |
| 50 } | 59 } |
| 51 | 60 |
| 52 class _Future<T> implements Future<T> { | 61 class _Future<T> implements Future<T> { |
| 53 // State of the future. The state determines the interpretation of the | 62 // State of the future. The state determines the interpretation of the |
| 54 // [resultOrListeners] field. | 63 // [resultOrListeners] field. |
| 55 // TODO(lrn): rename field since it can also contain a chained future. | 64 // TODO(lrn): rename field since it can also contain a chained future. |
| 56 | 65 |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 224 } | 233 } |
| 225 | 234 |
| 226 void _setError(Object error, StackTrace stackTrace) { | 235 void _setError(Object error, StackTrace stackTrace) { |
| 227 assert(!_isComplete); // But may have a completion pending. | 236 assert(!_isComplete); // But may have a completion pending. |
| 228 _state = _ERROR; | 237 _state = _ERROR; |
| 229 _resultOrListeners = new _AsyncError(error, stackTrace); | 238 _resultOrListeners = new _AsyncError(error, stackTrace); |
| 230 } | 239 } |
| 231 | 240 |
| 232 void _addListener(_Future listener) { | 241 void _addListener(_Future listener) { |
| 233 assert(listener._nextListener == null); | 242 assert(listener._nextListener == null); |
| 243 _Future target = this; | |
|
floitsch
2013/10/29 18:13:35
spurious change?
Lasse Reichstein Nielsen
2013/10/30 09:22:17
ack, yes. Left over from debugging.
Removed.
| |
| 234 if (_isComplete) { | 244 if (_isComplete) { |
| 235 // Handle late listeners asynchronously. | 245 // Handle late listeners asynchronously. |
| 236 _zone.scheduleMicrotask(() { | 246 _zone.scheduleMicrotask(() { |
| 237 _propagateToListeners(this, listener); | 247 _propagateToListeners(this, listener); |
| 238 }); | 248 }); |
| 239 } else { | 249 } else { |
| 240 listener._nextListener = _resultOrListeners; | 250 listener._nextListener = _resultOrListeners; |
| 241 _resultOrListeners = listener; | 251 _resultOrListeners = listener; |
| 242 } | 252 } |
| 243 } | 253 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 307 assert(_onValue == null); | 317 assert(_onValue == null); |
| 308 assert(_onError == null); | 318 assert(_onError == null); |
| 309 assert(_whenCompleteAction == null); | 319 assert(_whenCompleteAction == null); |
| 310 assert(_errorTest == null); | 320 assert(_errorTest == null); |
| 311 | 321 |
| 312 if (stackTrace != null) { | 322 if (stackTrace != null) { |
| 313 // Force the stack trace onto the error, even if it already had one. | 323 // Force the stack trace onto the error, even if it already had one. |
| 314 _attachStackTrace(error, stackTrace); | 324 _attachStackTrace(error, stackTrace); |
| 315 } | 325 } |
| 316 | 326 |
| 317 _Future listeners = _isChained ? null : _removeListeners(); | 327 _Future listeners = _removeListeners(); |
| 318 _setError(error, stackTrace); | 328 _setError(error, stackTrace); |
| 319 _propagateToListeners(this, listeners); | 329 _propagateToListeners(this, listeners); |
| 320 } | 330 } |
| 321 | 331 |
| 322 void _asyncComplete(value) { | 332 void _asyncComplete(value) { |
| 323 assert(!_isComplete); | 333 assert(!_isComplete); |
| 324 assert(_onValue == null); | 334 assert(_onValue == null); |
| 325 assert(_onError == null); | 335 assert(_onError == null); |
| 326 assert(_whenCompleteAction == null); | 336 assert(_whenCompleteAction == null); |
| 327 assert(_errorTest == null); | 337 assert(_errorTest == null); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 535 } else { | 545 } else { |
| 536 listeners = listener._removeListeners(); | 546 listeners = listener._removeListeners(); |
| 537 _AsyncError asyncError = listenerValueOrError; | 547 _AsyncError asyncError = listenerValueOrError; |
| 538 listener._setError(asyncError.error, asyncError.stackTrace); | 548 listener._setError(asyncError.error, asyncError.stackTrace); |
| 539 } | 549 } |
| 540 // Prepare for next round. | 550 // Prepare for next round. |
| 541 source = listener; | 551 source = listener; |
| 542 } | 552 } |
| 543 } | 553 } |
| 544 } | 554 } |
| OLD | NEW |