Skip to content

Commit d91d674

Browse files
authored
Merge pull request #2853 from pdelvo/SA1134NonDeterminism
Fix that SA1134 Fix All maybe non-deterministic
2 parents 69d477f + 5431f37 commit d91d674

File tree

1 file changed

+39
-6
lines changed

1 file changed

+39
-6
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/ReadabilityRules/SA1134CodeFixProvider.cs

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace StyleCop.Analyzers.ReadabilityRules
1616
using Microsoft.CodeAnalysis.CSharp;
1717
using Microsoft.CodeAnalysis.CSharp.Syntax;
1818
using StyleCop.Analyzers.Helpers;
19+
using StyleCop.Analyzers.Settings.ObjectModel;
1920

2021
/// <summary>
2122
/// Implements a code fix for <see cref="SA1134AttributesMustNotShareLine"/>.
@@ -31,7 +32,7 @@ internal class SA1134CodeFixProvider : CodeFixProvider
3132
/// <inheritdoc/>
3233
public override FixAllProvider GetFixAllProvider()
3334
{
34-
return CustomFixAllProviders.BatchFixer;
35+
return FixAll.Instance;
3536
}
3637

3738
/// <inheritdoc/>
@@ -58,16 +59,25 @@ private static async Task<Document> GetTransformedDocumentAsync(Document documen
5859
{
5960
var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
6061
var settings = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, syntaxRoot.SyntaxTree, cancellationToken);
62+
var tokensToReplace = new Dictionary<SyntaxToken, SyntaxToken>();
63+
64+
AddTokensToReplaceToMap(tokensToReplace, syntaxRoot, diagnostic, settings);
65+
66+
var newSyntaxRoot = syntaxRoot.ReplaceTokens(tokensToReplace.Keys, (original, rewritten) => tokensToReplace[original]);
67+
var newDocument = document.WithSyntaxRoot(newSyntaxRoot.WithoutFormatting());
68+
69+
return newDocument;
70+
}
6171

72+
private static void AddTokensToReplaceToMap(Dictionary<SyntaxToken, SyntaxToken> tokensToReplace, SyntaxNode syntaxRoot, Diagnostic diagnostic, StyleCopSettings settings)
73+
{
6274
var attributeListSyntax = (AttributeListSyntax)syntaxRoot.FindNode(diagnostic.Location.SourceSpan);
6375

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

69-
var tokensToReplace = new Dictionary<SyntaxToken, SyntaxToken>();
70-
7181
if (diagnostic.Properties.ContainsKey(SA1134AttributesMustNotShareLine.FixWithNewLineBeforeKey))
7282
{
7383
var token = attributeListSyntax.OpenBracketToken;
@@ -89,11 +99,34 @@ private static async Task<Document> GetTransformedDocumentAsync(Document documen
8999
var newLeadingTrivia = nextToken.LeadingTrivia.Insert(0, indentationTrivia);
90100
tokensToReplace[nextToken] = nextToken.WithLeadingTrivia(newLeadingTrivia);
91101
}
102+
}
92103

93-
var newSyntaxRoot = syntaxRoot.ReplaceTokens(tokensToReplace.Keys, (original, rewritten) => tokensToReplace[original]);
94-
var newDocument = document.WithSyntaxRoot(newSyntaxRoot.WithoutFormatting());
104+
private class FixAll : DocumentBasedFixAllProvider
105+
{
106+
public static FixAllProvider Instance { get; } = new FixAll();
95107

96-
return newDocument;
108+
protected override string CodeActionTitle => ReadabilityResources.SA1134CodeFix;
109+
110+
protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document, ImmutableArray<Diagnostic> diagnostics)
111+
{
112+
if (diagnostics.IsEmpty)
113+
{
114+
return null;
115+
}
116+
117+
var syntaxRoot = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
118+
var settings = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, syntaxRoot.SyntaxTree, fixAllContext.CancellationToken);
119+
var tokensToReplace = new Dictionary<SyntaxToken, SyntaxToken>();
120+
121+
foreach (var diagnostic in diagnostics)
122+
{
123+
AddTokensToReplaceToMap(tokensToReplace, syntaxRoot, diagnostic, settings);
124+
}
125+
126+
var newSyntaxRoot = syntaxRoot.ReplaceTokens(tokensToReplace.Keys, (original, rewritten) => tokensToReplace[original]);
127+
128+
return newSyntaxRoot;
129+
}
97130
}
98131
}
99132
}

0 commit comments

Comments
 (0)