예제 #1
0
        private static bool CheckSymbol(
            SimpleMemberInvocationExpressionInfo invocationInfo,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocationInfo.InvocationExpression, cancellationToken);

            return(SymbolUtility.IsPublicInstanceNonGeneric(methodSymbol) &&
                   methodSymbol.IsContainingType(SpecialType.System_String) &&
                   methodSymbol.IsReturnType(SpecialType.System_String) &&
                   !methodSymbol.Parameters.Any());
        }
        public static bool IsFixable(
            InvocationExpressionSyntax invocation,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (!ParentIsElementAccessOrForEachExpression(invocation.WalkUpParentheses()))
            {
                return(false);
            }

            SimpleMemberInvocationExpressionInfo info = SyntaxInfo.SimpleMemberInvocationExpressionInfo(invocation);

            if (!info.Success)
            {
                return(false);
            }

            if (info.Arguments.Any())
            {
                return(false);
            }

            if (!string.Equals(info.NameText, "ToCharArray"))
            {
                return(false);
            }

            IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocation, cancellationToken);

            if (!SymbolUtility.IsPublicInstanceNonGeneric(methodSymbol, "ToCharArray"))
            {
                return(false);
            }

            if (methodSymbol.ContainingType?.SpecialType != SpecialType.System_String)
            {
                return(false);
            }

            if (methodSymbol.Parameters.Any())
            {
                return(false);
            }

            if (!(methodSymbol.ReturnType is IArrayTypeSymbol arrayType))
            {
                return(false);
            }

            return(arrayType.ElementType.SpecialType == SpecialType.System_Char);
        }
예제 #3
0
        public static async Task ComputeRefactoringAsync(RefactoringContext context, InvocationExpressionSyntax invocation)
        {
            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

            IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocation, context.CancellationToken);

            if (SymbolUtility.IsPublicInstanceNonGeneric(methodSymbol, "Contains") &&
                methodSymbol.IsContainingType(SpecialType.System_String) &&
                methodSymbol.HasSingleParameter(SpecialType.System_String))
            {
                context.RegisterRefactoring(
                    "Replace Contains with IndexOf", //Call 'IndexOf' instead of 'Replace'
                    cancellationToken => RefactorAsync(context.Document, invocation, cancellationToken));
            }
        }
예제 #4
0
        private static void Analyze(
            SyntaxNodeAnalysisContext context,
            SimpleMemberInvocationExpressionInfo invocationInfo,
            SimpleMemberInvocationExpressionInfo invocationInfo2)
        {
            if (invocationInfo2.InvocationExpression.SpanContainsDirectives())
            {
                return;
            }

            string name2 = invocationInfo2.NameText;

            if (name2 != "Equals" &&
                name2 != "StartsWith" &&
                name2 != "EndsWith" &&
                name2 != "IndexOf" &&
                name2 != "LastIndexOf" &&
                name2 != "Contains")
            {
                return;
            }

            SeparatedSyntaxList <ArgumentSyntax> arguments = invocationInfo2.Arguments;

            if (arguments.Count != 1)
            {
                return;
            }

            ExpressionSyntax argumentExpression = arguments[0].Expression.WalkDownParentheses();

            string name = invocationInfo.NameText;

            SimpleMemberInvocationExpressionInfo invocationInfo3;

            bool isStringLiteral = argumentExpression.IsKind(SyntaxKind.StringLiteralExpression);

            if (!isStringLiteral)
            {
                invocationInfo3 = SyntaxInfo.SimpleMemberInvocationExpressionInfo(argumentExpression);

                if (!invocationInfo3.Success)
                {
                    return;
                }

                string name3 = invocationInfo3.NameText;

                if (name != name3)
                {
                    return;
                }
            }

            SemanticModel     semanticModel     = context.SemanticModel;
            CancellationToken cancellationToken = context.CancellationToken;

            if (!CheckSymbol(invocationInfo, semanticModel, cancellationToken))
            {
                return;
            }

            IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocationInfo2.InvocationExpression, cancellationToken);

            if (!SymbolUtility.IsPublicInstanceNonGeneric(methodSymbol, name2))
            {
                return;
            }

            if (!methodSymbol.IsContainingType(SpecialType.System_String))
            {
                return;
            }

            SpecialType returnType = (name2.EndsWith("IndexOf", StringComparison.Ordinal))
                ? SpecialType.System_Int32
                : SpecialType.System_Boolean;

            if (!methodSymbol.IsReturnType(returnType))
            {
                return;
            }

            if (!methodSymbol.HasSingleParameter(SpecialType.System_String))
            {
                return;
            }

            if (!isStringLiteral &&
                !CheckSymbol(invocationInfo3, semanticModel, cancellationToken))
            {
                return;
            }

            ReportDiagnostic(context, invocationInfo2);
        }
예제 #5
0
        public static bool IsFixable(
            SimpleMemberInvocationExpressionInfo invocationInfo,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (invocationInfo.Expression.Kind() == SyntaxKind.BaseExpression)
            {
                return(false);
            }

            InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression;

            IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocationExpression, cancellationToken);

            if (SymbolUtility.IsPublicInstanceNonGeneric(methodSymbol, "ToString") &&
                methodSymbol.ReturnType.SpecialType == SpecialType.System_String &&
                !methodSymbol.Parameters.Any())
            {
                INamedTypeSymbol containingType = methodSymbol.ContainingType;

                if (containingType?.IsReferenceType == true &&
                    containingType.SpecialType != SpecialType.System_Enum)
                {
                    if (containingType.SpecialType == SpecialType.System_String)
                    {
                        return(true);
                    }

                    ExpressionSyntax expression = invocationExpression.WalkUpParentheses();

                    SyntaxNode parent = expression.Parent;

                    if (parent != null)
                    {
                        SyntaxKind kind = parent.Kind();

                        if (kind == SyntaxKind.Interpolation)
                        {
                            return(IsNotHidden(methodSymbol, containingType));
                        }
                        else if (kind == SyntaxKind.AddExpression)
                        {
                            if (!parent.ContainsDiagnostics &&
                                IsNotHidden(methodSymbol, containingType))
                            {
                                var addExpression = (BinaryExpressionSyntax)expression.Parent;

                                if (CSharpUtility.IsStringConcatenation(addExpression, semanticModel, cancellationToken))
                                {
                                    BinaryExpressionSyntax newAddExpression = addExpression.ReplaceNode(expression, invocationInfo.Expression);

                                    IMethodSymbol speculativeSymbol = semanticModel.GetSpeculativeMethodSymbol(addExpression.SpanStart, newAddExpression);

                                    return(SymbolUtility.IsStringAdditionOperator(speculativeSymbol));
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }