Skip to content
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

Change global option change notification to batch all option changes #73882

Merged
merged 3 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ protected sealed override ITaggerEventSource CreateEventSource(ITextView textVie
TaggerEventSources.OnViewSpanChanged(ThreadingContext, textView),
TaggerEventSources.OnWorkspaceChanged(subjectBuffer, AsyncListener),
TaggerEventSources.OnDocumentActiveContextChanged(subjectBuffer),
TaggerEventSources.OnGlobalOptionChanged(this.GlobalOptions, ClassificationOptionsStorage.ClassifyReassignedVariables),
TaggerEventSources.OnGlobalOptionChanged(this.GlobalOptions, ClassificationOptionsStorage.ClassifyObsoleteSymbols));
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions,
static option => option.Equals(ClassificationOptionsStorage.ClassifyReassignedVariables) || option.Equals(ClassificationOptionsStorage.ClassifyObsoleteSymbols)));
}

protected sealed override async Task ProduceTagsAsync(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,19 @@ protected override ITaggerEventSource CreateEventSource(ITextView textView, ITex
TaggerEventSources.OnViewSpanChanged(this.ThreadingContext, textView),
TaggerEventSources.OnWorkspaceChanged(subjectBuffer, this.AsyncListener),
new InlineHintKeyProcessorEventSource(_inlineHintKeyProcessor),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InlineHintsOptionsStorage.EnabledForParameters),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InlineHintsOptionsStorage.ForLiteralParameters),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InlineHintsOptionsStorage.ForIndexerParameters),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InlineHintsOptionsStorage.ForObjectCreationParameters),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InlineHintsOptionsStorage.ForOtherParameters),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InlineHintsOptionsStorage.SuppressForParametersThatMatchMethodIntent),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InlineHintsOptionsStorage.SuppressForParametersThatDifferOnlyBySuffix),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InlineHintsOptionsStorage.SuppressForParametersThatMatchArgumentName),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InlineHintsOptionsStorage.EnabledForTypes),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InlineHintsOptionsStorage.ForImplicitVariableTypes),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InlineHintsOptionsStorage.ForLambdaParameterTypes),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InlineHintsOptionsStorage.ForImplicitObjectCreation));
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, static option =>
option.Equals(InlineHintsOptionsStorage.EnabledForParameters) ||
option.Equals(InlineHintsOptionsStorage.ForLiteralParameters) ||
option.Equals(InlineHintsOptionsStorage.ForIndexerParameters) ||
option.Equals(InlineHintsOptionsStorage.ForObjectCreationParameters) ||
option.Equals(InlineHintsOptionsStorage.ForOtherParameters) ||
option.Equals(InlineHintsOptionsStorage.SuppressForParametersThatMatchMethodIntent) ||
option.Equals(InlineHintsOptionsStorage.SuppressForParametersThatDifferOnlyBySuffix) ||
option.Equals(InlineHintsOptionsStorage.SuppressForParametersThatMatchArgumentName) ||
option.Equals(InlineHintsOptionsStorage.EnabledForTypes) ||
option.Equals(InlineHintsOptionsStorage.ForImplicitVariableTypes) ||
option.Equals(InlineHintsOptionsStorage.ForLambdaParameterTypes) ||
option.Equals(InlineHintsOptionsStorage.ForImplicitObjectCreation)));
}

protected override void AddSpansToTag(ITextView? textView, ITextBuffer subjectBuffer, ref TemporaryArray<SnapshotSpan> result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,28 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using Microsoft.CodeAnalysis.Options;

namespace Microsoft.CodeAnalysis.Editor.Shared.Tagging;

internal partial class TaggerEventSources
{
private sealed class GlobalOptionChangedEventSource(IGlobalOptionService globalOptions, IOption2 globalOption) : AbstractTaggerEventSource
private sealed class GlobalOptionChangedEventSource(IGlobalOptionService globalOptions, Func<IOption2, bool> predicate) : AbstractTaggerEventSource
{
private readonly IOption2 _globalOption = globalOption;
private readonly IGlobalOptionService _globalOptions = globalOptions;

public override void Connect()
{
_globalOptions.AddOptionChangedHandler(this, OnGlobalOptionChanged);
globalOptions.AddOptionChangedHandler(this, OnGlobalOptionChanged);
}

public override void Disconnect()
{
_globalOptions.RemoveOptionChangedHandler(this, OnGlobalOptionChanged);
globalOptions.RemoveOptionChangedHandler(this, OnGlobalOptionChanged);
}

private void OnGlobalOptionChanged(object? sender, OptionChangedEventArgs e)
{
if (e.Option == _globalOption)
if (e.HasOption(predicate))
{
RaiseChanged();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
Expand Down Expand Up @@ -45,8 +46,8 @@ public static ITaggerEventSource OnSelectionChanged(ITextView textView)
public static ITaggerEventSource OnReadOnlyRegionsChanged(ITextBuffer subjectBuffer)
=> new ReadOnlyRegionsChangedEventSource(subjectBuffer);

public static ITaggerEventSource OnGlobalOptionChanged(IGlobalOptionService globalOptions, IOption2 globalOption)
=> new GlobalOptionChangedEventSource(globalOptions, globalOption);
public static ITaggerEventSource OnGlobalOptionChanged(IGlobalOptionService globalOptions, Func<IOption2, bool> predicate)
=> new GlobalOptionChangedEventSource(globalOptions, predicate);

public static ITaggerEventSource OnParseOptionChanged(ITextBuffer subjectBuffer)
=> new ParseOptionChangedEventSource(subjectBuffer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,15 @@ protected sealed override ITaggerEventSource CreateEventSource(ITextView? textVi
TaggerEventSources.OnTextChanged(subjectBuffer),
TaggerEventSources.OnParseOptionChanged(subjectBuffer),
TaggerEventSources.OnWorkspaceRegistrationChanged(subjectBuffer),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, BlockStructureOptionsStorage.ShowBlockStructureGuidesForCodeLevelConstructs),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, BlockStructureOptionsStorage.ShowBlockStructureGuidesForDeclarationLevelConstructs),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, BlockStructureOptionsStorage.ShowBlockStructureGuidesForCommentsAndPreprocessorRegions),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, BlockStructureOptionsStorage.ShowOutliningForCodeLevelConstructs),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, BlockStructureOptionsStorage.ShowOutliningForDeclarationLevelConstructs),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, BlockStructureOptionsStorage.ShowOutliningForCommentsAndPreprocessorRegions),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, BlockStructureOptionsStorage.CollapseRegionsWhenCollapsingToDefinitions),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, BlockStructureOptionsStorage.CollapseLocalFunctionsWhenCollapsingToDefinitions));
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, static option =>
option.Equals(BlockStructureOptionsStorage.ShowBlockStructureGuidesForCodeLevelConstructs) ||
option.Equals(BlockStructureOptionsStorage.ShowBlockStructureGuidesForDeclarationLevelConstructs) ||
option.Equals(BlockStructureOptionsStorage.ShowBlockStructureGuidesForCommentsAndPreprocessorRegions) ||
option.Equals(BlockStructureOptionsStorage.ShowOutliningForCodeLevelConstructs) ||
option.Equals(BlockStructureOptionsStorage.ShowOutliningForDeclarationLevelConstructs) ||
option.Equals(BlockStructureOptionsStorage.ShowOutliningForCommentsAndPreprocessorRegions) ||
option.Equals(BlockStructureOptionsStorage.CollapseRegionsWhenCollapsingToDefinitions) ||
option.Equals(BlockStructureOptionsStorage.CollapseLocalFunctionsWhenCollapsingToDefinitions)));
}

protected sealed override async Task ProduceTagsAsync(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,18 +324,15 @@ private ITaggerEventSource CreateEventSource()

// If there are any options specified for this tagger, then also hook up event
// notifications for when those options change.
var optionChangedEventSources = _dataSource.Options.Concat(_dataSource.FeatureOptions)
.Select(globalOption => TaggerEventSources.OnGlobalOptionChanged(_dataSource.GlobalOptions, globalOption))
.ToList();

if (optionChangedEventSources.Count == 0)
if (_dataSource.Options.IsEmpty && _dataSource.FeatureOptions.IsEmpty)
{
// No options specified for this tagger. So just keep the event source as is.
return eventSource;
}

optionChangedEventSources.Add(eventSource);
return TaggerEventSources.Compose(optionChangedEventSources);
return TaggerEventSources.Compose(
eventSource,
TaggerEventSources.OnGlobalOptionChanged(_dataSource.GlobalOptions, option =>
_dataSource.Options.Contains(option) || _dataSource.FeatureOptions.Contains(option)));
}

private void RaiseTagsChanged(ITextBuffer buffer, DiffResult difference)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -51,7 +52,7 @@ public DiagnosticAnalyzerService(

globalOptions.AddOptionChangedHandler(this, (_, e) =>
{
if (IsGlobalOptionAffectingDiagnostics(e.Option))
if (e.HasOption(IsGlobalOptionAffectingDiagnostics))
{
RequestDiagnosticRefresh();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Linq;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Roslyn.LanguageServer.Protocol;
Expand Down Expand Up @@ -39,8 +40,7 @@ protected override string GetWorkspaceRefreshName()

private void OnOptionChanged(object? sender, OptionChangedEventArgs e)
{
if (e.Option.Equals(LspOptionsStorage.LspEnableReferencesCodeLens) ||
e.Option.Equals(LspOptionsStorage.LspEnableTestsCodeLens))
if (e.HasOption(static option => option.Equals(LspOptionsStorage.LspEnableReferencesCodeLens) || option.Equals(LspOptionsStorage.LspEnableTestsCodeLens)))
{
EnqueueRefreshNotification(documentUri: null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -84,34 +85,28 @@ private async Task RefreshOptionsAsync(CancellationToken cancellationToken)
RoslynDebug.Assert(configurationsFromClient.Length == SupportedOptions.Sum(option => option is IPerLanguageValuedOption ? 2 : 1));

// LSP ensures the order of result from client should match the order we sent from server.
var optionsToUpdate = new ArrayBuilder<KeyValuePair<OptionKey2, object?>>();

for (var i = 0; i < configurationsFromClient.Length; i++)
{
var valueFromClient = configurationsFromClient[i];
var (option, languageName) = _optionsAndLanguageNamesToRefresh[i];

// If option doesn't exist in the client, don't try to update the option.
if (!string.IsNullOrEmpty(valueFromClient))
SetOption(option, valueFromClient, languageName);
}
}

private void SetOption(IOption2 option, string valueFromClient, string? languageName = null)
{
if (option.Definition.Serializer.TryParse(valueFromClient, out var result))
{
if (option is IPerLanguageValuedOption && languageName != null)
{
_globalOptionService.SetGlobalOption(new OptionKey2(option, language: languageName), result);
}
else
{
RoslynDebug.Assert(languageName == null);
_globalOptionService.SetGlobalOption(new OptionKey2(option, language: null), result);
if (option.Definition.Serializer.TryParse(valueFromClient, out var parsedValue))
{
optionsToUpdate.Add(KeyValuePairUtil.Create(new OptionKey2(option, language: languageName), parsedValue));
}
else
{
_lspLogger.LogWarning($"Failed to parse '{valueFromClient}' to type: '{option.Type.Name}'. '{option.Name}' would not be updated.");
}
}
}
else
{
_lspLogger.LogWarning($"Failed to parse {valueFromClient} to type: {option.Type.Name}. {option.Name} would not be updated.");
}

_globalOptionService.SetGlobalOptions(optionsToUpdate.ToImmutable());
}

private async Task<ImmutableArray<string?>> GetConfigurationsAsync(CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,19 @@ public override void Dispose()

private void OnOptionChanged(object? sender, OptionChangedEventArgs e)
{
if (e.Option.Equals(InlineHintsOptionsStorage.EnabledForParameters) ||
e.Option.Equals(InlineHintsOptionsStorage.ForIndexerParameters) ||
e.Option.Equals(InlineHintsOptionsStorage.ForLiteralParameters) ||
e.Option.Equals(InlineHintsOptionsStorage.ForOtherParameters) ||
e.Option.Equals(InlineHintsOptionsStorage.ForObjectCreationParameters) ||
e.Option.Equals(InlineHintsOptionsStorage.SuppressForParametersThatDifferOnlyBySuffix) ||
e.Option.Equals(InlineHintsOptionsStorage.SuppressForParametersThatMatchArgumentName) ||
e.Option.Equals(InlineHintsOptionsStorage.SuppressForParametersThatMatchMethodIntent) ||
e.Option.Equals(InlineHintsOptionsStorage.EnabledForTypes) ||
e.Option.Equals(InlineHintsOptionsStorage.ForImplicitVariableTypes) ||
e.Option.Equals(InlineHintsOptionsStorage.ForLambdaParameterTypes) ||
e.Option.Equals(InlineHintsOptionsStorage.ForImplicitObjectCreation))
if (e.HasOption(static option =>
option.Equals(InlineHintsOptionsStorage.EnabledForParameters) ||
option.Equals(InlineHintsOptionsStorage.ForIndexerParameters) ||
option.Equals(InlineHintsOptionsStorage.ForLiteralParameters) ||
option.Equals(InlineHintsOptionsStorage.ForOtherParameters) ||
option.Equals(InlineHintsOptionsStorage.ForObjectCreationParameters) ||
option.Equals(InlineHintsOptionsStorage.SuppressForParametersThatDifferOnlyBySuffix) ||
option.Equals(InlineHintsOptionsStorage.SuppressForParametersThatMatchArgumentName) ||
option.Equals(InlineHintsOptionsStorage.SuppressForParametersThatMatchMethodIntent) ||
option.Equals(InlineHintsOptionsStorage.EnabledForTypes) ||
option.Equals(InlineHintsOptionsStorage.ForImplicitVariableTypes) ||
option.Equals(InlineHintsOptionsStorage.ForLambdaParameterTypes) ||
option.Equals(InlineHintsOptionsStorage.ForImplicitObjectCreation)))
{
EnqueueRefreshNotification(documentUri: null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,12 @@ protected override ITaggerEventSource CreateEventSource(ITextView textView, ITex
// Note: Also generate tags when InheritanceMarginOptions.InheritanceMarginCombinedWithIndicatorMargin is changed,
// because we want to refresh the glyphs in indicator margin.
return TaggerEventSources.Compose(
TaggerEventSources.OnWorkspaceChanged(subjectBuffer, AsyncListener),
TaggerEventSources.OnViewSpanChanged(ThreadingContext, textView),
TaggerEventSources.OnDocumentActiveContextChanged(subjectBuffer),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InheritanceMarginOptionsStorage.ShowInheritanceMargin),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, InheritanceMarginOptionsStorage.InheritanceMarginCombinedWithIndicatorMargin));
TaggerEventSources.OnWorkspaceChanged(subjectBuffer, AsyncListener),
TaggerEventSources.OnViewSpanChanged(ThreadingContext, textView),
TaggerEventSources.OnDocumentActiveContextChanged(subjectBuffer),
TaggerEventSources.OnGlobalOptionChanged(GlobalOptions, static option =>
option.Equals(InheritanceMarginOptionsStorage.ShowInheritanceMargin) ||
option.Equals(InheritanceMarginOptionsStorage.InheritanceMarginCombinedWithIndicatorMargin)));
}

protected override async Task ProduceTagsAsync(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,9 @@ private void OnLayoutChanged(object sender, TextViewLayoutChangedEventArgs e)

private void OnGlobalOptionChanged(object sender, OptionChangedEventArgs e)
{
if (e.Option.Equals(InheritanceMarginOptionsStorage.ShowInheritanceMargin) ||
e.Option.Equals(InheritanceMarginOptionsStorage.InheritanceMarginCombinedWithIndicatorMargin))
if (e.HasOption(option =>
option.Equals(InheritanceMarginOptionsStorage.ShowInheritanceMargin) ||
option.Equals(InheritanceMarginOptionsStorage.InheritanceMarginCombinedWithIndicatorMargin)))
{
UpdateMarginVisibility();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,10 @@ private void SetupView(IVsTextView view)

private void GlobalOptionChanged(object sender, OptionChangedEventArgs e)
{
if (e.Language != _languageService.RoslynLanguageName ||
e.Option != NavigationBarViewOptionsStorage.ShowNavigationBar)
if (e.ChangedOptions.Any(item => item.key.Language == _languageService.RoslynLanguageName && item.key.Option.Equals(NavigationBarViewOptionsStorage.ShowNavigationBar)))
{
return;
AddOrRemoveDropdown();
}

AddOrRemoveDropdown();
}

private void AddOrRemoveDropdown()
Expand Down
Loading
Loading