OLD | NEW |
| (Empty) |
1 part of dart.async; | |
2 typedef dynamic _FutureOnValue<T>(T value); | |
3 typedef bool _FutureErrorTest(var error); | |
4 typedef _FutureAction(); | |
5 abstract class _Completer<T> implements Completer<T> {final _Future<T> future =
new _Future<T>(); | |
6 void complete([value]); | |
7 void completeError(Object error, [StackTrace stackTrace]) { | |
8 error = _nonNullError(error); | |
9 if (!future._mayComplete) throw new StateError("Future already completed"); | |
10 AsyncError replacement = Zone.current.errorCallback(error, stackTrace); | |
11 if (replacement != null) { | |
12 error = _nonNullError(replacement.error); | |
13 stackTrace = replacement.stackTrace; | |
14 } | |
15 _completeError(error, stackTrace); | |
16 } | |
17 void _completeError(Object error, StackTrace stackTrace); | |
18 bool get isCompleted => !future._mayComplete; | |
19 } | |
20 class _AsyncCompleter<T> extends _Completer<T> {void complete([value]) { | |
21 if (!future._mayComplete) throw new StateError("Future already completed"); | |
22 future._asyncComplete(value); | |
23 } | |
24 void _completeError(Object error, StackTrace stackTrace) { | |
25 future._asyncCompleteError(error, stackTrace); | |
26 } | |
27 } | |
28 class _SyncCompleter<T> extends _Completer<T> {void complete([value]) { | |
29 if (!future._mayComplete) throw new StateError("Future already completed"); | |
30 future._complete(value); | |
31 } | |
32 void _completeError(Object error, StackTrace stackTrace) { | |
33 future._completeError(error, stackTrace); | |
34 } | |
35 } | |
36 class _FutureListener {static const int MASK_VALUE = 1; | |
37 static const int MASK_ERROR = 2; | |
38 static const int MASK_TEST_ERROR = 4; | |
39 static const int MASK_WHENCOMPLETE = 8; | |
40 static const int STATE_CHAIN = 0; | |
41 static const int STATE_THEN = MASK_VALUE; | |
42 static const int STATE_THEN_ONERROR = MASK_VALUE | MASK_ERROR; | |
43 static const int STATE_CATCHERROR = MASK_ERROR; | |
44 static const int STATE_CATCHERROR_TEST = MASK_ERROR | MASK_TEST_ERROR; | |
45 static const int STATE_WHENCOMPLETE = MASK_WHENCOMPLETE; | |
46 _FutureListener _nextListener = null; | |
47 final _Future result; | |
48 final int state; | |
49 final Function callback; | |
50 final Function errorCallback; | |
51 _FutureListener.then(this.result, _FutureOnValue onValue, Function errorCallbac
k) : callback = onValue, errorCallback = errorCallback, state = (errorCallback =
= null) ? STATE_THEN : STATE_THEN_ONERROR; | |
52 _FutureListener.catchError(this.result, this.errorCallback, _FutureErrorTest te
st) : callback = test, state = (test == null) ? STATE_CATCHERROR : STATE_CATCHER
ROR_TEST; | |
53 _FutureListener.whenComplete(this.result, _FutureAction onComplete) : callback
= onComplete, errorCallback = null, state = STATE_WHENCOMPLETE; | |
54 _FutureListener.chain(this.result) : callback = null, errorCallback = null, sta
te = STATE_CHAIN; | |
55 Zone get _zone => result._zone; | |
56 bool get handlesValue => (state & MASK_VALUE != 0); | |
57 bool get handlesError => (state & MASK_ERROR != 0); | |
58 bool get hasErrorTest => (state == STATE_CATCHERROR_TEST); | |
59 bool get handlesComplete => (state == STATE_WHENCOMPLETE); | |
60 _FutureOnValue get _onValue { | |
61 assert (handlesValue); return DEVC$RT.cast(callback, Function, DEVC$RT.type((_Fu
tureOnValue<dynamic> _) { | |
62 } | |
63 ), "ImplicitCast", """line 112, column 12 of dart:async/future_impl.dart: """, c
allback is _FutureOnValue<dynamic>, true); | |
64 } | |
65 Function get _onError => errorCallback; | |
66 _FutureErrorTest get _errorTest { | |
67 assert (hasErrorTest); return DEVC$RT.cast(callback, Function, _FutureErrorTest,
"CompositeCast", """line 117, column 12 of dart:async/future_impl.dart: """, ca
llback is _FutureErrorTest, false); | |
68 } | |
69 _FutureAction get _whenCompleteAction { | |
70 assert (handlesComplete); return DEVC$RT.cast(callback, Function, _FutureAction,
"ImplicitCast", """line 121, column 12 of dart:async/future_impl.dart: """, cal
lback is _FutureAction, true); | |
71 } | |
72 } | |
73 class _Future<T> implements Future<T> {static const int _INCOMPLETE = 0; | |
74 static const int _PENDING_COMPLETE = 1; | |
75 static const int _CHAINED = 2; | |
76 static const int _VALUE = 4; | |
77 static const int _ERROR = 8; | |
78 int _state = _INCOMPLETE; | |
79 final Zone _zone = Zone.current; | |
80 var _resultOrListeners; | |
81 _Future(); | |
82 _Future.immediate(value) { | |
83 _asyncComplete(value); | |
84 } | |
85 _Future.immediateError(var error, [StackTrace stackTrace]) { | |
86 _asyncCompleteError(error, stackTrace); | |
87 } | |
88 bool get _mayComplete => _state == _INCOMPLETE; | |
89 bool get _isChained => _state == _CHAINED; | |
90 bool get _isComplete => _state >= _VALUE; | |
91 bool get _hasValue => _state == _VALUE; | |
92 bool get _hasError => _state == _ERROR; | |
93 set _isChained(bool value) { | |
94 if (value) { | |
95 assert (!_isComplete); _state = _CHAINED; | |
96 } | |
97 else { | |
98 assert (_isChained); _state = _INCOMPLETE; | |
99 } | |
100 } | |
101 Future then(f(T value), { | |
102 Function onError} | |
103 ) { | |
104 _Future result = new _Future(); | |
105 if (!identical(result._zone, _ROOT_ZONE)) { | |
106 f = ((__x12) => DEVC$RT.cast(__x12, ZoneUnaryCallback, DEVC$RT.type((__CastType1
0<T> _) { | |
107 } | |
108 ), "CompositeCast", """line 208, column 11 of dart:async/future_impl.dart: """,
__x12 is __CastType10<T>, false))(result._zone.registerUnaryCallback(f)); | |
109 if (onError != null) { | |
110 onError = _registerErrorHandler(onError, result._zone); | |
111 } | |
112 } | |
113 _addListener(new _FutureListener.then(result, f, onError)); | |
114 return result; | |
115 } | |
116 Future catchError(Function onError, { | |
117 bool test(error)} | |
118 ) { | |
119 _Future result = new _Future(); | |
120 if (!identical(result._zone, _ROOT_ZONE)) { | |
121 onError = _registerErrorHandler(onError, result._zone); | |
122 if (test != null) test = ((__x15) => DEVC$RT.cast(__x15, ZoneUnaryCallback, __C
astType13, "CompositeCast", """line 221, column 32 of dart:async/future_impl.dar
t: """, __x15 is __CastType13, false))(result._zone.registerUnaryCallback(test))
; | |
123 } | |
124 _addListener(new _FutureListener.catchError(result, onError, test)); | |
125 return result; | |
126 } | |
127 Future<T> whenComplete(action()) { | |
128 _Future result = new _Future<T>(); | |
129 if (!identical(result._zone, _ROOT_ZONE)) { | |
130 action = result._zone.registerCallback(action); | |
131 } | |
132 _addListener(new _FutureListener.whenComplete(result, action)); | |
133 return DEVC$RT.cast(result, DEVC$RT.type((_Future<dynamic> _) { | |
134 } | |
135 ), DEVC$RT.type((Future<T> _) { | |
136 } | |
137 ), "CompositeCast", """line 233, column 12 of dart:async/future_impl.dart: """,
result is Future<T>, false); | |
138 } | |
139 Stream<T> asStream() => new Stream<T>.fromFuture(this); | |
140 void _markPendingCompletion() { | |
141 if (!_mayComplete) throw new StateError("Future already completed"); | |
142 _state = _PENDING_COMPLETE; | |
143 } | |
144 T get _value { | |
145 assert (_isComplete && _hasValue); return DEVC$RT.cast(_resultOrListeners, dynam
ic, T, "CompositeCast", """line 245, column 12 of dart:async/future_impl.dart: "
"", _resultOrListeners is T, false); | |
146 } | |
147 AsyncError get _error { | |
148 assert (_isComplete && _hasError); return DEVC$RT.cast(_resultOrListeners, dynam
ic, AsyncError, "DynamicCast", """line 250, column 12 of dart:async/future_impl.
dart: """, _resultOrListeners is AsyncError, true); | |
149 } | |
150 void _setValue(T value) { | |
151 assert (!_isComplete); _state = _VALUE; | |
152 _resultOrListeners = value; | |
153 } | |
154 void _setErrorObject(AsyncError error) { | |
155 assert (!_isComplete); _state = _ERROR; | |
156 _resultOrListeners = error; | |
157 } | |
158 void _setError(Object error, StackTrace stackTrace) { | |
159 _setErrorObject(new AsyncError(error, stackTrace)); | |
160 } | |
161 void _addListener(_FutureListener listener) { | |
162 assert (listener._nextListener == null); if (_isComplete) { | |
163 _zone.scheduleMicrotask(() { | |
164 _propagateToListeners(this, listener); | |
165 } | |
166 ); | |
167 } | |
168 else { | |
169 listener._nextListener = DEVC$RT.cast(_resultOrListeners, dynamic, _FutureListen
er, "DynamicCast", """line 277, column 32 of dart:async/future_impl.dart: """, _
resultOrListeners is _FutureListener, true); | |
170 _resultOrListeners = listener; | |
171 } | |
172 } | |
173 _FutureListener _removeListeners() { | |
174 assert (!_isComplete); _FutureListener current = DEVC$RT.cast(_resultOrListeners
, dynamic, _FutureListener, "DynamicCast", """line 286, column 31 of dart:async/
future_impl.dart: """, _resultOrListeners is _FutureListener, true); | |
175 _resultOrListeners = null; | |
176 _FutureListener prev = null; | |
177 while (current != null) { | |
178 _FutureListener next = current._nextListener; | |
179 current._nextListener = prev; | |
180 prev = current; | |
181 current = next; | |
182 } | |
183 return prev; | |
184 } | |
185 static void _chainForeignFuture(Future source, _Future target) { | |
186 assert (!target._isComplete); assert (source is! _Future); target._isChained = t
rue; | |
187 source.then((value) { | |
188 assert (target._isChained); target._completeWithValue(value); | |
189 } | |
190 , onError: (error, [stackTrace]) { | |
191 assert (target._isChained); target._completeError(error, DEVC$RT.cast(stackTrace
, dynamic, StackTrace, "DynamicCast", """line 317, column 38 of dart:async/futur
e_impl.dart: """, stackTrace is StackTrace, true)); | |
192 } | |
193 ); | |
194 } | |
195 static void _chainCoreFuture(_Future source, _Future target) { | |
196 assert (!target._isComplete); assert (source is _Future); target._isChained = tr
ue; | |
197 _FutureListener listener = new _FutureListener.chain(target); | |
198 if (source._isComplete) { | |
199 _propagateToListeners(source, listener); | |
200 } | |
201 else { | |
202 source._addListener(listener); | |
203 } | |
204 } | |
205 void _complete(value) { | |
206 assert (!_isComplete); if (value is Future) { | |
207 if (value is _Future) { | |
208 _chainCoreFuture(DEVC$RT.cast(value, dynamic, DEVC$RT.type((_Future<dynamic> _)
{ | |
209 } | |
210 ), "DynamicCast", """line 341, column 26 of dart:async/future_impl.dart: """, va
lue is _Future<dynamic>, true), this); | |
211 } | |
212 else { | |
213 _chainForeignFuture(DEVC$RT.cast(value, dynamic, DEVC$RT.type((Future<dynamic> _
) { | |
214 } | |
215 ), "DynamicCast", """line 343, column 29 of dart:async/future_impl.dart: """, va
lue is Future<dynamic>, true), this); | |
216 } | |
217 } | |
218 else { | |
219 _FutureListener listeners = _removeListeners(); | |
220 _setValue(DEVC$RT.cast(value, dynamic, T, "CompositeCast", """line 347, column
17 of dart:async/future_impl.dart: """, value is T, false)); | |
221 _propagateToListeners(this, listeners); | |
222 } | |
223 } | |
224 void _completeWithValue(value) { | |
225 assert (!_isComplete); assert (value is! Future); _FutureListener listeners = _r
emoveListeners(); | |
226 _setValue(DEVC$RT.cast(value, dynamic, T, "CompositeCast", """line 357, column
15 of dart:async/future_impl.dart: """, value is T, false)); | |
227 _propagateToListeners(this, listeners); | |
228 } | |
229 void _completeError(error, [StackTrace stackTrace]) { | |
230 assert (!_isComplete); _FutureListener listeners = _removeListeners(); | |
231 _setError(error, stackTrace); | |
232 _propagateToListeners(this, listeners); | |
233 } | |
234 void _asyncComplete(value) { | |
235 assert (!_isComplete); if (value == null) { | |
236 } | |
237 else if (value is Future) { | |
238 Future<T> typedFuture = DEVC$RT.cast(value, dynamic, DEVC$RT.type((Future<T> _)
{ | |
239 } | |
240 ), "CompositeCast", """line 386, column 31 of dart:async/future_impl.dart: """,
value is Future<T>, false); | |
241 if (typedFuture is _Future) { | |
242 _Future<T> coreFuture = DEVC$RT.cast(typedFuture, DEVC$RT.type((Future<T> _) { | |
243 } | |
244 ), DEVC$RT.type((_Future<T> _) { | |
245 } | |
246 ), "CompositeCast", """line 388, column 33 of dart:async/future_impl.dart: """,
typedFuture is _Future<T>, false); | |
247 if (coreFuture._isComplete && coreFuture._hasError) { | |
248 _markPendingCompletion(); | |
249 _zone.scheduleMicrotask(() { | |
250 _chainCoreFuture(coreFuture, this); | |
251 } | |
252 ); | |
253 } | |
254 else { | |
255 _chainCoreFuture(coreFuture, this); | |
256 } | |
257 } | |
258 else { | |
259 _chainForeignFuture(typedFuture, this); | |
260 } | |
261 return;} | |
262 else { | |
263 T typedValue = DEVC$RT.cast(value, dynamic, T, "CompositeCast", """line 407, col
umn 22 of dart:async/future_impl.dart: """, value is T, false); | |
264 } | |
265 _markPendingCompletion(); | |
266 _zone.scheduleMicrotask(() { | |
267 _completeWithValue(value); | |
268 } | |
269 ); | |
270 } | |
271 void _asyncCompleteError(error, StackTrace stackTrace) { | |
272 assert (!_isComplete); _markPendingCompletion(); | |
273 _zone.scheduleMicrotask(() { | |
274 _completeError(error, stackTrace); | |
275 } | |
276 ); | |
277 } | |
278 static void _propagateToListeners(_Future source, _FutureListener listeners) { | |
279 while (true) { | |
280 assert (source._isComplete); bool hasError = source._hasError; | |
281 if (listeners == null) { | |
282 if (hasError) { | |
283 AsyncError asyncError = source._error; | |
284 source._zone.handleUncaughtError(asyncError.error, asyncError.stackTrace); | |
285 } | |
286 return;} | |
287 while (listeners._nextListener != null) { | |
288 _FutureListener listener = listeners; | |
289 listeners = listener._nextListener; | |
290 listener._nextListener = null; | |
291 _propagateToListeners(source, listener); | |
292 } | |
293 _FutureListener listener = listeners; | |
294 bool listenerHasValue = true; | |
295 final sourceValue = hasError ? null : source._value; | |
296 var listenerValueOrError = sourceValue; | |
297 bool isPropagationAborted = false; | |
298 if (hasError || (listener.handlesValue || listener.handlesComplete)) { | |
299 Zone zone = listener._zone; | |
300 if (hasError && !source._zone.inSameErrorZone(zone)) { | |
301 AsyncError asyncError = source._error; | |
302 source._zone.handleUncaughtError(asyncError.error, asyncError.stackTrace); | |
303 return;} | |
304 Zone oldZone; | |
305 if (!identical(Zone.current, zone)) { | |
306 oldZone = Zone._enter(zone); | |
307 } | |
308 bool handleValueCallback() { | |
309 try { | |
310 listenerValueOrError = zone.runUnary(listener._onValue, sourceValue); | |
311 return true; | |
312 } | |
313 catch (e, s) { | |
314 listenerValueOrError = new AsyncError(e, s); | |
315 return false; | |
316 } | |
317 } | |
318 void handleError() { | |
319 AsyncError asyncError = source._error; | |
320 bool matchesTest = true; | |
321 if (listener.hasErrorTest) { | |
322 _FutureErrorTest test = listener._errorTest; | |
323 try { | |
324 matchesTest = ((__x16) => DEVC$RT.cast(__x16, dynamic, bool, "DynamicCast",
"""line 499, column 29 of dart:async/future_impl.dart: """, __x16 is bool, true)
)(zone.runUnary(test, asyncError.error)); | |
325 } | |
326 catch (e, s) { | |
327 listenerValueOrError = identical(asyncError.error, e) ? asyncError : new Asy
ncError(e, s); | |
328 listenerHasValue = false; | |
329 return;} | |
330 } | |
331 Function errorCallback = listener._onError; | |
332 if (matchesTest && errorCallback != null) { | |
333 try { | |
334 if (errorCallback is ZoneBinaryCallback) { | |
335 listenerValueOrError = zone.runBinary(errorCallback, asyncError.error, asy
ncError.stackTrace); | |
336 } | |
337 else { | |
338 listenerValueOrError = zone.runUnary(DEVC$RT.cast(errorCallback, Function,
__CastType17, "ImplicitCast", """line 515, column 54 of dart:async/future_impl.
dart: """, errorCallback is __CastType17, true), asyncError.error); | |
339 } | |
340 } | |
341 catch (e, s) { | |
342 listenerValueOrError = identical(asyncError.error, e) ? asyncError : new Asy
ncError(e, s); | |
343 listenerHasValue = false; | |
344 return;} | |
345 listenerHasValue = true; | |
346 } | |
347 else { | |
348 listenerValueOrError = asyncError; | |
349 listenerHasValue = false; | |
350 } | |
351 } | |
352 void handleWhenCompleteCallback() { | |
353 var completeResult; | |
354 try { | |
355 completeResult = zone.run(listener._whenCompleteAction); | |
356 } | |
357 catch (e, s) { | |
358 if (hasError && identical(source._error.error, e)) { | |
359 listenerValueOrError = source._error; | |
360 } | |
361 else { | |
362 listenerValueOrError = new AsyncError(e, s); | |
363 } | |
364 listenerHasValue = false; | |
365 return;} | |
366 if (completeResult is Future) { | |
367 _Future result = listener.result; | |
368 result._isChained = true; | |
369 isPropagationAborted = true; | |
370 completeResult.then((ignored) { | |
371 _propagateToListeners(source, new _FutureListener.chain(result)); | |
372 } | |
373 , onError: (error, [stackTrace]) { | |
374 if (completeResult is! _Future) { | |
375 completeResult = new _Future(); | |
376 completeResult._setError(error, stackTrace); | |
377 } | |
378 _propagateToListeners(DEVC$RT.cast(completeResult, dynamic, DEVC$RT.type((_
Future<dynamic> _) { | |
379 } | |
380 ), "DynamicCast", """line 559, column 37 of dart:async/future_impl.dart: """
, completeResult is _Future<dynamic>, true), new _FutureListener.chain(result)); | |
381 } | |
382 ); | |
383 } | |
384 } | |
385 if (!hasError) { | |
386 if (listener.handlesValue) { | |
387 listenerHasValue = handleValueCallback(); | |
388 } | |
389 } | |
390 else { | |
391 handleError(); | |
392 } | |
393 if (listener.handlesComplete) { | |
394 handleWhenCompleteCallback(); | |
395 } | |
396 if (oldZone != null) Zone._leave(oldZone); | |
397 if (isPropagationAborted) return; if (listenerHasValue && !identical(sourceValu
e, listenerValueOrError) && listenerValueOrError is Future) { | |
398 Future chainSource = DEVC$RT.cast(listenerValueOrError, dynamic, DEVC$RT.type((F
uture<dynamic> _) { | |
399 } | |
400 ), "DynamicCast", """line 585, column 32 of dart:async/future_impl.dart: """, li
stenerValueOrError is Future<dynamic>, true); | |
401 _Future result = listener.result; | |
402 if (chainSource is _Future) { | |
403 if (chainSource._isComplete) { | |
404 result._isChained = true; | |
405 source = chainSource; | |
406 listeners = new _FutureListener.chain(result); | |
407 continue; | |
408 } | |
409 else { | |
410 _chainCoreFuture(chainSource, result); | |
411 } | |
412 } | |
413 else { | |
414 _chainForeignFuture(chainSource, result); | |
415 } | |
416 return;} | |
417 } | |
418 _Future result = listener.result; | |
419 listeners = result._removeListeners(); | |
420 if (listenerHasValue) { | |
421 result._setValue(listenerValueOrError); | |
422 } | |
423 else { | |
424 AsyncError asyncError = DEVC$RT.cast(listenerValueOrError, dynamic, AsyncError,
"DynamicCast", """line 610, column 33 of dart:async/future_impl.dart: """, liste
nerValueOrError is AsyncError, true); | |
425 result._setErrorObject(asyncError); | |
426 } | |
427 source = result; | |
428 } | |
429 } | |
430 Future timeout(Duration timeLimit, { | |
431 onTimeout()} | |
432 ) { | |
433 if (_isComplete) return new _Future.immediate(this); | |
434 _Future result = new _Future(); | |
435 Timer timer; | |
436 if (onTimeout == null) { | |
437 timer = new Timer(timeLimit, () { | |
438 result._completeError(new TimeoutException("Future not completed", timeLimit)); | |
439 } | |
440 ); | |
441 } | |
442 else { | |
443 Zone zone = Zone.current; | |
444 onTimeout = zone.registerCallback(onTimeout); | |
445 timer = new Timer(timeLimit, () { | |
446 try { | |
447 result._complete(zone.run(onTimeout)); | |
448 } | |
449 catch (e, s) { | |
450 result._completeError(e, s); | |
451 } | |
452 } | |
453 ); | |
454 } | |
455 this.then((T v) { | |
456 if (timer.isActive) { | |
457 timer.cancel(); | |
458 result._completeWithValue(v); | |
459 } | |
460 } | |
461 , onError: (e, s) { | |
462 if (timer.isActive) { | |
463 timer.cancel(); | |
464 result._completeError(e, DEVC$RT.cast(s, dynamic, StackTrace, "DynamicCast", ""
"line 646, column 34 of dart:async/future_impl.dart: """, s is StackTrace, true)
); | |
465 } | |
466 } | |
467 ); | |
468 return result; | |
469 } | |
470 } | |
471 typedef dynamic __CastType10<T>(T __u11); | |
472 typedef bool __CastType13(dynamic __u14); | |
473 typedef dynamic __CastType17(dynamic __u18); | |
OLD | NEW |