-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refresh diagnostics when fading options change #77322
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,10 @@ | |
using System.Collections.Immutable; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.CodeAnalysis.CodeStyle; | ||
using Microsoft.CodeAnalysis.Diagnostics; | ||
using Microsoft.CodeAnalysis.Options; | ||
using Microsoft.CodeAnalysis.PooledObjects; | ||
using Microsoft.CodeAnalysis.Text; | ||
using Roslyn.LanguageServer.Protocol; | ||
using Roslyn.Utilities; | ||
|
@@ -25,8 +28,11 @@ internal abstract partial class AbstractPullDiagnosticHandler<TDiagnosticsParams | |
/// well for us in the normal case. The latter still allows us to reuse diagnostics when changes happen that update | ||
/// the version stamp but not the content (for example, forking LSP text). | ||
/// </summary> | ||
private sealed class DiagnosticsPullCache(string uniqueKey) : VersionedPullCache<(int globalStateVersion, VersionStamp? dependentVersion), (int globalStateVersion, Checksum dependentChecksum), DiagnosticsRequestState, ImmutableArray<DiagnosticData>>(uniqueKey) | ||
private sealed class DiagnosticsPullCache(IGlobalOptionService globalOptions, string uniqueKey) | ||
: VersionedPullCache<(int globalStateVersion, VersionStamp? dependentVersion), (int globalStateVersion, Checksum dependentChecksum), DiagnosticsRequestState, ImmutableArray<DiagnosticData>>(uniqueKey) | ||
{ | ||
private readonly IGlobalOptionService _globalOptions = globalOptions; | ||
|
||
public override async Task<(int globalStateVersion, VersionStamp? dependentVersion)> ComputeCheapVersionAsync(DiagnosticsRequestState state, CancellationToken cancellationToken) | ||
{ | ||
return (state.GlobalStateVersion, await state.Project.GetDependentVersionAsync(cancellationToken).ConfigureAwait(false)); | ||
|
@@ -45,14 +51,28 @@ public override async Task<ImmutableArray<DiagnosticData>> ComputeDataAsync(Diag | |
return diagnostics; | ||
} | ||
|
||
public override Checksum ComputeChecksum(ImmutableArray<DiagnosticData> data) | ||
public override Checksum ComputeChecksum(ImmutableArray<DiagnosticData> data, string language) | ||
{ | ||
// Create checksums of diagnostic data and sort to ensure stable ordering for comparison. | ||
var diagnosticDataChecksums = data | ||
.SelectAsArray(d => Checksum.Create(d, SerializeDiagnosticData)) | ||
.Sort(); | ||
using var _ = ArrayBuilder<Checksum>.GetInstance(out var builder); | ||
foreach (var datum in data) | ||
builder.Add(Checksum.Create(datum, SerializeDiagnosticData)); | ||
|
||
// Ensure that if fading options change that we recompute the checksum as it will produce different data | ||
// that we would report to the client. | ||
var option1 = _globalOptions.GetOption(FadingOptions.FadeOutUnreachableCode, language); | ||
var option2 = _globalOptions.GetOption(FadingOptions.FadeOutUnusedImports, language); | ||
var option3 = _globalOptions.GetOption(FadingOptions.FadeOutUnusedMembers, language); | ||
|
||
var value = | ||
(option1 ? (1 << 2) : 0) | | ||
(option2 ? (1 << 1) : 0) | | ||
(option3 ? (1 << 0) : 0); | ||
|
||
builder.Add(new Checksum(0, value)); | ||
builder.Sort(); | ||
|
||
return Checksum.Create(diagnosticDataChecksums); | ||
return Checksum.Create(builder); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i needed to do tthe above because hte DiagnosticPullCache was computing the 'new daignostic checksum' and getting the same result. This si because it operates purely on DiagnosticData, and not on the 'transformed LSP diagnostics' that it would create from the data.
I opted for '3' for simplicity. Note that there is no actual checking if the option actually impacts the diagnostic results. We effectively just say that if any of these options changed that you should not use the cache and recompute. Given that changing this option would not be a common event, this seems totally reasonable. |
||
} | ||
|
||
private static void SerializeDiagnosticData(DiagnosticData diagnosticData, ObjectWriter writer) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this controls if the diagnostic service itself broadcasts taht a diagnostics refresh is needed.