|  | // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | part of dart.async; | 
|  |  | 
|  | deprecatedFutureValue(_FutureImpl future) => | 
|  | future._isComplete ? future._resultOrListeners : null; | 
|  |  | 
|  |  | 
|  | class _CompleterImpl<T> implements Completer<T> { | 
|  | final Future<T> future; | 
|  | bool _isComplete = false; | 
|  |  | 
|  | _CompleterImpl() : future = new _FutureImpl<T>(); | 
|  |  | 
|  | void complete([T value]) { | 
|  | if (_isComplete) throw new StateError("Future already completed"); | 
|  | _isComplete = true; | 
|  | _FutureImpl future = this.future; | 
|  | future._setValue(value); | 
|  | } | 
|  |  | 
|  | void completeError(Object error, [Object stackTrace = null]) { | 
|  | if (_isComplete) throw new StateError("Future already completed"); | 
|  | _isComplete = true; | 
|  | AsyncError asyncError; | 
|  | if (error is AsyncError) { | 
|  | asyncError = error; | 
|  | } else { | 
|  | asyncError = new AsyncError(error, stackTrace); | 
|  | } | 
|  | _FutureImpl future = this.future; | 
|  | future._setError(asyncError); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * A listener on a future. | 
|  | * | 
|  | * When the future completes, the [_sendValue] or [_sendError] method | 
|  | * is invoked with the result. | 
|  | * | 
|  | * Listeners are kept in a linked list. | 
|  | */ | 
|  | abstract class _FutureListener<T> { | 
|  | _FutureListener _nextListener; | 
|  | factory _FutureListener.wrap(_FutureImpl future) { | 
|  | return new _FutureListenerWrapper(future); | 
|  | } | 
|  | void _sendValue(T value); | 
|  | void _sendError(AsyncError error); | 
|  | } | 
|  |  | 
|  | /** Adapter for a [_FutureImpl] to be a future result listener. */ | 
|  | class _FutureListenerWrapper<T> implements _FutureListener<T> { | 
|  | _FutureImpl future; | 
|  | _FutureListener _nextListener; | 
|  | _FutureListenerWrapper(this.future); | 
|  | _sendValue(T value) { future._setValue(value); } | 
|  | _sendError(AsyncError error) { future._setError(error); } | 
|  | } | 
|  |  | 
|  | class _FutureImpl<T> implements Future<T> { | 
|  | static const int _INCOMPLETE = 0; | 
|  | static const int _VALUE = 1; | 
|  | static const int _ERROR = 2; | 
|  | static const int _UNHANDLED_ERROR = 4; | 
|  |  | 
|  | /** Whether the future is complete, and as what. */ | 
|  | int _state = _INCOMPLETE; | 
|  |  | 
|  | bool get _isComplete => _state != _INCOMPLETE; | 
|  | bool get _hasValue => _state == _VALUE; | 
|  | bool get _hasError => (_state & _ERROR) != 0; | 
|  | bool get _hasUnhandledError => (_state & _UNHANDLED_ERROR) != 0; | 
|  |  | 
|  | void _clearUnhandledError() { | 
|  | // Works because _UNHANDLED_ERROR is highest bit in use. | 
|  | _state &= ~_UNHANDLED_ERROR; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Either the result, or a list of listeners until the future completes. | 
|  | * | 
|  | * The result of the future is either a value or an [AsyncError]. | 
|  | * A result is only stored when the future has completed. | 
|  | * | 
|  | * The listeners is an internally linked list of [_FutureListener]s. | 
|  | * Listeners are only remembered while the future is not yet complete. | 
|  | * | 
|  | * Since the result and the listeners cannot occur at the same time, | 
|  | * we can use the same field for both. | 
|  | */ | 
|  | var _resultOrListeners; | 
|  |  | 
|  | _FutureImpl(); | 
|  |  | 
|  | _FutureImpl.immediate(T value) { | 
|  | _state = _VALUE; | 
|  | _resultOrListeners = value; | 
|  | } | 
|  |  | 
|  | _FutureImpl.immediateError(var error, [Object stackTrace]) { | 
|  | AsyncError asyncError; | 
|  | if (error is AsyncError) { | 
|  | asyncError = error; | 
|  | } else { | 
|  | asyncError = new AsyncError(error, stackTrace); | 
|  | } | 
|  | _setError(asyncError); | 
|  | } | 
|  |  | 
|  | factory _FutureImpl.wait(Iterable<Future> futures) { | 
|  | // TODO(ajohnsen): can we do better wrt. the generic type T? | 
|  | if (futures.isEmpty) { | 
|  | return new Future<List>.immediate(const []); | 
|  | } | 
|  |  | 
|  | Completer completer = new Completer<List>(); | 
|  | int remaining = futures.length; | 
|  | List values = new List.fixedLength(futures.length); | 
|  |  | 
|  | // As each future completes, put its value into the corresponding | 
|  | // position in the list of values. | 
|  | int i = 0; | 
|  | bool completed = false; | 
|  | for (Future future in futures) { | 
|  | int pos = i++; | 
|  | future.then((Object value) { | 
|  | values[pos] = value; | 
|  | if (--remaining == 0) { | 
|  | completer.complete(values); | 
|  | } | 
|  | }).catchError((error) { | 
|  | if (!completed) completer.completeError(error.error, error.stackTrace); | 
|  | completed = true; | 
|  | }); | 
|  | } | 
|  |  | 
|  | return completer.future; | 
|  | } | 
|  |  | 
|  | Future then(f(T value), { onError(AsyncError error) }) { | 
|  | if (!_isComplete) { | 
|  | if (onError == null) { | 
|  | return new _ThenFuture(f).._subscribeTo(this); | 
|  | } | 
|  | return new _SubscribeFuture(f, onError).._subscribeTo(this); | 
|  | } | 
|  | if (_hasError) { | 
|  | if (onError != null) { | 
|  | return _handleError(onError, null); | 
|  | } | 
|  | // The "f" funtion will never be called, so just return | 
|  | // a future that delegates to this. We don't want to return | 
|  | // this itself to give a signal that the future is complete. | 
|  | return new _FutureWrapper(this); | 
|  | } else { | 
|  | assert(_hasValue); | 
|  | return _handleValue(f); | 
|  | } | 
|  | } | 
|  |  | 
|  | Future catchError(f(AsyncError asyncError), { bool test(error) }) { | 
|  | if (_hasValue) { | 
|  | return new _FutureWrapper(this); | 
|  | } | 
|  | if (!_isComplete) { | 
|  | return new _CatchErrorFuture(f, test).._subscribeTo(this); | 
|  | } else { | 
|  | return _handleError(f, test); | 
|  | } | 
|  | } | 
|  |  | 
|  | Future<T> whenComplete(action()) { | 
|  | _WhenFuture<T> whenFuture = new _WhenFuture<T>(action); | 
|  | if (!_isComplete) { | 
|  | _addListener(whenFuture); | 
|  | } else if (_hasValue) { | 
|  | T value = _resultOrListeners; | 
|  | new Timer(0, (_) { | 
|  | whenFuture._sendValue(value); | 
|  | }); | 
|  | } else { | 
|  | assert(_hasError); | 
|  | _clearUnhandledError(); | 
|  | AsyncError error = _resultOrListeners; | 
|  | new Timer(0, (_) { | 
|  | whenFuture._sendError(error); | 
|  | }); | 
|  | } | 
|  | return whenFuture; | 
|  | } | 
|  |  | 
|  | /** Handle a late listener on a completed future with a value. */ | 
|  | Future _handleValue(onValue(var value)) { | 
|  | assert(_hasValue); | 
|  | _ThenFuture thenFuture = new _ThenFuture(onValue); | 
|  | T value = _resultOrListeners; | 
|  | new Timer(0, (_) { thenFuture._sendValue(value); }); | 
|  | return thenFuture; | 
|  | } | 
|  |  | 
|  | /** Handle a late listener on a completed future with an error. */ | 
|  | Future _handleError(onError(AsyncError error), bool test(error)) { | 
|  | assert(_hasError); | 
|  | _clearUnhandledError(); | 
|  | AsyncError error = _resultOrListeners; | 
|  | _CatchErrorFuture errorFuture = new _CatchErrorFuture(onError, test); | 
|  | new Timer(0, (_) { errorFuture._sendError(error); }); | 
|  | return errorFuture; | 
|  | } | 
|  |  | 
|  | Stream<T> asStream() => new Stream.fromFuture(this); | 
|  |  | 
|  | void _setValue(T value) { | 
|  | if (_isComplete) throw new StateError("Future already completed"); | 
|  | _FutureListener listeners = _removeListeners(); | 
|  | _state = _VALUE; | 
|  | _resultOrListeners = value; | 
|  | while (listeners != null) { | 
|  | _FutureListener listener = listeners; | 
|  | listeners = listener._nextListener; | 
|  | listener._nextListener = null; | 
|  | listener._sendValue(value); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _setError(AsyncError error) { | 
|  | if (_isComplete) throw new StateError("Future already completed"); | 
|  | _FutureListener listeners = _removeListeners(); | 
|  | _state = _ERROR; | 
|  | _resultOrListeners = error; | 
|  | if (listeners == null) { | 
|  | _scheduleUnhandledError(); | 
|  | return; | 
|  | } | 
|  | do { | 
|  | _FutureListener listener = listeners; | 
|  | listeners = listener._nextListener; | 
|  | listener._nextListener = null; | 
|  | listener._sendError(error); | 
|  | } while (listeners != null); | 
|  | } | 
|  |  | 
|  | void _scheduleUnhandledError() { | 
|  | _state |= _UNHANDLED_ERROR; | 
|  | // Wait for the rest of the current event's duration to see | 
|  | // if a subscriber is added to handle the error. | 
|  | new Timer(0, (_) { | 
|  | if (_hasUnhandledError) { | 
|  | // No error handler has been added since the error was set. | 
|  | _clearUnhandledError(); | 
|  | AsyncError error = _resultOrListeners; | 
|  | print("Uncaught Error: ${error.error}"); | 
|  | if (error.stackTrace != null) { | 
|  | print("Stack Trace:\n${error.stackTrace}\n"); | 
|  | } | 
|  | throw error.error; | 
|  | } | 
|  | }); | 
|  | } | 
|  |  | 
|  | void _addListener(_FutureListener listener) { | 
|  | assert(!_isComplete); | 
|  | assert(listener._nextListener == null); | 
|  | listener._nextListener = _resultOrListeners; | 
|  | _resultOrListeners = listener; | 
|  | } | 
|  |  | 
|  | _FutureListener _removeListeners() { | 
|  | // Reverse listeners before returning them, so the resulting list is in | 
|  | // subscription order. | 
|  | assert(!_isComplete); | 
|  | _FutureListener current = _resultOrListeners; | 
|  | _resultOrListeners = null; | 
|  | _FutureListener prev = null; | 
|  | while (current != null) { | 
|  | _FutureListener next = current._nextListener; | 
|  | current._nextListener = prev; | 
|  | prev = current; | 
|  | current = next; | 
|  | } | 
|  | return prev; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Make another [_FutureImpl] receive the result of this one. | 
|  | * | 
|  | * If this future is already complete, the [future] is notified | 
|  | * immediately. This function is only called during event resolution | 
|  | * where it's acceptable to send an event. | 
|  | */ | 
|  | void _chain(_FutureImpl future) { | 
|  | if (!_isComplete) { | 
|  | _addListener(future._asListener()); | 
|  | } else if (_hasValue) { | 
|  | future._setValue(_resultOrListeners); | 
|  | } else { | 
|  | assert(_hasError); | 
|  | _clearUnhandledError(); | 
|  | future._setError(_resultOrListeners); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Helper function to handle the result of transforming an incoming event. | 
|  | * | 
|  | * If the result is itself a [Future], this future is linked to that | 
|  | * future's output. If not, this future is completed with the result. | 
|  | */ | 
|  | void _setOrChainValue(var result) { | 
|  | if (result is Future) { | 
|  | // Result should be a Future<T>. | 
|  | if (result is _FutureImpl) { | 
|  | _FutureImpl chainFuture = result; | 
|  | chainFuture._chain(this); | 
|  | return; | 
|  | } else { | 
|  | Future future = result; | 
|  | future.then(_setValue, | 
|  | onError: _setError); | 
|  | return; | 
|  | } | 
|  | } else { | 
|  | // Result must be of type T. | 
|  | _setValue(result); | 
|  | } | 
|  | } | 
|  |  | 
|  | _FutureListener _asListener() => new _FutureListener.wrap(this); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Transforming future base class. | 
|  | * | 
|  | * A transforming future is itself a future and a future listener. | 
|  | * Subclasses override [_sendValue]/[_sendError] to intercept | 
|  | * the results of a previous future. | 
|  | */ | 
|  | abstract class _TransformFuture<S, T> extends _FutureImpl<T> | 
|  | implements _FutureListener<S> { | 
|  | // _FutureListener implementation. | 
|  | _FutureListener _nextListener; | 
|  |  | 
|  | void _sendValue(S value); | 
|  |  | 
|  | void _sendError(AsyncError error); | 
|  |  | 
|  | void _subscribeTo(_FutureImpl future) { | 
|  | future._addListener(this); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** The onValue and onError handlers return either a value or a future */ | 
|  | typedef dynamic _FutureOnValue<T>(T value); | 
|  | typedef dynamic _FutureOnError(AsyncError error); | 
|  | /** Test used by [Future.catchError] to handle skip some errors. */ | 
|  | typedef bool _FutureErrorTest(var error); | 
|  | /** Used by [WhenFuture]. */ | 
|  | typedef _FutureAction(); | 
|  |  | 
|  | /** Future returned by [Future.then] with no [:onError:] parameter. */ | 
|  | class _ThenFuture<S, T> extends _TransformFuture<S, T> { | 
|  | // TODO(ahe): Restore type when feature is implemented in dart2js | 
|  | // checked mode. | 
|  | final /* _FutureOnValue<S> */ _onValue; | 
|  |  | 
|  | _ThenFuture(this._onValue); | 
|  |  | 
|  | _sendValue(S value) { | 
|  | assert(_onValue != null); | 
|  | var result; | 
|  | try { | 
|  | result = _onValue(value); | 
|  | } on AsyncError catch (e) { | 
|  | _setError(e); | 
|  | return; | 
|  | } catch (e, s) { | 
|  | _setError(new AsyncError(e, s)); | 
|  | return; | 
|  | } | 
|  | _setOrChainValue(result); | 
|  | } | 
|  |  | 
|  | void _sendError(AsyncError error) { | 
|  | _setError(error); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** Future returned by [Future.catchError]. */ | 
|  | class _CatchErrorFuture<T> extends _TransformFuture<T,T> { | 
|  | final _FutureErrorTest _test; | 
|  | final _FutureOnError _onError; | 
|  |  | 
|  | _CatchErrorFuture(this._onError, this._test); | 
|  |  | 
|  | _sendValue(T value) { | 
|  | _setValue(value); | 
|  | } | 
|  |  | 
|  | _sendError(AsyncError error) { | 
|  | assert(_onError != null); | 
|  | // if _test is supplied, check if it returns true, otherwise just | 
|  | // forward the error unmodified. | 
|  | if (_test != null) { | 
|  | bool matchesTest; | 
|  | try { | 
|  | matchesTest = _test(error.error); | 
|  | } catch (e, s) { | 
|  | _setError(new AsyncError.withCause(e, s, error)); | 
|  | return; | 
|  | } | 
|  | if (!matchesTest) { | 
|  | _setError(error); | 
|  | return; | 
|  | } | 
|  | } | 
|  | // Act on the error, and use the result as this future's result. | 
|  | var result; | 
|  | try { | 
|  | result = _onError(error); | 
|  | } on AsyncError catch (e) { | 
|  | _setError(e); | 
|  | return; | 
|  | } catch (e, s) { | 
|  | _setError(new AsyncError.withCause(e, s, error)); | 
|  | return; | 
|  | } | 
|  | _setOrChainValue(result); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** Future returned by [Future.then] with an [:onError:] parameter. */ | 
|  | class _SubscribeFuture<S, T> extends _ThenFuture<S, T> { | 
|  | final _FutureOnError _onError; | 
|  |  | 
|  | _SubscribeFuture(onValue(S value), this._onError) : super(onValue); | 
|  |  | 
|  | // The _sendValue method is inherited from ThenFuture. | 
|  |  | 
|  | void _sendError(AsyncError error) { | 
|  | assert(_onError != null); | 
|  | var result; | 
|  | try { | 
|  | result = _onError(error); | 
|  | } on AsyncError catch (e) { | 
|  | _setError(e); | 
|  | return; | 
|  | } catch (e, s) { | 
|  | _setError(new AsyncError.withCause(e, s, error)); | 
|  | return; | 
|  | } | 
|  | _setOrChainValue(result); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** Future returned by [Future.whenComplete]. */ | 
|  | class _WhenFuture<T> extends _TransformFuture<T, T> { | 
|  | final _FutureAction _action; | 
|  |  | 
|  | _WhenFuture(this._action); | 
|  |  | 
|  | void _sendValue(T value) { | 
|  | try { | 
|  | var result = _action(); | 
|  | if (result is Future) { | 
|  | Future resultFuture = result; | 
|  | resultFuture.then((_) { | 
|  | _setValue(value); | 
|  | }, onError: _setError); | 
|  | return; | 
|  | } | 
|  | } on AsyncError catch (e) { | 
|  | _setError(e); | 
|  | return; | 
|  | } catch (e, s) { | 
|  | _setError(new AsyncError(e, s)); | 
|  | return; | 
|  | } | 
|  | _setValue(value); | 
|  | } | 
|  |  | 
|  | void _sendError(AsyncError error) { | 
|  | try { | 
|  | var result = _action(); | 
|  | if (result is Future) { | 
|  | Future resultFuture = result; | 
|  | // TODO(lrn): Find a way to combine [error] into [e]. | 
|  | resultFuture.then((_) { | 
|  | _setError(error); | 
|  | }, onError: _setError); | 
|  | return; | 
|  | } | 
|  | } on AsyncError catch (e) { | 
|  | error = e; | 
|  | } catch (e, s) { | 
|  | error = new AsyncError.withCause(e, s, error); | 
|  | } | 
|  | _setError(error); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Thin wrapper around a [Future]. | 
|  | * | 
|  | * This is used to return a "new" [Future] that effectively work just | 
|  | * as an existing [Future], without making this discoverable by comparing | 
|  | * identities. | 
|  | */ | 
|  | class _FutureWrapper<T> implements Future<T> { | 
|  | final Future<T> _future; | 
|  |  | 
|  | _FutureWrapper(this._future); | 
|  |  | 
|  | Future then(function(T value), { onError(AsyncError error) }) { | 
|  | return _future.then(function, onError: onError); | 
|  | } | 
|  |  | 
|  | Future catchError(function(AsyncError error), {bool test(var error)}) { | 
|  | return _future.catchError(function, test: test); | 
|  | } | 
|  |  | 
|  | Future<T> whenComplete(action()) { | 
|  | return _future.whenComplete(action); | 
|  | } | 
|  |  | 
|  | Stream<T> asStream() => new Stream.fromFuture(_future); | 
|  | } |