public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpression memberInvocation)
        {
            ExpressionSyntax expression = memberInvocation.InvocationExpression.WalkUpParentheses();

            SyntaxNode parent = expression.Parent;

            SyntaxKind kind = parent.Kind();

            if (kind == SyntaxKind.SimpleMemberAccessExpression)
            {
                if (!MemberInvocationExpression.TryCreate(parent.Parent, out MemberInvocationExpression memberInvocation2))
                {
                    return;
                }

                Analyze(context, memberInvocation, memberInvocation2);
            }
            else if (kind == SyntaxKind.Argument)
            {
                Analyze(context, memberInvocation, (ArgumentSyntax)parent);
            }
            else if (kind == SyntaxKind.EqualsExpression ||
                     kind == SyntaxKind.NotEqualsExpression)
            {
                Analyze(context, memberInvocation, expression, (BinaryExpressionSyntax)parent);
            }
        }
        private static bool IsFixable(
            SyntaxNodeAnalysisContext context,
            MemberInvocationExpression invocation,
            ArgumentSyntax argument,
            SeparatedSyntaxList <ArgumentSyntax> arguments)
        {
            if (object.ReferenceEquals(argument, arguments[0]))
            {
                ExpressionSyntax expression = arguments[1].Expression?.WalkDownParentheses();

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

                    if (kind == SyntaxKind.InvocationExpression)
                    {
                        return(TryCreateCaseChangingInvocation(expression, out MemberInvocationExpression invocation2) &&
                               invocation.NameText == invocation2.NameText &&
                               CheckSymbol(invocation, context.SemanticModel, context.CancellationToken) &&
                               CheckSymbol(invocation2, context.SemanticModel, context.CancellationToken));
                    }
                    else if (kind == SyntaxKind.StringLiteralExpression)
                    {
                        return(CheckSymbol(invocation, context.SemanticModel, context.CancellationToken));
                    }
                }
            }
            else
            {
                return(arguments[0].Expression?.WalkDownParentheses().Kind() == SyntaxKind.StringLiteralExpression &&
                       CheckSymbol(invocation, context.SemanticModel, context.CancellationToken));
            }

            return(false);
        }
        public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpression memberInvocation)
        {
            ExpressionSyntax expression = memberInvocation.Expression;

            if (expression.Kind() != SyntaxKind.SimpleMemberAccessExpression)
            {
                return;
            }

            var memberAccessExpression = (MemberAccessExpressionSyntax)expression;

            var fieldSymbol = context.SemanticModel.GetSymbol(memberAccessExpression, context.CancellationToken) as IFieldSymbol;

            if (fieldSymbol == null)
            {
                return;
            }

            INamedTypeSymbol containingType = fieldSymbol.ContainingType;

            if (containingType?.TypeKind != TypeKind.Enum)
            {
                return;
            }

            if (containingType.HasAttribute(context.GetTypeByMetadataName(MetadataNames.System_FlagsAttribute)))
            {
                return;
            }

            context.ReportDiagnostic(DiagnosticDescriptors.UseNameOfOperator, memberInvocation.InvocationExpression);
        }
        public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpression invocation)
        {
            InvocationExpressionSyntax invocationExpression = invocation.InvocationExpression;

            if (invocationExpression.IsParentKind(SyntaxKind.SimpleMemberAccessExpression))
            {
                return;
            }

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

            if (!semanticModel.TryGetExtensionMethodInfo(invocationExpression, out MethodInfo methodInfo, ExtensionMethodKind.Reduced, cancellationToken))
            {
                return;
            }

            if (!methodInfo.IsLinqExtensionOfIEnumerableOfTWithoutParameters("Any"))
            {
                return;
            }

            string propertyName = CSharpUtility.GetCountOrLengthPropertyName(invocation.Expression, semanticModel, cancellationToken);

            if (propertyName == null)
            {
                return;
            }

            context.ReportDiagnostic(
                DiagnosticDescriptors.UseCountOrLengthPropertyInsteadOfAnyMethod,
                Location.Create(context.Node.SyntaxTree, TextSpan.FromBounds(invocation.Name.Span.Start, invocationExpression.Span.End)),
                ImmutableDictionary.CreateRange(new KeyValuePair <string, string>[] { new KeyValuePair <string, string>("PropertyName", propertyName) }),
                propertyName);
        }
Beispiel #5
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            ArgumentSyntax argument = root
                                      .FindNode(context.Span, getInnermostNodeForTie: true)?
                                      .FirstAncestorOrSelf <ArgumentSyntax>();

            Debug.Assert(argument != null, $"{nameof(argument)} is null");

            if (argument == null)
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case DiagnosticIdentifiers.OptimizeStringBuilderAppendCall:
                {
                    MemberInvocationExpression memberInvocation = MemberInvocationExpression.Create((InvocationExpressionSyntax)argument.Parent.Parent);

                    CodeAction codeAction = CodeAction.Create(
                        $"Optimize '{memberInvocation.NameText}' call",
                        cancellationToken => OptimizeStringBuilderAppendCallRefactoring.RefactorAsync(context.Document, argument, memberInvocation, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }
                }
            }
        }
        public static bool CanRefactor(
            MemberInvocationExpression memberInvocation,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax argumentExpression = memberInvocation.ArgumentList.Arguments[0].Expression;

            if (argumentExpression?.IsMissing != false)
            {
                return(false);
            }

            if (memberInvocation.Expression?.IsMissing != false)
            {
                return(false);
            }

            if (!semanticModel.TryGetExtensionMethodInfo(memberInvocation.InvocationExpression, out MethodInfo methodInfo, ExtensionMethodKind.Reduced, cancellationToken))
            {
                return(false);
            }

            if (!methodInfo.IsLinqElementAt(allowImmutableArrayExtension: true))
            {
                return(false);
            }

            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(memberInvocation.Expression, cancellationToken);

            return(CSharpUtility.HasAccessibleIndexer(typeSymbol, semanticModel, memberInvocation.InvocationExpression.SpanStart));
        }
Beispiel #7
0
        public static bool CanRefactor(
            MemberInvocationExpression memberInvocation,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax argumentExpression = memberInvocation.ArgumentList.Arguments[0].Expression;

            if (argumentExpression?.IsMissing == false &&
                memberInvocation.Expression?.IsMissing == false &&
                semanticModel
                .GetExtensionMethodInfo(memberInvocation.InvocationExpression, cancellationToken)
                .MethodInfo
                .IsLinqElementAt(allowImmutableArrayExtension: true))
            {
                ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(memberInvocation.Expression, cancellationToken);

                if (typeSymbol?.IsErrorType() == false &&
                    (typeSymbol.IsArrayType() || ExistsApplicableIndexer(memberInvocation.InvocationExpression, argumentExpression, typeSymbol, semanticModel)))
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #8
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out ArgumentSyntax argument))
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case DiagnosticIdentifiers.OptimizeStringBuilderAppendCall:
                {
                    MemberInvocationExpression memberInvocation = MemberInvocationExpression.Create((InvocationExpressionSyntax)argument.Parent.Parent);

                    CodeAction codeAction = CodeAction.Create(
                        $"Optimize '{memberInvocation.NameText}' call",
                        cancellationToken => OptimizeStringBuilderAppendCallRefactoring.RefactorAsync(context.Document, argument, memberInvocation, cancellationToken),
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }
                }
            }
        }
Beispiel #9
0
        public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpression memberInvocation)
        {
            ExpressionSyntax expression = memberInvocation.Expression;

            if (expression.IsKind(SyntaxKind.InvocationExpression))
            {
                MemberInvocationExpression memberInvocation2;
                if (MemberInvocationExpression.TryCreate((InvocationExpressionSyntax)expression, out memberInvocation2))
                {
                    switch (memberInvocation2.NameText)
                    {
                    case "OrderBy":
                    case "OrderByDescending":
                    {
                        if (IsLinqExtensionOfIEnumerableOfT(context, memberInvocation.InvocationExpression) &&
                            IsLinqExtensionOfIEnumerableOfT(context, memberInvocation2.InvocationExpression))
                        {
                            context.ReportDiagnostic(
                                DiagnosticDescriptors.CallThenByInsteadOfOrderBy,
                                memberInvocation.Name,
                                (memberInvocation.NameText == "OrderByDescending") ? "Descending" : null);
                        }

                        break;
                    }
                    }
                }
            }
        }
        public static Task <Document> RefactorAsync(
            Document document,
            IfStatementSyntax ifStatement,
            CancellationToken cancellationToken)
        {
            StatementSyntax statement = (ExpressionStatementSyntax)ifStatement.GetSingleStatementOrDefault();

            MemberInvocationExpression memberInvocation;

            MemberInvocationExpression.TryCreate(statement, out memberInvocation);

            int             insertIndex  = memberInvocation.Expression.Span.End - statement.FullSpan.Start;
            StatementSyntax newStatement = ParseStatement(statement.ToFullString().Insert(insertIndex, "?"));

            IEnumerable <SyntaxTrivia> leading = ifStatement.DescendantTrivia(TextSpan.FromBounds(ifStatement.SpanStart, statement.SpanStart));

            newStatement = (leading.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                ? newStatement.WithLeadingTrivia(ifStatement.GetLeadingTrivia())
                : newStatement.WithLeadingTrivia(ifStatement.GetLeadingTrivia().Concat(leading));

            IEnumerable <SyntaxTrivia> trailing = ifStatement.DescendantTrivia(TextSpan.FromBounds(statement.Span.End, ifStatement.Span.End));

            newStatement = (leading.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                ? newStatement.WithTrailingTrivia(ifStatement.GetTrailingTrivia())
                : newStatement.WithTrailingTrivia(trailing.Concat(ifStatement.GetTrailingTrivia()));

            return(document.ReplaceNodeAsync(ifStatement, newStatement, cancellationToken));
        }
Beispiel #11
0
        public static bool IsFixable(
            MemberInvocationExpression memberInvocation,
            SemanticModel semanticModel,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            InvocationExpressionSyntax invocationExpression = memberInvocation.InvocationExpression;

            MethodInfo info;

            if (semanticModel.TryGetMethodInfo(invocationExpression, out info, cancellationToken) &&
                info.IsName("ToString") &&
                info.IsPublic &&
                !info.IsStatic &&
                info.IsReturnType(SpecialType.System_String) &&
                !info.IsGenericMethod &&
                !info.IsExtensionMethod &&
                !info.Parameters.Any())
            {
                INamedTypeSymbol containingType = info.ContainingType;

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

                    if (invocationExpression.IsParentKind(SyntaxKind.Interpolation))
                    {
                        return(IsNotHidden(info.Symbol, containingType));
                    }

                    ExpressionSyntax expression = invocationExpression.WalkUpParentheses();

                    SyntaxNode parent = expression.Parent;

                    if (parent?.IsKind(SyntaxKind.AddExpression) == true &&
                        !parent.ContainsDiagnostics &&
                        IsNotHidden(info.Symbol, containingType))
                    {
                        var addExpression = (BinaryExpressionSyntax)expression.Parent;

                        ExpressionSyntax left  = addExpression.Left;
                        ExpressionSyntax right = addExpression.Right;

                        if (left == expression)
                        {
                            return(IsFixable(memberInvocation, addExpression, right, left, semanticModel, cancellationToken));
                        }
                        else
                        {
                            return(IsFixable(memberInvocation, addExpression, left, right, semanticModel, cancellationToken));
                        }
                    }
                }
            }

            return(false);
        }
Beispiel #12
0
        public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpression memberInvocation)
        {
            switch (memberInvocation.NameText)
            {
            case "ElementAtOrDefault":
            case "FirstOrDefault":
            case "LastOrDefault":
            {
                InvocationExpressionSyntax invocationExpression = memberInvocation.InvocationExpression;

                ExpressionSyntax expression = invocationExpression.WalkUpParentheses();

                if (IsExpressionOfAccessExpression(expression))
                {
                    MethodInfo methodInfo;
                    if (context.SemanticModel.TryGetMethodInfo(invocationExpression, out methodInfo, context.CancellationToken) &&
                        methodInfo.ReturnType.IsReferenceType &&
                        methodInfo.IsContainingType(MetadataNames.System_Linq_Enumerable))
                    {
                        ReportDiagnostic(context, expression);
                    }
                }

                break;
            }
            }
        }
Beispiel #13
0
        protected override bool IsFixableStatement(
            StatementSyntax statement,
            string name,
            ITypeSymbol typeSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (statement.SpanOrLeadingTriviaContainsDirectives())
            {
                return(false);
            }

            if (!(statement is ExpressionStatementSyntax expressionStatement))
            {
                return(false);
            }

            if (!SimpleAssignmentExpression.TryCreate(expressionStatement.Expression, out SimpleAssignmentExpression simpleAssignment))
            {
                return(false);
            }

            if (name != (simpleAssignment.Left as IdentifierNameSyntax)?.Identifier.ValueText)
            {
                return(false);
            }

            if (!MemberInvocationExpression.TryCreate(simpleAssignment.Right, out MemberInvocationExpression memberInvocation))
            {
                return(false);
            }

            if (!(WalkDownMethodChain(memberInvocation).Expression is IdentifierNameSyntax identifierName))
            {
                return(false);
            }

            if (name != identifierName.Identifier.ValueText)
            {
                return(false);
            }

            if (!semanticModel.TryGetMethodInfo(memberInvocation.InvocationExpression, out MethodInfo methodInfo, cancellationToken))
            {
                return(false);
            }

            if (!methodInfo.ReturnType.Equals(typeSymbol))
            {
                return(false);
            }

            if (IsReferenced(memberInvocation.InvocationExpression, identifierName, name, semanticModel, cancellationToken))
            {
                return(false);
            }

            return(true);
        }
Beispiel #14
0
        public static bool IsFixable(
            MemberInvocationExpression memberInvocation,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            InvocationExpressionSyntax invocationExpression = memberInvocation.InvocationExpression;

            SyntaxNode parent = invocationExpression.Parent;

            switch (parent?.Kind())
            {
            case SyntaxKind.ExpressionStatement:
            {
                var expressionStatement = (ExpressionStatementSyntax)parent;

                if (!(WalkDownMethodChain(memberInvocation).Expression is IdentifierNameSyntax identifierName))
                {
                    break;
                }

                string name = identifierName.Identifier.ValueText;

                return(WithoutAssignment.Analyze(memberInvocation, expressionStatement, name, semanticModel, cancellationToken));
            }

            case SyntaxKind.SimpleAssignmentExpression:
            {
                var assinmentExpression = (AssignmentExpressionSyntax)parent;

                if (!(assinmentExpression.Left is IdentifierNameSyntax identifierName))
                {
                    break;
                }

                if (assinmentExpression.Right != invocationExpression)
                {
                    break;
                }

                if (!(assinmentExpression.Parent is ExpressionStatementSyntax expressionStatement))
                {
                    break;
                }

                string name = identifierName.Identifier.ValueText;

                if (name != (WalkDownMethodChain(memberInvocation).Expression as IdentifierNameSyntax)?.Identifier.ValueText)
                {
                    break;
                }

                return(WithAssignment.Analyze(memberInvocation, expressionStatement, name, semanticModel, cancellationToken));
            }
            }

            return(false);
        }
Beispiel #15
0
        protected static MemberInvocationExpression WalkDownMethodChain(MemberInvocationExpression memberInvocation)
        {
            while (MemberInvocationExpression.TryCreate(memberInvocation.Expression, out MemberInvocationExpression memberInvocation2))
            {
                memberInvocation = memberInvocation2;
            }

            return(memberInvocation);
        }
        public static async Task <Document> RefactorAsync(
            Document document,
            InvocationExpressionSyntax invocationExpression,
            CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            MemberDeclarationSyntax memberDeclaration = invocationExpression.FirstAncestor <MemberDeclarationSyntax>();

            Debug.Assert(memberDeclaration != null, "");

            if (memberDeclaration != null)
            {
                BaseTypeDeclarationSyntax typeDeclaration = memberDeclaration.FirstAncestor <BaseTypeDeclarationSyntax>();

                Debug.Assert(typeDeclaration != null, "");

                if (typeDeclaration != null)
                {
                    MemberInvocationExpression memberInvocation = MemberInvocationExpression.Create(invocationExpression);

                    string fieldName = NameGenerator.Default.EnsureUniqueLocalName("_regex", semanticModel, invocationExpression.SpanStart, cancellationToken: cancellationToken);

                    MemberAccessExpressionSyntax newMemberAccess = memberInvocation.MemberAccessExpression.WithExpression(IdentifierName(Identifier(fieldName).WithRenameAnnotation()));

                    ArgumentListPair pair = RewriteArgumentLists(memberInvocation.ArgumentList, semanticModel, cancellationToken);

                    InvocationExpressionSyntax newInvocationExpression = invocationExpression
                                                                         .WithExpression(newMemberAccess)
                                                                         .WithArgumentList(pair.ArgumentList1);

                    MemberDeclarationSyntax newTypeDeclaration = typeDeclaration.ReplaceNode(invocationExpression, newInvocationExpression);

                    TypeSyntax regexType = semanticModel.GetTypeByMetadataName(MetadataNames.System_Text_RegularExpressions_Regex).ToMinimalTypeSyntax(semanticModel, typeDeclaration.SpanStart);

                    FieldDeclarationSyntax fieldDeclaration = FieldDeclaration(
                        (ShouldBeStatic(memberDeclaration, semanticModel, cancellationToken))
                            ? Modifiers.PrivateStaticReadOnly()
                            : Modifiers.PrivateReadOnly(),
                        regexType,
                        Identifier(fieldName),
                        EqualsValueClause(
                            ObjectCreationExpression(regexType, pair.ArgumentList2)));

                    SyntaxList <MemberDeclarationSyntax> newMembers = newTypeDeclaration
                                                                      .GetMembers()
                                                                      .InsertMember(fieldDeclaration, MemberDeclarationComparer.ByKind);

                    newTypeDeclaration = newTypeDeclaration.WithMembers(newMembers);

                    return(await document.ReplaceNodeAsync(typeDeclaration, newTypeDeclaration, cancellationToken).ConfigureAwait(false));
                }
            }

            return(document);
        }
 private static bool CheckSymbol(
     MemberInvocationExpression invocation,
     SemanticModel semanticModel,
     CancellationToken cancellationToken)
 {
     return(semanticModel.TryGetMethodInfo(invocation.InvocationExpression, out MethodInfo info, cancellationToken) &&
            info.IsPublicInstanceStringMethod() &&
            info.ReturnsString &&
            !info.Parameters.Any());
 }
        private static InvocationExpressionSyntax ConvertInterpolatedStringExpressionToInvocationExpression(
            InterpolatedStringExpressionSyntax interpolatedString,
            MemberInvocationExpression memberInvocation)
        {
            bool isVerbatim = interpolatedString.IsVerbatim();

            bool isAppendLine = string.Equals(memberInvocation.NameText, "AppendLine", StringComparison.Ordinal);

            InvocationExpressionSyntax invocation = memberInvocation.InvocationExpression;

            InvocationExpressionSyntax newExpression = null;

            SyntaxList <InterpolatedStringContentSyntax> contents = interpolatedString.Contents;

            for (int i = 0; i < contents.Count; i++)
            {
                InterpolatedStringContentConversion conversion = InterpolatedStringContentConversion.Create(contents[i], isVerbatim);

                string name = conversion.Name;
                SeparatedSyntaxList <ArgumentSyntax> arguments = conversion.Arguments;

                if (i == contents.Count - 1 &&
                    isAppendLine &&
                    !string.Equals(name, "AppendFormat", StringComparison.Ordinal))
                {
                    name = "AppendLine";
                }

                if (newExpression == null)
                {
                    newExpression = invocation
                                    .ReplaceNode(memberInvocation.Name, IdentifierName(name).WithTriviaFrom(memberInvocation.Name))
                                    .WithArgumentList(invocation.ArgumentList.WithArguments(arguments).WithoutTrailingTrivia());
                }
                else
                {
                    newExpression = SimpleMemberInvocationExpression(
                        newExpression,
                        IdentifierName(name),
                        ArgumentList(arguments));
                }

                if (i == contents.Count - 1 &&
                    isAppendLine &&
                    string.Equals(name, "AppendFormat", StringComparison.Ordinal))
                {
                    newExpression = SimpleMemberInvocationExpression(
                        newExpression,
                        IdentifierName("AppendLine"),
                        ArgumentList());
                }
            }

            return(newExpression);
        }
Beispiel #19
0
        private string GetTextToAppend(ExpressionStatementSyntax expressionStatement)
        {
            MemberInvocationExpression memberInvocation = MemberInvocationExpression.Create(GetInvocationExpression(expressionStatement));

            MemberInvocationExpression firstMemberInvocation = WalkDownMethodChain(memberInvocation);

            InvocationExpressionSyntax invocationExpression = memberInvocation.InvocationExpression;

            return(invocationExpression
                   .ToString()
                   .Substring(firstMemberInvocation.OperatorToken.SpanStart - invocationExpression.SpanStart));
        }
Beispiel #20
0
        public bool Analyze(
            MemberInvocationExpression memberInvocation,
            StatementSyntax statement,
            string name,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (statement.SpanOrTrailingTriviaContainsDirectives())
            {
                return(false);
            }

            if (!StatementContainer.TryCreate(statement, out StatementContainer container))
            {
                return(false);
            }

            SyntaxList <StatementSyntax> statements = container.Statements;

            if (statements.Count == 1)
            {
                return(false);
            }

            if (!semanticModel.TryGetMethodInfo(memberInvocation.InvocationExpression, out MethodInfo methodInfo, cancellationToken))
            {
                return(false);
            }

            ITypeSymbol typeSymbol = methodInfo.ReturnType;

            int i = statements.IndexOf(statement);

            if (i != 0 &&
                IsFixableStatement(statements[i - 1], name, typeSymbol, semanticModel, cancellationToken))
            {
                return(false);
            }

            int j = i;

            while (j < statements.Count - 1)
            {
                if (!IsFixableStatement(statements[j + 1], name, typeSymbol, semanticModel, cancellationToken))
                {
                    break;
                }

                j++;
            }

            return(j > i);
        }
        internal static Task <Document> RefactorAsync(
            Document document,
            MemberInvocationExpression memberInvocation,
            string comparisonName,
            CancellationToken cancellationToken)
        {
            SeparatedSyntaxList <ArgumentSyntax> arguments = memberInvocation.ArgumentList.Arguments;

            InvocationExpressionSyntax invocationExpression = memberInvocation.InvocationExpression;

            if (arguments.Count == 2)
            {
                ArgumentListSyntax newArgumentList = ArgumentList(
                    CreateArgument(arguments[0]),
                    CreateArgument(arguments[1]),
                    Argument(CreateStringComparison(comparisonName)));

                InvocationExpressionSyntax newNode = invocationExpression.WithArgumentList(newArgumentList);

                return(document.ReplaceNodeAsync(invocationExpression, newNode, cancellationToken));
            }
            else
            {
                var memberAccess  = (MemberAccessExpressionSyntax)invocationExpression.Expression;
                var invocation2   = (InvocationExpressionSyntax)memberAccess.Expression;
                var memberAccess2 = (MemberAccessExpressionSyntax)invocation2.Expression;

                MemberAccessExpressionSyntax newMemberAccess = memberAccess.WithExpression(memberAccess2.Expression);

                bool isContains = memberAccess.Name.Identifier.ValueText == "Contains";

                if (isContains)
                {
                    newMemberAccess = newMemberAccess.WithName(newMemberAccess.Name.WithIdentifier(Identifier("IndexOf").WithTriviaFrom(newMemberAccess.Name.Identifier)));
                }

                ArgumentListSyntax newArgumentList = ArgumentList(
                    CreateArgument(arguments[0]),
                    Argument(CreateStringComparison(comparisonName)));

                ExpressionSyntax newNode = invocationExpression
                                           .WithExpression(newMemberAccess)
                                           .WithArgumentList(newArgumentList);

                if (isContains)
                {
                    newNode = GreaterThanOrEqualExpression(newNode.Parenthesize(), NumericLiteralExpression(0)).Parenthesize();
                }

                return(document.ReplaceNodeAsync(invocationExpression, newNode, cancellationToken));
            }
        }
        public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpression memberInvocation)
        {
            InvocationExpressionSyntax invocationExpression = memberInvocation.InvocationExpression;

            if (invocationExpression.IsParentKind(SyntaxKind.ExpressionStatement) &&
                !invocationExpression.SpanOrTrailingTriviaContainsDirectives())
            {
                StatementSyntax expressionStatement = (ExpressionStatementSyntax)invocationExpression.Parent;

                StatementContainer container;
                if (StatementContainer.TryCreate(expressionStatement, out container))
                {
                    SyntaxList <StatementSyntax> statements = container.Statements;

                    if (statements.Count > 1)
                    {
                        SemanticModel     semanticModel     = context.SemanticModel;
                        CancellationToken cancellationToken = context.CancellationToken;

                        INamedTypeSymbol symbol = context.GetTypeByMetadataName(MetadataNames.System_Text_StringBuilder);

                        if (symbol != null &&
                            IsFixable(memberInvocation, symbol, semanticModel, cancellationToken))
                        {
                            ExpressionSyntax expression = GetFirstInvocationInMethodChain(memberInvocation, symbol, semanticModel, cancellationToken).Expression;

                            int i = statements.IndexOf(expressionStatement);

                            if (i == 0 ||
                                !IsFixable(statements[i - 1], expression, symbol, semanticModel, cancellationToken))
                            {
                                int j = i;
                                while (j < statements.Count - 1)
                                {
                                    if (!IsFixable(statements[j + 1], expression, symbol, semanticModel, cancellationToken))
                                    {
                                        break;
                                    }

                                    j++;
                                }

                                if (j > i)
                                {
                                    context.ReportDiagnostic(DiagnosticDescriptors.UseMethodChaining, expressionStatement);
                                }
                            }
                        }
                    }
                }
            }
        }
        private static bool TryCreateCaseChangingInvocation(ExpressionSyntax expression, out MemberInvocationExpression invocation)
        {
            if (MemberInvocationExpression.TryCreate(expression, out invocation) &&
                !invocation.ArgumentList.Arguments.Any())
            {
                string name = invocation.NameText;

                return(name == "ToLower" ||
                       name == "ToLowerInvariant" ||
                       name == "ToUpper" ||
                       name == "ToUpperInvariant");
            }

            invocation = default(MemberInvocationExpression);
            return(false);
        }
        private static string GetTextToAppend(
            ExpressionStatementSyntax expressionStatement,
            INamedTypeSymbol stringBuilderSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            MemberInvocationExpression memberInvocation = MemberInvocationExpression.Create((InvocationExpressionSyntax)expressionStatement.Expression);

            MemberInvocationExpression firstMemberInvocation = GetFirstInvocationInMethodChain(memberInvocation, stringBuilderSymbol, semanticModel, cancellationToken);

            InvocationExpressionSyntax invocationExpression = memberInvocation.InvocationExpression;

            return(invocationExpression
                   .ToString()
                   .Substring(firstMemberInvocation.OperatorToken.SpanStart - invocationExpression.SpanStart));
        }
Beispiel #25
0
        public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpression memberInvocation)
        {
            if (IsFixable(memberInvocation, context.SemanticModel, context.CancellationToken))
            {
                InvocationExpressionSyntax invocationExpression = memberInvocation.InvocationExpression;

                TextSpan span = TextSpan.FromBounds(memberInvocation.OperatorToken.Span.Start, invocationExpression.Span.End);

                if (!invocationExpression.ContainsDirectives(span))
                {
                    context.ReportDiagnostic(
                        DiagnosticDescriptors.RemoveRedundantToStringCall,
                        Location.Create(invocationExpression.SyntaxTree, span));
                }
            }
        }
        private static MemberInvocationExpression GetFirstInvocationInMethodChain(
            MemberInvocationExpression memberInvocation,
            INamedTypeSymbol stringBuilderSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            MemberInvocationExpression memberInvocation2;

            while (MemberInvocationExpression.TryCreate(memberInvocation.Expression, out memberInvocation2) &&
                   IsFixable(memberInvocation2, stringBuilderSymbol, semanticModel, cancellationToken))
            {
                memberInvocation = memberInvocation2;
            }

            return(memberInvocation);
        }
Beispiel #27
0
        public static void Analyze(
            SyntaxNodeAnalysisContext context,
            MemberInvocationExpression memberInvocation)
        {
            InvocationExpressionSyntax invocationExpression = memberInvocation.InvocationExpression;

            if (IsFixable(invocationExpression, context.SemanticModel, context.CancellationToken))
            {
                TextSpan span = TextSpan.FromBounds(memberInvocation.Name.Span.Start, invocationExpression.Span.End);

                if (!invocationExpression.ContainsDirectives(span))
                {
                    context.ReportDiagnostic(
                        DiagnosticDescriptors.CallCastInsteadOfSelect,
                        Location.Create(invocationExpression.SyntaxTree, span));
                }
            }
        }
        private static InvocationExpressionSyntax CreateInvocationExpression(
            InvocationExpressionSyntax innerInvocationExpression,
            InvocationExpressionSyntax outerInvocationExpression)
        {
            MemberInvocationExpression memberInvocation = MemberInvocationExpression.Create(innerInvocationExpression);

            switch (memberInvocation.NameText)
            {
            case "Substring":
            {
                SeparatedSyntaxList <ArgumentSyntax> arguments = memberInvocation.ArgumentList.Arguments;

                ArgumentListSyntax argumentList = ArgumentList(
                    Argument(memberInvocation.Expression),
                    arguments[0],
                    arguments[1]
                    );

                return(CreateNewInvocationExpression(outerInvocationExpression, "Append", argumentList));
            }

            case "Remove":
            {
                SeparatedSyntaxList <ArgumentSyntax> arguments = memberInvocation.ArgumentList.Arguments;

                ArgumentListSyntax argumentList = ArgumentList(
                    Argument(memberInvocation.Expression),
                    Argument(NumericLiteralExpression(0)),
                    arguments[0]
                    );

                return(CreateNewInvocationExpression(outerInvocationExpression, "Append", argumentList));
            }

            case "Format":
            {
                return(CreateNewInvocationExpression(outerInvocationExpression, "AppendFormat", memberInvocation.ArgumentList));
            }
            }

            Debug.Fail(innerInvocationExpression.ToString());
            return(outerInvocationExpression);
        }
Beispiel #29
0
        public static bool CanRefactor(MemberInvocationExpression memberInvocation, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            if (memberInvocation.Expression?.IsMissing == false &&
                semanticModel
                .GetExtensionMethodInfo(memberInvocation.InvocationExpression, ExtensionMethodKind.Reduced, cancellationToken)
                .MethodInfo
                .IsLinqExtensionOfIEnumerableOfTWithoutParameters("First", allowImmutableArrayExtension: true))
            {
                ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(memberInvocation.Expression, cancellationToken);

                if (typeSymbol?.IsErrorType() == false &&
                    (typeSymbol.IsArrayType() || ExistsApplicableIndexer(memberInvocation.InvocationExpression, typeSymbol, semanticModel)))
                {
                    return(true);
                }
            }

            return(false);
        }
        private static bool IsFixable(InvocationExpressionSyntax invocationExpression, SemanticModel semanticModel, CancellationToken cancellationToken)
        {
            MemberInvocationExpression memberInvocation;

            if (MemberInvocationExpression.TryCreate(invocationExpression, out memberInvocation))
            {
                MethodInfo methodInfo;
                if (semanticModel.TryGetMethodInfo(memberInvocation.InvocationExpression, out methodInfo, cancellationToken) &&
                    methodInfo.IsContainingType(SpecialType.System_String) &&
                    methodInfo.IsReturnType(SpecialType.System_String))
                {
                    switch (methodInfo.Name)
                    {
                    case "Substring":
                    {
                        if (methodInfo.HasParameters(SpecialType.System_Int32, SpecialType.System_Int32))
                        {
                            return(true);
                        }

                        break;
                    }

                    case "Remove":
                    {
                        if (methodInfo.HasParameter(SpecialType.System_Int32))
                        {
                            return(true);
                        }

                        break;
                    }

                    case "Format":
                    {
                        return(true);
                    }
                    }
                }
            }

            return(false);
        }