private IAstNode Process_ReadWriteComplex_ByConverter(ReadWriteComplex op, int operationId) { IAstNode result; result = AstBuildHelper.WriteMembersChain( op.Destination.MembersChain, AstBuildHelper.ReadLocalRA(locTo), AstBuildHelper.CallMethod( op.Converter.GetType().GetMethod("Invoke"), new AstCastclassRef( (IAstRef)AstBuildHelper.ReadMemberRV( GetStoredObject(operationId, typeof(ReadWriteComplex)), typeof(ReadWriteComplex).GetProperty("Converter") ), op.Converter.GetType() ), new List <IAstStackItem>() { AstBuildHelper.ReadMembersChain( AstBuildHelper.ReadLocalRA(locFrom), op.Source.MembersChain ), AstBuildHelper.ReadLocalRV(locState), } ) ); return(result); }
private IAstNode Process_ReadWriteComplex(ReadWriteComplex op, int operationId) { IAstNode result; if (op.Converter != null) { result = Process_ReadWriteComplex_ByConverter(op, operationId); } else { result = Process_ReadWriteComplex_Copying(op); } if (op.SourceFilter != null) { result = Process_SourceFilter(op, operationId, result); } if (op.DestinationFilter != null) { result = Process_DestinationFilter(op, operationId, 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); }