You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
3.1 KiB

  1. using System;
  2. using System.Linq;
  3. using EnvDTE;
  4. using Microsoft.VisualStudio.Shell;
  5. using VSLangProj;
  6. namespace ICSharpCode.ILSpy.AddIn.Commands
  7. {
  8. class OpenReferenceCommand : ILSpyCommand
  9. {
  10. static OpenReferenceCommand instance;
  11. public OpenReferenceCommand(ILSpyAddInPackage owner)
  12. : base(owner, PkgCmdIDList.cmdidOpenReferenceInILSpy)
  13. {
  14. ThreadHelper.ThrowIfNotOnUIThread();
  15. }
  16. protected override void OnBeforeQueryStatus(object sender, EventArgs e)
  17. {
  18. ThreadHelper.ThrowIfNotOnUIThread();
  19. if (sender is OleMenuCommand menuItem)
  20. {
  21. menuItem.Visible = false;
  22. var selectedItemData = owner.GetSelectedItemsData<object>().FirstOrDefault();
  23. if (selectedItemData == null)
  24. return;
  25. /*
  26. * Assure that we only show the context menu item on items we intend:
  27. * - Project references
  28. * - NuGet package references
  29. */
  30. if ((AssemblyReferenceForILSpy.Detect(selectedItemData) != null)
  31. || (ProjectReferenceForILSpy.Detect(selectedItemData) != null)
  32. || (NuGetReferenceForILSpy.Detect(selectedItemData) != null))
  33. {
  34. menuItem.Visible = true;
  35. }
  36. }
  37. }
  38. protected override void OnExecute(object sender, EventArgs e)
  39. {
  40. ThreadHelper.ThrowIfNotOnUIThread();
  41. var itemObject = owner.GetSelectedItemsData<object>().FirstOrDefault();
  42. if (itemObject == null)
  43. return;
  44. var referenceItem = AssemblyReferenceForILSpy.Detect(itemObject);
  45. if (referenceItem != null)
  46. {
  47. Reference reference = itemObject as Reference;
  48. var project = reference.ContainingProject;
  49. var roslynProject = owner.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == project.FileName);
  50. var references = GetReferences(roslynProject);
  51. var parameters = referenceItem.GetILSpyParameters(references);
  52. if (references.TryGetValue(reference.Name, out var path))
  53. OpenAssembliesInILSpy(parameters);
  54. else
  55. owner.ShowMessage("Could not find reference '{0}', please ensure the project and all references were built correctly!", reference.Name);
  56. return;
  57. }
  58. // Handle project references
  59. var projectRefItem = ProjectReferenceForILSpy.Detect(itemObject);
  60. if (projectRefItem != null)
  61. {
  62. var projectItem = itemObject as ProjectItem;
  63. string fileName = projectItem.ContainingProject?.FileName;
  64. if (!string.IsNullOrEmpty(fileName))
  65. {
  66. var roslynProject = owner.Workspace.CurrentSolution.Projects.FirstOrDefault(p => p.FilePath == fileName);
  67. var references = GetReferences(roslynProject);
  68. if (references.TryGetValue(projectItem.Name, out DetectedReference path))
  69. {
  70. OpenAssembliesInILSpy(projectRefItem.GetILSpyParameters(references));
  71. return;
  72. }
  73. }
  74. OpenAssembliesInILSpy(projectRefItem.GetILSpyParameters());
  75. return;
  76. }
  77. // Handle NuGet references
  78. var nugetRefItem = NuGetReferenceForILSpy.Detect(itemObject);
  79. if (nugetRefItem != null)
  80. {
  81. OpenAssembliesInILSpy(nugetRefItem.GetILSpyParameters());
  82. return;
  83. }
  84. }
  85. internal static void Register(ILSpyAddInPackage owner)
  86. {
  87. ThreadHelper.ThrowIfNotOnUIThread();
  88. instance = new OpenReferenceCommand(owner);
  89. }
  90. }
  91. }