diff --git a/ILSpy/AboutPage.cs b/ILSpy/AboutPage.cs
index bfe32f3cd..1eafd77e4 100644
--- a/ILSpy/AboutPage.cs
+++ b/ILSpy/AboutPage.cs
@@ -38,7 +38,7 @@ using ICSharpCode.ILSpy.Themes;
namespace ICSharpCode.ILSpy
{
- [ExportMainMenuCommand(Menu = nameof(Resources._Help), Header = nameof(Resources._About), MenuOrder = 99999)]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._Help), Header = nameof(Resources._About), MenuOrder = 99999)]
sealed class AboutPage : SimpleCommand
{
public override void Execute(object parameter)
diff --git a/ILSpy/Commands/CheckForUpdatesCommand.cs b/ILSpy/Commands/CheckForUpdatesCommand.cs
index b7fbb7c9b..c398c1c1d 100644
--- a/ILSpy/Commands/CheckForUpdatesCommand.cs
+++ b/ILSpy/Commands/CheckForUpdatesCommand.cs
@@ -21,7 +21,7 @@ using ICSharpCode.ILSpy.Properties;
namespace ICSharpCode.ILSpy
{
- [ExportMainMenuCommand(Menu = nameof(Resources._Help), Header = nameof(Resources._CheckUpdates), MenuOrder = 5000)]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._Help), Header = nameof(Resources._CheckUpdates), MenuOrder = 5000)]
sealed class CheckForUpdatesCommand : SimpleCommand
{
public override bool CanExecute(object parameter)
diff --git a/ILSpy/Commands/DecompileAllCommand.cs b/ILSpy/Commands/DecompileAllCommand.cs
index db4b24c87..ca6f926c5 100644
--- a/ILSpy/Commands/DecompileAllCommand.cs
+++ b/ILSpy/Commands/DecompileAllCommand.cs
@@ -30,7 +30,7 @@ using ICSharpCode.ILSpy.TextView;
namespace ICSharpCode.ILSpy
{
- [ExportMainMenuCommand(Menu = nameof(Resources._File), Header = nameof(Resources.DEBUGDecompile), MenuCategory = nameof(Resources.Open), MenuOrder = 2.5)]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDecompile), MenuCategory = nameof(Resources.Open), MenuOrder = 2.5)]
sealed class DecompileAllCommand : SimpleCommand
{
public override bool CanExecute(object parameter)
@@ -79,7 +79,7 @@ namespace ICSharpCode.ILSpy
}
}
- [ExportMainMenuCommand(Menu = nameof(Resources._File), Header = nameof(Resources.DEBUGDecompile100x), MenuCategory = nameof(Resources.Open), MenuOrder = 2.6)]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDecompile100x), MenuCategory = nameof(Resources.Open), MenuOrder = 2.6)]
sealed class Decompile100TimesCommand : SimpleCommand
{
public override void Execute(object parameter)
diff --git a/ILSpy/Commands/DisassembleAllCommand.cs b/ILSpy/Commands/DisassembleAllCommand.cs
index c34bea449..849dd15d7 100644
--- a/ILSpy/Commands/DisassembleAllCommand.cs
+++ b/ILSpy/Commands/DisassembleAllCommand.cs
@@ -28,7 +28,7 @@ using ICSharpCode.ILSpy.TextView;
namespace ICSharpCode.ILSpy
{
- [ExportMainMenuCommand(Menu = nameof(Resources._File), Header = nameof(Resources.DEBUGDisassemble), MenuCategory = nameof(Resources.Open), MenuOrder = 2.5)]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDisassemble), MenuCategory = nameof(Resources.Open), MenuOrder = 2.5)]
sealed class DisassembleAllCommand : SimpleCommand
{
public override bool CanExecute(object parameter)
diff --git a/ILSpy/Commands/ExitCommand.cs b/ILSpy/Commands/ExitCommand.cs
index 34ad7f93f..bbb68122c 100644
--- a/ILSpy/Commands/ExitCommand.cs
+++ b/ILSpy/Commands/ExitCommand.cs
@@ -19,7 +19,7 @@ using ICSharpCode.ILSpy.Properties;
namespace ICSharpCode.ILSpy
{
- [ExportMainMenuCommand(Menu = nameof(Resources._File), Header = nameof(Resources.E_xit), MenuOrder = 99999, MenuCategory = nameof(Resources.Exit))]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.E_xit), MenuOrder = 99999, MenuCategory = nameof(Resources.Exit))]
sealed class ExitCommand : SimpleCommand
{
public override void Execute(object parameter)
diff --git a/ILSpy/Commands/ExportCommandAttribute.cs b/ILSpy/Commands/ExportCommandAttribute.cs
index f8db38bbc..df72bb046 100644
--- a/ILSpy/Commands/ExportCommandAttribute.cs
+++ b/ILSpy/Commands/ExportCommandAttribute.cs
@@ -52,8 +52,11 @@ namespace ICSharpCode.ILSpy
#region Main Menu
public interface IMainMenuCommandMetadata
{
+ string MenuID { get; }
string MenuIcon { get; }
string Header { get; }
+ string ParentMenuID { get; }
+ [Obsolete("Please use ParentMenuID instead. We decided to rename the property for clarity. It will be removed in ILSpy 8.0.")]
string Menu { get; }
string MenuCategory { get; }
string InputGestureText { get; }
@@ -65,22 +68,36 @@ namespace ICSharpCode.ILSpy
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ExportMainMenuCommandAttribute : ExportAttribute, IMainMenuCommandMetadata
{
- bool isEnabled = true;
-
public ExportMainMenuCommandAttribute()
: base("MainMenuCommand", typeof(ICommand))
{
}
-
+ ///
+ /// Gets/Sets the ID of this menu item. Menu entries are not required to have an ID,
+ /// however, setting it allows to declare nested menu structures.
+ /// The built-in menus have the IDs "_File", "_View", "_Window" and "_Help".
+ /// Plugin authors are advised to use GUIDs as identifiers to prevent conflicts.
+ ///
+ /// NOTE: Defining cycles (for example by accidentally setting equal to )
+ /// will lead to a stack-overflow and crash of ILSpy at startup.
+ ///
+ public string MenuID { get; set; }
public string MenuIcon { get; set; }
public string Header { get; set; }
- public string Menu { get; set; }
+ ///
+ /// Gets/Sets the parent of this menu item. All menu items sharing the same parent will be displayed as sub-menu items.
+ /// If this property is set to , the menu item is displayed in the top-level menu.
+ /// The built-in menus have the IDs "_File", "_View", "_Window" and "_Help".
+ ///
+ /// NOTE: Defining cycles (for example by accidentally setting equal to )
+ /// will lead to a stack-overflow and crash of ILSpy at startup.
+ ///
+ public string ParentMenuID { get; set; }
+ [Obsolete("Please use ParentMenuID instead. We decided to rename the property for clarity. It will be removed in ILSpy 8.0.")]
+ public string Menu { get => ParentMenuID; set => ParentMenuID = value; }
public string MenuCategory { get; set; }
public string InputGestureText { get; set; }
- public bool IsEnabled {
- get { return isEnabled; }
- set { isEnabled = value; }
- }
+ public bool IsEnabled { get; set; } = true;
public double MenuOrder { get; set; }
}
#endregion
diff --git a/ILSpy/Commands/GeneratePdbContextMenuEntry.cs b/ILSpy/Commands/GeneratePdbContextMenuEntry.cs
index 2577206e6..473360ff5 100644
--- a/ILSpy/Commands/GeneratePdbContextMenuEntry.cs
+++ b/ILSpy/Commands/GeneratePdbContextMenuEntry.cs
@@ -98,7 +98,7 @@ namespace ICSharpCode.ILSpy
}
}
- [ExportMainMenuCommand(Menu = nameof(Resources._File), Header = nameof(Resources.GeneratePortable), MenuCategory = nameof(Resources.Save))]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.GeneratePortable), MenuCategory = nameof(Resources.Save))]
class GeneratePdbMainMenuEntry : SimpleCommand
{
public override bool CanExecute(object parameter)
diff --git a/ILSpy/Commands/ManageAssemblyListsCommand.cs b/ILSpy/Commands/ManageAssemblyListsCommand.cs
index 10ba404d2..ec58ff59d 100644
--- a/ILSpy/Commands/ManageAssemblyListsCommand.cs
+++ b/ILSpy/Commands/ManageAssemblyListsCommand.cs
@@ -21,7 +21,7 @@ using ICSharpCode.ILSpy.Properties;
namespace ICSharpCode.ILSpy
{
- [ExportMainMenuCommand(Menu = nameof(Resources._File), Header = nameof(Resources.ManageAssembly_Lists), MenuIcon = "Images/AssemblyList", MenuCategory = nameof(Resources.Open), MenuOrder = 1.7)]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.ManageAssembly_Lists), MenuIcon = "Images/AssemblyList", MenuCategory = nameof(Resources.Open), MenuOrder = 1.7)]
sealed class ManageAssemblyListsCommand : SimpleCommand
{
public override void Execute(object parameter)
diff --git a/ILSpy/Commands/OpenCommand.cs b/ILSpy/Commands/OpenCommand.cs
index 9e4030cc8..a1663a499 100644
--- a/ILSpy/Commands/OpenCommand.cs
+++ b/ILSpy/Commands/OpenCommand.cs
@@ -23,7 +23,7 @@ using ICSharpCode.ILSpy.Properties;
namespace ICSharpCode.ILSpy
{
[ExportToolbarCommand(ToolTip = nameof(Resources.Open), ToolbarIcon = "Images/Open", ToolbarCategory = nameof(Resources.Open), ToolbarOrder = 0)]
- [ExportMainMenuCommand(Menu = nameof(Resources._File), Header = nameof(Resources._Open), MenuIcon = "Images/Open", MenuCategory = nameof(Resources.Open), MenuOrder = 0)]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources._Open), MenuIcon = "Images/Open", MenuCategory = nameof(Resources.Open), MenuOrder = 0)]
sealed class OpenCommand : CommandWrapper
{
public OpenCommand()
diff --git a/ILSpy/Commands/OpenFromGacCommand.cs b/ILSpy/Commands/OpenFromGacCommand.cs
index e9d72811a..8f72d3b6a 100644
--- a/ILSpy/Commands/OpenFromGacCommand.cs
+++ b/ILSpy/Commands/OpenFromGacCommand.cs
@@ -19,7 +19,7 @@
using ICSharpCode.ILSpy.Properties;
namespace ICSharpCode.ILSpy
{
- [ExportMainMenuCommand(Menu = nameof(Resources._File), Header = nameof(Resources.OpenFrom_GAC), MenuIcon = "Images/AssemblyListGAC", MenuCategory = nameof(Resources.Open), MenuOrder = 1)]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.OpenFrom_GAC), MenuIcon = "Images/AssemblyListGAC", MenuCategory = nameof(Resources.Open), MenuOrder = 1)]
sealed class OpenFromGacCommand : SimpleCommand
{
public override void Execute(object parameter)
diff --git a/ILSpy/Commands/Pdb2XmlCommand.cs b/ILSpy/Commands/Pdb2XmlCommand.cs
index eada39b20..f64478feb 100644
--- a/ILSpy/Commands/Pdb2XmlCommand.cs
+++ b/ILSpy/Commands/Pdb2XmlCommand.cs
@@ -33,7 +33,7 @@ using Microsoft.DiaSymReader.Tools;
namespace ICSharpCode.ILSpy
{
- [ExportMainMenuCommand(Menu = nameof(Resources._File), Header = nameof(Resources.DEBUGDumpPDBAsXML), MenuCategory = nameof(Resources.Open), MenuOrder = 2.6)]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDumpPDBAsXML), MenuCategory = nameof(Resources.Open), MenuOrder = 2.6)]
sealed class Pdb2XmlCommand : SimpleCommand
{
public override bool CanExecute(object parameter)
diff --git a/ILSpy/Commands/RefreshCommand.cs b/ILSpy/Commands/RefreshCommand.cs
index b81c2260e..3e188a7e6 100644
--- a/ILSpy/Commands/RefreshCommand.cs
+++ b/ILSpy/Commands/RefreshCommand.cs
@@ -23,7 +23,7 @@ using ICSharpCode.ILSpy.Properties;
namespace ICSharpCode.ILSpy
{
[ExportToolbarCommand(ToolTip = nameof(Resources.RefreshCommand_ReloadAssemblies), ToolbarIcon = "Images/Refresh", ToolbarCategory = nameof(Resources.Open), ToolbarOrder = 2)]
- [ExportMainMenuCommand(Menu = nameof(Resources._File), Header = nameof(Resources._Reload), MenuIcon = "Images/Refresh", MenuCategory = nameof(Resources.Open), MenuOrder = 2)]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources._Reload), MenuIcon = "Images/Refresh", MenuCategory = nameof(Resources.Open), MenuOrder = 2)]
sealed class RefreshCommand : CommandWrapper
{
public RefreshCommand()
diff --git a/ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs b/ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs
index c368a8179..a0ca79479 100644
--- a/ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs
+++ b/ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs
@@ -24,7 +24,7 @@ using ICSharpCode.ILSpy.Properties;
namespace ICSharpCode.ILSpy
{
- [ExportMainMenuCommand(Menu = nameof(Resources._File), Header = nameof(Resources._RemoveAssembliesWithLoadErrors), MenuCategory = nameof(Resources.Remove), MenuOrder = 2.6)]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources._RemoveAssembliesWithLoadErrors), MenuCategory = nameof(Resources.Remove), MenuOrder = 2.6)]
class RemoveAssembliesWithLoadErrors : SimpleCommand
{
public override bool CanExecute(object parameter)
diff --git a/ILSpy/Commands/SaveCommand.cs b/ILSpy/Commands/SaveCommand.cs
index b8ca82bb1..9f07f518f 100644
--- a/ILSpy/Commands/SaveCommand.cs
+++ b/ILSpy/Commands/SaveCommand.cs
@@ -22,7 +22,7 @@ using ICSharpCode.ILSpy.Properties;
namespace ICSharpCode.ILSpy
{
- [ExportMainMenuCommand(Menu = nameof(Resources._File), Header = nameof(Resources._SaveCode), MenuIcon = "Images/Save", MenuCategory = nameof(Resources.Save), MenuOrder = 0)]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources._SaveCode), MenuIcon = "Images/Save", MenuCategory = nameof(Resources.Save), MenuOrder = 0)]
sealed class SaveCommand : CommandWrapper
{
public SaveCommand()
diff --git a/ILSpy/Commands/SortAssemblyListCommand.cs b/ILSpy/Commands/SortAssemblyListCommand.cs
index a9e09226a..a57999a71 100644
--- a/ILSpy/Commands/SortAssemblyListCommand.cs
+++ b/ILSpy/Commands/SortAssemblyListCommand.cs
@@ -24,7 +24,7 @@ using ICSharpCode.TreeView;
namespace ICSharpCode.ILSpy
{
- [ExportMainMenuCommand(Menu = nameof(Resources._View), Header = nameof(Resources.SortAssembly_listName), MenuIcon = "Images/Sort", MenuCategory = nameof(Resources.View))]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._View), Header = nameof(Resources.SortAssembly_listName), MenuIcon = "Images/Sort", MenuCategory = nameof(Resources.View))]
[ExportToolbarCommand(ToolTip = nameof(Resources.SortAssemblyListName), ToolbarIcon = "Images/Sort", ToolbarCategory = nameof(Resources.View))]
sealed class SortAssemblyListCommand : SimpleCommand, IComparer
{
@@ -40,7 +40,7 @@ namespace ICSharpCode.ILSpy
}
}
- [ExportMainMenuCommand(Menu = nameof(Resources._View), Header = nameof(Resources._CollapseTreeNodes), MenuIcon = "Images/CollapseAll", MenuCategory = nameof(Resources.View))]
+ [ExportMainMenuCommand(ParentMenuID = nameof(Resources._View), Header = nameof(Resources._CollapseTreeNodes), MenuIcon = "Images/CollapseAll", MenuCategory = nameof(Resources.View))]
[ExportToolbarCommand(ToolTip = nameof(Resources.CollapseTreeNodes), ToolbarIcon = "Images/CollapseAll", ToolbarCategory = nameof(Resources.View))]
sealed class CollapseAllCommand : SimpleCommand
{
diff --git a/ILSpy/ContextMenuEntry.cs b/ILSpy/ContextMenuEntry.cs
index d7b10617b..f13d6749c 100644
--- a/ILSpy/ContextMenuEntry.cs
+++ b/ILSpy/ContextMenuEntry.cs
@@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Windows;
@@ -117,6 +118,8 @@ namespace ICSharpCode.ILSpy
public interface IContextMenuEntryMetadata
{
+ string MenuID { get; }
+ string ParentMenuID { get; }
string Icon { get; }
string Header { get; }
string Category { get; }
@@ -135,7 +138,23 @@ namespace ICSharpCode.ILSpy
// entries default to end of menu unless given specific order position
Order = double.MaxValue;
}
-
+ ///
+ /// Gets/Sets the ID of this menu item. Menu entries are not required to have an ID,
+ /// however, setting it allows to declare nested menu structures.
+ /// Plugin authors are advised to use GUIDs as identifiers to prevent conflicts.
+ ///
+ /// NOTE: Defining cycles (for example by accidentally setting equal to )
+ /// will lead to a stack-overflow and crash of ILSpy at startup.
+ ///
+ public string MenuID { get; set; }
+ ///
+ /// Gets/Sets the parent of this menu item. All menu items sharing the same parent will be displayed as sub-menu items.
+ /// If this property is set to , the menu item is displayed in the top-level menu.
+ ///
+ /// NOTE: Defining cycles (for example by accidentally setting equal to )
+ /// will lead to a stack-overflow and crash of ILSpy at startup.
+ ///
+ public string ParentMenuID { get; set; }
public string Icon { get; set; }
public string Header { get; set; }
public string Category { get; set; }
@@ -267,41 +286,64 @@ namespace ICSharpCode.ILSpy
bool ShowContextMenu(TextViewContext context, out ContextMenu menu)
{
menu = new ContextMenu();
- foreach (var category in entries.OrderBy(c => c.Metadata.Order).GroupBy(c => c.Metadata.Category))
+ var menuGroups = new Dictionary[]>();
+ Lazy[] topLevelGroup = null;
+ foreach (var group in entries.OrderBy(c => c.Metadata.Order).GroupBy(c => c.Metadata.ParentMenuID))
{
- bool needSeparatorForCategory = menu.Items.Count > 0;
- foreach (var entryPair in category)
+ if (group.Key == null)
{
- IContextMenuEntry entry = entryPair.Value;
- if (entry.IsVisible(context))
+ topLevelGroup = group.ToArray();
+ }
+ else
+ {
+ menuGroups.Add(group.Key, group.ToArray());
+ }
+ }
+ BuildMenu(topLevelGroup ?? Array.Empty>(), menu.Items);
+ return menu.Items.Count > 0;
+
+ void BuildMenu(Lazy[] menuGroup, ItemCollection parent)
+ {
+ foreach (var category in menuGroup.GroupBy(c => c.Metadata.Category))
+ {
+ bool needSeparatorForCategory = parent.Count > 0;
+ foreach (var entryPair in category)
{
- if (needSeparatorForCategory)
- {
- menu.Items.Add(new Separator());
- needSeparatorForCategory = false;
- }
- MenuItem menuItem = new MenuItem();
- menuItem.Header = MainWindow.GetResourceString(entryPair.Metadata.Header);
- menuItem.InputGestureText = entryPair.Metadata.InputGestureText;
- if (!string.IsNullOrEmpty(entryPair.Metadata.Icon))
+ IContextMenuEntry entry = entryPair.Value;
+ if (entry.IsVisible(context))
{
- menuItem.Icon = new Image {
- Width = 16,
- Height = 16,
- Source = Images.Load(entryPair.Value, entryPair.Metadata.Icon)
- };
- }
- if (entryPair.Value.IsEnabled(context))
- {
- menuItem.Click += delegate { entry.Execute(context); };
+ if (needSeparatorForCategory)
+ {
+ parent.Add(new Separator());
+ needSeparatorForCategory = false;
+ }
+ MenuItem menuItem = new MenuItem();
+ menuItem.Header = MainWindow.GetResourceString(entryPair.Metadata.Header);
+ menuItem.InputGestureText = entryPair.Metadata.InputGestureText;
+ if (!string.IsNullOrEmpty(entryPair.Metadata.Icon))
+ {
+ menuItem.Icon = new Image {
+ Width = 16,
+ Height = 16,
+ Source = Images.Load(entryPair.Value, entryPair.Metadata.Icon)
+ };
+ }
+ if (entryPair.Value.IsEnabled(context))
+ {
+ menuItem.Click += delegate { entry.Execute(context); };
+ }
+ else
+ menuItem.IsEnabled = false;
+ parent.Add(menuItem);
+
+ if (entryPair.Metadata.MenuID != null && menuGroups.TryGetValue(entryPair.Metadata.MenuID, out var group))
+ {
+ BuildMenu(group, menuItem.Items);
+ }
}
- else
- menuItem.IsEnabled = false;
- menu.Items.Add(menuItem);
}
}
}
- return menu.Items.Count > 0;
}
}
}
diff --git a/ILSpy/Docking/CloseAllDocumentsCommand.cs b/ILSpy/Docking/CloseAllDocumentsCommand.cs
index d08af41e8..fc33eb8cd 100644
--- a/ILSpy/Docking/CloseAllDocumentsCommand.cs
+++ b/ILSpy/Docking/CloseAllDocumentsCommand.cs
@@ -8,7 +8,7 @@ using ICSharpCode.ILSpy.Properties;
namespace ICSharpCode.ILSpy.Docking
{
- [ExportMainMenuCommand(Header = nameof(Resources.Window_CloseAllDocuments), Menu = nameof(Resources._Window))]
+ [ExportMainMenuCommand(Header = nameof(Resources.Window_CloseAllDocuments), ParentMenuID = nameof(Resources._Window))]
class CloseAllDocumentsCommand : SimpleCommand
{
public override void Execute(object parameter)
@@ -17,7 +17,7 @@ namespace ICSharpCode.ILSpy.Docking
}
}
- [ExportMainMenuCommand(Header = nameof(Resources.Window_ResetLayout), Menu = nameof(Resources._Window))]
+ [ExportMainMenuCommand(Header = nameof(Resources.Window_ResetLayout), ParentMenuID = nameof(Resources._Window))]
class ResetLayoutCommand : SimpleCommand
{
public override void Execute(object parameter)
diff --git a/ILSpy/ExtensionMethods.cs b/ILSpy/ExtensionMethods.cs
index 23a376c1a..c34331e1d 100644
--- a/ILSpy/ExtensionMethods.cs
+++ b/ILSpy/ExtensionMethods.cs
@@ -112,20 +112,12 @@ namespace ICSharpCode.ILSpy
}
}
- /*
- public static bool IsCustomAttribute(this TypeDefinition type)
+ internal static void Deconstruct(this KeyValuePair pair, out TKey key, out TValue value)
{
- while (type.FullName != "System.Object") {
- var resolvedBaseType = type.BaseType.Resolve();
- if (resolvedBaseType == null)
- return false;
- if (resolvedBaseType.FullName == "System.Attribute")
- return true;
- type = resolvedBaseType;
- }
- return false;
+ key = pair.Key;
+ value = pair.Value;
}
- */
+
public static string ToSuffixString(this System.Reflection.Metadata.EntityHandle handle)
{
if (!DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens)
diff --git a/ILSpy/MainWindow.xaml.cs b/ILSpy/MainWindow.xaml.cs
index cd9a387a7..8f89011ff 100644
--- a/ILSpy/MainWindow.xaml.cs
+++ b/ILSpy/MainWindow.xaml.cs
@@ -241,42 +241,78 @@ namespace ICSharpCode.ILSpy
void InitMainMenu()
{
var mainMenuCommands = App.ExportProvider.GetExports("MainMenuCommand");
- foreach (var topLevelMenu in mainMenuCommands.OrderBy(c => c.Metadata.MenuOrder).GroupBy(c => c.Metadata.Menu))
- {
- var topLevelMenuItem = mainMenu.Items.OfType