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));
        }
        private SyntaxNode MapCollections(SyntaxNode sourceAccess, ITypeSymbol sourceListType, ITypeSymbol targetListType, MappingPath mappingPath)
        {
            var isReadonlyCollection  = ObjectHelper.IsReadonlyCollection(targetListType);
            var sourceListElementType = MappingHelper.GetElementType(sourceListType);
            var targetListElementType = MappingHelper.GetElementType(targetListType);

            if (ShouldCreateConversionBetweenTypes(targetListElementType, sourceListElementType))
            {
                var useConvert          = CanUseConvert(sourceListType);
                var selectAccess        = useConvert ?   syntaxGenerator.MemberAccessExpression(sourceAccess, "ConvertAll"): syntaxGenerator.MemberAccessExpression(sourceAccess, "Select");
                var lambdaParameterName = NameHelper.CreateLambdaParameterName(sourceAccess);
                var mappingLambda       = CreateMappingLambda(lambdaParameterName, sourceListElementType, targetListElementType, mappingPath);
                var selectInvocation    = syntaxGenerator.InvocationExpression(selectAccess, mappingLambda);
                var toList = useConvert? selectInvocation: AddMaterializeCollectionInvocation(syntaxGenerator, selectInvocation, targetListType);
                return(MappingHelper.WrapInReadonlyCollectionIfNecessary(toList, isReadonlyCollection, syntaxGenerator));
            }

            var toListInvocation = AddMaterializeCollectionInvocation(syntaxGenerator, sourceAccess, targetListType);

            return(MappingHelper.WrapInReadonlyCollectionIfNecessary(toListInvocation, isReadonlyCollection, syntaxGenerator));
        }