public static async Task <ImmutableArray <TextChange> > GetFormattingChangesAsync( Document document, char typedChar, int position, DocumentOptionSet documentOptions, CancellationToken cancellationToken) { Contract.ThrowIfFalse(document.Project.Language is LanguageNames.CSharp); var formattingService = document.GetRequiredLanguageService <ISyntaxFormattingService>(); if (!await formattingService.ShouldFormatOnTypedCharacterAsync(document, typedChar, position, cancellationToken).ConfigureAwait(false)) { return(ImmutableArray <TextChange> .Empty); } var services = document.Project.Solution.Workspace.Services; var globalOptions = document.Project.Solution.Workspace.Services.GetRequiredService <ILegacyGlobalOptionsWorkspaceService>(); var indentationOptions = new IndentationOptions( SyntaxFormattingOptions.Create(documentOptions, services, document.Project.Language), globalOptions.GlobalOptions.GetAutoFormattingOptions(document.Project.Language)); return(await formattingService.GetFormattingChangesOnTypedCharacterAsync(document, position, indentationOptions, cancellationToken).ConfigureAwait(false)); }
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())); }
public Indenter( AbstractIndentationService <TSyntaxRoot> service, SyntacticDocument document, IEnumerable <AbstractFormattingRule> rules, IndentationOptions options, TextLine lineToBeIndented, CancellationToken cancellationToken) { Document = document; _service = service; _syntaxFacts = document.Document.GetRequiredLanguageService <ISyntaxFactsService>(); Options = options; Root = (TSyntaxRoot)document.Root; LineToBeIndented = lineToBeIndented; _tabSize = options.FormattingOptions.TabSize; CancellationToken = cancellationToken; Rules = rules; Finder = new BottomUpBaseIndentationFinder( new ChainedFormattingRules(this.Rules, options.FormattingOptions), _tabSize, options.FormattingOptions.IndentationSize, tokenStream: null, document.Document.GetRequiredLanguageService <IHeaderFactsService>()); }
public static async Task <ImmutableArray <TextChange> > GetFormattingChangesAsync( Document document, char typedChar, int position, DocumentOptionSet documentOptions, CancellationToken cancellationToken) { Contract.ThrowIfFalse(document.Project.Language is LanguageNames.CSharp); var formattingService = document.GetRequiredLanguageService <ISyntaxFormattingService>(); if (!await formattingService.ShouldFormatOnTypedCharacterAsync(document, typedChar, position, cancellationToken).ConfigureAwait(false)) { return(ImmutableArray <TextChange> .Empty); } var languageServices = document.Project.LanguageServices; var services = document.Project.Solution.Workspace.Services; var globalOptions = services.GetRequiredService <ILegacyGlobalOptionsWorkspaceService>(); var optionsProvider = (OptionsProvider <SyntaxFormattingOptions>)globalOptions.CleanCodeGenerationOptionsProvider; var fallbackOptions = await optionsProvider.GetOptionsAsync(languageServices, cancellationToken).ConfigureAwait(false); var optionService = services.GetRequiredService <IOptionService>(); var configOptions = documentOptions.AsAnalyzerConfigOptions(optionService, document.Project.Language); var indentationOptions = new IndentationOptions(formattingService.GetFormattingOptions(configOptions, fallbackOptions)) { AutoFormattingOptions = globalOptions.GetAutoFormattingOptions(languageServices) }; return(await formattingService.GetFormattingChangesOnTypedCharacterAsync(document, position, indentationOptions, cancellationToken).ConfigureAwait(false)); }
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)); }
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)))); }
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)); }
private static int DetermineIndentationSteps(IndentationOptions indentationOptions, SyntaxToken token) { // For a closing brace use the indentation of the corresponding opening brace if (token.IsKind(SyntaxKind.CloseBraceToken)) { var depth = 1; while (depth > 0) { token = token.GetPreviousToken(); switch (token.Kind()) { case SyntaxKind.CloseBraceToken: depth++; break; case SyntaxKind.OpenBraceToken: depth--; break; } } } var startLine = GetTokenStartLinePosition(token).Line; while (!ContainsStartOfLine(token, startLine)) { token = token.GetPreviousToken(); } return(IndentationHelper.GetIndentationSteps(indentationOptions, token)); }
private static async Task TokenFormatWorkerAsync(TestWorkspace workspace, ITextBuffer buffer, int indentationLine, char ch) { var document = buffer.CurrentSnapshot.GetRelatedDocumentsWithChanges().First(); var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync(); var line = root.GetText().Lines[indentationLine]; var index = line.ToString().LastIndexOf(ch); Assert.InRange(index, 0, int.MaxValue); // get token var position = line.Start + index; var token = root.FindToken(position); var formattingRuleProvider = workspace.Services.GetService <IHostDependentFormattingRuleFactoryService>(); var rules = ImmutableArray.Create(formattingRuleProvider.CreateRule(document, position)).AddRange(Formatter.GetDefaultFormattingRules(document)); var options = new IndentationOptions( await document.GetSyntaxFormattingOptionsAsync(fallbackOptions: null, CancellationToken.None).ConfigureAwait(false), AutoFormattingOptions.Default); var formatter = new CSharpSmartTokenFormatter(options, rules, root); var changes = await formatter.FormatTokenAsync(token, CancellationToken.None); ApplyChanges(buffer, changes); }
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 TokenFormatWorkerAsync(TestWorkspace workspace, ITextBuffer buffer, int indentationLine, char ch, bool useTabs) { var document = buffer.CurrentSnapshot.GetRelatedDocumentsWithChanges().First(); var documentSyntax = await ParsedDocument.CreateAsync(document, CancellationToken.None); var line = documentSyntax.Text.Lines[indentationLine]; var index = line.ToString().LastIndexOf(ch); Assert.InRange(index, 0, int.MaxValue); // get token var position = line.Start + index; var token = documentSyntax.Root.FindToken(position); var formattingRuleProvider = workspace.Services.GetService <IHostDependentFormattingRuleFactoryService>(); var rules = ImmutableArray.Create(formattingRuleProvider.CreateRule(documentSyntax, position)).AddRange(Formatter.GetDefaultFormattingRules(document)); var options = new IndentationOptions( new CSharpSyntaxFormattingOptions { Common = new SyntaxFormattingOptions.CommonOptions() { LineFormatting = new LineFormattingOptions { UseTabs = useTabs } } }); var formatter = new CSharpSmartTokenFormatter(options, rules, (CompilationUnitSyntax)documentSyntax.Root, documentSyntax.Text); var changes = formatter.FormatToken(token, CancellationToken.None); buffer.ApplyChanges(changes); }
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)); }
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, 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); }
public Indenter( AbstractIndentation <TSyntaxRoot> service, SyntaxTree tree, ImmutableArray <AbstractFormattingRule> rules, IndentationOptions options, TextLine lineToBeIndented, ISmartTokenFormatter smartTokenFormatter, CancellationToken cancellationToken) { _service = service; _syntaxFacts = service.SyntaxFacts; Options = options; Tree = tree; Text = tree.GetText(cancellationToken); Root = (TSyntaxRoot)tree.GetRoot(cancellationToken); LineToBeIndented = lineToBeIndented; _tabSize = options.FormattingOptions.TabSize; SmartTokenFormatter = smartTokenFormatter; CancellationToken = cancellationToken; Rules = rules; Finder = new BottomUpBaseIndentationFinder( new ChainedFormattingRules(this.Rules, options.FormattingOptions), _tabSize, options.FormattingOptions.IndentationSize, tokenStream: null, service.HeaderFacts); }
private bool TryStart(CancellationToken cancellationToken) { this.AssertIsForeground(); var closingSnapshotPoint = ClosingPoint.GetPoint(SubjectBuffer.CurrentSnapshot); if (closingSnapshotPoint.Position < 1) { Debug.Fail("The closing point was not found at the expected position."); return(false); } var openingSnapshotPoint = closingSnapshotPoint.Subtract(1); if (openingSnapshotPoint.GetChar() != OpeningBrace) { // there is a bug in editor brace completion engine on projection buffer that already fixed in vs_pro. until that is FIed to use // I will make this not to assert // Debug.Fail("The opening brace was not found at the expected position."); return(false); } OpeningPoint = SubjectBuffer.CurrentSnapshot.CreateTrackingPoint(openingSnapshotPoint, PointTrackingMode.Positive); var context = GetBraceCompletionContext(); if (context == null) { return(false); } var braceResult = _service.GetBraceCompletionAsync(context.Value, cancellationToken).WaitAndGetResult(cancellationToken); if (braceResult == null) { return(false); } using var caretPreservingTransaction = new CaretPreservingEditTransaction(EditorFeaturesResources.Brace_Completion, _undoHistory, _editorOperations); // Apply the change to complete the brace. ApplyBraceCompletionResult(braceResult.Value); // switch the closing point from positive to negative tracking so that the closing point stays against the closing brace ClosingPoint = SubjectBuffer.CurrentSnapshot.CreateTrackingPoint(ClosingPoint.GetPoint(SubjectBuffer.CurrentSnapshot), PointTrackingMode.Negative); var contextAfterStart = GetBraceCompletionContext(); if (contextAfterStart != null) { var options = IndentationOptions.FromDocumentAsync(contextAfterStart.Value.Document, cancellationToken).WaitAndGetResult(cancellationToken); var changesAfterStart = _service.GetTextChangesAfterCompletionAsync(contextAfterStart.Value, options, cancellationToken).WaitAndGetResult(cancellationToken); if (changesAfterStart != null) { ApplyBraceCompletionResult(changesAfterStart.Value); } } caretPreservingTransaction.Complete(); return(true); }
private Indenter GetIndenter(Document document, int lineNumber, IndentationOptions options, CancellationToken cancellationToken) { var syntaxFormatting = this.SyntaxFormatting; #if CODE_STYLE var tree = document.GetSyntaxTreeAsync(cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken); Contract.ThrowIfNull(tree); #else var tree = document.GetRequiredSyntaxTreeSynchronously(cancellationToken); #endif var sourceText = tree.GetText(cancellationToken); var lineToBeIndented = sourceText.Lines[lineNumber]; #if CODE_STYLE var baseIndentationRule = NoOpFormattingRule.Instance; #else var workspace = document.Project.Solution.Workspace; var formattingRuleFactory = workspace.Services.GetRequiredService <IHostDependentFormattingRuleFactoryService>(); var baseIndentationRule = formattingRuleFactory.CreateRule(document, lineToBeIndented.Start); #endif var formattingRules = ImmutableArray.Create( baseIndentationRule, this.GetSpecializedIndentationFormattingRule(options.IndentStyle)).AddRange( syntaxFormatting.GetDefaultFormattingRules()); var smartTokenFormatter = CreateSmartTokenFormatter( (TSyntaxRoot)tree.GetRoot(cancellationToken), lineToBeIndented, options, baseIndentationRule); return(new Indenter(this, tree, formattingRules, options, lineToBeIndented, smartTokenFormatter, cancellationToken)); }
public void PostReturn() { this.AssertIsForeground(); if (this.GetCaretPosition().HasValue) { var closingSnapshotPoint = ClosingPoint.GetPoint(SubjectBuffer.CurrentSnapshot); if (closingSnapshotPoint.Position > 0 && HasNoForwardTyping(this.GetCaretPosition().Value, closingSnapshotPoint.Subtract(1))) { var context = GetBraceCompletionContext(); if (context == null) { return; } var options = IndentationOptions.FromDocumentAsync(context.Value.Document, CancellationToken.None).WaitAndGetResult(CancellationToken.None); var changesAfterReturn = _service.GetTextChangeAfterReturnAsync(context.Value, options, CancellationToken.None).WaitAndGetResult(CancellationToken.None); if (changesAfterReturn != null) { using var caretPreservingTransaction = new CaretPreservingEditTransaction(EditorFeaturesResources.Brace_Completion, _undoHistory, _editorOperations); ApplyBraceCompletionResult(changesAfterReturn.Value); caretPreservingTransaction.Complete(); } } } }
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)); }
/// <summary> /// Returns the text changes necessary to format the document after the user enters a /// character. The position provided is the position of the caret in the document after /// the character been inserted into the document. /// </summary> public static async Task <ImmutableArray <TextChange> > GetFormattingChangesAsync( Document document, char typedChar, int position, RazorIndentationOptions indentationOptions, RazorAutoFormattingOptions autoFormattingOptions, FormattingOptions.IndentStyle indentStyle, CancellationToken cancellationToken) { Contract.ThrowIfFalse(document.Project.Language is LanguageNames.CSharp); var formattingService = document.GetRequiredLanguageService <ISyntaxFormattingService>(); var documentSyntax = await ParsedDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false); if (!formattingService.ShouldFormatOnTypedCharacter(documentSyntax, typedChar, position, cancellationToken)) { return(ImmutableArray <TextChange> .Empty); } var formattingOptions = GetFormattingOptions(indentationOptions); var roslynIndentationOptions = new IndentationOptions(formattingOptions) { AutoFormattingOptions = autoFormattingOptions.UnderlyingObject, IndentStyle = (FormattingOptions2.IndentStyle)indentStyle }; return(formattingService.GetFormattingChangesOnTypedCharacter(documentSyntax, position, roslynIndentationOptions, cancellationToken)); }
protected override ISmartTokenFormatter CreateSmartTokenFormatter( CompilationUnitSyntax root, TextLine lineToBeIndented, IndentationOptions options, AbstractFormattingRule baseIndentationRule) { var rules = ImmutableArray.Create(baseIndentationRule).AddRange(CSharpSyntaxFormatting.Instance.GetDefaultFormattingRules()); return(new CSharpSmartTokenFormatter(options, rules, root)); }
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 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)); }
public InterpolatedStringSplitter( ParsedDocument document, int position, InterpolatedStringExpressionSyntax interpolatedStringExpression, IndentationOptions options, CancellationToken cancellationToken) : base(document, position, options, cancellationToken) { _interpolatedStringExpression = interpolatedStringExpression; }
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)); }
/// <summary> /// Gets a whitespace trivia containing the proper amount of indentation for new lines in the query of which the given token is a part. /// </summary> /// <param name="indentationOptions">The indentation options to use.</param> /// <param name="token">A token within a query expression.</param> /// <returns>A whitespace trivia containing the proper amount of indentation.</returns> internal static SyntaxTrivia GetQueryIndentationTrivia(IndentationOptions indentationOptions, SyntaxToken token) { var currentNode = token.Parent; while (!currentNode.IsKind(SyntaxKind.QueryExpression)) { currentNode = currentNode.Parent; } return(GetQueryIndentationTrivia(indentationOptions, (QueryExpressionSyntax)currentNode)); }
private Indenter GetIndenter(Document document, int lineNumber, FormattingOptions.IndentStyle indentStyle, CancellationToken cancellationToken) { var options = IndentationOptions.FromDocumentAsync(document, cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken); var syntacticDoc = SyntacticDocument.CreateAsync(document, cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken); var sourceText = syntacticDoc.Root.SyntaxTree.GetText(cancellationToken); var lineToBeIndented = sourceText.Lines[lineNumber]; var formattingRules = GetFormattingRules(document, lineToBeIndented.Start, indentStyle); return(new Indenter(this, syntacticDoc, formattingRules, options, lineToBeIndented, cancellationToken)); }
public CSharpSmartTokenFormatter( IndentationOptions options, ImmutableArray <AbstractFormattingRule> formattingRules, CompilationUnitSyntax root) { Contract.ThrowIfNull(root); _options = options; _formattingRules = formattingRules; _root = root; }
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)); }
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)); }
private static TextChange FixDiagnostic(IndentationOptions indentationOptions, SourceText sourceText, Diagnostic diagnostic) { TextSpan span = diagnostic.Location.SourceSpan; TextLine startLine = sourceText.Lines.GetLineFromPosition(span.Start); string text = sourceText.ToString(TextSpan.FromBounds(startLine.Start, span.End)); StringBuilder replacement = StringBuilderPool.Allocate(); int column = 0; for (int i = 0; i < text.Length; i++) { char c = text[i]; if (c == '\t') { var offsetWithinTabColumn = column % indentationOptions.TabSize; var spaceCount = indentationOptions.TabSize - offsetWithinTabColumn; if (i >= span.Start - startLine.Start) { replacement.Append(' ', spaceCount); } column += spaceCount; } else { if (i >= span.Start - startLine.Start) { replacement.Append(c); } if (c == '\n') { column = 0; } else { column++; } } } return new TextChange(span, StringBuilderPool.ReturnAndFree(replacement)); }
private static SyntaxNode UpdateSyntaxRoot(MemberDeclarationSyntax memberDeclaration, ImmutableArray<OrderingTrait> elementOrder, SyntaxNode syntaxRoot, IndentationOptions indentationOptions) { var parentDeclaration = memberDeclaration.Parent; var memberToMove = new MemberOrderHelper(memberDeclaration, elementOrder); if (parentDeclaration is TypeDeclarationSyntax) { return HandleTypeDeclaration(memberToMove, (TypeDeclarationSyntax)parentDeclaration, elementOrder, syntaxRoot, indentationOptions); } if (parentDeclaration is NamespaceDeclarationSyntax) { return HandleNamespaceDeclaration(memberToMove, (NamespaceDeclarationSyntax)parentDeclaration, elementOrder, syntaxRoot, indentationOptions); } if (parentDeclaration is CompilationUnitSyntax) { return HandleCompilationUnitDeclaration(memberToMove, (CompilationUnitSyntax)parentDeclaration, elementOrder, syntaxRoot, indentationOptions); } return syntaxRoot; }
private static ConstructorDeclarationSyntax ReformatConstructorDeclaration(ConstructorDeclarationSyntax constructorDeclaration, IndentationOptions indentationOptions, SyntaxTrivia newLine) { var constructorInitializer = constructorDeclaration.Initializer; var newParameterList = constructorDeclaration.ParameterList .WithTrailingTrivia(constructorDeclaration.ParameterList.GetTrailingTrivia().WithoutTrailingWhitespace().Add(newLine)); var indentationSteps = IndentationHelper.GetIndentationSteps(indentationOptions, constructorDeclaration); var indentation = IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, indentationSteps + 1); var newColonTrailingTrivia = constructorInitializer.ColonToken.TrailingTrivia.WithoutTrailingWhitespace(); var newColonToken = constructorInitializer.ColonToken .WithLeadingTrivia(indentation) .WithTrailingTrivia(newColonTrailingTrivia); var newInitializer = constructorInitializer .WithColonToken(newColonToken) .WithThisOrBaseKeyword(constructorInitializer.ThisOrBaseKeyword.WithLeadingTrivia(SyntaxFactory.Space)); return constructorDeclaration .WithParameterList(newParameterList) .WithInitializer(newInitializer); }
private static SyntaxNode HandleTypeDeclaration(MemberOrderHelper memberOrder, TypeDeclarationSyntax typeDeclarationNode, ImmutableArray<OrderingTrait> elementOrder, SyntaxNode syntaxRoot, IndentationOptions indentationOptions) { return OrderMember(memberOrder, typeDeclarationNode.Members, elementOrder, syntaxRoot, indentationOptions); }
private SyntaxNode RegisterPropertyLikeDeclarationCodeFix(SyntaxNode syntaxRoot, BasePropertyDeclarationSyntax node, IndentationOptions indentationOptions) { return this.ReformatElement(syntaxRoot, node, node.AccessorList.OpenBraceToken, node.AccessorList.CloseBraceToken, indentationOptions); }
private SyntaxNode RegisterMethodLikeDeclarationCodeFix(SyntaxNode syntaxRoot, BaseMethodDeclarationSyntax node, IndentationOptions indentationOptions) { return this.ReformatElement(syntaxRoot, node, node.Body.OpenBraceToken, node.Body.CloseBraceToken, indentationOptions); }
private static SyntaxNode HandleTypeDeclaration(MemberOrderHelper memberOrder, TypeDeclarationSyntax typeDeclarationNode, ElementOrderingChecks checks, SyntaxNode syntaxRoot, IndentationOptions indentationOptions) { return OrderMember(memberOrder, typeDeclarationNode.Members, checks, syntaxRoot, indentationOptions); }
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 int DetermineIndentationSteps(IndentationOptions indentationOptions, SyntaxToken token) { // For a closing brace use the indentation of the corresponding opening brace if (token.IsKind(SyntaxKind.CloseBraceToken)) { var depth = 1; while (depth > 0) { token = token.GetPreviousToken(); switch (token.Kind()) { case SyntaxKind.CloseBraceToken: depth++; break; case SyntaxKind.OpenBraceToken: depth--; break; } } } var startLine = GetTokenStartLinePosition(token).Line; while (!ContainsStartOfLine(token, startLine)) { token = token.GetPreviousToken(); } return IndentationHelper.GetIndentationSteps(indentationOptions, token); }
private static SyntaxNode ReformatAccessorAsMultipleLines(IndentationOptions indentationOptions, AccessorDeclarationSyntax accessor) { var accessorList = (AccessorListSyntax)accessor.Parent; var indentationSteps = IndentationHelper.GetIndentationSteps(indentationOptions, accessorList.OpenBraceToken) + 1; var indentation = IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, indentationSteps); var indentationStatements = IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, indentationSteps + 1); var newAccessor = accessor .WithModifiers(ReformatModifiersAsMultipleLines(accessor.Modifiers, indentation)) .WithKeyword(ReformatKeywordAsMultipleLines(accessor.Keyword, indentation, accessor.Modifiers.Count == 0)) .WithBody(ReformatBodyAsMultipleLines(accessor.Body, indentation, indentationStatements)); return newAccessor; }
private static SyntaxNode ReformatAccessorAsSingleLine(IndentationOptions indentationOptions, AccessorDeclarationSyntax accessor) { var newAccessor = accessor .WithModifiers(ReformatModifiersAsSingleLine(accessor.Modifiers)) .WithKeyword(ReformatKeywordAsSingleLine(accessor.Keyword)) .WithBody(ReformatBodyAsSingleLine(accessor.Body)); var accessorList = (AccessorListSyntax)accessor.Parent; var indentationSteps = IndentationHelper.GetIndentationSteps(indentationOptions, accessorList.OpenBraceToken); var indentation = IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, indentationSteps + 1); newAccessor = newAccessor.WithLeadingTrivia(newAccessor.GetLeadingTrivia().Insert(0, indentation)); return newAccessor; }
private static void BuildReplaceMapForConditionalDirectives(UsingsHelper usingsHelper, Dictionary<UsingDirectiveSyntax, UsingDirectiveSyntax> replaceMap, IndentationOptions indentationOptions, DirectiveSpan 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(indentationOptions, originalUsings[0].Parent); if (originalUsings[0].Parent is NamespaceDeclarationSyntax) { indentationSteps++; } var indentation = IndentationHelper.GenerateIndentationString(indentationOptions, indentationSteps); var modifiedUsings = usingsHelper.GenerateGroupedUsings(childSpan, indentation, false); for (var i = 0; i < originalUsings.Count; i++) { replaceMap.Add(originalUsings[i], modifiedUsings[i]); } } BuildReplaceMapForConditionalDirectives(usingsHelper, replaceMap, indentationOptions, childSpan); } }
private static SyntaxNode MoveMember(SyntaxNode syntaxRoot, MemberDeclarationSyntax member, MemberDeclarationSyntax targetMember, IndentationOptions indentationOptions) { 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(indentationOptions, targetMember); var indentationString = IndentationHelper.GenerateIndentationString(indentationOptions, 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 SyntaxNode OrderMember(MemberOrderHelper memberOrder, SyntaxList<MemberDeclarationSyntax> members, ImmutableArray<OrderingTrait> elementOrder, SyntaxNode syntaxRoot, IndentationOptions indentationOptions) { var memberIndex = members.IndexOf(memberOrder.Member); MemberOrderHelper target = default(MemberOrderHelper); for (var i = memberIndex - 1; i >= 0; --i) { var orderHelper = new MemberOrderHelper(members[i], elementOrder); if (orderHelper.Priority < memberOrder.Priority) { target = orderHelper; } else { break; } } return target.Member != null ? MoveMember(syntaxRoot, memberOrder.Member, target.Member, indentationOptions) : syntaxRoot; }
private static SyntaxNode HandleNamespaceDeclaration(MemberOrderHelper memberOrder, NamespaceDeclarationSyntax namespaceDeclaration, ImmutableArray<OrderingTrait> elementOrder, SyntaxNode syntaxRoot, IndentationOptions indentationOptions) { return OrderMember(memberOrder, namespaceDeclaration.Members, elementOrder, syntaxRoot, indentationOptions); }
private static SyntaxNode HandleCompilationUnitDeclaration(MemberOrderHelper memberOrder, CompilationUnitSyntax compilationUnitDeclaration, ImmutableArray<OrderingTrait> elementOrder, SyntaxNode syntaxRoot, IndentationOptions indentationOptions) { return OrderMember(memberOrder, compilationUnitDeclaration.Members, elementOrder, syntaxRoot, indentationOptions); }
private static SyntaxNode HandleCompilationUnitDeclaration(MemberOrderHelper memberOrder, CompilationUnitSyntax compilationUnitDeclaration, ElementOrderingChecks checks, SyntaxNode syntaxRoot, IndentationOptions indentationOptions) { return OrderMember(memberOrder, compilationUnitDeclaration.Members, checks, syntaxRoot, indentationOptions); }
private static SyntaxNode HandleNamespaceDeclaration(MemberOrderHelper memberOrder, NamespaceDeclarationSyntax namespaceDeclaration, ElementOrderingChecks checks, SyntaxNode syntaxRoot, IndentationOptions indentationOptions) { return OrderMember(memberOrder, namespaceDeclaration.Members, checks, syntaxRoot, indentationOptions); }
private SyntaxNode RegisterNamespaceDeclarationCodeFix(SyntaxNode syntaxRoot, NamespaceDeclarationSyntax node, IndentationOptions indentationOptions) { return this.ReformatElement(syntaxRoot, node, node.OpenBraceToken, node.CloseBraceToken, indentationOptions); }
private static void BuildReplaceMapForNamespaces(UsingsHelper usingsHelper, Dictionary<UsingDirectiveSyntax, UsingDirectiveSyntax> replaceMap, IndentationOptions indentationOptions) { var usingsPerNamespace = usingsHelper .GetContainedUsings(usingsHelper.RootSpan) .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(indentationOptions, usingList[0].Parent); if (usingList[0].Parent is NamespaceDeclarationSyntax) { indentationSteps++; } var indentation = IndentationHelper.GenerateIndentationString(indentationOptions, indentationSteps); var modifiedUsings = usingsHelper.GenerateGroupedUsings(usingList, indentation, false); for (var i = 0; i < usingList.Count; i++) { replaceMap.Add(usingList[i], modifiedUsings[i]); } } } }