Skip to content

Commit

Permalink
Merge pull request #3314 from tom-englert/dev/DependencyInjection
Browse files Browse the repository at this point in the history
Replace singletons with DI patterns...
  • Loading branch information
siegfriedpammer authored Nov 1, 2024
2 parents e96605c + a24e0f9 commit 1134313
Show file tree
Hide file tree
Showing 100 changed files with 1,082 additions and 1,036 deletions.
5 changes: 1 addition & 4 deletions ICSharpCode.ILSpyX/Analyzers/AnalyzerScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,14 @@ public class AnalyzerScope
/// </summary>
public bool IsLocal { get; }

public AssemblyList AssemblyList { get; }

public ISymbol AnalyzedSymbol { get; }

public ITypeDefinition TypeScope => typeScope;

Accessibility effectiveAccessibility;
readonly Accessibility effectiveAccessibility;

public AnalyzerScope(AssemblyList assemblyList, IEntity entity)
{
AssemblyList = assemblyList;
assemblyListSnapshot = assemblyList.GetSnapshot();
AnalyzedSymbol = entity;
DetermineEffectiveAccessibility(entity, out typeScope, out effectiveAccessibility);
Expand Down
1 change: 1 addition & 0 deletions ICSharpCode.ILSpyX/Analyzers/IAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public interface IAnalyzer
public interface IAnalyzerMetadata
{
string Header { get; }

int Order { get; }
}
}
6 changes: 4 additions & 2 deletions ILSpy.ReadyToRun/ReadyToRunDisassembler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,22 @@ internal class ReadyToRunDisassembler
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)
{
ReadyToRunMethod readyToRunMethod = runtimeFunction.Method;
WriteCommentLine(readyToRunMethod.SignatureString);

var options = SettingsService.Instance.GetSettings<ReadyToRunOptions>();
var options = settingsService.GetSettings<ReadyToRunOptions>();

if (options.IsShowGCInfo)
{
Expand Down
12 changes: 8 additions & 4 deletions ILSpy.ReadyToRun/ReadyToRunLanguage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@

using ILCompiler.Reflection.ReadyToRun;

using TomsToolbox.Composition;

using MetadataReader = System.Reflection.Metadata.MetadataReader;

namespace ICSharpCode.ILSpy.ReadyToRun
{
#if STRESS
Expand Down Expand Up @@ -97,7 +101,7 @@ public void WriteReference(IMember member, string text, bool isDefinition = fals

[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>();

Expand Down Expand Up @@ -175,7 +179,7 @@ public override void DecompileMethod(IMethod method, ITextOutput output, Decompi
.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
Expand Down Expand Up @@ -205,7 +209,7 @@ public override void DecompileMethod(IMethod method, ITextOutput output, Decompi
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);
}
}
}
Expand All @@ -218,7 +222,7 @@ public override void DecompileMethod(IMethod method, ITextOutput output, Decompi

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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public void VerifyReturnsOnlyInterfaceMembers()
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);
Expand Down
2 changes: 1 addition & 1 deletion ILSpy.Tests/Analyzers/MethodUsesAnalyzerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public void Setup()
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();
}

Expand Down
2 changes: 1 addition & 1 deletion ILSpy.Tests/Analyzers/TypeUsedByAnalyzerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public void Setup()
assemblyList = new AssemblyList();
testAssembly = assemblyList.OpenAssembly(typeof(MethodUsesAnalyzerTests).Assembly.Location);
testAssemblyTypeSystem = new DecompilerTypeSystem(testAssembly.GetMetadataFileOrNull(), testAssembly.GetAssemblyResolver());
language = new CSharpLanguage([]);
language = new CSharpLanguage();
}

[Test]
Expand Down
61 changes: 38 additions & 23 deletions ILSpy/AboutPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,51 @@
// DEALINGS IN THE SOFTWARE.

using System;
using System.Collections.Generic;
using System.Composition;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Navigation;

using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.Themes;
using ICSharpCode.ILSpy.Updates;
using ICSharpCode.ILSpyX.Settings;
using ICSharpCode.ILSpy.ViewModels;

namespace ICSharpCode.ILSpy
{
[ExportMainMenuCommand(ParentMenuID = nameof(Resources._Help), Header = nameof(Resources._About), MenuOrder = 99999)]
[Shared]
sealed class AboutPage : SimpleCommand
public sealed class AboutPage : SimpleCommand
{
readonly SettingsService settingsService;
readonly IEnumerable<IAboutPageAddition> aboutPageAdditions;

public AboutPage(SettingsService settingsService, IEnumerable<IAboutPageAddition> aboutPageAdditions)
{
this.settingsService = settingsService;
this.aboutPageAdditions = aboutPageAdditions;
MessageBus<ShowAboutPageEventArgs>.Subscribers += (_, e) => ShowAboutPage(e.TabPage);
}

public override void Execute(object parameter)
{
MainWindow.Instance.AssemblyTreeModel.NavigateTo(
new RequestNavigateEventArgs(new Uri("resource://aboutpage"), null),
inNewTabPage: true
);
MessageBus.Send(this, new NavigateToEventArgs(new(new("resource://aboutpage"), null), inNewTabPage: true));
}

private void ShowAboutPage(TabPageModel tabPage)
{
tabPage.ShowTextView(Display);
}

public static void Display(DecompilerTextView textView)
private void Display(DecompilerTextView textView)
{
AvalonEditTextOutput output = new AvalonEditTextOutput() {
Title = Resources.About,
Expand All @@ -61,23 +74,26 @@ public static void Display(DecompilerTextView textView)

output.AddUIElement(
delegate {
StackPanel stackPanel = new StackPanel();
stackPanel.HorizontalAlignment = HorizontalAlignment.Center;
stackPanel.Orientation = Orientation.Horizontal;
if (NotifyOfUpdatesStrategy.LatestAvailableVersion == null)
StackPanel stackPanel = new() {
HorizontalAlignment = HorizontalAlignment.Center,
Orientation = Orientation.Horizontal
};
if (UpdateService.LatestAvailableVersion == null)
{
AddUpdateCheckButton(stackPanel, textView);
}
else
{
// we already retrieved the latest version sometime earlier
ShowAvailableVersion(NotifyOfUpdatesStrategy.LatestAvailableVersion, stackPanel);
ShowAvailableVersion(UpdateService.LatestAvailableVersion, stackPanel);
}
CheckBox checkBox = new CheckBox();
checkBox.Margin = new Thickness(4);
checkBox.Content = Resources.AutomaticallyCheckUpdatesEveryWeek;
UpdateSettings settings = new UpdateSettings(SettingsService.Instance.SpySettings);
checkBox.SetBinding(CheckBox.IsCheckedProperty, new Binding("AutomaticUpdateCheckEnabled") { Source = settings });
CheckBox checkBox = new() {
Margin = new Thickness(4),
Content = Resources.AutomaticallyCheckUpdatesEveryWeek
};

var settings = settingsService.GetSettings<UpdateSettings>();
checkBox.SetBinding(ToggleButton.IsCheckedProperty, new Binding("AutomaticUpdateCheckEnabled") { Source = settings });
return new StackPanel {
Margin = new Thickness(0, 4, 0, 0),
Cursor = Cursors.Arrow,
Expand All @@ -86,16 +102,15 @@ public static void Display(DecompilerTextView textView)
});
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");
using (Stream s = typeof(AboutPage).Assembly.GetManifestResourceStream(typeof(AboutPage), Resources.ILSpyAboutPageTxt))
{
using (StreamReader r = new StreamReader(s))
{
string line;
while ((line = r.ReadLine()) != null)
while (r.ReadLine() is { } line)
{
output.WriteLine(line);
}
Expand Down Expand Up @@ -156,7 +171,7 @@ static void AddUpdateCheckButton(StackPanel stackPanel, DecompilerTextView textV

try
{
AvailableVersionInfo vInfo = await NotifyOfUpdatesStrategy.GetLatestVersionAsync();
AvailableVersionInfo vInfo = await UpdateService.GetLatestVersionAsync();
stackPanel.Children.Clear();
ShowAvailableVersion(vInfo, stackPanel);
}
Expand Down Expand Up @@ -199,7 +214,7 @@ static void ShowAvailableVersion(AvailableVersionInfo availableVersion, StackPan
button.Content = Resources.Download;
button.Cursor = Cursors.Arrow;
button.Click += delegate {
MainWindow.OpenLink(availableVersion.DownloadUrl);
GlobalUtils.OpenLink(availableVersion.DownloadUrl);
};
stackPanel.Children.Add(button);
}
Expand Down
23 changes: 12 additions & 11 deletions ILSpy/Analyzers/AnalyzeCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,18 @@
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))
Expand Down Expand Up @@ -62,30 +63,30 @@ public void Execute(TextViewContext context)
{
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
[Export]
[Shared]
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);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions ILSpy/Analyzers/AnalyzerSearchTreeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ protected IEnumerable<AnalyzerTreeNode> FetchChildren(CancellationToken ct)
{
if (symbol is IEntity)
{
var context = new AnalyzerContext() {
var context = new AnalyzerContext {
CancellationToken = ct,
Language = Language,
AssemblyList = MainWindow.Instance.AssemblyTreeModel.AssemblyList
AssemblyList = AssemblyList
};
var results = analyzer.Analyze(symbol, context).Select(SymbolTreeNodeFactory);
if (context.SortResults)
Expand Down
14 changes: 13 additions & 1 deletion ILSpy/Analyzers/AnalyzerTreeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,22 @@
// 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;
protected static Language Language => App.ExportProvider.GetExportedValue<LanguageService>().Language;

protected static AssemblyList AssemblyList => App.ExportProvider.GetExportedValue<AssemblyList>();

public override bool CanDelete()
{
Expand All @@ -42,6 +49,11 @@ public override void Delete()
DeleteCore();
}

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>
Expand Down
5 changes: 3 additions & 2 deletions ILSpy/Analyzers/AnalyzerTreeViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Analyzers.TreeNodes;
using ICSharpCode.ILSpy.AssemblyTree;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;

Expand All @@ -38,12 +39,12 @@ public class AnalyzerTreeViewModel : ToolPaneModel
{
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();
Expand Down
Loading

0 comments on commit 1134313

Please sign in to comment.