Example #1
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

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

            if (binaryExpression == null)
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case DiagnosticIdentifiers.SimplifyBooleanComparison:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Simplify boolean comparison",
                        cancellationToken => SimplifyBooleanComparisonRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);

                    break;
                }

                case DiagnosticIdentifiers.UseAnyMethodInsteadOfCountMethod:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Call 'Any' instead of 'Count'",
                        cancellationToken => UseAnyMethodInsteadOfCountMethodRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.AvoidNullLiteralExpressionOnLeftSideOfBinaryExpression:
                {
                    CodeAction codeAction = CodeAction.Create(
                        $"Swap '{binaryExpression.Left}' and '{binaryExpression.Right}'",
                        cancellationToken => SwapExpressionsInBinaryExpressionRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.UseStringIsNullOrEmptyMethod:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Use 'string.IsNullOrEmpty' method",
                        cancellationToken => UseStringIsNullOrEmptyMethodRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.SimplifyCoalesceExpression:
                {
                    ExpressionSyntax expression = binaryExpression.Left;

                    if (expression == null ||
                        !context.Span.Contains(expression.Span))
                    {
                        expression = binaryExpression.Right;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Simplify coalesce expression",
                        cancellationToken => SimplifyCoalesceExpressionRefactoring.RefactorAsync(context.Document, binaryExpression, expression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.RemoveRedundantAsOperator:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Remove redundant 'as' operator",
                        cancellationToken => RemoveRedundantAsOperatorRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.UseConditionalAccess:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Use conditional access",
                        cancellationToken => UseConditionalAccessRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.UseStringLengthInsteadOfComparisonWithEmptyString:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Use string.Length",
                        cancellationToken => UseStringLengthInsteadOfComparisonWithEmptyStringRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }
                }
            }
        }
Example #2
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

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

            if (binaryExpression == null)
            {
                return;
            }

            foreach (Diagnostic diagnostic in context.Diagnostics)
            {
                switch (diagnostic.Id)
                {
                case DiagnosticIdentifiers.SimplifyBooleanComparison:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Simplify boolean comparison",
                        cancellationToken => SimplifyBooleanComparisonRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);

                    break;
                }

                case DiagnosticIdentifiers.UseAnyMethodInsteadOfCountMethod:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Call 'Any' instead of 'Count'",
                        cancellationToken => UseAnyMethodInsteadOfCountMethodRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.AvoidNullLiteralExpressionOnLeftSideOfBinaryExpression:
                {
                    CodeAction codeAction = CodeAction.Create(
                        $"Swap '{binaryExpression.Left}' and '{binaryExpression.Right}'",
                        cancellationToken => SwapExpressionsInBinaryExpressionRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.UseStringIsNullOrEmptyMethod:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Use 'string.IsNullOrEmpty' method",
                        cancellationToken => UseStringIsNullOrEmptyMethodRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.SimplifyCoalesceExpression:
                {
                    ExpressionSyntax expression = binaryExpression.Left;

                    if (expression == null ||
                        !context.Span.Contains(expression.Span))
                    {
                        expression = binaryExpression.Right;
                    }

                    CodeAction codeAction = CodeAction.Create(
                        "Simplify coalesce expression",
                        cancellationToken => SimplifyCoalesceExpressionRefactoring.RefactorAsync(context.Document, binaryExpression, expression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.RemoveRedundantAsOperator:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Remove redundant 'as' operator",
                        cancellationToken => RemoveRedundantAsOperatorRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.UseStringLengthInsteadOfComparisonWithEmptyString:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Use string.Length",
                        cancellationToken => UseStringLengthInsteadOfComparisonWithEmptyStringRefactoring.RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.UnconstrainedTypeParameterCheckedForNull:
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(binaryExpression.Left, context.CancellationToken);

                    CodeAction codeAction = CodeAction.Create(
                        $"Use EqualityComparer<{typeSymbol.Name}>.Default",
                        cancellationToken => UnconstrainedTypeParameterCheckedForNullRefactoring.RefactorAsync(context.Document, binaryExpression, typeSymbol, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.ValueTypeCheckedForNull:
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(binaryExpression.Left, context.CancellationToken);

                    string title = null;

                    if (typeSymbol.IsPredefinedValueType() ||
                        typeSymbol.ExistsMethod(WellKnownMemberNames.EqualityOperatorName))
                    {
                        ExpressionSyntax expression = typeSymbol.ToDefaultValueSyntax(semanticModel, binaryExpression.Right.SpanStart);

                        title = $"Replace 'null' with '{expression}'";
                    }
                    else
                    {
                        title = $"Use EqualityComparer<{SymbolDisplay.GetMinimalString(typeSymbol, semanticModel, binaryExpression.Right.SpanStart)}>.Default";
                    }

                    CodeAction codeAction = CodeAction.Create(
                        title,
                        cancellationToken => ValueTypeCheckedForNullRefactoring.RefactorAsync(context.Document, binaryExpression, typeSymbol, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }

                case DiagnosticIdentifiers.UseIsOperatorInsteadOfAsOperator:
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Use is operator",
                        cancellationToken => UseIsOperatorInsteadOfAsOperatorRefactoring.
                        RefactorAsync(context.Document, binaryExpression, cancellationToken),
                        diagnostic.Id + EquivalenceKeySuffix);

                    context.RegisterCodeFix(codeAction, diagnostic);
                    break;
                }
                }
            }
        }