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; }
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 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; }
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; }