Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make all interpolated string handlers pass by ref #57536

Merged
merged 2 commits into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,30 @@ public void Asserts_Interpolation()
bool shouldAppend;

message = new Debug.AssertInterpolatedStringHandler(0, 0, true, out shouldAppend);
VerifyLogged(() => Debug.Assert(true, message), "");
VerifyLogged(() => Debug.Assert(true, ref message), "");

message = new Debug.AssertInterpolatedStringHandler(0, 0, true, out shouldAppend);
detailedMessage = new Debug.AssertInterpolatedStringHandler(0, 0, true, out shouldAppend);
VerifyLogged(() => Debug.Assert(true, message, detailedMessage), "");
VerifyLogged(() => Debug.Assert(true, ref message, ref detailedMessage), "");

message = new Debug.AssertInterpolatedStringHandler(0, 0, false, out shouldAppend);
message.AppendLiteral("assert passed");
VerifyAssert(() => Debug.Assert(false, message), "assert passed");
message.AppendLiteral("uh oh");
VerifyAssert(() => Debug.Assert(false, ref message), "uh oh");

message = new Debug.AssertInterpolatedStringHandler(0, 0, false, out shouldAppend);
message.AppendLiteral("assert passed");
message.AppendLiteral("uh oh");
detailedMessage = new Debug.AssertInterpolatedStringHandler(0, 0, false, out shouldAppend);
detailedMessage.AppendLiteral("nothing is wrong");
VerifyAssert(() => Debug.Assert(false, message, detailedMessage), "assert passed", "nothing is wrong");
detailedMessage.AppendLiteral("something went wrong");
VerifyAssert(() => Debug.Assert(false, ref message, ref detailedMessage), "uh oh", "something went wrong");
}

[Fact]
public void Asserts_Interpolation_Syntax()
{
VerifyLogged(() => Debug.Assert(true, $"you won't see this {EmptyToString.Instance}"), "");
VerifyLogged(() => Debug.Assert(true, $"you won't see this {EmptyToString.Instance}", $"you won't see this {EmptyToString.Instance}"), "");
VerifyAssert(() => Debug.Assert(false, $"uh oh{EmptyToString.Instance}"), "uh oh");
VerifyAssert(() => Debug.Assert(false, $"uh oh{EmptyToString.Instance}", $"something went wrong{EmptyToString.Instance}"), "uh oh", "something went wrong");
}

[Fact]
Expand All @@ -41,21 +50,31 @@ public void WriteIf_Interpolation()

handler = new Debug.WriteIfInterpolatedStringHandler(0, 0, true, out shouldAppend);
handler.AppendLiteral("logged");
VerifyLogged(() => Debug.WriteIf(true, handler), "logged");
VerifyLogged(() => Debug.WriteIf(true, ref handler), "logged");

handler = new Debug.WriteIfInterpolatedStringHandler(0, 0, false, out shouldAppend);
VerifyLogged(() => Debug.WriteIf(false, handler), "");
VerifyLogged(() => Debug.WriteIf(false, ref handler), "");

handler = new Debug.WriteIfInterpolatedStringHandler(0, 0, true, out shouldAppend);
handler.AppendLiteral("logged");
VerifyLogged(() => Debug.WriteIf(true, handler, "category"), "category: logged");
VerifyLogged(() => Debug.WriteIf(true, ref handler, "category"), "category: logged");

handler = new Debug.WriteIfInterpolatedStringHandler(0, 0, false, out shouldAppend);
VerifyLogged(() => Debug.WriteIf(false, handler, "category"), "");
VerifyLogged(() => Debug.WriteIf(false, ref handler, "category"), "");

GoToNextLine();
}

[Fact]
public void WriteIf_Interpolation_Syntax()
{
VerifyLogged(() => Debug.WriteIf(true, $"{EmptyToString.Instance}logged"), "logged");
VerifyLogged(() => Debug.WriteIf(false, $"{EmptyToString.Instance}logged"), "");
VerifyLogged(() => Debug.WriteIf(true, $"{EmptyToString.Instance}logged", "category"), "category: logged");
VerifyLogged(() => Debug.WriteIf(false, $"{EmptyToString.Instance}logged", "category"), "");
GoToNextLine();
}

[Fact]
public void WriteLineIf_Interpolation()
{
Expand All @@ -64,17 +83,27 @@ public void WriteLineIf_Interpolation()

handler = new Debug.WriteIfInterpolatedStringHandler(0, 0, true, out shouldAppend);
handler.AppendLiteral("logged");
VerifyLogged(() => Debug.WriteLineIf(true, handler), "logged" + Environment.NewLine);
VerifyLogged(() => Debug.WriteLineIf(true, ref handler), "logged" + Environment.NewLine);

handler = new Debug.WriteIfInterpolatedStringHandler(0, 0, false, out shouldAppend);
VerifyLogged(() => Debug.WriteLineIf(false, handler), "");
VerifyLogged(() => Debug.WriteLineIf(false, ref handler), "");

handler = new Debug.WriteIfInterpolatedStringHandler(0, 0, true, out shouldAppend);
handler.AppendLiteral("logged");
VerifyLogged(() => Debug.WriteLineIf(true, handler, "category"), "category: logged" + Environment.NewLine);
VerifyLogged(() => Debug.WriteLineIf(true, ref handler, "category"), "category: logged" + Environment.NewLine);

handler = new Debug.WriteIfInterpolatedStringHandler(0, 0, false, out shouldAppend);
VerifyLogged(() => Debug.WriteLineIf(false, handler, "category"), "");
VerifyLogged(() => Debug.WriteLineIf(false, ref handler, "category"), "");
}

[Fact]
public void WriteLineIf_Interpolation_Syntax()
{
VerifyLogged(() => Debug.WriteLineIf(true, $"{EmptyToString.Instance}logged"), "logged" + Environment.NewLine);
VerifyLogged(() => Debug.WriteLineIf(false, $"{EmptyToString.Instance}logged"), "");
VerifyLogged(() => Debug.WriteLineIf(true, $"{EmptyToString.Instance}logged", "category"), "category: logged" + Environment.NewLine);
VerifyLogged(() => Debug.WriteLineIf(false, $"{EmptyToString.Instance}logged", "category"), "");
GoToNextLine();
}

[Theory]
Expand Down Expand Up @@ -131,7 +160,7 @@ public void DebugHandler_AppendOverloads_MatchStringBuilderHandler()
actual.AppendFormatted((object)DayOfWeek.Monday, 42, null);
expected.AppendFormatted((object)DayOfWeek.Monday, 42, null);

VerifyAssert(() => Debug.Assert(false, actual), sb.ToString());
VerifyAssert(() => Debug.Assert(false, ref actual), sb.ToString());
}

[Fact]
Expand Down Expand Up @@ -174,7 +203,13 @@ public void WriteIfHandler_AppendOverloads_MatchStringBuilderHandler()
actual.AppendFormatted((object)DayOfWeek.Monday, 42, null);
expected.AppendFormatted((object)DayOfWeek.Monday, 42, null);

VerifyLogged(() => Debug.WriteIf(true, actual), sb.ToString());
VerifyLogged(() => Debug.WriteIf(true, ref actual), sb.ToString());
}

private sealed class EmptyToString
{
public static EmptyToString Instance { get; } = new EmptyToString();
public override string ToString() => "";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ public static void Assert([DoesNotReturnIf(false)] bool condition, string? messa
Assert(condition, message, string.Empty);

[Conditional("DEBUG")]
public static void Assert([DoesNotReturnIf(false)] bool condition, [InterpolatedStringHandlerArgument("condition")] AssertInterpolatedStringHandler message) =>
Assert(condition, message.ToString());
public static void Assert([DoesNotReturnIf(false)] bool condition, [InterpolatedStringHandlerArgument("condition")] ref AssertInterpolatedStringHandler message) =>
Assert(condition, message.ToStringAndClear());

[Conditional("DEBUG")]
public static void Assert([DoesNotReturnIf(false)] bool condition, string? message, string? detailMessage)
Expand All @@ -100,8 +100,8 @@ public static void Assert([DoesNotReturnIf(false)] bool condition, string? messa
}

[Conditional("DEBUG")]
public static void Assert([DoesNotReturnIf(false)] bool condition, [InterpolatedStringHandlerArgument("condition")] AssertInterpolatedStringHandler message, [InterpolatedStringHandlerArgument("condition")] AssertInterpolatedStringHandler detailMessage) =>
Assert(condition, message.ToString(), detailMessage.ToString());
public static void Assert([DoesNotReturnIf(false)] bool condition, [InterpolatedStringHandlerArgument("condition")] ref AssertInterpolatedStringHandler message, [InterpolatedStringHandlerArgument("condition")] ref AssertInterpolatedStringHandler detailMessage) =>
Assert(condition, message.ToStringAndClear(), detailMessage.ToStringAndClear());

[Conditional("DEBUG")]
public static void Assert([DoesNotReturnIf(false)] bool condition, string? message, string detailMessageFormat, params object?[] args) =>
Expand Down Expand Up @@ -197,8 +197,8 @@ public static void WriteIf(bool condition, string? message)
}

[Conditional("DEBUG")]
public static void WriteIf(bool condition, [InterpolatedStringHandlerArgument("condition")] WriteIfInterpolatedStringHandler message) =>
WriteIf(condition, message.ToString());
public static void WriteIf(bool condition, [InterpolatedStringHandlerArgument("condition")] ref WriteIfInterpolatedStringHandler message) =>
WriteIf(condition, message.ToStringAndClear());

[Conditional("DEBUG")]
public static void WriteIf(bool condition, object? value)
Expand All @@ -219,8 +219,8 @@ public static void WriteIf(bool condition, string? message, string? category)
}

[Conditional("DEBUG")]
public static void WriteIf(bool condition, [InterpolatedStringHandlerArgument("condition")] WriteIfInterpolatedStringHandler message, string? category) =>
WriteIf(condition, message.ToString(), category);
public static void WriteIf(bool condition, [InterpolatedStringHandlerArgument("condition")] ref WriteIfInterpolatedStringHandler message, string? category) =>
WriteIf(condition, message.ToStringAndClear(), category);

[Conditional("DEBUG")]
public static void WriteIf(bool condition, object? value, string? category)
Expand Down Expand Up @@ -259,8 +259,8 @@ public static void WriteLineIf(bool condition, string? message)
}

[Conditional("DEBUG")]
public static void WriteLineIf(bool condition, [InterpolatedStringHandlerArgument("condition")] WriteIfInterpolatedStringHandler message) =>
WriteLineIf(condition, message.ToString());
public static void WriteLineIf(bool condition, [InterpolatedStringHandlerArgument("condition")] ref WriteIfInterpolatedStringHandler message) =>
WriteLineIf(condition, message.ToStringAndClear());

[Conditional("DEBUG")]
public static void WriteLineIf(bool condition, string? message, string? category)
Expand All @@ -272,8 +272,8 @@ public static void WriteLineIf(bool condition, string? message, string? category
}

[Conditional("DEBUG")]
public static void WriteLineIf(bool condition, [InterpolatedStringHandlerArgument("condition")] WriteIfInterpolatedStringHandler message, string? category) =>
WriteLineIf(condition, message.ToString(), category);
public static void WriteLineIf(bool condition, [InterpolatedStringHandlerArgument("condition")] ref WriteIfInterpolatedStringHandler message, string? category) =>
WriteLineIf(condition, message.ToStringAndClear(), category);

/// <summary>Provides an interpolated string handler for <see cref="Debug.Assert"/> that only performs formatting if the assert fails.</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
Expand All @@ -298,16 +298,21 @@ public AssertInterpolatedStringHandler(int literalLength, int formattedCount, bo
}
else
{
_stringBuilderHandler = new StringBuilder.AppendInterpolatedStringHandler(literalLength, formattedCount, new StringBuilder(DefaultInterpolatedStringHandler.GetDefaultLength(literalLength, formattedCount)));
// Only used when failing an assert. Additional allocation here doesn't matter; just create a new StringBuilder.
_stringBuilderHandler = new StringBuilder.AppendInterpolatedStringHandler(literalLength, formattedCount, new StringBuilder());
shouldAppend = true;
}
}

/// <summary>Extracts the built string from the handler.</summary>
internal new string ToString() =>
_stringBuilderHandler._stringBuilder is StringBuilder sb ?
internal string ToStringAndClear()
{
string s = _stringBuilderHandler._stringBuilder is StringBuilder sb ?
sb.ToString() :
string.Empty;
_stringBuilderHandler = default;
return s;
}

/// <summary>Writes the specified string to the handler.</summary>
/// <param name="value">The string to write.</param>
Expand Down Expand Up @@ -378,7 +383,9 @@ public WriteIfInterpolatedStringHandler(int literalLength, int formattedCount, b
{
if (condition)
{
_stringBuilderHandler = new StringBuilder.AppendInterpolatedStringHandler(literalLength, formattedCount, new StringBuilder(DefaultInterpolatedStringHandler.GetDefaultLength(literalLength, formattedCount)));
// Only used in debug, but could be used on non-failure code paths, so use a cached builder.
_stringBuilderHandler = new StringBuilder.AppendInterpolatedStringHandler(literalLength, formattedCount,
StringBuilderCache.Acquire(DefaultInterpolatedStringHandler.GetDefaultLength(literalLength, formattedCount)));
shouldAppend = true;
}
else
Expand All @@ -389,10 +396,14 @@ public WriteIfInterpolatedStringHandler(int literalLength, int formattedCount, b
}

/// <summary>Extracts the built string from the handler.</summary>
internal new string ToString() =>
_stringBuilderHandler._stringBuilder is StringBuilder sb ?
sb.ToString() :
internal string ToStringAndClear()
{
string s = _stringBuilderHandler._stringBuilder is StringBuilder sb ?
StringBuilderCache.GetStringAndRelease(sb) :
stephentoub marked this conversation as resolved.
Show resolved Hide resolved
string.Empty;
_stringBuilderHandler = default;
return s;
}

/// <summary>Writes the specified string to the handler.</summary>
/// <param name="value">The string to write.</param>
Expand Down
Loading