public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindNode(root, context.Span, out SyntaxNode node))
            {
                return;
            }

            Diagnostic diagnostic = context.Diagnostics[0];

            if (diagnostic.Properties.TryGetValue("Identifier", out string identifier))
            {
                CodeAction codeAction = CodeAction.Create(
                    Title,
                    ct => UseNameOfOperatorRefactoring.RefactorAsync(context.Document, (LiteralExpressionSyntax)node, identifier, ct),
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
            }
            else
            {
                CodeAction codeAction = CodeAction.Create(
                    Title,
                    ct => UseNameOfOperatorRefactoring.RefactorAsync(context.Document, (InvocationExpressionSyntax)node, ct),
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
            }
        }
        public override void Initialize(AnalysisContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            base.Initialize(context);

            context.RegisterSyntaxNodeAction(
                f => UseNameOfOperatorRefactoring.AnalyzeArgument(f),
                SyntaxKind.Argument);
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out LiteralExpressionSyntax node))
            {
                return;
            }

            string identifier = context.Diagnostics[0].Properties["Identifier"];

            CodeAction codeAction = CodeAction.Create(
                "Use nameof operator",
                cancellationToken => UseNameOfOperatorRefactoring.RefactorAsync(context.Document, node, identifier, cancellationToken),
                GetEquivalenceKey(DiagnosticIdentifiers.UseNameOfOperator));

            context.RegisterCodeFix(codeAction, context.Diagnostics[0]);
        }
Esempio n. 4
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

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

            if (node == null)
            {
                return;
            }

            CodeAction codeAction = CodeAction.Create(
                "Use nameof operator",
                cancellationToken => UseNameOfOperatorRefactoring.RefactorAsync(context.Document, node, cancellationToken),
                DiagnosticIdentifiers.UseNameOfOperator + EquivalenceKeySuffix);

            context.RegisterCodeFix(codeAction, context.Diagnostics);
        }
        private void AnalyzeArgument(SyntaxNodeAnalysisContext context)
        {
            var argument = (ArgumentSyntax)context.Node;

            UseNameOfOperatorRefactoring.Analyze(context, argument);
        }
        private void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context)
        {
            var invocation = (InvocationExpressionSyntax)context.Node;

            ExpressionSyntax expression = invocation.Expression;

            if (expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) == true)
            {
                var memberAccess = (MemberAccessExpressionSyntax)expression;

                ArgumentListSyntax argumentList = invocation.ArgumentList;

                if (argumentList?.IsMissing == false)
                {
                    int argumentCount = argumentList.Arguments.Count;

                    string methodName = memberAccess.Name?.Identifier.ValueText;

                    if (argumentCount == 0)
                    {
                        switch (methodName)
                        {
                        case "Any":
                        {
                            SimplifyLinqMethodChainRefactoring.Analyze(context, invocation, memberAccess, methodName);
                            break;
                        }

                        case "Cast":
                        {
                            CallOfTypeInsteadOfWhereAndCastRefactoring.Analyze(context, invocation);
                            break;
                        }

                        case "Count":
                        {
                            SimplifyLinqMethodChainRefactoring.Analyze(context, invocation, memberAccess, methodName);
                            break;
                        }

                        case "First":
                        case "FirstOrDefault":
                        case "Last":
                        case "LastOrDefault":
                        case "LongCount":
                        case "Single":
                        case "SingleOrDefault":
                        {
                            SimplifyLinqMethodChainRefactoring.Analyze(context, invocation, memberAccess, methodName);
                            break;
                        }
                        }
                    }
                    else if (argumentCount == 1)
                    {
                        switch (methodName)
                        {
                        case "FirstOrDefault":
                        {
                            CallFindInsteadOfFirstOrDefaultRefactoring.Analyze(context, invocation, memberAccess);
                            break;
                        }

                        case "Where":
                        {
                            CombineEnumerableWhereMethodChainRefactoring.Analyze(context, invocation, memberAccess);
                            break;
                        }
                        }
                    }
                }
            }

            if (UseBitwiseOperationInsteadOfCallingHasFlagRefactoring.CanRefactor(invocation, context.SemanticModel, context.CancellationToken) &&
                !invocation.SpanContainsDirectives())
            {
                context.ReportDiagnostic(DiagnosticDescriptors.UseBitwiseOperationInsteadOfCallingHasFlag, invocation);
            }

            RemoveRedundantStringToCharArrayCallRefactoring.Analyze(context, invocation);

            CombineEnumerableWhereAndAnyRefactoring.AnalyzeInvocationExpression(context);

            if (!invocation.ContainsDiagnostics)
            {
                if (!invocation.SpanContainsDirectives())
                {
                    CallExtensionMethodAsInstanceMethodAnalysis analysis = CallExtensionMethodAsInstanceMethodRefactoring.Analyze(invocation, context.SemanticModel, context.CancellationToken);

                    if (analysis.Success &&
                        context.SemanticModel
                        .GetEnclosingNamedType(analysis.InvocationExpression.SpanStart, context.CancellationToken)?
                        .Equals(analysis.MethodSymbol.ContainingType) == false)
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.CallExtensionMethodAsInstanceMethod, invocation);
                    }
                }

                MemberInvocationExpression memberInvocation;
                if (MemberInvocationExpression.TryCreate(invocation, out memberInvocation))
                {
                    if (!invocation.SpanContainsDirectives())
                    {
                        UseRegexInstanceInsteadOfStaticMethodRefactoring.Analyze(context, memberInvocation);
                    }

                    string methodName = memberInvocation.NameText;

                    AvoidNullReferenceExceptionRefactoring.Analyze(context, memberInvocation);

                    int argumentCount = memberInvocation.ArgumentList.Arguments.Count;

                    switch (argumentCount)
                    {
                    case 0:
                        {
                            switch (methodName)
                            {
                            case "Any":
                            {
                                UseCountOrLengthPropertyInsteadOfAnyMethodRefactoring.Analyze(context, memberInvocation);
                                break;
                            }

                            case "Count":
                            {
                                UseInsteadOfCountMethodRefactoring.Analyze(context, memberInvocation);
                                break;
                            }

                            case "First":
                            {
                                if (!memberInvocation.Expression.IsKind(SyntaxKind.InvocationExpression) &&
                                    UseElementAccessInsteadOfFirstRefactoring.CanRefactor(memberInvocation, context.SemanticModel, context.CancellationToken))
                                {
                                    context.ReportDiagnostic(DiagnosticDescriptors.UseElementAccessInsteadOfFirst, memberInvocation.Name);
                                }

                                break;
                            }

                            case "ToString":
                            {
                                RemoveRedundantToStringCallRefactoring.Analyze(context, memberInvocation);
                                UseNameOfOperatorRefactoring.Analyze(context, memberInvocation);
                                break;
                            }

                            case "ToLower":
                            case "ToLowerInvariant":
                            case "ToUpper":
                            case "ToUpperInvariant":
                            {
                                UseStringComparisonRefactoring.Analyze(context, memberInvocation);
                                break;
                            }
                            }

                            break;
                        }

                    case 1:
                    {
                        switch (methodName)
                        {
                        case "ElementAt":
                        {
                            if (!memberInvocation.Expression.IsKind(SyntaxKind.InvocationExpression) &&
                                UseElementAccessInsteadOfElementAtRefactoring.CanRefactor(memberInvocation, context.SemanticModel, context.CancellationToken))
                            {
                                context.ReportDiagnostic(DiagnosticDescriptors.UseElementAccessInsteadOfElementAt, memberInvocation.Name);
                            }

                            break;
                        }
                        }

                        break;
                    }
                    }

                    switch (methodName)
                    {
                    case "Append":
                    case "AppendLine":
                    case "AppendFormat":
                    case "Insert":
                    {
                        OptimizeStringBuilderAppendCallRefactoring.Analyze(context, memberInvocation);
                        break;
                    }

                    case "Select":
                    {
                        if (argumentCount == 1 ||
                            argumentCount == 2)
                        {
                            CallCastInsteadOfSelectRefactoring.Analyze(context, memberInvocation);
                        }

                        break;
                    }

                    case "OrderBy":
                    case "OrderByDescending":
                    {
                        if (argumentCount == 1 ||
                            argumentCount == 2 ||
                            argumentCount == 3)
                        {
                            CallThenByInsteadOfOrderByRefactoring.Analyze(context, memberInvocation);
                        }

                        break;
                    }
                    }

                    if (UseMethodChainingRefactoring.IsFixable(memberInvocation, context.SemanticModel, context.CancellationToken))
                    {
                        context.ReportDiagnostic(DiagnosticDescriptors.UseMethodChaining, memberInvocation.InvocationExpression);
                    }
                }
            }
        }