Chromium Code Reviews| OLD | NEW |
|---|---|
| 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) => |
| 18 '', | 18 JS('', 'new (${getGenericClass(SyncIterable)}($E).new)($gen, $args)'); |
| 19 '''(() => { | |
| 20 const SyncIterable_E = ${getGenericClass(SyncIterable)}($E); | |
| 21 return new SyncIterable_E($gen, $args); | |
| 22 })()'''); | |
| 23 | 19 |
| 24 @JSExportName('async') | 20 @JSExportName('async') |
| 25 async_(gen, T, @rest args) => JS( | 21 async_(gen, T, @rest args) => JS( |
| 26 '', | 22 '', |
| 27 '''(() => { | 23 '''(() => { |
| 28 let iter; | 24 let iter; |
| 29 const FutureT = ${getGenericClass(Future)}($T); | 25 const FutureT = ${getGenericClass(Future)}($T); |
| 30 let _FutureType; | 26 let _FutureType; |
| 31 // Return the raw class type or null if not a class object. | 27 // Return the raw class type or null if not a class object. |
| 32 // This is streamlined to test for native futures. | 28 // This is streamlined to test for native futures. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 return result.then($T)((x) => x, {onError: onError}); | 68 return result.then($T)((x) => x, {onError: onError}); |
| 73 } else { | 69 } else { |
| 74 return result; | 70 return result; |
| 75 } | 71 } |
| 76 }); | 72 }); |
| 77 // TODO(jmesserly): optimize this further. | 73 // TODO(jmesserly): optimize this further. |
| 78 _FutureType = _getRawClassType(result); | 74 _FutureType = _getRawClassType(result); |
| 79 return result; | 75 return result; |
| 80 })()'''); | 76 })()'''); |
| 81 | 77 |
| 82 // Implementation inspired by _AsyncStarStreamController in | 78 /// Implementation inspired by _AsyncStarStreamController in |
| 83 // dart-lang/sdk's runtime/lib/core_patch.dart | 79 /// dart-lang/sdk's runtime/lib/core_patch.dart |
| 84 // | 80 /// |
| 85 // Given input like: | 81 /// Given input like: |
| 86 // | 82 /// |
| 87 // foo() async* { | 83 /// foo() async* { |
| 88 // yield 1; | 84 /// yield 1; |
| 89 // yield* bar(); | 85 /// yield* bar(); |
| 90 // print(await baz()); | 86 /// print(await baz()); |
| 91 // } | 87 /// } |
| 92 // | 88 /// |
| 93 // This generates as: | 89 /// This generates as: |
| 94 // | 90 /// |
| 95 // function foo() { | 91 /// function foo() { |
| 96 // return dart.asyncStar(function*(stream) { | 92 /// return dart.asyncStar(function*(stream) { |
| 97 // if (stream.add(1)) return; | 93 /// if (stream.add(1)) return; |
| 98 // yield; | 94 /// yield; |
| 99 // if (stream.addStream(bar()) return; | 95 /// if (stream.addStream(bar()) return; |
| 100 // yield; | 96 /// yield; |
| 101 // print(yield baz()); | 97 /// print(yield baz()); |
| 102 // }); | 98 /// }); |
| 103 // } | 99 /// } |
| 104 // | 100 /// |
| 105 // TODO(ochafik): Port back to Dart (which it used to be in the past). | 101 // TODO(jmesserly): port back to Dart, based on VM's equivalent class. |
| 106 final _AsyncStarStreamController = JS( | 102 final _AsyncStarStreamController = JS( |
| 107 '', | 103 '', |
| 108 ''' | 104 ''' |
| 109 class _AsyncStarStreamController { | 105 class _AsyncStarStreamController { |
| 110 constructor(generator, T, args) { | 106 constructor(generator, T, args) { |
| 111 this.isAdding = false; | 107 this.isAdding = false; |
| 112 this.isWaiting = false; | 108 this.isWaiting = false; |
| 113 this.isScheduled = false; | 109 this.isScheduled = false; |
| 114 this.isSuspendedAtYield = false; | 110 this.isSuspendedAtYield = false; |
| 115 this.canceler = null; | 111 this.canceler = null; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 238 // with the error. | 234 // with the error. |
| 239 this.canceler.completeError(error, stackTrace); | 235 this.canceler.completeError(error, stackTrace); |
| 240 return; | 236 return; |
| 241 } | 237 } |
| 242 if (!this.controller.hasListener) return; | 238 if (!this.controller.hasListener) return; |
| 243 this.controller.addError(error, stackTrace); | 239 this.controller.addError(error, stackTrace); |
| 244 } | 240 } |
| 245 } | 241 } |
| 246 '''); | 242 '''); |
| 247 | 243 |
| 248 /// Returns a Stream of T implemented by an async* function. */ | 244 /// Returns a Stream of T implemented by an async* function. |
| 249 /// | 245 asyncStar(gen, T, @rest args) => JS('', 'new #(#, #, #).controller.stream', |
|
vsm
2017/06/12 19:39:31
Do we need a '.new' here on the constructor?
Jennifer Messerly
2017/06/12 22:19:34
we don't because it's a JavaScript class not a Dar
| |
| 250 asyncStar(gen, T, @rest args) => JS( | 246 _AsyncStarStreamController, gen, T, args); |
| 251 '', | |
| 252 '''(() => { | |
| 253 return new $_AsyncStarStreamController($gen, $T, $args).controller.stream; | |
| 254 })()'''); | |
| OLD | NEW |