|  | // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | part of dart.async; | 
|  |  | 
|  | typedef ZoneCallback<R> = R Function(); | 
|  | typedef ZoneUnaryCallback<R, T> = R Function(T); | 
|  | typedef ZoneBinaryCallback<R, T1, T2> = R Function(T1, T2); | 
|  |  | 
|  | /// The type of a custom [Zone.handleUncaughtError] implementation function. | 
|  | /// | 
|  | /// Receives the [Zone] that the handler was registered on as [self], | 
|  | /// a delegate forwarding to the handlers of [self]'s parent zone as [parent], | 
|  | /// and the current zone where the error was uncaught as [zone], | 
|  | /// which will have [self] as a parent zone. | 
|  | /// | 
|  | /// The [error] and [stackTrace] are the error and stack trace that | 
|  | /// was uncaught in [zone]. | 
|  | /// | 
|  | /// The function must only access zone-related functionality through | 
|  | /// [self], [parent] or [zone]. | 
|  | /// It should not depend on the current zone ([Zone.current]). | 
|  | /// | 
|  | /// If the uncaught error handler throws, the error will be passed | 
|  | /// to `parent.handleUncaughtError`. If the thrown object is [error], | 
|  | /// the throw is considered a re-throw and the original [stackTrace] | 
|  | /// is retained. This allows an asynchronous error to leave the error zone. | 
|  | typedef HandleUncaughtErrorHandler = | 
|  | void Function( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | Object error, | 
|  | StackTrace stackTrace, | 
|  | ); | 
|  |  | 
|  | /// The type of a custom [Zone.run] implementation function. | 
|  | /// | 
|  | /// Receives the [Zone] that the handler was registered on as [self], | 
|  | /// a delegate forwarding to the handlers of [self]'s parent zone as [parent], | 
|  | /// and the current zone where the error was uncaught as [zone], | 
|  | /// which will have [self] as a parent zone. | 
|  | /// | 
|  | /// The function [f] is the function which was passed to the | 
|  | /// [Zone.run] of [zone]. | 
|  | /// | 
|  | /// The default behavior of [Zone.run] is | 
|  | /// to call [f] in the current zone, [zone]. | 
|  | /// A custom handler can do things before, after or instead of | 
|  | /// calling [f]. | 
|  | /// | 
|  | /// The function must only access zone-related functionality through | 
|  | /// [self], [parent] or [zone]. | 
|  | /// It should not depend on the current zone ([Zone.current]). | 
|  | typedef RunHandler = | 
|  | R Function<R>(Zone self, ZoneDelegate parent, Zone zone, R Function() f); | 
|  |  | 
|  | /// The type of a custom [Zone.runUnary] implementation function. | 
|  | /// | 
|  | /// Receives the [Zone] that the handler was registered on as [self], | 
|  | /// a delegate forwarding to the handlers of [self]'s parent zone as [parent], | 
|  | /// and the current zone where the error was uncaught as [zone], | 
|  | /// which will have [self] as a parent zone. | 
|  | /// | 
|  | /// The function [f] and value [arg] are the function and argument | 
|  | /// which was passed to the [Zone.runUnary] of [zone]. | 
|  | /// | 
|  | /// The default behavior of [Zone.runUnary] is | 
|  | /// to call [f] with argument [arg] in the current zone, [zone]. | 
|  | /// A custom handler can do things before, after or instead of | 
|  | /// calling [f]. | 
|  | /// | 
|  | /// The function must only access zone-related functionality through | 
|  | /// [self], [parent] or [zone]. | 
|  | /// It should not depend on the current zone ([Zone.current]). | 
|  | typedef RunUnaryHandler = | 
|  | R Function<R, T>( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | R Function(T arg) f, | 
|  | T arg, | 
|  | ); | 
|  |  | 
|  | /// The type of a custom [Zone.runBinary] implementation function. | 
|  | /// | 
|  | /// Receives the [Zone] that the handler was registered on as [self], | 
|  | /// a delegate forwarding to the handlers of [self]'s parent zone as [parent], | 
|  | /// and the current zone where the error was uncaught as [zone], | 
|  | /// which will have [self] as a parent zone. | 
|  | /// | 
|  | /// The function [f] and values [arg1] and [arg2] are the function and arguments | 
|  | /// which was passed to the [Zone.runBinary] of [zone]. | 
|  | /// | 
|  | /// The default behavior of [Zone.runUnary] is | 
|  | /// to call [f] with arguments [arg1] and [arg2] in the current zone, [zone]. | 
|  | /// A custom handler can do things before, after or instead of | 
|  | /// calling [f]. | 
|  | /// | 
|  | /// The function must only access zone-related functionality through | 
|  | /// [self], [parent] or [zone]. | 
|  | /// It should not depend on the current zone ([Zone.current]). | 
|  | typedef RunBinaryHandler = | 
|  | R Function<R, T1, T2>( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | R Function(T1 arg1, T2 arg2) f, | 
|  | T1 arg1, | 
|  | T2 arg2, | 
|  | ); | 
|  |  | 
|  | /// The type of a custom [Zone.registerCallback] implementation function. | 
|  | /// | 
|  | /// Receives the [Zone] that the handler was registered on as [self], | 
|  | /// a delegate forwarding to the handlers of [self]'s parent zone as [parent], | 
|  | /// and the current zone where the error was uncaught as [zone], | 
|  | /// which will have [self] as a parent zone. | 
|  | /// | 
|  | /// The function [f] is the function which was passed to the | 
|  | /// [Zone.registerCallback] of [zone]. | 
|  | /// | 
|  | /// The handler should return either the function [f] | 
|  | /// or another function replacing [f], | 
|  | /// typically by wrapping [f] in a function | 
|  | /// which does something extra before and after invoking [f] | 
|  | /// | 
|  | /// The function must only access zone-related functionality through | 
|  | /// [self], [parent] or [zone]. | 
|  | /// It should not depend on the current zone ([Zone.current]). | 
|  | typedef RegisterCallbackHandler = | 
|  | ZoneCallback<R> Function<R>( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | R Function() f, | 
|  | ); | 
|  |  | 
|  | /// The type of a custom [Zone.registerUnaryCallback] implementation function. | 
|  | /// | 
|  | /// Receives the [Zone] that the handler was registered on as [self], | 
|  | /// a delegate forwarding to the handlers of [self]'s parent zone as [parent], | 
|  | /// and the current zone where the error was uncaught as [zone], | 
|  | /// which will have [self] as a parent zone. | 
|  | /// | 
|  | /// The function [f] is the function which was passed to the | 
|  | /// which was passed to the [Zone.registerUnaryCallback] of [zone]. | 
|  | /// | 
|  | /// The handler should return either the function [f] | 
|  | /// or another function replacing [f], | 
|  | /// typically by wrapping [f] in a function | 
|  | /// which does something extra before and after invoking [f] | 
|  | /// | 
|  | /// The function must only access zone-related functionality through | 
|  | /// [self], [parent] or [zone]. | 
|  | /// It should not depend on the current zone ([Zone.current]). | 
|  | typedef RegisterUnaryCallbackHandler = | 
|  | ZoneUnaryCallback<R, T> Function<R, T>( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | R Function(T arg) f, | 
|  | ); | 
|  |  | 
|  | /// The type of a custom [Zone.registerBinaryCallback] implementation function. | 
|  | /// | 
|  | /// Receives the [Zone] that the handler was registered on as [self], | 
|  | /// a delegate forwarding to the handlers of [self]'s parent zone as [parent], | 
|  | /// and the current zone where the error was uncaught as [zone], | 
|  | /// which will have [self] as a parent zone. | 
|  | /// | 
|  | /// The function [f] is the function which was passed to the | 
|  | /// which was passed to the [Zone.registerBinaryCallback] of [zone]. | 
|  | /// | 
|  | /// The handler should return either the function [f] | 
|  | /// or another function replacing [f], | 
|  | /// typically by wrapping [f] in a function | 
|  | /// which does something extra before and after invoking [f] | 
|  | typedef RegisterBinaryCallbackHandler = | 
|  | ZoneBinaryCallback<R, T1, T2> Function<R, T1, T2>( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | R Function(T1 arg1, T2 arg2) f, | 
|  | ); | 
|  |  | 
|  | /// The type of a custom [Zone.errorCallback] implementation function. | 
|  | /// | 
|  | /// The [error] and [stackTrace] are the error and stack trace | 
|  | /// passed to [Zone.errorCallback] of [zone]. | 
|  | /// | 
|  | /// The function will be called when a synchronous error becomes an | 
|  | /// asynchronous error, either by being caught, for example by a `Future.then` | 
|  | /// callback throwing, or when used to create an asynchronous error | 
|  | /// programmatically, for example using `Future.error` or `Completer.complete`. | 
|  | /// | 
|  | /// If the function does not want to replace the error or stack trace, | 
|  | /// it should just return `parent.errorCallback(zone, error, stackTrace)`, | 
|  | /// giving the parent zone the chance to intercept. | 
|  | /// | 
|  | /// If the function does want to replace the error and/or stack trace, | 
|  | /// say with `error2` and `stackTrace2`, it should still allow the | 
|  | /// parent zone to intercept those errors, for examples as: | 
|  | /// ```dart | 
|  | ///   return parent.errorCallback(zone, error, stackTrace) ?? | 
|  | ///       AsyncError(error, stackTrace); | 
|  | /// ``` | 
|  | /// | 
|  | /// The function returns either `null` if the original error and stack trace | 
|  | /// is unchanged, avoiding any allocation in the most common case, | 
|  | /// or an [AsyncError] containing a replacement error and stack trace | 
|  | /// which will be used in place of the originals as the asynchronous error. | 
|  | /// | 
|  | /// The [self] [Zone] is the zone the handler was registered on, | 
|  | /// the [parent] delegate forwards to the handlers of [self]'s parent zone, | 
|  | /// and [zone] is the current zone where the error was uncaught, | 
|  | /// which will have [self] as an ancestor zone. | 
|  | /// | 
|  | /// The error callback handler **must not** throw. | 
|  | /// | 
|  | /// The function must only access zone-related functionality through | 
|  | /// [self], [parent] or [zone]. | 
|  | /// It should not depend on the current zone ([Zone.current]). | 
|  | typedef ErrorCallbackHandler = | 
|  | AsyncError? Function( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | Object error, | 
|  | StackTrace? stackTrace, | 
|  | ); | 
|  |  | 
|  | /// The type of a custom [Zone.scheduleMicrotask] implementation function. | 
|  | /// | 
|  | /// Receives the [Zone] that the handler was registered on as [self], | 
|  | /// a delegate forwarding to the handlers of [self]'s parent zone as [parent], | 
|  | /// and the current zone where the error was uncaught as [zone], | 
|  | /// which will have [self] as a parent zone. | 
|  | /// | 
|  | /// The function [f] is the function which was | 
|  | /// passed to [Zone.scheduleMicrotask] of [zone]. | 
|  | /// | 
|  | /// The custom handler can choose to replace the function [f] | 
|  | /// with one that does something before, after or instead of calling [f], | 
|  | /// and then call `parent.scheduleMicrotask(zone, replacement)`. | 
|  | /// or it can implement its own microtask scheduling queue, which typically | 
|  | /// still depends on `parent.scheduleMicrotask` to as a way to get started. | 
|  | /// | 
|  | /// The function must only access zone-related functionality through | 
|  | /// [self], [parent] or [zone]. | 
|  | /// It should not depend on the current zone ([Zone.current]). | 
|  | typedef ScheduleMicrotaskHandler = | 
|  | void Function(Zone self, ZoneDelegate parent, Zone zone, void Function() f); | 
|  |  | 
|  | /// The type of a custom [Zone.createTimer] implementation function. | 
|  | /// | 
|  | /// Receives the [Zone] that the handler was registered on as [self], | 
|  | /// a delegate forwarding to the handlers of [self]'s parent zone as [parent], | 
|  | /// and the current zone where the error was uncaught as [zone], | 
|  | /// which will have [self] as a parent zone. | 
|  | /// | 
|  | /// The callback function [f] and [duration] are the ones which were | 
|  | /// passed to [Zone.createTimer] of [zone] | 
|  | /// (possibly through the [Timer] constructor). | 
|  | /// | 
|  | /// The custom handler can choose to replace the function [f] | 
|  | /// with one that does something before, after or instead of calling [f], | 
|  | /// and then call `parent.createTimer(zone, replacement)`. | 
|  | /// or it can implement its own timer queue, which typically | 
|  | /// still depends on `parent.createTimer` to as a way to get started. | 
|  | /// | 
|  | /// The function should return a [Timer] object which can be used | 
|  | /// to inspect and control the scheduled timer callback. | 
|  | /// | 
|  | /// The function must only access zone-related functionality through | 
|  | /// [self], [parent] or [zone]. | 
|  | /// It should not depend on the current zone ([Zone.current]). | 
|  | typedef CreateTimerHandler = | 
|  | Timer Function( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | Duration duration, | 
|  | void Function() f, | 
|  | ); | 
|  |  | 
|  | /// The type of a custom [Zone.createPeriodicTimer] implementation function. | 
|  | /// | 
|  | /// Receives the [Zone] that the handler was registered on as [self], | 
|  | /// a delegate forwarding to the handlers of [self]'s parent zone as [parent], | 
|  | /// and the current zone where the error was uncaught as [zone], | 
|  | /// which will have [self] as a parent zone. | 
|  | /// | 
|  | /// The callback function [f] and [period] are the ones which were | 
|  | /// passed to [Zone.createPeriodicTimer] of [zone] | 
|  | /// (possibly through the [Timer.periodic] constructor). | 
|  | /// | 
|  | /// The custom handler can choose to replace the function [f] | 
|  | /// with one that does something before, after or instead of calling [f], | 
|  | /// and then call `parent.createTimer(zone, replacement)`. | 
|  | /// or it can implement its own timer queue, which typically | 
|  | /// still depends on `parent.createTimer` to as a way to get started. | 
|  | /// | 
|  | /// The function should return a [Timer] object which can be used | 
|  | /// to inspect and control the scheduled timer callbacks. | 
|  | /// | 
|  | /// The function must only access zone-related functionality through | 
|  | /// [self], [parent] or [zone]. | 
|  | /// It should not depend on the current zone ([Zone.current]). | 
|  | typedef CreatePeriodicTimerHandler = | 
|  | Timer Function( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | Duration period, | 
|  | void Function(Timer timer) f, | 
|  | ); | 
|  |  | 
|  | /// The type of a custom [Zone.print] implementation function. | 
|  | /// | 
|  | /// Receives the [Zone] that the handler was registered on as [self], | 
|  | /// a delegate forwarding to the handlers of [self]'s parent zone as [parent], | 
|  | /// and the current zone where the error was uncaught as [zone], | 
|  | /// which will have [self] as a parent zone. | 
|  | /// | 
|  | /// The string [line] is the one which was passed to [Zone.print] of [zone], | 
|  | /// (possibly through the global [print] function). | 
|  | /// | 
|  | /// The custom handler can intercept print operations and | 
|  | /// redirect them to other targets than the console. | 
|  | /// | 
|  | /// The function must only access zone-related functionality through | 
|  | /// [self], [parent] or [zone]. | 
|  | /// It should not depend on the current zone ([Zone.current]). | 
|  | typedef PrintHandler = | 
|  | void Function(Zone self, ZoneDelegate parent, Zone zone, String line); | 
|  |  | 
|  | /// The type of a custom [Zone.fork] implementation function. | 
|  | /// | 
|  | /// Receives the [Zone] that the handler was registered on as [self], | 
|  | /// a delegate forwarding to the handlers of [self]'s parent zone as [parent], | 
|  | /// and the current zone where the error was uncaught as [zone], | 
|  | /// which will have [self] as a parent zone. | 
|  | /// | 
|  | /// The handler should create a new zone with [zone] as its | 
|  | /// immediate parent zone. | 
|  | /// | 
|  | /// The [specification] and [zoneValues] are the ones which were | 
|  | /// passed to [Zone.fork] of [zone]. They specify the custom zone | 
|  | /// handlers and zone variables that the new zone should have. | 
|  | /// | 
|  | /// The custom handler can change the specification or zone | 
|  | /// values before calling `parent.fork(zone, specification, zoneValues)`, | 
|  | /// but it has to call the [parent]'s [ZoneDelegate.fork] in order | 
|  | /// to create a valid [Zone] object. | 
|  | /// | 
|  | /// The function must only access zone-related functionality through | 
|  | /// [self], [parent] or [zone]. | 
|  | /// It should not depend on the current zone ([Zone.current]). | 
|  | typedef ForkHandler = | 
|  | Zone Function( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | ZoneSpecification? specification, | 
|  | Map<Object?, Object?>? zoneValues, | 
|  | ); | 
|  |  | 
|  | class _ZoneFunction<T extends Function> { | 
|  | final _Zone zone; | 
|  | final T function; | 
|  | const _ZoneFunction(this.zone, this.function); | 
|  | } | 
|  |  | 
|  | /// A parameter object with custom zone function handlers for [Zone.fork]. | 
|  | /// | 
|  | /// A zone specification is a parameter object passed to [Zone.fork] | 
|  | /// and any underlying [ForkHandler] custom implementations. | 
|  | /// The individual handlers, if set to a non-null value, | 
|  | /// will be the implementation of the corresponding [Zone] methods | 
|  | /// for a forked zone created using this zone specification. | 
|  | /// | 
|  | /// Handlers have the same signature as the same-named methods on [Zone], | 
|  | /// but receive three additional arguments: | 
|  | /// | 
|  | ///   1. The zone the handlers are attached to (the "self" zone). | 
|  | ///      This is the zone created by [Zone.fork] where the handler is | 
|  | ///      passed as part of the zone delegation. | 
|  | ///   2. A [ZoneDelegate] to the parent zone. | 
|  | ///   3. The "current" zone at the time the request was made. | 
|  | ///      The self zone is always a parent zone of the current zone. | 
|  | /// | 
|  | /// Handlers can either stop propagating the request (by simply not calling the | 
|  | /// parent handler), or forward to the parent zone, potentially modifying the | 
|  | /// arguments on the way. | 
|  | abstract final class ZoneSpecification { | 
|  | /// Creates a specification with the provided handlers. | 
|  | /// | 
|  | /// If the [handleUncaughtError] is provided, the new zone will be a new | 
|  | /// "error zone" which will prevent errors from flowing into other | 
|  | /// error zones (see [Zone.errorZone], [Zone.inSameErrorZone]). | 
|  | const factory ZoneSpecification({ | 
|  | HandleUncaughtErrorHandler? handleUncaughtError, | 
|  | RunHandler? run, | 
|  | RunUnaryHandler? runUnary, | 
|  | RunBinaryHandler? runBinary, | 
|  | RegisterCallbackHandler? registerCallback, | 
|  | RegisterUnaryCallbackHandler? registerUnaryCallback, | 
|  | RegisterBinaryCallbackHandler? registerBinaryCallback, | 
|  | ErrorCallbackHandler? errorCallback, | 
|  | ScheduleMicrotaskHandler? scheduleMicrotask, | 
|  | CreateTimerHandler? createTimer, | 
|  | CreatePeriodicTimerHandler? createPeriodicTimer, | 
|  | PrintHandler? print, | 
|  | ForkHandler? fork, | 
|  | }) = _ZoneSpecification; | 
|  |  | 
|  | /// Creates a specification from [other] and provided handlers. | 
|  | /// | 
|  | /// The created zone specification has the handlers of [other] | 
|  | /// and any individually provided handlers. | 
|  | /// If a handler is provided both through [other] and individually, | 
|  | /// the individually provided handler overrides the one from [other]. | 
|  | factory ZoneSpecification.from( | 
|  | ZoneSpecification other, { | 
|  | HandleUncaughtErrorHandler? handleUncaughtError, | 
|  | RunHandler? run, | 
|  | RunUnaryHandler? runUnary, | 
|  | RunBinaryHandler? runBinary, | 
|  | RegisterCallbackHandler? registerCallback, | 
|  | RegisterUnaryCallbackHandler? registerUnaryCallback, | 
|  | RegisterBinaryCallbackHandler? registerBinaryCallback, | 
|  | ErrorCallbackHandler? errorCallback, | 
|  | ScheduleMicrotaskHandler? scheduleMicrotask, | 
|  | CreateTimerHandler? createTimer, | 
|  | CreatePeriodicTimerHandler? createPeriodicTimer, | 
|  | PrintHandler? print, | 
|  | ForkHandler? fork, | 
|  | }) { | 
|  | return ZoneSpecification( | 
|  | handleUncaughtError: handleUncaughtError ?? other.handleUncaughtError, | 
|  | run: run ?? other.run, | 
|  | runUnary: runUnary ?? other.runUnary, | 
|  | runBinary: runBinary ?? other.runBinary, | 
|  | registerCallback: registerCallback ?? other.registerCallback, | 
|  | registerUnaryCallback: | 
|  | registerUnaryCallback ?? other.registerUnaryCallback, | 
|  | registerBinaryCallback: | 
|  | registerBinaryCallback ?? other.registerBinaryCallback, | 
|  | errorCallback: errorCallback ?? other.errorCallback, | 
|  | scheduleMicrotask: scheduleMicrotask ?? other.scheduleMicrotask, | 
|  | createTimer: createTimer ?? other.createTimer, | 
|  | createPeriodicTimer: createPeriodicTimer ?? other.createPeriodicTimer, | 
|  | print: print ?? other.print, | 
|  | fork: fork ?? other.fork, | 
|  | ); | 
|  | } | 
|  |  | 
|  | /// A custom [Zone.handleUncaughtError] implementation for a new zone. | 
|  | HandleUncaughtErrorHandler? get handleUncaughtError; | 
|  |  | 
|  | /// A custom [Zone.run] implementation for a new zone. | 
|  | RunHandler? get run; | 
|  |  | 
|  | /// A custom [Zone.runUnary] implementation for a new zone. | 
|  | RunUnaryHandler? get runUnary; | 
|  |  | 
|  | /// A custom [Zone.runBinary] implementation for a new zone. | 
|  | RunBinaryHandler? get runBinary; | 
|  |  | 
|  | /// A custom [Zone.registerCallback] implementation for a new zone. | 
|  | RegisterCallbackHandler? get registerCallback; | 
|  |  | 
|  | /// A custom [Zone.registerUnaryCallback] implementation for a new zone. | 
|  | RegisterUnaryCallbackHandler? get registerUnaryCallback; | 
|  |  | 
|  | /// A custom [Zone.registerBinaryCallback] implementation for a new zone. | 
|  | RegisterBinaryCallbackHandler? get registerBinaryCallback; | 
|  |  | 
|  | /// A custom [Zone.errorCallback] implementation for a new zone. | 
|  | ErrorCallbackHandler? get errorCallback; | 
|  |  | 
|  | /// A custom [Zone.scheduleMicrotask] implementation for a new zone. | 
|  | ScheduleMicrotaskHandler? get scheduleMicrotask; | 
|  |  | 
|  | /// A custom [Zone.createTimer] implementation for a new zone. | 
|  | CreateTimerHandler? get createTimer; | 
|  |  | 
|  | /// A custom [Zone.createPeriodicTimer] implementation for a new zone. | 
|  | CreatePeriodicTimerHandler? get createPeriodicTimer; | 
|  |  | 
|  | /// A custom [Zone.print] implementation for a new zone. | 
|  | PrintHandler? get print; | 
|  |  | 
|  | /// A custom [Zone.handleUncaughtError] implementation for a new zone. | 
|  | ForkHandler? get fork; | 
|  | } | 
|  |  | 
|  | /// Internal [ZoneSpecification] class. | 
|  | /// | 
|  | /// The implementation wants to rely on the fact that the getters cannot change | 
|  | /// dynamically. We thus require users to go through the redirecting | 
|  | /// [ZoneSpecification] constructor which instantiates this class. | 
|  | base class _ZoneSpecification implements ZoneSpecification { | 
|  | const _ZoneSpecification({ | 
|  | this.handleUncaughtError, | 
|  | this.run, | 
|  | this.runUnary, | 
|  | this.runBinary, | 
|  | this.registerCallback, | 
|  | this.registerUnaryCallback, | 
|  | this.registerBinaryCallback, | 
|  | this.errorCallback, | 
|  | this.scheduleMicrotask, | 
|  | this.createTimer, | 
|  | this.createPeriodicTimer, | 
|  | this.print, | 
|  | this.fork, | 
|  | }); | 
|  |  | 
|  | final HandleUncaughtErrorHandler? handleUncaughtError; | 
|  | final RunHandler? run; | 
|  | final RunUnaryHandler? runUnary; | 
|  | final RunBinaryHandler? runBinary; | 
|  | final RegisterCallbackHandler? registerCallback; | 
|  | final RegisterUnaryCallbackHandler? registerUnaryCallback; | 
|  | final RegisterBinaryCallbackHandler? registerBinaryCallback; | 
|  | final ErrorCallbackHandler? errorCallback; | 
|  | final ScheduleMicrotaskHandler? scheduleMicrotask; | 
|  | final CreateTimerHandler? createTimer; | 
|  | final CreatePeriodicTimerHandler? createPeriodicTimer; | 
|  | final PrintHandler? print; | 
|  | final ForkHandler? fork; | 
|  | } | 
|  |  | 
|  | /// An adapted view of the parent zone. | 
|  | /// | 
|  | /// This class allows the implementation of a zone method to invoke methods on | 
|  | /// the parent zone while retaining knowledge of the originating zone. | 
|  | /// | 
|  | /// Custom zones (created through [Zone.fork] or [runZoned]) can provide | 
|  | /// implementations of most methods of zones. This is similar to overriding | 
|  | /// methods on [Zone], except that this mechanism doesn't require subclassing. | 
|  | /// | 
|  | /// A custom zone function (provided through a [ZoneSpecification]) typically | 
|  | /// records or wraps its parameters and then delegates the operation to its | 
|  | /// parent zone using the provided [ZoneDelegate]. | 
|  | /// | 
|  | /// While zones have access to their parent zone (through [Zone.parent]) it is | 
|  | /// recommended to call the methods on the provided parent delegate for two | 
|  | /// reasons: | 
|  | /// 1. the delegate methods take an additional `zone` argument which is the | 
|  | ///   zone the action has been initiated in. | 
|  | /// 2. delegate calls are more efficient, since the implementation knows how | 
|  | ///   to skip zones that would just delegate to their parents. | 
|  | abstract final class ZoneDelegate { | 
|  | // Invoke the [HandleUncaughtErrorHandler] of the zone with a current zone. | 
|  | void handleUncaughtError(Zone zone, Object error, StackTrace stackTrace); | 
|  |  | 
|  | // Invokes the [RunHandler] of the zone with a current zone. | 
|  | R run<R>(Zone zone, R f()); | 
|  |  | 
|  | // Invokes the [RunUnaryHandler] of the zone with a current zone. | 
|  | R runUnary<R, T>(Zone zone, R f(T arg), T arg); | 
|  |  | 
|  | // Invokes the [RunBinaryHandler] of the zone with a current zone. | 
|  | R runBinary<R, T1, T2>(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2); | 
|  |  | 
|  | // Invokes the [RegisterCallbackHandler] of the zone with a current zone. | 
|  | ZoneCallback<R> registerCallback<R>(Zone zone, R f()); | 
|  |  | 
|  | // Invokes the [RegisterUnaryHandler] of the zone with a current zone. | 
|  | ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(Zone zone, R f(T arg)); | 
|  |  | 
|  | // Invokes the [RegisterBinaryHandler] of the zone with a current zone. | 
|  | ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( | 
|  | Zone zone, | 
|  | R f(T1 arg1, T2 arg2), | 
|  | ); | 
|  |  | 
|  | // Invokes the [ErrorCallbackHandler] of the zone with a current zone. | 
|  | AsyncError? errorCallback(Zone zone, Object error, StackTrace? stackTrace); | 
|  |  | 
|  | // Invokes the [ScheduleMicrotaskHandler] of the zone with a current zone. | 
|  | void scheduleMicrotask(Zone zone, void f()); | 
|  |  | 
|  | // Invokes the [CreateTimerHandler] of the zone with a current zone. | 
|  | Timer createTimer(Zone zone, Duration duration, void f()); | 
|  |  | 
|  | // Invokes the [CreatePeriodicTimerHandler] of the zone with a current zone. | 
|  | Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)); | 
|  |  | 
|  | // Invokes the [PrintHandler] of the zone with a current zone. | 
|  | void print(Zone zone, String line); | 
|  |  | 
|  | // Invokes the [ForkHandler] of the zone with a current zone. | 
|  | Zone fork(Zone zone, ZoneSpecification? specification, Map? zoneValues); | 
|  | } | 
|  |  | 
|  | /// A zone represents an environment that remains stable across asynchronous | 
|  | /// calls. | 
|  | /// | 
|  | /// All code is executed in the context of a zone, | 
|  | /// available to the code as [Zone.current]. | 
|  | /// The initial `main` function runs in the context of | 
|  | /// the default zone ([Zone.root]). | 
|  | /// Code can be run in a different zone using either | 
|  | ///  [runZoned] or [runZonedGuarded] to create a new zone and run code in it, | 
|  | /// or [Zone.run] to run code in the context of an existing zone | 
|  | /// which may have been created earlier using [Zone.fork]. | 
|  | /// | 
|  | /// Developers can create a new zone that overrides some of the functionality of | 
|  | /// an existing zone. For example, custom zones can replace or modify the | 
|  | /// behavior of `print`, timers, microtasks or how uncaught errors are handled. | 
|  | /// | 
|  | /// The [Zone] class is not subclassable, but users can provide custom zones by | 
|  | /// forking an existing zone (usually [Zone.current]) with a [ZoneSpecification]. | 
|  | /// This is similar to creating a new class that extends the base `Zone` class | 
|  | /// and that overrides some methods, except without actually creating a new | 
|  | /// class. Instead the overriding methods are provided as functions that | 
|  | /// explicitly take the equivalent of their own class, the "super" class and the | 
|  | /// `this` object as parameters. | 
|  | /// | 
|  | /// Asynchronous callbacks always run in the context of the zone where they were | 
|  | /// scheduled. This is implemented using two steps: | 
|  | /// 1. the callback is first registered using one of [registerCallback], | 
|  | ///   [registerUnaryCallback], or [registerBinaryCallback]. This allows the zone | 
|  | ///   to record that a callback exists and potentially modify it (by returning a | 
|  | ///   different callback). The code doing the registration (e.g., `Future.then`) | 
|  | ///   also remembers the current zone so that it can later run the callback in | 
|  | ///   that zone. | 
|  | /// 2. At a later point the registered callback is run in the remembered zone, | 
|  | ///    using one of [run], [runUnary] or [runBinary]. | 
|  | /// | 
|  | /// This is all handled internally by the platform code and most users don't need | 
|  | /// to worry about it. However, developers of new asynchronous operations, | 
|  | /// provided by the underlying system, must follow the protocol to be zone | 
|  | /// compatible. | 
|  | /// | 
|  | /// For convenience, zones provide [bindCallback] (and the corresponding | 
|  | /// [bindUnaryCallback] and [bindBinaryCallback]) to make it easier to respect | 
|  | /// the zone contract: these functions first invoke the corresponding `register` | 
|  | /// functions and then wrap the returned function so that it runs in the current | 
|  | /// zone when it is later asynchronously invoked. | 
|  | /// | 
|  | /// Similarly, zones provide [bindCallbackGuarded] (and the corresponding | 
|  | /// [bindUnaryCallbackGuarded] and [bindBinaryCallbackGuarded]), when the | 
|  | /// callback should be invoked through [Zone.runGuarded]. | 
|  | @vmIsolateUnsendable | 
|  | abstract final class Zone { | 
|  | // Private constructor so that it is not possible instantiate a Zone class. | 
|  | Zone._(); | 
|  |  | 
|  | /// The root zone. | 
|  | /// | 
|  | /// All isolate entry functions (`main` or spawned functions) start running in | 
|  | /// the root zone (that is, [Zone.current] is identical to [Zone.root] when the | 
|  | /// entry function is called). If no custom zone is created, the rest of the | 
|  | /// program always runs in the root zone. | 
|  | /// | 
|  | /// The root zone implements the default behavior of all zone operations. | 
|  | /// Many methods, like [registerCallback] do the bare minimum required of the | 
|  | /// function, and are only provided as a hook for custom zones. Others, like | 
|  | /// [scheduleMicrotask], interact with the underlying system to implement the | 
|  | /// desired behavior. | 
|  | static const Zone root = _rootZone; | 
|  |  | 
|  | /// The currently running zone. | 
|  | static _Zone _current = _rootZone; | 
|  |  | 
|  | /// The zone that is currently active. | 
|  | static Zone get current => _current; | 
|  |  | 
|  | /// Handles uncaught asynchronous errors. | 
|  | /// | 
|  | /// There are two kind of asynchronous errors that are handled by this | 
|  | /// function: | 
|  | /// 1. Uncaught errors that were thrown in asynchronous callbacks, for example, | 
|  | ///   a `throw` in the function passed to [Timer.run]. | 
|  | /// 2. Asynchronous errors that are pushed through [Future] and [Stream] | 
|  | ///   chains, but for which nobody registered an error handler. | 
|  | ///   Most asynchronous classes, like [Future] or [Stream] push errors to their | 
|  | ///   listeners. Errors are propagated this way until either a listener handles | 
|  | ///   the error (for example with [Future.catchError]), or no listener is | 
|  | ///   available anymore. In the latter case, futures and streams invoke the | 
|  | ///   zone's [handleUncaughtError]. | 
|  | /// | 
|  | /// By default, when handled by the root zone, uncaught asynchronous errors are | 
|  | /// treated like uncaught synchronous exceptions. | 
|  | void handleUncaughtError(Object error, StackTrace stackTrace); | 
|  |  | 
|  | /// The parent zone of the this zone. | 
|  | /// | 
|  | /// Is `null` if `this` is the [root] zone. | 
|  | /// | 
|  | /// Zones are created by [fork] on an existing zone, or by [runZoned] which | 
|  | /// forks the [current] zone. The new zone's parent zone is the zone it was | 
|  | /// forked from. | 
|  | Zone? get parent; | 
|  |  | 
|  | /// The error zone is responsible for dealing with uncaught errors. | 
|  | /// | 
|  | /// This is the closest parent zone of this zone that provides a | 
|  | /// [handleUncaughtError] method. | 
|  | /// | 
|  | /// Asynchronous errors in futures never cross zone boundaries | 
|  | /// between zones with different error handlers. | 
|  | /// | 
|  | /// Example: | 
|  | /// ```dart | 
|  | /// import 'dart:async'; | 
|  | /// | 
|  | /// main() { | 
|  | ///   var future; | 
|  | ///   runZonedGuarded(() { | 
|  | ///     // The asynchronous error is caught by the custom zone which prints | 
|  | ///     // 'asynchronous error'. | 
|  | ///     future = Future.error("asynchronous error"); | 
|  | ///   }, (error) { print(error); });  // Creates a zone with an error handler. | 
|  | ///   // The following `catchError` handler is never invoked, because the | 
|  | ///   // custom zone created by the call to `runZonedGuarded` provides an | 
|  | ///   // error handler. | 
|  | ///   future.catchError((error) { throw "is never reached"; }); | 
|  | /// } | 
|  | /// ``` | 
|  | /// | 
|  | /// Note that errors cannot enter a child zone with a different error handler | 
|  | /// either: | 
|  | /// ```dart | 
|  | /// import 'dart:async'; | 
|  | /// | 
|  | /// main() { | 
|  | ///   runZonedGuarded(() { | 
|  | ///     // The following asynchronous error is *not* caught by the `catchError` | 
|  | ///     // in the nested zone, since errors are not to cross zone boundaries | 
|  | ///     // with different error handlers. | 
|  | ///     // Instead the error is handled by the current error handler, | 
|  | ///     // printing "Caught by outer zone: asynchronous error". | 
|  | ///     var future = Future.error("asynchronous error"); | 
|  | ///     runZonedGuarded(() { | 
|  | ///       future.catchError((e) { throw "is never reached"; }); | 
|  | ///     }, (error, stack) { throw "is never reached"; }); | 
|  | ///   }, (error, stack) { print("Caught by outer zone: $error"); }); | 
|  | /// } | 
|  | /// ``` | 
|  | Zone get errorZone; | 
|  |  | 
|  | /// Whether this zone and [otherZone] are in the same error zone. | 
|  | /// | 
|  | /// Two zones are in the same error zone if they have the same [errorZone]. | 
|  | bool inSameErrorZone(Zone otherZone); | 
|  |  | 
|  | /// Creates a new zone as a child zone of this zone. | 
|  | /// | 
|  | /// The new zone uses the closures in the given [specification] to override | 
|  | /// the parent zone's behavior. All specification entries that are `null` | 
|  | /// inherit the behavior from the parent zone (`this`). | 
|  | /// | 
|  | /// The new zone inherits the stored values (accessed through [operator []]) | 
|  | /// of this zone and updates them with values from [zoneValues], which either | 
|  | /// adds new values or overrides existing ones. | 
|  | /// | 
|  | /// Note that the fork operation is interceptable. A zone can thus change | 
|  | /// the zone specification (or zone values), giving the parent zone full | 
|  | /// control over the child zone. | 
|  | Zone fork({ | 
|  | ZoneSpecification? specification, | 
|  | Map<Object?, Object?>? zoneValues, | 
|  | }); | 
|  |  | 
|  | /// Executes [action] in this zone. | 
|  | /// | 
|  | /// By default (as implemented in the [root] zone), runs [action] | 
|  | /// with [current] set to this zone. | 
|  | /// | 
|  | /// If [action] throws, the synchronous exception is not caught by the zone's | 
|  | /// error handler. Use [runGuarded] to achieve that. | 
|  | /// | 
|  | /// Since the root zone is the only zone that can modify the value of | 
|  | /// [current], custom zones intercepting run should always delegate to their | 
|  | /// parent zone. They may take actions before and after the call. | 
|  | R run<R>(R action()); | 
|  |  | 
|  | /// Executes the given [action] with [argument] in this zone. | 
|  | /// | 
|  | /// As [run] except that [action] is called with one [argument] instead of | 
|  | /// none. | 
|  | R runUnary<R, T>(R action(T argument), T argument); | 
|  |  | 
|  | /// Executes the given [action] with [argument1] and [argument2] in this | 
|  | /// zone. | 
|  | /// | 
|  | /// As [run] except that [action] is called with two arguments instead of none. | 
|  | R runBinary<R, T1, T2>( | 
|  | R action(T1 argument1, T2 argument2), | 
|  | T1 argument1, | 
|  | T2 argument2, | 
|  | ); | 
|  |  | 
|  | /// Executes the given [action] in this zone and catches synchronous | 
|  | /// errors. | 
|  | /// | 
|  | /// This function is equivalent to: | 
|  | /// ```dart | 
|  | /// try { | 
|  | ///   this.run(action); | 
|  | /// } catch (e, s) { | 
|  | ///   this.handleUncaughtError(e, s); | 
|  | /// } | 
|  | /// ``` | 
|  | /// | 
|  | /// See [run]. | 
|  | void runGuarded(void action()); | 
|  |  | 
|  | /// Executes the given [action] with [argument] in this zone and | 
|  | /// catches synchronous errors. | 
|  | /// | 
|  | /// See [runGuarded]. | 
|  | void runUnaryGuarded<T>(void action(T argument), T argument); | 
|  |  | 
|  | /// Executes the given [action] with [argument1] and [argument2] in this | 
|  | /// zone and catches synchronous errors. | 
|  | /// | 
|  | /// See [runGuarded]. | 
|  | void runBinaryGuarded<T1, T2>( | 
|  | void action(T1 argument1, T2 argument2), | 
|  | T1 argument1, | 
|  | T2 argument2, | 
|  | ); | 
|  |  | 
|  | /// Registers the given callback in this zone. | 
|  | /// | 
|  | /// When implementing an asynchronous primitive that uses callbacks, the | 
|  | /// callback must be registered using [registerCallback] at the point where the | 
|  | /// user provides the callback. This allows zones to record other information | 
|  | /// that they need at the same time, perhaps even wrapping the callback, so | 
|  | /// that the callback is prepared when it is later run in the same zones | 
|  | /// (using [run]). For example, a zone may decide | 
|  | /// to store the stack trace (at the time of the registration) with the | 
|  | /// callback. | 
|  | /// | 
|  | /// Returns the callback that should be used in place of the provided | 
|  | /// [callback]. Frequently zones simply return the original callback. | 
|  | /// | 
|  | /// Custom zones may intercept this operation. The default implementation in | 
|  | /// [Zone.root] returns the original callback unchanged. | 
|  | ZoneCallback<R> registerCallback<R>(R callback()); | 
|  |  | 
|  | /// Registers the given callback in this zone. | 
|  | /// | 
|  | /// Similar to [registerCallback] but with a unary callback. | 
|  | ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(R callback(T arg)); | 
|  |  | 
|  | /// Registers the given callback in this zone. | 
|  | /// | 
|  | /// Similar to [registerCallback] but with a binary callback. | 
|  | ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( | 
|  | R callback(T1 arg1, T2 arg2), | 
|  | ); | 
|  |  | 
|  | /// Registers the provided [callback] and returns a function that will | 
|  | /// execute in this zone. | 
|  | /// | 
|  | /// Equivalent to: | 
|  | /// ```dart | 
|  | /// ZoneCallback registered = this.registerCallback(callback); | 
|  | /// return () => this.run(registered); | 
|  | /// ``` | 
|  | ZoneCallback<R> bindCallback<R>(R callback()); | 
|  |  | 
|  | /// Registers the provided [callback] and returns a function that will | 
|  | /// execute in this zone. | 
|  | /// | 
|  | /// Equivalent to: | 
|  | /// ```dart | 
|  | /// ZoneCallback registered = this.registerUnaryCallback(callback); | 
|  | /// return (arg) => this.runUnary(registered, arg); | 
|  | /// ``` | 
|  | ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R callback(T argument)); | 
|  |  | 
|  | /// Registers the provided [callback] and returns a function that will | 
|  | /// execute in this zone. | 
|  | /// | 
|  | /// Equivalent to: | 
|  | /// ```dart | 
|  | /// ZoneCallback registered = registerBinaryCallback(callback); | 
|  | /// return (arg1, arg2) => this.runBinary(registered, arg1, arg2); | 
|  | /// ``` | 
|  | ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>( | 
|  | R callback(T1 argument1, T2 argument2), | 
|  | ); | 
|  |  | 
|  | /// Registers the provided [callback] and returns a function that will | 
|  | /// execute in this zone. | 
|  | /// | 
|  | /// When the function executes, errors are caught and treated as uncaught | 
|  | /// errors. | 
|  | /// | 
|  | /// Equivalent to: | 
|  | /// ```dart | 
|  | /// ZoneCallback registered = this.registerCallback(callback); | 
|  | /// return () => this.runGuarded(registered); | 
|  | /// ``` | 
|  | void Function() bindCallbackGuarded(void Function() callback); | 
|  |  | 
|  | /// Registers the provided [callback] and returns a function that will | 
|  | /// execute in this zone. | 
|  | /// | 
|  | /// When the function executes, errors are caught and treated as uncaught | 
|  | /// errors. | 
|  | /// | 
|  | /// Equivalent to: | 
|  | /// ```dart | 
|  | /// ZoneCallback registered = this.registerUnaryCallback(callback); | 
|  | /// return (arg) => this.runUnaryGuarded(registered, arg); | 
|  | /// ``` | 
|  | void Function(T) bindUnaryCallbackGuarded<T>(void callback(T argument)); | 
|  |  | 
|  | ///  Registers the provided [callback] and returns a function that will | 
|  | ///  execute in this zone. | 
|  | /// | 
|  | ///  Equivalent to: | 
|  | /// ```dart | 
|  | ///  ZoneCallback registered = registerBinaryCallback(callback); | 
|  | ///  return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2); | 
|  | /// ``` | 
|  | void Function(T1, T2) bindBinaryCallbackGuarded<T1, T2>( | 
|  | void callback(T1 argument1, T2 argument2), | 
|  | ); | 
|  |  | 
|  | /// Intercepts errors when added programmatically to a [Future] or [Stream]. | 
|  | /// | 
|  | /// When calling [Completer.completeError], [StreamController.addError], | 
|  | /// or some [Future] constructors, the current zone is allowed to intercept | 
|  | /// and replace the error. | 
|  | /// | 
|  | /// Future constructors invoke this function when the error is received | 
|  | /// directly, for example with [Future.error], or when the error is caught | 
|  | /// synchronously, for example with [Future.sync]. | 
|  | /// | 
|  | /// There is no guarantee that an error is only sent through [errorCallback] | 
|  | /// once. Libraries that use intermediate controllers or completers might | 
|  | /// end up invoking [errorCallback] multiple times. | 
|  | /// | 
|  | /// Returns `null` if no replacement is desired. Otherwise returns an instance | 
|  | /// of [AsyncError] holding the new pair of error and stack trace. | 
|  | /// | 
|  | /// Custom zones may intercept this operation. | 
|  | /// | 
|  | /// Implementations of a new asynchronous primitive that converts synchronous | 
|  | /// errors to asynchronous errors rarely need to invoke [errorCallback], since | 
|  | /// errors are usually reported through future completers or stream | 
|  | /// controllers. | 
|  | AsyncError? errorCallback(Object error, StackTrace? stackTrace); | 
|  |  | 
|  | /// Runs [callback] asynchronously in this zone. | 
|  | /// | 
|  | /// The global `scheduleMicrotask` delegates to the [current] zone's | 
|  | /// [scheduleMicrotask]. The root zone's implementation interacts with the | 
|  | /// underlying system to schedule the given callback as a microtask. | 
|  | /// | 
|  | /// Custom zones may intercept this operation (for example to wrap the given | 
|  | /// [callback]), or to implement their own microtask scheduler. | 
|  | /// In the latter case, they will usually still use the parent zone's | 
|  | /// [ZoneDelegate.scheduleMicrotask] to attach themselves to the existing | 
|  | /// event loop. | 
|  | void scheduleMicrotask(void Function() callback); | 
|  |  | 
|  | /// Creates a [Timer] where the callback is executed in this zone. | 
|  | Timer createTimer(Duration duration, void Function() callback); | 
|  |  | 
|  | /// Creates a periodic [Timer] where the callback is executed in this zone. | 
|  | Timer createPeriodicTimer(Duration period, void callback(Timer timer)); | 
|  |  | 
|  | /// Prints the given [line]. | 
|  | /// | 
|  | /// The global `print` function delegates to the current zone's [print] | 
|  | /// function which makes it possible to intercept printing. | 
|  | /// | 
|  | /// Example: | 
|  | /// ```dart | 
|  | /// import 'dart:async'; | 
|  | /// | 
|  | /// main() { | 
|  | ///   runZoned(() { | 
|  | ///     // Ends up printing: "Intercepted: in zone". | 
|  | ///     print("in zone"); | 
|  | ///   }, zoneSpecification: new ZoneSpecification( | 
|  | ///       print: (Zone self, ZoneDelegate parent, Zone zone, String line) { | 
|  | ///     parent.print(zone, "Intercepted: $line"); | 
|  | ///   })); | 
|  | /// } | 
|  | /// ``` | 
|  | void print(String line); | 
|  |  | 
|  | /// Call to enter the [Zone]. | 
|  | /// | 
|  | /// The previous current zone is returned. | 
|  | static _Zone _enter(_Zone zone) { | 
|  | assert(!identical(zone, _current)); | 
|  | _Zone previous = _current; | 
|  | _current = zone; | 
|  | return previous; | 
|  | } | 
|  |  | 
|  | /// Call to leave the [Zone]. | 
|  | /// | 
|  | /// The previous [Zone] must be provided as `previous`. | 
|  | static void _leave(_Zone previous) { | 
|  | assert(previous != null); | 
|  | Zone._current = previous; | 
|  | } | 
|  |  | 
|  | /// Retrieves the zone-value associated with [key]. | 
|  | /// | 
|  | /// If this zone does not contain the value looks up the same key in the | 
|  | /// parent zone. If the [key] is not found returns `null`. | 
|  | /// | 
|  | /// Any object can be used as key, as long as it has compatible `operator ==` | 
|  | /// and `hashCode` implementations. | 
|  | /// By controlling access to the key, a zone can grant or deny access to the | 
|  | /// zone value. | 
|  | dynamic operator [](Object? key); | 
|  | } | 
|  |  | 
|  | base class _ZoneDelegate implements ZoneDelegate { | 
|  | final _Zone _delegationTarget; | 
|  |  | 
|  | _ZoneDelegate(this._delegationTarget); | 
|  |  | 
|  | void handleUncaughtError(Zone zone, Object error, StackTrace stackTrace) { | 
|  | _delegationTarget._processUncaughtError(zone, error, stackTrace); | 
|  | } | 
|  |  | 
|  | R run<R>(Zone zone, R f()) { | 
|  | var implementation = _delegationTarget._run; | 
|  | _Zone implZone = implementation.zone; | 
|  | var handler = implementation.function as RunHandler; | 
|  | return handler(implZone, implZone._parentDelegate, zone, f); | 
|  | } | 
|  |  | 
|  | R runUnary<R, T>(Zone zone, R f(T arg), T arg) { | 
|  | var implementation = _delegationTarget._runUnary; | 
|  | _Zone implZone = implementation.zone; | 
|  | var handler = implementation.function as RunUnaryHandler; | 
|  | return handler(implZone, implZone._parentDelegate, zone, f, arg); | 
|  | } | 
|  |  | 
|  | R runBinary<R, T1, T2>(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { | 
|  | var implementation = _delegationTarget._runBinary; | 
|  | _Zone implZone = implementation.zone; | 
|  | var handler = implementation.function as RunBinaryHandler; | 
|  | return handler(implZone, implZone._parentDelegate, zone, f, arg1, arg2); | 
|  | } | 
|  |  | 
|  | ZoneCallback<R> registerCallback<R>(Zone zone, R f()) { | 
|  | var implementation = _delegationTarget._registerCallback; | 
|  | _Zone implZone = implementation.zone; | 
|  | var handler = implementation.function as RegisterCallbackHandler; | 
|  | return handler(implZone, implZone._parentDelegate, zone, f); | 
|  | } | 
|  |  | 
|  | ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(Zone zone, R f(T arg)) { | 
|  | var implementation = _delegationTarget._registerUnaryCallback; | 
|  | _Zone implZone = implementation.zone; | 
|  | var handler = implementation.function as RegisterUnaryCallbackHandler; | 
|  | return handler(implZone, implZone._parentDelegate, zone, f); | 
|  | } | 
|  |  | 
|  | ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( | 
|  | Zone zone, | 
|  | R f(T1 arg1, T2 arg2), | 
|  | ) { | 
|  | var implementation = _delegationTarget._registerBinaryCallback; | 
|  | _Zone implZone = implementation.zone; | 
|  | var handler = implementation.function as RegisterBinaryCallbackHandler; | 
|  | return handler(implZone, implZone._parentDelegate, zone, f); | 
|  | } | 
|  |  | 
|  | AsyncError? errorCallback(Zone zone, Object error, StackTrace? stackTrace) { | 
|  | var implementation = _delegationTarget._errorCallback; | 
|  | _Zone implZone = implementation.zone; | 
|  | if (identical(implZone, _rootZone)) return null; | 
|  | ErrorCallbackHandler handler = implementation.function; | 
|  | return handler(implZone, implZone._parentDelegate, zone, error, stackTrace); | 
|  | } | 
|  |  | 
|  | void scheduleMicrotask(Zone zone, f()) { | 
|  | var implementation = _delegationTarget._scheduleMicrotask; | 
|  | _Zone implZone = implementation.zone; | 
|  | ScheduleMicrotaskHandler handler = implementation.function; | 
|  | handler(implZone, implZone._parentDelegate, zone, f); | 
|  | } | 
|  |  | 
|  | Timer createTimer(Zone zone, Duration duration, void f()) { | 
|  | var implementation = _delegationTarget._createTimer; | 
|  | _Zone implZone = implementation.zone; | 
|  | CreateTimerHandler handler = implementation.function; | 
|  | return handler(implZone, implZone._parentDelegate, zone, duration, f); | 
|  | } | 
|  |  | 
|  | Timer createPeriodicTimer(Zone zone, Duration period, void f(Timer timer)) { | 
|  | var implementation = _delegationTarget._createPeriodicTimer; | 
|  | _Zone implZone = implementation.zone; | 
|  | CreatePeriodicTimerHandler handler = implementation.function; | 
|  | return handler(implZone, implZone._parentDelegate, zone, period, f); | 
|  | } | 
|  |  | 
|  | void print(Zone zone, String line) { | 
|  | var implementation = _delegationTarget._print; | 
|  | _Zone implZone = implementation.zone; | 
|  | PrintHandler handler = implementation.function; | 
|  | handler(implZone, implZone._parentDelegate, zone, line); | 
|  | } | 
|  |  | 
|  | Zone fork( | 
|  | Zone zone, | 
|  | ZoneSpecification? specification, | 
|  | Map<Object?, Object?>? zoneValues, | 
|  | ) { | 
|  | var implementation = _delegationTarget._fork; | 
|  | _Zone implZone = implementation.zone; | 
|  | ForkHandler handler = implementation.function; | 
|  | return handler( | 
|  | implZone, | 
|  | implZone._parentDelegate, | 
|  | zone, | 
|  | specification, | 
|  | zoneValues, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// Base class for Zone implementations. | 
|  | abstract base class _Zone implements Zone { | 
|  | const _Zone(); | 
|  |  | 
|  | // TODO(floitsch): the types of the `_ZoneFunction`s should have a type for | 
|  | // all fields. | 
|  | _ZoneFunction<RunHandler> get _run; | 
|  | _ZoneFunction<RunUnaryHandler> get _runUnary; | 
|  | _ZoneFunction<RunBinaryHandler> get _runBinary; | 
|  | _ZoneFunction<RegisterCallbackHandler> get _registerCallback; | 
|  | _ZoneFunction<RegisterUnaryCallbackHandler> get _registerUnaryCallback; | 
|  | _ZoneFunction<RegisterBinaryCallbackHandler> get _registerBinaryCallback; | 
|  | _ZoneFunction<ErrorCallbackHandler> get _errorCallback; | 
|  | _ZoneFunction<ScheduleMicrotaskHandler> get _scheduleMicrotask; | 
|  | _ZoneFunction<CreateTimerHandler> get _createTimer; | 
|  | _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer; | 
|  | _ZoneFunction<PrintHandler> get _print; | 
|  | _ZoneFunction<ForkHandler> get _fork; | 
|  | _ZoneFunction<HandleUncaughtErrorHandler> get _handleUncaughtError; | 
|  | // Parent zone. Only `null` for the root zone. | 
|  | _Zone? get parent; | 
|  | ZoneDelegate get _delegate; | 
|  | ZoneDelegate get _parentDelegate; | 
|  | Map<Object?, Object?> get _map; | 
|  |  | 
|  | bool inSameErrorZone(Zone otherZone) { | 
|  | return identical(this, otherZone) || | 
|  | identical(errorZone, otherZone.errorZone); | 
|  | } | 
|  |  | 
|  | void _processUncaughtError(Zone zone, Object error, StackTrace stackTrace) { | 
|  | var implementation = _handleUncaughtError; | 
|  | _Zone implZone = implementation.zone; | 
|  | if (identical(implZone, _rootZone)) { | 
|  | _rootHandleError(error, stackTrace); | 
|  | return; | 
|  | } | 
|  | HandleUncaughtErrorHandler handler = implementation.function; | 
|  | ZoneDelegate parentDelegate = implZone._parentDelegate; | 
|  | _Zone parentZone = implZone.parent!; // Not null for non-root zones. | 
|  | _Zone currentZone = Zone._current; | 
|  | try { | 
|  | Zone._current = parentZone; | 
|  | handler(implZone, parentDelegate, zone, error, stackTrace); | 
|  | Zone._current = currentZone; | 
|  | } catch (e, s) { | 
|  | Zone._current = currentZone; | 
|  | parentZone._processUncaughtError( | 
|  | implZone, | 
|  | e, | 
|  | identical(error, e) ? stackTrace : s, | 
|  | ); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | base class _CustomZone extends _Zone { | 
|  | // The actual zone and implementation of each of these | 
|  | // inheritable zone functions. | 
|  | // TODO(floitsch): the types of the `_ZoneFunction`s should have a type for | 
|  | // all fields, but we can't use generic function types as type arguments. | 
|  | _ZoneFunction<RunHandler> _run; | 
|  | _ZoneFunction<RunUnaryHandler> _runUnary; | 
|  | _ZoneFunction<RunBinaryHandler> _runBinary; | 
|  | _ZoneFunction<RegisterCallbackHandler> _registerCallback; | 
|  | _ZoneFunction<RegisterUnaryCallbackHandler> _registerUnaryCallback; | 
|  | _ZoneFunction<RegisterBinaryCallbackHandler> _registerBinaryCallback; | 
|  | _ZoneFunction<ErrorCallbackHandler> _errorCallback; | 
|  | _ZoneFunction<ScheduleMicrotaskHandler> _scheduleMicrotask; | 
|  | _ZoneFunction<CreateTimerHandler> _createTimer; | 
|  | _ZoneFunction<CreatePeriodicTimerHandler> _createPeriodicTimer; | 
|  | _ZoneFunction<PrintHandler> _print; | 
|  | _ZoneFunction<ForkHandler> _fork; | 
|  | _ZoneFunction<HandleUncaughtErrorHandler> _handleUncaughtError; | 
|  |  | 
|  | // A cached delegate to this zone. | 
|  | ZoneDelegate? _delegateCache; | 
|  |  | 
|  | /// The parent zone. | 
|  | final _Zone parent; | 
|  |  | 
|  | /// The zone's scoped value declaration map. | 
|  | /// | 
|  | /// This is always a [HashMap]. | 
|  | final Map<Object?, Object?> _map; | 
|  |  | 
|  | ZoneDelegate get _delegate => _delegateCache ??= _ZoneDelegate(this); | 
|  | ZoneDelegate get _parentDelegate => parent._delegate; | 
|  |  | 
|  | _CustomZone(this.parent, ZoneSpecification specification, this._map) | 
|  | : _run = parent._run, | 
|  | _runUnary = parent._runUnary, | 
|  | _runBinary = parent._runBinary, | 
|  | _registerCallback = parent._registerCallback, | 
|  | _registerUnaryCallback = parent._registerUnaryCallback, | 
|  | _registerBinaryCallback = parent._registerBinaryCallback, | 
|  | _errorCallback = parent._errorCallback, | 
|  | _scheduleMicrotask = parent._scheduleMicrotask, | 
|  | _createTimer = parent._createTimer, | 
|  | _createPeriodicTimer = parent._createPeriodicTimer, | 
|  | _print = parent._print, | 
|  | _fork = parent._fork, | 
|  | _handleUncaughtError = parent._handleUncaughtError { | 
|  | // The root zone will have implementations of all parts of the | 
|  | // specification, so it will never try to access the (null) parent. | 
|  | // All other zones have a non-null parent. | 
|  | var run = specification.run; | 
|  | if (run != null) { | 
|  | _run = _ZoneFunction<RunHandler>(this, run); | 
|  | } | 
|  | var runUnary = specification.runUnary; | 
|  | if (runUnary != null) { | 
|  | _runUnary = _ZoneFunction<RunUnaryHandler>(this, runUnary); | 
|  | } | 
|  | var runBinary = specification.runBinary; | 
|  | if (runBinary != null) { | 
|  | _runBinary = _ZoneFunction<RunBinaryHandler>(this, runBinary); | 
|  | } | 
|  | var registerCallback = specification.registerCallback; | 
|  | if (registerCallback != null) { | 
|  | _registerCallback = _ZoneFunction<RegisterCallbackHandler>( | 
|  | this, | 
|  | registerCallback, | 
|  | ); | 
|  | } | 
|  | var registerUnaryCallback = specification.registerUnaryCallback; | 
|  | if (registerUnaryCallback != null) { | 
|  | _registerUnaryCallback = _ZoneFunction<RegisterUnaryCallbackHandler>( | 
|  | this, | 
|  | registerUnaryCallback, | 
|  | ); | 
|  | } | 
|  | var registerBinaryCallback = specification.registerBinaryCallback; | 
|  | if (registerBinaryCallback != null) { | 
|  | _registerBinaryCallback = _ZoneFunction<RegisterBinaryCallbackHandler>( | 
|  | this, | 
|  | registerBinaryCallback, | 
|  | ); | 
|  | } | 
|  | var errorCallback = specification.errorCallback; | 
|  | if (errorCallback != null) { | 
|  | _errorCallback = _ZoneFunction<ErrorCallbackHandler>(this, errorCallback); | 
|  | } | 
|  | var scheduleMicrotask = specification.scheduleMicrotask; | 
|  | if (scheduleMicrotask != null) { | 
|  | _scheduleMicrotask = _ZoneFunction<ScheduleMicrotaskHandler>( | 
|  | this, | 
|  | scheduleMicrotask, | 
|  | ); | 
|  | } | 
|  | var createTimer = specification.createTimer; | 
|  | if (createTimer != null) { | 
|  | _createTimer = _ZoneFunction<CreateTimerHandler>(this, createTimer); | 
|  | } | 
|  | var createPeriodicTimer = specification.createPeriodicTimer; | 
|  | if (createPeriodicTimer != null) { | 
|  | _createPeriodicTimer = _ZoneFunction<CreatePeriodicTimerHandler>( | 
|  | this, | 
|  | createPeriodicTimer, | 
|  | ); | 
|  | } | 
|  | var print = specification.print; | 
|  | if (print != null) { | 
|  | _print = _ZoneFunction<PrintHandler>(this, print); | 
|  | } | 
|  | var fork = specification.fork; | 
|  | if (fork != null) { | 
|  | _fork = _ZoneFunction<ForkHandler>(this, fork); | 
|  | } | 
|  | var handleUncaughtError = specification.handleUncaughtError; | 
|  | if (handleUncaughtError != null) { | 
|  | _handleUncaughtError = _ZoneFunction<HandleUncaughtErrorHandler>( | 
|  | this, | 
|  | handleUncaughtError, | 
|  | ); | 
|  | } | 
|  | } | 
|  |  | 
|  | /// The closest error-handling zone. | 
|  | /// | 
|  | /// Returns this zone if it has an error-handler. Otherwise returns the | 
|  | /// parent's error-zone. | 
|  | Zone get errorZone => _handleUncaughtError.zone; | 
|  |  | 
|  | void runGuarded(void f()) { | 
|  | try { | 
|  | run(f); | 
|  | } catch (e, s) { | 
|  | handleUncaughtError(e, s); | 
|  | } | 
|  | } | 
|  |  | 
|  | void runUnaryGuarded<T>(void f(T arg), T arg) { | 
|  | try { | 
|  | runUnary(f, arg); | 
|  | } catch (e, s) { | 
|  | handleUncaughtError(e, s); | 
|  | } | 
|  | } | 
|  |  | 
|  | void runBinaryGuarded<T1, T2>(void f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { | 
|  | try { | 
|  | runBinary(f, arg1, arg2); | 
|  | } catch (e, s) { | 
|  | handleUncaughtError(e, s); | 
|  | } | 
|  | } | 
|  |  | 
|  | ZoneCallback<R> bindCallback<R>(R f()) { | 
|  | var registered = registerCallback(f); | 
|  | return () => this.run(registered); | 
|  | } | 
|  |  | 
|  | ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg)) { | 
|  | var registered = registerUnaryCallback(f); | 
|  | return (arg) => this.runUnary(registered, arg); | 
|  | } | 
|  |  | 
|  | ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>( | 
|  | R f(T1 arg1, T2 arg2), | 
|  | ) { | 
|  | var registered = registerBinaryCallback(f); | 
|  | return (arg1, arg2) => this.runBinary(registered, arg1, arg2); | 
|  | } | 
|  |  | 
|  | void Function() bindCallbackGuarded(void f()) { | 
|  | var registered = registerCallback(f); | 
|  | return () => this.runGuarded(registered); | 
|  | } | 
|  |  | 
|  | void Function(T) bindUnaryCallbackGuarded<T>(void f(T arg)) { | 
|  | var registered = registerUnaryCallback(f); | 
|  | return (arg) => this.runUnaryGuarded(registered, arg); | 
|  | } | 
|  |  | 
|  | void Function(T1, T2) bindBinaryCallbackGuarded<T1, T2>( | 
|  | void f(T1 arg1, T2 arg2), | 
|  | ) { | 
|  | var registered = registerBinaryCallback(f); | 
|  | return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2); | 
|  | } | 
|  |  | 
|  | dynamic operator [](Object? key) { | 
|  | var result = _map[key]; | 
|  | if (result != null || _map.containsKey(key)) return result; | 
|  | // If we are not the root zone, look up in the parent zone. | 
|  | if (parent != null) { | 
|  | // We do not optimize for repeatedly looking up a key which isn't | 
|  | // there. That would require storing the key and keeping it alive. | 
|  | // Copying the key/value from the parent does not keep any new values | 
|  | // alive. | 
|  | var value = parent[key]; | 
|  | if (value != null) { | 
|  | _map[key] = value; | 
|  | } | 
|  | return value; | 
|  | } | 
|  | assert(this == _rootZone); | 
|  | return null; | 
|  | } | 
|  |  | 
|  | // Methods that can be customized by the zone specification. | 
|  |  | 
|  | void handleUncaughtError(Object error, StackTrace stackTrace) { | 
|  | _processUncaughtError(this, error, stackTrace); | 
|  | } | 
|  |  | 
|  | Zone fork({ | 
|  | ZoneSpecification? specification, | 
|  | Map<Object?, Object?>? zoneValues, | 
|  | }) { | 
|  | var implementation = this._fork; | 
|  | ZoneDelegate parentDelegate = implementation.zone._parentDelegate; | 
|  | ForkHandler handler = implementation.function; | 
|  | return handler( | 
|  | implementation.zone, | 
|  | parentDelegate, | 
|  | this, | 
|  | specification, | 
|  | zoneValues, | 
|  | ); | 
|  | } | 
|  |  | 
|  | R run<R>(R f()) { | 
|  | var implementation = this._run; | 
|  | ZoneDelegate parentDelegate = implementation.zone._parentDelegate; | 
|  | var handler = implementation.function as RunHandler; | 
|  | return handler(implementation.zone, parentDelegate, this, f); | 
|  | } | 
|  |  | 
|  | R runUnary<R, T>(R f(T arg), T arg) { | 
|  | var implementation = this._runUnary; | 
|  | ZoneDelegate parentDelegate = implementation.zone._parentDelegate; | 
|  | var handler = implementation.function as RunUnaryHandler; | 
|  | return handler(implementation.zone, parentDelegate, this, f, arg); | 
|  | } | 
|  |  | 
|  | R runBinary<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { | 
|  | var implementation = this._runBinary; | 
|  | ZoneDelegate parentDelegate = implementation.zone._parentDelegate; | 
|  | var handler = implementation.function as RunBinaryHandler; | 
|  | return handler(implementation.zone, parentDelegate, this, f, arg1, arg2); | 
|  | } | 
|  |  | 
|  | ZoneCallback<R> registerCallback<R>(R callback()) { | 
|  | var implementation = this._registerCallback; | 
|  | ZoneDelegate parentDelegate = implementation.zone._parentDelegate; | 
|  | var handler = implementation.function as RegisterCallbackHandler; | 
|  | return handler(implementation.zone, parentDelegate, this, callback); | 
|  | } | 
|  |  | 
|  | ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(R callback(T arg)) { | 
|  | var implementation = this._registerUnaryCallback; | 
|  | ZoneDelegate parentDelegate = implementation.zone._parentDelegate; | 
|  | var handler = implementation.function as RegisterUnaryCallbackHandler; | 
|  | return handler(implementation.zone, parentDelegate, this, callback); | 
|  | } | 
|  |  | 
|  | ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( | 
|  | R callback(T1 arg1, T2 arg2), | 
|  | ) { | 
|  | var implementation = this._registerBinaryCallback; | 
|  | ZoneDelegate parentDelegate = implementation.zone._parentDelegate; | 
|  | var handler = implementation.function as RegisterBinaryCallbackHandler; | 
|  | return handler(implementation.zone, parentDelegate, this, callback); | 
|  | } | 
|  |  | 
|  | AsyncError? errorCallback(Object error, StackTrace? stackTrace) { | 
|  | var implementation = this._errorCallback; | 
|  | final _Zone implementationZone = implementation.zone; | 
|  | if (identical(implementationZone, _rootZone)) return null; | 
|  | final ZoneDelegate parentDelegate = implementationZone._parentDelegate; | 
|  | ErrorCallbackHandler handler = implementation.function; | 
|  | return handler(implementationZone, parentDelegate, this, error, stackTrace); | 
|  | } | 
|  |  | 
|  | void scheduleMicrotask(void f()) { | 
|  | var implementation = this._scheduleMicrotask; | 
|  | ZoneDelegate parentDelegate = implementation.zone._parentDelegate; | 
|  | ScheduleMicrotaskHandler handler = implementation.function; | 
|  | return handler(implementation.zone, parentDelegate, this, f); | 
|  | } | 
|  |  | 
|  | Timer createTimer(Duration duration, void f()) { | 
|  | var implementation = this._createTimer; | 
|  | ZoneDelegate parentDelegate = implementation.zone._parentDelegate; | 
|  | CreateTimerHandler handler = implementation.function; | 
|  | return handler(implementation.zone, parentDelegate, this, duration, f); | 
|  | } | 
|  |  | 
|  | Timer createPeriodicTimer(Duration duration, void f(Timer timer)) { | 
|  | var implementation = this._createPeriodicTimer; | 
|  | ZoneDelegate parentDelegate = implementation.zone._parentDelegate; | 
|  | CreatePeriodicTimerHandler handler = implementation.function; | 
|  | return handler(implementation.zone, parentDelegate, this, duration, f); | 
|  | } | 
|  |  | 
|  | void print(String line) { | 
|  | var implementation = this._print; | 
|  | ZoneDelegate parentDelegate = implementation.zone._parentDelegate; | 
|  | PrintHandler handler = implementation.function; | 
|  | return handler(implementation.zone, parentDelegate, this, line); | 
|  | } | 
|  | } | 
|  |  | 
|  | void _rootHandleUncaughtError( | 
|  | Zone? self, | 
|  | ZoneDelegate? parent, | 
|  | Zone zone, | 
|  | Object error, | 
|  | StackTrace stackTrace, | 
|  | ) { | 
|  | _rootHandleError(error, stackTrace); | 
|  | } | 
|  |  | 
|  | void _rootHandleError(Object error, StackTrace stackTrace) { | 
|  | _schedulePriorityAsyncCallback(() { | 
|  | Error.throwWithStackTrace(error, stackTrace); | 
|  | }); | 
|  | } | 
|  |  | 
|  | R _rootRun<R>(Zone? self, ZoneDelegate? parent, Zone zone, R f()) { | 
|  | if (identical(Zone._current, zone)) return f(); | 
|  |  | 
|  | if (zone is! _Zone) { | 
|  | throw ArgumentError.value(zone, "zone", "Can only run in platform zones"); | 
|  | } | 
|  |  | 
|  | _Zone old = Zone._enter(zone); | 
|  | try { | 
|  | return f(); | 
|  | } finally { | 
|  | Zone._leave(old); | 
|  | } | 
|  | } | 
|  |  | 
|  | R _rootRunUnary<R, T>( | 
|  | Zone? self, | 
|  | ZoneDelegate? parent, | 
|  | Zone zone, | 
|  | R f(T arg), | 
|  | T arg, | 
|  | ) { | 
|  | if (identical(Zone._current, zone)) return f(arg); | 
|  |  | 
|  | if (zone is! _Zone) { | 
|  | throw ArgumentError.value(zone, "zone", "Can only run in platform zones"); | 
|  | } | 
|  |  | 
|  | _Zone old = Zone._enter(zone); | 
|  | try { | 
|  | return f(arg); | 
|  | } finally { | 
|  | Zone._leave(old); | 
|  | } | 
|  | } | 
|  |  | 
|  | R _rootRunBinary<R, T1, T2>( | 
|  | Zone? self, | 
|  | ZoneDelegate? parent, | 
|  | Zone zone, | 
|  | R f(T1 arg1, T2 arg2), | 
|  | T1 arg1, | 
|  | T2 arg2, | 
|  | ) { | 
|  | if (identical(Zone._current, zone)) return f(arg1, arg2); | 
|  |  | 
|  | if (zone is! _Zone) { | 
|  | throw ArgumentError.value(zone, "zone", "Can only run in platform zones"); | 
|  | } | 
|  |  | 
|  | _Zone old = Zone._enter(zone); | 
|  | try { | 
|  | return f(arg1, arg2); | 
|  | } finally { | 
|  | Zone._leave(old); | 
|  | } | 
|  | } | 
|  |  | 
|  | ZoneCallback<R> _rootRegisterCallback<R>( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | R f(), | 
|  | ) { | 
|  | return f; | 
|  | } | 
|  |  | 
|  | ZoneUnaryCallback<R, T> _rootRegisterUnaryCallback<R, T>( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | R f(T arg), | 
|  | ) { | 
|  | return f; | 
|  | } | 
|  |  | 
|  | ZoneBinaryCallback<R, T1, T2> _rootRegisterBinaryCallback<R, T1, T2>( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | R f(T1 arg1, T2 arg2), | 
|  | ) { | 
|  | return f; | 
|  | } | 
|  |  | 
|  | AsyncError? _rootErrorCallback( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | Object error, | 
|  | StackTrace? stackTrace, | 
|  | ) => null; | 
|  |  | 
|  | void _rootScheduleMicrotask( | 
|  | Zone? self, | 
|  | ZoneDelegate? parent, | 
|  | Zone zone, | 
|  | void f(), | 
|  | ) { | 
|  | if (!identical(_rootZone, zone)) { | 
|  | bool hasErrorHandler = !_rootZone.inSameErrorZone(zone); | 
|  | if (hasErrorHandler) { | 
|  | f = zone.bindCallbackGuarded(f); | 
|  | } else { | 
|  | f = zone.bindCallback(f); | 
|  | } | 
|  | } | 
|  | _scheduleAsyncCallback(f); | 
|  | } | 
|  |  | 
|  | Timer _rootCreateTimer( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | Duration duration, | 
|  | void Function() callback, | 
|  | ) { | 
|  | if (!identical(_rootZone, zone)) { | 
|  | callback = zone.bindCallback(callback); | 
|  | } | 
|  | return Timer._createTimer(duration, callback); | 
|  | } | 
|  |  | 
|  | Timer _rootCreatePeriodicTimer( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | Duration duration, | 
|  | void callback(Timer timer), | 
|  | ) { | 
|  | if (!identical(_rootZone, zone)) { | 
|  | callback = zone.bindUnaryCallback<void, Timer>(callback); | 
|  | } | 
|  | return Timer._createPeriodicTimer(duration, callback); | 
|  | } | 
|  |  | 
|  | void _rootPrint(Zone self, ZoneDelegate parent, Zone zone, String line) { | 
|  | printToConsole(line); | 
|  | } | 
|  |  | 
|  | void _printToZone(String line) { | 
|  | Zone.current.print(line); | 
|  | } | 
|  |  | 
|  | Zone _rootFork( | 
|  | Zone? self, | 
|  | ZoneDelegate? parent, | 
|  | Zone zone, | 
|  | ZoneSpecification? specification, | 
|  | Map<Object?, Object?>? zoneValues, | 
|  | ) { | 
|  | if (zone is! _Zone) { | 
|  | throw ArgumentError.value(zone, "zone", "Can only fork a platform zone"); | 
|  | } | 
|  | // TODO(floitsch): it would be nice if we could get rid of this hack. | 
|  | // Change the static zoneOrDirectPrint function to go through zones | 
|  | // from now on. | 
|  | printToZone = _printToZone; | 
|  |  | 
|  | if (specification == null) { | 
|  | specification = const ZoneSpecification(); | 
|  | } else if (specification is! _ZoneSpecification) { | 
|  | specification = ZoneSpecification.from(specification); | 
|  | } | 
|  | Map<Object?, Object?> valueMap; | 
|  | if (zoneValues == null) { | 
|  | valueMap = zone._map; | 
|  | } else { | 
|  | valueMap = HashMap<Object?, Object?>.from(zoneValues); | 
|  | } | 
|  | if (specification == null) | 
|  | throw "unreachable"; // TODO(lrn): Remove when type promotion works. | 
|  | return _CustomZone(zone, specification, valueMap); | 
|  | } | 
|  |  | 
|  | base class _RootZone extends _Zone { | 
|  | const _RootZone(); | 
|  |  | 
|  | _ZoneFunction<RunHandler> get _run => | 
|  | const _ZoneFunction<RunHandler>(_rootZone, _rootRun); | 
|  | _ZoneFunction<RunUnaryHandler> get _runUnary => | 
|  | const _ZoneFunction<RunUnaryHandler>(_rootZone, _rootRunUnary); | 
|  | _ZoneFunction<RunBinaryHandler> get _runBinary => | 
|  | const _ZoneFunction<RunBinaryHandler>(_rootZone, _rootRunBinary); | 
|  | _ZoneFunction<RegisterCallbackHandler> get _registerCallback => | 
|  | const _ZoneFunction<RegisterCallbackHandler>( | 
|  | _rootZone, | 
|  | _rootRegisterCallback, | 
|  | ); | 
|  | _ZoneFunction<RegisterUnaryCallbackHandler> get _registerUnaryCallback => | 
|  | const _ZoneFunction<RegisterUnaryCallbackHandler>( | 
|  | _rootZone, | 
|  | _rootRegisterUnaryCallback, | 
|  | ); | 
|  | _ZoneFunction<RegisterBinaryCallbackHandler> get _registerBinaryCallback => | 
|  | const _ZoneFunction<RegisterBinaryCallbackHandler>( | 
|  | _rootZone, | 
|  | _rootRegisterBinaryCallback, | 
|  | ); | 
|  | _ZoneFunction<ErrorCallbackHandler> get _errorCallback => | 
|  | const _ZoneFunction<ErrorCallbackHandler>(_rootZone, _rootErrorCallback); | 
|  | _ZoneFunction<ScheduleMicrotaskHandler> get _scheduleMicrotask => | 
|  | const _ZoneFunction<ScheduleMicrotaskHandler>( | 
|  | _rootZone, | 
|  | _rootScheduleMicrotask, | 
|  | ); | 
|  | _ZoneFunction<CreateTimerHandler> get _createTimer => | 
|  | const _ZoneFunction<CreateTimerHandler>(_rootZone, _rootCreateTimer); | 
|  | _ZoneFunction<CreatePeriodicTimerHandler> get _createPeriodicTimer => | 
|  | const _ZoneFunction<CreatePeriodicTimerHandler>( | 
|  | _rootZone, | 
|  | _rootCreatePeriodicTimer, | 
|  | ); | 
|  | _ZoneFunction<PrintHandler> get _print => | 
|  | const _ZoneFunction<PrintHandler>(_rootZone, _rootPrint); | 
|  | _ZoneFunction<ForkHandler> get _fork => | 
|  | const _ZoneFunction<ForkHandler>(_rootZone, _rootFork); | 
|  | _ZoneFunction<HandleUncaughtErrorHandler> get _handleUncaughtError => | 
|  | const _ZoneFunction<HandleUncaughtErrorHandler>( | 
|  | _rootZone, | 
|  | _rootHandleUncaughtError, | 
|  | ); | 
|  |  | 
|  | // The parent zone. | 
|  | _Zone? get parent => null; | 
|  |  | 
|  | /// The zone's scoped value declaration map. | 
|  | /// | 
|  | /// This is always a [HashMap]. | 
|  | Map<Object?, Object?> get _map => _rootMap; | 
|  |  | 
|  | static final _rootMap = HashMap(); | 
|  |  | 
|  | static ZoneDelegate? _rootDelegate; | 
|  |  | 
|  | ZoneDelegate get _delegate => _rootDelegate ??= _ZoneDelegate(this); | 
|  | // It's a lie, but the root zone never uses the parent delegate. | 
|  | ZoneDelegate get _parentDelegate => _delegate; | 
|  |  | 
|  | /// The closest error-handling zone. | 
|  | /// | 
|  | /// Returns `this` if `this` has an error-handler. Otherwise returns the | 
|  | /// parent's error-zone. | 
|  | Zone get errorZone => this; | 
|  |  | 
|  | // Zone interface. | 
|  |  | 
|  | void runGuarded(void f()) { | 
|  | try { | 
|  | if (identical(_rootZone, Zone._current)) { | 
|  | f(); | 
|  | return; | 
|  | } | 
|  | _rootRun(null, null, this, f); | 
|  | } catch (e, s) { | 
|  | handleUncaughtError(e, s); | 
|  | } | 
|  | } | 
|  |  | 
|  | void runUnaryGuarded<T>(void f(T arg), T arg) { | 
|  | try { | 
|  | if (identical(_rootZone, Zone._current)) { | 
|  | f(arg); | 
|  | return; | 
|  | } | 
|  | _rootRunUnary(null, null, this, f, arg); | 
|  | } catch (e, s) { | 
|  | handleUncaughtError(e, s); | 
|  | } | 
|  | } | 
|  |  | 
|  | void runBinaryGuarded<T1, T2>(void f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { | 
|  | try { | 
|  | if (identical(_rootZone, Zone._current)) { | 
|  | f(arg1, arg2); | 
|  | return; | 
|  | } | 
|  | _rootRunBinary(null, null, this, f, arg1, arg2); | 
|  | } catch (e, s) { | 
|  | handleUncaughtError(e, s); | 
|  | } | 
|  | } | 
|  |  | 
|  | ZoneCallback<R> bindCallback<R>(R f()) { | 
|  | return () => this.run<R>(f); | 
|  | } | 
|  |  | 
|  | ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg)) { | 
|  | return (arg) => this.runUnary<R, T>(f, arg); | 
|  | } | 
|  |  | 
|  | ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>( | 
|  | R f(T1 arg1, T2 arg2), | 
|  | ) { | 
|  | return (arg1, arg2) => this.runBinary<R, T1, T2>(f, arg1, arg2); | 
|  | } | 
|  |  | 
|  | void Function() bindCallbackGuarded(void f()) { | 
|  | return () => this.runGuarded(f); | 
|  | } | 
|  |  | 
|  | void Function(T) bindUnaryCallbackGuarded<T>(void f(T arg)) { | 
|  | return (arg) => this.runUnaryGuarded(f, arg); | 
|  | } | 
|  |  | 
|  | void Function(T1, T2) bindBinaryCallbackGuarded<T1, T2>( | 
|  | void f(T1 arg1, T2 arg2), | 
|  | ) { | 
|  | return (arg1, arg2) => this.runBinaryGuarded(f, arg1, arg2); | 
|  | } | 
|  |  | 
|  | dynamic operator [](Object? key) => null; | 
|  |  | 
|  | // Methods that can be customized by the zone specification. | 
|  |  | 
|  | void handleUncaughtError(Object error, StackTrace stackTrace) { | 
|  | _rootHandleError(error, stackTrace); | 
|  | } | 
|  |  | 
|  | Zone fork({ | 
|  | ZoneSpecification? specification, | 
|  | Map<Object?, Object?>? zoneValues, | 
|  | }) { | 
|  | return _rootFork(null, null, this, specification, zoneValues); | 
|  | } | 
|  |  | 
|  | R run<R>(R f()) { | 
|  | if (identical(Zone._current, _rootZone)) return f(); | 
|  | return _rootRun(null, null, this, f); | 
|  | } | 
|  |  | 
|  | @pragma('vm:invisible') | 
|  | R runUnary<R, T>(R f(T arg), T arg) { | 
|  | if (identical(Zone._current, _rootZone)) return f(arg); | 
|  | return _rootRunUnary(null, null, this, f, arg); | 
|  | } | 
|  |  | 
|  | R runBinary<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { | 
|  | if (identical(Zone._current, _rootZone)) return f(arg1, arg2); | 
|  | return _rootRunBinary(null, null, this, f, arg1, arg2); | 
|  | } | 
|  |  | 
|  | ZoneCallback<R> registerCallback<R>(R f()) => f; | 
|  |  | 
|  | ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(R f(T arg)) => f; | 
|  |  | 
|  | ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( | 
|  | R f(T1 arg1, T2 arg2), | 
|  | ) => f; | 
|  |  | 
|  | AsyncError? errorCallback(Object error, StackTrace? stackTrace) => null; | 
|  |  | 
|  | void scheduleMicrotask(void f()) { | 
|  | _rootScheduleMicrotask(null, null, this, f); | 
|  | } | 
|  |  | 
|  | Timer createTimer(Duration duration, void f()) { | 
|  | return Timer._createTimer(duration, f); | 
|  | } | 
|  |  | 
|  | Timer createPeriodicTimer(Duration duration, void f(Timer timer)) { | 
|  | return Timer._createPeriodicTimer(duration, f); | 
|  | } | 
|  |  | 
|  | void print(String line) { | 
|  | printToConsole(line); | 
|  | } | 
|  | } | 
|  |  | 
|  | const _Zone _rootZone = _RootZone(); | 
|  |  | 
|  | /// Runs [body] in its own zone. | 
|  | /// | 
|  | /// Creates a new zone using [Zone.fork] based on [zoneSpecification] and | 
|  | /// [zoneValues], then runs [body] in that zone and returns the result. | 
|  | /// | 
|  | /// Example use: | 
|  | /// ```dart | 
|  | /// var secret = "arglebargle"; // Or a random generated string. | 
|  | /// var result = runZoned( | 
|  | ///     () async { | 
|  | ///       await Future.delayed(Duration(seconds: 5), () { | 
|  | ///         print("${Zone.current[#_secret]} glop glyf"); | 
|  | ///       }); | 
|  | ///     }, | 
|  | ///     zoneValues: {#_secret: secret}, | 
|  | ///     zoneSpecification: | 
|  | ///         ZoneSpecification(print: (Zone self, parent, zone, String value) { | 
|  | ///       if (value.contains(Zone.current[#_secret] as String)) { | 
|  | ///         value = "--censored--"; | 
|  | ///       } | 
|  | ///       parent.print(zone, value); | 
|  | ///     })); | 
|  | /// secret = ""; // Erase the evidence. | 
|  | /// await result; // Wait for asynchronous computation to complete. | 
|  | /// ``` | 
|  | /// The new zone intercepts `print` and stores a value under the private | 
|  | /// symbol `#_secret`. The secret is available from the new [Zone] object, | 
|  | /// which is the [Zone.current] for the body, | 
|  | /// and is also the first, `self`, parameter to the `print` handler function. | 
|  | /// | 
|  | /// If the [ZoneSpecification.handleUncaughtError] is set, or the deprecated | 
|  | /// [onError] callback is passed, the created zone will be an _error zone_. | 
|  | /// Asynchronous errors in futures never cross zone boundaries between zones | 
|  | /// with a different [Zone.errorZone]. | 
|  | /// A consequence of that behavior can be that a [Future] which completes as an | 
|  | /// error in the created zone will seem to never complete when used from a zone | 
|  | /// that belongs to a different error zone. | 
|  | /// Multiple attempts to use the future in a zone where the error is | 
|  | /// inaccessible will cause the error to be reported *again* in it's original | 
|  | /// error zone. | 
|  | /// | 
|  | /// See [runZonedGuarded] in place of using the deprected [onError] argument. | 
|  | /// If [onError] is provided this function also tries to catch and handle | 
|  | /// synchronous errors from [body], but may throw an error anyway returning | 
|  | /// `null` if the generic argument [R] is not nullable. | 
|  | R runZoned<R>( | 
|  | R body(), { | 
|  | Map<Object?, Object?>? zoneValues, | 
|  | ZoneSpecification? zoneSpecification, | 
|  | @Deprecated("Use runZonedGuarded instead") Function? onError, | 
|  | }) { | 
|  | if (onError != null) { | 
|  | // TODO: Remove this when code have been migrated off using [onError]. | 
|  | if (onError is! void Function(Object, StackTrace)) { | 
|  | if (onError is void Function(Object)) { | 
|  | var originalOnError = onError; | 
|  | onError = (Object error, StackTrace stack) => originalOnError(error); | 
|  | } else { | 
|  | throw ArgumentError.value( | 
|  | onError, | 
|  | "onError", | 
|  | "Must be Function(Object) or Function(Object, StackTrace)", | 
|  | ); | 
|  | } | 
|  | } | 
|  | return runZonedGuarded( | 
|  | body, | 
|  | onError, | 
|  | zoneSpecification: zoneSpecification, | 
|  | zoneValues: zoneValues, | 
|  | ) | 
|  | as R; | 
|  | } | 
|  | return _runZoned<R>(body, zoneValues, zoneSpecification); | 
|  | } | 
|  |  | 
|  | /// Runs [body] in its own error zone. | 
|  | /// | 
|  | /// Creates a new zone using [Zone.fork] based on [zoneSpecification] and | 
|  | /// [zoneValues], then runs [body] in that zone and returns the result. | 
|  | /// | 
|  | /// The [onError] function is used *both* to handle asynchronous errors | 
|  | /// by overriding [ZoneSpecification.handleUncaughtError] in [zoneSpecification], | 
|  | /// if any, *and* to handle errors thrown synchronously by the call to [body]. | 
|  | /// | 
|  | /// If an error occurs synchronously in [body], | 
|  | /// then throwing in the [onError] handler | 
|  | /// makes the call to `runZonedGuarded` throw that error, | 
|  | /// and otherwise the call to `runZonedGuarded` returns `null`. | 
|  | /// | 
|  | /// The created zone will always be an _error zone_. | 
|  | /// Asynchronous errors in futures never cross zone boundaries between zones | 
|  | /// with a different [Zone.errorZone]. | 
|  | /// A consequence of that behavior can be that a [Future] which completes as an | 
|  | /// error in the created zone will seem to never complete when used from a zone | 
|  | /// that belongs to a different error zone. | 
|  | /// Multiple attempts to use the future in a zone where the error is | 
|  | /// inaccessible will cause the error to be reported *again* in it's original | 
|  | /// error zone. | 
|  | R? runZonedGuarded<R>( | 
|  | R body(), | 
|  | void onError(Object error, StackTrace stack), { | 
|  | Map<Object?, Object?>? zoneValues, | 
|  | ZoneSpecification? zoneSpecification, | 
|  | }) { | 
|  | _Zone parentZone = Zone._current; | 
|  | HandleUncaughtErrorHandler errorHandler = ( | 
|  | Zone self, | 
|  | ZoneDelegate parent, | 
|  | Zone zone, | 
|  | Object error, | 
|  | StackTrace stackTrace, | 
|  | ) { | 
|  | try { | 
|  | parentZone.runBinary(onError, error, stackTrace); | 
|  | } catch (e, s) { | 
|  | if (identical(e, error)) { | 
|  | parent.handleUncaughtError(zone, error, stackTrace); | 
|  | } else { | 
|  | parent.handleUncaughtError(zone, e, s); | 
|  | } | 
|  | } | 
|  | }; | 
|  | if (zoneSpecification == null) { | 
|  | zoneSpecification = ZoneSpecification(handleUncaughtError: errorHandler); | 
|  | } else { | 
|  | zoneSpecification = ZoneSpecification.from( | 
|  | zoneSpecification, | 
|  | handleUncaughtError: errorHandler, | 
|  | ); | 
|  | } | 
|  | try { | 
|  | return _runZoned<R>(body, zoneValues, zoneSpecification); | 
|  | } catch (error, stackTrace) { | 
|  | onError(error, stackTrace); | 
|  | } | 
|  | return null; | 
|  | } | 
|  |  | 
|  | /// Runs [body] in a new zone based on [zoneValues] and [specification]. | 
|  | R _runZoned<R>( | 
|  | R body(), | 
|  | Map<Object?, Object?>? zoneValues, | 
|  | ZoneSpecification? specification, | 
|  | ) => Zone.current | 
|  | .fork(specification: specification, zoneValues: zoneValues) | 
|  | .run<R>(body); |