Example #1
0
        private async Task <SyntaxNode> MapCollectionsAsync(MappingElement source, AnnotatedType targetListType, MappingPath mappingPath, MappingContext mappingContext)
        {
            var isReadonlyCollection  = ObjectHelper.IsReadonlyCollection(targetListType.Type);
            var sourceListElementType = MappingHelper.GetElementType(source.ExpressionType.Type);
            var targetListElementType = MappingHelper.GetElementType(targetListType.Type);

            if (sourceListElementType.CanBeNull && targetListElementType.CanBeNull == false)
            {
                var whereFilter         = SyntaxFactoryExtensions.CreateMethodAccessExpression(source.Expression, source.ExpressionType.CanBeNull, $"OfType<{sourceListElementType.Type.Name}>");
                var lambdaParameterName = NameHelper.CreateLambdaParameterName(source.Expression);
                var mappingLambda       = await CreateMappingLambdaAsync(lambdaParameterName, sourceListElementType.AsNotNull(), targetListElementType, mappingPath, mappingContext).ConfigureAwait(false);

                var selectExpression = SyntaxFactoryExtensions.CreateMethodAccessExpression(whereFilter, false, "Select", mappingLambda);
                var toList           = AddMaterializeCollectionInvocation(syntaxGenerator, selectExpression, targetListType.Type, false);
                return(MappingHelper.WrapInReadonlyCollectionIfNecessary(toList, isReadonlyCollection, syntaxGenerator));
            }

            if (ShouldCreateConversionBetweenTypes(targetListElementType.Type, sourceListElementType.Type))
            {
                var useConvert          = CanUseConvert(source.ExpressionType.Type);
                var mapMethod           = useConvert ? "ConvertAll": "Select";
                var lambdaParameterName = NameHelper.CreateLambdaParameterName(source.Expression);
                var mappingLambda       = await CreateMappingLambdaAsync(lambdaParameterName, sourceListElementType, targetListElementType, mappingPath, mappingContext).ConfigureAwait(false);

                var selectExpression = SyntaxFactoryExtensions.CreateMethodAccessExpression(source.Expression, source.ExpressionType.CanBeNull, mapMethod, mappingLambda);
                var toList           = useConvert? selectExpression: AddMaterializeCollectionInvocation(syntaxGenerator, selectExpression, targetListType.Type, false);
                return(MappingHelper.WrapInReadonlyCollectionIfNecessary(toList, isReadonlyCollection, syntaxGenerator));
            }

            var toListInvocation = AddMaterializeCollectionInvocation(syntaxGenerator, source.Expression, targetListType.Type, source.ExpressionType.CanBeNull);

            return(MappingHelper.WrapInReadonlyCollectionIfNecessary(toListInvocation, isReadonlyCollection, syntaxGenerator));
        }
Example #2
0
        private MappingElement ConvertToSimpleType(AnnotatedType targetType, MappingElement source, MappingContext mappingContext)
        {
            var conversion = semanticModel.Compilation.ClassifyConversion(source.ExpressionType.Type, targetType.Type);

            if (conversion.Exists == false)
            {
                var wrapper = GetWrappingInfo(source.ExpressionType.Type, targetType.Type, mappingContext);
                if (wrapper.Type == WrapperInfoType.ObjectField)
                {
                    return(new MappingElement
                    {
                        Expression = SyntaxFactoryExtensions.CreateMemberAccessExpression(source.Expression, source.ExpressionType.CanBeNull, wrapper.UnwrappingObjectField.Name),
                        ExpressionType = wrapper.UnwrappingObjectField.Type
                    });
                }
                if (wrapper.Type == WrapperInfoType.Method)
                {
                    return(new MappingElement
                    {
                        Expression = SyntaxFactoryExtensions.CreateMethodAccessExpression(source.Expression, source.ExpressionType.CanBeNull, wrapper.UnwrappingMethod.Name),
                        ExpressionType = new AnnotatedType(wrapper.UnwrappingMethod.ReturnType)
                    });
                }

                if (targetType.Type.SpecialType == SpecialType.System_String && source.ExpressionType.Type.TypeKind == TypeKind.Enum)
                {
                    var toStringAccess = SyntaxFactoryExtensions.CreateMethodAccessExpression(source.Expression, source.ExpressionType.CanBeNull, "ToString");
                    return(new MappingElement
                    {
                        Expression = toStringAccess,
                        ExpressionType = targetType
                    });
                }

                if (source.ExpressionType.Type.SpecialType == SpecialType.System_String && targetType.Type.TypeKind == TypeKind.Enum)
                {
                    var parseEnumAccess = syntaxGenerator.MemberAccessExpression(SyntaxFactory.ParseTypeName("System.Enum"), "Parse");
                    var enumType        = SyntaxFactory.ParseTypeName(targetType.Type.Name);
                    var parseInvocation = (InvocationExpressionSyntax)syntaxGenerator.InvocationExpression(parseEnumAccess, new[]
                    {
                        syntaxGenerator.TypeOfExpression(enumType),
                        source.Expression,
                        syntaxGenerator.TrueLiteralExpression()
                    });

                    return(new MappingElement()
                    {
                        Expression = (ExpressionSyntax)syntaxGenerator.CastExpression(enumType, parseInvocation),
                        ExpressionType = targetType.AsNotNull()
                    });
                }
            }
            else if (conversion.IsExplicit)
            {
                return(new MappingElement()
                {
                    Expression = (ExpressionSyntax)syntaxGenerator.CastExpression(targetType.Type, source.Expression),
                    ExpressionType = targetType
                });
            }
            return(source);
        }