Catch() public static method

Creates a CatchBlock representing a catch statement with a reference to the caught object for use in the handler body.
public static Catch ( System.Linq.Expressions.ParameterExpression variable, Expression body ) : CatchBlock
variable System.Linq.Expressions.ParameterExpression A representing a reference to the object caught by this handler.
body Expression The body of the catch statement.
return CatchBlock
コード例 #1
0
        public EvaluationCallback Create(Node node)
        {
            var compilerstate = new CompilerState
            {
                FunctionState = Exp.Parameter(typeof(Character), "state"),
                ErrorVariable = Exp.Parameter(typeof(bool), "error")
            };
            var result = Make(compilerstate, node);

            if (result.Type == typeof(bool))
            {
                result = ToInteger(result);
            }
            if (result.Type == typeof(int) || result.Type == typeof(float))
            {
                // int or float convert to number
                var constructor = typeof(Number).GetConstructor(new[] { result.Type });
                result = Exp.New(constructor, new[] { result });

                // wrap the evaluation in a try..catch
                var exceptionParameter = Exp.Parameter(typeof(Exception), "e");
                var writeLineMethod    = typeof(Console).GetMethod(nameof(Console.WriteLine), new Type[] { typeof(string) });
                var toStringMethod     = typeof(Exception).GetMethod(nameof(Exception.ToString));
                var catchBody          = Exp.Block(
                    Exp.Call(null, writeLineMethod, Exp.Call(exceptionParameter, toStringMethod)),
                    Exp.Constant(new Number(0)));
                result = Exp.TryCatch(result, Exp.Catch(exceptionParameter, catchBody));
                // create lambda
                var func = Exp.Lambda <Func <Character, bool, Number> >(result, compilerstate.FunctionState, compilerstate.ErrorVariable).Compile();
                return(new EvaluationCallback(o => func(o, false)));
            }
            throw new Exception();
        }
コード例 #2
0
        public void TryCatchTypeBody()
        {
            var expected = LinqExpression.TryCatch(
                LinqExpression.Constant(0L),
                LinqExpression.Catch(
                    typeof(Exception),
                    LinqExpression.Constant(0L)));

            using var g = new GraphEngine.Graph();
            g.LoadFromString(@"
@prefix : <http://example.com/> .

:s
    :tryBody _:zero ;
    :tryHandlers (
        [
            :catchType [
                :typeName ""System.Exception"" ;
            ] ;
            :catchBody _:zero ;
        ]
    ) ;
.
_:zero
    :constantValue 0 ;
.
");
            var s = g.GetUriNode(":s");

            var actual = Expression.Parse(s).LinqExpression;

            Console.WriteLine(actual.GetDebugView());

            actual.Should().Be(expected);
        }
コード例 #3
0
        public LambdaExpression CreateLambda(Type from, Type to)
        {
            var input     = Ex.Parameter(from, "input");
            var convert   = ConvertMethod(from, to);
            var exception = Ex.Parameter(typeof(Exception), "exception");
            var block     = Ex.TryCatch(
                Result(to, Ex.Call(convert, convert.GetParameters().Select(pi => getParameter(pi, input)))),
                Ex.Catch(exception, NoResult(to)));
            var lambda = Ex.Lambda(block, input);

            return(lambda);
        }
コード例 #4
0
        public void TryCatchVariableBodyFilter()
        {
            var expected = LinqExpression.TryCatch(
                LinqExpression.Constant(0L),
                LinqExpression.Catch(
                    LinqExpression.Parameter(
                        typeof(Exception)),
                    LinqExpression.Constant(0L),
                    LinqExpression.Equal(
                        LinqExpression.Constant(0L),
                        LinqExpression.Constant(0L))));

            using var g = new GraphEngine.Graph();
            g.LoadFromString(@"
@prefix : <http://example.com/> .
@prefix xt: <http://example.com/ExpressionTypes/> .

:s
    :tryBody _:zero ;
    :tryHandlers (
        [
            :catchVariable [
                :parameterType [
                    :typeName ""System.Exception"" ;
                ] ;
            ] ;
            :catchBody _:zero ;
            :catchFilter [
                :binaryExpressionType xt:Equal ;
                :binaryLeft _:zero ;
                :binaryRight _:zero ;
            ] ;
        ]
    ) ;
.
_:zero
    :constantValue 0 ;
.
");
            var s = g.GetUriNode(":s");

            var actual = Expression.Parse(s).LinqExpression;

            Console.WriteLine(actual.GetDebugView());

            actual.Should().Be(expected);
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: dayanruben/TigerConverters
        public static Expression <Func <string[], int> > WrapMain(Expression program)
        {
            LabelTarget label = Expression.Label(typeof(int));

            BlockExpression programReturningNoErrorCode = Expression.Block(program, Expression.Constant(0));

            Expression <Action <Exception> > writeLine = s => Console.Error.WriteLine(s);

            ParameterExpression exitException = Expression.Variable(typeof(ExitException));
            ParameterExpression exception     = Expression.Variable(typeof(Exception));

            TryExpression programCatchingExceptions = Expression.TryCatch(programReturningNoErrorCode,
                                                                          Expression.Catch(exitException, Expression.Property(exitException, "Code")),
                                                                          Expression.Catch(exception, Expression.Block(writeLine.eInvoke(exception), Expression.Constant(1))));

            LabelExpression returnLabel = Expression.Label(label, programCatchingExceptions);

            ParameterExpression parameter             = Expression.Parameter(typeof(string[]), "args");
            Expression <Func <string[], int> > lambda = Expression.Lambda <Func <string[], int> >(returnLabel, parameter);

            return(lambda);
        }
コード例 #6
0
ファイル: Program.cs プロジェクト: xanatos/ExpressionFutures
        static void Main()
        {
            var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("bar"), AssemblyBuilderAccess.Save);
            var mod = asm.DefineDynamicModule("bar.dll");
            var typ = mod.DefineType("Foo");

            var lblRet = Expression.Label(typeof(int));
            var lbl1   = Expression.Label(typeof(int));
            var ex     = Expression.Parameter(typeof(Exception));

            var expressions = new Expression[]
            {
                Expression.TryFault(
                    Expression.Constant(1),
                    Expression.Constant(2)
                    ),
                Expression.Block(
                    Expression.TryFault(
                        Expression.Goto(lblRet, Expression.Constant(1)),
                        Expression.Constant(2)
                        ),
                    Expression.Label(lblRet, Expression.Constant(0))
                    ),
                Expression.Block(
                    Expression.TryFault(
                        Expression.Block(
                            Expression.Goto(lblRet, Expression.Constant(1)),
                            Expression.Constant(2)
                            ),
                        Expression.Constant(3)
                        ),
                    Expression.Label(lblRet, Expression.Constant(0))
                    ),
                Expression.Block(
                    Expression.TryFault(
                        Expression.Block(
                            Expression.Goto(lbl1, Expression.Constant(1)),
                            Expression.Goto(lblRet, Expression.Constant(2))
                            ),
                        Expression.Constant(3)
                        ),
                    Expression.Label(lbl1, Expression.Constant(-1)),
                    Expression.Label(lblRet, Expression.Constant(0))
                    ),
                Expression.TryCatch(
                    Expression.Constant(1),
                    Expression.Catch(ex, Expression.Constant(2), Expression.Constant(true))
                    ),
            };

            var i = 0;

            foreach (var expression in expressions)
            {
                var mtd = typ.DefineMethod("M" + i, MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[0]);
                Expression.Lambda <Func <int> >(expression).CompileToMethod(mtd);

                var cw = Expression.Lambda <Func <int> >(expression).CompileWithExceptionHandling();
                cw();

                i++;
            }
        }
コード例 #7
0
        public void MiscellaneousExpression_Try()
        {
            var tryCatch = Expr.TryCatch(Expr.Constant(false), Expr.Catch(typeof(Exception), Expr.Constant(false)));

            UnsupportedExpr(Property.Id, id => tryCatch, ExpressionType.Try);
        }
コード例 #8
0
        static LambdaExpression ApplyMethodHandler(string functionName, LambdaExpression functionLambda, IFunctionExecutionHandler handler)
        {
            // public static int MyMethod(object arg0, int arg1) { ... }

            // becomes:

            // (the 'handler' object is captured and called mh)
            // public static int MyMethodWrapped(object arg0, int arg1)
            // {
            //    var fhArgs = new FunctionExecutionArgs("MyMethod", new object[] { arg0, arg1});
            //    int result = default(int);
            //    try
            //    {
            //        fh.OnEntry(fhArgs);
            //        if (fhArgs.FlowBehavior == FlowBehavior.Return)
            //        {
            //            result = (int)fhArgs.ReturnValue;
            //        }
            //        else
            //        {
            //             // Inner call
            //             result = MyMethod(arg0, arg1);
            //             fhArgs.ReturnValue = result;
            //             fh.OnSuccess(fhArgs);
            //             result = (int)fhArgs.ReturnValue;
            //        }
            //    }
            //    catch ( Exception ex )
            //    {
            //        fhArgs.Exception = ex;
            //        fh.OnException(fhArgs);
            //        // Makes no sense to me yet - I've removed this FlowBehavior enum value.
            //        // if (fhArgs.FlowBehavior == FlowBehavior.Continue)
            //        // {
            //        //     // Finally will run, but can't change return value
            //        //     // Should we assign result...?
            //        //     // So Default value will be returned....?????
            //        //     fhArgs.Exception = null;
            //        // }
            //        // else
            //        if (fhArgs.FlowBehavior == FlowBehavior.Return)
            //        {
            //            // Clear the Exception and return the ReturnValue instead
            //            // Finally will run, but can't further change return value
            //            fhArgs.Exception = null;
            //            result = (int)fhArgs.ReturnValue;
            //        }
            //        else if (fhArgs.FlowBehavior == FlowBehavior.ThrowException)
            //        {
            //            throw fhArgs.Exception;
            //        }
            //        else // if (fhArgs.FlowBehavior == FlowBehavior.Default || fhArgs.FlowBehavior == FlowBehavior.RethrowException)
            //        {
            //            throw;
            //        }
            //    }
            //    finally
            //    {
            //        fh.OnExit(fhArgs);
            //        // NOTE: fhArgs.ReturnValue is not used again here...!
            //    }
            //
            //    return result;
            //  }
            // }

            // CONSIDER: There are some helpers in .NET to capture the exception context, which would allow us to preserve the stack trace in a fresh throw.

            // Ensure the handler object is captured.
            var mh       = Expression.Constant(handler);
            var funcName = Expression.Constant(functionName);

            // Prepare the functionHandlerArgs that will be threaded through the handler,
            // and a bunch of expressions that access various properties on it.
            var fhArgs              = Expr.Variable(typeof(FunctionExecutionArgs), "fhArgs");
            var fhArgsReturnValue   = SymbolExtensions.GetProperty(fhArgs, (FunctionExecutionArgs mea) => mea.ReturnValue);
            var fhArgsException     = SymbolExtensions.GetProperty(fhArgs, (FunctionExecutionArgs mea) => mea.Exception);
            var fhArgsFlowBehaviour = SymbolExtensions.GetProperty(fhArgs, (FunctionExecutionArgs mea) => mea.FlowBehavior);

            // Set up expressions to call the various handler methods.
            // TODO: Later we can determine which of these are actually implemented, and only write out the code needed in the particular case.
            var onEntry     = Expr.Call(mh, SymbolExtensions.GetMethodInfo <IFunctionExecutionHandler>(meh => meh.OnEntry(null)), fhArgs);
            var onSuccess   = Expr.Call(mh, SymbolExtensions.GetMethodInfo <IFunctionExecutionHandler>(meh => meh.OnSuccess(null)), fhArgs);
            var onException = Expr.Call(mh, SymbolExtensions.GetMethodInfo <IFunctionExecutionHandler>(meh => meh.OnException(null)), fhArgs);
            var onExit      = Expr.Call(mh, SymbolExtensions.GetMethodInfo <IFunctionExecutionHandler>(meh => meh.OnExit(null)), fhArgs);

            // Create the new parameters for the wrapper
            var outerParams = functionLambda.Parameters.Select(p => Expr.Parameter(p.Type, p.Name)).ToArray();
            // Create the array of parameter values that will be put into the method handler args.
            var paramsArray = Expr.NewArrayInit(typeof(object), outerParams.Select(p => Expr.Convert(p, typeof(object))));

            // Prepare the result and ex(ception) local variables
            var result = Expr.Variable(functionLambda.ReturnType, "result");
            var ex     = Expression.Parameter(typeof(Exception), "ex");

            // A bunch of helper expressions:
            // : new FunctionExecutionArgs(new object[] { arg0, arg1 })
            var fhArgsConstr = typeof(FunctionExecutionArgs).GetConstructor(new[] { typeof(string), typeof(object[]) });
            var newfhArgs    = Expr.New(fhArgsConstr, funcName, paramsArray);
            // : result = (int)fhArgs.ReturnValue
            var resultFromReturnValue = Expr.Assign(result, Expr.Convert(fhArgsReturnValue, functionLambda.ReturnType));
            // : fhArgs.ReturnValue = (object)result
            var returnValueFromResult = Expr.Assign(fhArgsReturnValue, Expr.Convert(result, typeof(object)));
            // : result = function(arg0, arg1)
            var resultFromInnerCall = Expr.Assign(result, Expr.Invoke(functionLambda, outerParams));

            // Build the Lambda wrapper, with the original parameters
            var lambda = Expr.Lambda(
                Expr.Block(new[] { fhArgs, result },
                           Expr.Assign(fhArgs, newfhArgs),
                           Expr.Assign(result, Expr.Default(result.Type)),
                           Expr.TryCatchFinally(
                               Expr.Block(
                                   onEntry,
                                   Expr.IfThenElse(
                                       Expr.Equal(fhArgsFlowBehaviour, Expr.Constant(FlowBehavior.Return)),
                                       resultFromReturnValue,
                                       Expr.Block(
                                           resultFromInnerCall,
                                           returnValueFromResult,
                                           onSuccess,
                                           resultFromReturnValue))),
                               onExit, // finally
                               Expr.Catch(ex,
                                          Expr.Block(
                                              Expr.Assign(fhArgsException, ex),
                                              onException,
                                              Expr.IfThenElse(
                                                  Expr.Equal(fhArgsFlowBehaviour, Expr.Constant(FlowBehavior.Return)),
                                                  Expr.Block(
                                                      Expr.Assign(fhArgsException, Expr.Constant(null, typeof(Exception))),
                                                      resultFromReturnValue),
                                                  Expr.IfThenElse(
                                                      Expr.Equal(fhArgsFlowBehaviour, Expr.Constant(FlowBehavior.ThrowException)),
                                                      Expr.Throw(fhArgsException),
                                                      Expr.Rethrow()))))
                               ),
                           result),
                functionName,
                outerParams);

            return(lambda);
        }
コード例 #9
0
 internal System.Linq.Expressions.CatchBlock ToCatchBlock() => SysExpr.Catch(Variable.ToParameterExpression(), Body.ToExpression());
コード例 #10
0
 public static Expression TryNoCatch(this Expression expression)
 => Expression.TryCatch(expression, Expression.Catch(typeof(Exception).ToParameter(), Expression.Empty()));