private IAstNode ProcessSrcReadOperation(SrcReadOperation srcReadOperation, int operationId) { var value = AstBuildHelper.ReadMembersChain( AstBuildHelper.ReadLocalRA(locFrom), srcReadOperation.Source.MembersChain ); return(WriteMappingValue(srcReadOperation, operationId, value)); }
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); }
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); }
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 )); }
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) } } }); }
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); }
/// <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)) } } }); }
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); }
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() )); }
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() )); }
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()); } }
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(); }
/// <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); } }
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); }
/// <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); }
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); }
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) } } ) }); }
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); }
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); }
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); }); }
/// <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); }
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); }
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") } ) ) } } } } }); }
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 } } )); }
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); }
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) ); } } }