mirror of
https://github.com/icsharpcode/ILSpy.git
synced 2026-10-12 02:15:58 +00:00
Merge pull request #695 from yoyobbi/dev.yggy.navigate-to-item
Add an "Open in ILSpy" option to the context menu in the code window.
This commit is contained in:
@@ -47,6 +47,10 @@
|
||||
<Group guid="guidILSpyAddInCmdSet" id="OpenILSpyProjGroup" priority="0x0200">
|
||||
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_PROJNODE"/>
|
||||
</Group>
|
||||
|
||||
<Group guid="guidILSpyAddInCmdSet" id="OpenILSpyCodeItemGroup" priority="0x0200">
|
||||
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN"/>
|
||||
</Group>
|
||||
</Groups>
|
||||
|
||||
<!--Buttons section. -->
|
||||
@@ -77,6 +81,14 @@
|
||||
</Strings>
|
||||
</Button>
|
||||
|
||||
<Button guid="guidILSpyAddInCmdSet" id="cmdidOpenCodeItemInILSpy" priority="0x0600" type="Button">
|
||||
<Parent guid="guidILSpyAddInCmdSet" id="OpenILSpyCodeItemGroup" />
|
||||
<Icon guid="guidImages" id="bmpLogo" />
|
||||
<Strings>
|
||||
<ButtonText>Open code in ILSpy</ButtonText>
|
||||
</Strings>
|
||||
</Button>
|
||||
|
||||
<Button guid="guidILSpyAddInCmdSet" id="cmdidOpenILSpy" priority="0x0600" type="Button">
|
||||
<Parent guid="guidILSpyAddInCmdSet" id="OpenILSpyGroup" />
|
||||
<Icon guid="guidImages" id="bmpLogo" />
|
||||
@@ -114,9 +126,11 @@
|
||||
<IDSymbol name="OpenILSpyGroup" value="0x1010" />
|
||||
<IDSymbol name="OpenILSpyRefGroup" value="0x1020" />
|
||||
<IDSymbol name="OpenILSpyProjGroup" value="0x1030" />
|
||||
<IDSymbol name="OpenILSpyCodeItemGroup" value="0x1040" />
|
||||
<IDSymbol name="cmdidOpenILSpy" value="0x0100" />
|
||||
<IDSymbol name="cmdidOpenReferenceInILSpy" value="0x0200" />
|
||||
<IDSymbol name="cmdidOpenProjectOutputInILSpy" value="0x0300" />
|
||||
<IDSymbol name="cmdidOpenCodeItemInILSpy" value="0x0400" />
|
||||
</GuidSymbol>
|
||||
|
||||
<GuidSymbol name="guidImages" value="{2f654db9-4641-4638-9937-27c6202b2a6a}" >
|
||||
|
||||
@@ -77,9 +77,14 @@ namespace ICSharpCode.ILSpy.AddIn
|
||||
mcs.AddCommand(menuItem2);
|
||||
|
||||
// Create the command for the menu item.
|
||||
CommandID menuCommandID3 = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)PkgCmdIDList.cmdidOpenILSpy);
|
||||
MenuCommand menuItem3 = new MenuCommand(OpenILSpyCallback, menuCommandID3);
|
||||
CommandID menuCommandID3 = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)PkgCmdIDList.cmdidOpenCodeItemInILSpy);
|
||||
MenuCommand menuItem3 = new MenuCommand(OpenCodeItemInILSpyCallback, menuCommandID3);
|
||||
mcs.AddCommand(menuItem3);
|
||||
|
||||
// Create the command for the menu item.
|
||||
CommandID menuCommandID4 = new CommandID(GuidList.guidILSpyAddInCmdSet, (int)PkgCmdIDList.cmdidOpenILSpy);
|
||||
MenuCommand menuItem4 = new MenuCommand(OpenILSpyCallback, menuCommandID4);
|
||||
mcs.AddCommand(menuItem4);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
@@ -122,6 +127,74 @@ namespace ICSharpCode.ILSpy.AddIn
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenCodeItemInILSpyCallback(object sender, EventArgs e)
|
||||
{
|
||||
var document = (EnvDTE.Document)(((EnvDTE80.DTE2)GetGlobalService(typeof(EnvDTE.DTE))).ActiveDocument);
|
||||
var selection = (EnvDTE.TextPoint)((EnvDTE.TextSelection)document.Selection).ActivePoint;
|
||||
var projectItem = document.ProjectItem;
|
||||
|
||||
string navigateTo = null;
|
||||
|
||||
// Find the full name of the method or class enclosing the current selection.
|
||||
// Note that order of testing is important, need to get the narrowest, most
|
||||
// internal element first.
|
||||
//
|
||||
// Add a prefix to match the ILSpy command line (see doc\Command Line.txt).
|
||||
// The prefix characters are documented in Appendix A of the C# specification:
|
||||
// E Event
|
||||
// F Field
|
||||
// M Method (including constructors, destructors, and operators)
|
||||
// N Namespace
|
||||
// P Property (including indexers)
|
||||
// T Type (such as class, delegate, enum, interface, and struct)
|
||||
navigateTo = GetCodeElementFullName("/navigateTo:M:", projectItem, selection, EnvDTE.vsCMElement.vsCMElementFunction);
|
||||
if (navigateTo == null) {
|
||||
navigateTo = GetCodeElementFullName("/navigateTo:E:", projectItem, selection, EnvDTE.vsCMElement.vsCMElementEvent);
|
||||
}
|
||||
if (navigateTo == null) {
|
||||
navigateTo = GetCodeElementFullName("/navigateTo:P:", projectItem, selection, EnvDTE.vsCMElement.vsCMElementProperty);
|
||||
}
|
||||
if (navigateTo == null) {
|
||||
navigateTo = GetCodeElementFullName("/navigateTo:T:", projectItem, selection,
|
||||
EnvDTE.vsCMElement.vsCMElementDelegate,
|
||||
EnvDTE.vsCMElement.vsCMElementEnum,
|
||||
EnvDTE.vsCMElement.vsCMElementInterface,
|
||||
EnvDTE.vsCMElement.vsCMElementStruct,
|
||||
EnvDTE.vsCMElement.vsCMElementClass);
|
||||
}
|
||||
|
||||
EnvDTE.Project project = projectItem.ContainingProject;
|
||||
EnvDTE.Configuration config = project.ConfigurationManager.ActiveConfiguration;
|
||||
string projectPath = Path.GetDirectoryName(project.FileName);
|
||||
string outputPath = config.Properties.Item("OutputPath").Value.ToString();
|
||||
string assemblyFileName = project.Properties.Item("OutputFileName").Value.ToString();
|
||||
|
||||
// Note that if navigateTo is still null this will just open ILSpy on the assembly.
|
||||
OpenAssemblyInILSpy(Path.Combine(projectPath, outputPath, assemblyFileName), navigateTo);
|
||||
}
|
||||
|
||||
private string GetCodeElementFullName(string prefix, EnvDTE.ProjectItem file, EnvDTE.TextPoint selection, params EnvDTE.vsCMElement[] elementTypes)
|
||||
{
|
||||
foreach (var elementType in elementTypes)
|
||||
{
|
||||
try
|
||||
{
|
||||
var codeElement = file.FileCodeModel.CodeElementFromPoint(selection, elementType);
|
||||
if (elementType == EnvDTE.vsCMElement.vsCMElementFunction)
|
||||
{
|
||||
// TODO: use codeElement.Parameters to disambiguate overloaded methods
|
||||
}
|
||||
return prefix + codeElement.FullName;
|
||||
}
|
||||
catch (COMException)
|
||||
{
|
||||
//Don’t do anything – this is expected if there is no such code element at specified point.
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void OpenILSpyCallback(object sender, EventArgs e)
|
||||
{
|
||||
Process.Start(GetILSpyPath());
|
||||
@@ -133,13 +206,19 @@ namespace ICSharpCode.ILSpy.AddIn
|
||||
return Path.Combine(basePath, "ILSpy.exe");
|
||||
}
|
||||
|
||||
private void OpenAssemblyInILSpy(string assemblyFileName)
|
||||
private void OpenAssemblyInILSpy(string assemblyFileName, params string[] arguments)
|
||||
{
|
||||
if (!File.Exists(assemblyFileName)) {
|
||||
ShowMessage("Could not find assembly '{0}', please ensure the project and all references were built correctly!", assemblyFileName);
|
||||
return;
|
||||
}
|
||||
Process.Start(GetILSpyPath(), Utils.ArgumentArrayToCommandLine(assemblyFileName));
|
||||
|
||||
string commandLineArguments = Utils.ArgumentArrayToCommandLine(assemblyFileName);
|
||||
if (arguments != null) {
|
||||
commandLineArguments = string.Concat(commandLineArguments, " ", Utils.ArgumentArrayToCommandLine(arguments));
|
||||
}
|
||||
|
||||
Process.Start(GetILSpyPath(), commandLineArguments);
|
||||
}
|
||||
|
||||
private void ShowMessage(string format, params object[] items)
|
||||
|
||||
@@ -9,5 +9,6 @@ namespace ICSharpCode.ILSpy.AddIn
|
||||
public const uint cmdidOpenILSpy = 0x100;
|
||||
public const uint cmdidOpenReferenceInILSpy = 0x200;
|
||||
public const uint cmdidOpenProjectOutputInILSpy = 0x300;
|
||||
public const uint cmdidOpenCodeItemInILSpy = 0x0400;
|
||||
};
|
||||
}
|
||||
@@ -74,6 +74,10 @@ namespace ICSharpCode.ILSpy.AddIn
|
||||
|
||||
static void AppendArgument(StringBuilder b, string arg)
|
||||
{
|
||||
if (arg == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (arg.Length > 0 && arg.IndexOfAny(charsNeedingQuoting) < 0) {
|
||||
b.Append(arg);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user