コード例 #1
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(
                    root,
                    context.Span,
                    out ExpressionSyntax expression,
                    predicate: f => f.IsKind(
                        SyntaxKind.InvocationExpression,
                        SyntaxKind.ElementAccessExpression,
                        SyntaxKind.ConditionalAccessExpression)))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            CodeAction codeAction = CodeAction.Create(
                "Fix formatting",
                ct =>
            {
                TextLineCollection lines = expression.SyntaxTree.GetText().Lines;

                TextLine line = lines.GetLineFromPosition(expression.SpanStart);

                TextSpan span = TextSpan.FromBounds(line.EndIncludingLineBreak, expression.Span.End);

                return(CodeFixHelpers.FixCallChainAsync(document, expression, span, ct));
            },
                GetEquivalenceKey(diagnostic));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
コード例 #2
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out BlockSyntax block))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            switch (diagnostic.Id)
            {
            case DiagnosticIdentifiers.AddNewLineAfterOpeningBraceOfBlock:
            case DiagnosticIdentifiers.AddNewLineAfterOpeningBraceOfEmptyBlock:
            case DiagnosticIdentifiers.AddNewLineAfterOpeningBraceOfAccessor:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddNewLine,
                    ct => CodeFixHelpers.AddNewLineAfterOpeningBraceAsync(document, block, ct),
                    GetEquivalenceKey(diagnostic));

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

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out TypeParameterConstraintClauseSyntax constraintClause))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            CodeAction codeAction = CodeAction.Create(
                CodeFixTitles.AddNewLine,
                ct =>
            {
                return(CodeFixHelpers.AddNewLineBeforeAndIncreaseIndentationAsync(
                           document,
                           constraintClause.WhereKeyword,
                           constraintClause.Parent.GetIndentation(ct),
                           ct));
            },
                GetEquivalenceKey(diagnostic));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
コード例 #4
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out BinaryExpressionSyntax binaryExpression))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            if (DiagnosticProperties.ContainsInvert(diagnostic.Properties))
            {
                CodeAction codeAction = CodeAction.Create(
                    $"Add newline after '{binaryExpression.OperatorToken.ToString()}' instead of before it",
                    ct => CodeFixHelpers.AddNewLineAfterInsteadOfBeforeAsync(document, binaryExpression.Left, binaryExpression.OperatorToken, binaryExpression.Right, ct),
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
            }
            else
            {
                CodeAction codeAction = CodeAction.Create(
                    $"Add newline before '{binaryExpression.OperatorToken.ToString()}' instead of after it",
                    ct => CodeFixHelpers.AddNewLineBeforeInsteadOfAfterAsync(document, binaryExpression.Left, binaryExpression.OperatorToken, binaryExpression.Right, ct),
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
            }
        }
コード例 #5
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            if (!TryFindTrivia(root, context.Span.Start, out SyntaxTrivia trivia, findInsideTrivia: false))
            {
                return;
            }

            switch (diagnostic.Id)
            {
            case DiagnosticIdentifiers.AddEmptyLineBetweenAccessors:
            case DiagnosticIdentifiers.AddEmptyLineBetweenSingleLineAccessors:
            case DiagnosticIdentifiers.AddEmptyLineBetweenUsingDirectivesWithDifferentRootNamespace:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddEmptyLine,
                    ct => CodeFixHelpers.AppendEndOfLineAsync(document, trivia.Token, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.RemoveEmptyLineBetweenSingleLineAccessors:
            case DiagnosticIdentifiers.RemoveEmptyLineBetweenUsingDirectivesWithDifferentRootNamespace:
            case DiagnosticIdentifiers.RemoveEmptyLineBetweenUsingDirectivesWithSameRootNamespace:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.RemoveEmptyLine,
                    ct => CodeFixHelpers.RemoveEmptyLinesBeforeAsync(document, trivia.Token, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.RemoveNewLineBeforeBaseList:
            case DiagnosticIdentifiers.RemoveNewLineBetweenClosingBraceAndWhileKeyword:
            case DiagnosticIdentifiers.RemoveNewLineBetweenIfKeywordAndElseKeyword:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.RemoveNewLine,
                    ct => CodeFixHelpers.ReplaceTriviaBetweenAsync(document, trivia.Token, trivia.Token.GetNextToken(), cancellationToken: ct),
                    GetEquivalenceKey(diagnostic));

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

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out StatementSyntax statement))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            switch (diagnostic.Id)
            {
            case DiagnosticIdentifiers.AddNewLineBeforeStatement:
            case DiagnosticIdentifiers.AddNewLineBeforeEmbeddedStatement:
            case DiagnosticIdentifiers.AddNewLineAfterSwitchLabel:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddNewLine,
                    ct => AddNewLineBeforeStatementAsync(document, statement, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.AddEmptyLineAfterEmbeddedStatement:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddEmptyLine,
                    ct => CodeFixHelpers.AppendEndOfLineAsync(document, statement, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.AddEmptyLineBeforeClosingBraceOfDoStatement:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddEmptyLine,
                    ct => CodeFixHelpers.AppendEndOfLineAsync(document, statement, ct),
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
                break;
            }
            }
        }
コード例 #7
0
        private static Task <Document> AddBlankLineAfterRegionDirectiveAndBeforeEndRegionAsync(
            Document document,
            DirectiveTriviaSyntax directiveTrivia,
            CancellationToken cancellationToken)
        {
            switch (directiveTrivia.Kind())
            {
            case SyntaxKind.RegionDirectiveTrivia:
                return(CodeFixHelpers.AddBlankLineAfterDirectiveAsync(document, directiveTrivia, cancellationToken));

            case SyntaxKind.EndRegionDirectiveTrivia:
                return(CodeFixHelpers.AddBlankLineBeforeDirectiveAsync(document, directiveTrivia, cancellationToken));

            default:
                throw new InvalidOperationException();
            }
        }
コード例 #8
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out MemberDeclarationSyntax memberDeclaration))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            switch (diagnostic.Id)
            {
            case DiagnosticIdentifiers.FormatTypeDeclarationBraces:
            {
                CodeAction codeAction = CodeAction.Create(
                    "Format braces on multiple lines",
                    ct => FormatTypeDeclarationBracesOnMultipleLinesAsync(document, memberDeclaration, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.PutConstructorInitializerOnItsOwnLine:
            {
                CodeAction codeAction = CodeAction.Create(
                    "Put constructor initializer on its own line",
                    ct =>
                    {
                        return(CodeFixHelpers.AddNewLineBeforeAndIncreaseIndentationAsync(
                                   document,
                                   ((ConstructorDeclarationSyntax)memberDeclaration).Initializer.ColonToken,
                                   SyntaxTriviaAnalysis.AnalyzeIndentation(memberDeclaration, ct),
                                   ct));
                    },
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
                break;
            }
            }
        }
コード例 #9
0
        private static Task <Document> AddNewLineAfterConditionalOperatorInsteadOfBeforeItAsync(
            Document document,
            ConditionalExpressionSyntax conditionalExpression,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax condition     = conditionalExpression.Condition;
            ExpressionSyntax whenTrue      = conditionalExpression.WhenTrue;
            ExpressionSyntax whenFalse     = conditionalExpression.WhenFalse;
            SyntaxToken      questionToken = conditionalExpression.QuestionToken;
            SyntaxToken      colonToken    = conditionalExpression.ColonToken;

            ExpressionSyntax newCondition     = condition;
            ExpressionSyntax newWhenTrue      = whenTrue;
            ExpressionSyntax newWhenFalse     = whenFalse;
            SyntaxToken      newQuestionToken = questionToken;
            SyntaxToken      newColonToken    = colonToken;

            if (SyntaxTriviaAnalysis.IsTokenPrecededWithNewLineAndNotFollowedWithNewLine(condition, questionToken, whenTrue))
            {
                var(left, token, right) = CodeFixHelpers.AddNewLineAfterTokenInsteadOfBeforeIt(condition, questionToken, whenTrue);

                newCondition     = left;
                newQuestionToken = token;
                newWhenTrue      = right;
            }

            if (SyntaxTriviaAnalysis.IsTokenPrecededWithNewLineAndNotFollowedWithNewLine(whenTrue, colonToken, whenFalse))
            {
                var(left, token, right) = CodeFixHelpers.AddNewLineAfterTokenInsteadOfBeforeIt(newWhenTrue, colonToken, whenFalse);

                newWhenTrue   = left;
                newColonToken = token;
                newWhenFalse  = right;
            }

            ConditionalExpressionSyntax newConditionalExpression = ConditionalExpression(
                newCondition,
                newQuestionToken,
                newWhenTrue,
                newColonToken,
                newWhenFalse);

            return(document.ReplaceNodeAsync(conditionalExpression, newConditionalExpression, cancellationToken));
        }
コード例 #10
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out MemberDeclarationSyntax memberDeclaration))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            switch (diagnostic.Id)
            {
            case DiagnosticIdentifiers.AddNewLineAfterOpeningBraceOfTypeDeclaration:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddNewLine,
                    ct => AddNewLineAfterOpeningBraceOfTypeDeclarationAsync(document, memberDeclaration, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.AddNewLineBeforeConstructorInitializer:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddNewLine,
                    ct =>
                    {
                        return(CodeFixHelpers.AddNewLineBeforeAndIncreaseIndentationAsync(
                                   document,
                                   ((ConstructorDeclarationSyntax)memberDeclaration).Initializer.ColonToken,
                                   SyntaxTriviaAnalysis.AnalyzeIndentation(memberDeclaration, ct),
                                   ct));
                    },
                    GetEquivalenceKey(diagnostic));

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

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out SwitchSectionSyntax switchSection))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            CodeAction codeAction = CodeAction.Create(
                CodeFixTitles.AddNewLine,
                ct => CodeFixHelpers.AppendEndOfLineAsync(document, switchSection, ct),
                GetEquivalenceKey(diagnostic));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
コード例 #12
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out BinaryExpressionSyntax binaryExpression))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            CodeAction codeAction = CodeAction.Create(
                "Fix formatting",
                ct => CodeFixHelpers.FixBinaryExpressionAsync(document, binaryExpression, ct),
                GetEquivalenceKey(diagnostic));

            context.RegisterCodeFix(codeAction, diagnostic);
        }
コード例 #13
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out ConditionalAccessExpressionSyntax conditionalAccess))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            if (diagnostic.Properties.TryGetValue(nameof(NewLinePosition), out string newLinePositionRaw) &&
                Enum.TryParse(newLinePositionRaw, out NewLinePosition newLinePosition) &&
                newLinePosition == NewLinePosition.After)
            {
                CodeAction codeAction = CodeAction.Create(
                    $"Place '{conditionalAccess.OperatorToken.ToString()}' on the previous line",
                    ct => CodeFixHelpers.AddNewLineAfterInsteadOfBeforeAsync(
                        document,
                        conditionalAccess.Expression,
                        conditionalAccess.OperatorToken,
                        conditionalAccess.WhenNotNull,
                        ct),
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
            }
            else
            {
                CodeAction codeAction = CodeAction.Create(
                    $"Place '{conditionalAccess.OperatorToken.ToString()}' on the next line",
                    ct => CodeFixHelpers.AddNewLineBeforeInsteadOfAfterAsync(
                        document,
                        conditionalAccess.Expression,
                        conditionalAccess.OperatorToken,
                        conditionalAccess.WhenNotNull,
                        ct),
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
            }
        }
コード例 #14
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            if (!TryFindTrivia(root, context.Span.Start, out SyntaxTrivia trivia, findInsideTrivia: false))
            {
                return;
            }

            switch (diagnostic.Id)
            {
            case DiagnosticIdentifiers.AddEmptyLineBetweenDeclarations:
            case DiagnosticIdentifiers.AddEmptyLineBetweenSingleLineDeclarations:
            case DiagnosticIdentifiers.AddEmptyLineBetweenDeclarationAndDocumentationComment:
            case DiagnosticIdentifiers.AddEmptyLineBetweenSingleLineDeclarationsOfDifferentKind:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddEmptyLine,
                    ct => CodeFixHelpers.AppendEndOfLineAsync(document, trivia.Token, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.RemoveEmptyLineBetweenSingleLineDeclarationsOfSameKind:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.RemoveEmptyLine,
                    ct => CodeFixHelpers.RemoveEmptyLinesBeforeAsync(document, trivia.Token, ct),
                    GetEquivalenceKey(diagnostic));

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

            if (!TryFindToken(root, context.Span.Start, out SyntaxToken token))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            switch (diagnostic.Id)
            {
            case DiagnosticIdentifiers.AddEmptyLineBetweenBlockAndStatement:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddEmptyLine,
                    ct => CodeFixHelpers.AppendEndOfLineAsync(document, token, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.AddNewLineBeforeConditionalOperatorInsteadOfAfterItOrViceVersa:
            {
                if (DiagnosticProperties.ContainsInvert(diagnostic.Properties))
                {
                    var conditionalExpression = (ConditionalExpressionSyntax)token.Parent;

                    string title = null;
                    if (token.IsKind(SyntaxKind.QuestionToken))
                    {
                        title = (SyntaxTriviaAnalysis.IsTokenFollowedWithNewLineAndNotPrecededWithNewLine(conditionalExpression.WhenTrue, conditionalExpression.ColonToken, conditionalExpression.WhenFalse))
                                    ? "Add newline after '?' and ':' instead of before it"
                                    : "Add newline after '?' instead of before it";
                    }
                    else
                    {
                        title = "Add newline after ':' instead of before it";
                    }

                    CodeAction codeAction = CodeAction.Create(
                        title,
                        ct => AddNewLineAfterConditionalOperatorInsteadOfBeforeItAsync(document, conditionalExpression, ct),
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }
                else
                {
                    var conditionalExpression = (ConditionalExpressionSyntax)token.Parent;

                    string title = null;
                    if (token.IsKind(SyntaxKind.QuestionToken))
                    {
                        title = (SyntaxTriviaAnalysis.IsTokenFollowedWithNewLineAndNotPrecededWithNewLine(conditionalExpression.WhenTrue, conditionalExpression.ColonToken, conditionalExpression.WhenFalse))
                                    ? "Add newline before '?' and ':' instead of after it"
                                    : "Add newline before '?' instead of after it";
                    }
                    else
                    {
                        title = "Add newline before ':' instead of after it";
                    }

                    CodeAction codeAction = CodeAction.Create(
                        title,
                        ct => AddNewLineBeforeConditionalOperatorInsteadOfAfterItAsync(document, conditionalExpression, ct),
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }

                break;
            }

            case DiagnosticIdentifiers.AddNewLineBeforeExpressionBodyArrowInsteadOfAfterItOrViceVersa:
            case DiagnosticIdentifiers.AddNewLineBeforeEqualsSignInsteadOfAfterItOrViceVersa:
            {
                AddNewLineBeforeOrAfter();
                break;
            }

            case DiagnosticIdentifiers.AddNewLineAfterAttributeList:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddNewLine,
                    ct => CodeFixHelpers.AddNewLineBeforeAsync(document, token, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.AddNewLineBetweenClosingBraceAndWhileKeywordOrViceVersa:
            {
                if (DiagnosticProperties.ContainsInvert(diagnostic.Properties))
                {
                    CodeAction codeAction = CodeAction.Create(
                        CodeFixTitles.RemoveNewLine,
                        ct => CodeFixHelpers.ReplaceTriviaBetweenAsync(document, token, token.GetNextToken(), cancellationToken: ct),
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }
                else
                {
                    CodeAction codeAction = CodeAction.Create(
                        CodeFixTitles.AddNewLine,
                        ct => CodeFixHelpers.AddNewLineBeforeAsync(document, token, ct),
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }

                break;
            }
            }

            void AddNewLineBeforeOrAfter()
            {
                if (DiagnosticProperties.ContainsInvert(diagnostic.Properties))
                {
                    CodeAction codeAction = CodeAction.Create(
                        $"Add newline after '{token}' instead of before it",
                        ct => CodeFixHelpers.AddNewLineAfterInsteadOfBeforeAsync(document, token, ct),
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }
                else
                {
                    CodeAction codeAction = CodeAction.Create(
                        $"Add newline before '{token}' instead of after it",
                        ct => CodeFixHelpers.AddNewLineBeforeInsteadOfAfterAsync(document, token, ct),
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }
            }
        }
コード例 #16
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindToken(root, context.Span.Start, out SyntaxToken token))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            switch (diagnostic.Id)
            {
            case DiagnosticIdentifiers.AddEmptyLineBetweenBlockAndStatement:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddEmptyLine,
                    ct => CodeFixHelpers.AppendEndOfLineAsync(document, token, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.AddNewLineBeforeConditionalOperatorInsteadOfAfterIt:
            {
                var conditionalExpression = (ConditionalExpressionSyntax)token.Parent;

                string title = null;
                if (token.IsKind(SyntaxKind.QuestionToken))
                {
                    title = (SyntaxTriviaAnalysis.IsTokenFollowedWithNewLineAndNotPrecededWithNewLine(conditionalExpression.WhenTrue, conditionalExpression.ColonToken, conditionalExpression.WhenFalse))
                                ? "Add newline before '?' and ':' instead of after it"
                                : "Add newline before '?' instead of after it";
                }
                else
                {
                    title = "Add newline before ':' instead of after it";
                }

                CodeAction codeAction = CodeAction.Create(
                    title,
                    ct => AddNewLineBeforeConditionalOperatorInsteadOfAfterItAsync(document, conditionalExpression, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.AddNewLineAfterConditionalOperatorInsteadOfBeforeIt:
            {
                var conditionalExpression = (ConditionalExpressionSyntax)token.Parent;

                string title = null;
                if (token.IsKind(SyntaxKind.QuestionToken))
                {
                    title = (SyntaxTriviaAnalysis.IsTokenFollowedWithNewLineAndNotPrecededWithNewLine(conditionalExpression.WhenTrue, conditionalExpression.ColonToken, conditionalExpression.WhenFalse))
                                ? "Add newline after '?' and ':' instead of before it"
                                : "Add newline after '?' instead of before it";
                }
                else
                {
                    title = "Add newline after ':' instead of before it";
                }

                CodeAction codeAction = CodeAction.Create(
                    title,
                    ct => AddNewLineAfterConditionalOperatorInsteadOfBeforeItAsync(document, conditionalExpression, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.AddNewLineAfterExpressionBodyArrowInsteadOfBeforeIt:
            {
                CodeAction codeAction = CodeAction.Create(
                    "Add newline after '=>' instead of before it",
                    ct =>
                    {
                        var expressionBody = (ArrowExpressionClauseSyntax)token.Parent;

                        return(CodeFixHelpers.AddNewLineAfterInsteadOfBeforeAsync(document, token.GetPreviousToken(), token, expressionBody.Expression, ct));
                    },
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.AddNewLineBeforeExpressionBodyArrowInsteadOfAfterIt:
            {
                CodeAction codeAction = CodeAction.Create(
                    "Add newline before '=>' instead of after it",
                    ct =>
                    {
                        var expressionBody = (ArrowExpressionClauseSyntax)token.Parent;

                        return(CodeFixHelpers.AddNewLineBeforeInsteadOfAfterAsync(document, token.GetPreviousToken(), token, expressionBody.Expression, ct));
                    },
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.AddNewLineAfterAttributeList:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddNewLine,
                    ct => CodeFixHelpers.AddNewLineBeforeAsync(document, token, ct),
                    GetEquivalenceKey(diagnostic));

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

            if (!TryFindFirstAncestorOrSelf(
                    root,
                    context.Span,
                    out SyntaxNode node,
                    findInsideTrivia: true,
                    predicate: f => f.IsKind(SyntaxKind.UsingDirective, SyntaxKind.RegionDirectiveTrivia, SyntaxKind.EndRegionDirectiveTrivia)))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            switch (node)
            {
            case UsingDirectiveSyntax usingDirective:
            {
                if (context.Span.Start == usingDirective.SpanStart)
                {
                    CodeAction codeAction = CodeAction.Create(
                        CodeFixTitles.AddBlankLine,
                        ct => AddBlankLineBeforeUsingDirectiveAsync(document, usingDirective, ct),
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }
                else
                {
                    CodeAction codeAction = CodeAction.Create(
                        CodeFixTitles.AddBlankLine,
                        ct => CodeFixHelpers.AppendEndOfLineAsync(document, usingDirective, ct),
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }

                break;
            }

            case RegionDirectiveTriviaSyntax regionDirective:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddBlankLine,
                    ct => CodeFixHelpers.AddBlankLineBeforeDirectiveAsync(document, regionDirective, ct),
                    GetEquivalenceKey(diagnostic));

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

            case EndRegionDirectiveTriviaSyntax endRegionDirective:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddBlankLine,
                    ct => CodeFixHelpers.AddBlankLineAfterDirectiveAsync(document, endRegionDirective, ct),
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
                break;
            }
            }
        }
コード例 #18
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            if (!TryFindTrivia(root, context.Span.Start, out SyntaxTrivia trivia, findInsideTrivia: false))
            {
                return;
            }

            switch (diagnostic.Id)
            {
            case DiagnosticIdentifiers.AddBlankLineAfterTopComment:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddBlankLine,
                    ct => document.ReplaceTokenAsync(trivia.Token, trivia.Token.AppendEndOfLineToLeadingTrivia(), ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.AddBlankLineBeforeTopDeclaration:
            case DiagnosticIdentifiers.AddBlankLineBetweenAccessors:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.AddBlankLine,
                    ct => CodeFixHelpers.AppendEndOfLineAsync(document, trivia.Token, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.BlankLineBetweenSingleLineAccessors:
            case DiagnosticIdentifiers.BlankLineBetweenUsingDirectives:
            {
                if (DiagnosticProperties.ContainsInvert(diagnostic.Properties))
                {
                    CodeAction codeAction = CodeAction.Create(
                        CodeFixTitles.RemoveBlankLine,
                        ct => CodeFixHelpers.RemoveBlankLinesBeforeAsync(document, trivia.Token, ct),
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }
                else
                {
                    CodeAction codeAction = CodeAction.Create(
                        CodeFixTitles.AddBlankLine,
                        ct => CodeFixHelpers.AppendEndOfLineAsync(document, trivia.Token, ct),
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }

                break;
            }

            case DiagnosticIdentifiers.RemoveBlankLineBetweenUsingDirectivesWithSameRootNamespace:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.RemoveBlankLine,
                    ct => CodeFixHelpers.RemoveBlankLinesBeforeAsync(document, trivia.Token, ct),
                    GetEquivalenceKey(diagnostic));

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

            case DiagnosticIdentifiers.RemoveNewLineBeforeBaseList:
            case DiagnosticIdentifiers.RemoveNewLineBetweenIfKeywordAndElseKeyword:
            {
                CodeAction codeAction = CodeAction.Create(
                    CodeFixTitles.RemoveNewLine,
                    ct => CodeFixHelpers.ReplaceTriviaBetweenAsync(document, trivia.Token, trivia.Token.GetNextToken(), cancellationToken: ct),
                    GetEquivalenceKey(diagnostic));

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