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);

            if (elementPopulation == Constants.EmptyExpression)
            {
                return(elementPopulation);
            }

            var loopBody = GetLoopBody(loopData, builder, breakLoop, elementPopulation);

            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);
        }
        public SourceElementsDictionaryPopulationLoopData(
            DictionaryEntryVariablePair dictionaryVariables,
            EnumerablePopulationBuilder builder)
        {
            _dictionaryVariables = dictionaryVariables;
            _builder             = builder;

            var sourceDictionaryMember = dictionaryVariables.SourceMember;

            _performElementChecks =
                ElementTypesAreSimple ||
                sourceDictionaryMember.HasObjectEntries ||
                (builder.Context.ElementTypesAreAssignable && !sourceDictionaryMember.ValueType.IsSimple());

            _targetMemberKey = dictionaryVariables
                               .GetTargetMemberDictionaryEnumerableElementKey(builder.Counter, MapperData);

            _useDirectValueAccess = ElementTypesAreSimple
                ? builder.Context.ElementTypesAreAssignable
                : sourceDictionaryMember.HasObjectEntries;

            var useSeparateTargetKeyVariable = !ElementTypesAreSimple && _performElementChecks;

            _targetElementKey = useSeparateTargetKeyVariable
                ? Expression.Variable(typeof(string), "targetElementKey")
                : dictionaryVariables.Key;

            _sourceElement     = _useDirectValueAccess ? GetDictionaryEntryValueAccess() : dictionaryVariables.Value;
            ContinueLoopTarget = Expression.Label(typeof(void), "Continue");
            LoopExitCheck      = MapperData.IsRoot ? GetRootLoopExitCheck() : GetKeyNotFoundLoopExitCheck();
        }
        private static BlockExpression GetLoopBody(
            IPopulationLoopData loopData,
            EnumerablePopulationBuilder builder,
            Expression breakLoop,
            Expression elementPopulation)
        {
            var ifExitCheckBreakLoop = Expression.IfThen(loopData.LoopExitCheck, breakLoop);
            var counterIncrement     = builder.GetCounterIncrement();

            elementPopulation = ApplySourceFilterIfAppropriate(elementPopulation, loopData, builder);

            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 SourceElementsDictionaryAdapter(
     DictionarySourceMember sourceMember,
     EnumerablePopulationBuilder builder)
     : base(builder)
 {
     _dictionaryVariables = new DictionaryEntryVariablePair(sourceMember, builder.MapperData);
 }
 public DictionaryPopulationBuilder(EnumerablePopulationBuilder wrappedBuilder)
 {
     _wrappedBuilder         = wrappedBuilder;
     _sourceDictionaryMember = wrappedBuilder.MapperData.GetDictionarySourceMemberOrNull();
     _targetDictionaryMember = (DictionaryTargetMember)MapperData.TargetMember;
     _mappingExpressions     = new List <Expression>();
 }
        private static Expression ApplySourceFilterIfAppropriate(
            Expression elementPopulation,
            IPopulationLoopData loopData,
            EnumerablePopulationBuilder builder)
        {
            if (!builder.MapperData.MapperContext.UserConfigurations.HasSourceValueFilters)
            {
                return(elementPopulation);
            }

            var sourceElement = loopData.GetSourceElementValue();

            var sourceValueFilters = builder.MapperData
                                     .GetSourceValueFilters(sourceElement.Type);

            if (sourceValueFilters.None())
            {
                return(elementPopulation);
            }

            var sourceFilterConditions = sourceValueFilters
                                         .GetFilterConditionsOrNull(sourceElement, builder.MapperData);

            return((sourceFilterConditions != null)
                ? Expression.IfThen(sourceFilterConditions, elementPopulation)
                : elementPopulation);
        }
 public SourceObjectDictionaryAdapter(
     DictionarySourceMember sourceMember,
     EnumerablePopulationBuilder builder)
     : base(builder)
 {
     _instanceDictionaryAdapter = new SourceInstanceDictionaryAdapter(sourceMember, builder);
     _emptyTarget = TargetTypeHelper.GetEmptyInstanceCreation(TargetTypeHelper.EnumerableInterfaceType);
 }
 public SourceInstanceDictionaryAdapter(
     DictionarySourceMember sourceMember,
     EnumerablePopulationBuilder builder)
     : base(builder)
 {
     _defaultAdapter     = new DefaultSourceEnumerableAdapter(builder);
     DictionaryVariables = new DictionaryEntryVariablePair(sourceMember, builder.MapperData);
 }
Esempio n. 9
0
        public SourceObjectDictionaryPopulationLoopData(
            Expression emptyTarget,
            DictionaryEntryVariablePair dictionaryVariables,
            EnumerablePopulationBuilder builder)
        {
            _emptyTarget = emptyTarget;
            _builder     = builder;

            _enumerableLoopData         = new EnumerableSourcePopulationLoopData(builder);
            _elementsDictionaryLoopData = new SourceElementsDictionaryPopulationLoopData(dictionaryVariables, builder);
            _sourceEnumerableFound      = Parameters.Create <bool>("sourceEnumerableFound");

            ContinueLoopTarget = Expression.Label(typeof(void), "Continue");
            LoopExitCheck      = GetCompositeLoopExitCheck();
        }
        public EnumerableSourcePopulationLoopData(
            EnumerablePopulationBuilder builder,
            Type elementType,
            Expression enumerableSubject)
        {
            Builder            = builder;
            _enumerableSubject = enumerableSubject;

            _getEnumeratorMethod = typeof(IEnumerable <>).MakeGenericType(elementType).GetPublicInstanceMethod("GetEnumerator");
            _enumerator          = Expression.Variable(_getEnumeratorMethod.ReturnType, "enumerator");

            ContinueLoopTarget = Expression.Label(typeof(void), "Continue");
            LoopExitCheck      = Expression.Not(Expression.Call(_enumerator, typeof(IEnumerator).GetPublicInstanceMethod("MoveNext")));
            SourceElement      = Expression.Property(_enumerator, "Current");
        }
        public IndexedSourcePopulationLoopData(EnumerablePopulationBuilder builder)
        {
            _builder           = builder;
            ContinueLoopTarget = Expression.Label(typeof(void), "Continue");
            LoopExitCheck      = Expression.Equal(builder.Counter, builder.GetSourceCountAccess());

            _indexedSourceAccess = builder.GetSourceIndexAccess();

            _useDirectValueAccess =
                builder.TargetElementsAreSimple ||
                builder.SourceTypeHelper.ElementType.RuntimeTypeNeeded() ||
                builder.TargetTypeHelper.ElementType.RuntimeTypeNeeded();

            _sourceElement = _useDirectValueAccess
                ? _indexedSourceAccess
                : builder.Context.GetSourceParameterFor(builder.SourceTypeHelper.ElementType);
        }
Esempio n. 12
0
        private static Expression GetForwardLinkSelection(Expression sourceEnumerable,
                                                          ParameterExpression linkParameter,
                                                          Member forwardLink,
                                                          IMemberMapperData mapperData)
        {
            var funcTypes         = new[] { linkParameter.Type, forwardLink.Type };
            var forwardLinkAccess = forwardLink.GetAccess(linkParameter);

            var forwardLinkLambda = Expression.Lambda(
                Expression.GetFuncType(funcTypes),
                forwardLinkAccess,
                linkParameter);

            return(Expression.Call(
                       EnumerablePopulationBuilder
                       .GetProjectionMethodFor(mapperData)
                       .MakeGenericMethod(funcTypes),
                       sourceEnumerable,
                       forwardLinkLambda));
        }
Esempio n. 13
0
        public static ISourceEnumerableAdapter GetAdapterFor(EnumerablePopulationBuilder builder)
        {
            var dictionarySourceMember = builder.MapperData.GetDictionarySourceMemberOrNull();

            if (dictionarySourceMember != null)
            {
                if (!builder.MapperData.IsRoot)
                {
                    if (dictionarySourceMember.HasObjectEntries)
                    {
                        return(new SourceObjectDictionaryAdapter(dictionarySourceMember, builder));
                    }

                    if (dictionarySourceMember.CouldContainSourceInstance)
                    {
                        return(new SourceInstanceDictionaryAdapter(dictionarySourceMember, builder));
                    }
                }

                return(new SourceElementsDictionaryAdapter(dictionarySourceMember, builder));
            }

            return(new DefaultSourceEnumerableAdapter(builder));
        }
Esempio n. 14
0
 public DefaultSourceEnumerableAdapter(EnumerablePopulationBuilder builder)
     : base(builder)
 {
 }
 protected SourceEnumerableAdapterBase(EnumerablePopulationBuilder builder)
 {
     Builder = builder;
 }
 public EnumerableSourcePopulationLoopData(EnumerablePopulationBuilder builder)
     : this(builder, builder.SourceTypeHelper.ElementType, builder.SourceValue)
 {
 }
Esempio n. 17
0
 public static BinaryExpression GetSourceEnumerableFoundTest(
     Expression emptyTarget,
     EnumerablePopulationBuilder builder)
 {
     return(Expression.NotEqual(builder.SourceValue, emptyTarget));
 }