private static void BuildReplaceMapForNamespaces(UsingsSorter usingsHelper, Dictionary <UsingDirectiveSyntax, UsingDirectiveSyntax> replaceMap, IndentationSettings indentationSettings, bool qualifyNames) { var usingsPerNamespace = usingsHelper .GetContainedUsings(TreeTextSpan.Empty) .GroupBy(ud => ud.Parent) .Select(gr => gr.ToList()); foreach (var usingList in usingsPerNamespace) { if (usingList.Count > 0) { // sort the original using declarations on Span.Start, in order to have the correct replace mapping. usingList.Sort(CompareSpanStart); var indentationSteps = IndentationHelper.GetIndentationSteps(indentationSettings, usingList[0].Parent); if (usingList[0].Parent is NamespaceDeclarationSyntax) { indentationSteps++; } var indentation = IndentationHelper.GenerateIndentationString(indentationSettings, indentationSteps); var modifiedUsings = usingsHelper.GenerateGroupedUsings(usingList, indentation, false, qualifyNames); for (var i = 0; i < usingList.Count; i++) { replaceMap.Add(usingList[i], modifiedUsings[i]); } } } }
private static void BuildReplaceMapForConditionalDirectives(UsingsSorter usingsHelper, Dictionary <UsingDirectiveSyntax, UsingDirectiveSyntax> replaceMap, IndentationSettings indentationSettings, TreeTextSpan rootSpan) { foreach (var childSpan in rootSpan.Children) { var originalUsings = usingsHelper.GetContainedUsings(childSpan); if (originalUsings.Count > 0) { // sort the original using declarations on Span.Start, in order to have the correct replace mapping. originalUsings.Sort(CompareSpanStart); var indentationSteps = IndentationHelper.GetIndentationSteps(indentationSettings, originalUsings[0].Parent); if (originalUsings[0].Parent is NamespaceDeclarationSyntax) { indentationSteps++; } var indentation = IndentationHelper.GenerateIndentationString(indentationSettings, indentationSteps); var modifiedUsings = usingsHelper.GenerateGroupedUsings(childSpan, indentation, false, qualifyNames: false); for (var i = 0; i < originalUsings.Count; i++) { replaceMap.Add(originalUsings[i], modifiedUsings[i]); } } BuildReplaceMapForConditionalDirectives(usingsHelper, replaceMap, indentationSettings, childSpan); } }
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; } } var settings = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, cancellationToken); SyntaxTriviaList newTrivia = SyntaxFactory.TriviaList( SyntaxFactory.CarriageReturnLineFeed, SyntaxFactory.Whitespace(lineText.Substring(0, indentLength) + IndentationHelper.GenerateIndentationString(settings.Indentation, 1))); SyntaxToken updatedToken = originalToken.WithLeadingTrivia(originalToken.LeadingTrivia.AddRange(newTrivia)); SyntaxNode updatedRoot = root.ReplaceToken(originalToken, updatedToken); return(document.WithSyntaxRoot(updatedRoot)); }
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)); }
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 string DetermineIndentation(CompilationUnitSyntax compilationUnit, IndentationSettings indentationSettings, UsingDirectivesPlacement usingDirectivesPlacement) { string usingsIndentation; if (usingDirectivesPlacement == UsingDirectivesPlacement.InsideNamespace) { var rootNamespace = compilationUnit.Members.OfType <NamespaceDeclarationSyntax>().First(); var indentationLevel = IndentationHelper.GetIndentationSteps(indentationSettings, rootNamespace); usingsIndentation = IndentationHelper.GenerateIndentationString(indentationSettings, indentationLevel + 1); } else { usingsIndentation = string.Empty; } return(usingsIndentation); }
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 string DetermineIndentation(CompilationUnitSyntax compilationUnit, IndentationSettings indentationSettings, UsingDirectivesPlacement usingDirectivesPlacement) { string usingsIndentation; if (usingDirectivesPlacement == UsingDirectivesPlacement.InsideNamespace) { var rootNamespace = compilationUnit.Members.First(member => BaseNamespaceDeclarationSyntaxWrapper.IsInstance(member)); var indentationLevel = IndentationHelper.GetIndentationSteps(indentationSettings, rootNamespace); if (!rootNamespace.IsKind(SyntaxKindEx.FileScopedNamespaceDeclaration)) { indentationLevel++; } usingsIndentation = IndentationHelper.GenerateIndentationString(indentationSettings, indentationLevel); } else { usingsIndentation = string.Empty; } return(usingsIndentation); }
private static SyntaxNode MoveMember(SyntaxNode syntaxRoot, MemberDeclarationSyntax member, MemberDeclarationSyntax targetMember, IndentationSettings indentationSettings) { var firstToken = syntaxRoot.GetFirstToken(); var fileHeader = GetFileHeader(firstToken.LeadingTrivia); syntaxRoot = syntaxRoot.TrackNodes(member, targetMember, firstToken.Parent); var memberToMove = syntaxRoot.GetCurrentNode(member); var targetMemberTracked = syntaxRoot.GetCurrentNode(targetMember); if (!memberToMove.HasLeadingTrivia) { var targetIndentationLevel = IndentationHelper.GetIndentationSteps(indentationSettings, targetMember); var indentationString = IndentationHelper.GenerateIndentationString(indentationSettings, targetIndentationLevel); memberToMove = memberToMove.WithLeadingTrivia(SyntaxFactory.Whitespace(indentationString)); } if (!HasLeadingBlankLines(targetMember) && HasLeadingBlankLines(member)) { memberToMove = memberToMove.WithTrailingTrivia(memberToMove.GetTrailingTrivia().Add(SyntaxFactory.CarriageReturnLineFeed)); memberToMove = memberToMove.WithLeadingTrivia(GetLeadingTriviaWithoutLeadingBlankLines(memberToMove)); } syntaxRoot = syntaxRoot.InsertNodesBefore(targetMemberTracked, new[] { memberToMove }); var fieldToMoveTracked = syntaxRoot.GetCurrentNodes(member).Last(); syntaxRoot = syntaxRoot.RemoveNode(fieldToMoveTracked, SyntaxRemoveOptions.KeepNoTrivia); if (fileHeader.Any()) { var oldFirstToken = syntaxRoot.GetCurrentNode(firstToken.Parent).ChildTokens().First(); syntaxRoot = syntaxRoot.ReplaceToken(oldFirstToken, oldFirstToken.WithLeadingTrivia(StripFileHeader(oldFirstToken.LeadingTrivia))); var newFirstToken = syntaxRoot.GetFirstToken(); syntaxRoot = syntaxRoot.ReplaceToken(newFirstToken, newFirstToken.WithLeadingTrivia(fileHeader.AddRange(newFirstToken.LeadingTrivia))); } return(syntaxRoot); }
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 SyntaxNode ReformatElement(SyntaxNode syntaxRoot, SyntaxNode element, SyntaxToken openBraceToken, SyntaxToken closeBraceToken, IndentationOptions indentationOptions) { var tokenSubstitutions = new Dictionary <SyntaxToken, SyntaxToken>(); var parentLastToken = openBraceToken.GetPreviousToken(); var parentEndLine = parentLastToken.GetLineSpan().EndLinePosition.Line; var blockStartLine = openBraceToken.GetLineSpan().StartLinePosition.Line; // reformat parent if it is on the same line as the block. if (parentEndLine == blockStartLine) { var newTrailingTrivia = parentLastToken.TrailingTrivia .WithoutTrailingWhitespace() .Add(SyntaxFactory.CarriageReturnLineFeed); tokenSubstitutions.Add(parentLastToken, parentLastToken.WithTrailingTrivia(newTrailingTrivia)); } var parentIndentationLevel = IndentationHelper.GetIndentationSteps(indentationOptions, element); var indentationString = IndentationHelper.GenerateIndentationString(indentationOptions, parentIndentationLevel); var contentIndentationString = IndentationHelper.GenerateIndentationString(indentationOptions, parentIndentationLevel + 1); // reformat opening brace tokenSubstitutions.Add(openBraceToken, this.FormatBraceToken(openBraceToken, indentationString)); // reformat start of content var startOfContentToken = openBraceToken.GetNextToken(); if (startOfContentToken != closeBraceToken) { var newStartOfContentTokenLeadingTrivia = startOfContentToken.LeadingTrivia .WithoutTrailingWhitespace() .Add(SyntaxFactory.Whitespace(contentIndentationString)); tokenSubstitutions.Add(startOfContentToken, startOfContentToken.WithLeadingTrivia(newStartOfContentTokenLeadingTrivia)); } // reformat end of content var endOfContentToken = closeBraceToken.GetPreviousToken(); if (endOfContentToken != openBraceToken) { var newEndOfContentTokenTrailingTrivia = endOfContentToken.TrailingTrivia .WithoutTrailingWhitespace() .Add(SyntaxFactory.CarriageReturnLineFeed); // check if the token already exists (occurs when there is only one token in the block) if (tokenSubstitutions.ContainsKey(endOfContentToken)) { tokenSubstitutions[endOfContentToken] = tokenSubstitutions[endOfContentToken].WithTrailingTrivia(newEndOfContentTokenTrailingTrivia); } else { tokenSubstitutions.Add(endOfContentToken, endOfContentToken.WithTrailingTrivia(newEndOfContentTokenTrailingTrivia)); } } // reformat closing brace tokenSubstitutions.Add(closeBraceToken, this.FormatBraceToken(closeBraceToken, indentationString)); var rewriter = new TokenRewriter(tokenSubstitutions); var newSyntaxRoot = rewriter.Visit(syntaxRoot); return(newSyntaxRoot); }
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 void ReformatBlock(IndentationSettings indentationSettings, BlockSyntax block, Dictionary <SyntaxToken, SyntaxToken> tokenReplaceMap) { var parentIndentationLevel = IndentationHelper.GetIndentationSteps(indentationSettings, GetStatementParent(block.Parent)); // use one additional step of indentation for lambdas / anonymous methods switch (block.Parent.Kind()) { case SyntaxKind.AnonymousMethodExpression: case SyntaxKind.SimpleLambdaExpression: case SyntaxKind.ParenthesizedLambdaExpression: parentIndentationLevel++; break; } var indentationString = IndentationHelper.GenerateIndentationString(indentationSettings, parentIndentationLevel); var statementIndentationString = IndentationHelper.GenerateIndentationString(indentationSettings, 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(); bool addNewLineAfterCloseBrace; switch (block.CloseBraceToken.GetNextToken().Kind()) { case SyntaxKind.CloseParenToken: case SyntaxKind.CommaToken: case SyntaxKind.SemicolonToken: addNewLineAfterCloseBrace = false; break; default: addNewLineAfterCloseBrace = (newCloseBraceTrailingTrivia.Count == 0) || !newCloseBraceTrailingTrivia.Last().IsKind(SyntaxKind.EndOfLineTrivia); break; } if (addNewLineAfterCloseBrace) { newCloseBraceTrailingTrivia = newCloseBraceTrailingTrivia.Add(SyntaxFactory.CarriageReturnLineFeed); } AddToReplaceMap(tokenReplaceMap, block.OpenBraceToken, block.OpenBraceToken.WithLeadingTrivia(newOpenBraceLeadingTrivia).WithTrailingTrivia(newOpenBraceTrailingTrivia)); AddToReplaceMap(tokenReplaceMap, block.CloseBraceToken, block.CloseBraceToken.WithLeadingTrivia(newCloseBraceLeadingTrivia).WithTrailingTrivia(newCloseBraceTrailingTrivia)); foreach (var statement in block.Statements) { var firstToken = statement.GetFirstToken(); var lastToken = statement.GetLastToken(); var newLeadingTrivia = firstToken.LeadingTrivia .WithoutTrailingWhitespace() .Add(SyntaxFactory.Whitespace(statementIndentationString)); var newTrailingTrivia = lastToken.TrailingTrivia .WithoutTrailingWhitespace() .Add(SyntaxFactory.CarriageReturnLineFeed); AddToReplaceMap(tokenReplaceMap, firstToken, firstToken.WithLeadingTrivia(newLeadingTrivia)); AddToReplaceMap(tokenReplaceMap, lastToken, lastToken.WithTrailingTrivia(newTrailingTrivia)); } }
private static BlockSyntax ReformatBlock(Document document, IndentationSettings indentationSettings, BlockSyntax block) { var parentIndentationLevel = IndentationHelper.GetIndentationSteps(indentationSettings, GetStatementParent(block.Parent)); // use one additional step of indentation for lambdas / anonymous methods switch (block.Parent.Kind()) { case SyntaxKind.AnonymousMethodExpression: case SyntaxKind.SimpleLambdaExpression: case SyntaxKind.ParenthesizedLambdaExpression: parentIndentationLevel++; break; } var indentationString = IndentationHelper.GenerateIndentationString(indentationSettings, parentIndentationLevel); var statementIndentationString = IndentationHelper.GenerateIndentationString(indentationSettings, 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(); bool addNewLineAfterCloseBrace; switch (block.CloseBraceToken.GetNextToken().Kind()) { case SyntaxKind.CloseParenToken: case SyntaxKind.CommaToken: case SyntaxKind.SemicolonToken: addNewLineAfterCloseBrace = false; break; default: addNewLineAfterCloseBrace = (newCloseBraceTrailingTrivia.Count == 0) || !newCloseBraceTrailingTrivia.Last().IsKind(SyntaxKind.EndOfLineTrivia); break; } if (addNewLineAfterCloseBrace) { 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)); }
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)); }