Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support navigating to Object Browser from the Dependencies tree #9602

Merged
merged 9 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
<!-- 3rd party -->
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="IsExternalInit" Version="1.0.3" />
<PackageVersion Include="PolySharp" Version="1.15.0" />

<!-- Tests -->
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.5.0-preview-20221003-04" />
Expand Down
2 changes: 1 addition & 1 deletion eng/imports/HostAgnostic.props
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@

<!-- 3rd party -->
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="IsExternalInit" PrivateAssets="all" />
<PackageReference Include="PolySharp" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers" />
Copy link
Contributor

@zewditu zewditu Dec 4, 2024

Choose a reason for hiding this comment

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

I wish to learn more if there is a document I can refer about such kind setting more properties or constraint in package reference.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think this document should cover that info: https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files

Let me know if there are specific questions that doc doesn't answer for you.

Note that the change here is based on the recommendation from NuGet.org: https://www.nuget.org/packages/PolySharp/


<!-- Host-Agnostic Visual Studio -->
<PackageReference Include="Microsoft.VisualStudio.ImageCatalog" />
Expand Down
34 changes: 27 additions & 7 deletions src/Microsoft.VisualStudio.ProjectSystem.Managed.VS/Menus.vsct
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,19 @@
<Group guid="guidManagedProjectSystemCommandSet" id="DebugTargetMenuDebugFrameworkGroup" priority="0x0100">
<Parent guid="guidManagedProjectSystemCommandSet" id="DebugTargetMenuDebugFrameworkMenu"/>
</Group>
<!-- This is the ordering group. Handles ordering files. -->
<!-- Group added to transitive assembly references -->
<Group guid="guidSHLMainMenu" id="IDG_VS_CTXT_ITEM_OBJECTBROWSER" priority="0x0100">
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_TRANSITIVE_ASSEMBLY_REFERENCE"/>
</Group>
<!-- Group added to transitive COM references -->
<Group guid="guidSHLMainMenu" id="IDG_VS_CTXT_ITEM_OBJECTBROWSER" priority="0x0100">
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_COMREFERENCE"/>
</Group>
<!-- Group added to transitive project references -->
<Group guid="guidSHLMainMenu" id="IDG_VS_CTXT_ITEM_OBJECTBROWSER" priority="0x0100">
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_PROJECTREFERENCE"/>
</Group>
<!-- This is the ordering group. Handles ordering files. -->
<Group guid="guidManagedProjectSystemOrderCommandSet" id="OrderingGroup" priority="0x100">
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE" />
</Group>
Expand Down Expand Up @@ -202,33 +214,38 @@
</Button>
</Buttons>
</Commands>


<CommandPlacements>
<CommandPlacement guid="guidVSStd2K" id="ECMD_VIEWREFINOBJECTBROWSER" priority="0x0200">
<Parent guid="guidSHLMainMenu" id="IDG_VS_CTXT_ITEM_OBJECTBROWSER"/>
</CommandPlacement>
</CommandPlacements>

<KeyBindings>
<KeyBinding guid="guidManagedProjectSystemCommandSet" id="cmdidNavigateToProject" editor="guidSolutionExplorerToolWindow" key1="VK_F12"/>
</KeyBindings>

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

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

<!-- IDSymbol values should be spaced out, leaving space to add new values in future. -->

<GuidSymbol name="guidDebugTargetHandlerPackage" value="{6e87cfad-6c05-4adf-9cd7-3b7943875b7c}">
<IDSymbol name="DebugTargetMenuControllerGroup" value="0x1000" />
<IDSymbol name="DebugTargetMenuControllerFooterGroup" value="0x2000" />

</GuidSymbol>

<GuidSymbol name="guidManagedProjectSystemCommandSet" value="{568ABDF7-D522-474D-9EED-34B5E5095BA5}">
<!-- Note that these need room to grow hence they need to be spaced out-->
<IDSymbol name="cmdidProjectDebugger" value="0x0100" />
<IDSymbol name="cmdidGenerateNuGetPackageProjectContextMenu" value="0x2000" />
<IDSymbol name="cmdidGenerateNuGetPackageTopLevelBuild" value="0x2001" />
<IDSymbol name="cmdidNavigateToProject" value="0x2002" />
<IDSymbol name="DebugTargetMenuDebugFrameworkMenu" value="0x3000" />
<IDSymbol name="DebugTargetMenuDebugFrameworkGroup" value="0x3001" />
<IDSymbol name="cmdidDebugFrameworks" value="0x3050" /> <!--needs space to grow-->

<IDSymbol name="cmdidDebugFrameworks" value="0x3050" />
<IDSymbol name="NavigateGroup" value="0x4000" />
</GuidSymbol>

Expand All @@ -247,8 +264,11 @@
</GuidSymbol>

<GuidSymbol name="guidSHLMainMenu" value="{ 0xd309f791, 0x903f, 0x11d0, { 0x9e, 0xfc, 0x00, 0xa0, 0xc9, 0x11, 0x00, 0x4f } }">
<IDSymbol name="IDM_VS_CTXT_COMREFERENCE" value="0x04A5" />
melytc marked this conversation as resolved.
Show resolved Hide resolved
<IDSymbol name="IDG_VS_CTXT_ITEM_OBJECTBROWSER" value="0x02F6" />
<IDSymbol name="IDM_VS_CTXT_PROJECTREFERENCE" value="0x04A7"/>
<IDSymbol name="IDM_VS_CTXT_SHAREDPROJECTREFERENCE" value="0x04A8" />
<IDSymbol name="IDM_VS_CTXT_TRANSITIVE_ASSEMBLY_REFERENCE" value="0x04B1" />
</GuidSymbol>

<GuidSymbol name="SlnExplorerGuid" value="{3AE79031-E1BC-11D0-8F78-00A0C9110057}" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<CreateVsixContainer>false</CreateVsixContainer>
<UseCodebase>false</UseCodebase>

<!-- Nuget -->
<!-- NuGet -->
<IsPackable>true</IsPackable>
<Description>Microsoft VisualStudio ProjectSystem for Managed Languages Project hosts that interact with VisualStudio interfaces.</Description>
<Summary>Microsoft VisualStudio Managed Project System VS Components</Summary>
Expand All @@ -29,6 +29,7 @@
<PackageReference Include="Microsoft.VisualStudio.HotReload.Components" />
<PackageReference Include="Microsoft.VisualStudio.ProjectSystem.Query" />
<PackageReference Include="Microsoft.VisualStudio.ProjectSystem.VS" />
<PackageReference Include="IsExternalInit" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ public async ValueTask RestartAsync(CancellationToken cancellationToken)
{
WriteToOutputWindow(VSResources.HotReloadRestartInProgress, cancellationToken);


if (_callback is IProjectHotReloadSessionCallback2 callBack2)
{
await callBack2.RestartProjectAsync(_isRunningUnderDebugger, cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// 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.

namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.AttachedCollections;

/// <summary>
/// Used by implementations of <see cref="IRelatableItem"/> that support opening in Visual Studio's Object Browser via their context menu.
/// </summary>
public interface IObjectBrowserItem : IRelatableItem
{
/// <summary>
/// Gets the absolute path to an assembly that should be opened in the Object Browser.
/// </summary>
string? AssemblyPath { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@

namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.AttachedCollections.Implementation
{
internal sealed class FrameworkReferenceAssemblyItem : RelatableItemBase
internal sealed class FrameworkReferenceAssemblyItem : RelatableItemBase, IObjectBrowserItem
{
private const int IDM_VS_CTXT_TRANSITIVE_ASSEMBLY_REFERENCE = 0x04B1;

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

public string AssemblyName { get; }
public string? Path { get; }
Expand All @@ -38,33 +38,33 @@ public FrameworkReferenceAssemblyItem(string assemblyName, string? path, string?

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

private sealed class BrowseObject : LocalizableProperties
{
private readonly FrameworkReferenceAssemblyItem _item;
string? IObjectBrowserItem.AssemblyPath => GetAssemblyPath();

public BrowseObject(FrameworkReferenceAssemblyItem log) => _item = log;
private string? GetAssemblyPath() => Path is not null
? System.IO.Path.GetFullPath(System.IO.Path.Combine(Framework.Path, Path))
Copy link
Contributor

Choose a reason for hiding this comment

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

just curious, how does this path look like? are any of the paths rooted?

Copy link
Member Author

Choose a reason for hiding this comment

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

It ultimately ends up as an absolute path to the assembly, so that we can use it in the object browser and show it in the "Properties" view. The Framework.Path is something like C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.36 and the Path is something like ref\net6.0\Microsoft.CSharp.dll. The GetFullPath just makes the path look normal (i.e. consistent / vs \ characters).

: null;

public override string GetComponentName() => _item.AssemblyName;
private sealed class BrowseObject(FrameworkReferenceAssemblyItem item) : LocalizableProperties
{
public override string GetComponentName() => item.AssemblyName;

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

[BrowseObjectDisplayName(nameof(VSResources.FrameworkAssemblyAssemblyNameDisplayName))]
[BrowseObjectDescription(nameof(VSResources.FrameworkAssemblyAssemblyNameDescription))]
public string AssemblyName => _item.Text;
public string AssemblyName => item.Text;

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

[BrowseObjectDisplayName(nameof(VSResources.FrameworkAssemblyAssemblyVersionDisplayName))]
[BrowseObjectDescription(nameof(VSResources.FrameworkAssemblyAssemblyVersionDescription))]
public string AssemblyVersion => _item.AssemblyVersion ?? "";
public string AssemblyVersion => item.AssemblyVersion ?? "";

[BrowseObjectDisplayName(nameof(VSResources.FrameworkAssemblyFileVersionDisplayName))]
[BrowseObjectDescription(nameof(VSResources.FrameworkAssemblyFileVersionDescription))]
public string FileVersion => _item.FileVersion ?? "";
public string FileVersion => item.FileVersion ?? "";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,78 @@ namespace Microsoft.VisualStudio.ProjectSystem.VS.Tree.Dependencies.AttachedColl
{
public abstract partial class RelatableItemBase
{
internal sealed class MenuController : IContextMenuController
{
private readonly Guid _menuGuid;
private readonly int _menuId;
/// <summary>
/// Creates a <see cref="IContextMenuController"/> for use in overrides of <see cref="ContextMenuController"/>.
/// </summary>
public static IContextMenuController CreateContextMenuController(Guid menuGuid, int menuId) => new MenuController(menuGuid, menuId);

public MenuController(Guid menuGuid, int menuId)
{
_menuGuid = menuGuid;
_menuId = menuId;
}
internal sealed class MenuController(Guid menuGuid, int menuId) : IContextMenuController
{
public static ImmutableArray<IRelatableItem> CurrentItems { get; private set; } = [];

public bool ShowContextMenu(IEnumerable<object> items, Point location)
{
bool shouldShowMenu = items.All(item => item is IRelatableItem);
ImmutableArray<IRelatableItem>? relatableItems = GetItems();

if (relatableItems is null)
{
return false;
}

CurrentItems = relatableItems.Value;

try
{
return ShowContextMenu();
}
finally
{
CurrentItems = [];
}

if (shouldShowMenu)
ImmutableArray<IRelatableItem>? GetItems()
{
ImmutableArray<IRelatableItem>.Builder? builder = null;

foreach (object item in items)
{
if (item is IRelatableItem relatableItem)
{
builder ??= ImmutableArray.CreateBuilder<IRelatableItem>();
builder.Add(relatableItem);
}
else
{
return null;
}
}

if (builder is null)
{
return null;
}

return builder.ToImmutable();
}

bool ShowContextMenu()
{
if (Package.GetGlobalService(typeof(SVsUIShell)) is IVsUIShell shell)
{
Guid guidContextMenu = _menuGuid;
Guid guidContextMenu = menuGuid;

int result = shell.ShowContextMenu(
dwCompRole: 0,
rclsidActive: ref guidContextMenu,
nMenuId: _menuId,
pos: new[] { new POINTS { x = (short)location.X, y = (short)location.Y } },
nMenuId: menuId,
pos: [new POINTS { x = (short)location.X, y = (short)location.Y }],
pCmdTrgtActive: null);

return ErrorHandler.Succeeded(result);
}
}

return false;
return false;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public abstract partial class RelatableItemBase : AttachedCollectionItemBase, IR
{
private const int IDM_VS_CTXT_DEPENDENCY_TRANSITIVE_ITEM = 0x04B0;

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

private AggregateContainsRelationCollection? _containsCollection;

Expand Down
Loading
Loading