Exemple #1
0
        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);
        }
Exemple #2
0
 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);
 }
Exemple #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);
        }
        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);
        }
Exemple #5
0
    /// <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);
    }