From ea9d829b8ff33b5299fd18c69be5acce0381d184 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 14 Jan 2021 12:28:01 -0800 Subject: [PATCH] Avoid thread pool starvation in IDiagnosticUpdateSource.GetDiagnostics Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1265747 --- .../AbstractDiagnosticsTaggerProvider.cs | 16 ++++----- .../Diagnostics/DiagnosticServiceTests.cs | 33 ++++++++++--------- .../Test/Diagnostics/MockDiagnosticService.cs | 15 +++++---- .../Squiggles/TestDiagnosticTagProducer.cs | 4 +-- .../AbstractHostDiagnosticUpdateSource.cs | 5 +-- .../DefaultDiagnosticAnalyzerService.cs | 4 +-- .../DiagnosticAnalyzerService_UpdateSource.cs | 6 ++-- .../Portable/Diagnostics/DiagnosticService.cs | 27 +++++++-------- .../Diagnostics/IDiagnosticService.cs | 11 ++++--- .../IDiagnosticServiceExtensions.cs | 23 ++++++------- .../Diagnostics/IDiagnosticUpdateSource.cs | 10 +++--- .../EditAndContinueDiagnosticUpdateSource.cs | 5 +-- .../WorkspacePullDiagnosticHandler.cs | 3 +- .../LanguageClient/InProcLanguageServer.cs | 2 +- ...DiagnosticListTable.LiveTableDataSource.cs | 4 ++- .../ExternalErrorDiagnosticUpdateSource.cs | 4 +-- .../Test.Next/Services/LspDiagnosticsTests.cs | 10 +++--- .../DefaultDiagnosticUpdateSourceTests.vb | 10 +++--- .../DiagnosticTableDataSourceTests.vb | 10 +++--- .../ExternalDiagnosticUpdateSourceTests.vb | 4 +-- 20 files changed, 106 insertions(+), 100 deletions(-) diff --git a/src/EditorFeatures/Core/Implementation/Diagnostics/AbstractDiagnosticsTaggerProvider.cs b/src/EditorFeatures/Core/Implementation/Diagnostics/AbstractDiagnosticsTaggerProvider.cs index 404222d070cc4..11a43d41c492a 100644 --- a/src/EditorFeatures/Core/Implementation/Diagnostics/AbstractDiagnosticsTaggerProvider.cs +++ b/src/EditorFeatures/Core/Implementation/Diagnostics/AbstractDiagnosticsTaggerProvider.cs @@ -8,7 +8,6 @@ using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Common; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.Shared.Preview; using Microsoft.CodeAnalysis.Editor.Shared.Tagging; @@ -121,11 +120,10 @@ protected internal virtual ImmutableArray GetLocationsTo protected override Task ProduceTagsAsync(TaggerContext context, DocumentSnapshotSpan spanToTag, int? caretPosition) { - ProduceTags(context, spanToTag); - return Task.CompletedTask; + return ProduceTagsAsync(context, spanToTag); } - private void ProduceTags(TaggerContext context, DocumentSnapshotSpan spanToTag) + private async Task ProduceTagsAsync(TaggerContext context, DocumentSnapshotSpan spanToTag) { if (!this.IsEnabled) { @@ -155,13 +153,13 @@ private void ProduceTags(TaggerContext context, DocumentSnapshotSpan spanT foreach (var bucket in buckets) { - ProduceTags( + await ProduceTagsAsync( context, spanToTag, workspace, document, - suppressedDiagnosticsSpans, bucket, cancellationToken); + suppressedDiagnosticsSpans, bucket, cancellationToken).ConfigureAwait(false); } } - private void ProduceTags( + private async Task ProduceTagsAsync( TaggerContext context, DocumentSnapshotSpan spanToTag, Workspace workspace, Document document, NormalizedSnapshotSpanCollection? suppressedDiagnosticsSpans, @@ -170,11 +168,11 @@ private void ProduceTags( try { var id = bucket.Id; - var diagnostics = _diagnosticService.GetPushDiagnostics( + var diagnostics = await _diagnosticService.GetPushDiagnosticsAsync( workspace, document.Project.Id, document.Id, id, includeSuppressedDiagnostics: false, diagnosticMode: InternalDiagnosticsOptions.NormalDiagnosticMode, - cancellationToken); + cancellationToken).ConfigureAwait(false); var isLiveUpdate = id is ISupportLiveUpdate; diff --git a/src/EditorFeatures/Test/Diagnostics/DiagnosticServiceTests.cs b/src/EditorFeatures/Test/Diagnostics/DiagnosticServiceTests.cs index 20559cf06b020..08b025fd05645 100644 --- a/src/EditorFeatures/Test/Diagnostics/DiagnosticServiceTests.cs +++ b/src/EditorFeatures/Test/Diagnostics/DiagnosticServiceTests.cs @@ -8,6 +8,7 @@ using System.Collections.Immutable; using System.Linq; using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.Test.Utilities; @@ -31,7 +32,7 @@ private static DiagnosticService GetDiagnosticService(TestWorkspace workspace) } [Fact, Trait(Traits.Feature, Traits.Features.Diagnostics)] - public void TestGetDiagnostics1() + public async Task TestGetDiagnostics1() { using var workspace = new TestWorkspace(composition: FeaturesTestCompositions.Features); var mutex = new ManualResetEvent(false); @@ -46,21 +47,21 @@ public void TestGetDiagnostics1() var id = Tuple.Create(workspace, document); var diagnostic = RaiseDiagnosticEvent(mutex, source, workspace, document.Project.Id, document.Id, id); - var data1 = diagnosticService.GetPushDiagnostics(workspace, null, null, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); + var data1 = await diagnosticService.GetPushDiagnosticsAsync(workspace, null, null, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); Assert.Equal(diagnostic, data1.Single()); - var data2 = diagnosticService.GetPushDiagnostics(workspace, document.Project.Id, null, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); + var data2 = await diagnosticService.GetPushDiagnosticsAsync(workspace, document.Project.Id, null, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); Assert.Equal(diagnostic, data2.Single()); - var data3 = diagnosticService.GetPushDiagnostics(workspace, document.Project.Id, document.Id, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); + var data3 = await diagnosticService.GetPushDiagnosticsAsync(workspace, document.Project.Id, document.Id, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); Assert.Equal(diagnostic, data3.Single()); - var data4 = diagnosticService.GetPushDiagnostics(workspace, document.Project.Id, document.Id, id, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); + var data4 = await diagnosticService.GetPushDiagnosticsAsync(workspace, document.Project.Id, document.Id, id, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); Assert.Equal(diagnostic, data4.Single()); } [Fact, Trait(Traits.Feature, Traits.Features.Diagnostics)] - public void TestGetDiagnostics2() + public async Task TestGetDiagnostics2() { using var workspace = new TestWorkspace(composition: FeaturesTestCompositions.Features); var mutex = new ManualResetEvent(false); @@ -85,24 +86,24 @@ public void TestGetDiagnostics2() RaiseDiagnosticEvent(mutex, source, workspace, document.Project.Id, null, id3); RaiseDiagnosticEvent(mutex, source, workspace, null, null, Tuple.Create(workspace)); - var data1 = diagnosticService.GetPushDiagnostics(workspace, null, null, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); + var data1 = await diagnosticService.GetPushDiagnosticsAsync(workspace, null, null, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); Assert.Equal(5, data1.Count()); - var data2 = diagnosticService.GetPushDiagnostics(workspace, document.Project.Id, null, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); + var data2 = await diagnosticService.GetPushDiagnosticsAsync(workspace, document.Project.Id, null, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); Assert.Equal(4, data2.Count()); - var data3 = diagnosticService.GetPushDiagnostics(workspace, document.Project.Id, null, id3, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); + var data3 = await diagnosticService.GetPushDiagnosticsAsync(workspace, document.Project.Id, null, id3, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); Assert.Equal(1, data3.Count()); - var data4 = diagnosticService.GetPushDiagnostics(workspace, document.Project.Id, document.Id, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); + var data4 = await diagnosticService.GetPushDiagnosticsAsync(workspace, document.Project.Id, document.Id, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); Assert.Equal(2, data4.Count()); - var data5 = diagnosticService.GetPushDiagnostics(workspace, document.Project.Id, document.Id, id, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); + var data5 = await diagnosticService.GetPushDiagnosticsAsync(workspace, document.Project.Id, document.Id, id, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); Assert.Equal(1, data5.Count()); } [Fact, Trait(Traits.Feature, Traits.Features.Diagnostics)] - public void TestCleared() + public async Task TestCleared() { using var workspace = new TestWorkspace(composition: FeaturesTestCompositions.Features); var mutex = new ManualResetEvent(false); @@ -128,7 +129,7 @@ public void TestCleared() RaiseDiagnosticEvent(mutex, source2, workspace, null, null, Tuple.Create(workspace)); // confirm data is there. - var data1 = diagnosticService.GetPushDiagnostics(workspace, null, null, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); + var data1 = await diagnosticService.GetPushDiagnosticsAsync(workspace, null, null, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); Assert.Equal(5, data1.Count()); diagnosticService.DiagnosticsUpdated -= MarkSet; @@ -143,7 +144,7 @@ public void TestCleared() mutex.WaitOne(); // confirm there are 2 data left - var data2 = diagnosticService.GetPushDiagnostics(workspace, null, null, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); + var data2 = await diagnosticService.GetPushDiagnosticsAsync(workspace, null, null, null, includeSuppressedDiagnostics: false, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None); Assert.Equal(2, data2.Count()); void MarkCalled(object sender, DiagnosticsUpdatedArgs args) @@ -207,8 +208,8 @@ public TestDiagnosticUpdateSource(bool support, DiagnosticData[] diagnosticData) public event EventHandler DiagnosticsUpdated; public event EventHandler DiagnosticsCleared; - public ImmutableArray GetDiagnostics(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) - => _support ? _diagnosticData : ImmutableArray.Empty; + public ValueTask> GetDiagnosticsAsync(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) + => new(_support ? _diagnosticData : ImmutableArray.Empty); public void RaiseDiagnosticsUpdatedEvent(DiagnosticsUpdatedArgs args) => DiagnosticsUpdated?.Invoke(this, args); diff --git a/src/EditorFeatures/Test/Diagnostics/MockDiagnosticService.cs b/src/EditorFeatures/Test/Diagnostics/MockDiagnosticService.cs index 8e47a8fa308f3..b3116b972beb2 100644 --- a/src/EditorFeatures/Test/Diagnostics/MockDiagnosticService.cs +++ b/src/EditorFeatures/Test/Diagnostics/MockDiagnosticService.cs @@ -3,15 +3,15 @@ // 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.Linq; using System.Threading; -using Microsoft.CodeAnalysis.Common; +using System.Threading.Tasks; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Options; +using Roslyn.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics @@ -33,17 +33,18 @@ public MockDiagnosticService() { } + [Obsolete] public ImmutableArray GetDiagnostics(Workspace workspace, ProjectId? projectId, DocumentId? documentId, object? id, bool includeSuppressedDiagnostics, CancellationToken cancellationToken) - => GetPushDiagnostics(workspace, projectId, documentId, id, includeSuppressedDiagnostics, InternalDiagnosticsOptions.NormalDiagnosticMode, cancellationToken); + => GetPushDiagnosticsAsync(workspace, projectId, documentId, id, includeSuppressedDiagnostics, InternalDiagnosticsOptions.NormalDiagnosticMode, cancellationToken).AsTask().WaitAndGetResult_CanCallOnBackground(cancellationToken); - public ImmutableArray GetPullDiagnostics(Workspace workspace, ProjectId? projectId, DocumentId? documentId, object? id, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) + public ValueTask> GetPullDiagnosticsAsync(Workspace workspace, ProjectId? projectId, DocumentId? documentId, object? id, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) { - return GetDiagnostics(workspace, projectId, documentId); + return new ValueTask>(GetDiagnostics(workspace, projectId, documentId)); } - public ImmutableArray GetPushDiagnostics(Workspace workspace, ProjectId? projectId, DocumentId? documentId, object? id, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) + public ValueTask> GetPushDiagnosticsAsync(Workspace workspace, ProjectId? projectId, DocumentId? documentId, object? id, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) { - return GetDiagnostics(workspace, projectId, documentId); + return new ValueTask>(GetDiagnostics(workspace, projectId, documentId)); } private ImmutableArray GetDiagnostics(Workspace workspace, ProjectId? projectId, DocumentId? documentId) diff --git a/src/EditorFeatures/TestUtilities/Squiggles/TestDiagnosticTagProducer.cs b/src/EditorFeatures/TestUtilities/Squiggles/TestDiagnosticTagProducer.cs index 2adce8d10f6f3..d5215d7f24244 100644 --- a/src/EditorFeatures/TestUtilities/Squiggles/TestDiagnosticTagProducer.cs +++ b/src/EditorFeatures/TestUtilities/Squiggles/TestDiagnosticTagProducer.cs @@ -88,8 +88,8 @@ public event EventHandler DiagnosticsCleared { add { } remove { } } public bool SupportGetDiagnostics => false; - public ImmutableArray GetDiagnostics(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) - => includeSuppressedDiagnostics ? _diagnostics : _diagnostics.WhereAsArray(d => !d.IsSuppressed); + public ValueTask> GetDiagnosticsAsync(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) + => new(includeSuppressedDiagnostics ? _diagnostics : _diagnostics.WhereAsArray(d => !d.IsSuppressed)); } } } diff --git a/src/Features/Core/Portable/Diagnostics/AbstractHostDiagnosticUpdateSource.cs b/src/Features/Core/Portable/Diagnostics/AbstractHostDiagnosticUpdateSource.cs index f783d6f168070..d44319b754851 100644 --- a/src/Features/Core/Portable/Diagnostics/AbstractHostDiagnosticUpdateSource.cs +++ b/src/Features/Core/Portable/Diagnostics/AbstractHostDiagnosticUpdateSource.cs @@ -6,6 +6,7 @@ using System.Collections.Immutable; using System.Linq; using System.Threading; +using System.Threading.Tasks; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Diagnostics @@ -24,8 +25,8 @@ internal abstract class AbstractHostDiagnosticUpdateSource : IDiagnosticUpdateSo public bool SupportGetDiagnostics => false; - public ImmutableArray GetDiagnostics(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, CancellationToken cancellationToken) - => ImmutableArray.Empty; + public ValueTask> GetDiagnosticsAsync(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, CancellationToken cancellationToken) + => new(ImmutableArray.Empty); public event EventHandler? DiagnosticsUpdated; public event EventHandler DiagnosticsCleared { add { } remove { } } diff --git a/src/Features/Core/Portable/Diagnostics/DefaultDiagnosticAnalyzerService.cs b/src/Features/Core/Portable/Diagnostics/DefaultDiagnosticAnalyzerService.cs index 233e763581c82..df9c2f081b6dd 100644 --- a/src/Features/Core/Portable/Diagnostics/DefaultDiagnosticAnalyzerService.cs +++ b/src/Features/Core/Portable/Diagnostics/DefaultDiagnosticAnalyzerService.cs @@ -51,10 +51,10 @@ public event EventHandler DiagnosticsCleared { add { } remove { } } // this only support push model, pull model will be provided by DiagnosticService by caching everything this one pushed public bool SupportGetDiagnostics => false; - public ImmutableArray GetDiagnostics(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) + public ValueTask> GetDiagnosticsAsync(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) { // pull model not supported - return ImmutableArray.Empty; + return new ValueTask>(ImmutableArray.Empty); } internal void RaiseDiagnosticsUpdated(DiagnosticsUpdatedArgs state) diff --git a/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerService_UpdateSource.cs b/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerService_UpdateSource.cs index d4e536e0592a2..a79ac2c00d815 100644 --- a/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerService_UpdateSource.cs +++ b/src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerService_UpdateSource.cs @@ -82,14 +82,14 @@ internal void RaiseBulkDiagnosticsUpdated(Func, T bool IDiagnosticUpdateSource.SupportGetDiagnostics => true; - ImmutableArray IDiagnosticUpdateSource.GetDiagnostics(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, CancellationToken cancellationToken) + ValueTask> IDiagnosticUpdateSource.GetDiagnosticsAsync(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, CancellationToken cancellationToken) { if (id != null) { - return GetSpecificCachedDiagnosticsAsync(workspace, id, includeSuppressedDiagnostics, cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken); + return new ValueTask>(GetSpecificCachedDiagnosticsAsync(workspace, id, includeSuppressedDiagnostics, cancellationToken)); } - return GetCachedDiagnosticsAsync(workspace, projectId, documentId, includeSuppressedDiagnostics, cancellationToken).WaitAndGetResult_CanCallOnBackground(cancellationToken); + return new ValueTask>(GetCachedDiagnosticsAsync(workspace, projectId, documentId, includeSuppressedDiagnostics, cancellationToken)); } } } diff --git a/src/Features/Core/Portable/Diagnostics/DiagnosticService.cs b/src/Features/Core/Portable/Diagnostics/DiagnosticService.cs index 305c84de82c58..bf1a84b6eb1f6 100644 --- a/src/Features/Core/Portable/Diagnostics/DiagnosticService.cs +++ b/src/Features/Core/Portable/Diagnostics/DiagnosticService.cs @@ -211,16 +211,17 @@ private void OnCleared(object sender, EventArgs e) RaiseDiagnosticsCleared((IDiagnosticUpdateSource)sender); } + [Obsolete] ImmutableArray IDiagnosticService.GetDiagnostics(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, CancellationToken cancellationToken) - => GetPushDiagnostics(workspace, projectId, documentId, id, includeSuppressedDiagnostics, InternalDiagnosticsOptions.NormalDiagnosticMode, cancellationToken); + => GetPushDiagnosticsAsync(workspace, projectId, documentId, id, includeSuppressedDiagnostics, InternalDiagnosticsOptions.NormalDiagnosticMode, cancellationToken).AsTask().WaitAndGetResult_CanCallOnBackground(cancellationToken); - public ImmutableArray GetPullDiagnostics(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) - => GetDiagnostics(workspace, projectId, documentId, id, includeSuppressedDiagnostics, forPullDiagnostics: true, diagnosticMode, cancellationToken); + public ValueTask> GetPullDiagnosticsAsync(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) + => GetDiagnosticsAsync(workspace, projectId, documentId, id, includeSuppressedDiagnostics, forPullDiagnostics: true, diagnosticMode, cancellationToken); - public ImmutableArray GetPushDiagnostics(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) - => GetDiagnostics(workspace, projectId, documentId, id, includeSuppressedDiagnostics, forPullDiagnostics: false, diagnosticMode, cancellationToken); + public ValueTask> GetPushDiagnosticsAsync(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) + => GetDiagnosticsAsync(workspace, projectId, documentId, id, includeSuppressedDiagnostics, forPullDiagnostics: false, diagnosticMode, cancellationToken); - private ImmutableArray GetDiagnostics( + private ValueTask> GetDiagnosticsAsync( Workspace workspace, ProjectId projectId, DocumentId documentId, @@ -234,19 +235,19 @@ private ImmutableArray GetDiagnostics( // push client and pull diagnostics are on, they get nothing. var isPull = workspace.IsPullDiagnostics(diagnosticMode); if (forPullDiagnostics != isPull) - return ImmutableArray.Empty; + return new ValueTask>(ImmutableArray.Empty); if (id != null) { // get specific one - return GetSpecificDiagnostics(workspace, projectId, documentId, id, includeSuppressedDiagnostics, cancellationToken); + return GetSpecificDiagnosticsAsync(workspace, projectId, documentId, id, includeSuppressedDiagnostics, cancellationToken); } // get aggregated ones - return GetDiagnostics(workspace, projectId, documentId, includeSuppressedDiagnostics, cancellationToken); + return GetDiagnosticsAsync(workspace, projectId, documentId, includeSuppressedDiagnostics, cancellationToken); } - private ImmutableArray GetSpecificDiagnostics(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, CancellationToken cancellationToken) + private async ValueTask> GetSpecificDiagnosticsAsync(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var buffer); @@ -257,7 +258,7 @@ private ImmutableArray GetSpecificDiagnostics(Workspace workspac buffer.Clear(); if (source.SupportGetDiagnostics) { - var diagnostics = source.GetDiagnostics(workspace, projectId, documentId, id, includeSuppressedDiagnostics, cancellationToken); + var diagnostics = await source.GetDiagnosticsAsync(workspace, projectId, documentId, id, includeSuppressedDiagnostics, cancellationToken).ConfigureAwait(false); if (diagnostics.Length > 0) return diagnostics; } @@ -279,7 +280,7 @@ private ImmutableArray GetSpecificDiagnostics(Workspace workspac return ImmutableArray.Empty; } - private ImmutableArray GetDiagnostics( + private async ValueTask> GetDiagnosticsAsync( Workspace workspace, ProjectId projectId, DocumentId documentId, bool includeSuppressedDiagnostics, CancellationToken cancellationToken) { using var _1 = ArrayBuilder.GetInstance(out var result); @@ -291,7 +292,7 @@ private ImmutableArray GetDiagnostics( buffer.Clear(); if (source.SupportGetDiagnostics) { - result.AddRange(source.GetDiagnostics(workspace, projectId, documentId, id: null, includeSuppressedDiagnostics, cancellationToken)); + result.AddRange(await source.GetDiagnosticsAsync(workspace, projectId, documentId, id: null, includeSuppressedDiagnostics, cancellationToken).ConfigureAwait(false)); } else { diff --git a/src/Features/Core/Portable/Diagnostics/IDiagnosticService.cs b/src/Features/Core/Portable/Diagnostics/IDiagnosticService.cs index b8bb9ccedd622..d58da26d2f404 100644 --- a/src/Features/Core/Portable/Diagnostics/IDiagnosticService.cs +++ b/src/Features/Core/Portable/Diagnostics/IDiagnosticService.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Immutable; using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis.Options; namespace Microsoft.CodeAnalysis.Diagnostics @@ -23,7 +24,7 @@ internal interface IDiagnosticService event EventHandler DiagnosticsUpdated; /// - /// This call is equivalent to passing in . + /// This call is equivalent to passing in . /// [Obsolete("Legacy overload for TypeScript. Use GetPullDiagnostics or GetPushDiagnostics instead.", error: false)] ImmutableArray GetDiagnostics( @@ -36,7 +37,7 @@ ImmutableArray GetDiagnostics( /// only provides diagnostics for either push or pull purposes (but not both). /// If the caller's desired purpose doesn't match the option value, then this will return nothing, otherwise it /// will return the requested diagnostics. - ImmutableArray GetPullDiagnostics( + ValueTask> GetPullDiagnosticsAsync( Workspace workspace, ProjectId? projectId, DocumentId? documentId, object? id, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken); @@ -47,13 +48,13 @@ ImmutableArray GetPullDiagnostics( /// only provides diagnostics for either push or pull purposes (but not both). /// If the caller's desired purpose doesn't match the option value, then this will return nothing, otherwise it /// will return the requested diagnostics. - ImmutableArray GetPushDiagnostics( + ValueTask> GetPushDiagnosticsAsync( Workspace workspace, ProjectId? projectId, DocumentId? documentId, object? id, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken); /// /// Get current buckets storing our grouped diagnostics. Specific buckets can be retrieved by calling . + /// cref="IDiagnosticServiceExtensions.GetDiagnosticsAsync"/>. /// /// Option controlling if pull diagnostics are allowed for the client. The /// only provides diagnostics for either push or pull purposes (but not both). @@ -65,7 +66,7 @@ ImmutableArray GetPullDiagnosticBuckets( /// /// Get current buckets storing our grouped diagnostics. Specific buckets can be retrieved by calling . + /// cref="IDiagnosticServiceExtensions.GetDiagnosticsAsync"/>. /// /// Option controlling if pull diagnostics are allowed for the client. The only provides diagnostics for either push or pull purposes (but not both). If diff --git a/src/Features/Core/Portable/Diagnostics/IDiagnosticServiceExtensions.cs b/src/Features/Core/Portable/Diagnostics/IDiagnosticServiceExtensions.cs index 291066910e14f..dc23733f543d8 100644 --- a/src/Features/Core/Portable/Diagnostics/IDiagnosticServiceExtensions.cs +++ b/src/Features/Core/Portable/Diagnostics/IDiagnosticServiceExtensions.cs @@ -4,6 +4,7 @@ using System.Collections.Immutable; using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.PooledObjects; using Roslyn.Utilities; @@ -12,33 +13,33 @@ namespace Microsoft.CodeAnalysis.Diagnostics { internal static class IDiagnosticServiceExtensions { - public static ImmutableArray GetPullDiagnostics(this IDiagnosticService service, DiagnosticBucket bucket, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) - => service.GetPullDiagnostics(bucket.Workspace, bucket.ProjectId, bucket.DocumentId, bucket.Id, includeSuppressedDiagnostics, diagnosticMode, cancellationToken); + public static ValueTask> GetPullDiagnosticsAsync(this IDiagnosticService service, DiagnosticBucket bucket, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) + => service.GetPullDiagnosticsAsync(bucket.Workspace, bucket.ProjectId, bucket.DocumentId, bucket.Id, includeSuppressedDiagnostics, diagnosticMode, cancellationToken); - public static ImmutableArray GetPushDiagnostics(this IDiagnosticService service, DiagnosticBucket bucket, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) - => service.GetPushDiagnostics(bucket.Workspace, bucket.ProjectId, bucket.DocumentId, bucket.Id, includeSuppressedDiagnostics, diagnosticMode, cancellationToken); + public static ValueTask> GetPushDiagnosticsAsync(this IDiagnosticService service, DiagnosticBucket bucket, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) + => service.GetPushDiagnosticsAsync(bucket.Workspace, bucket.ProjectId, bucket.DocumentId, bucket.Id, includeSuppressedDiagnostics, diagnosticMode, cancellationToken); - public static ImmutableArray GetPushDiagnostics( + public static ValueTask> GetPushDiagnosticsAsync( this IDiagnosticService service, Document document, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) { - return GetDiagnostics(service, document, includeSuppressedDiagnostics, forPullDiagnostics: false, diagnosticMode, cancellationToken); + return GetDiagnosticsAsync(service, document, includeSuppressedDiagnostics, forPullDiagnostics: false, diagnosticMode, cancellationToken); } - public static ImmutableArray GetPullDiagnostics( + public static ValueTask> GetPullDiagnosticsAsync( this IDiagnosticService service, Document document, bool includeSuppressedDiagnostics, Option2 diagnosticMode, CancellationToken cancellationToken) { - return GetDiagnostics(service, document, includeSuppressedDiagnostics, forPullDiagnostics: true, diagnosticMode, cancellationToken); + return GetDiagnosticsAsync(service, document, includeSuppressedDiagnostics, forPullDiagnostics: true, diagnosticMode, cancellationToken); } - public static ImmutableArray GetDiagnostics( + public static async ValueTask> GetDiagnosticsAsync( this IDiagnosticService service, Document document, bool includeSuppressedDiagnostics, @@ -61,8 +62,8 @@ public static ImmutableArray GetDiagnostics( Contract.ThrowIfFalse(document.Id.Equals(bucket.DocumentId)); var diagnostics = forPullDiagnostics - ? service.GetPullDiagnostics(bucket, includeSuppressedDiagnostics, diagnosticMode, cancellationToken) - : service.GetPushDiagnostics(bucket, includeSuppressedDiagnostics, diagnosticMode, cancellationToken); + ? await service.GetPullDiagnosticsAsync(bucket, includeSuppressedDiagnostics, diagnosticMode, cancellationToken).ConfigureAwait(false) + : await service.GetPushDiagnosticsAsync(bucket, includeSuppressedDiagnostics, diagnosticMode, cancellationToken).ConfigureAwait(false); result.AddRange(diagnostics); } diff --git a/src/Features/Core/Portable/Diagnostics/IDiagnosticUpdateSource.cs b/src/Features/Core/Portable/Diagnostics/IDiagnosticUpdateSource.cs index 335a8dd234b85..9644b6d7913a8 100644 --- a/src/Features/Core/Portable/Diagnostics/IDiagnosticUpdateSource.cs +++ b/src/Features/Core/Portable/Diagnostics/IDiagnosticUpdateSource.cs @@ -2,11 +2,10 @@ // 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.Collections.Immutable; using System.Threading; +using System.Threading.Tasks; namespace Microsoft.CodeAnalysis.Diagnostics { @@ -26,13 +25,14 @@ internal interface IDiagnosticUpdateSource event EventHandler DiagnosticsCleared; /// - /// Return true if the source supports GetDiagnostics API otherwise, return false so that the engine can cache data from DiagnosticsUpdated in memory + /// Return if the source supports API otherwise, return + /// so that the engine can cache data from in memory. /// bool SupportGetDiagnostics { get; } /// - /// Get diagnostics stored in the source + /// Get diagnostics stored in the source. /// - ImmutableArray GetDiagnostics(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, CancellationToken cancellationToken); + ValueTask> GetDiagnosticsAsync(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics, CancellationToken cancellationToken); } } diff --git a/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticUpdateSource.cs b/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticUpdateSource.cs index b1cccc5662ffe..41a4c3d71ea4b 100644 --- a/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticUpdateSource.cs +++ b/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticUpdateSource.cs @@ -8,6 +8,7 @@ using System.Composition; using System.Diagnostics.CodeAnalysis; using System.Threading; +using System.Threading.Tasks; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.PooledObjects; @@ -38,8 +39,8 @@ internal EditAndContinueDiagnosticUpdateSource() /// public bool SupportGetDiagnostics => false; - public ImmutableArray GetDiagnostics(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) - => ImmutableArray.Empty; + public ValueTask> GetDiagnosticsAsync(Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) + => new(ImmutableArray.Empty); /// /// Clears all diagnostics reported thru this source. diff --git a/src/Features/LanguageServer/Protocol/Handler/Diagnostics/WorkspacePullDiagnosticHandler.cs b/src/Features/LanguageServer/Protocol/Handler/Diagnostics/WorkspacePullDiagnosticHandler.cs index 1b83b8d890a0d..cedd5b5f8faad 100644 --- a/src/Features/LanguageServer/Protocol/Handler/Diagnostics/WorkspacePullDiagnosticHandler.cs +++ b/src/Features/LanguageServer/Protocol/Handler/Diagnostics/WorkspacePullDiagnosticHandler.cs @@ -119,8 +119,7 @@ protected override Task> GetDiagnosticsAsync( // For closed files, go to the IDiagnosticService for results. These won't necessarily be totally up to // date. However, that's fine as these are closed files and won't be in the process of being edited. So // any deviations in the spans of diagnostics shouldn't be impactful for the user. - var diagnostics = this.DiagnosticService.GetPullDiagnostics(document, includeSuppressedDiagnostics: false, diagnosticMode, cancellationToken); - return Task.FromResult(diagnostics); + return DiagnosticService.GetPullDiagnosticsAsync(document, includeSuppressedDiagnostics: false, diagnosticMode, cancellationToken).AsTask(); } } } diff --git a/src/VisualStudio/Core/Def/Implementation/LanguageClient/InProcLanguageServer.cs b/src/VisualStudio/Core/Def/Implementation/LanguageClient/InProcLanguageServer.cs index 0409c97d8d1c7..0f162e98e66e6 100644 --- a/src/VisualStudio/Core/Def/Implementation/LanguageClient/InProcLanguageServer.cs +++ b/src/VisualStudio/Core/Def/Implementation/LanguageClient/InProcLanguageServer.cs @@ -578,7 +578,7 @@ private async Task SendDiagnosticsNotificationAsync(Uri uri, ImmutableArray GetItems() { var provider = _source._diagnosticService; - var items = provider.GetPushDiagnostics(_workspace, _projectId, _documentId, _id, includeSuppressedDiagnostics: true, InternalDiagnosticsOptions.NormalDiagnosticMode, cancellationToken: CancellationToken.None) + var items = provider.GetPushDiagnosticsAsync(_workspace, _projectId, _documentId, _id, includeSuppressedDiagnostics: true, InternalDiagnosticsOptions.NormalDiagnosticMode, cancellationToken: CancellationToken.None) + .AsTask() + .WaitAndGetResult_CanCallOnBackground(CancellationToken.None) .Where(ShouldInclude) .Select(data => DiagnosticTableItem.Create(_workspace, data)); diff --git a/src/VisualStudio/Core/Def/Implementation/TaskList/ExternalErrorDiagnosticUpdateSource.cs b/src/VisualStudio/Core/Def/Implementation/TaskList/ExternalErrorDiagnosticUpdateSource.cs index 38e4b0ba42c8b..fc0f43f2c0a57 100644 --- a/src/VisualStudio/Core/Def/Implementation/TaskList/ExternalErrorDiagnosticUpdateSource.cs +++ b/src/VisualStudio/Core/Def/Implementation/TaskList/ExternalErrorDiagnosticUpdateSource.cs @@ -524,10 +524,10 @@ private void RaiseBuildProgressChanged(BuildProgress progress) #region not supported public bool SupportGetDiagnostics { get { return false; } } - public ImmutableArray GetDiagnostics( + public ValueTask> GetDiagnosticsAsync( Workspace workspace, ProjectId projectId, DocumentId documentId, object id, bool includeSuppressedDiagnostics = false, CancellationToken cancellationToken = default) { - return ImmutableArray.Empty; + return new ValueTask>(ImmutableArray.Empty); } #endregion diff --git a/src/VisualStudio/Core/Test.Next/Services/LspDiagnosticsTests.cs b/src/VisualStudio/Core/Test.Next/Services/LspDiagnosticsTests.cs index 1fe62179be982..2c884ebeae278 100644 --- a/src/VisualStudio/Core/Test.Next/Services/LspDiagnosticsTests.cs +++ b/src/VisualStudio/Core/Test.Next/Services/LspDiagnosticsTests.cs @@ -397,20 +397,20 @@ static InProcLanguageServer CreateLanguageServer(Stream inputStream, Stream outp private void SetupMockWithDiagnostics(Mock diagnosticServiceMock, DocumentId documentId, ImmutableArray diagnostics) { - diagnosticServiceMock.Setup(d => d.GetPushDiagnostics( + diagnosticServiceMock.Setup(d => d.GetPushDiagnosticsAsync( It.IsAny(), It.IsAny(), documentId, It.IsAny(), It.IsAny(), It.IsAny>(), - It.IsAny())).Returns(diagnostics); + It.IsAny())).Returns(new ValueTask>(diagnostics)); } private void SetupMockDiagnosticSequence(Mock diagnosticServiceMock, DocumentId documentId, ImmutableArray firstDiagnostics, ImmutableArray secondDiagnostics) { - diagnosticServiceMock.SetupSequence(d => d.GetPushDiagnostics( + diagnosticServiceMock.SetupSequence(d => d.GetPushDiagnosticsAsync( It.IsAny(), It.IsAny(), documentId, @@ -418,8 +418,8 @@ private void SetupMockDiagnosticSequence(Mock diagnosticServ It.IsAny(), It.IsAny>(), It.IsAny())) - .Returns(firstDiagnostics) - .Returns(secondDiagnostics); + .Returns(new ValueTask>(firstDiagnostics)) + .Returns(new ValueTask>(secondDiagnostics)); } private async Task> CreateMockDiagnosticDataAsync(Document document, string id) diff --git a/src/VisualStudio/Core/Test/Diagnostics/DefaultDiagnosticUpdateSourceTests.vb b/src/VisualStudio/Core/Test/Diagnostics/DefaultDiagnosticUpdateSourceTests.vb index c238cb069a7a2..2a2827dd931c1 100644 --- a/src/VisualStudio/Core/Test/Diagnostics/DefaultDiagnosticUpdateSourceTests.vb +++ b/src/VisualStudio/Core/Test/Diagnostics/DefaultDiagnosticUpdateSourceTests.vb @@ -106,7 +106,7 @@ class A Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Await listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync() - Dim diagnostics = diagnosticService.GetPushDiagnostics( + Dim diagnostics = Await diagnosticService.GetPushDiagnosticsAsync( workspace, document.Project.Id, document.Id, Nothing, includeSuppressedDiagnostics:=False, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None) Assert.Single(diagnostics) @@ -144,7 +144,7 @@ class A Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Await listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync() - Dim diagnostics = diagnosticService.GetPushDiagnostics( + Dim diagnostics = Await diagnosticService.GetPushDiagnosticsAsync( workspace, document.Project.Id, document.Id, Nothing, includeSuppressedDiagnostics:=False, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None) ' error CS0246: The type or namespace name 'M' could not be found @@ -183,7 +183,7 @@ class A Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Await listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync() - Dim diagnostics = diagnosticService.GetPushDiagnostics( + Dim diagnostics = Await diagnosticService.GetPushDiagnosticsAsync( workspace, document.Project.Id, document.Id, Nothing, includeSuppressedDiagnostics:=False, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None) ' error CS1002: ; expected @@ -225,7 +225,7 @@ class A Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Await listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync() - Dim diagnostics = diagnosticService.GetPushDiagnostics( + Dim diagnostics = Await diagnosticService.GetPushDiagnosticsAsync( workspace, document.Project.Id, document.Id, Nothing, includeSuppressedDiagnostics:=False, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None) AssertEx.Empty(diagnostics) @@ -328,7 +328,7 @@ End Class Dim listenerProvider = workspace.ExportProvider.GetExportedValue(Of IAsynchronousOperationListenerProvider) Await listenerProvider.GetWaiter(FeatureAttribute.DiagnosticService).ExpeditedWaitAsync() - Dim diagnostics = diagnosticService.GetPushDiagnostics( + Dim diagnostics = Await diagnosticService.GetPushDiagnosticsAsync( workspace, document.Project.Id, document.Id, Nothing, includeSuppressedDiagnostics:=False, InternalDiagnosticsOptions.NormalDiagnosticMode, CancellationToken.None) Assert.Single(diagnostics) diff --git a/src/VisualStudio/Core/Test/Diagnostics/DiagnosticTableDataSourceTests.vb b/src/VisualStudio/Core/Test/Diagnostics/DiagnosticTableDataSourceTests.vb index 6831b130c1223..4864c7697aad2 100644 --- a/src/VisualStudio/Core/Test/Diagnostics/DiagnosticTableDataSourceTests.vb +++ b/src/VisualStudio/Core/Test/Diagnostics/DiagnosticTableDataSourceTests.vb @@ -823,15 +823,15 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics Public Function GetDiagnostics(workspace As Workspace, projectId As ProjectId, documentId As DocumentId, id As Object, includeSuppressedDiagnostics As Boolean, cancellationToken As CancellationToken) As ImmutableArray(Of DiagnosticData) Implements IDiagnosticService.GetDiagnostics - Return GetPushDiagnostics(workspace, projectId, documentId, id, includeSuppressedDiagnostics, InternalDiagnosticsOptions.NormalDiagnosticMode, cancellationToken) + Return GetPushDiagnosticsAsync(workspace, projectId, documentId, id, includeSuppressedDiagnostics, InternalDiagnosticsOptions.NormalDiagnosticMode, cancellationToken).AsTask().WaitAndGetResult_CanCallOnBackground(cancellationToken) End Function - Public Function GetPullDiagnostics(workspace As Workspace, projectId As ProjectId, documentId As DocumentId, id As Object, includeSuppressedDiagnostics As Boolean, diagnosticMode As Option2(Of DiagnosticMode), cancellationToken As CancellationToken) As ImmutableArray(Of DiagnosticData) Implements IDiagnosticService.GetPullDiagnostics - Return GetDiagnostics(workspace, projectId, documentId, includeSuppressedDiagnostics) + Public Function GetPullDiagnosticsAsync(workspace As Workspace, projectId As ProjectId, documentId As DocumentId, id As Object, includeSuppressedDiagnostics As Boolean, diagnosticMode As Option2(Of DiagnosticMode), cancellationToken As CancellationToken) As ValueTask(Of ImmutableArray(Of DiagnosticData)) Implements IDiagnosticService.GetPullDiagnosticsAsync + Return New ValueTask(Of ImmutableArray(Of DiagnosticData))(GetDiagnostics(workspace, projectId, documentId, includeSuppressedDiagnostics)) End Function - Public Function GetPushDiagnostics(workspace As Workspace, projectId As ProjectId, documentId As DocumentId, id As Object, includeSuppressedDiagnostics As Boolean, diagnosticMode As Option2(Of DiagnosticMode), cancellationToken As CancellationToken) As ImmutableArray(Of DiagnosticData) Implements IDiagnosticService.GetPushDiagnostics - Return GetDiagnostics(workspace, projectId, documentId, includeSuppressedDiagnostics) + Public Function GetPushDiagnosticsAsync(workspace As Workspace, projectId As ProjectId, documentId As DocumentId, id As Object, includeSuppressedDiagnostics As Boolean, diagnosticMode As Option2(Of DiagnosticMode), cancellationToken As CancellationToken) As ValueTask(Of ImmutableArray(Of DiagnosticData)) Implements IDiagnosticService.GetPushDiagnosticsAsync + Return New ValueTask(Of ImmutableArray(Of DiagnosticData))(GetDiagnostics(workspace, projectId, documentId, includeSuppressedDiagnostics)) End Function Private Function GetDiagnostics( diff --git a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb index 669b790195056..8789ca0e8ac3d 100644 --- a/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb +++ b/src/VisualStudio/Core/Test/Diagnostics/ExternalDiagnosticUpdateSourceTests.vb @@ -494,8 +494,8 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Diagnostics Public Event DiagnosticsUpdated As EventHandler(Of DiagnosticsUpdatedArgs) Implements IDiagnosticUpdateSource.DiagnosticsUpdated Public Event DiagnosticsCleared As EventHandler Implements IDiagnosticUpdateSource.DiagnosticsCleared - Public Function GetDiagnostics(workspace As Workspace, projectId As ProjectId, documentId As DocumentId, id As Object, includeSuppressedDiagnostics As Boolean, cancellationToken As CancellationToken) As ImmutableArray(Of DiagnosticData) Implements IDiagnosticUpdateSource.GetDiagnostics - Return If(includeSuppressedDiagnostics, _data, _data.WhereAsArray(Function(d) Not d.IsSuppressed)) + Public Function GetDiagnosticsAsync(workspace As Workspace, projectId As ProjectId, documentId As DocumentId, id As Object, includeSuppressedDiagnostics As Boolean, cancellationToken As CancellationToken) As ValueTask(Of ImmutableArray(Of DiagnosticData)) Implements IDiagnosticUpdateSource.GetDiagnosticsAsync + Return New ValueTask(Of ImmutableArray(Of DiagnosticData))(If(includeSuppressedDiagnostics, _data, _data.WhereAsArray(Function(d) Not d.IsSuppressed))) End Function Public Sub Reanalyze(workspace As Workspace, Optional projectIds As IEnumerable(Of ProjectId) = Nothing, Optional documentIds As IEnumerable(Of DocumentId) = Nothing, Optional highPriority As Boolean = False) Implements IDiagnosticAnalyzerService.Reanalyze