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

Side by Side Diff: sdk/lib/core/future_impl.dart

Issue 11412139: Make exceptions propagate through multiple Future branches. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years 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 | « no previous file | tests/co19/co19-compiler.status » ('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 2012 Google Inc. All Rights Reserved. 1 // Copyright 2012 Google Inc. All Rights Reserved.
2 // Dart core library. 2 // Dart core library.
3 3
4 class _FutureImpl<T> implements Future<T> { 4 class _FutureImpl<T> implements Future<T> {
5 5
6 bool _isComplete = false; 6 bool _isComplete = false;
7 7
8 /** 8 /**
9 * Value that was provided to this Future by the Completer 9 * Value that was provided to this Future by the Completer
10 */ 10 */
11 T _value; 11 T _value;
12 12
13 /** 13 /**
14 * Exception that occured, if there was a problem providing 14 * Exception that occured, if there was a problem providing
15 * Value. 15 * Value.
16 */ 16 */
17 Object _exception; 17 Object _exception;
18 18
19 /** 19 /**
20 * Stack trace associated with [_exception], if one was provided. 20 * Stack trace associated with [_exception], if one was provided.
21 */ 21 */
22 Object _stackTrace; 22 Object _stackTrace;
23 23
24 /** 24 /**
25 * true, if any onException handler handled the exception. 25 * true, if any onException handler handled the exception.
26 */ 26 */
27 bool _exceptionHandled = false; 27 bool _exceptionHandled = false;
28 28
29 /** 29 /**
30 * true if an exception in this future should be thrown to the top level.
31 */
32 bool _throwOnException = false;
33
34 /**
30 * Listeners waiting to receive the value of this future. 35 * Listeners waiting to receive the value of this future.
31 */ 36 */
32 final List<Function> _successListeners; 37 final List<Function> _successListeners;
33 38
34 /** 39 /**
35 * Exception handlers waiting for exceptions. 40 * Exception handlers waiting for exceptions.
36 */ 41 */
37 final List<Function> _exceptionHandlers; 42 final List<Function> _exceptionHandlers;
38 43
39 /** 44 /**
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 } 86 }
82 87
83 bool get hasValue { 88 bool get hasValue {
84 return isComplete && _exception == null; 89 return isComplete && _exception == null;
85 } 90 }
86 91
87 void then(void onSuccess(T value)) { 92 void then(void onSuccess(T value)) {
88 if (hasValue) { 93 if (hasValue) {
89 onSuccess(value); 94 onSuccess(value);
90 } else if (!isComplete) { 95 } else if (!isComplete) {
96 _throwOnException = true;
91 _successListeners.add(onSuccess); 97 _successListeners.add(onSuccess);
92 } else if (!_exceptionHandled) { 98 } else if (!_exceptionHandled) {
93 throw new FutureUnhandledException(_exception, stackTrace); 99 throw new FutureUnhandledException(_exception, stackTrace);
94 } 100 }
95 } 101 }
96 102
103 void _handleSuccess(void onSuccess(T value)) {
104 if (hasValue) {
105 onSuccess(value);
106 } else if (!isComplete) {
107 _successListeners.add(onSuccess);
108 }
109 }
110
97 void handleException(bool onException(Object exception)) { 111 void handleException(bool onException(Object exception)) {
98 if (_exceptionHandled) return; 112 if (_exceptionHandled) return;
99 if (_isComplete) { 113 if (_isComplete) {
100 if (_exception != null) { 114 if (_exception != null) {
101 _exceptionHandled = onException(_exception); 115 _exceptionHandled = onException(_exception);
102 } 116 }
103 } else { 117 } else {
104 _exceptionHandlers.add(onException); 118 _exceptionHandlers.add(onException);
105 } 119 }
106 } 120 }
(...skipping 21 matching lines...) Expand all
128 break; 142 break;
129 } 143 }
130 } 144 }
131 } 145 }
132 146
133 if (hasValue) { 147 if (hasValue) {
134 for (Function listener in _successListeners) { 148 for (Function listener in _successListeners) {
135 listener(value); 149 listener(value);
136 } 150 }
137 } else { 151 } else {
138 if (!_exceptionHandled && _successListeners.length > 0) { 152 if (!_exceptionHandled && _throwOnException) {
139 throw new FutureUnhandledException(_exception, stackTrace); 153 throw new FutureUnhandledException(_exception, stackTrace);
140 } 154 }
141 } 155 }
142 } finally { 156 } finally {
143 for (Function listener in _completionListeners) { 157 for (Function listener in _completionListeners) {
144 try { 158 try {
145 listener(this); 159 listener(this);
146 } catch (e) {} 160 } catch (e) {}
147 } 161 }
148 } 162 }
(...skipping 18 matching lines...) Expand all
167 _exception = exception; 181 _exception = exception;
168 _stackTrace = stackTrace; 182 _stackTrace = stackTrace;
169 _complete(); 183 _complete();
170 } 184 }
171 185
172 Future transform(Function transformation) { 186 Future transform(Function transformation) {
173 final completer = new Completer(); 187 final completer = new Completer();
174 188
175 _forwardException(this, completer); 189 _forwardException(this, completer);
176 190
177 then((v) { 191 _handleSuccess((v) {
178 var transformed = null; 192 var transformed = null;
179 try { 193 try {
180 transformed = transformation(v); 194 transformed = transformation(v);
181 } catch (e, stackTrace) { 195 } catch (e, stackTrace) {
182 completer.completeException(e, stackTrace); 196 completer.completeException(e, stackTrace);
183 return; 197 return;
184 } 198 }
185 completer.complete(transformed); 199 completer.complete(transformed);
186 }); 200 });
187 201
188 return completer.future; 202 return completer.future;
189 } 203 }
190 204
191 Future chain(Function transformation) { 205 Future chain(Function transformation) {
192 final completer = new Completer(); 206 final completer = new Completer();
193 207
194 _forwardException(this, completer); 208 _forwardException(this, completer);
195 then((v) { 209 _handleSuccess((v) {
196 var future = null; 210 var future = null;
197 try { 211 try {
198 future = transformation(v); 212 future = transformation(v);
199 } catch (ex, stackTrace) { 213 } catch (ex, stackTrace) {
200 completer.completeException(ex, stackTrace); 214 completer.completeException(ex, stackTrace);
201 return; 215 return;
202 } 216 }
203 217
204 _forward(future, completer); 218 _forward(future, completer);
205 }); 219 });
(...skipping 10 matching lines...) Expand all
216 // If the transformation itself returns a future, then we will 230 // If the transformation itself returns a future, then we will
217 // complete to what that completes to. 231 // complete to what that completes to.
218 if (result is Future) { 232 if (result is Future) {
219 _forward(result, completer); 233 _forward(result, completer);
220 } else { 234 } else {
221 completer.complete(result); 235 completer.complete(result);
222 } 236 }
223 } catch (innerException, stackTrace) { 237 } catch (innerException, stackTrace) {
224 completer.completeException(innerException, stackTrace); 238 completer.completeException(innerException, stackTrace);
225 } 239 }
226 return true; 240 return false;
227 }); 241 });
228 242
229 then(completer.complete); 243 _handleSuccess(completer.complete);
230 244
231 return completer.future; 245 return completer.future;
232 } 246 }
233 247
234 /** 248 /**
235 * Forwards the success or error completion from [future] to [completer]. 249 * Forwards the success or error completion from [future] to [completer].
236 */ 250 */
237 _forward(Future future, Completer completer) { 251 _forward(Future future, Completer completer) {
238 _forwardException(future, completer); 252 _forwardException(future, completer);
239 future.then(completer.complete); 253 future._handleSuccess(completer.complete);
240 } 254 }
241 255
242 /** 256 /**
243 * Forwards the exception completion from [future] to [completer]. 257 * Forwards the exception completion from [future] to [completer].
244 */ 258 */
245 _forwardException(Future future, Completer completer) { 259 _forwardException(Future future, Completer completer) {
246 future.handleException((e) { 260 future.handleException((e) {
247 completer.completeException(e, future.stackTrace); 261 completer.completeException(e, future.stackTrace);
248 return true; 262 return false;
249 }); 263 });
250 } 264 }
251 } 265 }
252 266
253 class _CompleterImpl<T> implements Completer<T> { 267 class _CompleterImpl<T> implements Completer<T> {
254 268
255 final _FutureImpl<T> _futureImpl; 269 final _FutureImpl<T> _futureImpl;
256 270
257 _CompleterImpl() : _futureImpl = new _FutureImpl() {} 271 _CompleterImpl() : _futureImpl = new _FutureImpl() {}
258 272
259 Future<T> get future { 273 Future<T> get future {
260 return _futureImpl; 274 return _futureImpl;
261 } 275 }
262 276
263 void complete(T value) { 277 void complete(T value) {
264 _futureImpl._setValue(value); 278 _futureImpl._setValue(value);
265 } 279 }
266 280
267 void completeException(Object exception, [Object stackTrace]) { 281 void completeException(Object exception, [Object stackTrace]) {
268 _futureImpl._setException(exception, stackTrace); 282 _futureImpl._setException(exception, stackTrace);
269 } 283 }
270 } 284 }
271 285
OLDNEW
« no previous file with comments | « no previous file | tests/co19/co19-compiler.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698