diff options
-rw-r--r-- | src/SMAPI/Framework/Deprecations/DeprecationManager.cs | 4 | ||||
-rw-r--r-- | src/SMAPI/Framework/Deprecations/DeprecationWarning.cs | 4 | ||||
-rw-r--r-- | src/SMAPI/Framework/Deprecations/ImmutableStackTrace.cs | 53 |
3 files changed, 57 insertions, 4 deletions
diff --git a/src/SMAPI/Framework/Deprecations/DeprecationManager.cs b/src/SMAPI/Framework/Deprecations/DeprecationManager.cs index da17ce7e..84ce2132 100644 --- a/src/SMAPI/Framework/Deprecations/DeprecationManager.cs +++ b/src/SMAPI/Framework/Deprecations/DeprecationManager.cs @@ -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) diff --git a/src/SMAPI/Framework/Deprecations/DeprecationWarning.cs b/src/SMAPI/Framework/Deprecations/DeprecationWarning.cs index 38062daf..e00881b1 100644 --- a/src/SMAPI/Framework/Deprecations/DeprecationWarning.cs +++ b/src/SMAPI/Framework/Deprecations/DeprecationWarning.cs @@ -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; diff --git a/src/SMAPI/Framework/Deprecations/ImmutableStackTrace.cs b/src/SMAPI/Framework/Deprecations/ImmutableStackTrace.cs new file mode 100644 index 00000000..059d871c --- /dev/null +++ b/src/SMAPI/Framework/Deprecations/ImmutableStackTrace.cs @@ -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 + ); + } + } +} |