| Index: analyzer/lib/src/cancelable_future.dart
|
| diff --git a/analyzer/lib/src/cancelable_future.dart b/analyzer/lib/src/cancelable_future.dart
|
| deleted file mode 100644
|
| index 4ec7b269816dcb931b472ca8877bd26b470b4471..0000000000000000000000000000000000000000
|
| --- a/analyzer/lib/src/cancelable_future.dart
|
| +++ /dev/null
|
| @@ -1,300 +0,0 @@
|
| -// Copyright (c) 2014, 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.
|
| -
|
| -library cancelable_future;
|
| -
|
| -import 'dart:async';
|
| -
|
| -/**
|
| - * Type of callback called when the future returned by a CancelableCompleter
|
| - * is canceled.
|
| - */
|
| -typedef void CancelHandler();
|
| -
|
| -/**
|
| - * A way to produce [CancelableFuture] objects and to complete them later with
|
| - * a value or error.
|
| - *
|
| - * This class behaves like the standard library [Completer] class, except that
|
| - * its [future] getter returns a [CancelableFuture].
|
| - *
|
| - * If the future is canceled before being completed, the [CancelHandler] which
|
| - * was passed to the constructor is invoked, and any further attempt to
|
| - * complete the future has no effect. For example, in the following code:
|
| - *
|
| - * main() {
|
| - * var cc = new CancelableCompleter(() {
|
| - * print('cancelled'); // (2)
|
| - * });
|
| - * cc.future.then((value) {
|
| - * print('completed with value $value');
|
| - * }, onError: (error) {
|
| - * print('completed with error $error'); // (3)
|
| - * });
|
| - * cc.future.cancel(); // (1)
|
| - * }
|
| - *
|
| - * The call at (1) causes (2) to be invoked immediately. (3) will be invoked
|
| - * later (on a microtask), with an error that is an instance of
|
| - * [FutureCanceledError].
|
| - *
|
| - * Note that since the closure passed to then() is executed on a microtask,
|
| - * there is a short window of time between the call to [complete] and the
|
| - * client being informed that the future has completed. During this window,
|
| - * any attempt to cancel the future will have no effect. For example, in the
|
| - * following code:
|
| - *
|
| - * main() {
|
| - * var cc = new CancelableCompleter(() {
|
| - * print('cancelled'); // (3)
|
| - * });
|
| - * cc.future.then((value) {
|
| - * print('completed with value $value'); // (4)
|
| - * }, onError: (error) {
|
| - * print('completed with error $error');
|
| - * });
|
| - * cc.complete(100); // (1)
|
| - * cc.future.cancel(); // (2)
|
| - * }
|
| - *
|
| - * The call at (1) will place the completer in the "completed" state, so the
|
| - * call at (2) will have no effect (in particular, (3) won't ever execute).
|
| - * Later, (4) will be invoked on a microtask.
|
| - */
|
| -class CancelableCompleter<T> implements Completer<T> {
|
| - /**
|
| - * The completer which holds the state of the computation. If the
|
| - * computation is canceled, this completer will remain in the non-completed
|
| - * state.
|
| - */
|
| - final Completer<T> _innerCompleter = new Completer<T>.sync();
|
| -
|
| - /**
|
| - * The completer which holds the future that is exposed to the client
|
| - * through [future]. If the computation is canceled, this completer will
|
| - * be completed with a FutureCanceledError.
|
| - */
|
| - final Completer<T> _outerCompleter = new Completer<T>();
|
| -
|
| - /**
|
| - * The callback to invoke if the 'cancel' method is called on the future
|
| - * returned by [future]. This callback will only be invoked if the future
|
| - * is canceled before being completed.
|
| - */
|
| - final CancelHandler _onCancel;
|
| -
|
| - _CancelableCompleterFuture<T> _future;
|
| -
|
| - /**
|
| - * Create a CancelableCompleter that will invoke the given callback
|
| - * synchronously if its future is canceled. The callback will not be
|
| - * invoked if the future is completed before being canceled.
|
| - */
|
| - CancelableCompleter(this._onCancel) {
|
| - _future = new _CancelableCompleterFuture<T>(this);
|
| -
|
| - // When the client completes the inner completer, we need to check whether
|
| - // the outer completer has been completed. If it has, then the operation
|
| - // was canceled before it finished, and it's too late to un-cancel it, so
|
| - // we just ignore the result from the inner completer. If it hasn't, then
|
| - // we simply pass along the result from the inner completer to the outer
|
| - // completer.
|
| - //
|
| - // Note that the reason it is safe for the inner completer to be
|
| - // synchronous is that we don't expose its future to client code, and we
|
| - // only use it to complete the outer completer (which is asynchronous).
|
| - _innerCompleter.future.then((T value) {
|
| - if (!_outerCompleter.isCompleted) {
|
| - _outerCompleter.complete(value);
|
| - }
|
| - }, onError: (Object error, StackTrace stackTrace) {
|
| - if (!_outerCompleter.isCompleted) {
|
| - _outerCompleter.completeError(error, stackTrace);
|
| - }
|
| - });
|
| - }
|
| -
|
| - /**
|
| - * The [CancelableFuture] that will contain the result provided to this
|
| - * completer.
|
| - */
|
| - @override
|
| - CancelableFuture<T> get future => _future;
|
| -
|
| - /**
|
| - * Whether the future has been completed. This is independent of whether
|
| - * the future has been canceled.
|
| - */
|
| - @override
|
| - bool get isCompleted => _innerCompleter.isCompleted;
|
| -
|
| - /**
|
| - * Complete [future] with the supplied value. If the future has previously
|
| - * been canceled, this will have no effect on [future], however it will
|
| - * still set [isCompleted] to true.
|
| - */
|
| - @override
|
| - void complete([value]) {
|
| - _innerCompleter.complete(value);
|
| - }
|
| -
|
| - /**
|
| - * Complete [future] with an error. If the future has previously been
|
| - * canceled, this will have no effect on [future], however it will still set
|
| - * [isCompleted] to true.
|
| - */
|
| - @override
|
| - void completeError(Object error, [StackTrace stackTrace]) {
|
| - _innerCompleter.completeError(error, stackTrace);
|
| - }
|
| -
|
| - void _cancel() {
|
| - if (!_outerCompleter.isCompleted) {
|
| - _outerCompleter.completeError(new FutureCanceledError());
|
| - _onCancel();
|
| - }
|
| - }
|
| -}
|
| -
|
| -/**
|
| - * An object representing a delayed computation that can be canceled.
|
| - */
|
| -abstract class CancelableFuture<T> implements Future<T> {
|
| - /**
|
| - * A CancelableFuture containing the result of calling [computation]
|
| - * asynchronously. Since the computation is started without delay, calling
|
| - * the future's cancel method will have no effect.
|
| - */
|
| - factory CancelableFuture(computation()) =>
|
| - new _WrappedFuture<T>(new Future<T>(computation));
|
| -
|
| - /**
|
| - * A CancelableFuture containing the result of calling [computation] after
|
| - * [duration] has passed.
|
| - *
|
| - * TODO(paulberry): if the future is canceled before the duration has
|
| - * elapsed, the computation should not be performed.
|
| - */
|
| - factory CancelableFuture.delayed(Duration duration, [computation()]) =>
|
| - new _WrappedFuture<T>(new Future<T>.delayed(duration, computation));
|
| -
|
| - /**
|
| - * A CancelableFuture that completes with error. Since the future is
|
| - * completed without delay, calling the future's cancel method will have no
|
| - * effect.
|
| - */
|
| - factory CancelableFuture.error(Object error, [StackTrace stackTrace]) =>
|
| - new _WrappedFuture<T>(new Future<T>.error(error, stackTrace));
|
| -
|
| - /**
|
| - * A CancelableFuture containing the result of calling [computation]
|
| - * asynchronously with scheduleMicrotask. Since the computation is started
|
| - * without delay, calling the future's cancel method will have no effect.
|
| - */
|
| - factory CancelableFuture.microtask(computation()) =>
|
| - new _WrappedFuture<T>(new Future<T>.microtask(computation));
|
| -
|
| - /**
|
| - * A CancelableFuture containing the result of immediately calling
|
| - * [computation]. Since the computation is started without delay, calling
|
| - * the future's cancel method will have no effect.
|
| - */
|
| - factory CancelableFuture.sync(computation()) =>
|
| - new _WrappedFuture<T>(new Future<T>.sync(computation));
|
| -
|
| - /**
|
| - * A CancelableFuture whose value is available in the next event-loop
|
| - * iteration. Since the value is available without delay, calling the
|
| - * future's cancel method will have no effect.
|
| - */
|
| - factory CancelableFuture.value([value]) =>
|
| - new _WrappedFuture<T>(new Future<T>.value(value));
|
| -
|
| - /**
|
| - * If the delayed computation has not yet completed, attempt to cancel it.
|
| - * Note that the cancellation is not always possible. If the computation
|
| - * could be canceled, the future is completed with a FutureCanceledError.
|
| - * Otherwise it will behave as though cancel() was not called.
|
| - *
|
| - * Note that attempting to cancel a future that has already completed will
|
| - * never succeed--futures that have already completed retain their final
|
| - * state forever.
|
| - */
|
| - void cancel();
|
| -}
|
| -
|
| -/**
|
| - * Error which is used to complete any [CancelableFuture] which has been
|
| - * successfully canceled by calling its 'cancel' method.
|
| - */
|
| -class FutureCanceledError {}
|
| -
|
| -class _CancelableCompleterFuture<T> implements CancelableFuture<T> {
|
| - final CancelableCompleter<T> _completer;
|
| -
|
| - _CancelableCompleterFuture(this._completer);
|
| -
|
| - @override
|
| - Stream<T> asStream() {
|
| - // TODO(paulberry): Implement this in such a way that
|
| - // StreamSubscription.cancel() cancels the future.
|
| - return _completer._outerCompleter.future.asStream();
|
| - }
|
| -
|
| - @override
|
| - void cancel() {
|
| - _completer._cancel();
|
| - }
|
| -
|
| - @override
|
| - Future catchError(Function onError, {bool test(Object error)}) =>
|
| - _completer._outerCompleter.future.catchError(onError, test: test);
|
| -
|
| - @override
|
| - Future then(onValue(T value), {Function onError}) =>
|
| - _completer._outerCompleter.future.then(onValue, onError: onError);
|
| -
|
| - @override
|
| - Future timeout(Duration timeLimit, {onTimeout()}) {
|
| - // TODO(paulberry): Implement this in such a way that a timeout cancels
|
| - // the future.
|
| - return _completer._outerCompleter.future.timeout(timeLimit,
|
| - onTimeout: onTimeout);
|
| - }
|
| -
|
| - @override
|
| - Future<T> whenComplete(action()) =>
|
| - _completer._outerCompleter.future.whenComplete(action);
|
| -}
|
| -
|
| -/**
|
| - * A CancelableFuture that wraps an ordinary Future. Attempting to cancel a
|
| - * _WrappedFuture has no effect.
|
| - */
|
| -class _WrappedFuture<T> implements CancelableFuture<T> {
|
| - final Future<T> _future;
|
| -
|
| - _WrappedFuture(this._future);
|
| -
|
| - @override
|
| - Stream<T> asStream() => _future.asStream();
|
| -
|
| - @override
|
| - void cancel() {}
|
| -
|
| - @override
|
| - Future catchError(Function onError, {bool test(Object error)}) =>
|
| - _future.catchError(onError, test: test);
|
| -
|
| - @override
|
| - Future then(onValue(value), {Function onError}) =>
|
| - _future.then(onValue, onError: onError);
|
| -
|
| - @override
|
| - Future timeout(Duration timeLimit, {onTimeout()}) =>
|
| - _future.timeout(timeLimit, onTimeout: onTimeout);
|
| -
|
| - @override
|
| - Future<T> whenComplete(action()) => _future.whenComplete(action);
|
| -}
|
|
|