Browse Source

Get rid of singletons, replace with DI: MainWindow, Settings and Language service

pull/3314/head
tom-englert 6 months ago
parent
commit
560d89a42f
  1. 6
      ILSpy.ReadyToRun/ReadyToRunDisassembler.cs
  2. 12
      ILSpy.ReadyToRun/ReadyToRunLanguage.cs
  3. 2
      ILSpy.Tests/Analyzers/MemberImplementsInterfaceAnalyzerTests.cs
  4. 2
      ILSpy.Tests/Analyzers/MethodUsesAnalyzerTests.cs
  5. 2
      ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs
  6. 15
      ILSpy/AboutPage.cs
  7. 21
      ILSpy/Analyzers/AnalyzeCommand.cs
  8. 2
      ILSpy/Analyzers/AnalyzerSearchTreeNode.cs
  9. 14
      ILSpy/Analyzers/AnalyzerTreeNode.cs
  10. 5
      ILSpy/Analyzers/AnalyzerTreeViewModel.cs
  11. 15
      ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs
  12. 7
      ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs
  13. 5
      ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs
  14. 5
      ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs
  15. 7
      ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs
  16. 5
      ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs
  17. 16
      ILSpy/App.xaml.cs
  18. 53
      ILSpy/AssemblyTree/AssemblyTreeModel.cs
  19. 9
      ILSpy/Commands/CheckForUpdatesCommand.cs
  20. 25
      ILSpy/Commands/DecompileAllCommand.cs
  21. 8
      ILSpy/Commands/DisassembleAllCommand.cs
  22. 2
      ILSpy/Commands/ExitCommand.cs
  23. 20
      ILSpy/Commands/GeneratePdbContextMenuEntry.cs
  24. 37
      ILSpy/Commands/ILSpyCommands.cs
  25. 6
      ILSpy/Commands/ManageAssemblyListsCommand.cs
  26. 2
      ILSpy/Commands/OpenFromGacCommand.cs
  27. 7
      ILSpy/Commands/Pdb2XmlCommand.cs
  28. 11
      ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs
  29. 11
      ILSpy/Commands/SaveCodeContextMenuEntry.cs
  30. 12
      ILSpy/Commands/SaveCommand.cs
  31. 9
      ILSpy/Commands/SelectPdbContextMenuEntry.cs
  32. 8
      ILSpy/Commands/SetThemeCommand.cs
  33. 9
      ILSpy/Commands/SortAssemblyListCommand.cs
  34. 3
      ILSpy/ContextMenuEntry.cs
  35. 36
      ILSpy/Docking/DockWorkspace.cs
  36. 7
      ILSpy/ExtensionMethods.cs
  37. 4
      ILSpy/Languages/CSharpILMixedLanguage.cs
  38. 38
      ILSpy/Languages/CSharpLanguage.cs
  39. 6
      ILSpy/Languages/ILLanguage.cs
  40. 8
      ILSpy/Languages/Language.cs
  41. 18
      ILSpy/Languages/LanguageService.cs
  42. 10
      ILSpy/MainWindow.xaml
  43. 59
      ILSpy/MainWindow.xaml.cs
  44. 16
      ILSpy/MainWindowViewModel.cs
  45. 2
      ILSpy/Metadata/CorTables/EventTableTreeNode.cs
  46. 2
      ILSpy/Metadata/CorTables/FieldTableTreeNode.cs
  47. 2
      ILSpy/Metadata/CorTables/MethodTableTreeNode.cs
  48. 2
      ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs
  49. 2
      ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs
  50. 2
      ILSpy/Metadata/DebugMetadataTablesTreeNode.cs
  51. 5
      ILSpy/Metadata/MetadataProtocolHandler.cs
  52. 2
      ILSpy/Metadata/MetadataTablesTreeNode.cs
  53. 17
      ILSpy/Options/OptionsDialog.xaml.cs
  54. 4
      ILSpy/Options/OptionsDialogViewModel.cs
  55. 64
      ILSpy/Search/SearchPane.xaml.cs
  56. 9
      ILSpy/Search/SearchPaneModel.cs
  57. 4
      ILSpy/Search/SearchResultFactory.cs
  58. 3
      ILSpy/SolutionWriter.cs
  59. 2
      ILSpy/TaskHelper.cs
  60. 60
      ILSpy/TextView/DecompilerTextView.cs
  61. 13
      ILSpy/TextView/DocumentationUIBuilder.cs
  62. 32
      ILSpy/Themes/WindowStyleManagerBehavior.cs
  63. 11
      ILSpy/TreeNodes/AssemblyListTreeNode.cs
  64. 4
      ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs
  65. 21
      ILSpy/TreeNodes/AssemblyTreeNode.cs
  66. 2
      ILSpy/TreeNodes/DerivedTypesEntryNode.cs
  67. 6
      ILSpy/TreeNodes/EventTreeNode.cs
  68. 6
      ILSpy/TreeNodes/FieldTreeNode.cs
  69. 28
      ILSpy/TreeNodes/ILSpyTreeNode.cs
  70. 8
      ILSpy/TreeNodes/MethodTreeNode.cs
  71. 8
      ILSpy/TreeNodes/PropertyTreeNode.cs
  72. 2
      ILSpy/TreeNodes/ReferenceFolderTreeNode.cs
  73. 3
      ILSpy/TreeNodes/ResourceNodes/ResourceEntryNode.cs
  74. 6
      ILSpy/TreeNodes/TypeTreeNode.cs
  75. 15
      ILSpy/Util/MenuService.cs
  76. 9
      ILSpy/Util/SettingsService.cs
  77. 18
      ILSpy/ViewModels/ManageAssemblyListsViewModel.cs
  78. 23
      ILSpy/ViewModels/TabPageModel.cs
  79. 20
      ILSpy/Views/DebugSteps.xaml.cs
  80. 4
      ILSpy/Views/ManageAssemblyLIstsDialog.xaml.cs
  81. 5
      TestPlugin/MainMenuCommand.cs

6
ILSpy.ReadyToRun/ReadyToRunDisassembler.cs

@ -38,12 +38,14 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -38,12 +38,14 @@ namespace ICSharpCode.ILSpy.ReadyToRun
private readonly ITextOutput output;
private readonly ReadyToRunReader reader;
private readonly RuntimeFunction runtimeFunction;
private readonly SettingsService settingsService;
public ReadyToRunDisassembler(ITextOutput output, ReadyToRunReader reader, RuntimeFunction runtimeFunction)
public ReadyToRunDisassembler(ITextOutput output, ReadyToRunReader reader, RuntimeFunction runtimeFunction, SettingsService settingsService)
{
this.output = output;
this.reader = reader;
this.runtimeFunction = runtimeFunction;
this.settingsService = settingsService;
}
public void Disassemble(PEFile currentFile, int bitness, ulong address, bool showMetadataTokens, bool showMetadataTokensInBase10)
@ -51,7 +53,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -51,7 +53,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
ReadyToRunMethod readyToRunMethod = runtimeFunction.Method;
WriteCommentLine(readyToRunMethod.SignatureString);
var options = SettingsService.Instance.GetSettings<ReadyToRunOptions>();
var options = settingsService.GetSettings<ReadyToRunOptions>();
if (options.IsShowGCInfo)
{

12
ILSpy.ReadyToRun/ReadyToRunLanguage.cs

@ -38,6 +38,10 @@ using ICSharpCode.ILSpyX; @@ -38,6 +38,10 @@ using ICSharpCode.ILSpyX;
using ILCompiler.Reflection.ReadyToRun;
using TomsToolbox.Composition;
using MetadataReader = System.Reflection.Metadata.MetadataReader;
namespace ICSharpCode.ILSpy.ReadyToRun
{
#if STRESS
@ -97,7 +101,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -97,7 +101,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
[Export(typeof(Language))]
[Shared]
internal class ReadyToRunLanguage : Language
internal class ReadyToRunLanguage(SettingsService settingsService, IExportProvider exportProvider) : Language
{
private static readonly ConditionalWeakTable<MetadataFile, ReadyToRunReaderCacheEntry> readyToRunReaders = new ConditionalWeakTable<MetadataFile, ReadyToRunReaderCacheEntry>();
@ -175,7 +179,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -175,7 +179,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
.GroupBy(m => m.MethodHandle)
.ToDictionary(g => g.Key, g => g.ToArray());
}
var displaySettings = SettingsService.Instance.DisplaySettings;
var displaySettings = settingsService.DisplaySettings;
bool showMetadataTokens = displaySettings.ShowMetadataTokens;
bool showMetadataTokensInBase10 = displaySettings.ShowMetadataTokensInBase10;
#if STRESS
@ -205,7 +209,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -205,7 +209,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
file = ((IlSpyAssemblyMetadata)readyToRunMethod.ComponentReader).Module;
}
new ReadyToRunDisassembler(output, disassemblingReader, runtimeFunction).Disassemble(file, bitness, (ulong)runtimeFunction.StartAddress, showMetadataTokens, showMetadataTokensInBase10);
new ReadyToRunDisassembler(output, disassemblingReader, runtimeFunction, settingsService).Disassemble(file, bitness, (ulong)runtimeFunction.StartAddress, showMetadataTokens, showMetadataTokensInBase10);
}
}
}
@ -218,7 +222,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun @@ -218,7 +222,7 @@ namespace ICSharpCode.ILSpy.ReadyToRun
public override RichText GetRichTextTooltip(IEntity entity)
{
return LanguageService.Instance.ILLanguage.GetRichTextTooltip(entity);
return exportProvider.GetExportedValue<LanguageService>().ILLanguage.GetRichTextTooltip(entity);
}
private ReadyToRunReaderCacheEntry GetReader(LoadedAssembly assembly, MetadataFile file)

2
ILSpy.Tests/Analyzers/MemberImplementsInterfaceAnalyzerTests.cs

@ -145,7 +145,7 @@ namespace ICSharpCode.ILSpy.Tests.Analyzers @@ -145,7 +145,7 @@ namespace ICSharpCode.ILSpy.Tests.Analyzers
var analyzer = new MemberImplementsInterfaceAnalyzer();
// Act
var results = analyzer.Analyze(symbol, new AnalyzerContext() { AssemblyList = new ILSpyX.AssemblyList(), Language = new CSharpLanguage([]) });
var results = analyzer.Analyze(symbol, new AnalyzerContext() { AssemblyList = new ILSpyX.AssemblyList(), Language = new CSharpLanguage() });
// Assert
Assert.That(results, Is.Not.Null);

2
ILSpy.Tests/Analyzers/MethodUsesAnalyzerTests.cs

@ -30,7 +30,7 @@ namespace ICSharpCode.ILSpy.Tests.Analyzers @@ -30,7 +30,7 @@ namespace ICSharpCode.ILSpy.Tests.Analyzers
testAssembly = assemblyList.OpenAssembly(typeof(MethodUsesAnalyzerTests).Assembly.Location);
assemblyList.OpenAssembly(typeof(void).Assembly.Location);
testAssemblyTypeSystem = testAssembly.GetTypeSystemOrNull();
language = new CSharpLanguage([]);
language = new CSharpLanguage();
typeDefinition = testAssemblyTypeSystem.FindType(typeof(TestCases.Main.MainAssembly)).GetDefinition();
}

2
ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs

@ -41,7 +41,7 @@ namespace ICSharpCode.ILSpy.Tests.Analyzers @@ -41,7 +41,7 @@ namespace ICSharpCode.ILSpy.Tests.Analyzers
assemblyList = new AssemblyList();
testAssembly = assemblyList.OpenAssembly(typeof(MethodUsesAnalyzerTests).Assembly.Location);
testAssemblyTypeSystem = new DecompilerTypeSystem(testAssembly.GetMetadataFileOrNull(), testAssembly.GetAssemblyResolver());
language = new CSharpLanguage([]);
language = new CSharpLanguage();
}
[Test]

15
ILSpy/AboutPage.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Composition;
using System.IO;
using System.Text.RegularExpressions;
@ -28,6 +29,7 @@ using System.Windows.Navigation; @@ -28,6 +29,7 @@ using System.Windows.Navigation;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.Themes;
@ -38,17 +40,22 @@ namespace ICSharpCode.ILSpy @@ -38,17 +40,22 @@ namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._Help), Header = nameof(Resources._About), MenuOrder = 99999)]
[Shared]
sealed class AboutPage : SimpleCommand
public sealed class AboutPageCommand(AssemblyTreeModel assemblyTreeModel) : SimpleCommand
{
public override void Execute(object parameter)
{
MainWindow.Instance.AssemblyTreeModel.NavigateTo(
assemblyTreeModel.NavigateTo(
new RequestNavigateEventArgs(new Uri("resource://aboutpage"), null),
inNewTabPage: true
);
}
}
public static void Display(DecompilerTextView textView)
[Export]
[Shared]
public sealed class AboutPage(IEnumerable<IAboutPageAddition> aboutPageAdditions)
{
public void Display(DecompilerTextView textView)
{
AvalonEditTextOutput output = new AvalonEditTextOutput() {
Title = Resources.About,
@ -86,7 +93,7 @@ namespace ICSharpCode.ILSpy @@ -86,7 +93,7 @@ namespace ICSharpCode.ILSpy
});
output.WriteLine();
foreach (var plugin in App.ExportProvider.GetExportedValues<IAboutPageAddition>())
foreach (var plugin in aboutPageAdditions)
plugin.Write(output);
output.WriteLine();
output.Address = new Uri("resource://AboutPage");

21
ILSpy/Analyzers/AnalyzeCommand.cs

@ -20,17 +20,18 @@ using System.Composition; @@ -20,17 +20,18 @@ using System.Composition;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TreeNodes;
using TomsToolbox.Composition;
namespace ICSharpCode.ILSpy.Analyzers
{
[ExportContextMenuEntry(Header = nameof(Resources.Analyze), Icon = "Images/Search", Category = nameof(Resources.Analyze), InputGestureText = "Ctrl+R", Order = 100)]
[Shared]
internal sealed class AnalyzeContextMenuCommand : IContextMenuEntry
internal sealed class AnalyzeContextMenuCommand(AnalyzerTreeViewModel analyzerTreeView) : IContextMenuEntry
{
private static readonly AnalyzerTreeViewModel AnalyzerTreeView = App.ExportProvider.GetExportedValue<AnalyzerTreeViewModel>();
public bool IsVisible(TextViewContext context)
{
if (context.TreeView is AnalyzerTreeView && context.SelectedTreeNodes != null && context.SelectedTreeNodes.All(n => n.Parent.IsRoot))
@ -62,30 +63,28 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -62,30 +63,28 @@ namespace ICSharpCode.ILSpy.Analyzers
{
foreach (var node in context.SelectedTreeNodes.OfType<IMemberTreeNode>().ToArray())
{
AnalyzerTreeView.Analyze(node.Member);
analyzerTreeView.Analyze(node.Member);
}
}
else if (context.Reference is { Reference: IEntity entity })
{
AnalyzerTreeView.Analyze(entity);
analyzerTreeView.Analyze(entity);
}
}
}
internal sealed class AnalyzeCommand : SimpleCommand
public sealed class AnalyzeCommand(AssemblyTreeModel assemblyTreeModel, AnalyzerTreeViewModel analyzerTreeViewModel) : SimpleCommand
{
private static readonly AnalyzerTreeViewModel AnalyzerTreeView = App.ExportProvider.GetExportedValue<AnalyzerTreeViewModel>();
public override bool CanExecute(object parameter)
{
return MainWindow.Instance.AssemblyTreeModel.SelectedNodes.All(n => n is IMemberTreeNode);
return assemblyTreeModel.SelectedNodes.All(n => n is IMemberTreeNode);
}
public override void Execute(object parameter)
{
foreach (var node in MainWindow.Instance.AssemblyTreeModel.SelectedNodes.OfType<IMemberTreeNode>())
foreach (var node in assemblyTreeModel.SelectedNodes.OfType<IMemberTreeNode>())
{
AnalyzerTreeView.Analyze(node.Member);
analyzerTreeViewModel.Analyze(node.Member);
}
}
}

2
ILSpy/Analyzers/AnalyzerSearchTreeNode.cs

@ -61,7 +61,7 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -61,7 +61,7 @@ namespace ICSharpCode.ILSpy.Analyzers
var context = new AnalyzerContext() {
CancellationToken = ct,
Language = Language,
AssemblyList = MainWindow.Instance.AssemblyTreeModel.AssemblyList
AssemblyList = AssemblyTreeModel.AssemblyList
};
var results = analyzer.Analyze(symbol, context).Select(SymbolTreeNodeFactory);
if (context.SortResults)

14
ILSpy/Analyzers/AnalyzerTreeNode.cs

@ -17,15 +17,20 @@ @@ -17,15 +17,20 @@
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.Analyzers;
using ICSharpCode.ILSpyX.TreeView;
using TomsToolbox.Composition;
namespace ICSharpCode.ILSpy.Analyzers
{
public abstract class AnalyzerTreeNode : SharpTreeNode
{
public Language Language => LanguageService.Instance.Language;
public static Language Language => App.ExportProvider.GetExportedValue<LanguageService>().Language;
public override bool CanDelete()
{
@ -42,6 +47,13 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -42,6 +47,13 @@ namespace ICSharpCode.ILSpy.Analyzers
DeleteCore();
}
public static AssemblyTreeModel AssemblyTreeModel { get; } = App.ExportProvider.GetExportedValue<AssemblyTreeModel>();
public static ICollection<IExport<IAnalyzer, IAnalyzerMetadata>> Analyzers => App.ExportProvider
.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer")
.OrderBy(item => item.Metadata?.Order)
.ToArray();
/// <summary>
/// Handles changes to the assembly list.
/// </summary>

5
ILSpy/Analyzers/AnalyzerTreeViewModel.cs

@ -24,6 +24,7 @@ using System.Windows.Input; @@ -24,6 +24,7 @@ using System.Windows.Input;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Analyzers.TreeNodes;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
@ -38,12 +39,12 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -38,12 +39,12 @@ namespace ICSharpCode.ILSpy.Analyzers
{
public const string PaneContentId = "analyzerPane";
public AnalyzerTreeViewModel()
public AnalyzerTreeViewModel(AssemblyTreeModel assemblyTreeModel)
{
ContentId = PaneContentId;
Title = Properties.Resources.Analyze;
ShortcutKey = new(Key.R, ModifierKeys.Control);
AssociatedCommand = ILSpyCommands.Analyze;
AssociatedCommand = new AnalyzeCommand(assemblyTreeModel, this);
}
public AnalyzerRootNode Root { get; } = new();

15
ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs

@ -17,15 +17,12 @@ @@ -17,15 +17,12 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpyX.Analyzers;
internal sealed class AnalyzedEventTreeNode : AnalyzerEntityTreeNode
{
readonly IEvent analyzedEvent;
@ -54,16 +51,12 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -54,16 +51,12 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
if (TryFindBackingField(analyzedEvent, out var backingField))
this.Children.Add(new AnalyzedFieldTreeNode(backingField));
//foreach (var accessor in analyzedEvent.OtherMethods)
// this.Children.Add(new AnalyzedAccessorTreeNode(accessor, null));
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order))
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
if (analyzer.Show(analyzedEvent))
{
this.Children.Add(new AnalyzerSearchTreeNode(analyzedEvent, analyzer, lazy.Metadata.Header));
this.Children.Add(new AnalyzerSearchTreeNode(analyzedEvent, analyzer, lazy.Metadata?.Header));
}
}
}
@ -73,7 +66,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -73,7 +66,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
backingField = null;
foreach (var field in analyzedEvent.DeclaringTypeDefinition.GetFields(options: GetMemberOptions.IgnoreInheritedMembers))
{
if (field.Name == analyzedEvent.Name && field.Accessibility == Accessibility.Private)
if (field.Name == analyzedEvent.Name && field.Accessibility == Decompiler.TypeSystem.Accessibility.Private)
{
backingField = field;
return true;

7
ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs

@ -17,11 +17,9 @@ @@ -17,11 +17,9 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpyX.Analyzers;
namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
@ -41,13 +39,12 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -41,13 +39,12 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
protected override void LoadChildren()
{
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order))
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
if (analyzer.Show(analyzedField))
{
this.Children.Add(new AnalyzerSearchTreeNode(analyzedField, analyzer, lazy.Metadata.Header));
this.Children.Add(new AnalyzerSearchTreeNode(analyzedField, analyzer, lazy.Metadata?.Header));
}
}
}

5
ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs

@ -17,11 +17,9 @@ @@ -17,11 +17,9 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpyX.Analyzers;
namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
@ -43,8 +41,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -43,8 +41,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
protected override void LoadChildren()
{
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order))
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
if (analyzer.Show(analyzedMethod))

5
ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs

@ -17,11 +17,9 @@ @@ -17,11 +17,9 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Windows;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpyX.Analyzers;
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;
namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
@ -42,8 +40,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -42,8 +40,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
protected override void LoadChildren()
{
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order))
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
if (analyzer.Show(analyzedModule))

7
ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs

@ -17,11 +17,9 @@ @@ -17,11 +17,9 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpyX.Analyzers;
namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
@ -48,11 +46,8 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -48,11 +46,8 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
this.Children.Add(new AnalyzedAccessorTreeNode(analyzedProperty.Getter, "get"));
if (analyzedProperty.CanSet)
this.Children.Add(new AnalyzedAccessorTreeNode(analyzedProperty.Setter, "set"));
//foreach (var accessor in analyzedProperty.OtherMethods)
// this.Children.Add(new AnalyzedPropertyAccessorTreeNode(accessor, null));
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order))
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
if (analyzer.Show(analyzedProperty))

5
ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs

@ -17,11 +17,9 @@ @@ -17,11 +17,9 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpyX.Analyzers;
namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
{
@ -41,8 +39,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes @@ -41,8 +39,7 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes
protected override void LoadChildren()
{
var analyzers = App.ExportProvider.GetExports<IAnalyzer, IAnalyzerMetadata>("Analyzer");
foreach (var lazy in analyzers.OrderBy(item => item.Metadata.Order))
foreach (var lazy in Analyzers)
{
var analyzer = lazy.Value;
if (analyzer.Show(analyzedType))

16
ILSpy/App.xaml.cs

@ -71,8 +71,10 @@ namespace ICSharpCode.ILSpy @@ -71,8 +71,10 @@ namespace ICSharpCode.ILSpy
var cmdArgs = Environment.GetCommandLineArgs().Skip(1);
CommandLineArguments = CommandLineArguments.Create(cmdArgs);
var settingsService = new SettingsService();
bool forceSingleInstance = (CommandLineArguments.SingleInstance ?? true)
&& !SettingsService.Instance.MiscSettings.AllowMultipleInstances;
&& !settingsService.MiscSettings.AllowMultipleInstances;
if (forceSingleInstance)
{
SingleInstance.Attach(); // will auto-exit for second instance
@ -81,7 +83,7 @@ namespace ICSharpCode.ILSpy @@ -81,7 +83,7 @@ namespace ICSharpCode.ILSpy
InitializeComponent();
if (!InitializeDependencyInjection(SettingsService.Instance))
if (!InitializeDependencyInjection(settingsService))
{
// There is something completely wrong with DI, probably some service registration is missing => nothing we can do to recover, so stop and shut down.
Exit += (_, _) => MessageBox.Show(StartupExceptions.FormatExceptions(), "Sorry we crashed!");
@ -106,7 +108,7 @@ namespace ICSharpCode.ILSpy @@ -106,7 +108,7 @@ namespace ICSharpCode.ILSpy
// Add data templates registered via MEF.
Resources.MergedDictionaries.Add(DataTemplateManager.CreateDynamicDataTemplates(ExportProvider));
var sessionSettings = SettingsService.Instance.SessionSettings;
var sessionSettings = settingsService.SessionSettings;
ThemeManager.Current.Theme = sessionSettings.Theme;
if (!string.IsNullOrEmpty(sessionSettings.CurrentCulture))
{
@ -129,7 +131,7 @@ namespace ICSharpCode.ILSpy @@ -129,7 +131,7 @@ namespace ICSharpCode.ILSpy
MessageBox.Show(unknownArguments, "ILSpy Unknown Command Line Arguments Passed");
}
SettingsService.Instance.AssemblyListManager.CreateDefaultAssemblyLists();
settingsService.AssemblyListManager.CreateDefaultAssemblyLists();
}
public new static App Current => (App)Application.Current;
@ -187,6 +189,10 @@ namespace ICSharpCode.ILSpy @@ -187,6 +189,10 @@ namespace ICSharpCode.ILSpy
services.BindExports(Assembly.GetExecutingAssembly());
// Add the settings service
services.AddSingleton(settingsService);
// Add the export provider
services.AddSingleton(_ => ExportProvider);
// Add the docking manager
services.AddSingleton(serviceProvider => serviceProvider.GetService<MainWindow>().DockManager);
var serviceProvider = services.BuildServiceProvider(new ServiceProviderOptions { ValidateOnBuild = true });
@ -209,7 +215,7 @@ namespace ICSharpCode.ILSpy @@ -209,7 +215,7 @@ namespace ICSharpCode.ILSpy
{
base.OnStartup(e);
MainWindow = new();
MainWindow = ExportProvider.GetExportedValue<MainWindow>();
MainWindow.Show();
}

53
ILSpy/AssemblyTree/AssemblyTreeModel.cs

@ -47,6 +47,7 @@ using ICSharpCode.ILSpyX; @@ -47,6 +47,7 @@ using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.Settings;
using ICSharpCode.ILSpyX.TreeView;
using TomsToolbox.Composition;
using TomsToolbox.Essentials;
using TomsToolbox.Wpf;
@ -67,9 +68,20 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -67,9 +68,20 @@ namespace ICSharpCode.ILSpy.AssemblyTree
private readonly NavigationHistory<NavigationState> history = new();
private bool isNavigatingHistory;
private readonly AboutPage aboutPage;
private readonly SearchPaneModel searchPaneModel;
private readonly SettingsService settingsService;
private readonly LanguageService languageService;
private readonly IExportProvider exportProvider;
public AssemblyTreeModel()
public AssemblyTreeModel(AboutPage aboutPage, SearchPaneModel searchPaneModel, SettingsService settingsService, LanguageService languageService, IExportProvider exportProvider)
{
this.aboutPage = aboutPage;
this.searchPaneModel = searchPaneModel;
this.settingsService = settingsService;
this.languageService = languageService;
this.exportProvider = exportProvider;
Title = Resources.Assemblies;
ContentId = PaneContentId;
IsCloseable = false;
@ -80,7 +92,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -80,7 +92,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
refreshThrottle = new DispatcherThrottle(DispatcherPriority.Background, RefreshInternal);
AssemblyList = SettingsService.Instance.CreateEmptyAssemblyList();
AssemblyList = settingsService.CreateEmptyAssemblyList();
}
private void Settings_PropertyChanged(object? sender, PropertyChangedEventArgs e)
@ -151,7 +163,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -151,7 +163,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
{
LoadAssemblies(args.AssembliesToLoad, commandLineLoadedAssemblies, focusNode: false);
if (args.Language != null)
LanguageService.Instance.Language = LanguageService.Instance.GetLanguage(args.Language);
languageService.Language = languageService.GetLanguage(args.Language);
return true;
}
@ -161,7 +173,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -161,7 +173,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
/// </summary>
private async Task HandleCommandLineArgumentsAfterShowList(CommandLineArguments args, ISettingsProvider? spySettings = null)
{
var sessionSettings = SettingsService.Instance.SessionSettings;
var sessionSettings = settingsService.SessionSettings;
var relevantAssemblies = commandLineLoadedAssemblies.ToList();
commandLineLoadedAssemblies.Clear(); // clear references once we don't need them anymore
@ -170,10 +182,8 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -170,10 +182,8 @@ namespace ICSharpCode.ILSpy.AssemblyTree
if (args.Search != null)
{
var searchPane = App.ExportProvider.GetExportedValue<SearchPaneModel>();
searchPane.SearchTerm = args.Search;
searchPane.Show();
this.searchPaneModel.SearchTerm = args.Search;
this.searchPaneModel.Show();
}
}
@ -290,11 +300,11 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -290,11 +300,11 @@ namespace ICSharpCode.ILSpy.AssemblyTree
SelectNode(node);
// only if not showing the about page, perform the update check:
await MainWindow.Instance.ShowMessageIfUpdatesAvailableAsync(spySettings);
await App.Current.MainWindow.ShowMessageIfUpdatesAvailableAsync(spySettings);
}
else
{
DockWorkspace.Instance.ActiveTabPage.ShowTextView(AboutPage.Display);
DockWorkspace.Instance.ActiveTabPage.ShowTextView(aboutPage.Display);
}
}
}
@ -363,11 +373,11 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -363,11 +373,11 @@ namespace ICSharpCode.ILSpy.AssemblyTree
public void Initialize()
{
AssemblyList = SettingsService.Instance.LoadInitialAssemblyList();
AssemblyList = settingsService.LoadInitialAssemblyList();
HandleCommandLineArguments(App.CommandLineArguments);
var loadPreviousAssemblies = SettingsService.Instance.MiscSettings.LoadPreviousAssemblies;
var loadPreviousAssemblies = settingsService.MiscSettings.LoadPreviousAssemblies;
if (AssemblyList.GetAssemblies().Length == 0
&& AssemblyList.ListName == AssemblyListManager.DefaultListName
&& loadPreviousAssemblies)
@ -377,7 +387,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -377,7 +387,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
ShowAssemblyList(AssemblyList);
var sessionSettings = SettingsService.Instance.SessionSettings;
var sessionSettings = settingsService.SessionSettings;
if (sessionSettings.ActiveAutoLoadedAssembly != null
&& File.Exists(sessionSettings.ActiveAutoLoadedAssembly))
{
@ -389,7 +399,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -389,7 +399,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
private async Task OpenAssemblies()
{
await HandleCommandLineArgumentsAfterShowList(App.CommandLineArguments, SettingsService.Instance.SpySettings);
await HandleCommandLineArgumentsAfterShowList(App.CommandLineArguments, settingsService.SpySettings);
if (FormatExceptions(App.StartupExceptions.ToArray(), out var output))
{
@ -416,7 +426,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -416,7 +426,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
private void ShowAssemblyList(string name)
{
AssemblyList list = SettingsService.Instance.AssemblyListManager.LoadList(name);
AssemblyList list = settingsService.AssemblyListManager.LoadList(name);
//Only load a new list when it is a different one
if (list.ListName != AssemblyList.ListName)
{
@ -655,8 +665,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -655,8 +665,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
}
if (protocol != "decompile")
{
var protocolHandlers = App.ExportProvider.GetExportedValues<IProtocolHandler>();
foreach (var handler in protocolHandlers)
foreach (var handler in exportProvider.GetExportedValues<IProtocolHandler>())
{
var node = handler.Resolve(protocol, file, unresolvedEntity.Handle, out bool newTabPage);
if (node != null)
@ -793,7 +802,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -793,7 +802,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
return;
}
var options = LanguageService.Instance.CreateDecompilationOptions(activeTabPage);
var options = activeTabPage.CreateDecompilationOptions();
options.TextViewState = newState;
activeTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(this.CurrentLanguage, this.SelectedNodes, options));
}
@ -803,9 +812,9 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -803,9 +812,9 @@ namespace ICSharpCode.ILSpy.AssemblyTree
DecompileSelectedNodes(DockWorkspace.Instance.ActiveTabPage.GetState() as DecompilerTextViewState);
}
public Language CurrentLanguage => LanguageService.Instance.Language;
public Language CurrentLanguage => languageService.Language;
public LanguageVersion? CurrentLanguageVersion => LanguageService.Instance.LanguageVersion;
public LanguageVersion? CurrentLanguageVersion => languageService.LanguageVersion;
public IEnumerable<ILSpyTreeNode> SelectedNodes {
get {
@ -858,7 +867,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -858,7 +867,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
if (e.Uri.Host == "aboutpage")
{
RecordHistory();
DockWorkspace.Instance.ActiveTabPage.ShowTextView(AboutPage.Display);
DockWorkspace.Instance.ActiveTabPage.ShowTextView(aboutPage.Display);
e.Handled = true;
return;
}
@ -912,7 +921,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree @@ -912,7 +921,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree
{
var path = GetPathForNode(SelectedItem);
ShowAssemblyList(SettingsService.Instance.AssemblyListManager.LoadList(AssemblyList.ListName));
ShowAssemblyList(settingsService.AssemblyListManager.LoadList(AssemblyList.ListName));
SelectNode(FindNodeByPath(path, true), inNewTabPage: false);
RefreshDecompiledView();

9
ILSpy/Commands/CheckForUpdatesCommand.cs

@ -25,16 +25,11 @@ namespace ICSharpCode.ILSpy @@ -25,16 +25,11 @@ namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._Help), Header = nameof(Resources._CheckUpdates), MenuOrder = 5000)]
[Shared]
sealed class CheckForUpdatesCommand : SimpleCommand
sealed class CheckForUpdatesCommand(SettingsService settingsService) : SimpleCommand
{
public override bool CanExecute(object parameter)
{
return base.CanExecute(parameter);
}
public override async void Execute(object parameter)
{
await MainWindow.Instance.ShowMessageIfUpdatesAvailableAsync(SettingsService.Instance.SpySettings, forceCheck: true);
await App.Current.MainWindow.ShowMessageIfUpdatesAvailableAsync(settingsService.SpySettings, forceCheck: true);
}
}
}

25
ILSpy/Commands/DecompileAllCommand.cs

@ -27,24 +27,19 @@ using System.Linq; @@ -27,24 +27,19 @@ using System.Linq;
using System.Threading.Tasks;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDecompile), MenuCategory = nameof(Resources.Open), MenuOrder = 2.5)]
[Shared]
sealed class DecompileAllCommand : SimpleCommand
sealed class DecompileAllCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : SimpleCommand
{
private readonly IReadOnlyCollection<IResourceFileHandler> resourceFileHandlers;
public DecompileAllCommand(IEnumerable<IResourceFileHandler> resourceFileHandlers)
{
this.resourceFileHandlers = resourceFileHandlers.ToArray();
}
public override bool CanExecute(object parameter)
{
return System.IO.Directory.Exists("c:\\temp\\decompiled");
@ -55,7 +50,7 @@ namespace ICSharpCode.ILSpy @@ -55,7 +50,7 @@ namespace ICSharpCode.ILSpy
Docking.DockWorkspace.Instance.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
AvalonEditTextOutput output = new AvalonEditTextOutput();
Parallel.ForEach(
Partitioner.Create(MainWindow.Instance.AssemblyTreeModel.AssemblyList.GetAssemblies(), loadBalance: true),
Partitioner.Create(assemblyTreeModel.AssemblyList.GetAssemblies(), loadBalance: true),
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = ct },
delegate (LoadedAssembly asm) {
if (!asm.HasLoadError)
@ -66,10 +61,10 @@ namespace ICSharpCode.ILSpy @@ -66,10 +61,10 @@ namespace ICSharpCode.ILSpy
{
try
{
var options = LanguageService.Instance.CreateDecompilationOptions(DockWorkspace.Instance.ActiveTabPage);
var options = DockWorkspace.Instance.ActiveTabPage.CreateDecompilationOptions();
options.CancellationToken = ct;
options.FullDecompilation = true;
new CSharpLanguage(resourceFileHandlers).DecompileAssembly(asm, new PlainTextOutput(writer), options);
new CSharpLanguage().DecompileAssembly(asm, new PlainTextOutput(writer), options);
}
catch (Exception ex)
{
@ -96,15 +91,15 @@ namespace ICSharpCode.ILSpy @@ -96,15 +91,15 @@ namespace ICSharpCode.ILSpy
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDecompile100x), MenuCategory = nameof(Resources.Open), MenuOrder = 2.6)]
[Shared]
sealed class Decompile100TimesCommand : SimpleCommand
sealed class Decompile100TimesCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : SimpleCommand
{
public override void Execute(object parameter)
{
const int numRuns = 100;
var language = LanguageService.Instance.Language;
var nodes = MainWindow.Instance.AssemblyTreeModel.SelectedNodes.ToArray();
var language = languageService.Language;
var nodes = assemblyTreeModel.SelectedNodes.ToArray();
DockWorkspace dockWorkspace = DockWorkspace.Instance;
var options = LanguageService.Instance.CreateDecompilationOptions(dockWorkspace.ActiveTabPage);
var options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions();
dockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
options.CancellationToken = ct;
Stopwatch w = Stopwatch.StartNew();

8
ILSpy/Commands/DisassembleAllCommand.cs

@ -24,14 +24,16 @@ using System.Composition; @@ -24,14 +24,16 @@ using System.Composition;
using System.Diagnostics;
using System.Threading.Tasks;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDisassemble), MenuCategory = nameof(Resources.Open), MenuOrder = 2.5)]
[Shared]
sealed class DisassembleAllCommand : SimpleCommand
sealed class DisassembleAllCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : SimpleCommand
{
public override bool CanExecute(object parameter)
{
@ -45,7 +47,7 @@ namespace ICSharpCode.ILSpy @@ -45,7 +47,7 @@ namespace ICSharpCode.ILSpy
dockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
AvalonEditTextOutput output = new();
Parallel.ForEach(
Partitioner.Create(MainWindow.Instance.AssemblyTreeModel.AssemblyList.GetAssemblies(), loadBalance: true),
Partitioner.Create(assemblyTreeModel.AssemblyList.GetAssemblies(), loadBalance: true),
new() { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = ct },
asm => {
if (!asm.HasLoadError)
@ -56,7 +58,7 @@ namespace ICSharpCode.ILSpy @@ -56,7 +58,7 @@ namespace ICSharpCode.ILSpy
{
try
{
var options = LanguageService.Instance.CreateDecompilationOptions(dockWorkspace.ActiveTabPage);
var options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions();
options.FullDecompilation = true;
options.CancellationToken = ct;
new ILLanguage().DecompileAssembly(asm, new Decompiler.PlainTextOutput(writer), options);

2
ILSpy/Commands/ExitCommand.cs

@ -27,7 +27,7 @@ namespace ICSharpCode.ILSpy @@ -27,7 +27,7 @@ namespace ICSharpCode.ILSpy
{
public override void Execute(object parameter)
{
MainWindow.Instance.Close();
App.Current.MainWindow.Close();
}
}
}

20
ILSpy/Commands/GeneratePdbContextMenuEntry.cs

@ -29,10 +29,12 @@ using ICSharpCode.Decompiler.CSharp; @@ -29,10 +29,12 @@ using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
using Microsoft.Win32;
@ -41,14 +43,14 @@ namespace ICSharpCode.ILSpy @@ -41,14 +43,14 @@ namespace ICSharpCode.ILSpy
{
[ExportContextMenuEntry(Header = nameof(Resources.GeneratePortable))]
[Shared]
class GeneratePdbContextMenuEntry : IContextMenuEntry
class GeneratePdbContextMenuEntry(LanguageService languageService) : IContextMenuEntry
{
public void Execute(TextViewContext context)
{
var assembly = (context.SelectedTreeNodes?.FirstOrDefault() as AssemblyTreeNode)?.LoadedAssembly;
if (assembly == null)
return;
GeneratePdbForAssembly(assembly);
GeneratePdbForAssembly(assembly, languageService);
}
public bool IsEnabled(TextViewContext context) => true;
@ -60,7 +62,7 @@ namespace ICSharpCode.ILSpy @@ -60,7 +62,7 @@ namespace ICSharpCode.ILSpy
&& tn.LoadedAssembly.IsLoadedAsValidAssembly;
}
internal static void GeneratePdbForAssembly(LoadedAssembly assembly)
internal static void GeneratePdbForAssembly(LoadedAssembly assembly, LanguageService languageService)
{
var file = assembly.GetMetadataFileOrNull() as PEFile;
if (!PortablePdbWriter.HasCodeViewDebugDirectoryEntry(file))
@ -75,7 +77,7 @@ namespace ICSharpCode.ILSpy @@ -75,7 +77,7 @@ namespace ICSharpCode.ILSpy
if (dlg.ShowDialog() != true)
return;
DockWorkspace dockWorkspace = DockWorkspace.Instance;
DecompilationOptions options = LanguageService.Instance.CreateDecompilationOptions(dockWorkspace.ActiveTabPage);
DecompilationOptions options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions();
string fileName = dlg.FileName;
dockWorkspace.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
AvalonEditTextOutput output = new AvalonEditTextOutput();
@ -108,21 +110,21 @@ namespace ICSharpCode.ILSpy @@ -108,21 +110,21 @@ namespace ICSharpCode.ILSpy
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.GeneratePortable), MenuCategory = nameof(Resources.Save))]
[Shared]
class GeneratePdbMainMenuEntry : SimpleCommand
class GeneratePdbMainMenuEntry(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : SimpleCommand
{
public override bool CanExecute(object parameter)
{
return MainWindow.Instance.AssemblyTreeModel.SelectedNodes?.Count() == 1
&& MainWindow.Instance.AssemblyTreeModel.SelectedNodes?.FirstOrDefault() is AssemblyTreeNode tn
return assemblyTreeModel.SelectedNodes?.Count() == 1
&& assemblyTreeModel.SelectedNodes?.FirstOrDefault() is AssemblyTreeNode tn
&& !tn.LoadedAssembly.HasLoadError;
}
public override void Execute(object parameter)
{
var assembly = (MainWindow.Instance.AssemblyTreeModel.SelectedNodes?.FirstOrDefault() as AssemblyTreeNode)?.LoadedAssembly;
var assembly = (assemblyTreeModel.SelectedNodes?.FirstOrDefault() as AssemblyTreeNode)?.LoadedAssembly;
if (assembly == null)
return;
GeneratePdbContextMenuEntry.GeneratePdbForAssembly(assembly);
GeneratePdbContextMenuEntry.GeneratePdbForAssembly(assembly, languageService);
}
}
}

37
ILSpy/Commands/ILSpyCommands.cs

@ -1,37 +0,0 @@ @@ -1,37 +0,0 @@
// Copyright (c) 2018 Siegfried Pammer
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using ICSharpCode.ILSpy.Analyzers;
using ICSharpCode.ILSpy.Commands;
namespace ICSharpCode.ILSpy
{
static class ILSpyCommands
{
public static readonly AnalyzeCommand Analyze = new AnalyzeCommand();
public static readonly ManageAssemblyListsCommand ManageAssemblyListsCommand = new ManageAssemblyListsCommand();
public static readonly SetThemeCommand SetTheme = new SetThemeCommand();
}
}

6
ILSpy/Commands/ManageAssemblyListsCommand.cs

@ -25,12 +25,12 @@ namespace ICSharpCode.ILSpy @@ -25,12 +25,12 @@ namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.ManageAssembly_Lists), MenuIcon = "Images/AssemblyList", MenuCategory = nameof(Resources.Open), MenuOrder = 1.7)]
[Shared]
sealed class ManageAssemblyListsCommand : SimpleCommand
sealed class ManageAssemblyListsCommand(SettingsService settingsService) : SimpleCommand
{
public override void Execute(object parameter)
{
ManageAssemblyListsDialog dlg = new ManageAssemblyListsDialog();
dlg.Owner = MainWindow.Instance;
ManageAssemblyListsDialog dlg = new ManageAssemblyListsDialog(settingsService);
dlg.Owner = App.Current.MainWindow;
dlg.ShowDialog();
}
}

2
ILSpy/Commands/OpenFromGacCommand.cs

@ -43,7 +43,7 @@ namespace ICSharpCode.ILSpy @@ -43,7 +43,7 @@ namespace ICSharpCode.ILSpy
public override void Execute(object parameter)
{
OpenFromGacDialog dlg = new OpenFromGacDialog {
Owner = MainWindow.Instance
Owner = App.Current.MainWindow
};
if (dlg.ShowDialog() == true)

7
ILSpy/Commands/Pdb2XmlCommand.cs

@ -26,6 +26,7 @@ using System.Threading.Tasks; @@ -26,6 +26,7 @@ using System.Threading.Tasks;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
@ -36,18 +37,18 @@ namespace ICSharpCode.ILSpy @@ -36,18 +37,18 @@ namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources.DEBUGDumpPDBAsXML), MenuCategory = nameof(Resources.Open), MenuOrder = 2.6)]
[Shared]
sealed class Pdb2XmlCommand : SimpleCommand
sealed class Pdb2XmlCommand(AssemblyTreeModel assemblyTreeModel) : SimpleCommand
{
public override bool CanExecute(object parameter)
{
var selectedNodes = MainWindow.Instance.AssemblyTreeModel.SelectedNodes;
var selectedNodes = assemblyTreeModel.SelectedNodes;
return selectedNodes?.Any() == true
&& selectedNodes.All(n => n is AssemblyTreeNode asm && !asm.LoadedAssembly.HasLoadError);
}
public override void Execute(object parameter)
{
Execute(MainWindow.Instance.AssemblyTreeModel.SelectedNodes.OfType<AssemblyTreeNode>());
Execute(assemblyTreeModel.SelectedNodes.OfType<AssemblyTreeNode>());
}
internal static void Execute(IEnumerable<AssemblyTreeNode> nodes)

11
ILSpy/Commands/RemoveAssembliesWithLoadErrors.cs

@ -26,15 +26,8 @@ namespace ICSharpCode.ILSpy @@ -26,15 +26,8 @@ namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources._RemoveAssembliesWithLoadErrors), MenuCategory = nameof(Resources.Remove), MenuOrder = 2.6)]
[Shared]
class RemoveAssembliesWithLoadErrors : SimpleCommand
class RemoveAssembliesWithLoadErrors(AssemblyTreeModel assemblyTreeModel) : SimpleCommand
{
private readonly AssemblyTreeModel assemblyTreeModel;
public RemoveAssembliesWithLoadErrors(AssemblyTreeModel assemblyTreeModel)
{
this.assemblyTreeModel = assemblyTreeModel;
}
public override bool CanExecute(object parameter)
{
return assemblyTreeModel.AssemblyList.GetAssemblies().Any(l => l.HasLoadError);
@ -46,7 +39,7 @@ namespace ICSharpCode.ILSpy @@ -46,7 +39,7 @@ namespace ICSharpCode.ILSpy
{
if (!assembly.HasLoadError)
continue;
var node = MainWindow.Instance.AssemblyTreeModel.FindAssemblyNode(assembly);
var node = assemblyTreeModel.FindAssemblyNode(assembly);
if (node != null && node.CanDelete())
node.Delete();
}

11
ILSpy/Commands/SaveCodeContextMenuEntry.cs

@ -35,11 +35,11 @@ namespace ICSharpCode.ILSpy.TextView @@ -35,11 +35,11 @@ namespace ICSharpCode.ILSpy.TextView
{
[ExportContextMenuEntry(Header = nameof(Resources._SaveCode), Category = nameof(Resources.Save), Icon = "Images/Save")]
[Shared]
sealed class SaveCodeContextMenuEntry : IContextMenuEntry
sealed class SaveCodeContextMenuEntry(LanguageService languageService) : IContextMenuEntry
{
public void Execute(TextViewContext context)
{
Execute(context.SelectedTreeNodes);
Execute(context.SelectedTreeNodes, languageService);
}
public bool IsEnabled(TextViewContext context) => true;
@ -57,12 +57,11 @@ namespace ICSharpCode.ILSpy.TextView @@ -57,12 +57,11 @@ namespace ICSharpCode.ILSpy.TextView
|| (selectedNodes.Count > 1 && (selectedNodes.All(n => n is AssemblyTreeNode) || selectedNodes.All(n => n is IMemberTreeNode)));
}
public static void Execute(IReadOnlyList<SharpTreeNode> selectedNodes)
public static void Execute(IReadOnlyList<SharpTreeNode> selectedNodes, LanguageService languageService)
{
var settingsService = SettingsService.Instance;
var dockWorkspace = Docking.DockWorkspace.Instance;
var currentLanguage = LanguageService.Instance.Language;
var currentLanguage = languageService.Language;
var tabPage = dockWorkspace.ActiveTabPage;
tabPage.ShowTextView(textView => {
if (selectedNodes.Count == 1 && selectedNodes[0] is ILSpyTreeNode singleSelection)
@ -88,7 +87,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -88,7 +87,7 @@ namespace ICSharpCode.ILSpy.TextView
// Fallback: if nobody was able to handle the request, use default behavior.
// try to save all nodes to disk.
var options = LanguageService.Instance.CreateDecompilationOptions(dockWorkspace.ActiveTabPage);
var options = dockWorkspace.ActiveTabPage.CreateDecompilationOptions();
options.FullDecompilation = true;
textView.SaveToDisk(currentLanguage, selectedNodes.OfType<ILSpyTreeNode>(), options);
});

12
ILSpy/Commands/SaveCommand.cs

@ -28,16 +28,8 @@ namespace ICSharpCode.ILSpy @@ -28,16 +28,8 @@ namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._File), Header = nameof(Resources._SaveCode), MenuIcon = "Images/Save", MenuCategory = nameof(Resources.Save), MenuOrder = 0)]
[Shared]
sealed class SaveCommand : CommandWrapper
sealed class SaveCommand(AssemblyTreeModel assemblyTreeModel, LanguageService languageService) : CommandWrapper(ApplicationCommands.Save)
{
private AssemblyTreeModel assemblyTreeModel;
public SaveCommand(AssemblyTreeModel assemblyTreeModel)
: base(ApplicationCommands.Save)
{
this.assemblyTreeModel = assemblyTreeModel;
}
protected override void OnCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.Handled = true;
@ -46,7 +38,7 @@ namespace ICSharpCode.ILSpy @@ -46,7 +38,7 @@ namespace ICSharpCode.ILSpy
protected override void OnExecute(object sender, ExecutedRoutedEventArgs e)
{
SaveCodeContextMenuEntry.Execute(assemblyTreeModel.SelectedNodes.ToList());
SaveCodeContextMenuEntry.Execute(assemblyTreeModel.SelectedNodes.ToList(), languageService);
}
}
}

9
ILSpy/Commands/SelectPdbContextMenuEntry.cs

@ -21,6 +21,7 @@ using System.IO; @@ -21,6 +21,7 @@ using System.IO;
using System.Linq;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TreeNodes;
@ -29,7 +30,7 @@ namespace ICSharpCode.ILSpy @@ -29,7 +30,7 @@ namespace ICSharpCode.ILSpy
{
[ExportContextMenuEntry(Header = nameof(Resources.SelectPDB))]
[Shared]
class SelectPdbContextMenuEntry : IContextMenuEntry
class SelectPdbContextMenuEntry(AssemblyTreeModel assemblyTreeModel) : IContextMenuEntry
{
public async void Execute(TextViewContext context)
{
@ -48,10 +49,10 @@ namespace ICSharpCode.ILSpy @@ -48,10 +49,10 @@ namespace ICSharpCode.ILSpy
await assembly.LoadDebugInfo(dlg.FileName);
}
var node = (AssemblyTreeNode)MainWindow.Instance.AssemblyTreeModel.FindNodeByPath(new[] { assembly.FileName }, true);
var node = (AssemblyTreeNode)assemblyTreeModel.FindNodeByPath(new[] { assembly.FileName }, true);
node.UpdateToolTip();
MainWindow.Instance.AssemblyTreeModel.SelectNode(node);
MainWindow.Instance.AssemblyTreeModel.RefreshDecompiledView();
assemblyTreeModel.SelectNode(node);
assemblyTreeModel.RefreshDecompiledView();
}
public bool IsEnabled(TextViewContext context) => true;

8
ILSpy/Commands/SetThemeCommand.cs

@ -1,13 +1,17 @@ @@ -1,13 +1,17 @@

using System.Composition;
namespace ICSharpCode.ILSpy.Commands
{
public class SetThemeCommand : SimpleCommand
[Export]
[Shared]
public class SetThemeCommand(SettingsService settingsService) : SimpleCommand
{
public override void Execute(object parameter)
{
if (parameter is string theme)
{
SettingsService.Instance.SessionSettings.Theme = theme;
settingsService.SessionSettings.Theme = theme;
}
}
}

9
ILSpy/Commands/SortAssemblyListCommand.cs

@ -20,6 +20,7 @@ using System; @@ -20,6 +20,7 @@ using System;
using System.Collections.Generic;
using System.Composition;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.TreeView;
@ -29,22 +30,22 @@ namespace ICSharpCode.ILSpy @@ -29,22 +30,22 @@ namespace ICSharpCode.ILSpy
[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))]
[Shared]
sealed class SortAssemblyListCommand : SimpleCommand
sealed class SortAssemblyListCommand(AssemblyTreeModel assemblyTreeModel) : SimpleCommand
{
public override void Execute(object parameter)
{
MainWindow.Instance.AssemblyTreeModel.SortAssemblyList();
assemblyTreeModel.SortAssemblyList();
}
}
[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))]
[Shared]
sealed class CollapseAllCommand : SimpleCommand
sealed class CollapseAllCommand(AssemblyTreeModel assemblyTreeModel) : SimpleCommand
{
public override void Execute(object parameter)
{
MainWindow.Instance.AssemblyTreeModel.CollapseAll();
assemblyTreeModel.CollapseAll();
}
}

3
ILSpy/ContextMenuEntry.cs

@ -31,6 +31,7 @@ using ICSharpCode.ILSpyX.TreeView; @@ -31,6 +31,7 @@ using ICSharpCode.ILSpyX.TreeView;
using TomsToolbox.Composition;
using TomsToolbox.Essentials;
using TomsToolbox.Wpf.Composition;
namespace ICSharpCode.ILSpy
{
@ -222,7 +223,7 @@ namespace ICSharpCode.ILSpy @@ -222,7 +223,7 @@ namespace ICSharpCode.ILSpy
private ContextMenuProvider(Control control)
{
entries = App.ExportProvider.GetExports<IContextMenuEntry, IContextMenuEntryMetadata>().ToArray();
entries = control.GetExportProvider().GetExports<IContextMenuEntry, IContextMenuEntryMetadata>().ToArray();
this.control = control;
}

36
ILSpy/Docking/DockWorkspace.cs

@ -32,6 +32,7 @@ using AvalonDock.Layout.Serialization; @@ -32,6 +32,7 @@ using AvalonDock.Layout.Serialization;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.ILSpy.Analyzers;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Search;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.ViewModels;
@ -44,15 +45,21 @@ namespace ICSharpCode.ILSpy.Docking @@ -44,15 +45,21 @@ namespace ICSharpCode.ILSpy.Docking
{
public class DockWorkspace : ObservableObject, ILayoutUpdateStrategy
{
private static SessionSettings SessionSettings => SettingsService.Instance.SessionSettings;
private static readonly IExportProvider exportProvider = App.ExportProvider;
private readonly IExportProvider exportProvider = App.ExportProvider;
private static SettingsService SettingsService => exportProvider.GetExportedValue<SettingsService>();
private static LanguageService LanguageService => exportProvider.GetExportedValue<LanguageService>();
private static SessionSettings SessionSettings => SettingsService.SessionSettings;
public static readonly DockWorkspace Instance = new();
private readonly ObservableCollection<TabPageModel> tabPages = [];
private DockingManager dockingManager;
private DockingManager DockingManager => exportProvider.GetExportedValue<DockingManager>();
AssemblyTreeModel AssemblyTreeModel => exportProvider.GetExportedValue<AssemblyTreeModel>();
private DockWorkspace()
{
@ -123,7 +130,7 @@ namespace ICSharpCode.ILSpy.Docking @@ -123,7 +130,7 @@ namespace ICSharpCode.ILSpy.Docking
public void AddTabPage(TabPageModel tabPage = null)
{
tabPages.Add(tabPage ?? new TabPageModel());
tabPages.Add(tabPage ?? new TabPageModel(AssemblyTreeModel, SettingsService, LanguageService));
}
public ReadOnlyObservableCollection<TabPageModel> TabPages { get; }
@ -170,29 +177,28 @@ namespace ICSharpCode.ILSpy.Docking @@ -170,29 +177,28 @@ namespace ICSharpCode.ILSpy.Docking
{
if (state.DecompiledNodes != null)
{
MainWindow.Instance.AssemblyTreeModel.SelectNodes(state.DecompiledNodes);
AssemblyTreeModel.SelectNodes(state.DecompiledNodes);
}
else
{
MainWindow.Instance.AssemblyTreeModel.NavigateTo(new(state.ViewedUri, null));
AssemblyTreeModel.NavigateTo(new(state.ViewedUri, null));
}
}
}
}
public PaneModel ActivePane {
get => dockingManager?.ActiveContent as PaneModel;
get => DockingManager?.ActiveContent as PaneModel;
set {
if (dockingManager is not null)
dockingManager.ActiveContent = value;
if (DockingManager is not null)
DockingManager.ActiveContent = value;
}
}
public void InitializeLayout(DockingManager manager)
public void InitializeLayout()
{
this.dockingManager = manager;
manager.LayoutUpdateStrategy = this;
XmlLayoutSerializer serializer = new XmlLayoutSerializer(manager);
DockingManager.LayoutUpdateStrategy = this;
XmlLayoutSerializer serializer = new XmlLayoutSerializer(DockingManager);
serializer.LayoutSerializationCallback += LayoutSerializationCallback;
try
{
@ -254,8 +260,8 @@ namespace ICSharpCode.ILSpy.Docking @@ -254,8 +260,8 @@ namespace ICSharpCode.ILSpy.Docking
}
CloseAllTabs();
SessionSettings.DockLayout.Reset();
InitializeLayout(MainWindow.Instance.dockManager);
MainWindow.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)MainWindow.Instance.AssemblyTreeModel.RefreshDecompiledView);
InitializeLayout();
App.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, AssemblyTreeModel.RefreshDecompiledView);
}
static readonly PropertyInfo previousContainerProperty = typeof(LayoutContent).GetProperty("PreviousContainer", BindingFlags.NonPublic | BindingFlags.Instance);

7
ILSpy/ExtensionMethods.cs

@ -76,10 +76,11 @@ namespace ICSharpCode.ILSpy @@ -76,10 +76,11 @@ namespace ICSharpCode.ILSpy
return result;
}
public static ICompilation? GetTypeSystemWithCurrentOptionsOrNull(this MetadataFile file)
public static ICompilation? GetTypeSystemWithCurrentOptionsOrNull(this MetadataFile file, SettingsService settingsService)
{
return LoadedAssemblyExtensions.GetLoadedAssembly(file)
.GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(SettingsService.Instance.DecompilerSettings));
return file
.GetLoadedAssembly()
.GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(settingsService.DecompilerSettings));
}
#region DPI independence

4
ILSpy/Languages/CSharpILMixedLanguage.cs

@ -43,13 +43,13 @@ namespace ICSharpCode.ILSpy @@ -43,13 +43,13 @@ namespace ICSharpCode.ILSpy
[Export(typeof(Language))]
[Shared]
class CSharpILMixedLanguage : ILLanguage
class CSharpILMixedLanguage(SettingsService settingsService) : ILLanguage
{
public override string Name => "IL with C#";
protected override ReflectionDisassembler CreateDisassembler(ITextOutput output, DecompilationOptions options)
{
var displaySettings = SettingsService.Instance.DisplaySettings;
var displaySettings = settingsService.DisplaySettings;
return new ReflectionDisassembler(output,
new MixedMethodBodyDisassembler(output, options) {
DetectControlStructure = detectControlStructure,

38
ILSpy/Languages/CSharpLanguage.cs

@ -38,6 +38,7 @@ using ICSharpCode.Decompiler.Metadata; @@ -38,6 +38,7 @@ using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.Output;
using ICSharpCode.Decompiler.Solution;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpyX;
@ -55,25 +56,18 @@ namespace ICSharpCode.ILSpy @@ -55,25 +56,18 @@ namespace ICSharpCode.ILSpy
[Shared]
public class CSharpLanguage : Language
{
readonly IReadOnlyCollection<IResourceFileHandler> resourceFileHandlers;
string name = "C#";
bool showAllMembers = false;
int transformCount = int.MaxValue;
public CSharpLanguage(IEnumerable<IResourceFileHandler> resourceFileHandlers)
{
this.resourceFileHandlers = resourceFileHandlers.ToArray();
}
#if DEBUG
internal static IEnumerable<CSharpLanguage> GetDebugLanguages(IReadOnlyCollection<IResourceFileHandler> resourceFileHandlers)
internal static IEnumerable<CSharpLanguage> GetDebugLanguages()
{
string lastTransformName = "no transforms";
int transformCount = 0;
foreach (var transform in CSharpDecompiler.GetAstTransforms())
{
yield return new CSharpLanguage(resourceFileHandlers) {
yield return new() {
transformCount = transformCount,
name = "C# - " + lastTransformName,
showAllMembers = true
@ -81,7 +75,7 @@ namespace ICSharpCode.ILSpy @@ -81,7 +75,7 @@ namespace ICSharpCode.ILSpy
lastTransformName = "after " + transform.GetType().Name;
transformCount++;
}
yield return new CSharpLanguage(resourceFileHandlers) {
yield return new() {
name = "C# - " + lastTransformName,
showAllMembers = true
};
@ -364,15 +358,15 @@ namespace ICSharpCode.ILSpy @@ -364,15 +358,15 @@ namespace ICSharpCode.ILSpy
void AddReferenceWarningMessage(MetadataFile module, ITextOutput output)
{
var loadedAssembly = MainWindow.Instance.AssemblyTreeModel.AssemblyList.GetAssemblies().FirstOrDefault(la => la.GetMetadataFileOrNull() == module);
var loadedAssembly = AssemblyTreeModel.AssemblyList.GetAssemblies().FirstOrDefault(la => la.GetMetadataFileOrNull() == module);
if (loadedAssembly == null || !loadedAssembly.LoadedAssemblyReferencesInfo.HasErrors)
return;
string line1 = Properties.Resources.WarningSomeAssemblyReference;
string line2 = Properties.Resources.PropertyManuallyMissingReferencesListLoadedAssemblies;
AddWarningMessage(module, output, line1, line2, Properties.Resources.ShowAssemblyLoad, Images.ViewCode, delegate {
ILSpyTreeNode assemblyNode = MainWindow.Instance.AssemblyTreeModel.FindTreeNode(module);
ILSpyTreeNode assemblyNode = AssemblyTreeModel.FindTreeNode(module);
assemblyNode.EnsureLazyChildren();
MainWindow.Instance.AssemblyTreeModel.SelectNode(assemblyNode.Children.OfType<ReferenceFolderTreeNode>().Single());
AssemblyTreeModel.SelectNode(assemblyNode.Children.OfType<ReferenceFolderTreeNode>().Single());
});
}
@ -436,7 +430,7 @@ namespace ICSharpCode.ILSpy @@ -436,7 +430,7 @@ namespace ICSharpCode.ILSpy
{
options.DecompilerSettings.UseSdkStyleProjectFormat = false;
}
var decompiler = new ILSpyWholeProjectDecompiler(assembly, options, resourceFileHandlers) {
var decompiler = new ILSpyWholeProjectDecompiler(assembly, options) {
ProgressIndicator = options.Progress
};
return decompiler.DecompileProject(module, options.SaveAsProjectDirectory, new TextOutputWriter(output), options.CancellationToken);
@ -549,20 +543,18 @@ namespace ICSharpCode.ILSpy @@ -549,20 +543,18 @@ namespace ICSharpCode.ILSpy
{
readonly LoadedAssembly assembly;
readonly DecompilationOptions options;
private readonly IReadOnlyCollection<IResourceFileHandler> resourceFileHandlers;
public ILSpyWholeProjectDecompiler(LoadedAssembly assembly, DecompilationOptions options, IReadOnlyCollection<IResourceFileHandler> resourceFileHandlers)
public ILSpyWholeProjectDecompiler(LoadedAssembly assembly, DecompilationOptions options)
: base(options.DecompilerSettings, assembly.GetAssemblyResolver(options.DecompilerSettings.AutoLoadAssemblyReferences, options.DecompilerSettings.ApplyWindowsRuntimeProjections), null, assembly.GetAssemblyReferenceClassifier(options.DecompilerSettings.ApplyWindowsRuntimeProjections), assembly.GetDebugInfoOrNull())
{
this.assembly = assembly;
this.options = options;
this.resourceFileHandlers = resourceFileHandlers;
}
protected override IEnumerable<ProjectItemInfo> WriteResourceToFile(string fileName, string resourceName, Stream entryStream)
{
var context = new ResourceFileHandlerContext(options);
foreach (var handler in resourceFileHandlers)
foreach (var handler in ResourceFileHandlers)
{
if (handler.CanHandle(fileName, context))
{
@ -576,19 +568,19 @@ namespace ICSharpCode.ILSpy @@ -576,19 +568,19 @@ namespace ICSharpCode.ILSpy
}
}
static CSharpAmbience CreateAmbience()
CSharpAmbience CreateAmbience()
{
CSharpAmbience ambience = new CSharpAmbience();
// Do not forget to update CSharpAmbienceTests.ILSpyMainTreeViewTypeFlags, if this ever changes.
ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.PlaceReturnTypeAfterParameterList;
if (SettingsService.Instance.DecompilerSettings.LiftNullables)
if (SettingsService.DecompilerSettings.LiftNullables)
{
ambience.ConversionFlags |= ConversionFlags.UseNullableSpecifierForValueTypes;
}
return ambience;
}
static string EntityToString(IEntity entity, bool includeDeclaringTypeName, bool includeNamespace, bool includeNamespaceOfDeclaringTypeName)
string EntityToString(IEntity entity, bool includeDeclaringTypeName, bool includeNamespace, bool includeNamespaceOfDeclaringTypeName)
{
// Do not forget to update CSharpAmbienceTests, if this ever changes.
var ambience = CreateAmbience();
@ -784,7 +776,7 @@ namespace ICSharpCode.ILSpy @@ -784,7 +776,7 @@ namespace ICSharpCode.ILSpy
public override bool ShowMember(IEntity member)
{
MetadataFile assembly = member.ParentModule.MetadataFile;
return showAllMembers || !CSharpDecompiler.MemberIsHidden(assembly, member.MetadataToken, SettingsService.Instance.DecompilerSettings);
return showAllMembers || !CSharpDecompiler.MemberIsHidden(assembly, member.MetadataToken, SettingsService.DecompilerSettings);
}
public override RichText GetRichTextTooltip(IEntity entity)
@ -793,7 +785,7 @@ namespace ICSharpCode.ILSpy @@ -793,7 +785,7 @@ namespace ICSharpCode.ILSpy
var output = new StringWriter();
var decoratedWriter = new TextWriterTokenWriter(output);
var writer = new CSharpHighlightingTokenWriter(TokenWriter.InsertRequiredSpaces(decoratedWriter), locatable: decoratedWriter);
var settings = SettingsService.Instance.DecompilerSettings;
var settings = SettingsService.DecompilerSettings;
if (!settings.LiftNullables)
{
flags &= ~ConversionFlags.UseNullableSpecifierForValueTypes;

6
ILSpy/Languages/ILLanguage.cs

@ -31,6 +31,7 @@ using ICSharpCode.Decompiler.TypeSystem; @@ -31,6 +31,7 @@ using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
namespace ICSharpCode.ILSpy
@ -58,7 +59,7 @@ namespace ICSharpCode.ILSpy @@ -58,7 +59,7 @@ namespace ICSharpCode.ILSpy
protected virtual ReflectionDisassembler CreateDisassembler(ITextOutput output, DecompilationOptions options)
{
var displaySettings = SettingsService.Instance.DisplaySettings;
var displaySettings = SettingsService.DisplaySettings;
output.IndentationString = options.DecompilerSettings.CSharpFormattingOptions.IndentationString;
return new ReflectionDisassembler(output, options.CancellationToken) {
DetectControlStructure = detectControlStructure,
@ -198,10 +199,9 @@ namespace ICSharpCode.ILSpy @@ -198,10 +199,9 @@ namespace ICSharpCode.ILSpy
public override RichText GetRichTextTooltip(IEntity entity)
{
var output = new AvalonEditTextOutput() { IgnoreNewLineAndIndent = true };
var settingsService = SettingsService.Instance;
var dockWorkspace = DockWorkspace.Instance;
var disasm = CreateDisassembler(output, LanguageService.Instance.CreateDecompilationOptions(dockWorkspace.ActiveTabPage));
var disasm = CreateDisassembler(output, dockWorkspace.ActiveTabPage.CreateDecompilationOptions());
MetadataFile module = entity.ParentModule?.MetadataFile;
if (module == null)
{

8
ILSpy/Languages/Language.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Text;
@ -29,6 +30,7 @@ using ICSharpCode.Decompiler.Solution; @@ -29,6 +30,7 @@ using ICSharpCode.Decompiler.Solution;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.Abstractions;
@ -42,6 +44,12 @@ namespace ICSharpCode.ILSpy @@ -42,6 +44,12 @@ namespace ICSharpCode.ILSpy
/// </remarks>
public abstract class Language : ILanguage
{
public static SettingsService SettingsService { get; } = App.ExportProvider.GetExportedValue<SettingsService>();
public static AssemblyTreeModel AssemblyTreeModel { get; } = App.ExportProvider.GetExportedValue<AssemblyTreeModel>();
public static ICollection<IResourceFileHandler> ResourceFileHandlers { get; } = App.ExportProvider.GetExportedValues<IResourceFileHandler>().ToArray();
/// <summary>
/// Gets the name of the language (as shown in the UI)
/// </summary>

18
ILSpy/Languages/LanguageService.cs

@ -21,26 +21,23 @@ @@ -21,26 +21,23 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Composition;
using System.Linq;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
using TomsToolbox.Wpf;
namespace ICSharpCode.ILSpy
{
[Export]
[Shared]
public class LanguageService : ObservableObjectBase
{
public static readonly LanguageService Instance = new(App.ExportProvider.GetExportedValues<Language>(), App.ExportProvider.GetExportedValues<IResourceFileHandler>(), SettingsService.Instance);
private readonly LanguageSettings languageSettings;
private readonly SettingsService settingsService;
public LanguageService(IEnumerable<Language> languages, IEnumerable<IResourceFileHandler> resourceFileHandlers, SettingsService settingsService)
public LanguageService(IEnumerable<Language> languages, SettingsService settingsService)
{
this.settingsService = settingsService;
languageSettings = settingsService.SessionSettings.LanguageSettings;
var sortedLanguages = languages.ToList();
@ -48,7 +45,7 @@ namespace ICSharpCode.ILSpy @@ -48,7 +45,7 @@ namespace ICSharpCode.ILSpy
sortedLanguages.Sort((a, b) => string.Compare(a.Name, b.Name, StringComparison.Ordinal));
#if DEBUG
sortedLanguages.AddRange(ILAstLanguage.GetDebugLanguages());
sortedLanguages.AddRange(CSharpLanguage.GetDebugLanguages(resourceFileHandlers.ToArray()));
sortedLanguages.AddRange(CSharpLanguage.GetDebugLanguages());
#endif
AllLanguages = sortedLanguages.AsReadOnly();
@ -143,10 +140,5 @@ namespace ICSharpCode.ILSpy @@ -143,10 +140,5 @@ namespace ICSharpCode.ILSpy
languageSettings.LanguageVersionId = languageVersion?.Version;
}
}
public DecompilationOptions CreateDecompilationOptions(TabPageModel tabPage)
{
return new(LanguageVersion, settingsService.DecompilerSettings, settingsService.DisplaySettings) { Progress = tabPage.Content as IProgress<DecompilationProgress> };
}
}
}

10
ILSpy/MainWindow.xaml

@ -18,6 +18,8 @@ @@ -18,6 +18,8 @@
xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes"
xmlns:toms="urn:TomsToolbox"
xmlns:viewModels="clr-namespace:ICSharpCode.ILSpy.ViewModels"
xmlns:composition="urn:TomsToolbox.Composition"
xmlns:commands="clr-namespace:ICSharpCode.ILSpy.Commands"
d:DataContext="{d:DesignInstance local:MainWindowViewModel}">
<Window.Resources>
@ -36,7 +38,7 @@ @@ -36,7 +38,7 @@
</b:Interaction.Behaviors>
<Window.InputBindings>
<KeyBinding Key="R" Modifiers="Control" Command="{x:Static local:ILSpyCommands.Analyze}" />
<KeyBinding Key="R" Modifiers="Control" Command="{Binding AnalyzeCommand}" />
<KeyBinding Key="Z" Modifiers="Control" Command="{x:Static NavigationCommands.BrowseBack}" />
</Window.InputBindings>
@ -60,7 +62,7 @@ @@ -60,7 +62,7 @@
<MenuItem Header="{x:Static properties:Resources.Theme}" ItemsSource="{x:Static themes:ThemeManager.AllThemes}">
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
<Setter Property="Command" Value="{x:Static local:ILSpyCommands.SetTheme}" />
<Setter Property="Command" Value="{composition:Import {x:Type commands:SetThemeCommand}}" />
<Setter Property="CommandParameter" Value="{Binding}" />
<Setter Property="IsCheckable" Value="True" />
<!-- Required by AvalonDock's MenuItem style to show the checkmark -->
@ -123,7 +125,7 @@ @@ -123,7 +125,7 @@
ToolTip="{x:Static properties:Resources.SelectAssemblyListDropdownTooltip}"
SelectedItem="{Binding SessionSettings.ActiveAssemblyList}" />
</Grid>
<Button Command="{x:Static local:ILSpyCommands.ManageAssemblyListsCommand}"
<Button Command="{composition:Import {x:Type local:ManageAssemblyListsCommand}}"
ToolTip="{x:Static properties:Resources.ManageAssemblyLists}">
<Image Width="16" Height="16" Source="{controls:XamlResource Images/AssemblyList}"
Style="{StaticResource DarkModeAwareImageStyle}" />
@ -186,7 +188,7 @@ @@ -186,7 +188,7 @@
</StatusBarItem>
</StatusBar>
<avalondock:DockingManager x:Name="dockManager"
<avalondock:DockingManager x:Name="DockManager"
DataContext="{Binding Workspace}"
AnchorablesSource="{Binding ToolPanes}"
DocumentsSource="{Binding TabPages}"

59
ILSpy/MainWindow.xaml.cs

@ -17,7 +17,9 @@ @@ -17,7 +17,9 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Composition;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
@ -30,7 +32,6 @@ using System.Windows.Threading; @@ -30,7 +32,6 @@ using System.Windows.Threading;
using AvalonDock.Layout.Serialization;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.Updates;
using ICSharpCode.ILSpyX.FileLoaders;
@ -44,25 +45,22 @@ namespace ICSharpCode.ILSpy @@ -44,25 +45,22 @@ namespace ICSharpCode.ILSpy
/// <summary>
/// The main window of the application.
/// </summary>
partial class MainWindow : Window
[Export]
[Shared]
#pragma warning disable MEF003 // Main window is a singleton
partial class MainWindow
{
static MainWindow instance;
private readonly AssemblyTreeModel assemblyTreeModel;
private readonly IEnumerable<IFileLoader> fileLoaders;
private readonly MenuService menuService;
private readonly SettingsService settingsService;
private readonly MainWindowViewModel mainWindowViewModel = new();
public static MainWindow Instance {
get { return instance; }
}
public AssemblyTreeModel AssemblyTreeModel {
get {
return App.ExportProvider.GetExportedValue<AssemblyTreeModel>();
}
}
public MainWindow()
public MainWindow(MainWindowViewModel mainWindowViewModel, AssemblyTreeModel assemblyTreeModel, IEnumerable<IFileLoader> fileLoaders, MenuService menuService, SettingsService settingsService)
{
instance = this;
this.assemblyTreeModel = assemblyTreeModel;
this.fileLoaders = fileLoaders;
this.menuService = menuService;
this.settingsService = settingsService;
// Make sure Images are initialized on the UI thread.
this.Icon = Images.ILSpyIcon;
@ -74,12 +72,12 @@ namespace ICSharpCode.ILSpy @@ -74,12 +72,12 @@ namespace ICSharpCode.ILSpy
InitFileLoaders();
Dispatcher.BeginInvoke(DispatcherPriority.Background, () => {
mainWindowViewModel.Workspace.InitializeLayout(dockManager);
MenuService.Instance.Init(mainMenu, toolBar, InputBindings);
mainWindowViewModel.Workspace.InitializeLayout();
menuService.Init(mainMenu, toolBar, InputBindings);
Dispatcher.BeginInvoke(DispatcherPriority.Background, () => {
AssemblyTreeModel.Initialize();
AssemblyTreeModel.Show();
assemblyTreeModel.Initialize();
assemblyTreeModel.Show();
});
});
}
@ -97,9 +95,8 @@ namespace ICSharpCode.ILSpy @@ -97,9 +95,8 @@ namespace ICSharpCode.ILSpy
void InitFileLoaders()
{
// TODO
foreach (var loader in App.ExportProvider.GetExportedValues<IFileLoader>())
foreach (var loader in fileLoaders)
{
}
}
@ -113,7 +110,7 @@ namespace ICSharpCode.ILSpy @@ -113,7 +110,7 @@ namespace ICSharpCode.ILSpy
var source = PresentationSource.FromVisual(this);
var sessionSettings = SettingsService.Instance.SessionSettings;
var sessionSettings = settingsService.SessionSettings;
// Validate and Set Window Bounds
var windowBounds = Rect.Transform(sessionSettings.WindowBounds, source?.CompositionTarget?.TransformToDevice ?? Matrix.Identity);
@ -185,7 +182,7 @@ namespace ICSharpCode.ILSpy @@ -185,7 +182,7 @@ namespace ICSharpCode.ILSpy
else
{
updatePanel.Visibility = Visibility.Collapsed;
string downloadUrl = await NotifyOfUpdatesStrategy.CheckForUpdatesAsync(SettingsService.Instance.SpySettings);
string downloadUrl = await NotifyOfUpdatesStrategy.CheckForUpdatesAsync(settingsService.SpySettings);
AdjustUpdateUIAfterCheck(downloadUrl, true);
}
}
@ -243,22 +240,22 @@ namespace ICSharpCode.ILSpy @@ -243,22 +240,22 @@ namespace ICSharpCode.ILSpy
base.OnStateChanged(e);
// store window state in settings only if it's not minimized
if (this.WindowState != WindowState.Minimized)
SettingsService.Instance.SessionSettings.WindowState = this.WindowState;
settingsService.SessionSettings.WindowState = this.WindowState;
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
var snapshot = SettingsService.Instance.CreateSnapshot();
var snapshot = settingsService.CreateSnapshot();
var sessionSettings = snapshot.GetSettings<SessionSettings>();
sessionSettings.ActiveAssemblyList = AssemblyTreeModel.AssemblyList.ListName;
sessionSettings.ActiveTreeViewPath = AssemblyTreeModel.SelectedPath;
sessionSettings.ActiveAutoLoadedAssembly = GetAutoLoadedAssemblyNode(AssemblyTreeModel.SelectedItem);
sessionSettings.ActiveAssemblyList = assemblyTreeModel.AssemblyList.ListName;
sessionSettings.ActiveTreeViewPath = assemblyTreeModel.SelectedPath;
sessionSettings.ActiveAutoLoadedAssembly = GetAutoLoadedAssemblyNode(assemblyTreeModel.SelectedItem);
sessionSettings.WindowBounds = this.RestoreBounds;
sessionSettings.DockLayout.Serialize(new XmlLayoutSerializer(dockManager));
sessionSettings.DockLayout.Serialize(new XmlLayoutSerializer(DockManager));
snapshot.Save();
}

16
ILSpy/MainWindowViewModel.cs

@ -16,6 +16,10 @@ @@ -16,6 +16,10 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Composition;
using ICSharpCode.ILSpy.Analyzers;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpyX;
@ -23,11 +27,15 @@ using TomsToolbox.Wpf; @@ -23,11 +27,15 @@ using TomsToolbox.Wpf;
namespace ICSharpCode.ILSpy
{
class MainWindowViewModel : ObservableObject
[Export]
[Shared]
public class MainWindowViewModel(AssemblyTreeModel assemblyTreeModel, AnalyzerTreeViewModel analyzerTreeViewModel, SettingsService settingsService, LanguageService languageService) : ObservableObject
{
public DockWorkspace Workspace => DockWorkspace.Instance;
public SessionSettings SessionSettings => SettingsService.Instance.SessionSettings;
public LanguageService LanguageService => LanguageService.Instance;
public AssemblyListManager AssemblyListManager => SettingsService.Instance.AssemblyListManager;
public SessionSettings SessionSettings => settingsService.SessionSettings;
public LanguageService LanguageService => languageService;
public AssemblyListManager AssemblyListManager => settingsService.AssemblyListManager;
public AnalyzeCommand AnalyzeCommand { get; } = new(assemblyTreeModel, analyzerTreeViewModel);
}
}

2
ILSpy/Metadata/CorTables/EventTableTreeNode.cs

@ -94,7 +94,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -94,7 +94,7 @@ namespace ICSharpCode.ILSpy.Metadata
IEntity IMemberTreeNode.Member {
get {
return ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule)?.GetDefinition(handle);
return ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule)?.GetDefinition(handle);
}
}

2
ILSpy/Metadata/CorTables/FieldTableTreeNode.cs

@ -95,7 +95,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -95,7 +95,7 @@ namespace ICSharpCode.ILSpy.Metadata
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(fieldDef.Name):X} \"{Name}\"";
IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule)?.GetDefinition(handle);
IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule)?.GetDefinition(handle);
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int Signature => MetadataTokens.GetHeapOffset(fieldDef.Signature);

2
ILSpy/Metadata/CorTables/MethodTableTreeNode.cs

@ -131,7 +131,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -131,7 +131,7 @@ namespace ICSharpCode.ILSpy.Metadata
}
}
IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule)?.GetDefinition(handle);
IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule)?.GetDefinition(handle);
public MethodDefEntry(MetadataFile metadataFile, MethodDefinitionHandle handle)
{

2
ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs

@ -92,7 +92,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -92,7 +92,7 @@ namespace ICSharpCode.ILSpy.Metadata
public string NameTooltip => $"{MetadataTokens.GetHeapOffset(propertyDef.Name):X} \"{Name}\"";
IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule).GetDefinition(handle);
IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule)?.GetDefinition(handle);
[ColumnInfo("X8", Kind = ColumnKind.HeapOffset)]
public int Signature => MetadataTokens.GetHeapOffset(propertyDef.Signature);

2
ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs

@ -173,7 +173,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -173,7 +173,7 @@ namespace ICSharpCode.ILSpy.Metadata
}
}
IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull()?.MainModule).GetDefinition(handle);
IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule)?.GetDefinition(handle);
public TypeDefEntry(MetadataFile metadataFile, TypeDefinitionHandle handle)
{

2
ILSpy/Metadata/DebugMetadataTablesTreeNode.cs

@ -58,7 +58,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -58,7 +58,7 @@ namespace ICSharpCode.ILSpy.Metadata
if (ShowTable(TableIndex.CustomDebugInformation))
this.Children.Add(new CustomDebugInformationTableTreeNode(metadataFile));
bool ShowTable(TableIndex table) => !SettingsService.Instance.DisplaySettings.HideEmptyMetadataTables || metadataFile.Metadata.GetTableRowCount(table) > 0;
bool ShowTable(TableIndex table) => !SettingsService.DisplaySettings.HideEmptyMetadataTables || metadataFile.Metadata.GetTableRowCount(table) > 0;
}
public override bool View(TabPageModel tabPage)

5
ILSpy/Metadata/MetadataProtocolHandler.cs

@ -21,20 +21,21 @@ using System.Linq; @@ -21,20 +21,21 @@ using System.Linq;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy.Metadata
{
[Export(typeof(IProtocolHandler))]
[Shared]
class MetadataProtocolHandler : IProtocolHandler
class MetadataProtocolHandler(AssemblyTreeModel assemblyTreeModel) : IProtocolHandler
{
public ILSpyTreeNode Resolve(string protocol, MetadataFile module, Handle handle, out bool newTabPage)
{
newTabPage = true;
if (protocol != "metadata")
return null;
var assemblyTreeNode = MainWindow.Instance.AssemblyTreeModel.FindTreeNode(module) as AssemblyTreeNode;
var assemblyTreeNode = assemblyTreeModel.FindTreeNode(module) as AssemblyTreeNode;
if (assemblyTreeNode == null)
return null;
var mxNode = assemblyTreeNode.Children.OfType<MetadataTreeNode>().FirstOrDefault();

2
ILSpy/Metadata/MetadataTablesTreeNode.cs

@ -50,7 +50,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -50,7 +50,7 @@ namespace ICSharpCode.ILSpy.Metadata
}
}
internal static bool ShowTable(TableIndex table, MetadataReader metadata) => !SettingsService.Instance.DisplaySettings.HideEmptyMetadataTables || metadata.GetTableRowCount(table) > 0;
internal static bool ShowTable(TableIndex table, MetadataReader metadata) => !SettingsService.DisplaySettings.HideEmptyMetadataTables || metadata.GetTableRowCount(table) > 0;
internal static MetadataTableTreeNode CreateTableTreeNode(TableIndex table, MetadataFile metadataFile)
{

17
ILSpy/Options/OptionsDialog.xaml.cs

@ -29,9 +29,9 @@ namespace ICSharpCode.ILSpy.Options @@ -29,9 +29,9 @@ namespace ICSharpCode.ILSpy.Options
/// </summary>
public sealed partial class OptionsDialog
{
public OptionsDialog()
public OptionsDialog(SettingsService settingsService)
{
DataContext = new OptionsDialogViewModel();
DataContext = new OptionsDialogViewModel(settingsService);
InitializeComponent();
}
}
@ -59,19 +59,12 @@ namespace ICSharpCode.ILSpy.Options @@ -59,19 +59,12 @@ namespace ICSharpCode.ILSpy.Options
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._View), Header = nameof(Resources._Options), MenuCategory = nameof(Resources.Options), MenuOrder = 999)]
[Shared]
sealed class ShowOptionsCommand : SimpleCommand
sealed class ShowOptionsCommand(AssemblyTreeModel assemblyTreeModel, SettingsService settingsService) : SimpleCommand
{
private readonly AssemblyTreeModel assemblyTreeModel;
public ShowOptionsCommand(AssemblyTreeModel assemblyTreeModel)
{
this.assemblyTreeModel = assemblyTreeModel;
}
public override void Execute(object parameter)
{
OptionsDialog dlg = new() {
Owner = MainWindow.Instance,
OptionsDialog dlg = new(settingsService) {
Owner = App.Current.MainWindow,
};
if (dlg.ShowDialog() == true)
{

4
ILSpy/Options/OptionsDialogViewModel.cs

@ -46,9 +46,9 @@ namespace ICSharpCode.ILSpy.Options @@ -46,9 +46,9 @@ namespace ICSharpCode.ILSpy.Options
.ExceptNullItems()
.ToArray();
public OptionsDialogViewModel()
public OptionsDialogViewModel(SettingsService settingsService)
{
this.snapshot = SettingsService.Instance.CreateSnapshot();
this.snapshot = settingsService.CreateSnapshot();
foreach (var optionPage in optionPages)
{

64
ILSpy/Search/SearchPane.xaml.cs

@ -33,9 +33,11 @@ using System.Windows.Media; @@ -33,9 +33,11 @@ using System.Windows.Media;
using System.Windows.Threading;
using ICSharpCode.ILSpy.AppEnv;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.Abstractions;
using ICSharpCode.ILSpyX.Extensions;
using ICSharpCode.ILSpyX.Search;
@ -57,13 +59,20 @@ namespace ICSharpCode.ILSpy.Search @@ -57,13 +59,20 @@ namespace ICSharpCode.ILSpy.Search
RunningSearch currentSearch;
bool runSearchOnNextShow;
IComparer<SearchResult> resultsComparer;
readonly AssemblyTreeModel assemblyTreeModel;
readonly ITreeNodeFactory treeNodeFactory;
readonly SettingsService settingsService;
public ObservableCollection<SearchResult> Results { get; } = [];
string SearchTerm => searchBox.Text;
public SearchPane()
public SearchPane(AssemblyTreeModel assemblyTreeModel, ITreeNodeFactory treeNodeFactory, SettingsService settingsService)
{
this.assemblyTreeModel = assemblyTreeModel;
this.treeNodeFactory = treeNodeFactory;
this.settingsService = settingsService;
InitializeComponent();
ContextMenuProvider.Add(listBox);
@ -214,7 +223,7 @@ namespace ICSharpCode.ILSpy.Search @@ -214,7 +223,7 @@ namespace ICSharpCode.ILSpy.Search
var timer = Stopwatch.StartNew();
int resultsAdded = 0;
while (Results.Count < MAX_RESULTS && timer.ElapsedMilliseconds < MAX_REFRESH_TIME_MS && currentSearch.resultQueue.TryTake(out var result))
while (Results.Count < MAX_RESULTS && timer.ElapsedMilliseconds < MAX_REFRESH_TIME_MS && currentSearch.ResultQueue.TryTake(out var result))
{
Results.InsertSorted(result, resultsComparer);
++resultsAdded;
@ -243,8 +252,7 @@ namespace ICSharpCode.ILSpy.Search @@ -243,8 +252,7 @@ namespace ICSharpCode.ILSpy.Search
currentSearch = null;
}
MainWindow mainWindow = MainWindow.Instance;
resultsComparer = SettingsService.Instance.DisplaySettings.SortResults ?
resultsComparer = settingsService.DisplaySettings.SortResults ?
SearchResult.ComparerByFitness :
SearchResult.ComparerByName;
Results.Clear();
@ -254,9 +262,12 @@ namespace ICSharpCode.ILSpy.Search @@ -254,9 +262,12 @@ namespace ICSharpCode.ILSpy.Search
{
searchProgressBar.IsIndeterminate = true;
startedSearch = new(await mainWindow.AssemblyTreeModel.AssemblyList.GetAllAssemblies(), searchTerm,
(SearchMode)searchModeComboBox.SelectedIndex, mainWindow.AssemblyTreeModel.CurrentLanguage,
SettingsService.Instance.SessionSettings.LanguageSettings.ShowApiLevel);
startedSearch = new(await assemblyTreeModel.AssemblyList.GetAllAssemblies(),
searchTerm,
(SearchMode)searchModeComboBox.SelectedIndex,
assemblyTreeModel.CurrentLanguage,
treeNodeFactory,
settingsService);
currentSearch = startedSearch;
await startedSearch.Run();
@ -285,15 +296,20 @@ namespace ICSharpCode.ILSpy.Search @@ -285,15 +296,20 @@ namespace ICSharpCode.ILSpy.Search
readonly SearchMode searchMode;
readonly Language language;
readonly ApiVisibility apiVisibility;
public readonly IProducerConsumerCollection<SearchResult> resultQueue = new ConcurrentQueue<SearchResult>();
readonly ITreeNodeFactory treeNodeFactory;
readonly SettingsService settingsService;
public IProducerConsumerCollection<SearchResult> ResultQueue { get; } = new ConcurrentQueue<SearchResult>();
public RunningSearch(IList<LoadedAssembly> assemblies, string searchTerm, SearchMode searchMode,
Language language, ApiVisibility apiVisibility)
Language language, ITreeNodeFactory treeNodeFactory, SettingsService settingsService)
{
this.assemblies = assemblies;
this.language = language;
this.searchMode = searchMode;
this.apiVisibility = apiVisibility;
this.apiVisibility = settingsService.SessionSettings.LanguageSettings.ShowApiLevel;
this.treeNodeFactory = treeNodeFactory;
this.settingsService = settingsService;
this.searchRequest = Parse(searchTerm);
}
@ -454,8 +470,8 @@ namespace ICSharpCode.ILSpy.Search @@ -454,8 +470,8 @@ namespace ICSharpCode.ILSpy.Search
request.Keywords = keywords.ToArray();
request.RegEx = regex;
request.SearchResultFactory = new SearchResultFactory(language);
request.TreeNodeFactory = new TreeNodeFactory();
request.DecompilerSettings = SettingsService.Instance.DecompilerSettings;
request.TreeNodeFactory = this.treeNodeFactory;
request.DecompilerSettings = settingsService.DecompilerSettings;
return request;
}
@ -504,29 +520,29 @@ namespace ICSharpCode.ILSpy.Search @@ -504,29 +520,29 @@ namespace ICSharpCode.ILSpy.Search
switch (request.Mode)
{
case SearchMode.TypeAndMember:
return new MemberSearchStrategy(language, apiVisibility, request, resultQueue);
return new MemberSearchStrategy(language, apiVisibility, request, ResultQueue);
case SearchMode.Type:
return new MemberSearchStrategy(language, apiVisibility, request, resultQueue, MemberSearchKind.Type);
return new MemberSearchStrategy(language, apiVisibility, request, ResultQueue, MemberSearchKind.Type);
case SearchMode.Member:
return new MemberSearchStrategy(language, apiVisibility, request, resultQueue, request.MemberSearchKind);
return new MemberSearchStrategy(language, apiVisibility, request, ResultQueue, request.MemberSearchKind);
case SearchMode.Literal:
return new LiteralSearchStrategy(language, apiVisibility, request, resultQueue);
return new LiteralSearchStrategy(language, apiVisibility, request, ResultQueue);
case SearchMode.Method:
return new MemberSearchStrategy(language, apiVisibility, request, resultQueue, MemberSearchKind.Method);
return new MemberSearchStrategy(language, apiVisibility, request, ResultQueue, MemberSearchKind.Method);
case SearchMode.Field:
return new MemberSearchStrategy(language, apiVisibility, request, resultQueue, MemberSearchKind.Field);
return new MemberSearchStrategy(language, apiVisibility, request, ResultQueue, MemberSearchKind.Field);
case SearchMode.Property:
return new MemberSearchStrategy(language, apiVisibility, request, resultQueue, MemberSearchKind.Property);
return new MemberSearchStrategy(language, apiVisibility, request, ResultQueue, MemberSearchKind.Property);
case SearchMode.Event:
return new MemberSearchStrategy(language, apiVisibility, request, resultQueue, MemberSearchKind.Event);
return new MemberSearchStrategy(language, apiVisibility, request, ResultQueue, MemberSearchKind.Event);
case SearchMode.Token:
return new MetadataTokenSearchStrategy(language, apiVisibility, request, resultQueue);
return new MetadataTokenSearchStrategy(language, apiVisibility, request, ResultQueue);
case SearchMode.Resource:
return new ResourceSearchStrategy(apiVisibility, request, resultQueue);
return new ResourceSearchStrategy(apiVisibility, request, ResultQueue);
case SearchMode.Assembly:
return new AssemblySearchStrategy(request, resultQueue, AssemblySearchKind.NameOrFileName);
return new AssemblySearchStrategy(request, ResultQueue, AssemblySearchKind.NameOrFileName);
case SearchMode.Namespace:
return new NamespaceSearchStrategy(request, resultQueue);
return new NamespaceSearchStrategy(request, ResultQueue);
}
return null;

9
ILSpy/Search/SearchPaneModel.cs

@ -37,11 +37,14 @@ namespace ICSharpCode.ILSpy.Search @@ -37,11 +37,14 @@ namespace ICSharpCode.ILSpy.Search
[Export]
public class SearchPaneModel : ToolPaneModel
{
private string searchTerm;
public const string PaneContentId = "searchPane";
public SearchPaneModel()
private readonly SettingsService settingsService;
private string searchTerm;
public SearchPaneModel(SettingsService settingsService)
{
this.settingsService = settingsService;
ContentId = PaneContentId;
Title = Properties.Resources.SearchPane_Search;
Icon = "Images/Search";
@ -64,7 +67,7 @@ namespace ICSharpCode.ILSpy.Search @@ -64,7 +67,7 @@ namespace ICSharpCode.ILSpy.Search
new() { Mode = SearchMode.Namespace, Image = Images.Namespace, Name = "Namespace" }
];
public SessionSettings SessionSettings => SettingsService.Instance.SessionSettings;
public SessionSettings SessionSettings => settingsService.SessionSettings;
public string SearchTerm {
get => searchTerm;

4
ILSpy/Search/SearchResultFactory.cs

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Composition;
using System.Windows.Media;
using ICSharpCode.Decompiler.Metadata;
@ -158,6 +160,8 @@ namespace ICSharpCode.ILSpy.Search @@ -158,6 +160,8 @@ namespace ICSharpCode.ILSpy.Search
}
}
[Export(typeof(ITreeNodeFactory))]
[Shared]
internal class TreeNodeFactory : ITreeNodeFactory
{
public ITreeNode Create(Resource resource)

3
ILSpy/SolutionWriter.cs

@ -30,6 +30,7 @@ using ICSharpCode.Decompiler.Solution; @@ -30,6 +30,7 @@ using ICSharpCode.Decompiler.Solution;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
namespace ICSharpCode.ILSpy
@ -213,7 +214,7 @@ namespace ICSharpCode.ILSpy @@ -213,7 +214,7 @@ namespace ICSharpCode.ILSpy
using (var projectFileWriter = new StreamWriter(projectFileName))
{
var projectFileOutput = new PlainTextOutput(projectFileWriter);
var options = LanguageService.Instance.CreateDecompilationOptions(DockWorkspace.Instance.ActiveTabPage);
var options = DockWorkspace.Instance.ActiveTabPage.CreateDecompilationOptions();
options.FullDecompilation = true;
options.CancellationToken = ct;
options.SaveAsProjectDirectory = targetDirectory;

2
ILSpy/TaskHelper.cs

@ -197,7 +197,7 @@ namespace ICSharpCode.ILSpy @@ -197,7 +197,7 @@ namespace ICSharpCode.ILSpy
/// </summary>
public static void HandleExceptions(this Task task)
{
task.Catch<Exception>(exception => MainWindow.Instance.Dispatcher.BeginInvoke(new Action(delegate {
task.Catch<Exception>(exception => App.Current.Dispatcher.BeginInvoke(new Action(delegate {
AvalonEditTextOutput output = new();
output.Write(exception.ToString());
Docking.DockWorkspace.Instance.ShowText(output);

60
ILSpy/TextView/DecompilerTextView.cs

@ -74,6 +74,9 @@ namespace ICSharpCode.ILSpy.TextView @@ -74,6 +74,9 @@ namespace ICSharpCode.ILSpy.TextView
/// </summary>
public sealed partial class DecompilerTextView : UserControl, IHaveState, IProgress<DecompilationProgress>
{
readonly AssemblyTreeModel assemblyTreeModel;
readonly SettingsService settingsService;
private readonly LanguageService languageService;
readonly ReferenceElementGenerator referenceElementGenerator;
readonly UIElementGenerator uiElementGenerator;
readonly List<VisualLineElementGenerator?> activeCustomElementGenerators = new List<VisualLineElementGenerator?>();
@ -94,8 +97,12 @@ namespace ICSharpCode.ILSpy.TextView @@ -94,8 +97,12 @@ namespace ICSharpCode.ILSpy.TextView
readonly List<ITextMarker> localReferenceMarks = new List<ITextMarker>();
#region Constructor
public DecompilerTextView()
public DecompilerTextView(TabPageModel tabPage)
{
this.assemblyTreeModel = tabPage.AssemblyTreeModel;
this.settingsService = tabPage.SettingsService;
this.languageService = tabPage.LanguageService;
RegisterHighlighting();
InitializeComponent();
@ -113,9 +120,9 @@ namespace ICSharpCode.ILSpy.TextView @@ -113,9 +120,9 @@ namespace ICSharpCode.ILSpy.TextView
textEditor.TextArea.Caret.PositionChanged += HighlightBrackets;
textEditor.MouseMove += TextEditorMouseMove;
textEditor.MouseLeave += TextEditorMouseLeave;
textEditor.SetBinding(Control.FontFamilyProperty, new Binding { Source = SettingsService.Instance.DisplaySettings, Path = new PropertyPath("SelectedFont") });
textEditor.SetBinding(Control.FontSizeProperty, new Binding { Source = SettingsService.Instance.DisplaySettings, Path = new PropertyPath("SelectedFontSize") });
textEditor.SetBinding(TextEditor.WordWrapProperty, new Binding { Source = SettingsService.Instance.DisplaySettings, Path = new PropertyPath("EnableWordWrap") });
textEditor.SetBinding(Control.FontFamilyProperty, new Binding { Source = settingsService.DisplaySettings, Path = new PropertyPath("SelectedFont") });
textEditor.SetBinding(Control.FontSizeProperty, new Binding { Source = settingsService.DisplaySettings, Path = new PropertyPath("SelectedFontSize") });
textEditor.SetBinding(TextEditor.WordWrapProperty, new Binding { Source = settingsService.DisplaySettings, Path = new PropertyPath("EnableWordWrap") });
// disable Tab editing command (useless for read-only editor); allow using tab for focus navigation instead
RemoveEditCommand(EditingCommands.TabForward);
@ -130,7 +137,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -130,7 +137,7 @@ namespace ICSharpCode.ILSpy.TextView
// SearchPanel
SearchPanel searchPanel = SearchPanel.Install(textEditor.TextArea);
searchPanel.RegisterCommands(Application.Current.MainWindow.CommandBindings);
searchPanel.RegisterCommands(App.Current.MainWindow.CommandBindings);
searchPanel.SetResourceReference(SearchPanel.MarkerBrushProperty, ResourceKeys.SearchResultBackgroundBrush);
searchPanel.Loaded += (_, _) => {
// HACK: fix search text box
@ -207,14 +214,14 @@ namespace ICSharpCode.ILSpy.TextView @@ -207,14 +214,14 @@ namespace ICSharpCode.ILSpy.TextView
{
if (margin is LineNumberMargin || margin is System.Windows.Shapes.Line)
{
margin.Visibility = SettingsService.Instance.DisplaySettings.ShowLineNumbers ? Visibility.Visible : Visibility.Collapsed;
margin.Visibility = settingsService.DisplaySettings.ShowLineNumbers ? Visibility.Visible : Visibility.Collapsed;
}
}
}
void SetHighlightCurrentLine()
{
textEditor.Options.HighlightCurrentLine = SettingsService.Instance.DisplaySettings.HighlightCurrentLine;
textEditor.Options.HighlightCurrentLine = settingsService.DisplaySettings.HighlightCurrentLine;
}
#endregion
@ -400,10 +407,12 @@ namespace ICSharpCode.ILSpy.TextView @@ -400,10 +407,12 @@ namespace ICSharpCode.ILSpy.TextView
object? GenerateTooltip(ReferenceSegment segment)
{
var fontSize = settingsService.DisplaySettings.SelectedFontSize;
if (segment.Reference is ICSharpCode.Decompiler.Disassembler.OpCodeInfo code)
{
XmlDocumentationProvider docProvider = XmlDocLoader.MscorlibDocumentation;
DocumentationUIBuilder renderer = new DocumentationUIBuilder(new CSharpAmbience(), LanguageService.Instance.Language.SyntaxHighlighting);
DocumentationUIBuilder renderer = new DocumentationUIBuilder(new CSharpAmbience(), languageService.Language.SyntaxHighlighting, settingsService.DisplaySettings);
renderer.AddSignatureBlock($"{code.Name} (0x{code.Code:x})");
if (docProvider != null)
{
@ -413,18 +422,18 @@ namespace ICSharpCode.ILSpy.TextView @@ -413,18 +422,18 @@ namespace ICSharpCode.ILSpy.TextView
renderer.AddXmlDocumentation(documentation, null, null);
}
}
return new FlowDocumentTooltip(renderer.CreateDocument());
return new FlowDocumentTooltip(renderer.CreateDocument(), fontSize);
}
else if (segment.Reference is IEntity entity)
{
var document = CreateTooltipForEntity(entity);
if (document == null)
return null;
return new FlowDocumentTooltip(document);
return new FlowDocumentTooltip(document, fontSize);
}
else if (segment.Reference is EntityReference unresolvedEntity)
{
var module = unresolvedEntity.ResolveAssembly(MainWindow.Instance.AssemblyTreeModel.AssemblyList);
var module = unresolvedEntity.ResolveAssembly(assemblyTreeModel.AssemblyList);
if (module == null)
return null;
var typeSystem = new DecompilerTypeSystem(module,
@ -441,7 +450,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -441,7 +450,7 @@ namespace ICSharpCode.ILSpy.TextView
var document = CreateTooltipForEntity(resolved);
if (document == null)
return null;
return new FlowDocumentTooltip(document);
return new FlowDocumentTooltip(document, fontSize);
}
catch (BadImageFormatException)
{
@ -451,10 +460,10 @@ namespace ICSharpCode.ILSpy.TextView @@ -451,10 +460,10 @@ namespace ICSharpCode.ILSpy.TextView
return null;
}
static FlowDocument? CreateTooltipForEntity(IEntity resolved)
FlowDocument? CreateTooltipForEntity(IEntity resolved)
{
Language currentLanguage = LanguageService.Instance.Language;
DocumentationUIBuilder renderer = new DocumentationUIBuilder(new CSharpAmbience(), currentLanguage.SyntaxHighlighting);
Language currentLanguage = languageService.Language;
DocumentationUIBuilder renderer = new DocumentationUIBuilder(new CSharpAmbience(), currentLanguage.SyntaxHighlighting, settingsService.DisplaySettings);
RichText richText = currentLanguage.GetRichTextTooltip(resolved);
if (richText == null)
{
@ -484,7 +493,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -484,7 +493,7 @@ namespace ICSharpCode.ILSpy.TextView
IEntity? ResolveReference(string idString)
{
return AssemblyTreeModel.FindEntityInRelevantAssemblies(idString, MainWindow.Instance.AssemblyTreeModel.AssemblyList.GetAssemblies());
return AssemblyTreeModel.FindEntityInRelevantAssemblies(idString, assemblyTreeModel.AssemblyList.GetAssemblies());
}
}
@ -492,13 +501,12 @@ namespace ICSharpCode.ILSpy.TextView @@ -492,13 +501,12 @@ namespace ICSharpCode.ILSpy.TextView
{
readonly FlowDocumentScrollViewer viewer;
public FlowDocumentTooltip(FlowDocument document)
public FlowDocumentTooltip(FlowDocument document, double fontSize)
{
TextOptions.SetTextFormattingMode(this, TextFormattingMode.Display);
double fontSize = SettingsService.Instance.DisplaySettings.SelectedFontSize;
viewer = new FlowDocumentScrollViewer() {
Width = document.MinPageWidth + fontSize * 5,
MaxWidth = MainWindow.Instance.ActualWidth
MaxWidth = App.Current.MainWindow.ActualWidth
};
viewer.Document = document;
Border border = new Border {
@ -542,9 +550,9 @@ namespace ICSharpCode.ILSpy.TextView @@ -542,9 +550,9 @@ namespace ICSharpCode.ILSpy.TextView
#region Highlight brackets
void HighlightBrackets(object? sender, EventArgs e)
{
if (SettingsService.Instance.DisplaySettings.HighlightMatchingBraces)
if (settingsService.DisplaySettings.HighlightMatchingBraces)
{
var result = LanguageService.Instance.Language.BracketSearcher.SearchBracket(textEditor.Document, textEditor.CaretOffset);
var result = languageService.Language.BracketSearcher.SearchBracket(textEditor.Document, textEditor.CaretOffset);
bracketHighlightRenderer.SetHighlight(result);
}
else
@ -564,7 +572,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -564,7 +572,7 @@ namespace ICSharpCode.ILSpy.TextView
progressTitle.Text = !string.IsNullOrWhiteSpace(value.Title) ? value.Title : Properties.Resources.Decompiling;
progressText.Text = value.Status;
progressText.Visibility = !string.IsNullOrWhiteSpace(progressText.Text) ? Visibility.Visible : Visibility.Collapsed;
var taskBar = MainWindow.Instance.TaskbarItemInfo;
var taskBar = App.Current.MainWindow.TaskbarItemInfo;
if (taskBar != null)
{
taskBar.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal;
@ -594,7 +602,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -594,7 +602,7 @@ namespace ICSharpCode.ILSpy.TextView
progressText.Text = null;
progressText.Visibility = Visibility.Collapsed;
waitAdorner.BeginAnimation(OpacityProperty, new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(0.5)), FillBehavior.Stop));
var taskBar = MainWindow.Instance.TaskbarItemInfo;
var taskBar = App.Current.MainWindow.TaskbarItemInfo;
if (taskBar != null)
{
taskBar.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Indeterminate;
@ -633,7 +641,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -633,7 +641,7 @@ namespace ICSharpCode.ILSpy.TextView
progressBar.IsIndeterminate = false;
progressText.Text = null;
progressText.Visibility = Visibility.Collapsed;
var taskBar = MainWindow.Instance.TaskbarItemInfo;
var taskBar = App.Current.MainWindow.TaskbarItemInfo;
if (taskBar != null)
{
taskBar.ProgressState = System.Windows.Shell.TaskbarItemProgressState.None;
@ -764,7 +772,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -764,7 +772,7 @@ namespace ICSharpCode.ILSpy.TextView
{
if (state != null)
{
state.RestoreFoldings(textOutput.Foldings, SettingsService.Instance.DisplaySettings.ExpandMemberDefinitions);
state.RestoreFoldings(textOutput.Foldings, settingsService.DisplaySettings.ExpandMemberDefinitions);
textEditor.ScrollToVerticalOffset(state.VerticalOffset);
textEditor.ScrollToHorizontalOffset(state.HorizontalOffset);
}
@ -788,7 +796,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -788,7 +796,7 @@ namespace ICSharpCode.ILSpy.TextView
}
currentAddress = textOutput.Address;
currentTitle = textOutput.Title;
expandMemberDefinitions = SettingsService.Instance.DisplaySettings.ExpandMemberDefinitions;
expandMemberDefinitions = settingsService.DisplaySettings.ExpandMemberDefinitions;
}
#endregion

13
ILSpy/TextView/DocumentationUIBuilder.cs

@ -19,15 +19,12 @@ @@ -19,15 +19,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Xml;
using System.Xml.Linq;
using ICSharpCode.AvalonEdit.Document;
@ -47,14 +44,16 @@ namespace ICSharpCode.ILSpy.TextView @@ -47,14 +44,16 @@ namespace ICSharpCode.ILSpy.TextView
{
readonly IAmbience ambience;
readonly IHighlightingDefinition highlightingDefinition;
readonly DisplaySettings displaySettings;
readonly FlowDocument document;
BlockCollection blockCollection;
InlineCollection inlineCollection;
public DocumentationUIBuilder(IAmbience ambience, IHighlightingDefinition highlightingDefinition)
public DocumentationUIBuilder(IAmbience ambience, IHighlightingDefinition highlightingDefinition, DisplaySettings displaySettings)
{
this.ambience = ambience;
this.highlightingDefinition = highlightingDefinition;
this.displaySettings = displaySettings;
this.document = new FlowDocument();
this.blockCollection = document.Blocks;
@ -115,12 +114,12 @@ namespace ICSharpCode.ILSpy.TextView @@ -115,12 +114,12 @@ namespace ICSharpCode.ILSpy.TextView
// Paragraph sadly does not support TextWrapping.NoWrap
var text = new TextBlock {
FontFamily = GetCodeFont(),
FontSize = SettingsService.Instance.DisplaySettings.SelectedFontSize,
FontSize = displaySettings.SelectedFontSize,
TextAlignment = TextAlignment.Left
};
text.Inlines.AddRange(richText.CreateRuns(document));
text.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
this.document.MinPageWidth = Math.Min(text.DesiredSize.Width, MainWindow.Instance.ActualWidth);
this.document.MinPageWidth = Math.Min(text.DesiredSize.Width, App.Current.MainWindow.ActualWidth);
block.Inlines.AddRange(richText.CreateRuns(document));
block.FontFamily = GetCodeFont();
block.TextAlignment = TextAlignment.Left;
@ -435,7 +434,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -435,7 +434,7 @@ namespace ICSharpCode.ILSpy.TextView
FontFamily GetCodeFont()
{
return SettingsService.Instance.DisplaySettings.SelectedFont;
return displaySettings.SelectedFont;
}
public void AddInline(Inline inline)

32
ILSpy/Themes/WindowStyleManagerBehavior.cs

@ -27,6 +27,7 @@ using ICSharpCode.ILSpy.Options; @@ -27,6 +27,7 @@ using ICSharpCode.ILSpy.Options;
using TomsToolbox.Essentials;
using TomsToolbox.Wpf;
using TomsToolbox.Wpf.Composition;
using TomsToolbox.Wpf.Interactivity;
namespace ICSharpCode.ILSpy.Themes
@ -42,7 +43,7 @@ namespace ICSharpCode.ILSpy.Themes @@ -42,7 +43,7 @@ namespace ICSharpCode.ILSpy.Themes
{
base.OnAttached();
SettingsService.Instance.DisplaySettings.PropertyChanged += DisplaySettings_PropertyChanged;
MessageBus<SettingsChangedEventArgs>.Subscribers += (sender, e) => DisplaySettings_PropertyChanged(sender, e);
_foreground = AssociatedObject.Track(Control.ForegroundProperty);
_background = AssociatedObject.Track(Control.BackgroundProperty);
@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.Themes @@ -50,7 +51,7 @@ namespace ICSharpCode.ILSpy.Themes
_foreground.Changed += Color_Changed;
_background.Changed += Color_Changed;
UpdateWindowStyle();
UpdateWindowStyle(AssociatedObject.GetExportProvider().GetExportedValue<SettingsService>().DisplaySettings);
ApplyThemeToWindowCaption();
}
@ -60,8 +61,6 @@ namespace ICSharpCode.ILSpy.Themes @@ -60,8 +61,6 @@ namespace ICSharpCode.ILSpy.Themes
_foreground.Changed -= Color_Changed;
_background.Changed -= Color_Changed;
SettingsService.Instance.DisplaySettings.PropertyChanged -= DisplaySettings_PropertyChanged;
}
private void Color_Changed(object sender, EventArgs e)
@ -69,12 +68,14 @@ namespace ICSharpCode.ILSpy.Themes @@ -69,12 +68,14 @@ namespace ICSharpCode.ILSpy.Themes
ApplyThemeToWindowCaption();
}
private void UpdateWindowStyle()
private void UpdateWindowStyle(DisplaySettings displaySettings)
{
var window = AssociatedObject;
if (SettingsService.Instance.DisplaySettings.StyleWindowTitleBar)
if (displaySettings.StyleWindowTitleBar)
{
window.Style = (Style)window.FindResource(TomsToolbox.Wpf.Styles.ResourceKeys.WindowStyle);
}
}
private static void ShowRestartNotification()
@ -84,16 +85,19 @@ namespace ICSharpCode.ILSpy.Themes @@ -84,16 +85,19 @@ namespace ICSharpCode.ILSpy.Themes
private void DisplaySettings_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(DisplaySettings.StyleWindowTitleBar))
{
if (!SettingsService.Instance.DisplaySettings.StyleWindowTitleBar)
{
restartNotificationThrottle.Tick();
return;
}
if (sender is not DisplaySettings displaySettings)
return;
if (e.PropertyName != nameof(DisplaySettings.StyleWindowTitleBar))
return;
UpdateWindowStyle();
if (!displaySettings.StyleWindowTitleBar)
{
restartNotificationThrottle.Tick();
return;
}
UpdateWindowStyle(displaySettings);
}
private void ApplyThemeToWindowCaption()

11
ILSpy/TreeNodes/AssemblyListTreeNode.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
@ -25,6 +26,7 @@ using ICSharpCode.Decompiler; @@ -25,6 +26,7 @@ using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpyX;
using ICSharpCode.ILSpyX.TreeView;
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;
@ -45,7 +47,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -45,7 +47,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
public AssemblyListTreeNode(AssemblyList assemblyList)
{
this.assemblyList = assemblyList ?? throw new ArgumentNullException(nameof(assemblyList));
ArgumentNullException.ThrowIfNull(assemblyList);
this.assemblyList = assemblyList;
BindToObservableCollection(assemblyList);
}
@ -107,8 +112,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -107,8 +112,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
.Distinct()
.ToArray();
assemblyList.Move(assemblies, index);
var nodes = assemblies.SelectArray(MainWindow.Instance.AssemblyTreeModel.FindTreeNode);
MainWindow.Instance.AssemblyTreeModel.SelectNodes(nodes);
var nodes = assemblies.SelectArray(AssemblyTreeModel.FindTreeNode);
AssemblyTreeModel.SelectNodes(nodes);
}
}

4
ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs

@ -85,11 +85,11 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -85,11 +85,11 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
this.Children.Add(new AssemblyReferenceReferencedTypesTreeNode(module, r));
var resolver = parentAssembly.LoadedAssembly.GetAssemblyResolver(SettingsService.Instance.DecompilerSettings.AutoLoadAssemblyReferences);
var resolver = parentAssembly.LoadedAssembly.GetAssemblyResolver(SettingsService.DecompilerSettings.AutoLoadAssemblyReferences);
var referencedModule = resolver.Resolve(r);
if (referencedModule != null)
{
var module = (MetadataModule)referencedModule.GetTypeSystemWithCurrentOptionsOrNull().MainModule;
var module = (MetadataModule)referencedModule.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule;
foreach (var childRef in referencedModule.AssemblyReferences)
this.Children.Add(new AssemblyReferenceTreeNode(module, childRef, parentAssembly));
}

21
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -263,7 +263,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -263,7 +263,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
ns.Children.Clear();
}
namespaces.Clear();
bool useNestedStructure = SettingsService.Instance.DisplaySettings.UseNestedNamespaceNodes;
bool useNestedStructure = SettingsService.DisplaySettings.UseNestedNamespaceNodes;
foreach (var type in assembly.TopLevelTypeDefinitions.OrderBy(t => t.ReflectionName, NaturalStringComparer.Instance))
{
var ns = GetOrCreateNamespaceTreeNode(type.Namespace);
@ -329,7 +329,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -329,7 +329,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
ns.Children.Clear();
}
namespaces.Clear();
bool useNestedStructure = SettingsService.Instance.DisplaySettings.UseNestedNamespaceNodes;
bool useNestedStructure = SettingsService.DisplaySettings.UseNestedNamespaceNodes;
foreach (var type in assembly.TopLevelTypeDefinitions.OrderBy(t => t.ReflectionName, NaturalStringComparer.Instance))
{
var ns = GetOrCreateNamespaceTreeNode(type.Namespace);
@ -547,7 +547,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -547,7 +547,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
dlg.Filter = language.Name + " project|*" + language.ProjectFileExtension + "|" + language.Name + " single file|*" + language.FileExtension + "|All files|*.*";
if (dlg.ShowDialog() == true)
{
var options = LanguageService.Instance.CreateDecompilationOptions(DockWorkspace.Instance.ActiveTabPage);
var options = DockWorkspace.Instance.ActiveTabPage.CreateDecompilationOptions();
options.FullDecompilation = true;
if (dlg.FilterIndex == 1)
{
@ -608,7 +608,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -608,7 +608,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
[ExportContextMenuEntry(Header = nameof(Resources._Reload), Icon = "images/Refresh")]
[Shared]
sealed class ReloadAssembly : IContextMenuEntry
sealed class ReloadAssembly(AssemblyTreeModel assemblyTreeModel) : IContextMenuEntry
{
public bool IsVisible(TextViewContext context)
{
@ -636,14 +636,14 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -636,14 +636,14 @@ namespace ICSharpCode.ILSpy.TreeNodes
la.AssemblyList.ReloadAssembly(la.FileName);
}
}
MainWindow.Instance.AssemblyTreeModel.SelectNodes(paths.Select(p => MainWindow.Instance.AssemblyTreeModel.FindNodeByPath(p, true)).ToArray());
MainWindow.Instance.AssemblyTreeModel.RefreshDecompiledView();
assemblyTreeModel.SelectNodes(paths.Select(p => assemblyTreeModel.FindNodeByPath(p, true)).ToArray());
assemblyTreeModel.RefreshDecompiledView();
}
}
[ExportContextMenuEntry(Header = nameof(Resources._LoadDependencies), Category = nameof(Resources.Dependencies))]
[Shared]
sealed class LoadDependencies : IContextMenuEntry
sealed class LoadDependencies(AssemblyTreeModel assemblyTreeModel) : IContextMenuEntry
{
public bool IsVisible(TextViewContext context)
{
@ -677,13 +677,13 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -677,13 +677,13 @@ namespace ICSharpCode.ILSpy.TreeNodes
}
}
await Task.WhenAll(tasks);
MainWindow.Instance.AssemblyTreeModel.RefreshDecompiledView();
assemblyTreeModel.RefreshDecompiledView();
}
}
[ExportContextMenuEntry(Header = nameof(Resources._AddMainList), Category = nameof(Resources.Dependencies))]
[Shared]
sealed class AddToMainList : IContextMenuEntry
sealed class AddToMainList(AssemblyTreeModel assemblyTreeModel) : IContextMenuEntry
{
public bool IsVisible(TextViewContext context)
{
@ -712,7 +712,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -712,7 +712,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
node.RaisePropertyChanged(nameof(ILSpyTreeNode.IsAutoLoaded));
}
}
MainWindow.Instance.AssemblyTreeModel.AssemblyList.RefreshSave();
assemblyTreeModel.AssemblyList.RefreshSave();
}
}

2
ILSpy/TreeNodes/DerivedTypesEntryNode.cs

@ -55,7 +55,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -55,7 +55,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
return FilterResult.Hidden;
if (settings.SearchTermMatches(type.Name))
{
if (type.DeclaringType != null && (settings.ShowApiLevel != ApiVisibility.All || !LanguageService.Instance.Language.ShowMember(type)))
if (type.DeclaringType != null && (settings.ShowApiLevel != ApiVisibility.All || !LanguageService.Language.ShowMember(type)))
return FilterResult.Hidden;
else
return FilterResult.Match;

6
ILSpy/TreeNodes/EventTreeNode.cs

@ -51,8 +51,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -51,8 +51,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
private IEvent GetEventDefinition()
{
return ((MetadataModule)EventDefinition.ParentModule.MetadataFile
?.GetTypeSystemWithCurrentOptionsOrNull()
return ((MetadataModule)EventDefinition.ParentModule?.MetadataFile
?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)
?.MainModule)?.GetDefinition((EventDefinitionHandle)EventDefinition.MetadataToken) ?? EventDefinition;
}
@ -72,7 +72,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -72,7 +72,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
if (settings.ShowApiLevel == ApiVisibility.PublicOnly && !IsPublicAPI)
return FilterResult.Hidden;
if (settings.SearchTermMatches(EventDefinition.Name) && (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Instance.Language.ShowMember(EventDefinition)))
if (settings.SearchTermMatches(EventDefinition.Name) && (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Language.ShowMember(EventDefinition)))
return FilterResult.Match;
else
return FilterResult.Hidden;

6
ILSpy/TreeNodes/FieldTreeNode.cs

@ -43,8 +43,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -43,8 +43,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
private IField GetFieldDefinition()
{
return ((MetadataModule)FieldDefinition.ParentModule.MetadataFile
?.GetTypeSystemWithCurrentOptionsOrNull()
return ((MetadataModule)FieldDefinition.ParentModule?.MetadataFile
?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)
?.MainModule)?.GetDefinition((FieldDefinitionHandle)FieldDefinition.MetadataToken) ?? FieldDefinition;
}
@ -73,7 +73,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -73,7 +73,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
if (settings.ShowApiLevel == ApiVisibility.PublicOnly && !IsPublicAPI)
return FilterResult.Hidden;
if (settings.SearchTermMatches(FieldDefinition.Name) && (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Instance.Language.ShowMember(FieldDefinition)))
if (settings.SearchTermMatches(FieldDefinition.Name) && (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Language.ShowMember(FieldDefinition)))
return FilterResult.Match;
else
return FilterResult.Hidden;

28
ILSpy/TreeNodes/ILSpyTreeNode.cs

@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
@ -27,6 +26,7 @@ using System.Windows.Threading; @@ -27,6 +26,7 @@ using System.Windows.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpyX.Abstractions;
using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions;
using ICSharpCode.ILSpyX.TreeView;
@ -45,9 +45,17 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -45,9 +45,17 @@ namespace ICSharpCode.ILSpy.TreeNodes
MessageBus<SettingsChangedEventArgs>.Subscribers += (sender, e) => Settings_Changed(sender, e);
}
LanguageSettings LanguageSettings => SettingsService.Instance.SessionSettings.LanguageSettings;
LanguageSettings LanguageSettings => SettingsService.SessionSettings.LanguageSettings;
public Language Language => LanguageService.Instance.Language;
public Language Language => LanguageService.Language;
public static AssemblyTreeModel AssemblyTreeModel { get; } = App.ExportProvider.GetExportedValue<AssemblyTreeModel>();
public static ICollection<IResourceNodeFactory> ResourceNodeFactories { get; } = App.ExportProvider.GetExportedValues<IResourceNodeFactory>().ToArray();
public static SettingsService SettingsService { get; } = App.ExportProvider.GetExportedValue<SettingsService>();
public static LanguageService LanguageService { get; } = App.ExportProvider.GetExportedValue<LanguageService>();
public virtual FilterResult Filter(LanguageSettings settings)
{
@ -71,8 +79,11 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -71,8 +79,11 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override void ActivateItemSecondary(IPlatformRoutedEventArgs e)
{
MainWindow.Instance.AssemblyTreeModel.SelectNode(this, inNewTabPage: true);
MainWindow.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Background, (Action)MainWindow.Instance.AssemblyTreeModel.RefreshDecompiledView);
var assemblyTreeModel = AssemblyTreeModel;
assemblyTreeModel.SelectNode(this, inNewTabPage: true);
App.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, assemblyTreeModel.RefreshDecompiledView);
}
/// <summary>
@ -87,6 +98,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -87,6 +98,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override void OnChildrenChanged(NotifyCollectionChangedEventArgs e)
{
base.OnChildrenChanged(e);
if (e.NewItems != null)
{
if (IsVisible)
@ -99,7 +112,6 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -99,7 +112,6 @@ namespace ICSharpCode.ILSpy.TreeNodes
childrenNeedFiltering = true;
}
}
base.OnChildrenChanged(e);
}
void ApplyFilterToChild(ILSpyTreeNode child)
@ -162,11 +174,11 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -162,11 +174,11 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected string GetSuffixString(EntityHandle handle)
{
if (!SettingsService.Instance.DisplaySettings.ShowMetadataTokens)
if (!SettingsService.DisplaySettings.ShowMetadataTokens)
return string.Empty;
int token = MetadataTokens.GetToken(handle);
if (SettingsService.Instance.DisplaySettings.ShowMetadataTokensInBase10)
if (SettingsService.DisplaySettings.ShowMetadataTokensInBase10)
return " @" + token;
return " @" + token.ToString("x8");
}

8
ILSpy/TreeNodes/MethodTreeNode.cs

@ -43,8 +43,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -43,8 +43,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
private IMethod GetMethodDefinition()
{
return ((MetadataModule)MethodDefinition.ParentModule.MetadataFile
?.GetTypeSystemWithCurrentOptionsOrNull()
return ((MetadataModule)MethodDefinition.ParentModule?.MetadataFile
?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)
?.MainModule)?.GetDefinition((MethodDefinitionHandle)MethodDefinition.MetadataToken) ?? MethodDefinition;
}
@ -103,7 +103,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -103,7 +103,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
if (settings.ShowApiLevel == ApiVisibility.PublicOnly && !IsPublicAPI)
return FilterResult.Hidden;
if (settings.SearchTermMatches(MethodDefinition.Name) && (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Instance.Language.ShowMember(MethodDefinition)))
if (settings.SearchTermMatches(MethodDefinition.Name) && (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Language.ShowMember(MethodDefinition)))
return FilterResult.Match;
else
return FilterResult.Hidden;
@ -127,7 +127,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -127,7 +127,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override string ToString()
{
return LanguageService.Instance.ILLanguage.MethodToString(MethodDefinition, false, false, false);
return LanguageService.ILLanguage.MethodToString(MethodDefinition, false, false, false);
}
}
}

8
ILSpy/TreeNodes/PropertyTreeNode.cs

@ -53,8 +53,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -53,8 +53,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
private IProperty GetPropertyDefinition()
{
return ((MetadataModule)PropertyDefinition.ParentModule.MetadataFile
?.GetTypeSystemWithCurrentOptionsOrNull()
return ((MetadataModule)PropertyDefinition.ParentModule?.MetadataFile
?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)
?.MainModule)?.GetDefinition((PropertyDefinitionHandle)PropertyDefinition.MetadataToken) ?? PropertyDefinition;
}
@ -75,7 +75,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -75,7 +75,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
if (settings.ShowApiLevel == ApiVisibility.PublicOnly && !IsPublicAPI)
return FilterResult.Hidden;
if (settings.SearchTermMatches(PropertyDefinition.Name) && (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Instance.Language.ShowMember(PropertyDefinition)))
if (settings.SearchTermMatches(PropertyDefinition.Name) && (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Language.ShowMember(PropertyDefinition)))
return FilterResult.Match;
else
return FilterResult.Hidden;
@ -104,7 +104,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -104,7 +104,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override string ToString()
{
return LanguageService.Instance.ILLanguage.PropertyToString(PropertyDefinition, false, false, false);
return LanguageService.ILLanguage.PropertyToString(PropertyDefinition, false, false, false);
}
}
}

2
ILSpy/TreeNodes/ReferenceFolderTreeNode.cs

@ -49,7 +49,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -49,7 +49,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected override void LoadChildren()
{
var metadata = module.Metadata;
var metadataModule = (MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull().MainModule;
var metadataModule = (MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule;
foreach (var r in module.AssemblyReferences.OrderBy(r => r.Name))
this.Children.Add(new AssemblyReferenceTreeNode(metadataModule, r, parentAssembly));
foreach (var r in metadata.GetModuleReferences().OrderBy(r => metadata.GetString(metadata.GetModuleReference(r).Name)))

3
ILSpy/TreeNodes/ResourceNodes/ResourceEntryNode.cs

@ -22,7 +22,6 @@ using System.IO; @@ -22,7 +22,6 @@ using System.IO;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpyX.Abstractions;
using Microsoft.Win32;
@ -58,7 +57,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -58,7 +57,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public static ILSpyTreeNode Create(Resource resource)
{
ILSpyTreeNode result = null;
foreach (var factory in App.ExportProvider.GetExportedValues<IResourceNodeFactory>())
foreach (var factory in ResourceNodeFactories)
{
result = factory.CreateNode(resource) as ILSpyTreeNode;
if (result != null)

6
ILSpy/TreeNodes/TypeTreeNode.cs

@ -49,8 +49,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -49,8 +49,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
return ((MetadataModule)ParentAssemblyNode.LoadedAssembly
.GetMetadataFileOrNull()
?.GetTypeSystemWithCurrentOptionsOrNull()
?.MainModule).GetDefinition((SRM.TypeDefinitionHandle)TypeDefinition.MetadataToken);
?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)
?.MainModule)?.GetDefinition((SRM.TypeDefinitionHandle)TypeDefinition.MetadataToken);
}
public override bool IsPublicAPI {
@ -73,7 +73,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -73,7 +73,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
return FilterResult.Hidden;
if (settings.SearchTermMatches(TypeDefinition.Name))
{
if (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Instance.Language.ShowMember(TypeDefinition))
if (settings.ShowApiLevel == ApiVisibility.All || LanguageService.Language.ShowMember(TypeDefinition))
return FilterResult.Match;
else
return FilterResult.Hidden;

15
ILSpy/Util/MenuService.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using System.Composition;
using System.Globalization;
using System.Linq;
using System.Windows;
@ -35,10 +36,10 @@ using TomsToolbox.Wpf.Converters; @@ -35,10 +36,10 @@ using TomsToolbox.Wpf.Converters;
namespace ICSharpCode.ILSpy.Util
{
internal class MenuService
[Export]
[Shared]
public class MenuService(IExportProvider exportProvider)
{
public static readonly MenuService Instance = new();
private readonly DockWorkspace dockWorkspace = DockWorkspace.Instance;
public void Init(Menu mainMenu, ToolBar toolBar, InputBindingCollection inputBindings)
@ -48,9 +49,9 @@ namespace ICSharpCode.ILSpy.Util @@ -48,9 +49,9 @@ namespace ICSharpCode.ILSpy.Util
InitToolbar(toolBar);
}
static void InitMainMenu(Menu mainMenu)
void InitMainMenu(Menu mainMenu)
{
var mainMenuCommands = App.ExportProvider.GetExports<ICommand, IMainMenuCommandMetadata>("MainMenuCommand");
var mainMenuCommands = exportProvider.GetExports<ICommand, IMainMenuCommandMetadata>("MainMenuCommand");
// Start by constructing the individual flat menus
var parentMenuItems = new Dictionary<string, MenuItem>();
var menuGroups = mainMenuCommands.OrderBy(c => c.Metadata?.MenuOrder).GroupBy(c => c.Metadata?.ParentMenuID).ToArray();
@ -150,11 +151,11 @@ namespace ICSharpCode.ILSpy.Util @@ -150,11 +151,11 @@ namespace ICSharpCode.ILSpy.Util
windowMenuItem.ItemsSource = allItems;
}
static void InitToolbar(ToolBar toolBar)
void InitToolbar(ToolBar toolBar)
{
int navigationPos = 0;
int openPos = 1;
var toolbarCommandsByTitle = App.ExportProvider.GetExports<ICommand, IToolbarCommandMetadata>("ToolbarCommand")
var toolbarCommandsByTitle = exportProvider.GetExports<ICommand, IToolbarCommandMetadata>("ToolbarCommand")
.OrderBy(c => c.Metadata?.ToolbarOrder)
.GroupBy(c => c.Metadata?.ToolbarCategory);

9
ILSpy/Util/SettingsService.cs

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
using System;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Composition;
using System.Xml.Linq;
using ICSharpCode.Decompiler;
@ -110,13 +111,9 @@ namespace ICSharpCode.ILSpy.Util @@ -110,13 +111,9 @@ namespace ICSharpCode.ILSpy.Util
}
}
public class SettingsService : SettingsServiceBase
public class SettingsService() : SettingsServiceBase(LoadSettings())
{
public static readonly SettingsService Instance = new();
private SettingsService() : base(LoadSettings())
{
}
public static readonly SettingsService Instance = App.ExportProvider.GetExportedValue<SettingsService>();
public SessionSettings SessionSettings => GetSettings<SessionSettings>();

18
ILSpy/ViewModels/ManageAssemblyListsViewModel.cs

@ -35,11 +35,13 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -35,11 +35,13 @@ namespace ICSharpCode.ILSpy.ViewModels
{
private readonly AssemblyListManager manager;
private readonly Window parent;
private readonly SessionSettings sessionSettings;
public ManageAssemblyListsViewModel(Window parent)
public ManageAssemblyListsViewModel(Window parent, SettingsService settingsService)
{
this.manager = SettingsService.Instance.AssemblyListManager;
this.manager = settingsService.AssemblyListManager;
this.parent = parent;
this.sessionSettings = settingsService.SessionSettings;
NewCommand = new DelegateCommand(ExecuteNew);
CloneCommand = new DelegateCommand(ExecuteClone, CanExecuteClone);
@ -174,7 +176,7 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -174,7 +176,7 @@ namespace ICSharpCode.ILSpy.ViewModels
return;
manager.ClearAll();
manager.CreateDefaultAssemblyLists();
SettingsService.Instance.SessionSettings.ActiveAssemblyList = manager.AssemblyLists[0];
sessionSettings.ActiveAssemblyList = manager.AssemblyLists[0];
}
private void ExecuteDelete()
@ -189,9 +191,9 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -189,9 +191,9 @@ namespace ICSharpCode.ILSpy.ViewModels
if (manager.AssemblyLists.Count > 0)
{
SelectedAssemblyList = manager.AssemblyLists[Math.Max(0, index - 1)];
if (SettingsService.Instance.SessionSettings.ActiveAssemblyList == assemblyList)
if (sessionSettings.ActiveAssemblyList == assemblyList)
{
SettingsService.Instance.SessionSettings.ActiveAssemblyList = SelectedAssemblyList;
sessionSettings.ActiveAssemblyList = SelectedAssemblyList;
}
}
}
@ -232,9 +234,9 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -232,9 +234,9 @@ namespace ICSharpCode.ILSpy.ViewModels
string assemblyList = SelectedAssemblyList;
SelectedAssemblyList = dlg.ListName;
manager.RenameList(assemblyList, dlg.ListName);
if (SettingsService.Instance.SessionSettings.ActiveAssemblyList == assemblyList)
if (sessionSettings.ActiveAssemblyList == assemblyList)
{
SettingsService.Instance.SessionSettings.ActiveAssemblyList = manager.AssemblyLists[manager.AssemblyLists.Count - 1];
sessionSettings.ActiveAssemblyList = manager.AssemblyLists[manager.AssemblyLists.Count - 1];
}
}
}
@ -272,7 +274,7 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -272,7 +274,7 @@ namespace ICSharpCode.ILSpy.ViewModels
private void ExecuteSelectAssemblyList()
{
SettingsService.Instance.SessionSettings.ActiveAssemblyList = SelectedAssemblyList;
sessionSettings.ActiveAssemblyList = SelectedAssemblyList;
this.parent.Close();
}
}

23
ILSpy/ViewModels/TabPageModel.cs

@ -21,6 +21,8 @@ using System.Linq; @@ -21,6 +21,8 @@ using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.TextView;
using TomsToolbox.Wpf;
@ -29,8 +31,16 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -29,8 +31,16 @@ namespace ICSharpCode.ILSpy.ViewModels
{
public class TabPageModel : PaneModel
{
public TabPageModel()
public AssemblyTreeModel AssemblyTreeModel { get; }
public SettingsService SettingsService { get; }
public LanguageService LanguageService { get; }
public TabPageModel(AssemblyTreeModel assemblyTreeModel, SettingsService settingsService, LanguageService languageService)
{
AssemblyTreeModel = assemblyTreeModel;
SettingsService = settingsService;
LanguageService = languageService;
this.Title = Properties.Resources.NewTab;
}
@ -72,7 +82,7 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -72,7 +82,7 @@ namespace ICSharpCode.ILSpy.ViewModels
{
if (!(tabPage.Content is DecompilerTextView textView))
{
textView = new DecompilerTextView();
textView = new DecompilerTextView(tabPage);
tabPage.Content = textView;
}
tabPage.Title = Properties.Resources.Decompiling;
@ -83,7 +93,7 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -83,7 +93,7 @@ namespace ICSharpCode.ILSpy.ViewModels
{
if (!(tabPage.Content is DecompilerTextView textView))
{
textView = new DecompilerTextView();
textView = new DecompilerTextView(tabPage);
tabPage.Content = textView;
}
string oldTitle = tabPage.Title;
@ -105,7 +115,7 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -105,7 +115,7 @@ namespace ICSharpCode.ILSpy.ViewModels
{
if (!(tabPage.Content is DecompilerTextView textView))
{
textView = new DecompilerTextView();
textView = new DecompilerTextView(tabPage);
tabPage.Content = textView;
}
string oldTitle = tabPage.Title;
@ -129,6 +139,11 @@ namespace ICSharpCode.ILSpy.ViewModels @@ -129,6 +139,11 @@ namespace ICSharpCode.ILSpy.ViewModels
focusable?.Focus();
}
public static DecompilationOptions CreateDecompilationOptions(this TabPageModel tabPage)
{
return new(tabPage.LanguageService.LanguageVersion, tabPage.SettingsService.DecompilerSettings, tabPage.SettingsService.DisplaySettings) { Progress = tabPage.Content as IProgress<DecompilationProgress> };
}
}
public interface IHaveState

20
ILSpy/Views/DebugSteps.xaml.cs

@ -7,6 +7,7 @@ using System.Windows.Input; @@ -7,6 +7,7 @@ using System.Windows.Input;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.Docking;
using ICSharpCode.ILSpy.ViewModels;
@ -18,6 +19,10 @@ namespace ICSharpCode.ILSpy @@ -18,6 +19,10 @@ namespace ICSharpCode.ILSpy
[NonShared]
public partial class DebugSteps : UserControl
{
private readonly AssemblyTreeModel assemblyTreeModel;
private readonly SettingsService settingsService;
private readonly LanguageService languageService;
static readonly ILAstWritingOptions writingOptions = new ILAstWritingOptions {
UseFieldSugar = true,
UseLogicOperationSugar = true
@ -28,8 +33,12 @@ namespace ICSharpCode.ILSpy @@ -28,8 +33,12 @@ namespace ICSharpCode.ILSpy
#if DEBUG
ILAstLanguage language;
#endif
public DebugSteps()
public DebugSteps(AssemblyTreeModel assemblyTreeModel, SettingsService settingsService, LanguageService languageService)
{
this.assemblyTreeModel = assemblyTreeModel;
this.settingsService = settingsService;
this.languageService = languageService;
InitializeComponent();
#if DEBUG
@ -38,7 +47,7 @@ namespace ICSharpCode.ILSpy @@ -38,7 +47,7 @@ namespace ICSharpCode.ILSpy
writingOptions.PropertyChanged += WritingOptions_PropertyChanged;
if (LanguageService.Instance.Language is ILAstLanguage l)
if (languageService.Language is ILAstLanguage l)
{
l.StepperUpdated += ILAstStepperUpdated;
language = l;
@ -72,7 +81,7 @@ namespace ICSharpCode.ILSpy @@ -72,7 +81,7 @@ namespace ICSharpCode.ILSpy
{
language.StepperUpdated -= ILAstStepperUpdated;
}
if (LanguageService.Instance.Language is ILAstLanguage l)
if (languageService.Language is ILAstLanguage l)
{
l.StepperUpdated += ILAstStepperUpdated;
language = l;
@ -123,10 +132,9 @@ namespace ICSharpCode.ILSpy @@ -123,10 +132,9 @@ namespace ICSharpCode.ILSpy
void DecompileAsync(int step, bool isDebug = false)
{
lastSelectedStep = step;
var window = MainWindow.Instance;
var state = DockWorkspace.Instance.ActiveTabPage.GetState();
DockWorkspace.Instance.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(window.AssemblyTreeModel.CurrentLanguage, window.AssemblyTreeModel.SelectedNodes,
new DecompilationOptions(window.AssemblyTreeModel.CurrentLanguageVersion, SettingsService.Instance.DecompilerSettings, SettingsService.Instance.DisplaySettings) {
DockWorkspace.Instance.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(assemblyTreeModel.CurrentLanguage, assemblyTreeModel.SelectedNodes,
new DecompilationOptions(assemblyTreeModel.CurrentLanguageVersion, settingsService.DecompilerSettings, settingsService.DisplaySettings) {
StepLimit = step,
IsDebug = isDebug,
TextViewState = state as TextView.DecompilerTextViewState

4
ILSpy/Views/ManageAssemblyLIstsDialog.xaml.cs

@ -29,10 +29,10 @@ namespace ICSharpCode.ILSpy @@ -29,10 +29,10 @@ namespace ICSharpCode.ILSpy
/// </summary>
public partial class ManageAssemblyListsDialog : Window
{
public ManageAssemblyListsDialog()
public ManageAssemblyListsDialog(SettingsService settingsService)
{
InitializeComponent();
DataContext = new ManageAssemblyListsViewModel(this);
DataContext = new ManageAssemblyListsViewModel(this, settingsService);
}
private void PreconfiguredAssemblyListsMenuClick(object sender, RoutedEventArgs e)

5
TestPlugin/MainMenuCommand.cs

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
using System.Composition;
using ICSharpCode.ILSpy;
using ICSharpCode.ILSpy.AssemblyTree;
namespace TestPlugin
{
@ -19,11 +20,11 @@ namespace TestPlugin @@ -19,11 +20,11 @@ namespace TestPlugin
// ToolbarOrder: controls the order in which the items appear (items are sorted by this value)
[ExportToolbarCommand(ToolTip = "Clears the current assembly list", ToolbarIcon = "Clear.png", ToolbarCategory = "Open", ToolbarOrder = 1.5)]
[Shared]
public class UnloadAllAssembliesCommand : SimpleCommand
public class UnloadAllAssembliesCommand(AssemblyTreeModel assemblyTreeModel) : SimpleCommand
{
public override void Execute(object parameter)
{
foreach (var loadedAssembly in MainWindow.Instance.AssemblyTreeModel.AssemblyList.GetAssemblies())
foreach (var loadedAssembly in assemblyTreeModel.AssemblyList.GetAssemblies())
{
loadedAssembly.AssemblyList.Unload(loadedAssembly);
}

Loading…
Cancel
Save