DebugTools.Assert(bool, string) does not allocate if string is a format string anymore.

This commit is contained in:
Pieter-Jan Briers
2022-05-10 00:59:36 +02:00
parent 3ae4bb03f5
commit 15932fb9aa
2 changed files with 68 additions and 0 deletions

View File

@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using JetBrains.Annotations;
namespace Robust.Shared.Utility
@@ -46,6 +47,21 @@ namespace Robust.Shared.Utility
throw new DebugAssertException(message);
}
/// <summary>
/// An assertion that will <see langword="throw" /> an exception if the
/// <paramref name="condition" /> is not true.
/// </summary>
/// <param name="condition">Condition that must be true.</param>
/// <param name="message">Exception message.</param>
[Conditional("DEBUG")]
[AssertionMethod]
public static void Assert([AssertionCondition(AssertionConditionType.IS_TRUE)]
bool condition, [InterpolatedStringHandlerArgument("condition")] ref AssertInterpolatedStringHandler message)
{
if (!condition)
throw new DebugAssertException(message.ToStringAndClear());
}
/// <summary>
/// An assertion that will <see langword="throw" /> an exception if the
/// <paramref name="arg" /> is <see langword="null" />.
@@ -86,6 +102,32 @@ namespace Robust.Shared.Utility
{
Debugger.Break();
}
[InterpolatedStringHandler]
public ref struct AssertInterpolatedStringHandler
{
private DefaultInterpolatedStringHandler _handler;
public AssertInterpolatedStringHandler(int literalLength, int formattedCount, bool condition, out bool shouldAppend)
{
if (condition)
{
shouldAppend = false;
_handler = default;
}
else
{
shouldAppend = true;
_handler = new DefaultInterpolatedStringHandler(literalLength, formattedCount);
}
}
public string ToStringAndClear() => _handler.ToStringAndClear();
public override string ToString() => _handler.ToString();
public void AppendLiteral(string value) => _handler.AppendLiteral(value);
public void AppendFormatted<T>(T value) => _handler.AppendFormatted(value);
public void AppendFormatted<T>(T value, string? format) => _handler.AppendFormatted(value, format);
}
}
[Virtual]

View File

@@ -0,0 +1,26 @@
using System;
using System.Diagnostics;
using NUnit.Framework;
using Robust.Shared.Utility;
namespace Robust.UnitTesting.Shared.Utility;
[TestFixture]
[Parallelizable(ParallelScope.All)]
[TestOf(typeof(DebugTools))]
public sealed class DebugTools_Test
{
[Test]
[TestCase(true, 5)]
[Conditional("DEBUG")]
public void TestAssertFormatNoAlloc(bool check, int val)
{
var allocA = GC.GetAllocatedBytesForCurrentThread();
DebugTools.Assert(check, $"Oops: {val}");
var allocB = GC.GetAllocatedBytesForCurrentThread();
Assert.That(allocB, Is.EqualTo(allocA));
}
}