Apply string interpolation optimizations to netstandard2.0 as well
This commit is contained in:
Родитель
759ebbb427
Коммит
8bf09314f7
|
@ -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()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче