Make Zone API strong mode clean.

Review-Url: https://codereview.chromium.org/2959163002 .
This commit is contained in:
Florian Loitsch 2017-06-28 13:16:35 +02:00
parent a6127e7361
commit 0b35711d48
43 changed files with 374 additions and 332 deletions

View file

@ -115,7 +115,7 @@ abstract class CompilerTask {
/// of other measuring zones, but we still need to call through the parent
/// chain. Consequently, we use a zone value keyed by [measurer] to see if
/// we should measure or not when delegating.
_run(Zone self, ZoneDelegate parent, Zone zone, f()) {
R _run<R>(Zone self, ZoneDelegate parent, Zone zone, R f()) {
if (zone[measurer] != this) return parent.run(zone, f);
CompilerTask previous = _start();
try {
@ -126,7 +126,8 @@ abstract class CompilerTask {
}
/// Same as [run] except that [f] takes one argument, [arg].
_runUnary(Zone self, ZoneDelegate parent, Zone zone, f(arg), arg) {
R _runUnary<R, T>(
Zone self, ZoneDelegate parent, Zone zone, R f(T arg), T arg) {
if (zone[measurer] != this) return parent.runUnary(zone, f, arg);
CompilerTask previous = _start();
try {
@ -137,7 +138,8 @@ abstract class CompilerTask {
}
/// Same as [run] except that [f] takes two arguments ([a1] and [a2]).
_runBinary(Zone self, ZoneDelegate parent, Zone zone, f(a1, a2), a1, a2) {
R _runBinary<R, T1, T2>(Zone self, ZoneDelegate parent, Zone zone,
R f(T1 a1, T2 a2), T1 a1, T2 a2) {
if (zone[measurer] != this) return parent.runBinary(zone, f, a1, a2);
CompilerTask previous = _start();
try {

View file

@ -519,7 +519,7 @@ abstract class Future<T> {
// context of all the previous iterations' callbacks.
// This avoids, e.g., deeply nested stack traces from the stack trace
// package.
nextIteration = Zone.current.bindUnaryCallback((bool keepGoing) {
nextIteration = Zone.current.bindUnaryCallbackGuarded((bool keepGoing) {
while (keepGoing) {
FutureOr<bool> result;
try {
@ -537,7 +537,7 @@ abstract class Future<T> {
keepGoing = result;
}
doneSignal._complete(null);
}, runGuarded: true);
});
nextIteration(true);
return doneSignal;
}

View file

@ -144,8 +144,7 @@ void scheduleMicrotask(void callback()) {
null, null, currentZone, currentZone.registerCallback(callback));
return;
}
Zone.current
.scheduleMicrotask(Zone.current.bindCallback(callback, runGuarded: true));
Zone.current.scheduleMicrotask(Zone.current.bindCallbackGuarded(callback));
}
class _AsyncRun {

View file

@ -332,7 +332,7 @@ class _BufferingStreamSubscription<T>
_checkState(wasInputPaused);
}
void _sendError(var error, StackTrace stackTrace) {
void _sendError(Object error, StackTrace stackTrace) {
assert(!_isCanceled);
assert(!_isPaused);
assert(!_inCallback);
@ -345,12 +345,11 @@ class _BufferingStreamSubscription<T>
_state |= _STATE_IN_CALLBACK;
// TODO(floitsch): this dynamic should be 'void'.
if (_onError is ZoneBinaryCallback<dynamic, Object, StackTrace>) {
ZoneBinaryCallback<dynamic, Object, StackTrace> errorCallback = _onError
as Object/*=ZoneBinaryCallback<dynamic, Object, StackTrace>*/;
ZoneBinaryCallback<dynamic, Object, StackTrace> errorCallback =
_onError;
_zone.runBinaryGuarded(errorCallback, error, stackTrace);
} else {
_zone.runUnaryGuarded<dynamic, Object>(
_onError as Object/*=ZoneUnaryCallback<dynamic, Object>*/, error);
_zone.runUnaryGuarded<Object>(_onError, error);
}
_state &= ~_STATE_IN_CALLBACK;
}

View file

@ -48,8 +48,8 @@ abstract class Timer {
// be invoked in the root zone.
return Zone.current.createTimer(duration, callback);
}
return Zone.current.createTimer(
duration, Zone.current.bindCallback(callback, runGuarded: true));
return Zone.current
.createTimer(duration, Zone.current.bindCallbackGuarded(callback));
}
/**
@ -74,10 +74,7 @@ abstract class Timer {
// be invoked in the root zone.
return Zone.current.createPeriodicTimer(duration, callback);
}
// TODO(floitsch): the return type should be 'void', and the type
// should be inferred.
var boundCallback = Zone.current
.bindUnaryCallback<dynamic, Timer>(callback, runGuarded: true);
var boundCallback = Zone.current.bindUnaryCallbackGuarded<Timer>(callback);
return Zone.current.createPeriodicTimer(duration, boundCallback);
}

View file

@ -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);
}

View file

@ -36968,7 +36968,7 @@ class Window extends EventTarget
@DomName('Window.requestAnimationFrame')
int requestAnimationFrame(FrameRequestCallback callback) {
_ensureRequestAnimationFrame();
return _requestAnimationFrame(_wrapZone/*<num, dynamic>*/(callback));
return _requestAnimationFrame(_wrapZone(callback));
}
/**
@ -42906,9 +42906,9 @@ class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
// TODO(leafp): It would be better to write this as
// _onData = onData == null ? null :
// onData is _wrapZoneCallback<Event, dynamic>
// ? _wrapZone/*<Event, dynamic>*/(onData)
// : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
// onData is void Function(Event)
// ? _wrapZone<Event>(onData)
// : _wrapZone<Event>((e) => onData(e as T))
// In order to support existing tests which pass the wrong type of events but
// use a more general listener, without causing as much slowdown for things
// which are typed correctly. But this currently runs afoul of restrictions
@ -42917,7 +42917,7 @@ class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
this._target, this._eventType, void onData(T event), this._useCapture)
: _onData = onData == null
? null
: _wrapZone<Event, dynamic>((e) => (onData as dynamic)(e)) {
: _wrapZone<Event>((e) => (onData as dynamic)(e)) {
_tryResume();
}
@ -42939,7 +42939,7 @@ class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
}
// Remove current event listener.
_unlisten();
_onData = _wrapZone/*<Event, dynamic>*/(handleData);
_onData = _wrapZone<Event>(handleData);
_tryResume();
}
@ -46314,24 +46314,18 @@ class _WrappedEvent implements Event {
// 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.
// TODO(jacobr): remove these typedefs when dart:async supports generic types.
typedef R _wrapZoneCallback<A, R>(A a);
typedef R _wrapZoneBinaryCallback<A, B, R>(A a, B b);
_wrapZoneCallback/*<A, R>*/ _wrapZone/*<A, R>*/(
_wrapZoneCallback/*<A, R>*/ callback) {
void Function(T) _wrapZone<T>(void Function(T) callback) {
// For performance reasons avoid wrapping if we are in the root zone.
if (Zone.current == Zone.ROOT) return callback;
if (callback == null) return null;
return Zone.current.bindUnaryCallback/*<R, A>*/(callback, runGuarded: true);
return Zone.current.bindUnaryCallbackGuarded(callback);
}
_wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(
_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
void Function(T1, T2) _wrapBinaryZone<T1, T2>(void Function(T1, T2) callback) {
// For performance reasons avoid wrapping if we are in the root zone.
if (Zone.current == Zone.ROOT) return callback;
if (callback == null) return null;
return Zone.current
.bindBinaryCallback/*<R, A, B>*/(callback, runGuarded: true);
return Zone.current.bindBinaryCallbackGuarded(callback);
}
/**

View file

@ -49043,9 +49043,9 @@ class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
// TODO(leafp): It would be better to write this as
// _onData = onData == null ? null :
// onData is _wrapZoneCallback<Event, dynamic>
// ? _wrapZone/*<Event, dynamic>*/(onData)
// : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
// onData is void Function(Event)
// ? _wrapZone<Event>(onData)
// : _wrapZone<Event>((e) => onData(e as T))
// In order to support existing tests which pass the wrong type of events but
// use a more general listener, without causing as much slowdown for things
// which are typed correctly. But this currently runs afoul of restrictions
@ -49054,7 +49054,7 @@ class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
this._target, this._eventType, void onData(T event), this._useCapture)
: _onData = onData == null
? null
: _wrapZone<Event, dynamic>((e) => (onData as dynamic)(e)) {
: _wrapZone<Event>((e) => (onData as dynamic)(e)) {
_tryResume();
}
@ -49076,7 +49076,7 @@ class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
}
// Remove current event listener.
_unlisten();
_onData = _wrapZone/*<Event, dynamic>*/(handleData);
_onData = _wrapZone<Event>(handleData);
_tryResume();
}
@ -52383,24 +52383,18 @@ class _WrappedEvent implements Event {
// 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.
// TODO(jacobr): remove these typedefs when dart:async supports generic types.
typedef R _wrapZoneCallback<A, R>(A a);
typedef R _wrapZoneBinaryCallback<A, B, R>(A a, B b);
_wrapZoneCallback/*<A, R>*/ _wrapZone/*<A, R>*/(
_wrapZoneCallback/*<A, R>*/ callback) {
void Function(T) _wrapZone<T>(void Function(T) callback) {
// For performance reasons avoid wrapping if we are in the root zone.
if (Zone.current == Zone.ROOT) return callback;
if (callback == null) return null;
return Zone.current.bindUnaryCallback/*<R, A>*/(callback, runGuarded: true);
return Zone.current.bindUnaryCallbackGuarded(callback);
}
_wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(
_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
void Function(T1, T2) _wrapBinaryZone<T1, T2>(void Function(T1, T2) callback) {
// For performance reasons avoid wrapping if we are in the root zone.
if (Zone.current == Zone.ROOT) return callback;
if (callback == null) return null;
return Zone.current
.bindBinaryCallback/*<R, A, B>*/(callback, runGuarded: true);
return Zone.current.bindBinaryCallbackGuarded(callback);
}
/**

View file

@ -18,13 +18,21 @@ Language/Statements/Assert/syntax_t04: Pass, Fail # assert now has an optional s
LibTest/typed_data/ByteData/buffer_A01_t01: Fail # co19 r736 bug - sent comment.
LibTest/core/RegExp/firstMatch_A01_t01: Fail # co19 issue 742
LibTest/async/Zone/bindBinaryCallback_A01_t02: Fail # co19 issue TODO
LibTest/async/Zone/bindCallback_A01_t02: Fail # co19 issue TODO
LibTest/async/Zone/bindUnaryCallback_A01_t02: Fail # co19 issue TODO
[ $compiler != dart2analyzer ]
# Tests that fail on every runtime, but not on the analyzer.
Language/Classes/same_name_type_variable_t04: Pass, MissingCompileTimeError, Fail # Issue 14513,25525
Language/Classes/same_name_type_variable_t07: Pass, MissingCompileTimeError, Fail # Issue 14513,25525
Language/Expressions/Instance_Creation/Const/abstract_class_t01: Pass, Fail # co19 issue 66
Language/Expressions/Instance_Creation/Const/abstract_class_t03: Pass, Fail # co19 issue 66
LibTest/async/Stream/asBroadcastStream_A02_t01: Fail # co19 issue 687
LibTest/async/Zone/runBinaryGuarded_A01_t01: Fail # co19 issue TODO
LibTest/async/Zone/runGuarded_A01_t01: Fail # co19 issue TODO
LibTest/async/Zone/runUnaryGuarded_A01_t01: Fail # co19 issue TODO
LibTest/core/Expando/Expando_A03_t01: RuntimeError # Issue 17735
LibTest/core/Expando/Expando_A03_t03: RuntimeError # Issue 17735
LibTest/core/Expando/Expando_A03_t04: RuntimeError # Issue 17735

View file

@ -94,7 +94,8 @@ increaseDepth() {
Expect.isTrue(depth < 20);
}
registerCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
ZoneCallback<R> registerCallback<R>(
Zone self, ZoneDelegate parent, Zone zone, R f()) {
var oldDepth = depth;
increaseDepth();
return parent.registerCallback(zone, () {
@ -103,7 +104,8 @@ registerCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
});
}
registerUnaryCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(
Zone self, ZoneDelegate parent, Zone zone, R f(T arg)) {
var oldDepth = depth;
increaseDepth();
return parent.registerUnaryCallback(zone, (x) {
@ -112,7 +114,8 @@ registerUnaryCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
});
}
registerBinaryCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>(
Zone self, ZoneDelegate parent, Zone zone, R f(T1 arg1, T2 arg2)) {
var oldDepth = depth;
increaseDepth();
return parent.registerBinaryCallback(zone, (x, y) {

View file

@ -155,7 +155,8 @@ main() {
return 42;
};
forked = Zone.current.fork(specification: new ZoneSpecification(
registerCallback: (Zone self, ZoneDelegate parent, Zone origin, f()) {
registerCallback:
<R>(Zone self, ZoneDelegate parent, Zone origin, R f()) {
if (!identical(f, callback)) return f;
registerCallDelta++; // Increment calls to register.
expect(origin, forked);

View file

@ -8,20 +8,19 @@ import 'package:async_helper/async_helper.dart';
main() {
asyncStart();
// Ensure that `runZoned`'s onError handles synchronous errors but delegates
// to the top-level when the handler returns false.
// Ensure that `runZoned`'s onError handles synchronous errors, and throwing
// in the error handler at that point (when it is a synchronous error) yields
// a synchronous error.
try {
runZoned(() {
throw 0;
}, onError: (e) {
Expect.equals(0, e);
if (false) //# 01: runtime error
throw e; //#01 : ok
asyncEnd();
throw e; //# 01: runtime error
});
} catch (e) {
// We should never see an error here.
if (false) //# 01: continued
asyncEnd(); return; //# 01: continued
rethrow;
}
}

View file

@ -24,13 +24,11 @@ main() {
Expect.equals(0, e);
Expect.isTrue(sawInnerHandler);
// If we are waiting for an error, don't asyncEnd, but let it time out.
if (false) //# 01: runtime error
throw e; //# 01: ok
asyncEnd();
throw e; // //# 01: continued
});
} catch (e) {
// We should never see an error here.
if (false) // //# 01: continued
asyncEnd(); return; //# 01: continued
rethrow;
}
}

View file

@ -64,27 +64,28 @@ void testStream(
registerExpect += 3;
Expect.equals(registerExpect, registerCount, name);
},
zoneSpecification:
new ZoneSpecification(registerCallback: (self, p, z, callback()) {
zoneSpecification: new ZoneSpecification(
registerCallback: <R>(self, p, z, R callback()) {
Expect.identical(zone, self, name);
registerCount++;
return () {
Expect.identical(zone, Zone.current, name);
callback();
return callback();
};
}, registerUnaryCallback: (self, p, z, callback(a)) {
}, registerUnaryCallback: <R, T>(self, p, z, R callback(T a)) {
Expect.identical(zone, self, name);
registerCount++;
return (a) {
Expect.identical(zone, Zone.current, name);
callback(a);
return callback(a);
};
}, registerBinaryCallback: (self, package, z, callback(a, b)) {
}, registerBinaryCallback:
<R, T1, T2>(self, package, z, R callback(T1 a, T2 b)) {
Expect.identical(zone, self, name);
registerCount++;
return (a, b) {
Expect.identical(zone, Zone.current, name);
callback(a, b);
return callback(a, b);
};
}));

View file

@ -14,7 +14,8 @@ main() {
Expect.identical(Zone.ROOT, Zone.current);
Zone forked = Zone.current.fork(specification: new ZoneSpecification(
registerCallback: (Zone self, ZoneDelegate parent, Zone origin, f()) {
registerCallback:
<R>(Zone self, ZoneDelegate parent, Zone origin, R f()) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.current, Zone.ROOT);
@ -31,7 +32,7 @@ main() {
Expect.identical(forked, Zone.current);
return 99;
};
var registered = forked.bindCallback(fun, runGuarded: false);
var registered = forked.bindCallback(fun);
Expect.isFalse(identical(fun, registered));
var result = registered();

View file

@ -15,7 +15,7 @@ main() {
Expect.identical(Zone.ROOT, Zone.current);
Zone forked = Zone.current.fork(specification: new ZoneSpecification(
registerUnaryCallback:
(Zone self, ZoneDelegate parent, Zone origin, f(arg)) {
<R, T>(Zone self, ZoneDelegate parent, Zone origin, R f(T arg)) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.current, Zone.ROOT);
@ -32,7 +32,7 @@ main() {
Expect.identical(forked, Zone.current);
return x + 99;
};
var bound = forked.bindUnaryCallback(fun, runGuarded: false);
var bound = forked.bindUnaryCallback(fun);
Expect.isFalse(identical(fun, bound));
// It is legal to invoke the callback in a different zone. This is, of course,

View file

@ -116,8 +116,8 @@ main() {
expectedDebugTrace = [fork3Trace, fork2Trace, globalTrace];
throw "gee";
});
}, runGuarded: false);
}, runGuarded: false);
});
});
openTests++;
f();
f2();

View file

@ -21,9 +21,9 @@ main() {
events.add("forked.fork");
Function descriptionRun = zoneSpecification.run;
ZoneSpecification modified = new ZoneSpecification.from(zoneSpecification,
run: (self, parent, origin, f) {
run: <R>(self, parent, origin, R f()) {
events.add("wrapped run");
return descriptionRun(self, parent, origin, () {
return descriptionRun<R>(self, parent, origin, () {
events.add("wrapped f");
return f();
});
@ -33,7 +33,7 @@ main() {
events.add("start");
Zone forkedChild = forked.fork(specification: new ZoneSpecification(
run: (Zone self, ZoneDelegate parent, Zone origin, f()) {
run: <R>(Zone self, ZoneDelegate parent, Zone origin, R f()) {
events.add("executing child run");
return parent.run(origin, f);
}));

View file

@ -14,7 +14,8 @@ main() {
Expect.identical(Zone.ROOT, Zone.current);
Zone forked = Zone.current.fork(specification: new ZoneSpecification(
registerCallback: (Zone self, ZoneDelegate parent, Zone origin, f()) {
registerCallback:
<R>(Zone self, ZoneDelegate parent, Zone origin, R f()) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.current, Zone.ROOT);

View file

@ -15,7 +15,7 @@ main() {
Expect.identical(Zone.ROOT, Zone.current);
Zone forked = Zone.current.fork(specification: new ZoneSpecification(
registerUnaryCallback:
(Zone self, ZoneDelegate parent, Zone origin, f(arg)) {
<R>(Zone self, ZoneDelegate parent, Zone origin, R f(arg)) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.current, Zone.ROOT);

View file

@ -11,7 +11,7 @@ main() {
Zone forked = Zone.current.fork();
var f = Zone.current.bindCallback(() {
Expect.identical(Zone.ROOT, Zone.current);
}, runGuarded: false);
});
forked.run(() {
f();
});

View file

@ -7,6 +7,8 @@ import 'package:async_helper/async_helper.dart';
import 'dart:async';
main() {
var result;
Completer done = new Completer();
List events = [];
@ -17,7 +19,7 @@ main() {
Zone forked;
forked = Zone.current.fork(
specification: new ZoneSpecification(
run: (Zone self, ZoneDelegate parent, Zone origin, f()) {
run: <R>(Zone self, ZoneDelegate parent, Zone origin, R f()) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.ROOT, Zone.current);
@ -28,19 +30,19 @@ main() {
Expect.identical(Zone.ROOT, Zone.current);
Expect.identical(forked, origin);
events.add("forked.handleUncaught $error");
return 499;
result = 499;
}));
var result = forked.runGuarded(() {
forked.runGuarded(() {
events.add("runGuarded 1");
Expect.identical(forked, Zone.current);
return 42;
result = 42;
});
Expect.identical(Zone.ROOT, Zone.current);
Expect.equals(42, result);
events.add("after runGuarded 1");
result = forked.runGuarded(() {
forked.runGuarded(() {
events.add("runGuarded 2");
Expect.identical(forked, Zone.current);
throw 42;
@ -56,9 +58,10 @@ main() {
"forked.handleUncaught 42"
], events);
result = null;
events.clear();
asyncStart();
result = forked.runGuarded(() {
forked.runGuarded(() {
Expect.identical(forked, Zone.current);
events.add("run closure");
forked.scheduleMicrotask(() {

View file

@ -13,13 +13,13 @@ main() {
bool shouldForward = true;
Expect.identical(Zone.ROOT, Zone.current);
Zone forked = Zone.current.fork(specification: new ZoneSpecification(
run: (Zone self, ZoneDelegate parent, Zone origin, f()) {
run: <R>(Zone self, ZoneDelegate parent, Zone origin, R f()) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.ROOT, Zone.current);
events.add("forked.run");
if (shouldForward) return parent.run(origin, f);
return 42;
return 42 as R;
}));
events.add("zone forked");

View file

@ -12,14 +12,17 @@ main() {
bool shouldForward = true;
Expect.identical(Zone.ROOT, Zone.current);
Zone forked = Zone.current.fork(specification: new ZoneSpecification(
runUnary: (Zone self, ZoneDelegate parent, Zone origin, f(arg), arg) {
Zone forked = Zone.current.fork(specification: new ZoneSpecification(runUnary:
<R, T>(Zone self, ZoneDelegate parent, Zone origin, R f(arg), T arg) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.current, Zone.ROOT);
events.add("forked.run1");
if (shouldForward) return parent.runUnary(origin, f, arg + 1);
return 42;
if (shouldForward) {
var nextArg = (arg as int) + 1;
return parent.runUnary(origin, f, nextArg as T);
}
return 42 as R;
}));
events.add("zone forked");

View file

@ -207,8 +207,8 @@ main() {
];
valueObjects.forEach((v) => checkInstance(reflect(v), 'value object'));
uncaughtErrorHandler(self, parent, zone, error, stack) {}
;
void uncaughtErrorHandler(self, parent, zone, error, stack) {}
var zoneSpec =
new ZoneSpecification(handleUncaughtError: uncaughtErrorHandler);
testZone = Zone.current.fork(specification: zoneSpec);

View file

@ -94,7 +94,8 @@ increaseDepth() {
Expect.isTrue(depth < 20);
}
registerCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
ZoneCallback<R> registerCallback<R>(
Zone self, ZoneDelegate parent, Zone zone, R f()) {
var oldDepth = depth;
increaseDepth();
return parent.registerCallback(zone, () {
@ -103,7 +104,8 @@ registerCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
});
}
registerUnaryCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
ZoneUnaryCallback<R, T> registerUnaryCallback<R, T>(
Zone self, ZoneDelegate parent, Zone zone, R f(T arg)) {
var oldDepth = depth;
increaseDepth();
return parent.registerUnaryCallback(zone, (x) {
@ -112,7 +114,8 @@ registerUnaryCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
});
}
registerBinaryCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
ZoneBinaryCallback<R, T1, T2> registerBinaryCallback<R, T1, T2>(
Zone self, ZoneDelegate parent, Zone zone, R f(T1 arg1, T2 arg2)) {
var oldDepth = depth;
increaseDepth();
return parent.registerBinaryCallback(zone, (x, y) {
@ -121,7 +124,7 @@ registerBinaryCallback(Zone self, ZoneDelegate parent, Zone zone, f) {
});
}
sm(Zone self, ZoneDelegate parent, Zone zone, f) {
void sm(Zone self, ZoneDelegate parent, Zone zone, f) {
var oldDepth = depth;
increaseDepth();
return parent.scheduleMicrotask(zone, () {

View file

@ -155,7 +155,8 @@ main() {
return 42;
};
forked = Zone.current.fork(specification: new ZoneSpecification(
registerCallback: (Zone self, ZoneDelegate parent, Zone origin, f()) {
registerCallback:
<R>(Zone self, ZoneDelegate parent, Zone origin, R f()) {
if (!identical(f, callback)) return f;
registerCallDelta++; // Increment calls to register.
expect(origin, forked);

View file

@ -64,27 +64,28 @@ void testStream(
registerExpect += 3;
Expect.equals(registerExpect, registerCount, name);
},
zoneSpecification:
new ZoneSpecification(registerCallback: (self, p, z, callback()) {
zoneSpecification: new ZoneSpecification(
registerCallback: <R>(self, p, z, R callback()) {
Expect.identical(zone, self, name);
registerCount++;
return () {
Expect.identical(zone, Zone.current, name);
callback();
return callback();
};
}, registerUnaryCallback: (self, p, z, callback(a)) {
}, registerUnaryCallback: <R, T>(self, p, z, R callback(T a)) {
Expect.identical(zone, self, name);
registerCount++;
return (a) {
Expect.identical(zone, Zone.current, name);
callback(a);
return callback(a);
};
}, registerBinaryCallback: (self, package, z, callback(a, b)) {
}, registerBinaryCallback:
<R, T1, T2>(self, package, z, R callback(T1 a, T2 b)) {
Expect.identical(zone, self, name);
registerCount++;
return (a, b) {
Expect.identical(zone, Zone.current, name);
callback(a, b);
return callback(a, b);
};
}));

View file

@ -14,7 +14,8 @@ main() {
Expect.identical(Zone.ROOT, Zone.current);
Zone forked = Zone.current.fork(specification: new ZoneSpecification(
registerCallback: (Zone self, ZoneDelegate parent, Zone origin, f()) {
registerCallback:
<R>(Zone self, ZoneDelegate parent, Zone origin, R f()) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.current, Zone.ROOT);
@ -31,7 +32,7 @@ main() {
Expect.identical(forked, Zone.current);
return 99;
};
var registered = forked.bindCallback(fun, runGuarded: false);
var registered = forked.bindCallback(fun);
Expect.isFalse(identical(fun, registered));
var result = registered();

View file

@ -15,7 +15,7 @@ main() {
Expect.identical(Zone.ROOT, Zone.current);
Zone forked = Zone.current.fork(specification: new ZoneSpecification(
registerUnaryCallback:
(Zone self, ZoneDelegate parent, Zone origin, f(arg)) {
<R, T>(Zone self, ZoneDelegate parent, Zone origin, R f(T arg)) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.current, Zone.ROOT);
@ -32,7 +32,7 @@ main() {
Expect.identical(forked, Zone.current);
return x + 99;
};
var bound = forked.bindUnaryCallback(fun, runGuarded: false);
var bound = forked.bindUnaryCallback(fun);
Expect.isFalse(identical(fun, bound));
// It is legal to invoke the callback in a different zone. This is, of course,

View file

@ -116,8 +116,8 @@ main() {
expectedDebugTrace = [fork3Trace, fork2Trace, globalTrace];
throw "gee";
});
}, runGuarded: false);
}, runGuarded: false);
});
});
openTests++;
f();
f2();

View file

@ -19,9 +19,9 @@ main() {
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.ROOT, Zone.current);
events.add("forked.fork");
Function descriptionRun = zoneSpecification.run;
var descriptionRun = zoneSpecification.run;
ZoneSpecification modified = new ZoneSpecification.from(zoneSpecification,
run: (self, parent, origin, f) {
run: <R>(self, parent, origin, R f()) {
events.add("wrapped run");
return descriptionRun(self, parent, origin, () {
events.add("wrapped f");
@ -33,7 +33,7 @@ main() {
events.add("start");
Zone forkedChild = forked.fork(specification: new ZoneSpecification(
run: (Zone self, ZoneDelegate parent, Zone origin, f()) {
run: <R>(Zone self, ZoneDelegate parent, Zone origin, R f()) {
events.add("executing child run");
return parent.run(origin, f);
}));

View file

@ -14,7 +14,8 @@ main() {
Expect.identical(Zone.ROOT, Zone.current);
Zone forked = Zone.current.fork(specification: new ZoneSpecification(
registerCallback: (Zone self, ZoneDelegate parent, Zone origin, f()) {
registerCallback:
<R>(Zone self, ZoneDelegate parent, Zone origin, R f()) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.current, Zone.ROOT);

View file

@ -15,7 +15,7 @@ main() {
Expect.identical(Zone.ROOT, Zone.current);
Zone forked = Zone.current.fork(specification: new ZoneSpecification(
registerUnaryCallback:
(Zone self, ZoneDelegate parent, Zone origin, f(arg)) {
<R, T>(Zone self, ZoneDelegate parent, Zone origin, R f(T arg)) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.current, Zone.ROOT);

View file

@ -11,7 +11,7 @@ main() {
Zone forked = Zone.current.fork();
var f = Zone.current.bindCallback(() {
Expect.identical(Zone.ROOT, Zone.current);
}, runGuarded: false);
});
forked.run(() {
f();
});

View file

@ -13,11 +13,13 @@ main() {
// runGuarded calls run, captures the synchronous error (if any) and
// gives that one to handleUncaughtError.
var result;
Expect.identical(Zone.ROOT, Zone.current);
Zone forked;
forked = Zone.current.fork(
specification: new ZoneSpecification(
run: (Zone self, ZoneDelegate parent, Zone origin, f()) {
run: <R>(Zone self, ZoneDelegate parent, Zone origin, R f()) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.ROOT, Zone.current);
@ -28,19 +30,20 @@ main() {
Expect.identical(Zone.ROOT, Zone.current);
Expect.identical(forked, origin);
events.add("forked.handleUncaught $error");
return 499;
result = 499;
}));
var result = forked.runGuarded(() {
forked.runGuarded(() {
events.add("runGuarded 1");
Expect.identical(forked, Zone.current);
return 42;
result = 42;
});
Expect.identical(Zone.ROOT, Zone.current);
Expect.equals(42, result);
events.add("after runGuarded 1");
result = forked.runGuarded(() {
result = null;
forked.runGuarded(() {
events.add("runGuarded 2");
Expect.identical(forked, Zone.current);
throw 42;
@ -56,9 +59,10 @@ main() {
"forked.handleUncaught 42"
], events);
result = null;
events.clear();
asyncStart();
result = forked.runGuarded(() {
forked.runGuarded(() {
Expect.identical(forked, Zone.current);
events.add("run closure");
forked.scheduleMicrotask(() {

View file

@ -13,13 +13,13 @@ main() {
bool shouldForward = true;
Expect.identical(Zone.ROOT, Zone.current);
Zone forked = Zone.current.fork(specification: new ZoneSpecification(
run: (Zone self, ZoneDelegate parent, Zone origin, f()) {
run: <R>(Zone self, ZoneDelegate parent, Zone origin, R f()) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.ROOT, Zone.current);
events.add("forked.run");
if (shouldForward) return parent.run(origin, f);
return 42;
return 42 as R;
}));
events.add("zone forked");

View file

@ -12,14 +12,14 @@ main() {
bool shouldForward = true;
Expect.identical(Zone.ROOT, Zone.current);
Zone forked = Zone.current.fork(specification: new ZoneSpecification(
runUnary: (Zone self, ZoneDelegate parent, Zone origin, f(arg), arg) {
Zone forked = Zone.current.fork(specification: new ZoneSpecification(runUnary:
<R, T>(Zone self, ZoneDelegate parent, Zone origin, R f(arg), T arg) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.current, Zone.ROOT);
events.add("forked.run1");
if (shouldForward) return parent.runUnary(origin, f, arg + 1);
return 42;
return 42 as R;
}));
events.add("zone forked");

View file

@ -190,8 +190,8 @@ main() {
];
valueObjects.forEach((v) => checkInstance(reflect(v), 'value object'));
uncaughtErrorHandler(self, parent, zone, error, stack) {}
;
void uncaughtErrorHandler(self, parent, zone, error, stack) {}
var zoneSpec =
new ZoneSpecification(handleUncaughtError: uncaughtErrorHandler);
testZone = Zone.current.fork(specification: zoneSpec);

View file

@ -225,9 +225,9 @@ class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
// TODO(leafp): It would be better to write this as
// _onData = onData == null ? null :
// onData is _wrapZoneCallback<Event, dynamic>
// ? _wrapZone/*<Event, dynamic>*/(onData)
// : _wrapZone/*<Event, dynamic>*/((e) => onData(e as T))
// onData is void Function(Event)
// ? _wrapZone<Event>(onData)
// : _wrapZone<Event>((e) => onData(e as T))
// In order to support existing tests which pass the wrong type of events but
// use a more general listener, without causing as much slowdown for things
// which are typed correctly. But this currently runs afoul of restrictions
@ -236,7 +236,7 @@ class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
this._target, this._eventType, void onData(T event), this._useCapture)
: _onData = onData == null
? null
: _wrapZone<Event, dynamic>((e) => (onData as dynamic)(e)) {
: _wrapZone<Event>((e) => (onData as dynamic)(e)) {
_tryResume();
}
@ -258,7 +258,7 @@ class _EventStreamSubscription<T extends Event> extends StreamSubscription<T> {
}
// Remove current event listener.
_unlisten();
_onData = _wrapZone/*<Event, dynamic>*/(handleData);
_onData = _wrapZone<Event>(handleData);
_tryResume();
}

View file

@ -4,24 +4,18 @@
part of dart.dom.html;
// TODO(jacobr): remove these typedefs when dart:async supports generic types.
typedef R _wrapZoneCallback<A, R>(A a);
typedef R _wrapZoneBinaryCallback<A, B, R>(A a, B b);
_wrapZoneCallback/*<A, R>*/ _wrapZone/*<A, R>*/(
_wrapZoneCallback/*<A, R>*/ callback) {
void Function(T) _wrapZone<T>(void Function(T) callback) {
// For performance reasons avoid wrapping if we are in the root zone.
if (Zone.current == Zone.ROOT) return callback;
if (callback == null) return null;
return Zone.current.bindUnaryCallback/*<R, A>*/(callback, runGuarded: true);
return Zone.current.bindUnaryCallbackGuarded(callback);
}
_wrapZoneBinaryCallback/*<A, B, R>*/ _wrapBinaryZone/*<A, B, R>*/(
_wrapZoneBinaryCallback/*<A, B, R>*/ callback) {
void Function(T1, T2) _wrapBinaryZone<T1, T2>(void Function(T1, T2) callback) {
// For performance reasons avoid wrapping if we are in the root zone.
if (Zone.current == Zone.ROOT) return callback;
if (callback == null) return null;
return Zone.current
.bindBinaryCallback/*<R, A, B>*/(callback, runGuarded: true);
return Zone.current.bindBinaryCallbackGuarded(callback);
}
/**

View file

@ -115,7 +115,7 @@ $if DART2JS
@DomName('Window.requestAnimationFrame')
int requestAnimationFrame(FrameRequestCallback callback) {
_ensureRequestAnimationFrame();
return _requestAnimationFrame(_wrapZone/*<num, dynamic>*/(callback));
return _requestAnimationFrame(_wrapZone(callback));
}
/**

View file

@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:io';
import 'dart:async';
Future<String> getVersion(var rootPath) {
var suffix = Platform.operatingSystem == 'windows' ? '.exe' : '';