Example #1
0
        private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            SyntaxToken originalToken = root.FindToken(diagnostic.Location.SourceSpan.Start);

            SyntaxTree tree       = root.SyntaxTree;
            SourceText sourceText = await tree.GetTextAsync(cancellationToken).ConfigureAwait(false);

            TextLine sourceLine = sourceText.Lines.GetLineFromPosition(originalToken.SpanStart);

            string lineText = sourceText.ToString(sourceLine.Span);
            int    indentLength;

            for (indentLength = 0; indentLength < lineText.Length; indentLength++)
            {
                if (!char.IsWhiteSpace(lineText[indentLength]))
                {
                    break;
                }
            }

            IndentationOptions indentationOptions = IndentationOptions.FromDocument(document);
            SyntaxTriviaList   newTrivia          =
                SyntaxFactory.TriviaList(
                    SyntaxFactory.CarriageReturnLineFeed,
                    SyntaxFactory.Whitespace(lineText.Substring(0, indentLength) + IndentationHelper.GenerateIndentationString(indentationOptions, 1)));

            SyntaxToken updatedToken = originalToken.WithLeadingTrivia(originalToken.LeadingTrivia.AddRange(newTrivia));
            SyntaxNode  updatedRoot  = root.ReplaceToken(originalToken, updatedToken);

            return(document.WithSyntaxRoot(updatedRoot));
        }
Example #2
0
        private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var indentationOptions = IndentationOptions.FromDocument(document);
            var syntaxRoot         = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var violatingTrivia = syntaxRoot.FindTrivia(diagnostic.Location.SourceSpan.Start);

            var stringBuilder = new StringBuilder();

            var column = violatingTrivia.GetLocation().GetLineSpan().StartLinePosition.Character;

            foreach (var c in violatingTrivia.ToFullString())
            {
                if (c == '\t')
                {
                    var offsetWithinTabColumn = column % indentationOptions.TabSize;
                    var spaceCount            = indentationOptions.TabSize - offsetWithinTabColumn;

                    stringBuilder.Append(' ', spaceCount);
                    column += spaceCount;
                }
                else
                {
                    stringBuilder.Append(c);
                    column++;
                }
            }

            var newSyntaxRoot = syntaxRoot.ReplaceTrivia(violatingTrivia, SyntaxFactory.Whitespace(stringBuilder.ToString(), elastic: false));

            return(document.WithSyntaxRoot(newSyntaxRoot));
        }
Example #3
0
        private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var violatingAttribute = (AttributeSyntax)syntaxRoot.FindNode(diagnostic.Location.SourceSpan).Parent;
            var attributeList      = (AttributeListSyntax)violatingAttribute.Parent;
            var newAttributeLists  = new List <AttributeListSyntax>();

            var indentationOptions = IndentationOptions.FromDocument(document);
            var indentationSteps   = IndentationHelper.GetIndentationSteps(indentationOptions, attributeList);
            var indentationTrivia  = IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, indentationSteps);

            for (var i = 0; i < attributeList.Attributes.Count; i++)
            {
                var newAttributes    = SyntaxFactory.SingletonSeparatedList(attributeList.Attributes[i]);
                var newAttributeList = SyntaxFactory.AttributeList(attributeList.Target, newAttributes);

                newAttributeList = (i == 0)
                    ? newAttributeList.WithLeadingTrivia(attributeList.GetLeadingTrivia())
                    : newAttributeList.WithLeadingTrivia(indentationTrivia);

                newAttributeList = (i == (attributeList.Attributes.Count - 1))
                    ? newAttributeList.WithTrailingTrivia(attributeList.GetTrailingTrivia())
                    : newAttributeList.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed);

                newAttributeLists.Add(newAttributeList);
            }

            var newSyntaxRoot = syntaxRoot.ReplaceNode(attributeList, newAttributeLists);
            var newDocument   = document.WithSyntaxRoot(newSyntaxRoot.WithoutFormatting());

            return(newDocument);
        }
            protected override async Task <SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);

                if (diagnostics.IsEmpty)
                {
                    return(null);
                }

                var        indentationOptions = IndentationOptions.FromDocument(document);
                SourceText sourceText         = await document.GetTextAsync(fixAllContext.CancellationToken).ConfigureAwait(false);

                List <TextChange> changes = new List <TextChange>();

                foreach (var diagnostic in diagnostics)
                {
                    changes.Add(FixDiagnostic(indentationOptions, sourceText, diagnostic));
                }

                changes.Sort((left, right) => left.Span.Start.CompareTo(right.Span.Start));

                SyntaxTree tree = await document.GetSyntaxTreeAsync(fixAllContext.CancellationToken).ConfigureAwait(false);

                return(await tree.WithChangedText(sourceText.WithChanges(changes)).GetRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false));
            }
            protected override async Task <SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document, ImmutableArray <Diagnostic> diagnostics)
            {
                if (diagnostics.IsEmpty)
                {
                    return(null);
                }

                var indentationOptions = IndentationOptions.FromDocument(document);
                var settings           = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, fixAllContext.CancellationToken);
                var elementOrder       = settings.OrderingRules.ElementOrder;
                var syntaxRoot         = await document.GetSyntaxRootAsync().ConfigureAwait(false);

                var trackedDiagnosticMembers = new List <MemberDeclarationSyntax>();

                foreach (var diagnostic in diagnostics)
                {
                    var memberDeclaration = syntaxRoot.FindNode(diagnostic.Location.SourceSpan).FirstAncestorOrSelf <MemberDeclarationSyntax>();
                    if (memberDeclaration == null)
                    {
                        continue;
                    }

                    trackedDiagnosticMembers.Add(memberDeclaration);
                }

                syntaxRoot = syntaxRoot.TrackNodes(trackedDiagnosticMembers);

                foreach (var member in trackedDiagnosticMembers)
                {
                    var memberDeclaration = syntaxRoot.GetCurrentNode(member);
                    syntaxRoot = UpdateSyntaxRoot(memberDeclaration, elementOrder, syntaxRoot, indentationOptions);
                }

                return(syntaxRoot);
            }
        private Document CreateCodeFix(Document document, Diagnostic diagnostic, SyntaxNode syntaxRoot)
        {
            SyntaxNode newSyntaxRoot      = syntaxRoot;
            var        node               = syntaxRoot.FindNode(diagnostic.Location.SourceSpan);
            var        indentationOptions = IndentationOptions.FromDocument(document);

            switch (node.Kind())
            {
            case SyntaxKind.ClassDeclaration:
            case SyntaxKind.InterfaceDeclaration:
            case SyntaxKind.StructDeclaration:
            case SyntaxKind.EnumDeclaration:
                newSyntaxRoot = this.RegisterBaseTypeDeclarationCodeFix(syntaxRoot, (BaseTypeDeclarationSyntax)node, indentationOptions);
                break;

            case SyntaxKind.AccessorList:
                newSyntaxRoot = this.RegisterPropertyLikeDeclarationCodeFix(syntaxRoot, (BasePropertyDeclarationSyntax)node.Parent, indentationOptions);
                break;

            case SyntaxKind.Block:
                newSyntaxRoot = this.RegisterMethodLikeDeclarationCodeFix(syntaxRoot, (BaseMethodDeclarationSyntax)node.Parent, indentationOptions);
                break;

            case SyntaxKind.NamespaceDeclaration:
                newSyntaxRoot = this.RegisterNamespaceDeclarationCodeFix(syntaxRoot, (NamespaceDeclarationSyntax)node, indentationOptions);
                break;
            }

            return(document.WithSyntaxRoot(newSyntaxRoot));
        }
        private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var        indentationOptions = IndentationOptions.FromDocument(document);
            SourceText sourceText         = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            return(document.WithText(sourceText.WithChanges(FixDiagnostic(indentationOptions, sourceText, diagnostic))));
        }
Example #8
0
        private static async Task <Document> GetTransformedDocumentForMultipleLinesAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var queryExpression = (QueryExpressionSyntax)syntaxRoot.FindNode(diagnostic.Location.SourceSpan).Parent;
            var replaceMap      = new Dictionary <SyntaxToken, SyntaxToken>();

            var nodeList = CreateQueryNodeList(queryExpression);

            var indentationOptions = IndentationOptions.FromDocument(document);
            var indentationTrivia  = QueryIndentationHelpers.GetQueryIndentationTrivia(indentationOptions, queryExpression);

            for (var i = 1; i < nodeList.Length; i++)
            {
                var token          = nodeList[i].GetFirstToken();
                var precedingToken = token.GetPreviousToken();

                if (precedingToken.GetLine() == token.GetLine())
                {
                    var triviaList          = precedingToken.TrailingTrivia.AddRange(token.LeadingTrivia);
                    var processedTriviaList = triviaList.WithoutTrailingWhitespace().Add(SyntaxFactory.CarriageReturnLineFeed);

                    replaceMap.Add(precedingToken, precedingToken.WithTrailingTrivia(processedTriviaList));
                    replaceMap.Add(token, token.WithLeadingTrivia(indentationTrivia));
                }
            }

            var newSyntaxRoot = syntaxRoot.ReplaceTokens(replaceMap.Keys, (t1, t2) => replaceMap[t1]).WithoutFormatting();

            return(document.WithSyntaxRoot(newSyntaxRoot));
        }
        private static async Task <Document> GetTransformedDocumentForMutipleLinesAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var indentationOptions = IndentationOptions.FromDocument(document);

            var node         = syntaxRoot.FindNode(diagnostic.Location.SourceSpan);
            var accessorList = GetAccessorList(node);
            var replacements = new Dictionary <SyntaxNode, SyntaxNode>();

            foreach (var accessor in accessorList.Accessors)
            {
                var reformattedAccessor = ReformatAccessorAsMultipleLines(indentationOptions, accessor);
                if (accessor != accessorList.Accessors.Last())
                {
                    // insert an empty line between accessors
                    reformattedAccessor = reformattedAccessor.WithTrailingTrivia(reformattedAccessor.GetTrailingTrivia().Add(SyntaxFactory.CarriageReturnLineFeed));
                }

                replacements[accessor] = reformattedAccessor;
            }

            var newSyntaxRoot = syntaxRoot.ReplaceNodes(replacements.Keys, (original, maybeRewritten) => replacements[original]);

            return(document.WithSyntaxRoot(newSyntaxRoot.WithoutFormatting()));
        }
Example #10
0
        private BlockSyntax ReformatBlock(CodeFixContext context, BlockSyntax block)
        {
            var indentationOptions     = IndentationOptions.FromDocument(context.Document);
            var parentIndentationLevel = IndentationHelper.GetIndentationSteps(indentationOptions, block.Parent);

            var indentationString          = IndentationHelper.GenerateIndentationString(indentationOptions, parentIndentationLevel);
            var statementIndentationString = IndentationHelper.GenerateIndentationString(indentationOptions, parentIndentationLevel + 1);

            var newOpenBraceLeadingTrivia = block.OpenBraceToken.LeadingTrivia
                                            .WithoutTrailingWhitespace()
                                            .Add(SyntaxFactory.Whitespace(indentationString));

            var newOpenBraceTrailingTrivia = block.OpenBraceToken.TrailingTrivia
                                             .WithoutTrailingWhitespace()
                                             .Add(SyntaxFactory.CarriageReturnLineFeed);

            var newCloseBraceLeadingTrivia = block.CloseBraceToken.LeadingTrivia
                                             .WithoutTrailingWhitespace()
                                             .Add(SyntaxFactory.Whitespace(indentationString));

            var newCloseBraceTrailingTrivia = block.CloseBraceToken.TrailingTrivia
                                              .WithoutTrailingWhitespace();

            // only add an end-of-line to the close brace if there is none yet.
            if ((newCloseBraceTrailingTrivia.Count == 0) || !newCloseBraceTrailingTrivia.Last().IsKind(SyntaxKind.EndOfLineTrivia))
            {
                newCloseBraceTrailingTrivia = newCloseBraceTrailingTrivia.Add(SyntaxFactory.CarriageReturnLineFeed);
            }

            var openBraceToken = SyntaxFactory.Token(SyntaxKind.OpenBraceToken)
                                 .WithLeadingTrivia(newOpenBraceLeadingTrivia)
                                 .WithTrailingTrivia(newOpenBraceTrailingTrivia);

            var closeBraceToken = SyntaxFactory.Token(SyntaxKind.CloseBraceToken)
                                  .WithLeadingTrivia(newCloseBraceLeadingTrivia)
                                  .WithTrailingTrivia(newCloseBraceTrailingTrivia);

            var statements = SyntaxFactory.List <StatementSyntax>();

            foreach (var statement in block.Statements)
            {
                var newLeadingTrivia = statement.GetLeadingTrivia()
                                       .WithoutTrailingWhitespace()
                                       .Add(SyntaxFactory.Whitespace(statementIndentationString));

                var newTrailingTrivia = statement.GetTrailingTrivia()
                                        .WithoutTrailingWhitespace()
                                        .Add(SyntaxFactory.CarriageReturnLineFeed);

                var modifiedStatement = statement
                                        .WithLeadingTrivia(newLeadingTrivia)
                                        .WithTrailingTrivia(newTrailingTrivia);

                statements = statements.Add(modifiedStatement);
            }

            return(SyntaxFactory.Block(openBraceToken, statements, closeBraceToken));
        }
Example #11
0
        private static SyntaxNode ReformatStatementAndParent(Document document, SyntaxNode syntaxRoot, StatementSyntax statement)
        {
            var parentLastToken = statement.GetFirstToken().GetPreviousToken();

            var parentEndLine      = parentLastToken.GetEndLine();
            var statementStartLine = statement.GetFirstToken().GetLine();

            var newParentLastToken = parentLastToken;

            if (parentEndLine == statementStartLine)
            {
                var newTrailingTrivia = parentLastToken.TrailingTrivia
                                        .WithoutTrailingWhitespace()
                                        .Add(SyntaxFactory.CarriageReturnLineFeed);

                newParentLastToken = newParentLastToken.WithTrailingTrivia(newTrailingTrivia);
            }

            var parentNextToken = statement.GetLastToken().GetNextToken();

            var nextTokenLine      = parentNextToken.GetLine();
            var statementCloseLine = statement.GetLastToken().GetEndLine();

            var newParentNextToken = parentNextToken;

            if (nextTokenLine == statementCloseLine)
            {
                var indentationOptions     = IndentationOptions.FromDocument(document);
                var parentIndentationLevel = IndentationHelper.GetIndentationSteps(indentationOptions, GetStatementParent(statement.Parent));
                var indentationString      = IndentationHelper.GenerateIndentationString(indentationOptions, parentIndentationLevel);
                newParentNextToken = newParentNextToken.WithLeadingTrivia(SyntaxFactory.Whitespace(indentationString));
            }

            var newStatement  = ReformatStatement(document, statement);
            var newSyntaxRoot = syntaxRoot.ReplaceSyntax(
                new[] { statement },
                (originalNode, rewrittenNode) => originalNode == statement ? newStatement : rewrittenNode,
                new[] { parentLastToken, parentNextToken },
                (originalToken, rewrittenToken) =>
            {
                if (originalToken == parentLastToken)
                {
                    return(newParentLastToken);
                }
                else if (originalToken == parentNextToken)
                {
                    return(newParentNextToken);
                }
                else
                {
                    return(rewrittenToken);
                }
            },
                Enumerable.Empty <SyntaxTrivia>(),
                (originalTrivia, rewrittenTrivia) => rewrittenTrivia);

            return(newSyntaxRoot.WithoutFormatting());
        }
        private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var indentationOptions = IndentationOptions.FromDocument(document);
            var syntaxRoot         = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var violatingTrivia = syntaxRoot.FindTrivia(diagnostic.Location.SourceSpan.Start);

            var stringBuilder = new StringBuilder();

            int    firstTriviaIndex = violatingTrivia.GetLineSpan().StartLinePosition.Character;
            string relevantText;

            if (firstTriviaIndex == 0)
            {
                relevantText = violatingTrivia.ToFullString();
            }
            else
            {
                SourceText sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

                relevantText = sourceText.ToString(new TextSpan(violatingTrivia.FullSpan.Start - firstTriviaIndex, firstTriviaIndex + violatingTrivia.FullSpan.Length));
            }

            int column = 0;

            for (int i = 0; i < relevantText.Length; i++)
            {
                char c = relevantText[i];
                if (c == '\t')
                {
                    var offsetWithinTabColumn = column % indentationOptions.TabSize;
                    var spaceCount            = indentationOptions.TabSize - offsetWithinTabColumn;

                    if (i >= firstTriviaIndex)
                    {
                        stringBuilder.Append(' ', spaceCount);
                    }

                    column += spaceCount;
                }
                else
                {
                    if (i >= firstTriviaIndex)
                    {
                        stringBuilder.Append(c);
                    }

                    column++;
                }
            }

            var newSyntaxRoot = syntaxRoot.ReplaceTrivia(violatingTrivia, SyntaxFactory.Whitespace(stringBuilder.ToString()));

            return(document.WithSyntaxRoot(newSyntaxRoot));
        }
        public async Task VerifyGetIndentationStepsAsync(string indentationString, int expectedIndentationSteps, int indentationSize, int tabSize)
        {
            var testSource         = $"{indentationString}public class TestClass {{}}";
            var document           = CreateTestDocument(testSource, indentationSize, false, tabSize);
            var indentationOptions = IndentationOptions.FromDocument(document);

            var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);

            var firstToken = syntaxRoot.GetFirstToken();

            Assert.Equal(expectedIndentationSteps, IndentationHelper.GetIndentationSteps(indentationOptions, firstToken));
        }
        public async Task VerifyGetIndentationStepsForTokenNotAtStartOfLineAsync()
        {
            var testSource         = "    public class TestClass {}";
            var document           = CreateTestDocument(testSource);
            var indentationOptions = IndentationOptions.FromDocument(document);

            var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);

            var secondToken = syntaxRoot.GetFirstToken().GetNextToken();

            Assert.Equal(0, IndentationHelper.GetIndentationSteps(indentationOptions, secondToken));
        }
        private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var indentationOptions = IndentationOptions.FromDocument(document);
            var newLine            = TriviaHelper.GetNewLineTrivia(document);

            var constructorInitializer = (ConstructorInitializerSyntax)syntaxRoot.FindNode(diagnostic.Location.SourceSpan);
            var constructorDeclaration = (ConstructorDeclarationSyntax)constructorInitializer.Parent;

            var newConstructorDeclaration = ReformatConstructorDeclaration(constructorDeclaration, indentationOptions, newLine);

            var newSyntaxRoot = syntaxRoot.ReplaceNode(constructorDeclaration, newConstructorDeclaration);

            return(document.WithSyntaxRoot(newSyntaxRoot));
        }
Example #16
0
            protected override async Task <SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document, ImmutableArray <Diagnostic> diagnostics)
            {
                if (diagnostics.IsEmpty)
                {
                    return(null);
                }

                var syntaxRoot = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);

                var indentationOptions = IndentationOptions.FromDocument(document);
                var newLine            = FormattingHelper.GetNewLineTrivia(document);

                var nodes = diagnostics.Select(diagnostic => syntaxRoot.FindNode(diagnostic.Location.SourceSpan).Parent);

                return(syntaxRoot.ReplaceNodes(nodes, (originalNode, rewrittenNode) => ReformatConstructorDeclaration((ConstructorDeclarationSyntax)rewrittenNode, indentationOptions, newLine)));
            }
Example #17
0
        private static StatementSyntax ReformatStatement(Document document, StatementSyntax statement)
        {
            var indentationOptions     = IndentationOptions.FromDocument(document);
            var parentIndentationLevel = IndentationHelper.GetIndentationSteps(indentationOptions, GetStatementParent(statement.Parent));

            // use one additional step of indentation for lambdas / anonymous methods
            switch (statement.Parent.Kind())
            {
            case SyntaxKind.AnonymousMethodExpression:
            case SyntaxKind.SimpleLambdaExpression:
            case SyntaxKind.ParenthesizedLambdaExpression:
                parentIndentationLevel++;
                break;
            }

            var statementIndentationString = IndentationHelper.GenerateIndentationString(indentationOptions, parentIndentationLevel + 1);

            var newFirstTokenLeadingTrivia = statement.GetFirstToken().LeadingTrivia
                                             .WithoutTrailingWhitespace()
                                             .Add(SyntaxFactory.Whitespace(statementIndentationString));

            var newLastTokenTrailingTrivia = statement.GetLastToken().TrailingTrivia
                                             .WithoutTrailingWhitespace()
                                             .Add(SyntaxFactory.CarriageReturnLineFeed);

            var firstToken = statement.GetFirstToken().WithLeadingTrivia(newFirstTokenLeadingTrivia);
            var lastToken  = statement.GetLastToken().WithTrailingTrivia(newLastTokenTrailingTrivia);

            return(statement.ReplaceTokens(
                       new[] { statement.GetFirstToken(), statement.GetLastToken() },
                       (originalToken, rewrittenToken) =>
            {
                if (originalToken == statement.GetFirstToken())
                {
                    return firstToken;
                }
                else if (originalToken == statement.GetLastToken())
                {
                    return lastToken;
                }
                else
                {
                    return rewrittenToken;
                }
            }));
        }
        private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var nodeInSourceSpan = syntaxRoot.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);
            AttributeListSyntax attributeList = nodeInSourceSpan.FirstAncestorOrSelf <AttributeListSyntax>();

            var indentationOptions = IndentationOptions.FromDocument(document);
            var indentationSteps   = IndentationHelper.GetIndentationSteps(indentationOptions, attributeList);
            var indentationTrivia  = IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, indentationSteps);

            List <AttributeListSyntax> newAttributeLists = GetNewAttributeList(attributeList, indentationTrivia);

            var newSyntaxRoot = syntaxRoot.ReplaceNode(attributeList, newAttributeLists);
            var newDocument   = document.WithSyntaxRoot(newSyntaxRoot.WithoutFormatting());

            return(newDocument);
        }
        private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var settings     = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, cancellationToken);
            var elementOrder = settings.OrderingRules.ElementOrder;
            var syntaxRoot   = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var indentationOptions = IndentationOptions.FromDocument(document);

            var memberDeclaration = syntaxRoot.FindNode(diagnostic.Location.SourceSpan).FirstAncestorOrSelf <MemberDeclarationSyntax>();

            if (memberDeclaration == null)
            {
                return(document);
            }

            syntaxRoot = UpdateSyntaxRoot(memberDeclaration, elementOrder, syntaxRoot, indentationOptions);

            return(document.WithSyntaxRoot(syntaxRoot));
        }
Example #20
0
        private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var orderingChecks = await GetEnabledRulesForDocumentAsync(document, cancellationToken).ConfigureAwait(false);

            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var indentationOptions = IndentationOptions.FromDocument(document);

            var memberDeclaration = syntaxRoot.FindNode(diagnostic.Location.SourceSpan).FirstAncestorOrSelf <MemberDeclarationSyntax>();

            if (memberDeclaration == null)
            {
                return(document);
            }

            syntaxRoot = UpdateSyntaxRoot(memberDeclaration, orderingChecks, syntaxRoot, indentationOptions);

            return(document.WithSyntaxRoot(syntaxRoot));
        }
        private static async Task <Document> GetTransformedDocumentForSingleLineAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var indentationOptions = IndentationOptions.FromDocument(document);

            var node         = syntaxRoot.FindNode(diagnostic.Location.SourceSpan);
            var accessorList = GetAccessorList(node);
            var replacements = new Dictionary <SyntaxNode, SyntaxNode>();

            foreach (var accessor in accessorList.Accessors)
            {
                replacements[accessor] = ReformatAccessorAsSingleLine(indentationOptions, accessor);
            }

            var newSyntaxRoot = syntaxRoot.ReplaceNodes(replacements.Keys, (original, maybeRewritten) => replacements[original]);

            return(document.WithSyntaxRoot(newSyntaxRoot.WithoutFormatting()));
        }
        private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var indentationOptions = IndentationOptions.FromDocument(document);

            var attributeListSyntax = (AttributeListSyntax)syntaxRoot.FindNode(diagnostic.Location.SourceSpan);

            // use the containing type to determine the indentation level, anything else is less reliable.
            var containingType    = attributeListSyntax.Parent?.Parent;
            var indentationSteps  = (containingType != null) ? IndentationHelper.GetIndentationSteps(indentationOptions, containingType) + 1 : 0;
            var indentationTrivia = IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, indentationSteps);

            var tokensToReplace = new Dictionary <SyntaxToken, SyntaxToken>();

            if (diagnostic.Properties.ContainsKey(SA1134AttributesMustNotShareLine.FixWithNewLineBeforeKey))
            {
                var token     = attributeListSyntax.OpenBracketToken;
                var prevToken = token.GetPreviousToken();

                tokensToReplace[prevToken] = prevToken.WithTrailingTrivia(prevToken.TrailingTrivia.WithoutTrailingWhitespace().Add(SyntaxFactory.CarriageReturnLineFeed));

                var newLeadingTrivia = token.LeadingTrivia.Insert(0, indentationTrivia);
                tokensToReplace[token] = token.WithLeadingTrivia(newLeadingTrivia);
            }

            if (diagnostic.Properties.ContainsKey(SA1134AttributesMustNotShareLine.FixWithNewLineAfterKey))
            {
                var token     = attributeListSyntax.CloseBracketToken;
                var nextToken = token.GetNextToken();

                tokensToReplace[token] = token.WithTrailingTrivia(token.TrailingTrivia.WithoutTrailingWhitespace().Add(SyntaxFactory.CarriageReturnLineFeed));

                var newLeadingTrivia = nextToken.LeadingTrivia.Insert(0, indentationTrivia);
                tokensToReplace[nextToken] = nextToken.WithLeadingTrivia(newLeadingTrivia);
            }

            var newSyntaxRoot = syntaxRoot.ReplaceTokens(tokensToReplace.Keys, (original, rewritten) => tokensToReplace[original]);
            var newDocument   = document.WithSyntaxRoot(newSyntaxRoot.WithoutFormatting());

            return(newDocument);
        }
Example #23
0
        private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var token = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);

            var indentationOptions = IndentationOptions.FromDocument(document);
            var indentationTrivia  = QueryIndentationHelpers.GetQueryIndentationTrivia(indentationOptions, token);

            var precedingToken = token.GetPreviousToken();

            var replaceMap = new Dictionary <SyntaxToken, SyntaxToken>()
            {
                [precedingToken] = precedingToken.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed),
                [token]          = token.WithLeadingTrivia(indentationTrivia)
            };

            var newSyntaxRoot = syntaxRoot.ReplaceTokens(replaceMap.Keys, (t1, t2) => replaceMap[t1]).WithoutFormatting();

            return(document.WithSyntaxRoot(newSyntaxRoot));
        }
            protected override async Task <SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document, ImmutableArray <Diagnostic> diagnostics)
            {
                if (diagnostics.IsEmpty)
                {
                    return(null);
                }

                var indentationOptions = IndentationOptions.FromDocument(document);
                var syntaxRoot         = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);

                var nodes = diagnostics.Select(diagnostic => syntaxRoot.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true).FirstAncestorOrSelf <AttributeListSyntax>());

                var newRoot = syntaxRoot.TrackNodes(nodes);

                foreach (var attributeList in nodes)
                {
                    var indentationSteps  = IndentationHelper.GetIndentationSteps(indentationOptions, attributeList);
                    var indentationTrivia = IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, indentationSteps);
                    newRoot = newRoot.ReplaceNode(newRoot.GetCurrentNode(attributeList), GetNewAttributeList(attributeList, indentationTrivia));
                }

                return(newRoot);
            }
Example #25
0
            protected override async Task <SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);

                if (diagnostics.IsEmpty)
                {
                    return(null);
                }

                var indentationOptions = IndentationOptions.FromDocument(document);
                var orderingChecks     = await GetEnabledRulesForDocumentAsync(document, fixAllContext.CancellationToken).ConfigureAwait(false);

                var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);

                var trackedDiagnosticMembers = new List <MemberDeclarationSyntax>();

                foreach (var diagnostic in diagnostics)
                {
                    var memberDeclaration = syntaxRoot.FindNode(diagnostic.Location.SourceSpan).FirstAncestorOrSelf <MemberDeclarationSyntax>();
                    if (memberDeclaration == null)
                    {
                        continue;
                    }

                    trackedDiagnosticMembers.Add(memberDeclaration);
                }

                syntaxRoot = syntaxRoot.TrackNodes(trackedDiagnosticMembers);

                foreach (var member in trackedDiagnosticMembers)
                {
                    var memberDeclaration = syntaxRoot.GetCurrentNode(member);
                    syntaxRoot = UpdateSyntaxRoot(memberDeclaration, orderingChecks, syntaxRoot, indentationOptions);
                }

                return(syntaxRoot);
            }
Example #26
0
        private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var whereToken     = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
            var precedingToken = whereToken.GetPreviousToken();
            var endToken       = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.End);
            var afterEndToken  = endToken.GetNextToken();

            var parentIndentation  = GetParentIndentation(whereToken);
            var indentationOptions = IndentationOptions.FromDocument(document);
            var indentationTrivia  = SyntaxFactory.Whitespace(parentIndentation + IndentationHelper.GenerateIndentationString(indentationOptions, 1));

            var replaceMap = new Dictionary <SyntaxToken, SyntaxToken>()
            {
                [precedingToken] = precedingToken.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed),
                [whereToken]     = whereToken.WithLeadingTrivia(indentationTrivia),
                [endToken]       = endToken.WithTrailingTrivia(RemoveUnnecessaryWhitespaceTrivia(endToken).Add(SyntaxFactory.CarriageReturnLineFeed)),
            };

            if (afterEndToken.IsKind(SyntaxKind.EqualsGreaterThanToken))
            {
                replaceMap.Add(afterEndToken, afterEndToken.WithLeadingTrivia(indentationTrivia));
            }
            else if (afterEndToken.IsKind(SyntaxKind.OpenBraceToken))
            {
                replaceMap.Add(afterEndToken, afterEndToken.WithLeadingTrivia(SyntaxFactory.Whitespace(parentIndentation)));
            }
            else if (afterEndToken.IsKind(SyntaxKind.WhereKeyword))
            {
                replaceMap.Add(afterEndToken, afterEndToken.WithLeadingTrivia(indentationTrivia));
            }

            var newSyntaxRoot = syntaxRoot.ReplaceTokens(replaceMap.Keys, (t1, t2) => replaceMap[t1]).WithoutFormatting();

            return(document.WithSyntaxRoot(newSyntaxRoot));
        }
        private static Task <Document> GetTransformedDocumentAsync(Document document, SyntaxNode syntaxRoot, CancellationToken cancellationToken)
        {
            var compilationUnit = (CompilationUnitSyntax)syntaxRoot;

            var indentationOptions = IndentationOptions.FromDocument(document);

            var usingsHelper   = new UsingsHelper(document, compilationUnit);
            var namespaceCount = CountNamespaces(compilationUnit.Members);

            // Only move using declarations inside the namespace when
            // - SA1200 is enabled
            // - There are no global attributes
            // - There is only a single namespace declared at the top level
            var moveInsideNamespace =
                !document.Project.CompilationOptions.IsAnalyzerSuppressed(SA1200UsingDirectivesMustBePlacedWithinNamespace.DiagnosticId) &&
                !compilationUnit.AttributeLists.Any() &&
                compilationUnit.Members.Count == 1 &&
                namespaceCount == 1;

            string usingsIndentation;

            if (moveInsideNamespace)
            {
                var rootNamespace    = compilationUnit.Members.OfType <NamespaceDeclarationSyntax>().First();
                var indentationLevel = IndentationHelper.GetIndentationSteps(indentationOptions, rootNamespace);
                usingsIndentation = IndentationHelper.GenerateIndentationString(indentationOptions, indentationLevel + 1);
            }
            else
            {
                usingsIndentation = string.Empty;
            }

            // - The strategy is to strip all using directive that are not inside a conditional directive and replace them later with a sorted list at the correct spot
            // - The using directives that are inside a conditional directive are replaced (in sorted order) on the spot.
            // - Conditional directives are not moved, as correctly parsing them is too tricky
            // - No using directives will be stripped when there are multiple namespaces. In that case everything is replaced on the spot.
            List <UsingDirectiveSyntax> stripList;
            var replaceMap = new Dictionary <UsingDirectiveSyntax, UsingDirectiveSyntax>();

            // When there are multiple namespaces, do not move using statements outside of them, only sort.
            if (namespaceCount > 1)
            {
                BuildReplaceMapForNamespaces(usingsHelper, replaceMap, indentationOptions);
                stripList = new List <UsingDirectiveSyntax>();
            }
            else
            {
                stripList = usingsHelper.GetContainedUsings(usingsHelper.RootSpan);
            }

            BuildReplaceMapForConditionalDirectives(usingsHelper, replaceMap, indentationOptions, usingsHelper.RootSpan);

            var usingSyntaxRewriter = new UsingSyntaxRewriter(stripList, replaceMap);
            var newSyntaxRoot       = usingSyntaxRewriter.Visit(syntaxRoot);

            if (moveInsideNamespace)
            {
                newSyntaxRoot = AddUsingsToNamespace(newSyntaxRoot, usingsHelper, usingsIndentation, replaceMap.Any());
            }
            else if (namespaceCount <= 1)
            {
                newSyntaxRoot = AddUsingsToCompilationRoot(newSyntaxRoot, usingsHelper, usingsIndentation, replaceMap.Any());
            }

            newSyntaxRoot = ReAddFileHeader(syntaxRoot, newSyntaxRoot);

            var newDocument = document.WithSyntaxRoot(newSyntaxRoot.WithoutFormatting());

            return(Task.FromResult(newDocument));
        }
        private static async Task <Document> GetTransformedDocumentAsync(Document document, SyntaxNode syntaxRoot, CancellationToken cancellationToken)
        {
            var fileHeader      = GetFileHeader(syntaxRoot);
            var compilationUnit = (CompilationUnitSyntax)syntaxRoot;

            var settings      = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, cancellationToken);
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var indentationOptions = IndentationOptions.FromDocument(document);

            var usingsHelper   = new UsingsHelper(settings, semanticModel, compilationUnit, fileHeader);
            var namespaceCount = CountNamespaces(compilationUnit.Members);

            // Only move using declarations inside the namespace when
            // - There are no global attributes
            // - There is only a single namespace declared at the top level
            // - OrderingSettings.UsingDirectivesPlacement is set to InsideNamespace
            UsingDirectivesPlacement usingDirectivesPlacement;

            switch (settings.OrderingRules.UsingDirectivesPlacement)
            {
            case UsingDirectivesPlacement.InsideNamespace:
                if (compilationUnit.AttributeLists.Any() ||
                    compilationUnit.Members.Count > 1 ||
                    namespaceCount > 1)
                {
                    // Override the user's setting with a more conservative one
                    usingDirectivesPlacement = UsingDirectivesPlacement.Preserve;
                }
                else if (namespaceCount == 0)
                {
                    usingDirectivesPlacement = UsingDirectivesPlacement.OutsideNamespace;
                }
                else
                {
                    usingDirectivesPlacement = UsingDirectivesPlacement.InsideNamespace;
                }

                break;

            case UsingDirectivesPlacement.OutsideNamespace:
                usingDirectivesPlacement = UsingDirectivesPlacement.OutsideNamespace;
                break;

            case UsingDirectivesPlacement.Preserve:
            default:
                usingDirectivesPlacement = UsingDirectivesPlacement.Preserve;
                break;
            }

            string usingsIndentation;

            if (usingDirectivesPlacement == UsingDirectivesPlacement.InsideNamespace)
            {
                var rootNamespace    = compilationUnit.Members.OfType <NamespaceDeclarationSyntax>().First();
                var indentationLevel = IndentationHelper.GetIndentationSteps(indentationOptions, rootNamespace);
                usingsIndentation = IndentationHelper.GenerateIndentationString(indentationOptions, indentationLevel + 1);
            }
            else
            {
                usingsIndentation = string.Empty;
            }

            // - The strategy is to strip all using directive that are not inside a conditional directive and replace them later with a sorted list at the correct spot
            // - The using directives that are inside a conditional directive are replaced (in sorted order) on the spot.
            // - Conditional directives are not moved, as correctly parsing them is too tricky
            // - No using directives will be stripped when there are multiple namespaces. In that case everything is replaced on the spot.
            List <UsingDirectiveSyntax> stripList;
            var replaceMap = new Dictionary <UsingDirectiveSyntax, UsingDirectiveSyntax>();

            // When there are multiple namespaces, do not move using statements outside of them, only sort.
            if (usingDirectivesPlacement == UsingDirectivesPlacement.Preserve)
            {
                BuildReplaceMapForNamespaces(usingsHelper, replaceMap, indentationOptions, false);
                stripList = new List <UsingDirectiveSyntax>();
            }
            else
            {
                stripList = usingsHelper.GetContainedUsings(usingsHelper.RootSpan);
            }

            BuildReplaceMapForConditionalDirectives(usingsHelper, replaceMap, indentationOptions, usingsHelper.RootSpan);

            var usingSyntaxRewriter = new UsingSyntaxRewriter(stripList, replaceMap, fileHeader);
            var newSyntaxRoot       = usingSyntaxRewriter.Visit(syntaxRoot);

            if (usingDirectivesPlacement == UsingDirectivesPlacement.InsideNamespace)
            {
                newSyntaxRoot = AddUsingsToNamespace(newSyntaxRoot, usingsHelper, usingsIndentation, replaceMap.Any());
            }
            else if (usingDirectivesPlacement == UsingDirectivesPlacement.OutsideNamespace)
            {
                newSyntaxRoot = AddUsingsToCompilationRoot(newSyntaxRoot, usingsHelper, usingsIndentation, replaceMap.Any());
            }

            // Final cleanup
            newSyntaxRoot = StripMultipleBlankLines(newSyntaxRoot);
            newSyntaxRoot = ReAddFileHeader(newSyntaxRoot, fileHeader);

            var newDocument = document.WithSyntaxRoot(newSyntaxRoot.WithoutFormatting());

            return(newDocument);
        }
        private static Dictionary <SyntaxToken, SyntaxToken> GenerateBraceFixes(Document document, ImmutableArray <SyntaxToken> braceTokens)
        {
            var tokenReplacements = new Dictionary <SyntaxToken, SyntaxToken>();

            foreach (var braceToken in braceTokens)
            {
                var braceLine             = LocationHelpers.GetLineSpan(braceToken).StartLinePosition.Line;
                var braceReplacementToken = braceToken;

                var indentationOptions = IndentationOptions.FromDocument(document);
                var indentationSteps   = DetermineIndentationSteps(indentationOptions, braceToken);

                var previousToken = braceToken.GetPreviousToken();
                var nextToken     = braceToken.GetNextToken();

                if (IsAccessorWithSingleLineBlock(previousToken, braceToken))
                {
                    var newTrailingTrivia = previousToken.TrailingTrivia
                                            .WithoutTrailingWhitespace()
                                            .Add(SyntaxFactory.Space);

                    AddReplacement(tokenReplacements, previousToken, previousToken.WithTrailingTrivia(newTrailingTrivia));

                    braceReplacementToken = braceReplacementToken.WithLeadingTrivia(braceToken.LeadingTrivia.WithoutLeadingWhitespace());
                }
                else
                {
                    // Check if we need to apply a fix before the brace
                    if (LocationHelpers.GetLineSpan(previousToken).StartLinePosition.Line == braceLine)
                    {
                        if (!braceTokens.Contains(previousToken))
                        {
                            var sharedTrivia = braceReplacementToken.LeadingTrivia.WithoutTrailingWhitespace();
                            var previousTokenNewTrailingTrivia = previousToken.TrailingTrivia
                                                                 .WithoutTrailingWhitespace()
                                                                 .AddRange(sharedTrivia)
                                                                 .Add(SyntaxFactory.CarriageReturnLineFeed);

                            AddReplacement(tokenReplacements, previousToken, previousToken.WithTrailingTrivia(previousTokenNewTrailingTrivia));
                        }

                        braceReplacementToken = braceReplacementToken.WithLeadingTrivia(IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, indentationSteps));
                    }

                    // Check if we need to apply a fix after the brace
                    // if a closing brace is followed by a semi-colon or closing paren, no fix is needed.
                    if ((LocationHelpers.GetLineSpan(nextToken).StartLinePosition.Line == braceLine) &&
                        (!braceToken.IsKind(SyntaxKind.CloseBraceToken) || !IsValidFollowingToken(nextToken)))
                    {
                        var sharedTrivia      = nextToken.LeadingTrivia.WithoutTrailingWhitespace();
                        var newTrailingTrivia = braceReplacementToken.TrailingTrivia
                                                .WithoutTrailingWhitespace()
                                                .AddRange(sharedTrivia)
                                                .Add(SyntaxFactory.CarriageReturnLineFeed);

                        if (!braceTokens.Contains(nextToken))
                        {
                            int newIndentationSteps;
                            if (braceToken.IsKind(SyntaxKind.OpenBraceToken))
                            {
                                newIndentationSteps = indentationSteps + 1;
                            }
                            else if (nextToken.IsKind(SyntaxKind.CloseBraceToken))
                            {
                                newIndentationSteps = Math.Max(0, indentationSteps - 1);
                            }
                            else
                            {
                                newIndentationSteps = indentationSteps;
                            }

                            AddReplacement(tokenReplacements, nextToken, nextToken.WithLeadingTrivia(IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, newIndentationSteps)));
                        }

                        braceReplacementToken = braceReplacementToken.WithTrailingTrivia(newTrailingTrivia);
                    }
                }

                AddReplacement(tokenReplacements, braceToken, braceReplacementToken);
            }

            return(tokenReplacements);
        }
Example #30
0
        private static async Task <Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var curlyBracketToken            = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
            var curlyBracketLine             = curlyBracketToken.GetLocation().GetLineSpan().StartLinePosition.Line;
            var curlyBracketReplacementToken = curlyBracketToken;

            var indentationOptions = IndentationOptions.FromDocument(document);
            var indentationSteps   = DetermineIndentationSteps(indentationOptions, curlyBracketToken);

            var previousToken = curlyBracketToken.GetPreviousToken();
            var nextToken     = curlyBracketToken.GetNextToken();

            var rewriter = new Rewriter();

            if (IsAccessorWithSingleLineBlock(previousToken, curlyBracketToken))
            {
                var newTrailingTrivia = previousToken.TrailingTrivia
                                        .WithoutTrailingWhitespace()
                                        .Add(SyntaxFactory.Space);

                rewriter.AddReplacement(previousToken, previousToken.WithTrailingTrivia(newTrailingTrivia));

                curlyBracketReplacementToken = curlyBracketReplacementToken.WithLeadingTrivia(curlyBracketToken.LeadingTrivia.WithoutLeadingWhitespace());
            }
            else
            {
                // Check if we need to apply a fix before the curly bracket
                if (previousToken.GetLocation().GetLineSpan().StartLinePosition.Line == curlyBracketLine)
                {
                    var sharedTrivia = curlyBracketReplacementToken.LeadingTrivia.WithoutTrailingWhitespace();
                    var previousTokenNewTrailingTrivia = previousToken.TrailingTrivia
                                                         .WithoutTrailingWhitespace()
                                                         .AddRange(sharedTrivia)
                                                         .Add(SyntaxFactory.CarriageReturnLineFeed);

                    rewriter.AddReplacement(previousToken, previousToken.WithTrailingTrivia(previousTokenNewTrailingTrivia));

                    curlyBracketReplacementToken = curlyBracketReplacementToken.WithLeadingTrivia(IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, indentationSteps));
                }

                // Check if we need to apply a fix after the curly bracket
                // if a closing curly bracket is followed by a semi-colon or closing paren, no fix is needed.
                if ((nextToken.GetLocation().GetLineSpan().StartLinePosition.Line == curlyBracketLine) &&
                    (!curlyBracketToken.IsKind(SyntaxKind.CloseBraceToken) || !IsValidFollowingToken(nextToken)))
                {
                    var sharedTrivia      = nextToken.LeadingTrivia.WithoutTrailingWhitespace();
                    var newTrailingTrivia = curlyBracketReplacementToken.TrailingTrivia
                                            .WithoutTrailingWhitespace()
                                            .AddRange(sharedTrivia)
                                            .Add(SyntaxFactory.CarriageReturnLineFeed);

                    int newIndentationSteps;
                    if (curlyBracketToken.IsKind(SyntaxKind.OpenBraceToken))
                    {
                        newIndentationSteps = indentationSteps + 1;
                    }
                    else if (nextToken.IsKind(SyntaxKind.CloseBraceToken))
                    {
                        newIndentationSteps = Math.Max(0, indentationSteps - 1);
                    }
                    else
                    {
                        newIndentationSteps = indentationSteps;
                    }

                    rewriter.AddReplacement(nextToken, nextToken.WithLeadingTrivia(IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, newIndentationSteps)));

                    curlyBracketReplacementToken = curlyBracketReplacementToken.WithTrailingTrivia(newTrailingTrivia);
                }
            }

            rewriter.AddReplacement(curlyBracketToken, curlyBracketReplacementToken);

            var newSyntaxRoot = rewriter.Visit(syntaxRoot).WithoutFormatting();

            return(document.WithSyntaxRoot(newSyntaxRoot));
        }