Skip to content

Commit

Permalink
Merge pull request #19188 from tmeschter/FixHierarchyMapper
Browse files Browse the repository at this point in the history
Consider name when matching hierarchy items to projects
  • Loading branch information
tmeschter authored May 3, 2017
2 parents 454e442 + 4e3db2b commit 8f02e04
Showing 1 changed file with 16 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,16 @@ public bool TryGetProjectId(IVsHierarchyItem hierarchyItem, string targetFramewo
return false;
}

// A project node is represented in two different hierarchies: the solution's IVsHierarchy (where it is a leaf node)
// and the project's own IVsHierarchy (where it is the root node). The IVsHierarchyItem joins them together for the
// purpose of creating the tree displayed in Solution Explorer. The project's hierarchy is what is passed from the
// project system to the language service, so that's the one the one to query here. To do that we need to get
// the "nested" hierarchy from the IVsHierarchyItem.
var nestedHierarchy = hierarchyItem.HierarchyIdentity.NestedHierarchy;
var nestedHierarchyId = hierarchyItem.HierarchyIdentity.NestedItemID;

if (!nestedHierarchy.TryGetCanonicalName(nestedHierarchyId, out string nestedCanonicalName))
if (!nestedHierarchy.TryGetCanonicalName(nestedHierarchyId, out string nestedCanonicalName)
|| !nestedHierarchy.TryGetItemName(nestedHierarchyId, out string nestedName))
{
projectId = default(ProjectId);
return false;
Expand All @@ -41,8 +47,16 @@ public bool TryGetProjectId(IVsHierarchyItem hierarchyItem, string targetFramewo
var project = _workspace.DeferredState.ProjectTracker.ImmutableProjects
.Where(p =>
{
// Here we try to match the hierarchy from Solution Explorer to a hierarchy from the Roslyn project.
// The canonical name of a hierarchy item must be unique _within_ an hierarchy, but since we're
// examining multiple hierarchies the canonical name could be the same. Indeed this happens when two
// project files are in the same folder--they both use the full path to the _folder_ as the canonical
// name. To distinguish them we also examine the "regular" name, which will necessarily be different
// if the two projects are in the same folder.
if (p.Hierarchy.TryGetCanonicalName((uint)VSConstants.VSITEMID.Root, out string projectCanonicalName)
&& projectCanonicalName.Equals(nestedCanonicalName, System.StringComparison.OrdinalIgnoreCase))
&& p.Hierarchy.TryGetItemName((uint)VSConstants.VSITEMID.Root, out string projectName)
&& projectCanonicalName.Equals(nestedCanonicalName, System.StringComparison.OrdinalIgnoreCase)
&& projectName.Equals(nestedName))
{
if (targetFrameworkMoniker == null)
{
Expand Down

0 comments on commit 8f02e04

Please sign in to comment.