| Index: tool/input_sdk/private/generators.dart
|
| diff --git a/lib/runtime/dart/_generators.js b/tool/input_sdk/private/generators.dart
|
| similarity index 57%
|
| copy from lib/runtime/dart/_generators.js
|
| copy to tool/input_sdk/private/generators.dart
|
| index 442ae736eaa30134fd4fc2b657c1c2235bdfd365..8f0833193919d0396519df2d06ff2d745d718739 100644
|
| --- a/lib/runtime/dart/_generators.js
|
| +++ b/tool/input_sdk/private/generators.dart
|
| @@ -2,93 +2,87 @@
|
| // 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.
|
| - */
|
| -dart_library.library('dart/_generators', null, /* Imports */[
|
| -], /* Lazy Imports */[
|
| - 'dart/_operations',
|
| - 'dart/_js_helper',
|
| - 'dart/core',
|
| - 'dart/collection',
|
| - 'dart/async'
|
| -], function(exports, _operations, _js_helper, core, collection, async) {
|
| - 'use strict';
|
| -
|
| - const _jsIterator = Symbol('_jsIterator');
|
| - const _current = Symbol('_current');
|
| -
|
| - function syncStar(gen, E, ...args) {
|
| - const SyncIterable_E = _js_helper.SyncIterable$(E);
|
| - return new SyncIterable_E(gen, args);
|
| +/// 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.
|
| +library dart._generators;
|
| +
|
| +import 'dart:_foreign_helper' show JS, JsName, rest, spread, genericTypeConstructor;
|
| +import 'dart:_js_helper' show SyncIterable;
|
| +import 'dart:_operations' show instanceOf, stackTrace;
|
| +
|
| +import 'dart:async';
|
| +
|
| +final _jsIterator = JS('', 'Symbol("_jsIterator")');
|
| +final _current = JS('', 'Symbol("_current")');
|
| +
|
| +syncStar(gen, E, @rest args) => JS('', '''(() => {
|
| + // TODO(ochafik).
|
| + const SyncIterable_E = ${genericTypeConstructor(SyncIterable)}($E);
|
| + return new SyncIterable_E($gen, $args);
|
| +})()''');
|
| +
|
| +@JsName('async')
|
| +async_(gen, T, @rest args) => JS('', '''(() => {
|
| + let iter;
|
| + function onValue(res) {
|
| + if (res === void 0) res = null;
|
| + return next(iter.next(res));
|
| }
|
| - exports.syncStar = syncStar;
|
| -
|
| - function async_(gen, T, ...args) {
|
| - 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 (!_operations.instanceOf(future, async.Future$)) {
|
| - future = async.Future.value(future);
|
| - }
|
| - // Chain the Future so `await` receives the Future's value.
|
| - return future.then(onValue, {onError: onError});
|
| + 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, ${genericTypeConstructor(Future)})) {
|
| + future = $Future.value(future);
|
| }
|
| - return async.Future$(T).new(function() {
|
| - iter = gen(...args)[Symbol.iterator]();
|
| - return onValue();
|
| - });
|
| + // Chain the Future so `await` receives the Future's value.
|
| + return future.then(onValue, {onError: onError});
|
| }
|
| - exports.async = async_;
|
| -
|
| - // 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());
|
| - // });
|
| - // }
|
| + return ${genericTypeConstructor(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());
|
| +// });
|
| +// }
|
| +final _AsyncStarStreamController = JS('', '''
|
| class _AsyncStarStreamController {
|
| constructor(generator, T, args) {
|
| this.isAdding = false;
|
| @@ -97,7 +91,7 @@ dart_library.library('dart/_generators', null, /* Imports */[
|
| this.isSuspendedAtYield = false;
|
| this.canceler = null;
|
| this.iterator = generator(this, ...args)[Symbol.iterator]();
|
| - this.controller = async.StreamController$(T).new({
|
| + this.controller = ${genericTypeConstructor(StreamController)}(T).new({
|
| onListen: () => this.scheduleGenerator(),
|
| onResume: () => this.onResume(),
|
| onCancel: () => this.onCancel()
|
| @@ -115,7 +109,7 @@ dart_library.library('dart/_generators', null, /* Imports */[
|
| return null;
|
| }
|
| if (this.canceler == null) {
|
| - this.canceler = async.Completer.new();
|
| + this.canceler = $Completer.new();
|
| this.scheduleGenerator();
|
| }
|
| return this.canceler.future;
|
| @@ -141,7 +135,7 @@ dart_library.library('dart/_generators', null, /* Imports */[
|
| return;
|
| }
|
| this.isScheduled = true;
|
| - async.scheduleMicrotask(() => this.runBody());
|
| + $scheduleMicrotask(() => this.runBody());
|
| }
|
|
|
| runBody(opt_awaitValue) {
|
| @@ -152,7 +146,7 @@ dart_library.library('dart/_generators', null, /* Imports */[
|
| try {
|
| iter = this.iterator.next(opt_awaitValue);
|
| } catch (e) {
|
| - this.addError(e, _operations.stackTrace(e));
|
| + this.addError(e, $stackTrace(e));
|
| this.close();
|
| return;
|
| }
|
| @@ -172,8 +166,8 @@ dart_library.library('dart/_generators', null, /* Imports */[
|
| // that we should schedule `await` in `async*` the same as in `async`.
|
| this.isWaiting = true;
|
| let future = iter.value;
|
| - if (!_operations.instanceOf(future, async.Future$)) {
|
| - future = async.Future.value(future);
|
| + if (!$instanceOf(future, ${genericTypeConstructor(Future)})) {
|
| + future = $Future.value(future);
|
| }
|
| return future.then((x) => this.runBody(x),
|
| { onError: (e, s) => this.throwError(e, s) });
|
| @@ -225,10 +219,10 @@ dart_library.library('dart/_generators', null, /* Imports */[
|
| this.controller.addError(error, stackTrace);
|
| }
|
| }
|
| +''');
|
|
|
| - /** Returns a Stream of T implemented by an async* function. */
|
| - function asyncStar(gen, T, ...args) {
|
| - return new _AsyncStarStreamController(gen, T, args).controller.stream;
|
| - }
|
| - exports.asyncStar = asyncStar;
|
| -});
|
| +/// Returns a Stream of T implemented by an async* function. */
|
| +///
|
| +asyncStar(gen, T, @rest args) => JS('', '''(() => {
|
| + return new _AsyncStarStreamController($gen, $T, $args).controller.stream;
|
| +})()''');
|
|
|