Esempio n. 1
0
        public MappingElement MapExpression(MappingElement source, ITypeSymbol targetType, MappingContext mappingContext, MappingPath mappingPath = null)
        {
            if (source == null)
            {
                return(null);
            }

            if (mappingPath == null)
            {
                mappingPath = new MappingPath();
            }

            var sourceType = source.ExpressionType;

            if (mappingPath.AddToMapped(sourceType) == false)
            {
                return(new MappingElement()
                {
                    ExpressionType = sourceType,
                    Expression = source.Expression.WithTrailingTrivia(SyntaxFactory.Comment(" /* Stop recursive mapping */"))
                });
            }


            if (mappingContext.FindConversion(sourceType, targetType) is {} userDefinedConversion)
            {
                return(new MappingElement()
                {
                    ExpressionType = targetType,
                    Expression = (ExpressionSyntax)syntaxGenerator.InvocationExpression(userDefinedConversion, source.Expression)
                });
            }


            if (ObjectHelper.IsSimpleType(targetType) && SymbolHelper.IsNullable(sourceType, out var underlyingType))
            {
                source = new MappingElement()
                {
                    Expression     = (ExpressionSyntax)syntaxGenerator.MemberAccessExpression(source.Expression, "Value"),
                    ExpressionType = underlyingType
                };
            }

            if (IsUnwrappingNeeded(targetType, source))
            {
                return(TryToUnwrap(targetType, source, mappingContext));
            }

            if (ShouldCreateConversionBetweenTypes(targetType, sourceType))
            {
                return(TryToCreateMappingExpression(source, targetType, mappingPath, mappingContext));
            }

            return(source);
        }
Esempio n. 2
0
        public async Task <MappingElement> MapExpression(MappingElement source, AnnotatedType targetType, MappingContext mappingContext, MappingPath mappingPath = null)
        {
            if (source == null)
            {
                return(null);
            }

            if (mappingPath == null)
            {
                mappingPath = new MappingPath();
            }

            var sourceType = source.ExpressionType;

            if (mappingPath.AddToMapped(sourceType.Type) == false)
            {
                return(new MappingElement()
                {
                    ExpressionType = sourceType,
                    Expression = source.Expression.WithTrailingTrivia(SyntaxFactory.Comment(" /* Stop recursive mapping */")),
                });
            }

            if (mappingContext.FindConversion(sourceType, targetType) is {} userDefinedConversion)
            {
                //TODO: Check if conversion accept nullable type
                var invocationExpression  = (ExpressionSyntax)syntaxGenerator.InvocationExpression(userDefinedConversion.Conversion, source.Expression);
                var protectResultFromNull = targetType.CanBeNull == false && userDefinedConversion.ToType.CanBeNull;
                var conversionExpression  = protectResultFromNull ? OrFailWhenExpressionNull(invocationExpression) : invocationExpression;
                return(new MappingElement
                {
                    ExpressionType = targetType,
                    Expression = HandleSafeNull(source, userDefinedConversion.FromType, conversionExpression)
                });
            }


            if (ObjectHelper.IsSimpleType(targetType.Type) && SymbolHelper.IsNullable(sourceType.Type, out var underlyingType))
            {
                return(new MappingElement
                {
                    Expression = OrFailWhenArgumentNull(source.Expression),
                    ExpressionType = new AnnotatedType(underlyingType, false)
                });
            }

            if (IsConversionToSimpleTypeNeeded(targetType.Type, source.ExpressionType.Type))
            {
                var conversion = ConvertToSimpleType(targetType, source, mappingContext);
                if (targetType.CanBeNull == false && conversion.ExpressionType.CanBeNull)
                {
                    return(new MappingElement
                    {
                        ExpressionType = conversion.ExpressionType.AsNotNull(),
                        Expression = OrFailWhenArgumentNull(conversion.Expression)
                    });
                }
                return(conversion);
            }

            if (ShouldCreateConversionBetweenTypes(targetType.Type, sourceType.Type))
            {
                return(await  TryToCreateMappingExpression(source, targetType, mappingPath, mappingContext).ConfigureAwait(false));
            }


            if (source.ExpressionType.Type.Equals(targetType.Type) && source.ExpressionType.CanBeNull && targetType.CanBeNull == false)
            {
                return(new MappingElement
                {
                    Expression = OrFailWhenArgumentNull(source.Expression),
                    ExpressionType = source.ExpressionType.AsNotNull()
                });
            }
            return(source);
        }