Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 import "dart:math"; | 5 import "dart:math"; |
| 6 import "dart:typed_data"; | 6 import "dart:typed_data"; |
| 7 | 7 |
| 8 // We need to pass the exception and stack trace objects as second and third | 8 // We need to pass the exception and stack trace objects as second and third |
| 9 // parameter to the continuation. See vm/ast_transformer.cc for usage. | 9 // parameter to the continuation. See vm/ast_transformer.cc for usage. |
| 10 void _asyncCatchHelper(catchFunction, continuation) { | 10 void _asyncCatchHelper(catchFunction, continuation) { |
| 11 catchFunction((e, s) => continuation(null, e, s)); | 11 catchFunction((e, s) => continuation(null, e, s)); |
| 12 } | 12 } |
| 13 | 13 |
| 14 // The members of this class are cloned and added to each class that | 14 // The members of this class are cloned and added to each class that |
| 15 // represents an enum type. | 15 // represents an enum type. |
| 16 class _EnumHelper { | 16 class _EnumHelper { |
| 17 // Declare the list of enum value names private. When this field is | 17 // Declare the list of enum value names private. When this field is |
| 18 // cloned into a user-defined enum class, the field will be inaccessible | 18 // cloned into a user-defined enum class, the field will be inaccessible |
| 19 // because of the library-specific name suffix. The toString() function | 19 // because of the library-specific name suffix. The toString() function |
| 20 // below can access it because it uses the same name suffix. | 20 // below can access it because it uses the same name suffix. |
| 21 static const List<String> _enum_names = null; | 21 static const List<String> _enum_names = null; |
| 22 String toString() => _enum_names[index]; | 22 String toString() => _enum_names[index]; |
| 23 } | 23 } |
| 24 | 24 |
| 25 typedef bool SyncGeneratorCallback(Iterator iterator); | 25 |
| 26 // _AsyncStarStreamController is used by the compiler to implement | |
| 27 // async* generator functions. | |
| 28 class _AsyncStarStreamController { | |
| 29 StreamController controller; | |
| 30 Function asyncStarBody; | |
| 31 bool isCancelled = false; | |
|
Lasse Reichstein Nielsen
2015/02/24 13:12:34
"isCanceled"
I've recently been informed that one
hausner
2015/02/25 22:07:41
I'm using controller.hasListener now. Apparently t
| |
| 32 bool isAdding = false; | |
| 33 | |
| 34 Stream get stream => controller.stream; | |
| 35 | |
| 36 // Adds element to steam, returns true iff the caller should suspend | |
| 37 // execution of the generator. | |
| 38 bool add(event) { | |
| 39 // TODO(hausner): what is the expected behavior if the stream | |
| 40 // has been cancelled? | |
| 41 if (isCancelled) return true; | |
|
Lasse Reichstein Nielsen
2015/02/24 13:12:34
Since you are using a single-subscription controll
hausner
2015/02/25 22:07:41
Done.
| |
| 42 controller.add(event); | |
| 43 if (true) { | |
|
Lasse Reichstein Nielsen
2015/02/24 13:12:34
if (true) ?
hausner
2015/02/25 22:07:41
That was a way to have the dart2js and the spec-co
| |
| 44 // Always suspend. Matches dart2js implementation but not Spec. | |
| 45 scheduleMicrotask(asyncStarBody); | |
|
Lasse Reichstein Nielsen
2015/02/24 13:12:34
If the stream subscription is paused, you should n
hausner
2015/02/25 22:07:41
Done.
| |
| 46 return true; | |
| 47 } | |
| 48 // Tell caller to suspend the generator if the controller is paused. | |
| 49 return controller.isPaused; | |
| 50 } | |
| 51 | |
| 52 // Adds stream, tells caller to suspend execution of the generator | |
| 53 // function. The generator will be scheduled again when all of the | |
| 54 // elements of the added stream have been consumed. | |
| 55 bool addStream(Stream stream) { | |
| 56 // TODO(hausner): what is the expected behavior if the stream | |
| 57 // has been cancelled? | |
|
Lasse Reichstein Nielsen
2015/02/24 13:12:34
If controller.stream has been canceled or if the a
hausner
2015/02/25 22:07:41
Done.
| |
| 58 if (isCancelled) return true; | |
| 59 isAdding = true; | |
| 60 var whenDoneAdding = | |
| 61 controller.addStream(stream as Stream, cancelOnError: false); | |
| 62 whenDoneAdding.then((_) { | |
| 63 isAdding = false; | |
| 64 if (!controller.isPaused) { | |
| 65 scheduleMicrotask(asyncStarBody); | |
| 66 } | |
| 67 }); | |
| 68 return true; | |
| 69 } | |
| 70 | |
| 71 addError(error, stackTrace) { | |
| 72 controller.addError(error, stackTrace); | |
| 73 } | |
| 74 | |
| 75 close() { | |
| 76 controller.close(); | |
|
Lasse Reichstein Nielsen
2015/02/24 13:12:34
If the subscription was paused, you will need to s
hausner
2015/02/25 22:07:41
Done. One thing that is still sup-optimal: the con
| |
| 77 } | |
| 78 | |
| 79 _AsyncStarStreamController(this.asyncStarBody) { | |
| 80 controller = new StreamController(onListen: this.onListen, | |
| 81 onResume: this.onResume, | |
| 82 onCancel: this.onCancel); | |
| 83 } | |
| 84 | |
| 85 onListen() { | |
| 86 scheduleMicrotask(asyncStarBody); | |
| 87 } | |
| 88 | |
| 89 onResume() { | |
| 90 if (!isAdding) { | |
| 91 scheduleMicrotask(asyncStarBody); | |
|
Lasse Reichstein Nielsen
2015/02/24 13:12:34
You can get two onResumes in a row if someone does
hausner
2015/02/25 22:07:41
Acknowledged.
| |
| 92 } | |
| 93 } | |
| 94 | |
| 95 onCancel() { | |
| 96 isCancelled = true; | |
|
Lasse Reichstein Nielsen
2015/02/24 13:12:34
If the subscription was paused, you will need to s
hausner
2015/02/25 22:07:41
See comment above.
| |
| 97 } | |
| 98 } | |
| 99 | |
| 26 | 100 |
| 27 // _SyncIterable and _syncIterator are used by the compiler to | 101 // _SyncIterable and _syncIterator are used by the compiler to |
| 28 // implement sync* generator functions. A sync* generator allocates | 102 // implement sync* generator functions. A sync* generator allocates |
| 29 // and returns a new _SyncIterable object. | 103 // and returns a new _SyncIterable object. |
| 104 | |
| 105 typedef bool SyncGeneratorCallback(Iterator iterator); | |
| 106 | |
| 30 class _SyncIterable extends IterableBase { | 107 class _SyncIterable extends IterableBase { |
| 31 // moveNextFn is the closurized body of the generator function. | 108 // moveNextFn is the closurized body of the generator function. |
| 32 final SyncGeneratorCallback moveNextFn; | 109 final SyncGeneratorCallback moveNextFn; |
| 33 | 110 |
| 34 const _SyncIterable(this.moveNextFn); | 111 const _SyncIterable(this.moveNextFn); |
| 35 | 112 |
| 36 get iterator { | 113 get iterator { |
| 37 return new _SyncIterator(moveNextFn._clone()); | 114 return new _SyncIterator(moveNextFn._clone()); |
| 38 } | 115 } |
| 39 } | 116 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 67 if (isYieldEach) { | 144 if (isYieldEach) { |
| 68 // Spec mandates: it is a dynamic error if the class of [the object | 145 // Spec mandates: it is a dynamic error if the class of [the object |
| 69 // returned by yield*] does not implement Iterable. | 146 // returned by yield*] does not implement Iterable. |
| 70 yieldEachIterator = (current as Iterable).iterator; | 147 yieldEachIterator = (current as Iterable).iterator; |
| 71 continue; | 148 continue; |
| 72 } | 149 } |
| 73 return true; | 150 return true; |
| 74 } | 151 } |
| 75 } | 152 } |
| 76 } | 153 } |
| OLD | NEW |