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

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

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

Powered by Google App Engine
This is Rietveld 408576698