Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix navigation in findrefs #55979

Merged
merged 2 commits into from
Aug 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ internal partial class StreamingFindUsagesPresenter
/// contents of that line, and hovering will reveal a tooltip showing that line along
/// with a few lines above/below it.
/// </summary>
private class DocumentSpanEntry : AbstractDocumentSpanEntry, ISupportsNavigation
private sealed class DocumentSpanEntry : AbstractDocumentSpanEntry, ISupportsNavigation
{
private readonly HighlightSpanKind _spanKind;
private readonly ExcerptResult _excerptResult;
Expand Down Expand Up @@ -280,30 +280,37 @@ private static Span GetRegionSpanForReference(SourceText sourceText, TextSpan so
sourceText.Lines[lastLineNumber].End);
}

async Task<bool> ISupportsNavigation.TryNavigateToAsync(bool isPreview, CancellationToken cancellationToken)
public bool CanNavigateTo()
{
// If the document is a source generated document, we need to do the navigation ourselves;
// this is because the file path given to the table control isn't a real file path to a file
// on disk.
if (_excerptResult.Document is SourceGeneratedDocument)
{
var workspace = _excerptResult.Document.Project.Solution.Workspace;
var documentNavigationService = workspace.Services.GetService<IDocumentNavigationService>();

if (documentNavigationService != null)
{
await this.Presenter.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
return documentNavigationService.TryNavigateToSpan(
workspace,
_excerptResult.Document.Id,
_excerptResult.Span,
workspace.Options.WithChangedOption(NavigationOptions.PreferProvisionalTab, isPreview),
cancellationToken);
}
return documentNavigationService != null;
}

return false;
}

public Task NavigateToAsync(bool isPreview, CancellationToken cancellationToken)
{
Contract.ThrowIfFalse(CanNavigateTo());

// If the document is a source generated document, we need to do the navigation ourselves;
// this is because the file path given to the table control isn't a real file path to a file
// on disk.

var workspace = _excerptResult.Document.Project.Solution.Workspace;
var documentNavigationService = workspace.Services.GetRequiredService<IDocumentNavigationService>();

return documentNavigationService.TryNavigateToSpanAsync(
workspace,
_excerptResult.Document.Id,
_excerptResult.Span,
workspace.Options.WithChangedOption(NavigationOptions.PreferProvisionalTab, isPreview),
cancellationToken);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// See the LICENSE file in the project root for more information.

using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.Wpf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@ public MetadataDefinitionItemEntry(
return null;
}

Task<bool> ISupportsNavigation.TryNavigateToAsync(bool isPreview, CancellationToken cancellationToken)
public bool CanNavigateTo()
=> true;

public Task NavigateToAsync(bool isPreview, CancellationToken cancellationToken)
=> DefinitionBucket.DefinitionItem.TryNavigateToAsync(
Presenter._workspace, showInPreviewTab: isPreview, activateTab: !isPreview, cancellationToken); // Only activate the tab if not opening in preview

protected override IList<Inline> CreateLineTextInlines()
=> DefinitionBucket.DefinitionItem.DisplayParts
.ToInlines(Presenter.ClassificationFormatMap, Presenter.TypeMap);
.ToInlines(Presenter.ClassificationFormatMap, Presenter.TypeMap);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.Shell.TableManager;
using Roslyn.Utilities;

namespace Microsoft.VisualStudio.LanguageServices.FindUsages
{
internal partial class StreamingFindUsagesPresenter
{
private class SimpleMessageEntry : Entry, ISupportsNavigation
private sealed class SimpleMessageEntry : Entry, ISupportsNavigation
{
private readonly RoslynDefinitionBucket? _navigationBucket;
private readonly string _message;
Expand Down Expand Up @@ -44,8 +45,15 @@ public static Task<Entry> CreateAsync(
};
}

public async Task<bool> TryNavigateToAsync(bool isPreview, CancellationToken cancellationToken)
=> _navigationBucket != null && await _navigationBucket.TryNavigateToAsync(isPreview, cancellationToken).ConfigureAwait(false);
public bool CanNavigateTo()
=> _navigationBucket != null && _navigationBucket.CanNavigateTo();

public Task NavigateToAsync(bool isPreview, CancellationToken cancellationToken)
{
Contract.ThrowIfFalse(CanNavigateTo());
Contract.ThrowIfNull(_navigationBucket);
return _navigationBucket.NavigateToAsync(isPreview, cancellationToken);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,15 @@ public override void PreprocessNavigate(ITableEntryHandle entry, TableEntryNavig
{
var supportsNavigation = entry.Identity as ISupportsNavigation ??
(entry.TryGetValue(StreamingFindUsagesPresenter.SelfKeyName, out var item) ? item as ISupportsNavigation : null);
if (supportsNavigation == null)
if (supportsNavigation != null &&
supportsNavigation.CanNavigateTo())
{
base.PreprocessNavigate(entry, e);
return;
// Fire and forget
e.Handled = true;
_ = ProcessNavigateAsync(supportsNavigation, e, _listener, _operationExecutor);
}

// Fire and forget
e.Handled = true;
_ = ProcessNavigateAsync(supportsNavigation, e, _listener, _operationExecutor);

base.PreprocessNavigate(entry, e);
return;

async static Task ProcessNavigateAsync(
Expand All @@ -83,7 +82,7 @@ async static Task ProcessNavigateAsync(
allowCancellation: true,
showProgress: false);

await supportsNavigation.TryNavigateToAsync(e.IsPreview, context.UserCancellationToken).ConfigureAwait(false);
await supportsNavigation.NavigateToAsync(e.IsPreview, context.UserCancellationToken).ConfigureAwait(false);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace Microsoft.VisualStudio.LanguageServices.FindUsages
{
internal interface ISupportsNavigation
{
Task<bool> TryNavigateToAsync(bool isPreview, CancellationToken cancellationToken);
bool CanNavigateTo();
Task NavigateToAsync(bool isPreview, CancellationToken cancellationToken);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ public static RoslynDefinitionBucket Create(
name, expandedByDefault, presenter, context, definitionItem);
}

public Task<bool> TryNavigateToAsync(bool isPreview, CancellationToken cancellationToken)
public bool CanNavigateTo()
=> true;

public Task NavigateToAsync(bool isPreview, CancellationToken cancellationToken)
=> DefinitionItem.TryNavigateToAsync(
_presenter._workspace, showInPreviewTab: isPreview, activateTab: !isPreview, cancellationToken); // Only activate the tab if not opening in preview

Expand Down