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 part of dart.async; | 5 part of dart.async; |
6 | 6 |
7 typedef R ZoneCallback<R>(); | 7 typedef R ZoneCallback<R>(); |
8 typedef R ZoneUnaryCallback<R, T>(T arg); | 8 typedef R ZoneUnaryCallback<R, T>(T arg); |
9 typedef R ZoneBinaryCallback<R, T1, T2>(T1 arg1, T2 arg2); | 9 typedef R ZoneBinaryCallback<R, T1, T2>(T1 arg1, T2 arg2); |
10 | 10 |
11 typedef HandleUncaughtErrorHandler = void Function(Zone self, | 11 // TODO(floitsch): we are abusing generic typedefs as typedefs for generic |
12 ZoneDelegate parent, Zone zone, Object error, StackTrace stackTrace); | 12 // functions. |
13 typedef RunHandler = R Function<R>( | 13 /*ABUSE*/ |
14 Zone self, ZoneDelegate parent, Zone zone, R Function() f); | 14 typedef R HandleUncaughtErrorHandler<R>( |
15 typedef RunUnaryHandler = R Function<R, T>( | 15 Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace); |
16 Zone self, ZoneDelegate parent, Zone zone, R Function(T arg) f, T arg); | 16 /*ABUSE*/ |
17 typedef RunBinaryHandler = R Function<R, T1, T2>(Zone self, ZoneDelegate parent, | 17 typedef R RunHandler<R>(Zone self, ZoneDelegate parent, Zone zone, R f()); |
18 Zone zone, R Function(T1 arg1, T2 arg2) f, T1 arg1, T2 arg2); | 18 /*ABUSE*/ |
19 typedef RegisterCallbackHandler = ZoneCallback<R> Function<R>( | 19 typedef R RunUnaryHandler<R, T>( |
20 Zone self, ZoneDelegate parent, Zone zone, R Function() f); | 20 Zone self, ZoneDelegate parent, Zone zone, R f(T arg), T arg); |
21 typedef RegisterUnaryCallbackHandler = ZoneUnaryCallback<R, T> Function<R, T>( | 21 /*ABUSE*/ |
22 Zone self, ZoneDelegate parent, Zone zone, R Function(T arg) f); | 22 typedef R RunBinaryHandler<R, T1, T2>(Zone self, ZoneDelegate parent, Zone zone, |
23 typedef RegisterBinaryCallbackHandler | 23 R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2); |
24 = ZoneBinaryCallback<R, T1, T2> Function<R, T1, T2>(Zone self, | 24 /*ABUSE*/ |
25 ZoneDelegate parent, Zone zone, R Function(T1 arg1, T2 arg2) f); | 25 typedef ZoneCallback<R> RegisterCallbackHandler<R>( |
| 26 Zone self, ZoneDelegate parent, Zone zone, R f()); |
| 27 /*ABUSE*/ |
| 28 typedef ZoneUnaryCallback<R, T> RegisterUnaryCallbackHandler<R, T>( |
| 29 Zone self, ZoneDelegate parent, Zone zone, R f(T arg)); |
| 30 /*ABUSE*/ |
| 31 typedef ZoneBinaryCallback<R, T1, T2> RegisterBinaryCallbackHandler<R, T1, T2>( |
| 32 Zone self, ZoneDelegate parent, Zone zone, R f(T1 arg1, T2 arg2)); |
26 typedef AsyncError ErrorCallbackHandler(Zone self, ZoneDelegate parent, | 33 typedef AsyncError ErrorCallbackHandler(Zone self, ZoneDelegate parent, |
27 Zone zone, Object error, StackTrace stackTrace); | 34 Zone zone, Object error, StackTrace stackTrace); |
28 typedef void ScheduleMicrotaskHandler( | 35 typedef void ScheduleMicrotaskHandler( |
29 Zone self, ZoneDelegate parent, Zone zone, void f()); | 36 Zone self, ZoneDelegate parent, Zone zone, void f()); |
30 typedef Timer CreateTimerHandler( | 37 typedef Timer CreateTimerHandler( |
31 Zone self, ZoneDelegate parent, Zone zone, Duration duration, void f()); | 38 Zone self, ZoneDelegate parent, Zone zone, Duration duration, void f()); |
32 typedef Timer CreatePeriodicTimerHandler(Zone self, ZoneDelegate parent, | 39 typedef Timer CreatePeriodicTimerHandler(Zone self, ZoneDelegate parent, |
33 Zone zone, Duration period, void f(Timer timer)); | 40 Zone zone, Duration period, void f(Timer timer)); |
34 typedef void PrintHandler( | 41 typedef void PrintHandler( |
35 Zone self, ZoneDelegate parent, Zone zone, String line); | 42 Zone self, ZoneDelegate parent, Zone zone, String line); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 * | 202 * |
196 * While zones have access to their parent zone (through [Zone.parent]) it is | 203 * While zones have access to their parent zone (through [Zone.parent]) it is |
197 * recommended to call the methods on the provided parent delegate for two | 204 * recommended to call the methods on the provided parent delegate for two |
198 * reasons: | 205 * reasons: |
199 * 1. the delegate methods take an additional `zone` argument which is the | 206 * 1. the delegate methods take an additional `zone` argument which is the |
200 * zone the action has been initiated in. | 207 * zone the action has been initiated in. |
201 * 2. delegate calls are more efficient, since the implementation knows how | 208 * 2. delegate calls are more efficient, since the implementation knows how |
202 * to skip zones that would just delegate to their parents. | 209 * to skip zones that would just delegate to their parents. |
203 */ | 210 */ |
204 abstract class ZoneDelegate { | 211 abstract class ZoneDelegate { |
205 void handleUncaughtError(Zone zone, error, StackTrace stackTrace); | 212 R handleUncaughtError<R>(Zone zone, error, StackTrace stackTrace); |
206 R run<R>(Zone zone, R f()); | 213 R run<R>(Zone zone, R f()); |
207 R runUnary<R, T>(Zone zone, R f(T arg), T arg); | 214 R runUnary<R, T>(Zone zone, R f(T arg), T arg); |
208 R runBinary<R, T1, T2>(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2); | 215 R runBinary<R, T1, T2>(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2); |
209 ZoneCallback<R> registerCallback<R>(Zone zone, R f()); | 216 ZoneCallback<R> registerCallback<R>(Zone zone, R f()); |
210 ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(Zone zone, R f(T arg)); | 217 ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(Zone zone, R f(T arg)); |
211 ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( | 218 ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( |
212 Zone zone, R f(T1 arg1, T2 arg2)); | 219 Zone zone, R f(T1 arg1, T2 arg2)); |
213 AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace); | 220 AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace); |
214 void scheduleMicrotask(Zone zone, void f()); | 221 void scheduleMicrotask(Zone zone, void f()); |
215 Timer createTimer(Zone zone, Duration duration, void f()); | 222 Timer createTimer(Zone zone, Duration duration, void f()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 * also remembers the current zone so that it can later run the callback in | 256 * also remembers the current zone so that it can later run the callback in |
250 * that zone. | 257 * that zone. |
251 * 2. At a later point the registered callback is run in the remembered zone. | 258 * 2. At a later point the registered callback is run in the remembered zone. |
252 * | 259 * |
253 * This is all handled internally by the platform code and most users don't need | 260 * This is all handled internally by the platform code and most users don't need |
254 * to worry about it. However, developers of new asynchronous operations, | 261 * to worry about it. However, developers of new asynchronous operations, |
255 * provided by the underlying system or through native extensions, must follow | 262 * provided by the underlying system or through native extensions, must follow |
256 * the protocol to be zone compatible. | 263 * the protocol to be zone compatible. |
257 * | 264 * |
258 * For convenience, zones provide [bindCallback] (and the corresponding | 265 * For convenience, zones provide [bindCallback] (and the corresponding |
259 * [bindUnaryCallback] and [bindBinaryCallback]) to make it easier to respect | 266 * [bindUnaryCallback] or [bindBinaryCallback]) to make it easier to respect the |
260 * the zone contract: these functions first invoke the corresponding `register` | 267 * zone contract: these functions first invoke the corresponding `register` |
261 * functions and then wrap the returned function so that it runs in the current | 268 * functions and then wrap the returned function so that it runs in the current |
262 * zone when it is later asynchronously invoked. | 269 * zone when it is later asynchronously invoked. |
263 * | |
264 * Similarly, zones provide [bindCallbackGuarded] (and the corresponding | |
265 * [bindUnaryCallbackGuarded] and [bindBinaryCallbackGuarded]), when the | |
266 * callback should be invoked through [Zone.runGuarded]. | |
267 */ | 270 */ |
268 abstract class Zone { | 271 abstract class Zone { |
269 // Private constructor so that it is not possible instantiate a Zone class. | 272 // Private constructor so that it is not possible instantiate a Zone class. |
270 Zone._(); | 273 Zone._(); |
271 | 274 |
272 /** | 275 /** |
273 * The root zone. | 276 * The root zone. |
274 * | 277 * |
275 * All isolate entry functions (`main` or spawned functions) start running in | 278 * All isolate entry functions (`main` or spawned functions) start running in |
276 * the root zone (that is, [Zone.current] is identical to [Zone.ROOT] when the | 279 * the root zone (that is, [Zone.current] is identical to [Zone.ROOT] when the |
(...skipping 25 matching lines...) Expand all Loading... |
302 * chains, but for which no child registered an error handler. | 305 * chains, but for which no child registered an error handler. |
303 * Most asynchronous classes, like [Future] or [Stream] push errors to their | 306 * Most asynchronous classes, like [Future] or [Stream] push errors to their |
304 * listeners. Errors are propagated this way until either a listener handles | 307 * listeners. Errors are propagated this way until either a listener handles |
305 * the error (for example with [Future.catchError]), or no listener is | 308 * the error (for example with [Future.catchError]), or no listener is |
306 * available anymore. In the latter case, futures and streams invoke the | 309 * available anymore. In the latter case, futures and streams invoke the |
307 * zone's [handleUncaughtError]. | 310 * zone's [handleUncaughtError]. |
308 * | 311 * |
309 * By default, when handled by the root zone, uncaught asynchronous errors are | 312 * By default, when handled by the root zone, uncaught asynchronous errors are |
310 * treated like uncaught synchronous exceptions. | 313 * treated like uncaught synchronous exceptions. |
311 */ | 314 */ |
312 void handleUncaughtError(error, StackTrace stackTrace); | 315 R handleUncaughtError<R>(error, StackTrace stackTrace); |
313 | 316 |
314 /** | 317 /** |
315 * The parent zone of the this zone. | 318 * The parent zone of the this zone. |
316 * | 319 * |
317 * Is `null` if `this` is the [ROOT] zone. | 320 * Is `null` if `this` is the [ROOT] zone. |
318 * | 321 * |
319 * Zones are created by [fork] on an existing zone, or by [runZoned] which | 322 * Zones are created by [fork] on an existing zone, or by [runZoned] which |
320 * forks the [current] zone. The new zone's parent zone is the zone it was | 323 * forks the [current] zone. The new zone's parent zone is the zone it was |
321 * forked from. | 324 * forked from. |
322 */ | 325 */ |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 R runBinary<R, T1, T2>( | 431 R runBinary<R, T1, T2>( |
429 R action(T1 argument1, T2 argument2), T1 argument1, T2 argument2); | 432 R action(T1 argument1, T2 argument2), T1 argument1, T2 argument2); |
430 | 433 |
431 /** | 434 /** |
432 * Executes the given [action] in this zone and catches synchronous | 435 * Executes the given [action] in this zone and catches synchronous |
433 * errors. | 436 * errors. |
434 * | 437 * |
435 * This function is equivalent to: | 438 * This function is equivalent to: |
436 * ``` | 439 * ``` |
437 * try { | 440 * try { |
438 * this.run(action); | 441 * return this.run(action); |
439 * } catch (e, s) { | 442 * } catch (e, s) { |
440 * this.handleUncaughtError(e, s); | 443 * return this.handleUncaughtError(e, s); |
441 * } | 444 * } |
442 * ``` | 445 * ``` |
443 * | 446 * |
444 * See [run]. | 447 * See [run]. |
445 */ | 448 */ |
446 void runGuarded(void action()); | 449 R runGuarded<R>(R action()); |
447 | 450 |
448 /** | 451 /** |
449 * Executes the given [action] with [argument] in this zone and | 452 * Executes the given [action] with [argument] in this zone and |
450 * catches synchronous errors. | 453 * catches synchronous errors. |
451 * | 454 * |
452 * See [runGuarded]. | 455 * See [runGuarded]. |
453 */ | 456 */ |
454 void runUnaryGuarded<T>(void action(T argument), T argument); | 457 R runUnaryGuarded<R, T>(R action(T argument), T argument); |
455 | 458 |
456 /** | 459 /** |
457 * Executes the given [action] with [argument1] and [argument2] in this | 460 * Executes the given [action] with [argument1] and [argument2] in this |
458 * zone and catches synchronous errors. | 461 * zone and catches synchronous errors. |
459 * | 462 * |
460 * See [runGuarded]. | 463 * See [runGuarded]. |
461 */ | 464 */ |
462 void runBinaryGuarded<T1, T2>( | 465 R runBinaryGuarded<R, T1, T2>( |
463 void action(T1 argument1, T2 argument2), T1 argument1, T2 argument2); | 466 R action(T1 argument1, T2 argument2), T1 argument1, T2 argument2); |
464 | 467 |
465 /** | 468 /** |
466 * Registers the given callback in this zone. | 469 * Registers the given callback in this zone. |
467 * | 470 * |
468 * When implementing an asynchronous primitive that uses callbacks, the | 471 * When implementing an asynchronous primitive that uses callbacks, the |
469 * callback must be registered using [registerCallback] at the point where the | 472 * callback must be registered using [registerCallback] at the point where the |
470 * user provides the callback. This allows zones to record other information | 473 * user provides the callback. This allows zones to record other information |
471 * that they need at the same time, perhaps even wrapping the callback, so | 474 * that they need at the same time, perhaps even wrapping the callback, so |
472 * that the callback is prepared when it is later run in the same zones | 475 * that the callback is prepared when it is later run in the same zones |
473 * (using [run]). For example, a zone may decide | 476 * (using [run]). For example, a zone may decide |
(...skipping 17 matching lines...) Expand all Loading... |
491 | 494 |
492 /** | 495 /** |
493 * Registers the given callback in this zone. | 496 * Registers the given callback in this zone. |
494 * | 497 * |
495 * Similar to [registerCallback] but with a unary callback. | 498 * Similar to [registerCallback] but with a unary callback. |
496 */ | 499 */ |
497 ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( | 500 ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( |
498 R callback(T1 arg1, T2 arg2)); | 501 R callback(T1 arg1, T2 arg2)); |
499 | 502 |
500 /** | 503 /** |
501 * Registers the provided [callback] and returns a function that will | |
502 * execute in this zone. | |
503 * | |
504 * Equivalent to: | 504 * Equivalent to: |
505 * | 505 * |
506 * ZoneCallback registered = this.registerCallback(callback); | 506 * ZoneCallback registered = this.registerCallback(action); |
| 507 * if (runGuarded) return () => this.runGuarded(registered); |
507 * return () => this.run(registered); | 508 * return () => this.run(registered); |
508 * | 509 * |
509 */ | 510 */ |
510 ZoneCallback<R> bindCallback<R>(R callback()); | 511 ZoneCallback<R> bindCallback<R>(R action(), {bool runGuarded: true}); |
511 | 512 |
512 /** | 513 /** |
513 * Registers the provided [callback] and returns a function that will | |
514 * execute in this zone. | |
515 * | |
516 * Equivalent to: | 514 * Equivalent to: |
517 * | 515 * |
518 * ZoneCallback registered = this.registerUnaryCallback(callback); | 516 * ZoneCallback registered = this.registerUnaryCallback(action); |
| 517 * if (runGuarded) return (arg) => this.runUnaryGuarded(registered, arg); |
519 * return (arg) => thin.runUnary(registered, arg); | 518 * return (arg) => thin.runUnary(registered, arg); |
520 */ | 519 */ |
521 ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R callback(T argument)); | 520 ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R action(T argument), |
| 521 {bool runGuarded: true}); |
522 | 522 |
523 /** | 523 /** |
524 * Registers the provided [callback] and returns a function that will | |
525 * execute in this zone. | |
526 * | |
527 * Equivalent to: | 524 * Equivalent to: |
528 * | 525 * |
529 * ZoneCallback registered = registerBinaryCallback(callback); | 526 * ZoneCallback registered = registerBinaryCallback(action); |
| 527 * if (runGuarded) { |
| 528 * return (arg1, arg2) => this.runBinaryGuarded(registered, arg); |
| 529 * } |
530 * return (arg1, arg2) => thin.runBinary(registered, arg1, arg2); | 530 * return (arg1, arg2) => thin.runBinary(registered, arg1, arg2); |
531 */ | 531 */ |
532 ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>( | 532 ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>( |
533 R callback(T1 argument1, T2 argument2)); | 533 R action(T1 argument1, T2 argument2), |
534 | 534 {bool runGuarded: true}); |
535 /** | |
536 * Registers the provided [callback] and returns a function that will | |
537 * execute in this zone. | |
538 * | |
539 * When the function executes, errors are caught and treated as uncaught | |
540 * errors. | |
541 * | |
542 * Equivalent to: | |
543 * | |
544 * ZoneCallback registered = this.registerCallback(callback); | |
545 * return () => this.runGuarded(registered); | |
546 * | |
547 */ | |
548 void Function() bindCallbackGuarded(void callback()); | |
549 | |
550 /** | |
551 * Registers the provided [callback] and returns a function that will | |
552 * execute in this zone. | |
553 * | |
554 * When the function executes, errors are caught and treated as uncaught | |
555 * errors. | |
556 * | |
557 * Equivalent to: | |
558 * | |
559 * ZoneCallback registered = this.registerUnaryCallback(callback); | |
560 * return (arg) => this.runUnaryGuarded(registered, arg); | |
561 */ | |
562 void Function(T) bindUnaryCallbackGuarded<T>(void callback(T argument)); | |
563 | |
564 /** | |
565 * Registers the provided [callback] and returns a function that will | |
566 * execute in this zone. | |
567 * | |
568 * Equivalent to: | |
569 * | |
570 * ZoneCallback registered = registerBinaryCallback(callback); | |
571 * return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2); | |
572 */ | |
573 void Function(T1, T2) bindBinaryCallbackGuarded<T1, T2>( | |
574 void callback(T1 argument1, T2 argument2)); | |
575 | 535 |
576 /** | 536 /** |
577 * Intercepts errors when added programmatically to a `Future` or `Stream`. | 537 * Intercepts errors when added programmatically to a `Future` or `Stream`. |
578 * | 538 * |
579 * When calling [Completer.completeError], [StreamController.addError], | 539 * When calling [Completer.completeError], [StreamController.addError], |
580 * or some [Future] constructors, the current zone is allowed to intercept | 540 * or some [Future] constructors, the current zone is allowed to intercept |
581 * and replace the error. | 541 * and replace the error. |
582 * | 542 * |
583 * Future constructors invoke this function when the error is received | 543 * Future constructors invoke this function when the error is received |
584 * directly, for example with [Future.error], or when the error is caught | 544 * directly, for example with [Future.error], or when the error is caught |
(...skipping 13 matching lines...) Expand all Loading... |
598 * Custom zones may intercept this operation. | 558 * Custom zones may intercept this operation. |
599 * | 559 * |
600 * Implementations of a new asynchronous primitive that converts synchronous | 560 * Implementations of a new asynchronous primitive that converts synchronous |
601 * errors to asynchronous errors rarely need to invoke [errorCallback], since | 561 * errors to asynchronous errors rarely need to invoke [errorCallback], since |
602 * errors are usually reported through future completers or stream | 562 * errors are usually reported through future completers or stream |
603 * controllers. | 563 * controllers. |
604 */ | 564 */ |
605 AsyncError errorCallback(Object error, StackTrace stackTrace); | 565 AsyncError errorCallback(Object error, StackTrace stackTrace); |
606 | 566 |
607 /** | 567 /** |
608 * Runs [callback] asynchronously in this zone. | 568 * Runs [action] asynchronously in this zone. |
609 * | 569 * |
610 * The global `scheduleMicrotask` delegates to the current zone's | 570 * The global `scheduleMicrotask` delegates to the current zone's |
611 * [scheduleMicrotask]. The root zone's implementation interacts with the | 571 * [scheduleMicrotask]. The root zone's implementation interacts with the |
612 * underlying system to schedule the given callback as a microtask. | 572 * underlying system to schedule the given callback as a microtask. |
613 * | 573 * |
614 * Custom zones may intercept this operation (for example to wrap the given | 574 * Custom zones may intercept this operation (for example to wrap the given |
615 * [callback]). | 575 * callback [action]). |
616 */ | 576 */ |
617 void scheduleMicrotask(void callback()); | 577 void scheduleMicrotask(void action()); |
618 | 578 |
619 /** | 579 /** |
620 * Creates a Timer where the callback is executed in this zone. | 580 * Creates a Timer where the callback is executed in this zone. |
621 */ | 581 */ |
622 Timer createTimer(Duration duration, void callback()); | 582 Timer createTimer(Duration duration, void callback()); |
623 | 583 |
624 /** | 584 /** |
625 * Creates a periodic Timer where the callback is executed in this zone. | 585 * Creates a periodic Timer where the callback is executed in this zone. |
626 */ | 586 */ |
627 Timer createPeriodicTimer(Duration period, void callback(Timer timer)); | 587 Timer createPeriodicTimer(Duration period, void callback(Timer timer)); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 ZoneDelegate _parentDelegate(_Zone zone) { | 649 ZoneDelegate _parentDelegate(_Zone zone) { |
690 if (zone.parent == null) return null; | 650 if (zone.parent == null) return null; |
691 return zone.parent._delegate; | 651 return zone.parent._delegate; |
692 } | 652 } |
693 | 653 |
694 class _ZoneDelegate implements ZoneDelegate { | 654 class _ZoneDelegate implements ZoneDelegate { |
695 final _Zone _delegationTarget; | 655 final _Zone _delegationTarget; |
696 | 656 |
697 _ZoneDelegate(this._delegationTarget); | 657 _ZoneDelegate(this._delegationTarget); |
698 | 658 |
699 void handleUncaughtError(Zone zone, error, StackTrace stackTrace) { | 659 R handleUncaughtError<R>(Zone zone, error, StackTrace stackTrace) { |
700 var implementation = _delegationTarget._handleUncaughtError; | 660 var implementation = _delegationTarget._handleUncaughtError; |
701 _Zone implZone = implementation.zone; | 661 _Zone implZone = implementation.zone; |
702 HandleUncaughtErrorHandler handler = implementation.function; | 662 HandleUncaughtErrorHandler handler = implementation.function; |
703 return handler( | 663 // TODO(floitsch): make this a generic method call on '<R>' once it's |
704 implZone, _parentDelegate(implZone), zone, error, stackTrace); | 664 // supported. Remove the unnecessary cast. |
| 665 return handler(implZone, _parentDelegate(implZone), zone, error, stackTrace) |
| 666 as Object/*=R*/; |
705 } | 667 } |
706 | 668 |
707 R run<R>(Zone zone, R f()) { | 669 R run<R>(Zone zone, R f()) { |
708 var implementation = _delegationTarget._run; | 670 var implementation = _delegationTarget._run; |
709 _Zone implZone = implementation.zone; | 671 _Zone implZone = implementation.zone; |
710 RunHandler handler = implementation.function; | 672 RunHandler handler = implementation.function; |
711 return handler(implZone, _parentDelegate(implZone), zone, f); | 673 // TODO(floitsch): make this a generic method call on '<R>' once it's |
| 674 // supported. Remove the unnecessary cast. |
| 675 return handler(implZone, _parentDelegate(implZone), zone, f) |
| 676 as Object/*=R*/; |
712 } | 677 } |
713 | 678 |
714 R runUnary<R, T>(Zone zone, R f(T arg), T arg) { | 679 R runUnary<R, T>(Zone zone, R f(T arg), T arg) { |
715 var implementation = _delegationTarget._runUnary; | 680 var implementation = _delegationTarget._runUnary; |
716 _Zone implZone = implementation.zone; | 681 _Zone implZone = implementation.zone; |
717 RunUnaryHandler handler = implementation.function; | 682 RunUnaryHandler handler = implementation.function; |
718 return handler(implZone, _parentDelegate(implZone), zone, f, arg); | 683 // TODO(floitsch): make this a generic method call on '<R, T>' once it's |
| 684 // supported. Remove the unnecessary cast. |
| 685 return handler(implZone, _parentDelegate(implZone), zone, f, arg) |
| 686 as Object/*=R*/; |
719 } | 687 } |
720 | 688 |
721 R runBinary<R, T1, T2>(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { | 689 R runBinary<R, T1, T2>(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
722 var implementation = _delegationTarget._runBinary; | 690 var implementation = _delegationTarget._runBinary; |
723 _Zone implZone = implementation.zone; | 691 _Zone implZone = implementation.zone; |
724 RunBinaryHandler handler = implementation.function; | 692 RunBinaryHandler handler = implementation.function; |
725 return handler(implZone, _parentDelegate(implZone), zone, f, arg1, arg2); | 693 // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once |
| 694 // it's supported. Remove the unnecessary cast. |
| 695 return handler(implZone, _parentDelegate(implZone), zone, f, arg1, arg2) |
| 696 as Object/*=R*/; |
726 } | 697 } |
727 | 698 |
728 ZoneCallback<R> registerCallback<R>(Zone zone, R f()) { | 699 ZoneCallback<R> registerCallback<R>(Zone zone, R f()) { |
729 var implementation = _delegationTarget._registerCallback; | 700 var implementation = _delegationTarget._registerCallback; |
730 _Zone implZone = implementation.zone; | 701 _Zone implZone = implementation.zone; |
731 RegisterCallbackHandler handler = implementation.function; | 702 RegisterCallbackHandler handler = implementation.function; |
732 return handler(implZone, _parentDelegate(implZone), zone, f); | 703 // TODO(floitsch): make this a generic method call on '<R>' once it's |
| 704 // supported. Remove the unnecessary cast. |
| 705 return handler(implZone, _parentDelegate(implZone), zone, f) |
| 706 as Object/*=ZoneCallback<R>*/; |
733 } | 707 } |
734 | 708 |
735 ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(Zone zone, R f(T arg)) { | 709 ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(Zone zone, R f(T arg)) { |
736 var implementation = _delegationTarget._registerUnaryCallback; | 710 var implementation = _delegationTarget._registerUnaryCallback; |
737 _Zone implZone = implementation.zone; | 711 _Zone implZone = implementation.zone; |
738 RegisterUnaryCallbackHandler handler = implementation.function; | 712 RegisterUnaryCallbackHandler handler = implementation.function; |
739 return handler(implZone, _parentDelegate(implZone), zone, f); | 713 // TODO(floitsch): make this a generic method call on '<R, T>' once it's |
| 714 // supported. Remove the unnecessary cast. |
| 715 return handler(implZone, _parentDelegate(implZone), zone, f) |
| 716 as Object/*=ZoneUnaryCallback<R, T>*/; |
740 } | 717 } |
741 | 718 |
742 ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( | 719 ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( |
743 Zone zone, R f(T1 arg1, T2 arg2)) { | 720 Zone zone, R f(T1 arg1, T2 arg2)) { |
744 var implementation = _delegationTarget._registerBinaryCallback; | 721 var implementation = _delegationTarget._registerBinaryCallback; |
745 _Zone implZone = implementation.zone; | 722 _Zone implZone = implementation.zone; |
746 RegisterBinaryCallbackHandler handler = implementation.function; | 723 RegisterBinaryCallbackHandler handler = implementation.function; |
747 return handler(implZone, _parentDelegate(implZone), zone, f); | 724 // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once |
| 725 // it's supported. Remove the unnecessary cast. |
| 726 return handler(implZone, _parentDelegate(implZone), zone, f) |
| 727 as Object/*=ZoneBinaryCallback<R, T1, T2>*/; |
748 } | 728 } |
749 | 729 |
750 AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace) { | 730 AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace) { |
751 var implementation = _delegationTarget._errorCallback; | 731 var implementation = _delegationTarget._errorCallback; |
752 _Zone implZone = implementation.zone; | 732 _Zone implZone = implementation.zone; |
753 if (identical(implZone, _ROOT_ZONE)) return null; | 733 if (identical(implZone, _ROOT_ZONE)) return null; |
754 ErrorCallbackHandler handler = implementation.function; | 734 ErrorCallbackHandler handler = implementation.function; |
755 return handler( | 735 return handler( |
756 implZone, _parentDelegate(implZone), zone, error, stackTrace); | 736 implZone, _parentDelegate(implZone), zone, error, stackTrace); |
757 } | 737 } |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 } | 889 } |
910 | 890 |
911 /** | 891 /** |
912 * The closest error-handling zone. | 892 * The closest error-handling zone. |
913 * | 893 * |
914 * Returns `this` if `this` has an error-handler. Otherwise returns the | 894 * Returns `this` if `this` has an error-handler. Otherwise returns the |
915 * parent's error-zone. | 895 * parent's error-zone. |
916 */ | 896 */ |
917 Zone get errorZone => _handleUncaughtError.zone; | 897 Zone get errorZone => _handleUncaughtError.zone; |
918 | 898 |
919 void runGuarded(void f()) { | 899 R runGuarded<R>(R f()) { |
920 try { | 900 try { |
921 run(f); | 901 return run(f); |
922 } catch (e, s) { | 902 } catch (e, s) { |
923 handleUncaughtError(e, s); | 903 return handleUncaughtError(e, s); |
924 } | 904 } |
925 } | 905 } |
926 | 906 |
927 void runUnaryGuarded<T>(void f(T arg), T arg) { | 907 R runUnaryGuarded<R, T>(R f(T arg), T arg) { |
928 try { | 908 try { |
929 runUnary(f, arg); | 909 return runUnary(f, arg); |
930 } catch (e, s) { | 910 } catch (e, s) { |
931 handleUncaughtError(e, s); | 911 return handleUncaughtError(e, s); |
932 } | 912 } |
933 } | 913 } |
934 | 914 |
935 void runBinaryGuarded<T1, T2>(void f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { | 915 R runBinaryGuarded<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
936 try { | 916 try { |
937 runBinary(f, arg1, arg2); | 917 return runBinary(f, arg1, arg2); |
938 } catch (e, s) { | 918 } catch (e, s) { |
939 handleUncaughtError(e, s); | 919 return handleUncaughtError(e, s); |
940 } | 920 } |
941 } | 921 } |
942 | 922 |
943 ZoneCallback<R> bindCallback<R>(R f()) { | 923 ZoneCallback<R> bindCallback<R>(R f(), {bool runGuarded: true}) { |
944 var registered = registerCallback(f); | 924 var registered = registerCallback(f); |
945 return () => this.run(registered); | 925 if (runGuarded) { |
| 926 return () => this.runGuarded(registered); |
| 927 } else { |
| 928 return () => this.run(registered); |
| 929 } |
946 } | 930 } |
947 | 931 |
948 ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg)) { | 932 ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg), |
| 933 {bool runGuarded: true}) { |
949 var registered = registerUnaryCallback(f); | 934 var registered = registerUnaryCallback(f); |
950 return (arg) => this.runUnary(registered, arg); | 935 if (runGuarded) { |
| 936 return (arg) => this.runUnaryGuarded(registered, arg); |
| 937 } else { |
| 938 return (arg) => this.runUnary(registered, arg); |
| 939 } |
951 } | 940 } |
952 | 941 |
953 ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>( | 942 ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>( |
954 R f(T1 arg1, T2 arg2)) { | 943 R f(T1 arg1, T2 arg2), |
| 944 {bool runGuarded: true}) { |
955 var registered = registerBinaryCallback(f); | 945 var registered = registerBinaryCallback(f); |
956 return (arg1, arg2) => this.runBinary(registered, arg1, arg2); | 946 if (runGuarded) { |
957 } | 947 return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2); |
958 | 948 } else { |
959 void Function() bindCallbackGuarded(void f()) { | 949 return (arg1, arg2) => this.runBinary(registered, arg1, arg2); |
960 var registered = registerCallback(f); | 950 } |
961 return () => this.runGuarded(registered); | |
962 } | |
963 | |
964 void Function(T) bindUnaryCallbackGuarded<T>(void f(T arg)) { | |
965 var registered = registerUnaryCallback(f); | |
966 return (arg) => this.runUnaryGuarded(registered, arg); | |
967 } | |
968 | |
969 void Function(T1, T2) bindBinaryCallbackGuarded<T1, T2>( | |
970 void f(T1 arg1, T2 arg2)) { | |
971 var registered = registerBinaryCallback(f); | |
972 return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2); | |
973 } | 951 } |
974 | 952 |
975 operator [](Object key) { | 953 operator [](Object key) { |
976 var result = _map[key]; | 954 var result = _map[key]; |
977 if (result != null || _map.containsKey(key)) return result; | 955 if (result != null || _map.containsKey(key)) return result; |
978 // If we are not the root zone, look up in the parent zone. | 956 // If we are not the root zone, look up in the parent zone. |
979 if (parent != null) { | 957 if (parent != null) { |
980 // We do not optimize for repeatedly looking up a key which isn't | 958 // We do not optimize for repeatedly looking up a key which isn't |
981 // there. That would require storing the key and keeping it alive. | 959 // there. That would require storing the key and keeping it alive. |
982 // Copying the key/value from the parent does not keep any new values | 960 // Copying the key/value from the parent does not keep any new values |
983 // alive. | 961 // alive. |
984 var value = parent[key]; | 962 var value = parent[key]; |
985 if (value != null) { | 963 if (value != null) { |
986 _map[key] = value; | 964 _map[key] = value; |
987 } | 965 } |
988 return value; | 966 return value; |
989 } | 967 } |
990 assert(this == _ROOT_ZONE); | 968 assert(this == _ROOT_ZONE); |
991 return null; | 969 return null; |
992 } | 970 } |
993 | 971 |
994 // Methods that can be customized by the zone specification. | 972 // Methods that can be customized by the zone specification. |
995 | 973 |
996 void handleUncaughtError(error, StackTrace stackTrace) { | 974 R handleUncaughtError<R>(error, StackTrace stackTrace) { |
997 var implementation = this._handleUncaughtError; | 975 var implementation = this._handleUncaughtError; |
998 assert(implementation != null); | 976 assert(implementation != null); |
999 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); | 977 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
1000 HandleUncaughtErrorHandler handler = implementation.function; | 978 HandleUncaughtErrorHandler handler = implementation.function; |
1001 return handler( | 979 // TODO(floitsch): make this a generic method call on '<R>' once it's |
1002 implementation.zone, parentDelegate, this, error, stackTrace); | 980 // supported. Remove the unnecessary cast. |
| 981 return handler(implementation.zone, parentDelegate, this, error, stackTrace) |
| 982 as Object/*=R*/; |
1003 } | 983 } |
1004 | 984 |
1005 Zone fork({ZoneSpecification specification, Map zoneValues}) { | 985 Zone fork({ZoneSpecification specification, Map zoneValues}) { |
1006 var implementation = this._fork; | 986 var implementation = this._fork; |
1007 assert(implementation != null); | 987 assert(implementation != null); |
1008 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); | 988 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
1009 ForkHandler handler = implementation.function; | 989 ForkHandler handler = implementation.function; |
1010 return handler( | 990 return handler( |
1011 implementation.zone, parentDelegate, this, specification, zoneValues); | 991 implementation.zone, parentDelegate, this, specification, zoneValues); |
1012 } | 992 } |
1013 | 993 |
1014 R run<R>(R f()) { | 994 R run<R>(R f()) { |
1015 var implementation = this._run; | 995 var implementation = this._run; |
1016 assert(implementation != null); | 996 assert(implementation != null); |
1017 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); | 997 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
1018 RunHandler handler = implementation.function; | 998 RunHandler handler = implementation.function; |
1019 return handler(implementation.zone, parentDelegate, this, f); | 999 // TODO(floitsch): make this a generic method call on '<R>' once it's |
| 1000 // supported. Remove the unnecessary cast. |
| 1001 return handler(implementation.zone, parentDelegate, this, f) |
| 1002 as Object/*=R*/; |
1020 } | 1003 } |
1021 | 1004 |
1022 R runUnary<R, T>(R f(T arg), T arg) { | 1005 R runUnary<R, T>(R f(T arg), T arg) { |
1023 var implementation = this._runUnary; | 1006 var implementation = this._runUnary; |
1024 assert(implementation != null); | 1007 assert(implementation != null); |
1025 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); | 1008 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
1026 RunUnaryHandler handler = implementation.function; | 1009 RunUnaryHandler handler = implementation.function; |
1027 return handler(implementation.zone, parentDelegate, this, f, arg); | 1010 // TODO(floitsch): make this a generic method call on '<R, T>' once it's |
| 1011 // supported. Remove the unnecessary cast. |
| 1012 return handler(implementation.zone, parentDelegate, this, f, arg) |
| 1013 as Object/*=R*/; |
1028 } | 1014 } |
1029 | 1015 |
1030 R runBinary<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { | 1016 R runBinary<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
1031 var implementation = this._runBinary; | 1017 var implementation = this._runBinary; |
1032 assert(implementation != null); | 1018 assert(implementation != null); |
1033 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); | 1019 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
1034 RunBinaryHandler handler = implementation.function; | 1020 RunBinaryHandler handler = implementation.function; |
1035 return handler(implementation.zone, parentDelegate, this, f, arg1, arg2); | 1021 // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once |
| 1022 // it's supported. Remove the unnecessary cast. |
| 1023 return handler(implementation.zone, parentDelegate, this, f, arg1, arg2) |
| 1024 as Object/*=R*/; |
1036 } | 1025 } |
1037 | 1026 |
1038 ZoneCallback<R> registerCallback<R>(R callback()) { | 1027 ZoneCallback<R> registerCallback<R>(R callback()) { |
1039 var implementation = this._registerCallback; | 1028 var implementation = this._registerCallback; |
1040 assert(implementation != null); | 1029 assert(implementation != null); |
1041 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); | 1030 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
1042 RegisterCallbackHandler handler = implementation.function; | 1031 RegisterCallbackHandler handler = implementation.function; |
1043 return handler(implementation.zone, parentDelegate, this, callback); | 1032 // TODO(floitsch): make this a generic method call on '<R>' once it's |
| 1033 // supported. Remove the unnecessary cast. |
| 1034 return handler(implementation.zone, parentDelegate, this, callback) |
| 1035 as Object/*=ZoneCallback<R>*/; |
1044 } | 1036 } |
1045 | 1037 |
1046 ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(R callback(T arg)) { | 1038 ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(R callback(T arg)) { |
1047 var implementation = this._registerUnaryCallback; | 1039 var implementation = this._registerUnaryCallback; |
1048 assert(implementation != null); | 1040 assert(implementation != null); |
1049 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); | 1041 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
1050 RegisterUnaryCallbackHandler handler = implementation.function; | 1042 RegisterUnaryCallbackHandler handler = implementation.function; |
1051 return handler(implementation.zone, parentDelegate, this, callback); | 1043 // TODO(floitsch): make this a generic method call on '<R, T>' once it's |
| 1044 // supported. Remove the unnecessary cast. |
| 1045 return handler(implementation.zone, parentDelegate, this, callback) |
| 1046 as Object/*=ZoneUnaryCallback<R, T>*/; |
1052 } | 1047 } |
1053 | 1048 |
1054 ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( | 1049 ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( |
1055 R callback(T1 arg1, T2 arg2)) { | 1050 R callback(T1 arg1, T2 arg2)) { |
1056 var implementation = this._registerBinaryCallback; | 1051 var implementation = this._registerBinaryCallback; |
1057 assert(implementation != null); | 1052 assert(implementation != null); |
1058 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); | 1053 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
1059 RegisterBinaryCallbackHandler handler = implementation.function; | 1054 RegisterBinaryCallbackHandler handler = implementation.function; |
1060 return handler(implementation.zone, parentDelegate, this, callback); | 1055 // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once |
| 1056 // it's supported. Remove the unnecessary cast. |
| 1057 return handler(implementation.zone, parentDelegate, this, callback) |
| 1058 as Object/*=ZoneBinaryCallback<R, T1, T2>*/; |
1061 } | 1059 } |
1062 | 1060 |
1063 AsyncError errorCallback(Object error, StackTrace stackTrace) { | 1061 AsyncError errorCallback(Object error, StackTrace stackTrace) { |
1064 var implementation = this._errorCallback; | 1062 var implementation = this._errorCallback; |
1065 assert(implementation != null); | 1063 assert(implementation != null); |
1066 final Zone implementationZone = implementation.zone; | 1064 final Zone implementationZone = implementation.zone; |
1067 if (identical(implementationZone, _ROOT_ZONE)) return null; | 1065 if (identical(implementationZone, _ROOT_ZONE)) return null; |
1068 final ZoneDelegate parentDelegate = _parentDelegate(implementationZone); | 1066 final ZoneDelegate parentDelegate = _parentDelegate(implementationZone); |
1069 ErrorCallbackHandler handler = implementation.function; | 1067 ErrorCallbackHandler handler = implementation.function; |
1070 return handler(implementationZone, parentDelegate, this, error, stackTrace); | 1068 return handler(implementationZone, parentDelegate, this, error, stackTrace); |
(...skipping 25 matching lines...) Expand all Loading... |
1096 | 1094 |
1097 void print(String line) { | 1095 void print(String line) { |
1098 var implementation = this._print; | 1096 var implementation = this._print; |
1099 assert(implementation != null); | 1097 assert(implementation != null); |
1100 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); | 1098 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
1101 PrintHandler handler = implementation.function; | 1099 PrintHandler handler = implementation.function; |
1102 return handler(implementation.zone, parentDelegate, this, line); | 1100 return handler(implementation.zone, parentDelegate, this, line); |
1103 } | 1101 } |
1104 } | 1102 } |
1105 | 1103 |
1106 void _rootHandleUncaughtError( | 1104 R _rootHandleUncaughtError<R>( |
1107 Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace) { | 1105 Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace) { |
1108 _schedulePriorityAsyncCallback(() { | 1106 _schedulePriorityAsyncCallback(() { |
1109 if (error == null) error = new NullThrownError(); | 1107 if (error == null) error = new NullThrownError(); |
1110 if (stackTrace == null) throw error; | 1108 if (stackTrace == null) throw error; |
1111 _rethrow(error, stackTrace); | 1109 _rethrow(error, stackTrace); |
1112 }); | 1110 }); |
1113 } | 1111 } |
1114 | 1112 |
1115 external void _rethrow(Object error, StackTrace stackTrace); | 1113 external void _rethrow(Object error, StackTrace stackTrace); |
1116 | 1114 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1161 | 1159 |
1162 ZoneBinaryCallback<R, T1, T2> _rootRegisterBinaryCallback<R, T1, T2>( | 1160 ZoneBinaryCallback<R, T1, T2> _rootRegisterBinaryCallback<R, T1, T2>( |
1163 Zone self, ZoneDelegate parent, Zone zone, R f(T1 arg1, T2 arg2)) { | 1161 Zone self, ZoneDelegate parent, Zone zone, R f(T1 arg1, T2 arg2)) { |
1164 return f; | 1162 return f; |
1165 } | 1163 } |
1166 | 1164 |
1167 AsyncError _rootErrorCallback(Zone self, ZoneDelegate parent, Zone zone, | 1165 AsyncError _rootErrorCallback(Zone self, ZoneDelegate parent, Zone zone, |
1168 Object error, StackTrace stackTrace) => | 1166 Object error, StackTrace stackTrace) => |
1169 null; | 1167 null; |
1170 | 1168 |
1171 void _rootScheduleMicrotask( | 1169 void _rootScheduleMicrotask(Zone self, ZoneDelegate parent, Zone zone, f()) { |
1172 Zone self, ZoneDelegate parent, Zone zone, void f()) { | |
1173 if (!identical(_ROOT_ZONE, zone)) { | 1170 if (!identical(_ROOT_ZONE, zone)) { |
1174 bool hasErrorHandler = !_ROOT_ZONE.inSameErrorZone(zone); | 1171 bool hasErrorHandler = !_ROOT_ZONE.inSameErrorZone(zone); |
1175 if (hasErrorHandler) { | 1172 f = zone.bindCallback(f, runGuarded: hasErrorHandler); |
1176 f = zone.bindCallbackGuarded(f); | |
1177 } else { | |
1178 f = zone.bindCallback(f); | |
1179 } | |
1180 // Use root zone as event zone if the function is already bound. | 1173 // Use root zone as event zone if the function is already bound. |
1181 zone = _ROOT_ZONE; | 1174 zone = _ROOT_ZONE; |
1182 } | 1175 } |
1183 _scheduleAsyncCallback(f); | 1176 _scheduleAsyncCallback(f); |
1184 } | 1177 } |
1185 | 1178 |
1186 Timer _rootCreateTimer(Zone self, ZoneDelegate parent, Zone zone, | 1179 Timer _rootCreateTimer(Zone self, ZoneDelegate parent, Zone zone, |
1187 Duration duration, void callback()) { | 1180 Duration duration, void callback()) { |
1188 if (!identical(_ROOT_ZONE, zone)) { | 1181 if (!identical(_ROOT_ZONE, zone)) { |
1189 callback = zone.bindCallback(callback); | 1182 callback = zone.bindCallback(callback); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1290 /** | 1283 /** |
1291 * The closest error-handling zone. | 1284 * The closest error-handling zone. |
1292 * | 1285 * |
1293 * Returns `this` if `this` has an error-handler. Otherwise returns the | 1286 * Returns `this` if `this` has an error-handler. Otherwise returns the |
1294 * parent's error-zone. | 1287 * parent's error-zone. |
1295 */ | 1288 */ |
1296 Zone get errorZone => this; | 1289 Zone get errorZone => this; |
1297 | 1290 |
1298 // Zone interface. | 1291 // Zone interface. |
1299 | 1292 |
1300 void runGuarded(void f()) { | 1293 R runGuarded<R>(R f()) { |
1301 try { | 1294 try { |
1302 if (identical(_ROOT_ZONE, Zone._current)) { | 1295 if (identical(_ROOT_ZONE, Zone._current)) { |
1303 f(); | 1296 return f(); |
1304 return; | |
1305 } | 1297 } |
1306 _rootRun(null, null, this, f); | 1298 return _rootRun<R>(null, null, this, f); |
1307 } catch (e, s) { | 1299 } catch (e, s) { |
1308 handleUncaughtError(e, s); | 1300 return handleUncaughtError<R>(e, s); |
1309 } | 1301 } |
1310 } | 1302 } |
1311 | 1303 |
1312 void runUnaryGuarded<T>(void f(T arg), T arg) { | 1304 R runUnaryGuarded<R, T>(R f(T arg), T arg) { |
1313 try { | 1305 try { |
1314 if (identical(_ROOT_ZONE, Zone._current)) { | 1306 if (identical(_ROOT_ZONE, Zone._current)) { |
1315 f(arg); | 1307 return f(arg); |
1316 return; | |
1317 } | 1308 } |
1318 _rootRunUnary(null, null, this, f, arg); | 1309 return _rootRunUnary<R, T>(null, null, this, f, arg); |
1319 } catch (e, s) { | 1310 } catch (e, s) { |
1320 handleUncaughtError(e, s); | 1311 return handleUncaughtError<R>(e, s); |
1321 } | 1312 } |
1322 } | 1313 } |
1323 | 1314 |
1324 void runBinaryGuarded<T1, T2>(void f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { | 1315 R runBinaryGuarded<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
1325 try { | 1316 try { |
1326 if (identical(_ROOT_ZONE, Zone._current)) { | 1317 if (identical(_ROOT_ZONE, Zone._current)) { |
1327 f(arg1, arg2); | 1318 return f(arg1, arg2); |
1328 return; | |
1329 } | 1319 } |
1330 _rootRunBinary(null, null, this, f, arg1, arg2); | 1320 return _rootRunBinary<R, T1, T2>(null, null, this, f, arg1, arg2); |
1331 } catch (e, s) { | 1321 } catch (e, s) { |
1332 handleUncaughtError(e, s); | 1322 return handleUncaughtError<R>(e, s); |
1333 } | 1323 } |
1334 } | 1324 } |
1335 | 1325 |
1336 ZoneCallback<R> bindCallback<R>(R f()) { | 1326 ZoneCallback<R> bindCallback<R>(R f(), {bool runGuarded: true}) { |
1337 return () => this.run<R>(f); | 1327 if (runGuarded) { |
| 1328 return () => this.runGuarded<R>(f); |
| 1329 } else { |
| 1330 return () => this.run<R>(f); |
| 1331 } |
1338 } | 1332 } |
1339 | 1333 |
1340 ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg)) { | 1334 ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg), |
1341 return (arg) => this.runUnary<R, T>(f, arg); | 1335 {bool runGuarded: true}) { |
| 1336 if (runGuarded) { |
| 1337 return (arg) => this.runUnaryGuarded<R, T>(f, arg); |
| 1338 } else { |
| 1339 return (arg) => this.runUnary<R, T>(f, arg); |
| 1340 } |
1342 } | 1341 } |
1343 | 1342 |
1344 ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>( | 1343 ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>( |
1345 R f(T1 arg1, T2 arg2)) { | 1344 R f(T1 arg1, T2 arg2), |
1346 return (arg1, arg2) => this.runBinary<R, T1, T2>(f, arg1, arg2); | 1345 {bool runGuarded: true}) { |
1347 } | 1346 if (runGuarded) { |
1348 | 1347 return (arg1, arg2) => this.runBinaryGuarded<R, T1, T2>(f, arg1, arg2); |
1349 void Function() bindCallbackGuarded(void f()) { | 1348 } else { |
1350 return () => this.runGuarded(f); | 1349 return (arg1, arg2) => this.runBinary<R, T1, T2>(f, arg1, arg2); |
1351 } | 1350 } |
1352 | |
1353 void Function(T) bindUnaryCallbackGuarded<T>(void f(T arg)) { | |
1354 return (arg) => this.runUnaryGuarded(f, arg); | |
1355 } | |
1356 | |
1357 void Function(T1, T2) bindBinaryCallbackGuarded<T1, T2>( | |
1358 void f(T1 arg1, T2 arg2)) { | |
1359 return (arg1, arg2) => this.runBinaryGuarded(f, arg1, arg2); | |
1360 } | 1351 } |
1361 | 1352 |
1362 operator [](Object key) => null; | 1353 operator [](Object key) => null; |
1363 | 1354 |
1364 // Methods that can be customized by the zone specification. | 1355 // Methods that can be customized by the zone specification. |
1365 | 1356 |
1366 void handleUncaughtError(error, StackTrace stackTrace) { | 1357 R handleUncaughtError<R>(error, StackTrace stackTrace) { |
1367 _rootHandleUncaughtError(null, null, this, error, stackTrace); | 1358 return _rootHandleUncaughtError(null, null, this, error, stackTrace); |
1368 } | 1359 } |
1369 | 1360 |
1370 Zone fork({ZoneSpecification specification, Map zoneValues}) { | 1361 Zone fork({ZoneSpecification specification, Map zoneValues}) { |
1371 return _rootFork(null, null, this, specification, zoneValues); | 1362 return _rootFork(null, null, this, specification, zoneValues); |
1372 } | 1363 } |
1373 | 1364 |
1374 R run<R>(R f()) { | 1365 R run<R>(R f()) { |
1375 if (identical(Zone._current, _ROOT_ZONE)) return f(); | 1366 if (identical(Zone._current, _ROOT_ZONE)) return f(); |
1376 return _rootRun(null, null, this, f); | 1367 return _rootRun(null, null, this, f); |
1377 } | 1368 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1411 void print(String line) { | 1402 void print(String line) { |
1412 printToConsole(line); | 1403 printToConsole(line); |
1413 } | 1404 } |
1414 } | 1405 } |
1415 | 1406 |
1416 const _ROOT_ZONE = const _RootZone(); | 1407 const _ROOT_ZONE = const _RootZone(); |
1417 | 1408 |
1418 /** | 1409 /** |
1419 * Runs [body] in its own zone. | 1410 * Runs [body] in its own zone. |
1420 * | 1411 * |
1421 * Returns the result of invoking [body]. | |
1422 * | |
1423 * If [onError] is non-null the zone is considered an error zone. All uncaught | 1412 * If [onError] is non-null the zone is considered an error zone. All uncaught |
1424 * errors, synchronous or asynchronous, in the zone are caught and handled | 1413 * errors, synchronous or asynchronous, in the zone are caught and handled |
1425 * by the callback. When the error is synchronous, throwing in the [onError] | 1414 * by the callback. |
1426 * handler, leads to a synchronous exception. | |
1427 * | |
1428 * Returns `null` when [body] threw, and a provided [onError] function completed | |
1429 * without throwing. | |
1430 * | 1415 * |
1431 * Errors may never cross error-zone boundaries. This is intuitive for leaving | 1416 * Errors may never cross error-zone boundaries. This is intuitive for leaving |
1432 * a zone, but it also applies for errors that would enter an error-zone. | 1417 * a zone, but it also applies for errors that would enter an error-zone. |
1433 * Errors that try to cross error-zone boundaries are considered uncaught. | 1418 * Errors that try to cross error-zone boundaries are considered uncaught. |
1434 * | 1419 * |
1435 * var future = new Future.value(499); | 1420 * var future = new Future.value(499); |
1436 * runZoned(() { | 1421 * runZoned(() { |
1437 * future = future.then((_) { throw "error in first error-zone"; }); | 1422 * future = future.then((_) { throw "error in first error-zone"; }); |
1438 * runZoned(() { | 1423 * runZoned(() { |
1439 * future = future.catchError((e) { print("Never reached!"); }); | 1424 * future = future.catchError((e) { print("Never reached!"); }); |
1440 * }, onError: (e) { print("unused error handler"); }); | 1425 * }, onError: (e) { print("unused error handler"); }); |
1441 * }, onError: (e) { print("catches error of first error-zone."); }); | 1426 * }, onError: (e) { print("catches error of first error-zone."); }); |
1442 * | 1427 * |
1443 * Example: | 1428 * Example: |
1444 * | 1429 * |
1445 * runZoned(() { | 1430 * runZoned(() { |
1446 * new Future(() { throw "asynchronous error"; }); | 1431 * new Future(() { throw "asynchronous error"; }); |
1447 * }, onError: print); // Will print "asynchronous error". | 1432 * }, onError: print); // Will print "asynchronous error". |
1448 */ | 1433 */ |
1449 R runZoned<R>(R body(), | 1434 R runZoned<R>(R body(), |
1450 {Map zoneValues, ZoneSpecification zoneSpecification, Function onError}) { | 1435 {Map zoneValues, ZoneSpecification zoneSpecification, Function onError}) { |
1451 // TODO(floitsch): the return type should be `void` here. | |
1452 if (onError != null && | |
1453 onError is! ZoneBinaryCallback<Object, Object, StackTrace> && | |
1454 onError is! ZoneUnaryCallback<Object, Object>) { | |
1455 throw new ArgumentError("onError callback must take an Object (the error), " | |
1456 "or an Object (the error) and a StackTrace"); | |
1457 } | |
1458 HandleUncaughtErrorHandler errorHandler; | 1436 HandleUncaughtErrorHandler errorHandler; |
1459 if (onError != null) { | 1437 if (onError != null) { |
1460 errorHandler = (Zone self, ZoneDelegate parent, Zone zone, error, | 1438 errorHandler = (Zone self, ZoneDelegate parent, Zone zone, error, |
1461 StackTrace stackTrace) { | 1439 StackTrace stackTrace) { |
1462 try { | 1440 try { |
1463 if (onError is void Function(Object, StackTrace)) { | 1441 // TODO(floitsch): the return type should be 'void'. |
1464 self.parent.runBinary(onError, error, stackTrace); | 1442 if (onError is ZoneBinaryCallback<dynamic, Object, StackTrace>) { |
1465 return; | 1443 return self.parent.runBinary(onError, error, stackTrace); |
1466 } | 1444 } |
1467 assert(onError is void Function(Object)); | 1445 return self.parent.runUnary(onError, error); |
1468 self.parent.runUnary(onError, error); | |
1469 } catch (e, s) { | 1446 } catch (e, s) { |
1470 if (identical(e, error)) { | 1447 if (identical(e, error)) { |
1471 parent.handleUncaughtError(zone, error, stackTrace); | 1448 return parent.handleUncaughtError(zone, error, stackTrace); |
1472 } else { | 1449 } else { |
1473 parent.handleUncaughtError(zone, e, s); | 1450 return parent.handleUncaughtError(zone, e, s); |
1474 } | 1451 } |
1475 } | 1452 } |
1476 }; | 1453 }; |
1477 } | 1454 } |
1478 if (zoneSpecification == null) { | 1455 if (zoneSpecification == null) { |
1479 zoneSpecification = | 1456 zoneSpecification = |
1480 new ZoneSpecification(handleUncaughtError: errorHandler); | 1457 new ZoneSpecification(handleUncaughtError: errorHandler); |
1481 } else if (errorHandler != null) { | 1458 } else if (errorHandler != null) { |
1482 zoneSpecification = new ZoneSpecification.from(zoneSpecification, | 1459 zoneSpecification = new ZoneSpecification.from(zoneSpecification, |
1483 handleUncaughtError: errorHandler); | 1460 handleUncaughtError: errorHandler); |
1484 } | 1461 } |
1485 Zone zone = Zone.current | 1462 Zone zone = Zone.current |
1486 .fork(specification: zoneSpecification, zoneValues: zoneValues); | 1463 .fork(specification: zoneSpecification, zoneValues: zoneValues); |
1487 if (onError != null) { | 1464 if (onError != null) { |
1488 try { | 1465 return zone.runGuarded(body); |
1489 return zone.run(body); | |
1490 } catch (e, stackTrace) { | |
1491 if (onError is ZoneBinaryCallback<R, Object, StackTrace>) { | |
1492 zone.runBinary(onError, e, stackTrace); | |
1493 return null; | |
1494 } | |
1495 assert(onError is ZoneUnaryCallback<R, Object>); | |
1496 zone.runUnary(onError, e); | |
1497 return null; | |
1498 } | |
1499 } else { | 1466 } else { |
1500 return zone.run(body); | 1467 return zone.run(body); |
1501 } | 1468 } |
1502 } | 1469 } |
OLD | NEW |