提交 efcee766 编写于 作者: J Jason Malinowski

Allow ordering of document option providers

This is implemented by adding metadata to exports of
IDocumentOptionsProviderFactories that specify the ordering like any
other provider. Although I would love to simplify this by simply
removing the factories entirely by simply having the Workspace
constructor directly add the instances, Visual Studio for Mac is also
exporting these so we'll maintain compat for now.
上级 21c8e2fa
......@@ -16,6 +16,7 @@
namespace Microsoft.CodeAnalysis.Editor.Options
{
[Export(typeof(IDocumentOptionsProviderFactory)), Shared]
[ExportMetadata("Name", PredefinedDocumentOptionsProviderNames.EditorConfig)]
class LegacyEditorConfigDocumentOptionsProviderFactory : IDocumentOptionsProviderFactory
{
private readonly ICodingConventionsManager _codingConventionsManager;
......
......@@ -100,7 +100,7 @@ internal abstract partial class VisualStudioWorkspaceImpl : VisualStudioWorkspac
internal FileWatchedPortableExecutableReferenceFactory FileWatchedReferenceFactory { get; }
private readonly Lazy<IProjectCodeModelFactory> _projectCodeModelFactory;
private readonly IEnumerable<IDocumentOptionsProviderFactory> _documentOptionsProviderFactories;
private readonly IEnumerable<Lazy<IDocumentOptionsProviderFactory, OrderableMetadata>> _documentOptionsProviderFactories;
private bool _documentOptionsProvidersInitialized = false;
private readonly Dictionary<ProjectId, CompilationOutputs> _projectCompilationOutputs = new Dictionary<ProjectId, CompilationOutputs>();
private readonly object _projectCompilationOutputsGuard = new object();
......@@ -108,7 +108,7 @@ internal abstract partial class VisualStudioWorkspaceImpl : VisualStudioWorkspac
private readonly Lazy<ExternalErrorDiagnosticUpdateSource> _lazyExternalErrorDiagnosticUpdateSource;
private bool _isExternalErrorDiagnosticUpdateSourceSubscribedToSolutionBuildEvents;
public VisualStudioWorkspaceImpl(ExportProvider exportProvider, IAsyncServiceProvider asyncServiceProvider, IEnumerable<IDocumentOptionsProviderFactory> documentOptionsProviderFactories)
public VisualStudioWorkspaceImpl(ExportProvider exportProvider, IAsyncServiceProvider asyncServiceProvider)
: base(VisualStudioMefHostServices.Create(exportProvider))
{
_threadingContext = exportProvider.GetExportedValue<IThreadingContext>();
......@@ -117,7 +117,7 @@ public VisualStudioWorkspaceImpl(ExportProvider exportProvider, IAsyncServicePro
_textBufferFactoryService = exportProvider.GetExportedValue<ITextBufferFactoryService>();
_projectionBufferFactoryService = exportProvider.GetExportedValue<IProjectionBufferFactoryService>();
_projectCodeModelFactory = exportProvider.GetExport<IProjectCodeModelFactory>();
_documentOptionsProviderFactories = documentOptionsProviderFactories;
_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.
......@@ -1928,16 +1928,7 @@ internal void EnsureDocumentOptionProvidersInitialized()
}
_documentOptionsProvidersInitialized = true;
foreach (var providerFactory in _documentOptionsProviderFactories)
{
var optionsProvider = providerFactory.TryCreate(this);
if (optionsProvider != null)
{
Services.GetRequiredService<IOptionService>().RegisterDocumentOptionsProvider(optionsProvider);
}
}
RegisterDocumentOptionProviders(_documentOptionsProviderFactories);
}
internal void SetMaxLanguageVersion(ProjectId projectId, string maxLanguageVersion)
......
......@@ -39,9 +39,8 @@ internal class RoslynVisualStudioWorkspace : VisualStudioWorkspaceImpl
public RoslynVisualStudioWorkspace(
ExportProvider exportProvider,
Lazy<IStreamingFindUsagesPresenter> streamingPresenter,
[ImportMany] IEnumerable<IDocumentOptionsProviderFactory> documentOptionsProviderFactories,
[Import(typeof(SVsServiceProvider))] IAsyncServiceProvider asyncServiceProvider)
: base(exportProvider, asyncServiceProvider, documentOptionsProviderFactories)
: base(exportProvider, asyncServiceProvider)
{
_streamingPresenter = streamingPresenter;
}
......
......@@ -87,8 +87,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Fr
<ImportingConstructor>
Public Sub New(exportProvider As Composition.ExportProvider)
MyBase.New(exportProvider,
exportProvider.GetExportedValue(Of MockServiceProvider),
exportProvider.GetExportedValues(Of IDocumentOptionsProviderFactory))
exportProvider.GetExportedValue(Of MockServiceProvider))
End Sub
Public Overrides Sub DisplayReferencedSymbols(solution As Microsoft.CodeAnalysis.Solution, referencedSymbols As IEnumerable(Of ReferencedSymbol))
......
......@@ -13,6 +13,7 @@
namespace Microsoft.CodeAnalysis.Options.EditorConfig
{
[Export(typeof(IDocumentOptionsProviderFactory)), Shared]
[ExportMetadata("Name", PredefinedDocumentOptionsProviderNames.EditorConfig)]
internal sealed class EditorConfigDocumentOptionsProviderFactory : IDocumentOptionsProviderFactory
{
[ImportingConstructor]
......
......@@ -49,6 +49,10 @@ 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>
......
using System;
using System.Collections.Generic;
using System.Text;
namespace Microsoft.CodeAnalysis.Options
{
internal static class PredefinedDocumentOptionsProviderNames
{
/// <summary>
/// The name of the providers for .editorconfig. Both the current and legacy providers will use this name, so that way any other clients can
/// order relative to the pair. The two factories are unordered themselves because only one ever actually gives a real provider.
/// </summary>
public const string EditorConfig = ".editorconfig";
}
}
......@@ -8,7 +8,9 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
......@@ -755,5 +757,18 @@ internal void OnProjectOptionsChanged(ProjectId projectId)
RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind.ProjectChanged, oldSolution, newSolution, projectId);
}
}
internal void RegisterDocumentOptionProviders(IEnumerable<Lazy<IDocumentOptionsProviderFactory, OrderableMetadata>> documentOptionsProviderFactories)
{
foreach (var providerFactory in ExtensionOrderer.Order(documentOptionsProviderFactories))
{
var optionsProvider = providerFactory.Value.TryCreate(this);
if (optionsProvider != null)
{
Services.GetRequiredService<IOptionService>().RegisterDocumentOptionsProvider(optionsProvider);
}
}
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.Host;
......@@ -34,15 +33,7 @@ public RemoteWorkspace()
var primaryWorkspace = exportProvider.GetExports<PrimaryWorkspace>().Single().Value;
primaryWorkspace.Register(this);
foreach (var providerFactory in exportProvider.GetExports<IDocumentOptionsProviderFactory>())
{
var optionsProvider = providerFactory.Value.TryCreate(this);
if (optionsProvider != null)
{
Services.GetRequiredService<IOptionService>().RegisterDocumentOptionsProvider(optionsProvider);
}
}
RegisterDocumentOptionProviders(exportProvider.GetExports<IDocumentOptionsProviderFactory, OrderableMetadata>());
Options = Options.WithChangedOption(CacheOptions.RecoverableTreeLengthThreshold, 0);
......
......@@ -18,17 +18,9 @@ private TemporaryWorkspace()
{
Options = Options.WithChangedOption(CacheOptions.RecoverableTreeLengthThreshold, 0);
var documentOptionsProviderFactories = ((IMefHostExportProvider)Services.HostServices).GetExports<IDocumentOptionsProviderFactory>();
var documentOptionsProviderFactories = ((IMefHostExportProvider)Services.HostServices).GetExports<IDocumentOptionsProviderFactory, OrderableMetadata>();
foreach (var factory in documentOptionsProviderFactories)
{
var documentOptionsProvider = factory.Value.TryCreate(this);
if (documentOptionsProvider != null)
{
Services.GetRequiredService<IOptionService>().RegisterDocumentOptionsProvider(documentOptionsProvider);
}
}
RegisterDocumentOptionProviders(documentOptionsProviderFactories);
}
public TemporaryWorkspace(Solution solution) : this()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册