Skip to content

Commit

Permalink
Highlight severity of assembly resolve log messages to make it easier…
Browse files Browse the repository at this point in the history
… to see errors.
  • Loading branch information
siegfriedpammer committed Aug 24, 2024
1 parent a4e372a commit 3d34a20
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 79 deletions.
61 changes: 1 addition & 60 deletions ILSpy/TextView/ThemeAwareHighlightingColorizer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Windows.Media;

using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Rendering;
Expand Down Expand Up @@ -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);
}
}
67 changes: 67 additions & 0 deletions ILSpy/Themes/ThemeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
59 changes: 51 additions & 8 deletions ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
/// <summary>
Expand Down Expand Up @@ -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;
}
}
}
}
4 changes: 2 additions & 2 deletions ILSpy/TreeNodes/ModuleReferenceTreeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}
}
16 changes: 7 additions & 9 deletions ILSpy/TreeNodes/ReferenceFolderTreeNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,29 +60,27 @@ 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<ILSpyTreeNode>())
node.Decompile(language, output, options);

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();
}
Expand Down

0 comments on commit 3d34a20

Please sign in to comment.