Index: sdk/lib/async/zone.dart |
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart |
index c7f254e396c39d6083939a7d7197f99a08d64bb8..6ed22ec6d235b2e82a19ca38b14767b841f55cc0 100644 |
--- a/sdk/lib/async/zone.dart |
+++ b/sdk/lib/async/zone.dart |
@@ -8,21 +8,28 @@ typedef R ZoneCallback<R>(); |
typedef R ZoneUnaryCallback<R, T>(T arg); |
typedef R ZoneBinaryCallback<R, T1, T2>(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); |
+// 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 AsyncError ErrorCallbackHandler(Zone self, ZoneDelegate parent, |
Zone zone, Object error, StackTrace stackTrace); |
typedef void ScheduleMicrotaskHandler( |
@@ -202,7 +209,7 @@ class _ZoneSpecification implements ZoneSpecification { |
* to skip zones that would just delegate to their parents. |
*/ |
abstract class ZoneDelegate { |
- void handleUncaughtError(Zone zone, error, StackTrace stackTrace); |
+ R handleUncaughtError<R>(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); |
@@ -256,14 +263,10 @@ abstract class ZoneDelegate { |
* 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` |
+ * [bindUnaryCallback] or [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. |
@@ -309,7 +312,7 @@ abstract class Zone { |
* By default, when handled by the root zone, uncaught asynchronous errors are |
* treated like uncaught synchronous exceptions. |
*/ |
- void handleUncaughtError(error, StackTrace stackTrace); |
+ R handleUncaughtError<R>(error, StackTrace stackTrace); |
/** |
* The parent zone of the this zone. |
@@ -435,15 +438,15 @@ abstract class Zone { |
* This function is equivalent to: |
* ``` |
* try { |
- * this.run(action); |
+ * return this.run(action); |
* } catch (e, s) { |
- * this.handleUncaughtError(e, s); |
+ * return this.handleUncaughtError(e, s); |
* } |
* ``` |
* |
* See [run]. |
*/ |
- void runGuarded(void action()); |
+ R runGuarded<R>(R action()); |
/** |
* Executes the given [action] with [argument] in this zone and |
@@ -451,7 +454,7 @@ abstract class Zone { |
* |
* See [runGuarded]. |
*/ |
- void runUnaryGuarded<T>(void action(T argument), T argument); |
+ R runUnaryGuarded<R, T>(R action(T argument), T argument); |
/** |
* Executes the given [action] with [argument1] and [argument2] in this |
@@ -459,8 +462,8 @@ abstract class Zone { |
* |
* See [runGuarded]. |
*/ |
- void runBinaryGuarded<T1, T2>( |
- void action(T1 argument1, T2 argument2), T1 argument1, T2 argument2); |
+ R runBinaryGuarded<R, T1, T2>( |
+ R action(T1 argument1, T2 argument2), T1 argument1, T2 argument2); |
/** |
* Registers the given callback in this zone. |
@@ -498,80 +501,37 @@ 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(callback); |
+ * ZoneCallback registered = this.registerCallback(action); |
+ * if (runGuarded) return () => this.runGuarded(registered); |
* return () => this.run(registered); |
* |
*/ |
- ZoneCallback<R> bindCallback<R>(R callback()); |
+ ZoneCallback<R> bindCallback<R>(R action(), {bool runGuarded: true}); |
/** |
- * Registers the provided [callback] and returns a function that will |
- * execute in this zone. |
- * |
* Equivalent to: |
* |
- * ZoneCallback registered = this.registerUnaryCallback(callback); |
+ * ZoneCallback registered = this.registerUnaryCallback(action); |
+ * if (runGuarded) return (arg) => this.runUnaryGuarded(registered, arg); |
* return (arg) => thin.runUnary(registered, arg); |
*/ |
- ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R callback(T argument)); |
+ ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R action(T argument), |
+ {bool runGuarded: true}); |
/** |
- * Registers the provided [callback] and returns a function that will |
- * execute in this zone. |
- * |
* Equivalent to: |
* |
- * ZoneCallback registered = registerBinaryCallback(callback); |
+ * ZoneCallback registered = registerBinaryCallback(action); |
+ * if (runGuarded) { |
+ * return (arg1, arg2) => this.runBinaryGuarded(registered, arg); |
+ * } |
* return (arg1, arg2) => thin.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: |
- * |
- * 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)); |
+ R action(T1 argument1, T2 argument2), |
+ {bool runGuarded: true}); |
/** |
* Intercepts errors when added programmatically to a `Future` or `Stream`. |
@@ -605,16 +565,16 @@ abstract class Zone { |
AsyncError errorCallback(Object error, StackTrace stackTrace); |
/** |
- * Runs [callback] asynchronously in this zone. |
+ * Runs [action] 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]). |
+ * callback [action]). |
*/ |
- void scheduleMicrotask(void callback()); |
+ void scheduleMicrotask(void action()); |
/** |
* Creates a Timer where the callback is executed in this zone. |
@@ -696,47 +656,64 @@ class _ZoneDelegate implements ZoneDelegate { |
_ZoneDelegate(this._delegationTarget); |
- void handleUncaughtError(Zone zone, error, StackTrace stackTrace) { |
+ R handleUncaughtError<R>(Zone zone, error, StackTrace stackTrace) { |
var implementation = _delegationTarget._handleUncaughtError; |
_Zone implZone = implementation.zone; |
HandleUncaughtErrorHandler handler = implementation.function; |
- return handler( |
- implZone, _parentDelegate(implZone), zone, error, stackTrace); |
+ // 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*/; |
} |
R run<R>(Zone zone, R f()) { |
var implementation = _delegationTarget._run; |
_Zone implZone = implementation.zone; |
RunHandler handler = implementation.function; |
- return handler(implZone, _parentDelegate(implZone), zone, f); |
+ // 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*/; |
} |
R runUnary<R, T>(Zone zone, R f(T arg), T arg) { |
var implementation = _delegationTarget._runUnary; |
_Zone implZone = implementation.zone; |
RunUnaryHandler handler = implementation.function; |
- return handler(implZone, _parentDelegate(implZone), zone, f, arg); |
+ // 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*/; |
} |
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; |
- return handler(implZone, _parentDelegate(implZone), zone, f, arg1, arg2); |
+ // 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*/; |
} |
ZoneCallback<R> registerCallback<R>(Zone zone, R f()) { |
var implementation = _delegationTarget._registerCallback; |
_Zone implZone = implementation.zone; |
RegisterCallbackHandler handler = implementation.function; |
- return handler(implZone, _parentDelegate(implZone), zone, f); |
+ // 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>*/; |
} |
ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(Zone zone, R f(T arg)) { |
var implementation = _delegationTarget._registerUnaryCallback; |
_Zone implZone = implementation.zone; |
RegisterUnaryCallbackHandler handler = implementation.function; |
- return handler(implZone, _parentDelegate(implZone), zone, f); |
+ // 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>*/; |
} |
ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( |
@@ -744,7 +721,10 @@ class _ZoneDelegate implements ZoneDelegate { |
var implementation = _delegationTarget._registerBinaryCallback; |
_Zone implZone = implementation.zone; |
RegisterBinaryCallbackHandler handler = implementation.function; |
- return handler(implZone, _parentDelegate(implZone), zone, f); |
+ // 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>*/; |
} |
AsyncError errorCallback(Zone zone, Object error, StackTrace stackTrace) { |
@@ -916,60 +896,58 @@ class _CustomZone extends _Zone { |
*/ |
Zone get errorZone => _handleUncaughtError.zone; |
- void runGuarded(void f()) { |
+ R runGuarded<R>(R f()) { |
try { |
- run(f); |
+ return run(f); |
} catch (e, s) { |
- handleUncaughtError(e, s); |
+ return handleUncaughtError(e, s); |
} |
} |
- void runUnaryGuarded<T>(void f(T arg), T arg) { |
+ R runUnaryGuarded<R, T>(R f(T arg), T arg) { |
try { |
- runUnary(f, arg); |
+ return runUnary(f, arg); |
} catch (e, s) { |
- handleUncaughtError(e, s); |
+ return handleUncaughtError(e, s); |
} |
} |
- void runBinaryGuarded<T1, T2>(void f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
+ R runBinaryGuarded<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
try { |
- runBinary(f, arg1, arg2); |
+ return runBinary(f, arg1, arg2); |
} catch (e, s) { |
- handleUncaughtError(e, s); |
+ return handleUncaughtError(e, s); |
} |
} |
- ZoneCallback<R> bindCallback<R>(R f()) { |
+ ZoneCallback<R> bindCallback<R>(R f(), {bool runGuarded: true}) { |
var registered = registerCallback(f); |
- return () => this.run(registered); |
+ if (runGuarded) { |
+ return () => this.runGuarded(registered); |
+ } else { |
+ return () => this.run(registered); |
+ } |
} |
- ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg)) { |
+ ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg), |
+ {bool runGuarded: true}) { |
var registered = registerUnaryCallback(f); |
- return (arg) => this.runUnary(registered, arg); |
+ if (runGuarded) { |
+ return (arg) => this.runUnaryGuarded(registered, arg); |
+ } else { |
+ return (arg) => this.runUnary(registered, arg); |
+ } |
} |
ZoneBinaryCallback<R, T1, T2> bindBinaryCallback<R, T1, T2>( |
- R f(T1 arg1, T2 arg2)) { |
+ R f(T1 arg1, T2 arg2), |
+ {bool runGuarded: true}) { |
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); |
+ if (runGuarded) { |
+ return (arg1, arg2) => this.runBinaryGuarded(registered, arg1, arg2); |
+ } else { |
+ return (arg1, arg2) => this.runBinary(registered, arg1, arg2); |
+ } |
} |
operator [](Object key) { |
@@ -993,13 +971,15 @@ class _CustomZone extends _Zone { |
// Methods that can be customized by the zone specification. |
- void handleUncaughtError(error, StackTrace stackTrace) { |
+ R handleUncaughtError<R>(error, StackTrace stackTrace) { |
var implementation = this._handleUncaughtError; |
assert(implementation != null); |
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
HandleUncaughtErrorHandler handler = implementation.function; |
- return handler( |
- implementation.zone, parentDelegate, this, error, stackTrace); |
+ // 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*/; |
} |
Zone fork({ZoneSpecification specification, Map zoneValues}) { |
@@ -1016,7 +996,10 @@ class _CustomZone extends _Zone { |
assert(implementation != null); |
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
RunHandler handler = implementation.function; |
- return handler(implementation.zone, parentDelegate, this, f); |
+ // 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*/; |
} |
R runUnary<R, T>(R f(T arg), T arg) { |
@@ -1024,7 +1007,10 @@ class _CustomZone extends _Zone { |
assert(implementation != null); |
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
RunUnaryHandler handler = implementation.function; |
- return handler(implementation.zone, parentDelegate, this, f, arg); |
+ // 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*/; |
} |
R runBinary<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
@@ -1032,7 +1018,10 @@ class _CustomZone extends _Zone { |
assert(implementation != null); |
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
RunBinaryHandler handler = implementation.function; |
- return handler(implementation.zone, parentDelegate, this, f, arg1, arg2); |
+ // 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*/; |
} |
ZoneCallback<R> registerCallback<R>(R callback()) { |
@@ -1040,7 +1029,10 @@ class _CustomZone extends _Zone { |
assert(implementation != null); |
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
RegisterCallbackHandler handler = implementation.function; |
- return handler(implementation.zone, parentDelegate, this, callback); |
+ // 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>*/; |
} |
ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(R callback(T arg)) { |
@@ -1048,7 +1040,10 @@ class _CustomZone extends _Zone { |
assert(implementation != null); |
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
RegisterUnaryCallbackHandler handler = implementation.function; |
- return handler(implementation.zone, parentDelegate, this, callback); |
+ // 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>*/; |
} |
ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>( |
@@ -1057,7 +1052,10 @@ class _CustomZone extends _Zone { |
assert(implementation != null); |
ZoneDelegate parentDelegate = _parentDelegate(implementation.zone); |
RegisterBinaryCallbackHandler handler = implementation.function; |
- return handler(implementation.zone, parentDelegate, this, callback); |
+ // 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>*/; |
} |
AsyncError errorCallback(Object error, StackTrace stackTrace) { |
@@ -1103,7 +1101,7 @@ class _CustomZone extends _Zone { |
} |
} |
-void _rootHandleUncaughtError( |
+R _rootHandleUncaughtError<R>( |
Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace) { |
_schedulePriorityAsyncCallback(() { |
if (error == null) error = new NullThrownError(); |
@@ -1168,15 +1166,10 @@ AsyncError _rootErrorCallback(Zone self, ZoneDelegate parent, Zone zone, |
Object error, StackTrace stackTrace) => |
null; |
-void _rootScheduleMicrotask( |
- Zone self, ZoneDelegate parent, Zone zone, void f()) { |
+void _rootScheduleMicrotask(Zone self, ZoneDelegate parent, Zone zone, f()) { |
if (!identical(_ROOT_ZONE, zone)) { |
bool hasErrorHandler = !_ROOT_ZONE.inSameErrorZone(zone); |
- if (hasErrorHandler) { |
- f = zone.bindCallbackGuarded(f); |
- } else { |
- f = zone.bindCallback(f); |
- } |
+ f = zone.bindCallback(f, runGuarded: hasErrorHandler); |
// Use root zone as event zone if the function is already bound. |
zone = _ROOT_ZONE; |
} |
@@ -1297,74 +1290,72 @@ class _RootZone extends _Zone { |
// Zone interface. |
- void runGuarded(void f()) { |
+ R runGuarded<R>(R f()) { |
try { |
if (identical(_ROOT_ZONE, Zone._current)) { |
- f(); |
- return; |
+ return f(); |
} |
- _rootRun(null, null, this, f); |
+ return _rootRun<R>(null, null, this, f); |
} catch (e, s) { |
- handleUncaughtError(e, s); |
+ return handleUncaughtError<R>(e, s); |
} |
} |
- void runUnaryGuarded<T>(void f(T arg), T arg) { |
+ R runUnaryGuarded<R, T>(R f(T arg), T arg) { |
try { |
if (identical(_ROOT_ZONE, Zone._current)) { |
- f(arg); |
- return; |
+ return f(arg); |
} |
- _rootRunUnary(null, null, this, f, arg); |
+ return _rootRunUnary<R, T>(null, null, this, f, arg); |
} catch (e, s) { |
- handleUncaughtError(e, s); |
+ return handleUncaughtError<R>(e, s); |
} |
} |
- void runBinaryGuarded<T1, T2>(void f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
+ R runBinaryGuarded<R, T1, T2>(R f(T1 arg1, T2 arg2), T1 arg1, T2 arg2) { |
try { |
if (identical(_ROOT_ZONE, Zone._current)) { |
- f(arg1, arg2); |
- return; |
+ return f(arg1, arg2); |
} |
- _rootRunBinary(null, null, this, f, arg1, arg2); |
+ return _rootRunBinary<R, T1, T2>(null, null, this, f, arg1, arg2); |
} catch (e, s) { |
- handleUncaughtError(e, s); |
+ return handleUncaughtError<R>(e, s); |
} |
} |
- ZoneCallback<R> bindCallback<R>(R f()) { |
- return () => this.run<R>(f); |
+ ZoneCallback<R> bindCallback<R>(R f(), {bool runGuarded: true}) { |
+ if (runGuarded) { |
+ return () => this.runGuarded<R>(f); |
+ } else { |
+ return () => this.run<R>(f); |
+ } |
} |
- ZoneUnaryCallback<R, T> bindUnaryCallback<R, T>(R f(T arg)) { |
- return (arg) => this.runUnary<R, T>(f, arg); |
+ 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); |
+ } |
} |
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); |
+ 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); |
+ } |
} |
operator [](Object key) => null; |
// Methods that can be customized by the zone specification. |
- void handleUncaughtError(error, StackTrace stackTrace) { |
- _rootHandleUncaughtError(null, null, this, error, stackTrace); |
+ R handleUncaughtError<R>(error, StackTrace stackTrace) { |
+ return _rootHandleUncaughtError(null, null, this, error, stackTrace); |
} |
Zone fork({ZoneSpecification specification, Map zoneValues}) { |
@@ -1418,15 +1409,9 @@ 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. 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. |
+ * by the callback. |
* |
* 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. |
@@ -1448,29 +1433,21 @@ 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 { |
- if (onError is void Function(Object, StackTrace)) { |
- self.parent.runBinary(onError, error, stackTrace); |
- return; |
+ // TODO(floitsch): the return type should be 'void'. |
+ if (onError is ZoneBinaryCallback<dynamic, Object, StackTrace>) { |
+ return self.parent.runBinary(onError, error, stackTrace); |
} |
- assert(onError is void Function(Object)); |
- self.parent.runUnary(onError, error); |
+ return self.parent.runUnary(onError, error); |
} catch (e, s) { |
if (identical(e, error)) { |
- parent.handleUncaughtError(zone, error, stackTrace); |
+ return parent.handleUncaughtError(zone, error, stackTrace); |
} else { |
- parent.handleUncaughtError(zone, e, s); |
+ return parent.handleUncaughtError(zone, e, s); |
} |
} |
}; |
@@ -1485,17 +1462,7 @@ R runZoned<R>(R body(), |
Zone zone = Zone.current |
.fork(specification: zoneSpecification, zoneValues: zoneValues); |
if (onError != null) { |
- 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; |
- } |
+ return zone.runGuarded(body); |
} else { |
return zone.run(body); |
} |