diff --git a/src/EditorFeatures/Core.Wpf/InlineRename/InlineRenameExperimentationOptions.cs b/src/EditorFeatures/Core.Wpf/InlineRename/InlineRenameExperimentationOptions.cs index 6db2688d26286..18437f5b6550d 100644 --- a/src/EditorFeatures/Core.Wpf/InlineRename/InlineRenameExperimentationOptions.cs +++ b/src/EditorFeatures/Core.Wpf/InlineRename/InlineRenameExperimentationOptions.cs @@ -8,7 +8,7 @@ namespace Microsoft.CodeAnalysis.Editor.InlineRename { internal sealed class InlineRenameExperimentationOptions { - public static readonly Option UseInlineAdornment = new( + public static readonly Option2 UseInlineAdornment = new( feature: "InlineRenameExperimentation", name: "UseInlineAdornment", defaultValue: false, diff --git a/src/EditorFeatures/Core/Logging/FunctionIdOptions.cs b/src/EditorFeatures/Core/Logging/FunctionIdOptions.cs index 6deb30b927425..e1e98531b9749 100644 --- a/src/EditorFeatures/Core/Logging/FunctionIdOptions.cs +++ b/src/EditorFeatures/Core/Logging/FunctionIdOptions.cs @@ -7,6 +7,7 @@ using System.Collections.Concurrent; using Microsoft.CodeAnalysis.Options; using Roslyn.Utilities; +using System.Collections.Generic; namespace Microsoft.CodeAnalysis.Internal.Log { @@ -25,13 +26,18 @@ private static Option2 CreateOption(FunctionId id) storageLocation: new LocalUserProfileStorageLocation(@"Roslyn\Internal\Performance\FunctionId\" + name)); } + private static IEnumerable GetFunctionIds() + => Enum.GetValues(typeof(FunctionId)).Cast(); + + public static IEnumerable GetOptions() + => GetFunctionIds().Select(GetOption); + public static Option2 GetOption(FunctionId id) => s_options.GetOrAdd(id, s_optionCreator); public static Func CreateFunctionIsEnabledPredicate(IGlobalOptionService globalOptions) { - var functionIds = Enum.GetValues(typeof(FunctionId)).Cast(); - var functionIdOptions = functionIds.ToDictionary(id => id, id => globalOptions.GetOption(GetOption(id))); + var functionIdOptions = GetFunctionIds().ToDictionary(id => id, id => globalOptions.GetOption(GetOption(id))); return functionId => functionIdOptions[functionId]; } } diff --git a/src/EditorFeatures/Core/Options/NavigationBarViewOptions.cs b/src/EditorFeatures/Core/Options/NavigationBarViewOptions.cs index b0f41b0ab1f37..cde4d9cbf4e2e 100644 --- a/src/EditorFeatures/Core/Options/NavigationBarViewOptions.cs +++ b/src/EditorFeatures/Core/Options/NavigationBarViewOptions.cs @@ -15,6 +15,6 @@ internal sealed class NavigationBarViewOptions { private const string FeatureName = "NavigationBarOptions"; - public static readonly PerLanguageOption ShowNavigationBar = new(FeatureName, nameof(ShowNavigationBar), defaultValue: true); + public static readonly PerLanguageOption2 ShowNavigationBar = new(FeatureName, "ShowNavigationBar", defaultValue: true); } } diff --git a/src/EditorFeatures/Test/Workspaces/ProjectCacheHostServiceFactoryTests.cs b/src/EditorFeatures/Test/Workspaces/ProjectCacheHostServiceFactoryTests.cs index da26fe720287a..794880a8e5f17 100644 --- a/src/EditorFeatures/Test/Workspaces/ProjectCacheHostServiceFactoryTests.cs +++ b/src/EditorFeatures/Test/Workspaces/ProjectCacheHostServiceFactoryTests.cs @@ -306,7 +306,7 @@ public override TWorkspaceService GetService() private sealed class MockOptionService : ILegacyWorkspaceOptionService { public IGlobalOptionService GlobalOptions { get; } = - new GlobalOptionService(workspaceThreadingService: null, ImmutableArray>.Empty, ImmutableArray>.Empty); + new GlobalOptionService(workspaceThreadingService: null, ImmutableArray>.Empty); public void RegisterWorkspace(Workspace workspace) { diff --git a/src/Features/Core/Portable/Diagnostics/AnalyzerConfigOptionSet+AnalyzerConfigOptionsImpl.cs b/src/Features/Core/Portable/Diagnostics/AnalyzerConfigOptionSet+AnalyzerConfigOptionsImpl.cs deleted file mode 100644 index 19a21b395b96f..0000000000000 --- a/src/Features/Core/Portable/Diagnostics/AnalyzerConfigOptionSet+AnalyzerConfigOptionsImpl.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// 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.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using Microsoft.CodeAnalysis.PooledObjects; - -namespace Microsoft.CodeAnalysis.Diagnostics -{ - internal sealed partial class AnalyzerConfigOptionSet - { - private sealed class AnalyzerConfigOptionsImpl : AnalyzerConfigOptions - { - private readonly AnalyzerConfigOptions _options; - private readonly AnalyzerConfigOptions _fallbackOptions; - - public AnalyzerConfigOptionsImpl(AnalyzerConfigOptions options, AnalyzerConfigOptions fallbackOptions) - { - _options = options; - _fallbackOptions = fallbackOptions; - } - - public override bool TryGetValue(string key, [NotNullWhen(true)] out string? value) - { - if (_options.TryGetValue(key, out value)) - { - return true; - } - - return _fallbackOptions.TryGetValue(key, out value); - } - - public override IEnumerable Keys - => _options.Keys.Concat(_fallbackOptions.Keys.Where(key => !_options.TryGetValue(key, out _))); - } - } -} diff --git a/src/Features/Core/Portable/Diagnostics/AnalyzerConfigOptionSet.cs b/src/Features/Core/Portable/Diagnostics/AnalyzerConfigOptionSet.cs deleted file mode 100644 index f48419815e699..0000000000000 --- a/src/Features/Core/Portable/Diagnostics/AnalyzerConfigOptionSet.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// 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 Microsoft.CodeAnalysis.Options; - -namespace Microsoft.CodeAnalysis.Diagnostics -{ - /// - /// This class proxies requests for option values first to the then to a backup if provided. - /// - internal sealed partial class AnalyzerConfigOptionSet : OptionSet - { - private readonly AnalyzerConfigOptions _analyzerConfigOptions; - private readonly OptionSet? _optionSet; - - public AnalyzerConfigOptionSet(AnalyzerConfigOptions analyzerConfigOptions, OptionSet? optionSet) - { - _analyzerConfigOptions = analyzerConfigOptions; - _optionSet = optionSet; - } - - private protected override object GetOptionCore(OptionKey optionKey) - { - // First try to find the option from the .editorconfig options parsed by the compiler. - if (_analyzerConfigOptions.TryGetEditorConfigOption(optionKey.Option, out var value)) - { - return value; - } - - // Fallback to looking for option from the document's optionset if unsuccessful. - return _optionSet?.GetOption(optionKey) ?? optionKey.Option.DefaultValue!; - } - - public override OptionSet WithChangedOption(OptionKey optionAndLanguage, object? value) - => throw new NotImplementedException(); - - private protected override AnalyzerConfigOptions CreateAnalyzerConfigOptions(ILegacyWorkspaceOptionService optionService, string? language) - { - if (_optionSet is null) - { - return _analyzerConfigOptions; - } - - return new AnalyzerConfigOptionsImpl(_analyzerConfigOptions, _optionSet.AsAnalyzerConfigOptions(optionService, language)); - } - - internal override IEnumerable GetChangedOptions(OptionSet optionSet) - => throw new NotImplementedException(); - } -} diff --git a/src/VisualStudio/Core/Impl/Options/AbstractOptionPage.cs b/src/VisualStudio/Core/Impl/Options/AbstractOptionPage.cs index 6467604de0811..9c8c08f06740d 100644 --- a/src/VisualStudio/Core/Impl/Options/AbstractOptionPage.cs +++ b/src/VisualStudio/Core/Impl/Options/AbstractOptionPage.cs @@ -5,6 +5,7 @@ #nullable disable using System; +using System.Linq; using Microsoft.CodeAnalysis.Options; using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Shell; @@ -31,7 +32,7 @@ private void EnsureOptionPageCreated() var componentModel = (IComponentModel)this.Site.GetService(typeof(SComponentModel)); var workspace = componentModel.GetService(); s_optionService = workspace.Services.GetService(); - s_optionStore = new OptionStore(new SolutionOptionSet(s_optionService), s_optionService.GlobalOptions.GetRegisteredOptions()); + s_optionStore = new OptionStore(new SolutionOptionSet(s_optionService), Enumerable.Empty()); } if (pageControl == null) @@ -60,7 +61,6 @@ protected override void OnActivate(System.ComponentModel.CancelEventArgs e) { // Reset the option store to the current state of the options. s_optionStore.SetOptions(new SolutionOptionSet(s_optionService)); - s_optionStore.SetRegisteredOptions(s_optionService.GlobalOptions.GetRegisteredOptions()); s_needsToUpdateOptionStore = false; } diff --git a/src/VisualStudio/Core/Impl/Options/AbstractOptionPreviewViewModel.cs b/src/VisualStudio/Core/Impl/Options/AbstractOptionPreviewViewModel.cs index 13119f6bab72c..f00d6cefbec37 100644 --- a/src/VisualStudio/Core/Impl/Options/AbstractOptionPreviewViewModel.cs +++ b/src/VisualStudio/Core/Impl/Options/AbstractOptionPreviewViewModel.cs @@ -139,7 +139,7 @@ public void UpdatePreview(string text) var document = project.AddDocument("document", SourceText.From(text, Encoding.UTF8)); var fallbackFormattingOptions = _globalOptions.GetSyntaxFormattingOptions(document.Project.LanguageServices); - var optionService = workspace.Services.GetRequiredService(); + var optionService = workspace.Services.GetRequiredService(); var configOptions = OptionStore.GetOptions().AsAnalyzerConfigOptions(optionService, document.Project.Language); var formattingService = document.GetRequiredLanguageService(); var formattingOptions = formattingService.GetFormattingOptions(configOptions, fallbackFormattingOptions); diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/StateResetInProcess.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/StateResetInProcess.cs index acd4f312b568e..5b3c3188773a7 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/StateResetInProcess.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/StateResetInProcess.cs @@ -44,26 +44,20 @@ public async Task ResetGlobalOptionsAsync(CancellationToken cancellationToken) configurationService.Clear(); var globalOptions = await GetComponentModelServiceAsync(cancellationToken); - ResetOption2(globalOptions, MetadataAsSourceOptionsStorage.NavigateToDecompiledSources); - ResetOption2(globalOptions, WorkspaceConfigurationOptionsStorage.EnableOpeningSourceGeneratedFilesInWorkspace); + ResetOption(globalOptions, MetadataAsSourceOptionsStorage.NavigateToDecompiledSources); + ResetOption(globalOptions, WorkspaceConfigurationOptionsStorage.EnableOpeningSourceGeneratedFilesInWorkspace); ResetPerLanguageOption(globalOptions, NavigationBarViewOptions.ShowNavigationBar); - ResetPerLanguageOption2(globalOptions, VisualStudioNavigationOptions.NavigateToObjectBrowser); - ResetPerLanguageOption2(globalOptions, FeatureOnOffOptions.AddImportsOnPaste); - ResetPerLanguageOption2(globalOptions, FeatureOnOffOptions.PrettyListing); - ResetPerLanguageOption2(globalOptions, CompletionViewOptions.EnableArgumentCompletionSnippets); + ResetPerLanguageOption(globalOptions, VisualStudioNavigationOptions.NavigateToObjectBrowser); + ResetPerLanguageOption(globalOptions, FeatureOnOffOptions.AddImportsOnPaste); + ResetPerLanguageOption(globalOptions, FeatureOnOffOptions.PrettyListing); + ResetPerLanguageOption(globalOptions, CompletionViewOptions.EnableArgumentCompletionSnippets); - static void ResetOption2(IGlobalOptionService globalOptions, Option2 option) + static void ResetOption(IGlobalOptionService globalOptions, Option2 option) { globalOptions.SetGlobalOption(new OptionKey(option, language: null), option.DefaultValue); } - static void ResetPerLanguageOption(IGlobalOptionService globalOptions, PerLanguageOption option) - { - globalOptions.SetGlobalOption(new OptionKey(option, LanguageNames.CSharp), option.DefaultValue); - globalOptions.SetGlobalOption(new OptionKey(option, LanguageNames.VisualBasic), option.DefaultValue); - } - - static void ResetPerLanguageOption2(IGlobalOptionService globalOptions, PerLanguageOption2 option) + static void ResetPerLanguageOption(IGlobalOptionService globalOptions, PerLanguageOption2 option) { globalOptions.SetGlobalOption(new OptionKey(option, LanguageNames.CSharp), option.DefaultValue); globalOptions.SetGlobalOption(new OptionKey(option, LanguageNames.VisualBasic), option.DefaultValue); diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalFeaturesOnOffPage.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/ForceLowMemoryModePage.cs similarity index 71% rename from src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalFeaturesOnOffPage.cs rename to src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/ForceLowMemoryModePage.cs index 1495f6be0d8cd..ca94828e18dd7 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalFeaturesOnOffPage.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/ForceLowMemoryModePage.cs @@ -10,6 +10,7 @@ using Microsoft.CodeAnalysis.Editor.Shared.Options; using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.NavigateTo; +using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Remote; using Microsoft.CodeAnalysis.SymbolSearch; using Microsoft.VisualStudio.LanguageServices; @@ -18,17 +19,15 @@ namespace Roslyn.VisualStudio.DiagnosticsWindow.OptionsPages { [Guid(Guids.RoslynOptionPageFeatureManagerFeaturesIdString)] - internal class InternalFeaturesOnOffPage : AbstractOptionPage + internal class ForceLowMemoryModePage : AbstractOptionPage { protected override AbstractOptionPageControl CreateOptionPage(IServiceProvider serviceProvider, OptionStore optionStore) - { - return new InternalFeaturesOptionsControl(nameof(InternalFeatureOnOffOptions), optionStore); - } + => new Control(optionStore); - internal class InternalFeaturesOptionsControl : InternalOptionsControl + internal sealed class Control : InternalOptionsControl { - public InternalFeaturesOptionsControl(string featureOptionName, OptionStore optionStore) - : base(featureOptionName, optionStore) + public Control(OptionStore optionStore) + : base(Array.Empty(), optionStore) { } @@ -48,14 +47,6 @@ protected override void AddOptions(Panel panel) lowMemoryGroup.Children.Add(new TextBlock { Text = "megabytes of extra memory in devenv.exe" }); panel.Children.Add(lowMemoryGroup); - - // add OOP feature options - var oopFeatureGroup = new StackPanel(); - - panel.Children.Add(oopFeatureGroup); - - // and add the rest of the options - base.AddOptions(panel); } } } diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalComponentsOnOffPage.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalComponentsOnOffPage.cs deleted file mode 100644 index dc5734a68e86e..0000000000000 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalComponentsOnOffPage.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#nullable disable - -using System; -using System.Runtime.InteropServices; -using Microsoft.CodeAnalysis.Editor.Shared.Options; - -namespace Microsoft.VisualStudio.LanguageServices.Implementation.Options -{ - [Guid(Guids.RoslynOptionPageFeatureManagerComponentsIdString)] - internal class InternalComponentsOnOffPage : AbstractOptionPage - { - protected override AbstractOptionPageControl CreateOptionPage(IServiceProvider serviceProvider, OptionStore optionStore) - { - return new InternalOptionsControl(nameof(EditorComponentOnOffOptions), optionStore); - } - } -} diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalOptionsControl.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalOptionsControl.cs index 68050d3e4eaec..9ed2ae7304328 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalOptionsControl.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/InternalOptionsControl.cs @@ -5,6 +5,7 @@ #nullable disable using System; +using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; @@ -16,12 +17,12 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Options { internal partial class InternalOptionsControl : AbstractOptionPageControl { - private readonly string _featureOptionName; + private readonly IEnumerable _options; - public InternalOptionsControl(string featureOptionName, OptionStore optionStore) + public InternalOptionsControl(IEnumerable options, OptionStore optionStore) : base(optionStore) { - _featureOptionName = featureOptionName; + _options = options; // options var optionsPanel = new StackPanel(); @@ -108,7 +109,7 @@ public InternalOptionsControl(string featureOptionName, OptionStore optionStore) protected virtual void AddOptions(Panel panel) { - foreach (var option in OptionStore.GetRegisteredOptions().Where(o => o.Feature == _featureOptionName).OrderBy(o => o.Name)) + foreach (var option in _options) { if (!option.IsPerLanguage) { diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceFunctionIdPage.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceFunctionIdPage.cs index de0071e4e78fd..3bb9b3c6f84ef 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceFunctionIdPage.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceFunctionIdPage.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#nullable disable - using System; using System.Runtime.InteropServices; using Microsoft.CodeAnalysis.Internal.Log; @@ -17,7 +15,7 @@ internal class PerformanceFunctionIdPage : AbstractOptionPage { protected override AbstractOptionPageControl CreateOptionPage(IServiceProvider serviceProvider, OptionStore optionStore) { - return new InternalOptionsControl(nameof(FunctionIdOptions), optionStore); + return new InternalOptionsControl(FunctionIdOptions.GetOptions(), optionStore); } } } diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceLoggersPage.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceLoggersPage.cs index 43f0d69544012..524ade4809d2e 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceLoggersPage.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/OptionPages/PerformanceLoggersPage.cs @@ -43,7 +43,7 @@ protected override AbstractOptionPageControl CreateOptionPage(IServiceProvider s _workspaceServices = workspace.Services; } - return new InternalOptionsControl(nameof(LoggerOptions), optionStore); + return new InternalOptionsControl(FunctionIdOptions.GetOptions(), optionStore); } protected override void OnApply(PageApplyEventArgs e) diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/PackageRegistration.pkgdef b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/PackageRegistration.pkgdef index 238576f313738..70a262f84bc83 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/PackageRegistration.pkgdef +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/PackageRegistration.pkgdef @@ -11,20 +11,9 @@ @="#0" "Package"="{49e24138-9ee3-49e0-8ede-6b39f49303bf}" -[$RootKey$\ToolsOptionsPages\Roslyn\FeatureManager\Components] -@="#0" -"Package"="{49e24138-9ee3-49e0-8ede-6b39f49303bf}" -"Page"="{6f738951-348c-4816-9ba4-f60d92d3e98e}" - [$RootKey$\AutomationProperties\Roslyn\FeatureManager] "Package"="{49e24138-9ee3-49e0-8ede-6b39f49303bf}" -[$RootKey$\AutomationProperties\Roslyn\FeatureManager\Components] -"Package"="{49e24138-9ee3-49e0-8ede-6b39f49303bf}" - -[$RootKey$\AutomationProperties\Roslyn\FeatureManager\Components] -"Name"="Roslyn\FeatureManager.Components" - [$RootKey$\ToolsOptionsPages\Roslyn\FeatureManager] @="#0" "Package"="{49e24138-9ee3-49e0-8ede-6b39f49303bf}" diff --git a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs index 97f95e17c3496..023a601334571 100644 --- a/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs +++ b/src/VisualStudio/VisualStudioDiagnosticsToolWindow/VisualStudioDiagnosticsWindowPackage.cs @@ -28,8 +28,7 @@ namespace Roslyn.VisualStudio.DiagnosticsWindow // The option page configuration is duplicated in PackageRegistration.pkgdef. // These attributes specify the menu structure to be used in Tools | Options. These are not // localized because they are for internal use only. - [ProvideOptionPage(typeof(InternalFeaturesOnOffPage), @"Roslyn\FeatureManager", @"Features", categoryResourceID: 0, pageNameResourceID: 0, supportsAutomation: true, SupportsProfiles = false)] - [ProvideOptionPage(typeof(InternalComponentsOnOffPage), @"Roslyn\FeatureManager", @"Components", categoryResourceID: 0, pageNameResourceID: 0, supportsAutomation: true, SupportsProfiles = false)] + [ProvideOptionPage(typeof(ForceLowMemoryModePage), @"Roslyn\FeatureManager", @"Features", categoryResourceID: 0, pageNameResourceID: 0, supportsAutomation: true, SupportsProfiles = false)] [ProvideOptionPage(typeof(PerformanceFunctionIdPage), @"Roslyn\Performance", @"FunctionId", categoryResourceID: 0, pageNameResourceID: 0, supportsAutomation: true, SupportsProfiles = false)] [ProvideOptionPage(typeof(PerformanceLoggersPage), @"Roslyn\Performance", @"Loggers", categoryResourceID: 0, pageNameResourceID: 0, supportsAutomation: true, SupportsProfiles = false)] [ProvideToolWindow(typeof(DiagnosticsWindow))] diff --git a/src/Workspaces/Core/Portable/Formatting/Formatter.cs b/src/Workspaces/Core/Portable/Formatting/Formatter.cs index e2e7250932a9d..d3c29a9188443 100644 --- a/src/Workspaces/Core/Portable/Formatting/Formatter.cs +++ b/src/Workspaces/Core/Portable/Formatting/Formatter.cs @@ -319,7 +319,7 @@ internal static IList GetFormattedTextChanges(SyntaxNode node, IEnum internal static SyntaxFormattingOptions GetFormattingOptions(Workspace workspace, OptionSet? optionSet, string language) { var syntaxFormattingService = workspace.Services.GetRequiredLanguageService(language); - var optionService = workspace.Services.GetRequiredService(); + var optionService = workspace.Services.GetRequiredService(); var configOptionSet = (optionSet ?? workspace.CurrentSolution.Options).AsAnalyzerConfigOptions(optionService, language); return syntaxFormattingService.GetFormattingOptions(configOptionSet, fallbackOptions: null); } @@ -327,7 +327,7 @@ internal static SyntaxFormattingOptions GetFormattingOptions(Workspace workspace #pragma warning disable RS0030 // Do not used banned APIs (backwards compatibility) internal static async ValueTask<(SyntaxFormattingOptions? Syntax, LineFormattingOptions Line)> GetFormattingOptionsAsync(Document document, OptionSet? optionSet, CancellationToken cancellationToken) { - var optionService = document.Project.Solution.Workspace.Services.GetRequiredService(); + var optionService = document.Project.Solution.Workspace.Services.GetRequiredService(); var configOptionSet = (optionSet ?? await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false)).AsAnalyzerConfigOptions(optionService, document.Project.Language); LineFormattingOptions lineFormattingOptions; @@ -370,7 +370,7 @@ public static async Task OrganizeImportsAsync(Document document, Cance #pragma warning disable RS0030 // Do not used banned APIs (backwards compatibility) internal static async ValueTask GetOrganizeImportsOptionsAsync(Document document, CancellationToken cancellationToken) { - var optionService = document.Project.Solution.Workspace.Services.GetRequiredService(); + var optionService = document.Project.Solution.Workspace.Services.GetRequiredService(); var configOptionSet = (await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false)).AsAnalyzerConfigOptions(optionService, document.Project.Language); return configOptionSet.GetOrganizeImportsOptions(fallbackOptions: null); } diff --git a/src/Workspaces/Core/Portable/Options/DocumentOptionSet.cs b/src/Workspaces/Core/Portable/Options/DocumentOptionSet.cs index ea8d8f8dd2247..b9968976441b8 100644 --- a/src/Workspaces/Core/Portable/Options/DocumentOptionSet.cs +++ b/src/Workspaces/Core/Portable/Options/DocumentOptionSet.cs @@ -108,7 +108,7 @@ public DocumentOptionSet WithChangedOption(PerLanguageOption option, T val internal DocumentOptionSet WithChangedOption(PerLanguageOption2 option, T value) => (DocumentOptionSet)WithChangedOption(option, _language, value); - private protected override AnalyzerConfigOptions CreateAnalyzerConfigOptions(ILegacyWorkspaceOptionService optionService, string? language) + private protected override AnalyzerConfigOptions CreateAnalyzerConfigOptions(IEditorConfigOptionMappingService optionService, string? language) { Debug.Assert((language ?? _language) == _language, $"Use of a {nameof(DocumentOptionSet)} is not expected to differ from the language it was constructed with."); return base.CreateAnalyzerConfigOptions(optionService, language ?? _language); diff --git a/src/Workspaces/Core/Portable/Options/EditorConfigOptionMappingService.cs b/src/Workspaces/Core/Portable/Options/EditorConfigOptionMappingService.cs new file mode 100644 index 0000000000000..33731b68375eb --- /dev/null +++ b/src/Workspaces/Core/Portable/Options/EditorConfigOptionMappingService.cs @@ -0,0 +1,166 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Collections.Immutable; +using System.Composition; +using System.Diagnostics.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Options.Providers; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.Options +{ + [ExportWorkspaceService(typeof(IEditorConfigOptionMappingService)), Shared] + internal sealed class EditorConfigOptionMappingService : IEditorConfigOptionMappingService + { + private static readonly ImmutableDictionary s_emptyEditorConfigKeysToOptions + = ImmutableDictionary.Create(AnalyzerConfigOptions.KeyComparer); + + private ImmutableDictionary _neutralEditorConfigKeysToOptions = s_emptyEditorConfigKeysToOptions; + private ImmutableDictionary _csharpEditorConfigKeysToOptions = s_emptyEditorConfigKeysToOptions; + private ImmutableDictionary _visualBasicEditorConfigKeysToOptions = s_emptyEditorConfigKeysToOptions; + + private readonly ImmutableDictionary>> _serializableOptionsByLanguage; + + [ImportingConstructor] + [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] + public EditorConfigOptionMappingService( + [ImportMany] IEnumerable> optionProviders) + { + _serializableOptionsByLanguage = CreateLazySerializableOptionsByLanguage(optionProviders); + } + + private static ImmutableDictionary>> CreateLazySerializableOptionsByLanguage(IEnumerable> optionProviders) + { + var builder = ImmutableDictionary.CreateBuilder>>(); + + foreach (var (language, lazyProvidersAndMetadata) in optionProviders.ToPerLanguageMap()) + { + builder.Add(language, new Lazy>(() => ComputeSerializableOptionsFromProviders(lazyProvidersAndMetadata))); + } + + return builder.ToImmutable(); + + // Local functions + static ImmutableHashSet ComputeSerializableOptionsFromProviders(ImmutableArray> lazyProvidersAndMetadata) + { + var builder = ImmutableHashSet.CreateBuilder(); + + foreach (var lazyProviderAndMetadata in lazyProvidersAndMetadata) + { + var provider = lazyProviderAndMetadata.Value; + if (!IsSolutionOptionProvider(provider)) + { + continue; + } + + builder.AddRange(provider.Options); + } + + return builder.ToImmutable(); + } + } + + // We only consider the options defined in the the DefaultAssemblies (Workspaces and Features) as serializable. + // This is due to the fact that other layers above are VS specific and do not execute in OOP. + internal static bool IsSolutionOptionProvider(IOptionProvider provider) + => MefHostServices.IsDefaultAssembly(provider.GetType().Assembly); + + public bool TryMapEditorConfigKeyToOption(string key, string? language, [NotNullWhen(true)] out IEditorConfigStorageLocation2? storageLocation, out OptionKey optionKey) + { + var temporaryOptions = s_emptyEditorConfigKeysToOptions; + ref var editorConfigToOptionsStorage = ref temporaryOptions; + switch (language) + { + case LanguageNames.CSharp: + editorConfigToOptionsStorage = ref _csharpEditorConfigKeysToOptions!; + break; + + case LanguageNames.VisualBasic: + editorConfigToOptionsStorage = ref _visualBasicEditorConfigKeysToOptions!; + break; + + case null: + case "": + editorConfigToOptionsStorage = ref _neutralEditorConfigKeysToOptions!; + break; + } + + var (option, storage) = ImmutableInterlocked.GetOrAdd( + ref editorConfigToOptionsStorage, + key, + (key, arg) => MapToOptionIgnorePerLanguage(arg.self, key, arg.language), + (self: this, language)); + + if (option is object) + { + RoslynDebug.AssertNotNull(storage); + storageLocation = storage; + optionKey = option.IsPerLanguage ? new OptionKey(option, language) : new OptionKey(option); + return true; + } + + storageLocation = null; + optionKey = default; + return false; + + // Local function + static (IOption? option, IEditorConfigStorageLocation2? storageLocation) MapToOptionIgnorePerLanguage(EditorConfigOptionMappingService service, string key, string? language) + { + // Use GetRegisteredSerializableOptions instead of GetRegisteredOptions to avoid loading assemblies for + // inactive languages. + foreach (var option in service.GetRegisteredSerializableOptions(ImmutableHashSet.Create(language ?? ""))) + { + foreach (var storage in option.StorageLocations) + { + if (storage is not IEditorConfigStorageLocation2 editorConfigStorage) + continue; + + if (!AnalyzerConfigOptions.KeyComparer.Equals(key, editorConfigStorage.KeyName)) + continue; + + return (option, editorConfigStorage); + } + } + + return (null, null); + } + } + + public ImmutableHashSet GetRegisteredSerializableOptions(ImmutableHashSet languages) + { + if (languages.IsEmpty) + { + return ImmutableHashSet.Empty; + } + + var builder = ImmutableHashSet.CreateBuilder(); + + // "string.Empty" for options from language agnostic option providers. + builder.AddRange(GetSerializableOptionsForLanguage(string.Empty)); + + foreach (var language in languages) + { + builder.AddRange(GetSerializableOptionsForLanguage(language)); + } + + return builder.ToImmutable(); + + // Local functions. + ImmutableHashSet GetSerializableOptionsForLanguage(string language) + { + if (_serializableOptionsByLanguage.TryGetValue(language, out var lazyOptions)) + { + return lazyOptions.Value; + } + + return ImmutableHashSet.Empty; + } + } + } +} diff --git a/src/Workspaces/Core/Portable/Options/GlobalOptionService.cs b/src/Workspaces/Core/Portable/Options/GlobalOptionService.cs index 630607de047d2..f76b3860aaa02 100644 --- a/src/Workspaces/Core/Portable/Options/GlobalOptionService.cs +++ b/src/Workspaces/Core/Portable/Options/GlobalOptionService.cs @@ -25,13 +25,8 @@ namespace Microsoft.CodeAnalysis.Options [Export(typeof(IGlobalOptionService)), Shared] internal sealed class GlobalOptionService : IGlobalOptionService { - private static readonly ImmutableDictionary s_emptyEditorConfigKeysToOptions - = ImmutableDictionary.Create(AnalyzerConfigOptions.KeyComparer); - private readonly IWorkspaceThreadingService? _workspaceThreadingService; - private readonly Lazy> _lazyAllOptions; private readonly ImmutableArray> _optionPersisterProviders; - private readonly ImmutableDictionary>> _serializableOptionsByLanguage; // access is interlocked private ImmutableArray _registeredWorkspaces; @@ -41,12 +36,6 @@ internal sealed class GlobalOptionService : IGlobalOptionService #region Guarded by _gate -#pragma warning disable IDE0044 // Add readonly modifier - https://github.com/dotnet/roslyn/issues/46785 - private ImmutableDictionary _neutralEditorConfigKeysToOptions = s_emptyEditorConfigKeysToOptions; - private ImmutableDictionary _csharpEditorConfigKeysToOptions = s_emptyEditorConfigKeysToOptions; - private ImmutableDictionary _visualBasicEditorConfigKeysToOptions = s_emptyEditorConfigKeysToOptions; -#pragma warning restore IDE0044 // Add readonly modifier - private ImmutableArray _lazyOptionPersisters; private ImmutableDictionary _currentValues; @@ -58,57 +47,18 @@ internal sealed class GlobalOptionService : IGlobalOptionService [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] public GlobalOptionService( [Import(AllowDefault = true)] IWorkspaceThreadingService? workspaceThreadingService, - [ImportMany] IEnumerable> optionProviders, [ImportMany] IEnumerable> optionPersisters) { _getOption = GetOption; _workspaceThreadingService = workspaceThreadingService; - _lazyAllOptions = new Lazy>(() => optionProviders.SelectMany(p => p.Value.Options).ToImmutableHashSet()); _optionPersisterProviders = optionPersisters.ToImmutableArray(); - _serializableOptionsByLanguage = CreateLazySerializableOptionsByLanguage(optionProviders); _registeredWorkspaces = ImmutableArray.Empty; _currentValues = ImmutableDictionary.Create(); _changedOptionKeys = ImmutableHashSet.Empty; } - private static ImmutableDictionary>> CreateLazySerializableOptionsByLanguage(IEnumerable> optionProviders) - { - var builder = ImmutableDictionary.CreateBuilder>>(); - - foreach (var (language, lazyProvidersAndMetadata) in optionProviders.ToPerLanguageMap()) - { - builder.Add(language, new Lazy>(() => ComputeSerializableOptionsFromProviders(lazyProvidersAndMetadata))); - } - - return builder.ToImmutable(); - - // Local functions - static ImmutableHashSet ComputeSerializableOptionsFromProviders(ImmutableArray> lazyProvidersAndMetadata) - { - var builder = ImmutableHashSet.CreateBuilder(); - - foreach (var lazyProviderAndMetadata in lazyProvidersAndMetadata) - { - var provider = lazyProviderAndMetadata.Value; - if (!IsSolutionOptionProvider(provider)) - { - continue; - } - - builder.AddRange(provider.Options); - } - - return builder.ToImmutable(); - } - } - - // We only consider the options defined in the the DefaultAssemblies (Workspaces and Features) as serializable. - // This is due to the fact that other layers above are VS specific and do not execute in OOP. - internal static bool IsSolutionOptionProvider(IOptionProvider provider) - => MefHostServices.IsDefaultAssembly(provider.GetType().Assembly); - private ImmutableArray GetOptionPersisters() { if (_lazyOptionPersisters.IsDefault) @@ -165,110 +115,9 @@ static async Task> GetOptionPersistersAsync( return optionKey.Option.DefaultValue; } - public IEnumerable GetRegisteredOptions() - => _lazyAllOptions.Value; - - public bool TryMapEditorConfigKeyToOption(string key, string? language, [NotNullWhen(true)] out IEditorConfigStorageLocation2? storageLocation, out OptionKey optionKey) - { - var temporaryOptions = s_emptyEditorConfigKeysToOptions; - ref var editorConfigToOptionsStorage = ref temporaryOptions; - switch (language) - { - case LanguageNames.CSharp: - editorConfigToOptionsStorage = ref _csharpEditorConfigKeysToOptions!; - break; - - case LanguageNames.VisualBasic: - editorConfigToOptionsStorage = ref _visualBasicEditorConfigKeysToOptions!; - break; - - case null: - case "": - editorConfigToOptionsStorage = ref _neutralEditorConfigKeysToOptions!; - break; - } - - var (option, storage) = ImmutableInterlocked.GetOrAdd( - ref editorConfigToOptionsStorage, - key, - (key, arg) => MapToOptionIgnorePerLanguage(arg.self, key, arg.language), - (self: this, language)); - - if (option is object) - { - RoslynDebug.AssertNotNull(storage); - storageLocation = storage; - optionKey = option.IsPerLanguage ? new OptionKey(option, language) : new OptionKey(option); - return true; - } - - storageLocation = null; - optionKey = default; - return false; - - // Local function - static (IOption? option, IEditorConfigStorageLocation2? storageLocation) MapToOptionIgnorePerLanguage(GlobalOptionService service, string key, string? language) - { - // Use GetRegisteredSerializableOptions instead of GetRegisteredOptions to avoid loading assemblies for - // inactive languages. - foreach (var option in service.GetRegisteredSerializableOptions(ImmutableHashSet.Create(language ?? ""))) - { - foreach (var storage in option.StorageLocations) - { - if (storage is not IEditorConfigStorageLocation2 editorConfigStorage) - continue; - - if (!AnalyzerConfigOptions.KeyComparer.Equals(key, editorConfigStorage.KeyName)) - continue; - - return (option, editorConfigStorage); - } - } - - return (null, null); - } - } - - public ImmutableHashSet GetRegisteredSerializableOptions(ImmutableHashSet languages) - { - if (languages.IsEmpty) - { - return ImmutableHashSet.Empty; - } - - var builder = ImmutableHashSet.CreateBuilder(); - - // "string.Empty" for options from language agnostic option providers. - builder.AddRange(GetSerializableOptionsForLanguage(string.Empty)); - - foreach (var language in languages) - { - builder.AddRange(GetSerializableOptionsForLanguage(language)); - } - - return builder.ToImmutable(); - - // Local functions. - ImmutableHashSet GetSerializableOptionsForLanguage(string language) - { - if (_serializableOptionsByLanguage.TryGetValue(language, out var lazyOptions)) - { - return lazyOptions.Value; - } - - return ImmutableHashSet.Empty; - } - } - - public T GetOption(Option option) - => OptionsHelpers.GetOption(option, _getOption); - public T GetOption(Option2 option) => OptionsHelpers.GetOption(option, _getOption); - public T GetOption(PerLanguageOption option, string? language) - => OptionsHelpers.GetOption(option, language, _getOption); - public T GetOption(PerLanguageOption2 option, string? language) => OptionsHelpers.GetOption(option, language, _getOption); diff --git a/src/Workspaces/Core/Portable/Options/IEditorConfigOptionMappingService.cs b/src/Workspaces/Core/Portable/Options/IEditorConfigOptionMappingService.cs new file mode 100644 index 0000000000000..2b8eeba2a66a8 --- /dev/null +++ b/src/Workspaces/Core/Portable/Options/IEditorConfigOptionMappingService.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Diagnostics.CodeAnalysis; +using Microsoft.CodeAnalysis.Host; + +namespace Microsoft.CodeAnalysis.Options +{ + internal interface IEditorConfigOptionMappingService : IWorkspaceService + { + /// + /// Map an .editorconfig key to a corresponding and + /// that can be used to read and write the value stored in an . + /// + /// The .editorconfig key. + /// The language to use for the , if the matching option has + /// set. + /// The for the key. + /// The for the key and language. + /// if a matching option was found; otherwise, . + bool TryMapEditorConfigKeyToOption(string key, string? language, [NotNullWhen(true)] out IEditorConfigStorageLocation2? storageLocation, out OptionKey optionKey); + } +} diff --git a/src/Workspaces/Core/Portable/Options/IGlobalOptionService.cs b/src/Workspaces/Core/Portable/Options/IGlobalOptionService.cs index b980dd27291f0..a677e06e681f0 100644 --- a/src/Workspaces/Core/Portable/Options/IGlobalOptionService.cs +++ b/src/Workspaces/Core/Portable/Options/IGlobalOptionService.cs @@ -21,21 +21,11 @@ namespace Microsoft.CodeAnalysis.Options /// internal interface IGlobalOptionService { - /// - /// Gets the current value of the specific option. - /// - T GetOption(Option option); - /// /// Gets the current value of the specific option. /// T GetOption(Option2 option); - /// - /// Gets the current value of the specific option. - /// - T GetOption(PerLanguageOption option, string? languageName); - /// /// Gets the current value of the specific option. /// @@ -74,28 +64,6 @@ internal interface IGlobalOptionService /// void SetGlobalOptions(ImmutableArray optionKeys, ImmutableArray values); - /// - /// Returns the set of all registered options. - /// - IEnumerable GetRegisteredOptions(); - - /// - /// Map an .editorconfig key to a corresponding and - /// that can be used to read and write the value stored in an . - /// - /// The .editorconfig key. - /// The language to use for the , if the matching option has - /// set. - /// The for the key. - /// The for the key and language. - /// if a matching option was found; otherwise, . - bool TryMapEditorConfigKeyToOption(string key, string? language, [NotNullWhen(true)] out IEditorConfigStorageLocation2? storageLocation, out OptionKey optionKey); - - /// - /// Returns the set of all registered serializable options applicable for the given . - /// - ImmutableHashSet GetRegisteredSerializableOptions(ImmutableHashSet languages); - event EventHandler? OptionChanged; /// diff --git a/src/Workspaces/Core/Portable/Options/OptionSet+AnalyzerConfigOptionsImpl.cs b/src/Workspaces/Core/Portable/Options/OptionSet+AnalyzerConfigOptionsImpl.cs index f139251731c33..521a7aea0e7a1 100644 --- a/src/Workspaces/Core/Portable/Options/OptionSet+AnalyzerConfigOptionsImpl.cs +++ b/src/Workspaces/Core/Portable/Options/OptionSet+AnalyzerConfigOptionsImpl.cs @@ -16,19 +16,19 @@ public abstract partial class OptionSet private sealed class AnalyzerConfigOptionsImpl : AnalyzerConfigOptions { private readonly OptionSet _optionSet; - private readonly ILegacyWorkspaceOptionService _optionService; + private readonly IEditorConfigOptionMappingService _optionMappingService; private readonly string? _language; - public AnalyzerConfigOptionsImpl(OptionSet optionSet, ILegacyWorkspaceOptionService optionService, string? language) + public AnalyzerConfigOptionsImpl(OptionSet optionSet, IEditorConfigOptionMappingService optionMappingService, string? language) { _optionSet = optionSet; - _optionService = optionService; + _optionMappingService = optionMappingService; _language = language; } public override bool TryGetValue(string key, [NotNullWhen(true)] out string? value) { - if (!_optionService.GlobalOptions.TryMapEditorConfigKeyToOption(key, _language, out var storageLocation, out var optionKey)) + if (!_optionMappingService.TryMapEditorConfigKeyToOption(key, _language, out var storageLocation, out var optionKey)) { // There are couple of reasons this assert might fire: // 1. Attempting to access an option which does not have an IEditorConfigStorageLocation. diff --git a/src/Workspaces/Core/Portable/Options/OptionSet.cs b/src/Workspaces/Core/Portable/Options/OptionSet.cs index 9bdd26e705e82..6c5944e49ceac 100644 --- a/src/Workspaces/Core/Portable/Options/OptionSet.cs +++ b/src/Workspaces/Core/Portable/Options/OptionSet.cs @@ -112,18 +112,18 @@ public OptionSet WithChangedOption(PerLanguageOption option, string? langu internal OptionSet WithChangedOption(PerLanguageOption2 option, string? language, T value) => WithChangedOption(new OptionKey(option, language), value); - internal AnalyzerConfigOptions AsAnalyzerConfigOptions(ILegacyWorkspaceOptionService optionService, string? language) + internal AnalyzerConfigOptions AsAnalyzerConfigOptions(IEditorConfigOptionMappingService optionMappingService, string? language) { return ImmutableInterlocked.GetOrAdd( ref _lazyAnalyzerConfigOptions, language ?? NoLanguageSentinel, - (string language, (OptionSet self, ILegacyWorkspaceOptionService optionService) arg) => arg.self.CreateAnalyzerConfigOptions(arg.optionService, (object)language == NoLanguageSentinel ? null : language), - (this, optionService)); + (string language, (OptionSet self, IEditorConfigOptionMappingService mapping) arg) => arg.self.CreateAnalyzerConfigOptions(arg.mapping, (object)language == NoLanguageSentinel ? null : language), + (this, optionMappingService)); } internal abstract IEnumerable GetChangedOptions(OptionSet optionSet); - private protected virtual AnalyzerConfigOptions CreateAnalyzerConfigOptions(ILegacyWorkspaceOptionService optionService, string? language) - => new AnalyzerConfigOptionsImpl(this, optionService, language); + private protected virtual AnalyzerConfigOptions CreateAnalyzerConfigOptions(IEditorConfigOptionMappingService optionMappingService, string? language) + => new AnalyzerConfigOptionsImpl(this, optionMappingService, language); } } diff --git a/src/Workspaces/Core/Portable/Simplification/Simplifier.cs b/src/Workspaces/Core/Portable/Simplification/Simplifier.cs index 52b1cddc5a16a..600d4d449dcc8 100644 --- a/src/Workspaces/Core/Portable/Simplification/Simplifier.cs +++ b/src/Workspaces/Core/Portable/Simplification/Simplifier.cs @@ -242,7 +242,7 @@ internal static async Task ReduceAsync( internal static async Task GetOptionsAsync(Document document, OptionSet? optionSet, CancellationToken cancellationToken) { var services = document.Project.Solution.Workspace.Services; - var optionService = services.GetRequiredService(); + var optionService = services.GetRequiredService(); var configOptionSet = (optionSet ?? await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false)).AsAnalyzerConfigOptions(optionService, document.Project.Language); var simplificationService = services.GetRequiredLanguageService(document.Project.Language); return simplificationService.GetSimplifierOptions(configOptionSet, fallbackOptions: null); diff --git a/src/Workspaces/CoreTest/WorkspaceServiceTests/GlobalOptionServiceTests.cs b/src/Workspaces/CoreTest/WorkspaceServiceTests/GlobalOptionServiceTests.cs index ba56090b487a3..64b355dbdf82c 100644 --- a/src/Workspaces/CoreTest/WorkspaceServiceTests/GlobalOptionServiceTests.cs +++ b/src/Workspaces/CoreTest/WorkspaceServiceTests/GlobalOptionServiceTests.cs @@ -26,24 +26,20 @@ namespace Microsoft.CodeAnalysis.UnitTests.WorkspaceServices [UseExportProvider] public class GlobalOptionServiceTests { - private static IGlobalOptionService GetGlobalOptionService(HostWorkspaceServices services, IOptionProvider? optionProvider = null, IOptionPersisterProvider? optionPersisterProvider = null) + private static IGlobalOptionService GetGlobalOptionService(HostWorkspaceServices services, IOptionPersisterProvider? optionPersisterProvider = null) { var mefHostServices = (IMefHostExportProvider)services.HostServices; var workspaceThreadingService = mefHostServices.GetExportedValues().SingleOrDefault(); return new GlobalOptionService( workspaceThreadingService, new[] - { - new Lazy(() => optionProvider ??= new TestOptionsProvider(), new LanguageMetadata(LanguageNames.CSharp)) - }, - new[] { new Lazy(() => optionPersisterProvider ??= new TestOptionsPersisterProvider()) }); } - private static ILegacyWorkspaceOptionService GetOptionService(HostWorkspaceServices services, IOptionProvider? optionProvider = null, IOptionPersisterProvider? optionPersisterProvider = null) - => new TestService(GetGlobalOptionService(services, optionProvider, optionPersisterProvider)); + private static ILegacyWorkspaceOptionService GetOptionService(HostWorkspaceServices services, IOptionPersisterProvider? optionPersisterProvider = null) + => new TestService(GetGlobalOptionService(services, optionPersisterProvider)); private sealed class TestService : ILegacyWorkspaceOptionService { @@ -170,21 +166,21 @@ public void GlobalOptions() { using var workspace = new AdhocWorkspace(); var globalOptions = GetGlobalOptionService(workspace.Services); - var option1 = new Option("Feature1", "Name1", defaultValue: 1); - var option2 = new Option("Feature2", "Name2", defaultValue: 2); - var option3 = new Option("Feature3", "Name3", defaultValue: 3); + var option1 = new Option2("Feature1", "Name1", defaultValue: 1); + var option2 = new Option2("Feature2", "Name2", defaultValue: 2); + var option3 = new Option2("Feature3", "Name3", defaultValue: 3); var changedOptions = new List(); var handler = new EventHandler((_, e) => changedOptions.Add(e)); globalOptions.OptionChanged += handler; - var values = globalOptions.GetOptions(ImmutableArray.Create(option1, option2)); + var values = globalOptions.GetOptions(ImmutableArray.Create(new OptionKey(option1), new OptionKey(option2))); Assert.Equal(1, values[0]); Assert.Equal(2, values[1]); globalOptions.SetGlobalOptions( - ImmutableArray.Create(option1, option2, option3), + ImmutableArray.Create(new OptionKey(option1), new OptionKey(option2), new OptionKey(option3)), ImmutableArray.Create(5, 6, 3)); AssertEx.Equal(new[] @@ -193,7 +189,7 @@ public void GlobalOptions() "Name2=6", }, changedOptions.Select(e => $"{e.OptionKey.Option.Name}={e.Value}")); - values = globalOptions.GetOptions(ImmutableArray.Create(option1, option2, option3)); + values = globalOptions.GetOptions(ImmutableArray.Create(new OptionKey(option1), new OptionKey(option2), new OptionKey(option3))); Assert.Equal(5, values[0]); Assert.Equal(6, values[1]); Assert.Equal(3, values[2]); @@ -338,7 +334,6 @@ public void TestPerLanguageCodeStyleOptions() // 3. IOptionService validation optionService.GlobalOptions.SetOptions(newOptionSet, ((SolutionOptionSet)newOptionSet).GetChangedOptions()); - Assert.Equal(newValueCodeStyleOption, optionService.GlobalOptions.GetOption(perLanguageOption, LanguageNames.CSharp)); Assert.Equal(newValueCodeStyleOption2, optionService.GlobalOptions.GetOption(perLanguageOption2, LanguageNames.CSharp)); } @@ -385,7 +380,6 @@ public void TestLanguageSpecificCodeStyleOptions() // 3. IOptionService validation optionService.GlobalOptions.SetOptions(newOptionSet, ((SolutionOptionSet)newOptionSet).GetChangedOptions()); - Assert.Equal(newValueCodeStyleOption, optionService.GlobalOptions.GetOption(option)); Assert.Equal(newValueCodeStyleOption2, optionService.GlobalOptions.GetOption(option2)); } diff --git a/src/Workspaces/CoreTestUtilities/OptionsCollection.cs b/src/Workspaces/CoreTestUtilities/OptionsCollection.cs index 4f36367bab2e7..1691f2c335347 100644 --- a/src/Workspaces/CoreTestUtilities/OptionsCollection.cs +++ b/src/Workspaces/CoreTestUtilities/OptionsCollection.cs @@ -76,7 +76,7 @@ public OptionSet ToOptionSet() public AnalyzerConfigOptions ToAnalyzerConfigOptions(HostLanguageServices languageServices) { - var optionService = languageServices.WorkspaceServices.GetRequiredService(); + var optionService = languageServices.WorkspaceServices.GetRequiredService(); return ToOptionSet().AsAnalyzerConfigOptions(optionService, languageServices.Language); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Simplification/SimplifierOptionsProviders.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Simplification/SimplifierOptionsProviders.cs deleted file mode 100644 index b379467fd3da2..0000000000000 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/Simplification/SimplifierOptionsProviders.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// 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.Text; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Shared.Extensions; - -namespace Microsoft.CodeAnalysis.Simplification; - -internal static partial class SimplifierOptionsProviders -{ - internal static async ValueTask GetSimplifierOptionsAsync(this Document document, ISimplification simplification, SimplifierOptionsProvider fallbackOptionsProvider, CancellationToken cancellationToken) - { -#if CODE_STYLE - var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); - return simplification.GetSimplifierOptions(document.Project.AnalyzerOptions.AnalyzerConfigOptionsProvider.GetOptions(syntaxTree), fallbackOptions: null); -#else - return await document.GetSimplifierOptionsAsync(fallbackOptionsProvider, cancellationToken).ConfigureAwait(false); -#endif - } -} diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/WorkspaceExtensions.projitems b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/WorkspaceExtensions.projitems index 3e005c0bd0bd0..84844e6a3cfe4 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/WorkspaceExtensions.projitems +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/WorkspaceExtensions.projitems @@ -66,7 +66,6 @@ -