Skip to content

Commit

Permalink
Don't compute the information for the code definition window if not open
Browse files Browse the repository at this point in the history
If the symbol your caret is over is from metadata, producing the
output might be really expensive, so let's not do it in that case. The
window clears anything when it's opened, so the user won't know it was
never doing anything when closed.
  • Loading branch information
jasonmalinowski committed Oct 21, 2021
1 parent e1b5726 commit 8408670
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ private async Task UpdateForCaretPositionAsync(SnapshotPoint pointInRoslynSnapsh
{
await _asyncListener.Delay(TimeSpan.FromMilliseconds(250), cancellationToken).ConfigureAwait(false);

// If it's not open, don't do anything, since if we are going to show locations in metadata that might
// be expensive. This doesn't cause a functional issue, since opening the window clears whatever was previously there
// so the user won't notice we weren't doing anything when it was open.
if (!await _codeDefinitionWindowService.IsWindowOpenAsync(cancellationToken).ConfigureAwait(false))
{
return;
}

var document = pointInRoslynSnapshot.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.CodeDefinitionWindow
{
internal interface ICodeDefinitionWindowService
{
Task<bool> IsWindowOpenAsync(CancellationToken cancellationToken);
Task SetContextAsync(ImmutableArray<CodeDefinitionWindowLocation> locations, CancellationToken cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ Namespace Microsoft.CodeAnalysis.Editor.CodeDefinitionWindow.UnitTests
Public Sub New()
End Sub

Public Function IsWindowOpenAsync(cancellationToken As CancellationToken) As Task(Of Boolean) Implements ICodeDefinitionWindowService.IsWindowOpenAsync
Throw New NotImplementedException()
End Function

Public Function SetContextAsync(locations As ImmutableArray(Of CodeDefinitionWindowLocation), cancellationToken As CancellationToken) As Task Implements ICodeDefinitionWindowService.SetContextAsync
Throw New NotImplementedException()
End Function
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections.Immutable;
using System.Composition;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
Expand All @@ -23,6 +24,9 @@ internal sealed class VisualStudioCodeDefinitionWindowService : ICodeDefinitionW
private readonly IAsyncServiceProvider _asyncServiceProvider;
private readonly IThreadingContext _threadingContext;

[DisallowNull]
private IVsCodeDefView? _lazyCodeDefView;

[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public VisualStudioCodeDefinitionWindowService(SVsServiceProvider asyncServiceProvider, IThreadingContext threadingContext)
Expand All @@ -31,6 +35,29 @@ public VisualStudioCodeDefinitionWindowService(SVsServiceProvider asyncServicePr
_threadingContext = threadingContext;
}

private async Task<IVsCodeDefView> GetVsCodeDefViewAsync()
{
if (_lazyCodeDefView is not null)
{
return _lazyCodeDefView;
}

_lazyCodeDefView = await _asyncServiceProvider.GetServiceAsync<SVsCodeDefView, IVsCodeDefView>().ConfigureAwait(false);

return _lazyCodeDefView;
}

public async Task<bool> IsWindowOpenAsync(CancellationToken cancellationToken)
{
var vsCodeDefView = await GetVsCodeDefViewAsync().ConfigureAwait(true);

// Switch to the UI thread before using the IVsCodeDefView service
await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

// IsVisible returns S_FALSE if it's not visible
return vsCodeDefView.IsVisible() == VSConstants.S_OK;
}

public async Task SetContextAsync(ImmutableArray<CodeDefinitionWindowLocation> locations, CancellationToken cancellationToken)
{
// If the new context has no location, then just don't update, instead of showing the
Expand Down

0 comments on commit 8408670

Please sign in to comment.