Apply string interpolation optimizations to netstandard2.0 as well

This commit is contained in:
Andrew Arnott 2023-07-27 13:28:22 -06:00
Родитель 759ebbb427
Коммит 8bf09314f7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: F33A420C60ED9C6F
12 изменённых файлов: 112 добавлений и 51 удалений

Просмотреть файл

@ -163,8 +163,6 @@ public static partial class Assumes
}
}
#if NET6_0_OR_GREATER
/// <summary>
/// Throws an public exception if a condition evaluates to true.
/// </summary>
@ -178,8 +176,6 @@ public static partial class Assumes
}
}
#endif
/// <summary>
/// Throws an public exception if a condition evaluates to false.
/// </summary>
@ -219,8 +215,6 @@ public static partial class Assumes
}
}
#if NET6_0_OR_GREATER
/// <summary>
/// Throws an public exception if a condition evaluates to false.
/// </summary>
@ -234,8 +228,6 @@ public static partial class Assumes
}
}
#endif
/// <summary>
/// Unconditionally throws an <see cref="InternalErrorException"/>.
/// </summary>

Просмотреть файл

@ -1,8 +1,9 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#if !NET5_0_OR_GREATER
#if !NET6_0_OR_GREATER
#pragma warning disable SA1402 // File may only contain a single type
#pragma warning disable SA1649 // File name should match first type name
#pragma warning disable SA1600 // Elements should be documented
@ -15,6 +16,24 @@ namespace System.Runtime.CompilerServices
{
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
internal sealed class InterpolatedStringHandlerAttribute : Attribute
{
public InterpolatedStringHandlerAttribute()
{
}
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
{
public InterpolatedStringHandlerArgumentAttribute(string argument) => this.Arguments = new string[] { argument };
public InterpolatedStringHandlerArgumentAttribute(params string[] arguments) => this.Arguments = arguments;
public string[] Arguments { get; }
}
}
#endif

Просмотреть файл

@ -91,8 +91,6 @@ public static class Report
}
}
#if NET6_0_OR_GREATER
/// <summary>
/// Reports an error if a condition does not evaluate to true.
/// </summary>
@ -105,8 +103,6 @@ public static class Report
}
}
#endif
/// <summary>
/// Reports a certain failure.
/// </summary>

Просмотреть файл

@ -418,8 +418,6 @@ public static class Requires
}
}
#if NET6_0_OR_GREATER
/// <summary>
/// Throws an <see cref="ArgumentException"/> if a condition does not evaluate to true.
/// </summary>
@ -432,8 +430,6 @@ public static class Requires
}
}
#endif
/// <summary>
/// Throws an <see cref="ArgumentException"/> if a condition does not evaluate to true.
/// </summary>

Просмотреть файл

@ -1,8 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#if NET6_0_OR_GREATER
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
@ -14,9 +12,12 @@ namespace Microsoft;
[InterpolatedStringHandler]
public ref struct ValidationInterpolatedStringHandler
{
private StringBuilder? stringBuilder;
#if NET6_0_OR_GREATER
/// <summary>The handler we use to perform the formatting.</summary>
private StringBuilder.AppendInterpolatedStringHandler stringBuilderHandler;
private StringBuilder? stringBuilder;
#endif
/// <summary>Initializes a new instance of the <see cref="ValidationInterpolatedStringHandler"/> struct.</summary>
/// <param name="literalLength">The number of constant characters outside of interpolation expressions in the interpolated string.</param>
@ -33,11 +34,17 @@ public ref struct ValidationInterpolatedStringHandler
else
{
// Only used when failing an assert. Additional allocation here doesn't matter; just create a new StringBuilder.
#if NET6_0_OR_GREATER
this.stringBuilderHandler = new StringBuilder.AppendInterpolatedStringHandler(literalLength, formattedCount, this.stringBuilder = new StringBuilder());
#else
this.stringBuilder = new();
#endif
shouldAppend = true;
}
}
#if NET6_0_OR_GREATER
/// <summary>Writes the specified string to the handler.</summary>
/// <param name="value">The string to write.</param>
public void AppendLiteral(string value) => this.stringBuilderHandler.AppendLiteral(value);
@ -92,15 +99,47 @@ public ref struct ValidationInterpolatedStringHandler
/// <param name="format">The format string.</param>
public void AppendFormatted(object? value, int alignment = 0, string? format = null) => this.stringBuilderHandler.AppendFormatted(value, alignment, format);
#else
/// <summary>Writes the specified string to the handler.</summary>
/// <param name="value">The string to write.</param>
public void AppendLiteral(string value) => this.stringBuilder!.Append(value);
/// <summary>Writes the specified value to the handler.</summary>
/// <param name="value">The value to write.</param>
/// <typeparam name="T">The type of the value to write.</typeparam>
public void AppendFormatted<T>(T value) => this.stringBuilder!.Append(value);
/// <summary>Writes the specified value to the handler.</summary>
/// <param name="value">The value to write.</param>
/// <param name="alignment">Minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value.</param>
/// <param name="format">The format string.</param>
/// <typeparam name="T">The type of the value to write.</typeparam>
public void AppendFormatted<T>(T value, int alignment = 0, string? format = null)
{
string result = value is IFormattable ? ((IFormattable)value).ToString(format, null) : (value?.ToString() ?? string.Empty);
bool left = alignment < 0;
alignment = Math.Abs(alignment);
if (result.Length < alignment)
{
string padding = new string(' ', alignment - result.Length);
result = left ? result + padding : padding + result;
}
this.stringBuilder!.Append(result);
}
#endif
/// <summary>Extracts the built string from the handler.</summary>
/// <returns>The formatted string.</returns>
internal string ToStringAndClear()
{
string s = this.stringBuilder?.ToString() ?? string.Empty;
this.stringBuilder = null;
#if NET6_0_OR_GREATER
this.stringBuilderHandler = default;
#endif
return s;
}
}
#endif

Просмотреть файл

@ -1,8 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#if NET6_0_OR_GREATER
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
@ -14,9 +12,12 @@ namespace Microsoft;
[InterpolatedStringHandler]
public ref struct ValidationInterpolatedStringHandlerInvertedCondition
{
private StringBuilder? stringBuilder;
#if NET6_0_OR_GREATER
/// <summary>The handler we use to perform the formatting.</summary>
private StringBuilder.AppendInterpolatedStringHandler stringBuilderHandler;
private StringBuilder? stringBuilder;
#endif
/// <summary>Initializes a new instance of the <see cref="ValidationInterpolatedStringHandlerInvertedCondition"/> struct.</summary>
/// <param name="literalLength">The number of constant characters outside of interpolation expressions in the interpolated string.</param>
@ -33,11 +34,17 @@ public ref struct ValidationInterpolatedStringHandlerInvertedCondition
else
{
// Only used when failing an assert. Additional allocation here doesn't matter; just create a new StringBuilder.
#if NET6_0_OR_GREATER
this.stringBuilderHandler = new StringBuilder.AppendInterpolatedStringHandler(literalLength, formattedCount, this.stringBuilder = new StringBuilder());
#else
this.stringBuilder = new();
#endif
shouldAppend = true;
}
}
#if NET6_0_OR_GREATER
/// <summary>Writes the specified string to the handler.</summary>
/// <param name="value">The string to write.</param>
public void AppendLiteral(string value) => this.stringBuilderHandler.AppendLiteral(value);
@ -92,15 +99,47 @@ public ref struct ValidationInterpolatedStringHandlerInvertedCondition
/// <param name="format">The format string.</param>
public void AppendFormatted(object? value, int alignment = 0, string? format = null) => this.stringBuilderHandler.AppendFormatted(value, alignment, format);
#else
/// <summary>Writes the specified string to the handler.</summary>
/// <param name="value">The string to write.</param>
public void AppendLiteral(string value) => this.stringBuilder!.Append(value);
/// <summary>Writes the specified value to the handler.</summary>
/// <param name="value">The value to write.</param>
/// <typeparam name="T">The type of the value to write.</typeparam>
public void AppendFormatted<T>(T value) => this.stringBuilder!.Append(value);
/// <summary>Writes the specified value to the handler.</summary>
/// <param name="value">The value to write.</param>
/// <param name="alignment">Minimum number of characters that should be written for this value. If the value is negative, it indicates left-aligned and the required minimum is the absolute value.</param>
/// <param name="format">The format string.</param>
/// <typeparam name="T">The type of the value to write.</typeparam>
public void AppendFormatted<T>(T value, int alignment = 0, string? format = null)
{
string result = value is IFormattable ? ((IFormattable)value).ToString(format, null) : (value?.ToString() ?? string.Empty);
bool left = alignment < 0;
alignment = Math.Abs(alignment);
if (result.Length < alignment)
{
string padding = new string(' ', alignment - result.Length);
result = left ? result + padding : padding + result;
}
this.stringBuilder!.Append(result);
}
#endif
/// <summary>Extracts the built string from the handler.</summary>
/// <returns>The formatted string.</returns>
internal string ToStringAndClear()
{
string s = this.stringBuilder?.ToString() ?? string.Empty;
this.stringBuilder = null;
#if NET6_0_OR_GREATER
this.stringBuilderHandler = default;
#endif
return s;
}
}
#endif

Просмотреть файл

@ -61,8 +61,6 @@ public static partial class Verify
}
}
#if NET6_0_OR_GREATER
/// <summary>
/// Throws an <see cref="InvalidOperationException"/> if a condition is false.
/// </summary>
@ -75,8 +73,6 @@ public static partial class Verify
}
}
#endif
/// <summary>
/// Throws an <see cref="InvalidOperationException"/> if a condition is false.
/// </summary>

Просмотреть файл

@ -34,8 +34,6 @@ public partial class AssumesTests : IDisposable
Assert.ThrowsAny<Exception>(() => Assumes.False(true, TestMessage, "arg1", "arg2"));
}
#if NET6_0_OR_GREATER
[Fact]
public void True_InterpolatedString()
{
@ -72,8 +70,6 @@ public partial class AssumesTests : IDisposable
Assert.StartsWith("Some generated string method.", ex.Message);
}
#endif
[Fact]
public void Fail()
{

Просмотреть файл

@ -107,8 +107,6 @@ public class ReportDebugTests : IDisposable
}
}
#if NET6_0_OR_GREATER
[Fact]
public void IfNot_InterpolatedString()
{
@ -124,14 +122,16 @@ public class ReportDebugTests : IDisposable
Report.IfNot(true, $"a{FormattingMethod()}c");
Assert.Equal(0, formatCount);
listener.Value.Setup(l => l.WriteLine("abc")).Verifiable();
#if NETCOREAPP
listener.Value.Setup(l => l.Fail("abc", string.Empty)).Verifiable();
#else
listener.Value.Setup(l => l.Fail("abc")).Verifiable();
#endif
Report.IfNot(false, $"a{FormattingMethod()}c");
Assert.Equal(1, formatCount);
}
}
#endif
[Fact]
public void IfNotPresent()
{

Просмотреть файл

@ -76,8 +76,6 @@ public class ReportReleaseTests : IDisposable
}
}
#if NET6_0_OR_GREATER
[Fact]
public void IfNot_InterpolatedString()
{
@ -97,8 +95,6 @@ public class ReportReleaseTests : IDisposable
}
}
#endif
[Fact]
public void IfNotPresent()
{

Просмотреть файл

@ -150,8 +150,6 @@ public class RequiresTests
Assert.StartsWith(TestStrings.FormatSomeError3Args("arg1", "arg2", "arg3"), ex.Message);
}
#if NET6_0_OR_GREATER
[Fact]
public void Argument_InterpolatedString()
{
@ -170,8 +168,6 @@ public class RequiresTests
Assert.StartsWith("Some generated string method.", ex.Message);
}
#endif
[Fact]
public void Fail()
{

Просмотреть файл

@ -21,8 +21,6 @@ public class VerifyTests
Assert.Throws<InvalidOperationException>(() => Verify.Operation(false, "throw", "arg1", "arg2", "arg3"));
}
#if NET6_0_OR_GREATER
[Fact]
public void Operation_InterpolatedString()
{
@ -41,8 +39,6 @@ public class VerifyTests
Assert.StartsWith("Some generated string method.", ex.Message);
}
#endif
[Fact]
public void OperationWithHelp()
{