add immutable stack trace to cache stack info

This commit is contained in:
Jesse Plamondon-Willard 2022-04-19 19:11:58 -04:00
parent 889004f1eb
commit e6c696fa6b
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
3 changed files with 57 additions and 4 deletions

View File

@ -63,7 +63,7 @@ namespace StardewModdingAPI.Framework.Deprecations
return;
// queue warning
var stack = new StackTrace(skipFrames: 1); // skip this method
ImmutableStackTrace stack = ImmutableStackTrace.Get(skipFrames: 1);
this.QueuedWarnings.Add(new DeprecationWarning(source, nounPhrase, version, severity, stack));
}
@ -134,7 +134,7 @@ namespace StardewModdingAPI.Framework.Deprecations
/// <summary>Get the simplest stack trace which shows where in the mod the deprecated code was called from.</summary>
/// <param name="stack">The stack trace.</param>
/// <param name="mod">The mod for which to show a stack trace.</param>
private string GetSimplifiedStackTrace(StackTrace stack, IModMetadata? mod)
private string GetSimplifiedStackTrace(ImmutableStackTrace stack, IModMetadata? mod)
{
// unknown mod, show entire stack trace
if (mod == null)

View File

@ -24,7 +24,7 @@ namespace StardewModdingAPI.Framework.Deprecations
public DeprecationLevel Level { get; }
/// <summary>The stack trace when the deprecation warning was raised.</summary>
public StackTrace StackTrace { get; }
public ImmutableStackTrace StackTrace { get; }
/*********
@ -36,7 +36,7 @@ namespace StardewModdingAPI.Framework.Deprecations
/// <param name="version">The SMAPI version which deprecated it.</param>
/// <param name="level">The deprecation level for the affected code.</param>
/// <param name="stackTrace">The stack trace when the deprecation warning was raised.</param>
public DeprecationWarning(IModMetadata? mod, string nounPhrase, string version, DeprecationLevel level, StackTrace stackTrace)
public DeprecationWarning(IModMetadata? mod, string nounPhrase, string version, DeprecationLevel level, ImmutableStackTrace stackTrace)
{
this.Mod = mod;
this.NounPhrase = nounPhrase;

View File

@ -0,0 +1,53 @@
using System.Diagnostics;
namespace StardewModdingAPI.Framework.Deprecations
{
/// <summary>An immutable stack trace that caches its values.</summary>
internal class ImmutableStackTrace
{
/*********
** Fields
*********/
/// <summary>The underlying stack trace.</summary>
private readonly StackTrace StackTrace;
/// <summary>The individual method calls in the stack trace.</summary>
private StackFrame[]? Frames;
/// <summary>The string representation of the stack trace.</summary>
private string? StringForm;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="stackTrace">The underlying stack trace.</param>
public ImmutableStackTrace(StackTrace stackTrace)
{
this.StackTrace = stackTrace;
}
/// <summary>Get the underlying frames.</summary>
/// <remarks>This is a reference to the underlying stack frames, so this array should not be edited.</remarks>
public StackFrame[] GetFrames()
{
return this.Frames ??= this.StackTrace.GetFrames();
}
/// <inheritdoc />
public override string ToString()
{
return this.StringForm ??= this.StackTrace.ToString();
}
/// <summary>Get the current stack trace.</summary>
/// <param name="skipFrames">The number of frames up the stack from which to start the trace.</param>
public static ImmutableStackTrace Get(int skipFrames = 0)
{
return new ImmutableStackTrace(
new StackTrace(skipFrames: skipFrames + 1) // also skip this method
);
}
}
}