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

Side by Side Diff: sdk/lib/async/future_impl.dart

Issue 2762953003: More minor type improvements in dart:async. (Closed)
Patch Set: More fixes. Created 3 years, 9 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 unified diff | Download patch
« no previous file with comments | « sdk/lib/async/future.dart ('k') | sdk/lib/async/stream.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 FutureOr<T> _FutureOnValue<S, T>(S value); 8 typedef FutureOr<T> _FutureOnValue<S, T>(S 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(Object error);
11 /** Used by [WhenFuture]. */ 11 /** Used by [WhenFuture]. */
12 typedef _FutureAction(); 12 typedef dynamic _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([FutureOr<T> value]); 17 void complete([FutureOr<T> value]);
18 18
19 void completeError(Object error, [StackTrace stackTrace]) { 19 void completeError(Object error, [StackTrace stackTrace]) {
20 error = _nonNullError(error); 20 error = _nonNullError(error);
21 if (!future._mayComplete) throw new StateError("Future already completed"); 21 if (!future._mayComplete) throw new StateError("Future already completed");
22 AsyncError replacement = Zone.current.errorCallback(error, stackTrace); 22 AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 } 56 }
57 } 57 }
58 58
59 class _FutureListener<S, T> { 59 class _FutureListener<S, T> {
60 static const int MASK_VALUE = 1; 60 static const int MASK_VALUE = 1;
61 static const int MASK_ERROR = 2; 61 static const int MASK_ERROR = 2;
62 static const int MASK_TEST_ERROR = 4; 62 static const int MASK_TEST_ERROR = 4;
63 static const int MASK_WHENCOMPLETE = 8; 63 static const int MASK_WHENCOMPLETE = 8;
64 static const int STATE_CHAIN = 0; 64 static const int STATE_CHAIN = 0;
65 static const int STATE_THEN = MASK_VALUE; 65 static const int STATE_THEN = MASK_VALUE;
66 // TODO(johnmccutchan): Remove the hard coded value. See #26030. 66 static const int STATE_THEN_ONERROR = MASK_VALUE | MASK_ERROR;
67 static const int STATE_THEN_ONERROR = 3; // MASK_VALUE | MASK_ERROR.
68 static const int STATE_CATCHERROR = MASK_ERROR; 67 static const int STATE_CATCHERROR = MASK_ERROR;
69 // TODO(johnmccutchan): Remove the hard coded value. See #26030. 68 static const int STATE_CATCHERROR_TEST = MASK_ERROR | MASK_TEST_ERROR;
70 static const int STATE_CATCHERROR_TEST = 6; // MASK_ERROR | MASK_TEST_ERROR.
71 static const int STATE_WHENCOMPLETE = MASK_WHENCOMPLETE; 69 static const int STATE_WHENCOMPLETE = MASK_WHENCOMPLETE;
72 // Listeners on the same future are linked through this link. 70 // Listeners on the same future are linked through this link.
73 _FutureListener _nextListener = null; 71 _FutureListener _nextListener = null;
74 // The future to complete when this listener is activated. 72 // The future to complete when this listener is activated.
75 final _Future<T> result; 73 final _Future<T> result;
76 // Which fields means what. 74 // Which fields means what.
77 final int state; 75 final int state;
78 // Used for then/whenDone callback and error test 76 // Used for then/whenDone callback and error test
79 final Function callback; 77 final Function callback;
80 // Used for error callbacks. 78 // Used for error callbacks.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 assert(handlesError); 124 assert(handlesError);
127 return _onError != null; 125 return _onError != null;
128 } 126 }
129 127
130 FutureOr<T> handleValue(S sourceResult) { 128 FutureOr<T> handleValue(S sourceResult) {
131 return _zone.runUnary<FutureOr<T>, S>(_onValue, sourceResult); 129 return _zone.runUnary<FutureOr<T>, S>(_onValue, sourceResult);
132 } 130 }
133 131
134 bool matchesErrorTest(AsyncError asyncError) { 132 bool matchesErrorTest(AsyncError asyncError) {
135 if (!hasErrorTest) return true; 133 if (!hasErrorTest) return true;
136 _FutureErrorTest test = _errorTest; 134 return _zone.runUnary<bool, Object>(_errorTest, asyncError.error);
137 return _zone.runUnary<bool, dynamic>(_errorTest, asyncError.error);
138 } 135 }
139 136
140 FutureOr<T> handleError(AsyncError asyncError) { 137 FutureOr<T> handleError(AsyncError asyncError) {
141 assert(handlesError && hasErrorCallback); 138 assert(handlesError && hasErrorCallback);
142 if (errorCallback is ZoneBinaryCallback) { 139 if (errorCallback is ZoneBinaryCallback) {
143 var typedErrorCallback = errorCallback as Object 140 var typedErrorCallback = errorCallback as Object
144 /*=ZoneBinaryCallback<FutureOr<T>, Object, StackTrace>*/; 141 /*=ZoneBinaryCallback<FutureOr<T>, Object, StackTrace>*/;
145 return _zone.runBinary( 142 return _zone.runBinary(
146 typedErrorCallback, asyncError.error, asyncError.stackTrace); 143 typedErrorCallback, asyncError.error, asyncError.stackTrace);
147 } else { 144 } else {
148 return _zone.runUnary<FutureOr<T>, dynamic>( 145 return _zone.runUnary<FutureOr<T>, Object>(
149 errorCallback, asyncError.error); 146 errorCallback, asyncError.error);
150 } 147 }
151 } 148 }
152 149
153 dynamic handleWhenComplete() { 150 dynamic handleWhenComplete() {
154 assert(!handlesError); 151 assert(!handlesError);
155 return _zone.run(_whenCompleteAction); 152 return _zone.run(_whenCompleteAction);
156 } 153 }
157 } 154 }
158 155
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 bool get _hasError => _state == _ERROR; 224 bool get _hasError => _state == _ERROR;
228 225
229 void _setChained(_Future source) { 226 void _setChained(_Future source) {
230 assert(_mayAddListener); 227 assert(_mayAddListener);
231 _state = _CHAINED; 228 _state = _CHAINED;
232 _resultOrListeners = source; 229 _resultOrListeners = source;
233 } 230 }
234 231
235 Future<E> then<E>(FutureOr<E> f(T value), {Function onError}) { 232 Future<E> then<E>(FutureOr<E> f(T value), {Function onError}) {
236 Zone currentZone = Zone.current; 233 Zone currentZone = Zone.current;
237 ZoneUnaryCallback registered;
238 if (!identical(currentZone, _ROOT_ZONE)) { 234 if (!identical(currentZone, _ROOT_ZONE)) {
239 f = currentZone.registerUnaryCallback<FutureOr<E>, T>(f); 235 f = currentZone.registerUnaryCallback<FutureOr<E>, T>(f);
240 if (onError != null) { 236 if (onError != null) {
241 onError = _registerErrorHandler<E>(onError, currentZone); 237 onError = _registerErrorHandler<E>(onError, currentZone);
242 } 238 }
243 } 239 }
244 return _thenNoZoneRegistration<E>(f, onError); 240 return _thenNoZoneRegistration<E>(f, onError);
245 } 241 }
246 242
247 // This method is used by async/await. 243 // This method is used by async/await.
248 Future<E> _thenNoZoneRegistration<E>(f(T value), Function onError) { 244 Future<E> _thenNoZoneRegistration<E>(
245 FutureOr<E> f(T value), Function onError) {
249 _Future<E> result = new _Future<E>(); 246 _Future<E> result = new _Future<E>();
250 _addListener(new _FutureListener<T, E>.then(result, f, onError)); 247 _addListener(new _FutureListener<T, E>.then(result, f, onError));
251 return result; 248 return result;
252 } 249 }
253 250
254 Future<T> catchError(Function onError, {bool test(error)}) { 251 Future<T> catchError(Function onError, {bool test(error)}) {
255 _Future<T> result = new _Future<T>(); 252 _Future<T> result = new _Future<T>();
256 if (!identical(result._zone, _ROOT_ZONE)) { 253 if (!identical(result._zone, _ROOT_ZONE)) {
257 onError = _registerErrorHandler<T>(onError, result._zone); 254 onError = _registerErrorHandler<T>(onError, result._zone);
258 if (test != null) test = result._zone.registerUnaryCallback(test); 255 if (test != null) test = result._zone.registerUnaryCallback(test);
259 } 256 }
260 _addListener(new _FutureListener<T, T>.catchError(result, onError, test)); 257 _addListener(new _FutureListener<T, T>.catchError(result, onError, test));
261 return result; 258 return result;
262 } 259 }
263 260
264 Future<T> whenComplete(action()) { 261 Future<T> whenComplete(dynamic action()) {
265 _Future<T> result = new _Future<T>(); 262 _Future<T> result = new _Future<T>();
266 if (!identical(result._zone, _ROOT_ZONE)) { 263 if (!identical(result._zone, _ROOT_ZONE)) {
267 action = result._zone.registerCallback<dynamic>(action); 264 action = result._zone.registerCallback<dynamic>(action);
268 } 265 }
269 _addListener(new _FutureListener<T, T>.whenComplete(result, action)); 266 _addListener(new _FutureListener<T, T>.whenComplete(result, action));
270 return result; 267 return result;
271 } 268 }
272 269
273 Stream<T> asStream() => new Stream<T>.fromFuture(this); 270 Stream<T> asStream() => new Stream<T>.fromFuture(this);
274 271
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 _FutureListener listeners = target._removeListeners(); 443 _FutureListener listeners = target._removeListeners();
447 target._cloneResult(source); 444 target._cloneResult(source);
448 _propagateToListeners(target, listeners); 445 _propagateToListeners(target, listeners);
449 } else { 446 } else {
450 _FutureListener listeners = target._resultOrListeners; 447 _FutureListener listeners = target._resultOrListeners;
451 target._setChained(source); 448 target._setChained(source);
452 source._prependListeners(listeners); 449 source._prependListeners(listeners);
453 } 450 }
454 } 451 }
455 452
456 void _complete(value) { 453 void _complete(FutureOr<T> value) {
457 assert(!_isComplete); 454 assert(!_isComplete);
458 if (value is Future) { 455 if (value is Future<T>) {
459 if (value is _Future) { 456 if (value is _Future<T>) {
460 _chainCoreFuture(value, this); 457 _chainCoreFuture(value, this);
461 } else { 458 } else {
462 _chainForeignFuture(value, this); 459 _chainForeignFuture(value, this);
463 } 460 }
464 } else { 461 } else {
465 _FutureListener listeners = _removeListeners(); 462 _FutureListener listeners = _removeListeners();
466 _setValue(value as Object/*=T*/); 463 _setValue(value as Object/*=T*/);
467 _propagateToListeners(this, listeners); 464 _propagateToListeners(this, listeners);
468 } 465 }
469 } 466 }
470 467
471 void _completeWithValue(T value) { 468 void _completeWithValue(T value) {
472 assert(!_isComplete); 469 assert(!_isComplete);
473 assert(value is! Future); 470 assert(value is! Future);
474 471
475 _FutureListener listeners = _removeListeners(); 472 _FutureListener listeners = _removeListeners();
476 _setValue(value); 473 _setValue(value);
477 _propagateToListeners(this, listeners); 474 _propagateToListeners(this, listeners);
478 } 475 }
479 476
480 void _completeError(error, [StackTrace stackTrace]) { 477 void _completeError(Object error, [StackTrace stackTrace]) {
481 assert(!_isComplete); 478 assert(!_isComplete);
482 479
483 _FutureListener listeners = _removeListeners(); 480 _FutureListener listeners = _removeListeners();
484 _setError(error, stackTrace); 481 _setError(error, stackTrace);
485 _propagateToListeners(this, listeners); 482 _propagateToListeners(this, listeners);
486 } 483 }
487 484
488 void _asyncComplete(value) { 485 void _asyncComplete(FutureOr<T> value) {
489 assert(!_isComplete); 486 assert(!_isComplete);
490 // Two corner cases if the value is a future: 487 // Two corner cases if the value is a future:
491 // 1. the future is already completed and an error. 488 // 1. the future is already completed and an error.
492 // 2. the future is not yet completed but might become an error. 489 // 2. the future is not yet completed but might become an error.
493 // The first case means that we must not immediately complete the Future, 490 // The first case means that we must not immediately complete the Future,
494 // as our code would immediately start propagating the error without 491 // as our code would immediately start propagating the error without
495 // giving the time to install error-handlers. 492 // giving the time to install error-handlers.
496 // However the second case requires us to deal with the value immediately. 493 // However the second case requires us to deal with the value immediately.
497 // Otherwise the value could complete with an error and report an 494 // Otherwise the value could complete with an error and report an
498 // unhandled error, even though we know we are already going to listen to 495 // unhandled error, even though we know we are already going to listen to
499 // it. 496 // it.
500 497
501 if (value is Future) { 498 if (value is Future<T>) {
502 // Assign to typed variables so we get earlier checks in checked mode. 499 if (value is _Future<T>) {
503 Future<T> typedFuture = value as Object/*=Future<T>*/; 500 if (value._hasError) {
504 if (typedFuture is _Future) {
505 _Future<T> coreFuture = typedFuture;
506 if (coreFuture._hasError) {
507 // Case 1 from above. Delay completion to enable the user to register 501 // Case 1 from above. Delay completion to enable the user to register
508 // callbacks. 502 // callbacks.
509 _setPendingComplete(); 503 _setPendingComplete();
510 _zone.scheduleMicrotask(() { 504 _zone.scheduleMicrotask(() {
511 _chainCoreFuture(coreFuture, this); 505 _chainCoreFuture(value, this);
512 }); 506 });
513 } else { 507 } else {
514 _chainCoreFuture(coreFuture, this); 508 _chainCoreFuture(value, this);
515 } 509 }
516 } else { 510 } else {
517 // Case 2 from above. Chain the future immediately. 511 // Case 2 from above. Chain the future immediately.
518 // Note that we are still completing asynchronously (through 512 // Note that we are still completing asynchronously (through
519 // _chainForeignFuture). 513 // _chainForeignFuture).
520 _chainForeignFuture(typedFuture, this); 514 _chainForeignFuture(value, this);
521 } 515 }
522 return; 516 return;
523 } 517 }
524 T typedValue = value as Object/*=T*/; 518 T typedValue = value as Object/*=T*/;
525 519
526 _setPendingComplete(); 520 _setPendingComplete();
527 _zone.scheduleMicrotask(() { 521 _zone.scheduleMicrotask(() {
528 _completeWithValue(typedValue); 522 _completeWithValue(typedValue);
529 }); 523 });
530 } 524 }
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 result._setValue(listenerValueOrError); 696 result._setValue(listenerValueOrError);
703 } else { 697 } else {
704 AsyncError asyncError = listenerValueOrError; 698 AsyncError asyncError = listenerValueOrError;
705 result._setErrorObject(asyncError); 699 result._setErrorObject(asyncError);
706 } 700 }
707 // Prepare for next round. 701 // Prepare for next round.
708 source = result; 702 source = result;
709 } 703 }
710 } 704 }
711 705
712 Future<T> timeout(Duration timeLimit, {onTimeout()}) { 706 Future<T> timeout(Duration timeLimit, {FutureOr<T> onTimeout()}) {
713 if (_isComplete) return new _Future.immediate(this); 707 if (_isComplete) return new _Future.immediate(this);
714 _Future<T> result = new _Future<T>(); 708 _Future<T> result = new _Future<T>();
715 Timer timer; 709 Timer timer;
716 if (onTimeout == null) { 710 if (onTimeout == null) {
717 timer = new Timer(timeLimit, () { 711 timer = new Timer(timeLimit, () {
718 result._completeError( 712 result._completeError(
719 new TimeoutException("Future not completed", timeLimit)); 713 new TimeoutException("Future not completed", timeLimit));
720 }); 714 });
721 } else { 715 } else {
722 Zone zone = Zone.current; 716 Zone zone = Zone.current;
(...skipping 13 matching lines...) Expand all
736 } 730 }
737 }, onError: (e, s) { 731 }, onError: (e, s) {
738 if (timer.isActive) { 732 if (timer.isActive) {
739 timer.cancel(); 733 timer.cancel();
740 result._completeError(e, s); 734 result._completeError(e, s);
741 } 735 }
742 }); 736 });
743 return result; 737 return result;
744 } 738 }
745 } 739 }
OLDNEW
« no previous file with comments | « sdk/lib/async/future.dart ('k') | sdk/lib/async/stream.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698