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

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/lib/async/future_impl.dart

Issue 2647833002: fix #28008, fix #28009 implement FutureOr<T> (Closed)
Patch Set: Merge remote-tracking branch 'origin/master' into 28008_futureort Created 3 years, 11 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
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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 121
122 /// Whether this listener has an error callback. 122 /// Whether this listener has an error callback.
123 /// 123 ///
124 /// This function must only be called if the listener [handlesError]. 124 /// This function must only be called if the listener [handlesError].
125 bool get hasErrorCallback { 125 bool get hasErrorCallback {
126 assert(handlesError); 126 assert(handlesError);
127 return _onError != null; 127 return _onError != null;
128 } 128 }
129 129
130 dynamic/*T|Future<T>*/ handleValue(S sourceResult) { 130 dynamic/*T|Future<T>*/ handleValue(S sourceResult) {
131 return _zone.runUnary/*<dynamic/*T|Future<T>*/, S>*/( 131 return _zone.runUnary<dynamic/*T|Future<T>*/, S>(
132 _onValue, sourceResult); 132 _onValue, sourceResult);
133 } 133 }
134 134
135 bool matchesErrorTest(AsyncError asyncError) { 135 bool matchesErrorTest(AsyncError asyncError) {
136 if (!hasErrorTest) return true; 136 if (!hasErrorTest) return true;
137 _FutureErrorTest test = _errorTest; 137 _FutureErrorTest test = _errorTest;
138 return _zone.runUnary/*<bool, dynamic>*/(_errorTest, asyncError.error); 138 return _zone.runUnary<bool, dynamic>(_errorTest, asyncError.error);
139 } 139 }
140 140
141 dynamic/*T|Future<T>*/ handleError(AsyncError asyncError) { 141 dynamic/*T|Future<T>*/ handleError(AsyncError asyncError) {
142 assert(handlesError && hasErrorCallback); 142 assert(handlesError && hasErrorCallback);
143 if (errorCallback is ZoneBinaryCallback) { 143 if (errorCallback is ZoneBinaryCallback) {
144 var typedErrorCallback = errorCallback as Object 144 var typedErrorCallback = errorCallback as Object
145 /*=ZoneBinaryCallback<Object/*T|Future<T>*/, Object, StackTrace>*/; 145 /*=ZoneBinaryCallback<Object/*T|Future<T>*/, Object, StackTrace>*/;
146 return _zone.runBinary(typedErrorCallback, 146 return _zone.runBinary(typedErrorCallback,
147 asyncError.error, 147 asyncError.error,
148 asyncError.stackTrace); 148 asyncError.stackTrace);
149 } else { 149 } else {
150 return _zone.runUnary/*<dynamic/*T|Future<T>*/, dynamic>*/( 150 return _zone.runUnary<dynamic/*T|Future<T>*/, dynamic>(
151 errorCallback, asyncError.error); 151 errorCallback, asyncError.error);
152 } 152 }
153 } 153 }
154 154
155 dynamic handleWhenComplete() { 155 dynamic handleWhenComplete() {
156 assert(!handlesError); 156 assert(!handlesError);
157 return _zone.run(_whenCompleteAction); 157 return _zone.run(_whenCompleteAction);
158 } 158 }
159 } 159 }
160 160
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 bool get _isChained => _state == _CHAINED; 223 bool get _isChained => _state == _CHAINED;
224 bool get _isComplete => _state >= _VALUE; 224 bool get _isComplete => _state >= _VALUE;
225 bool get _hasError => _state == _ERROR; 225 bool get _hasError => _state == _ERROR;
226 226
227 void _setChained(_Future source) { 227 void _setChained(_Future source) {
228 assert(_mayAddListener); 228 assert(_mayAddListener);
229 _state = _CHAINED; 229 _state = _CHAINED;
230 _resultOrListeners = source; 230 _resultOrListeners = source;
231 } 231 }
232 232
233 Future/*<E>*/ then/*<E>*/( 233 Future<E> then<E>(
234 /*=dynamic/*E|Future<E>*/*/ f(T value), { Function onError }) { 234 FutureOr<E> f(T value), { Function onError }) {
235 Zone currentZone = Zone.current; 235 Zone currentZone = Zone.current;
236 ZoneUnaryCallback registered; 236 ZoneUnaryCallback registered;
237 if (!identical(currentZone, _ROOT_ZONE)) { 237 if (!identical(currentZone, _ROOT_ZONE)) {
238 f = currentZone.registerUnaryCallback/*<dynamic, T>*/(f); 238 f = currentZone.registerUnaryCallback<FutureOr<E>, T>(f);
239 if (onError != null) { 239 if (onError != null) {
240 onError = _registerErrorHandler/*<T>*/(onError, currentZone); 240 onError = _registerErrorHandler<T>(onError, currentZone);
241 } 241 }
242 } 242 }
243 return _thenNoZoneRegistration/*<E>*/(f, onError); 243 return _thenNoZoneRegistration<E>(f, onError);
244 } 244 }
245 245
246 // This method is used by async/await. 246 // This method is used by async/await.
247 Future/*<E>*/ _thenNoZoneRegistration/*<E>*/(f(T value), Function onError) { 247 Future<E> _thenNoZoneRegistration<E>(f(T value), Function onError) {
248 _Future/*<E>*/ result = new _Future/*<E>*/(); 248 _Future<E> result = new _Future<E>();
249 _addListener(new _FutureListener/*<T, E>*/.then(result, f, onError)); 249 _addListener(new _FutureListener<T, E>.then(result, f, onError));
250 return result; 250 return result;
251 } 251 }
252 252
253 Future/*<T>*/ catchError(Function onError, { bool test(error) }) { 253 Future<T> catchError(Function onError, { bool test(error) }) {
254 _Future/*<T>*/ result = new _Future/*<T>*/(); 254 _Future<T> result = new _Future<T>();
255 if (!identical(result._zone, _ROOT_ZONE)) { 255 if (!identical(result._zone, _ROOT_ZONE)) {
256 onError = _registerErrorHandler/*<T>*/(onError, result._zone); 256 onError = _registerErrorHandler<T>(onError, result._zone);
257 if (test != null) test = result._zone.registerUnaryCallback(test); 257 if (test != null) test = result._zone.registerUnaryCallback(test);
258 } 258 }
259 _addListener(new _FutureListener/*<T, T>*/.catchError( 259 _addListener(new _FutureListener<T, T>.catchError(
260 result, onError, test)); 260 result, onError, test));
261 return result; 261 return result;
262 } 262 }
263 263
264 Future<T> whenComplete(action()) { 264 Future<T> whenComplete(action()) {
265 _Future<T> result = new _Future<T>(); 265 _Future<T> result = new _Future<T>();
266 if (!identical(result._zone, _ROOT_ZONE)) { 266 if (!identical(result._zone, _ROOT_ZONE)) {
267 action = result._zone.registerCallback/*<dynamic>*/(action); 267 action = result._zone.registerCallback<dynamic>(action);
268 } 268 }
269 _addListener(new _FutureListener/*<T, T>*/.whenComplete(result, action)); 269 _addListener(new _FutureListener<T, T>.whenComplete(result, action));
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 | « pkg/dev_compiler/tool/input_sdk/lib/async/future.dart ('k') | pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698