private ExpressionSyntax AddTypeConversion(VBSyntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded, ITypeSymbol vbType, ITypeSymbol vbConvertedType) { switch (conversionKind) { case TypeConversionKind.FractionalNumberRoundThenCast: csNode = vbType.IsNullable() && vbConvertedType.IsNullable() ? _vbNullableExpressionsConverter.InvokeConversionWhenNotNull(csNode, GetMathRoundMemberAccess(), GetTypeSyntax(vbConvertedType)) : AddRoundInvocation(vbType.IsNullable() ? csNode.NullableGetValueExpression() : csNode); return(AddTypeConversion(vbNode, csNode, TypeConversionKind.NonDestructiveCast, addParenthesisIfNeeded, vbType, vbConvertedType)); case TypeConversionKind.EnumConversionThenCast: vbConvertedType.IsNullable(out var convertedNullableType); var underlyingEnumType = ((INamedTypeSymbol)(convertedNullableType ?? vbConvertedType)).EnumUnderlyingType; csNode = vbType.IsNullable() && convertedNullableType != null ? _vbNullableExpressionsConverter.InvokeConversionWhenNotNull(csNode, GetConversionsMemberAccess(underlyingEnumType), GetTypeSyntax(vbConvertedType)) : AddTypeConversion(vbNode, csNode, TypeConversionKind.Conversion, addParenthesisIfNeeded, vbType, underlyingEnumType); return(AddTypeConversion(vbNode, csNode, TypeConversionKind.NonDestructiveCast, addParenthesisIfNeeded, vbType, vbConvertedType)); case TypeConversionKind.EnumCastThenConversion: var enumUnderlyingType = ((INamedTypeSymbol)vbType).EnumUnderlyingType; csNode = AddTypeConversion(vbNode, csNode, TypeConversionKind.NonDestructiveCast, addParenthesisIfNeeded, vbType, enumUnderlyingType); return(AddTypeConversion(vbNode, csNode, TypeConversionKind.Conversion, addParenthesisIfNeeded, enumUnderlyingType, vbConvertedType)); case TypeConversionKind.Unknown: case TypeConversionKind.Identity: return(addParenthesisIfNeeded ? vbNode.ParenthesizeIfPrecedenceCouldChange(csNode) : csNode); case TypeConversionKind.DestructiveCast: case TypeConversionKind.NonDestructiveCast: return(CreateCast(csNode, vbConvertedType)); case TypeConversionKind.Conversion: return(AddExplicitConvertTo(vbNode, csNode, vbType, vbConvertedType)); case TypeConversionKind.NullableBool: return(SyntaxFactory.BinaryExpression(SyntaxKind.EqualsExpression, csNode, LiteralConversions.GetLiteralExpression(true))); case TypeConversionKind.StringToCharArray: var memberAccessExpressionSyntax = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, csNode, SyntaxFactory.IdentifierName(nameof(string.ToCharArray))); return(SyntaxFactory.InvocationExpression(memberAccessExpressionSyntax, SyntaxFactory.ArgumentList())); case TypeConversionKind.DelegateConstructor: return(SyntaxFactory.ObjectCreationExpression(GetCommonDelegateTypeOrNull(vbNode, vbConvertedType)).WithArgumentList(new[] { csNode }.CreateCsArgList())); default: throw new ArgumentOutOfRangeException(nameof(conversionKind), conversionKind, null); } }
public ExpressionSyntax AddExplicitConversion(VBSyntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, bool addParenthesisIfNeeded = true, bool defaultToCast = false, bool isConst = false, ITypeSymbol forceSourceType = null, ITypeSymbol forceTargetType = null) { if (csNode == null) { return(null); } var conversionKind = AnalyzeConversion(vbNode, defaultToCast, isConst, forceSourceType, forceTargetType); csNode = addParenthesisIfNeeded && conversionKind is TypeConversionKind.DestructiveCast or TypeConversionKind.NonDestructiveCast ? vbNode.ParenthesizeIfPrecedenceCouldChange(csNode) : csNode; return(AddExplicitConversion(vbNode, csNode, conversionKind, addParenthesisIfNeeded, isConst, forceSourceType: forceSourceType, forceTargetType: forceTargetType).Expr); }