public void Should_not_allow_implicit_boxing_for_instance_expression()
        {
            MethodInfo objToStringInfo = typeof(object).GetMethod("ToString");
            var        ex = Assert.Throws <ArgumentException>(() => Expr.Call(Expr.Constant(22), objToStringInfo));

            Assert.That(ex.Message, Is.StringContaining("Instance expression of type System.Int32 does not match to type: System.Object"));
        }
Beispiel #2
0
        /// <summary>
        /// Converts a value from one type to another
        /// </summary>
        /// <param name="value">The value to convert</param>
        /// <param name="type">The type to convert the value to</param>
        /// <returns>The value converted to the requested type</returns>
        public static object ChangeType(object value, Type type)
        {
            if (value != null && value.GetType() == type)
            {
                return(value);
            }

            var expression = (Expression)Expression.Constant(value);

            // Special case for converting from string to enum for metadata filters
            if (expression.Type == typeof(SqlString) && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>) && type.GetGenericArguments()[0].IsEnum)
            {
                var nullCheck = NullCheck(expression);
                var nullValue = (Expression)Expression.Constant(null);
                nullValue = Expression.Convert(nullValue, type);
                var parsedValue = (Expression)Expression.Convert(expression, typeof(string));
                parsedValue = Expr.Call(() => Enum.Parse(Expr.Arg <Type>(), Expr.Arg <string>(), Expr.Arg <bool>()), Expression.Constant(type.GetGenericArguments()[0]), parsedValue, Expression.Constant(true));
                parsedValue = Expression.Convert(parsedValue, type);
                expression  = Expression.Condition(nullCheck, nullValue, parsedValue);
            }
            else if (expression.Type == typeof(SqlString) && type.IsEnum)
            {
                expression = (Expression)Expression.Convert(expression, typeof(string));
                expression = Expr.Call(() => Enum.Parse(Expr.Arg <Type>(), Expr.Arg <string>(), Expr.Arg <bool>()), Expression.Constant(type), expression, Expression.Constant(true));
                expression = Expression.Convert(expression, type);
            }
            else
            {
                expression = Expression.Convert(expression, type);
            }

            expression = Expression.Convert(expression, typeof(object));
            return(Expression.Lambda <Func <object> >(expression).Compile()());
        }
        public void Should_properly_map_parameters_with_this()
        {
            MethodInfo mi   = typeof(DerivedType).GetMethod("Call");
            var        func = CreateFunc <DerivedType, int, DerivedType>(Expr.Return(Expr.Call(Expr.Parameter(0, typeof(DerivedType)), mi, Expr.Parameter(1, typeof(int)))));
            var        obj  = func(new DerivedType(), 32);

            Assert.That(obj.X, Is.EqualTo(32));
        }
        public void Should_call_virtual_method()
        {
            var virtualMethodInfo = typeof(BaseClass).GetMethod("Virt");
            var func = CreateFunc <BaseClass, string>(Expr.Return(Expr.Call(Expr.Parameter(0, typeof(BaseClass)), virtualMethodInfo)));

            Assert.That(func(new BaseClass()), Is.EqualTo("base"));
            Assert.That(func(new DerivedClass()), Is.EqualTo("derived"));
        }
        public void Should_call_struct_instance_method_via_parameter()
        {
            var func = CreateFunc <Counter, Counter>(
                Expr.Call(Expr.Parameter(0, typeof(Counter)), typeof(Counter).GetMethod("Count")),
                Expr.Return(Expr.Parameter(0, typeof(Counter))));

            Assert.That(func(new Counter()).Value, Is.EqualTo(1));
        }
        public void Should_allow_hierarchy_conversion_for_instance()
        {
            MethodInfo methodInfo = typeof(BaseClass).GetMethod("Foo");
            var        func       = CreateFunc <DerivedClass, string>(Expr.Return(Expr.Call(Expr.Parameter(0, typeof(DerivedClass)), methodInfo)));

            Assert.That(func(new DerivedClass {
                Result = "hi"
            }), Is.EqualTo("hi"));
        }
        public void Should_call_struct_instance_method_via_field()
        {
            var func = CreateAction <CounterHolder>(Expr.Call(
                                                        Expr.ReadField(Expr.Parameter(0, typeof(CounterHolder)), typeof(CounterHolder).GetField("Counter")),
                                                        typeof(Counter).GetMethod("Count")));
            var holder = new CounterHolder();

            func(holder);
            Assert.That(holder.Counter.Value, Is.EqualTo(1));
        }
        public void Should_call_struct_instance_method_via_local_variable()
        {
            var local = Expr.LocalVariable(typeof(Counter), "s");
            var func  = CreateFunc <Counter, Counter>(
                Expr.DeclareLocal(local, Expr.Parameter(0, typeof(Counter))),
                Expr.Call(Expr.ReadLocal(local), typeof(Counter).GetMethod("Count")),
                Expr.Return(Expr.ReadLocal(local)));

            Assert.That(func(new Counter()).Value, Is.EqualTo(1));
        }
        private void AssertCounter <T>(T value, bool expectedResult)
        {
            var func = CreateAction <T, Counter>(Expr.IfThen(
                                                     Expr.Parameter(0, typeof(T)),
                                                     Expr.Call(Expr.Parameter(1, typeof(Counter)), typeof(Counter).GetMethod("Count"))));

            var counter = new Counter();

            func(value, counter);
            Assert.That(counter.Value, Is.EqualTo(expectedResult ? 1 : 0));
        }
Beispiel #10
0
        public void Should_execute_all_statements_in_block()
        {
            var addMethod = typeof(Counter).GetMethod("Add");
            var func      = CreateAction <Counter>(Expr.Block(
                                                       Expr.Call(Expr.Parameter(0, typeof(Counter)), addMethod),
                                                       Expr.Call(Expr.Parameter(0, typeof(Counter)), addMethod)));

            var cnt = new Counter();

            func(cnt);
            Assert.That(cnt.Value, Is.EqualTo(2));
        }
        public void Should_catch_exceptions()
        {
            var builder = new StringBuilder();
            Func <char, StringBuilder> appendFn = builder.Append;

            var argParam = Expr.Parameter(0, typeof(int));
            var sbParam  = Expr.Parameter(1, typeof(StringBuilder));
            var func     = CreateAction <int, StringBuilder>(Expr.TryCatchFinally(
                                                                 Expr.Block(
                                                                     Expr.IfThen(Expr.Equal(argParam, Expr.Constant(1)), Expr.Throw(Expr.New(typeof(InvalidOperationException)))),
                                                                     Expr.IfThen(Expr.Equal(argParam, Expr.Constant(2)), Expr.Throw(Expr.New(typeof(ArgumentNullException)))),
                                                                     Expr.IfThen(Expr.Equal(argParam, Expr.Constant(3)), Expr.Throw(Expr.New(typeof(ArgumentException)))),
                                                                     Expr.IfThen(Expr.Equal(argParam, Expr.Constant(4)), Expr.Throw(Expr.New(typeof(ArithmeticException)))),
                                                                     Expr.Call(sbParam, appendFn.Method, ConstChar('X'))
                                                                     ),
                                                                 Expr.Call(sbParam, appendFn.Method, ConstChar('F')),
                                                                 new CatchBlock(typeof(InvalidOperationException), Expr.Call(sbParam, appendFn.Method, ConstChar('I'))),
                                                                 new CatchBlock(typeof(ArgumentNullException), Expr.Block(Expr.Call(sbParam, appendFn.Method, ConstChar('N')), Expr.Rethrow())),
                                                                 new CatchBlock(typeof(ArgumentException), Expr.Call(sbParam, appendFn.Method, ConstChar('A'))),
                                                                 new CatchBlock(Expr.Call(sbParam, appendFn.Method, ConstChar('D')))));

            func(0, builder.Clear());
            Assert.That(builder.ToString(), Is.EqualTo("XF"));

            func(1, builder.Clear());
            Assert.That(builder.ToString(), Is.EqualTo("IF"));

            func(3, builder.Clear());
            Assert.That(builder.ToString(), Is.EqualTo("AF"));

            func(4, builder.Clear());
            Assert.That(builder.ToString(), Is.EqualTo("DF"));

            Assert.Throws <ArgumentNullException>(() => func(2, builder.Clear()));
            Assert.That(builder.ToString(), Is.EqualTo("NF"));
        }
        public void Should_not_allow_not_null_instance_for_static_method()
        {
            var ex = Assert.Throws <ArgumentException>(() => Expr.Call(Expr.Constant(21), _parseInfo, Expr.Constant("22")));

            Assert.That(ex.Message, Is.StringContaining("Static method cannot be called with instance parameter"));
        }
        public void Should_not_allow_null_expression_array()
        {
            var ex = Assert.Throws <ArgumentNullException>(() => Expr.Call(_toStringInfo, null));

            Assert.That(ex.Message, Is.StringContaining("arguments"));
        }
        public void Should_not_allow_null_methodInfo()
        {
            var ex = Assert.Throws <ArgumentNullException>(() => Expr.Call(null));

            Assert.That(ex.Message, Is.StringContaining("methodInfo"));
        }
        public void Should_not_allow_null_instance_for_non_static_method()
        {
            var ex = Assert.Throws <ArgumentNullException>(() => Expr.Call(null, _toStringInfo));

            Assert.That(ex.Message, Is.StringContaining("instance"));
        }
 public void VoidMethodTypeTest()
 {
     Assert.That(Expr.Call(_fooInfo).ExpressionType, Is.EqualTo(typeof(void)));
 }
 public void NonVoidMethodTypeTest()
 {
     Assert.That(Expr.Call(_formatInfo, Expr.Constant("{0}"), Expr.Convert(Expr.Constant(1), typeof(object))).ExpressionType, Is.EqualTo(typeof(string)));
 }
        public void Should_not_allow_exceeding_number_of_method_parameters()
        {
            var ex = Assert.Throws <ArgumentException>(() => Expr.Call(_fooInfo, Expr.Constant(1)));

            Assert.That(ex.Message, Is.StringContaining("Invalid amount of parameters supplied to method: Void Foo()"));
        }
Beispiel #19
0
        /// <summary>
        /// Compiles methods to access the data required for the DML operation
        /// </summary>
        /// <param name="mappings">The mappings of attribute name to source column</param>
        /// <param name="schema">The schema of data source</param>
        /// <param name="attributes">The attributes in the target metadata</param>
        /// <param name="dateTimeKind">The time zone that datetime values are supplied in</param>
        /// <returns></returns>
        protected Dictionary <string, Func <Entity, object> > CompileColumnMappings(EntityMetadata metadata, IDictionary <string, string> mappings, INodeSchema schema, IDictionary <string, AttributeMetadata> attributes, DateTimeKind dateTimeKind)
        {
            var attributeAccessors = new Dictionary <string, Func <Entity, object> >();
            var entityParam        = Expression.Parameter(typeof(Entity));

            foreach (var mapping in mappings)
            {
                var sourceColumnName  = mapping.Value;
                var destAttributeName = mapping.Key;

                if (!schema.ContainsColumn(sourceColumnName, out sourceColumnName))
                {
                    throw new QueryExecutionException($"Missing source column {mapping.Value}")
                          {
                              Node = this
                          }
                }
                ;

                // We might be using a virtual ___type attribute that has a different name in the metadata. We can safely
                // ignore these attributes - the attribute names have already been validated in the ExecutionPlanBuilder
                if (!attributes.TryGetValue(destAttributeName, out var attr) || attr.AttributeOf != null)
                {
                    continue;
                }

                var sourceType  = schema.Schema[sourceColumnName];
                var destType    = attr.GetAttributeType();
                var destSqlType = SqlTypeConverter.NetToSqlType(destType);

                var expr         = (Expression)Expression.Property(entityParam, typeof(Entity).GetCustomAttribute <DefaultMemberAttribute>().MemberName, Expression.Constant(sourceColumnName));
                var originalExpr = expr;

                if (sourceType == typeof(object))
                {
                    // null literal
                    expr = Expression.Constant(null, destType);
                    expr = Expr.Box(expr);
                }
                else
                {
                    expr = SqlTypeConverter.Convert(expr, sourceType);
                    expr = SqlTypeConverter.Convert(expr, destSqlType);
                    var convertedExpr = SqlTypeConverter.Convert(expr, destType);

                    if (attr is LookupAttributeMetadata lookupAttr && lookupAttr.AttributeType != AttributeTypeCode.PartyList)
                    {
                        // Special case: intersect attributes can be simple guids
                        if (metadata.IsIntersect != true)
                        {
                            if (sourceType == typeof(SqlEntityReference))
                            {
                                expr          = SqlTypeConverter.Convert(originalExpr, sourceType);
                                convertedExpr = SqlTypeConverter.Convert(expr, typeof(EntityReference));
                            }
                            else
                            {
                                Expression targetExpr;

                                if (lookupAttr.Targets.Length == 1)
                                {
                                    targetExpr = Expression.Constant(lookupAttr.Targets[0]);
                                }
                                else
                                {
                                    var sourceTargetColumnName = mappings[destAttributeName + "type"];
                                    var sourceTargetType       = schema.Schema[sourceTargetColumnName];
                                    targetExpr = Expression.Property(entityParam, typeof(Entity).GetCustomAttribute <DefaultMemberAttribute>().MemberName, Expression.Constant(sourceTargetColumnName));
                                    targetExpr = SqlTypeConverter.Convert(targetExpr, sourceTargetType);
                                    targetExpr = SqlTypeConverter.Convert(targetExpr, typeof(SqlString));
                                    targetExpr = SqlTypeConverter.Convert(targetExpr, typeof(string));
                                }

                                convertedExpr = Expression.New(
                                    typeof(EntityReference).GetConstructor(new[] { typeof(string), typeof(Guid) }),
                                    targetExpr,
                                    Expression.Convert(convertedExpr, typeof(Guid))
                                    );
                            }

                            destType = typeof(EntityReference);
                        }
                    }
                    else if (attr is EnumAttributeMetadata && !(attr is MultiSelectPicklistAttributeMetadata))
                    {
                        convertedExpr = Expression.New(
                            typeof(OptionSetValue).GetConstructor(new[] { typeof(int) }),
                            Expression.Convert(convertedExpr, typeof(int))
                            );
                        destType = typeof(OptionSetValue);
                    }
                    else if (attr is MoneyAttributeMetadata)
                    {
                        convertedExpr = Expression.New(
                            typeof(Money).GetConstructor(new[] { typeof(decimal) }),
                            Expression.Convert(expr, typeof(decimal))
                            );
                        destType = typeof(Money);
                    }
                    else if (attr is DateTimeAttributeMetadata)
                    {
                        convertedExpr = Expression.Convert(
                            Expr.Call(() => DateTime.SpecifyKind(Expr.Arg <DateTime>(), Expr.Arg <DateTimeKind>()),
                                      expr,
                                      Expression.Constant(dateTimeKind)
                                      ),
                            typeof(DateTime?)
                            );
                    }

                    // Check for null on the value BEFORE converting from the SQL to BCL type to avoid e.g. SqlDateTime.Null being converted to 1900-01-01
                    expr = Expression.Condition(
                        SqlTypeConverter.NullCheck(expr),
                        Expression.Constant(null, destType),
                        convertedExpr);

                    if (expr.Type.IsValueType)
                    {
                        expr = SqlTypeConverter.Convert(expr, typeof(object));
                    }
                }

                attributeAccessors[destAttributeName] = Expression.Lambda <Func <Entity, object> >(expr, entityParam).Compile();
            }
        public void Should_properly_map_parameters()
        {
            Func <int, char, string, long, bool, string> formatMethod = Format;
            var func = CreateFunc <int, char, string, long, bool, string>(Expr.Return(Expr.Call(
                                                                                          formatMethod.Method,
                                                                                          Expr.Parameter(0, typeof(int)),
                                                                                          Expr.Parameter(1, typeof(char)),
                                                                                          Expr.Parameter(2, typeof(string)),
                                                                                          Expr.Parameter(3, typeof(long)),
                                                                                          Expr.Parameter(4, typeof(bool)))));

            Assert.That(func(1, 'a', "text", -23, false), Is.EqualTo("1_a_text_-23_False"));
        }
Beispiel #21
0
        static void Main(string[] args)
        {
            var asmName      = "PlayGround.Generated";
            var fileName     = "PlayGround.Generated.dll";
            var asmBuilder   = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(asmName), AssemblyBuilderAccess.RunAndSave);
            var modBuilder   = asmBuilder.DefineDynamicModule(asmName, fileName, true);
            var typeBuilder  = modBuilder.DefineType("PlayGround.Generated.MyClass", TypeAttributes.Class | TypeAttributes.Public);
            var fieldBuilder = typeBuilder.DefineField("field", typeof(string), FieldAttributes.InitOnly | FieldAttributes.Static | FieldAttributes.Public);

            var cb      = typeBuilder.DefineTypeInitializer();
            var builder = new MethodBodyBuilder(cb);

            builder.AddStatements(
                Expr.WriteField(fieldBuilder, Expr.Constant("abc")),
                Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Constant("Hello my friend!")),
                Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string), typeof(object) }), Expr.Constant("What a {0} day!"), Expr.Constant("beautiful")),
                Expr.Call(typeof(Console).GetMethod("ReadKey", new Type[0])));
            Console.WriteLine(builder.ToString());
            builder.Compile();

            var mb = typeBuilder.DefineMethod("foo", MethodAttributes.Public);

            mb.SetReturnType(typeof(string));
            mb.SetParameters(typeof(int));
            mb.DefineParameter(1, ParameterAttributes.None, "val");
            builder = new MethodBodyBuilder(mb, typeof(int));
            builder.AddStatements(
                Expr.IfThen(Expr.Parameter(1, typeof(int)), Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Constant("aha!"))),
                Expr.Return(Expr.Call(
                                Expr.Call(
                                    Expr.New(typeof(StringBuilder)),
                                    typeof(StringBuilder).GetMethod("AppendFormat", new[] { typeof(string), typeof(object), typeof(object) }),
                                    Expr.Constant("{0}_{1}"),
                                    Expr.ReadField(fieldBuilder),
                                    Expr.Convert(Expr.Parameter(1, typeof(int)), typeof(object))),
                                typeof(StringBuilder).GetMethod("ToString", new Type[0]))));
            Console.WriteLine(builder.ToString());

            builder.Compile();

            mb = typeBuilder.DefineMethod("bar", MethodAttributes.Public);
            mb.SetReturnType(typeof(string));
            mb.SetParameters(typeof(string));
            mb.DefineParameter(1, ParameterAttributes.None, "text");

            builder = new MethodBodyBuilder(mb, typeof(string));

            builder.AddStatements(
                Expr.Return(
                    Expr.Call(typeof(string).GetMethod("Format", new[] { typeof(string), typeof(object), typeof(object) }), Expr.Constant("Result: {0}-{1}"),
                              Expr.IfThenElse(
                                  Expr.Parameter(1, typeof(string)),
                                  Expr.Call(typeof(string).GetMethod("Format", new[] { typeof(string), typeof(object) }), Expr.Constant("Date: {0}"), Expr.Convert(Expr.Parameter(1, typeof(string)), typeof(object))),
                                  Expr.Constant("Undefined!")),
                              Expr.Convert(Expr.Convert(Expr.Convert(Expr.Constant(16), typeof(object)), typeof(int)), typeof(object)))
                    ));

            Console.WriteLine(builder.ToString());

            builder.Compile();


            mb = typeBuilder.DefineMethod("tryFinally", MethodAttributes.Public);
            mb.SetParameters(typeof(string));
            mb.SetReturnType(typeof(void));
            mb.DefineParameter(1, ParameterAttributes.None, "value");

            builder = new MethodBodyBuilder(mb, typeof(string));

            builder.AddStatements(
                Expr.TryFinally(
                    Expr.IfThenElse(Expr.Parameter(1, typeof(string)),
                                    Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Parameter(1, typeof(string))),
                                    Expr.Throw(Expr.New(typeof(Exception), Expr.Constant("No string provided!")))),
                    Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Constant("finally!")))
                );

            Console.WriteLine(builder.ToString());
            builder.Compile();


            mb = typeBuilder.DefineMethod("tryCatchFinally", MethodAttributes.Public);
            mb.SetParameters(typeof(string));
            mb.SetReturnType(typeof(void));
            mb.DefineParameter(1, ParameterAttributes.None, "value");

            builder = new MethodBodyBuilder(mb, typeof(string));
            var loc1 = Expr.LocalVariable(typeof(Exception), "e");

            builder.AddStatements(
                Expr.TryCatchFinally(
                    Expr.IfThenElse(Expr.Parameter(1, typeof(string)),
                                    Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Parameter(1, typeof(string))),
                                    Expr.Throw(Expr.New(typeof(ArgumentNullException), Expr.Constant("No string provided!")))),
                    Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Constant("finally!")),
                    new CatchBlock(typeof(ArgumentNullException), loc1, Expr.Rethrow())
                    ));

            Console.WriteLine(builder.ToString());
            builder.Compile();


            mb = typeBuilder.DefineMethod("localVar", MethodAttributes.Public);
            mb.SetReturnType(typeof(void));


            var var1 = Expr.LocalVariable(typeof(string), "o");
            var var2 = Expr.LocalVariable(typeof(int), "i");

            builder = new MethodBodyBuilder(mb, typeof(string));
            builder.AddStatements(
                Expr.DeclareLocal(var1, Expr.Constant("High {0}!")),
                Expr.DeclareLocal(var2, Expr.Constant(5)),
                Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string), typeof(object) }), Expr.ReadLocal(var1), Expr.Convert(Expr.ReadLocal(var2), typeof(object))));

            Console.WriteLine(builder.ToString());
            builder.Compile();

            mb = typeBuilder.DefineMethod("negNot", MethodAttributes.Public);
            mb.SetReturnType(typeof(int));
            mb.SetParameters(typeof(byte));

            builder = new MethodBodyBuilder(mb, typeof(byte));
            builder.AddStatements(Expr.Return(Expr.Not(Expr.Negate(Expr.Parameter(1, typeof(byte))))));

            Console.WriteLine(builder.ToString());
            builder.Compile();

            mb = typeBuilder.DefineMethod("loop", MethodAttributes.Public);
            mb.SetReturnType(typeof(void));


            var iVar = Expr.LocalVariable(typeof(int), "i");

            builder = new MethodBodyBuilder(mb);
            builder.AddStatements(
                Expr.DeclareLocal(iVar, Expr.Constant(10)),
                Expr.Loop(Expr.IfThenElse(
                              Expr.ReadLocal(iVar),
                              Expr.Block(
                                  Expr.WriteLocal(iVar, Expr.Add(Expr.ReadLocal(iVar), Expr.Constant(-1))),
                                  Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Constant("loop!..."))),
                              Expr.LoopBreak()))
                );

            Console.WriteLine(builder.ToString());
            builder.Compile();

            mb = typeBuilder.DefineMethod("conv", MethodAttributes.Public);
            mb.SetReturnType(typeof(ulong));


            builder = new MethodBodyBuilder(mb);
            builder.AddStatements(Expr.Return(Expr.Convert(Expr.Constant(-1), typeof(ulong))));

            Console.WriteLine(builder.ToString());
            builder.Compile();


            mb = typeBuilder.DefineMethod("intTS", MethodAttributes.Public);
            mb.SetReturnType(typeof(string));


            builder = new MethodBodyBuilder(mb);
            builder.AddStatements(Expr.Return(Expr.Call(Expr.Constant(21), typeof(int).GetMethod("ToString", new Type[0]))));

            Console.WriteLine(builder.ToString());
            builder.Compile();

            mb = typeBuilder.DefineMethod("loadStructField", MethodAttributes.Public);
            mb.SetParameters(typeof(MyStruct));
            mb.SetReturnType(typeof(string));


            builder = new MethodBodyBuilder(mb, typeof(MyStruct));
            builder.AddStatements(Expr.Return(Expr.ReadField(Expr.Parameter(1, typeof(MyStruct)), typeof(MyStruct).GetField("MyField"))));

            Console.WriteLine(builder.ToString());
            builder.Compile();


            mb = typeBuilder.DefineMethod("saveStructField", MethodAttributes.Public);
            mb.SetParameters(typeof(MyStruct), typeof(string));
            mb.SetReturnType(typeof(MyStruct));


            builder = new MethodBodyBuilder(mb, typeof(MyStruct), typeof(string));
            builder.AddStatements(
                Expr.WriteField(Expr.Parameter(1, typeof(MyStruct)), typeof(MyStruct).GetField("MyField"), Expr.Parameter(2, typeof(string))),
                Expr.Return(Expr.Parameter(1, typeof(MyStruct))));

            Console.WriteLine(builder.ToString());
            builder.Compile();

            mb = typeBuilder.DefineMethod("createStruct", MethodAttributes.Public);
            mb.SetReturnType(typeof(MyStruct));

            builder = new MethodBodyBuilder(mb, typeof(MyStruct), typeof(string));
            builder.AddStatements(Expr.Return(Expr.New(typeof(MyStruct))));//, Expr.Constant(32L), Expr.Constant("abcd")

            Console.WriteLine(builder.ToString());
            builder.Compile();


            mb = typeBuilder.DefineMethod("catchException", MethodAttributes.Public);
            mb.SetReturnType(typeof(Exception));

            builder = new MethodBodyBuilder(mb);
            var local = Expr.LocalVariable(typeof(Exception), "e");

            builder.AddStatements(
                Expr.DeclareLocal(local),
                Expr.TryCatch(
                    Expr.Throw(Expr.New(typeof(InvalidOperationException), Expr.Constant("abc"))),
                    new CatchBlock(typeof(InvalidOperationException), local, false, Expr.Empty())),
                Expr.Return(Expr.ReadLocal(local)));

            Console.WriteLine(builder.ToString());
            builder.Compile();

            typeBuilder.CreateType();
            asmBuilder.Save(fileName);
        }
        public void Should_call_struct_instance_method()
        {
            var func = CreateFunc <string>(Expr.Return(Expr.Call(Expr.Constant(21), _toStringInfo)));

            Assert.That(func(), Is.EqualTo("21"));
        }
        public void Should_not_allow_insufficient_number_of_method_parameters()
        {
            var ex = Assert.Throws <ArgumentException>(() => Expr.Call(_formatInfo));

            Assert.That(ex.Message, Is.StringContaining("Invalid amount of parameters supplied to method: System.String Format(System.String, System.Object)"));
        }
        public void Should_allow_hierarchy_conversion_for_parameter()
        {
            var func = CreateFunc <string, string>(Expr.Return(Expr.Call(_formatInfo, Expr.Constant("Hello {0}!"), Expr.Parameter(0, typeof(string)))));

            Assert.That(func("world"), Is.EqualTo("Hello world!"));
        }
Beispiel #25
0
        /// <summary>
        /// Produces the required expression to convert values to a specific type
        /// </summary>
        /// <param name="expr">The expression that generates the values to convert</param>
        /// <param name="to">The type to convert to</param>
        /// <returns>An expression to generate values of the required type</returns>
        public static Expression Convert(Expression expr, Type to)
        {
            if (expr.Type == typeof(SqlDateTime) && (to == typeof(SqlBoolean) || to == typeof(SqlByte) || to == typeof(SqlInt16) || to == typeof(SqlInt32) || to == typeof(SqlInt64) || to == typeof(SqlDecimal) || to == typeof(SqlSingle) || to == typeof(SqlDouble)))
            {
                expr = Expression.Condition(
                    Expression.PropertyOrField(expr, nameof(SqlDateTime.IsNull)),
                    Expression.Constant(SqlDouble.Null),
                    Expression.Convert(
                        Expression.PropertyOrField(
                            Expression.Subtract(
                                Expression.Convert(expr, typeof(DateTime)),
                                Expression.Constant(SqlDateTime.MinValue)
                                ),
                            nameof(TimeSpan.TotalDays)
                            ),
                        typeof(SqlDouble)
                        )
                    );
            }

            if ((expr.Type == typeof(SqlBoolean) || expr.Type == typeof(SqlByte) || expr.Type == typeof(SqlInt16) || expr.Type == typeof(SqlInt32) || expr.Type == typeof(SqlInt64) || expr.Type == typeof(SqlDecimal) || expr.Type == typeof(SqlSingle) || expr.Type == typeof(SqlDouble)) && to == typeof(SqlDateTime))
            {
                expr = Expression.Condition(
                    NullCheck(expr),
                    Expression.Constant(SqlDateTime.Null),
                    Expression.Convert(
                        Expression.Call(
                            Expression.New(
                                typeof(DateTime).GetConstructor(new[] { typeof(int), typeof(int), typeof(int) }),
                                Expression.Constant(1900),
                                Expression.Constant(1),
                                Expression.Constant(1)
                                ),
                            typeof(DateTime).GetMethod(nameof(DateTime.MinValue.AddDays)),
                            Expression.Convert(
                                Expression.Convert(expr, typeof(SqlDouble)),
                                typeof(double)
                                )
                            ),
                        typeof(SqlDateTime)
                        )
                    );
            }

            if (expr.Type == typeof(SqlString) && to == typeof(EntityCollection))
            {
                expr = Expr.Call(() => ParseEntityCollection(Expr.Arg <SqlString>()), expr);
            }

            if (expr.Type == typeof(SqlString) && to == typeof(OptionSetValueCollection))
            {
                expr = Expr.Call(() => ParseOptionSetValueCollection(Expr.Arg <SqlString>()), expr);
            }

            if (expr.Type != to)
            {
                if (expr.Type == typeof(object) && expr is ConstantExpression constant && constant.Value == null && typeof(INullable).IsAssignableFrom(to))
                {
                    return(Expression.Constant(GetNullValue(to)));
                }

                expr = Expression.Convert(expr, to);

                if (to == typeof(SqlString))
                {
                    expr = Expr.Call(() => UseDefaultCollation(Expr.Arg <SqlString>()), expr);
                }
            }

            return(expr);
        }
        public void Should_not_allow_null_expression_in_array()
        {
            var ex = Assert.Throws <ArgumentNullException>(() => Expr.Call(_formatInfo, Expr.Constant("abs"), null));

            Assert.That(ex.Message, Is.StringContaining("arguments[1]"));
        }
Beispiel #27
0
        internal static Func <object, object> GetPropertyAccessor(PropertyInfo prop, Type targetType)
        {
            var rawParam = Expression.Parameter(typeof(object));
            var param    = SqlTypeConverter.Convert(rawParam, prop.DeclaringType);
            var value    = (Expression)Expression.Property(param, prop);

            // Extract base value from complex types
            if (value.Type.IsGenericType && value.Type.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                value = Expression.Property(value, nameof(Nullable <bool> .Value));
            }

            if (typeof(OptionMetadata).IsAssignableFrom(value.Type))
            {
                value = Expression.Property(value, nameof(OptionMetadata.Value));
            }

            if (value.Type.BaseType != null && value.Type.BaseType.IsGenericType && value.Type.BaseType.GetGenericTypeDefinition() == typeof(ManagedProperty <>))
            {
                value = Expression.Property(value, nameof(ManagedProperty <bool> .Value));
            }

            if (value.Type.BaseType != null && value.Type.BaseType.IsGenericType && value.Type.BaseType.GetGenericTypeDefinition() == typeof(ConstantsBase <>))
            {
                value = Expression.Property(value, nameof(ConstantsBase <bool> .Value));
            }

            if (value.Type.IsArray)
            {
                value = Expr.Call(() => String.Join(Expr.Arg <string>(), Expr.Arg <object[]>()), Expression.Constant(","), value);
            }

            if (value.Type == typeof(Label))
            {
                value = Expression.Property(value, nameof(Label.UserLocalizedLabel));
            }

            if (value.Type == typeof(LocalizedLabel))
            {
                value = Expression.Condition(Expression.Equal(value, Expression.Constant(null)), SqlTypeConverter.Convert(Expression.Constant(null), typeof(string)), Expression.Property(value, nameof(LocalizedLabel.Label)));
            }

            if (value.Type.IsEnum)
            {
                value = Expression.Call(value, nameof(Enum.ToString), Array.Empty <Type>());
            }

            if (typeof(MetadataBase).IsAssignableFrom(value.Type))
            {
                value = Expression.Condition(Expression.Equal(value, Expression.Constant(null)), SqlTypeConverter.Convert(Expression.Constant(null), typeof(Guid?)), Expression.Property(value, nameof(MetadataBase.MetadataId)));
            }

            var directConversionType = SqlTypeConverter.NetToSqlType(value.Type);

            if (directConversionType == typeof(SqlString) && value.Type != typeof(string))
            {
                value = Expression.Call(value, nameof(Object.ToString), Array.Empty <Type>());
            }

            var converted = SqlTypeConverter.Convert(value, directConversionType);

            if (targetType != directConversionType)
            {
                converted = SqlTypeConverter.Convert(converted, targetType);
            }

            // Return null literal if final value is null
            if (!value.Type.IsValueType)
            {
                value = Expression.Condition(Expression.Equal(value, Expression.Constant(null)), Expression.Constant(SqlTypeConverter.GetNullValue(targetType)), converted);
            }
            else
            {
                value = converted;
            }

            // Return null literal if original value is null
            if (!prop.PropertyType.IsValueType || prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable <>))
            {
                value = Expression.Condition(Expression.Equal(Expression.Property(param, prop), Expression.Constant(null)), Expression.Constant(SqlTypeConverter.GetNullValue(targetType)), value);
            }

            // Compile the function
            value = Expr.Box(value);
            var func = (Func <object, object>)Expression.Lambda(value, rawParam).Compile();

            return(func);
        }
        public void Should_not_allow_implicit_boxing_for_method_parameters()
        {
            var ex = Assert.Throws <ArgumentException>(() => Expr.Call(_formatInfo, Expr.Constant("{0}"), Expr.Constant(32)));

            Assert.That(ex.Message, Is.StringContaining("Parameter expression of type System.Int32 does not match to type: System.Object"));
        }