예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
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);
        }