Example #1
0
        public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression)
        {
            var sourceElementType = TypeHelper.GetElementType(sourceExpression.Type);
            var destElementType   = TypeHelper.GetElementType(destExpression.Type);

            var allowNullCollections = propertyMap?.TypeMap.Profile.AllowNullCollections ??
                                       configurationProvider.Configuration.AllowNullCollections;
            var ifNullExpr = allowNullCollections
                                 ? (Expression)Constant(null, destExpression.Type)
                                 : NewArrayBounds(destElementType, Constant(0));

            ParameterExpression itemParam;
            var itemExpr = typeMapRegistry.MapItemExpr(configurationProvider, propertyMap, sourceExpression.Type, destExpression.Type, contextExpression, out itemParam);

            //var count = source.Count();
            //var array = new TDestination[count];

            //int i = 0;
            //foreach (var item in source)
            //    array[i++] = newItemFunc(item, context);
            //return array;

            var countParam = Parameter(typeof(int), "count");
            var arrayParam = Parameter(destExpression.Type, "destinationArray");
            var indexParam = Parameter(typeof(int), "destinationArrayIndex");

            var actions    = new List <Expression>();
            var parameters = new List <ParameterExpression> {
                countParam, arrayParam, indexParam
            };

            var countMethod = typeof(Enumerable)
                              .GetTypeInfo()
                              .DeclaredMethods
                              .Single(mi => mi.Name == "Count" && mi.GetParameters().Length == 1)
                              .MakeGenericMethod(sourceElementType);

            actions.Add(Assign(countParam, Call(countMethod, sourceExpression)));
            actions.Add(Assign(arrayParam, NewArrayBounds(destElementType, countParam)));
            actions.Add(Assign(indexParam, Constant(0)));
            actions.Add(ForEach(sourceExpression, itemParam,
                                Assign(ArrayAccess(arrayParam, PostIncrementAssign(indexParam)), itemExpr)
                                ));
            actions.Add(arrayParam);

            var mapExpr = Block(parameters, actions);

            // return (source == null) ? ifNullExpr : Map<TSourceElement, TDestElement>(source, context);
            return(Condition(Equal(sourceExpression, Constant(null)), ifNullExpr, mapExpr));
        }
Example #2
0
        public Expression MapExpression(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider, PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression)
        {
            var sourceElementType = TypeHelper.GetElementType(sourceExpression.Type);
            var destElementType   = TypeHelper.GetElementType(destExpression.Type);

            if (destExpression.Type.IsAssignableFrom(sourceExpression.Type) && configurationProvider.ResolveTypeMap(sourceElementType, destElementType) == null)
            {
                // return (TDestination[]) source;
                var convertExpr = Expression.Convert(sourceExpression, destElementType.MakeArrayType());

                if (configurationProvider.Configuration.AllowNullCollections)
                {
                    return(convertExpr);
                }

                // return (TDestination[]) source ?? new TDestination[0];
                return(Expression.Coalesce(convertExpr, Expression.NewArrayBounds(destElementType, Expression.Constant(0))));
            }

            var ifNullExpr = configurationProvider.Configuration.AllowNullCollections
                                 ? (Expression)Expression.Constant(null, destExpression.Type)
                                 : Expression.NewArrayBounds(destElementType, Expression.Constant(0));

            var itemParam = Expression.Parameter(sourceElementType, "item");
            var itemExpr  = typeMapRegistry.MapItemExpr(configurationProvider, propertyMap, sourceExpression.Type, destExpression.Type, itemParam, contextExpression);

            //var count = source.Count();
            //var array = new TDestination[count];

            //int i = 0;
            //foreach (var item in source)
            //    array[i++] = newItemFunc(item, context);
            //return array;

            var countParam = Expression.Parameter(typeof(int), "count");
            var arrayParam = Expression.Parameter(destExpression.Type, "destinationArray");
            var indexParam = Expression.Parameter(typeof(int), "destinationArrayIndex");

            var actions    = new List <Expression>();
            var parameters = new List <ParameterExpression> {
                countParam, arrayParam, indexParam
            };

            var countMethod = typeof(Enumerable)
                              .GetTypeInfo()
                              .DeclaredMethods
                              .Single(mi => mi.Name == "Count" && mi.GetParameters().Length == 1)
                              .MakeGenericMethod(sourceElementType);

            actions.Add(Expression.Assign(countParam, Expression.Call(countMethod, sourceExpression)));
            actions.Add(Expression.Assign(arrayParam, Expression.NewArrayBounds(destElementType, countParam)));
            actions.Add(Expression.Assign(indexParam, Expression.Constant(0)));
            actions.Add(ExpressionExtensions.ForEach(sourceExpression, itemParam,
                                                     Expression.Assign(Expression.ArrayAccess(arrayParam, Expression.PostIncrementAssign(indexParam)), itemExpr)
                                                     ));
            actions.Add(arrayParam);

            var mapExpr = Expression.Block(parameters, actions);

            // return (source == null) ? ifNullExpr : Map<TSourceElement, TDestElement>(source, context);
            return(Expression.Condition(Expression.Equal(sourceExpression, Expression.Constant(null)), ifNullExpr, mapExpr));
        }