summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-04-19 19:11:58 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-04-19 19:11:58 -0400
commite6c696fa6b0bfe5ef013e1179765ce1dcb071c38 (patch)
tree6ebd183fa44bac23f14f21fdb9faa6fd56a7b61f
parent889004f1eba31aa3a5069e1dcbe79896d05720b0 (diff)
downloadSMAPI-e6c696fa6b0bfe5ef013e1179765ce1dcb071c38.tar.gz
SMAPI-e6c696fa6b0bfe5ef013e1179765ce1dcb071c38.tar.bz2
SMAPI-e6c696fa6b0bfe5ef013e1179765ce1dcb071c38.zip
add immutable stack trace to cache stack info
-rw-r--r--src/SMAPI/Framework/Deprecations/DeprecationManager.cs4
-rw-r--r--src/SMAPI/Framework/Deprecations/DeprecationWarning.cs4
-rw-r--r--src/SMAPI/Framework/Deprecations/ImmutableStackTrace.cs53
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
+ );
+ }
+ }
+}