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 // Equivalent of calling FATAL from C++ code. | 8 // Equivalent of calling FATAL from C++ code. |
| 9 _fatal(msg) native "DartCore_fatal"; | 9 _fatal(msg) native "DartCore_fatal"; |
| 10 | 10 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 | 29 |
| 30 | 30 |
| 31 // _AsyncStarStreamController is used by the compiler to implement | 31 // _AsyncStarStreamController is used by the compiler to implement |
| 32 // async* generator functions. | 32 // async* generator functions. |
| 33 class _AsyncStarStreamController { | 33 class _AsyncStarStreamController { |
| 34 StreamController controller; | 34 StreamController controller; |
| 35 Function asyncStarBody; | 35 Function asyncStarBody; |
| 36 bool isAdding = false; | 36 bool isAdding = false; |
| 37 bool onListenReceived = false; | 37 bool onListenReceived = false; |
| 38 bool isScheduled = false; | 38 bool isScheduled = false; |
| 39 Completer cancellationCompleter = null; | |
| 39 | 40 |
| 40 Stream get stream => controller.stream; | 41 Stream get stream => controller.stream; |
| 41 | 42 |
| 42 void runBody() { | 43 void runBody() { |
| 43 isScheduled = false; | 44 isScheduled = false; |
| 44 asyncStarBody(); | 45 asyncStarBody(); |
| 45 } | 46 } |
| 46 | 47 |
| 47 void scheduleGenerator() { | 48 void scheduleGenerator() { |
| 48 if (isScheduled || controller.isPaused || isAdding) { | 49 if (isScheduled || controller.isPaused || isAdding) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 86 var whenDoneAdding = | 87 var whenDoneAdding = |
| 87 controller.addStream(stream as Stream, cancelOnError: false); | 88 controller.addStream(stream as Stream, cancelOnError: false); |
| 88 whenDoneAdding.then((_) { | 89 whenDoneAdding.then((_) { |
| 89 isAdding = false; | 90 isAdding = false; |
| 90 scheduleGenerator(); | 91 scheduleGenerator(); |
| 91 }); | 92 }); |
| 92 return false; | 93 return false; |
| 93 } | 94 } |
| 94 | 95 |
| 95 void addError(error, stackTrace) { | 96 void addError(error, stackTrace) { |
| 97 if ((cancellationCompleter != null && | |
|
regis
2015/03/24 23:46:27
Redundant pair of parenthesis
hausner
2015/03/24 23:57:29
Done.
| |
| 98 !cancellationCompleter.isCompleted)) { | |
| 99 // If the stream has been cancelled, complete the cancellation future | |
| 100 // with the error. | |
| 101 cancellationCompleter.completeError(error, stackTrace); | |
| 102 return; | |
| 103 } | |
| 96 // If stream is cancelled, tell caller to exit the async generator. | 104 // If stream is cancelled, tell caller to exit the async generator. |
| 97 if (!controller.hasListener) return; | 105 if (!controller.hasListener) return; |
| 98 controller.addError(error, stackTrace); | 106 controller.addError(error, stackTrace); |
| 99 // No need to schedule the generator body here. This code is only | 107 // No need to schedule the generator body here. This code is only |
| 100 // called from the catch clause of the implicit try-catch-finally | 108 // called from the catch clause of the implicit try-catch-finally |
| 101 // around the generator body. That is, we are on the error path out | 109 // around the generator body. That is, we are on the error path out |
| 102 // of the generator and do not need to run the generator again. | 110 // of the generator and do not need to run the generator again. |
| 103 } | 111 } |
| 104 | 112 |
| 105 close() { | 113 close() { |
| 114 if ((cancellationCompleter != null) && | |
|
regis
2015/03/24 23:46:27
ditto
hausner
2015/03/24 23:57:29
This one actually had the closing paren in the rig
| |
| 115 !cancellationCompleter.isCompleted) { | |
| 116 // If the stream has been cancelled, complete the cancellation future | |
| 117 // with the error. | |
| 118 cancellationCompleter.complete(); | |
| 119 } | |
| 106 controller.close(); | 120 controller.close(); |
| 107 } | 121 } |
| 108 | 122 |
| 109 _AsyncStarStreamController(this.asyncStarBody) { | 123 _AsyncStarStreamController(this.asyncStarBody) { |
| 110 controller = new StreamController(onListen: this.onListen, | 124 controller = new StreamController(onListen: this.onListen, |
| 111 onResume: this.onResume, | 125 onResume: this.onResume, |
| 112 onCancel: this.onCancel); | 126 onCancel: this.onCancel); |
| 113 } | 127 } |
| 114 | 128 |
| 115 onListen() { | 129 onListen() { |
| 116 assert(!onListenReceived); | 130 assert(!onListenReceived); |
| 117 onListenReceived = true; | 131 onListenReceived = true; |
| 118 scheduleGenerator(); | 132 scheduleGenerator(); |
| 119 } | 133 } |
| 120 | 134 |
| 121 onResume() { | 135 onResume() { |
| 122 scheduleGenerator(); | 136 scheduleGenerator(); |
| 123 } | 137 } |
| 124 | 138 |
| 125 onCancel() { | 139 onCancel() { |
| 126 scheduleGenerator(); | 140 if (controller.isClosed) { |
| 141 return null; | |
| 142 } | |
| 143 if (cancellationCompleter == null) { | |
| 144 cancellationCompleter = new Completer(); | |
| 145 scheduleGenerator(); | |
| 146 } | |
| 147 return cancellationCompleter.future; | |
| 127 } | 148 } |
| 128 } | 149 } |
| 129 | 150 |
| 130 | 151 |
| 131 // _SyncIterable and _syncIterator are used by the compiler to | 152 // _SyncIterable and _syncIterator are used by the compiler to |
| 132 // implement sync* generator functions. A sync* generator allocates | 153 // implement sync* generator functions. A sync* generator allocates |
| 133 // and returns a new _SyncIterable object. | 154 // and returns a new _SyncIterable object. |
| 134 | 155 |
| 135 typedef bool SyncGeneratorCallback(Iterator iterator); | 156 typedef bool SyncGeneratorCallback(Iterator iterator); |
| 136 | 157 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 174 if (isYieldEach) { | 195 if (isYieldEach) { |
| 175 // Spec mandates: it is a dynamic error if the class of [the object | 196 // Spec mandates: it is a dynamic error if the class of [the object |
| 176 // returned by yield*] does not implement Iterable. | 197 // returned by yield*] does not implement Iterable. |
| 177 yieldEachIterator = (current as Iterable).iterator; | 198 yieldEachIterator = (current as Iterable).iterator; |
| 178 continue; | 199 continue; |
| 179 } | 200 } |
| 180 return true; | 201 return true; |
| 181 } | 202 } |
| 182 } | 203 } |
| 183 } | 204 } |
| OLD | NEW |