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