Ejemplo n.º 1
0
        private static BlockExpression GetLoopBody(
            IPopulationLoopData loopData,
            EnumerablePopulationBuilder builder,
            Expression breakLoop,
            Expression elementPopulation)
        {
            var ifExitCheckBreakLoop = Expression.IfThen(loopData.LoopExitCheck, breakLoop);
            var counterIncrement     = builder.GetCounterIncrement();

            if (elementPopulation.NodeType != ExpressionType.Block)
            {
                return(Expression.Block(ifExitCheckBreakLoop, elementPopulation, counterIncrement));
            }

            var elementPopulationBlock = (BlockExpression)elementPopulation;

            var loopExpressions = new Expression[elementPopulationBlock.Expressions.Count + 2];

            loopExpressions[0] = ifExitCheckBreakLoop;
            loopExpressions.CopyFrom(elementPopulationBlock.Expressions, startIndex: 1);
            loopExpressions[loopExpressions.Length - 1] = counterIncrement;

            return(elementPopulationBlock.Variables.Any()
                ? Expression.Block(elementPopulationBlock.Variables, loopExpressions)
                : Expression.Block(loopExpressions));
        }
        public static Expression BuildPopulationLoop <TLoopData>(
            this TLoopData loopData,
            EnumerablePopulationBuilder builder,
            IObjectMappingData mappingData,
            Func <TLoopData, IObjectMappingData, Expression> elementPopulationFactory)
            where TLoopData : IPopulationLoopData
        {
            // TODO: Not all enumerable mappings require the Counter
            var breakLoop = Expression.Break(Expression.Label(typeof(void), "Break"));

            var elementPopulation = elementPopulationFactory.Invoke(loopData, mappingData);

            var loopBody = Expression.Block(
                Expression.IfThen(loopData.LoopExitCheck, breakLoop),
                elementPopulation,
                builder.GetCounterIncrement());

            var populationLoop = loopData.NeedsContinueTarget
                ? Expression.Loop(loopBody, breakLoop.Target, loopData.ContinueLoopTarget)
                : Expression.Loop(loopBody, breakLoop.Target);

            var adaptedLoop = loopData.Adapt(populationLoop);

            var population = Expression.Block(
                new[] { builder.Counter },
                builder.Counter.AssignTo(ToNumericConverter <int> .Zero),
                adaptedLoop);

            return(population);
        }