Index: sdk/lib/async/zone.dart |
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart |
index 6ed22ec6d235b2e82a19ca38b14767b841f55cc0..c7f254e396c39d6083939a7d7197f99a08d64bb8 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 programmatically 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>); |
+ zone.runUnary(onError, e); |
+ return null; |
+ } |
} else { |
return zone.run(body); |
} |