Skip to content

Commit

Permalink
StreamingFindUsagesPresenterOptions (#72343)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmat authored Mar 1, 2024
1 parent 9ecb66e commit 9884888
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal sealed class VSTypeScriptStreamingFindUsagesPresenterAccessor(IStreamin
public (IVSTypeScriptFindUsagesContext context, CancellationToken cancellationToken) StartSearch(
string title, bool supportsReferences)
{
var (context, cancellationToken) = _underlyingObject.StartSearch(title, supportsReferences);
var (context, cancellationToken) = _underlyingObject.StartSearch(title, new StreamingFindUsagesPresenterOptions() { SupportsReferences = supportsReferences });
return (new VSTypeScriptFindUsagesContext(context), cancellationToken);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,14 @@ private async Task StreamingFindReferencesAsync(
// Let the presented know we're starting a search. It will give us back the context object that the FAR
// service will push results into. This operation is not externally cancellable. Instead, the find refs
// window will cancel it if another request is made to use it.
var (context, cancellationToken) = presenter.StartSearchWithCustomColumns(
var (context, cancellationToken) = presenter.StartSearch(
EditorFeaturesResources.Find_References,
supportsReferences: true,
includeContainingTypeAndMemberColumns: document.Project.SupportsCompilation,
includeKindColumn: document.Project.Language != LanguageNames.FSharp);
new StreamingFindUsagesPresenterOptions()
{
SupportsReferences = true,
IncludeContainingTypeAndMemberColumns = document.Project.SupportsCompilation,
IncludeKindColumn = document.Project.Language != LanguageNames.FSharp
});

using (Logger.LogBlock(
FunctionId.CommandHandler_FindAllReference,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ private async Task PresentResultsInStreamingPresenterAsync(
{
var cancellationToken = cancellationTokenSource.Token;
await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
var (presenterContext, presenterCancellationToken) = _streamingPresenter.StartSearch(DisplayName, supportsReferences: false);
var (presenterContext, presenterCancellationToken) = _streamingPresenter.StartSearch(DisplayName, StreamingFindUsagesPresenterOptions.Default);

try
{
Expand Down
35 changes: 23 additions & 12 deletions src/EditorFeatures/Core/Host/IStreamingFindReferencesPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -27,30 +28,40 @@ internal interface IStreamingFindUsagesPresenter
/// etc. etc.
/// </summary>
/// <param name="title">A title to display to the user in the presentation of the results.</param>
/// <param name="supportsReferences">Whether or not showing references is supported.
/// If true, then the presenter can group by definition, showing references underneath.
/// It can also show messages about no references being found at the end of the search.
/// If false, the presenter will not group by definitions, and will show the definition
/// items in isolation.</param>
/// <param name="options">Options</param>
/// <returns>A cancellation token that will be triggered if the presenter thinks the search
/// should stop. This can normally happen if the presenter view is closed, or recycled to
/// start a new search in it. Callers should only use this if they intend to report results
/// asynchronously and thus relinquish their own control over cancellation from their own
/// surrounding context. If the caller intends to populate the presenter synchronously,
/// then this cancellation token can be ignored.</returns>
(FindUsagesContext context, CancellationToken cancellationToken) StartSearch(string title, bool supportsReferences);

/// <summary>
/// Call this method to display the Containing Type, Containing Member, or Kind columns
/// </summary>
(FindUsagesContext context, CancellationToken cancellationToken) StartSearchWithCustomColumns(string title, bool supportsReferences, bool includeContainingTypeAndMemberColumns, bool includeKindColumn);
(FindUsagesContext context, CancellationToken cancellationToken) StartSearch(string title, StreamingFindUsagesPresenterOptions options);

/// <summary>
/// Clears all the items from the presenter.
/// </summary>
void ClearAll();
}

/// <summary>
/// <see cref="IStreamingFindUsagesPresenter.StartSearch(string, StreamingFindUsagesPresenterOptions)"/> options.
/// </summary>
/// <param name="SupportsReferences">
/// Whether or not showing references is supported.
/// If true, then the presenter can group by definition, showing references underneath.
/// It can also show messages about no references being found at the end of the search.
/// If false, the presenter will not group by definitions, and will show the definition
/// items in isolation.</param>
/// <param name="IncludeContainingTypeAndMemberColumns"></param>
/// <param name="IncludeKindColumn"></param>
internal readonly record struct StreamingFindUsagesPresenterOptions(
bool SupportsReferences = false,
bool IncludeContainingTypeAndMemberColumns = false,
bool IncludeKindColumn = false)
{
public static readonly StreamingFindUsagesPresenterOptions Default = new();
}

internal static class IStreamingFindUsagesPresenterExtensions
{
public static async Task<bool> TryPresentLocationOrNavigateIfOneAsync(
Expand Down Expand Up @@ -121,7 +132,7 @@ public static async Task<bool> TryPresentLocationOrNavigateIfOneAsync(
//
// We ignore the cancellation token returned by StartSearch as we're in a context where
// we've computed all the results and we're synchronously populating the UI with it.
var (context, _) = presenter.StartSearch(title, supportsReferences: false);
var (context, _) = presenter.StartSearch(title, StreamingFindUsagesPresenterOptions.Default);
try
{
foreach (var item in navigableItems)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@

#nullable disable

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.FindReferences;
using Microsoft.CodeAnalysis.FindUsages;
using Microsoft.CodeAnalysis.Shared.TestHooks;
Expand Down Expand Up @@ -49,14 +47,11 @@ private class MockStreamingFindUsagesPresenter : IStreamingFindUsagesPresenter
public MockStreamingFindUsagesPresenter(FindUsagesContext context)
=> _context = context;

public (FindUsagesContext, CancellationToken) StartSearch(string title, bool supportsReferences)
=> (_context, CancellationToken.None);

public void ClearAll()
{
}

public (FindUsagesContext, CancellationToken) StartSearchWithCustomColumns(string title, bool supportsReferences, bool includeContainingTypeAndMemberColumns, bool includeKindColumn)
public (FindUsagesContext, CancellationToken) StartSearch(string title, StreamingFindUsagesPresenterOptions options)
=> (_context, CancellationToken.None);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

Imports System.Threading
Imports Microsoft.CodeAnalysis.Editor.Host
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.FindReferences
Imports Microsoft.CodeAnalysis.FindUsages
Imports Microsoft.CodeAnalysis.Shared.TestHooks
Expand Down Expand Up @@ -74,11 +73,7 @@ class C
Public Sub ClearAll() Implements IStreamingFindUsagesPresenter.ClearAll
End Sub

Public Function StartSearch(title As String, supportsReferences As Boolean) As (FindUsagesContext, CancellationToken) Implements IStreamingFindUsagesPresenter.StartSearch
Return (_context, CancellationToken.None)
End Function

Public Function StartSearchWithCustomColumns(title As String, supportsReferences As Boolean, includeContainingTypeAndMemberColumns As Boolean, includeKindColumn As Boolean) As (FindUsagesContext, CancellationToken) Implements IStreamingFindUsagesPresenter.StartSearchWithCustomColumns
Public Function StartSearch(title As String, options As StreamingFindUsagesPresenterOptions) As (FindUsagesContext, CancellationToken) Implements IStreamingFindUsagesPresenter.StartSearch
Return (_context, CancellationToken.None)
End Function
End Class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,9 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities.GoToHelpers
Throw New NotImplementedException()
End Sub

Public Function StartSearch(title As String, alwaysShowDeclarations As Boolean) As (FindUsagesContext, CancellationToken) Implements IStreamingFindUsagesPresenter.StartSearch
Public Function StartSearch(title As String, options As StreamingFindUsagesPresenterOptions) As (FindUsagesContext, CancellationToken) Implements IStreamingFindUsagesPresenter.StartSearch
_action()
Return (Context, CancellationToken.None)
End Function

Public Function StartSearchWithCustomColumns(title As String, supportsReferences As Boolean, includeContainingTypeAndMemberColumns As Boolean, includeKindColumn As Boolean) As (FindUsagesContext, CancellationToken) Implements IStreamingFindUsagesPresenter.StartSearchWithCustomColumns
Return (Context, CancellationToken.None)
End Function
End Class
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public async Task FindSymbolReferencesAsync(ISymbol symbol, Project project, Can
// fire-and-forget streaming fashion). As such, we do not want to use the cancellation
// token provided by the presenter. Instead, we'll let our caller own if this work
// is cancelable.
var (context, _) = streamingPresenter.StartSearch(EditorFeaturesResources.Find_References, supportsReferences: true);
var (context, _) = streamingPresenter.StartSearch(EditorFeaturesResources.Find_References, new StreamingFindUsagesPresenterOptions { SupportsReferences = true });

var classificationOptions = globalOptions.GetClassificationOptionsProvider();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.FindUsages;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Notification;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.TestHooks;
Expand Down Expand Up @@ -47,7 +48,7 @@ internal partial class StreamingFindUsagesPresenter :
public readonly ClassificationTypeMap TypeMap;
public readonly IEditorFormatMapService FormatMapService;
private readonly IAsynchronousOperationListener _asyncListener;
public readonly IClassificationFormatMap ClassificationFormatMap;
private readonly Lazy<IClassificationFormatMap> _lazyClassificationFormatMap;

private readonly Workspace _workspace;
private readonly IGlobalOptionService _globalOptions;
Expand Down Expand Up @@ -121,11 +122,19 @@ private StreamingFindUsagesPresenter(
TypeMap = typeMap;
FormatMapService = formatMapService;
_asyncListener = asyncListenerProvider.GetListener(FeatureAttribute.FindReferences);
ClassificationFormatMap = classificationFormatMapService.GetClassificationFormatMap("tooltip");

_lazyClassificationFormatMap = new Lazy<IClassificationFormatMap>(() =>
{
AssertIsForeground();
return classificationFormatMapService.GetClassificationFormatMap("tooltip");
});

_customColumns = columns.ToImmutableArray();
}

public IClassificationFormatMap ClassificationFormatMap
=> _lazyClassificationFormatMap.Value;

private static IEnumerable<ITableColumnDefinition> GetCustomColumns(IEnumerable<Lazy<ITableColumnDefinition, NameMetadata>> columns)
{
foreach (var column in columns)
Expand Down Expand Up @@ -156,34 +165,10 @@ public void ClearAll()
}
}

/// <summary>
/// Starts a search that will not include Containing Type, Containing Member, or Kind columns
/// </summary>
/// <param name="title"></param>
/// <param name="supportsReferences"></param>
/// <returns></returns>
public (FindUsagesContext context, CancellationToken cancellationToken) StartSearch(string title, bool supportsReferences)
=> StartSearchWithCustomColumns(title, supportsReferences, includeContainingTypeAndMemberColumns: false, includeKindColumn: false);

/// <summary>
/// Start a search that may include Containing Type, Containing Member, or Kind information about the reference
/// </summary>
public (FindUsagesContext context, CancellationToken cancellationToken) StartSearchWithCustomColumns(
string title, bool supportsReferences, bool includeContainingTypeAndMemberColumns, bool includeKindColumn)
{
this.AssertIsForeground();
var context = StartSearchWorker(title, supportsReferences, includeContainingTypeAndMemberColumns, includeKindColumn);

// Keep track of this context object as long as it is being displayed in the UI.
// That way we can Clear it out if requested by a client. When the context is
// no longer being displayed, VS will dispose it and it will remove itself from
// this set.
_currentContexts.Add(context);
return (context, context.CancellationTokenSource!.Token);
}

private AbstractTableDataSourceFindUsagesContext StartSearchWorker(
string title, bool supportsReferences, bool includeContainingTypeAndMemberColumns, bool includeKindColumn)
public (FindUsagesContext context, CancellationToken cancellationToken) StartSearch(string title, StreamingFindUsagesPresenterOptions options)
{
this.AssertIsForeground();

Expand All @@ -205,9 +190,16 @@ private AbstractTableDataSourceFindUsagesContext StartSearchWorker(
StoreCurrentGroupingPriority(window);
}

return supportsReferences
? StartSearchWithReferences(window, desiredGroupingPriority, includeContainingTypeAndMemberColumns, includeKindColumn)
: StartSearchWithoutReferences(window, includeContainingTypeAndMemberColumns, includeKindColumn);
var context = options.SupportsReferences
? StartSearchWithReferences(window, desiredGroupingPriority, options.IncludeContainingTypeAndMemberColumns, options.IncludeKindColumn)
: StartSearchWithoutReferences(window, options.IncludeContainingTypeAndMemberColumns, options.IncludeKindColumn);

// Keep track of this context object as long as it is being displayed in the UI.
// That way we can Clear it out if requested by a client. When the context is
// no longer being displayed, VS will dispose it and it will remove itself from
// this set.
_currentContexts.Add(context);
return (context, context.CancellationTokenSource!.Token);
}

private AbstractTableDataSourceFindUsagesContext StartSearchWithReferences(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ private static async Task FindReferencesAsync(
// Let the presented know we're starting a search. It will give us back the context object that the FAR
// service will push results into. Because we kicked off this work in a fire and forget fashion,
// the presenter owns canceling this work (i.e. if it's closed or if another FAR request is made).
var (context, cancellationToken) = presenter.StartSearch(EditorFeaturesResources.Find_References, supportsReferences: true);
var (context, cancellationToken) = presenter.StartSearch(EditorFeaturesResources.Find_References, new StreamingFindUsagesPresenterOptions { SupportsReferences = true });

try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Imports Microsoft.VisualStudio.Shell.TableControl
Imports Microsoft.VisualStudio.Shell.TableManager
Imports Microsoft.VisualStudio.Text
Imports Roslyn.Test.Utilities
Imports Microsoft.CodeAnalysis.Editor.Host

Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Venus

Expand Down Expand Up @@ -68,7 +69,7 @@ class {|Definition:C1|}
Using workspace = EditorTestWorkspace.Create(input, composition:=composition, documentServiceProvider:=TestDocumentServiceProvider.Instance)

Dim presenter = New StreamingFindUsagesPresenter(workspace, workspace.ExportProvider.AsExportProvider())
Dim tuple = presenter.StartSearch("test", supportsReferences:=True)
Dim tuple = presenter.StartSearch("test", New StreamingFindUsagesPresenterOptions() With {.SupportsReferences = True})
Dim context = tuple.context

Dim cursorDocument = workspace.Documents.First(Function(d) d.CursorPosition.HasValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ public void ClearAll()
{
}

public (FindUsagesContext, CancellationToken) StartSearch(string title, bool supportsReferences)
=> (new SimpleFindUsagesContext(), CancellationToken.None);

public (FindUsagesContext, CancellationToken) StartSearchWithCustomColumns(string title, bool supportsReferences, bool includeContainingTypeAndMemberColumns, bool includeKindColumn)
public (FindUsagesContext, CancellationToken) StartSearch(string title, StreamingFindUsagesPresenterOptions options)
=> (new SimpleFindUsagesContext(), CancellationToken.None);
}
}

0 comments on commit 9884888

Please sign in to comment.