Exemplo n.º 1
0
    public (ExpressionSyntax Expr, bool IsCorrectType) GetConstantOrNull(VBSyntax.ExpressionSyntax vbNode, ITypeSymbol type, TypeConversionAnalyzer.TypeConversionKind analyzedConversionKind, ExpressionSyntax csNode)
    {
        var vbOperation = _semanticModel.GetOperation(vbNode).SkipParens(true);

        // Guideline tradeoff: Usually would aim for erring on the side of correct runtime behaviour. But making lots of simple constants unreadable for the sake of an edge case that will turn into an easily fixed compile error seems overkill.
        // See https://github.com/icsharpcode/CodeConverter/blob/master/.github/CONTRIBUTING.md#deciding-what-the-output-should-be
        bool isExactType = analyzedConversionKind == TypeConversionAnalyzer.TypeConversionKind.Identity;

        if ((isExactType || analyzedConversionKind == TypeConversionAnalyzer.TypeConversionKind.NonDestructiveCast) &&
            IsProbablyConstExpression(vbOperation))
        {
            return(csNode, isExactType);
        }

        if (TryCompileTimeEvaluate(vbOperation, out var result))
        {
            if (type.Name == "Char" && result is int resultInt)
            {
                result = Strings.ChrW(resultInt);
            }
            else if (ConversionsTypeFullNames.TryGetValue(type.GetFullMetadataName(), out var method))
            {
                result = method.Invoke(null, new[] { result });
            }
            return(LiteralConversions.GetLiteralExpression(result, convertedType: type), true);
        }

        return(null, false);
    }
Exemplo n.º 2
0
        private async Task <ExpressionSyntax> ConvertToStringComparisonOperatorAsync(VBSyntax.BinaryExpressionSyntax node, SyntaxKind expressionKind)
        {
            var(lhs, rhs) = await AcceptSidesAsync(node);

            lhs = VisualBasicEqualityComparison.VbCoerceToString(lhs, _semanticModel.GetTypeInfo(node.Left));
            rhs = VisualBasicEqualityComparison.VbCoerceToString(rhs, _semanticModel.GetTypeInfo(node.Right));
            var member = new KnownMethod(_compilerServices, _operators, "CompareString");
            var optionaCompareTextBoolLiteralExpression = _visualBasicEqualityComparison.OptionCompareTextCaseInsensitiveBoolExpression;
            var comparedLhs = member.Invoke(_visualBasicEqualityComparison.ExtraUsingDirectives, lhs, rhs, optionaCompareTextBoolLiteralExpression);

            return(SyntaxFactory.BinaryExpression(expressionKind, comparedLhs, LiteralConversions.GetLiteralExpression(0)));
        }
    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);
        }
    }
Exemplo n.º 4
0
 public static ExpressionSyntax Literal(object o, string textForUser = null, ITypeSymbol convertedType = null) => LiteralConversions.GetLiteralExpression(o, textForUser, convertedType);