public (ExpressionSyntax Expr, bool IsConst) AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded = false, bool requiresConst = false, ITypeSymbol forceSourceType = null, ITypeSymbol forceTargetType = null)
        {
            var  typeInfo        = ModelExtensions.GetTypeInfo(_semanticModel, vbNode);
            var  vbType          = forceSourceType ?? typeInfo.Type;
            var  vbConvertedType = forceTargetType ?? typeInfo.ConvertedType;
            bool resultConst     = false;

            if (requiresConst)
            {
                var(constExpression, isCorrectType) = _expressionEvaluator.GetConstantOrNull(vbNode, vbConvertedType, conversionKind, csNode);
                if (isCorrectType)
                {
                    return(constExpression, true);
                }
                if (constExpression != null)
                {
                    csNode      = constExpression ?? csNode;
                    resultConst = true;
                }
            }

            var typeConvertedResult = AddTypeConversion(vbNode, csNode, conversionKind, addParenthesisIfNeeded, vbType, vbConvertedType);

            return(typeConvertedResult, resultConst);
        }
        public (ExpressionSyntax Expr, bool IsConst) AddExplicitConversion(VBSyntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded = false, bool requiresConst = false, ITypeSymbol forceSourceType = null, ITypeSymbol forceTargetType = null)
        {
            var(vbType, vbConvertedType) = GetTypeInfo(vbNode, forceSourceType, forceTargetType);
            bool resultConst = false;

            if (requiresConst)
            {
                var(constExpression, isCorrectType) = _expressionEvaluator.GetConstantOrNull(vbNode, vbConvertedType, conversionKind, csNode);
                if (isCorrectType)
                {
                    return(constExpression, true);
                }
                if (constExpression != null)
                {
                    csNode      = constExpression ?? csNode;
                    resultConst = true;
                }
            }

            var typeConvertedResult = AddTypeConversion(vbNode, csNode, conversionKind, addParenthesisIfNeeded, vbType, vbConvertedType);

            return(typeConvertedResult, resultConst);
        }
        public ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded = false, bool isConst = false, ITypeSymbol forceTargetType = null)
        {
            var typeInfo        = ModelExtensions.GetTypeInfo(_semanticModel, vbNode);
            var vbType          = typeInfo.Type;
            var vbConvertedType = forceTargetType ?? typeInfo.ConvertedType;

            if (isConst && _expressionEvaluator.GetConstantOrNull(vbNode, vbConvertedType, csNode) is ExpressionSyntax constLiteral)
            {
                return(constLiteral);
            }

            switch (conversionKind)
            {
            case TypeConversionKind.Unknown:
            case TypeConversionKind.Identity:
                return(addParenthesisIfNeeded ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, 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()));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }