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

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

Issue 1966523003: Make _Future._chainForeignFuture not cause an assert. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Address comments Created 4 years, 7 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 | « no previous file | tests/lib/async/future_test.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 dynamic/*T|Future<T>*/ _FutureOnValue<S, T>(S value); 8 typedef dynamic/*T|Future<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(var error);
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 return result; 270 return result;
271 } 271 }
272 272
273 Stream<T> asStream() => new Stream<T>.fromFuture(this); 273 Stream<T> asStream() => new Stream<T>.fromFuture(this);
274 274
275 void _setPendingComplete() { 275 void _setPendingComplete() {
276 assert(_mayComplete); 276 assert(_mayComplete);
277 _state = _PENDING_COMPLETE; 277 _state = _PENDING_COMPLETE;
278 } 278 }
279 279
280 void _clearPendingComplete() {
281 assert(_isPendingComplete);
282 _state = _INCOMPLETE;
283 }
284
280 AsyncError get _error { 285 AsyncError get _error {
281 assert(_hasError); 286 assert(_hasError);
282 return _resultOrListeners; 287 return _resultOrListeners;
283 } 288 }
284 289
285 _Future get _chainSource { 290 _Future get _chainSource {
286 assert(_isChained); 291 assert(_isChained);
287 return _resultOrListeners; 292 return _resultOrListeners;
288 } 293 }
289 294
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 // in that case. 403 // in that case.
399 static void _chainForeignFuture(Future source, _Future target) { 404 static void _chainForeignFuture(Future source, _Future target) {
400 assert(!target._isComplete); 405 assert(!target._isComplete);
401 assert(source is! _Future); 406 assert(source is! _Future);
402 407
403 // Mark the target as chained (and as such half-completed). 408 // Mark the target as chained (and as such half-completed).
404 target._setPendingComplete(); 409 target._setPendingComplete();
405 try { 410 try {
406 source.then((value) { 411 source.then((value) {
407 assert(target._isPendingComplete); 412 assert(target._isPendingComplete);
408 target._completeWithValue(value); 413 // The "value" may be another future if the foreign future
414 // implementation is mis-behaving,
415 // so use _complete instead of _completeWithValue.
416 target._clearPendingComplete(); // Clear this first, it's set again.
417 target._complete(value);
409 }, 418 },
410 // TODO(floitsch): eventually we would like to make this non-optional 419 // TODO(floitsch): eventually we would like to make this non-optional
411 // and dependent on the listeners of the target future. If none of 420 // and dependent on the listeners of the target future. If none of
412 // the target future's listeners want to have the stack trace we don't 421 // the target future's listeners want to have the stack trace we don't
413 // need a trace. 422 // need a trace.
414 onError: (error, [stackTrace]) { 423 onError: (error, [stackTrace]) {
415 assert(target._isPendingComplete); 424 assert(target._isPendingComplete);
416 target._completeError(error, stackTrace); 425 target._completeError(error, stackTrace);
417 }); 426 });
418 } catch (e, s) { 427 } catch (e, s) {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 } catch (e, s) { 652 } catch (e, s) {
644 if (identical(source._error.error, e)) { 653 if (identical(source._error.error, e)) {
645 listenerValueOrError = source._error; 654 listenerValueOrError = source._error;
646 } else { 655 } else {
647 listenerValueOrError = new AsyncError(e, s); 656 listenerValueOrError = new AsyncError(e, s);
648 } 657 }
649 listenerHasError = true; 658 listenerHasError = true;
650 } 659 }
651 } 660 }
652 661
653 662
654 if (listener.handlesComplete) { 663 if (listener.handlesComplete) {
655 handleWhenCompleteCallback(); 664 handleWhenCompleteCallback();
656 } else if (!hasError) { 665 } else if (!hasError) {
657 if (listener.handlesValue) { 666 if (listener.handlesValue) {
658 handleValueCallback(); 667 handleValueCallback();
659 } 668 }
660 } else { 669 } else {
661 if (listener.handlesError) { 670 if (listener.handlesError) {
662 handleError(); 671 handleError();
663 } 672 }
664 } 673 }
665 674
666 // If we changed zone, oldZone will not be null. 675 // If we changed zone, oldZone will not be null.
667 if (oldZone != null) Zone._leave(oldZone); 676 if (oldZone != null) Zone._leave(oldZone);
668 677
669 // If the listener's value is a future we need to chain it. Note that 678 // If the listener's value is a future we need to chain it. Note that
670 // this can only happen if there is a callback. 679 // this can only happen if there is a callback.
671 if (listenerValueOrError is Future) { 680 if (listenerValueOrError is Future) {
672 Future chainSource = listenerValueOrError; 681 Future chainSource = listenerValueOrError;
673 // Shortcut if the chain-source is already completed. Just continue 682 // Shortcut if the chain-source is already completed. Just continue
674 // the loop. 683 // the loop.
675 _Future result = listener.result; 684 _Future result = listener.result;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 } 737 }
729 }, onError: (e, s) { 738 }, onError: (e, s) {
730 if (timer.isActive) { 739 if (timer.isActive) {
731 timer.cancel(); 740 timer.cancel();
732 result._completeError(e, s); 741 result._completeError(e, s);
733 } 742 }
734 }); 743 });
735 return result; 744 return result;
736 } 745 }
737 } 746 }
OLDNEW
« no previous file with comments | « no previous file | tests/lib/async/future_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698