Skip to content

Commit

Permalink
Merge pull request #75418 from CyrusNajmabadi/navToPosition2
Browse files Browse the repository at this point in the history
Have find references navigate to a position instead of a span
  • Loading branch information
CyrusNajmabadi authored Oct 10, 2024
2 parents b564dc6 + 238bdcb commit 3df983f
Show file tree
Hide file tree
Showing 22 changed files with 123 additions and 130 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

namespace Microsoft.CodeAnalysis.Interactive
{
internal sealed class InteractiveDocumentNavigationService : IDocumentNavigationService
internal sealed class InteractiveDocumentNavigationService : AbstractDocumentNavigationService
{
private readonly IThreadingContext _threadingContext;

Expand All @@ -24,13 +24,10 @@ public InteractiveDocumentNavigationService(IThreadingContext threadingContext)
_threadingContext = threadingContext;
}

public Task<bool> CanNavigateToSpanAsync(Workspace workspace, DocumentId documentId, TextSpan textSpan, bool allowInvalidSpan, CancellationToken cancellationToken)
public override Task<bool> CanNavigateToSpanAsync(Workspace workspace, DocumentId documentId, TextSpan textSpan, bool allowInvalidSpan, CancellationToken cancellationToken)
=> SpecializedTasks.True;

public Task<bool> CanNavigateToPositionAsync(Workspace workspace, DocumentId documentId, int position, int virtualSpace, CancellationToken cancellationToken)
=> SpecializedTasks.False;

public async Task<INavigableLocation?> GetLocationForSpanAsync(Workspace workspace, DocumentId documentId, TextSpan textSpan, bool allowInvalidSpan, CancellationToken cancellationToken)
public override async Task<INavigableLocation?> GetLocationForSpanAsync(Workspace workspace, DocumentId documentId, TextSpan textSpan, bool allowInvalidSpan, CancellationToken cancellationToken)
{
await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
if (workspace is not InteractiveWindowWorkspace interactiveWorkspace)
Expand Down Expand Up @@ -81,8 +78,5 @@ public Task<bool> CanNavigateToPositionAsync(Workspace workspace, DocumentId doc
return true;
});
}

public Task<INavigableLocation?> GetLocationForPositionAsync(Workspace workspace, DocumentId documentId, int position, int virtualSpace, CancellationToken cancellationToken)
=> SpecializedTasks.Null<INavigableLocation>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ protected async Task NavigateToPositionAsync(Workspace workspace, DocumentId doc
var navigationService = workspace.Services.GetRequiredService<IDocumentNavigationService>();

if (!await navigationService.TryNavigateToPositionAsync(
ThreadingContext, workspace, documentId, position, virtualSpace, NavigationOptions.Default, cancellationToken).ConfigureAwait(false))
ThreadingContext, workspace, documentId, position, virtualSpace,
allowInvalidPosition: false, NavigationOptions.Default, cancellationToken).ConfigureAwait(false))
{
// Ensure we're back on the UI thread before showing a failure message.
await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public async Task<bool> TryNavigateToItemAsync(
var workspace = document.Project.Solution.Workspace;
var navigationService = workspace.Services.GetRequiredService<IDocumentNavigationService>();
return await navigationService.TryNavigateToPositionAsync(
_threadingContext, workspace, document.Id, navigationSpan.Start, virtualSpace: 0, NavigationOptions.Default, cancellationToken).ConfigureAwait(false);
_threadingContext, workspace, document.Id, navigationSpan.Start, cancellationToken).ConfigureAwait(false);
}

public bool ShowItemGrayedIfNear(NavigationBarItem item)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ internal abstract partial class AbstractDefinitionLocationService(
var service = workspace.Services.GetRequiredService<IDocumentNavigationService>();

return service.GetLocationForPositionAsync(
workspace, document.Id, position, virtualSpace: 0, cancellationToken);
workspace, document.Id, position, cancellationToken);
}

public async Task<DefinitionLocation?> GetDefinitionLocationAsync(Document document, int position, CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,24 @@ public static async Task<bool> TryNavigateToSpanAsync(
}

public static async Task<bool> TryNavigateToPositionAsync(
this IDocumentNavigationService service, IThreadingContext threadingContext, Workspace workspace, DocumentId documentId, int position, int virtualSpace, NavigationOptions options, CancellationToken cancellationToken)
this IDocumentNavigationService service, IThreadingContext threadingContext, Workspace workspace, DocumentId documentId, int position, int virtualSpace, bool allowInvalidPosition, NavigationOptions options, CancellationToken cancellationToken)
{
var location = await service.GetLocationForPositionAsync(workspace, documentId, position, virtualSpace, cancellationToken).ConfigureAwait(false);
var location = await service.GetLocationForPositionAsync(workspace, documentId, position, virtualSpace, allowInvalidPosition, cancellationToken).ConfigureAwait(false);
return await location.TryNavigateToAsync(threadingContext, options, cancellationToken).ConfigureAwait(false);
}

public static async Task<bool> TryNavigateToPositionAsync(
public static Task<bool> TryNavigateToPositionAsync(
this IDocumentNavigationService service, IThreadingContext threadingContext, Workspace workspace, DocumentId documentId, int position, CancellationToken cancellationToken)
{
return service.TryNavigateToPositionAsync(threadingContext, workspace, documentId, position, NavigationOptions.Default, cancellationToken);
}

public static async Task<bool> TryNavigateToPositionAsync(
this IDocumentNavigationService service, IThreadingContext threadingContext, Workspace workspace, DocumentId documentId, int position, NavigationOptions options, CancellationToken cancellationToken)
{
var location = await service.GetLocationForPositionAsync(
workspace, documentId, position, cancellationToken).ConfigureAwait(false);
return await location.TryNavigateToAsync(threadingContext, NavigationOptions.Default, cancellationToken).ConfigureAwait(false);
return await location.TryNavigateToAsync(threadingContext, options, cancellationToken).ConfigureAwait(false);
}

public static async Task<bool> TryNavigateToLineAndOffsetAsync(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,16 @@ class C
handler.ExecuteCommand(New GoToDefinitionCommandArgs(view, baseDocument.GetTextBuffer()), TestCommandExecutionContext.Create())
Await waiter.ExpeditedWaitAsync()

Assert.True(mockDocumentNavigationService._triedNavigationToSpan)
Assert.Equal(New TextSpan(78, 2), mockDocumentNavigationService._span)
Assert.True(mockDocumentNavigationService._triedNavigationToPosition)
Assert.Equal(78, mockDocumentNavigationService._position)

workspace.SetDocumentContext(linkDocument.Id)

handler.ExecuteCommand(New GoToDefinitionCommandArgs(view, baseDocument.GetTextBuffer()), TestCommandExecutionContext.Create())
Await waiter.ExpeditedWaitAsync()

Assert.True(mockDocumentNavigationService._triedNavigationToSpan)
Assert.Equal(New TextSpan(121, 2), mockDocumentNavigationService._span)
Assert.True(mockDocumentNavigationService._triedNavigationToPosition)
Assert.Equal(121, mockDocumentNavigationService._position)
End Using
End Function

Expand Down Expand Up @@ -107,8 +107,8 @@ int y = x$$</Document>
handler.ExecuteCommand(New GoToDefinitionCommandArgs(view, document.GetTextBuffer()), TestCommandExecutionContext.Create())
Await waiter.ExpeditedWaitAsync()

Assert.True(mockDocumentNavigationService._triedNavigationToSpan)
Assert.Equal(New TextSpan(4, 1), mockDocumentNavigationService._span)
Assert.True(mockDocumentNavigationService._triedNavigationToPosition)
Assert.Equal(4, mockDocumentNavigationService._position)
Assert.Equal(document.Id, mockDocumentNavigationService._documentId)
End Using
End Function
Expand Down Expand Up @@ -157,8 +157,8 @@ class C
handler.ExecuteCommand(New GoToDefinitionCommandArgs(view, document.GetTextBuffer()), TestCommandExecutionContext.Create())
Await waiter.ExpeditedWaitAsync()

Assert.True(mockDocumentNavigationService._triedNavigationToSpan)
Assert.Equal(New TextSpan(22, 1), mockDocumentNavigationService._span)
Assert.True(mockDocumentNavigationService._triedNavigationToPosition)
Assert.Equal(22, mockDocumentNavigationService._position)
Assert.Equal(document.Id, mockDocumentNavigationService._documentId)
End Using
End Function
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.GoToDefinition
Dim definitionDocument = workspace.GetTestDocument(mockDocumentNavigationService._documentId)
Assert.Single(definitionDocument.SelectedSpans)
Dim expected = definitionDocument.SelectedSpans.Single()
Assert.True(expected.Length = 0)
Assert.Equal(expected.Start, mockDocumentNavigationService._position)

' The INavigableItemsPresenter should not have been called
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ Imports System.Threading
Imports Microsoft.CodeAnalysis.Editor.NavigableSymbols
Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Utilities
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.Navigation
Imports Microsoft.CodeAnalysis.Shared.TestHooks
Imports Microsoft.CodeAnalysis.Text
Expand All @@ -17,19 +16,17 @@ Imports Microsoft.VisualStudio.Text
Imports Microsoft.VisualStudio.Utilities

Namespace Microsoft.CodeAnalysis.Editor.UnitTests.NavigableSymbols

<[UseExportProvider]>
<Trait(Traits.Feature, Traits.Features.NavigableSymbols)>
Public Class NavigableSymbolsTest

Private Shared ReadOnly s_composition As TestComposition = EditorTestCompositions.EditorFeatures.AddParts(
GetType(MockDocumentNavigationServiceProvider),
GetType(MockSymbolNavigationServiceProvider))

<WpfFact>
Public Async Function TestCharp() As Task
Dim markup = "
class {|target:C|}
class {|target:|}C
{
{|highlighted:C|}$$ c
}"
Expand Down Expand Up @@ -72,7 +69,7 @@ class {|target:C|}
<WpfFact>
Public Async Function TestVB() As Task
Dim markup = "
Class {|target:C|}
Class {|target:|}C
Dim c as {|highlighted:C|}$$
End Class"
Dim text As String = Nothing
Expand Down Expand Up @@ -140,7 +137,7 @@ End Class"

Dim value As ImmutableArray(Of TextSpan) = Nothing
If spans.TryGetValue("target", value) Then
Assert.Equal(value.First(), navigationService.ProvidedTextSpan)
Assert.Equal(value.First().Start, navigationService.ProvidedPosition)
End If
End Function
End Class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities.GoToHelpers
Public _position As Integer = -1
Public _positionVirtualSpace As Integer = -1

Public Function CanNavigateToPositionAsync(workspace As Workspace, documentId As DocumentId, position As Integer, virtualSpace As Integer, cancellationToken As CancellationToken) As Task(Of Boolean) Implements IDocumentNavigationService.CanNavigateToPositionAsync
Public Function CanNavigateToPositionAsync(workspace As Workspace, documentId As DocumentId, position As Integer, virtualSpace As Integer, allowInvalidPosition As Boolean, cancellationToken As CancellationToken) As Task(Of Boolean) Implements IDocumentNavigationService.CanNavigateToPositionAsync
Return If(_canNavigateToPosition, SpecializedTasks.True, SpecializedTasks.False)
End Function

Public Function CanNavigateToSpanAsync(workspace As Workspace, documentId As DocumentId, textSpan As TextSpan, allowInvalidSpan As Boolean, cancellationToken As CancellationToken) As Task(Of Boolean) Implements IDocumentNavigationService.CanNavigateToSpanAsync
Return If(_canNavigateToSpan, SpecializedTasks.True, SpecializedTasks.False)
End Function

Public Function GetLocationForPositionAsync(workspace As Workspace, documentId As DocumentId, position As Integer, virtualSpace As Integer, cancellationToken As CancellationToken) As Task(Of INavigableLocation) Implements IDocumentNavigationService.GetLocationForPositionAsync
Public Function GetLocationForPositionAsync(workspace As Workspace, documentId As DocumentId, position As Integer, virtualSpace As Integer, allowInvalidPosition As Boolean, cancellationToken As CancellationToken) As Task(Of INavigableLocation) Implements IDocumentNavigationService.GetLocationForPositionAsync
Return Task.FromResult(Of INavigableLocation)(New NavigableLocation(
Function(o, c)
_triedNavigationToPosition = True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities
Public TryNavigateToPositionReturnValue As Boolean = True
Public TryNavigateToSpanReturnValue As Boolean = True

Public Function CanNavigateToPosition(workspace As Workspace, documentId As DocumentId, position As Integer, virtualSpace As Integer, cancellationToken As CancellationToken) As Task(Of Boolean) Implements IDocumentNavigationService.CanNavigateToPositionAsync
Public Function CanNavigateToPosition(workspace As Workspace, documentId As DocumentId, position As Integer, virtualSpace As Integer, allowInvalidPosition As Boolean, cancellationToken As CancellationToken) As Task(Of Boolean) Implements IDocumentNavigationService.CanNavigateToPositionAsync
Me.ProvidedDocumentId = documentId
Me.ProvidedPosition = position
Me.ProvidedVirtualSpace = virtualSpace
Expand All @@ -57,7 +57,7 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.Utilities
Return If(CanNavigateToSpanReturnValue, SpecializedTasks.True, SpecializedTasks.False)
End Function

Public Function GetLocationForPositionAsync(workspace As Workspace, documentId As DocumentId, position As Integer, virtualSpace As Integer, cancellationToken As CancellationToken) As Task(Of INavigableLocation) Implements IDocumentNavigationService.GetLocationForPositionAsync
Public Function GetLocationForPositionAsync(workspace As Workspace, documentId As DocumentId, position As Integer, virtualSpace As Integer, allowInvalidPosition As Boolean, cancellationToken As CancellationToken) As Task(Of INavigableLocation) Implements IDocumentNavigationService.GetLocationForPositionAsync
Me.ProvidedDocumentId = documentId
Me.ProvidedPosition = position
Me.ProvidedVirtualSpace = virtualSpace
Expand Down
3 changes: 2 additions & 1 deletion src/Features/Core/Portable/DocumentSpanExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ private static (Workspace workspace, IDocumentNavigationService service) GetNavi
public static Task<INavigableLocation?> GetNavigableLocationAsync(this DocumentSpan documentSpan, CancellationToken cancellationToken)
{
var (workspace, service) = GetNavigationParts(documentSpan);
return service.GetLocationForSpanAsync(workspace, documentSpan.Document.Id, documentSpan.SourceSpan, allowInvalidSpan: false, cancellationToken);
return service.GetLocationForPositionAsync(
workspace, documentSpan.Document.Id, documentSpan.SourceSpan.Start, cancellationToken);
}

public static async Task<bool> IsHiddenAsync(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public bool TryNavigateToPosition(Workspace workspace, DocumentId documentId, in
return _threadingProvider.Service.Run(async () =>
{
var location = await obj.GetLocationForPositionAsync(
workspace, documentId, position, virtualSpace, cancellationToken).ConfigureAwait(false);
workspace, documentId, position, virtualSpace, allowInvalidPosition: false, cancellationToken).ConfigureAwait(false);
return location != null &&
await location.NavigateToAsync(NavigationOptions.Default, cancellationToken).ConfigureAwait(false);
});
Expand All @@ -44,7 +44,7 @@ public bool TryNavigateToPosition(Workspace workspace, DocumentId documentId, in
return _threadingProvider.Service.Run(async () =>
{
var location = await obj.GetLocationForPositionAsync(
workspace, documentId, position, virtualSpace, cancellationToken).ConfigureAwait(false);
workspace, documentId, position, virtualSpace, allowInvalidPosition: false, cancellationToken).ConfigureAwait(false);
return location != null &&
await location.NavigateToAsync(NavigationOptions.Default, cancellationToken).ConfigureAwait(false);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,11 @@

using System;
using System.Composition;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Navigation;

[ExportWorkspaceService(typeof(IDocumentNavigationService), ServiceLayer.Default), Shared]
[method: ImportingConstructor]
[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
internal sealed class DefaultDocumentNavigationService() : IDocumentNavigationService
{
public Task<bool> CanNavigateToSpanAsync(Workspace workspace, DocumentId documentId, TextSpan textSpan, bool allowInvalidSpan, CancellationToken cancellationToken)
=> SpecializedTasks.False;

public Task<bool> CanNavigateToPositionAsync(Workspace workspace, DocumentId documentId, int position, int virtualSpace, CancellationToken cancellationToken)
=> SpecializedTasks.False;

public Task<INavigableLocation?> GetLocationForSpanAsync(Workspace workspace, DocumentId documentId, TextSpan textSpan, bool allowInvalidSpan, CancellationToken cancellationToken)
=> SpecializedTasks.Null<INavigableLocation>();

public Task<INavigableLocation?> GetLocationForPositionAsync(Workspace workspace, DocumentId documentId, int position, int virtualSpace, CancellationToken cancellationToken)
=> SpecializedTasks.Null<INavigableLocation>();
}
internal sealed class DefaultDocumentNavigationService() : AbstractDocumentNavigationService;
Loading

0 comments on commit 3df983f

Please sign in to comment.