Skip to content

Commit cd57e22

Browse files
authored
Merge pull request #9602 from drewnoakes/dep-tree-object-browser
Support navigating to Object Browser from the Dependencies tree
2 parents fa5feb1 + d2feb6e commit cd57e22

File tree

20 files changed

+281
-93
lines changed

20 files changed

+281
-93
lines changed

Directory.Packages.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115
<!-- 3rd party -->
116116
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
117117
<PackageVersion Include="IsExternalInit" Version="1.0.3" />
118+
<PackageVersion Include="PolySharp" Version="1.15.0" />
118119

119120
<!-- Tests -->
120121
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.5.0-preview-20221003-04" />

eng/imports/HostAgnostic.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060

6161
<!-- 3rd party -->
6262
<PackageReference Include="Newtonsoft.Json" />
63-
<PackageReference Include="IsExternalInit" PrivateAssets="all" />
63+
<PackageReference Include="PolySharp" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers" />
6464

6565
<!-- Host-Agnostic Visual Studio -->
6666
<PackageReference Include="Microsoft.VisualStudio.ImageCatalog" />

src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/Menus.vsct

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,19 @@
7676
<Group guid="guidManagedProjectSystemCommandSet" id="DebugTargetMenuDebugFrameworkGroup" priority="0x0100">
7777
<Parent guid="guidManagedProjectSystemCommandSet" id="DebugTargetMenuDebugFrameworkMenu"/>
7878
</Group>
79-
<!-- This is the ordering group. Handles ordering files. -->
79+
<!-- Group added to transitive assembly references -->
80+
<Group guid="guidSHLMainMenu" id="IDG_VS_CTXT_ITEM_OBJECTBROWSER" priority="0x0100">
81+
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_TRANSITIVE_ASSEMBLY_REFERENCE"/>
82+
</Group>
83+
<!-- Group added to transitive COM references -->
84+
<Group guid="guidSHLMainMenu" id="IDG_VS_CTXT_ITEM_OBJECTBROWSER" priority="0x0100">
85+
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_COMREFERENCE"/>
86+
</Group>
87+
<!-- Group added to transitive project references -->
88+
<Group guid="guidSHLMainMenu" id="IDG_VS_CTXT_ITEM_OBJECTBROWSER" priority="0x0100">
89+
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_PROJECTREFERENCE"/>
90+
</Group>
91+
<!-- This is the ordering group. Handles ordering files. -->
8092
<Group guid="guidManagedProjectSystemOrderCommandSet" id="OrderingGroup" priority="0x100">
8193
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE" />
8294
</Group>
@@ -202,33 +214,38 @@
202214
</Button>
203215
</Buttons>
204216
</Commands>
205-
217+
218+
<CommandPlacements>
219+
<CommandPlacement guid="guidVSStd2K" id="ECMD_VIEWREFINOBJECTBROWSER" priority="0x0200">
220+
<Parent guid="guidSHLMainMenu" id="IDG_VS_CTXT_ITEM_OBJECTBROWSER"/>
221+
</CommandPlacement>
222+
</CommandPlacements>
223+
206224
<KeyBindings>
207225
<KeyBinding guid="guidManagedProjectSystemCommandSet" id="cmdidNavigateToProject" editor="guidSolutionExplorerToolWindow" key1="VK_F12"/>
208226
</KeyBindings>
209227

210228
<Symbols>
211229
<GuidSymbol name="guidSolutionExplorerToolWindow" value="{3AE79031-E1BC-11D0-8F78-00A0C9110057}" />
212230

213-
<!-- This is out managed package guid. -->
231+
<!-- The .NET Project System package GUID. -->
214232
<GuidSymbol name="PackageGuidString" value="{860A27C0-B665-47F3-BC12-637E16A1050A}" />
215233

234+
<!-- IDSymbol values should be spaced out, leaving space to add new values in future. -->
235+
216236
<GuidSymbol name="guidDebugTargetHandlerPackage" value="{6e87cfad-6c05-4adf-9cd7-3b7943875b7c}">
217237
<IDSymbol name="DebugTargetMenuControllerGroup" value="0x1000" />
218238
<IDSymbol name="DebugTargetMenuControllerFooterGroup" value="0x2000" />
219-
220239
</GuidSymbol>
221240

222241
<GuidSymbol name="guidManagedProjectSystemCommandSet" value="{568ABDF7-D522-474D-9EED-34B5E5095BA5}">
223-
<!-- Note that these need room to grow hence they need to be spaced out-->
224242
<IDSymbol name="cmdidProjectDebugger" value="0x0100" />
225243
<IDSymbol name="cmdidGenerateNuGetPackageProjectContextMenu" value="0x2000" />
226244
<IDSymbol name="cmdidGenerateNuGetPackageTopLevelBuild" value="0x2001" />
227245
<IDSymbol name="cmdidNavigateToProject" value="0x2002" />
228246
<IDSymbol name="DebugTargetMenuDebugFrameworkMenu" value="0x3000" />
229247
<IDSymbol name="DebugTargetMenuDebugFrameworkGroup" value="0x3001" />
230-
<IDSymbol name="cmdidDebugFrameworks" value="0x3050" /> <!--needs space to grow-->
231-
248+
<IDSymbol name="cmdidDebugFrameworks" value="0x3050" />
232249
<IDSymbol name="NavigateGroup" value="0x4000" />
233250
</GuidSymbol>
234251

@@ -247,8 +264,11 @@
247264
</GuidSymbol>
248265

249266
<GuidSymbol name="guidSHLMainMenu" value="{ 0xd309f791, 0x903f, 0x11d0, { 0x9e, 0xfc, 0x00, 0xa0, 0xc9, 0x11, 0x00, 0x4f } }">
267+
<IDSymbol name="IDM_VS_CTXT_COMREFERENCE" value="0x04A5" />
268+
<IDSymbol name="IDG_VS_CTXT_ITEM_OBJECTBROWSER" value="0x02F6" />
250269
<IDSymbol name="IDM_VS_CTXT_PROJECTREFERENCE" value="0x04A7"/>
251270
<IDSymbol name="IDM_VS_CTXT_SHAREDPROJECTREFERENCE" value="0x04A8" />
271+
<IDSymbol name="IDM_VS_CTXT_TRANSITIVE_ASSEMBLY_REFERENCE" value="0x04B1" />
252272
</GuidSymbol>
253273

254274
<GuidSymbol name="SlnExplorerGuid" value="{3AE79031-E1BC-11D0-8F78-00A0C9110057}" />

src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/Microsoft.VisualStudio.ProjectSystem.Managed.VS.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<CreateVsixContainer>false</CreateVsixContainer>
1414
<UseCodebase>false</UseCodebase>
1515

16-
<!-- Nuget -->
16+
<!-- NuGet -->
1717
<IsPackable>true</IsPackable>
1818
<Description>Microsoft VisualStudio ProjectSystem for Managed Languages Project hosts that interact with VisualStudio interfaces.</Description>
1919
<Summary>Microsoft VisualStudio Managed Project System VS Components</Summary>
@@ -29,6 +29,7 @@
2929
<PackageReference Include="Microsoft.VisualStudio.HotReload.Components" />
3030
<PackageReference Include="Microsoft.VisualStudio.ProjectSystem.Query" />
3131
<PackageReference Include="Microsoft.VisualStudio.ProjectSystem.VS" />
32+
<PackageReference Include="IsExternalInit" PrivateAssets="all" />
3233
</ItemGroup>
3334

3435
<ItemGroup>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE.md file in the project root for more information.
2+
3+
namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.AttachedCollections;
4+
5+
/// <summary>
6+
/// Used by implementations of <see cref="IRelatableItem"/> that support opening in Visual Studio's Object Browser via their context menu.
7+
/// </summary>
8+
public interface IObjectBrowserItem : IRelatableItem
9+
{
10+
/// <summary>
11+
/// Gets the absolute path to an assembly that should be opened in the Object Browser.
12+
/// </summary>
13+
string? AssemblyPath { get; }
14+
}

src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Tree/Dependencies/AttachedCollections/Implementation/FrameworkReferenceAssemblyItem.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77

88
namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.AttachedCollections.Implementation
99
{
10-
internal sealed class FrameworkReferenceAssemblyItem : RelatableItemBase
10+
internal sealed class FrameworkReferenceAssemblyItem : RelatableItemBase, IObjectBrowserItem
1111
{
1212
private const int IDM_VS_CTXT_TRANSITIVE_ASSEMBLY_REFERENCE = 0x04B1;
1313

14-
private static readonly IContextMenuController s_defaultMenuController = new MenuController(VsMenus.guidSHLMainMenu, IDM_VS_CTXT_TRANSITIVE_ASSEMBLY_REFERENCE);
14+
private static readonly IContextMenuController s_defaultMenuController = CreateContextMenuController(VsMenus.guidSHLMainMenu, IDM_VS_CTXT_TRANSITIVE_ASSEMBLY_REFERENCE);
1515

1616
public string AssemblyName { get; }
1717
public string? Path { get; }
@@ -38,33 +38,33 @@ public FrameworkReferenceAssemblyItem(string assemblyName, string? path, string?
3838

3939
public override object? GetBrowseObject() => new BrowseObject(this);
4040

41-
private sealed class BrowseObject : LocalizableProperties
42-
{
43-
private readonly FrameworkReferenceAssemblyItem _item;
41+
string? IObjectBrowserItem.AssemblyPath => GetAssemblyPath();
4442

45-
public BrowseObject(FrameworkReferenceAssemblyItem log) => _item = log;
43+
private string? GetAssemblyPath() => Path is not null
44+
? System.IO.Path.GetFullPath(System.IO.Path.Combine(Framework.Path, Path))
45+
: null;
4646

47-
public override string GetComponentName() => _item.AssemblyName;
47+
private sealed class BrowseObject(FrameworkReferenceAssemblyItem item) : LocalizableProperties
48+
{
49+
public override string GetComponentName() => item.AssemblyName;
4850

4951
public override string GetClassName() => VSResources.FrameworkAssemblyBrowseObjectClassName;
5052

5153
[BrowseObjectDisplayName(nameof(VSResources.FrameworkAssemblyAssemblyNameDisplayName))]
5254
[BrowseObjectDescription(nameof(VSResources.FrameworkAssemblyAssemblyNameDescription))]
53-
public string AssemblyName => _item.Text;
55+
public string AssemblyName => item.Text;
5456

5557
[BrowseObjectDisplayName(nameof(VSResources.FrameworkAssemblyPathDisplayName))]
5658
[BrowseObjectDescription(nameof(VSResources.FrameworkAssemblyPathDescription))]
57-
public string Path => _item.Path is not null
58-
? System.IO.Path.GetFullPath(System.IO.Path.Combine(_item.Framework.Path, _item.Path))
59-
: "";
59+
public string Path => item.GetAssemblyPath() ?? "";
6060

6161
[BrowseObjectDisplayName(nameof(VSResources.FrameworkAssemblyAssemblyVersionDisplayName))]
6262
[BrowseObjectDescription(nameof(VSResources.FrameworkAssemblyAssemblyVersionDescription))]
63-
public string AssemblyVersion => _item.AssemblyVersion ?? "";
63+
public string AssemblyVersion => item.AssemblyVersion ?? "";
6464

6565
[BrowseObjectDisplayName(nameof(VSResources.FrameworkAssemblyFileVersionDisplayName))]
6666
[BrowseObjectDescription(nameof(VSResources.FrameworkAssemblyFileVersionDescription))]
67-
public string FileVersion => _item.FileVersion ?? "";
67+
public string FileVersion => item.FileVersion ?? "";
6868
}
6969
}
7070
}

src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Tree/Dependencies/AttachedCollections/RelatableItemBase.DefaultContextMenuController.cs

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,78 @@ namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.AttachedColl
99
{
1010
public abstract partial class RelatableItemBase
1111
{
12-
internal sealed class MenuController : IContextMenuController
13-
{
14-
private readonly Guid _menuGuid;
15-
private readonly int _menuId;
12+
/// <summary>
13+
/// Creates a <see cref="IContextMenuController"/> for use in overrides of <see cref="ContextMenuController"/>.
14+
/// </summary>
15+
public static IContextMenuController CreateContextMenuController(Guid menuGuid, int menuId) => new MenuController(menuGuid, menuId);
1616

17-
public MenuController(Guid menuGuid, int menuId)
18-
{
19-
_menuGuid = menuGuid;
20-
_menuId = menuId;
21-
}
17+
internal sealed class MenuController(Guid menuGuid, int menuId) : IContextMenuController
18+
{
19+
public static ImmutableArray<IRelatableItem> CurrentItems { get; private set; } = [];
2220

2321
public bool ShowContextMenu(IEnumerable<object> items, Point location)
2422
{
25-
bool shouldShowMenu = items.All(item => item is IRelatableItem);
23+
ImmutableArray<IRelatableItem>? relatableItems = GetItems();
24+
25+
if (relatableItems is null)
26+
{
27+
return false;
28+
}
29+
30+
CurrentItems = relatableItems.Value;
31+
32+
try
33+
{
34+
return ShowContextMenu();
35+
}
36+
finally
37+
{
38+
CurrentItems = [];
39+
}
2640

27-
if (shouldShowMenu)
41+
ImmutableArray<IRelatableItem>? GetItems()
42+
{
43+
ImmutableArray<IRelatableItem>.Builder? builder = null;
44+
45+
foreach (object item in items)
46+
{
47+
if (item is IRelatableItem relatableItem)
48+
{
49+
builder ??= ImmutableArray.CreateBuilder<IRelatableItem>();
50+
builder.Add(relatableItem);
51+
}
52+
else
53+
{
54+
return null;
55+
}
56+
}
57+
58+
if (builder is null)
59+
{
60+
return null;
61+
}
62+
63+
return builder.ToImmutable();
64+
}
65+
66+
bool ShowContextMenu()
2867
{
2968
if (Package.GetGlobalService(typeof(SVsUIShell)) is IVsUIShell shell)
3069
{
31-
Guid guidContextMenu = _menuGuid;
70+
Guid guidContextMenu = menuGuid;
3271

3372
int result = shell.ShowContextMenu(
3473
dwCompRole: 0,
3574
rclsidActive: ref guidContextMenu,
36-
nMenuId: _menuId,
37-
pos: new[] { new POINTS { x = (short)location.X, y = (short)location.Y } },
75+
nMenuId: menuId,
76+
pos: [new POINTS { x = (short)location.X, y = (short)location.Y }],
3877
pCmdTrgtActive: null);
3978

4079
return ErrorHandler.Succeeded(result);
4180
}
42-
}
4381

44-
return false;
82+
return false;
83+
}
4584
}
4685
}
4786
}

src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/ProjectSystem/VS/Tree/Dependencies/AttachedCollections/RelatableItemBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public abstract partial class RelatableItemBase : AttachedCollectionItemBase, IR
1414
{
1515
private const int IDM_VS_CTXT_DEPENDENCY_TRANSITIVE_ITEM = 0x04B0;
1616

17-
private static readonly IContextMenuController s_defaultMenuController = new MenuController(VsMenus.guidSHLMainMenu, IDM_VS_CTXT_DEPENDENCY_TRANSITIVE_ITEM);
17+
private static readonly IContextMenuController s_defaultMenuController = CreateContextMenuController(VsMenus.guidSHLMainMenu, IDM_VS_CTXT_DEPENDENCY_TRANSITIVE_ITEM);
1818

1919
private AggregateContainsRelationCollection? _containsCollection;
2020

0 commit comments

Comments
 (0)