Chromium Code Reviews| Index: sdk/lib/async/zone.dart |
| diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart |
| index 573603627f24ad056ffbb04ce72c4feeaded51d2..dd3e1333938d209e431d3c24df963ea046243cdb 100644 |
| --- a/sdk/lib/async/zone.dart |
| +++ b/sdk/lib/async/zone.dart |
| @@ -8,28 +8,21 @@ typedef R ZoneCallback<R>(); |
| typedef R ZoneUnaryCallback<R, T>(T arg); |
| typedef R ZoneBinaryCallback<R, T1, T2>(T1 arg1, T2 arg2); |
| -// TODO(floitsch): we are abusing generic typedefs as typedefs for generic |
| -// functions. |
| -/*ABUSE*/ |
| -typedef R HandleUncaughtErrorHandler<R>( |
| - Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace); |
| -/*ABUSE*/ |
| -typedef R RunHandler<R>(Zone self, ZoneDelegate parent, Zone zone, R f()); |
| -/*ABUSE*/ |
| -typedef R RunUnaryHandler<R, T>( |
| - Zone self, ZoneDelegate parent, Zone zone, R f(T arg), T arg); |
| -/*ABUSE*/ |
| -typedef R RunBinaryHandler<R, T1, T2>(Zone self, ZoneDelegate parent, Zone zone, |
| - R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2); |
| -/*ABUSE*/ |
| -typedef ZoneCallback<R> RegisterCallbackHandler<R>( |
| - Zone self, ZoneDelegate parent, Zone zone, R f()); |
| -/*ABUSE*/ |
| -typedef ZoneUnaryCallback<R, T> RegisterUnaryCallbackHandler<R, T>( |
| - Zone self, ZoneDelegate parent, Zone zone, R f(T arg)); |
| -/*ABUSE*/ |
| -typedef ZoneBinaryCallback<R, T1, T2> RegisterBinaryCallbackHandler<R, T1, T2>( |
| - Zone self, ZoneDelegate parent, Zone zone, R f(T1 arg1, T2 arg2)); |
| +typedef HandleUncaughtErrorHandler = void Function(Zone self, |
| + ZoneDelegate parent, Zone zone, Object error, StackTrace stackTrace); |
| +typedef RunHandler = R Function<R>( |
| + Zone self, ZoneDelegate parent, Zone zone, R Function() f); |
| +typedef RunUnaryHandler = R Function<R, T>( |
| + Zone self, ZoneDelegate parent, Zone zone, R Function(T arg) f, T arg); |
| +typedef RunBinaryHandler = R Function<R, T1, T2>(Zone self, ZoneDelegate parent, |
| + Zone zone, R Function(T1 arg1, T2 arg2) f, T1 arg1, T2 arg2); |
| +typedef RegisterCallbackHandler = ZoneCallback<R> Function<R>( |
| + Zone self, ZoneDelegate parent, Zone zone, R Function() f); |
| +typedef RegisterUnaryCallbackHandler = ZoneUnaryCallback<R, T> Function<R, T>( |
| + Zone self, ZoneDelegate parent, Zone zone, R Function(T arg) f); |
| +typedef RegisterBinaryCallbackHandler |
| + = ZoneBinaryCallback<R, T1, T2> Function<R, T1, T2>(Zone self, |
| + ZoneDelegate parent, Zone zone, R Function(T1 arg1, T2 arg2) f); |
| typedef AsyncError ErrorCallbackHandler(Zone self, ZoneDelegate parent, |
| Zone zone, Object error, StackTrace stackTrace); |
| typedef void ScheduleMicrotaskHandler( |
| @@ -209,7 +202,7 @@ class _ZoneSpecification implements ZoneSpecification { |
| * to skip zones that would just delegate to their parents. |
| */ |
| abstract class ZoneDelegate { |
| - R handleUncaughtError<R>(Zone zone, error, StackTrace stackTrace); |
| + void handleUncaughtError(Zone zone, error, StackTrace stackTrace); |
| R run<R>(Zone zone, R f()); |
| R runUnary<R, T>(Zone zone, R f(T arg), T arg); |
| R runBinary<R, T1, T2>(Zone zone, R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2); |
| @@ -263,10 +256,14 @@ abstract class ZoneDelegate { |
| * the protocol to be zone compatible. |
| * |
| * For convenience, zones provide [bindCallback] (and the corresponding |
| - * [bindUnaryCallback] or [bindBinaryCallback]) to make it easier to respect the |
| - * zone contract: these functions first invoke the corresponding `register` |
| + * [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]. |
| */ |
| abstract class Zone { |
| // Private constructor so that it is not possible instantiate a Zone class. |
| @@ -312,7 +309,7 @@ abstract class Zone { |
| * By default, when handled by the root zone, uncaught asynchronous errors are |
| * treated like uncaught synchronous exceptions. |
| */ |
| - R handleUncaughtError<R>(error, StackTrace stackTrace); |
| + void handleUncaughtError(error, StackTrace stackTrace); |
| /** |
| * The parent zone of the this zone. |
| @@ -438,15 +435,15 @@ abstract class Zone { |
| * This function is equivalent to: |
| * ``` |
| * try { |
| - * return this.run(action); |
| + * this.run(action); |
| * } catch (e, s) { |
| - * return this.handleUncaughtError(e, s); |
| + * this.handleUncaughtError(e, s); |
| * } |
| * ``` |
| * |
| * See [run]. |
| */ |
| - R runGuarded<R>(R action()); |
| + void runGuarded(void action()); |
| /** |
| * Executes the given [action] with [argument] in this zone and |
| @@ -454,7 +451,7 @@ abstract class Zone { |
| * |
| * See [runGuarded]. |
| */ |
| - R runUnaryGuarded<R, T>(R action(T argument), T argument); |
| + void runUnaryGuarded<T>(void action(T argument), T argument); |
| /** |
| * Executes the given [action] with [argument1] and [argument2] in this |
| @@ -462,8 +459,8 @@ abstract class Zone { |
| * |
| * See [runGuarded]. |
| */ |
| - R runBinaryGuarded<R, T1, T2>( |
| - R action(T1 argument1, T2 argument2), T1 argument1, T2 argument2); |
| + void runBinaryGuarded<T1, T2>( |
| + void action(T1 argument1, T2 argument2), T1 argument1, T2 argument2); |
| /** |
| * Registers the given callback in this zone. |
| @@ -501,37 +498,80 @@ abstract class Zone { |
| R callback(T1 arg1, T2 arg2)); |
| /** |
| + * Registers the provided [callback] and returns a function that will |
| + * execute in this zone. |
| + * |
| * Equivalent to: |
| * |
| - * ZoneCallback registered = this.registerCallback(action); |
| - * if (runGuarded) return () => this.runGuarded(registered); |
| + * ZoneCallback registered = this.registerCallback(callback); |
| * return () => this.run(registered); |
| * |
| */ |
| - ZoneCallback<R> bindCallback<R>(R action(), {bool runGuarded: true}); |
| + ZoneCallback<R> bindCallback<R>(R callback()); |
| /** |
| + * Registers the provided [callback] and returns a function that will |
| + * execute in this zone. |
| + * |
| * Equivalent to: |
| * |
| - * ZoneCallback registered = this.registerUnaryCallback(action); |
| - * if (runGuarded) return (arg) => this.runUnaryGuarded(registered, arg); |
| + * ZoneCallback registered = this.registerUnaryCallback(callback); |
| * return (arg) => thin.runUnary(registered, arg); |
| */ |
| - ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R action(T argument), |
| - {bool runGuarded: true}); |
| + 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: |
| * |
| - * ZoneCallback registered = registerBinaryCallback(action); |
| - * if (runGuarded) { |
| - * return (arg1, arg2) => this.runBinaryGuarded(registered, arg); |
| - * } |
| + * ZoneCallback registered = registerBinaryCallback(callback); |
| * return (arg1, arg2) => thin.runBinary(registered, arg1, arg2); |
| */ |
| ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>( |
| - R action(T1 argument1, T2 argument2), |
| - {bool runGuarded: true}); |
| + 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: |
| + * |
| + * ZoneCallback registered = this.registerCallback(callback); |
| + * return () => this.runGuarded(registered); |
| + * |
| + */ |
| + void Function() bindCallbackGuarded(void 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: |
| + * |
| + * 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: |
| + * |
| + * 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 programatically to a `Future` or `Stream`. |
| @@ -565,16 +605,16 @@ abstract class Zone { |
| AsyncError errorCallback(Object error, StackTrace stackTrace); |
| /** |
| - * Runs [action] asynchronously in this zone. |
| + * 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 [action]). |
| + * [callback]). |
| */ |
| - void scheduleMicrotask(void action()); |
| + void scheduleMicrotask(void callback()); |
| /** |
| * Creates a Timer where the callback is executed in this zone. |
| @@ -656,64 +696,47 @@ class _ZoneDelegate implements ZoneDelegate { |
| _ZoneDelegate(this._delegationTarget); |
| - R handleUncaughtError<R>(Zone zone, error, StackTrace stackTrace) { |
| + void handleUncaughtError(Zone zone, error, StackTrace stackTrace) { |
| var implementation = _delegationTarget._handleUncaughtError; |
| _Zone implZone = implementation.zone; |
| HandleUncaughtErrorHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R>' once it's |
| - // supported. Remove the unnecessary cast. |
| - return handler(implZone, _parentDelegate(implZone), zone, error, stackTrace) |
| - as Object/*=R*/; |
| + return handler( |
| + implZone, _parentDelegate(implZone), zone, error, stackTrace); |
| } |
| R run<R>(Zone zone, R f()) { |
| var implementation = _delegationTarget._run; |
| _Zone implZone = implementation.zone; |
| RunHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R>' once it's |
| - // supported. Remove the unnecessary cast. |
| - return handler(implZone, _parentDelegate(implZone), zone, f) |
| - as Object/*=R*/; |
| + return handler(implZone, _parentDelegate(implZone), zone, f); |
| } |
| R runUnary<R, T>(Zone zone, R f(T arg), T arg) { |
| var implementation = _delegationTarget._runUnary; |
| _Zone implZone = implementation.zone; |
| RunUnaryHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R, T>' once it's |
| - // supported. Remove the unnecessary cast. |
| - return handler(implZone, _parentDelegate(implZone), zone, f, arg) |
| - as Object/*=R*/; |
| + return handler(implZone, _parentDelegate(implZone), 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; |
| RunBinaryHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once |
| - // it's supported. Remove the unnecessary cast. |
| - return handler(implZone, _parentDelegate(implZone), zone, f, arg1, arg2) |
| - as Object/*=R*/; |
| + return handler(implZone, _parentDelegate(implZone), zone, f, arg1, arg2); |
| } |
| ZoneCallback<R> registerCallback<R>(Zone zone, R f()) { |
| var implementation = _delegationTarget._registerCallback; |
| _Zone implZone = implementation.zone; |
| RegisterCallbackHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R>' once it's |
| - // supported. Remove the unnecessary cast. |
| - return handler(implZone, _parentDelegate(implZone), zone, f) |
| - as Object/*=ZoneCallback<R>*/; |
| + return handler(implZone, _parentDelegate(implZone), zone, f); |
| } |
| ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(Zone zone, R f(T arg)) { |
| var implementation = _delegationTarget._registerUnaryCallback; |
| _Zone implZone = implementation.zone; |
| RegisterUnaryCallbackHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R, T>' once it's |
| - // supported. Remove the unnecessary cast. |
| - return handler(implZone, _parentDelegate(implZone), zone, f) |
| - as Object/*=ZoneUnaryCallback<R, T>*/; |
| + return handler(implZone, _parentDelegate(implZone), zone, f); |
| } |
| ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( |
| @@ -721,10 +744,7 @@ class _ZoneDelegate implements ZoneDelegate { |
| var implementation = _delegationTarget._registerBinaryCallback; |
| _Zone implZone = implementation.zone; |
| RegisterBinaryCallbackHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once |
| - // it's supported. Remove the unnecessary cast. |
| - return handler(implZone, _parentDelegate(implZone), zone, f) |
| - as Object/*=ZoneBinaryCallback<R, T1, T2>*/; |
| + return handler(implZone, _parentDelegate(implZone), zone, f); |
| } |
| AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace) { |
| @@ -896,58 +916,60 @@ class _CustomZone extends _Zone { |
| */ |
| Zone get errorZone => _handleUncaughtError.zone; |
| - R runGuarded<R>(R f()) { |
| + void runGuarded(void f()) { |
| try { |
| - return run(f); |
| + run(f); |
| } catch (e, s) { |
| - return handleUncaughtError(e, s); |
| + handleUncaughtError(e, s); |
| } |
| } |
| - R runUnaryGuarded<R, T>(R f(T arg), T arg) { |
| + void runUnaryGuarded<T>(void f(T arg), T arg) { |
| try { |
| - return runUnary(f, arg); |
| + runUnary(f, arg); |
| } catch (e, s) { |
| - return handleUncaughtError(e, s); |
| + handleUncaughtError(e, s); |
| } |
| } |
| - R runBinaryGuarded<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
| + void runBinaryGuarded<T1, T2>(void f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
| try { |
| - return runBinary(f, arg1, arg2); |
| + runBinary(f, arg1, arg2); |
| } catch (e, s) { |
| - return handleUncaughtError(e, s); |
| + handleUncaughtError(e, s); |
| } |
| } |
| - ZoneCallback<R> bindCallback<R>(R f(), {bool runGuarded: true}) { |
| + ZoneCallback<R> bindCallback<R>(R f()) { |
| var registered = registerCallback(f); |
| - if (runGuarded) { |
| - return () => this.runGuarded(registered); |
| - } else { |
| - return () => this.run(registered); |
| - } |
| + return () => this.run(registered); |
| } |
| - ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg), |
| - {bool runGuarded: true}) { |
| + ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg)) { |
| var registered = registerUnaryCallback(f); |
| - if (runGuarded) { |
| - return (arg) => this.runUnaryGuarded(registered, arg); |
| - } else { |
| - return (arg) => this.runUnary(registered, arg); |
| - } |
| + return (arg) => this.runUnary(registered, arg); |
| } |
| ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>( |
| - R f(T1 arg1, T2 arg2), |
| - {bool runGuarded: true}) { |
| + R f(T1 arg1, T2 arg2)) { |
| var registered = registerBinaryCallback(f); |
| - if (runGuarded) { |
| - return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2); |
| - } else { |
| - return (arg1, arg2) => this.runBinary(registered, arg1, arg2); |
| - } |
| + 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); |
| } |
| operator [](Object key) { |
| @@ -971,15 +993,13 @@ class _CustomZone extends _Zone { |
| // Methods that can be customized by the zone specification. |
| - R handleUncaughtError<R>(error, StackTrace stackTrace) { |
| + void handleUncaughtError(error, StackTrace stackTrace) { |
| var implementation = this._handleUncaughtError; |
| assert(implementation != null); |
| ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
| HandleUncaughtErrorHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R>' once it's |
| - // supported. Remove the unnecessary cast. |
| - return handler(implementation.zone, parentDelegate, this, error, stackTrace) |
| - as Object/*=R*/; |
| + return handler( |
| + implementation.zone, parentDelegate, this, error, stackTrace); |
| } |
| Zone fork({ZoneSpecification specification, Map zoneValues}) { |
| @@ -996,10 +1016,7 @@ class _CustomZone extends _Zone { |
| assert(implementation != null); |
| ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
| RunHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R>' once it's |
| - // supported. Remove the unnecessary cast. |
| - return handler(implementation.zone, parentDelegate, this, f) |
| - as Object/*=R*/; |
| + return handler(implementation.zone, parentDelegate, this, f); |
| } |
| R runUnary<R, T>(R f(T arg), T arg) { |
| @@ -1007,10 +1024,7 @@ class _CustomZone extends _Zone { |
| assert(implementation != null); |
| ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
| RunUnaryHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R, T>' once it's |
| - // supported. Remove the unnecessary cast. |
| - return handler(implementation.zone, parentDelegate, this, f, arg) |
| - as Object/*=R*/; |
| + return handler(implementation.zone, parentDelegate, this, f, arg); |
| } |
| R runBinary<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
| @@ -1018,10 +1032,7 @@ class _CustomZone extends _Zone { |
| assert(implementation != null); |
| ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
| RunBinaryHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once |
| - // it's supported. Remove the unnecessary cast. |
| - return handler(implementation.zone, parentDelegate, this, f, arg1, arg2) |
| - as Object/*=R*/; |
| + return handler(implementation.zone, parentDelegate, this, f, arg1, arg2); |
| } |
| ZoneCallback<R> registerCallback<R>(R callback()) { |
| @@ -1029,10 +1040,7 @@ class _CustomZone extends _Zone { |
| assert(implementation != null); |
| ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
| RegisterCallbackHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R>' once it's |
| - // supported. Remove the unnecessary cast. |
| - return handler(implementation.zone, parentDelegate, this, callback) |
| - as Object/*=ZoneCallback<R>*/; |
| + return handler(implementation.zone, parentDelegate, this, callback); |
| } |
| ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(R callback(T arg)) { |
| @@ -1040,10 +1048,7 @@ class _CustomZone extends _Zone { |
| assert(implementation != null); |
| ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
| RegisterUnaryCallbackHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R, T>' once it's |
| - // supported. Remove the unnecessary cast. |
| - return handler(implementation.zone, parentDelegate, this, callback) |
| - as Object/*=ZoneUnaryCallback<R, T>*/; |
| + return handler(implementation.zone, parentDelegate, this, callback); |
| } |
| ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( |
| @@ -1052,10 +1057,7 @@ class _CustomZone extends _Zone { |
| assert(implementation != null); |
| ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
| RegisterBinaryCallbackHandler handler = implementation.function; |
| - // TODO(floitsch): make this a generic method call on '<R, T1, T2>' once |
| - // it's supported. Remove the unnecessary cast. |
| - return handler(implementation.zone, parentDelegate, this, callback) |
| - as Object/*=ZoneBinaryCallback<R, T1, T2>*/; |
| + return handler(implementation.zone, parentDelegate, this, callback); |
| } |
| AsyncError errorCallback(Object error, StackTrace stackTrace) { |
| @@ -1101,7 +1103,7 @@ class _CustomZone extends _Zone { |
| } |
| } |
| -R _rootHandleUncaughtError<R>( |
| +void _rootHandleUncaughtError( |
| Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace) { |
| _schedulePriorityAsyncCallback(() { |
| if (error == null) error = new NullThrownError(); |
| @@ -1166,10 +1168,15 @@ AsyncError _rootErrorCallback(Zone self, ZoneDelegate parent, Zone zone, |
| Object error, StackTrace stackTrace) => |
| null; |
| -void _rootScheduleMicrotask(Zone self, ZoneDelegate parent, Zone zone, f()) { |
| +void _rootScheduleMicrotask( |
| + Zone self, ZoneDelegate parent, Zone zone, void f()) { |
| if (!identical(_ROOT_ZONE, zone)) { |
| bool hasErrorHandler = !_ROOT_ZONE.inSameErrorZone(zone); |
| - f = zone.bindCallback(f, runGuarded: hasErrorHandler); |
| + if (hasErrorHandler) { |
| + f = zone.bindCallbackGuarded(f); |
| + } else { |
| + f = zone.bindCallback(f); |
| + } |
| // Use root zone as event zone if the function is already bound. |
| zone = _ROOT_ZONE; |
| } |
| @@ -1290,72 +1297,74 @@ class _RootZone extends _Zone { |
| // Zone interface. |
| - R runGuarded<R>(R f()) { |
| + void runGuarded(void f()) { |
| try { |
| if (identical(_ROOT_ZONE, Zone._current)) { |
| - return f(); |
| + f(); |
| + return; |
| } |
| - return _rootRun<R>(null, null, this, f); |
| + _rootRun(null, null, this, f); |
| } catch (e, s) { |
| - return handleUncaughtError<R>(e, s); |
| + handleUncaughtError(e, s); |
| } |
| } |
| - R runUnaryGuarded<R, T>(R f(T arg), T arg) { |
| + void runUnaryGuarded<T>(void f(T arg), T arg) { |
| try { |
| if (identical(_ROOT_ZONE, Zone._current)) { |
| - return f(arg); |
| + f(arg); |
| + return; |
| } |
| - return _rootRunUnary<R, T>(null, null, this, f, arg); |
| + _rootRunUnary(null, null, this, f, arg); |
| } catch (e, s) { |
| - return handleUncaughtError<R>(e, s); |
| + handleUncaughtError(e, s); |
| } |
| } |
| - R runBinaryGuarded<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
| + void runBinaryGuarded<T1, T2>(void f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
| try { |
| if (identical(_ROOT_ZONE, Zone._current)) { |
| - return f(arg1, arg2); |
| + f(arg1, arg2); |
| + return; |
| } |
| - return _rootRunBinary<R, T1, T2>(null, null, this, f, arg1, arg2); |
| + _rootRunBinary(null, null, this, f, arg1, arg2); |
| } catch (e, s) { |
| - return handleUncaughtError<R>(e, s); |
| + handleUncaughtError(e, s); |
| } |
| } |
| - ZoneCallback<R> bindCallback<R>(R f(), {bool runGuarded: true}) { |
| - if (runGuarded) { |
| - return () => this.runGuarded<R>(f); |
| - } else { |
| - return () => this.run<R>(f); |
| - } |
| + ZoneCallback<R> bindCallback<R>(R f()) { |
| + return () => this.run<R>(f); |
| } |
| - ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg), |
| - {bool runGuarded: true}) { |
| - if (runGuarded) { |
| - return (arg) => this.runUnaryGuarded<R, T>(f, arg); |
| - } else { |
| - return (arg) => this.runUnary<R, T>(f, arg); |
| - } |
| + 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), |
| - {bool runGuarded: true}) { |
| - if (runGuarded) { |
| - return (arg1, arg2) => this.runBinaryGuarded<R, T1, T2>(f, arg1, arg2); |
| - } else { |
| - return (arg1, arg2) => this.runBinary<R, T1, T2>(f, arg1, arg2); |
| - } |
| + 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); |
| } |
| operator [](Object key) => null; |
| // Methods that can be customized by the zone specification. |
| - R handleUncaughtError<R>(error, StackTrace stackTrace) { |
| - return _rootHandleUncaughtError(null, null, this, error, stackTrace); |
| + void handleUncaughtError(error, StackTrace stackTrace) { |
| + _rootHandleUncaughtError(null, null, this, error, stackTrace); |
| } |
| Zone fork({ZoneSpecification specification, Map zoneValues}) { |
| @@ -1409,9 +1418,15 @@ const _ROOT_ZONE = const _RootZone(); |
| /** |
| * Runs [body] in its own zone. |
| * |
| + * Returns the result of invoking [body]. |
| + * |
| * If [onError] is non-null the zone is considered an error zone. All uncaught |
| * errors, synchronous or asynchronous, in the zone are caught and handled |
| - * by the callback. |
| + * by the callback. When the error is synchronous, throwing in the [onError] |
| + * handler, leads to a synchronous exception. |
| + * |
| + * Returns `null` when [body] threw, and a provided [onError] function completed |
| + * without throwing. |
| * |
| * Errors may never cross error-zone boundaries. This is intuitive for leaving |
| * a zone, but it also applies for errors that would enter an error-zone. |
| @@ -1433,21 +1448,29 @@ const _ROOT_ZONE = const _RootZone(); |
| */ |
| R runZoned<R>(R body(), |
| {Map zoneValues, ZoneSpecification zoneSpecification, Function onError}) { |
| + // TODO(floitsch): the return type should be `void` here. |
| + if (onError != null && |
| + onError is! ZoneBinaryCallback<Object, Object, StackTrace> && |
| + onError is! ZoneUnaryCallback<Object, Object>) { |
| + throw new ArgumentError("onError callback must take an Object (the error), " |
| + "or an Object (the error) and a StackTrace"); |
| + } |
| HandleUncaughtErrorHandler errorHandler; |
| if (onError != null) { |
| errorHandler = (Zone self, ZoneDelegate parent, Zone zone, error, |
| StackTrace stackTrace) { |
| try { |
| - // TODO(floitsch): the return type should be 'void'. |
| - if (onError is ZoneBinaryCallback<dynamic, Object, StackTrace>) { |
| - return self.parent.runBinary(onError, error, stackTrace); |
| + if (onError is void Function(Object, StackTrace)) { |
| + self.parent.runBinary(onError, error, stackTrace); |
| + return; |
| } |
| - return self.parent.runUnary(onError, error); |
| + assert(onError is void Function(Object)); |
| + self.parent.runUnary(onError, error); |
| } catch (e, s) { |
| if (identical(e, error)) { |
| - return parent.handleUncaughtError(zone, error, stackTrace); |
| + parent.handleUncaughtError(zone, error, stackTrace); |
| } else { |
| - return parent.handleUncaughtError(zone, e, s); |
| + parent.handleUncaughtError(zone, e, s); |
| } |
| } |
| }; |
| @@ -1462,7 +1485,17 @@ R runZoned<R>(R body(), |
| Zone zone = Zone.current |
| .fork(specification: zoneSpecification, zoneValues: zoneValues); |
| if (onError != null) { |
| - return zone.runGuarded(body); |
| + try { |
| + return zone.run(body); |
| + } catch (e, stackTrace) { |
| + if (onError is ZoneBinaryCallback<R, Object, StackTrace>) { |
| + zone.runBinary(onError, e, stackTrace); |
| + return null; |
| + } |
| + assert(onError is! ZoneUnaryCallback<R, Object>); |
|
vsm
2017/06/16 13:05:59
This assert is failing in DDC on lib/async/run_zon
floitsch
2017/06/16 19:54:17
Good catch. thanks.
done.
|
| + zone.runUnary(onError, e); |
| + return null; |
| + } |
| } else { |
| return zone.run(body); |
| } |