private static Expression GetConversionOrCreationExpression(
            this IMemberMapperData mapperData,
            Expression value,
            Type targetType,
            IList <ConfiguredObjectFactory> valueFactories)
        {
            var simpleMemberMapperData = SimpleMemberMapperData.Create(value, mapperData);

            var checkNestedAccesses =
                simpleMemberMapperData.TargetMemberIsEnumerableElement() &&
                value.Type.CanBeNull();

            var replacements = FixedSizeExpressionReplacementDictionary
                               .WithEquivalentKeys(3)
                               .Add(simpleMemberMapperData.SourceObject, value)
                               .Add(simpleMemberMapperData.TargetObject, mapperData.GetTargetMemberAccess())
                               .Add(simpleMemberMapperData.ElementIndex, simpleMemberMapperData.ElementIndexValue);

            var conversions = valueFactories.ProjectToArray(vf =>
            {
                var factoryExpression = vf.Create(simpleMemberMapperData);
                var condition         = vf.GetConditionOrNull(simpleMemberMapperData);

                if (checkNestedAccesses)
                {
                    var nestedAccessChecks = NestedAccessChecksFactory
                                             .GetNestedAccessChecksFor(factoryExpression);

                    if (nestedAccessChecks != null)
                    {
                        condition = condition != null
                            ? Expression.AndAlso(nestedAccessChecks, condition)
                            : nestedAccessChecks;
                    }
                }

                return(new SimpleTypeValueFactory
                {
                    Factory = factoryExpression.Replace(replacements).GetConversionTo(targetType),
                    Condition = condition?.Replace(replacements)
                });
            });

            if (conversions.Last().Condition != null)
            {
                conversions = conversions.Append(new SimpleTypeValueFactory
                {
                    Factory = mapperData.GetValueConversion(value, targetType) ??
                              simpleMemberMapperData.GetTargetMemberDefault()
                });
            }
            else if (conversions.Length == 1)
            {
                return(conversions[0].Factory);
            }

            return(GetConversionExpression(conversions));
        }
        public Expression Inject(Type[] contextTypes, IMemberMapperData mapperData)
        {
            if (mapperData.MappingDataObject.Type.IsAssignableTo(_contextType))
            {
                return(_lambda.ReplaceParameterWith(mapperData.MappingDataObject));
            }

            var args    = new ValueInjectionArgs(_lambda, _configInfo, contextTypes, mapperData);
            var context = args.GetAppropriateMappingContext();

            if (_isMappingContextInvokeLambda)
            {
                return(args.GetInvocationContextArgument(context));
            }

            var targetContextTypes = _contextType.GetGenericTypeArguments();
            var contextType        = context.IsCallback(targetContextTypes) ? _contextType : _contextType.GetAllInterfaces().First();

            var requiredValues = GetRequiredValues();

            var replacements = FixedSizeExpressionReplacementDictionary
                               .WithEquivalentKeys(requiredValues.ValuesCount);

            if (requiredValues.Includes(Parent))
            {
                replacements.Add(PropertyAccess(nameof(Parent), contextType), context.GetParentAccess());
            }

            if (requiredValues.Includes(Source))
            {
                replacements.Add(PropertyAccess(RootSourceMemberName, contextType), context.GetSourceAccess());
            }

            if (requiredValues.Includes(Target))
            {
                replacements.Add(PropertyAccess(RootTargetMemberName, contextType), context.GetTargetAccess());
            }

            if (requiredValues.Includes(CreatedObject))
            {
                replacements.Add(PropertyAccess(nameof(CreatedObject), contextType), context.GetCreatedObject());
            }

            if (requiredValues.Includes(ElementIndex))
            {
                replacements.Add(PropertyAccess(nameof(ElementIndex), contextType), context.GetElementIndex());
            }

            if (requiredValues.Includes(ElementKey))
            {
                replacements.Add(PropertyAccess(nameof(ElementKey), contextType), context.GetElementKey());
            }

            return(_lambda.Body.Replace(replacements));
        }
            protected override Expression GetFilterExpression(Expression sourceValue, ref bool hasFixedValueOperands)
            {
                var conditionReplacements = FixedSizeExpressionReplacementDictionary.WithEqualKeys(_filterConditions.Count);

                foreach (var filterCondition in _filterConditions)
                {
                    conditionReplacements.Add(
                        filterCondition.Filter,
                        filterCondition.GetConditionReplacement(sourceValue, ref hasFixedValueOperands));
                }

                return(ValuesFilter.Replace(conditionReplacements));
            }
Ejemplo n.º 4
0
        public static Expression GetDirectAccessMapping(
            Expression mapping,
            IMemberMapperData mapperData,
            MappingValues mappingValues,
            Expression createMappingDataCall)
        {
            var useLocalSourceValueVariable =
                ShouldUseLocalSourceValueVariable(mappingValues.SourceValue, mapping, mapperData);

            Expression sourceValue, sourceValueVariableValue;

            if (useLocalSourceValueVariable)
            {
                var sourceValueVariableName = mappingValues.SourceValue.Type.GetSourceValueVariableName();
                sourceValue = Expression.Variable(mappingValues.SourceValue.Type, sourceValueVariableName);
                sourceValueVariableValue = mappingValues.SourceValue;
            }
            else
            {
                sourceValue = mappingValues.SourceValue;
                sourceValueVariableValue = null;
            }

            var replacementsByTarget = FixedSizeExpressionReplacementDictionary
                                       .WithEquivalentKeys(4)
                                       .Add(mapperData.SourceObject, sourceValue)
                                       .Add(mapperData.TargetObject, mappingValues.TargetValue)
                                       .Add(mapperData.ElementKey, mappingValues.ElementKey)
                                       .Add(
                mapperData.ElementIndex,
                mappingValues.ElementIndex.GetConversionTo(mapperData.ElementIndex.Type));

            mapping = mapping
                      .Replace(replacementsByTarget)
                      .Replace(mapperData.MappingDataObject, createMappingDataCall);

            return(useLocalSourceValueVariable
                ? UseLocalValueVariable(
                       (ParameterExpression)sourceValue,
                       sourceValueVariableValue,
                       mapping,
                       mapperData)
                : mapping);
        }
            public override Expression Inject(Type[] contextTypes, IMemberMapperData mapperData)
            {
                var replacements = _isInvocation
                    ? FixedSizeExpressionReplacementDictionary.WithEqualKeys(RequiredValuesCount)
                    : FixedSizeExpressionReplacementDictionary.WithEquivalentKeys(RequiredValuesCount);

                var context = CreateContext(contextTypes, mapperData);

                if (_requiredValues.Includes(MappingContext))
                {
                    replacements.Add(_requiredValues.MappingContext, context.GetMappingDataAccess());
                }

                if (_requiredValues.Includes(Source))
                {
                    replacements.Add(_requiredValues.Source, context.GetSourceAccess());
                }

                if (_requiredValues.Includes(Target))
                {
                    replacements.Add(_requiredValues.Target, context.GetTargetAccess());
                }

                if (_requiredValues.Includes(CreatedObject))
                {
                    replacements.Add(_requiredValues.CreatedObject, context.GetCreatedObject());
                }

                if (_requiredValues.Includes(ElementIndex))
                {
                    replacements.Add(_requiredValues.ElementIndex, context.GetElementIndex());
                }

                if (_requiredValues.Includes(ElementKey))
                {
                    replacements.Add(_requiredValues.ElementKey, context.GetElementKey());
                }

                return(_lambdaBody.Replace(replacements));
            }
        protected override Expression GetTargetObjectCreation(
            IObjectMappingData mappingData,
            IList <Expression> memberPopulations)
        {
            var objectCreation = base.GetTargetObjectCreation(mappingData, memberPopulations);

            if (objectCreation == null)
            {
                memberPopulations.Clear();
                return(null);
            }

            if (memberPopulations.None())
            {
                return(objectCreation);
            }

            var memberBindings = GetMemberBindingsFrom(memberPopulations);

            if (memberBindings.None())
            {
                return(objectCreation);
            }

            var objectNewings      = NewExpressionFinder.FindIn(objectCreation);
            var newingReplacements = FixedSizeExpressionReplacementDictionary.WithEqualKeys(objectNewings.Count);

            foreach (var objectNewing in objectNewings)
            {
                var objectInit = Expression.MemberInit(objectNewing, memberBindings);

                newingReplacements.Add(objectNewing, objectInit);
            }

            var fullObjectInit = objectCreation.Replace(newingReplacements);

            return(fullObjectInit);
        }
Ejemplo n.º 7
0
        private static Expression CacheMultiInvocationResults(
            IList <Expression> multiInvocations,
            IList <ParameterExpression> variables,
            Expression populationExpressions)
        {
            var multiInvocationsCount = multiInvocations.Count;
            var cachedValuesCount     = multiInvocationsCount - 1;

            var valueVariablesByInvocation = FixedSizeExpressionReplacementDictionary
                                             .WithEquivalentKeys(cachedValuesCount);

            var previousValueVariableAssignment = default(Expression);
            var previousInvocation    = default(Expression);
            var previousValueVariable = default(ParameterExpression);

            for (var i = 0; i < multiInvocationsCount; ++i)
            {
                var invocation       = multiInvocations[i];
                var valueVariable    = variables[i];
                var isLastInvocation = i == cachedValuesCount;

                var valueVariableValue = invocation;

                for (var j = 0; j < i; ++j)
                {
                    valueVariableValue = valueVariableValue.Replace(
                        valueVariablesByInvocation.Keys[j],
                        valueVariablesByInvocation.Values[j],
                        ExpressionEvaluation.Equivalator);
                }

                if (!isLastInvocation)
                {
                    valueVariablesByInvocation.Add(valueVariableValue, valueVariable);
                }

                populationExpressions = populationExpressions.Replace(
                    valueVariableValue,
                    valueVariable,
                    ExpressionEvaluation.Equivalator);

                Expression valueVariableAssignment;

                if ((previousInvocation != null) && invocation.IsRootedIn(previousInvocation))
                {
                    var chainedValueVariableInvocation = valueVariableValue
                                                         .Replace(previousValueVariable, previousValueVariableAssignment);

                    valueVariableAssignment = valueVariable.AssignTo(chainedValueVariableInvocation);

                    var chainedAssignmentPopulation = populationExpressions.Replace(
                        chainedValueVariableInvocation,
                        valueVariableAssignment,
                        ExpressionEvaluation.Equivalator,
                        replacementCount: 1);

                    if (chainedAssignmentPopulation != populationExpressions)
                    {
                        populationExpressions = chainedAssignmentPopulation;

                        if (isLastInvocation)
                        {
                            return(populationExpressions);
                        }

                        goto SetPreviousValues;
                    }
                }

                valueVariableAssignment = valueVariable.AssignTo(valueVariableValue);

                populationExpressions = populationExpressions.ReplaceParameter(
                    valueVariable,
                    valueVariableAssignment,
                    replacementCount: 1);

SetPreviousValues:
                previousInvocation              = invocation;
                previousValueVariable           = valueVariable;
                previousValueVariableAssignment = valueVariableAssignment;
            }

            return(populationExpressions);
        }