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

Side by Side Diff: sdk/lib/async/stream_pipe.dart

Issue 11862008: Make Streams also cosider a thrown AsyncError a rethrow. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address reciew comments. Created 7 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « sdk/lib/async/stream_impl.dart ('k') | tests/lib/async/stream_controller_async_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of dart.async; 5 part of dart.async;
6 6
7 /** Utility function to create an [AsyncError] if [error] isn't one already. */
8 AsyncError _asyncError(Object error, Object stackTrace, [AsyncError cause]) {
9 if (error is AsyncError) return error;
10 if (cause == null) return new AsyncError(error, stackTrace);
11 return new AsyncError.withCause(error, stackTrace, cause);
12 }
13
14 /** Runs user code and takes actions depending on success or failure. */
15 _runUserCode(userCode(), onSuccess(value), onError(AsyncError error),
16 { AsyncError cause }) {
17 var result;
18 try {
19 result = userCode();
20 } on AsyncError catch (e) {
21 return onError(e);
22 } catch (e, s) {
23 if (cause == null) {
24 onError(new AsyncError(e, s));
25 } else {
26 onError(new AsyncError.withCause(e, s, cause));
27 }
28 }
29 onSuccess(result);
30 }
31
32 /** Helper function to make an onError argument to [_runUserCode]. */
33 _cancelAndError(StreamSubscription subscription, _FutureImpl future) =>
34 (AsyncError error) {
35 subscription.cancel();
36 future._setError(error);
37 };
38
39
7 /** 40 /**
8 * A wrapper around a stream that allows independent subscribers. 41 * A wrapper around a stream that allows independent subscribers.
9 * 42 *
10 * By default [this] subscribes to [_source] and forwards all events to its own 43 * By default [this] subscribes to [_source] and forwards all events to its own
11 * subscribers. It does not subscribe until there is a subscriber, and 44 * subscribers. It does not subscribe until there is a subscriber, and
12 * unsubscribes again when there are no subscribers left. 45 * unsubscribes again when there are no subscribers left.
13 * 46 *
14 * The events are passed through the [_handleData], [_handleError] and 47 * The events are passed through the [_handleData], [_handleError] and
15 * [_handleDone] methods. Subclasses are supposed to add handling of some of 48 * [_handleDone] methods. Subclasses are supposed to add handling of some of
16 * the events by overriding these methods. 49 * the events by overriding these methods.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 101
69 void _handleDone() { 102 void _handleDone() {
70 _close(); 103 _close();
71 } 104 }
72 } 105 }
73 106
74 107
75 abstract class _ForwardingTransformer<S, T> extends _ForwardingMultiStream<S, T> 108 abstract class _ForwardingTransformer<S, T> extends _ForwardingMultiStream<S, T>
76 implements StreamTransformer<S, T> { 109 implements StreamTransformer<S, T> {
77 Stream<T> bind(Stream<S> source) { 110 Stream<T> bind(Stream<S> source) {
78 assert(_source == null); 111 if (_source != null) throw new StateError("Already bound to source.");
79 _source = source; 112 _source = source;
80 if (_hasSubscribers) { 113 if (_hasSubscribers) {
81 _subscribeToSource(); 114 _subscribeToSource();
82 } 115 }
83 return this; 116 return this;
84 } 117 }
85 } 118 }
86 119
87 // ------------------------------------------------------------------- 120 // -------------------------------------------------------------------
88 // Stream transformers used by the default Stream implementation. 121 // Stream transformers used by the default Stream implementation.
89 // ------------------------------------------------------------------- 122 // -------------------------------------------------------------------
90 123
91 typedef bool _Predicate<T>(T value); 124 typedef bool _Predicate<T>(T value);
92 125
93 class WhereStream<T> extends _ForwardingTransformer<T, T> { 126 class WhereStream<T> extends _ForwardingTransformer<T, T> {
94 final _Predicate<T> _test; 127 final _Predicate<T> _test;
95 128
96 WhereStream(bool test(T value)) 129 WhereStream(bool test(T value))
97 : this._test = test; 130 : this._test = test;
98 131
99 void _handleData(T inputEvent) { 132 void _handleData(T inputEvent) {
100 bool satisfies; 133 bool satisfies;
101 try { 134 try {
102 satisfies = _test(inputEvent); 135 satisfies = _test(inputEvent);
103 } catch (e, s) { 136 } catch (e, s) {
104 _signalError(new AsyncError(e, s)); 137 _signalError(_asyncError(e, s));
105 return; 138 return;
106 } 139 }
107 if (satisfies) { 140 if (satisfies) {
108 _add(inputEvent); 141 _add(inputEvent);
109 } 142 }
110 } 143 }
111 } 144 }
112 145
113 146
114 typedef T _Transformation<S, T>(S value); 147 typedef T _Transformation<S, T>(S value);
115 148
116 /** 149 /**
117 * A stream pipe that converts data events before passing them on. 150 * A stream pipe that converts data events before passing them on.
118 */ 151 */
119 class MapStream<S, T> extends _ForwardingTransformer<S, T> { 152 class MapStream<S, T> extends _ForwardingTransformer<S, T> {
120 final _Transformation _transform; 153 final _Transformation _transform;
121 154
122 MapStream(T transform(S event)) 155 MapStream(T transform(S event))
123 : this._transform = transform; 156 : this._transform = transform;
124 157
125 void _handleData(S inputEvent) { 158 void _handleData(S inputEvent) {
126 T outputEvent; 159 T outputEvent;
127 try { 160 try {
128 outputEvent = _transform(inputEvent); 161 outputEvent = _transform(inputEvent);
129 } catch (e, s) { 162 } catch (e, s) {
130 _signalError(new AsyncError(e, s)); 163 _signalError(_asyncError(e, s));
131 return; 164 return;
132 } 165 }
133 _add(outputEvent); 166 _add(outputEvent);
134 } 167 }
135 } 168 }
136 169
137 /** 170 /**
138 * A stream pipe that converts data events before passing them on. 171 * A stream pipe that converts data events before passing them on.
139 */ 172 */
140 class ExpandStream<S, T> extends _ForwardingTransformer<S, T> { 173 class ExpandStream<S, T> extends _ForwardingTransformer<S, T> {
141 final _Transformation<S, Iterable<T>> _expand; 174 final _Transformation<S, Iterable<T>> _expand;
142 175
143 ExpandStream(Iterable<T> expand(S event)) 176 ExpandStream(Iterable<T> expand(S event))
144 : this._expand = expand; 177 : this._expand = expand;
145 178
146 void _handleData(S inputEvent) { 179 void _handleData(S inputEvent) {
147 try { 180 try {
148 for (T value in _expand(inputEvent)) { 181 for (T value in _expand(inputEvent)) {
149 _add(value); 182 _add(value);
150 } 183 }
151 } catch (e, s) { 184 } catch (e, s) {
152 // If either _expand or iterating the generated iterator throws, 185 // If either _expand or iterating the generated iterator throws,
153 // we abort the iteration. 186 // we abort the iteration.
154 _signalError(new AsyncError(e, s)); 187 _signalError(_asyncError(e, s));
155 } 188 }
156 } 189 }
157 } 190 }
158 191
159 192
160 typedef AsyncError _ErrorTransformation(AsyncError error); 193 typedef void _ErrorTransformation(AsyncError error);
194 typedef bool _ErrorTest(error);
161 195
162 /** 196 /**
163 * A stream pipe that converts or disposes error events 197 * A stream pipe that converts or disposes error events
164 * before passing them on. 198 * before passing them on.
165 */ 199 */
166 class HandleErrorStream<T> extends _ForwardingTransformer<T, T> { 200 class HandleErrorStream<T> extends _ForwardingTransformer<T, T> {
167 final _ErrorTransformation _transform; 201 final _ErrorTransformation _transform;
202 final _ErrorTest _test;
168 203
169 HandleErrorStream(AsyncError transform(AsyncError event)) 204 HandleErrorStream(void transform(AsyncError event), bool test(error))
170 : this._transform = transform; 205 : this._transform = transform, this._test = test;
171 206
172 void _handleError(AsyncError error) { 207 void _handleError(AsyncError error) {
173 try { 208 bool matches = true;
174 error = _transform(error); 209 if (_test != null) {
175 if (error == null) return; 210 try {
176 } catch (e, s) { 211 matches = _test(error.error);
177 error = new AsyncError.withCause(e, s, error); 212 } catch (e, s) {
213 _signalError(_asyncError(e, s, error));
214 return;
215 }
178 } 216 }
179 _signalError(error); 217 if (matches) {
218 try {
219 _transform(error);
220 } catch (e, s) {
221 _signalError(_asyncError(e, s, error));
222 return;
223 }
224 } else {
225 _signalError(error);
226 }
180 } 227 }
181 } 228 }
182 229
183 230
184 typedef void _TransformDataHandler<S, T>(S data, StreamSink<T> sink); 231 typedef void _TransformDataHandler<S, T>(S data, StreamSink<T> sink);
185 typedef void _TransformErrorHandler<T>(AsyncError data, StreamSink<T> sink); 232 typedef void _TransformErrorHandler<T>(AsyncError data, StreamSink<T> sink);
186 typedef void _TransformDoneHandler<T>(StreamSink<T> sink); 233 typedef void _TransformDoneHandler<T>(StreamSink<T> sink);
187 234
188 /** 235 /**
189 * A stream pipe that intercepts all events and can generate any event as 236 * A stream pipe that intercepts all events and can generate any event as
(...skipping 17 matching lines...) Expand all
207 this._onError = (onError == null ? _defaultHandleError : onError), 254 this._onError = (onError == null ? _defaultHandleError : onError),
208 this._onDone = (onDone == null ? _defaultHandleDone : onDone) { 255 this._onDone = (onDone == null ? _defaultHandleDone : onDone) {
209 // Cache the sink wrapper to avoid creating a new one for each event. 256 // Cache the sink wrapper to avoid creating a new one for each event.
210 this._sink = new _StreamImplSink(this); 257 this._sink = new _StreamImplSink(this);
211 } 258 }
212 259
213 void _handleData(S data) { 260 void _handleData(S data) {
214 try { 261 try {
215 return _onData(data, _sink); 262 return _onData(data, _sink);
216 } catch (e, s) { 263 } catch (e, s) {
217 _signalError(new AsyncError(e, s)); 264 _signalError(_asyncError(e, s));
218 } 265 }
219 } 266 }
220 267
221 void _handleError(AsyncError error) { 268 void _handleError(AsyncError error) {
222 try { 269 try {
223 _onError(error, _sink); 270 _onError(error, _sink);
224 } catch (e, s) { 271 } catch (e, s) {
225 _signalError(new AsyncError.withCause(e, s, error)); 272 _signalError(_asyncError(e, s, error));
226 } 273 }
227 } 274 }
228 275
229 void _handleDone() { 276 void _handleDone() {
230 try { 277 try {
231 _onDone(_sink); 278 _onDone(_sink);
232 } catch (e, s) { 279 } catch (e, s) {
233 _signalError(new AsyncError(e, s)); 280 _signalError(_asyncError(e, s));
234 } 281 }
235 } 282 }
236 283
237 /** Default data handler forwards all data. */ 284 /** Default data handler forwards all data. */
238 static void _defaultHandleData(dynamic data, StreamSink sink) { 285 static void _defaultHandleData(dynamic data, StreamSink sink) {
239 sink.add(data); 286 sink.add(data);
240 } 287 }
241 /** Default error handler forwards all errors. */ 288 /** Default error handler forwards all errors. */
242 static void _defaultHandleError(AsyncError error, StreamSink sink) { 289 static void _defaultHandleError(AsyncError error, StreamSink sink) {
243 sink.signalError(error); 290 sink.signalError(error);
(...skipping 29 matching lines...) Expand all
273 TransformStream(StreamTransformer<S, T> transform) 320 TransformStream(StreamTransformer<S, T> transform)
274 : this._transform = transform { 321 : this._transform = transform {
275 // Cache the sink wrapper to avoid creating a new one for each event. 322 // Cache the sink wrapper to avoid creating a new one for each event.
276 this._sink = new _StreamImplSink(this); 323 this._sink = new _StreamImplSink(this);
277 } 324 }
278 325
279 void _handleData(S data) { 326 void _handleData(S data) {
280 try { 327 try {
281 return _transform.handleData(data, _sink); 328 return _transform.handleData(data, _sink);
282 } catch (e, s) { 329 } catch (e, s) {
283 _controller.signalError(new AsyncError(e, s)); 330 _controller.signalError(_asyncError(e, s));
284 } 331 }
285 } 332 }
286 333
287 void _handleError(AsyncError error) { 334 void _handleError(AsyncError error) {
288 try { 335 try {
289 _transform.handleError(error, _sink); 336 _transform.handleError(error, _sink);
290 } catch (e, s) { 337 } catch (e, s) {
291 _controller.signalError(new AsyncError.withCause(e, s, error)); 338 _controller.signalError(_asyncError(e, s, error));
292 } 339 }
293 } 340 }
294 341
295 void _handleDone() { 342 void _handleDone() {
296 try { 343 try {
297 _transform.handleDone(_sink); 344 _transform.handleDone(_sink);
298 } catch (e, s) { 345 } catch (e, s) {
299 _controller.signalError(new AsyncError(e, s)); 346 _controller.signalError(_asyncError(e, s));
300 } 347 }
301 } 348 }
302 } 349 }
303 350
304 351
305 /** Helper class for transforming three functions into a StreamTransformer. */ 352 /** Helper class for transforming three functions into a StreamTransformer. */
306 class _StreamTransformerFunctionWrapper<S, T> 353 class _StreamTransformerFunctionWrapper<S, T>
307 extends _StreamTransformer<S, T> { 354 extends _StreamTransformer<S, T> {
308 final _TransformDataHandler<S, T> _handleData; 355 final _TransformDataHandler<S, T> _handleData;
309 final _TransformErrorHandler<T> _handleError; 356 final _TransformErrorHandler<T> _handleError;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 final _Predicate<T> _test; 407 final _Predicate<T> _test;
361 408
362 TakeWhileStream(bool test(T value)) 409 TakeWhileStream(bool test(T value))
363 : this._test = test; 410 : this._test = test;
364 411
365 void _handleData(T inputEvent) { 412 void _handleData(T inputEvent) {
366 bool satisfies; 413 bool satisfies;
367 try { 414 try {
368 satisfies = _test(inputEvent); 415 satisfies = _test(inputEvent);
369 } catch (e, s) { 416 } catch (e, s) {
370 _signalError(new AsyncError(e, s)); 417 _signalError(_asyncError(e, s));
371 // The test didn't say true. Didn't say false either, but we stop anyway. 418 // The test didn't say true. Didn't say false either, but we stop anyway.
372 _close(); 419 _close();
373 return; 420 return;
374 } 421 }
375 if (satisfies) { 422 if (satisfies) {
376 _add(inputEvent); 423 _add(inputEvent);
377 } else { 424 } else {
378 _close(); 425 _close();
379 } 426 }
380 } 427 }
(...skipping 26 matching lines...) Expand all
407 : this._test = test; 454 : this._test = test;
408 455
409 void _handleData(T inputEvent) { 456 void _handleData(T inputEvent) {
410 if (_hasFailed) { 457 if (_hasFailed) {
411 _add(inputEvent); 458 _add(inputEvent);
412 } 459 }
413 bool satisfies; 460 bool satisfies;
414 try { 461 try {
415 satisfies = _test(inputEvent); 462 satisfies = _test(inputEvent);
416 } catch (e, s) { 463 } catch (e, s) {
417 _signalError(new AsyncError(e, s)); 464 _signalError(_asyncError(e, s));
418 // A failure to return a boolean is considered "not matching". 465 // A failure to return a boolean is considered "not matching".
419 _hasFailed = true; 466 _hasFailed = true;
420 return; 467 return;
421 } 468 }
422 if (!satisfies) { 469 if (!satisfies) {
423 _hasFailed = true; 470 _hasFailed = true;
424 _add(inputEvent); 471 _add(inputEvent);
425 } 472 }
426 } 473 }
427 } 474 }
(...skipping 15 matching lines...) Expand all
443 return _add(inputEvent); 490 return _add(inputEvent);
444 } else { 491 } else {
445 bool isEqual; 492 bool isEqual;
446 try { 493 try {
447 if (_equals == null) { 494 if (_equals == null) {
448 isEqual = (_previous == inputEvent); 495 isEqual = (_previous == inputEvent);
449 } else { 496 } else {
450 isEqual = _equals(_previous, inputEvent); 497 isEqual = _equals(_previous, inputEvent);
451 } 498 }
452 } catch (e, s) { 499 } catch (e, s) {
453 _signalError(new AsyncError(e, s)); 500 _signalError(_asyncError(e, s));
454 return null; 501 return null;
455 } 502 }
456 if (!isEqual) { 503 if (!isEqual) {
457 _add(inputEvent); 504 _add(inputEvent);
458 _previous = inputEvent; 505 _previous = inputEvent;
459 } 506 }
460 } 507 }
461 } 508 }
462 } 509 }
OLDNEW
« no previous file with comments | « sdk/lib/async/stream_impl.dart ('k') | tests/lib/async/stream_controller_async_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698