From d3ba74ce5a4b75b8d09f80eae560d767d80790c3 Mon Sep 17 00:00:00 2001 From: Vitalii Mikhailov Date: Sat, 23 Dec 2023 16:23:02 +0200 Subject: [PATCH] Add method representation only if available Removed usage of System.Collections.Immutable and System.Runtime.CompilerServices.Unsafe where possible --- .../BUTR.CrashReport.Bannerlord.Source.csproj | 2 - .../CrashReportArchiveRenderer.cs | 1 - .../CrashReportCreator.cs | 168 ++++++++++-------- .../CrashReportHtmlRenderer.cs | 64 ++++--- .../CrashReportShared.cs | 1 - .../ImmutableArrayExtensions.cs | 59 ------ .../StringBuilderExtensions.cs | 2 + 7 files changed, 138 insertions(+), 159 deletions(-) delete mode 100644 src/BUTR.CrashReport.Bannerlord.Source/ImmutableArrayExtensions.cs diff --git a/src/BUTR.CrashReport.Bannerlord.Source/BUTR.CrashReport.Bannerlord.Source.csproj b/src/BUTR.CrashReport.Bannerlord.Source/BUTR.CrashReport.Bannerlord.Source.csproj index 3543c95..de8ec16 100644 --- a/src/BUTR.CrashReport.Bannerlord.Source/BUTR.CrashReport.Bannerlord.Source.csproj +++ b/src/BUTR.CrashReport.Bannerlord.Source/BUTR.CrashReport.Bannerlord.Source.csproj @@ -42,8 +42,6 @@ - - diff --git a/src/BUTR.CrashReport.Bannerlord.Source/CrashReportArchiveRenderer.cs b/src/BUTR.CrashReport.Bannerlord.Source/CrashReportArchiveRenderer.cs index 3b88663..cf66f53 100644 --- a/src/BUTR.CrashReport.Bannerlord.Source/CrashReportArchiveRenderer.cs +++ b/src/BUTR.CrashReport.Bannerlord.Source/CrashReportArchiveRenderer.cs @@ -50,7 +50,6 @@ namespace BUTR.CrashReport.Bannerlord using global::System.Collections.Generic; using global::System.IO; using global::System.IO.Compression; - using global::System.Linq; internal static class CrashReportArchiveRenderer { diff --git a/src/BUTR.CrashReport.Bannerlord.Source/CrashReportCreator.cs b/src/BUTR.CrashReport.Bannerlord.Source/CrashReportCreator.cs index 1249383..af32e3d 100644 --- a/src/BUTR.CrashReport.Bannerlord.Source/CrashReportCreator.cs +++ b/src/BUTR.CrashReport.Bannerlord.Source/CrashReportCreator.cs @@ -56,13 +56,11 @@ namespace BUTR.CrashReport.Bannerlord using global::System; using global::System.Collections.Generic; - using global::System.Collections.Immutable; using global::System.Globalization; using global::System.IO; using global::System.Linq; using global::System.Reflection; using global::System.Security.Cryptography; - using global::System.Threading.Tasks; internal class CrashReportCreator { @@ -81,7 +79,7 @@ public static CrashReportModel Create(CrashReportInfo crashReport) Modules = modules, Assemblies = GetAssemblyList(crashReport), HarmonyPatches = GetHarmonyPatchesListHtml(crashReport), - MonoModDetours = ImmutableArray.Empty, + MonoModDetours = Array.Empty(), Metadata = new() { LauncherType = GetLauncherType(crashReport), @@ -89,12 +87,14 @@ public static CrashReportModel Create(CrashReportInfo crashReport) Runtime = System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription, - AdditionalMetadata = ImmutableArray.Create( + AdditionalMetadata = new MetadataModel[] + { new MetadataModel { Key = "BUTRLoaderVersion", Value = GetBUTRLoaderVersion(crashReport) }, new MetadataModel { Key = "BLSEVersion", Value = GetBLSEVersion(crashReport) }, - new MetadataModel { Key = "LauncherExVersion", Value = GetLauncherExVersion(crashReport) }), + new MetadataModel { Key = "LauncherExVersion", Value = GetLauncherExVersion(crashReport) }, + }, }, - AdditionalMetadata = ImmutableArray.Empty, + AdditionalMetadata = Array.Empty(), }; } @@ -152,46 +152,46 @@ private static string GetLauncherVersion(CrashReportInfo crashReport) return "0"; } - private static ExceptionModel GetRecursiveException(CrashReportInfo crashReport, ImmutableArray modules, ImmutableArray assemblies) + private static ExceptionModel GetRecursiveException(CrashReportInfo crashReport, List modules, List assemblies) { - static ExceptionModel GetRecursiveException(CrashReportInfo crashReport, ImmutableArray modules, ImmutableArray assemblies, Exception ex) => new() + static ExceptionModel GetRecursiveException(CrashReportInfo crashReport, List modules, List assemblies, Exception ex) => new() { SourceModuleId = modules.FirstOrDefault(x => assemblies.Where(y => y.ModuleId == x.Id).Any(x => x.Name == ex.Source))?.Id, Type = ex.GetType().FullName ?? string.Empty, Message = ex.Message, - CallStack = ex.StackTrace, + CallStack = ex.StackTrace ?? string.Empty, InnerException = ex.InnerException is not null ? GetRecursiveException(crashReport, modules, assemblies, ex.InnerException) : null, - AdditionalMetadata = ImmutableArray.Empty, + AdditionalMetadata = Array.Empty(), }; return GetRecursiveException(crashReport, modules, assemblies, crashReport.Exception); } - private static ImmutableArray GetEnhancedStacktrace(CrashReportInfo crashReport) + private static List GetEnhancedStacktrace(CrashReportInfo crashReport) { - var builder = ImmutableArray.CreateBuilder(); + var enhancedStacktraceFrameModels = new List(); foreach (var stacktrace in crashReport.Stacktrace.GroupBy(x => x.StackFrameDescription)) { foreach (var entry in stacktrace) { - var methodsBuilder = ImmutableArray.CreateBuilder(); + var methods = new List(entry.PatchMethods.Length); foreach (var patchMethod in entry.PatchMethods) { - methodsBuilder.Add(new() + methods.Add(new() { ModuleId = patchMethod.ModuleInfo?.Id, MethodDeclaredTypeName = patchMethod.Method.DeclaringType?.FullName, MethodName = patchMethod.Method.Name, MethodFullDescription = patchMethod.Method.FullDescription(), - MethodParameters = patchMethod.Method.GetParameters().Select(x => x.ParameterType.FullName).ToImmutableArray(), - ILInstructions = patchMethod.ILInstructions.AsImmutableArray(), - CSharpILMixedInstructions = patchMethod.CSharpILMixedInstructions.AsImmutableArray(), - CSharpInstructions = patchMethod.CSharpInstructions.AsImmutableArray(), - AdditionalMetadata = ImmutableArray.Empty, + MethodParameters = patchMethod.Method.GetParameters().Select(x => x.ParameterType.FullName ?? string.Empty).ToArray(), + ILInstructions = patchMethod.ILInstructions, + CSharpILMixedInstructions = patchMethod.CSharpILMixedInstructions, + CSharpInstructions = patchMethod.CSharpInstructions, + AdditionalMetadata = Array.Empty(), }); } - builder.Add(new() + enhancedStacktraceFrameModels.Add(new() { FrameDescription = entry.StackFrameDescription, ExecutingMethod = new() @@ -200,12 +200,12 @@ private static ImmutableArray GetEnhancedStacktrac MethodDeclaredTypeName = entry.Method.DeclaringType?.FullName, MethodName = entry.Method.Name, MethodFullDescription = entry.Method.FullDescription(), - MethodParameters = entry.Method.GetParameters().Select(x => x.ParameterType.FullName).ToImmutableArray(), - NativeInstructions = entry.NativeInstructions.AsImmutableArray(), - ILInstructions = entry.ILInstructions.AsImmutableArray(), - CSharpILMixedInstructions = entry.CSharpILMixedInstructions.AsImmutableArray(), - CSharpInstructions = entry.CSharpInstructions.AsImmutableArray(), - AdditionalMetadata = ImmutableArray.Empty, + MethodParameters = entry.Method.GetParameters().Select(x => x.ParameterType.FullName ?? string.Empty).ToArray(), + NativeInstructions = entry.NativeInstructions, + ILInstructions = entry.ILInstructions, + CSharpILMixedInstructions = entry.CSharpILMixedInstructions, + CSharpInstructions = entry.CSharpInstructions, + AdditionalMetadata = Array.Empty(), }, OriginalMethod = entry.OriginalMethod is not null ? new() { @@ -213,50 +213,49 @@ private static ImmutableArray GetEnhancedStacktrac MethodDeclaredTypeName = entry.OriginalMethod.Method.DeclaringType?.FullName, MethodName = entry.OriginalMethod.Method.Name, MethodFullDescription = entry.OriginalMethod.Method.FullDescription(), - MethodParameters = entry.OriginalMethod.Method.GetParameters().Select(x => x.ParameterType.FullName).ToImmutableArray(), - ILInstructions = entry.OriginalMethod.ILInstructions.AsImmutableArray(), - CSharpILMixedInstructions = entry.OriginalMethod.CSharpILMixedInstructions.AsImmutableArray(), - CSharpInstructions = entry.OriginalMethod.CSharpInstructions.AsImmutableArray(), - AdditionalMetadata = ImmutableArray.Empty + MethodParameters = entry.OriginalMethod.Method.GetParameters().Select(x => x.ParameterType.FullName ?? string.Empty).ToArray(), + ILInstructions = entry.OriginalMethod.ILInstructions, + CSharpILMixedInstructions = entry.OriginalMethod.CSharpILMixedInstructions, + CSharpInstructions = entry.OriginalMethod.CSharpInstructions, + AdditionalMetadata = Array.Empty() } : null, - PatchMethods = methodsBuilder.ToImmutable(), + PatchMethods = methods, ILOffset = entry.ILOffset, NativeOffset = entry.NativeOffset, MethodFromStackframeIssue = entry.MethodFromStackframeIssue, - AdditionalMetadata = ImmutableArray.Empty, + AdditionalMetadata = Array.Empty(), }); } } - return builder.ToImmutable(); + return enhancedStacktraceFrameModels; } - private static ImmutableArray GetInvolvedModuleList(CrashReportInfo crashReport) + private static List GetInvolvedModuleList(CrashReportInfo crashReport) { - var builder = ImmutableArray.CreateBuilder(); + var involvedModuleModels = new List(); foreach (var stacktrace in crashReport.FilteredStacktrace.GroupBy(m => m.ModuleInfo)) { var module = stacktrace.Key; if (module is null) continue; - builder.Add(new() + involvedModuleModels.Add(new() { ModuleId = module.Id, EnhancedStacktraceFrameName = stacktrace.Last().StackFrameDescription, - AdditionalMetadata = ImmutableArray.Empty, + AdditionalMetadata = Array.Empty(), }); } - return builder.ToImmutable(); + return involvedModuleModels; } - private static ImmutableArray GetModuleList(CrashReportInfo crashReport) + private static List GetModuleList(CrashReportInfo crashReport) { - var builder = ImmutableArray.CreateBuilder(); - + var moduleModels = new List(crashReport.LoadedModules.Count); foreach (var module in crashReport.LoadedModules.OfType().Select(x => x.InternalModuleInfo)) { var isManagedByVortex = File.Exists(Path.Combine(module.Path, "__folder_managed_by_vortex")); - builder.Add(new() + moduleModels.Add(new() { Id = module.Id, Name = module.Name, @@ -274,8 +273,8 @@ private static ImmutableArray GetModuleList(CrashReportInfo crashRe IsOptional = x.IsOptional, Version = !x.Version.Equals(ApplicationVersion.Empty) ? x.Version.ToString() : null, VersionRange = !x.VersionRange.Equals(ApplicationVersionRange.Empty) ? x.VersionRange.ToString() : null, - AdditionalMetadata = ImmutableArray.Empty, - }).ToImmutableArray(), + AdditionalMetadata = Array.Empty(), + }).ToArray(), SubModules = module.SubModules.Where(ModuleInfoHelper.CheckIfSubModuleCanBeLoaded).Select(x => new ModuleSubModuleModel { Name = x.Name, @@ -283,17 +282,40 @@ private static ImmutableArray GetModuleList(CrashReportInfo crashRe Entrypoint = x.SubModuleClassType, AdditionalMetadata = x.Assemblies.Select(y => new MetadataModel { Key = "METADATA:Assembly", Value = y }) .Concat(x.Tags.SelectMany(y => y.Value.Select(z => new MetadataModel { Key = y.Key, Value = z }))) - .ToImmutableArray(), - }).ToImmutableArray(), - AdditionalMetadata = ImmutableArray.Create(new MetadataModel { Key = "METADATA:MANAGED_BY_VORTEX", Value = isManagedByVortex.ToString()}), + .ToArray(), + }).ToArray(), + AdditionalMetadata = new MetadataModel[] + { + new MetadataModel { Key = "METADATA:MANAGED_BY_VORTEX", Value = isManagedByVortex.ToString() }, + }, }); } - - return builder.ToImmutable(); + return moduleModels; } - private static ImmutableArray GetAssemblyList(CrashReportInfo crashReport) + private static List GetAssemblyList(CrashReportInfo crashReport) { + static bool IsGAC(Assembly assembly) + { + try + { +#pragma warning disable SYSLIB0005 + return assembly.GlobalAssemblyCache; +#pragma warning restore SYSLIB0005 + } + catch (Exception) { return false; } + } + static ProcessorArchitecture GetProcessorArchitecture(AssemblyName assemblyName) + { + try + { +#pragma warning disable SYSLIB0037 + return assemblyName.ProcessorArchitecture; +#pragma warning restore SYSLIB0037 + } + catch (Exception) { return ProcessorArchitecture.None; } + } + static string CalculateMD5(string filename) { using var md5 = MD5.Create(); @@ -302,7 +324,7 @@ static string CalculateMD5(string filename) return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); } - var builder = ImmutableArray.CreateBuilder(); + var assemblyModels = new List(crashReport.AvailableAssemblies.Count); foreach (var (assemblyName, assembly) in crashReport.AvailableAssemblies) { @@ -317,8 +339,8 @@ static string CalculateMD5(string filename) } var systemAssemblyDirectory = Path.GetDirectoryName(typeof(object).Assembly.Location); - var isGAC = assembly.GlobalAssemblyCache; - var isSystem = !assembly.IsDynamic && !string.IsNullOrWhiteSpace(assembly.Location) && Path.GetDirectoryName(assembly.Location).Equals(systemAssemblyDirectory, StringComparison.Ordinal); + var isGAC = IsGAC(assembly); + var isSystem = !assembly.IsDynamic && !string.IsNullOrWhiteSpace(assembly.Location) && Path.GetDirectoryName(assembly.Location)?.Equals(systemAssemblyDirectory, StringComparison.Ordinal) == true; var isTWCore = !assembly.IsDynamic && assembly.Location.IndexOf(@"Mount & Blade II Bannerlord\bin\", StringComparison.InvariantCultureIgnoreCase) >= 0; var type = AssemblyModelType.Unclassified; @@ -328,14 +350,14 @@ static string CalculateMD5(string filename) if (isTWCore) type |= AssemblyModelType.GameCore; if (module is not null) type |= AssemblyModelType.Module; if (module is not null && module.IsOfficial) type |= AssemblyModelType.GameModule; - builder.Add(new() + assemblyModels.Add(new() { ModuleId = module?.Id, - Name = assemblyName.Name, + Name = assemblyName.Name ?? string.Empty, Culture = assemblyName.CultureName, - PublicKeyToken = string.Join(string.Empty, Array.ConvertAll(assemblyName.GetPublicKeyToken(), x => x.ToString("x2", CultureInfo.InvariantCulture))), - Version = assemblyName.Version.ToString(), - Architecture = assemblyName.ProcessorArchitecture.ToString(), + PublicKeyToken = string.Join(string.Empty, Array.ConvertAll(assemblyName.GetPublicKeyToken() ?? Array.Empty(), x => x.ToString("x2", CultureInfo.InvariantCulture))), + Version = assemblyName.Version?.ToString() ?? string.Empty, + Architecture = GetProcessorArchitecture(assemblyName).ToString(), Hash = assembly.IsDynamic || string.IsNullOrWhiteSpace(assembly.Location) || !File.Exists(assembly.Location) ? string.Empty : CalculateMD5(assembly.Location), AnonymizedPath = assembly.IsDynamic ? "DYNAMIC" : string.IsNullOrWhiteSpace(assembly.Location) ? "EMPTY" : !File.Exists(assembly.Location) ? "MISSING" : Anonymizer.AnonymizePath(assembly.Location), Type = type, @@ -344,20 +366,20 @@ static string CalculateMD5(string filename) Namespace = x.Namespace, Name = x.Name, FullName = x.FullName, - }).ToImmutableArray() : ImmutableArray.Empty, - ImportedAssemblyReferences = assembly.GetReferencedAssemblies().Select(x => AssemblyImportedReferenceModelExtensions.Create(x)).ToImmutableArray(), - AdditionalMetadata = ImmutableArray.Empty, + }).ToArray() : Array.Empty(), + ImportedAssemblyReferences = assembly.GetReferencedAssemblies().Select(x => AssemblyImportedReferenceModelExtensions.Create(x)).ToArray(), + AdditionalMetadata = Array.Empty(), }); } - return builder.ToImmutable(); + return assemblyModels; } - private static ImmutableArray GetHarmonyPatchesListHtml(CrashReportInfo crashReport) + private static List GetHarmonyPatchesListHtml(CrashReportInfo crashReport) { - var builder = ImmutableArray.CreateBuilder(); + var builder = new List(crashReport.LoadedHarmonyPatches.Count); - static void AppendPatches(ImmutableArray.Builder builder, HarmonyPatchModelType type, IEnumerable patches) + static void AppendPatches(List builder, HarmonyPatchModelType type, IEnumerable patches) { foreach (var patch in patches) { @@ -370,16 +392,16 @@ static void AppendPatches(ImmutableArray.Builder builder, Har Namespace = $"{patch.PatchMethod.DeclaringType!.FullName}.{patch.PatchMethod.Name}", Index = patch.index, Priority = patch.priority, - Before = patch.before.ToImmutableArray(), - After = patch.after.ToImmutableArray(), - AdditionalMetadata = ImmutableArray.Empty, + Before = patch.before, + After = patch.after, + AdditionalMetadata = Array.Empty(), }); } } foreach (var (originalMethod, patches) in crashReport.LoadedHarmonyPatches) { - var patchBuilder = ImmutableArray.CreateBuilder(); + var patchBuilder = new List(patches.Prefixes.Count + patches.Postfixes.Count + patches.Finalizers.Count + patches.Transpilers.Count); AppendPatches(patchBuilder, HarmonyPatchModelType.Prefix, patches.Prefixes); AppendPatches(patchBuilder, HarmonyPatchModelType.Postfix, patches.Postfixes); @@ -392,13 +414,13 @@ static void AppendPatches(ImmutableArray.Builder builder, Har { OriginalMethodDeclaredTypeName = originalMethod.DeclaringType?.FullName, OriginalMethodName = originalMethod.Name, - Patches = patchBuilder.ToImmutable(), - AdditionalMetadata = ImmutableArray.Empty, + Patches = patchBuilder, + AdditionalMetadata = Array.Empty(), }); } } - return builder.ToImmutable(); + return builder; } } } diff --git a/src/BUTR.CrashReport.Bannerlord.Source/CrashReportHtmlRenderer.cs b/src/BUTR.CrashReport.Bannerlord.Source/CrashReportHtmlRenderer.cs index c46d71f..2229d1e 100644 --- a/src/BUTR.CrashReport.Bannerlord.Source/CrashReportHtmlRenderer.cs +++ b/src/BUTR.CrashReport.Bannerlord.Source/CrashReportHtmlRenderer.cs @@ -48,11 +48,9 @@ namespace BUTR.CrashReport.Bannerlord { using global::BUTR.CrashReport.Extensions; using global::BUTR.CrashReport.Models; - using global::BUTR.CrashReport.Utils; using global::System; using global::System.Collections.Generic; - using global::System.Collections.Immutable; using global::System.IO; using global::System.Linq; using global::System.Text; @@ -519,15 +517,23 @@ private static string GetEnhancedStacktraceHtml(CrashReportModel crashReport) .Append("Method: ").Append(stacktrace.ExecutingMethod.MethodFullDescription.EscapeGenerics()).Append("
") .Append("Method From Stackframe Issue: ").Append(stacktrace.MethodFromStackframeIssue).Append("
") .Append("Approximate IL Offset: ").Append(stacktrace.ILOffset is not null ? $"{stacktrace.ILOffset:X4}" : "UNKNOWN").Append("
") - .Append("Native Offset: ").Append(stacktrace.NativeOffset is not null ? $"{stacktrace.NativeOffset:X4}" : "UNKNOWN") - .AppendIf(stacktrace.ExecutingMethod.ILInstructions.Count > 0, $"
+ IL:
")
-                    .AppendJoinIf(stacktrace.ExecutingMethod.ILInstructions.Count > 0, Environment.NewLine, stacktrace.ExecutingMethod.ILInstructions.Select(x => x.EscapeGenerics()).ToArray()).Append("
") - .AppendIf(stacktrace.ExecutingMethod.CSharpILMixedInstructions.Count > 0, $"
+ IL with C#:
")
-                    .AppendJoinIf(stacktrace.ExecutingMethod.CSharpILMixedInstructions.Count > 0, Environment.NewLine, stacktrace.ExecutingMethod.CSharpILMixedInstructions.Select(x => x.EscapeGenerics()).ToArray()).Append("
") - .AppendIf(stacktrace.ExecutingMethod.CSharpInstructions.Count > 0, $"
+ C#:
")
-                    .AppendJoinIf(stacktrace.ExecutingMethod.CSharpInstructions.Count > 0, Environment.NewLine, stacktrace.ExecutingMethod.CSharpInstructions.Select(x => x.EscapeGenerics()).ToArray()).Append("
") - .AppendIf(stacktrace.ExecutingMethod.NativeInstructions.Count > 0, $"
+ Native:
")
-                    .AppendJoinIf(stacktrace.ExecutingMethod.NativeInstructions.Count > 0, Environment.NewLine, stacktrace.ExecutingMethod.NativeInstructions.Select(x => x.EscapeGenerics()).ToArray()).Append("
") + .Append("Native Offset: ").Append(stacktrace.NativeOffset is not null ? $"{stacktrace.NativeOffset:X4}" : "UNKNOWN").Append("
") + .AppendIf(stacktrace.ExecutingMethod.ILInstructions.Count > 0, sp => sp + .Append($"
+ IL:
")
+                        .AppendJoin(Environment.NewLine, stacktrace.ExecutingMethod.ILInstructions.Select(x => x.EscapeGenerics()))
+                        .Append("
")) + .AppendIf(stacktrace.ExecutingMethod.CSharpILMixedInstructions.Count > 0, sp => sp + .Append($"
+ IL with C#:
")
+                        .AppendJoin(Environment.NewLine, stacktrace.ExecutingMethod.CSharpILMixedInstructions.Select(x => x.EscapeGenerics()))
+                        .Append("
")) + .AppendIf(stacktrace.ExecutingMethod.CSharpInstructions.Count > 0, sp => sp + .Append($"
+ C#:
")
+                        .AppendJoin(Environment.NewLine, stacktrace.ExecutingMethod.CSharpInstructions.Select(x => x.EscapeGenerics()))
+                        .Append("
")) + .AppendIf(stacktrace.ExecutingMethod.NativeInstructions.Count > 0, sp => sp + .Append($"
+ Native:
")
+                        .AppendJoin(Environment.NewLine, stacktrace.ExecutingMethod.NativeInstructions.Select(x => x.EscapeGenerics()))
+                        .Append("
")) .Append("") .Append(""); @@ -545,12 +551,18 @@ private static string GetEnhancedStacktraceHtml(CrashReportModel crashReport) .AppendIf(moduleId == "UNKNOWN", sb => sb.Append("Module Id: ").Append(moduleId).Append("
")) .AppendIf(moduleId != "UNKNOWN", sb => sb.Append("Module Id: ").Append("").Append(moduleId).Append("").Append("
")) .Append("Method: ").Append(method.MethodFullDescription.EscapeGenerics()).Append("
") - .AppendIf(method.ILInstructions.Count > 0, $"
+ IL:
")
-                            .AppendJoinIf(method.ILInstructions.Count > 0, Environment.NewLine, method.ILInstructions.Select(x => x.EscapeGenerics()).ToArray()).Append("
") - .AppendIf(method.CSharpILMixedInstructions.Count > 0, $"
+ IL with C#:
")
-                            .AppendJoinIf(method.CSharpILMixedInstructions.Count > 0, Environment.NewLine, method.CSharpILMixedInstructions.Select(x => x.EscapeGenerics()).ToArray()).Append("
") - .AppendIf(method.CSharpInstructions.Count > 0, $"
+ C#:
")
-                            .AppendJoinIf(method.CSharpInstructions.Count > 0, Environment.NewLine, method.CSharpInstructions.Select(x => x.EscapeGenerics()).ToArray()).Append("
") + .AppendIf(method.ILInstructions.Count > 0, sp => sp + .Append($"
+ IL:
")
+                                .AppendJoin(Environment.NewLine, method.ILInstructions.Select(x => x.EscapeGenerics()))
+                                .Append("
")) + .AppendIf(method.CSharpILMixedInstructions.Count > 0, sp => sp + .Append($"
+ IL with C#:
")
+                                .AppendJoin(Environment.NewLine, method.CSharpILMixedInstructions.Select(x => x.EscapeGenerics()))
+                                .Append("
")) + .AppendIf(method.CSharpInstructions.Count > 0, sp => sp + .Append($"
+ C#:
")
+                                .AppendJoin(Environment.NewLine, method.CSharpInstructions.Select(x => x.EscapeGenerics()))
+                                .Append("
")) .Append(""); } sb.Append(""); @@ -567,12 +579,18 @@ private static string GetEnhancedStacktraceHtml(CrashReportModel crashReport) .AppendIf(moduleId2 == "UNKNOWN", sb => sb.Append("Module Id: ").Append(moduleId2).Append("
")) .AppendIf(moduleId2 != "UNKNOWN", sb => sb.Append("Module Id: ").Append("").Append(moduleId2).Append("").Append("
")) .Append("Method: ").Append(stacktrace.OriginalMethod.MethodFullDescription.EscapeGenerics()).Append("
") - .AppendIf(stacktrace.OriginalMethod.ILInstructions.Count > 0, $"
+ IL:
")
-                        .AppendJoinIf(stacktrace.OriginalMethod.ILInstructions.Count > 0, Environment.NewLine, stacktrace.OriginalMethod.ILInstructions.Select(x => x.EscapeGenerics()).ToArray()).Append("
") - .AppendIf(stacktrace.OriginalMethod.CSharpILMixedInstructions.Count > 0, $"
+ IL with C#:
")
-                        .AppendJoinIf(stacktrace.OriginalMethod.CSharpILMixedInstructions.Count > 0, Environment.NewLine, stacktrace.OriginalMethod.CSharpILMixedInstructions.Select(x => x.EscapeGenerics()).ToArray()).Append("
") - .AppendIf(stacktrace.OriginalMethod.CSharpInstructions.Count > 0, $"
+ C#:
")
-                        .AppendJoinIf(stacktrace.OriginalMethod.CSharpInstructions.Count > 0, Environment.NewLine, stacktrace.OriginalMethod.CSharpInstructions.Select(x => x.EscapeGenerics()).ToArray()).Append("
") + .AppendIf(stacktrace.OriginalMethod.ILInstructions.Count > 0, sb => sb + .Append($"
+ IL:
")
+                            .AppendJoin(Environment.NewLine, stacktrace.OriginalMethod.ILInstructions.Select(x => x.EscapeGenerics()))
+                            .Append("
")) + .AppendIf(stacktrace.OriginalMethod.CSharpILMixedInstructions.Count > 0, sb => sb + .Append($"
+ IL with C#:
")
+                            .AppendJoin(Environment.NewLine, stacktrace.OriginalMethod.CSharpILMixedInstructions.Select(x => x.EscapeGenerics()))
+                            .Append("
")) + .AppendIf(stacktrace.OriginalMethod.CSharpInstructions.Count > 0, sb => sb + .Append($"
+ C#:
")
+                            .AppendJoin(Environment.NewLine, stacktrace.OriginalMethod.CSharpInstructions.Select(x => x.EscapeGenerics()))
+                            .Append("
")) .Append("") .Append(""); } diff --git a/src/BUTR.CrashReport.Bannerlord.Source/CrashReportShared.cs b/src/BUTR.CrashReport.Bannerlord.Source/CrashReportShared.cs index 791f25d..5a36563 100644 --- a/src/BUTR.CrashReport.Bannerlord.Source/CrashReportShared.cs +++ b/src/BUTR.CrashReport.Bannerlord.Source/CrashReportShared.cs @@ -49,7 +49,6 @@ namespace BUTR.CrashReport.Bannerlord using global::System.Collections.Generic; using global::System.Linq; - using global::System.Reflection; internal static class CrashReportShared { diff --git a/src/BUTR.CrashReport.Bannerlord.Source/ImmutableArrayExtensions.cs b/src/BUTR.CrashReport.Bannerlord.Source/ImmutableArrayExtensions.cs deleted file mode 100644 index 9614fa2..0000000 --- a/src/BUTR.CrashReport.Bannerlord.Source/ImmutableArrayExtensions.cs +++ /dev/null @@ -1,59 +0,0 @@ -// -// This code file has automatically been added by the "BUTR.CrashReport.Bannerlord.Source" NuGet package (https://www.nuget.org/packages/BUTR.CrashReport.Bannerlord.Source). -// Please see https://github.com/BUTR/BUTR.CrashReport for more information. -// -// IMPORTANT: -// DO NOT DELETE THIS FILE if you are using a "packages.config" file to manage your NuGet references. -// Consider migrating to PackageReferences instead: -// https://docs.microsoft.com/en-us/nuget/consume-packages/migrate-packages-config-to-package-reference -// Migrating brings the following benefits: -// * The "BUTR.CrashReport.Bannerlord.Source" folder and the "ImmutableArrayExtensions.cs" file don't appear in your project. -// * The added file is immutable and can therefore not be modified by coincidence. -// * Updating/Uninstalling the package will work flawlessly. -// - -#region License -// MIT License -// -// Copyright (c) Bannerlord's Unofficial Tools & Resources -// -// 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. -#endregion - -#if !BUTRCRASHREPORT_DISABLE -#nullable enable -#if !BUTRCRASHREPORT_ENABLEWARNINGS -#pragma warning disable -#endif - -namespace BUTR.CrashReport.Bannerlord -{ - using global::System.Collections.Immutable; - using global::System.Runtime.CompilerServices; - - public static class ImmutableArrayExtensions - { - public static T[] AsArray(this ImmutableArray immutableArray) => Unsafe.As, T[]>(ref immutableArray); - public static ImmutableArray AsImmutableArray(this T[] array) => Unsafe.As>(ref array); - } -} - -#pragma warning restore -#nullable restore -#endif // BUTRCRASHREPORT_DISABLE \ No newline at end of file diff --git a/src/BUTR.CrashReport.Bannerlord.Source/StringBuilderExtensions.cs b/src/BUTR.CrashReport.Bannerlord.Source/StringBuilderExtensions.cs index 2fac09b..eebdfdd 100644 --- a/src/BUTR.CrashReport.Bannerlord.Source/StringBuilderExtensions.cs +++ b/src/BUTR.CrashReport.Bannerlord.Source/StringBuilderExtensions.cs @@ -53,6 +53,8 @@ internal static class StringBuilderExtensions { public static string EscapeGenerics(this string str) => str.Replace("<", "<").Replace(">", ">"); + public static StringBuilder AppendIf(this StringBuilder builder, Func lambda) => lambda(builder); + public static StringBuilder AppendJoin(this StringBuilder builder, string separator, IEnumerable lines) => AppendJoinIf(builder, true, separator, lines.ToArray()); public static StringBuilder AppendJoin(this StringBuilder builder, char separator, IEnumerable lines) => AppendJoinIf(builder, true, separator, lines.ToArray()); public static StringBuilder AppendJoinIf(this StringBuilder builder, bool condition, string separator, IReadOnlyList lines)