Open mgoertz-msft opened 2 years ago
FYI @tmat
Is this equivalent to to the NameAndFlavor
internal property we already have? If not equivalent, could you clarify how they are different?
I think it is the same as NameAndFlavor
, though this property is rather hacky. We should do better.
I'm fine with doing better. I just wanted to know if 'ContextName' was something different. Note: i think we do need more than one property here. Because there is just the 'Name' (which includes both pieces), and then the 'Context/FlavorName'. But then there's still a need to get the name without the flavor/context name.
I'm fine with doing better. I just wanted to know if 'ContextName' was something different.
It's different. There are two names, meaningfully, for Visual Studio projects:
Rather than exposing the string directly, I'd hope we'd expose APIs more like what is actually needed though. @mgoertz-msft there are already some public APIs for getting the active context and changing context for Roslyn where we'll do all the project system stuff as an implementation detail for you; were those not sufficient here?
The "project system name", which is a name given to us for various legacy VS APIs.
I would really love to not expose that.
@jasonmalinowski OK, so perhaps I haven't found the right APIs then. I need to be able to get and set the active project context's project and listen to an event for when that changes. How would I do that?
@mgoertz-msft So one thing that might be a problem here is we generally speak in terms of a document having an active context, not a project. This was because our model is largely built to support the navigation bar and editor-centric features like classification. To make that a bit more concrete, we don't have a way to ask "what is the active context of this CPS project" as a direct question, instead because [a] we don't actually have a concept of "the CPS project" but also [b] for all you know the file that's added to the CPS project is being linked into another project, and you need the running document table to decide which is really active.
What you can do is go from a text buffer to the DocumentId via GetOpenDocumentInCurrentContext which returns the right context already considering everything. For changes we have this event. It seems setting the method is internal though (Workspace.SetDocumentContext); I admit I'm not sure why that's the case.
@mgoertz-msft Perhaps what might also help here is to have a bit of the (ahem) context? Do you just need a dropdown for XAML editors similar to what we have, or something else?
@jasonmalinowski Correct:
... for other IDE features, such as the XAML language service to look at a hierarchy's current project context to determine the matching Roslyn Project or to implement our own project context switcher
So one thing that might be a problem here is we generally speak in terms of a document having an active context, not a project.
@jasonmalinowski Yes, in this case that is a problem because for multi-targeted projects the VisualStudioWorkspaceImpl sets the __VSHPROPID8.VSHPROPID_ActiveIntellisenseProjectContext
on the hierarchy, which does represent the entire project and not just a document. And that's really the context we need to be able to associate with a Roslyn project, so we can get the correct compilation from the currently active project context for our type system - at least as long as our language service still runs in proc.
How does another C# document (docB) know if the first document's (docA) context has been changed because of a multi-targeting project context switch or because of docA being a linked file? I suppose in that case docA nav bar would show all TFMs in addition to the projects it's linked into and as long as docB is part of the newly active project then its nav bar would switch to that as well. Is that how it works?
Besides that, while GetDocumentIdInCurrentContext works for XAML in MAUI projects, GetRelatedDocumentIds always returns an empty result for the same XAML text container. So to get all the Roslyn projects I currently need to enumerate all projects with the same project file path.
Long story short, it seems that if we were to make Workspace.SetDocumentContext public and support additional files in GetRelatedDocumentIds then we should be able to support nav bars for additional documents in multi-targeting projects.
Background and Motivation
Multi-targeting projects, such as MAUI projects, include multiple TFMs causing the creation of one Roslyn
Project
per TFM. The NavigationBar feature provides support for switching the document context between these Projects, which ends up setting theIVsHierarchy
property__VSHPROPID8.VSHPROPID_ActiveIntellisenseProjectContext
inVisualStudioWorkspaceImpl
.Unfortunately, this there is no API to get the context string from
Project
orProjectId
, so there is no way for other IDE features, such as the XAML language service to look at a hierarchy's current project context to determine the matching RoslynProject
or to implement our own project context switcher.VisualStudioWorkspaceImpl
keeps its own internal map_projectSystemNameToProjectsMap
for this purpose.Thankfully, at least the correct unique project context name is stored as the
ProjectId.DebugName
and can be extracted viaProjectId.ToString()
, which we are going to take advantage of for now, but this is less than ideal and there should really be a dedicated API for this on eitherProject
orProjectId
.Proposed API
Usage Examples
Alternative Designs
If changing the signature of Project/ProjectId is not an option, then perhaps a public extension method could be provided:
Risks
New API, so the risk should be very low.