Throw() public static method

Creates a UnaryExpression that represents a throwing of an exception.
public static Throw ( Expression value ) : UnaryExpression
value Expression An .
return UnaryExpression
Ejemplo n.º 1
0
        internal MetaObject /*!*/ CreateMetaObject(MetaObjectBinder /*!*/ action, MetaObject /*!*/[] /*!*/ siteArgs)
        {
            var expr = _error ? Ast.Throw(_result) : _result;

            Restrictions restrictions;

            if (_condition != null)
            {
                var deferral = action.Defer(siteArgs);
                expr         = Ast.Condition(_condition, AstUtils.Convert(expr, typeof(object)), deferral.Expression);
                restrictions = deferral.Restrictions;
            }
            else
            {
                restrictions = Restrictions.Empty;
            }

            if (_temps != null)
            {
                expr = Ast.Block(_temps, expr);
            }

            if (_restriction != null)
            {
                restrictions = restrictions.Merge(Restrictions.GetExpressionRestriction(_restriction));
            }

            return(new MetaObject(expr, restrictions));
        }
        public void Throw()
        {
            var expression =
                LinqExpression.Throw(null);

            ShouldRoundrip(expression);
        }
Ejemplo n.º 3
0
        private Exp CheckIfZero(CompilerState state, Exp expression)
        {
            if (state == null)
            {
                throw new Exception();
            }
            if (expression == null)
            {
                throw new Exception();
            }

            if (expression.Type == typeof(int))
            {
                var constructor = typeof(Exception).GetConstructor(new Type[] { typeof(string) });
                return(Exp.Block(
                           Exp.IfThen(Exp.Equal(expression, Exp.Constant(0)),
                                      Exp.Throw(Exp.New(constructor, Exp.Constant("Division by zero")))),
                           expression));
            }

            if (expression.Type == typeof(float))
            {
                var constructor = typeof(Exception).GetConstructor(new Type[] { typeof(string) });
                return(Exp.Block(
                           Exp.IfThen(Exp.Equal(expression, Exp.Constant(0.0f)),
                                      Exp.Throw(Exp.New(constructor, Exp.Constant("Division by zero")))),
                           expression));
            }
            return(expression);
        }
        public void Throw_type()
        {
            var expression =
                LinqExpression.Throw(
                    null,
                    typeof(Exception));

            ShouldRoundrip(expression);
        }
        public void Throw_value()
        {
            var expression =
                LinqExpression.Throw(
                    LinqExpression.New(
                        typeof(ArgumentException)));

            ShouldRoundrip(expression);
        }
Ejemplo n.º 6
0
        public static Ex DictSafeGet(this Ex dict, Ex key, string err)
        {
            return(Ex.Block(
                       Ex.IfThen(Ex.Not(ExUtils.DictContains(dict, key)), Ex.Throw(Ex.Constant(new Exception(err)))),
                       dict.DictGet(key)
                       ));

            /*
             * return Ex.Condition(ExUtils.DictContains<K, V>(dict, key), dict.DictGet(key), Ex.Block(
             *  Ex.Throw(Ex.Constant(new Exception(err))),
             *  dict.DictGet(key)
             * ));*/
        }
        private UnaryExpression UnaryExpression(
            ExpressionType nodeType, System.Type type, JObject obj)
        {
            var operand = this.Prop(obj, "operand", this.Expression);
            var method  = this.Prop(obj, "method", this.Method);

            switch (nodeType)
            {
            case ExpressionType.ArrayLength: return(Expr.ArrayLength(operand));

            case ExpressionType.Convert: return(Expr.Convert(operand, type, method));

            case ExpressionType.ConvertChecked: return(Expr.ConvertChecked(operand, type, method));

            case ExpressionType.Decrement: return(Expr.Decrement(operand, method));

            case ExpressionType.Increment: return(Expr.Increment(operand, method));

            case ExpressionType.IsFalse: return(Expr.IsFalse(operand, method));

            case ExpressionType.IsTrue: return(Expr.IsTrue(operand, method));

            case ExpressionType.Negate: return(Expr.Negate(operand, method));

            case ExpressionType.NegateChecked: return(Expr.NegateChecked(operand, method));

            case ExpressionType.Not: return(Expr.Not(operand, method));

            case ExpressionType.OnesComplement: return(Expr.OnesComplement(operand, method));

            case ExpressionType.PostDecrementAssign: return(Expr.PostDecrementAssign(operand, method));

            case ExpressionType.PostIncrementAssign: return(Expr.PostIncrementAssign(operand, method));

            case ExpressionType.PreDecrementAssign: return(Expr.PreDecrementAssign(operand, method));

            case ExpressionType.PreIncrementAssign: return(Expr.PreIncrementAssign(operand, method));

            case ExpressionType.Quote: return(Expr.Quote(operand));

            case ExpressionType.Throw: return(Expr.Throw(operand, type));

            case ExpressionType.TypeAs: return(Expr.TypeAs(operand, type));

            case ExpressionType.UnaryPlus: return(Expr.UnaryPlus(operand, method));

            case ExpressionType.Unbox: return(Expr.Unbox(operand, type));

            default: throw new NotSupportedException();
            }
        }
Ejemplo n.º 8
0
        void ConvertArgumentToParamType(List <Argument> arguments, ParameterInfo[] parameters, out Expr failExpr)
        {
            failExpr = null;

            for (int i = 0; i < arguments.Count; i++)
            {
                var arg   = arguments[i];
                var param = parameters[i];

                if (param.ParameterType == typeof(bool) && arg.Type != typeof(bool))
                {
                    arg.Expression = ExprHelpers.ConvertToBoolean(context, arg.Expression);
                }
                else if (param.ParameterType == typeof(double) && arg.Type == typeof(string))
                {
                    arg.Expression = ExprHelpers.ConvertToNumberAndCheck(
                        context, arg.Expression,
                        ExceptionMessage.INVOKE_BAD_ARGUMENT_GOT, i + 1, "number", "string");
                }
                else if (param.ParameterType == typeof(string) && arg.Type != typeof(string))
                {
                    arg.Expression = Expr.Call(arg.Expression, MemberInfos.ObjectToString, arg.Expression);
                }
                else
                {
                    if (arg.Type == param.ParameterType || arg.Type.IsSubclassOf(param.ParameterType))
                    {
                        arg.Expression = Expr.Convert(arg.Expression, param.ParameterType);
                    }
                    else
                    {
                        Func <Expr, Expr> typeNameExpr =
                            obj => Expr.Invoke(
                                Expr.Constant((Func <object, string>)BaseLibrary.Type),
                                Expr.Convert(obj, typeof(object)));

                        // Ugly reflection hack
                        failExpr = Expr.Throw(
                            Expr.New(
                                MemberInfos.NewRuntimeException,
                                Expr.Constant(ExceptionMessage.INVOKE_BAD_ARGUMENT_GOT),
                                Expr.NewArrayInit(
                                    typeof(object),
                                    Expr.Constant(i + 1, typeof(object)),
                                    typeNameExpr(Expr.Constant(Activator.CreateInstance(param.ParameterType))),
                                    typeNameExpr(arg.Expression))));
                        break;
                    }
                }
            }
        }
Ejemplo n.º 9
0
        void CheckNumberOfArguments(List <Argument> arguments, ParameterInfo[] parameters, out Expr failExpr)
        {
            failExpr = null;
            Debug.Assert(arguments.Count <= parameters.Length);

            if (arguments.Count < parameters.Length)
            {
                failExpr = Expr.Throw(
                    Expr.New(
                        MemberInfos.NewRuntimeException,
                        Expr.Constant(ExceptionMessage.INVOKE_BAD_ARGUMENT_EXPECTED),
                        Expr.Constant(new object[] { arguments.Count + 1, "value" })));
            }
        }
Ejemplo n.º 10
0
        internal void SetRule(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args)
        {
            Assert.NotNull(metaBuilder, args);
            Debug.Assert(args.SimpleArgumentCount == 0 && !args.Signature.HasBlock && !args.Signature.HasSplattedArgument && !args.Signature.HasRhsArgument);
            Debug.Assert(args.Signature.HasScope);

            var ec = args.RubyContext;

            // implicit conversions should only depend on a static type:
            if (TryImplicitConversion(metaBuilder, args))
            {
                if (args.Target == null)
                {
                    metaBuilder.AddRestriction(Ast.Equal(args.TargetExpression, Ast.Constant(null, args.TargetExpression.Type)));
                }
                else
                {
                    metaBuilder.AddTypeRestriction(args.Target.GetType(), args.TargetExpression);
                }
                return;
            }

            // check for type version:
            metaBuilder.AddTargetTypeTest(args);

            string     toMethodName            = ToMethodName;
            Expression targetClassNameConstant = Ast.Constant(ec.GetClassOf(args.Target).Name);

            // Kernel#respond_to? method is not overridden => we can optimize
            RubyMemberInfo respondToMethod = ec.ResolveMethod(args.Target, Symbols.RespondTo, true).InvalidateSitesOnOverride();

            if (respondToMethod == null ||
                // the method is defined in library, hasn't been replaced by user defined method (TODO: maybe we should make this check better)
                (respondToMethod.DeclaringModule == ec.KernelModule && respondToMethod is RubyMethodGroupInfo))
            {
                RubyMemberInfo conversionMethod = ec.ResolveMethod(args.Target, toMethodName, false).InvalidateSitesOnOverride();
                if (conversionMethod == null)
                {
                    // error:
                    SetError(metaBuilder, targetClassNameConstant, args);
                    return;
                }
                else
                {
                    // invoke target.to_xxx() and validate it; returns an instance of TTargetType:
                    conversionMethod.BuildCall(metaBuilder, args, toMethodName);

                    if (!metaBuilder.Error && ConversionResultValidator != null)
                    {
                        metaBuilder.Result = ConversionResultValidator.OpCall(targetClassNameConstant, AstFactory.Box(metaBuilder.Result));
                    }
                    return;
                }
            }
            else if (!RubyModule.IsMethodVisible(respondToMethod, false))
            {
                // respond_to? is private:
                SetError(metaBuilder, targetClassNameConstant, args);
                return;
            }

            // slow path: invoke respond_to?, to_xxx and result validation:

            var conversionCallSite = Ast.Dynamic(
                RubyCallAction.Make(toMethodName, RubyCallSignature.WithScope(0)),
                typeof(object),
                args.ScopeExpression, args.TargetExpression
                );

            Expression opCall;

            metaBuilder.Result = Ast.Condition(
                // If

                // respond_to?()
                Methods.IsTrue.OpCall(
                    Ast.Dynamic(
                        RubyCallAction.Make(Symbols.RespondTo, RubyCallSignature.WithScope(1)),
                        typeof(object),
                        args.ScopeExpression, args.TargetExpression, Ast.Constant(SymbolTable.StringToId(toMethodName))
                        )
                    ),

                // Then

                // to_xxx():
                opCall = (ConversionResultValidator == null) ? conversionCallSite :
                         ConversionResultValidator.OpCall(targetClassNameConstant, conversionCallSite),

                // Else

                AstUtils.Convert(
                    (ConversionResultValidator == null) ? args.TargetExpression :
                    Ast.Convert(
                        Ast.Throw(Methods.CreateTypeConversionError.OpCall(targetClassNameConstant, Ast.Constant(TargetTypeName))),
                        typeof(object)
                        ),
                    opCall.Type
                    )
                );
        }
Ejemplo n.º 11
0
        private static AstHelper CreateRuntime(ModuleBuilder module)
        {
            var result = new AstHelper(module);

            result.Types.Add("int", typeof(int));
            result.Types.Add("string", typeof(string));
            result.Types.Add("bool", typeof(bool));

            Expression <Action <string> > print = a => Console.Write(a);

            result.Functions.Add("print", new FunctionReference(print, typeof(void), typeof(string)));
            Expression <Action <string> > printline = a => Console.WriteLine(a);

            result.Functions.Add("printline", new FunctionReference(printline, typeof(void), typeof(string)));

            Expression <Action <int> > printi = a => Console.WriteLine(a);

            result.Functions.Add("print", new FunctionReference(printi, typeof(void), typeof(int)));

            Expression <Func <string> > readLine = () => Console.ReadLine();

            result.Functions.Add("readline", new FunctionReference(readLine, typeof(string)));

            Expression <Func <int, string> > str = a => a.ToString(CultureInfo.InvariantCulture);

            result.Functions.Add("str", new FunctionReference(str, typeof(string), typeof(int)));

            // function ord(s : string) : int
            // Return the ASCII value of the first character of s, or €1 if s is empty.
            Expression <Func <string, int> > ord = a => string.IsNullOrEmpty(a) ? -1 : (int)a[0];

            result.Functions.Add("ord", new FunctionReference(ord, typeof(int), typeof(string)));

            // function chr(i : int) : string
            // Return a single-character string for ASCII value i. Terminate program if i is out of range.
            // todo when chr is called terminate the program if i is out of range
            Expression <Func <int, string> > chr = a => ((char)a).ToString();

            result.Functions.Add("chr", new FunctionReference(chr, typeof(string), typeof(int)));

            // function size(s : string) : int
            // Return the number of characters in s.
            Expression <Func <string, int> > size = a => a.Length;

            result.Functions.Add("size", new FunctionReference(size, typeof(int), typeof(string)));

            // function substring(s:string,f:int,n:int):string
            // Return the substring of s starting at the character f (first character is numbered zero) and going for n characters.
            Expression <Func <string, int, int, string> > substring = (s, f, n) => s.Substring(f, n);

            result.Functions.Add("substring",
                                 new FunctionReference(substring, typeof(int), typeof(string), typeof(int),
                                                       typeof(int)));

            // function concat (s1:string, s2:string):string
            // Return a new string consisting of s1 followed by s2.
            Expression <Func <string, string, string> > concat = (s1, s2) => s1 + s2;

            result.Functions.Add("concat",
                                 new FunctionReference(concat, typeof(string), typeof(string), typeof(string)));

            // function not(i : int) : int
            // Return 1 if i is zero, 0 otherwise.
            Expression <Func <int, int> > not = i => i == 0 ? 1 : 0;

            result.Functions.Add("not", new FunctionReference(not, typeof(int), typeof(int)));

            // function exit(i : int)
            // Terminate execution of the program with code i.
            ConstructorInfo            constructor = typeof(ExitException).GetConstructor(new[] { typeof(int) });
            ParameterExpression        parameter   = Expression.Parameter(typeof(int));
            Expression <Action <int> > exit        =
                Expression.Lambda <Action <int> >(Expression.Throw(Expression.New(constructor, parameter)), parameter);

            result.Functions.Add("exit", new FunctionReference(exit, typeof(void), typeof(int)));

            return(result);
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
0
 // Returns a throw SimulationDiverged expression at At.
 private LinqExpr ThrowSimulationDiverged(LinqExpr At)
 {
     return(LinqExpr.Throw(LinqExpr.New(typeof(SimulationDiverged).GetConstructor(new Type[] { At.Type }), At)));
 }
Ejemplo n.º 14
0
        /// <summary>
        /// Creates verifier which checks object public properties.
        /// </summary>
        /// <typeparam name="TVerifier">Verifier type.</typeparam>
        /// <param name="propertyFilter">Object public properties filter; can be null to generate code for all the properties.</param>
        /// <param name="checkExprFunc">Function which generates property value check expression (if returns true then check is failed).
        /// Function obtains variable which holds property value and additional arguments.</param>
        /// <param name="createExceptionExpr">New exception creation expression used when check is failed.</param>
        /// <returns>Verifier instance.</returns>
        public static TVerifier Create <TVerifier>(
            Func <Type, bool> propertyFilter,
            Func <Expression, IList <ParameterExpression>, Expr> checkExprFunc,
            LambdaExpression createExceptionExpr) where TVerifier : class
        {
            VerifyUtil.NotNull(checkExprFunc, "checkExprFunc");
            VerifyUtil.NotNull(createExceptionExpr, "createExceptionExpr");

            Type argumentsType = typeof(TVerifier).GetGenericArguments()[0];
            Type type          = argumentsType.GetGenericArguments()[0];

            // Prepare lambda action parameters - first is Argument<T>, others are additionalParamTypes
            var objectParam      = Expr.Parameter(argumentsType);
            var objectVar        = Expr.Parameter(type);
            var genericArguments = typeof(TVerifier).GetGenericArguments();
            var additionalParams = genericArguments.Skip(1).Take(genericArguments.Length - 2).Select(Expr.Parameter).ToList();

            Expr lambdaBody;

            if (type.IsAnonymous())
            {
                // Take createExceptionExpr lambda, extract first parameter from it and replace additional parameters in body
                var exceptionNameParam   = createExceptionExpr.Parameters[0];
                var exceptionObjectParam = createExceptionExpr.Parameters[1];
                var exceptionBody        = createExceptionExpr.ReplaceParams(additionalParams);

                // Obtain type public properties to check
                propertyFilter = propertyFilter ?? (_ => true);
                var properties = type.GetProperties().OrderBy(pi => pi.Name).Where(pi => propertyFilter(pi.PropertyType));

                // Obtain argument values from fields since it's faster
                var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance).OrderBy(fi => fi.Name).Where(fi => propertyFilter(fi.FieldType)).ToList();

                // Generate "if (checkExpr) then throw createExceptionExpr;" for each of the properties
                var propertyChecks = properties
                                     .Select(
                    (pi, i) =>
                {
                    var valueVar = Expr.Field(objectVar, fields[i]);
                    return((Expr)Expr.IfThen(
                               checkExprFunc(valueVar, additionalParams),
                               Expr.Throw(
                                   exceptionBody
                                   .Replace(exceptionNameParam, Expr.Constant(pi.Name))
                                   .Replace(exceptionObjectParam, valueVar.ConvertIfNeeded(exceptionObjectParam.Type)))));
                })
                                     .ToList();

                // Prepare null check - if null is supplied then all checks are passed since nothing to check
                var checksBody = propertyChecks.Any()
                                        ? Expr.IfThen(
                    Expr.ReferenceNotEqual(objectVar, Expr.Constant(null, type)),
                    propertyChecks.Count > 1 ? Expr.Block(propertyChecks) : propertyChecks[0])
                                        : null;

                lambdaBody = propertyChecks.Any()
                                        ? (Expr)Expr.Block(
                    new[] { objectVar },
                    new Expr[] { Expr.Assign(objectVar, Expr.Field(objectParam, "Holder")) }
                    .Concat(new[] { checksBody })
                    .Concat(new[] { objectParam }))
                                        : objectParam;
            }
            else
            {
                // Not anonymous type - throw an exception
                lambdaBody = Expr.Block(
                    Expr.Throw(
                        Expr.New(
                            VerifyArgsExceptionCtor,
                            Expr.Constant(string.Format(ErrorMessages.NotAnonymousType, type)))),
                    objectParam);
            }

            // Pull it all together, execute checks only if supplied object is not null
            var lambda = Expr.Lambda <TVerifier>(
                lambdaBody,
                new[] { objectParam }.Concat(additionalParams));

            return(lambda.Compile());
        }