| Index: tool/input_sdk/private/generators.dart
|
| diff --git a/tool/input_sdk/private/generators.dart b/tool/input_sdk/private/generators.dart
|
| deleted file mode 100644
|
| index 6203f71973b5e16da645f6af929f7197c7d6af3d..0000000000000000000000000000000000000000
|
| --- a/tool/input_sdk/private/generators.dart
|
| +++ /dev/null
|
| @@ -1,223 +0,0 @@
|
| -// Copyright (c) 2015, 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.
|
| -
|
| -/// This library adapts ES6 generators to implement Dart's async/await.
|
| -/// It's designed to interact with Dart's Future/Stream and follow Dart
|
| -/// async/await semantics.
|
| -/// See https://github.com/dart-lang/dev_compiler/issues/245 for ideas on
|
| -/// reconciling Dart's Future and ES6 Promise.
|
| -/// Inspired by `co`: https://github.com/tj/co/blob/master/index.js, which is a
|
| -/// stepping stone for proposed ES7 async/await, and uses ES6 Promises.
|
| -part of dart._runtime;
|
| -
|
| -final _jsIterator = JS('', 'Symbol("_jsIterator")');
|
| -final _current = JS('', 'Symbol("_current")');
|
| -
|
| -syncStar(gen, E, @rest args) => JS('', '''(() => {
|
| - const SyncIterable_E = ${getGenericClass(SyncIterable)}($E);
|
| - return new SyncIterable_E($gen, $args);
|
| -})()''');
|
| -
|
| -@JSExportName('async')
|
| -async_(gen, T, @rest args) => JS('', '''(() => {
|
| - let iter;
|
| - function onValue(res) {
|
| - if (res === void 0) res = null;
|
| - return next(iter.next(res));
|
| - }
|
| - function onError(err) {
|
| - // If the awaited Future throws, we want to convert this to an exception
|
| - // thrown from the `yield` point, as if it was thrown there.
|
| - //
|
| - // If the exception is not caught inside `gen`, it will emerge here, which
|
| - // will send it to anyone listening on this async function's Future<T>.
|
| - //
|
| - // In essence, we are giving the code inside the generator a chance to
|
| - // use try-catch-finally.
|
| - return next(iter.throw(err));
|
| - }
|
| - function next(ret) {
|
| - if (ret.done) return ret.value;
|
| - // Checks if the awaited value is a Future.
|
| - let future = ret.value;
|
| - if (!$instanceOf(future, ${getGenericClass(Future)})) {
|
| - future = $Future.value(future);
|
| - }
|
| - // Chain the Future so `await` receives the Future's value.
|
| - return future.then(onValue, {onError: onError});
|
| - }
|
| - return ${getGenericClass(Future)}(T).new(function() {
|
| - iter = $gen(...$args)[Symbol.iterator]();
|
| - return onValue();
|
| - });
|
| -})()''');
|
| -
|
| -// Implementation inspired by _AsyncStarStreamController in
|
| -// dart-lang/sdk's runtime/lib/core_patch.dart
|
| -//
|
| -// Given input like:
|
| -//
|
| -// foo() async* {
|
| -// yield 1;
|
| -// yield* bar();
|
| -// print(await baz());
|
| -// }
|
| -//
|
| -// This generates as:
|
| -//
|
| -// function foo() {
|
| -// return dart.asyncStar(function*(stream) {
|
| -// if (stream.add(1)) return;
|
| -// yield;
|
| -// if (stream.addStream(bar()) return;
|
| -// yield;
|
| -// print(yield baz());
|
| -// });
|
| -// }
|
| -//
|
| -// TODO(ochafik): Port back to Dart (which it used to be in the past).
|
| -final _AsyncStarStreamController = JS('', '''
|
| - class _AsyncStarStreamController {
|
| - constructor(generator, T, args) {
|
| - this.isAdding = false;
|
| - this.isWaiting = false;
|
| - this.isScheduled = false;
|
| - this.isSuspendedAtYield = false;
|
| - this.canceler = null;
|
| - this.iterator = generator(this, ...args)[Symbol.iterator]();
|
| - this.controller = ${getGenericClass(StreamController)}(T).new({
|
| - onListen: () => this.scheduleGenerator(),
|
| - onResume: () => this.onResume(),
|
| - onCancel: () => this.onCancel()
|
| - });
|
| - }
|
| -
|
| - onResume() {
|
| - if (this.isSuspendedAtYield) {
|
| - this.scheduleGenerator();
|
| - }
|
| - }
|
| -
|
| - onCancel() {
|
| - if (this.controller.isClosed) {
|
| - return null;
|
| - }
|
| - if (this.canceler == null) {
|
| - this.canceler = $Completer.new();
|
| - this.scheduleGenerator();
|
| - }
|
| - return this.canceler.future;
|
| - }
|
| -
|
| - close() {
|
| - if (this.canceler != null && !this.canceler.isCompleted) {
|
| - // If the stream has been cancelled, complete the cancellation future
|
| - // with the error.
|
| - this.canceler.complete();
|
| - }
|
| - this.controller.close();
|
| - }
|
| -
|
| - scheduleGenerator() {
|
| - // TODO(jmesserly): is this paused check in the right place? Assuming the
|
| - // async* Stream yields, then is paused (by other code), the body will
|
| - // already be scheduled. This will cause at least one more iteration to
|
| - // run (adding another data item to the Stream) before actually pausing.
|
| - // It could be fixed by moving the `isPaused` check inside `runBody`.
|
| - if (this.isScheduled || this.controller.isPaused ||
|
| - this.isAdding || this.isWaiting) {
|
| - return;
|
| - }
|
| - this.isScheduled = true;
|
| - $scheduleMicrotask(() => this.runBody());
|
| - }
|
| -
|
| - runBody(opt_awaitValue) {
|
| - this.isScheduled = false;
|
| - this.isSuspendedAtYield = false;
|
| - this.isWaiting = false;
|
| - let iter;
|
| - try {
|
| - iter = this.iterator.next(opt_awaitValue);
|
| - } catch (e) {
|
| - this.addError(e, $stackTrace(e));
|
| - this.close();
|
| - return;
|
| - }
|
| - if (iter.done) {
|
| - this.close();
|
| - return;
|
| - }
|
| -
|
| - // If we're suspended at a yield/yield*, we're done for now.
|
| - if (this.isSuspendedAtYield || this.isAdding) return;
|
| -
|
| - // Handle `await`: if we get a value passed to `yield` it means we are
|
| - // waiting on this Future. Make sure to prevent scheduling, and pass the
|
| - // value back as the result of the `yield`.
|
| - //
|
| - // TODO(jmesserly): is the timing here correct? The assumption here is
|
| - // that we should schedule `await` in `async*` the same as in `async`.
|
| - this.isWaiting = true;
|
| - let future = iter.value;
|
| - if (!$instanceOf(future, ${getGenericClass(Future)})) {
|
| - future = $Future.value(future);
|
| - }
|
| - return future.then((x) => this.runBody(x),
|
| - { onError: (e, s) => this.throwError(e, s) });
|
| - }
|
| -
|
| - // Adds element to stream, returns true if the caller should terminate
|
| - // execution of the generator.
|
| - add(event) {
|
| - // If stream is cancelled, tell caller to exit the async generator.
|
| - if (!this.controller.hasListener) return true;
|
| - this.controller.add(event);
|
| - this.scheduleGenerator();
|
| - this.isSuspendedAtYield = true;
|
| - return false;
|
| - }
|
| -
|
| - // Adds the elements of stream into this controller's stream.
|
| - // The generator will be scheduled again when all of the
|
| - // elements of the added stream have been consumed.
|
| - // Returns true if the caller should terminate
|
| - // execution of the generator.
|
| - addStream(stream) {
|
| - // If stream is cancelled, tell caller to exit the async generator.
|
| - if (!this.controller.hasListener) return true;
|
| -
|
| - this.isAdding = true;
|
| - this.controller.addStream(stream, {cancelOnError: false}).then(() => {
|
| - this.isAdding = false;
|
| - this.scheduleGenerator();
|
| - }, { onError: (e, s) => this.throwError(e, s) });
|
| - }
|
| -
|
| - throwError(error, stackTrace) {
|
| - try {
|
| - this.iterator.throw(error);
|
| - } catch (e) {
|
| - this.addError(e, stackTrace);
|
| - }
|
| - }
|
| -
|
| - addError(error, stackTrace) {
|
| - if ((this.canceler != null) && !this.canceler.isCompleted) {
|
| - // If the stream has been cancelled, complete the cancellation future
|
| - // with the error.
|
| - this.canceler.completeError(error, stackTrace);
|
| - return;
|
| - }
|
| - if (!this.controller.hasListener) return;
|
| - this.controller.addError(error, stackTrace);
|
| - }
|
| - }
|
| -''');
|
| -
|
| -/// Returns a Stream of T implemented by an async* function. */
|
| -///
|
| -asyncStar(gen, T, @rest args) => JS('', '''(() => {
|
| - return new $_AsyncStarStreamController($gen, $T, $args).controller.stream;
|
| -})()''');
|
|
|