Skip to content

Ensure we do not need to go back to compilations/symbols when a user selects a navbar item.#53887

Merged
CyrusNajmabadi merged 27 commits intodotnet:mainfrom
CyrusNajmabadi:navBarSpans
Jun 5, 2021
Merged

Ensure we do not need to go back to compilations/symbols when a user selects a navbar item.#53887
CyrusNajmabadi merged 27 commits intodotnet:mainfrom
CyrusNajmabadi:navBarSpans

Conversation

@CyrusNajmabadi
Copy link
Contributor

@CyrusNajmabadi CyrusNajmabadi commented Jun 4, 2021

Fixes #53646
Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1334030

Followup to #53878.

This is part of a larger refactoring for navbars. The final form will be that a navbar item can store:

  1. teh full (tracking) span(s) in this document that will be used to determine if the item should be selected based on user position.
  2. the (tracking) span in the document to navigate to if the item is selected.
  3. the doc-id + span if the item should cause navigation to another file (for example, in partial cases).

This PR does '2' and '3'.

@ghost ghost added the Area-IDE label Jun 4, 2021
{
await NavigateToSymbolItemAsync(document, (RoslynNavigationBarItem.SymbolItem)item.UnderlyingItem, cancellationToken).ConfigureAwait(false);
await NavigateToSymbolItemAsync(document, item, (RoslynNavigationBarItem.SymbolItem)item.UnderlyingItem, textSnapshot, cancellationToken).ConfigureAwait(false);
return true;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c# no longer needs to do any sort of complex processing logic when navigating. VB still does, but it's much more minor (And can hopefully be removed ina followup).

Contract.ThrowIfNull(symbolItem.Location.OtherDocumentInfo);
var otherLocation = symbolItem.Location.OtherDocumentInfo.Value;
return Task.FromResult((otherLocation.documentId, otherLocation.navigationSpan.Start, 0));
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by default, all symbol navigation can be driven entirely based on the information stored in the item.

OfType(Of RoslynNavigationBarItem.SymbolItem).
ToList()

Assert.True(navigableItems.Count() = navigableItems.Distinct(New NavigationBarItemNavigationSymbolComparer(isCaseSensitive)).Count(), "The items were not unique by SymbolID and index.")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will see about restoring some sort of check here. but this part was all based on symbolkeys which just has no meaning now.

Dim text = Await destinationDocument.GetTextAsync(cancellationToken).ConfigureAwait(False)
Dim navPoint = NavigationPointHelpers.GetNavigationPoint(text, indentSize:=4, methodBlock)
Return (navigationLocation.documentId, navPoint.Position, navPoint.VirtualSpaces)
End If
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this part is still unfortunate. VB has some really funky legacy behavior here around jumping to a blank line (including into virtual space). I just didn't want to clutter the underlying api even more with this, so i kept this part at the vb editor level. Note though that at least now we still avoid semantics. All the work done here just uses syntax/text, so it should still be better than before.

{
_nextIds.TryGetValue(id, out var nextId);
_nextIds[id] = nextId + 1;
return nextId;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i literally cannot even understand what this logic could have ever meant.

RoslynNavigationBarItem item, Document document, SourceText text, string? containerName = null)
{
if (item is not RoslynNavigationBarItem.SymbolItem symbolItem || symbolItem.SelectionSpan == null)
if (item is not RoslynNavigationBarItem.SymbolItem symbolItem || symbolItem.Location.InDocumentInfo == null)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dibarbet for confirmation. FOr LSP i'm assuming it only supports document symbols navigating within the document.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly it seems to depend on which type we return. SymbolInformation defines its span as a Location which contains both the document and location inside the document. But DocumentSymbol (the newer type) defines the spans as Range which does not not have a document piece. So it seems like SymbolInformation does support navigation between documents, but DocumentSymbol does not.

Additionally, neither DocumentSymbol nor SymbolInformation allow multiple ranges, which we would definitely need for partial declarations. I'm going to see if there are existing issues on these, otherwise I'll file them

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feature request for allowing location in DocumentSymbol
microsoft/language-server-protocol#1255

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol. i love the incosistencies.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feature request for multiple locations
microsoft/language-server-protocol#1285

@CyrusNajmabadi CyrusNajmabadi marked this pull request as ready for review June 4, 2021 20:14
@CyrusNajmabadi CyrusNajmabadi requested review from a team as code owners June 4, 2021 20:14
{
if (item.NavigationSymbolIndex < symbols.CandidateSymbols.Length)
{
symbol = symbols.CandidateSymbols[item.NavigationSymbolIndex];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i legit do not believe this was ever safe or sensible. esp in an oop world.


// See if there are any references in the starting file. We always prefer those for any symbol we find.
var referencesInCurrentFile = allReferences.WhereAsArray(r => r.SyntaxTree == tree);
if (referencesInCurrentFile.Length > 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a possible case where there are caret locations in the current document, but the navigation action should take you to a different document?

It seems like the answer is no for partial types (navigation just takes you to the declaration in the file). And for partial methods it looks like currently 2 different items in the navbar, one for the declaration and one for the implementation. So I'm guessing this case doesn't matter but wanted to confirm

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a possible case where there are caret locations in the current document, but the navigation action should take you to a different document?

I can technically think of a case. You could technically have a symbol that had a part in the current file that was totally hidden. In that case we should instead navigate to the location in another file that was not hidden...

However, we didn't really support that before, so i'm ok with this limitation staying.

@CyrusNajmabadi CyrusNajmabadi enabled auto-merge June 5, 2021 04:23
@CyrusNajmabadi CyrusNajmabadi merged commit f172963 into dotnet:main Jun 5, 2021
@ghost ghost added this to the Next milestone Jun 5, 2021
@CyrusNajmabadi CyrusNajmabadi deleted the navBarSpans branch June 5, 2021 05:28
@RikkiGibson RikkiGibson modified the milestones: Next, 17.0.P2 Jun 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Navigation bar is broken for partial classes

3 participants