Skip to content

Commit

Permalink
Remove IDocumentOptionsProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
tmat committed May 13, 2022
1 parent 7213a48 commit c334a38
Show file tree
Hide file tree
Showing 15 changed files with 46 additions and 234 deletions.
2 changes: 0 additions & 2 deletions src/EditorFeatures/TestUtilities/Workspaces/TestWorkspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,6 @@ public TestWorkspace(
_backgroundParser.Start();

_metadataAsSourceFileService = ExportProvider.GetExportedValues<IMetadataAsSourceFileService>().FirstOrDefault();

RegisterDocumentOptionProviders(ExportProvider.GetExports<IDocumentOptionsProviderFactory, OrderableMetadata>());
}

internal static TestComposition GetComposition(TestComposition? composition)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Options.EditorConfig;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Text;
using static Microsoft.CodeAnalysis.CodeActions.CodeAction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,6 @@ public void SetOptions(OptionSet optionSet)
throw new NotImplementedException();
}

public void RegisterDocumentOptionsProvider(IDocumentOptionsProvider documentOptionsProvider)
{
throw new NotImplementedException();
}

public Task<OptionSet> GetUpdatedOptionSetForDocumentAsync(Document document, OptionSet optionSet, CancellationToken cancellationToken)
{
throw new NotImplementedException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,7 @@ public async Task<VisualStudioProject> CreateAndAddToWorkspaceAsync(
? filePath
: null;

// After the call to EnsureDocumentOptionProvidersInitializedAsync, everything can be off the UI thread.
// Thus, we have a ConfigureAwait(false) on the call and switch explicitly after.
await _visualStudioWorkspaceImpl.EnsureDocumentOptionProvidersInitializedAsync(cancellationToken).ConfigureAwait(false);
// Following can be off the UI thread.
await TaskScheduler.Default;

// From this point on, we start mutating the solution. So make us non cancellable.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,6 @@ internal abstract partial class VisualStudioWorkspaceImpl : VisualStudioWorkspac
internal FileWatchedPortableExecutableReferenceFactory FileWatchedReferenceFactory { get; }

private readonly Lazy<IProjectCodeModelFactory> _projectCodeModelFactory;
private readonly IEnumerable<Lazy<IDocumentOptionsProviderFactory, OrderableMetadata>> _documentOptionsProviderFactories;
private bool _documentOptionsProvidersInitialized = false;

private readonly Lazy<ExternalErrorDiagnosticUpdateSource> _lazyExternalErrorDiagnosticUpdateSource;
private readonly IAsynchronousOperationListener _workspaceListener;
Expand All @@ -145,7 +143,6 @@ public VisualStudioWorkspaceImpl(ExportProvider exportProvider, IAsyncServicePro
_textBufferFactoryService = exportProvider.GetExportedValue<ITextBufferFactoryService>();
_projectionBufferFactoryService = exportProvider.GetExportedValue<IProjectionBufferFactoryService>();
_projectCodeModelFactory = exportProvider.GetExport<IProjectCodeModelFactory>();
_documentOptionsProviderFactories = exportProvider.GetExports<IDocumentOptionsProviderFactory, OrderableMetadata>();

// We fetch this lazily because VisualStudioProjectFactory depends on VisualStudioWorkspaceImpl -- we have a circularity. Since this
// exists right now as a compat shim, we'll just do this.
Expand Down Expand Up @@ -2039,23 +2036,6 @@ await ApplyBatchChangeToWorkspaceAsync(solutionChanges =>
});
}

internal async Task EnsureDocumentOptionProvidersInitializedAsync(CancellationToken cancellationToken)
{
// HACK: switch to the UI thread, ensure we initialize our options provider which depends on a
// UI-affinitized experimentation service
await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

_foregroundObject.AssertIsForeground();

if (_documentOptionsProvidersInitialized)
{
return;
}

_documentOptionsProvidersInitialized = true;
RegisterDocumentOptionProviders(_documentOptionsProviderFactories);
}

[PerformanceSensitive("https://github.com/dotnet/roslyn/issues/54137", AllowLocks = false)]
internal void SetMaxLanguageVersion(ProjectId projectId, string? maxLanguageVersion)
{
Expand Down

This file was deleted.

20 changes: 0 additions & 20 deletions src/Workspaces/Core/Portable/Options/IDocumentOptions.cs

This file was deleted.

25 changes: 0 additions & 25 deletions src/Workspaces/Core/Portable/Options/IDocumentOptionsProvider.cs

This file was deleted.

This file was deleted.

6 changes: 0 additions & 6 deletions src/Workspaces/Core/Portable/Options/IOptionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,6 @@ internal interface IOptionService : IWorkspaceService

event EventHandler<OptionChangedEventArgs> OptionChanged;

/// <summary>
/// Registers a provider that can modify the result of <see cref="Document.GetOptionsAsync(CancellationToken)"/>. Providers registered earlier are queried first
/// for options, and the first provider to give a value wins.
/// </summary>
void RegisterDocumentOptionsProvider(IDocumentOptionsProvider documentOptionsProvider);

/// <summary>
/// Returns the <see cref="OptionSet"/> that applies to a specific document, given that document and the global options.
/// </summary>
Expand Down
95 changes: 43 additions & 52 deletions src/Workspaces/Core/Portable/Options/OptionServiceFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
using System.Collections.Immutable;
using System.Composition;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Roslyn.Utilities;
Expand Down Expand Up @@ -41,16 +44,13 @@ internal sealed class OptionService : IWorkspaceOptionService
private readonly TaskQueue _taskQueue;

/// <summary>
/// Gate guarding <see cref="_eventHandlers"/> and <see cref="_documentOptionsProviders"/>.
/// Gate guarding <see cref="_eventHandlers"/>.
/// </summary>
private readonly object _gate = new();

private ImmutableArray<EventHandler<OptionChangedEventArgs>> _eventHandlers =
ImmutableArray<EventHandler<OptionChangedEventArgs>>.Empty;

private ImmutableArray<IDocumentOptionsProvider> _documentOptionsProviders =
ImmutableArray<IDocumentOptionsProvider>.Empty;

public OptionService(
IGlobalOptionService globalOptionService,
HostWorkspaceServices workspaceServices)
Expand Down Expand Up @@ -127,59 +127,27 @@ public event EventHandler<OptionChangedEventArgs> OptionChanged
public void RegisterWorkspace(Workspace workspace) => _globalOptionService.RegisterWorkspace(workspace);
public void UnregisterWorkspace(Workspace workspace) => _globalOptionService.UnregisterWorkspace(workspace);

public void RegisterDocumentOptionsProvider(IDocumentOptionsProvider documentOptionsProvider)
{
if (documentOptionsProvider == null)
{
throw new ArgumentNullException(nameof(documentOptionsProvider));
}

lock (_gate)
{
_documentOptionsProviders = _documentOptionsProviders.Add(documentOptionsProvider);
}
}

public async Task<OptionSet> GetUpdatedOptionSetForDocumentAsync(Document document, OptionSet optionSet, CancellationToken cancellationToken)
{
ImmutableArray<IDocumentOptionsProvider> documentOptionsProviders;

lock (_gate)
{
documentOptionsProviders = _documentOptionsProviders;
}

var realizedDocumentOptions = new List<IDocumentOptions>();

foreach (var provider in documentOptionsProviders)
{
cancellationToken.ThrowIfCancellationRequested();

var documentOption = await provider.GetOptionsForDocumentAsync(document, cancellationToken).ConfigureAwait(false);

if (documentOption != null)
{
realizedDocumentOptions.Add(documentOption);
}
}

return new DocumentSpecificOptionSet(realizedDocumentOptions, optionSet);
var provider = (ProjectState.ProjectAnalyzerConfigOptionsProvider)document.Project.State.AnalyzerOptions.AnalyzerConfigOptionsProvider;
var options = await provider.GetOptionsAsync(document.DocumentState, cancellationToken).ConfigureAwait(false);
return new DocumentSpecificOptionSet(options, optionSet);
}

private class DocumentSpecificOptionSet : OptionSet
private sealed class DocumentSpecificOptionSet : OptionSet
{
private readonly OptionSet _underlyingOptions;
private readonly List<IDocumentOptions> _documentOptions;
private readonly StructuredAnalyzerConfigOptions? _configOptions;
private ImmutableDictionary<OptionKey, object?> _values;

public DocumentSpecificOptionSet(List<IDocumentOptions> documentOptions, OptionSet underlyingOptions)
: this(documentOptions, underlyingOptions, ImmutableDictionary<OptionKey, object?>.Empty)
public DocumentSpecificOptionSet(StructuredAnalyzerConfigOptions? configOptions, OptionSet underlyingOptions)
: this(configOptions, underlyingOptions, ImmutableDictionary<OptionKey, object?>.Empty)
{
}

public DocumentSpecificOptionSet(List<IDocumentOptions> documentOptions, OptionSet underlyingOptions, ImmutableDictionary<OptionKey, object?> values)
public DocumentSpecificOptionSet(StructuredAnalyzerConfigOptions? configOptions, OptionSet underlyingOptions, ImmutableDictionary<OptionKey, object?> values)
{
_documentOptions = documentOptions;
_configOptions = configOptions;
_underlyingOptions = underlyingOptions;
_values = values;
}
Expand All @@ -193,21 +161,44 @@ public DocumentSpecificOptionSet(List<IDocumentOptions> documentOptions, OptionS
return value;
}

foreach (var documentOptionSource in _documentOptions)
if (TryGetAnalyzerConfigOption(optionKey, out value))
{
if (documentOptionSource.TryGetDocumentOption(optionKey, out value))
{
// Cache and return
return ImmutableInterlocked.GetOrAdd(ref _values, optionKey, value);
}
// Cache and return
return ImmutableInterlocked.GetOrAdd(ref _values, optionKey, value);
}

// We don't have a document specific value, so forward
return _underlyingOptions.GetOption(optionKey);
}

private bool TryGetAnalyzerConfigOption(OptionKey option, out object? value)
{
if (_configOptions == null)
{
value = null;
return false;
}

var editorConfigPersistence = (IEditorConfigStorageLocation?)option.Option.StorageLocations.SingleOrDefault(static location => location is IEditorConfigStorageLocation);
if (editorConfigPersistence == null)
{
value = null;
return false;
}

try
{
return editorConfigPersistence.TryGetOption(_configOptions, option.Option.Type, out value);
}
catch (Exception e) when (FatalError.ReportAndCatch(e))
{
value = null;
return false;
}
}

public override OptionSet WithChangedOption(OptionKey optionAndLanguage, object? value)
=> new DocumentSpecificOptionSet(_documentOptions, _underlyingOptions, _values.SetItem(optionAndLanguage, value));
=> new DocumentSpecificOptionSet(_configOptions, _underlyingOptions, _values.SetItem(optionAndLanguage, value));

internal override IEnumerable<OptionKey> GetChangedOptions(OptionSet optionSet)
{
Expand Down
3 changes: 0 additions & 3 deletions src/Workspaces/Core/Portable/Workspace/Workspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Options.EditorConfig;
using Microsoft.CodeAnalysis.Remote;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities;
Expand Down Expand Up @@ -92,8 +91,6 @@ protected Workspace(HostServices host, string? workspaceKind)
_optionService, ImmutableDictionary<OptionKey, object?>.Empty, changedOptionKeysSerializable: ImmutableHashSet<OptionKey>.Empty);

_latestSolution = CreateSolution(info, emptyOptions, analyzerReferences: SpecializedCollections.EmptyReadOnlyList<AnalyzerReference>());

_optionService.RegisterDocumentOptionsProvider(EditorConfigDocumentOptionsProviderFactory.Create());
}

internal void LogTestMessage(string message)
Expand Down
Loading

0 comments on commit c334a38

Please sign in to comment.