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

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

Issue 2456803004: fixes #27586, prefer context type in generic inference (Closed)
Patch Set: fix Created 3 years, 10 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 FutureOr<E> f(T value), { Function onError }) { 234 /*=dynamic/*E|Future<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<FutureOr<E>, T>(f); 238 f = currentZone.registerUnaryCallback/*<dynamic, 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
285 AsyncError get _error { 280 AsyncError get _error {
286 assert(_hasError); 281 assert(_hasError);
287 return _resultOrListeners; 282 return _resultOrListeners;
288 } 283 }
289 284
290 _Future get _chainSource { 285 _Future get _chainSource {
291 assert(_isChained); 286 assert(_isChained);
292 return _resultOrListeners; 287 return _resultOrListeners;
293 } 288 }
294 289
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 // in that case. 398 // in that case.
404 static void _chainForeignFuture(Future source, _Future target) { 399 static void _chainForeignFuture(Future source, _Future target) {
405 assert(!target._isComplete); 400 assert(!target._isComplete);
406 assert(source is! _Future); 401 assert(source is! _Future);
407 402
408 // Mark the target as chained (and as such half-completed). 403 // Mark the target as chained (and as such half-completed).
409 target._setPendingComplete(); 404 target._setPendingComplete();
410 try { 405 try {
411 source.then((value) { 406 source.then((value) {
412 assert(target._isPendingComplete); 407 assert(target._isPendingComplete);
413 // The "value" may be another future if the foreign future 408 target._completeWithValue(value);
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);
418 }, 409 },
419 // TODO(floitsch): eventually we would like to make this non-optional 410 // TODO(floitsch): eventually we would like to make this non-optional
420 // and dependent on the listeners of the target future. If none of 411 // and dependent on the listeners of the target future. If none of
421 // the target future's listeners want to have the stack trace we don't 412 // the target future's listeners want to have the stack trace we don't
422 // need a trace. 413 // need a trace.
423 onError: (error, [stackTrace]) { 414 onError: (error, [stackTrace]) {
424 assert(target._isPendingComplete); 415 assert(target._isPendingComplete);
425 target._completeError(error, stackTrace); 416 target._completeError(error, stackTrace);
426 }); 417 });
427 } catch (e, s) { 418 } catch (e, s) {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 } catch (e, s) { 643 } catch (e, s) {
653 if (identical(source._error.error, e)) { 644 if (identical(source._error.error, e)) {
654 listenerValueOrError = source._error; 645 listenerValueOrError = source._error;
655 } else { 646 } else {
656 listenerValueOrError = new AsyncError(e, s); 647 listenerValueOrError = new AsyncError(e, s);
657 } 648 }
658 listenerHasError = true; 649 listenerHasError = true;
659 } 650 }
660 } 651 }
661 652
662 653
663 if (listener.handlesComplete) { 654 if (listener.handlesComplete) {
664 handleWhenCompleteCallback(); 655 handleWhenCompleteCallback();
665 } else if (!hasError) { 656 } else if (!hasError) {
666 if (listener.handlesValue) { 657 if (listener.handlesValue) {
667 handleValueCallback(); 658 handleValueCallback();
668 } 659 }
669 } else { 660 } else {
670 if (listener.handlesError) { 661 if (listener.handlesError) {
671 handleError(); 662 handleError();
672 } 663 }
673 } 664 }
674 665
675 // If we changed zone, oldZone will not be null. 666 // If we changed zone, oldZone will not be null.
676 if (oldZone != null) Zone._leave(oldZone); 667 if (oldZone != null) Zone._leave(oldZone);
677 668
678 // If the listener's value is a future we need to chain it. Note that 669 // If the listener's value is a future we need to chain it. Note that
679 // this can only happen if there is a callback. 670 // this can only happen if there is a callback.
680 if (listenerValueOrError is Future) { 671 if (listenerValueOrError is Future) {
681 Future chainSource = listenerValueOrError; 672 Future chainSource = listenerValueOrError;
682 // Shortcut if the chain-source is already completed. Just continue 673 // Shortcut if the chain-source is already completed. Just continue
683 // the loop. 674 // the loop.
684 _Future result = listener.result; 675 _Future result = listener.result;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 } 728 }
738 }, onError: (e, s) { 729 }, onError: (e, s) {
739 if (timer.isActive) { 730 if (timer.isActive) {
740 timer.cancel(); 731 timer.cancel();
741 result._completeError(e, s); 732 result._completeError(e, s);
742 } 733 }
743 }); 734 });
744 return result; 735 return result;
745 } 736 }
746 } 737 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698