public IAstNode ProcessOperations() { var result = new AstComplexNode(); foreach (var operation in operations) { IAstNode completeOperation = null; int operationId = AddObjectToStore(operation); if (operation is OperationsBlock) { completeOperation = new MappingOperationsProcessor(this) { operations = (operation as OperationsBlock).Operations }.ProcessOperations(); } else if (operation is ReadWriteComplex) { completeOperation = Process_ReadWriteComplex(operation as ReadWriteComplex, operationId); } else if (operation is DestSrcReadOperation) { completeOperation = ProcessDestSrcReadOperation(operation as DestSrcReadOperation, operationId); } else if (operation is SrcReadOperation) { completeOperation = ProcessSrcReadOperation(operation as SrcReadOperation, operationId); } else if (operation is DestWriteOperation) { completeOperation = ProcessDestWriteOperation(operation as DestWriteOperation, operationId); } else if (operation is ReadWriteSimple) { completeOperation = ProcessReadWriteSimple(operation as ReadWriteSimple, operationId); } if (completeOperation == null) { continue; } if (locException != null) { var tryCatch = CreateExceptionHandlingBlock(operationId, completeOperation); result.nodes.Add(tryCatch); } else { result.nodes.Add(completeOperation); } } return(result); }
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); }
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 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); }
/// <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); }