Class ClassicCpsRewriterWithErrorPropagation
Expression tree rewriter that turns an expression into a Continuation Passing Style (CPS) expression using an Action<T> based callback method and an Action<Exception> callback for error propagation.
Inheritance
Inherited Members
Namespace: System.Linq.CompilerServices
Assembly: Nuqleon.Linq.CompilerServices.dll
Syntax
public sealed class ClassicCpsRewriterWithErrorPropagation : CpsRewriterBase<SuccessErrorContinuationPair>
Examples
Examples are provided on the various methods, assuming the following methods are defined:
[UseAsyncMethod]
int Div(int a, int b)
{
return a / b;
}
void Div(int a, int b, Action<int> success, Action<Exception> error)
{
if (b == 0)
error(new DivisionByZeroException());
success(a / b);
}
Constructors
ClassicCpsRewriterWithErrorPropagation()
Declaration
public ClassicCpsRewriterWithErrorPropagation()
Methods
GetContinuationParameters(MethodInfo)
Gets the continuation parameter types that are used during method overload resolution by appending those to the parameters type of the synchronous method.
Declaration
protected override IEnumerable<Type> GetContinuationParameters(MethodInfo method)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Reflection.MethodInfo | method | Method to find continuation parameters for, e.g. by inspecting its return type and creating the corresponding callback parameter type. |
Returns
| Type | Description |
|---|---|
| System.Collections.Generic.IEnumerable<System.Type> | Continuation parameter types to check for when searching for an asynchronous method overload. |
Overrides
InvokeContinuation(SuccessErrorContinuationPair, Expression)
Creates an invocation of the given continuation.
Declaration
protected override Expression InvokeContinuation(SuccessErrorContinuationPair continuation, Expression argument)
Parameters
| Type | Name | Description |
|---|---|---|
| SuccessErrorContinuationPair | continuation | Continuation to invoke. |
| System.Linq.Expressions.Expression | argument | Argument to pass to the continuation's invocation. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.Expression | Expression representing the invocation of the continuation. |
Overrides
MakeAsyncMethodCall(Expression, MethodInfo, IEnumerable<Expression>, SuccessErrorContinuationPair)
Creates an asynchronous method call with the given continuation.
Declaration
protected override Expression MakeAsyncMethodCall(Expression instance, MethodInfo method, IEnumerable<Expression> arguments, SuccessErrorContinuationPair continuation)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression | instance | Instance of the method call. |
| System.Reflection.MethodInfo | method | Method to call. |
| System.Collections.Generic.IEnumerable<System.Linq.Expressions.Expression> | arguments | Arguments of the method call. |
| SuccessErrorContinuationPair | continuation | Continuation to supply to the asynchronous method. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.Expression | Expression representing an asynchronous method call with the given continuation. |
Overrides
MakeContinuation(Expression, ParameterExpression, SuccessErrorContinuationPair)
Creates a new continuation with the given result parameter to run the specified remainder computation.
Declaration
protected override SuccessErrorContinuationPair MakeContinuation(Expression remainder, ParameterExpression resultParameter, SuccessErrorContinuationPair currentContinuation)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression | remainder | Remainder of the expression to evaluate upon invocation of the continuation. |
| System.Linq.Expressions.ParameterExpression | resultParameter | Parameter with the result of the expression evaluation preceding the invocation of the continuation. |
| SuccessErrorContinuationPair | currentContinuation | Current continuation being processed upon requesting a new continuation. |
Returns
| Type | Description |
|---|---|
| SuccessErrorContinuationPair | Continuation object that will execute the remainder computation, given the specified result parameter. |
Overrides
Rewrite(Expression)
Rewrites the given expression to a lambda expression that accepts success and failure callbacks and executes the expression using CPS.
Declaration
public LambdaExpression Rewrite(Expression expression)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression | expression | Expression to rewrite. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.LambdaExpression | Lambda expression that, given a success callback and a failure callback, will execute the expression using CPS. |
Examples
This method will rewrite the following expression:
Div(1, Div(Div(2, 3), 4))
into:
(success, error) => Div(2, 3, x0 => Div(x0, 4, x1 => Div(1, x1, success, error), error), error)
Evaluation order of side-effects is preserved. The following expression:
Div(Foo(1), Div(Div(2, 3), 4))
will be rewritten into:
(success, error) => Invoke(x0 => Div(2, 3, x1 => Div(x1, 4, x2 => Div(x0, x2, success, error), error), error), Foo(1))
Rewrite(Expression, Expression, Expression)
Rewrites the given expression to a CPS expression using the specified callbacks.
Declaration
public Expression Rewrite(Expression expression, Expression success, Expression failure)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression | expression | Expression to rewrite. |
| System.Linq.Expressions.Expression | success | Continuation to call upon success. |
| System.Linq.Expressions.Expression | failure | Continuation to call upon failure. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.Expression | Rewritten expression using CPS. |
Examples
This method will rewrite the following expression:
Div(1, Div(Div(2, 3), 4))
into:
Div(2, 3, x0 => Div(x0, 4, x1 => Div(1, x1, success, failure), failure), failure)
Evaluation order of side-effects is preserved. The following expression:
Div(Foo(1), Div(Div(2, 3), 4))
will be rewritten into:
Invoke(x0 => Div(2, 3, x1 => Div(x1, 4, x2 => Div(x0, x2, callback, failure), failure), failure), Foo(1))
Rewrite(Expression<Action>)
Rewrites the given expression to a lambda expression that accepts success and failure callbacks and executes the expression using CPS.
Declaration
public Expression<Action<Action, Action<Exception>>> Rewrite(Expression<Action> expression)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression<System.Action> | expression | Expression to rewrite. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.Expression<System.Action<System.Action, System.Action<System.Exception>>> | Lambda expression that, given a success callback and a failure callback, will execute the expression using CPS. |
Examples
This method will rewrite the following expression:
() => Bar(1, 2, 3)
into:
(success, error) => Bar(1, 2, 3, success, error)
Evaluation order of side-effects is preserved. The following expression:
() => Bar(Foo(1), 2, 3)
will be rewritten into:
(success, error) => Invoke(x0 => Bar(x0, 2, 3, callback, error), Foo(1))
Rewrite(Expression<Action>, Expression<Action>, Expression<Action<Exception>>)
Rewrites the given expression to a CPS expression using the specified callbacks.
Declaration
public Expression Rewrite(Expression<Action> expression, Expression<Action> success, Expression<Action<Exception>> failure)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression<System.Action> | expression | Lambda expression whose body to rewrite. |
| System.Linq.Expressions.Expression<System.Action> | success | Continuation to call upon success. |
| System.Linq.Expressions.Expression<System.Action<System.Exception>> | failure | Continuation to call upon failure. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.Expression | Rewritten expression using CPS. |
Examples
This method will rewrite the following expression:
() => Bar(1, 2, 3)
into:
Bar(success, failure)
Evaluation order of side-effects is preserved. The following expression:
() => Bar(Foo(1), 2, 3)
will be rewritten into:
Invoke(x0 => Bar(x0, 2, 3, success, failure), Foo(1))
Rewrite(LambdaExpression)
Rewrites the given expression to a lambda expression that accepts success and failure callbacks and executes the expression using CPS.
Declaration
public LambdaExpression Rewrite(LambdaExpression expression)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.LambdaExpression | expression | Expression to rewrite. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.LambdaExpression | Lambda expression that, given a success callback and a failure callback, will execute the expression using CPS. |
Examples
This method will rewrite the following expression:
(a, b, c, d) => Div(a, Div(Div(b, c), d))
into:
(a, b, c, d, success, error) => Div(b, c, x0 => Div(x0, d, x1 => Div(a, x1, success, error), error), error)
Evaluation order of side-effects is preserved. The following expression:
(a, b, c, d) => Div(Foo(a), Div(Div(b, c), d))
will be rewritten into:
(a, b, c, d, success, error) => Invoke(x0 => Div(b, c, x1 => Div(x1, d, x2 => Div(x0, x2, success, error), error), error), Foo(a))
Rewrite<T>(Expression<Action<T>>)
Rewrites the given expression to a lambda expression that accepts success and failure callbacks and executes the expression using CPS.
Declaration
public Expression<Action<T, Action, Action<Exception>>> Rewrite<T>(Expression<Action<T>> expression)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression<System.Action<T>> | expression | Expression to rewrite. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.Expression<System.Action<T, System.Action, System.Action<System.Exception>>> | Lambda expression that, given a callback, will execute the expression using CPS. |
Type Parameters
| Name | Description |
|---|---|
| T | Type of the parameter passed to the computation. |
Examples
This method will rewrite the following expression:
x => Bar(x, 2, 3)
into:
(x, success, failure) => Bar(x, 2, 3, success, failure)
Evaluation order of side-effects is preserved. The following expression:
x => Bar(Foo(x), 2, 3)
will be rewritten into:
(x, success, failure) => Invoke(x0 => Bar(x0, 2, 3, success, failure), Foo(x))
Rewrite<TResult>(Expression<Func<TResult>>)
Rewrites the given expression to a lambda expression that accepts success and failure callbacks and executes the expression using CPS.
Declaration
public Expression<Action<Action<TResult>, Action<Exception>>> Rewrite<TResult>(Expression<Func<TResult>> expression)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression<System.Func<TResult>> | expression | Expression to rewrite. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.Expression<System.Action<System.Action<TResult>, System.Action<System.Exception>>> | Lambda expression that, given a success callback and a failure callback, will execute the expression using CPS. |
Type Parameters
| Name | Description |
|---|---|
| TResult | Type of the result produced by the expression. |
Examples
This method will rewrite the following expression:
() => Div(1, Div(Div(2, 3), 4))
into:
(success, error) => Div(2, 3, x0 => Div(x0, 4, x1 => Div(1, x1, success, error), error), error)
Evaluation order of side-effects is preserved. The following expression:
() => Div(Foo(1), Div(Div(2, 3), 4))
will be rewritten into:
(success, error) => Invoke(x0 => Div(2, 3, x1 => Div(x1, 4, x2 => Div(x0, x2, callback, error), error), error), Foo(1))
Rewrite<TResult>(Expression<Func<TResult>>, Expression<Action<TResult>>, Expression<Action<Exception>>)
Rewrites the given expression to a CPS expression using the specified callbacks.
Declaration
public Expression Rewrite<TResult>(Expression<Func<TResult>> expression, Expression<Action<TResult>> success, Expression<Action<Exception>> failure)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression<System.Func<TResult>> | expression | Lambda expression whose body to rewrite. |
| System.Linq.Expressions.Expression<System.Action<TResult>> | success | Continuation to call upon success. |
| System.Linq.Expressions.Expression<System.Action<System.Exception>> | failure | Continuation to call upon failure. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.Expression | Rewritten expression using CPS. |
Type Parameters
| Name | Description |
|---|---|
| TResult | Type of the result produced by the expression. |
Examples
This method will rewrite the following expression:
() => Div(1, Div(Div(2, 3), 4))
into:
Div(2, 3, x0 => Div(x0, 4, x1 => Div(1, x1, success, failure), failure), failure)
Evaluation order of side-effects is preserved. The following expression:
() => Div(Foo(1), Div(Div(2, 3), 4))
will be rewritten into:
Invoke(x0 => Div(2, 3, x1 => Div(x1, 4, x2 => Div(x0, x2, success, failure), failure), failure), Foo(1))
Rewrite<T1, T2>(Expression<Action<T1, T2>>)
Rewrites the given expression to a lambda expression that accepts success and failure callbacks and executes the expression using CPS.
Declaration
public Expression<Action<T1, T2, Action, Action<Exception>>> Rewrite<T1, T2>(Expression<Action<T1, T2>> expression)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression<System.Action<T1, T2>> | expression | Expression to rewrite. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.Expression<System.Action<T1, T2, System.Action, System.Action<System.Exception>>> | Lambda expression that, given a callback, will execute the expression using CPS. |
Type Parameters
| Name | Description |
|---|---|
| T1 | Type of the first parameter passed to the computation. |
| T2 | Type of the second parameter passed to the computation. |
Examples
This method will rewrite the following expression:
(x, y) => Bar(x, y, 3)
into:
(x, y, success, failure) => Bar(x, y, 3, success, failure)
Evaluation order of side-effects is preserved. The following expression:
(x, y) => Bar(Foo(x), y, 3)
will be rewritten into:
(x, y, success, failure) => Invoke(x0 => Bar(x0, y, 3, success, failure), Foo(x))
Rewrite<T, TResult>(Expression<Func<T, TResult>>)
Rewrites the given expression to a lambda expression that accepts success and failure callbacks and executes the expression using CPS.
Declaration
public Expression<Action<T, Action<TResult>, Action<Exception>>> Rewrite<T, TResult>(Expression<Func<T, TResult>> expression)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression<System.Func<T, TResult>> | expression | Expression to rewrite. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.Expression<System.Action<T, System.Action<TResult>, System.Action<System.Exception>>> | Lambda expression that, given a callback, will execute the expression using CPS. |
Type Parameters
| Name | Description |
|---|---|
| T | Type of the parameter passed to the computation. |
| TResult | Type of the result produced by the expression. |
Examples
This method will rewrite the following expression:
x => Add(1, Add(Add(2, x), 4))
into:
(x, success, failure) => Add(2, x, x0 => Add(x0, 4, x1 => Add(1, x1, success, failure), failure), failure)
Evaluation order of side-effects is preserved. The following expression:
x => Add(Foo(1), Add(Add(2, x), 4))
will be rewritten into:
(x, success, failure) => Invoke(x0 => Add(2, x, x1 => Add(x1, 4, x2 => Add(x0, x2, success, failure), failure), failure), Foo(1))
Rewrite<T1, T2, T3>(Expression<Action<T1, T2, T3>>)
Rewrites the given expression to a lambda expression that accepts success and failure callbacks and executes the expression using CPS.
Declaration
public Expression<Action<T1, T2, T3, Action, Action<Exception>>> Rewrite<T1, T2, T3>(Expression<Action<T1, T2, T3>> expression)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression<System.Action<T1, T2, T3>> | expression | Expression to rewrite. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.Expression<System.Action<T1, T2, T3, System.Action, System.Action<System.Exception>>> | Lambda expression that, given a callback, will execute the expression using CPS. |
Type Parameters
| Name | Description |
|---|---|
| T1 | Type of the first parameter passed to the computation. |
| T2 | Type of the second parameter passed to the computation. |
| T3 | Type of the third parameter passed to the computation. |
Examples
This method will rewrite the following expression:
(x, y, z) => Bar(x, y, z)
into:
(x, y, z, success, failure) => Bar(x, y, z, success, failure)
Evaluation order of side-effects is preserved. The following expression:
(x, y, z) => Bar(Foo(x), y, z)
will be rewritten into:
(x, y, z, success, failure) => Invoke(x0 => Bar(x0, y, z, success, failure), Foo(x))
Rewrite<T1, T2, TResult>(Expression<Func<T1, T2, TResult>>)
Rewrites the given expression to a lambda expression that accepts success and failure callbacks and executes the expression using CPS.
Declaration
public Expression<Action<T1, T2, Action<TResult>, Action<Exception>>> Rewrite<T1, T2, TResult>(Expression<Func<T1, T2, TResult>> expression)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression<System.Func<T1, T2, TResult>> | expression | Expression to rewrite. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.Expression<System.Action<T1, T2, System.Action<TResult>, System.Action<System.Exception>>> | Lambda expression that, given a callback, will execute the expression using CPS. |
Type Parameters
| Name | Description |
|---|---|
| T1 | Type of the first parameter passed to the computation. |
| T2 | Type of the second parameter passed to the computation. |
| TResult | Type of the result produced by the expression. |
Examples
This method will rewrite the following expression:
(x, y) => Add(1, Add(Add(2, x), y))
into:
(x, y, success, failure) => Add(2, x, x0 => Add(x0, y, x1 => Add(1, x1, success, failure), failure), failure)
Evaluation order of side-effects is preserved. The following expression:
(x, y) => Add(Foo(1), Add(Add(2, x), y))
will be rewritten into:
(x, y, success, failure) => Invoke(x0 => Add(2, x, x1 => Add(x1, y, x2 => Add(x0, x2, success, failure), failure), failure), Foo(1))
Rewrite<T1, T2, T3, TResult>(Expression<Func<T1, T2, T3, TResult>>)
Rewrites the given expression to a lambda expression that accepts success and failure callbacks and executes the expression using CPS.
Declaration
public Expression<Action<T1, T2, T3, Action<TResult>, Action<Exception>>> Rewrite<T1, T2, T3, TResult>(Expression<Func<T1, T2, T3, TResult>> expression)
Parameters
| Type | Name | Description |
|---|---|---|
| System.Linq.Expressions.Expression<System.Func<T1, T2, T3, TResult>> | expression | Expression to rewrite. |
Returns
| Type | Description |
|---|---|
| System.Linq.Expressions.Expression<System.Action<T1, T2, T3, System.Action<TResult>, System.Action<System.Exception>>> | Lambda expression that, given a callback, will execute the expression using CPS. |
Type Parameters
| Name | Description |
|---|---|
| T1 | Type of the first parameter passed to the computation. |
| T2 | Type of the second parameter passed to the computation. |
| T3 | Type of the third parameter passed to the computation. |
| TResult | Type of the result produced by the expression. |
Examples
This method will rewrite the following expression:
(x, y, z) => Add(x, Add(Add(2, y), z))
into:
(x, y, z, success, failure) => Add(2, y, x0 => Add(x0, z, x1 => Add(x, x1, success, failure), failure), failure)
Evaluation order of side-effects is preserved. The following expression:
(x, y, z) => Add(Foo(x), Add(Add(2, y), z))
will be rewritten into:
(x, y, z, success, failure) => Invoke(x0 => Add(2, y, x1 => Add(x1, z, x2 => Add(x0, x2, success, failure), failure), failure), Foo(x))