Exemplo n.º 1
0
        public ExpressionSyntax AddExplicitConvertTo(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, ITypeSymbol type)
        {
            var displayType = type.ToMinimalDisplayString(_semanticModel, vbNode.SpanStart);

            if (csNode is InvocationExpressionSyntax invoke &&
                invoke.Expression is MemberAccessExpressionSyntax expr &&
                expr.Expression is IdentifierNameSyntax name && name.Identifier.ValueText == "Conversions" &&
                expr.Name.Identifier.ValueText == $"To{displayType}")
            {
                return(csNode);
            }

            var method = typeof(Microsoft.VisualBasic.CompilerServices.Conversions).GetMethod($"To{displayType}");

            if (method == null)
            {
                throw new NotImplementedException($"Unimplemented conversion for {displayType}");
            }

            // Need to use Conversions rather than Convert to match what VB does, eg. True -> -1
            _extraUsingDirectives.Add("Microsoft.VisualBasic.CompilerServices");
            var memberAccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                    SyntaxFactory.IdentifierName("Conversions"), SyntaxFactory.IdentifierName($"To{displayType}"));
            var arguments = SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(csNode)));

            return(SyntaxFactory.InvocationExpression(memberAccess, arguments));
        }
Exemplo n.º 2
0
        private ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded)
        {
            var vbConvertedType = _semanticModel.GetTypeInfo(vbNode).ConvertedType;

            switch (conversionKind)
            {
            case TypeConversionKind.Unknown:
            case TypeConversionKind.Identity:
                return(addParenthesisIfNeeded ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode) : csNode);

            case TypeConversionKind.DestructiveCast:
            case TypeConversionKind.NonDestructiveCast:
                var typeName = (TypeSyntax)_csSyntaxGenerator.TypeExpression(vbConvertedType);
                if (csNode is CastExpressionSyntax cast && cast.Type.IsEquivalentTo(typeName))
                {
                    return(csNode);
                }
                return(ValidSyntaxFactory.CastExpression(typeName, csNode));

            case TypeConversionKind.Conversion:
                return(AddExplicitConvertTo(vbNode, csNode, vbConvertedType));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemplo n.º 3
0
        public ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, bool addParenthesisIfNeeded = false, bool alwaysExplicit = false, bool implicitCastFromIntToEnum = false)
        {
            var conversionKind = AnalyzeConversion(vbNode, csNode, alwaysExplicit, implicitCastFromIntToEnum, out var vbConvertedType);

            csNode = addParenthesisIfNeeded && conversionKind == TypeConversionKind.Implicit
                ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode)
                : csNode;
            return(AddExplicitConversion(vbNode, csNode, vbConvertedType, conversionKind, addParenthesisIfNeeded));
        }
            private VB.Syntax.ForStatementSyntax CreateForStatement(CS.Syntax.ForStatementSyntax node)
            {
                string variableName = node.Declaration.Variables[0].Identifier.ValueText;

                VB.Syntax.ForStepClauseSyntax stepClause = CreateForStepClause(node);
                VB.Syntax.ExpressionSyntax    toValue    = CreateForToValue(node);
                return(VB.SyntaxFactory.ForStatement(
                           controlVariable: VB.SyntaxFactory.IdentifierName(variableName),
                           fromValue: nodeVisitor.VisitExpression(node.Declaration.Variables[0].Initializer.Value),
                           toValue: toValue,
                           stepClause: stepClause));
            }
Exemplo n.º 5
0
        private void VisitMethodsEx(SyntaxNodeAnalysisContext ctx)
        {
            var node = ctx.Node as Microsoft.CodeAnalysis.VisualBasic.Syntax.MethodBlockSyntax;

            if (node == null)
            { //Not the expected node type
                return;
            }

            //Iterating over the list of annotation for a given method
            foreach (var attribute in node.BlockStatement.AttributeLists)
            {
                if (attribute.Attributes.Count == 0)
                {
                    continue;                                  //Bound check .. Unlikely to happens
                }
                var att = attribute.Attributes[0];
                //Extract the annotation identifier
                var identifier = att.Name as Microsoft.CodeAnalysis.VisualBasic.Syntax.IdentifierNameSyntax;

                if (identifier == null)
                {
                    continue;
                }

                if (identifier.Identifier.Text == "ValidateInput")
                {
                    var hasArgumentFalse = false;
                    Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax expression = null;
                    foreach (var arg in att.ArgumentList.Arguments)
                    {
                        var literal = arg.GetExpression() as Microsoft.CodeAnalysis.VisualBasic.Syntax.LiteralExpressionSyntax;
                        if (literal.Token.ValueText == "false")
                        {
                            hasArgumentFalse = true;
                            expression       = arg.GetExpression();
                        }
                    }

                    if (hasArgumentFalse && expression != null)
                    {
                        ctx.ReportDiagnostic(Diagnostic.Create(Rule, expression.GetLocation()));
                    }
                }
            }
        }
Exemplo n.º 6
0
        private ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode,
                                                       ITypeSymbol vbConvertedType, TypeConversionKind conversionKind, bool addParenthesisIfNeeded)
        {
            switch (conversionKind)
            {
            case TypeConversionKind.Unknown:
            case TypeConversionKind.Identity:
                return(addParenthesisIfNeeded ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode) : csNode);

            case TypeConversionKind.Implicit:
                return(ValidSyntaxFactory.CastExpression(_semanticModel.GetCsTypeSyntax(vbConvertedType, vbNode), csNode));

            case TypeConversionKind.Explicit:
                return(AddExplicitConvertTo(vbNode, csNode, vbConvertedType));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
            private VB.Syntax.ExpressionSyntax CreateForToValue(CS.Syntax.ForStatementSyntax node)
            {
                VB.Syntax.ExpressionSyntax expression = nodeVisitor.VisitExpression(((CS.Syntax.BinaryExpressionSyntax)node.Condition).Right);

                if (!node.Condition.IsKind(CS.SyntaxKind.LessThanOrEqualExpression) &&
                    !node.Condition.IsKind(CS.SyntaxKind.GreaterThanOrEqualExpression))
                {
                    if (node.Condition.IsKind(CS.SyntaxKind.LessThanExpression))
                    {
                        return(VB.SyntaxFactory.SubtractExpression(
                                   expression, CreateOneExpression()));
                    }

                    if (node.Condition.IsKind(CS.SyntaxKind.GreaterThanExpression))
                    {
                        return(VB.SyntaxFactory.AddExpression(
                                   expression, CreateOneExpression()));
                    }
                }

                return(expression);
            }
    public static IOperation GetExpressionOperation(this SemanticModel semanticModel, Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax expressionSyntax)
    {
        var op = semanticModel.GetOperation(expressionSyntax);

        while (true)
        {
            switch (op)
            {
            case IArgumentOperation argumentOperation:
                op = argumentOperation.Value;
                continue;

            case IConversionOperation conversionOperation:
                op = conversionOperation.Operand;
                continue;

            case IParenthesizedOperation parenthesizedOperation:
                op = parenthesizedOperation.Operand;
                continue;

            default:
                return(op);
            }
        }
    }
 public void VisitInvocationAndCreation(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax node, Microsoft.CodeAnalysis.VisualBasic.Syntax.ArgumentListSyntax argList, ExecutionState state)
 {
 }
Exemplo n.º 10
0
        private TypeConversionKind AnalyzeConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, bool alwaysExplicit, bool implicitCastFromIntToEnum, out ITypeSymbol vbConvertedType)
        {
            var typeInfo = _semanticModel.GetTypeInfo(vbNode);
            var vbType   = typeInfo.Type;

            vbConvertedType = typeInfo.ConvertedType;
            if (vbType is null || vbConvertedType is null)
            {
                return(TypeConversionKind.Unknown);
            }

            if (vbType.IsEnumType())
            {
                if (vbConvertedType.IsNumericType())
                {
                    return(TypeConversionKind.Implicit);
                }
                else if (vbType.Equals(vbConvertedType) ||
                         (vbConvertedType.IsNullable() && vbType.Equals(vbConvertedType.GetNullableUnderlyingType())) ||
                         vbConvertedType.SpecialType == SpecialType.System_Object)
                {
                    return(TypeConversionKind.Identity);
                }
                else
                {
                    return(TypeConversionKind.Explicit);
                }
            }

            var vbCompilation = _semanticModel.Compilation as Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilation;
            var vbConversion  = vbCompilation.ClassifyConversion(vbType, vbConvertedType);

            var csType          = _csCompilation.GetTypeByMetadataName(vbType.GetFullMetadataName());
            var csConvertedType = _csCompilation.GetTypeByMetadataName(vbConvertedType.GetFullMetadataName());

            if (csType == null || csConvertedType == null)
            {
                if (alwaysExplicit && vbType != vbConvertedType)
                {
                    return(TypeConversionKind.Implicit);
                }
                return(TypeConversionKind.Unknown);
            }

            var csConversion = _csCompilation.ClassifyConversion(csType, csConvertedType);

            bool isConvertToString = vbConversion.IsString && vbConvertedType.SpecialType == SpecialType.System_String;
            bool isArithmetic      = vbNode.IsKind(Microsoft.CodeAnalysis.VisualBasic.SyntaxKind.AddExpression,
                                                   Microsoft.CodeAnalysis.VisualBasic.SyntaxKind.SubtractExpression,
                                                   Microsoft.CodeAnalysis.VisualBasic.SyntaxKind.MultiplyExpression,
                                                   Microsoft.CodeAnalysis.VisualBasic.SyntaxKind.DivideExpression,
                                                   Microsoft.CodeAnalysis.VisualBasic.SyntaxKind.IntegerDivideExpression);

            if (!csConversion.Exists || csConversion.IsUnboxing)
            {
                if (isConvertToString || vbConversion.IsNarrowing)
                {
                    return(TypeConversionKind.Explicit);
                }
            }
            else if (vbConversion.IsWidening && vbConversion.IsNumeric && csConversion.IsImplicit && csConversion.IsNumeric)
            {
                // Safe overapproximation: A cast is really only needed to help resolve the overload for the operator/method used.
                // e.g. When VB "&" changes to C# "+", there are lots more overloads available that implicit casts could match.
                // e.g. sbyte * ulong uses the decimal * operator in VB. In C# it's ambiguous - see ExpressionTests.vb "TestMul".
                var typeName = _semanticModel.GetCsTypeSyntax(vbConvertedType, vbNode);
                if (csNode is CastExpressionSyntax cast && cast.Type.IsEquivalentTo(typeName))
                {
                    return(TypeConversionKind.Identity);
                }
                return(TypeConversionKind.Implicit);
            }
            else if (csConversion.IsExplicit && csConversion.IsEnumeration)
            {
                return(implicitCastFromIntToEnum ? TypeConversionKind.Identity : TypeConversionKind.Implicit);
            }
            else if (csConversion.IsExplicit && vbConversion.IsNumeric && vbType.TypeKind != TypeKind.Enum)
            {
                return(TypeConversionKind.Explicit);
            }
            else if (isArithmetic)
            {
                var arithmeticConversion =
                    vbCompilation.ClassifyConversion(vbConvertedType, vbCompilation.GetTypeByMetadataName("System.Int32"));
                if (arithmeticConversion.IsWidening && !arithmeticConversion.IsIdentity)
                {
                    return(TypeConversionKind.Explicit);
                }
            }
            else if (alwaysExplicit && vbType != vbConvertedType)
            {
                return(TypeConversionKind.Implicit);
            }

            return(TypeConversionKind.Identity);
        }