Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(529)

Unified Diff: lib/runtime/dart/_generators.js

Issue 1530563003: Generate all runtime files from dart. (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Reverted to new .dart files in input_sdk: please compare them against previous patchset Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/runtime/dart/_generators.js
diff --git a/lib/runtime/dart/_generators.js b/lib/runtime/dart/_generators.js
index 442ae736eaa30134fd4fc2b657c1c2235bdfd365..80edc442d03477ef71cda46c2d1baf003a04df16 100644
--- a/lib/runtime/dart/_generators.js
+++ b/lib/runtime/dart/_generators.js
@@ -1,95 +1,40 @@
-// 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.
- */
dart_library.library('dart/_generators', null, /* Imports */[
-], /* Lazy Imports */[
- 'dart/_operations',
+ 'dart/_classes'
+], /* Lazy imports */[
'dart/_js_helper',
- 'dart/core',
- 'dart/collection',
+ 'dart/_operations',
'dart/async'
-], function(exports, _operations, _js_helper, core, collection, async) {
+], function(exports, classes, _js_helper, _operations, async$) {
'use strict';
-
- const _jsIterator = Symbol('_jsIterator');
- const _current = Symbol('_current');
-
+ 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);
}
- exports.syncStar = syncStar;
-
- function async_(gen, T, ...args) {
+ 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);
+ 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});
}
- return async.Future$(T).new(function() {
+ return async$.Future$(T).new(function() {
iter = gen(...args)[Symbol.iterator]();
return onValue();
});
}
- 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());
- // });
- // }
- class _AsyncStarStreamController {
+ const _AsyncStarStreamController = class _AsyncStarStreamController {
constructor(generator, T, args) {
this.isAdding = false;
this.isWaiting = false;
@@ -97,53 +42,40 @@ 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({
- onListen: () => this.scheduleGenerator(),
- onResume: () => this.onResume(),
- onCancel: () => this.onCancel()
+ this.controller = async$.StreamController$(T).new({
+ onListen: (() => this.scheduleGenerator()).bind(this),
+ onResume: (() => this.onResume()).bind(this),
+ onCancel: (() => this.onCancel()).bind(this)
});
}
-
onResume() {
if (this.isSuspendedAtYield) {
this.scheduleGenerator();
}
}
-
onCancel() {
if (this.controller.isClosed) {
return null;
}
if (this.canceler == null) {
- this.canceler = async.Completer.new();
+ this.canceler = async$.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) {
+ if (this.isScheduled || this.controller.isPaused || this.isAdding || this.isWaiting) {
return;
}
this.isScheduled = true;
- async.scheduleMicrotask(() => this.runBody());
+ async$.scheduleMicrotask((() => this.runBody()).bind(this));
}
-
runBody(opt_awaitValue) {
this.isScheduled = false;
this.isSuspendedAtYield = false;
@@ -156,79 +88,60 @@ dart_library.library('dart/_generators', null, /* Imports */[
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 (!_operations.instanceOf(future, async.Future$)) {
- future = async.Future.value(future);
+ if (!_operations.instanceOf(future, async$.Future$)) {
+ future = async$.Future.value(future);
}
- return future.then((x) => this.runBody(x),
- { onError: (e, s) => this.throwError(e, s) });
+ return future.then((x => this.runBody(x)).bind(this), {
+ onError: ((e, s) => this.throwError(e, s)).bind(this)
+ });
}
-
- // 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.controller.addStream(stream, {cancelOnError: false}).then((() => {
this.isAdding = false;
this.scheduleGenerator();
- }, { onError: (e, s) => this.throwError(e, s) });
+ }).bind(this), {
+ onError: ((e, s) => this.throwError(e, s)).bind(this)
+ });
}
-
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.
+ if (this.canceler != null && !this.canceler.isCompleted) {
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. */
+ };
function asyncStar(gen, T, ...args) {
return new _AsyncStarStreamController(gen, T, args).controller.stream;
}
+ // Exports:
+ exports.syncStar = syncStar;
+ exports.async = async;
exports.asyncStar = asyncStar;
});

Powered by Google App Engine
This is Rietveld 408576698