85 lines
2.9 KiB
C#
85 lines
2.9 KiB
C#
// Copyright (c) Ben A Adams. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
namespace DTLib.Ben.Demystifier;
|
|
|
|
public partial class EnhancedStackTrace : StackTrace, IEnumerable<EnhancedStackFrame>
|
|
{
|
|
private readonly List<EnhancedStackFrame> _frames;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the System.Diagnostics.StackTrace class using the
|
|
/// provided exception object
|
|
/// </summary>
|
|
public EnhancedStackTrace(Exception e)
|
|
{
|
|
_frames = GetFrames(new StackTrace(e, true));
|
|
}
|
|
|
|
public EnhancedStackTrace(StackTrace stackTrace)
|
|
{
|
|
_frames = GetFrames(stackTrace);
|
|
}
|
|
|
|
/// <returns>The number of frames in the stack trace.</returns>
|
|
public override int FrameCount => _frames.Count;
|
|
|
|
IEnumerator<EnhancedStackFrame> IEnumerable<EnhancedStackFrame>.GetEnumerator() => _frames.GetEnumerator();
|
|
|
|
IEnumerator IEnumerable.GetEnumerator() => _frames.GetEnumerator();
|
|
|
|
public static EnhancedStackTrace Current()
|
|
=> new EnhancedStackTrace(new StackTrace(1 /* skip this one frame */, true));
|
|
|
|
/// <param name="index">The index of the stack frame requested.</param>
|
|
/// <returns>The specified stack frame.</returns>
|
|
public override StackFrame GetFrame(int index) => _frames[index];
|
|
|
|
/// <returns>a copy of all stack frames in the current stack trace. </returns>
|
|
public override StackFrame[] GetFrames() => _frames.ToArray();
|
|
|
|
/// <summary>
|
|
/// Builds a readable representation of the stack trace.
|
|
/// </summary>
|
|
public override string ToString()
|
|
{
|
|
if (_frames.Count == 0) return "";
|
|
|
|
var sb = new StringBuilder();
|
|
AppendTo(sb);
|
|
return sb.ToString();
|
|
}
|
|
|
|
public void AppendTo(StringBuilder sb)
|
|
{
|
|
var count = _frames.Count;
|
|
for (var i = 0; i < count; i++)
|
|
{
|
|
if (i > 0) sb.Append(Environment.NewLine);
|
|
var frame = _frames[i];
|
|
sb.Append(" at ");
|
|
frame.MethodInfo.AppendTo(sb);
|
|
|
|
var fileName = frame.GetFileName();
|
|
if (!string.IsNullOrEmpty(fileName))
|
|
sb.Append(" in ").Append(TryGetFullPath(fileName!));
|
|
|
|
var lineNo = frame.GetFileLineNumber();
|
|
if (lineNo != 0)
|
|
sb.Append(':').Append(lineNo);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to convert a given <paramref name="filePath" /> to a full path.
|
|
/// Returns original value if the conversion isn't possible or a given path is relative.
|
|
/// </summary>
|
|
public static string TryGetFullPath(string filePath)
|
|
{
|
|
if (Uri.TryCreate(filePath, UriKind.Absolute, out var uri) && uri.IsFile)
|
|
return Uri.UnescapeDataString(uri.AbsolutePath);
|
|
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
|
return filePath.Replace('/', '\\');
|
|
return filePath;
|
|
}
|
|
} |