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