提交 cb2970c1 编写于 作者: M Manish Vasani

Fix race condition in CodeFixService

Ensure that we process diagnostics ordered by their span and then diagnostic ID. This fixes a race condition seen in intermittent failures for ConfigureCodeStyleOptionValueAndSeverity where the order of configuration/suppression fixes is non-deterministic
上级 e94cd673
...@@ -160,7 +160,8 @@ public async Task<ImmutableArray<CodeFixCollection>> GetFixesAsync(Document docu ...@@ -160,7 +160,8 @@ public async Task<ImmutableArray<CodeFixCollection>> GetFixesAsync(Document docu
// group diagnostics by their diagnostics span // group diagnostics by their diagnostics span
// invariant: later code gathers & runs CodeFixProviders for diagnostics with one identical diagnostics span (that gets set later as CodeFixCollection's TextSpan) // invariant: later code gathers & runs CodeFixProviders for diagnostics with one identical diagnostics span (that gets set later as CodeFixCollection's TextSpan)
Dictionary<TextSpan, List<DiagnosticData>>? aggregatedDiagnostics = null; // order diagnostics by span and then diagnostic ID.
SortedDictionary<TextSpan, SortedList<DiagnosticId, DiagnosticData>>? aggregatedDiagnostics = null;
foreach (var diagnostic in await _diagnosticService.GetDiagnosticsForSpanAsync(document, range, diagnosticIdOpt: null, includeConfigurationFixes, addOperationScope, cancellationToken).ConfigureAwait(false)) foreach (var diagnostic in await _diagnosticService.GetDiagnosticsForSpanAsync(document, range, diagnosticIdOpt: null, includeConfigurationFixes, addOperationScope, cancellationToken).ConfigureAwait(false))
{ {
if (diagnostic.IsSuppressed) if (diagnostic.IsSuppressed)
...@@ -170,8 +171,8 @@ public async Task<ImmutableArray<CodeFixCollection>> GetFixesAsync(Document docu ...@@ -170,8 +171,8 @@ public async Task<ImmutableArray<CodeFixCollection>> GetFixesAsync(Document docu
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
aggregatedDiagnostics ??= new Dictionary<TextSpan, List<DiagnosticData>>(); aggregatedDiagnostics ??= new SortedDictionary<TextSpan, SortedList<string, DiagnosticData>>();
aggregatedDiagnostics.GetOrAdd(diagnostic.GetTextSpan(), _ => new List<DiagnosticData>()).Add(diagnostic); aggregatedDiagnostics.GetOrAdd(diagnostic.GetTextSpan(), _ => new SortedList<DiagnosticId, DiagnosticData>()).Add(diagnostic.Id, diagnostic);
} }
if (aggregatedDiagnostics == null) if (aggregatedDiagnostics == null)
...@@ -184,7 +185,7 @@ public async Task<ImmutableArray<CodeFixCollection>> GetFixesAsync(Document docu ...@@ -184,7 +185,7 @@ public async Task<ImmutableArray<CodeFixCollection>> GetFixesAsync(Document docu
foreach (var spanAndDiagnostic in aggregatedDiagnostics) foreach (var spanAndDiagnostic in aggregatedDiagnostics)
{ {
await AppendFixesAsync( await AppendFixesAsync(
document, spanAndDiagnostic.Key, spanAndDiagnostic.Value, fixAllForInSpan: false, isBlocking, document, spanAndDiagnostic.Key, spanAndDiagnostic.Value.Values, fixAllForInSpan: false, isBlocking,
result, addOperationScope, cancellationToken).ConfigureAwait(false); result, addOperationScope, cancellationToken).ConfigureAwait(false);
} }
...@@ -204,7 +205,7 @@ int GetValue(CodeFixCollection c) ...@@ -204,7 +205,7 @@ int GetValue(CodeFixCollection c)
foreach (var spanAndDiagnostic in aggregatedDiagnostics) foreach (var spanAndDiagnostic in aggregatedDiagnostics)
{ {
await AppendConfigurationsAsync( await AppendConfigurationsAsync(
document, spanAndDiagnostic.Key, spanAndDiagnostic.Value, document, spanAndDiagnostic.Key, spanAndDiagnostic.Value.Values,
result, cancellationToken).ConfigureAwait(false); result, cancellationToken).ConfigureAwait(false);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册