Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace singletons with DI patterns... #3314

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading