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

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/lib/async/zone.dart

Issue 2698353003: unfork DDC's copy of most SDK libraries (Closed)
Patch Set: revert core_patch Created 3 years, 9 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of dart.async;
6
7 typedef R ZoneCallback<R>();
8 typedef R ZoneUnaryCallback<R, T>(T arg);
9 typedef R ZoneBinaryCallback<R, T1, T2>(T1 arg1, T2 arg2);
10
11 // TODO(floitsch): we are abusing generic typedefs as typedefs for generic
12 // functions.
13 /*ABUSE*/
14 typedef R HandleUncaughtErrorHandler<R>(
15 Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace);
16 /*ABUSE*/
17 typedef R RunHandler<R>(Zone self, ZoneDelegate parent, Zone zone, R f());
18 /*ABUSE*/
19 typedef R RunUnaryHandler<R, T>(
20 Zone self, ZoneDelegate parent, Zone zone, R f(T arg), T arg);
21 /*ABUSE*/
22 typedef R RunBinaryHandler<R, T1, T2>(
23 Zone self, ZoneDelegate parent, Zone zone,
24 R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2);
25 /*ABUSE*/
26 typedef ZoneCallback<R> RegisterCallbackHandler<R>(
27 Zone self, ZoneDelegate parent, Zone zone, R f());
28 /*ABUSE*/
29 typedef ZoneUnaryCallback<R, T> RegisterUnaryCallbackHandler<R, T>(
30 Zone self, ZoneDelegate parent, Zone zone, R f(T arg));
31 /*ABUSE*/
32 typedef ZoneBinaryCallback<R, T1, T2> RegisterBinaryCallbackHandler<R, T1, T2>(
33 Zone self, ZoneDelegate parent, Zone zone, R f(T1 arg1, T2 arg2));
34 typedef AsyncError ErrorCallbackHandler(Zone self, ZoneDelegate parent,
35 Zone zone, Object error, StackTrace stackTrace);
36 typedef void ScheduleMicrotaskHandler(
37 Zone self, ZoneDelegate parent, Zone zone, void f());
38 typedef Timer CreateTimerHandler(
39 Zone self, ZoneDelegate parent, Zone zone, Duration duration, void f());
40 typedef Timer CreatePeriodicTimerHandler(
41 Zone self, ZoneDelegate parent, Zone zone,
42 Duration period, void f(Timer timer));
43 typedef void PrintHandler(
44 Zone self, ZoneDelegate parent, Zone zone, String line);
45 typedef Zone ForkHandler(Zone self, ZoneDelegate parent, Zone zone,
46 ZoneSpecification specification,
47 Map zoneValues);
48
49 /** Pair of error and stack trace. Returned by [Zone.errorCallback]. */
50 class AsyncError implements Error {
51 final Object error;
52 final StackTrace stackTrace;
53
54 AsyncError(this.error, this.stackTrace);
55
56 String toString() => '$error';
57 }
58
59
60 class _ZoneFunction<T extends Function> {
61 final _Zone zone;
62 final T function;
63 const _ZoneFunction(this.zone, this.function);
64 }
65
66 /**
67 * This class provides the specification for a forked zone.
68 *
69 * When forking a new zone (see [Zone.fork]) one can override the default
70 * behavior of the zone by providing callbacks. These callbacks must be
71 * given in an instance of this class.
72 *
73 * Handlers have the same signature as the same-named methods on [Zone] but
74 * receive three additional arguments:
75 *
76 * 1. the zone the handlers are attached to (the "self" zone).
77 * 2. a [ZoneDelegate] to the parent zone.
78 * 3. the zone that first received the request (before the request was
79 * bubbled up).
80 *
81 * Handlers can either stop propagation the request (by simply not calling the
82 * parent handler), or forward to the parent zone, potentially modifying the
83 * arguments on the way.
84 */
85 abstract class ZoneSpecification {
86 /**
87 * Creates a specification with the provided handlers.
88 */
89 const factory ZoneSpecification({
90 HandleUncaughtErrorHandler handleUncaughtError,
91 RunHandler run,
92 RunUnaryHandler runUnary,
93 RunBinaryHandler runBinary,
94 RegisterCallbackHandler registerCallback,
95 RegisterUnaryCallbackHandler registerUnaryCallback,
96 RegisterBinaryCallbackHandler registerBinaryCallback,
97 ErrorCallbackHandler errorCallback,
98 ScheduleMicrotaskHandler scheduleMicrotask,
99 CreateTimerHandler createTimer,
100 CreatePeriodicTimerHandler createPeriodicTimer,
101 PrintHandler print,
102 ForkHandler fork
103 }) = _ZoneSpecification;
104
105 /**
106 * Creates a specification from [other] with the provided handlers overriding
107 * the ones in [other].
108 */
109 factory ZoneSpecification.from(ZoneSpecification other, {
110 HandleUncaughtErrorHandler handleUncaughtError: null,
111 RunHandler run: null,
112 RunUnaryHandler runUnary: null,
113 RunBinaryHandler runBinary: null,
114 RegisterCallbackHandler registerCallback: null,
115 RegisterUnaryCallbackHandler registerUnaryCallback: null,
116 RegisterBinaryCallbackHandler registerBinaryCallback: null,
117 ErrorCallbackHandler errorCallback: null,
118 ScheduleMicrotaskHandler scheduleMicrotask: null,
119 CreateTimerHandler createTimer: null,
120 CreatePeriodicTimerHandler createPeriodicTimer: null,
121 PrintHandler print: null,
122 ForkHandler fork: null
123 }) {
124 return new ZoneSpecification(
125 handleUncaughtError: handleUncaughtError ?? other.handleUncaughtError,
126 run: run ?? other.run,
127 runUnary: runUnary ?? other.runUnary,
128 runBinary: runBinary ?? other.runBinary,
129 registerCallback: registerCallback ?? other.registerCallback,
130 registerUnaryCallback: registerUnaryCallback ??
131 other.registerUnaryCallback,
132 registerBinaryCallback: registerBinaryCallback ??
133 other.registerBinaryCallback,
134 errorCallback: errorCallback ?? other.errorCallback,
135 scheduleMicrotask: scheduleMicrotask ?? other.scheduleMicrotask,
136 createTimer : createTimer ?? other.createTimer,
137 createPeriodicTimer: createPeriodicTimer ?? other.createPeriodicTimer,
138 print : print ?? other.print,
139 fork: fork ?? other.fork);
140 }
141
142 HandleUncaughtErrorHandler get handleUncaughtError;
143 RunHandler get run;
144 RunUnaryHandler get runUnary;
145 RunBinaryHandler get runBinary;
146 RegisterCallbackHandler get registerCallback;
147 RegisterUnaryCallbackHandler get registerUnaryCallback;
148 RegisterBinaryCallbackHandler get registerBinaryCallback;
149 ErrorCallbackHandler get errorCallback;
150 ScheduleMicrotaskHandler get scheduleMicrotask;
151 CreateTimerHandler get createTimer;
152 CreatePeriodicTimerHandler get createPeriodicTimer;
153 PrintHandler get print;
154 ForkHandler get fork;
155 }
156
157 /**
158 * Internal [ZoneSpecification] class.
159 *
160 * The implementation wants to rely on the fact that the getters cannot change
161 * dynamically. We thus require users to go through the redirecting
162 * [ZoneSpecification] constructor which instantiates this class.
163 */
164 class _ZoneSpecification implements ZoneSpecification {
165 const _ZoneSpecification({
166 this.handleUncaughtError: null,
167 this.run: null,
168 this.runUnary: null,
169 this.runBinary: null,
170 this.registerCallback: null,
171 this.registerUnaryCallback: null,
172 this.registerBinaryCallback: null,
173 this.errorCallback: null,
174 this.scheduleMicrotask: null,
175 this.createTimer: null,
176 this.createPeriodicTimer: null,
177 this.print: null,
178 this.fork: null
179 });
180
181 final HandleUncaughtErrorHandler handleUncaughtError;
182 final RunHandler run;
183 final RunUnaryHandler runUnary;
184 final RunBinaryHandler runBinary;
185 final RegisterCallbackHandler registerCallback;
186 final RegisterUnaryCallbackHandler registerUnaryCallback;
187 final RegisterBinaryCallbackHandler registerBinaryCallback;
188 final ErrorCallbackHandler errorCallback;
189 final ScheduleMicrotaskHandler scheduleMicrotask;
190 final CreateTimerHandler createTimer;
191 final CreatePeriodicTimerHandler createPeriodicTimer;
192 final PrintHandler print;
193 final ForkHandler fork;
194 }
195
196 /**
197 * This class wraps zones for delegation.
198 *
199 * When forwarding to parent zones one can't just invoke the parent zone's
200 * exposed functions (like [Zone.run]), but one needs to provide more
201 * information (like the zone the `run` was initiated). Zone callbacks thus
202 * receive more information including this [ZoneDelegate] class. When delegating
203 * to the parent zone one should go through the given instance instead of
204 * directly invoking the parent zone.
205 */
206 abstract class ZoneDelegate {
207 /*=R*/ handleUncaughtError/*<R>*/(
208 Zone zone, error, StackTrace stackTrace);
209 /*=R*/ run/*<R>*/(Zone zone, /*=R*/ f());
210 /*=R*/ runUnary/*<R, T>*/(Zone zone, /*=R*/ f(/*=T*/ arg), /*=T*/ arg);
211 /*=R*/ runBinary/*<R, T1, T2>*/(Zone zone,
212 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2);
213 ZoneCallback/*<R>*/ registerCallback/*<R>*/(Zone zone, /*=R*/ f());
214 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
215 Zone zone, /*=R*/ f(/*=T*/ arg));
216 ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
217 Zone zone, /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2));
218 AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace);
219 void scheduleMicrotask(Zone zone, void f());
220 Timer createTimer(Zone zone, Duration duration, void f());
221 Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer));
222 void print(Zone zone, String line);
223 Zone fork(Zone zone, ZoneSpecification specification, Map zoneValues);
224 }
225
226 /**
227 * A Zone represents the asynchronous version of a dynamic extent. Asynchronous
228 * callbacks are executed in the zone they have been queued in. For example,
229 * the callback of a `future.then` is executed in the same zone as the one where
230 * the `then` was invoked.
231 */
232 abstract class Zone {
233 // Private constructor so that it is not possible instantiate a Zone class.
234 Zone._();
235
236 /** The root zone that is implicitly created. */
237 static const Zone ROOT = _ROOT_ZONE;
238
239 /** The currently running zone. */
240 static Zone _current = _ROOT_ZONE;
241
242 static Zone get current => _current;
243
244 /*=R*/ handleUncaughtError/*<R>*/(error, StackTrace stackTrace);
245
246 /**
247 * Returns the parent zone.
248 *
249 * Returns `null` if `this` is the [ROOT] zone.
250 */
251 Zone get parent;
252
253 /**
254 * The error zone is the one that is responsible for dealing with uncaught
255 * errors.
256 * Errors are not allowed to cross between zones with different error-zones.
257 *
258 * This is the closest parent or ancestor zone of this zone that has a custom
259 * [handleUncaughtError] method.
260 */
261 Zone get errorZone;
262
263 /**
264 * Returns true if `this` and [otherZone] are in the same error zone.
265 *
266 * Two zones are in the same error zone if they inherit their
267 * [handleUncaughtError] callback from the same [errorZone].
268 */
269 bool inSameErrorZone(Zone otherZone);
270
271 /**
272 * Creates a new zone as a child of `this`.
273 *
274 * The new zone will have behavior like the current zone, except where
275 * overridden by functions in [specification].
276 *
277 * The new zone will have the same stored values (accessed through
278 * `operator []`) as this zone, but updated with the keys and values
279 * in [zoneValues]. If a key is in both this zone's values and in
280 * `zoneValues`, the new zone will use the value from `zoneValues``.
281 */
282 Zone fork({ ZoneSpecification specification,
283 Map zoneValues });
284
285 /**
286 * Executes the given function [f] in this zone.
287 */
288 /*=R*/ run/*<R>*/(/*=R*/ f());
289
290 /**
291 * Executes the given callback [f] with argument [arg] in this zone.
292 */
293 /*=R*/ runUnary/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg);
294
295 /**
296 * Executes the given callback [f] with argument [arg1] and [arg2] in this
297 * zone.
298 */
299 /*=R*/ runBinary/*<R, T1, T2>*/(
300 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2);
301
302 /**
303 * Executes the given function [f] in this zone.
304 *
305 * Same as [run] but catches uncaught errors and gives them to
306 * [handleUncaughtError].
307 */
308 /*=R*/ runGuarded/*<R>*/(/*=R*/ f());
309
310 /**
311 * Executes the given callback [f] in this zone.
312 *
313 * Same as [runUnary] but catches uncaught errors and gives them to
314 * [handleUncaughtError].
315 */
316 /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg);
317
318 /**
319 * Executes the given callback [f] in this zone.
320 *
321 * Same as [runBinary] but catches uncaught errors and gives them to
322 * [handleUncaughtError].
323 */
324 /*=R*/ runBinaryGuarded/*<R, T1, T2>*/(
325 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2);
326
327 /**
328 * Registers the given callback in this zone.
329 *
330 * It is good practice to register asynchronous or delayed callbacks before
331 * invoking [run]. This gives the zone a chance to wrap the callback and
332 * to store information with the callback. For example, a zone may decide
333 * to store the stack trace (at the time of the registration) with the
334 * callback.
335 *
336 * Returns a potentially new callback that should be used in place of the
337 * given [callback].
338 */
339 ZoneCallback/*<R>*/ registerCallback/*<R>*/(/*=R*/ callback());
340
341 /**
342 * Registers the given callback in this zone.
343 *
344 * Similar to [registerCallback] but with a unary callback.
345 */
346 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
347 /*=R*/ callback(/*=T*/ arg));
348
349 /**
350 * Registers the given callback in this zone.
351 *
352 * Similar to [registerCallback] but with a unary callback.
353 */
354 ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
355 /*=R*/ callback(/*=T1*/ arg1, /*=T2*/ arg2));
356
357 /**
358 * Equivalent to:
359 *
360 * ZoneCallback registered = registerCallback(f);
361 * if (runGuarded) return () => this.runGuarded(registered);
362 * return () => this.run(registered);
363 *
364 */
365 ZoneCallback/*<R>*/ bindCallback/*<R>*/(
366 /*=R*/ f(), { bool runGuarded: true });
367
368 /**
369 * Equivalent to:
370 *
371 * ZoneCallback registered = registerUnaryCallback(f);
372 * if (runGuarded) return (arg) => this.runUnaryGuarded(registered, arg);
373 * return (arg) => thin.runUnary(registered, arg);
374 */
375 ZoneUnaryCallback/*<R, T>*/ bindUnaryCallback/*<R, T>*/(
376 /*=R*/ f(/*=T*/ arg), { bool runGuarded: true });
377
378 /**
379 * Equivalent to:
380 *
381 * ZoneCallback registered = registerBinaryCallback(f);
382 * if (runGuarded) {
383 * return (arg1, arg2) => this.runBinaryGuarded(registered, arg);
384 * }
385 * return (arg1, arg2) => thin.runBinary(registered, arg1, arg2);
386 */
387 ZoneBinaryCallback/*<R, T1, T2>*/ bindBinaryCallback/*<R, T1, T2>*/(
388 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), { bool runGuarded: true });
389
390 /**
391 * Intercepts errors when added programmatically to a `Future` or `Stream`.
392 *
393 * When caling [Completer.completeError], [Stream.addError],
394 * or [Future] constructors that take an error or a callback that may throw,
395 * the current zone is allowed to intercept and replace the error.
396 *
397 * When other libraries use intermediate controllers or completers, such
398 * calls may contain errors that have already been processed.
399 *
400 * Return `null` if no replacement is desired.
401 * The original error is used unchanged in that case.
402 * Otherwise return an instance of [AsyncError] holding
403 * the new pair of error and stack trace.
404 * If the [AsyncError.error] is `null`, it is replaced by a [NullThrownError].
405 */
406 AsyncError errorCallback(Object error, StackTrace stackTrace);
407
408 /**
409 * Runs [f] asynchronously in this zone.
410 */
411 void scheduleMicrotask(void f());
412
413 /**
414 * Creates a Timer where the callback is executed in this zone.
415 */
416 Timer createTimer(Duration duration, void callback());
417
418 /**
419 * Creates a periodic Timer where the callback is executed in this zone.
420 */
421 Timer createPeriodicTimer(Duration period, void callback(Timer timer));
422
423 /**
424 * Prints the given [line].
425 */
426 void print(String line);
427
428 /**
429 * Call to enter the Zone.
430 *
431 * The previous current zone is returned.
432 */
433 static Zone _enter(Zone zone) {
434 assert(zone != null);
435 assert(!identical(zone, _current));
436 Zone previous = _current;
437 _current = zone;
438 return previous;
439 }
440
441 /**
442 * Call to leave the Zone.
443 *
444 * The previous Zone must be provided as `previous`.
445 */
446 static void _leave(Zone previous) {
447 assert(previous != null);
448 Zone._current = previous;
449 }
450
451 /**
452 * Retrieves the zone-value associated with [key].
453 *
454 * If this zone does not contain the value looks up the same key in the
455 * parent zone. If the [key] is not found returns `null`.
456 *
457 * Any object can be used as key, as long as it has compatible `operator ==`
458 * and `hashCode` implementations.
459 * By controlling access to the key, a zone can grant or deny access to the
460 * zone value.
461 */
462 operator [](Object key);
463 }
464
465 ZoneDelegate _parentDelegate(_Zone zone) {
466 if (zone.parent == null) return null;
467 return zone.parent._delegate;
468 }
469
470 class _ZoneDelegate implements ZoneDelegate {
471 final _Zone _delegationTarget;
472
473 _ZoneDelegate(this._delegationTarget);
474
475 /*=R*/ handleUncaughtError/*<R>*/(
476 Zone zone, error, StackTrace stackTrace) {
477 var implementation = _delegationTarget._handleUncaughtError;
478 _Zone implZone = implementation.zone;
479 HandleUncaughtErrorHandler handler = implementation.function;
480 // TODO(floitsch): make this a generic method call on '<R>' once it's
481 // supported. Remove the unnecessary cast.
482 return handler(
483 implZone, _parentDelegate(implZone), zone, error, stackTrace)
484 as Object/*=R*/;
485 }
486
487 /*=R*/ run/*<R>*/(Zone zone, /*=R*/ f()) {
488 var implementation = _delegationTarget._run;
489 _Zone implZone = implementation.zone;
490 RunHandler handler = implementation.function;
491 // TODO(floitsch): make this a generic method call on '<R>' once it's
492 // supported. Remove the unnecessary cast.
493 return handler(implZone, _parentDelegate(implZone), zone, f)
494 as Object/*=R*/;
495 }
496
497 /*=R*/ runUnary/*<R, T>*/(Zone zone, /*=R*/ f(/*=T*/ arg), /*=T*/ arg) {
498 var implementation = _delegationTarget._runUnary;
499 _Zone implZone = implementation.zone;
500 RunUnaryHandler handler = implementation.function;
501 // TODO(floitsch): make this a generic method call on '<R, T>' once it's
502 // supported. Remove the unnecessary cast.
503 return handler(
504 implZone, _parentDelegate(implZone), zone, f, arg) as Object/*=R*/;
505 }
506
507 /*=R*/ runBinary/*<R, T1, T2>*/(Zone zone,
508 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2) {
509 var implementation = _delegationTarget._runBinary;
510 _Zone implZone = implementation.zone;
511 RunBinaryHandler handler = implementation.function;
512 // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once
513 // it's supported. Remove the unnecessary cast.
514 return handler(
515 implZone, _parentDelegate(implZone), zone, f, arg1, arg2)
516 as Object/*=R*/;
517 }
518
519 ZoneCallback/*<R>*/ registerCallback/*<R>*/(Zone zone, /*=R*/ f()) {
520 var implementation = _delegationTarget._registerCallback;
521 _Zone implZone = implementation.zone;
522 RegisterCallbackHandler handler = implementation.function;
523 // TODO(floitsch): make this a generic method call on '<R>' once it's
524 // supported. Remove the unnecessary cast.
525 return handler(implZone, _parentDelegate(implZone), zone, f)
526 as Object/*=ZoneCallback<R>*/;
527 }
528
529 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
530 Zone zone, /*=R*/ f(/*=T*/ arg)) {
531 var implementation = _delegationTarget._registerUnaryCallback;
532 _Zone implZone = implementation.zone;
533 RegisterUnaryCallbackHandler handler = implementation.function;
534 // TODO(floitsch): make this a generic method call on '<R, T>' once it's
535 // supported. Remove the unnecessary cast.
536 return handler(implZone, _parentDelegate(implZone), zone, f)
537 as Object/*=ZoneUnaryCallback<R, T>*/;
538 }
539
540 ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
541 Zone zone, /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2)) {
542 var implementation = _delegationTarget._registerBinaryCallback;
543 _Zone implZone = implementation.zone;
544 RegisterBinaryCallbackHandler handler = implementation.function;
545 // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once
546 // it's supported. Remove the unnecessary cast.
547 return handler(implZone, _parentDelegate(implZone), zone, f)
548 as Object/*=ZoneBinaryCallback<R, T1, T2>*/;
549 }
550
551 AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace) {
552 var implementation = _delegationTarget._errorCallback;
553 _Zone implZone = implementation.zone;
554 if (identical(implZone, _ROOT_ZONE)) return null;
555 ErrorCallbackHandler handler = implementation.function;
556 return handler(implZone, _parentDelegate(implZone), zone,
557 error, stackTrace);
558 }
559
560 void scheduleMicrotask(Zone zone, f()) {
561 var implementation = _delegationTarget._scheduleMicrotask;
562 _Zone implZone = implementation.zone;
563 ScheduleMicrotaskHandler handler = implementation.function;
564 handler(implZone, _parentDelegate(implZone), zone, f);
565 }
566
567 Timer createTimer(Zone zone, Duration duration, void f()) {
568 var implementation = _delegationTarget._createTimer;
569 _Zone implZone = implementation.zone;
570 CreateTimerHandler handler = implementation.function;
571 return handler(implZone, _parentDelegate(implZone), zone, duration, f);
572 }
573
574 Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)) {
575 var implementation = _delegationTarget._createPeriodicTimer;
576 _Zone implZone = implementation.zone;
577 CreatePeriodicTimerHandler handler = implementation.function;
578 return handler(implZone, _parentDelegate(implZone), zone, period, f);
579 }
580
581 void print(Zone zone, String line) {
582 var implementation = _delegationTarget._print;
583 _Zone implZone = implementation.zone;
584 PrintHandler handler = implementation.function;
585 handler(implZone, _parentDelegate(implZone), zone, line);
586 }
587
588 Zone fork(Zone zone, ZoneSpecification specification,
589 Map zoneValues) {
590 var implementation = _delegationTarget._fork;
591 _Zone implZone = implementation.zone;
592 ForkHandler handler = implementation.function;
593 return handler(
594 implZone, _parentDelegate(implZone), zone, specification, zoneValues);
595 }
596 }
597
598
599 /**
600 * Base class for Zone implementations.
601 */
602 abstract class _Zone implements Zone {
603 const _Zone();
604
605 _ZoneFunction<RunHandler> get _run;
606 _ZoneFunction<RunUnaryHandler> get _runUnary;
607 _ZoneFunction<RunBinaryHandler> get _runBinary;
608 _ZoneFunction<RegisterCallbackHandler> get _registerCallback;
609 _ZoneFunction<RegisterUnaryCallbackHandler> get _registerUnaryCallback;
610 _ZoneFunction<RegisterBinaryCallbackHandler> get _registerBinaryCallback;
611 _ZoneFunction<ErrorCallbackHandler> get _errorCallback;
612 _ZoneFunction<ScheduleMicrotaskHandler> get _scheduleMicrotask;
613 _ZoneFunction<CreateTimerHandler> get _createTimer;
614 _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer;
615 _ZoneFunction<PrintHandler> get _print;
616 _ZoneFunction<ForkHandler> get _fork;
617 _ZoneFunction<HandleUncaughtErrorHandler> get _handleUncaughtError;
618 _Zone get parent;
619 ZoneDelegate get _delegate;
620 Map get _map;
621
622 bool inSameErrorZone(Zone otherZone) {
623 return identical(this, otherZone) ||
624 identical(errorZone, otherZone.errorZone);
625 }
626 }
627
628 class _CustomZone extends _Zone {
629 // The actual zone and implementation of each of these
630 // inheritable zone functions.
631 _ZoneFunction<RunHandler> _run;
632 _ZoneFunction<RunUnaryHandler> _runUnary;
633 _ZoneFunction<RunBinaryHandler> _runBinary;
634 _ZoneFunction<RegisterCallbackHandler> _registerCallback;
635 _ZoneFunction<RegisterUnaryCallbackHandler> _registerUnaryCallback;
636 _ZoneFunction<RegisterBinaryCallbackHandler> _registerBinaryCallback;
637 _ZoneFunction<ErrorCallbackHandler> _errorCallback;
638 _ZoneFunction<ScheduleMicrotaskHandler> _scheduleMicrotask;
639 _ZoneFunction<CreateTimerHandler> _createTimer;
640 _ZoneFunction<CreatePeriodicTimerHandler> _createPeriodicTimer;
641 _ZoneFunction<PrintHandler> _print;
642 _ZoneFunction<ForkHandler> _fork;
643 _ZoneFunction<HandleUncaughtErrorHandler> _handleUncaughtError;
644
645 // A cached delegate to this zone.
646 ZoneDelegate _delegateCache;
647
648 /// The parent zone.
649 final _Zone parent;
650
651 /// The zone's scoped value declaration map.
652 ///
653 /// This is always a [HashMap].
654 final Map _map;
655
656 ZoneDelegate get _delegate {
657 if (_delegateCache != null) return _delegateCache;
658 _delegateCache = new _ZoneDelegate(this);
659 return _delegateCache;
660 }
661
662 _CustomZone(this.parent, ZoneSpecification specification, this._map) {
663 // The root zone will have implementations of all parts of the
664 // specification, so it will never try to access the (null) parent.
665 // All other zones have a non-null parent.
666 _run = (specification.run != null)
667 ? new _ZoneFunction<RunHandler>(this, specification.run)
668 : parent._run;
669 _runUnary = (specification.runUnary != null)
670 ? new _ZoneFunction<RunUnaryHandler>(this, specification.runUnary)
671 : parent._runUnary;
672 _runBinary = (specification.runBinary != null)
673 ? new _ZoneFunction<RunBinaryHandler>(this, specification.runBinary)
674 : parent._runBinary;
675 _registerCallback = (specification.registerCallback != null)
676 ? new _ZoneFunction<RegisterCallbackHandler>(
677 this, specification.registerCallback)
678 : parent._registerCallback;
679 _registerUnaryCallback = (specification.registerUnaryCallback != null)
680 ? new _ZoneFunction<RegisterUnaryCallbackHandler>(
681 this, specification.registerUnaryCallback)
682 : parent._registerUnaryCallback;
683 _registerBinaryCallback = (specification.registerBinaryCallback != null)
684 ? new _ZoneFunction<RegisterBinaryCallbackHandler>(
685 this, specification.registerBinaryCallback)
686 : parent._registerBinaryCallback;
687 _errorCallback = (specification.errorCallback != null)
688 ? new _ZoneFunction<ErrorCallbackHandler>(
689 this, specification.errorCallback)
690 : parent._errorCallback;
691 _scheduleMicrotask = (specification.scheduleMicrotask != null)
692 ? new _ZoneFunction<ScheduleMicrotaskHandler>(
693 this, specification.scheduleMicrotask)
694 : parent._scheduleMicrotask;
695 _createTimer = (specification.createTimer != null)
696 ? new _ZoneFunction<CreateTimerHandler>(this, specification.createTimer)
697 : parent._createTimer;
698 _createPeriodicTimer = (specification.createPeriodicTimer != null)
699 ? new _ZoneFunction<CreatePeriodicTimerHandler>(
700 this, specification.createPeriodicTimer)
701 : parent._createPeriodicTimer;
702 _print = (specification.print != null)
703 ? new _ZoneFunction<PrintHandler>(this, specification.print)
704 : parent._print;
705 _fork = (specification.fork != null)
706 ? new _ZoneFunction<ForkHandler>(this, specification.fork)
707 : parent._fork;
708 _handleUncaughtError = (specification.handleUncaughtError != null)
709 ? new _ZoneFunction<HandleUncaughtErrorHandler>(
710 this, specification.handleUncaughtError)
711 : parent._handleUncaughtError;
712 }
713
714 /**
715 * The closest error-handling zone.
716 *
717 * Returns `this` if `this` has an error-handler. Otherwise returns the
718 * parent's error-zone.
719 */
720 Zone get errorZone => _handleUncaughtError.zone;
721
722 /*=R*/ runGuarded/*<R>*/(/*=R*/ f()) {
723 try {
724 return run(f);
725 } catch (e, s) {
726 return handleUncaughtError(e, s);
727 }
728 }
729
730 /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg) {
731 try {
732 return runUnary(f, arg);
733 } catch (e, s) {
734 return handleUncaughtError(e, s);
735 }
736 }
737
738 /*=R*/ runBinaryGuarded/*<R, T1, T2>*/(
739 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2) {
740 try {
741 return runBinary(f, arg1, arg2);
742 } catch (e, s) {
743 return handleUncaughtError(e, s);
744 }
745 }
746
747 ZoneCallback/*<R>*/ bindCallback/*<R>*/(
748 /*=R*/ f(), { bool runGuarded: true }) {
749 var registered = registerCallback(f);
750 if (runGuarded) {
751 return () => this.runGuarded(registered);
752 } else {
753 return () => this.run(registered);
754 }
755 }
756
757 ZoneUnaryCallback/*<R, T>*/ bindUnaryCallback/*<R, T>*/(
758 /*=R*/ f(/*=T*/ arg), { bool runGuarded: true }) {
759 var registered = registerUnaryCallback(f);
760 if (runGuarded) {
761 return (arg) => this.runUnaryGuarded(registered, arg);
762 } else {
763 return (arg) => this.runUnary(registered, arg);
764 }
765 }
766
767 ZoneBinaryCallback/*<R, T1, T2>*/ bindBinaryCallback/*<R, T1, T2>*/(
768 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), { bool runGuarded: true }) {
769 var registered = registerBinaryCallback(f);
770 if (runGuarded) {
771 return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2);
772 } else {
773 return (arg1, arg2) => this.runBinary(registered, arg1, arg2);
774 }
775 }
776
777 operator [](Object key) {
778 var result = _map[key];
779 if (result != null || _map.containsKey(key)) return result;
780 // If we are not the root zone, look up in the parent zone.
781 if (parent != null) {
782 // We do not optimize for repeatedly looking up a key which isn't
783 // there. That would require storing the key and keeping it alive.
784 // Copying the key/value from the parent does not keep any new values
785 // alive.
786 var value = parent[key];
787 if (value != null) {
788 _map[key] = value;
789 }
790 return value;
791 }
792 assert(this == _ROOT_ZONE);
793 return null;
794 }
795
796 // Methods that can be customized by the zone specification.
797
798 /*=R*/ handleUncaughtError/*<R>*/(error, StackTrace stackTrace) {
799 var implementation = this._handleUncaughtError;
800 assert(implementation != null);
801 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
802 HandleUncaughtErrorHandler handler = implementation.function;
803 // TODO(floitsch): make this a generic method call on '<R>' once it's
804 // supported. Remove the unnecessary cast.
805 return handler(
806 implementation.zone, parentDelegate, this, error, stackTrace)
807 as Object/*=R*/;
808 }
809
810 Zone fork({ZoneSpecification specification, Map zoneValues}) {
811 var implementation = this._fork;
812 assert(implementation != null);
813 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
814 ForkHandler handler = implementation.function;
815 return handler(implementation.zone, parentDelegate, this,
816 specification, zoneValues);
817 }
818
819 /*=R*/ run/*<R>*/(/*=R*/ f()) {
820 var implementation = this._run;
821 assert(implementation != null);
822 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
823 RunHandler handler = implementation.function;
824 // TODO(floitsch): make this a generic method call on '<R>' once it's
825 // supported. Remove the unnecessary cast.
826 return handler(implementation.zone, parentDelegate, this, f)
827 as Object/*=R*/;
828 }
829
830 /*=R*/ runUnary/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg) {
831 var implementation = this._runUnary;
832 assert(implementation != null);
833 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
834 RunUnaryHandler handler = implementation.function;
835 // TODO(floitsch): make this a generic method call on '<R, T>' once it's
836 // supported. Remove the unnecessary cast.
837 return handler(implementation.zone, parentDelegate, this, f, arg)
838 as Object/*=R*/;
839 }
840
841 /*=R*/ runBinary/*<R, T1, T2>*/(
842 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2) {
843 var implementation = this._runBinary;
844 assert(implementation != null);
845 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
846 RunBinaryHandler handler = implementation.function;
847 // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once
848 // it's supported. Remove the unnecessary cast.
849 return handler(
850 implementation.zone, parentDelegate, this, f, arg1, arg2)
851 as Object/*=R*/;
852 }
853
854 ZoneCallback/*<R>*/ registerCallback/*<R>*/(/*=R*/ callback()) {
855 var implementation = this._registerCallback;
856 assert(implementation != null);
857 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
858 RegisterCallbackHandler handler = implementation.function;
859 // TODO(floitsch): make this a generic method call on '<R>' once it's
860 // supported. Remove the unnecessary cast.
861 return handler(implementation.zone, parentDelegate, this, callback)
862 as Object/*=ZoneCallback<R>*/;
863 }
864
865 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
866 /*=R*/ callback(/*=T*/ arg)) {
867 var implementation = this._registerUnaryCallback;
868 assert(implementation != null);
869 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
870 RegisterUnaryCallbackHandler handler = implementation.function;
871 // TODO(floitsch): make this a generic method call on '<R, T>' once it's
872 // supported. Remove the unnecessary cast.
873 return handler(implementation.zone, parentDelegate, this, callback)
874 as Object/*=ZoneUnaryCallback<R, T>*/;
875 }
876
877 ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
878 /*=R*/ callback(/*=T1*/ arg1, /*=T2*/ arg2)) {
879 var implementation = this._registerBinaryCallback;
880 assert(implementation != null);
881 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
882 RegisterBinaryCallbackHandler handler = implementation.function;
883 // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once
884 // it's supported. Remove the unnecessary cast.
885 return handler(implementation.zone, parentDelegate, this, callback)
886 as Object/*=ZoneBinaryCallback<R, T1, T2>*/;
887 }
888
889 AsyncError errorCallback(Object error, StackTrace stackTrace) {
890 var implementation = this._errorCallback;
891 assert(implementation != null);
892 final Zone implementationZone = implementation.zone;
893 if (identical(implementationZone, _ROOT_ZONE)) return null;
894 final ZoneDelegate parentDelegate = _parentDelegate(implementationZone);
895 ErrorCallbackHandler handler = implementation.function;
896 return handler(
897 implementationZone, parentDelegate, this, error, stackTrace);
898 }
899
900 void scheduleMicrotask(void f()) {
901 var implementation = this._scheduleMicrotask;
902 assert(implementation != null);
903 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
904 ScheduleMicrotaskHandler handler = implementation.function;
905 return handler(implementation.zone, parentDelegate, this, f);
906 }
907
908 Timer createTimer(Duration duration, void f()) {
909 var implementation = this._createTimer;
910 assert(implementation != null);
911 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
912 CreateTimerHandler handler = implementation.function;
913 return handler(implementation.zone, parentDelegate, this, duration, f);
914 }
915
916 Timer createPeriodicTimer(Duration duration, void f(Timer timer)) {
917 var implementation = this._createPeriodicTimer;
918 assert(implementation != null);
919 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
920 CreatePeriodicTimerHandler handler = implementation.function;
921 return handler(
922 implementation.zone, parentDelegate, this, duration, f);
923 }
924
925 void print(String line) {
926 var implementation = this._print;
927 assert(implementation != null);
928 ZoneDelegate parentDelegate = _parentDelegate(implementation.zone);
929 PrintHandler handler = implementation.function;
930 return handler(implementation.zone, parentDelegate, this, line);
931 }
932 }
933
934 /*=R*/ _rootHandleUncaughtError/*<R>*/(
935 Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace) {
936 _schedulePriorityAsyncCallback(() {
937 if (error == null) error = new NullThrownError();
938 if (stackTrace == null) throw error;
939 _rethrow(error, stackTrace);
940 });
941 }
942
943 external void _rethrow(Object error, StackTrace stackTrace);
944
945 /*=R*/ _rootRun/*<R>*/(Zone self, ZoneDelegate parent, Zone zone, /*=R*/ f()) {
946 if (Zone._current == zone) return f();
947
948 Zone old = Zone._enter(zone);
949 try {
950 return f();
951 } finally {
952 Zone._leave(old);
953 }
954 }
955
956 /*=R*/ _rootRunUnary/*<R, T>*/(Zone self, ZoneDelegate parent, Zone zone,
957 /*=R*/ f(/*=T*/ arg), /*=T*/ arg) {
958 if (Zone._current == zone) return f(arg);
959
960 Zone old = Zone._enter(zone);
961 try {
962 return f(arg);
963 } finally {
964 Zone._leave(old);
965 }
966 }
967
968 /*=R*/ _rootRunBinary/*<R, T1, T2>*/(Zone self, ZoneDelegate parent, Zone zone,
969 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2) {
970 if (Zone._current == zone) return f(arg1, arg2);
971
972 Zone old = Zone._enter(zone);
973 try {
974 return f(arg1, arg2);
975 } finally {
976 Zone._leave(old);
977 }
978 }
979
980 ZoneCallback/*<R>*/ _rootRegisterCallback/*<R>*/(
981 Zone self, ZoneDelegate parent, Zone zone, /*=R*/ f()) {
982 return f;
983 }
984
985 ZoneUnaryCallback/*<R, T>*/ _rootRegisterUnaryCallback/*<R, T>*/(
986 Zone self, ZoneDelegate parent, Zone zone, /*=R*/ f(/*=T*/ arg)) {
987 return f;
988 }
989
990 ZoneBinaryCallback/*<R, T1, T2>*/ _rootRegisterBinaryCallback/*<R, T1, T2>*/(
991 Zone self, ZoneDelegate parent, Zone zone,
992 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2)) {
993 return f;
994 }
995
996 AsyncError _rootErrorCallback(Zone self, ZoneDelegate parent, Zone zone,
997 Object error, StackTrace stackTrace) => null;
998
999 void _rootScheduleMicrotask(Zone self, ZoneDelegate parent, Zone zone, f()) {
1000 if (!identical(_ROOT_ZONE, zone)) {
1001 bool hasErrorHandler = !_ROOT_ZONE.inSameErrorZone(zone);
1002 f = zone.bindCallback(f, runGuarded: hasErrorHandler);
1003 // Use root zone as event zone if the function is already bound.
1004 zone = _ROOT_ZONE;
1005 }
1006 _scheduleAsyncCallback(f);
1007 }
1008
1009 Timer _rootCreateTimer(Zone self, ZoneDelegate parent, Zone zone,
1010 Duration duration, void callback()) {
1011 if (!identical(_ROOT_ZONE, zone)) {
1012 callback = zone.bindCallback(callback);
1013 }
1014 return Timer._createTimer(duration, callback);
1015 }
1016
1017 Timer _rootCreatePeriodicTimer(
1018 Zone self, ZoneDelegate parent, Zone zone,
1019 Duration duration, void callback(Timer timer)) {
1020 if (!identical(_ROOT_ZONE, zone)) {
1021 // TODO(floitsch): the return type should be 'void'.
1022 callback = zone.bindUnaryCallback/*<dynamic, Timer>*/(callback);
1023 }
1024 return Timer._createPeriodicTimer(duration, callback);
1025 }
1026
1027 void _rootPrint(Zone self, ZoneDelegate parent, Zone zone, String line) {
1028 printToConsole(line);
1029 }
1030
1031 void _printToZone(String line) {
1032 Zone.current.print(line);
1033 }
1034
1035 Zone _rootFork(Zone self, ZoneDelegate parent, Zone zone,
1036 ZoneSpecification specification,
1037 Map zoneValues) {
1038 // TODO(floitsch): it would be nice if we could get rid of this hack.
1039 // Change the static zoneOrDirectPrint function to go through zones
1040 // from now on.
1041 printToZone = _printToZone;
1042
1043 if (specification == null) {
1044 specification = const ZoneSpecification();
1045 } else if (specification is! _ZoneSpecification) {
1046 throw new ArgumentError("ZoneSpecifications must be instantiated"
1047 " with the provided constructor.");
1048 }
1049 Map valueMap;
1050 if (zoneValues == null) {
1051 if (zone is _Zone) {
1052 valueMap = zone._map;
1053 } else {
1054 valueMap = new HashMap();
1055 }
1056 } else {
1057 valueMap = new HashMap.from(zoneValues);
1058 }
1059 return new _CustomZone(zone, specification, valueMap);
1060 }
1061
1062 class _RootZone extends _Zone {
1063 const _RootZone();
1064
1065 _ZoneFunction<RunHandler> get _run =>
1066 const _ZoneFunction<RunHandler>(_ROOT_ZONE, _rootRun);
1067 _ZoneFunction<RunUnaryHandler> get _runUnary =>
1068 const _ZoneFunction<RunUnaryHandler>(_ROOT_ZONE, _rootRunUnary);
1069 _ZoneFunction<RunBinaryHandler> get _runBinary =>
1070 const _ZoneFunction<RunBinaryHandler>(_ROOT_ZONE, _rootRunBinary);
1071 _ZoneFunction<RegisterCallbackHandler> get _registerCallback =>
1072 const _ZoneFunction<RegisterCallbackHandler>(
1073 _ROOT_ZONE, _rootRegisterCallback);
1074 _ZoneFunction<RegisterUnaryCallbackHandler> get _registerUnaryCallback =>
1075 const _ZoneFunction<RegisterUnaryCallbackHandler>(
1076 _ROOT_ZONE, _rootRegisterUnaryCallback);
1077 _ZoneFunction<RegisterBinaryCallbackHandler> get _registerBinaryCallback =>
1078 const _ZoneFunction<RegisterBinaryCallbackHandler>(
1079 _ROOT_ZONE, _rootRegisterBinaryCallback);
1080 _ZoneFunction<ErrorCallbackHandler> get _errorCallback =>
1081 const _ZoneFunction<ErrorCallbackHandler>(_ROOT_ZONE, _rootErrorCallback);
1082 _ZoneFunction<ScheduleMicrotaskHandler> get _scheduleMicrotask =>
1083 const _ZoneFunction<ScheduleMicrotaskHandler>(
1084 _ROOT_ZONE, _rootScheduleMicrotask);
1085 _ZoneFunction<CreateTimerHandler> get _createTimer =>
1086 const _ZoneFunction<CreateTimerHandler>(_ROOT_ZONE, _rootCreateTimer);
1087 _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer =>
1088 const _ZoneFunction<CreatePeriodicTimerHandler>(_ROOT_ZONE, _rootCreatePer iodicTimer);
1089 _ZoneFunction<PrintHandler> get _print =>
1090 const _ZoneFunction<PrintHandler>(_ROOT_ZONE, _rootPrint);
1091 _ZoneFunction<ForkHandler> get _fork =>
1092 const _ZoneFunction<ForkHandler>(_ROOT_ZONE, _rootFork);
1093 _ZoneFunction<HandleUncaughtErrorHandler> get _handleUncaughtError =>
1094 const _ZoneFunction<HandleUncaughtErrorHandler>(
1095 _ROOT_ZONE, _rootHandleUncaughtError);
1096
1097 // The parent zone.
1098 _Zone get parent => null;
1099
1100 /// The zone's scoped value declaration map.
1101 ///
1102 /// This is always a [HashMap].
1103 Map get _map => _rootMap;
1104
1105 static Map _rootMap = new HashMap();
1106
1107 static ZoneDelegate _rootDelegate;
1108
1109 ZoneDelegate get _delegate {
1110 if (_rootDelegate != null) return _rootDelegate;
1111 return _rootDelegate = new _ZoneDelegate(this);
1112 }
1113
1114 /**
1115 * The closest error-handling zone.
1116 *
1117 * Returns `this` if `this` has an error-handler. Otherwise returns the
1118 * parent's error-zone.
1119 */
1120 Zone get errorZone => this;
1121
1122 // Zone interface.
1123
1124 /*=R*/ runGuarded/*<R>*/(/*=R*/ f()) {
1125 try {
1126 if (identical(_ROOT_ZONE, Zone._current)) {
1127 return f();
1128 }
1129 return _rootRun/*<R>*/(null, null, this, f);
1130 } catch (e, s) {
1131 return handleUncaughtError/*<R>*/(e, s);
1132 }
1133 }
1134
1135 /*=R*/ runUnaryGuarded/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg) {
1136 try {
1137 if (identical(_ROOT_ZONE, Zone._current)) {
1138 return f(arg);
1139 }
1140 return _rootRunUnary/*<R, T>*/(null, null, this, f, arg);
1141 } catch (e, s) {
1142 return handleUncaughtError/*<R>*/(e, s);
1143 }
1144 }
1145
1146 /*=R*/ runBinaryGuarded/*<R, T1, T2>*/(
1147 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2) {
1148 try {
1149 if (identical(_ROOT_ZONE, Zone._current)) {
1150 return f(arg1, arg2);
1151 }
1152 return _rootRunBinary/*<R, T1, T2>*/(null, null, this, f, arg1, arg2);
1153 } catch (e, s) {
1154 return handleUncaughtError/*<R>*/(e, s);
1155 }
1156 }
1157
1158 ZoneCallback/*<R>*/ bindCallback/*<R>*/(
1159 /*=R*/ f(), { bool runGuarded: true }) {
1160 if (runGuarded) {
1161 return () => this.runGuarded/*<R>*/(f);
1162 } else {
1163 return () => this.run/*<R>*/(f);
1164 }
1165 }
1166
1167 ZoneUnaryCallback/*<R, T>*/ bindUnaryCallback/*<R, T>*/(
1168 /*=R*/ f(/*=T*/ arg), { bool runGuarded: true }) {
1169 if (runGuarded) {
1170 return (arg) => this.runUnaryGuarded/*<R, T>*/(f, arg);
1171 } else {
1172 return (arg) => this.runUnary/*<R, T>*/(f, arg);
1173 }
1174 }
1175
1176 ZoneBinaryCallback/*<R, T1, T2>*/ bindBinaryCallback/*<R, T1, T2>*/(
1177 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), { bool runGuarded: true }) {
1178 if (runGuarded) {
1179 return (arg1, arg2) =>
1180 this.runBinaryGuarded/*<R, T1, T2>*/(f, arg1, arg2);
1181 } else {
1182 return (arg1, arg2) => this.runBinary/*<R, T1, T2>*/(f, arg1, arg2);
1183 }
1184 }
1185
1186 operator [](Object key) => null;
1187
1188 // Methods that can be customized by the zone specification.
1189
1190 /*=R*/ handleUncaughtError/*<R>*/(error, StackTrace stackTrace) {
1191 return _rootHandleUncaughtError(null, null, this, error, stackTrace);
1192 }
1193
1194 Zone fork({ZoneSpecification specification, Map zoneValues}) {
1195 return _rootFork(null, null, this, specification, zoneValues);
1196 }
1197
1198 /*=R*/ run/*<R>*/(/*=R*/ f()) {
1199 if (identical(Zone._current, _ROOT_ZONE)) return f();
1200 return _rootRun(null, null, this, f);
1201 }
1202
1203 /*=R*/ runUnary/*<R, T>*/(/*=R*/ f(/*=T*/ arg), /*=T*/ arg) {
1204 if (identical(Zone._current, _ROOT_ZONE)) return f(arg);
1205 return _rootRunUnary(null, null, this, f, arg);
1206 }
1207
1208 /*=R*/ runBinary/*<R, T1, T2>*/(
1209 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2), /*=T1*/ arg1, /*=T2*/ arg2) {
1210 if (identical(Zone._current, _ROOT_ZONE)) return f(arg1, arg2);
1211 return _rootRunBinary(null, null, this, f, arg1, arg2);
1212 }
1213
1214 ZoneCallback/*<R>*/ registerCallback/*<R>*/(/*=R*/ f()) => f;
1215
1216 ZoneUnaryCallback/*<R, T>*/ registerUnaryCallback/*<R, T>*/(
1217 /*=R*/ f(/*=T*/ arg)) => f;
1218
1219 ZoneBinaryCallback/*<R, T1, T2>*/ registerBinaryCallback/*<R, T1, T2>*/(
1220 /*=R*/ f(/*=T1*/ arg1, /*=T2*/ arg2)) => f;
1221
1222 AsyncError errorCallback(Object error, StackTrace stackTrace) => null;
1223
1224 void scheduleMicrotask(void f()) {
1225 _rootScheduleMicrotask(null, null, this, f);
1226 }
1227
1228 Timer createTimer(Duration duration, void f()) {
1229 return Timer._createTimer(duration, f);
1230 }
1231
1232 Timer createPeriodicTimer(Duration duration, void f(Timer timer)) {
1233 return Timer._createPeriodicTimer(duration, f);
1234 }
1235
1236 void print(String line) {
1237 printToConsole(line);
1238 }
1239 }
1240
1241 const _ROOT_ZONE = const _RootZone();
1242
1243 /**
1244 * Runs [body] in its own zone.
1245 *
1246 * If [onError] is non-null the zone is considered an error zone. All uncaught
1247 * errors, synchronous or asynchronous, in the zone are caught and handled
1248 * by the callback.
1249 *
1250 * Errors may never cross error-zone boundaries. This is intuitive for leaving
1251 * a zone, but it also applies for errors that would enter an error-zone.
1252 * Errors that try to cross error-zone boundaries are considered uncaught.
1253 *
1254 * var future = new Future.value(499);
1255 * runZoned(() {
1256 * future = future.then((_) { throw "error in first error-zone"; });
1257 * runZoned(() {
1258 * future = future.catchError((e) { print("Never reached!"); });
1259 * }, onError: (e) { print("unused error handler"); });
1260 * }, onError: (e) { print("catches error of first error-zone."); });
1261 *
1262 * Example:
1263 *
1264 * runZoned(() {
1265 * new Future(() { throw "asynchronous error"; });
1266 * }, onError: print); // Will print "asynchronous error".
1267 */
1268 /*=R*/ runZoned/*<R>*/(/*=R*/ body(),
1269 { Map zoneValues,
1270 ZoneSpecification zoneSpecification,
1271 Function onError }) {
1272 HandleUncaughtErrorHandler errorHandler;
1273 if (onError != null) {
1274 errorHandler = (Zone self, ZoneDelegate parent, Zone zone,
1275 error, StackTrace stackTrace) {
1276 try {
1277 // Change this is check back to
1278 // onError is ZoneBinaryCallback<dynamic/*=R*/, dynamic, StackTrace>
1279 // once is checks for that type are handled correctly.
1280 if (onError is ZoneBinaryCallback<dynamic, dynamic, StackTrace>) {
1281 return self.parent.runBinary(onError, error, stackTrace) as Object/*=R */;
1282 }
1283 return self.parent.runUnary(onError, error);
1284 } catch(e, s) {
1285 if (identical(e, error)) {
1286 return parent.handleUncaughtError(zone, error, stackTrace);
1287 } else {
1288 return parent.handleUncaughtError(zone, e, s);
1289 }
1290 }
1291 };
1292 }
1293 if (zoneSpecification == null) {
1294 zoneSpecification =
1295 new ZoneSpecification(handleUncaughtError: errorHandler);
1296 } else if (errorHandler != null) {
1297 zoneSpecification =
1298 new ZoneSpecification.from(zoneSpecification,
1299 handleUncaughtError: errorHandler);
1300 }
1301 Zone zone = Zone.current.fork(specification: zoneSpecification,
1302 zoneValues: zoneValues);
1303 if (onError != null) {
1304 return zone.runGuarded(body);
1305 } else {
1306 return zone.run(body);
1307 }
1308 }
OLDNEW
« no previous file with comments | « pkg/dev_compiler/tool/input_sdk/lib/async/timer.dart ('k') | pkg/dev_compiler/tool/input_sdk/lib/collection/collection.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698