From 3d34a20b48c8bb5daca70fbfacb5109a56e542e2 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 24 Aug 2024 22:15:48 +0200 Subject: [PATCH] Highlight severity of assembly resolve log messages to make it easier to see errors. --- .../ThemeAwareHighlightingColorizer.cs | 61 +---------------- ILSpy/Themes/ThemeManager.cs | 67 +++++++++++++++++++ ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs | 59 +++++++++++++--- ILSpy/TreeNodes/ModuleReferenceTreeNode.cs | 4 +- ILSpy/TreeNodes/ReferenceFolderTreeNode.cs | 16 ++--- 5 files changed, 128 insertions(+), 79 deletions(-) diff --git a/ILSpy/TextView/ThemeAwareHighlightingColorizer.cs b/ILSpy/TextView/ThemeAwareHighlightingColorizer.cs index 8139094826..b92b944e68 100644 --- a/ILSpy/TextView/ThemeAwareHighlightingColorizer.cs +++ b/ILSpy/TextView/ThemeAwareHighlightingColorizer.cs @@ -1,6 +1,4 @@ -using System; using System.Collections.Generic; -using System.Windows.Media; using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Rendering; @@ -40,66 +38,9 @@ private HighlightingColor GetColorForDarkTheme(HighlightingColor lightColor) if (!_darkColors.TryGetValue(lightColor, out var darkColor)) { - darkColor = lightColor.Clone(); - darkColor.Foreground = AdjustForDarkTheme(darkColor.Foreground); - darkColor.Background = AdjustForDarkTheme(darkColor.Background); - - _darkColors[lightColor] = darkColor; + _darkColors[lightColor] = darkColor = ThemeManager.GetColorForDarkTheme(lightColor); } return darkColor; } - - private static HighlightingBrush? AdjustForDarkTheme(HighlightingBrush? lightBrush) - { - if (lightBrush is SimpleHighlightingBrush simpleBrush && simpleBrush.GetBrush(null) is SolidColorBrush brush) - { - return new SimpleHighlightingBrush(AdjustForDarkTheme(brush.Color)); - } - - return lightBrush; - } - - private static Color AdjustForDarkTheme(Color color) - { - var c = System.Drawing.Color.FromArgb(color.R, color.G, color.B); - var (h, s, l) = (c.GetHue(), c.GetSaturation(), c.GetBrightness()); - - // Invert the lightness, but also increase it a bit - l = 1f - MathF.Pow(l, 1.2f); - - // Desaturate the colors, as they'd be too intense otherwise - if (s > 0.75f && l < 0.75f) - { - s *= 0.75f; - l *= 1.2f; - } - - var (r, g, b) = HslToRgb(h, s, l); - return Color.FromArgb(color.A, r, g, b); - } - - private static (byte r, byte g, byte b) HslToRgb(float h, float s, float l) - { - // https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB - - var c = (1f - Math.Abs(2f * l - 1f)) * s; - h = h % 360f / 60f; - var x = c * (1f - Math.Abs(h % 2f - 1f)); - - var (r1, g1, b1) = (int)Math.Floor(h) switch { - 0 => (c, x, 0f), - 1 => (x, c, 0f), - 2 => (0f, c, x), - 3 => (0f, x, c), - 4 => (x, 0f, c), - _ => (c, 0f, x) - }; - - var m = l - c / 2f; - var r = (byte)((r1 + m) * 255f); - var g = (byte)((g1 + m) * 255f); - var b = (byte)((b1 + m) * 255f); - return (r, g, b); - } } diff --git a/ILSpy/Themes/ThemeManager.cs b/ILSpy/Themes/ThemeManager.cs index d0210a2846..419e4026ce 100644 --- a/ILSpy/Themes/ThemeManager.cs +++ b/ILSpy/Themes/ThemeManager.cs @@ -132,5 +132,72 @@ private void UpdateTheme(string? themeName) } } } + + public static HighlightingColor GetColorForDarkTheme(HighlightingColor lightColor) + { + if (lightColor.Foreground is null && lightColor.Background is null) + { + return lightColor; + } + + var darkColor = lightColor.Clone(); + darkColor.Foreground = AdjustForDarkTheme(darkColor.Foreground); + darkColor.Background = AdjustForDarkTheme(darkColor.Background); + + return darkColor; + } + + private static HighlightingBrush? AdjustForDarkTheme(HighlightingBrush? lightBrush) + { + if (lightBrush is SimpleHighlightingBrush simpleBrush && simpleBrush.GetBrush(null) is SolidColorBrush brush) + { + return new SimpleHighlightingBrush(AdjustForDarkTheme(brush.Color)); + } + + return lightBrush; + } + + private static Color AdjustForDarkTheme(Color color) + { + var c = System.Drawing.Color.FromArgb(color.R, color.G, color.B); + var (h, s, l) = (c.GetHue(), c.GetSaturation(), c.GetBrightness()); + + // Invert the lightness, but also increase it a bit + l = 1f - MathF.Pow(l, 1.2f); + + // Desaturate the colors, as they'd be too intense otherwise + if (s > 0.75f && l < 0.75f) + { + s *= 0.75f; + l *= 1.2f; + } + + var (r, g, b) = HslToRgb(h, s, l); + return Color.FromArgb(color.A, r, g, b); + } + + private static (byte r, byte g, byte b) HslToRgb(float h, float s, float l) + { + // https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB + + var c = (1f - Math.Abs(2f * l - 1f)) * s; + h = h % 360f / 60f; + var x = c * (1f - Math.Abs(h % 2f - 1f)); + + var (r1, g1, b1) = (int)Math.Floor(h) switch { + 0 => (c, x, 0f), + 1 => (x, c, 0f), + 2 => (0f, c, x), + 3 => (0f, x, c), + 4 => (x, 0f, c), + _ => (c, 0f, x) + }; + + var m = l - c / 2f; + var r = (byte)((r1 + m) * 255f); + var g = (byte)((g1 + m) * 255f); + var b = (byte)((b1 + m) * 255f); + return (r, g, b); + } } } diff --git a/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs b/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs index 708eeb51d7..f0046694b8 100644 --- a/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs @@ -17,15 +17,17 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Windows; +using System.Windows.Media; using System.Windows.Threading; +using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.Decompiler; using ICSharpCode.Decompiler.Metadata; using ICSharpCode.Decompiler.TypeSystem; +using ICSharpCode.ILSpy.Themes; using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions; -using TomsToolbox.Wpf.Controls; - namespace ICSharpCode.ILSpy.TreeNodes { /// @@ -98,25 +100,66 @@ public override void Decompile(Language language, ITextOutput output, Decompilat var loaded = parentAssembly.LoadedAssembly.LoadedAssemblyReferencesInfo.TryGetInfo(r.FullName, out var info); if (r.IsWindowsRuntime) { - language.WriteCommentLine(output, r.FullName + " [WinRT]" + (!loaded ? " (unresolved)" : "")); + output.WriteLine(r.FullName + " [WinRT]" + (!loaded ? " (unresolved)" : "")); } else { - language.WriteCommentLine(output, r.FullName + (!loaded ? " (unresolved)" : "")); + output.WriteLine(r.FullName + (!loaded ? " (unresolved)" : "")); } if (loaded) { output.Indent(); - language.WriteCommentLine(output, "Assembly reference loading information:"); + output.WriteLine("Assembly reference loading information:"); if (info.HasErrors) - language.WriteCommentLine(output, "There were some problems during assembly reference load, see below for more information!"); - foreach (var item in info.Messages) { - language.WriteCommentLine(output, $"{item.Item1}: {item.Item2}"); + output.WriteLine("There were some problems during assembly reference load, see below for more information!"); } + PrintAssemblyLoadLogMessages(output, info); output.Unindent(); output.WriteLine(); } } + + internal static void PrintAssemblyLoadLogMessages(ITextOutput output, UnresolvedAssemblyNameReference asm) + { + HighlightingColor red = GetColor(Colors.Red); + HighlightingColor yellow = GetColor(Colors.Yellow); + + var smartOutput = output as ISmartTextOutput; + + foreach (var item in asm.Messages) + { + switch (item.Item1) + { + case MessageKind.Error: + smartOutput?.BeginSpan(red); + output.Write("Error: "); + smartOutput?.EndSpan(); + break; + case MessageKind.Warning: + smartOutput?.BeginSpan(yellow); + output.Write("Warning: "); + smartOutput?.EndSpan(); + break; + default: + output.Write(item.Item1 + ": "); + break; + } + output.WriteLine(item.Item2); + } + + static HighlightingColor GetColor(Color color) + { + var hc = new HighlightingColor { + Foreground = new SimpleHighlightingBrush(color), + FontWeight = FontWeights.Bold + }; + if (ThemeManager.Current.IsDarkTheme) + { + return ThemeManager.GetColorForDarkTheme(hc); + } + return hc; + } + } } } diff --git a/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs b/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs index b9a1d6de22..24fe4eb51d 100644 --- a/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs +++ b/ILSpy/TreeNodes/ModuleReferenceTreeNode.cs @@ -87,8 +87,8 @@ public override void ActivateItem(IPlatformRoutedEventArgs e) public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) { - language.WriteCommentLine(output, moduleName); - language.WriteCommentLine(output, containsMetadata ? "contains metadata" : "contains no metadata"); + output.WriteLine(moduleName); + output.WriteLine(containsMetadata ? "contains metadata" : "contains no metadata"); } } } diff --git a/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs b/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs index 2f3942083d..355a965370 100644 --- a/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs +++ b/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs @@ -60,12 +60,12 @@ public override void Decompile(Language language, ITextOutput output, Decompilat { string targetFramework = parentAssembly.LoadedAssembly.GetTargetFrameworkIdAsync().GetAwaiter().GetResult(); string runtimePack = parentAssembly.LoadedAssembly.GetRuntimePackAsync().GetAwaiter().GetResult(); - language.WriteCommentLine(output, $"Detected TargetFramework-Id: {targetFramework}"); - language.WriteCommentLine(output, $"Detected RuntimePack: {runtimePack}"); + output.WriteLine($"Detected TargetFramework-Id: {targetFramework}"); + output.WriteLine($"Detected RuntimePack: {runtimePack}"); App.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(EnsureLazyChildren)); output.WriteLine(); - language.WriteCommentLine(output, "Referenced assemblies (in metadata order):"); + output.WriteLine("Referenced assemblies (in metadata order):"); // Show metadata order of references foreach (var node in this.Children.OfType()) node.Decompile(language, output, options); @@ -73,16 +73,14 @@ public override void Decompile(Language language, ITextOutput output, Decompilat output.WriteLine(); output.WriteLine(); // Show full assembly load log: - language.WriteCommentLine(output, "Assembly load log including transitive references:"); + output.WriteLine("Assembly load log including transitive references:"); var info = parentAssembly.LoadedAssembly.LoadedAssemblyReferencesInfo; + foreach (var asm in info.Entries) { - language.WriteCommentLine(output, asm.FullName); + output.WriteLine(asm.FullName); output.Indent(); - foreach (var item in asm.Messages) - { - language.WriteCommentLine(output, $"{item.Item1}: {item.Item2}"); - } + AssemblyReferenceTreeNode.PrintAssemblyLoadLogMessages(output, asm); output.Unindent(); output.WriteLine(); }