Skip to content

Commit 3800735

Browse files
committed
Implement a custom Fix All provider for SA1514
1 parent b1c6db9 commit 3800735

File tree

1 file changed

+35
-13
lines changed

1 file changed

+35
-13
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/LayoutRules/SA1514CodeFixProvider.cs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace StyleCop.Analyzers.LayoutRules
55
{
66
using System.Collections.Immutable;
77
using System.Composition;
8+
using System.Linq;
89
using System.Threading;
910
using System.Threading.Tasks;
1011
using Microsoft.CodeAnalysis;
@@ -27,7 +28,7 @@ internal class SA1514CodeFixProvider : CodeFixProvider
2728
/// <inheritdoc/>
2829
public override FixAllProvider GetFixAllProvider()
2930
{
30-
return CustomFixAllProviders.BatchFixer;
31+
return FixAll.Instance;
3132
}
3233

3334
/// <inheritdoc/>
@@ -47,23 +48,44 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
4748
}
4849

4950
private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
51+
{
52+
var newRoot = await GetTransformedDocumentAsync(document, ImmutableArray.Create(diagnostic), cancellationToken).ConfigureAwait(false);
53+
return document.WithSyntaxRoot(newRoot);
54+
}
55+
56+
private static async Task<SyntaxNode> GetTransformedDocumentAsync(Document document, ImmutableArray<Diagnostic> diagnostics, CancellationToken cancellationToken)
5057
{
5158
var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
5259

53-
var documentationHeader = syntaxRoot.FindTrivia(diagnostic.Location.SourceSpan.Start);
54-
var triviaList = documentationHeader.Token.LeadingTrivia;
55-
var documentationHeaderIndex = triviaList.IndexOf(documentationHeader);
60+
var documentationHeaders = diagnostics.Select(diagnostic => syntaxRoot.FindTrivia(diagnostic.Location.SourceSpan.Start)).ToArray();
61+
return syntaxRoot.ReplaceTokens(
62+
documentationHeaders.Select(header => header.Token),
63+
(originalToken, rewrittenToken) =>
64+
{
65+
var triviaList = rewrittenToken.LeadingTrivia;
66+
var documentationHeaderIndex = originalToken.LeadingTrivia.IndexOf(originalToken.LeadingTrivia.First(documentationHeaders.Contains));
5667

57-
// Keep any leading whitespace with the documentation header
58-
var index = documentationHeaderIndex - 1;
59-
while ((index >= 0) && triviaList[index].IsKind(SyntaxKind.WhitespaceTrivia))
60-
{
61-
index--;
62-
}
68+
// Keep any leading whitespace with the documentation header
69+
var index = documentationHeaderIndex - 1;
70+
while ((index >= 0) && triviaList[index].IsKind(SyntaxKind.WhitespaceTrivia))
71+
{
72+
index--;
73+
}
74+
75+
var newLeadingTrivia = rewrittenToken.LeadingTrivia.Insert(index + 1, SyntaxFactory.CarriageReturnLineFeed);
76+
return rewrittenToken.WithLeadingTrivia(newLeadingTrivia);
77+
});
78+
}
79+
80+
private class FixAll : DocumentBasedFixAllProvider
81+
{
82+
public static FixAllProvider Instance { get; } =
83+
new FixAll();
84+
85+
protected override string CodeActionTitle => LayoutResources.SA1514CodeFix;
6386

64-
var newLeadingTrivia = documentationHeader.Token.LeadingTrivia.Insert(index + 1, SyntaxFactory.CarriageReturnLineFeed);
65-
var newSyntaxRoot = syntaxRoot.ReplaceToken(documentationHeader.Token, documentationHeader.Token.WithLeadingTrivia(newLeadingTrivia));
66-
return document.WithSyntaxRoot(newSyntaxRoot);
87+
protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document, ImmutableArray<Diagnostic> diagnostics)
88+
=> await GetTransformedDocumentAsync(document, diagnostics, fixAllContext.CancellationToken).ConfigureAwait(false);
6789
}
6890
}
6991
}

0 commit comments

Comments
 (0)