提交 d6527dca 编写于 作者: C CyrusNajmabadi 提交者: GitHub

Merge pull request #15445 from CyrusNajmabadi/deterministicCodeActionApplication

Make BatchFix code action application deterministic.
...@@ -454,7 +454,7 @@ End Class]]> ...@@ -454,7 +454,7 @@ End Class]]>
</Project> </Project>
</Workspace>.ToString() </Workspace>.ToString()
Await TestAsync(input, expected, compareTokens:=False, fixAllActionEquivalenceKey:=Nothing) Await TestAsync(input, expected, compareTokens:=False)
End Function End Function
End Class End Class
End Namespace End Namespace
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
...@@ -24,8 +25,9 @@ public PragmaWarningBatchFixAllProvider(AbstractSuppressionCodeFixProvider suppr ...@@ -24,8 +25,9 @@ public PragmaWarningBatchFixAllProvider(AbstractSuppressionCodeFixProvider suppr
_suppressionFixProvider = suppressionFixProvider; _suppressionFixProvider = suppressionFixProvider;
} }
public override async Task AddDocumentFixesAsync( protected override async Task AddDocumentFixesAsync(
Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, Document document, ImmutableArray<Diagnostic> diagnostics,
ConcurrentBag<(Diagnostic diagnostic, CodeAction action)> fixes,
FixAllState fixAllState, CancellationToken cancellationToken) FixAllState fixAllState, CancellationToken cancellationToken)
{ {
var pragmaActionsBuilder = ArrayBuilder<IPragmaBasedCodeAction>.GetInstance(); var pragmaActionsBuilder = ArrayBuilder<IPragmaBasedCodeAction>.GetInstance();
...@@ -58,9 +60,9 @@ public PragmaWarningBatchFixAllProvider(AbstractSuppressionCodeFixProvider suppr ...@@ -58,9 +60,9 @@ public PragmaWarningBatchFixAllProvider(AbstractSuppressionCodeFixProvider suppr
pragmaDiagnosticsBuilder.ToImmutableAndFree(), pragmaDiagnosticsBuilder.ToImmutableAndFree(),
fixAllState, cancellationToken); fixAllState, cancellationToken);
addFix(pragmaBatchFix); fixes.Add((diagnostic: null, pragmaBatchFix));
} }
} }
} }
} }
} }
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
...@@ -32,8 +33,9 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider) ...@@ -32,8 +33,9 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider)
_suppressionFixProvider = suppressionFixProvider; _suppressionFixProvider = suppressionFixProvider;
} }
public override async Task AddDocumentFixesAsync( protected override async Task AddDocumentFixesAsync(
Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, Document document, ImmutableArray<Diagnostic> diagnostics,
ConcurrentBag<(Diagnostic diagnostic, CodeAction action)> fixes,
FixAllState fixAllState, CancellationToken cancellationToken) FixAllState fixAllState, CancellationToken cancellationToken)
{ {
// Batch all the pragma remove suppression fixes by executing them sequentially for the document. // Batch all the pragma remove suppression fixes by executing them sequentially for the document.
...@@ -64,7 +66,7 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider) ...@@ -64,7 +66,7 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider)
} }
else else
{ {
addFix(codeAction); fixes.Add((diagnostic, codeAction));
} }
} }
} }
...@@ -79,12 +81,13 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider) ...@@ -79,12 +81,13 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider)
pragmaDiagnosticsBuilder.ToImmutableAndFree(), pragmaDiagnosticsBuilder.ToImmutableAndFree(),
fixAllState, cancellationToken); fixAllState, cancellationToken);
addFix(pragmaBatchFix); fixes.Add((diagnostic: null, pragmaBatchFix));
} }
} }
public async override Task AddProjectFixesAsync( protected async override Task AddProjectFixesAsync(
Project project, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, Project project, ImmutableArray<Diagnostic> diagnostics,
ConcurrentBag<(Diagnostic diagnostic, CodeAction action)> bag,
FixAllState fixAllState, CancellationToken cancellationToken) FixAllState fixAllState, CancellationToken cancellationToken)
{ {
foreach (var diagnostic in diagnostics.Where(d => !d.Location.IsInSource && d.IsSuppressed)) foreach (var diagnostic in diagnostics.Where(d => !d.Location.IsInSource && d.IsSuppressed))
...@@ -99,13 +102,15 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider) ...@@ -99,13 +102,15 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider)
removeSuppressionCodeAction = removeSuppressionCodeAction.CloneForFixMultipleContext(); removeSuppressionCodeAction = removeSuppressionCodeAction.CloneForFixMultipleContext();
} }
addFix(removeSuppressionCodeAction); bag.Add((diagnostic, removeSuppressionCodeAction));
} }
} }
} }
public override async Task<CodeAction> TryGetMergedFixAsync( public override async Task<CodeAction> TryGetMergedFixAsync(
IEnumerable<CodeAction> batchOfFixes, FixAllState fixAllState, CancellationToken cancellationToken) ImmutableArray<(Diagnostic diagnostic, CodeAction action)> batchOfFixes,
FixAllState fixAllState,
CancellationToken cancellationToken)
{ {
// Batch all the attribute removal fixes into a single fix. // Batch all the attribute removal fixes into a single fix.
// Pragma removal fixes have already been batch for each document AddDocumentFixes method. // Pragma removal fixes have already been batch for each document AddDocumentFixes method.
...@@ -115,10 +120,10 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider) ...@@ -115,10 +120,10 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider)
var currentSolution = oldSolution; var currentSolution = oldSolution;
var attributeRemoveFixes = new List<AttributeRemoveAction>(); var attributeRemoveFixes = new List<AttributeRemoveAction>();
var newBatchOfFixes = new List<CodeAction>(); var newBatchOfFixes = new List<(Diagnostic diagnostic, CodeAction action)>();
foreach (var codeAction in batchOfFixes) foreach (var codeAction in batchOfFixes)
{ {
var attributeRemoveFix = codeAction as AttributeRemoveAction; var attributeRemoveFix = codeAction.action as AttributeRemoveAction;
if (attributeRemoveFix != null) if (attributeRemoveFix != null)
{ {
attributeRemoveFixes.Add(attributeRemoveFix); attributeRemoveFixes.Add(attributeRemoveFix);
...@@ -152,10 +157,11 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider) ...@@ -152,10 +157,11 @@ public BatchFixer(AbstractSuppressionCodeFixProvider suppressionFixProvider)
equivalenceKey: fixAllState.CodeActionEquivalenceKey); equivalenceKey: fixAllState.CodeActionEquivalenceKey);
#pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction #pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction
newBatchOfFixes.Insert(0, batchAttributeRemoveFix); newBatchOfFixes.Insert(0, (diagnostic: null, batchAttributeRemoveFix));
} }
return await base.TryGetMergedFixAsync(newBatchOfFixes, fixAllState, cancellationToken).ConfigureAwait(false); return await base.TryGetMergedFixAsync(
newBatchOfFixes.ToImmutableArray(), fixAllState, cancellationToken).ConfigureAwait(false);
} }
private static async Task<ImmutableArray<SyntaxNode>> GetAttributeNodesToFixAsync(ImmutableArray<AttributeRemoveAction> attributeRemoveFixes, CancellationToken cancellationToken) private static async Task<ImmutableArray<SyntaxNode>> GetAttributeNodesToFixAsync(ImmutableArray<AttributeRemoveAction> attributeRemoveFixes, CancellationToken cancellationToken)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Linq; using System.Linq;
...@@ -24,15 +25,16 @@ internal class BatchSimplificationFixAllProvider : BatchFixAllProvider ...@@ -24,15 +25,16 @@ internal class BatchSimplificationFixAllProvider : BatchFixAllProvider
protected BatchSimplificationFixAllProvider() { } protected BatchSimplificationFixAllProvider() { }
public override async Task AddDocumentFixesAsync( protected override async Task AddDocumentFixesAsync(
Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, Document document, ImmutableArray<Diagnostic> diagnostics,
ConcurrentBag<(Diagnostic diagnostic, CodeAction action)> fixes,
FixAllState fixAllState, CancellationToken cancellationToken) FixAllState fixAllState, CancellationToken cancellationToken)
{ {
var changedDocument = await AddSimplifierAnnotationsAsync( var changedDocument = await AddSimplifierAnnotationsAsync(
document, diagnostics, fixAllState, cancellationToken).ConfigureAwait(false); document, diagnostics, fixAllState, cancellationToken).ConfigureAwait(false);
var title = GetFixAllTitle(fixAllState); var title = GetFixAllTitle(fixAllState);
var codeAction = new MyCodeAction(title, (c) => Task.FromResult(changedDocument)); var codeAction = new MyCodeAction(title, c => Task.FromResult(changedDocument));
addFix(codeAction); fixes.Add((diagnostics.First(), codeAction));
} }
/// <summary> /// <summary>
......
...@@ -126,11 +126,11 @@ public static void LogDiagnosticsStats(ImmutableDictionary<Project, ImmutableArr ...@@ -126,11 +126,11 @@ public static void LogDiagnosticsStats(ImmutableDictionary<Project, ImmutableArr
})); }));
} }
public static void LogFixesToMergeStats(ConcurrentBag<CodeAction> fixesToMerge) public static void LogFixesToMergeStats(int count)
{ {
Logger.Log(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, KeyValueLogMessage.Create(m => Logger.Log(FunctionId.CodeFixes_FixAllOccurrencesComputation_Merge, KeyValueLogMessage.Create(m =>
{ {
m[s_totalFixesToMerge] = fixesToMerge.Count; m[s_totalFixesToMerge] = count;
})); }));
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册