Esempio n. 1
0
        private IAstNode ProcessSrcReadOperation(SrcReadOperation srcReadOperation, int operationId)
        {
            var value = AstBuildHelper.ReadMembersChain(
                AstBuildHelper.ReadLocalRA(locFrom),
                srcReadOperation.Source.MembersChain
                );

            return(WriteMappingValue(srcReadOperation, operationId, value));
        }
Esempio n. 2
0
 public void Compile(CompilationContext context)
 {
     AstBuildHelper.CallMethod(
         _setMethod,
         _targetObject,
         new List <IAstStackItem>()
     {
         _value
     }
         ).Compile(context);
 }
    /// <summary>
    /// </summary>
    /// <param name="context">The context.</param>
    /// <exception cref="Exception"></exception>
    public virtual void Compile(CompilationContext context)
    {
        var mi = PropertyInfo.GetGetMethod();

        if (mi == null)
        {
            throw new Exception("Property " + PropertyInfo.Name + " doesn't have get accessor");
        }

        AstBuildHelper.CallMethod(mi, SourceObject, null).Compile(context);
    }
Esempio n. 4
0
        private IAstRefOrValue ConvertMappingValue(
            ReadWriteSimple rwMapOp,
            int operationId,
            IAstRefOrValue sourceValue)
        {
            IAstRefOrValue convertedValue = sourceValue;

            if (rwMapOp.Converter != null)
            {
                convertedValue = AstBuildHelper.CallMethod(
                    rwMapOp.Converter.GetType().GetMethod("Invoke"),
                    new AstCastclassRef(
                        (IAstRef)AstBuildHelper.ReadMemberRV(
                            GetStoredObject(operationId, typeof(ReadWriteSimple)),
                            typeof(ReadWriteSimple).GetProperty("Converter")
                            ),
                        rwMapOp.Converter.GetType()
                        ),
                    new List <IAstStackItem>()
                {
                    sourceValue,
                    AstBuildHelper.ReadLocalRV(locState),
                }
                    );
            }
            else
            {
                if (rwMapOp.ShallowCopy && rwMapOp.Destination.MemberType == rwMapOp.Source.MemberType)
                {
                    convertedValue = sourceValue;
                }
                else
                {
                    var mi = staticConvertersManager.GetStaticConverter(rwMapOp.Source.MemberType, rwMapOp.Destination.MemberType);
                    if (mi != null)
                    {
                        convertedValue = AstBuildHelper.CallMethod(
                            mi,
                            null,
                            new List <IAstStackItem> {
                            sourceValue
                        }
                            );
                    }
                    else
                    {
                        convertedValue = ConvertByMapper(rwMapOp);
                    }
                }
            }

            return(convertedValue);
        }
Esempio n. 5
0
 private IAstNode Process_SourceFilter(IReadWriteOperation op, int operationId, IAstNode result)
 {
     return(Process_ValuesFilter(
                op,
                operationId,
                result,
                AstBuildHelper.ReadMembersChain(
                    AstBuildHelper.ReadLocalRA(locFrom),
                    op.Source.MembersChain
                    ),
                "SourceFilter",
                op.SourceFilter
                ));
 }
Esempio n. 6
0
 private IAstNode Process_DestinationFilter(IReadWriteOperation op, int operationId, IAstNode result)
 {
     return(Process_ValuesFilter(
                op,
                operationId,
                result,
                AstBuildHelper.ReadMembersChain(
                    AstBuildHelper.ReadLocalRA(locTo),
                    op.Destination.MembersChain
                    ),
                "DestinationFilter",
                op.DestinationFilter
                ));
 }
 /// <summary>
 ///   Copies an argument to local variable
 /// </summary>
 /// <param name="loc"></param>
 /// <param name="argIndex"></param>
 /// <returns></returns>
 public static IAstNode InitializeLocal(LocalBuilder loc, int argIndex)
 {
     return(new AstComplexNode
     {
         Nodes = new List <IAstNode>
         {
             new AstInitializeLocalVariable(loc),
             new AstWriteLocal
             {
                 LocalIndex = loc.LocalIndex,
                 LocalType = loc.LocalType,
                 Value = AstBuildHelper.ReadArgumentRV(argIndex, Metadata <object> .Type)
             }
         }
     });
 }
Esempio n. 8
0
        public static void BuildCreateTargetInstanceMethod(Type type, TypeBuilder typeBuilder)
        {
            if (ReflectionUtils.IsNullable(type))
            {
                type = Nullable.GetUnderlyingType(type);
            }

            MethodBuilder methodBuilder = typeBuilder.DefineMethod(
                "CreateTargetInstance",
                MethodAttributes.Public | MethodAttributes.Virtual,
                typeof(object),
                null
                );

            ILGenerator        ilGen   = methodBuilder.GetILGenerator();
            CompilationContext context = new CompilationContext(ilGen);
            IAstRefOrValue     returnValue;

            if (type.IsValueType)
            {
                LocalBuilder lb = ilGen.DeclareLocal(type);
                new AstInitializeLocalVariable(lb).Compile(context);

                returnValue =
                    new AstBox()
                {
                    Value = AstBuildHelper.ReadLocalRV(lb)
                };
            }
            else
            {
                returnValue =
                    ReflectionUtils.HasDefaultConstructor(type)
                        ?
                    new AstNewObject()
                {
                    ObjectType = type
                }
                        :
                (IAstRefOrValue) new AstConstantNull();
            }
            new AstReturn()
            {
                ReturnType  = type,
                ReturnValue = returnValue
            }.Compile(context);
        }
Esempio n. 9
0
 /// <summary>
 /// Copies an argument to local variable
 /// </summary>
 /// <Param name="loc"></Param>
 /// <Param name="argIndex"></Param>
 /// <returns></returns>
 public static IAstNode InitializeLocal(LocalBuilder loc, int argIndex)
 {
     return(new AstComplexNode()
     {
         nodes =
             new List <IAstNode>()
         {
             new AstInitializeLocalVariable(loc),
             new AstWriteLocal()
             {
                 localIndex = loc.LocalIndex,
                 localType = loc.LocalType,
                 value = AstBuildHelper.ReadArgumentRV(argIndex, typeof(object))
             }
         }
     });
 }
Esempio n. 10
0
        private IAstNode ProcessReadWriteSimple(ReadWriteSimple readWriteSimple, int operationId)
        {
            IAstRefOrValue sourceValue = ReadSrcMappingValue(readWriteSimple, operationId);

            IAstRefOrValue convertedValue;

            if (readWriteSimple.NullSubstitutor != null && (ReflectionUtils.IsNullable(readWriteSimple.Source.MemberType) || !readWriteSimple.Source.MemberType.IsValueType()))
            {
                convertedValue = new AstIfTernar(
                    ReflectionUtils.IsNullable(readWriteSimple.Source.MemberType)
                        ? (IAstValue) new AstExprNot(AstBuildHelper.ReadPropertyRV(new AstValueToAddr((IAstValue)sourceValue), readWriteSimple.Source.MemberType.GetProperty("HasValue")))
                        : new AstExprIsNull(sourceValue),
                    GetNullValue(readWriteSimple.NullSubstitutor),     // source is null
                    AstBuildHelper.CastClass(
                        ConvertMappingValue(
                            readWriteSimple,
                            operationId,
                            sourceValue
                            ),
                        readWriteSimple.Destination.MemberType
                        )
                    );
            }
            else
            {
                convertedValue =
                    ConvertMappingValue(
                        readWriteSimple,
                        operationId,
                        sourceValue
                        );
            }

            IAstNode result = WriteMappingValue(readWriteSimple, operationId, convertedValue);

            if (readWriteSimple.SourceFilter != null)
            {
                result = Process_SourceFilter(readWriteSimple, operationId, result);
            }

            if (readWriteSimple.DestinationFilter != null)
            {
                result = Process_DestinationFilter(readWriteSimple, operationId, result);
            }
            return(result);
        }
Esempio n. 11
0
 private static IAstRefOrValue CreateCallDelegate(Delegate del, ParameterInfo[] parameters)
 {
     return
         (AstBuildHelper.CallMethod(
              del.GetType().GetMethod("Invoke"),
              new AstCastclassRef(
                  AstBuildHelper.ReadFieldRV(
                      new AstReadThis()
     {
         thisType = typeof(DelegateInvokerBase)
     },
                      typeof(DelegateInvokerBase).GetField("_del", BindingFlags.NonPublic | BindingFlags.Instance)
                      ),
                  del.GetType()
                  ),
              parameters.Select((p, idx) => (IAstStackItem)AstBuildHelper.ReadArgumentRV(idx + 1, typeof(object))).ToList()
              ));
 }
Esempio n. 12
0
 private static IAstRefOrValue CreateCallMethod(MethodInfo mi, ParameterInfo[] parameters)
 {
     return
         (AstBuildHelper.CallMethod(
              mi,
              mi.IsStatic ? null :
              new AstCastclassRef(
                  AstBuildHelper.ReadFieldRV(
                      new AstReadThis()
     {
         thisType = typeof(MethodInvokerBase)
     },
                      typeof(MethodInvokerBase).GetField("targetObject", BindingFlags.NonPublic | BindingFlags.Instance)
                      ),
                  mi.DeclaringType
                  ),
              parameters.Select((p, idx) => (IAstStackItem)AstBuildHelper.ReadArgumentRV(idx + 1, typeof(object))).ToList()
              ));
 }
Esempio n. 13
0
 private IAstRefOrValue GetNullValue(Delegate nullSubstitutor)
 {
     if (nullSubstitutor != null)
     {
         var substId = AddObjectToStore(nullSubstitutor);
         return
             (AstBuildHelper.CallMethod(
                  nullSubstitutor.GetType().GetMethod("Invoke"),
                  GetStoredObject(substId, nullSubstitutor.GetType()),
                  new List <IAstStackItem>
         {
             AstBuildHelper.ReadLocalRV(locState)
         }
                  ));
     }
     else
     {
         return(new AstConstantNull());
     }
 }
Esempio n. 14
0
        public void Create_IfNull()
        {
            var type = DynamicAssemblyManager.DefineMapperType("MyClassType");
            var convertMethod = type.DefineMethod("Create_IfNull", MethodAttributes.Public, null,
                new []{typeof(SourceObject), typeof(DestinationObject), typeof(IResourceMapper<object>), typeof(object)});

            convertMethod.DefineParameter(1, ParameterAttributes.None, "source");
            convertMethod.DefineParameter(2, ParameterAttributes.None, "destination");
            convertMethod.DefineParameter(3, ParameterAttributes.None, "mapper");
            convertMethod.DefineParameter(4, ParameterAttributes.None, "context");
            var context = new CompilationContext(convertMethod.GetILGenerator());

            new AstWriteArgument(1, typeof(DestinationObject), new AstIfNull(
                (IAstRef)AstBuildHelper.ReadArgumentRA(1, typeof(DestinationObject)),
                new AstNewObject(typeof(DestinationObject), new IAstStackItem[0])))
                .Compile(context);
            new AstReturnVoid().Compile(context);
            type.CreateType();
            DynamicAssemblyManager.SaveAssembly();
        }
Esempio n. 15
0
    /// <summary>
    /// </summary>
    /// <param name="context">The context.</param>
    public void Compile(CompilationContext context)
    {
        if (!(_value is IAstRef) && !ReflectionHelper.IsNullable(_value.ItemType))
        {
            context.Emit(OpCodes.Ldc_I4_1);
        }
        else if (ReflectionHelper.IsNullable(_value.ItemType))
        {
            AstBuildHelper.ReadPropertyRV(new AstValueToAddr((IAstValue)_value), _value.ItemType.GetProperty("HasValue"))
            .Compile(context);

            context.Emit(OpCodes.Ldc_I4_0);
            context.Emit(OpCodes.Ceq);
        }
        else
        {
            _value.Compile(context);
            new AstConstantNull().Compile(context);
            context.Emit(OpCodes.Ceq);
        }
    }
Esempio n. 16
0
 private IAstNode Process_ValuesFilter(
     IReadWriteOperation op,
     int operationId,
     IAstNode result,
     IAstRefOrValue value,
     string fieldName,
     Delegate filterDelegate
     )
 {
     result = new AstComplexNode
     {
         nodes = new List <IAstNode>
         {
             new AstIf
             {
                 condition = (IAstValue)AstBuildHelper.CallMethod(
                     filterDelegate.GetType().GetMethod("Invoke"),
                     new AstCastclassRef(
                         (IAstRef)AstBuildHelper.ReadMemberRV(
                             GetStoredObject(operationId, typeof(IReadWriteOperation)),
                             typeof(IReadWriteOperation).GetProperty(fieldName)
                             ),
                         filterDelegate.GetType()
                         ),
                     new List <IAstStackItem>()
                 {
                     value,
                     AstBuildHelper.ReadLocalRV(locState),
                 }
                     ),
                 trueBranch = new AstComplexNode {
                     nodes = new List <IAstNode> {
                         result
                     }
                 }
             }
         }
     };
     return(result);
 }
Esempio n. 17
0
    /// <summary>
    ///   Builds the create target instance method.
    /// </summary>
    /// <param name="type">The type.</param>
    /// <param name="typeBuilder">The type builder.</param>
    public static void BuildCreateTargetInstanceMethod(Type type, TypeBuilder typeBuilder)
    {
        // var expr = (Expression<Func<object>>)ObjectFactory.GenerateConstructorExpression(type).ToObject();
        if (ReflectionHelper.IsNullable(type))
        {
            type = type.GetUnderlyingTypeCache();
        }

        var methodBuilder = typeBuilder.DefineMethod(
            nameof(MapperBase.CreateTargetInstance),
            MethodAttributes.Public | MethodAttributes.Virtual,
            Metadata <object> .Type,
            null);

        var            ilGen   = methodBuilder.GetILGenerator();
        var            context = new CompilationContext(ilGen);
        IAstRefOrValue returnValue;

        if (type.IsValueType)
        {
            var lb = ilGen.DeclareLocal(type);
            new AstInitializeLocalVariable(lb).Compile(context);

            returnValue = new AstBox {
                Value = AstBuildHelper.ReadLocalRV(lb)
            };
        }
        else
        {
            returnValue = ReflectionHelper.HasDefaultConstructor(type)
        ? new AstNewObject {
                ObjectType = type
            }
        : new AstConstantNull();
        }

        new AstReturn {
            ReturnType = type, ReturnValue = returnValue
        }.Compile(context);
    }
Esempio n. 18
0
        private static IAstRef GetStoredObject(int objectIndex, Type castType)
        {
            var result = (IAstRef)AstBuildHelper.ReadArrayItemRV(
                (IAstRef)AstBuildHelper.ReadFieldRA(
                    new AstReadThis()
            {
                thisType = typeof(ObjectsMapperBaseImpl)
            },
                    typeof(ObjectsMapperBaseImpl).GetField(
                        "StroredObjects",
                        BindingFlags.Instance | BindingFlags.Public
                        )
                    ),
                objectIndex
                );

            if (castType != null)
            {
                result = new AstCastclassRef(result, castType);
            }
            return(result);
        }
Esempio n. 19
0
        private static IAstNode InvokeCopyImpl(Type copiedObjectType, string copyMethodName)
        {
            var mi = typeof(MapperForCollectionImpl).GetMethod(
                copyMethodName,
                BindingFlags.Instance | BindingFlags.NonPublic
                ).MakeGenericMethod(new Type[] { ExtractElementType(copiedObjectType) });

            return(new AstReturn()
            {
                returnType = typeof(object),
                returnValue = AstBuildHelper.CallMethod(
                    mi,
                    AstBuildHelper.ReadThis(typeof(MapperForCollectionImpl)),
                    new List <IAstStackItem>
                {
                    new AstReadArgumentRef()
                    {
                        argumentIndex = 1, argumentType = typeof(object)
                    }
                }
                    )
            });
        }
Esempio n. 20
0
        private IAstRefOrValue ConvertByMapper(ReadWriteSimple mapping)
        {
            IAstRefOrValue     convertedValue;
            ObjectsMapperDescr mapper = objectsMapperManager.GetMapperInt(
                mapping.Source.MemberType,
                mapping.Destination.MemberType,
                mappingConfigurator);
            int mapperId = AddObjectToStore(mapper);

            convertedValue = AstBuildHelper.CallMethod(
                typeof(ObjectsMapperBaseImpl).GetMethod(
                    "Map",
                    new Type[] { typeof(object), typeof(object), typeof(object) }
                    ),

                new AstReadFieldRef
            {
                fieldInfo    = typeof(ObjectsMapperDescr).GetField("mapper"),
                sourceObject = GetStoredObject(mapperId, mapper.GetType())
            },

                new List <IAstStackItem>()
            {
                AstBuildHelper.ReadMembersChain(
                    AstBuildHelper.ReadLocalRA(locFrom),
                    mapping.Source.MembersChain
                    ),
                AstBuildHelper.ReadMembersChain(
                    AstBuildHelper.ReadLocalRA(locTo),
                    mapping.Destination.MembersChain
                    ),
                (IAstRef)AstBuildHelper.ReadLocalRA(locState)
            }
                );
            return(convertedValue);
        }
Esempio n. 21
0
        private IAstNode WriteMappingValue(
            IMappingOperation mappingOperation,
            int mappingItemId,
            IAstRefOrValue value)
        {
            IAstNode writeValue;

            if (mappingOperation is SrcReadOperation)
            {
                writeValue = AstBuildHelper.CallMethod(
                    typeof(ValueSetter).GetMethod("Invoke"),
                    new AstCastclassRef(
                        (IAstRef)AstBuildHelper.ReadMemberRV(
                            GetStoredObject(mappingItemId, typeof(SrcReadOperation)),
                            typeof(SrcReadOperation).GetProperty("Setter")
                            ),
                        (mappingOperation as SrcReadOperation).Setter.GetType()
                        ),
                    new List <IAstStackItem>()
                {
                    AstBuildHelper.ReadLocalRV(locTo),
                    value,
                    AstBuildHelper.ReadLocalRV(locState),
                }
                    );
            }
            else
            {
                writeValue = AstBuildHelper.WriteMembersChain(
                    (mappingOperation as IDestOperation).Destination.MembersChain,
                    AstBuildHelper.ReadLocalRA(locTo),
                    value
                    );
            }
            return(writeValue);
        }
Esempio n. 22
0
        public override MapperAction <TContext> BuildAction <TFrom, TTo>(IMappingCollection <TFrom, TTo, TContext> map)
        {
            ExportMapInformation(map);

            var convertMethod = GetOrCreateConvertor(typeof(TFrom), typeof(TTo));
            var context       = new CompilationContext(convertMethod.GetILGenerator());

            new AstWriteArgument(1, typeof(TTo), new AstIfNull(
                                     (IAstRef)AstBuildHelper.ReadArgumentRA(1, typeof(TTo)),
                                     AstBuildHelper.CastClass(AstBuildHelper.CallMethod(GetConstructOrThrowMethod(),
                                                                                        AstBuildHelper.ReadFieldRA(null, _mapperField),
                                                                                        new List <IAstStackItem> {
                new AstTypeof {
                    type = typeof(TTo)
                }
            }), typeof(TTo))
                                     )).Compile(context);

            if (map.UpdatesContext)
            {
                var funcField = _type.DefineField(GetFieldName <TFrom, TTo>(),
                                                  typeof(Func <object, object, TContext, TContext>),
                                                  FieldAttributes.Public | FieldAttributes.Static);
                _constructorValues.Add(funcField.Name, map.ContextUpdater);
//                        var sourceFuncRoot = setter.SourceRoot.Length > 0 ?
//                            AstBuildHelper.ReadMembersChain(AstBuildHelper.ReadArgumentRA(0, typeof(TFrom)), setter.SourceRoot)
//                            : AstBuildHelper.ReadArgumentRV(0, typeof(TFrom));
                var method = funcField.FieldType.GetMethod("Invoke",
                                                           new [] { typeof(object), typeof(object), typeof(TContext) });

                var contextUpdater = AstBuildHelper.CallMethod(
                    method,
                    AstBuildHelper.ReadFieldRA(null, funcField),
                    new List <IAstStackItem> {
                    AstBuildHelper.ReadArgumentRV(0, typeof(TFrom)),
                    AstBuildHelper.ReadArgumentRA(1, typeof(TTo)),
                    AstBuildHelper.ReadArgumentRA(2, typeof(TContext))
                });

                new AstWriteArgument(2, typeof(TContext), contextUpdater).Compile(context);
            }

            foreach (var iteratingSetter in map.Setters.Where(s => !s.IsIgnored))
            {
                var setter = iteratingSetter;
                if (setter.Remap)
                {
                    _mapper.RequireOneWayMap(setter.SourceType, setter.DestinationType, typeof(TFrom), typeof(TTo));
                }
                switch (setter.SourceObjectType)
                {
                case MemberEntryType.Function:
                    var funcField = _type.DefineField(GetFieldName <TFrom, TTo>(), setter.SourceFunc.GetType(),
                                                      FieldAttributes.Public | FieldAttributes.Static);
                    _constructorValues.Add(funcField.Name, setter.SourceFunc);
//                        var sourceFuncRoot = setter.SourceRoot.Length > 0 ?
//                            AstBuildHelper.ReadMembersChain(AstBuildHelper.ReadArgumentRA(0, typeof(TFrom)), setter.SourceRoot)
//                            : AstBuildHelper.ReadArgumentRV(0, typeof(TFrom));
                    var method     = funcField.FieldType.GetMethod("Invoke", new [] { typeof(object), typeof(object), typeof(TContext) });
                    var sourceFunc = AstBuildHelper.CallMethod(
                        method,
                        AstBuildHelper.ReadFieldRA(null, funcField),
                        new List <IAstStackItem> {
                        AstBuildHelper.ReadArgumentRV(0, typeof(TFrom)),
                        AstBuildHelper.ReadArgumentRA(1, typeof(TTo)),
                        AstBuildHelper.ReadArgumentRA(2, typeof(TContext))
                    });
                    if (setter.Remap)
                    {
                        var remapper    = GetOrCreateMapper(setter.SourceType, setter.DestinationType);
                        var remapMethod = AstBuildHelper.CallMethod(GetConvertMethod(setter.SourceType, setter.DestinationType),
                                                                    AstBuildHelper.ReadFieldRA(null, remapper),
                                                                    new List <IAstStackItem> {
                            sourceFunc,
                            AstBuildHelper.ReadMembersChain(AstBuildHelper.ReadArgumentRA(1, typeof(TTo)), setter.DestinationMember),
                            AstBuildHelper.ReadArgumentRA(2, typeof(TContext)),
                        });
                        var destination = AstBuildHelper.WriteMembersChain(setter.DestinationMember,
                                                                           AstBuildHelper.ReadArgumentRA(1, typeof(TTo)),
                                                                           remapMethod);
                        destination.Compile(context);
                    }
                    else
                    {
                        var destination = AstBuildHelper.WriteMembersChain(setter.DestinationMember,
                                                                           AstBuildHelper.ReadArgumentRA(1, typeof(TTo)),
                                                                           sourceFunc);
                        destination.Compile(context);
                    }
                    break;

                case MemberEntryType.Member:
                    var sourceMember = AstBuildHelper.ReadMembersChain(AstBuildHelper.ReadArgumentRA(0, typeof(TFrom)),
                                                                       setter.SourceRoot.Union(setter.SourceMember).ToArray());
                    if (setter.Remap)
                    {
                        var remapper    = GetOrCreateMapper(setter.SourceType, setter.DestinationType);
                        var remapMethod = AstBuildHelper.CallMethod(GetConvertMethod(setter.SourceType, setter.DestinationType),
                                                                    AstBuildHelper.ReadFieldRA(null, remapper),
                                                                    new List <IAstStackItem> {
                            sourceMember,
                            AstBuildHelper.ReadMembersChain(AstBuildHelper.ReadArgumentRA(1, typeof(TTo)), setter.DestinationMember),
                            AstBuildHelper.ReadArgumentRA(2, typeof(TContext)),
                        });
                        var destination = AstBuildHelper.WriteMembersChain(setter.DestinationMember,
                                                                           AstBuildHelper.ReadArgumentRA(1, typeof(TTo)),
                                                                           remapMethod);
                        destination.Compile(context);
                    }
                    else
                    {
                        var destination = AstBuildHelper.WriteMembersChain(setter.DestinationMember,
                                                                           AstBuildHelper.ReadArgumentRA(1, typeof(TTo)),
                                                                           sourceMember);
                        destination.Compile(context);
                    }
                    break;

                default:
                    throw new ArgumentOutOfRangeException(setter.SourceObjectType.ToString(), "MemberEntryType not supported");
                }
            }

            new AstReturn {
                returnValue = AstBuildHelper.ReadArgumentRV(1, typeof(TTo)), returnType = typeof(TTo)
            }.Compile(context);
            var name = convertMethod.Name;
            Func <TFrom, TTo, TContext, TTo> converter = null;

            return((from, to, contxt) => {
                if (converter == null)
                {
                    converter = (Func <TFrom, TTo, TContext, TTo>)Delegate.CreateDelegate(
                        typeof(Func <TFrom, TTo, TContext, TTo>), null,
                        _type.GetMethod(name));
                }
                return converter((TFrom)from, (TTo)to, (TContext)contxt);
            });
        }
Esempio n. 23
0
    /// <summary>
    ///   Builds the copy impl method.
    /// </summary>
    public void BuildCopyImplMethod()
    {
        if (ReflectionHelper.IsNullable(_from))
        {
            _from = _from.GetUnderlyingTypeCache();
        }

        if (ReflectionHelper.IsNullable(_to))
        {
            _to = _to.GetUnderlyingTypeCache();
        }

        var methodBuilder = _typeBuilder.DefineMethod(
            nameof(MapperBase.MapImpl),
            MethodAttributes.Public | MethodAttributes.Virtual,
            Metadata <object> .Type,
            new[] { Metadata <object> .Type, Metadata <object> .Type, Metadata <object> .Type });

        var ilGen = methodBuilder.GetILGenerator();
        var compilationContext = new CompilationContext(ilGen);

        var mapperAst = new AstComplexNode();

        var          locFrom      = ilGen.DeclareLocal(_from);
        var          locTo        = ilGen.DeclareLocal(_to);
        var          locState     = ilGen.DeclareLocal(Metadata <object> .Type);
        LocalBuilder locException = null;

        mapperAst.Nodes.Add(BuilderUtils.InitializeLocal(locFrom, 1));
        mapperAst.Nodes.Add(BuilderUtils.InitializeLocal(locTo, 2));
        mapperAst.Nodes.Add(BuilderUtils.InitializeLocal(locState, 3));

#if DEBUG
        locException = compilationContext.ILGenerator.DeclareLocal(Metadata <Exception> .Type);
#endif

        var mappingOperations = _mappingConfigurator.GetMappingOperations(_from, _to);
        var staticConverter   = _mappingConfigurator.GetStaticConvertersManager();

        mapperAst.Nodes.Add(
            new MappingOperationsProcessor
        {
            LocException            = locException,
            LocFrom                 = locFrom,
            LocState                = locState,
            LocTo                   = locTo,
            ObjectsMapperManager    = _objectsMapperManager,
            CompilationContext      = compilationContext,
            StoredObjects           = StoredObjects,
            Operations              = mappingOperations,
            MappingConfigurator     = _mappingConfigurator,
            RootOperation           = _mappingConfigurator.GetRootMappingOperation(_from, _to),
            StaticConvertersManager = staticConverter ?? StaticConvertersManager.DefaultInstance
        }.ProcessOperations());

        mapperAst.Nodes.Add(
            new AstReturn {
            ReturnType = Metadata <object> .Type, ReturnValue = AstBuildHelper.ReadLocalRV(locTo)
        });

        mapperAst.Compile(compilationContext);
    }
Esempio n. 24
0
        public void BuildCopyImplMethod()
        {
            if (ReflectionUtils.IsNullable(_from))
            {
                _from = Nullable.GetUnderlyingType(_from);
            }
            if (ReflectionUtils.IsNullable(_to))
            {
                _to = Nullable.GetUnderlyingType(_to);
            }

            MethodBuilder methodBuilder = _typeBuilder.DefineMethod(
                "MapImpl",
                MethodAttributes.Public | MethodAttributes.Virtual,
                typeof(object),
                new Type[] { typeof(object), typeof(object), typeof(object) }
                );

            ILGenerator        ilGen = methodBuilder.GetILGenerator();
            CompilationContext compilationContext = new CompilationContext(ilGen);

            AstComplexNode mapperAst    = new AstComplexNode();
            var            locFrom      = ilGen.DeclareLocal(_from);
            var            locTo        = ilGen.DeclareLocal(_to);
            var            locState     = ilGen.DeclareLocal(typeof(object));
            LocalBuilder   locException = null;

            mapperAst.Nodes.Add(BuilderUtils.InitializeLocal(locFrom, 1));
            mapperAst.Nodes.Add(BuilderUtils.InitializeLocal(locTo, 2));
            mapperAst.Nodes.Add(BuilderUtils.InitializeLocal(locState, 3));

#if DEBUG
            locException = compilationContext.ILGenerator.DeclareLocal(typeof(Exception));
#endif
            var mappingOperations = _mappingConfigurator.GetMappingOperations(_from, _to);
            StaticConvertersManager staticConverter = _mappingConfigurator.GetStaticConvertersManager();
            mapperAst.Nodes.Add(
                new MappingOperationsProcessor()
            {
                LocException            = locException,
                LocFrom                 = locFrom,
                LocState                = locState,
                LocTo                   = locTo,
                ObjectsMapperManager    = _objectsMapperManager,
                CompilationContext      = compilationContext,
                StoredObjects           = StoredObjects,
                Operations              = mappingOperations,
                MappingConfigurator     = _mappingConfigurator,
                RootOperation           = _mappingConfigurator.GetRootMappingOperation(_from, _to),
                StaticConvertersManager = staticConverter ?? StaticConvertersManager.DefaultInstance
            }.ProcessOperations()
                );
            mapperAst.Nodes.Add(
                new AstReturn()
            {
                ReturnType  = typeof(object),
                ReturnValue = AstBuildHelper.ReadLocalRV(locTo)
            }
                );

            mapperAst.Compile(compilationContext);
        }
Esempio n. 25
0
        private IAstNode ProcessDestWriteOperation(DestWriteOperation destWriteOperation, int operationId)
        {
            LocalBuilder locValueToWrite = null;

            locValueToWrite = this.compilationContext.ilGenerator.DeclareLocal(destWriteOperation.Getter.GetMethodInfo().ReturnType);

            var cmdValue = new AstWriteLocal(
                locValueToWrite,
                AstBuildHelper.CallMethod(
                    destWriteOperation.Getter.GetType().GetMethod("Invoke"),
                    new AstCastclassRef(
                        (IAstRef)AstBuildHelper.ReadMemberRV(
                            GetStoredObject(operationId, typeof(DestWriteOperation)),
                            typeof(DestWriteOperation).GetProperty("Getter")
                            ),
                        destWriteOperation.Getter.GetType()
                        ),
                    new List <IAstStackItem>
            {
                AstBuildHelper.ReadLocalRV(locFrom),
                AstBuildHelper.ReadLocalRV(locState)
            }
                    )
                );

            return
                (new AstComplexNode
            {
                nodes = new List <IAstNode>
                {
                    cmdValue,
                    new AstIf()
                    {
                        condition = new AstExprEquals(
                            (IAstValue)AstBuildHelper.ReadMembersChain(
                                AstBuildHelper.ReadLocalRA(locValueToWrite),
                                new[] { (MemberInfo)locValueToWrite.LocalType.GetField("action") }
                                ),
                            new AstConstantInt32()
                        {
                            value = 0
                        }
                            ),
                        trueBranch = new AstComplexNode
                        {
                            nodes = new List <IAstNode>
                            {
                                AstBuildHelper.WriteMembersChain(
                                    destWriteOperation.Destination.MembersChain,
                                    AstBuildHelper.ReadLocalRA(locTo),
                                    AstBuildHelper.ReadMembersChain(
                                        AstBuildHelper.ReadLocalRA(locValueToWrite),
                                        new[] { (MemberInfo)locValueToWrite.LocalType.GetField("value") }
                                        )
                                    )
                            }
                        }
                    }
                }
            });
        }
Esempio n. 26
0
        public static IAstRefOrValue Convert(
            Type destinationType,
            Type sourceType,
            IAstRefOrValue sourceValue
            )
        {
            if (destinationType == sourceValue.itemType)
            {
                return(sourceValue);
            }

            if (destinationType == typeof(string))
            {
                return
                    (new AstCallMethodRef(
                         typeof(NativeConverter).GetMethod(
                             "ObjectToString",
                             BindingFlags.NonPublic | BindingFlags.Static
                             ),
                         null,
                         new List <IAstStackItem>()
                {
                    sourceValue
                }
                         ));
            }

            foreach (var m in typeof(Convert).GetMethods(BindingFlags.Static | BindingFlags.Public))
            {
                if (m.ReturnType == destinationType)
                {
                    var parameters = m.GetParameters();
                    if (parameters.Length == 1 && parameters[0].ParameterType == sourceType)
                    {
                        return
                            (AstBuildHelper.CallMethod(
                                 m,
                                 null,
                                 new List <IAstStackItem> {
                            sourceValue
                        }
                                 ));
                    }
                }
            }

            return(AstBuildHelper.CallMethod(
                       typeof(EMConvert).GetMethod(
                           "ChangeType",
                           new[]
            {
                typeof(object),
                typeof(Type),
                typeof(Type)
            }
                           ),
                       null,
                       new List <IAstStackItem> {
                sourceValue,
                new AstTypeof()
                {
                    type = sourceType
                },
                new AstTypeof()
                {
                    type = destinationType
                }
            }
                       ));
        }
Esempio n. 27
0
        private IAstNode Process_ReadWriteComplex_Copying(ReadWriteComplex op)
        {
            var          result = new AstComplexNode();
            LocalBuilder origTempSrc, origTempDst;
            LocalBuilder tempSrc = compilationContext.ilGenerator.DeclareLocal(op.Source.MemberType);
            LocalBuilder tempDst = compilationContext.ilGenerator.DeclareLocal(op.Destination.MemberType);

            origTempSrc = tempSrc;
            origTempDst = tempDst;

            result.nodes.Add(
                new AstWriteLocal(tempSrc, AstBuildHelper.ReadMembersChain(AstBuildHelper.ReadLocalRA(locFrom), op.Source.MembersChain)
                                  )
                );
            result.nodes.Add(
                new AstWriteLocal(tempDst, AstBuildHelper.ReadMembersChain(AstBuildHelper.ReadLocalRA(locTo), op.Destination.MembersChain))
                );

            var writeNullToDest =
                new List <IAstNode>
            {
                AstBuildHelper.WriteMembersChain(
                    op.Destination.MembersChain,
                    AstBuildHelper.ReadLocalRA(locTo),
                    GetNullValue(op.NullSubstitutor)
                    )
            };

            // Target construction
            var initDest = new List <IAstNode>();
            var custCtr  = op.TargetConstructor;

            if (custCtr != null)
            {
                int custCtrIdx = AddObjectToStore(custCtr);
                initDest.Add(
                    new AstWriteLocal(
                        tempDst,
                        AstBuildHelper.CallMethod(
                            custCtr.GetType().GetMethod("Invoke"),
                            GetStoredObject(custCtrIdx, custCtr.GetType()),
                            null
                            )
                        )
                    );
            }
            else
            {
                initDest.Add(
                    new AstWriteLocal(tempDst, new AstNewObject(op.Destination.MemberType, null))
                    );
            }

            var copying = new List <IAstNode>();

            // if destination is nullable, create a temp target variable with underlying destination type
            if (ReflectionUtils.IsNullable(op.Source.MemberType))
            {
                tempSrc = compilationContext.ilGenerator.DeclareLocal(Nullable.GetUnderlyingType(op.Source.MemberType));
                copying.Add(
                    new AstWriteLocal(
                        tempSrc,
                        AstBuildHelper.ReadPropertyRV(
                            AstBuildHelper.ReadLocalRA(origTempSrc),
                            op.Source.MemberType.GetProperty("Value")
                            )
                        )
                    );
            }

            // If destination is null, initialize it.
            if (ReflectionUtils.IsNullable(op.Destination.MemberType) || !op.Destination.MemberType.IsValueType())
            {
                copying.Add(
                    new AstIf()
                {
                    condition = ReflectionUtils.IsNullable(op.Destination.MemberType)
                                                        ? (IAstValue) new AstExprNot((IAstValue)AstBuildHelper.ReadPropertyRV(AstBuildHelper.ReadLocalRA(origTempDst), op.Destination.MemberType.GetProperty("HasValue")))
                                                        : new AstExprIsNull(AstBuildHelper.ReadLocalRV(origTempDst)),
                    trueBranch = new AstComplexNode()
                    {
                        nodes = initDest
                    }
                }
                    );
                if (ReflectionUtils.IsNullable(op.Destination.MemberType))
                {
                    tempDst = compilationContext.ilGenerator.DeclareLocal(Nullable.GetUnderlyingType(op.Destination.MemberType));
                    copying.Add(
                        new AstWriteLocal(
                            tempDst,
                            AstBuildHelper.ReadPropertyRV(
                                AstBuildHelper.ReadLocalRA(origTempDst),
                                op.Destination.MemberType.GetProperty("Value")
                                )
                            )
                        );
                }
            }

            // Suboperations
            copying.Add(
                new AstComplexNode()
            {
                nodes = new List <IAstNode>
                {
                    new MappingOperationsProcessor(this)
                    {
                        operations    = op.Operations,
                        locTo         = tempDst,
                        locFrom       = tempSrc,
                        rootOperation = mappingConfigurator.GetRootMappingOperation(op.Source.MemberType, op.Destination.MemberType)
                    }.ProcessOperations()
                }
            }
                );

            IAstRefOrValue processedValue;

            if (ReflectionUtils.IsNullable(op.Destination.MemberType))
            {
                processedValue =
                    new AstNewObject(
                        op.Destination.MemberType,
                        new[]
                {
                    AstBuildHelper.ReadLocalRV(tempDst)
                }
                        );
            }
            else
            {
                processedValue = AstBuildHelper.ReadLocalRV(origTempDst);
            }

            if (op.ValuesPostProcessor != null)
            {
                int postProcessorId = AddObjectToStore(op.ValuesPostProcessor);
                processedValue =
                    AstBuildHelper.CallMethod(
                        op.ValuesPostProcessor.GetType().GetMethod("Invoke"),
                        GetStoredObject(postProcessorId, op.ValuesPostProcessor.GetType()),
                        new List <IAstStackItem>
                {
                    processedValue,
                    AstBuildHelper.ReadLocalRV(locState)
                }
                        );
            }

            copying.Add(
                AstBuildHelper.WriteMembersChain(
                    op.Destination.MembersChain,
                    AstBuildHelper.ReadLocalRA(locTo),
                    processedValue
                    )
                );

            if (ReflectionUtils.IsNullable(op.Source.MemberType) || !op.Source.MemberType.IsValueType())
            {
                result.nodes.Add(
                    new AstIf()
                {
                    condition = ReflectionUtils.IsNullable(op.Source.MemberType)
                                                        ? (IAstValue) new AstExprNot((IAstValue)AstBuildHelper.ReadPropertyRV(AstBuildHelper.ReadLocalRA(origTempSrc), op.Source.MemberType.GetProperty("HasValue")))
                                                        : new AstExprIsNull(AstBuildHelper.ReadLocalRV(origTempSrc)),
                    trueBranch = new AstComplexNode()
                    {
                        nodes = writeNullToDest
                    },
                    falseBranch = new AstComplexNode()
                    {
                        nodes = copying
                    }
                }
                    );
            }
            else
            {
                result.nodes.AddRange(copying);
            }
            return(result);
        }
Esempio n. 28
0
        public void Compile(CompilationContext context)
        {
            if (ReflectionUtils.IsNullable(ObjectType))
            {
                IAstRefOrValue underlyingValue;
                var            underlyingType = Nullable.GetUnderlyingType(ObjectType);
                if (ConstructorParams == null || ConstructorParams.Length == 0)
                {
                    LocalBuilder temp = context.ILGenerator.DeclareLocal(underlyingType);
                    new AstInitializeLocalVariable(temp).Compile(context);
                    underlyingValue = AstBuildHelper.ReadLocalRV(temp);
                }
                else
                {
                    underlyingValue = (IAstValue)ConstructorParams[0];
                }

                ConstructorInfo constructor = ObjectType.GetConstructor(
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance,
                    null,
                    new[] { underlyingType },
                    null);

                underlyingValue.Compile(context);
                context.EmitNewObject(constructor);
            }
            else
            {
                Type[] types;
                if (ConstructorParams == null || ConstructorParams.Length == 0)
                {
                    types = new Type[0];
                }
                else
                {
                    types = ConstructorParams.Select(c => c.ItemType).ToArray();
                    foreach (var p in ConstructorParams)
                    {
                        p.Compile(context);
                    }
                }

                ConstructorInfo ci = ObjectType.GetConstructor(types);
                if (ci != null)
                {
                    context.EmitNewObject(ci);
                }
                else if (ObjectType.IsValueType)
                {
                    LocalBuilder temp = context.ILGenerator.DeclareLocal(ObjectType);
                    new AstInitializeLocalVariable(temp).Compile(context);
                    AstBuildHelper.ReadLocalRV(temp).Compile(context);
                }
                else
                {
                    throw new Exception(
                              String.Format("Constructor for types [{0}] not found in {1}", types.ToCSV(","), ObjectType.FullName)
                              );
                }
            }
        }