From df7000463aad9a276d216c281320c1a4fe6776c2 Mon Sep 17 00:00:00 2001 From: Dennis Fischer Date: Mon, 7 Jan 2019 20:59:44 +0100 Subject: [PATCH] Fix that SA1134 Fix All maybe non-deterministic --- .../ReadabilityRules/SA1134CodeFixProvider.cs | 45 ++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/ReadabilityRules/SA1134CodeFixProvider.cs b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/ReadabilityRules/SA1134CodeFixProvider.cs index 08940cfe9..daf349312 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/ReadabilityRules/SA1134CodeFixProvider.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/ReadabilityRules/SA1134CodeFixProvider.cs @@ -14,6 +14,7 @@ namespace StyleCop.Analyzers.ReadabilityRules using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using StyleCop.Analyzers.Helpers; + using StyleCop.Analyzers.Settings.ObjectModel; /// /// Implements a code fix for . @@ -29,7 +30,7 @@ internal class SA1134CodeFixProvider : CodeFixProvider /// public override FixAllProvider GetFixAllProvider() { - return CustomFixAllProviders.BatchFixer; + return FixAll.Instance; } /// @@ -52,7 +53,18 @@ private static async Task GetTransformedDocumentAsync(Document documen { var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var settings = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, cancellationToken); + var tokensToReplace = new Dictionary(); + + AddTokensToReplaceToMap(tokensToReplace, syntaxRoot, diagnostic, settings); + + var newSyntaxRoot = syntaxRoot.ReplaceTokens(tokensToReplace.Keys, (original, rewritten) => tokensToReplace[original]); + var newDocument = document.WithSyntaxRoot(newSyntaxRoot.WithoutFormatting()); + + return newDocument; + } + private static void AddTokensToReplaceToMap(Dictionary tokensToReplace, SyntaxNode syntaxRoot, Diagnostic diagnostic, StyleCopSettings settings) + { var attributeListSyntax = (AttributeListSyntax)syntaxRoot.FindNode(diagnostic.Location.SourceSpan); // use the containing type to determine the indentation level, anything else is less reliable. @@ -60,8 +72,6 @@ private static async Task GetTransformedDocumentAsync(Document documen var indentationSteps = (containingType != null) ? IndentationHelper.GetIndentationSteps(settings.Indentation, containingType) + 1 : 0; var indentationTrivia = IndentationHelper.GenerateWhitespaceTrivia(settings.Indentation, indentationSteps); - var tokensToReplace = new Dictionary(); - if (diagnostic.Properties.ContainsKey(SA1134AttributesMustNotShareLine.FixWithNewLineBeforeKey)) { var token = attributeListSyntax.OpenBracketToken; @@ -83,11 +93,34 @@ private static async Task GetTransformedDocumentAsync(Document documen var newLeadingTrivia = nextToken.LeadingTrivia.Insert(0, indentationTrivia); tokensToReplace[nextToken] = nextToken.WithLeadingTrivia(newLeadingTrivia); } + } - var newSyntaxRoot = syntaxRoot.ReplaceTokens(tokensToReplace.Keys, (original, rewritten) => tokensToReplace[original]); - var newDocument = document.WithSyntaxRoot(newSyntaxRoot.WithoutFormatting()); + private class FixAll : DocumentBasedFixAllProvider + { + public static FixAllProvider Instance { get; } = new FixAll(); - return newDocument; + protected override string CodeActionTitle => ReadabilityResources.SA1134CodeFix; + + protected override async Task FixAllInDocumentAsync(FixAllContext fixAllContext, Document document, ImmutableArray diagnostics) + { + if (diagnostics.IsEmpty) + { + return null; + } + + var syntaxRoot = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false); + var settings = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, fixAllContext.CancellationToken); + var tokensToReplace = new Dictionary(); + + foreach (var diagnostic in diagnostics) + { + AddTokensToReplaceToMap(tokensToReplace, syntaxRoot, diagnostic, settings); + } + + var newSyntaxRoot = syntaxRoot.ReplaceTokens(tokensToReplace.Keys, (original, rewritten) => tokensToReplace[original]); + + return newSyntaxRoot; + } } } }