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

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/generators.dart

Issue 2804113002: DDC fix for foreign futures (Closed)
Patch Set: Optimize Created 3 years, 8 months 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// This library adapts ES6 generators to implement Dart's async/await. 5 /// This library adapts ES6 generators to implement Dart's async/await.
6 /// It's designed to interact with Dart's Future/Stream and follow Dart 6 /// It's designed to interact with Dart's Future/Stream and follow Dart
7 /// async/await semantics. 7 /// async/await semantics.
8 /// See https://github.com/dart-lang/sdk/issues/27315 for ideas on 8 /// See https://github.com/dart-lang/sdk/issues/27315 for ideas on
9 /// reconciling Dart's Future and ES6 Promise. 9 /// reconciling Dart's Future and ES6 Promise.
10 /// Inspired by `co`: https://github.com/tj/co/blob/master/index.js, which is a 10 /// Inspired by `co`: https://github.com/tj/co/blob/master/index.js, which is a
11 /// stepping stone for proposed ES7 async/await, and uses ES6 Promises. 11 /// stepping stone for proposed ES7 async/await, and uses ES6 Promises.
12 part of dart._runtime; 12 part of dart._runtime;
13 13
14 final _jsIterator = JS('', 'Symbol("_jsIterator")'); 14 final _jsIterator = JS('', 'Symbol("_jsIterator")');
15 final _current = JS('', 'Symbol("_current")'); 15 final _current = JS('', 'Symbol("_current")');
16 16
17 syncStar(gen, E, @rest args) => JS( 17 syncStar(gen, E, @rest args) => JS(
18 '', 18 '',
19 '''(() => { 19 '''(() => {
20 const SyncIterable_E = ${getGenericClass(SyncIterable)}($E); 20 const SyncIterable_E = ${getGenericClass(SyncIterable)}($E);
21 return new SyncIterable_E($gen, $args); 21 return new SyncIterable_E($gen, $args);
22 })()'''); 22 })()''');
23 23
24 @JSExportName('async') 24 @JSExportName('async')
25 async_(gen, T, @rest args) => JS( 25 async_(gen, T, @rest args) => JS(
26 '', 26 '',
27 '''(() => { 27 '''(() => {
28 let iter; 28 let iter;
29 const FutureT = ${getGenericClass(Future)}($T);
30 let _FutureType;
31 // Return the raw class type or null if not a class object.
32 // This is streamlined to test for native futures.
33 function _getRawClassType(obj) {
34 if (!obj) return null;
35 let constructor = obj.constructor;
36 if (!constructor == null) return null;
37 return $getGenericClass(constructor);
38 }
29 function onValue(res) { 39 function onValue(res) {
30 if (res === void 0) res = null; 40 if (res === void 0) res = null;
31 return next(iter.next(res)); 41 return next(iter.next(res));
32 } 42 }
33 function onError(err) { 43 function onError(err) {
34 // If the awaited Future throws, we want to convert this to an exception 44 // If the awaited Future throws, we want to convert this to an exception
35 // thrown from the `yield` point, as if it was thrown there. 45 // thrown from the `yield` point, as if it was thrown there.
36 // 46 //
37 // If the exception is not caught inside `gen`, it will emerge here, which 47 // If the exception is not caught inside `gen`, it will emerge here, which
38 // will send it to anyone listening on this async function's Future<T>. 48 // will send it to anyone listening on this async function's Future<T>.
39 // 49 //
40 // In essence, we are giving the code inside the generator a chance to 50 // In essence, we are giving the code inside the generator a chance to
41 // use try-catch-finally. 51 // use try-catch-finally.
42 return next(iter.throw(err)); 52 return next(iter.throw(err));
43 } 53 }
44 function next(ret) { 54 function next(ret) {
45 let future = ret.value; 55 let future = ret.value;
46 if (ret.done) { 56 if (ret.done) {
47 return ret.value; 57 return ret.value;
48 } 58 }
49 // Checks if the awaited value is a Future. 59 // Wraps if future is not a native Future.
50 if (!$instanceOf(future, $Future)) { 60 if (_getRawClassType(future) !== _FutureType) {
51 future = $Future.value(future); 61 future = $Future.value(future);
52 } 62 }
53 // Chain the Future so `await` receives the Future's value. 63 // Chain the Future so `await` receives the Future's value.
54 return future.then($dynamic)(onValue, {onError: onError}); 64 return future.then($dynamic)(onValue, {onError: onError});
55 } 65 }
56 let FutureT = ${getGenericClass(Future)(T)}; 66 let result = FutureT.microtask(function() {
57 return FutureT.microtask(function() {
58 iter = $gen.apply(null, $args)[Symbol.iterator](); 67 iter = $gen.apply(null, $args)[Symbol.iterator]();
59 var result = onValue(); 68 var result = onValue();
60 if ($strongInstanceOf(result, FutureT) == null) { 69 if ($strongInstanceOf(result, FutureT) == null) {
61 // Chain the Future<dynamic> to a Future<T> to produce the correct 70 // Chain the Future<dynamic> to a Future<T> to produce the correct
62 // final type. 71 // final type.
63 return result.then($T)((x) => x, {onError: onError}); 72 return result.then($T)((x) => x, {onError: onError});
64 } else { 73 } else {
65 return result; 74 return result;
66 } 75 }
67 }); 76 });
77 // TODO(jmesserly): optimize this further.
78 _FutureType = _getRawClassType(result);
79 return result;
68 })()'''); 80 })()''');
69 81
70 // Implementation inspired by _AsyncStarStreamController in 82 // Implementation inspired by _AsyncStarStreamController in
71 // dart-lang/sdk's runtime/lib/core_patch.dart 83 // dart-lang/sdk's runtime/lib/core_patch.dart
72 // 84 //
73 // Given input like: 85 // Given input like:
74 // 86 //
75 // foo() async* { 87 // foo() async* {
76 // yield 1; 88 // yield 1;
77 // yield* bar(); 89 // yield* bar();
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 } 245 }
234 '''); 246 ''');
235 247
236 /// Returns a Stream of T implemented by an async* function. */ 248 /// Returns a Stream of T implemented by an async* function. */
237 /// 249 ///
238 asyncStar(gen, T, @rest args) => JS( 250 asyncStar(gen, T, @rest args) => JS(
239 '', 251 '',
240 '''(() => { 252 '''(() => {
241 return new $_AsyncStarStreamController($gen, $T, $args).controller.stream; 253 return new $_AsyncStarStreamController($gen, $T, $args).controller.stream;
242 })()'''); 254 })()''');
OLDNEW
« no previous file with comments | « pkg/dev_compiler/test/codegen_expected/varargs.js ('k') | tests/language_strong/async_await_foreign_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698