Add feature to show users what global-usings are in scope at the top of a file.#60893
Conversation
| if (allDeclarationNodes.IsEmpty) | ||
|
|
||
| var syntaxFacts = document.GetRequiredLanguageService<ISyntaxFactsService>(); | ||
| var imports = syntaxFacts.GetImportsOfCompilationUnit(root); |
There was a problem hiding this comment.
will likely need to move this OOP.
| => new( | ||
| member.DisplayTexts.JoinText(), | ||
| member.Glyph.GetImageMoniker(), | ||
| InheritanceMarginHelpers.CreateModelsForTargetItems(member.TargetItems)); |
There was a problem hiding this comment.
inlined to single caller.
src/VisualStudio/Core/Def/InheritanceMargin/InheritanceMarginTag.cs
Outdated
Show resolved
Hide resolved
davidwengier
left a comment
There was a problem hiding this comment.
you're "inheriting" these using-directives
I'll remember this. Next time you tell me I put something in the wrong place, you just watch out!
| // project level imports come first. | ||
| (null, not null) => -1, | ||
| (not null, null) => 1, | ||
| // both are from different files. Sort by file path first, then location in file if same file path. |
There was a problem hiding this comment.
I wonder if this distinction is useful, or if just sorting them all alphabetically is just as good?
Related: By "project level" do you mean the VB global imports that are specified on the command line? Because if so, isn't it impossible for "project level imports" and "global usings" to appear int he same list, since they're relevant to different languages?
Update: After looking at the rest of the PR, yes, the above is true. So I guess my comment is "this could potentially just be simplified to sort by namespace and nobody will care". Potentially.
There was a problem hiding this comment.
I wonder if this distinction is useful, or if just sorting them all alphabetically is just as good?
I def like sorting as per the items in a file, as that makes it feel like you're getting a little view into that file :)
There was a problem hiding this comment.
Related: By "project level" do you mean the VB global imports that are specified on the command line? Because if so, isn't it impossible for "project level imports" and "global usings" to appear int he same list, since they're relevant to different languages?
you are correct. the above is a little bit of paranoia... i'll see if i can comfortably clean it up though!
| InheritanceRelationship.OverriddenMember => ServicesVSResources.Overridden_members, | ||
| InheritanceRelationship.OverridingMember => ServicesVSResources.Overriding_members, | ||
| InheritanceRelationship.ImplementingMember => ServicesVSResources.Implementing_members, | ||
| InheritanceRelationship.InheritedImport => item.DisplayTexts.JoinText(), |
There was a problem hiding this comment.
Nope! this is already localized.
| DisplayTexts = displayTexts; | ||
| Glyph = glyph; | ||
| TargetItems = targetItems; | ||
| TargetItems = isOrdered ? targetItems : targetItems.OrderBy(item => item.DisplayName).ToImmutableArray(); |
There was a problem hiding this comment.
Seems like a place might be benefited from our offline discussion. (Move all the data processing part to OOP)
I am fine with this approach now, but could you add a comment here to explain isOrdered would only be used for showing the global using?
There was a problem hiding this comment.
yup. i will move this OOP and add the comment.
| /// </summary> | ||
| public readonly int LineNumber; | ||
|
|
||
| public readonly string? TopLevelDisplayText; |
There was a problem hiding this comment.
Similar comments as other comment, could you add a comment here to explain this would only be used showing global usings?
I would help when later I start refactoring this
|
InheritanceMargin is controlled by this Option https://sourceroslyn.io/#Microsoft.VisualStudio.LanguageServices/InheritanceMargin/InheritanceMarginTaggerProvider.cs,100 Do you feel it would be fine to also let this feature controlled by this option? |
|
The overall approach LGTM. I guess there are still some in progress works so just ping me after it's done I can take a second look. Two potential future items (not blocking issue for this features) in my mind:
|
i think i'll add an option for this. |
| @@ -1,107 +0,0 @@ | |||
| // Licensed to the .NET Foundation under one or more agreements. | |||
There was a problem hiding this comment.
this was moved down to Features. Unfortunatelly, github seems to view it as a delete :(
| namespace Microsoft.CodeAnalysis.CSharp.InheritanceMargin | ||
| { | ||
| [ExportLanguageService(typeof(IInheritanceMarginService), LanguageNames.CSharp), Shared] | ||
| internal class CSharpInheritanceMarginService : AbstractInheritanceMarginService |
There was a problem hiding this comment.
these types moved to Features level. That way they can also be used by the remote service, while still utilizing inheritance (instead of statics).
| [DataContract] | ||
| internal readonly struct DocumentIdSpan | ||
| { | ||
| private readonly Workspace _workspace; |
There was a problem hiding this comment.
remove workspace. That allowed thsi type to become serializable, which made it so all the types in inheritance margin can be serializable themselves (no need for a duplicate hierarchy).
| public async ValueTask<ImmutableArray<InheritanceMarginItem>> GetInheritanceMemberItemsAsync( | ||
| Document document, | ||
| TextSpan spanToSearch, | ||
| CancellationToken cancellationToken) |
There was a problem hiding this comment.
this was a move, but the logic here did change somewhat. namely that we can still call into OOP, even if we have no membersymbolkeys (since we may have global imports).
| private async ValueTask<(Project remapped, SymbolKeyAndLineNumberArray symbolKeyAndLineNumbers)> GetMemberSymbolKeysAsync( | ||
| Document document, | ||
| TextSpan spanToSearch, | ||
| CancellationToken cancellationToken) |
There was a problem hiding this comment.
this was an extract method. however, isntead of calling into oop, it determines what data it wants to call into oop with.
| namespace Microsoft.CodeAnalysis.InheritanceMargin | ||
| { | ||
| internal static class InheritanceMarginServiceHelper | ||
| internal abstract partial class AbstractInheritanceMarginService |
There was a problem hiding this comment.
this became non-static and a partial part of AbstractInheritanceMarginService. taht way it can benefit from inheritance for when we want C# and VB to differ in behavior (for example, titles of htings).
| TextSpan spanToSearch, | ||
| ArrayBuilder<InheritanceMarginItem> items, | ||
| CancellationToken cancellationToken) | ||
| { |
There was a problem hiding this comment.
this is new logic for this PR.
| namespace Microsoft.CodeAnalysis.InheritanceMargin | ||
| { | ||
| [DataContract] | ||
| internal readonly struct InheritanceMarginItem |
There was a problem hiding this comment.
made these types into message-pack compatible types. this allowes us to get rid of the SerializableXXX siblings.
…ag.cs Co-authored-by: Joey Robichaud <joseph.robichaud@microsoft.com>
…i/roslyn into globalUsingsMargin
|
@Cosifne this is ready for review. |
Depends on #59533. So Draft PR for now.
I'm reusing 'inheritance' margin because (if you squint) you're "inheriting" these using-directives from the global scope.
Looks like this:
When clicking on that item, you get:
Clicking on any item takes you to the declaration location for it:
If you have multiple files bringing in directives, this shows up as:
Todo: