提交 4c8ac93e 编写于 作者: H HeeJae Chang

moved error and todo list initialization to VS workspace.

we used to initialize those when packages are loaded. but with CPS, those packages are no longer automatically loaded with solution open (perf win)

so now, it is moved to VSWorkspace ctor and it gets initialized when the workspace is created.

considered making it on demand but due to reversed dependency (error reproting happening in lower layer), required some plumbing so looked into how expensive the initialization is. and it turns out due to previous work done in these area, initialization was quite cheap. any expensive one was already lazy or consumed by CPSProjectFactory already.

so, just moved initialization into VSWorkspace ctor and fixed MEF dependencies.
上级 0362ecd0
......@@ -7,6 +7,7 @@
using System.IO;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Host;
......@@ -14,16 +15,16 @@
using Microsoft.CodeAnalysis.Scripting;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Editor;
using Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell.TableManager;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.TextManager.Interop;
using Roslyn.Utilities;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem
{
using Workspace = Microsoft.CodeAnalysis.Workspace;
[Export(typeof(MiscellaneousFilesWorkspace))]
internal sealed partial class MiscellaneousFilesWorkspace : Workspace, IVsRunningDocTableEvents2
{
......@@ -59,6 +60,9 @@ internal sealed partial class MiscellaneousFilesWorkspace : Workspace, IVsRunnin
IMetadataAsSourceFileService fileTrackingMetadataAsSourceService,
SaveEventsService saveEventsService,
VisualStudioWorkspace visualStudioWorkspace,
IDiagnosticService diagnosticService,
ITodoListProvider todoListProvider,
ITableManagerProvider provider,
SVsServiceProvider serviceProvider) :
base(visualStudioWorkspace.Services.HostServices, WorkspaceKind.MiscellaneousFiles)
{
......@@ -73,6 +77,9 @@ internal sealed partial class MiscellaneousFilesWorkspace : Workspace, IVsRunnin
_metadataReferences = ImmutableArray.CreateRange(CreateMetadataReferences());
saveEventsService.StartSendingSaveEvents();
MiscellaneousDiagnosticListTable.Register(this, diagnosticService, provider);
MiscellaneousTodoListTable.Register(this, todoListProvider, provider);
}
public void RegisterLanguage(Guid languageGuid, string languageName, string scriptExtension)
......
......@@ -11,11 +11,11 @@
using EnvDTE;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.EditAndContinue;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Microsoft.CodeAnalysis.SolutionCrawler;
using Microsoft.CodeAnalysis.Text;
......@@ -25,6 +25,7 @@
using Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.Extensions;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.MetadataReferences;
using Microsoft.VisualStudio.LanguageServices.Implementation.TaskList;
using Microsoft.VisualStudio.LanguageServices.Implementation.Venus;
using Microsoft.VisualStudio.LanguageServices.Utilities;
using Microsoft.VisualStudio.Shell;
......@@ -34,7 +35,6 @@
using Roslyn.Utilities;
using VSLangProj;
using VSLangProj140;
using VSLangProj80;
using IAsyncServiceProvider = Microsoft.VisualStudio.Shell.IAsyncServiceProvider;
using OleInterop = Microsoft.VisualStudio.OLE.Interop;
......@@ -121,8 +121,16 @@ public VisualStudioWorkspaceImpl(ExportProvider exportProvider, IAsyncServicePro
FileWatchedReferenceFactory = exportProvider.GetExportedValue<FileWatchedPortableExecutableReferenceFactory>();
FileWatchedReferenceFactory.ReferenceChanged += this.RefreshMetadataReferencesForFile;
ExternalErrorDiagnosticUpdateSource = new ExternalErrorDiagnosticUpdateSource(
this,
exportProvider.GetExportedValue<IDiagnosticAnalyzerService>(),
exportProvider.GetExportedValue<IDiagnosticUpdateSourceRegistrationService>(),
exportProvider.GetExportedValue<IAsynchronousOperationListenerProvider>());
}
internal ExternalErrorDiagnosticUpdateSource ExternalErrorDiagnosticUpdateSource { get; }
public async System.Threading.Tasks.Task ConnectToOpenFileTrackerOnUIThreadAsync(IAsyncServiceProvider asyncServiceProvider)
{
// Create services that are bound to the UI thread
......
......@@ -8,13 +8,18 @@
namespace Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource
{
internal class MiscellaneousDiagnosticListTable : VisualStudioBaseDiagnosticListTable
internal sealed class MiscellaneousDiagnosticListTable : VisualStudioBaseDiagnosticListTable
{
internal const string IdentifierString = nameof(MiscellaneousDiagnosticListTable);
private readonly LiveTableDataSource _source;
public MiscellaneousDiagnosticListTable(MiscellaneousFilesWorkspace workspace, IDiagnosticService diagnosticService, ITableManagerProvider provider) :
public static void Register(MiscellaneousFilesWorkspace workspace, IDiagnosticService diagnosticService, ITableManagerProvider provider)
{
new MiscellaneousDiagnosticListTable(workspace, diagnosticService, provider);
}
private MiscellaneousDiagnosticListTable(MiscellaneousFilesWorkspace workspace, IDiagnosticService diagnosticService, ITableManagerProvider provider) :
base(workspace, provider)
{
_source = new LiveTableDataSource(workspace, diagnosticService, IdentifierString);
......
......@@ -6,11 +6,16 @@
namespace Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource
{
internal class MiscellaneousTodoListTable : VisualStudioBaseTodoListTable
internal sealed class MiscellaneousTodoListTable : VisualStudioBaseTodoListTable
{
internal const string IdentifierString = nameof(MiscellaneousTodoListTable);
public MiscellaneousTodoListTable(MiscellaneousFilesWorkspace workspace, ITodoListProvider todoListProvider, ITableManagerProvider provider) :
public static void Register(MiscellaneousFilesWorkspace workspace, ITodoListProvider todoListProvider, ITableManagerProvider provider)
{
new MiscellaneousTodoListTable(workspace, todoListProvider, provider);
}
private MiscellaneousTodoListTable(MiscellaneousFilesWorkspace workspace, ITodoListProvider todoListProvider, ITableManagerProvider provider) :
base(workspace, todoListProvider, IdentifierString, provider)
{
ConnectWorkspaceEvents();
......
......@@ -51,7 +51,6 @@ internal sealed class VisualStudioSuppressionFixService : IVisualStudioSuppressi
SVsServiceProvider serviceProvider,
VisualStudioWorkspaceImpl workspace,
IDiagnosticAnalyzerService diagnosticService,
ExternalErrorDiagnosticUpdateSource buildErrorDiagnosticService,
ICodeFixService codeFixService,
ICodeActionEditHandlerService editHandlerService,
IVisualStudioDiagnosticListSuppressionStateService suppressionStateService,
......@@ -60,7 +59,7 @@ internal sealed class VisualStudioSuppressionFixService : IVisualStudioSuppressi
{
_workspace = workspace;
_diagnosticService = diagnosticService;
_buildErrorDiagnosticService = buildErrorDiagnosticService;
_buildErrorDiagnosticService = workspace.ExternalErrorDiagnosticUpdateSource;
_codeFixService = codeFixService;
_suppressionStateService = (VisualStudioDiagnosticListSuppressionStateService)suppressionStateService;
_editHandlerService = editHandlerService;
......
// 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.ComponentModel;
using System.ComponentModel.Composition;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.LanguageServices.Implementation.TaskList;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell.TableManager;
using Microsoft.VisualStudio.TaskStatusCenter;
using Task = System.Threading.Tasks.Task;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource
{
using Workspace = Microsoft.CodeAnalysis.Workspace;
[Export(typeof(VisualStudioDiagnosticListTable))]
internal partial class VisualStudioDiagnosticListTable : VisualStudioBaseDiagnosticListTable
{
internal const string IdentifierString = nameof(VisualStudioDiagnosticListTable);
private readonly IErrorList _errorList;
private readonly LiveTableDataSource _liveTableSource;
private readonly BuildTableDataSource _buildTableSource;
[ImportingConstructor]
public VisualStudioDiagnosticListTable(
SVsServiceProvider serviceProvider,
VisualStudioWorkspace workspace,
private IErrorList _errorList;
public static async Task RegisterAsync(
Shell.IAsyncServiceProvider asyncServiceProvider,
VisualStudioWorkspaceImpl workspace,
IDiagnosticService diagnosticService,
ITableManagerProvider provider)
{
var table = new VisualStudioDiagnosticListTable(workspace, diagnosticService, workspace.ExternalErrorDiagnosticUpdateSource, provider);
table.SetErrorList((IErrorList)await asyncServiceProvider.GetServiceAsync(typeof(SVsErrorList)).ConfigureAwait(false));
}
private VisualStudioDiagnosticListTable(
Workspace workspace,
IDiagnosticService diagnosticService,
ExternalErrorDiagnosticUpdateSource errorSource,
ITableManagerProvider provider) :
this(workspace, diagnosticService, errorSource, provider)
base(workspace, provider)
{
ConnectWorkspaceEvents();
_liveTableSource = new LiveTableDataSource(workspace, diagnosticService, IdentifierString);
_buildTableSource = new BuildTableDataSource(workspace, errorSource);
_errorList = serviceProvider.GetService(typeof(SVsErrorList)) as IErrorList;
if (_errorList == null)
{
AddInitialTableSource(workspace.CurrentSolution, _liveTableSource);
return;
ConnectWorkspaceEvents();
}
private void SetErrorList(IErrorList errorList)
{
_errorList = errorList;
_errorList.PropertyChanged += OnErrorListPropertyChanged;
AddInitialTableSource(workspace.CurrentSolution, GetCurrentDataSource());
AddInitialTableSource(Workspace.CurrentSolution, GetCurrentDataSource());
SuppressionStateColumnDefinition.SetDefaultFilter(_errorList.TableControl);
}
......@@ -59,27 +67,16 @@ private ITableDataSource GetCurrentDataSource()
/// this is for test only
internal VisualStudioDiagnosticListTable(Workspace workspace, IDiagnosticService diagnosticService, ITableManagerProvider provider) :
this(workspace, diagnosticService, errorSource: null, provider)
base(workspace, provider)
{
AddInitialTableSource(workspace.CurrentSolution, _liveTableSource);
AddInitialTableSource(workspace.CurrentSolution, new LiveTableDataSource(workspace, diagnosticService, IdentifierString));
}
/// this is for test only
internal VisualStudioDiagnosticListTable(Workspace workspace, ExternalErrorDiagnosticUpdateSource errorSource, ITableManagerProvider provider) :
this(workspace, diagnosticService: null, errorSource, provider)
{
AddInitialTableSource(workspace.CurrentSolution, _buildTableSource);
}
private VisualStudioDiagnosticListTable(
Workspace workspace,
IDiagnosticService diagnosticService,
ExternalErrorDiagnosticUpdateSource errorSource,
ITableManagerProvider provider) :
base(workspace, diagnosticService, provider)
base(workspace, provider)
{
_liveTableSource = new LiveTableDataSource(workspace, diagnosticService, IdentifierString);
_buildTableSource = new BuildTableDataSource(workspace, errorSource);
AddInitialTableSource(workspace.CurrentSolution, new BuildTableDataSource(workspace, errorSource));
}
protected override void AddTableSourceIfNecessary(Solution solution)
......
......@@ -10,7 +10,13 @@ internal class VisualStudioTodoListTable : VisualStudioBaseTodoListTable
{
internal const string IdentifierString = nameof(VisualStudioTodoListTable);
public VisualStudioTodoListTable(Workspace workspace, ITodoListProvider todoListProvider, ITableManagerProvider provider) :
public static void Register(Workspace workspace, ITodoListProvider todoListProvider, ITableManagerProvider provider)
{
new VisualStudioTodoListTable(workspace, todoListProvider, provider);
}
// internal for testing
internal VisualStudioTodoListTable(Workspace workspace, ITodoListProvider todoListProvider, ITableManagerProvider provider) :
base(workspace, todoListProvider, IdentifierString, provider)
{
ConnectWorkspaceEvents();
......
......@@ -16,24 +16,24 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.TaskList
[Export(typeof(HostDiagnosticUpdateSource))]
internal sealed class HostDiagnosticUpdateSource : AbstractHostDiagnosticUpdateSource
{
private readonly VisualStudioWorkspaceImpl _workspace;
private readonly Lazy<VisualStudioWorkspaceImpl> _workspace;
private readonly object _gate = new object();
private readonly Dictionary<ProjectId, HashSet<object>> _diagnosticMap = new Dictionary<ProjectId, HashSet<object>>();
[ImportingConstructor]
public HostDiagnosticUpdateSource(VisualStudioWorkspaceImpl workspace, IDiagnosticUpdateSourceRegistrationService registrationService)
public HostDiagnosticUpdateSource(Lazy<VisualStudioWorkspaceImpl> workspace, IDiagnosticUpdateSourceRegistrationService registrationService)
{
_workspace = workspace;
registrationService.Register(this);
}
public override Microsoft.CodeAnalysis.Workspace Workspace
public override Workspace Workspace
{
get
{
return _workspace;
return _workspace.Value;
}
}
......@@ -41,7 +41,7 @@ private void RaiseDiagnosticsCreatedForProject(ProjectId projectId, object key,
{
var args = DiagnosticsUpdatedArgs.DiagnosticsCreated(
CreateId(projectId, key),
_workspace,
Workspace,
solution: null,
projectId: projectId,
documentId: null,
......@@ -54,7 +54,7 @@ private void RaiseDiagnosticsRemovedForProject(ProjectId projectId, object key)
{
var args = DiagnosticsUpdatedArgs.DiagnosticsRemoved(
CreateId(projectId, key),
_workspace,
Workspace,
solution: null,
projectId: projectId,
documentId: null);
......
......@@ -11,7 +11,6 @@
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem.Extensions;
using Microsoft.VisualStudio.LanguageServices.Implementation.Venus;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.TextManager.Interop;
using Roslyn.Utilities;
......@@ -30,11 +29,11 @@ internal class ProjectExternalErrorReporter : IVsReportExternalErrors, IVsLangua
private readonly ExternalErrorDiagnosticUpdateSource _diagnosticProvider;
public ProjectExternalErrorReporter(ProjectId projectId, string errorCodePrefix, IServiceProvider serviceProvider)
: this(projectId, errorCodePrefix, serviceProvider.GetMefService<VisualStudioWorkspace>(), serviceProvider.GetMefService<ExternalErrorDiagnosticUpdateSource>())
: this(projectId, errorCodePrefix, serviceProvider.GetMefService<VisualStudioWorkspaceImpl>())
{
}
public ProjectExternalErrorReporter(ProjectId projectId, string errorCodePrefix, VisualStudioWorkspace workspace, ExternalErrorDiagnosticUpdateSource diagnosticProvider)
public ProjectExternalErrorReporter(ProjectId projectId, string errorCodePrefix, VisualStudioWorkspaceImpl workspace)
{
Debug.Assert(workspace != null);
......@@ -44,7 +43,7 @@ public ProjectExternalErrorReporter(ProjectId projectId, string errorCodePrefix,
_projectId = projectId;
_errorCodePrefix = errorCodePrefix;
_workspace = workspace;
_diagnosticProvider = diagnosticProvider;
_diagnosticProvider = workspace.ExternalErrorDiagnosticUpdateSource;
}
private bool CanHandle(string errorId)
......
......@@ -114,8 +114,6 @@ protected override async Task LoadComponentsAsync(CancellationToken cancellation
// we need to load it as early as possible since we can have errors from
// package from each language very early
this.ComponentModel.GetService<TaskCenterSolutionAnalysisProgressReporter>();
this.ComponentModel.GetService<VisualStudioDiagnosticListTable>();
this.ComponentModel.GetService<VisualStudioTodoListTable>();
this.ComponentModel.GetService<VisualStudioDiagnosticListTableCommandHandler>().Initialize(this);
this.ComponentModel.GetService<VisualStudioMetadataAsSourceFileSupportService>();
......@@ -139,9 +137,6 @@ private async Task LoadComponentsBackgroundAsync(CancellationToken cancellationT
commandHandlerServiceFactory.Initialize(ContentTypeNames.RoslynContentType);
await LoadInteractiveMenusAsync(cancellationToken).ConfigureAwait(true);
this.ComponentModel.GetService<MiscellaneousTodoListTable>();
this.ComponentModel.GetService<MiscellaneousDiagnosticListTable>();
// Initialize any experiments async
var experiments = this.ComponentModel.DefaultExportProvider.GetExportedValues<IExperiment>();
foreach (var experiment in experiments)
......
......@@ -21,7 +21,6 @@ internal partial class CPSProjectFactory : IWorkspaceProjectContextFactory
private readonly VisualStudioProjectFactory _projectFactory;
private readonly VisualStudioWorkspaceImpl _workspace;
private readonly IProjectCodeModelFactory _projectCodeModelFactory;
private readonly ExternalErrorDiagnosticUpdateSource _externalErrorDiagnosticUpdateSource;
private static readonly ImmutableDictionary<string, string> s_projectLanguageToErrorCodePrefixMap =
ImmutableDictionary.CreateRange(StringComparer.OrdinalIgnoreCase, new[]
......@@ -36,13 +35,11 @@ internal partial class CPSProjectFactory : IWorkspaceProjectContextFactory
public CPSProjectFactory(
VisualStudioProjectFactory projectFactory,
VisualStudioWorkspaceImpl workspace,
IProjectCodeModelFactory projectCodeModelFactory,
[Import(AllowDefault = true)] /* not present in unit tests */ ExternalErrorDiagnosticUpdateSource externalErrorDiagnosticUpdateSource)
IProjectCodeModelFactory projectCodeModelFactory)
{
_projectFactory = projectFactory;
_workspace = workspace;
_projectCodeModelFactory = projectCodeModelFactory;
_externalErrorDiagnosticUpdateSource = externalErrorDiagnosticUpdateSource;
}
IWorkspaceProjectContext IWorkspaceProjectContextFactory.CreateProjectContext(
......@@ -59,7 +56,7 @@ internal partial class CPSProjectFactory : IWorkspaceProjectContextFactory
if (s_projectLanguageToErrorCodePrefixMap.TryGetKey(languageName, out var prefix))
{
errorReporter = new ProjectExternalErrorReporter(visualStudioProject.Id, prefix, _workspace, _externalErrorDiagnosticUpdateSource);
errorReporter = new ProjectExternalErrorReporter(visualStudioProject.Id, prefix, _workspace);
}
return new CPSProject(visualStudioProject, _workspace, _projectCodeModelFactory, errorReporter, projectGuid, binOutputPath);
......
......@@ -6,6 +6,8 @@
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor;
using Microsoft.CodeAnalysis.Editor.GoToDefinition;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.Undo;
......@@ -17,8 +19,10 @@
using Microsoft.VisualStudio.LanguageServices.Implementation.Interop;
using Microsoft.VisualStudio.LanguageServices.Implementation.Library.ObjectBrowser.Lists;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.LanguageServices.Implementation.TableDataSource;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell.TableManager;
using Microsoft.VisualStudio.Threading;
using Roslyn.Utilities;
using IAsyncServiceProvider = Microsoft.VisualStudio.Shell.IAsyncServiceProvider;
......@@ -49,6 +53,17 @@ internal class RoslynVisualStudioWorkspace : VisualStudioWorkspaceImpl
Services.GetRequiredService<IOptionService>().RegisterDocumentOptionsProvider(optionsProvider);
}
}
// this will register todo list and error list to VS
VisualStudioDiagnosticListTable.RegisterAsync(
asyncServiceProvider, this,
exportProvider.GetExportedValue<IDiagnosticService>(),
exportProvider.GetExportedValue<ITableManagerProvider>()).Forget();
VisualStudioTodoListTable.Register(
this,
exportProvider.GetExportedValue<ITodoListProvider>(),
exportProvider.GetExportedValue<ITableManagerProvider>());
}
internal override IInvisibleEditor OpenInvisibleEditor(DocumentId documentId)
......
......@@ -29,7 +29,12 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim
<WpfFact, Trait(Traits.Feature, Traits.Features.Diagnostics)>
Public Sub AnalyzerErrorsAreUpdated()
Dim hostDiagnosticUpdateSource = New HostDiagnosticUpdateSource(Nothing, New MockDiagnosticUpdateSourceRegistrationService())
Dim lazyWorkspace = New Lazy(Of VisualStudioWorkspaceImpl)(
Function()
Return Nothing
End Function)
Dim hostDiagnosticUpdateSource = New HostDiagnosticUpdateSource(lazyWorkspace, New MockDiagnosticUpdateSourceRegistrationService())
Dim file = Path.GetTempFileName()
Dim eventHandler = New EventHandlers(file)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册