Skip to content

Commit 6ac3ef3

Browse files
committed
Implement a custom Fix All provider for SA1506
1 parent f6a148e commit 6ac3ef3

File tree

1 file changed

+60
-40
lines changed

1 file changed

+60
-40
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/LayoutRules/SA1506CodeFixProvider.cs

Lines changed: 60 additions & 40 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 SA1506CodeFixProvider : CodeFixProvider
2728
/// <inheritdoc/>
2829
public override FixAllProvider GetFixAllProvider()
2930
{
30-
return CustomFixAllProviders.BatchFixer;
31+
return FixAll.Instance;
3132
}
3233

3334
/// <inheritdoc/>
@@ -48,53 +49,72 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
4849

4950
private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
5051
{
51-
var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
52+
var newRoot = await GetTransformedDocumentAsync(document, ImmutableArray.Create(diagnostic), cancellationToken).ConfigureAwait(false);
53+
return document.WithSyntaxRoot(newRoot);
54+
}
5255

53-
var token = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
54-
var triviaList = token.LeadingTrivia;
56+
private static async Task<SyntaxNode> GetTransformedDocumentAsync(Document document, ImmutableArray<Diagnostic> diagnostics, CancellationToken cancellationToken)
57+
{
58+
var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
59+
return syntaxRoot.ReplaceTokens(
60+
diagnostics.Select(diagnostic => syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start)),
61+
(originalToken, rewrittenToken) =>
62+
{
63+
var triviaList = rewrittenToken.LeadingTrivia;
5564

56-
var index = triviaList.IndexOf(SyntaxKind.SingleLineDocumentationCommentTrivia);
65+
var index = triviaList.IndexOf(SyntaxKind.SingleLineDocumentationCommentTrivia);
5766

58-
int currentLineStart = index + 1;
59-
bool onBlankLine = true;
60-
for (int currentIndex = currentLineStart; currentIndex < triviaList.Count; currentIndex++)
61-
{
62-
switch (triviaList[currentIndex].Kind())
63-
{
64-
case SyntaxKind.EndOfLineTrivia:
65-
if (onBlankLine)
67+
int currentLineStart = index + 1;
68+
bool onBlankLine = true;
69+
for (int currentIndex = currentLineStart; currentIndex < triviaList.Count; currentIndex++)
6670
{
67-
triviaList = triviaList.RemoveRange(currentLineStart, currentIndex - currentLineStart + 1);
68-
currentIndex = currentLineStart - 1;
69-
continue;
70-
}
71-
else
72-
{
73-
currentLineStart = currentIndex + 1;
74-
onBlankLine = true;
75-
break;
76-
}
71+
switch (triviaList[currentIndex].Kind())
72+
{
73+
case SyntaxKind.EndOfLineTrivia:
74+
if (onBlankLine)
75+
{
76+
triviaList = triviaList.RemoveRange(currentLineStart, currentIndex - currentLineStart + 1);
77+
currentIndex = currentLineStart - 1;
78+
continue;
79+
}
80+
else
81+
{
82+
currentLineStart = currentIndex + 1;
83+
onBlankLine = true;
84+
break;
85+
}
7786

78-
case SyntaxKind.WhitespaceTrivia:
79-
break;
87+
case SyntaxKind.WhitespaceTrivia:
88+
break;
8089

81-
default:
82-
if (triviaList[currentIndex].HasBuiltinEndLine())
83-
{
84-
currentLineStart = currentIndex + 1;
85-
onBlankLine = true;
86-
break;
87-
}
88-
else
89-
{
90-
onBlankLine = false;
91-
break;
90+
default:
91+
if (triviaList[currentIndex].HasBuiltinEndLine())
92+
{
93+
currentLineStart = currentIndex + 1;
94+
onBlankLine = true;
95+
break;
96+
}
97+
else
98+
{
99+
onBlankLine = false;
100+
break;
101+
}
102+
}
92103
}
93-
}
94-
}
95104

96-
var newSyntaxRoot = syntaxRoot.ReplaceToken(token, token.WithLeadingTrivia(triviaList));
97-
return document.WithSyntaxRoot(newSyntaxRoot);
105+
return rewrittenToken.WithLeadingTrivia(triviaList);
106+
});
107+
}
108+
109+
private class FixAll : DocumentBasedFixAllProvider
110+
{
111+
public static FixAllProvider Instance { get; } =
112+
new FixAll();
113+
114+
protected override string CodeActionTitle => LayoutResources.SA1506CodeFix;
115+
116+
protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document, ImmutableArray<Diagnostic> diagnostics)
117+
=> await GetTransformedDocumentAsync(document, diagnostics, fixAllContext.CancellationToken).ConfigureAwait(false);
98118
}
99119
}
100120
}

0 commit comments

Comments
 (0)