From 0c5e29f77c8c2b9bedb750731114a1bf77ece178 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 25 Mar 2023 19:41:21 +1100 Subject: [PATCH 001/313] cleanup --- src/Polyfill/PolyfillExtensions_KeyValuePair.cs | 3 --- src/Polyfill/PolyfillExtensions_Memory.cs | 3 --- src/Polyfill/PolyfillExtensions_Stream.cs | 3 --- src/Polyfill/PolyfillExtensions_String.cs | 3 --- 4 files changed, 12 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs index 31a6652c..994b627e 100644 --- a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs +++ b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs @@ -9,9 +9,6 @@ using System; using System.Collections.Generic; -#if PolyPublic -public -#endif static partial class PolyfillExtensions { public static void Deconstruct( diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index a8a1edfc..90efa2d3 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -8,9 +8,6 @@ using System; using System.Text; -#if PolyPublic -public -#endif static partial class PolyfillExtensions { public static bool Contains(this ReadOnlySpan target, char value) diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index a5e19ef3..361068b3 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -11,9 +11,6 @@ using System.Threading; using System.Threading.Tasks; -#if PolyPublic -public -#endif static partial class PolyfillExtensions { public static ValueTask ReadAsync( diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/PolyfillExtensions_String.cs index 83d4037f..7964ad36 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/PolyfillExtensions_String.cs @@ -8,9 +8,6 @@ using System; using System.Text; -#if PolyPublic -public -#endif static partial class PolyfillExtensions { public static bool Contains(this string target, string value, StringComparison comparisonType) => From 43831e2967b72c95c9ec7fdbb76be803ef04d4d0 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 25 Mar 2023 20:15:15 +1100 Subject: [PATCH 002/313] add String.GetHashCode(StringComparison) (#6) --- readme.md | 11 +++----- src/Polyfill/PolyfillExtensions_String.cs | 14 ++++++++++ src/Tests/PolyfillExtensionsSample.cs | 17 ------------ src/Tests/PolyfillExtensionsSample_String.cs | 29 ++++++++++++++++++++ 4 files changed, 47 insertions(+), 24 deletions(-) create mode 100644 src/Tests/PolyfillExtensionsSample_String.cs diff --git a/readme.md b/readme.md index f51e30c5..c9d953dc 100644 --- a/readme.md +++ b/readme.md @@ -350,12 +350,11 @@ The class `PolyfillExtensions` includes the following extension methods: * `bool StartsWith(this string, char)` * `bool EndsWith(this string, char)` + * `public int GetHashCode(this string, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) ### Memory -[System.Memory](#systemmemory) reference required. - * `bool Contains(this ReadOnlySpan, char)` * `void Append(this StringBuilder, ReadOnlySpan)` * `bool SequenceEqual(this ReadOnlySpan, string)` @@ -365,8 +364,6 @@ The class `PolyfillExtensions` includes the following extension methods: ### Stream / StreamReader -[System.Threading.Tasks.Extensions](#systemthreadingtasksextensions) reference required. - * `ValueTask ReadAsync(this Stream, Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) * `ValueTask WriteAsync(this Stream, ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) * `ValueTask ReadAsync(this StreamReader, Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readasync#system-io-streamreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) @@ -380,7 +377,7 @@ The class `PolyfillExtensions` includes the following extension methods: ## References -If any of the below reference are included, the related polyfills will be disabled. +If any of the below reference are not included, the related polyfills will be disabled. ### System.ValueTuple @@ -396,7 +393,7 @@ If consuming in a project that targets `net461` or `net462`, a reference to [Sys ### System.Memory -If consuming in a project that targets `netstandard`, `netframework`, or `netcoreapp2*`, a reference to [System.Memory](https://www.nuget.org/packages/System.Memory/) nuget is required. +If using Span APIs and consuming in a project that targets `netstandard`, `netframework`, or `netcoreapp2*`, a reference to [System.Memory](https://www.nuget.org/packages/System.Memory/) nuget is required. ``` + FromComparison(comparisonType).GetHashCode(target); + + static StringComparer FromComparison(StringComparison comparison) => + comparison switch + { + StringComparison.CurrentCulture => StringComparer.CurrentCulture, + StringComparison.CurrentCultureIgnoreCase => StringComparer.CurrentCultureIgnoreCase, + StringComparison.InvariantCulture => StringComparer.InvariantCulture, + StringComparison.InvariantCultureIgnoreCase => StringComparer.InvariantCultureIgnoreCase, + StringComparison.Ordinal => StringComparer.Ordinal, + StringComparison.OrdinalIgnoreCase => StringComparer.OrdinalIgnoreCase, + }; + public static bool Contains(this string target, string value, StringComparison comparisonType) => target.IndexOf(value, comparisonType) >= 0; diff --git a/src/Tests/PolyfillExtensionsSample.cs b/src/Tests/PolyfillExtensionsSample.cs index 04f8e391..4b7295a6 100644 --- a/src/Tests/PolyfillExtensionsSample.cs +++ b/src/Tests/PolyfillExtensionsSample.cs @@ -4,21 +4,4 @@ [DebuggerNonUserCode] partial class PolyfillExtensionsSample { - [Test] - public void EndsWith() - { - Assert.True("value".EndsWith('e')); - Assert.False("".EndsWith('e')); - } - - [Test] - public void StringContainsStringComparison() => - Assert.True("value".Contains("E", StringComparison.OrdinalIgnoreCase)); - - [Test] - public void StartsWith() - { - Assert.True("value".StartsWith('v')); - Assert.False("".StartsWith('v')); - } } diff --git a/src/Tests/PolyfillExtensionsSample_String.cs b/src/Tests/PolyfillExtensionsSample_String.cs new file mode 100644 index 00000000..e7358463 --- /dev/null +++ b/src/Tests/PolyfillExtensionsSample_String.cs @@ -0,0 +1,29 @@ +// ReSharper disable PartialTypeWithSinglePart + +partial class PolyfillExtensionsSample +{ + [Test] + public void GetHashCodeStringComparison() + { + var hash = "value".GetHashCode(StringComparison.Ordinal); + Assert.AreNotEqual(0, hash); + } + + [Test] + public void EndsWith() + { + Assert.True("value".EndsWith('e')); + Assert.False("".EndsWith('e')); + } + + [Test] + public void StringContainsStringComparison() => + Assert.True("value".Contains("E", StringComparison.OrdinalIgnoreCase)); + + [Test] + public void StartsWith() + { + Assert.True("value".StartsWith('v')); + Assert.False("".StartsWith('v')); + } +} From 6c781f033e3a451df25cd355f66f89d2c1d9fa27 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 25 Mar 2023 21:36:20 +1100 Subject: [PATCH 003/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 9635e01b..3d7de255 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.4.0 + 1.5.0 1.0.0 Polyfill true From 80a77183fd0a095c4857a12b945f9b7620f41919 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 26 Mar 2023 18:02:22 +1100 Subject: [PATCH 004/313] docs --- contributing.md | 31 +++++++++++++++++++++++++++++++ readme.md | 27 ++++++++++++++++++++++----- src/Polyfill/Polyfill.csproj | 1 - 3 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 contributing.md diff --git a/contributing.md b/contributing.md new file mode 100644 index 00000000..1f670cc5 --- /dev/null +++ b/contributing.md @@ -0,0 +1,31 @@ +## Solution Structure + + +### Polyfill + +The main project that produces the nuget. + + +### Tests + +A nUnit test project that verifies all the APIs. + + +### NoRefsTests + +Some features of Polyfill [require nuget references](/#references) to be enabled. The NoRefsTests project had none of those refecences and tests the subset of features that do not require references. + + +### PublicTests + +Polyfill supports [making all APIs public](#consuming-and-type-visibility). The PublicTests project tests that scenario. + + +### UnsafeTests + +Some feature of Polyfill leverage unsafe code for better performance. For example `Append(this StringBuilder, ReadOnlySpan)`. The UnsafeTests project tests this scenario vie enabling `True`. + + +### Consume + +Polufill supports back to `net461` and `netcoreapp2.0`. However nUnit only support back to `net462` and `netcoreapp3.1`. The Consume project targets all frameworks that Polyfill supports, and consumes all APIs to ensure that they all compile on those frameworks \ No newline at end of file diff --git a/readme.md b/readme.md index c9d953dc..cb2f8a4a 100644 --- a/readme.md +++ b/readme.md @@ -353,20 +353,37 @@ The class `PolyfillExtensions` includes the following extension methods: * `public int GetHashCode(this string, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) -### Memory +### ReadOnlySpan * `bool Contains(this ReadOnlySpan, char)` - * `void Append(this StringBuilder, ReadOnlySpan)` * `bool SequenceEqual(this ReadOnlySpan, string)` - * `bool Equals(this StringBuilder, ReadOnlySpan)` + + +### Span + * `bool SequenceEqual(this Span, string)` -### Stream / StreamReader +### StringBuilder + + * `void Append(this StringBuilder, ReadOnlySpan)`. Will perform better if `True` is enabled in the consuming project. + * `bool Equals(this StringBuilder, ReadOnlySpan)` + + +### Stream * `ValueTask ReadAsync(this Stream, Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) * `ValueTask WriteAsync(this Stream, ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) - * `ValueTask ReadAsync(this StreamReader, Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readasync#system-io-streamreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) + + +### StreamReader + + * `ValueTask ReadAsync(this Stream, Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `ValueTask WriteAsync(this Stream, ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) + + +### StreamWriter + * `ValueTask WriteAsync(this StreamWriter, ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index c308d80f..70532cff 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -16,5 +16,4 @@ configuration=$(Configuration);version=$(PackageVersion);authors=$(Authors);projectUrl=$(PackageProjectUrl);description=$(Description);tags=$(PackageTags) - \ No newline at end of file From 759b9d440c0a79a2e2770d892981b58fabc8fdbd Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 26 Mar 2023 19:08:50 +1100 Subject: [PATCH 005/313] Update contributing.md --- contributing.md | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/contributing.md b/contributing.md index 1f670cc5..42ed7925 100644 --- a/contributing.md +++ b/contributing.md @@ -1,3 +1,6 @@ +# Contributing + + ## Solution Structure @@ -28,4 +31,44 @@ Some feature of Polyfill leverage unsafe code for better performance. For exampl ### Consume -Polufill supports back to `net461` and `netcoreapp2.0`. However nUnit only support back to `net462` and `netcoreapp3.1`. The Consume project targets all frameworks that Polyfill supports, and consumes all APIs to ensure that they all compile on those frameworks \ No newline at end of file +Polyfill supports back to `net461` and `netcoreapp2.0`. However nUnit only support back to `net462` and `netcoreapp3.1`. The Consume project targets all frameworks that Polyfill supports, and consumes all APIs to ensure that they all compile on those frameworks + + +## Submitting a new polyfill API + + +### Valid APIs + +An API is a valid candidate to be polyfilled if it exists in the current stable version of .net or is planned for a future version .net + +APIs that require a reference to a bridging nuget (similar to [System.ValueTuple](https://www.nuget.org/packages/System.ValueTuple/) or [System.Memory](https://www.nuget.org/packages/System.Memory/)) will only be accepted if, in a future version of .net that nuget is not required. + + +### Raise Pull Request not an Issue + +If a new API is valid, dont bother raising a GitHub issue to ask about it. Instead submit a Pull Request that adds that API. Any discussion can happen in the PR comments. + + +### Add the new API to the Polyfill project + + +#### Conditional Compilation + +The code for the API should be wrapped in conditional compilation statements + +``` +#if NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X +``` + +The following additional compilation constants are provided: + + * `NETCOREAPPX`: indicates if netcore is being targeted. + * `NETCOREAPP2X`: indicates if any major or minor version of netcore 2 is being targeted. + * `NETCOREAPP3X`: indicates if any major or minor version of netcore 3 is being targeted. + * `NET4X`: indicates if any major or minor version of NET46 is being targeted. + * `NET46X`: indicates if any major or minor version of NET46 is being targeted. + * `NET47X`: indicates if any major or minor version of NET47 is being targeted. + * `NET48X`: indicates if any major or minor version of NET48 is being targeted. + * `MEMORYREFERENCED`: indicates if [System.Memory](https://www.nuget.org/packages/System.Memory/)) is referenced. + * `TASKSEXTENSIONSREFERENCED`: indicates if [System.Threading.Tasks.Extensions](https://www.nuget.org/packages/System.Threading.Tasks.Extensions/)) is referenced. + * `VALUETUPLEREFERENCED`: indicates if [System.ValueTuple](https://www.nuget.org/packages/System.ValueTuple/)) is referenced. \ No newline at end of file From 219aaa391b5987f658abefd6897b0d7cb93794f2 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 26 Mar 2023 19:12:38 +1100 Subject: [PATCH 006/313] docs --- contributing.md | 28 +++++++++++++++++++++++++++- src/Polyfill/placeholder.txt | 1 - 2 files changed, 27 insertions(+), 2 deletions(-) delete mode 100644 src/Polyfill/placeholder.txt diff --git a/contributing.md b/contributing.md index 42ed7925..c7f5f3be 100644 --- a/contributing.md +++ b/contributing.md @@ -71,4 +71,30 @@ The following additional compilation constants are provided: * `NET48X`: indicates if any major or minor version of NET48 is being targeted. * `MEMORYREFERENCED`: indicates if [System.Memory](https://www.nuget.org/packages/System.Memory/)) is referenced. * `TASKSEXTENSIONSREFERENCED`: indicates if [System.Threading.Tasks.Extensions](https://www.nuget.org/packages/System.Threading.Tasks.Extensions/)) is referenced. - * `VALUETUPLEREFERENCED`: indicates if [System.ValueTuple](https://www.nuget.org/packages/System.ValueTuple/)) is referenced. \ No newline at end of file + * `VALUETUPLEREFERENCED`: indicates if [System.ValueTuple](https://www.nuget.org/packages/System.ValueTuple/)) is referenced. + + +#### Warnings disabled + +Warnings must be disabled with a pragma. + +``` +#pragma warning disable +``` + +This is required to prevent custom code formatting rule in consuming projects from giving false warnings + + +#### ReSharper / Rider + +Any potential ReSharper or Rider cde formatting issues should be disabled. For example: + +``` +// ReSharper disable RedundantUsingDirective +// ReSharper disable UnusedMember.Global +``` + + +#### Assume Implicit usings is disabled + +Having Implicit enabled is optional for the consuming project. So ensure all using statements are included. diff --git a/src/Polyfill/placeholder.txt b/src/Polyfill/placeholder.txt deleted file mode 100644 index 0ceefd36..00000000 --- a/src/Polyfill/placeholder.txt +++ /dev/null @@ -1 +0,0 @@ -to stop the nullability types being pulled into net6 \ No newline at end of file From af043beb8e2afd41ab3e0990f94a4d051dc3b038 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 26 Mar 2023 19:50:12 +1100 Subject: [PATCH 007/313] cleanup --- src/Polyfill/PolyfillExtensions_Stream.cs | 32 ------------------- .../PolyfillExtensions_StreamReader.cs | 32 +++++++++++++++++++ .../PolyfillExtensions_StreamWriter.cs | 32 +++++++++++++++++++ src/Tests/PolyfillExtensionsSample_Stream.cs | 12 ------- .../PolyfillExtensionsSample_StreamReader.cs | 14 ++++++++ src/Tests/Tests.csproj | 29 ++++------------- 6 files changed, 85 insertions(+), 66 deletions(-) create mode 100644 src/Polyfill/PolyfillExtensions_StreamReader.cs create mode 100644 src/Polyfill/PolyfillExtensions_StreamWriter.cs create mode 100644 src/Tests/PolyfillExtensionsSample_StreamReader.cs diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index 361068b3..cbe86319 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -26,22 +26,6 @@ public static ValueTask ReadAsync( return new(stream.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken)); } - public static ValueTask ReadAsync( - this StreamReader reader, - Memory buffer, - CancellationToken cancellationToken = default) - { - // StreamReader doesn't accept cancellation token (pre-netstd2.1) - cancellationToken.ThrowIfCancellationRequested(); - - if (!MemoryMarshal.TryGetArray((ReadOnlyMemory)buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - - return new(reader.ReadAsync(segment.Array!, segment.Offset, segment.Count)); - } - public static ValueTask WriteAsync( this Stream stream, ReadOnlyMemory buffer, @@ -55,22 +39,6 @@ public static ValueTask WriteAsync( return new(stream.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken)); } - public static ValueTask WriteAsync( - this StreamWriter stream, - ReadOnlyMemory buffer, - CancellationToken cancellationToken = default) - { - // StreamReader doesn't accept cancellation token (pre-netstd2.1) - cancellationToken.ThrowIfCancellationRequested(); - - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - - return new(stream.WriteAsync(segment.Array!, segment.Offset, segment.Count)); - } - public static Task CopyToAsync( this Stream stream, Stream destination, diff --git a/src/Polyfill/PolyfillExtensions_StreamReader.cs b/src/Polyfill/PolyfillExtensions_StreamReader.cs new file mode 100644 index 00000000..b092dff7 --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_StreamReader.cs @@ -0,0 +1,32 @@ +#if TASKSEXTENSIONSREFERENCED && (NET4X || NETSTANDARD2_0 || NETCOREAPP2_0) + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable UnusedMember.Global + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; + +static partial class PolyfillExtensions +{ + public static ValueTask ReadAsync( + this StreamReader reader, + Memory buffer, + CancellationToken cancellationToken = default) + { + // StreamReader doesn't accept cancellation token (pre-netstd2.1) + cancellationToken.ThrowIfCancellationRequested(); + + if (!MemoryMarshal.TryGetArray((ReadOnlyMemory)buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + + return new(reader.ReadAsync(segment.Array!, segment.Offset, segment.Count)); + } +} +#endif \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_StreamWriter.cs b/src/Polyfill/PolyfillExtensions_StreamWriter.cs new file mode 100644 index 00000000..43630c67 --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_StreamWriter.cs @@ -0,0 +1,32 @@ +#if TASKSEXTENSIONSREFERENCED && (NET4X || NETSTANDARD2_0 || NETCOREAPP2_0) + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable UnusedMember.Global + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; + +static partial class PolyfillExtensions +{ + public static ValueTask WriteAsync( + this StreamWriter writer, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + // StreamReader doesn't accept cancellation token (pre-netstd2.1) + cancellationToken.ThrowIfCancellationRequested(); + + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + + return new(writer.WriteAsync(segment.Array!, segment.Offset, segment.Count)); + } +} +#endif \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsSample_Stream.cs b/src/Tests/PolyfillExtensionsSample_Stream.cs index ad9e503a..f0032553 100644 --- a/src/Tests/PolyfillExtensionsSample_Stream.cs +++ b/src/Tests/PolyfillExtensionsSample_Stream.cs @@ -1,17 +1,5 @@ partial class PolyfillExtensionsSample { - [Test] - public async Task StreamReaderReadAsync() - { - using var stream = new MemoryStream("value"u8.ToArray()); - var result = new char[5]; - var memory = new Memory(result); - using var reader = new StreamReader(stream); - var read = await reader.ReadAsync(memory); - Assert.AreEqual(5, read); - Assert.IsTrue("value".SequenceEqual(result)); - } - [Test] public async Task StreamReadAsync() { diff --git a/src/Tests/PolyfillExtensionsSample_StreamReader.cs b/src/Tests/PolyfillExtensionsSample_StreamReader.cs new file mode 100644 index 00000000..f56dc97f --- /dev/null +++ b/src/Tests/PolyfillExtensionsSample_StreamReader.cs @@ -0,0 +1,14 @@ +partial class PolyfillExtensionsSample +{ + [Test] + public async Task StreamReaderReadAsync() + { + using var stream = new MemoryStream("value"u8.ToArray()); + var result = new char[5]; + var memory = new Memory(result); + using var reader = new StreamReader(stream); + var read = await reader.ReadAsync(memory); + Assert.AreEqual(5, read); + Assert.IsTrue("value".SequenceEqual(result)); + } +} diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index c39f0073..51db5641 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -21,28 +21,13 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - - - - - - - + + + + + + + From 81f28b458a2cbf33fe2d72bb848797a63beb4324 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 26 Mar 2023 19:58:35 +1100 Subject: [PATCH 008/313] cleanup --- contributing.md | 1 - src/Polyfill/Polyfill.props | 3 --- src/Polyfill/PolyfillExtensions_KeyValuePair.cs | 8 ++++---- src/Polyfill/PolyfillExtensions_Memory.cs | 5 +++-- src/Polyfill/PolyfillExtensions_Stream.cs | 14 +++++++------- src/Polyfill/PolyfillExtensions_StreamReader.cs | 6 +++--- src/Polyfill/PolyfillExtensions_StreamWriter.cs | 6 +++--- 7 files changed, 20 insertions(+), 23 deletions(-) diff --git a/contributing.md b/contributing.md index c7f5f3be..557d6193 100644 --- a/contributing.md +++ b/contributing.md @@ -65,7 +65,6 @@ The following additional compilation constants are provided: * `NETCOREAPPX`: indicates if netcore is being targeted. * `NETCOREAPP2X`: indicates if any major or minor version of netcore 2 is being targeted. * `NETCOREAPP3X`: indicates if any major or minor version of netcore 3 is being targeted. - * `NET4X`: indicates if any major or minor version of NET46 is being targeted. * `NET46X`: indicates if any major or minor version of NET46 is being targeted. * `NET47X`: indicates if any major or minor version of NET47 is being targeted. * `NET48X`: indicates if any major or minor version of NET48 is being targeted. diff --git a/src/Polyfill/Polyfill.props b/src/Polyfill/Polyfill.props index 78930b06..ad28323d 100644 --- a/src/Polyfill/Polyfill.props +++ b/src/Polyfill/Polyfill.props @@ -26,9 +26,6 @@ $(DefineConstants);NET48X - - $(DefineConstants);NET4X - $(DefineConstants);NETCOREAPPX diff --git a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs index 994b627e..0cd47cfa 100644 --- a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs +++ b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs @@ -1,4 +1,4 @@ -#if NET4X || NETSTANDARD2_0 +#if NETFRAMEWORK || NETSTANDARD2_0 #pragma warning disable @@ -12,12 +12,12 @@ static partial class PolyfillExtensions { public static void Deconstruct( - this KeyValuePair pair, + this KeyValuePair target, out TKey key, out TValue value) { - key = pair.Key; - value = pair.Value; + key = target.Key; + value = target.Value; } } #endif \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index 90efa2d3..3d2d004d 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -1,4 +1,4 @@ -#if MEMORYREFERENCED && (NET4X || NETSTANDARD || NETCOREAPP2X) +#if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X) #pragma warning disable @@ -7,6 +7,7 @@ using System; using System.Text; +using System.Runtime.InteropServices; static partial class PolyfillExtensions { @@ -33,7 +34,7 @@ public static void Append(this StringBuilder target, ReadOnlySpan value) #if AllowUnsafeBlocks unsafe { - fixed (char* valueChars = &System.Runtime.InteropServices.MemoryMarshal.GetReference(value)) + fixed (char* valueChars = &MemoryMarshal.GetReference(value)) { target.Append(valueChars, value.Length); } diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index cbe86319..460a76ae 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -1,4 +1,4 @@ -#if TASKSEXTENSIONSREFERENCED && (NET4X || NETSTANDARD2_0 || NETCOREAPP2_0) +#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) #pragma warning disable @@ -14,7 +14,7 @@ static partial class PolyfillExtensions { public static ValueTask ReadAsync( - this Stream stream, + this Stream target, Memory buffer, CancellationToken cancellationToken = default) { @@ -23,11 +23,11 @@ public static ValueTask ReadAsync( segment = new(buffer.ToArray()); } - return new(stream.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken)); + return new(target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken)); } public static ValueTask WriteAsync( - this Stream stream, + this Stream target, ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { @@ -36,13 +36,13 @@ public static ValueTask WriteAsync( segment = new(buffer.ToArray()); } - return new(stream.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken)); + return new(target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken)); } public static Task CopyToAsync( - this Stream stream, + this Stream target, Stream destination, CancellationToken cancellationToken = default) => - stream.CopyToAsync(destination, 81920, cancellationToken); + target.CopyToAsync(destination, 81920, cancellationToken); } #endif \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_StreamReader.cs b/src/Polyfill/PolyfillExtensions_StreamReader.cs index b092dff7..32dd6e45 100644 --- a/src/Polyfill/PolyfillExtensions_StreamReader.cs +++ b/src/Polyfill/PolyfillExtensions_StreamReader.cs @@ -1,4 +1,4 @@ -#if TASKSEXTENSIONSREFERENCED && (NET4X || NETSTANDARD2_0 || NETCOREAPP2_0) +#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) #pragma warning disable @@ -14,7 +14,7 @@ static partial class PolyfillExtensions { public static ValueTask ReadAsync( - this StreamReader reader, + this StreamReader target, Memory buffer, CancellationToken cancellationToken = default) { @@ -26,7 +26,7 @@ public static ValueTask ReadAsync( segment = new(buffer.ToArray()); } - return new(reader.ReadAsync(segment.Array!, segment.Offset, segment.Count)); + return new(target.ReadAsync(segment.Array!, segment.Offset, segment.Count)); } } #endif \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_StreamWriter.cs b/src/Polyfill/PolyfillExtensions_StreamWriter.cs index 43630c67..c3ce4705 100644 --- a/src/Polyfill/PolyfillExtensions_StreamWriter.cs +++ b/src/Polyfill/PolyfillExtensions_StreamWriter.cs @@ -1,4 +1,4 @@ -#if TASKSEXTENSIONSREFERENCED && (NET4X || NETSTANDARD2_0 || NETCOREAPP2_0) +#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) #pragma warning disable @@ -14,7 +14,7 @@ static partial class PolyfillExtensions { public static ValueTask WriteAsync( - this StreamWriter writer, + this StreamWriter target, ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { @@ -26,7 +26,7 @@ public static ValueTask WriteAsync( segment = new(buffer.ToArray()); } - return new(writer.WriteAsync(segment.Array!, segment.Offset, segment.Count)); + return new(target.WriteAsync(segment.Array!, segment.Offset, segment.Count)); } } #endif \ No newline at end of file From 7802596118a77dd8e93d1b5d394cec8c38b7dcc7 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 26 Mar 2023 20:19:42 +1100 Subject: [PATCH 009/313] Update contributing.md --- contributing.md | 128 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 5 deletions(-) diff --git a/contributing.md b/contributing.md index 557d6193..74fd3929 100644 --- a/contributing.md +++ b/contributing.md @@ -11,7 +11,7 @@ The main project that produces the nuget. ### Tests -A nUnit test project that verifies all the APIs. +A NUnit test project that verifies all the APIs. ### NoRefsTests @@ -31,7 +31,7 @@ Some feature of Polyfill leverage unsafe code for better performance. For exampl ### Consume -Polyfill supports back to `net461` and `netcoreapp2.0`. However nUnit only support back to `net462` and `netcoreapp3.1`. The Consume project targets all frameworks that Polyfill supports, and consumes all APIs to ensure that they all compile on those frameworks +Polyfill supports back to `net461` and `netcoreapp2.0`. However NUnit only support back to `net462` and `netcoreapp3.1`. The Consume project targets all frameworks that Polyfill supports, and consumes all APIs to ensure that they all compile on those frameworks ## Submitting a new polyfill API @@ -54,7 +54,7 @@ If a new API is valid, dont bother raising a GitHub issue to ask about it. Inste #### Conditional Compilation -The code for the API should be wrapped in conditional compilation statements +The code for the API should be wrapped in conditional compilation statements. For example: ``` #if NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X @@ -69,7 +69,7 @@ The following additional compilation constants are provided: * `NET47X`: indicates if any major or minor version of NET47 is being targeted. * `NET48X`: indicates if any major or minor version of NET48 is being targeted. * `MEMORYREFERENCED`: indicates if [System.Memory](https://www.nuget.org/packages/System.Memory/)) is referenced. - * `TASKSEXTENSIONSREFERENCED`: indicates if [System.Threading.Tasks.Extensions](https://www.nuget.org/packages/System.Threading.Tasks.Extensions/)) is referenced. + * `TASKSEXTENSIONSREFERENCED`: indicates if [System.Threading.Tasks.Extensions](https://www.nuget.org/packages/System.Threading.Tasks.Extensions/)) is referenced. * `VALUETUPLEREFERENCED`: indicates if [System.ValueTuple](https://www.nuget.org/packages/System.ValueTuple/)) is referenced. @@ -96,4 +96,122 @@ Any potential ReSharper or Rider cde formatting issues should be disabled. For e #### Assume Implicit usings is disabled -Having Implicit enabled is optional for the consuming project. So ensure all using statements are included. +Having Implicit usings enabled is optional for the consuming project. So ensure all using statements are included. + + +#### Make public if + +Polyfill supports [making all APIs public](#consuming-and-type-visibility). This is done by making types public if `PolyPublic`. For example: + +``` +#if PolyPublic +public +#endif +sealed class ... +``` + + +#### If the API is attribute based + +Add a new class containing the Attribute + +Example: + + + +```cs +#if !NET5_0_OR_GREATER + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable UnusedMember.Global + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + +namespace System.Runtime.CompilerServices; + +/// +/// Used to indicate to the compiler that a method should be called +/// in its containing module's initializer. +/// +/// +/// When one or more valid methods +/// with this attribute are found in a compilation, the compiler will +/// emit a module initializer which calls each of the attributed methods. +/// +/// Certain requirements are imposed on any method targeted with this attribute: +/// - The method must be `static`. +/// - The method must be an ordinary member method, as opposed to a property accessor, constructor, local function, etc. +/// - The method must be parameterless. +/// - The method must return `void`. +/// - The method must not be generic or be contained in a generic type. +/// - The method's effective accessibility must be `internal` or `public`. +/// +/// The specification for module initializers in the .NET runtime can be found here: +/// https://github.com/dotnet/runtime/blob/master/docs/design/specs/Ecma-335-Augments.md#module-initializer +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage( + validOn: AttributeTargets.Method, + Inherited = false)] +#if PolyPublic +public +#endif +sealed class ModuleInitializerAttribute : + Attribute +{ +} + +#endif +``` +snippet source | anchor + + + +#### If the API is a missing instance method + +Add an extension method to `PolyfillExtensions_TYPE.cs` where `TYPE` is the type the method extending. So, for example, APIs that target `StreamWriter` go in `PolyfillExtensions_StreamWriter.cs`. + +Example: + + + +```cs +#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable UnusedMember.Global + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; + +static partial class PolyfillExtensions +{ + public static ValueTask WriteAsync( + this StreamWriter target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + // StreamReader doesn't accept cancellation token (pre-netstd2.1) + cancellationToken.ThrowIfCancellationRequested(); + + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + + return new(target.WriteAsync(segment.Array!, segment.Offset, segment.Count)); + } +} +#endif +``` +snippet source | anchor + From d034fd7dfd79f30c5d993f32d1d6b2724b720dbe Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 26 Mar 2023 20:25:44 +1100 Subject: [PATCH 010/313] docs --- contributing.md | 11 ++++++++++- src/Polyfill/PolyfillExtensions_StreamWriter.cs | 9 +++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/contributing.md b/contributing.md index 74fd3929..62cfd3ac 100644 --- a/contributing.md +++ b/contributing.md @@ -195,6 +195,15 @@ using System.Threading.Tasks; static partial class PolyfillExtensions { + /// + /// Asynchronously writes a character memory region to the stream. + /// + /// The character memory region to write to the stream. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// A task that represents the asynchronous write operation. public static ValueTask WriteAsync( this StreamWriter target, ReadOnlyMemory buffer, @@ -213,5 +222,5 @@ static partial class PolyfillExtensions } #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Polyfill/PolyfillExtensions_StreamWriter.cs b/src/Polyfill/PolyfillExtensions_StreamWriter.cs index c3ce4705..33d8bac6 100644 --- a/src/Polyfill/PolyfillExtensions_StreamWriter.cs +++ b/src/Polyfill/PolyfillExtensions_StreamWriter.cs @@ -13,6 +13,15 @@ static partial class PolyfillExtensions { + /// + /// Asynchronously writes a character memory region to the stream. + /// + /// The character memory region to write to the stream. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// A task that represents the asynchronous write operation. public static ValueTask WriteAsync( this StreamWriter target, ReadOnlyMemory buffer, From fa2bead85a85f5d6c72ba2870b1e2583244a3107 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 26 Mar 2023 20:38:38 +1100 Subject: [PATCH 011/313] docs --- contributing.md | 23 +++++++++++++++++++ src/NoRefsTests/NoRefsTests.csproj | 2 +- ...nsSample.cs => PolyfillExtensionsTests.cs} | 2 +- ...y.cs => PolyfillExtensionsTests_Memory.cs} | 2 +- ...m.cs => PolyfillExtensionsTests_Stream.cs} | 2 +- ...> PolyfillExtensionsTests_StreamReader.cs} | 2 +- ...g.cs => PolyfillExtensionsTests_String.cs} | 2 +- 7 files changed, 29 insertions(+), 6 deletions(-) rename src/Tests/{PolyfillExtensionsSample.cs => PolyfillExtensionsTests.cs} (69%) rename src/Tests/{PolyfillExtensionsSample_Memory.cs => PolyfillExtensionsTests_Memory.cs} (93%) rename src/Tests/{PolyfillExtensionsSample_Stream.cs => PolyfillExtensionsTests_Stream.cs} (90%) rename src/Tests/{PolyfillExtensionsSample_StreamReader.cs => PolyfillExtensionsTests_StreamReader.cs} (91%) rename src/Tests/{PolyfillExtensionsSample_String.cs => PolyfillExtensionsTests_String.cs} (94%) diff --git a/contributing.md b/contributing.md index 62cfd3ac..52c625c3 100644 --- a/contributing.md +++ b/contributing.md @@ -110,6 +110,10 @@ public sealed class ... ``` +#### XML API comment + +The XML API comments should match the actual API. + #### If the API is attribute based @@ -224,3 +228,22 @@ static partial class PolyfillExtensions ``` snippet source | anchor + + +### Add a test + +Add a for the new API to the Tests project. + +Extension method tests to `PolyfillExtensionsTests_TYPE.cs` where `TYPE` is the type the method extending. So, for example, APIs that target `StreamWriter` go in `PolyfillExtensionsTests_StreamWriter.cs`. For example: + +snippet: PolyfillExtensionsTests_StreamReader.cs + + +### Add documentation + +Add documentation for the API to the `readme.md`. + + +### Add to the Consume project + +Add a simple usage of the API to the Consume project. \ No newline at end of file diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 698009c4..71d370bf 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -24,7 +24,7 @@ - + diff --git a/src/Tests/PolyfillExtensionsSample.cs b/src/Tests/PolyfillExtensionsTests.cs similarity index 69% rename from src/Tests/PolyfillExtensionsSample.cs rename to src/Tests/PolyfillExtensionsTests.cs index 4b7295a6..526a150b 100644 --- a/src/Tests/PolyfillExtensionsSample.cs +++ b/src/Tests/PolyfillExtensionsTests.cs @@ -2,6 +2,6 @@ [TestFixture] [DebuggerNonUserCode] -partial class PolyfillExtensionsSample +partial class PolyfillExtensionsTests { } diff --git a/src/Tests/PolyfillExtensionsSample_Memory.cs b/src/Tests/PolyfillExtensionsTests_Memory.cs similarity index 93% rename from src/Tests/PolyfillExtensionsSample_Memory.cs rename to src/Tests/PolyfillExtensionsTests_Memory.cs index 0a74d5a4..187d664d 100644 --- a/src/Tests/PolyfillExtensionsSample_Memory.cs +++ b/src/Tests/PolyfillExtensionsTests_Memory.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsSample +partial class PolyfillExtensionsTests { [Test] public void SpanContains() => diff --git a/src/Tests/PolyfillExtensionsSample_Stream.cs b/src/Tests/PolyfillExtensionsTests_Stream.cs similarity index 90% rename from src/Tests/PolyfillExtensionsSample_Stream.cs rename to src/Tests/PolyfillExtensionsTests_Stream.cs index f0032553..133f09a7 100644 --- a/src/Tests/PolyfillExtensionsSample_Stream.cs +++ b/src/Tests/PolyfillExtensionsTests_Stream.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsSample +partial class PolyfillExtensionsTests { [Test] public async Task StreamReadAsync() diff --git a/src/Tests/PolyfillExtensionsSample_StreamReader.cs b/src/Tests/PolyfillExtensionsTests_StreamReader.cs similarity index 91% rename from src/Tests/PolyfillExtensionsSample_StreamReader.cs rename to src/Tests/PolyfillExtensionsTests_StreamReader.cs index f56dc97f..ae20c7eb 100644 --- a/src/Tests/PolyfillExtensionsSample_StreamReader.cs +++ b/src/Tests/PolyfillExtensionsTests_StreamReader.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsSample +partial class PolyfillExtensionsTests { [Test] public async Task StreamReaderReadAsync() diff --git a/src/Tests/PolyfillExtensionsSample_String.cs b/src/Tests/PolyfillExtensionsTests_String.cs similarity index 94% rename from src/Tests/PolyfillExtensionsSample_String.cs rename to src/Tests/PolyfillExtensionsTests_String.cs index e7358463..2754644f 100644 --- a/src/Tests/PolyfillExtensionsSample_String.cs +++ b/src/Tests/PolyfillExtensionsTests_String.cs @@ -1,6 +1,6 @@ // ReSharper disable PartialTypeWithSinglePart -partial class PolyfillExtensionsSample +partial class PolyfillExtensionsTests { [Test] public void GetHashCodeStringComparison() From 2380306288870899b1041d8ab706456af8dec0ed Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 26 Mar 2023 20:41:25 +1100 Subject: [PATCH 012/313] Update contributing.md --- contributing.md | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/contributing.md b/contributing.md index 52c625c3..ccd9f787 100644 --- a/contributing.md +++ b/contributing.md @@ -4,32 +4,32 @@ ## Solution Structure -### Polyfill +### Polyfill project The main project that produces the nuget. -### Tests +### Tests project A NUnit test project that verifies all the APIs. -### NoRefsTests +### NoRefsTests project Some features of Polyfill [require nuget references](/#references) to be enabled. The NoRefsTests project had none of those refecences and tests the subset of features that do not require references. -### PublicTests +### PublicTests project Polyfill supports [making all APIs public](#consuming-and-type-visibility). The PublicTests project tests that scenario. -### UnsafeTests +### UnsafeTests project Some feature of Polyfill leverage unsafe code for better performance. For example `Append(this StringBuilder, ReadOnlySpan)`. The UnsafeTests project tests this scenario vie enabling `True`. -### Consume +### Consume project Polyfill supports back to `net461` and `netcoreapp2.0`. However NUnit only support back to `net462` and `netcoreapp3.1`. The Consume project targets all frameworks that Polyfill supports, and consumes all APIs to ensure that they all compile on those frameworks @@ -236,7 +236,26 @@ Add a for the new API to the Tests project. Extension method tests to `PolyfillExtensionsTests_TYPE.cs` where `TYPE` is the type the method extending. So, for example, APIs that target `StreamWriter` go in `PolyfillExtensionsTests_StreamWriter.cs`. For example: -snippet: PolyfillExtensionsTests_StreamReader.cs + + +```cs +partial class PolyfillExtensionsTests +{ + [Test] + public async Task StreamReaderReadAsync() + { + using var stream = new MemoryStream("value"u8.ToArray()); + var result = new char[5]; + var memory = new Memory(result); + using var reader = new StreamReader(stream); + var read = await reader.ReadAsync(memory); + Assert.AreEqual(5, read); + Assert.IsTrue("value".SequenceEqual(result)); + } +} +``` +snippet source | anchor + ### Add documentation @@ -246,4 +265,4 @@ Add documentation for the API to the `readme.md`. ### Add to the Consume project -Add a simple usage of the API to the Consume project. \ No newline at end of file +Add a simple usage of the API to the Consume project. From 4d23c212f4e9fbcd14ae6be225a26d0f4f9e4371 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 26 Mar 2023 20:45:03 +1100 Subject: [PATCH 013/313] Update Polyfill.nuspec --- src/Polyfill/Polyfill.nuspec | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Polyfill/Polyfill.nuspec b/src/Polyfill/Polyfill.nuspec index c737e44c..108ee41f 100644 --- a/src/Polyfill/Polyfill.nuspec +++ b/src/Polyfill/Polyfill.nuspec @@ -12,9 +12,6 @@ $description$ $copyright$ $tags$ - - - From fe5493261e337583c5286fdbe25b8ca9e6443aab Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 26 Mar 2023 20:49:46 +1100 Subject: [PATCH 014/313] Update contributing.md --- contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributing.md b/contributing.md index ccd9f787..ca30047b 100644 --- a/contributing.md +++ b/contributing.md @@ -86,7 +86,7 @@ This is required to prevent custom code formatting rule in consuming projects fr #### ReSharper / Rider -Any potential ReSharper or Rider cde formatting issues should be disabled. For example: +Any potential ReSharper or Rider code formatting issues should be disabled. For example: ``` // ReSharper disable RedundantUsingDirective From 7e56120f2e259fbed99aa927954ea22359a9d6d5 Mon Sep 17 00:00:00 2001 From: David Wengier Date: Mon, 27 Mar 2023 10:14:54 +1100 Subject: [PATCH 015/313] Noticed a typo while reading this last night (#7) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maybe I should have waited until October to PR this... 🤔 --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index cb2f8a4a..85bb5229 100644 --- a/readme.md +++ b/readme.md @@ -333,7 +333,7 @@ Reference: [Improvements in native code interop in .NET 5.0](https://devblogs.mi ### SuppressGCTransition - * [SuppressGCTransitionAttribte](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.suppressgctransitionattribute) + * [SuppressGCTransitionAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.suppressgctransitionattribute) ### DisableRuntimeMarshalling From 7ee3a6bcafb33365c724223ee3886a6b1ba2e37c Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 27 Mar 2023 19:44:04 +1100 Subject: [PATCH 016/313] exclude PolyfillExtensions from ides --- src/Polyfill/PolyfillExtensions.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Polyfill/PolyfillExtensions.cs b/src/Polyfill/PolyfillExtensions.cs index 6294c8fd..1fcfa293 100644 --- a/src/Polyfill/PolyfillExtensions.cs +++ b/src/Polyfill/PolyfillExtensions.cs @@ -3,9 +3,11 @@ // ReSharper disable RedundantUsingDirective // ReSharper disable PartialTypeWithSinglePart +using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +[EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] #if PolyPublic From 4453994acaa62042665479b48d312def39fb3192 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 27 Mar 2023 20:27:26 +1100 Subject: [PATCH 017/313] Update PolyfillExtensions_Stream.cs --- src/Polyfill/PolyfillExtensions_Stream.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index 460a76ae..b06f2d76 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -39,6 +39,13 @@ public static ValueTask WriteAsync( return new(target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken)); } + /// + /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified + /// cancellation token. Both streams positions are advanced by the number of bytes copied. + /// + /// The stream to which the contents of the current stream will be copied. + /// The token to monitor for cancellation requests. The default value is None. + /// public static Task CopyToAsync( this Stream target, Stream destination, From 8910411007c0b81326b2d3b2ad04a0aa867f7783 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 27 Mar 2023 20:32:14 +1100 Subject: [PATCH 018/313] Update PolyfillExtensions_Stream.cs --- src/Polyfill/PolyfillExtensions_Stream.cs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index b06f2d76..8cc89149 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -13,6 +13,20 @@ static partial class PolyfillExtensions { + /// + /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by + /// the number of bytes read, and monitors cancellation requests. + /// + /// The region of memory to write the data into. + /// + /// The token to monitor for cancellation requests. The default value is None. + /// + /// + /// A task that represents the asynchronous read operation. The value of its Result property contains the + /// total number of bytes read into the buffer. The result value can be less than the number of bytes allocated in + /// the buffer if that many bytes are not currently available, or it can be 0 (zero) if the end of the stream has + /// been reached. + /// public static ValueTask ReadAsync( this Stream target, Memory buffer, @@ -26,6 +40,15 @@ public static ValueTask ReadAsync( return new(target.ReadAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken)); } + /// + /// Asynchronously writes a sequence of bytes to the current stream, advances the current position + /// within this stream by the number of bytes written, and monitors cancellation requests. + /// + /// The region of memory to write data from. + /// + /// The token to monitor for cancellation requests. The default value is None. + /// + /// A task that represents the asynchronous write operation. public static ValueTask WriteAsync( this Stream target, ReadOnlyMemory buffer, From 513b62885f8dda40ddd38eb13075b80963eb576f Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 27 Mar 2023 20:32:22 +1100 Subject: [PATCH 019/313] Update PolyfillExtensions_Stream.cs --- src/Polyfill/PolyfillExtensions_Stream.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index 8cc89149..fccfbd5d 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -67,8 +67,10 @@ public static ValueTask WriteAsync( /// cancellation token. Both streams positions are advanced by the number of bytes copied. /// /// The stream to which the contents of the current stream will be copied. - /// The token to monitor for cancellation requests. The default value is None. - /// + /// + /// The token to monitor for cancellation requests. The default value is None. + /// + /// A task that represents the asynchronous copy operation. public static Task CopyToAsync( this Stream target, Stream destination, From 9da0bd971e51b706d734369dd41c440b21144e60 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 27 Mar 2023 20:32:35 +1100 Subject: [PATCH 020/313] Update PolyfillExtensionsTests_Stream.cs --- src/Tests/PolyfillExtensionsTests_Stream.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/PolyfillExtensionsTests_Stream.cs b/src/Tests/PolyfillExtensionsTests_Stream.cs index 133f09a7..e0fc417b 100644 --- a/src/Tests/PolyfillExtensionsTests_Stream.cs +++ b/src/Tests/PolyfillExtensionsTests_Stream.cs @@ -1,7 +1,7 @@ partial class PolyfillExtensionsTests { [Test] - public async Task StreamReadAsync() + public async Task StreamReadAsyncMemory() { var input = new byte[]{1,2}; using var stream = new MemoryStream(input); From 1d7883169f2d256fefdf533ee9478ed1908a52fe Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 27 Mar 2023 21:13:02 +1100 Subject: [PATCH 021/313] String split and contains (#8) --- readme.md | 5 ++- src/Consume/Consume.cs | 4 ++ src/Directory.Build.props | 2 +- src/Polyfill/PolyfillExtensions_String.cs | 43 +++++++++++++++++++-- src/Tests/PolyfillExtensionsTests_String.cs | 11 ++++++ 5 files changed, 60 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index 85bb5229..674f61ef 100644 --- a/readme.md +++ b/readme.md @@ -350,7 +350,10 @@ The class `PolyfillExtensions` includes the following extension methods: * `bool StartsWith(this string, char)` * `bool EndsWith(this string, char)` - * `public int GetHashCode(this string, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) + * `int GetHashCode(this string, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) + * `string[] Split(this string, char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split?system-string-split(system-char-system-stringsplitoptions)) + * `string[] Split(char, int, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split?system-string-split(system-char-system-int32-system-stringsplitoptions)) + * `bool Contains(char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains?system-string-contains(system-char)) ### ReadOnlySpan diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index c6bad6a7..24b04095 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -61,6 +61,10 @@ class Consume var index = "value"[^2]; var startsWith = "value".StartsWith('a'); var endsWith = "value".EndsWith('a'); + + var split = "a b".Split(' ', StringSplitOptions.RemoveEmptyEntries); + split = "a b".Split(' ', 2, StringSplitOptions.RemoveEmptyEntries); + var contains = "a b".Contains(' '); } void KeyValuePairDeconstruct(IEnumerable> variables) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 3d7de255..75ca198a 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.5.0 + 1.6.0 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/PolyfillExtensions_String.cs index 08429ae6..d76887db 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/PolyfillExtensions_String.cs @@ -1,4 +1,3 @@ -#if NETFRAMEWORK || NETSTANDARD2_0 #pragma warning disable @@ -10,6 +9,8 @@ static partial class PolyfillExtensions { +#if NETFRAMEWORK || NETSTANDARD2_0 + public static int GetHashCode(this string target, StringComparison comparisonType) => FromComparison(comparisonType).GetHashCode(target); @@ -48,5 +49,41 @@ public static bool EndsWith(this string target, char value) return lastPos < target.Length && target[lastPos] == value; } -} -#endif \ No newline at end of file + + /// + /// Splits a string into a maximum number of substrings based on a specified delimiting character and, optionally, + /// options. Splits a string into a maximum number of substrings based on the provided character separator, + /// optionally omitting empty substrings from the result. + /// + /// A character that delimits the substrings in this instance. + /// A bitwise combination of the enumeration values that specifies whether to trim substrings + /// and include empty substrings. + /// An array that contains at most count substrings from this instance that are delimited by separator. + public static string[] Split(this string target, char separator, StringSplitOptions options = StringSplitOptions.None) => + target.Split(new[] {separator}, options); + + /// + /// Splits a string into a maximum number of substrings based on a specified delimiting character and, optionally, + /// options. Splits a string into a maximum number of substrings based on the provided character separator, + /// optionally omitting empty substrings from the result. + /// + /// A character that delimits the substrings in this instance. + /// The maximum number of elements expected in the array. + /// A bitwise combination of the enumeration values that specifies whether to trim substrings + /// and include empty substrings. + /// An array that contains at most count substrings from this instance that are delimited by separator. + public static string[] Split(this string target, char separator, int count, StringSplitOptions options = StringSplitOptions.None) => + target.Split(new[] {separator}, count, options); +#endif + +#if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0 + /// + /// Returns a value indicating whether a specified character occurs within this string. + /// + /// This method performs an ordinal (case-sensitive and culture-insensitive) comparison. + /// The character to seek. + /// true if the value parameter occurs within this string; otherwise, false. + public static bool Contains(this string target, char value) => + target.IndexOf(value) >= 0; +#endif +} \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_String.cs b/src/Tests/PolyfillExtensionsTests_String.cs index 2754644f..c897d4a3 100644 --- a/src/Tests/PolyfillExtensionsTests_String.cs +++ b/src/Tests/PolyfillExtensionsTests_String.cs @@ -26,4 +26,15 @@ public void StartsWith() Assert.True("value".StartsWith('v')); Assert.False("".StartsWith('v')); } + + [Test] + public void Split() + { + Assert.AreEqual(new []{"a","b"}, "a b".Split(' ', StringSplitOptions.RemoveEmptyEntries)); + Assert.AreEqual(new []{"a","b"}, "a b".Split(' ', 2, StringSplitOptions.RemoveEmptyEntries)); + } + + [Test] + public void ContainsChar() => + Assert.True("value".Contains('v')); } From 49982a99e17a661cb799aa455d1317b775734e0f Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 27 Mar 2023 21:48:53 +1100 Subject: [PATCH 022/313] add IReadOnlyDictionary GetValueOrDefault (#9) --- readme.md | 5 ++ src/Consume/Consume.cs | 10 ++++ .../PolyfillExtensions_IReadOnlyDictionary.cs | 58 +++++++++++++++++++ ...fillExtensionsTests_IReadOnlyDictionary.cs | 15 +++++ 4 files changed, 88 insertions(+) create mode 100644 src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs create mode 100644 src/Tests/PolyfillExtensionsTests_IReadOnlyDictionary.cs diff --git a/readme.md b/readme.md index 674f61ef..969544d1 100644 --- a/readme.md +++ b/readme.md @@ -346,6 +346,11 @@ Reference: [Improvements in native code interop in .NET 5.0](https://devblogs.mi The class `PolyfillExtensions` includes the following extension methods: +### IReadOnlyDictionary + + * ` TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) + + ### String * `bool StartsWith(this string, char)` diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 24b04095..af671bc4 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics; @@ -62,6 +64,14 @@ class Consume var startsWith = "value".StartsWith('a'); var endsWith = "value".EndsWith('a'); + var dictionary = new Dictionary + { + {"key", "value"} + }; + + dictionary.GetValueOrDefault("key"); + dictionary.GetValueOrDefault("key", "default"); + var split = "a b".Split(' ', StringSplitOptions.RemoveEmptyEntries); split = "a b".Split(' ', 2, StringSplitOptions.RemoveEmptyEntries); var contains = "a b".Contains(' '); diff --git a/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs b/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs new file mode 100644 index 00000000..21a78b5b --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs @@ -0,0 +1,58 @@ +#if NETFRAMEWORK || NETSTANDARD2_0 + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable UnusedMember.Global + +using System; +using System.Collections.Generic; + +static partial class PolyfillExtensions +{ + /// + /// Tries to get the value associated with the specified key in the dictionary. + /// + /// A dictionary with keys of type TKey and values of type TValue. + /// The key of the value to get. + /// The type of the keys in the dictionary. + /// The type of the values in the dictionary. + /// A TValue instance. When the method is successful, the returned object is the value associated with + /// the specified key. When the method fails, it returns the default value for TValue. + public static TValue? GetValueOrDefault( + this IReadOnlyDictionary target, + TKey key) + { + if (target.TryGetValue(key, out var result)) + { + return result; + } + + return default; + } + + /// + /// Tries to get the value associated with the specified key in the dictionary. + /// + /// A dictionary with keys of type TKey and values of type TValue. + /// The key of the value to get. + /// A dictionary with keys of type TKey and values of type TValue. + /// The type of the keys in the dictionary. + /// The type of the values in the dictionary. + /// A TValue instance. When the method is successful, the returned object is the value associated with + /// the specified key. When the method fails, it returns the default value for TValue. + public static TValue GetValueOrDefault( + this IReadOnlyDictionary target, + TKey key, + TValue defaultValue = default) + { + if (target.TryGetValue(key, out var result)) + { + return result!; + } + + return defaultValue; + } +} +#endif \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_IReadOnlyDictionary.cs b/src/Tests/PolyfillExtensionsTests_IReadOnlyDictionary.cs new file mode 100644 index 00000000..4c52bf96 --- /dev/null +++ b/src/Tests/PolyfillExtensionsTests_IReadOnlyDictionary.cs @@ -0,0 +1,15 @@ +partial class PolyfillExtensionsTests +{ + [Test] + public void IReadOnlyDictionaryGetValueOrDefault() + { + var dictionary = new Dictionary + { + {"key", "value"} + }; + + Assert.AreEqual("value", dictionary.GetValueOrDefault("key")); + Assert.AreEqual(null, dictionary.GetValueOrDefault("key1")); + Assert.AreEqual("value1", dictionary.GetValueOrDefault("key1","value1")); + } +} From 9c58335a137e9bc2769a85dc6fd362741bc20052 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 27 Mar 2023 22:01:07 +1100 Subject: [PATCH 023/313] Add IEnumerable Append (#10) --- readme.md | 5 +++ src/Consume/Consume.cs | 7 ++++ .../PolyfillExtensions_IEnumerable.cs | 33 +++++++++++++++++++ .../PolyfillExtensionsTests_IEnumerable.cs | 10 ++++++ 4 files changed, 55 insertions(+) create mode 100644 src/Polyfill/PolyfillExtensions_IEnumerable.cs create mode 100644 src/Tests/PolyfillExtensionsTests_IEnumerable.cs diff --git a/readme.md b/readme.md index 969544d1..45507914 100644 --- a/readme.md +++ b/readme.md @@ -346,6 +346,11 @@ Reference: [Improvements in native code interop in .NET 5.0](https://devblogs.mi The class `PolyfillExtensions` includes the following extension methods: +### IEnumerable + + * `IEnumerable Append(this IEnumerable, TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.append) + + ### IReadOnlyDictionary * ` TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index af671bc4..f09d423c 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -1,3 +1,4 @@ +// ReSharper disable RedundantUsingDirective #nullable enable using System; @@ -5,6 +6,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; @@ -61,9 +63,14 @@ class Consume var range = "value"[1..]; var index = "value"[^2]; + var startsWith = "value".StartsWith('a'); var endsWith = "value".EndsWith('a'); + + var enumerable = (IEnumerable)new List {"a", "b"}; + var append = enumerable.Append("c"); + var dictionary = new Dictionary { {"key", "value"} diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs new file mode 100644 index 00000000..827a7bfc --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -0,0 +1,33 @@ +#if NET46X || NET47 + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable UnusedMember.Global + +using System; +using System.Collections.Generic; + +static partial class PolyfillExtensions +{ + /// + /// Appends a value to the end of the sequence. + /// + /// A sequence of values. + /// The value to append to source. + /// The type of the elements of source. + /// A new sequence that ends with element. + public static IEnumerable Append( + this IEnumerable source, + TSource element) + { + foreach (var item in source) + { + yield return item; + } + + yield return element; + } +} +#endif \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_IEnumerable.cs b/src/Tests/PolyfillExtensionsTests_IEnumerable.cs new file mode 100644 index 00000000..5e4b7175 --- /dev/null +++ b/src/Tests/PolyfillExtensionsTests_IEnumerable.cs @@ -0,0 +1,10 @@ +partial class PolyfillExtensionsTests +{ + [Test] + public void IEnumerableAppend() + { + var enumerable = (IEnumerable)new List {"a", "b"}; + + Assert.IsTrue(enumerable.Append("c").SequenceEqual(new List {"a", "b", "c"})); + } +} From d29811cdb77cda78737a717c65553a86a74bfb22 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 27 Mar 2023 23:00:38 +1100 Subject: [PATCH 024/313] add SkipLast (#11) --- readme.md | 1 + src/Consume/Consume.cs | 1 + src/Directory.Build.props | 2 +- .../PolyfillExtensions_IEnumerable.cs | 22 ++++++++++++++++--- .../PolyfillExtensionsTests_IEnumerable.cs | 8 +++++++ 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 45507914..c50948be 100644 --- a/readme.md +++ b/readme.md @@ -349,6 +349,7 @@ The class `PolyfillExtensions` includes the following extension methods: ### IEnumerable * `IEnumerable Append(this IEnumerable, TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.append) + * ` IEnumerable SkipLast(this IEnumerable, int)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) ### IReadOnlyDictionary diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index f09d423c..15988374 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -70,6 +70,7 @@ class Consume var enumerable = (IEnumerable)new List {"a", "b"}; var append = enumerable.Append("c"); + var skipLast = enumerable.SkipLast(1); var dictionary = new Dictionary { diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 75ca198a..3432b806 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.6.0 + 1.7.0 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index 827a7bfc..d1b1ff87 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -1,4 +1,3 @@ -#if NET46X || NET47 #pragma warning disable @@ -8,9 +7,12 @@ using System; using System.Collections.Generic; +using System.Linq; static partial class PolyfillExtensions { +#if NET46X || NET47 + /// /// Appends a value to the end of the sequence. /// @@ -29,5 +31,19 @@ public static IEnumerable Append( yield return element; } -} -#endif \ No newline at end of file +#endif + +#if NETFRAMEWORK || NETSTANDARD2_0 + /// + /// Returns a new enumerable collection that contains the elements from source with the last count elements of the + /// source collection omitted. + /// + /// An enumerable collection instance. + /// The number of elements to omit from the end of the collection. + /// The type of the elements in the enumerable collection. + /// A new enumerable collection that contains the elements from source minus count elements from the end + /// of the collection. + public static IEnumerable SkipLast(this IEnumerable source, int count) => + source.Reverse().Skip(count).Reverse(); +#endif +} \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_IEnumerable.cs b/src/Tests/PolyfillExtensionsTests_IEnumerable.cs index 5e4b7175..b5e13ffe 100644 --- a/src/Tests/PolyfillExtensionsTests_IEnumerable.cs +++ b/src/Tests/PolyfillExtensionsTests_IEnumerable.cs @@ -7,4 +7,12 @@ public void IEnumerableAppend() Assert.IsTrue(enumerable.Append("c").SequenceEqual(new List {"a", "b", "c"})); } + + [Test] + public void IEnumerableSkipLast() + { + var enumerable = (IEnumerable)new List {"a", "b"}; + + Assert.IsTrue(enumerable.SkipLast(1).SequenceEqual(new List {"a"})); + } } From 1a1db2b3f66d9f3e5b0e9fe2a97b5544e7306374 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 29 Mar 2023 18:14:48 +1100 Subject: [PATCH 025/313] Update appveyor.yml --- src/appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/appveyor.yml b/src/appveyor.yml index 063702e9..b1fa26e0 100644 --- a/src/appveyor.yml +++ b/src/appveyor.yml @@ -1,7 +1,7 @@ image: - Visual Studio 2022 -#- macOS -#- Ubuntu +- macOS +- Ubuntu environment: DOTNET_NOLOGO: true DOTNET_CLI_TELEMETRY_OPTOUT: true From 9badde6874d4992bb06491203ef7efc2be6e7a94 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 29 Mar 2023 18:46:55 +1100 Subject: [PATCH 026/313] Resolve http global problem (#13) --- src/Consume/Consume.csproj | 1 - src/Directory.Build.props | 2 +- src/NoRefsTests/NoRefsTests.csproj | 1 - src/Polyfill/ResolveHttpGlobalProblem.cs | 19 +++++++++++++++++++ src/PublicTests/PublicTests.csproj | 1 - src/Tests/Tests.csproj | 1 - src/UnsafeTests/UnsafeTests.csproj | 1 - 7 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 src/Polyfill/ResolveHttpGlobalProblem.cs diff --git a/src/Consume/Consume.csproj b/src/Consume/Consume.csproj index d8f98c6f..5007011a 100644 --- a/src/Consume/Consume.csproj +++ b/src/Consume/Consume.csproj @@ -5,7 +5,6 @@ $(TargetFrameworks);netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 - diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 3432b806..0d43fedc 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.7.0 + 1.8.0 1.0.0 Polyfill true diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 71d370bf..0998442b 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -4,7 +4,6 @@ $(TargetFrameworks);netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 - Pollyfill\%(RecursiveDir)%(Filename).cs diff --git a/src/Polyfill/ResolveHttpGlobalProblem.cs b/src/Polyfill/ResolveHttpGlobalProblem.cs new file mode 100644 index 00000000..140d0070 --- /dev/null +++ b/src/Polyfill/ResolveHttpGlobalProblem.cs @@ -0,0 +1,19 @@ +#if NETFRAMEWORK + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable UnusedMember.Global + +using System.ComponentModel; + +namespace System.Net.Http +{ + [EditorBrowsable(EditorBrowsableState.Never)] + static class ResolveHttpGlobalProblem + { + } +} + +#endif \ No newline at end of file diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index bb434acf..5ac032ed 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -5,7 +5,6 @@ true - Pollyfill\%(RecursiveDir)%(Filename).cs diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 51db5641..d6158f0a 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -4,7 +4,6 @@ $(TargetFrameworks);netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 - Pollyfill\%(RecursiveDir)%(Filename).cs diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 8c99a93b..427ab820 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -5,7 +5,6 @@ True - Pollyfill\%(RecursiveDir)%(Filename).cs From d9d5d187a3215b82b27f3e31679a1f72e153a2fd Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 29 Mar 2023 19:26:33 +1100 Subject: [PATCH 027/313] Update Tests.csproj --- src/Tests/Tests.csproj | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index d6158f0a..78b3c1b4 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -24,9 +24,11 @@ - + - + From 8f862a423b2c65f8683f55f8f40bb7a5ffad6066 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 29 Mar 2023 20:51:18 +1100 Subject: [PATCH 028/313] Update readme.md --- readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readme.md b/readme.md index c50948be..6686ca57 100644 --- a/readme.md +++ b/readme.md @@ -197,6 +197,8 @@ class SkipLocalsInitSample Reference: [Indices and ranges](https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/ranges-indexes) +If consuming in a project that targets net461 or net462, a reference to System.ValueTuple is required. See [References: System.ValueTuple](#systemvaluetuple). + ```cs From 6f378599fad876645d99305b08bd4138e9409864 Mon Sep 17 00:00:00 2001 From: Stuart Lang Date: Thu, 30 Mar 2023 10:55:52 +0100 Subject: [PATCH 029/313] Update readme.md (#15) --- readme.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/readme.md b/readme.md index 6686ca57..17fd260f 100644 --- a/readme.md +++ b/readme.md @@ -3,7 +3,7 @@ [![Build status](https://ci.appveyor.com/api/projects/status/s6eqqg4ipeovebgd?svg=true)](https://ci.appveyor.com/project/SimonCropp/Polyfill) [![Polyfill NuGet Status](https://img.shields.io/nuget/v/Polyfill.svg)](https://www.nuget.org/packages/Polyfill/) -Source only package that exposes newer .net and C# features to older runtimes. +Source only package that exposes newer .NET and C# features to older runtimes. The package targets `netstandard2.0` and is designed to support the following runtimes. @@ -19,12 +19,12 @@ https://nuget.org/packages/Polyfill/ ### SDK / LangVersion -This project uses features from the current stable SDK and c# language. As such consuming projects should target those: +This project uses features from the current stable SDK and C# language. As such consuming projects should target those: ### LangVersion -``` +```xml latest @@ -33,7 +33,7 @@ This project uses features from the current stable SDK and c# language. As such ### global.json -``` +```json { "sdk": { "version": "7.0.202", @@ -52,7 +52,7 @@ The default type visibility for all polyfills is `internal`. This means it can b If Polyfill is being consumed in a solution that produce an app, then it is recommended to use the Polyfill nuget only in the root "app project" and enable `PolyPublic`. -``` +```xml true @@ -356,7 +356,7 @@ The class `PolyfillExtensions` includes the following extension methods: ### IReadOnlyDictionary - * ` TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) + * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) ### String @@ -417,7 +417,7 @@ If any of the below reference are not included, the related polyfills will be di If consuming in a project that targets `net461` or `net462`, a reference to [System.ValueTuple](https://www.nuget.org/packages/System.ValueTuple/) nuget is required. -``` +```xml @@ -428,7 +428,7 @@ If consuming in a project that targets `net461` or `net462`, a reference to [Sys If using Span APIs and consuming in a project that targets `netstandard`, `netframework`, or `netcoreapp2*`, a reference to [System.Memory](https://www.nuget.org/packages/System.Memory/) nuget is required. -``` +```xml Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From df7fa5bcc3e29687bf2b5d8d71004a041c60c457 Mon Sep 17 00:00:00 2001 From: Oleksii Holub <1935960+Tyrrrz@users.noreply.github.com> Date: Sat, 1 Apr 2023 09:28:36 +0300 Subject: [PATCH 031/313] Add polyfills for `HttpContent` & `HttpClient` (#16) --- src/Consume/Consume.csproj | 1 + src/Polyfill/Polyfill.props | 1 + src/Polyfill/Polyfill.targets | 4 + src/Polyfill/PolyfillExtensions_HttpClient.cs | 173 ++++++++++++++++++ .../PolyfillExtensions_HttpContent.cs | 63 +++++++ src/PublicTests/PublicTests.csproj | 1 + .../PolyfillExtensionsTests_HttpClient.cs | 130 +++++++++++++ src/Tests/Tests.csproj | 7 +- src/UnsafeTests/UnsafeTests.csproj | 3 + 9 files changed, 379 insertions(+), 4 deletions(-) create mode 100644 src/Polyfill/PolyfillExtensions_HttpClient.cs create mode 100644 src/Polyfill/PolyfillExtensions_HttpContent.cs create mode 100644 src/Tests/PolyfillExtensionsTests_HttpClient.cs diff --git a/src/Consume/Consume.csproj b/src/Consume/Consume.csproj index 2f5ed565..7c9fd914 100644 --- a/src/Consume/Consume.csproj +++ b/src/Consume/Consume.csproj @@ -7,6 +7,7 @@ + Pollyfill\%(RecursiveDir)%(Filename).cs diff --git a/src/Polyfill/Polyfill.props b/src/Polyfill/Polyfill.props index ad28323d..3f82ce4c 100644 --- a/src/Polyfill/Polyfill.props +++ b/src/Polyfill/Polyfill.props @@ -9,6 +9,7 @@ false false false + false $(TargetFramework.ToLower()) diff --git a/src/Polyfill/Polyfill.targets b/src/Polyfill/Polyfill.targets index 94d5a590..b91b8cc0 100644 --- a/src/Polyfill/Polyfill.targets +++ b/src/Polyfill/Polyfill.targets @@ -14,6 +14,10 @@ Condition="@(PackageReference->WithMetadataValue('Identity', 'System.Threading.Tasks.Extensions')->Count()) != 0">true $(DefineConstants);TASKSEXTENSIONSREFERENCED + true + $(DefineConstants);HTTPREFERENCED \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_HttpClient.cs b/src/Polyfill/PolyfillExtensions_HttpClient.cs new file mode 100644 index 00000000..c2cbd75d --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_HttpClient.cs @@ -0,0 +1,173 @@ +#if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD2_0 || NETCOREAPP2X || NETCOREAPP3X) + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable UnusedMember.Global + +using System; +using System.IO; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +static partial class PolyfillExtensions +{ + /// + /// Send a GET request to the specified Uri and return the response body as a stream in an asynchronous operation. + /// + /// + /// This operation will not block. The returned object will complete after the response headers are read. + /// This method does not read nor buffer the response body. + /// + /// The Uri the request is sent to. + /// The cancellation token to cancel the operation. + /// The task object representing the asynchronous operation. + public static async Task GetStreamAsync( + this HttpClient httpClient, + string requestUri, + CancellationToken cancellationToken = default) + { + try + { + // Must not be disposed for the stream to be usable + var response = await httpClient.GetAsync( + requestUri, + HttpCompletionOption.ResponseHeadersRead, + cancellationToken + ).ConfigureAwait(false); + + response.EnsureSuccessStatusCode(); + + return await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); + } + // Older versions of HttpClient methods don't propagate the cancellation token inside the exception + catch (OperationCanceledException ex) when ( + ex.CancellationToken != cancellationToken && + cancellationToken.IsCancellationRequested) + { + throw new OperationCanceledException(ex.Message, ex.InnerException, cancellationToken); + } + } + + /// + /// Send a GET request to the specified Uri and return the response body as a stream in an asynchronous operation. + /// + /// + /// This operation will not block. The returned object will complete after the response headers are read. + /// This method does not read nor buffer the response body. + /// + /// The Uri the request is sent to. + /// The cancellation token to cancel the operation. + /// The task object representing the asynchronous operation. + public static async Task GetStreamAsync( + this HttpClient httpClient, + Uri requestUri, + CancellationToken cancellationToken = default) => + await httpClient.GetStreamAsync(requestUri.ToString(), cancellationToken).ConfigureAwait(false); + + /// + /// Send a GET request to the specified Uri and return the response body as a byte array in an asynchronous operation. + /// + /// + /// This operation will not block. The returned object will complete after the response headers are read. + /// This method does not read nor buffer the response body. + /// + /// The Uri the request is sent to. + /// The cancellation token to cancel the operation. + /// The task object representing the asynchronous operation. + public static async Task GetByteArrayAsync( + this HttpClient httpClient, + string requestUri, + CancellationToken cancellationToken = default) + { + try + { + using var response = await httpClient.GetAsync( + requestUri, + HttpCompletionOption.ResponseHeadersRead, + cancellationToken + ).ConfigureAwait(false); + + response.EnsureSuccessStatusCode(); + + return await response.Content.ReadAsByteArrayAsync(cancellationToken).ConfigureAwait(false); + } + // Older versions of HttpClient methods don't propagate the cancellation token inside the exception + catch (OperationCanceledException ex) when ( + ex.CancellationToken != cancellationToken && + cancellationToken.IsCancellationRequested) + { + throw new OperationCanceledException(ex.Message, ex.InnerException, cancellationToken); + } + } + + /// + /// Send a GET request to the specified Uri and return the response body as a byte array in an asynchronous operation. + /// + /// + /// This operation will not block. The returned object will complete after the response headers are read. + /// This method does not read nor buffer the response body. + /// + /// The Uri the request is sent to. + /// The cancellation token to cancel the operation. + /// The task object representing the asynchronous operation. + public static async Task GetByteArrayAsync( + this HttpClient httpClient, + Uri requestUri, + CancellationToken cancellationToken = default) => + await httpClient.GetByteArrayAsync(requestUri.ToString(), cancellationToken).ConfigureAwait(false); + + /// + /// Send a GET request to the specified Uri and return the response body as a string in an asynchronous operation. + /// + /// + /// This operation will not block. The returned object will complete after the response headers are read. + /// This method does not read nor buffer the response body. + /// + /// The Uri the request is sent to. + /// The cancellation token to cancel the operation. + /// The task object representing the asynchronous operation. + public static async Task GetStringAsync( + this HttpClient httpClient, + string requestUri, + CancellationToken cancellationToken = default) + { + try + { + using var response = await httpClient.GetAsync( + requestUri, + HttpCompletionOption.ResponseHeadersRead, + cancellationToken + ).ConfigureAwait(false); + + response.EnsureSuccessStatusCode(); + + return await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + } + // Older versions of HttpClient methods don't propagate the cancellation token inside the exception + catch (OperationCanceledException ex) when ( + ex.CancellationToken != cancellationToken && + cancellationToken.IsCancellationRequested) + { + throw new OperationCanceledException(ex.Message, ex.InnerException, cancellationToken); + } + } + + /// + /// Send a GET request to the specified Uri and return the response body as a string in an asynchronous operation. + /// + /// + /// This operation will not block. The returned object will complete after the response headers are read. + /// This method does not read nor buffer the response body. + /// + /// The Uri the request is sent to. + /// The cancellation token to cancel the operation. + /// The task object representing the asynchronous operation. + public static async Task GetStringAsync( + this HttpClient httpClient, + Uri requestUri, + CancellationToken cancellationToken = default) => + await httpClient.GetStringAsync(requestUri.ToString(), cancellationToken).ConfigureAwait(false); +} +#endif \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_HttpContent.cs b/src/Polyfill/PolyfillExtensions_HttpContent.cs new file mode 100644 index 00000000..5c0d565b --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_HttpContent.cs @@ -0,0 +1,63 @@ +#if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD2_0 || NETCOREAPP2X || NETCOREAPP3X) + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable UnusedMember.Global + +using System.IO; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +static partial class PolyfillExtensions +{ + /// + /// Serializes the HTTP content and returns a stream that represents the content. + /// + /// + /// Note that this method will internally buffer the content unless CreateContentReadStreamAsync() has been implemented to do otherwise. + /// + /// The token to monitor for cancellation requests. The default value is None. + /// The task object representing the asynchronous operation. + public static async Task ReadAsStreamAsync( + this HttpContent httpContent, + CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + return await httpContent.ReadAsStreamAsync().ConfigureAwait(false); + } + + /// + /// Serializes the HTTP content to a byte array as an asynchronous operation. + /// + /// + /// Note that this method will internally buffer the content unless CreateContentReadStreamAsync() has been implemented to do otherwise. + /// + /// The token to monitor for cancellation requests. The default value is None. + /// The task object representing the asynchronous operation. + public static async Task ReadAsByteArrayAsync( + this HttpContent httpContent, + CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + return await httpContent.ReadAsByteArrayAsync().ConfigureAwait(false); + } + + /// + /// Serializes the HTTP content to a string as an asynchronous operation. + /// + /// + /// Note that this method will internally buffer the content unless CreateContentReadStreamAsync() has been implemented to do otherwise. + /// + /// The token to monitor for cancellation requests. The default value is None. + /// The task object representing the asynchronous operation. + public static async Task ReadAsStringAsync( + this HttpContent httpContent, + CancellationToken cancellationToken = default) + { + cancellationToken.ThrowIfCancellationRequested(); + return await httpContent.ReadAsStringAsync().ConfigureAwait(false); + } +} +#endif \ No newline at end of file diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 5ac032ed..a384298e 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -27,6 +27,7 @@ + diff --git a/src/Tests/PolyfillExtensionsTests_HttpClient.cs b/src/Tests/PolyfillExtensionsTests_HttpClient.cs new file mode 100644 index 00000000..3149b320 --- /dev/null +++ b/src/Tests/PolyfillExtensionsTests_HttpClient.cs @@ -0,0 +1,130 @@ +// These tests cover HttpContent polyfills as well + +using System.Net; +using System.Net.Http; + +partial class PolyfillExtensionsTests +{ + private class FakeHttpMessageHandler : HttpMessageHandler + { + protected override Task SendAsync( + HttpRequestMessage request, + CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + + return Task.FromResult( + new HttpResponseMessage(HttpStatusCode.OK) + { + RequestMessage = request, + Content = new StringContent("Fake Content") + } + ); + } + } + + [Test] + public async Task HttpClientGetStreamAsync_Positive() + { + // Arrange + var cancellationToken = new CancellationToken(); + using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); + + // Act + using var stream = await httpClient.GetStreamAsync("https://example.com", cancellationToken); + using var reader = new StreamReader(stream); + var content = await reader.ReadToEndAsync(); + + // Assert + Assert.AreEqual("Fake Content", content); + } + + [Test] + public async Task HttpClientGetStreamAsync_Negative() + { + // Arrange + var cancellationToken = new CancellationToken(true); + using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); + + // Act + try + { + await httpClient.GetStreamAsync("https://example.com", cancellationToken); + Assert.Fail(); + } + catch (OperationCanceledException ex) + { + // Assert + Assert.IsTrue(ex.CancellationToken.IsCancellationRequested); + } + } + + [Test] + public async Task HttpClientGetByteArrayAsync_Positive() + { + // Arrange + var cancellationToken = new CancellationToken(); + using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); + + // Act + var bytes = await httpClient.GetByteArrayAsync("https://example.com", cancellationToken); + var content = Encoding.UTF8.GetString(bytes); + + // Assert + Assert.AreEqual("Fake Content", content); + } + + [Test] + public async Task HttpClientGetByteArrayAsync_Negative() + { + // Arrange + var cancellationToken = new CancellationToken(true); + using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); + + // Act + try + { + await httpClient.GetByteArrayAsync("https://example.com", cancellationToken); + Assert.Fail(); + } + catch (OperationCanceledException ex) + { + // Assert + Assert.IsTrue(ex.CancellationToken.IsCancellationRequested); + } + } + + [Test] + public async Task HttpClientGetStringAsync_Positive() + { + // Arrange + var cancellationToken = new CancellationToken(); + using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); + + // Act + var content = await httpClient.GetStringAsync("https://example.com", cancellationToken); + + // Assert + Assert.AreEqual("Fake Content", content); + } + + [Test] + public async Task HttpClientGetStringAsync_Negative() + { + // Arrange + var cancellationToken = new CancellationToken(true); + using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); + + // Act + try + { + await httpClient.GetStringAsync("https://example.com", cancellationToken); + Assert.Fail(); + } + catch (OperationCanceledException ex) + { + // Assert + Assert.IsTrue(ex.CancellationToken.IsCancellationRequested); + } + } +} \ No newline at end of file diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 78b3c1b4..65c0eb38 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -24,11 +24,10 @@ - + - + + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 427ab820..7ebceb23 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -37,6 +37,9 @@ + + + true + net461;net462;net47;net471;net472;net48;net481;net6.0-windows + $(TargetFrameworks);netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 + + + + + + + + + Pollyfill\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs + + + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs + + + Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs + + + + + \ No newline at end of file diff --git a/src/Polyfill.sln b/src/Polyfill.sln index c5fb7d40..1b1b4388 100644 --- a/src/Polyfill.sln +++ b/src/Polyfill.sln @@ -27,6 +27,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoRefsTests", "NoRefsTests\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PublicTests", "PublicTests\PublicTests.csproj", "{9FBD54A6-461C-4754-B77A-222E06BF89B6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeClassicReferences", "ConsumeClassicReferences\ConsumeClassicReferences.csproj", "{CF7D4778-6A32-4E7D-B80B-3507974B443B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -61,6 +63,10 @@ Global {9FBD54A6-461C-4754-B77A-222E06BF89B6}.Debug|Any CPU.Build.0 = Debug|Any CPU {9FBD54A6-461C-4754-B77A-222E06BF89B6}.Release|Any CPU.ActiveCfg = Release|Any CPU {9FBD54A6-461C-4754-B77A-222E06BF89B6}.Release|Any CPU.Build.0 = Release|Any CPU + {CF7D4778-6A32-4E7D-B80B-3507974B443B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CF7D4778-6A32-4E7D-B80B-3507974B443B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CF7D4778-6A32-4E7D-B80B-3507974B443B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CF7D4778-6A32-4E7D-B80B-3507974B443B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From e5e0f467fdd4c2852c838978214483090b9eb776 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 1 Apr 2023 19:52:01 +1100 Subject: [PATCH 033/313] docs --- .../PolyfillExtensions_HttpContent.cs | 21 +++++++++++++------ src/Polyfill/PolyfillExtensions_Stream.cs | 6 +++--- .../PolyfillExtensions_StreamReader.cs | 9 ++++++++ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_HttpContent.cs b/src/Polyfill/PolyfillExtensions_HttpContent.cs index 5c0d565b..e6fe10a5 100644 --- a/src/Polyfill/PolyfillExtensions_HttpContent.cs +++ b/src/Polyfill/PolyfillExtensions_HttpContent.cs @@ -16,9 +16,12 @@ static partial class PolyfillExtensions /// Serializes the HTTP content and returns a stream that represents the content. /// /// - /// Note that this method will internally buffer the content unless CreateContentReadStreamAsync() has been implemented to do otherwise. + /// Note that this method will internally buffer the content unless CreateContentReadStreamAsync() has been + /// implemented to do otherwise. /// - /// The token to monitor for cancellation requests. The default value is None. + /// + /// The token to monitor for cancellation requests. The default value is . + /// /// The task object representing the asynchronous operation. public static async Task ReadAsStreamAsync( this HttpContent httpContent, @@ -32,9 +35,12 @@ public static async Task ReadAsStreamAsync( /// Serializes the HTTP content to a byte array as an asynchronous operation. /// /// - /// Note that this method will internally buffer the content unless CreateContentReadStreamAsync() has been implemented to do otherwise. + /// Note that this method will internally buffer the content unless CreateContentReadStreamAsync() has been + /// implemented to do otherwise. /// - /// The token to monitor for cancellation requests. The default value is None. + /// + /// The token to monitor for cancellation requests. The default value is . + /// /// The task object representing the asynchronous operation. public static async Task ReadAsByteArrayAsync( this HttpContent httpContent, @@ -48,9 +54,12 @@ public static async Task ReadAsByteArrayAsync( /// Serializes the HTTP content to a string as an asynchronous operation. /// /// - /// Note that this method will internally buffer the content unless CreateContentReadStreamAsync() has been implemented to do otherwise. + /// Note that this method will internally buffer the content unless CreateContentReadStreamAsync() has been + /// implemented to do otherwise. /// - /// The token to monitor for cancellation requests. The default value is None. + /// + /// The token to monitor for cancellation requests. The default value is . + /// /// The task object representing the asynchronous operation. public static async Task ReadAsStringAsync( this HttpContent httpContent, diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index fccfbd5d..50b0880b 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -19,7 +19,7 @@ static partial class PolyfillExtensions /// /// The region of memory to write the data into. /// - /// The token to monitor for cancellation requests. The default value is None. + /// The token to monitor for cancellation requests. The default value is . /// /// /// A task that represents the asynchronous read operation. The value of its Result property contains the @@ -46,7 +46,7 @@ public static ValueTask ReadAsync( /// /// The region of memory to write data from. /// - /// The token to monitor for cancellation requests. The default value is None. + /// The token to monitor for cancellation requests. The default value is . /// /// A task that represents the asynchronous write operation. public static ValueTask WriteAsync( @@ -68,7 +68,7 @@ public static ValueTask WriteAsync( /// /// The stream to which the contents of the current stream will be copied. /// - /// The token to monitor for cancellation requests. The default value is None. + /// The token to monitor for cancellation requests. The default value is . /// /// A task that represents the asynchronous copy operation. public static Task CopyToAsync( diff --git a/src/Polyfill/PolyfillExtensions_StreamReader.cs b/src/Polyfill/PolyfillExtensions_StreamReader.cs index 32dd6e45..74611b67 100644 --- a/src/Polyfill/PolyfillExtensions_StreamReader.cs +++ b/src/Polyfill/PolyfillExtensions_StreamReader.cs @@ -13,6 +13,15 @@ static partial class PolyfillExtensions { + /// + /// Asynchronously reads the characters from the current stream into a memory block. + /// + /// + /// When this method returns, contains the specified memory block of characters replaced by the characters read + /// from the current source. + /// + /// The token to monitor for cancellation requests. The default value is . + /// public static ValueTask ReadAsync( this StreamReader target, Memory buffer, From efe20243782b79370b843eb8c9c43671aa2702ad Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 1 Apr 2023 19:53:19 +1100 Subject: [PATCH 034/313] Update PolyfillExtensions_StreamReader.cs --- src/Polyfill/PolyfillExtensions_StreamReader.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_StreamReader.cs b/src/Polyfill/PolyfillExtensions_StreamReader.cs index 74611b67..157a7b6b 100644 --- a/src/Polyfill/PolyfillExtensions_StreamReader.cs +++ b/src/Polyfill/PolyfillExtensions_StreamReader.cs @@ -20,8 +20,15 @@ static partial class PolyfillExtensions /// When this method returns, contains the specified memory block of characters replaced by the characters read /// from the current source. /// - /// The token to monitor for cancellation requests. The default value is . - /// + /// + /// The token to monitor for cancellation requests. The default value is . + /// + /// + /// A value task that represents the asynchronous read operation. The value of the type parameter of the value task + /// contains the number of characters that have been read, or 0 if at the end of the stream and no data was read. + /// The number will be less than or equal to the length, depending on whether the data is + /// available within the stream. + /// public static ValueTask ReadAsync( this StreamReader target, Memory buffer, From cf54a907982bae22297fae528094dca9677d6b05 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 1 Apr 2023 20:25:09 +1100 Subject: [PATCH 035/313] add StreamReader.ReadToEndAsync(CancellationToken) (#17) --- contributing.md | 16 ++++++- readme.md | 34 +++++++-------- src/Consume/Consume.cs | 10 ++++- .../PolyfillExtensions_StreamReader.cs | 42 ++++++++++++++++--- .../PolyfillExtensionsTests_HttpClient.cs | 40 +++++++++--------- .../PolyfillExtensionsTests_StreamReader.cs | 9 ++++ 6 files changed, 106 insertions(+), 45 deletions(-) diff --git a/contributing.md b/contributing.md index ca30047b..338596ed 100644 --- a/contributing.md +++ b/contributing.md @@ -34,6 +34,11 @@ Some feature of Polyfill leverage unsafe code for better performance. For exampl Polyfill supports back to `net461` and `netcoreapp2.0`. However NUnit only support back to `net462` and `netcoreapp3.1`. The Consume project targets all frameworks that Polyfill supports, and consumes all APIs to ensure that they all compile on those frameworks +### ConsumeClassicReferences Project + +Test the scenario when references are added through `snippet source | anchor +snippet source | anchor diff --git a/readme.md b/readme.md index 17fd260f..0d7b3984 100644 --- a/readme.md +++ b/readme.md @@ -350,8 +350,8 @@ The class `PolyfillExtensions` includes the following extension methods: ### IEnumerable - * `IEnumerable Append(this IEnumerable, TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.append) - * ` IEnumerable SkipLast(this IEnumerable, int)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) + * `IEnumerable Append(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.append) + * ` IEnumerable SkipLast(int)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) ### IReadOnlyDictionary @@ -361,51 +361,51 @@ The class `PolyfillExtensions` includes the following extension methods: ### String - * `bool StartsWith(this string, char)` - * `bool EndsWith(this string, char)` - * `int GetHashCode(this string, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) - * `string[] Split(this string, char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split?system-string-split(system-char-system-stringsplitoptions)) + * `bool StartsWith(char)` + * `bool EndsWith(char)` + * `int GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) + * `string[] Split(char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split?system-string-split(system-char-system-stringsplitoptions)) * `string[] Split(char, int, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split?system-string-split(system-char-system-int32-system-stringsplitoptions)) * `bool Contains(char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains?system-string-contains(system-char)) ### ReadOnlySpan - * `bool Contains(this ReadOnlySpan, char)` - * `bool SequenceEqual(this ReadOnlySpan, string)` + * `bool Contains(char)` + * `bool SequenceEqual(string)` ### Span - * `bool SequenceEqual(this Span, string)` + * `bool SequenceEqual(string)` ### StringBuilder - * `void Append(this StringBuilder, ReadOnlySpan)`. Will perform better if `True` is enabled in the consuming project. - * `bool Equals(this StringBuilder, ReadOnlySpan)` + * `void Append(ReadOnlySpan)`. Will perform better if `True` is enabled in the consuming project. + * `bool Equals(ReadOnlySpan)` ### Stream - * `ValueTask ReadAsync(this Stream, Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) - * `ValueTask WriteAsync(this Stream, ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) ### StreamReader - * `ValueTask ReadAsync(this Stream, Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) - * `ValueTask WriteAsync(this Stream, ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `ValueTask ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readtoendasync?system-io-streamreader-readtoendasync(system-threading-cancellationtoken)) ### StreamWriter - * `ValueTask WriteAsync(this StreamWriter, ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### KeyValuePair - * `public static void Deconstruct(this KeyValuePair, out TKey, out TValue)` + * `public static void Deconstruct(out TKey, out TValue)` ## References diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 15988374..5c43d3af 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -11,6 +11,7 @@ using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; +using System.Threading; using System.Threading.Tasks; class Consume @@ -97,13 +98,18 @@ void KeyValuePairDeconstruct(IEnumerable> variables async Task StreamReaderReadAsync() { - using var stream = new MemoryStream("value"u8.ToArray()); var result = new char[5]; var memory = new Memory(result); - using var reader = new StreamReader(stream); + var reader = new StreamReader(new MemoryStream()); var read = await reader.ReadAsync(memory); } + async Task StreamReaderReadToEndAsync() + { + var reader = new StreamReader(new MemoryStream()); + var read = await reader.ReadToEndAsync(CancellationToken.None); + } + async Task StreamReadAsync() { var input = new byte[] diff --git a/src/Polyfill/PolyfillExtensions_StreamReader.cs b/src/Polyfill/PolyfillExtensions_StreamReader.cs index 157a7b6b..d736ff02 100644 --- a/src/Polyfill/PolyfillExtensions_StreamReader.cs +++ b/src/Polyfill/PolyfillExtensions_StreamReader.cs @@ -1,5 +1,3 @@ -#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) - #pragma warning disable // ReSharper disable RedundantUsingDirective @@ -13,6 +11,7 @@ static partial class PolyfillExtensions { +#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) /// /// Asynchronously reads the characters from the current stream into a memory block. /// @@ -34,7 +33,6 @@ public static ValueTask ReadAsync( Memory buffer, CancellationToken cancellationToken = default) { - // StreamReader doesn't accept cancellation token (pre-netstd2.1) cancellationToken.ThrowIfCancellationRequested(); if (!MemoryMarshal.TryGetArray((ReadOnlyMemory)buffer, out var segment)) @@ -44,5 +42,39 @@ public static ValueTask ReadAsync( return new(target.ReadAsync(segment.Array!, segment.Offset, segment.Count)); } -} -#endif \ No newline at end of file +#endif + +#if !NET7_0_OR_GREATER + /// + /// Reads all characters from the current position to the end of the stream asynchronously and returns them as one string. + /// + /// The token to monitor for cancellation requests. + /// A task that represents the asynchronous read operation. The value of the TResult parameter contains + /// a string with the characters from the current position to the end of the stream. + /// The number of characters is larger than . + /// The stream reader has been disposed. + /// The reader is currently in use by a previous read operation. + /// + /// The following example shows how to read the contents of a file by using the method. + /// + /// using CancellationTokenSource tokenSource = new (TimeSpan.FromSeconds(1)); + /// using StreamReader reader = File.OpenText("existingfile.txt"); + /// + /// Console.WriteLine(await reader.ReadToEndAsync(tokenSource.Token)); + /// + /// + /// + /// If this method is canceled via , some data + /// that has been read from the current but not stored (by the + /// ) or returned (to the caller) may be lost. + /// + public static Task ReadToEndAsync( + this StreamReader target, + CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + + return target.ReadToEndAsync(); + } +#endif +} \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_HttpClient.cs b/src/Tests/PolyfillExtensionsTests_HttpClient.cs index 3149b320..a05acc91 100644 --- a/src/Tests/PolyfillExtensionsTests_HttpClient.cs +++ b/src/Tests/PolyfillExtensionsTests_HttpClient.cs @@ -5,13 +5,13 @@ partial class PolyfillExtensionsTests { - private class FakeHttpMessageHandler : HttpMessageHandler + class FakeHttpMessageHandler : HttpMessageHandler { protected override Task SendAsync( HttpRequestMessage request, - CancellationToken cancellationToken) + CancellationToken cancellation) { - cancellationToken.ThrowIfCancellationRequested(); + cancellation.ThrowIfCancellationRequested(); return Task.FromResult( new HttpResponseMessage(HttpStatusCode.OK) @@ -27,13 +27,13 @@ protected override Task SendAsync( public async Task HttpClientGetStreamAsync_Positive() { // Arrange - var cancellationToken = new CancellationToken(); + var cancellation = new CancellationToken(); using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); // Act - using var stream = await httpClient.GetStreamAsync("https://example.com", cancellationToken); + using var stream = await httpClient.GetStreamAsync("https://example.com", cancellation); using var reader = new StreamReader(stream); - var content = await reader.ReadToEndAsync(); + var content = await reader.ReadToEndAsync(cancellation); // Assert Assert.AreEqual("Fake Content", content); @@ -43,19 +43,19 @@ public async Task HttpClientGetStreamAsync_Positive() public async Task HttpClientGetStreamAsync_Negative() { // Arrange - var cancellationToken = new CancellationToken(true); + var cancellation = new CancellationToken(true); using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); // Act try { - await httpClient.GetStreamAsync("https://example.com", cancellationToken); + await httpClient.GetStreamAsync("https://example.com", cancellation); Assert.Fail(); } - catch (OperationCanceledException ex) + catch (OperationCanceledException exception) { // Assert - Assert.IsTrue(ex.CancellationToken.IsCancellationRequested); + Assert.IsTrue(exception.CancellationToken.IsCancellationRequested); } } @@ -63,11 +63,11 @@ public async Task HttpClientGetStreamAsync_Negative() public async Task HttpClientGetByteArrayAsync_Positive() { // Arrange - var cancellationToken = new CancellationToken(); + var cancellation = new CancellationToken(); using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); // Act - var bytes = await httpClient.GetByteArrayAsync("https://example.com", cancellationToken); + var bytes = await httpClient.GetByteArrayAsync("https://example.com", cancellation); var content = Encoding.UTF8.GetString(bytes); // Assert @@ -78,19 +78,19 @@ public async Task HttpClientGetByteArrayAsync_Positive() public async Task HttpClientGetByteArrayAsync_Negative() { // Arrange - var cancellationToken = new CancellationToken(true); + var cancellation = new CancellationToken(true); using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); // Act try { - await httpClient.GetByteArrayAsync("https://example.com", cancellationToken); + await httpClient.GetByteArrayAsync("https://example.com", cancellation); Assert.Fail(); } - catch (OperationCanceledException ex) + catch (OperationCanceledException exception) { // Assert - Assert.IsTrue(ex.CancellationToken.IsCancellationRequested); + Assert.IsTrue(exception.CancellationToken.IsCancellationRequested); } } @@ -112,19 +112,19 @@ public async Task HttpClientGetStringAsync_Positive() public async Task HttpClientGetStringAsync_Negative() { // Arrange - var cancellationToken = new CancellationToken(true); + var cancellation = new CancellationToken(true); using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); // Act try { - await httpClient.GetStringAsync("https://example.com", cancellationToken); + await httpClient.GetStringAsync("https://example.com", cancellation); Assert.Fail(); } - catch (OperationCanceledException ex) + catch (OperationCanceledException exception) { // Assert - Assert.IsTrue(ex.CancellationToken.IsCancellationRequested); + Assert.IsTrue(exception.CancellationToken.IsCancellationRequested); } } } \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_StreamReader.cs b/src/Tests/PolyfillExtensionsTests_StreamReader.cs index ae20c7eb..239c85b3 100644 --- a/src/Tests/PolyfillExtensionsTests_StreamReader.cs +++ b/src/Tests/PolyfillExtensionsTests_StreamReader.cs @@ -11,4 +11,13 @@ public async Task StreamReaderReadAsync() Assert.AreEqual(5, read); Assert.IsTrue("value".SequenceEqual(result)); } + + [Test] + public async Task StreamReaderReadToEndAsync() + { + using var stream = new MemoryStream("value"u8.ToArray()); + using var reader = new StreamReader(stream); + var read = await reader.ReadToEndAsync(CancellationToken.None); + Assert.AreEqual("value", read); + } } From 37e77623b9a6ea582ffb94e2dfa78f445600b021 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 1 Apr 2023 21:11:54 +1100 Subject: [PATCH 036/313] Update readme.md --- readme.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/readme.md b/readme.md index 0d7b3984..593e0292 100644 --- a/readme.md +++ b/readme.md @@ -408,6 +408,16 @@ The class `PolyfillExtensions` includes the following extension methods: * `public static void Deconstruct(out TKey, out TValue)` +### HttpClient + + * `public async Task GetStreamAsync(string, CancellationToken)` + * `public async Task GetStreamAsync(Uri, CancellationToken)` + * `public async Task GetByteArrayAsync(string, CancellationToken)` + * `public async Task GetByteArrayAsync(Uri, CancellationToken)` + * `public async Task GetStringAsync(string, CancellationToken)` + * `public Task GetStringAsync(Uri, CancellationToken)` + + ## References If any of the below reference are not included, the related polyfills will be disabled. From c3edcf3cdb1d669847fbaeec9603d64473ffe15a Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 1 Apr 2023 21:14:22 +1100 Subject: [PATCH 037/313] docs --- readme.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/readme.md b/readme.md index 593e0292..4adfc2f8 100644 --- a/readme.md +++ b/readme.md @@ -405,17 +405,24 @@ The class `PolyfillExtensions` includes the following extension methods: ### KeyValuePair - * `public static void Deconstruct(out TKey, out TValue)` + * `void Deconstruct(out TKey, out TValue)` ### HttpClient - * `public async Task GetStreamAsync(string, CancellationToken)` - * `public async Task GetStreamAsync(Uri, CancellationToken)` - * `public async Task GetByteArrayAsync(string, CancellationToken)` - * `public async Task GetByteArrayAsync(Uri, CancellationToken)` - * `public async Task GetStringAsync(string, CancellationToken)` - * `public Task GetStringAsync(Uri, CancellationToken)` + * `Task GetStreamAsync(string, CancellationToken)` + * `Task GetStreamAsync(Uri, CancellationToken)` + * `Task GetByteArrayAsync(string, CancellationToken)` + * `Task GetByteArrayAsync(Uri, CancellationToken)` + * `Task GetStringAsync(string, CancellationToken)` + * `Task GetStringAsync(Uri, CancellationToken)` + + +### HttpContent + + * `Task ReadAsStreamAsync(CancellationToken cancellationToken)` + * `Task ReadAsByteArrayAsync(CancellationToken cancellationToken)` + * `Task ReadAsStringAsync(CancellationToken)` ## References From 908f9e1e9847c82f147c2f7c522ca149124d9c9d Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 1 Apr 2023 21:25:27 +1100 Subject: [PATCH 038/313] redundant async --- src/Polyfill/PolyfillExtensions_HttpClient.cs | 24 +++++++++---------- .../PolyfillExtensions_HttpContent.cs | 12 +++++----- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_HttpClient.cs b/src/Polyfill/PolyfillExtensions_HttpClient.cs index c2cbd75d..26478ba8 100644 --- a/src/Polyfill/PolyfillExtensions_HttpClient.cs +++ b/src/Polyfill/PolyfillExtensions_HttpClient.cs @@ -60,11 +60,11 @@ public static async Task GetStreamAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - public static async Task GetStreamAsync( + public static Task GetStreamAsync( this HttpClient httpClient, Uri requestUri, CancellationToken cancellationToken = default) => - await httpClient.GetStreamAsync(requestUri.ToString(), cancellationToken).ConfigureAwait(false); + httpClient.GetStreamAsync(requestUri.ToString(), cancellationToken); /// /// Send a GET request to the specified Uri and return the response body as a byte array in an asynchronous operation. @@ -94,11 +94,11 @@ public static async Task GetByteArrayAsync( return await response.Content.ReadAsByteArrayAsync(cancellationToken).ConfigureAwait(false); } // Older versions of HttpClient methods don't propagate the cancellation token inside the exception - catch (OperationCanceledException ex) when ( - ex.CancellationToken != cancellationToken && + catch (OperationCanceledException exception) when ( + exception.CancellationToken != cancellationToken && cancellationToken.IsCancellationRequested) { - throw new OperationCanceledException(ex.Message, ex.InnerException, cancellationToken); + throw new OperationCanceledException(exception.Message, exception.InnerException, cancellationToken); } } @@ -112,11 +112,11 @@ public static async Task GetByteArrayAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - public static async Task GetByteArrayAsync( + public static Task GetByteArrayAsync( this HttpClient httpClient, Uri requestUri, CancellationToken cancellationToken = default) => - await httpClient.GetByteArrayAsync(requestUri.ToString(), cancellationToken).ConfigureAwait(false); + httpClient.GetByteArrayAsync(requestUri.ToString(), cancellationToken); /// /// Send a GET request to the specified Uri and return the response body as a string in an asynchronous operation. @@ -146,11 +146,11 @@ public static async Task GetStringAsync( return await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); } // Older versions of HttpClient methods don't propagate the cancellation token inside the exception - catch (OperationCanceledException ex) when ( - ex.CancellationToken != cancellationToken && + catch (OperationCanceledException exception) when ( + exception.CancellationToken != cancellationToken && cancellationToken.IsCancellationRequested) { - throw new OperationCanceledException(ex.Message, ex.InnerException, cancellationToken); + throw new OperationCanceledException(exception.Message, exception.InnerException, cancellationToken); } } @@ -164,10 +164,10 @@ public static async Task GetStringAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - public static async Task GetStringAsync( + public static Task GetStringAsync( this HttpClient httpClient, Uri requestUri, CancellationToken cancellationToken = default) => - await httpClient.GetStringAsync(requestUri.ToString(), cancellationToken).ConfigureAwait(false); + httpClient.GetStringAsync(requestUri.ToString(), cancellationToken); } #endif \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_HttpContent.cs b/src/Polyfill/PolyfillExtensions_HttpContent.cs index e6fe10a5..ef67120e 100644 --- a/src/Polyfill/PolyfillExtensions_HttpContent.cs +++ b/src/Polyfill/PolyfillExtensions_HttpContent.cs @@ -23,12 +23,12 @@ static partial class PolyfillExtensions /// The token to monitor for cancellation requests. The default value is . /// /// The task object representing the asynchronous operation. - public static async Task ReadAsStreamAsync( + public static Task ReadAsStreamAsync( this HttpContent httpContent, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); - return await httpContent.ReadAsStreamAsync().ConfigureAwait(false); + return httpContent.ReadAsStreamAsync(); } /// @@ -42,12 +42,12 @@ public static async Task ReadAsStreamAsync( /// The token to monitor for cancellation requests. The default value is . /// /// The task object representing the asynchronous operation. - public static async Task ReadAsByteArrayAsync( + public static Task ReadAsByteArrayAsync( this HttpContent httpContent, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); - return await httpContent.ReadAsByteArrayAsync().ConfigureAwait(false); + return httpContent.ReadAsByteArrayAsync(); } /// @@ -61,12 +61,12 @@ public static async Task ReadAsByteArrayAsync( /// The token to monitor for cancellation requests. The default value is . /// /// The task object representing the asynchronous operation. - public static async Task ReadAsStringAsync( + public static Task ReadAsStringAsync( this HttpContent httpContent, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); - return await httpContent.ReadAsStringAsync().ConfigureAwait(false); + return httpContent.ReadAsStringAsync(); } } #endif \ No newline at end of file From 34e1212c004add4eca4544efc1dfdb9f7aab3356 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 1 Apr 2023 21:41:16 +1100 Subject: [PATCH 039/313] support for transitive dependencies (#18) --- src/ConsumeIndirect/ConsumeIndirect.csproj | 28 ++++++++++++++++++++++ src/Polyfill.sln | 6 +++++ src/Polyfill/Polyfill.targets | 17 ++++++++----- 3 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 src/ConsumeIndirect/ConsumeIndirect.csproj diff --git a/src/ConsumeIndirect/ConsumeIndirect.csproj b/src/ConsumeIndirect/ConsumeIndirect.csproj new file mode 100644 index 00000000..193567ce --- /dev/null +++ b/src/ConsumeIndirect/ConsumeIndirect.csproj @@ -0,0 +1,28 @@ + + + true + net461;net462;net47;net471;net472;net48;net481;net6.0-windows + $(TargetFrameworks);netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 + + + + + Pollyfill\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs + + + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs + + + Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs + + + + + + \ No newline at end of file diff --git a/src/Polyfill.sln b/src/Polyfill.sln index 1b1b4388..75179836 100644 --- a/src/Polyfill.sln +++ b/src/Polyfill.sln @@ -29,6 +29,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PublicTests", "PublicTests\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeClassicReferences", "ConsumeClassicReferences\ConsumeClassicReferences.csproj", "{CF7D4778-6A32-4E7D-B80B-3507974B443B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeIndirect", "ConsumeIndirect\ConsumeIndirect.csproj", "{955038AF-1073-4BB0-8AF7-D4597B7C2DAB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -67,6 +69,10 @@ Global {CF7D4778-6A32-4E7D-B80B-3507974B443B}.Debug|Any CPU.Build.0 = Debug|Any CPU {CF7D4778-6A32-4E7D-B80B-3507974B443B}.Release|Any CPU.ActiveCfg = Release|Any CPU {CF7D4778-6A32-4E7D-B80B-3507974B443B}.Release|Any CPU.Build.0 = Release|Any CPU + {955038AF-1073-4BB0-8AF7-D4597B7C2DAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {955038AF-1073-4BB0-8AF7-D4597B7C2DAB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {955038AF-1073-4BB0-8AF7-D4597B7C2DAB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {955038AF-1073-4BB0-8AF7-D4597B7C2DAB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Polyfill/Polyfill.targets b/src/Polyfill/Polyfill.targets index b91b8cc0..10b139ba 100644 --- a/src/Polyfill/Polyfill.targets +++ b/src/Polyfill/Polyfill.targets @@ -1,21 +1,26 @@ - + + $(PrepareForBuildDependsOn);PrintAllDeps + + + + + true + Condition="@(PackageDependencies->WithMetadataValue('Identity', 'System.ValueTuple')->Count()) != 0">true $(DefineConstants);VALUETUPLEREFERENCED true + Condition="@(PackageDependencies->WithMetadataValue('Identity', 'System.Memory')->Count()) != 0">true $(DefineConstants);MEMORYREFERENCED true + Condition="@(PackageDependencies->WithMetadataValue('Identity', 'System.Threading.Tasks.Extensions')->Count()) != 0">true $(DefineConstants);TASKSEXTENSIONSREFERENCED true + Condition="@(PackageDependencies->WithMetadataValue('Identity', 'System.Net.Http')->Count()) != 0 OR @(Reference->WithMetadataValue('Identity', 'System.Net.Http')->Count()) != 0">true $(DefineConstants);HTTPREFERENCED From 3297ca0c6348b2e72b66616a206918808d49900f Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 1 Apr 2023 21:43:05 +1100 Subject: [PATCH 040/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 0d43fedc..3226db1c 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.8.0 + 1.9.0 1.0.0 Polyfill true From dda34ff4e20ec17ba175e75495976716124b00a9 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 2 Apr 2023 08:51:38 +1000 Subject: [PATCH 041/313] Update Consume.cs --- src/Consume/Consume.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 5c43d3af..465533a5 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -7,6 +7,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; +using System.Net.Http; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; @@ -68,6 +69,16 @@ class Consume var startsWith = "value".StartsWith('a'); var endsWith = "value".EndsWith('a'); + new HttpClient().GetStreamAsync("", CancellationToken.None); + new HttpClient().GetStreamAsync(new Uri(""), CancellationToken.None); + new HttpClient().GetByteArrayAsync("", CancellationToken.None); + new HttpClient().GetByteArrayAsync(new Uri(""), CancellationToken.None); + new HttpClient().GetStringAsync("", CancellationToken.None); + new HttpClient().GetStringAsync(new Uri(""), CancellationToken.None); + + new ByteArrayContent(new byte[]{}).ReadAsStreamAsync(CancellationToken.None); + new ByteArrayContent(new byte[]{}).ReadAsByteArrayAsync(CancellationToken.None); + new ByteArrayContent(new byte[]{}).ReadAsStringAsync(CancellationToken.None); var enumerable = (IEnumerable)new List {"a", "b"}; var append = enumerable.Append("c"); From 43b5457e918b40ee177663194b0730fc53d87f69 Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 1 Apr 2023 15:52:20 -0700 Subject: [PATCH 042/313] Add NetStd2.1 for HTTP polyfills (#19) --- src/Polyfill/PolyfillExtensions_HttpClient.cs | 2 +- src/Polyfill/PolyfillExtensions_HttpContent.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_HttpClient.cs b/src/Polyfill/PolyfillExtensions_HttpClient.cs index 26478ba8..6806146c 100644 --- a/src/Polyfill/PolyfillExtensions_HttpClient.cs +++ b/src/Polyfill/PolyfillExtensions_HttpClient.cs @@ -1,4 +1,4 @@ -#if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD2_0 || NETCOREAPP2X || NETCOREAPP3X) +#if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD || NETCOREAPP2X || NETCOREAPP3X) #pragma warning disable diff --git a/src/Polyfill/PolyfillExtensions_HttpContent.cs b/src/Polyfill/PolyfillExtensions_HttpContent.cs index ef67120e..ebe5e315 100644 --- a/src/Polyfill/PolyfillExtensions_HttpContent.cs +++ b/src/Polyfill/PolyfillExtensions_HttpContent.cs @@ -1,4 +1,4 @@ -#if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD2_0 || NETCOREAPP2X || NETCOREAPP3X) +#if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD || NETCOREAPP2X || NETCOREAPP3X) #pragma warning disable From 77052df18c46321e4ecddb2ce6d2a7ea1efc28a1 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 2 Apr 2023 08:53:25 +1000 Subject: [PATCH 043/313] . --- src/Consume/Consume.cs | 26 +++++++++++++++----------- src/Directory.Build.props | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 465533a5..3670c0bd 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -14,6 +14,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +#pragma warning disable CS4014 class Consume { @@ -69,17 +70,6 @@ class Consume var startsWith = "value".StartsWith('a'); var endsWith = "value".EndsWith('a'); - new HttpClient().GetStreamAsync("", CancellationToken.None); - new HttpClient().GetStreamAsync(new Uri(""), CancellationToken.None); - new HttpClient().GetByteArrayAsync("", CancellationToken.None); - new HttpClient().GetByteArrayAsync(new Uri(""), CancellationToken.None); - new HttpClient().GetStringAsync("", CancellationToken.None); - new HttpClient().GetStringAsync(new Uri(""), CancellationToken.None); - - new ByteArrayContent(new byte[]{}).ReadAsStreamAsync(CancellationToken.None); - new ByteArrayContent(new byte[]{}).ReadAsByteArrayAsync(CancellationToken.None); - new ByteArrayContent(new byte[]{}).ReadAsStringAsync(CancellationToken.None); - var enumerable = (IEnumerable)new List {"a", "b"}; var append = enumerable.Append("c"); var skipLast = enumerable.SkipLast(1); @@ -97,6 +87,20 @@ class Consume var contains = "a b".Contains(' '); } + static void Http() + { + new HttpClient().GetStreamAsync("", CancellationToken.None); + new HttpClient().GetStreamAsync(new Uri(""), CancellationToken.None); + new HttpClient().GetByteArrayAsync("", CancellationToken.None); + new HttpClient().GetByteArrayAsync(new Uri(""), CancellationToken.None); + new HttpClient().GetStringAsync("", CancellationToken.None); + new HttpClient().GetStringAsync(new Uri(""), CancellationToken.None); + + new ByteArrayContent(new byte[] { }).ReadAsStreamAsync(CancellationToken.None); + new ByteArrayContent(new byte[] { }).ReadAsByteArrayAsync(CancellationToken.None); + new ByteArrayContent(new byte[] { }).ReadAsStringAsync(CancellationToken.None); + } + void KeyValuePairDeconstruct(IEnumerable> variables) { foreach (var (name, value) in variables) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 3226db1c..7f73cc02 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.9.0 + 1.9.1 1.0.0 Polyfill true From a2cee1d1a74f21bee8c6ca3c96e6e45a8c1f3458 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 3 Apr 2023 20:46:46 +1000 Subject: [PATCH 044/313] Gen api (#20) --- api_list.include.md | 76 ++++++++++++++++ contributing.md | 5 +- readme.md | 88 +++++++++---------- src/NoRefsTests/NoRefsTests.csproj | 16 ++-- src/Polyfill.sln | 19 ++-- src/Polyfill/PolyfillExtensions_HttpClient.cs | 8 ++ .../PolyfillExtensions_HttpContent.cs | 5 ++ .../PolyfillExtensions_IEnumerable.cs | 4 + .../PolyfillExtensions_IReadOnlyDictionary.cs | 16 +++- .../PolyfillExtensions_KeyValuePair.cs | 8 ++ src/Polyfill/PolyfillExtensions_Memory.cs | 45 ++++++++-- src/Polyfill/PolyfillExtensions_Stream.cs | 5 ++ .../PolyfillExtensions_StreamReader.cs | 4 + .../PolyfillExtensions_StreamWriter.cs | 3 + src/Polyfill/PolyfillExtensions_String.cs | 32 +++++++ src/PublicTests/PublicTests.csproj | 4 +- src/Tests/BuildApiTest.cs | 72 +++++++++++++++ src/Tests/ModuleInitializer.cs | 8 ++ src/Tests/Tests.csproj | 3 + src/UnsafeTests/UnsafeTests.csproj | 34 +++---- 20 files changed, 354 insertions(+), 101 deletions(-) create mode 100644 api_list.include.md create mode 100644 src/Tests/BuildApiTest.cs create mode 100644 src/Tests/ModuleInitializer.cs diff --git a/api_list.include.md b/api_list.include.md new file mode 100644 index 00000000..7e44a9dd --- /dev/null +++ b/api_list.include.md @@ -0,0 +1,76 @@ +### HttpClient + + * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### HttpContent + + * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### IEnumerable + + * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### IReadOnlyDictionary + + * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### IReadOnlyDictionary + + * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### KeyValuePair + + * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### ReadOnlySpan + + * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### ReadOnlySpan + + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### Span + + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### Stream + + * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### StreamReader + + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### StreamWriter + + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### String + + * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### StringBuilder + + * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### StringComparison + + diff --git a/contributing.md b/contributing.md index 338596ed..38f86266 100644 --- a/contributing.md +++ b/contributing.md @@ -199,8 +199,10 @@ Example: using System; using System.IO; using System.Runtime.InteropServices; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; +// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { @@ -213,6 +215,7 @@ static partial class PolyfillExtensions /// The default value is . /// /// A task that represents the asynchronous write operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] public static ValueTask WriteAsync( this StreamWriter target, ReadOnlyMemory buffer, @@ -231,7 +234,7 @@ static partial class PolyfillExtensions } #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/readme.md b/readme.md index 4adfc2f8..05659d05 100644 --- a/readme.md +++ b/readme.md @@ -347,82 +347,82 @@ Reference: [Improvements in native code interop in .NET 5.0](https://devblogs.mi The class `PolyfillExtensions` includes the following extension methods: +### HttpClient -### IEnumerable - - * `IEnumerable Append(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.append) - * ` IEnumerable SkipLast(int)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) + * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### HttpContent -### IReadOnlyDictionary + * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) +### IEnumerable + * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) -### String +### IReadOnlyDictionary - * `bool StartsWith(char)` - * `bool EndsWith(char)` - * `int GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) - * `string[] Split(char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split?system-string-split(system-char-system-stringsplitoptions)) - * `string[] Split(char, int, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split?system-string-split(system-char-system-int32-system-stringsplitoptions)) - * `bool Contains(char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains?system-string-contains(system-char)) + * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### IReadOnlyDictionary -### ReadOnlySpan + * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `bool Contains(char)` - * `bool SequenceEqual(string)` +### KeyValuePair + * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) -### Span +### ReadOnlySpan - * `bool SequenceEqual(string)` + * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### ReadOnlySpan -### StringBuilder + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `void Append(ReadOnlySpan)`. Will perform better if `True` is enabled in the consuming project. - * `bool Equals(ReadOnlySpan)` +### Span + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### Stream - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) - + * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### StreamReader - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) - * `ValueTask ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readtoendasync?system-io-streamreader-readtoendasync(system-threading-cancellationtoken)) - + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### StreamWriter - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - - -### KeyValuePair - - * `void Deconstruct(out TKey, out TValue)` + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### String -### HttpClient + * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task GetStreamAsync(string, CancellationToken)` - * `Task GetStreamAsync(Uri, CancellationToken)` - * `Task GetByteArrayAsync(string, CancellationToken)` - * `Task GetByteArrayAsync(Uri, CancellationToken)` - * `Task GetStringAsync(string, CancellationToken)` - * `Task GetStringAsync(Uri, CancellationToken)` +### StringBuilder + * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) -### HttpContent +### StringComparison - * `Task ReadAsStreamAsync(CancellationToken cancellationToken)` - * `Task ReadAsByteArrayAsync(CancellationToken cancellationToken)` - * `Task ReadAsStringAsync(CancellationToken)` + ## References diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 0998442b..9f3828f5 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -10,7 +10,7 @@ Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs - + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs @@ -19,19 +19,17 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + + + - - - + + + diff --git a/src/Polyfill.sln b/src/Polyfill.sln index 75179836..5991cb1c 100644 --- a/src/Polyfill.sln +++ b/src/Polyfill.sln @@ -18,18 +18,21 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polyfill", "Polyfill\Polyfill.csproj", "{698FB675-3480-4107-8CAE-51452C6138CE}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{CA1869D1-4531-40C7-AE55-5885F4DD8448}" + ProjectSection(ProjectDependencies) = postProject + {32C38E3C-4040-455F-A27D-4EA5DB0F8EFA} = {32C38E3C-4040-455F-A27D-4EA5DB0F8EFA} + EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Consume", "Consume\Consume.csproj", "{32C38E3C-4040-455F-A27D-4EA5DB0F8EFA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Consume", "Consume\Consume.csproj", "{32C38E3C-4040-455F-A27D-4EA5DB0F8EFA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnsafeTests", "UnsafeTests\UnsafeTests.csproj", "{F49A3C33-48A3-4954-9AC0-5C7B30AC2B2B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnsafeTests", "UnsafeTests\UnsafeTests.csproj", "{F49A3C33-48A3-4954-9AC0-5C7B30AC2B2B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoRefsTests", "NoRefsTests\NoRefsTests.csproj", "{B46221EE-4806-423A-B21A-36E6B1D50027}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoRefsTests", "NoRefsTests\NoRefsTests.csproj", "{B46221EE-4806-423A-B21A-36E6B1D50027}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PublicTests", "PublicTests\PublicTests.csproj", "{9FBD54A6-461C-4754-B77A-222E06BF89B6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PublicTests", "PublicTests\PublicTests.csproj", "{9FBD54A6-461C-4754-B77A-222E06BF89B6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeClassicReferences", "ConsumeClassicReferences\ConsumeClassicReferences.csproj", "{CF7D4778-6A32-4E7D-B80B-3507974B443B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsumeClassicReferences", "ConsumeClassicReferences\ConsumeClassicReferences.csproj", "{CF7D4778-6A32-4E7D-B80B-3507974B443B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeIndirect", "ConsumeIndirect\ConsumeIndirect.csproj", "{955038AF-1073-4BB0-8AF7-D4597B7C2DAB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsumeIndirect", "ConsumeIndirect\ConsumeIndirect.csproj", "{955038AF-1073-4BB0-8AF7-D4597B7C2DAB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -41,10 +44,6 @@ Global {698FB675-3480-4107-8CAE-51452C6138CE}.Debug|Any CPU.Build.0 = Debug|Any CPU {698FB675-3480-4107-8CAE-51452C6138CE}.Release|Any CPU.ActiveCfg = Release|Any CPU {698FB675-3480-4107-8CAE-51452C6138CE}.Release|Any CPU.Build.0 = Release|Any CPU - {B4BAD33E-CF70-448F-AAF1-ED8941E5C875}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B4BAD33E-CF70-448F-AAF1-ED8941E5C875}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B4BAD33E-CF70-448F-AAF1-ED8941E5C875}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B4BAD33E-CF70-448F-AAF1-ED8941E5C875}.Release|Any CPU.Build.0 = Release|Any CPU {CA1869D1-4531-40C7-AE55-5885F4DD8448}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CA1869D1-4531-40C7-AE55-5885F4DD8448}.Debug|Any CPU.Build.0 = Debug|Any CPU {CA1869D1-4531-40C7-AE55-5885F4DD8448}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/src/Polyfill/PolyfillExtensions_HttpClient.cs b/src/Polyfill/PolyfillExtensions_HttpClient.cs index 6806146c..922b412c 100644 --- a/src/Polyfill/PolyfillExtensions_HttpClient.cs +++ b/src/Polyfill/PolyfillExtensions_HttpClient.cs @@ -4,12 +4,14 @@ // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global +// ReSharper disable RedundantAttributeSuffix using System; using System.IO; using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { @@ -23,6 +25,7 @@ static partial class PolyfillExtensions /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)")] public static async Task GetStreamAsync( this HttpClient httpClient, string requestUri, @@ -60,6 +63,7 @@ public static async Task GetStreamAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)")] public static Task GetStreamAsync( this HttpClient httpClient, Uri requestUri, @@ -76,6 +80,7 @@ public static Task GetStreamAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)")] public static async Task GetByteArrayAsync( this HttpClient httpClient, string requestUri, @@ -112,6 +117,7 @@ public static async Task GetByteArrayAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)")] public static Task GetByteArrayAsync( this HttpClient httpClient, Uri requestUri, @@ -128,6 +134,7 @@ public static Task GetByteArrayAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)")] public static async Task GetStringAsync( this HttpClient httpClient, string requestUri, @@ -164,6 +171,7 @@ public static async Task GetStringAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)")] public static Task GetStringAsync( this HttpClient httpClient, Uri requestUri, diff --git a/src/Polyfill/PolyfillExtensions_HttpContent.cs b/src/Polyfill/PolyfillExtensions_HttpContent.cs index ebe5e315..188d05d3 100644 --- a/src/Polyfill/PolyfillExtensions_HttpContent.cs +++ b/src/Polyfill/PolyfillExtensions_HttpContent.cs @@ -3,12 +3,14 @@ #pragma warning disable // ReSharper disable RedundantUsingDirective +// ReSharper disable RedundantAttributeSuffix // ReSharper disable UnusedMember.Global using System.IO; using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { @@ -23,6 +25,7 @@ static partial class PolyfillExtensions /// The token to monitor for cancellation requests. The default value is . /// /// The task object representing the asynchronous operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)")] public static Task ReadAsStreamAsync( this HttpContent httpContent, CancellationToken cancellationToken = default) @@ -42,6 +45,7 @@ public static Task ReadAsStreamAsync( /// The token to monitor for cancellation requests. The default value is . /// /// The task object representing the asynchronous operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)")] public static Task ReadAsByteArrayAsync( this HttpContent httpContent, CancellationToken cancellationToken = default) @@ -61,6 +65,7 @@ public static Task ReadAsByteArrayAsync( /// The token to monitor for cancellation requests. The default value is . /// /// The task object representing the asynchronous operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)")] public static Task ReadAsStringAsync( this HttpContent httpContent, CancellationToken cancellationToken = default) diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index d1b1ff87..112d77e7 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -7,7 +7,9 @@ using System; using System.Collections.Generic; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; using System.Linq; +// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { @@ -20,6 +22,7 @@ static partial class PolyfillExtensions /// The value to append to source. /// The type of the elements of source. /// A new sequence that ends with element. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.append")] public static IEnumerable Append( this IEnumerable source, TSource element) @@ -43,6 +46,7 @@ public static IEnumerable Append( /// The type of the elements in the enumerable collection. /// A new enumerable collection that contains the elements from source minus count elements from the end /// of the collection. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast")] public static IEnumerable SkipLast(this IEnumerable source, int count) => source.Reverse().Skip(count).Reverse(); #endif diff --git a/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs b/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs index 21a78b5b..59a25038 100644 --- a/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs +++ b/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs @@ -8,6 +8,8 @@ using System; using System.Collections.Generic; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { @@ -18,8 +20,11 @@ static partial class PolyfillExtensions /// The key of the value to get. /// The type of the keys in the dictionary. /// The type of the values in the dictionary. - /// A TValue instance. When the method is successful, the returned object is the value associated with - /// the specified key. When the method fails, it returns the default value for TValue. + /// + /// A TValue instance. When the method is successful, the returned object is the value associated with + /// the specified key. When the method fails, it returns the default value for TValue. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault")] public static TValue? GetValueOrDefault( this IReadOnlyDictionary target, TKey key) @@ -40,8 +45,11 @@ static partial class PolyfillExtensions /// A dictionary with keys of type TKey and values of type TValue. /// The type of the keys in the dictionary. /// The type of the values in the dictionary. - /// A TValue instance. When the method is successful, the returned object is the value associated with - /// the specified key. When the method fails, it returns the default value for TValue. + /// + /// A TValue instance. When the method is successful, the returned object is the value associated with + /// the specified key. When the method fails, it returns the default value for TValue. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)")] public static TValue GetValueOrDefault( this IReadOnlyDictionary target, TKey key, diff --git a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs index 0cd47cfa..39a30b07 100644 --- a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs +++ b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs @@ -5,12 +5,20 @@ // ReSharper disable RedundantUsingDirective // ReSharper disable PartialTypeWithSinglePart // ReSharper disable UnusedMember.Global +// ReSharper disable RedundantAttributeSuffix using System; using System.Collections.Generic; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { + /// + /// Deconstructs the current + /// + /// The key of the current . + /// The value of the current . + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct")] public static void Deconstruct( this KeyValuePair target, out TKey key, diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index 3d2d004d..af0c5670 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -4,13 +4,22 @@ // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global +// ReSharper disable RedundantAttributeSuffix using System; using System.Text; using System.Runtime.InteropServices; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { + //TODO: move to generic + /// + /// Indicates whether a specified value is found in a read-only span. Values are compared using IEquatable{T}.Equals(T). + /// + /// The value to search for. + /// true if found, false otherwise. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)")] public static bool Contains(this ReadOnlySpan target, char value) { foreach (var ch in target) @@ -24,11 +33,17 @@ public static bool Contains(this ReadOnlySpan target, char value) return false; } - public static void Append(this StringBuilder target, ReadOnlySpan value) + /// + /// Appends the string representation of a specified read-only character span to this instance. + /// + /// The read-only character span to append. + /// A reference to this instance after the append operation is completed. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))")] + public static StringBuilder Append(this StringBuilder target, ReadOnlySpan value) { if (value.Length <= 0) { - return; + return target; } #if AllowUnsafeBlocks @@ -42,8 +57,10 @@ public static void Append(this StringBuilder target, ReadOnlySpan value) #else target.Append(value.ToArray()); #endif + return target; } + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal?view=net-7.0#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] public static bool SequenceEqual(this ReadOnlySpan target, string other) { if (target.Length != other.Length) @@ -64,9 +81,10 @@ public static bool SequenceEqual(this ReadOnlySpan target, string other) return true; } - public static bool Equals(this StringBuilder target, ReadOnlySpan span) + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))")] + public static bool SequenceEqual(this Span target, string other) { - if (target.Length != span.Length) + if (target.Length != other.Length) { return false; } @@ -74,7 +92,7 @@ public static bool Equals(this StringBuilder target, ReadOnlySpan span) for (var index = 0; index < target.Length; index++) { var ch1 = target[index]; - var ch2 = span[index]; + var ch2 = other[index]; if (ch1 != ch2) { return false; @@ -84,9 +102,20 @@ public static bool Equals(this StringBuilder target, ReadOnlySpan span) return true; } - public static bool SequenceEqual(this Span target, string other) + /// + /// Returns a value indicating whether the characters in this instance are equal to the characters in a specified + /// read-only character span. + /// + /// The character span to compare with the current instance. + /// + /// The Equals method performs an ordinal comparison to determine whether the characters in the current instance + /// and span are equal. + /// + /// true if the characters in this instance and span are the same; otherwise, false. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))")] + public static bool Equals(this StringBuilder target, ReadOnlySpan span) { - if (target.Length != other.Length) + if (target.Length != span.Length) { return false; } @@ -94,7 +123,7 @@ public static bool SequenceEqual(this Span target, string other) for (var index = 0; index < target.Length; index++) { var ch1 = target[index]; - var ch2 = other[index]; + var ch2 = span[index]; if (ch1 != ch2) { return false; diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index 50b0880b..7ac2e7ea 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -10,6 +10,8 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { @@ -27,6 +29,7 @@ static partial class PolyfillExtensions /// the buffer if that many bytes are not currently available, or it can be 0 (zero) if the end of the stream has /// been reached. /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)")] public static ValueTask ReadAsync( this Stream target, Memory buffer, @@ -49,6 +52,7 @@ public static ValueTask ReadAsync( /// The token to monitor for cancellation requests. The default value is . /// /// A task that represents the asynchronous write operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)")] public static ValueTask WriteAsync( this Stream target, ReadOnlyMemory buffer, @@ -71,6 +75,7 @@ public static ValueTask WriteAsync( /// The token to monitor for cancellation requests. The default value is . /// /// A task that represents the asynchronous copy operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)")] public static Task CopyToAsync( this Stream target, Stream destination, diff --git a/src/Polyfill/PolyfillExtensions_StreamReader.cs b/src/Polyfill/PolyfillExtensions_StreamReader.cs index d736ff02..e3c9793e 100644 --- a/src/Polyfill/PolyfillExtensions_StreamReader.cs +++ b/src/Polyfill/PolyfillExtensions_StreamReader.cs @@ -6,8 +6,10 @@ using System; using System.IO; using System.Runtime.InteropServices; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; +// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { @@ -28,6 +30,7 @@ static partial class PolyfillExtensions /// The number will be less than or equal to the length, depending on whether the data is /// available within the stream. /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)")] public static ValueTask ReadAsync( this StreamReader target, Memory buffer, @@ -68,6 +71,7 @@ public static ValueTask ReadAsync( /// that has been read from the current but not stored (by the /// ) or returned (to the caller) may be lost. /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readtoendasync#system-io-streamreader-readtoendasync(system-threading-cancellationtoken)")] public static Task ReadToEndAsync( this StreamReader target, CancellationToken cancellationToken) diff --git a/src/Polyfill/PolyfillExtensions_StreamWriter.cs b/src/Polyfill/PolyfillExtensions_StreamWriter.cs index 33d8bac6..9afed4c2 100644 --- a/src/Polyfill/PolyfillExtensions_StreamWriter.cs +++ b/src/Polyfill/PolyfillExtensions_StreamWriter.cs @@ -8,8 +8,10 @@ using System; using System.IO; using System.Runtime.InteropServices; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; +// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { @@ -22,6 +24,7 @@ static partial class PolyfillExtensions /// The default value is . /// /// A task that represents the asynchronous write operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] public static ValueTask WriteAsync( this StreamWriter target, ReadOnlyMemory buffer, diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/PolyfillExtensions_String.cs index d76887db..589a1892 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/PolyfillExtensions_String.cs @@ -5,12 +5,20 @@ // ReSharper disable PartialTypeWithSinglePart using System; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; using System.Text; +// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { #if NETFRAMEWORK || NETSTANDARD2_0 + /// + /// Returns the hash code for this string using the specified rules. + /// + /// One of the enumeration values that specifies the rules to use in the comparison. + /// A 32-bit signed integer hash code. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)")] public static int GetHashCode(this string target, StringComparison comparisonType) => FromComparison(comparisonType).GetHashCode(target); @@ -25,9 +33,23 @@ static StringComparer FromComparison(StringComparison comparison) => StringComparison.OrdinalIgnoreCase => StringComparer.OrdinalIgnoreCase, }; + /// + /// Returns a value indicating whether a specified string occurs within this string, using the specified comparison rules. + /// + /// The string to seek. + /// One of the enumeration values that specifies the rules to use in the comparison. + /// true if the value parameter occurs within this string, or if value is the empty string (""); otherwise, false. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains?view=net-8.0#system-string-contains(system-string-system-stringcomparison)")] public static bool Contains(this string target, string value, StringComparison comparisonType) => target.IndexOf(value, comparisonType) >= 0; + /// + /// Determines whether this string instance starts with the specified character. + /// + /// The character to compare. + /// This method performs an ordinal (case-sensitive and culture-insensitive) comparison. + /// true if value matches the beginning of this string; otherwise, false. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] public static bool StartsWith(this string target, char value) { if (target.Length == 0) @@ -38,6 +60,13 @@ public static bool StartsWith(this string target, char value) return target[0] == value; } + /// + /// Returns a value indicating whether a specified character occurs within this string. + /// + /// The character to seek. + /// This method performs an ordinal (case-sensitive and culture-insensitive) comparison. + /// true if the value parameter occurs within this string; otherwise, false. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] public static bool EndsWith(this string target, char value) { if (target.Length == 0) @@ -59,6 +88,7 @@ public static bool EndsWith(this string target, char value) /// A bitwise combination of the enumeration values that specifies whether to trim substrings /// and include empty substrings. /// An array that contains at most count substrings from this instance that are delimited by separator. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)")] public static string[] Split(this string target, char separator, StringSplitOptions options = StringSplitOptions.None) => target.Split(new[] {separator}, options); @@ -72,6 +102,7 @@ public static string[] Split(this string target, char separator, StringSplitOpti /// A bitwise combination of the enumeration values that specifies whether to trim substrings /// and include empty substrings. /// An array that contains at most count substrings from this instance that are delimited by separator. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)")] public static string[] Split(this string target, char separator, int count, StringSplitOptions options = StringSplitOptions.None) => target.Split(new[] {separator}, count, options); #endif @@ -83,6 +114,7 @@ public static string[] Split(this string target, char separator, int count, Stri /// This method performs an ordinal (case-sensitive and culture-insensitive) comparison. /// The character to seek. /// true if the value parameter occurs within this string; otherwise, false. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] public static bool Contains(this string target, char value) => target.IndexOf(value) >= 0; #endif diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index a384298e..26210e81 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -20,7 +20,9 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + + + diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs new file mode 100644 index 00000000..d37b0993 --- /dev/null +++ b/src/Tests/BuildApiTest.cs @@ -0,0 +1,72 @@ +#if NET8_0 && DEBUG +[TestFixture] +class BuildApiTest +{ + static string[] namespacesToClean = + { + "System.Collections.Generic.", + "System.Threading.Tasks.", + "System.Threading.", + "System.Net.Http.", + "System.Text.", + "System.IO.", + "System.", + }; + + [Test] + [Explicit] + public void Run() + { + var solutionDirectory = VerifyTests.AttributeReader.GetSolutionDirectory(); + var path = Path.Combine(solutionDirectory, @"Consume\bin\Debug\netstandard2.0\Consume.dll"); + var md = Path.Combine(solutionDirectory, @"..\api_list.include.md"); + File.Delete(md); + using var module = Mono.Cecil.ModuleDefinition.ReadModule(path); + var extensions = module.GetTypes().Single(_ => _.Name == nameof(PolyfillExtensions)); + using var writer = File.CreateText(md); + + foreach (var type in extensions.Methods.GroupBy(_ => _.Parameters[0].ParameterType).OrderBy(_ => _.Key.Name)) + { + var targetType = type.Key; + var targetFullName = targetType.FullName.Replace("`1", "").Replace("`2", ""); + writer.WriteLine($"### {SimpleTypeName(targetFullName)}"); + writer.WriteLine(); + foreach (var method in type.OrderBy(_ => _.Name)) + { + if (!method.IsPublic) + { + continue; + } + var parameters = string.Join(", ", method.Parameters.Skip(1).Select(_ => SimpleTypeName(_.ParameterType.FullName))); + var typeArgs = ""; + if (method.HasGenericParameters) + { + typeArgs = $"<{string.Join(", ", method.GenericParameters.Select(_ => _.Name))}>"; + } + + var signature = $"{SimpleTypeName(method.ReturnType.FullName)} {method.Name}{typeArgs}({parameters})"; + var descriptionAttribute = method.CustomAttributes + .SingleOrDefault(_ => _.AttributeType.Name == "DescriptionAttribute"); + if (descriptionAttribute == null) + { + throw new($"Description required {method.FullName}"); + } + writer.WriteLine($" * `{signature}` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken))"); + } + + writer.WriteLine(); + } + } + + static string SimpleTypeName(string fullName) + { + var name = fullName.Replace("`1", "").Replace("`2", ""); + foreach (var toClean in namespacesToClean) + { + name = name.Replace(toClean, ""); + } + + return name; + } +} +#endif \ No newline at end of file diff --git a/src/Tests/ModuleInitializer.cs b/src/Tests/ModuleInitializer.cs new file mode 100644 index 00000000..e5187346 --- /dev/null +++ b/src/Tests/ModuleInitializer.cs @@ -0,0 +1,8 @@ +using VerifyTests; + +public static class ModuleInitializer +{ + [ModuleInitializer] + public static void Initialize() => + VerifyDiffPlex.Initialize(); +} \ No newline at end of file diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 65c0eb38..bb715ea5 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -19,6 +19,9 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs + + + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 7ebceb23..d8107e1e 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -20,31 +20,17 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + + + - - - - - - - + + + + + + + From bbe9a69424512974c94d72c513ae4c88ffb44a80 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 3 Apr 2023 21:14:35 +1000 Subject: [PATCH 045/313] docs --- src/Polyfill/PolyfillExtensions_Memory.cs | 2 +- src/Polyfill/PolyfillExtensions_String.cs | 2 +- src/Tests/BuildApiTest.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index af0c5670..1195a88d 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -60,7 +60,7 @@ public static StringBuilder Append(this StringBuilder target, ReadOnlySpan return target; } - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal?view=net-7.0#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] public static bool SequenceEqual(this ReadOnlySpan target, string other) { if (target.Length != other.Length) diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/PolyfillExtensions_String.cs index 589a1892..3160ac03 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/PolyfillExtensions_String.cs @@ -39,7 +39,7 @@ static StringComparer FromComparison(StringComparison comparison) => /// The string to seek. /// One of the enumeration values that specifies the rules to use in the comparison. /// true if the value parameter occurs within this string, or if value is the empty string (""); otherwise, false. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains?view=net-8.0#system-string-contains(system-string-system-stringcomparison)")] + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)")] public static bool Contains(this string target, string value, StringComparison comparisonType) => target.IndexOf(value, comparisonType) >= 0; diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index d37b0993..d9991223 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -65,7 +65,7 @@ static string SimpleTypeName(string fullName) { name = name.Replace(toClean, ""); } - + return name; } } From 454e421de1b53ffee79b8822814f2d167e00d228 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 3 Apr 2023 22:01:02 +1000 Subject: [PATCH 046/313] Make span extensions generic (#21) --- api_list.include.md | 8 ++++-- readme.md | 8 ++++-- src/Consume/Consume.cs | 1 + src/Polyfill/PolyfillExtensions_Memory.cs | 30 ++++++++++++++++++--- src/Tests/BuildApiTest.cs | 1 - src/Tests/PolyfillExtensionsTests_Memory.cs | 12 +++++++-- 6 files changed, 49 insertions(+), 11 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index 7e44a9dd..6bb0d0fe 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -29,14 +29,18 @@ * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) -### ReadOnlySpan +### ReadOnlySpan - * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### ReadOnlySpan * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### Span + + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### Span * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/readme.md b/readme.md index 05659d05..6f36dae3 100644 --- a/readme.md +++ b/readme.md @@ -378,14 +378,18 @@ The class `PolyfillExtensions` includes the following extension methods: * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) -### ReadOnlySpan +### ReadOnlySpan - * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### ReadOnlySpan * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### Span + + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### Span * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 3670c0bd..a06df565 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -141,6 +141,7 @@ async Task StreamReadAsync() void SpanContains() { var contains = "value".AsSpan().Contains('e'); + contains = new Span().Contains('e'); } void SpanSequenceEqual() diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index 1195a88d..2dfb7331 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -13,18 +13,40 @@ static partial class PolyfillExtensions { - //TODO: move to generic /// /// Indicates whether a specified value is found in a read-only span. Values are compared using IEquatable{T}.Equals(T). /// /// The value to search for. /// true if found, false otherwise. [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)")] - public static bool Contains(this ReadOnlySpan target, char value) + public static bool Contains(this ReadOnlySpan target, T value) + where T : IEquatable { - foreach (var ch in target) + for (var index = 0; index < target.Length; index++) + { + var item = target[index]; + if (item.Equals(value)) + { + return true; + } + } + + return false; + } + + /// + /// Indicates whether a specified value is found in a only span. Values are compared using IEquatable{T}.Equals(T). + /// + /// The value to search for. + /// true if found, false otherwise. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)")] + public static bool Contains(this Span target, T value) + where T : IEquatable + { + for (var index = 0; index < target.Length; index++) { - if (ch == value) + var item = target[index]; + if (item.Equals(value)) { return true; } diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index d9991223..f49fac47 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -14,7 +14,6 @@ class BuildApiTest }; [Test] - [Explicit] public void Run() { var solutionDirectory = VerifyTests.AttributeReader.GetSolutionDirectory(); diff --git a/src/Tests/PolyfillExtensionsTests_Memory.cs b/src/Tests/PolyfillExtensionsTests_Memory.cs index 187d664d..c0b7f6da 100644 --- a/src/Tests/PolyfillExtensionsTests_Memory.cs +++ b/src/Tests/PolyfillExtensionsTests_Memory.cs @@ -1,12 +1,20 @@ partial class PolyfillExtensionsTests { [Test] - public void SpanContains() => + public void SpanContains() + { Assert.True("value".AsSpan().Contains('e')); + var span = new Span("value".ToCharArray()); + Assert.True(span.Contains('e')); + } [Test] - public void SpanSequenceEqual() => + public void SpanSequenceEqual() + { Assert.True("value".AsSpan().SequenceEqual("value")); + var span = new Span("value".ToCharArray()); + Assert.True(span.SequenceEqual("value")); + } [Test] public void SpanStringBuilderAppend() From ef3590d4b71dc95fd55a3ead10c4541b803d08ac Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 3 Apr 2023 22:40:19 +1000 Subject: [PATCH 047/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 7f73cc02..72ffb56b 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.9.1 + 1.10.0 1.0.0 Polyfill true From ca26f6007f41a42605f3a8c4e3e763377e80fa0f Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 5 Apr 2023 13:28:06 +1000 Subject: [PATCH 048/313] add Nanosecond and Millisecond (#22) --- api_list.include.md | 10 +++ readme.md | 12 ++- src/Directory.Build.props | 2 +- src/Polyfill/PolyfillExtensions_DateTime.cs | 84 +++++++++++++++++++ src/Tests/PolyfillExtensionsTests_DateTime.cs | 22 +++++ 5 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 src/Polyfill/PolyfillExtensions_DateTime.cs create mode 100644 src/Tests/PolyfillExtensionsTests_DateTime.cs diff --git a/api_list.include.md b/api_list.include.md index 6bb0d0fe..f3f636a4 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -1,3 +1,13 @@ +### DateTime + + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### DateTimeOffset + + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### HttpClient * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/readme.md b/readme.md index 6f36dae3..03f577eb 100644 --- a/readme.md +++ b/readme.md @@ -347,7 +347,17 @@ Reference: [Improvements in native code interop in .NET 5.0](https://devblogs.mi The class `PolyfillExtensions` includes the following extension methods: -### HttpClient +### DateTime + + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### DateTimeOffset + + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### HttpClient * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 72ffb56b..5b43c91a 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.10.0 + 1.11.0 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_DateTime.cs b/src/Polyfill/PolyfillExtensions_DateTime.cs new file mode 100644 index 00000000..f3d3c50f --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_DateTime.cs @@ -0,0 +1,84 @@ + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable UnusedMember.Global + +using System; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +// ReSharper disable RedundantAttributeSuffix + +static partial class PolyfillExtensions +{ + const long TicksPerMicrosecond = 10; + + /// + /// Gets the nanosecond component of the time represented by the current DateTime object. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond")] + public static int Nanosecond( + this DateTime target) + { +#if NET7_0_OR_GREATER + return target.Nanosecond; +#else + return (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; +#endif + } + + /// + /// Gets the nanosecond component of the time represented by the current DateTimeOffset object. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond")] + public static int Nanosecond( + this DateTimeOffset target) + { +#if NET7_0_OR_GREATER + return target.Nanosecond; +#else + return (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; +#endif + } + /// + /// Gets the microsecond component of the time represented by the current DateTime object. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond")] + public static int Microsecond( + this DateTime target) + { +#if NET7_0_OR_GREATER + return target.Microsecond; +#else + return (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; +#endif + } + + /// + /// Gets the microsecond component of the time represented by the current DateTimeOffset object. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond")] + public static int Microsecond( + this DateTimeOffset target) + { +#if NET7_0_OR_GREATER + return target.Microsecond; +#else + return (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; +#endif + } + + static long TicksComponent(this DateTime target) + { + var withNoSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); + var secondsPart = target - withNoSeconds; + return secondsPart.Ticks; + } + + static long TicksComponent(this DateTimeOffset target) + { + var withNoSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); + var secondsPart = target - withNoSeconds; + return secondsPart.Ticks; + } +} \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_DateTime.cs b/src/Tests/PolyfillExtensionsTests_DateTime.cs new file mode 100644 index 00000000..50b9dc3e --- /dev/null +++ b/src/Tests/PolyfillExtensionsTests_DateTime.cs @@ -0,0 +1,22 @@ +partial class PolyfillExtensionsTests +{ +#if NET7_0_OR_GREATER + + static DateTimeOffset dateTimeOffset = DateTimeOffset.Now; + static DateTime dateTime = DateTime.Now; + + [Test] + public void Nanoseconds() + { + Assert.AreEqual(dateTimeOffset.Nanosecond, dateTimeOffset.Nanosecond()); + Assert.AreEqual(dateTime.Nanosecond, dateTime.Nanosecond()); + } + + [Test] + public void Microsecond() + { + Assert.AreEqual(dateTimeOffset.Microsecond, dateTimeOffset.Microsecond()); + Assert.AreEqual(dateTime.Microsecond, dateTime.Microsecond()); + } +#endif +} \ No newline at end of file From 69ce8b7d1741311c4b29af47a9ac29ac82d02dec Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 5 Apr 2023 14:05:45 +1000 Subject: [PATCH 049/313] add TimeSpan Microseconds and Nanoseconds (#23) --- api_list.include.md | 5 ++ readme.md | 5 ++ src/Directory.Build.props | 2 +- src/Polyfill/PolyfillExtensions_DateTime.cs | 63 ++++++++++++++----- src/Tests/PolyfillExtensionsTests_DateTime.cs | 3 + 5 files changed, 61 insertions(+), 17 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index f3f636a4..5dc147b3 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -88,3 +88,8 @@ ### StringComparison +### TimeSpan + + * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + diff --git a/readme.md b/readme.md index 03f577eb..f3c1364b 100644 --- a/readme.md +++ b/readme.md @@ -436,6 +436,11 @@ The class `PolyfillExtensions` includes the following extension methods: ### StringComparison + +### TimeSpan + + * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 5b43c91a..7ff4bf6e 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.11.0 + 1.12.0 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_DateTime.cs b/src/Polyfill/PolyfillExtensions_DateTime.cs index f3d3c50f..7295849a 100644 --- a/src/Polyfill/PolyfillExtensions_DateTime.cs +++ b/src/Polyfill/PolyfillExtensions_DateTime.cs @@ -14,11 +14,23 @@ static partial class PolyfillExtensions const long TicksPerMicrosecond = 10; /// - /// Gets the nanosecond component of the time represented by the current DateTime object. + /// Gets the nanosecond component of the time represented by the current object. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds")] + public static int Nanoseconds(this TimeSpan target) + { +#if NET7_0_OR_GREATER + return target.Nanoseconds; +#else + return (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; +#endif + } + + /// + /// Gets the nanosecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond")] - public static int Nanosecond( - this DateTime target) + public static int Nanosecond(this DateTime target) { #if NET7_0_OR_GREATER return target.Nanosecond; @@ -28,11 +40,10 @@ public static int Nanosecond( } /// - /// Gets the nanosecond component of the time represented by the current DateTimeOffset object. + /// Gets the nanosecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond")] - public static int Nanosecond( - this DateTimeOffset target) + public static int Nanosecond(this DateTimeOffset target) { #if NET7_0_OR_GREATER return target.Nanosecond; @@ -40,12 +51,26 @@ public static int Nanosecond( return (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; #endif } + + /// + /// Gets the microsecond component of the time represented by the current object. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond")] + public static int Microseconds(this TimeSpan target) + { +#if NET7_0_OR_GREATER + return target.Microseconds; +#else + return (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; +#endif + } + + /// - /// Gets the microsecond component of the time represented by the current DateTime object. + /// Gets the microsecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond")] - public static int Microsecond( - this DateTime target) + public static int Microsecond(this DateTime target) { #if NET7_0_OR_GREATER return target.Microsecond; @@ -55,11 +80,10 @@ public static int Microsecond( } /// - /// Gets the microsecond component of the time represented by the current DateTimeOffset object. + /// Gets the microsecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond")] - public static int Microsecond( - this DateTimeOffset target) + public static int Microsecond(this DateTimeOffset target) { #if NET7_0_OR_GREATER return target.Microsecond; @@ -68,17 +92,24 @@ public static int Microsecond( #endif } + static long TicksComponent(this TimeSpan target) + { + var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); + var secondsPart = target - noSeconds; + return secondsPart.Ticks; + } + static long TicksComponent(this DateTime target) { - var withNoSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); - var secondsPart = target - withNoSeconds; + var noSeconds = new DateTime(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Kind); + var secondsPart = target - noSeconds; return secondsPart.Ticks; } static long TicksComponent(this DateTimeOffset target) { - var withNoSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); - var secondsPart = target - withNoSeconds; + var noSeconds = new DateTimeOffset(target.Year, target.Month, target.Day, target.Hour, target.Minute, 0, target.Offset); + var secondsPart = target - noSeconds; return secondsPart.Ticks; } } \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_DateTime.cs b/src/Tests/PolyfillExtensionsTests_DateTime.cs index 50b9dc3e..5580ab2f 100644 --- a/src/Tests/PolyfillExtensionsTests_DateTime.cs +++ b/src/Tests/PolyfillExtensionsTests_DateTime.cs @@ -4,11 +4,13 @@ partial class PolyfillExtensionsTests static DateTimeOffset dateTimeOffset = DateTimeOffset.Now; static DateTime dateTime = DateTime.Now; + static TimeSpan timeSpan = DateTime.Now.TimeOfDay; [Test] public void Nanoseconds() { Assert.AreEqual(dateTimeOffset.Nanosecond, dateTimeOffset.Nanosecond()); + Assert.AreEqual(timeSpan.Nanoseconds, timeSpan.Nanoseconds()); Assert.AreEqual(dateTime.Nanosecond, dateTime.Nanosecond()); } @@ -16,6 +18,7 @@ public void Nanoseconds() public void Microsecond() { Assert.AreEqual(dateTimeOffset.Microsecond, dateTimeOffset.Microsecond()); + Assert.AreEqual(timeSpan.Microseconds, timeSpan.Microseconds()); Assert.AreEqual(dateTime.Microsecond, dateTime.Microsecond()); } #endif From 6eff537cbae51523f8f2c560e3455c2041ec49b4 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 5 Apr 2023 20:17:16 +1000 Subject: [PATCH 050/313] cleanup --- ... => PolyfillExtensions_MicroNanosecond.cs} | 49 +++++++------------ ...olyfillExtensionsTests_MicroNanosecond.cs} | 0 2 files changed, 18 insertions(+), 31 deletions(-) rename src/Polyfill/{PolyfillExtensions_DateTime.cs => PolyfillExtensions_MicroNanosecond.cs} (72%) rename src/Tests/{PolyfillExtensionsTests_DateTime.cs => PolyfillExtensionsTests_MicroNanosecond.cs} (100%) diff --git a/src/Polyfill/PolyfillExtensions_DateTime.cs b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs similarity index 72% rename from src/Polyfill/PolyfillExtensions_DateTime.cs rename to src/Polyfill/PolyfillExtensions_MicroNanosecond.cs index 7295849a..d2e777f3 100644 --- a/src/Polyfill/PolyfillExtensions_DateTime.cs +++ b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs @@ -17,80 +17,67 @@ static partial class PolyfillExtensions /// Gets the nanosecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds")] - public static int Nanoseconds(this TimeSpan target) - { + public static int Nanoseconds(this TimeSpan target) => #if NET7_0_OR_GREATER - return target.Nanoseconds; + target.Nanoseconds; #else - return (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; #endif - } /// /// Gets the nanosecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond")] - public static int Nanosecond(this DateTime target) - { + public static int Nanosecond(this DateTime target) => #if NET7_0_OR_GREATER - return target.Nanosecond; + target.Nanosecond; #else - return (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; #endif - } /// /// Gets the nanosecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond")] - public static int Nanosecond(this DateTimeOffset target) - { + public static int Nanosecond(this DateTimeOffset target) => #if NET7_0_OR_GREATER - return target.Nanosecond; + target.Nanosecond; #else - return (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; #endif - } /// /// Gets the microsecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond")] - public static int Microseconds(this TimeSpan target) - { + public static int Microseconds(this TimeSpan target) => #if NET7_0_OR_GREATER - return target.Microseconds; + target.Microseconds; #else - return (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; + (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; #endif - } - /// /// Gets the microsecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond")] - public static int Microsecond(this DateTime target) - { + public static int Microsecond(this DateTime target) => #if NET7_0_OR_GREATER - return target.Microsecond; + target.Microsecond; #else - return (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; + (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; #endif - } /// /// Gets the microsecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond")] - public static int Microsecond(this DateTimeOffset target) - { + public static int Microsecond(this DateTimeOffset target) => #if NET7_0_OR_GREATER - return target.Microsecond; + target.Microsecond; #else - return (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; + (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; #endif - } static long TicksComponent(this TimeSpan target) { diff --git a/src/Tests/PolyfillExtensionsTests_DateTime.cs b/src/Tests/PolyfillExtensionsTests_MicroNanosecond.cs similarity index 100% rename from src/Tests/PolyfillExtensionsTests_DateTime.cs rename to src/Tests/PolyfillExtensionsTests_MicroNanosecond.cs From 5f475fbed0f2cca1339c32fcc2da7563b1ad7a37 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 5 Apr 2023 21:30:22 +1000 Subject: [PATCH 051/313] add AddMicroseconds (#24) --- api_list.include.md | 2 ++ readme.md | 2 ++ src/Directory.Build.props | 2 +- .../PolyfillExtensions_MicroNanosecond.cs | 24 ++++++++++++++++++- ...PolyfillExtensionsTests_MicroNanosecond.cs | 15 ++++++++++-- 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index 5dc147b3..6b1b83a8 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -1,10 +1,12 @@ ### DateTime + * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### DateTimeOffset + * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/readme.md b/readme.md index f3c1364b..0a9cfe25 100644 --- a/readme.md +++ b/readme.md @@ -349,11 +349,13 @@ The class `PolyfillExtensions` includes the following extension methods: ### DateTime + * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### DateTimeOffset + * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 7ff4bf6e..01da7055 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.12.0 + 1.13.0 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs index d2e777f3..62f46d07 100644 --- a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs +++ b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs @@ -11,7 +11,7 @@ static partial class PolyfillExtensions { - const long TicksPerMicrosecond = 10; + const long TicksPerMicrosecond = TimeSpan.TicksPerMillisecond * 1000; /// /// Gets the nanosecond component of the time represented by the current object. @@ -79,6 +79,28 @@ public static int Microsecond(this DateTimeOffset target) => (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; #endif + /// + /// Returns a new object that adds a specified number of microseconds to the value of this instance.. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds")] + public static DateTime AddMicroseconds(this DateTime target, double microseconds) => +#if NET7_0_OR_GREATER + target.AddMicroseconds(microseconds); +#else + target.AddMilliseconds(microseconds / 1000); +#endif + + /// + /// Returns a new object that adds a specified number of microseconds to the value of this instance.. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds")] + public static DateTimeOffset AddMicroseconds(this DateTimeOffset target, double microseconds) => +#if NET7_0_OR_GREATER + target.AddMicroseconds(microseconds); +#else + target.AddMilliseconds(microseconds / 1000); +#endif + static long TicksComponent(this TimeSpan target) { var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); diff --git a/src/Tests/PolyfillExtensionsTests_MicroNanosecond.cs b/src/Tests/PolyfillExtensionsTests_MicroNanosecond.cs index 5580ab2f..890a5741 100644 --- a/src/Tests/PolyfillExtensionsTests_MicroNanosecond.cs +++ b/src/Tests/PolyfillExtensionsTests_MicroNanosecond.cs @@ -1,11 +1,10 @@ partial class PolyfillExtensionsTests { -#if NET7_0_OR_GREATER - static DateTimeOffset dateTimeOffset = DateTimeOffset.Now; static DateTime dateTime = DateTime.Now; static TimeSpan timeSpan = DateTime.Now.TimeOfDay; +#if NET7_0_OR_GREATER [Test] public void Nanoseconds() { @@ -22,4 +21,16 @@ public void Microsecond() Assert.AreEqual(dateTime.Microsecond, dateTime.Microsecond()); } #endif + + [Test] + public void AddMicroseconds() + { + var fromTicksDateTimeOffset = dateTimeOffset.AddSeconds(1); + var fromMicrosecondsDateTimeOffset = dateTimeOffset.AddMicroseconds(1000000); + Assert.AreEqual(fromTicksDateTimeOffset, fromMicrosecondsDateTimeOffset); + + var fromTicksDateTime = dateTime.AddSeconds(1); + var fromMicrosecondsDateTime = dateTime.AddMicroseconds(1000000); + Assert.AreEqual(fromTicksDateTime, fromMicrosecondsDateTime); + } } \ No newline at end of file From 36af73f5ee7fa44836f5d9caf2ab4ddf0aeb7792 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 5 Apr 2023 22:42:19 +1000 Subject: [PATCH 052/313] add StreamWriter.WriteLineAsync (#25) --- api_list.include.md | 1 + contributing.md | 28 ++++++++++++++++++- readme.md | 1 + src/Directory.Build.props | 2 +- .../PolyfillExtensions_StreamWriter.cs | 26 +++++++++++++++++ .../PolyfillExtensionsTests_StreamWriter.cs | 26 +++++++++++++++++ 6 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 src/Tests/PolyfillExtensionsTests_StreamWriter.cs diff --git a/api_list.include.md b/api_list.include.md index 6b1b83a8..b7b6365a 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -71,6 +71,7 @@ ### StreamWriter * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### String diff --git a/contributing.md b/contributing.md index 38f86266..a3ac3d38 100644 --- a/contributing.md +++ b/contributing.md @@ -231,10 +231,36 @@ static partial class PolyfillExtensions return new(target.WriteAsync(segment.Array!, segment.Offset, segment.Count)); } + + /// + /// Asynchronously writes the text representation of a character memory region to the stream, followed by a line terminator. + /// + /// The character memory region to write to the stream. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// A task that represents the asynchronous write operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writelineasync#system-io-streamwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] + public static ValueTask WriteLineAsync( + this StreamWriter target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + // StreamReader doesn't accept cancellation token (pre-netstd2.1) + cancellationToken.ThrowIfCancellationRequested(); + + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + + return new(target.WriteLineAsync(segment.Array!, segment.Offset, segment.Count)); + } } #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/readme.md b/readme.md index 0a9cfe25..ecf55edb 100644 --- a/readme.md +++ b/readme.md @@ -420,6 +420,7 @@ The class `PolyfillExtensions` includes the following extension methods: ### StreamWriter * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### String diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 01da7055..3755d3f1 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.13.0 + 1.14.0 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_StreamWriter.cs b/src/Polyfill/PolyfillExtensions_StreamWriter.cs index 9afed4c2..be531ad2 100644 --- a/src/Polyfill/PolyfillExtensions_StreamWriter.cs +++ b/src/Polyfill/PolyfillExtensions_StreamWriter.cs @@ -40,5 +40,31 @@ public static ValueTask WriteAsync( return new(target.WriteAsync(segment.Array!, segment.Offset, segment.Count)); } + + /// + /// Asynchronously writes the text representation of a character memory region to the stream, followed by a line terminator. + /// + /// The character memory region to write to the stream. + /// + /// The token to monitor for cancellation requests. + /// The default value is . + /// + /// A task that represents the asynchronous write operation. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writelineasync#system-io-streamwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] + public static ValueTask WriteLineAsync( + this StreamWriter target, + ReadOnlyMemory buffer, + CancellationToken cancellationToken = default) + { + // StreamReader doesn't accept cancellation token (pre-netstd2.1) + cancellationToken.ThrowIfCancellationRequested(); + + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + + return new(target.WriteLineAsync(segment.Array!, segment.Offset, segment.Count)); + } } #endif \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_StreamWriter.cs b/src/Tests/PolyfillExtensionsTests_StreamWriter.cs new file mode 100644 index 00000000..916c211f --- /dev/null +++ b/src/Tests/PolyfillExtensionsTests_StreamWriter.cs @@ -0,0 +1,26 @@ +partial class PolyfillExtensionsTests +{ + [Test] + public async Task StreamWriterWriteAsync() + { + using var stream = new MemoryStream(); + var memory = new Memory("value".ToArray()); + using var writer = new StreamWriter(stream); + await writer.WriteAsync(memory); + await writer.FlushAsync(); + var s = Encoding.UTF8.GetString(stream.ToArray()); + Assert.AreEqual("value", s); + } + + [Test] + public async Task StreamWriterWriteLineAsync() + { + using var stream = new MemoryStream(); + var memory = new Memory("value".ToArray()); + using var writer = new StreamWriter(stream); + await writer.WriteLineAsync(memory); + await writer.FlushAsync(); + var s = Encoding.UTF8.GetString(stream.ToArray()); + Assert.AreEqual("value" + Environment.NewLine, s); + } +} From b8e52abb6217cd8e532fb975b4723ca05622e771 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 7 Apr 2023 14:49:49 +1000 Subject: [PATCH 053/313] Create notes.md --- notes.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 notes.md diff --git a/notes.md b/notes.md new file mode 100644 index 00000000..b41c1968 --- /dev/null +++ b/notes.md @@ -0,0 +1 @@ +apidiff https://github.com/dotnet/core/blob/main/release-notes/8.0/8.0.1/api-diff/README.md \ No newline at end of file From 297eb67174804865d80d4017451a73ab27225606 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Apr 2023 17:07:30 +1000 Subject: [PATCH 054/313] Bump Verify.NUnit from 19.12.0 to 19.12.1 in /src (#26) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 19.12.0 to 19.12.1. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/compare/19.12.0...19.12.1) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 4 ++-- src/PublicTests/PublicTests.csproj | 4 ++-- src/Tests/Tests.csproj | 4 ++-- src/UnsafeTests/UnsafeTests.csproj | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 9f3828f5..cc2a3c61 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -1,4 +1,4 @@ - + net462;net472;net48;net6.0-windows $(TargetFrameworks);netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 @@ -24,7 +24,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 26210e81..ffd21700 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -1,4 +1,4 @@ - + net462;net472;net48 $(TargetFrameworks);netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 @@ -21,7 +21,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index bb715ea5..14dd526d 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -1,4 +1,4 @@ - + net462;net472;net48;net6.0-windows $(TargetFrameworks);netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 @@ -20,7 +20,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index d8107e1e..977d8496 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -1,4 +1,4 @@ - + net462;net472;net48 $(TargetFrameworks);netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 @@ -21,7 +21,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 37e07f5e1d0357e13087be7668b9ca09c894b66e Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 11 Apr 2023 22:30:14 +1000 Subject: [PATCH 055/313] add StringBuilder.CopyTo (#27) --- api_list.include.md | 1 + notes.md | 2 +- readme.md | 1 + src/Consume/Consume.cs | 7 +- src/Directory.Build.props | 2 +- src/Polyfill/PolyfillExtensions_Memory.cs | 58 ---------- .../PolyfillExtensions_StringBuilder.cs | 109 ++++++++++++++++++ .../PolyfillExtensionsTests_StringBuilder.cs | 26 +++++ 8 files changed, 143 insertions(+), 63 deletions(-) create mode 100644 src/Polyfill/PolyfillExtensions_StringBuilder.cs create mode 100644 src/Tests/PolyfillExtensionsTests_StringBuilder.cs diff --git a/api_list.include.md b/api_list.include.md index b7b6365a..8193fff8 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -86,6 +86,7 @@ ### StringBuilder * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### StringComparison diff --git a/notes.md b/notes.md index b41c1968..71109e0e 100644 --- a/notes.md +++ b/notes.md @@ -1 +1 @@ -apidiff https://github.com/dotnet/core/blob/main/release-notes/8.0/8.0.1/api-diff/README.md \ No newline at end of file +apidiff https://github.com/dotnet/core/blob/main/release-notes/8.0/8.0.1/api-diff/README.md diff --git a/readme.md b/readme.md index ecf55edb..f46155fe 100644 --- a/readme.md +++ b/readme.md @@ -435,6 +435,7 @@ The class `PolyfillExtensions` includes the following extension methods: ### StringBuilder * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### StringComparison diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index a06df565..f799b639 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -138,10 +138,11 @@ async Task StreamReadAsync() var read = await stream.ReadAsync(memory); } - void SpanContains() + void StringBuilderCopyTo() { - var contains = "value".AsSpan().Contains('e'); - contains = new Span().Contains('e'); + var builder = new StringBuilder("value"); + var span = new Span(new char[1]); + builder.CopyTo(0, span, 1); } void SpanSequenceEqual() diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 3755d3f1..2caf8981 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.14.0 + 1.15.0 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index 2dfb7331..28023345 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -55,33 +55,6 @@ public static bool Contains(this Span target, T value) return false; } - /// - /// Appends the string representation of a specified read-only character span to this instance. - /// - /// The read-only character span to append. - /// A reference to this instance after the append operation is completed. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))")] - public static StringBuilder Append(this StringBuilder target, ReadOnlySpan value) - { - if (value.Length <= 0) - { - return target; - } - -#if AllowUnsafeBlocks - unsafe - { - fixed (char* valueChars = &MemoryMarshal.GetReference(value)) - { - target.Append(valueChars, value.Length); - } - } -#else - target.Append(value.ToArray()); -#endif - return target; - } - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] public static bool SequenceEqual(this ReadOnlySpan target, string other) { @@ -123,36 +96,5 @@ public static bool SequenceEqual(this Span target, string other) return true; } - - /// - /// Returns a value indicating whether the characters in this instance are equal to the characters in a specified - /// read-only character span. - /// - /// The character span to compare with the current instance. - /// - /// The Equals method performs an ordinal comparison to determine whether the characters in the current instance - /// and span are equal. - /// - /// true if the characters in this instance and span are the same; otherwise, false. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))")] - public static bool Equals(this StringBuilder target, ReadOnlySpan span) - { - if (target.Length != span.Length) - { - return false; - } - - for (var index = 0; index < target.Length; index++) - { - var ch1 = target[index]; - var ch2 = span[index]; - if (ch1 != ch2) - { - return false; - } - } - - return true; - } } #endif \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_StringBuilder.cs b/src/Polyfill/PolyfillExtensions_StringBuilder.cs new file mode 100644 index 00000000..9c686941 --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_StringBuilder.cs @@ -0,0 +1,109 @@ +#if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable UnusedMember.Global + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using System.Threading; +using System.Threading.Tasks; +// ReSharper disable RedundantAttributeSuffix + +static partial class PolyfillExtensions +{ + /// + /// Copies the characters from a specified segment of this instance to a destination Char span. + /// + /// The starting position in this instance where characters will be copied from. The index is zero-based. + /// The writable span where characters will be copied. + /// The number of characters to be copied. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)")] + public static void CopyTo( + this StringBuilder target, + int sourceIndex, + Span destination, + int count) + { + var destinationIndex = 0; + while (true) + { + if (sourceIndex == target.Length) + { + break; + } + + if (destinationIndex == count) + { + break; + } + + destination[destinationIndex] = target[sourceIndex]; + destinationIndex++; + sourceIndex++; + } + } + + /// + /// Appends the string representation of a specified read-only character span to this instance. + /// + /// The read-only character span to append. + /// A reference to this instance after the append operation is completed. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))")] + public static StringBuilder Append(this StringBuilder target, ReadOnlySpan value) + { + if (value.Length <= 0) + { + return target; + } + +#if AllowUnsafeBlocks + unsafe + { + fixed (char* valueChars = &MemoryMarshal.GetReference(value)) + { + target.Append(valueChars, value.Length); + } + } +#else + target.Append(value.ToArray()); +#endif + return target; + } + + /// + /// Returns a value indicating whether the characters in this instance are equal to the characters in a specified + /// read-only character span. + /// + /// The character span to compare with the current instance. + /// + /// The Equals method performs an ordinal comparison to determine whether the characters in the current instance + /// and span are equal. + /// + /// true if the characters in this instance and span are the same; otherwise, false. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))")] + public static bool Equals(this StringBuilder target, ReadOnlySpan span) + { + if (target.Length != span.Length) + { + return false; + } + + for (var index = 0; index < target.Length; index++) + { + var ch1 = target[index]; + var ch2 = span[index]; + if (ch1 != ch2) + { + return false; + } + } + + return true; + } +} +#endif \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_StringBuilder.cs b/src/Tests/PolyfillExtensionsTests_StringBuilder.cs new file mode 100644 index 00000000..f0344114 --- /dev/null +++ b/src/Tests/PolyfillExtensionsTests_StringBuilder.cs @@ -0,0 +1,26 @@ +// ReSharper disable PartialTypeWithSinglePart + +partial class PolyfillExtensionsTests +{ + [Test] + public void StringBuilderCopyTo() + { + var builder = new StringBuilder("value"); + + var span = new Span(new char[1]); + builder.CopyTo(0, span, 1); + Assert.True(span.SequenceEqual("v")); + + span = new(new char[1]); + builder.CopyTo(1, span, 1); + Assert.True(span.SequenceEqual("a")); + + span = new(new char[2]); + builder.CopyTo(1, span, 2); + Assert.True(span.SequenceEqual("al")); + + span = new(new char[5]); + builder.CopyTo(0, span, 5); + Assert.True(span.SequenceEqual("value")); + } +} \ No newline at end of file From e6170a283f3cccf8260d05f901bd60c7e7e12bfb Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 13 Apr 2023 11:57:48 +1000 Subject: [PATCH 056/313] Add Span.StartsWith (#28) --- api_list.include.md | 8 ++++ readme.md | 8 ++++ src/Consume/Consume.cs | 5 ++ src/Polyfill/PolyfillExtensions_Memory.cs | 52 +++++---------------- src/Tests/PolyfillExtensionsTests_Memory.cs | 16 +++++++ 5 files changed, 49 insertions(+), 40 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index 8193fff8..835c8d90 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -49,6 +49,10 @@ * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### ReadOnlySpan + + * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### Span * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) @@ -57,6 +61,10 @@ * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### Span + + * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### Stream * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/readme.md b/readme.md index f46155fe..c00deb21 100644 --- a/readme.md +++ b/readme.md @@ -398,6 +398,10 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### ReadOnlySpan + + * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### Span * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) @@ -406,6 +410,10 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### Span + + * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### Stream * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index f799b639..936e8a64 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -150,6 +150,11 @@ void SpanSequenceEqual() var sequenceEqual = "value".AsSpan().SequenceEqual("value"); } + void SpanStartsWith() + { + var sequenceEqual = "value".AsSpan().StartsWith("value"); + } + void SpanStringBuilderAppend() { var builder = new StringBuilder(); diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index 28023345..89d08601 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -24,8 +24,7 @@ public static bool Contains(this ReadOnlySpan target, T value) { for (var index = 0; index < target.Length; index++) { - var item = target[index]; - if (item.Equals(value)) + if (target[index].Equals(value)) { return true; } @@ -45,8 +44,7 @@ public static bool Contains(this Span target, T value) { for (var index = 0; index < target.Length; index++) { - var item = target[index]; - if (item.Equals(value)) + if (target[index].Equals(value)) { return true; } @@ -56,45 +54,19 @@ public static bool Contains(this Span target, T value) } [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] - public static bool SequenceEqual(this ReadOnlySpan target, string other) - { - if (target.Length != other.Length) - { - return false; - } - - for (var index = 0; index < target.Length; index++) - { - var ch1 = target[index]; - var ch2 = other[index]; - if (ch1 != ch2) - { - return false; - } - } - - return true; - } + public static bool SequenceEqual(this ReadOnlySpan target, string other) => + target.SequenceEqual(other.AsSpan()); [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))")] - public static bool SequenceEqual(this Span target, string other) - { - if (target.Length != other.Length) - { - return false; - } + public static bool SequenceEqual(this Span target, string other) => + target.SequenceEqual(other.AsSpan()); - for (var index = 0; index < target.Length; index++) - { - var ch1 = target[index]; - var ch2 = other[index]; - if (ch1 != ch2) - { - return false; - } - } + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] + public static bool StartsWith(this ReadOnlySpan target, string other) => + target.StartsWith(other.AsSpan()); - return true; - } + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))")] + public static bool StartsWith(this Span target, string other) => + target.StartsWith(other.AsSpan()); } #endif \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_Memory.cs b/src/Tests/PolyfillExtensionsTests_Memory.cs index c0b7f6da..92301de4 100644 --- a/src/Tests/PolyfillExtensionsTests_Memory.cs +++ b/src/Tests/PolyfillExtensionsTests_Memory.cs @@ -12,8 +12,24 @@ public void SpanContains() public void SpanSequenceEqual() { Assert.True("value".AsSpan().SequenceEqual("value")); + Assert.False("value".AsSpan().SequenceEqual("value2")); + Assert.False("value".AsSpan().SequenceEqual("v")); var span = new Span("value".ToCharArray()); Assert.True(span.SequenceEqual("value")); + Assert.False(span.SequenceEqual("value2")); + Assert.False(span.SequenceEqual("v")); + } + + [Test] + public void SpanStartsWith() + { + Assert.True("value".AsSpan().StartsWith("value")); + Assert.False("value".AsSpan().StartsWith("value2")); + Assert.True("value".AsSpan().StartsWith("v")); + var span = new Span("value".ToCharArray()); + Assert.True(span.StartsWith("value")); + Assert.False(span.StartsWith("value2")); + Assert.True(span.StartsWith("val")); } [Test] From 8ec7b12bb0f1f6accdaeffb662de6a2a2180f95f Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 13 Apr 2023 12:05:49 +1000 Subject: [PATCH 057/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 2caf8981..5f2e92a5 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.15.0 + 1.16.0 1.0.0 Polyfill true From 12c921cfdfe85f22881a80523bc2896f77c87e62 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Apr 2023 19:22:18 +1000 Subject: [PATCH 058/313] Bump Verify.NUnit from 19.12.1 to 19.12.2 in /src (#29) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 19.12.1 to 19.12.2. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/compare/19.12.1...19.12.2) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index cc2a3c61..f80ecf2e 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -24,7 +24,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index ffd21700..cb398125 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -21,7 +21,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 14dd526d..e2f58dff 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -20,7 +20,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 977d8496..cb321a56 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -21,7 +21,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 90a6c65cf3fcff59dbdc4cff1cba383f14a8bf10 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 14 Apr 2023 20:12:35 +1000 Subject: [PATCH 059/313] add IsGenericMethodParameter, GetMemberWithSameMetadataDefinitionAs, and HasSameMetadataDefinitionAs (#31) --- api_list.include.md | 8 ++++ readme.md | 8 ++++ src/Consume/Consume.cs | 20 +++++++- src/Polyfill/PolyfillExtensions_Type.cs | 64 +++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 src/Polyfill/PolyfillExtensions_Type.cs diff --git a/api_list.include.md b/api_list.include.md index 835c8d90..aaab4185 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -41,6 +41,10 @@ * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### Reflection.MemberInfo + + * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### ReadOnlySpan * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) @@ -105,3 +109,7 @@ * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### Type + + * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + diff --git a/readme.md b/readme.md index c00deb21..0846139c 100644 --- a/readme.md +++ b/readme.md @@ -390,6 +390,10 @@ The class `PolyfillExtensions` includes the following extension methods: * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### Reflection.MemberInfo + + * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### ReadOnlySpan * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) @@ -453,6 +457,10 @@ The class `PolyfillExtensions` includes the following extension methods: * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### Type + + * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 936e8a64..f26eaab2 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -8,6 +8,7 @@ using System.IO; using System.Linq; using System.Net.Http; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; @@ -147,12 +148,27 @@ void StringBuilderCopyTo() void SpanSequenceEqual() { - var sequenceEqual = "value".AsSpan().SequenceEqual("value"); + var result = "value".AsSpan().SequenceEqual("value"); } void SpanStartsWith() { - var sequenceEqual = "value".AsSpan().StartsWith("value"); + var result = "value".AsSpan().StartsWith("value"); + } + + void IsGenericMethodParameter() + { + var result = typeof(string).IsGenericMethodParameter(); + } + + void HasSameMetadataDefinitionAs(MemberInfo info) + { + var result = info.HasSameMetadataDefinitionAs(info); + } + + void GetMemberWithSameMetadataDefinitionAs(MemberInfo info) + { + var result = typeof(string).GetMemberWithSameMetadataDefinitionAs(info); } void SpanStringBuilderAppend() diff --git a/src/Polyfill/PolyfillExtensions_Type.cs b/src/Polyfill/PolyfillExtensions_Type.cs new file mode 100644 index 00000000..33ba2e8a --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_Type.cs @@ -0,0 +1,64 @@ + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable UnusedMember.Global +// ReSharper disable RedundantAttributeSuffix + +using System; +using System.Reflection; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; + +static partial class PolyfillExtensions +{ + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas")] + public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInfo other) + { +#if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0 + return target.MetadataToken == other.MetadataToken && + target.Module.Equals(other.Module); +#else + return target.HasSameMetadataDefinitionAs(other); +#endif + } + + /// + /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter")] + public static bool IsGenericMethodParameter(this Type target) + { +#if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0 + return target.IsGenericParameter && + target.DeclaringMethod != null; +#else + return target.IsGenericMethodParameter; +#endif + } + +#if !NET6_0_OR_GREATER + + /// + /// Searches for the MemberInfo on the current Type that matches the specified MemberInfo. + /// + /// The MemberInfo to find on the current Type. + /// The MemberInfo to find on the current Type. + /// An object representing the member on the current Type that matches the specified member. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.type.getmemberwithsamemetadatadefinitionas")] + internal static MemberInfo GetMemberWithSameMetadataDefinitionAs(this Type type, MemberInfo member) + { + const BindingFlags all = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; + foreach (var info in type.GetMembers(all)) + { + if (info.HasSameMetadataDefinitionAs(member)) + { + return info; + } + } + + throw new MissingMemberException(type.FullName, member.Name); + } + +#endif +} \ No newline at end of file From 020be91291013b141e90463c2badaf20f3c92295 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 14 Apr 2023 20:13:45 +1000 Subject: [PATCH 060/313] add Span.EndsWith (#30) --- api_list.include.md | 10 +++++++++- readme.md | 2 +- src/Consume/Consume.cs | 12 ++++++++++-- src/Polyfill/PolyfillExtensions_Memory.cs | 13 +++++++++++-- src/Tests/PolyfillExtensionsTests_Memory.cs | 12 ++++++++++++ 5 files changed, 43 insertions(+), 6 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index aaab4185..69919d06 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -55,7 +55,11 @@ ### ReadOnlySpan - * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### ReadOnlySpan + + * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### Span @@ -69,6 +73,10 @@ * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### Span + + * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### Stream * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/readme.md b/readme.md index 0846139c..e39d7a77 100644 --- a/readme.md +++ b/readme.md @@ -404,7 +404,7 @@ The class `PolyfillExtensions` includes the following extension methods: ### ReadOnlySpan - * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### Span diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index f26eaab2..2b9f0c63 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -153,9 +153,17 @@ void SpanSequenceEqual() void SpanStartsWith() { - var result = "value".AsSpan().StartsWith("value"); + var startsWith = "value".AsSpan().StartsWith("value"); + startsWith = "value".AsSpan().StartsWith("value", StringComparison.Ordinal); } + + void SpanEndsWith() + { + var result = "value".AsSpan().EndsWith("value"); + result = "value".AsSpan().EndsWith("value", StringComparison.Ordinal); + } + void IsGenericMethodParameter() { var result = typeof(string).IsGenericMethodParameter(); @@ -169,7 +177,7 @@ void HasSameMetadataDefinitionAs(MemberInfo info) void GetMemberWithSameMetadataDefinitionAs(MemberInfo info) { var result = typeof(string).GetMemberWithSameMetadataDefinitionAs(info); - } + } void SpanStringBuilderAppend() { diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index 89d08601..604caede 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -7,6 +7,7 @@ // ReSharper disable RedundantAttributeSuffix using System; +using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; @@ -62,11 +63,19 @@ public static bool SequenceEqual(this Span target, string other) => target.SequenceEqual(other.AsSpan()); [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] - public static bool StartsWith(this ReadOnlySpan target, string other) => - target.StartsWith(other.AsSpan()); + public static bool StartsWith(this ReadOnlySpan target, string other, StringComparison comparison = StringComparison.CurrentCulture) => + target.StartsWith(other.AsSpan(), comparison); [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))")] public static bool StartsWith(this Span target, string other) => target.StartsWith(other.AsSpan()); + + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] + public static bool EndsWith(this ReadOnlySpan target, string other, StringComparison comparison = StringComparison.CurrentCulture) => + target.EndsWith(other.AsSpan(), comparison); + + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))")] + public static bool EndsWith(this Span target, string other) => + target.EndsWith(other.AsSpan()); } #endif \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_Memory.cs b/src/Tests/PolyfillExtensionsTests_Memory.cs index 92301de4..77783f9d 100644 --- a/src/Tests/PolyfillExtensionsTests_Memory.cs +++ b/src/Tests/PolyfillExtensionsTests_Memory.cs @@ -32,6 +32,18 @@ public void SpanStartsWith() Assert.True(span.StartsWith("val")); } + [Test] + public void SpanEndsWith() + { + Assert.True("value".AsSpan().EndsWith("value")); + Assert.False("value".AsSpan().EndsWith("value2")); + Assert.True("value".AsSpan().EndsWith("e")); + var span = new Span("value".ToCharArray()); + Assert.True(span.EndsWith("value")); + Assert.False(span.EndsWith("value2")); + Assert.True(span.EndsWith("lue")); + } + [Test] public void SpanStringBuilderAppend() { From 0e8f08048eb0c0225d3366cc855667b9e49b1654 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 14 Apr 2023 20:17:36 +1000 Subject: [PATCH 061/313] Update readme.md --- readme.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/readme.md b/readme.md index e39d7a77..16fcfac4 100644 --- a/readme.md +++ b/readme.md @@ -406,6 +406,10 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### ReadOnlySpan + + * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### Span * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) @@ -418,6 +422,10 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) +### Span + + * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### Stream * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) From 665e309ee810e9b4d4f65470b51f0997eec29944 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 14 Apr 2023 21:59:17 +1000 Subject: [PATCH 062/313] docs --- api_list.include.md | 94 +++++++++++++++++++-------------------- readme.md | 94 +++++++++++++++++++-------------------- src/Tests/BuildApiTest.cs | 4 +- 3 files changed, 97 insertions(+), 95 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index 69919d06..a3d61ec1 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -1,123 +1,123 @@ ### DateTime - * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond) ### DateTimeOffset - * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond) ### HttpClient - * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) + * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)) + * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) + * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) ### HttpContent - * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) + * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) + * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) ### IEnumerable - * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) ### IReadOnlyDictionary - * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) ### IReadOnlyDictionary - * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) ### KeyValuePair - * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) ### Reflection.MemberInfo - * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas) ### ReadOnlySpan - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) ### ReadOnlySpan - * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) ### ReadOnlySpan - * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) ### ReadOnlySpan - * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) ### Span - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) ### Span - * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) ### Span - * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) ### Span - * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) ### Stream - * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) ### StreamReader - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readtoendasync#system-io-streamreader-readtoendasync(system-threading-cancellationtoken)) ### StreamWriter * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writelineasync#system-io-streamwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### String - * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) + * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) + * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)) + * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)) + * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) ### StringBuilder - * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) + * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) + * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) ### StringComparison ### TimeSpan - * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond) + * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) ### Type - * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) diff --git a/readme.md b/readme.md index 16fcfac4..716f0cbf 100644 --- a/readme.md +++ b/readme.md @@ -349,126 +349,126 @@ The class `PolyfillExtensions` includes the following extension methods: ### DateTime - * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond) ### DateTimeOffset - * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond) ### HttpClient - * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) + * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)) + * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) + * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) ### HttpContent - * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) + * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) + * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) ### IEnumerable - * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) ### IReadOnlyDictionary - * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) ### IReadOnlyDictionary - * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) ### KeyValuePair - * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) ### Reflection.MemberInfo - * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas) ### ReadOnlySpan - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) ### ReadOnlySpan - * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) ### ReadOnlySpan - * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) ### ReadOnlySpan - * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) ### Span - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) ### Span - * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) ### Span - * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) ### Span - * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) ### Stream - * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) ### StreamReader - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readtoendasync#system-io-streamreader-readtoendasync(system-threading-cancellationtoken)) ### StreamWriter * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writelineasync#system-io-streamwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### String - * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) + * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) + * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)) + * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)) + * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) ### StringBuilder - * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) + * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) + * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) ### StringComparison ### TimeSpan - * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond) + * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) ### Type - * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index f49fac47..5c49fed7 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -36,6 +36,7 @@ public void Run() { continue; } + var parameters = string.Join(", ", method.Parameters.Skip(1).Select(_ => SimpleTypeName(_.ParameterType.FullName))); var typeArgs = ""; if (method.HasGenericParameters) @@ -50,7 +51,8 @@ public void Run() { throw new($"Description required {method.FullName}"); } - writer.WriteLine($" * `{signature}` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken))"); + + writer.WriteLine($" * `{signature}` [reference]({descriptionAttribute.ConstructorArguments.Single().Value})"); } writer.WriteLine(); From a6064474c2febd2a30e09fa49a05ab29102ab7c2 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 17 Apr 2023 11:28:25 +1000 Subject: [PATCH 063/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index f80ecf2e..9c66faff 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -24,7 +24,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index cb398125..44ff8d14 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -21,7 +21,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index e2f58dff..46cb8e11 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -20,7 +20,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index cb321a56..d180f60e 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -21,7 +21,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From a9545d522fa9a8af22573fdd44b677b854086439 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 17 Apr 2023 20:11:57 +1000 Subject: [PATCH 064/313] Add Nullability APIs (#32) --- api_list.include.md | 30 +- readme.md | 187 ++--- src/Consume/Consume.csproj | 3 + .../ConsumeClassicReferences.csproj | 3 + src/ConsumeIndirect/ConsumeIndirect.csproj | 3 + src/NoRefsTests/NoRefsTests.csproj | 7 +- src/Polyfill/Nullability/NullabilityInfo.cs | 80 +++ .../Nullability/NullabilityInfoContext.cs | 666 ++++++++++++++++++ .../Nullability/NullabilityInfoExtensions.cs | 143 ++++ src/Polyfill/Polyfill.nuspec | 2 + src/PublicTests/PublicTests.csproj | 5 +- src/Tests/BuildApiTest.cs | 15 +- src/Tests/NullabilitySamples.cs | 68 ++ src/Tests/NullabilitySync.cs | 80 +++ src/Tests/NullabilityTarget.cs | 10 + src/Tests/Tests.csproj | 3 + src/UnsafeTests/UnsafeTests.csproj | 5 +- 17 files changed, 1177 insertions(+), 133 deletions(-) create mode 100644 src/Polyfill/Nullability/NullabilityInfo.cs create mode 100644 src/Polyfill/Nullability/NullabilityInfoContext.cs create mode 100644 src/Polyfill/Nullability/NullabilityInfoExtensions.cs create mode 100644 src/Tests/NullabilitySamples.cs create mode 100644 src/Tests/NullabilitySync.cs create mode 100644 src/Tests/NullabilityTarget.cs diff --git a/api_list.include.md b/api_list.include.md index a3d61ec1..39ae1a41 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -10,6 +10,18 @@ * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond) +### Reflection.EventInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + +### Reflection.FieldInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + ### HttpClient * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) @@ -43,7 +55,22 @@ ### Reflection.MemberInfo + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas) + * `Boolean IsNullable()` + +### Reflection.ParameterInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + +### Reflection.PropertyInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` ### ReadOnlySpan @@ -109,9 +136,6 @@ * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) -### StringComparison - - ### TimeSpan * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond) diff --git a/readme.md b/readme.md index 716f0cbf..57b14b37 100644 --- a/readme.md +++ b/readme.md @@ -347,129 +347,7 @@ Reference: [Improvements in native code interop in .NET 5.0](https://devblogs.mi The class `PolyfillExtensions` includes the following extension methods: -### DateTime - - * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) - * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) - * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond) - -### DateTimeOffset - - * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) - * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) - * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond) - -### HttpClient - - * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) - * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) - * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)) - * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)) - * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) - * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) - -### HttpContent - - * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) - * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) - * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) - -### IEnumerable - - * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) - -### IReadOnlyDictionary - - * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) - -### IReadOnlyDictionary - - * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) - -### KeyValuePair - - * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) - -### Reflection.MemberInfo - - * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas) - -### ReadOnlySpan - - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) - -### ReadOnlySpan - - * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - -### ReadOnlySpan - - * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - -### ReadOnlySpan - - * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - -### Span - - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) - -### Span - - * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) - -### Span - - * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) - -### Span - - * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) - -### Stream - - * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) - -### StreamReader - - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) - * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readtoendasync#system-io-streamreader-readtoendasync(system-threading-cancellationtoken)) - -### StreamWriter - - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writelineasync#system-io-streamwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - -### String - - * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) - * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) - * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) - * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) - * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)) - * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)) - * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) - -### StringBuilder - - * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) - * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) - * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) - -### StringComparison - - -### TimeSpan - - * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond) - * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) - -### Type - - * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) - + ## References @@ -514,6 +392,69 @@ If using ValueTask APIs and consuming in a project that target `netframework`, ` ``` +## Nullability + + +### Example target class + +Given the following class + + + +```cs +class NullabilityTarget +{ + public string? StringField; + public string?[] ArrayField; + public Dictionary GenericField; +} +``` +snippet source | anchor + + + +### NullabilityInfoContext + + + +```cs +[Test] +public void Test() +{ + var type = typeof(NullabilityTarget); + var arrayField = type.GetField("ArrayField")!; + var genericField = type.GetField("GenericField")!; + + var context = new NullabilityInfoContext(); + + var arrayInfo = context.Create(arrayField); + + Assert.AreEqual(NullabilityState.NotNull, arrayInfo.ReadState); + Assert.AreEqual(NullabilityState.Nullable, arrayInfo.ElementType!.ReadState); + + var genericInfo = context.Create(genericField); + + Assert.AreEqual(NullabilityState.NotNull, genericInfo.ReadState); + Assert.AreEqual(NullabilityState.NotNull, genericInfo.GenericTypeArguments[0].ReadState); + Assert.AreEqual(NullabilityState.Nullable, genericInfo.GenericTypeArguments[1].ReadState); +} +``` +snippet source | anchor + + + +### NullabilityInfoExtensions + +`NullabilityInfoExtensions` provides static and thread safe wrapper around `NullabilityInfoContext`. It adds three extension methods to each of ParameterInfo, PropertyInfo, EventInfo, and FieldInfo. + + * `GetNullabilityInfo`: returns the `NullabilityInfo` for the target info. + * `GetNullability`: returns the `NullabilityState` for the state (`NullabilityInfo.ReadState` or `NullabilityInfo.WriteState` depending on which has more info) of target info. + * `IsNullable`: given the state (`NullabilityInfo.ReadState` or `NullabilityInfo.WriteState` depending on which has more info) of the info: + * Returns true if state is `NullabilityState.Nullable`. + * Returns false if state is `NullabilityState.NotNull`. + * Throws an exception if state is `NullabilityState.Unknown`. + + ## Alternatives diff --git a/src/Consume/Consume.csproj b/src/Consume/Consume.csproj index 7c9fd914..117f401e 100644 --- a/src/Consume/Consume.csproj +++ b/src/Consume/Consume.csproj @@ -15,6 +15,9 @@ Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs + + Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs diff --git a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj index ae038c29..d81058b6 100644 --- a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj +++ b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj @@ -16,6 +16,9 @@ Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs + + Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs diff --git a/src/ConsumeIndirect/ConsumeIndirect.csproj b/src/ConsumeIndirect/ConsumeIndirect.csproj index 193567ce..cbec079c 100644 --- a/src/ConsumeIndirect/ConsumeIndirect.csproj +++ b/src/ConsumeIndirect/ConsumeIndirect.csproj @@ -12,6 +12,9 @@ Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs + + Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 9c66faff..55954f58 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -10,6 +10,9 @@ Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs + + Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs @@ -19,7 +22,9 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + + + diff --git a/src/Polyfill/Nullability/NullabilityInfo.cs b/src/Polyfill/Nullability/NullabilityInfo.cs new file mode 100644 index 00000000..54f37df2 --- /dev/null +++ b/src/Polyfill/Nullability/NullabilityInfo.cs @@ -0,0 +1,80 @@ + +#if !NET6_0_OR_GREATER + +#nullable enable + +// ReSharper disable All + +using System.Linq; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.ObjectModel; + +namespace System.Reflection +{ + /// + /// A class that represents nullability info + /// + #if PolyPublic +public +#endif +sealed class NullabilityInfo + { + internal NullabilityInfo(Type type, NullabilityState readState, NullabilityState writeState, + NullabilityInfo? elementType, NullabilityInfo[] typeArguments) + { + Type = type; + ReadState = readState; + WriteState = writeState; + ElementType = elementType; + GenericTypeArguments = typeArguments; + } + + /// + /// The of the member or generic parameter + /// to which this NullabilityInfo belongs + /// + public Type Type { get; } + /// + /// The nullability read state of the member + /// + public NullabilityState ReadState { get; internal set; } + /// + /// The nullability write state of the member + /// + public NullabilityState WriteState { get; internal set; } + /// + /// If the member type is an array, gives the of the elements of the array, null otherwise + /// + public NullabilityInfo? ElementType { get; } + /// + /// If the member type is a generic type, gives the array of for each type parameter + /// + public NullabilityInfo[] GenericTypeArguments { get; } + } + + /// + /// An enum that represents nullability state + /// + #if PolyPublic +public +#endif +enum NullabilityState + { + /// + /// Nullability context not enabled (oblivious) + /// + Unknown, + /// + /// Non nullable value or reference type + /// + NotNull, + /// + /// Nullable value or reference type + /// + Nullable + } +} + +#endif diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs new file mode 100644 index 00000000..7289dea0 --- /dev/null +++ b/src/Polyfill/Nullability/NullabilityInfoContext.cs @@ -0,0 +1,666 @@ + +#if !NET6_0_OR_GREATER + +#nullable enable + +// ReSharper disable All + +using System.Linq; +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; + +namespace System.Reflection +{ + /// + /// Provides APIs for populating nullability information/context from reflection members: + /// , , and . + /// + #if PolyPublic +public +#endif +sealed class NullabilityInfoContext + { + private const string CompilerServicesNameSpace = "System.Runtime.CompilerServices"; + private readonly Dictionary _publicOnlyModules = new(); + private readonly Dictionary _context = new(); + + internal static bool IsSupported { get; } = + AppContext.TryGetSwitch("System.Reflection.NullabilityInfoContext.IsSupported", out bool isSupported) ? isSupported : true; + + [Flags] + private enum NotAnnotatedStatus + { + None = 0x0, // no restriction, all members annotated + Private = 0x1, // private members not annotated + Internal = 0x2 // internal members not annotated + } + + private NullabilityState? GetNullableContext(MemberInfo? memberInfo) + { + while (memberInfo != null) + { + if (_context.TryGetValue(memberInfo, out NullabilityState state)) + { + return state; + } + + foreach (CustomAttributeData attribute in memberInfo.GetCustomAttributesData()) + { + if (attribute.AttributeType.Name == "NullableContextAttribute" && + attribute.AttributeType.Namespace == CompilerServicesNameSpace && + attribute.ConstructorArguments.Count == 1) + { + state = TranslateByte(attribute.ConstructorArguments[0].Value); + _context.Add(memberInfo, state); + return state; + } + } + + memberInfo = memberInfo.DeclaringType; + } + + return null; + } + + /// + /// Populates for the given . + /// If the nullablePublicOnly feature is set for an assembly, like it does in .NET SDK, the private and/or internal member's + /// nullability attributes are omitted, in this case the API will return NullabilityState.Unknown state. + /// + /// The parameter which nullability info gets populated + /// If the parameterInfo parameter is null + /// + public NullabilityInfo Create(ParameterInfo parameterInfo) + { + + EnsureIsSupported(); + + IList attributes = parameterInfo.GetCustomAttributesData(); + NullableAttributeStateParser parser = parameterInfo.Member is MethodBase method && IsPrivateOrInternalMethodAndAnnotationDisabled(method) + ? NullableAttributeStateParser.Unknown + : CreateParser(attributes); + NullabilityInfo nullability = GetNullabilityInfo(parameterInfo.Member, parameterInfo.ParameterType, parser); + + if (nullability.ReadState != NullabilityState.Unknown) + { + CheckParameterMetadataType(parameterInfo, nullability); + } + + CheckNullabilityAttributes(nullability, attributes); + return nullability; + } + + private void CheckParameterMetadataType(ParameterInfo parameter, NullabilityInfo nullability) + { + if (parameter.Member is MethodInfo method) + { + MethodInfo metaMethod = GetMethodMetadataDefinition(method); + ParameterInfo? metaParameter = null; + if (string.IsNullOrEmpty(parameter.Name)) + { + metaParameter = metaMethod.ReturnParameter; + } + else + { + ParameterInfo[] parameters = metaMethod.GetParameters(); + for (int i = 0; i < parameters.Length; i++) + { + if (parameter.Position == i && + parameter.Name == parameters[i].Name) + { + metaParameter = parameters[i]; + break; + } + } + } + + if (metaParameter != null) + { + CheckGenericParameters(nullability, metaMethod, metaParameter.ParameterType, parameter.Member.ReflectedType); + } + } + } + + private static MethodInfo GetMethodMetadataDefinition(MethodInfo method) + { + if (method.IsGenericMethod && !method.IsGenericMethodDefinition) + { + method = method.GetGenericMethodDefinition(); + } + + return (MethodInfo)GetMemberMetadataDefinition(method); + } + + private static void CheckNullabilityAttributes(NullabilityInfo nullability, IList attributes) + { + var codeAnalysisReadState = NullabilityState.Unknown; + var codeAnalysisWriteState = NullabilityState.Unknown; + + foreach (CustomAttributeData attribute in attributes) + { + if (attribute.AttributeType.Namespace == "System.Diagnostics.CodeAnalysis") + { + if (attribute.AttributeType.Name == "NotNullAttribute") + { + codeAnalysisReadState = NullabilityState.NotNull; + } + else if ((attribute.AttributeType.Name == "MaybeNullAttribute" || + attribute.AttributeType.Name == "MaybeNullWhenAttribute") && + codeAnalysisReadState == NullabilityState.Unknown && + !IsValueTypeOrValueTypeByRef(nullability.Type)) + { + codeAnalysisReadState = NullabilityState.Nullable; + } + else if (attribute.AttributeType.Name == "DisallowNullAttribute") + { + codeAnalysisWriteState = NullabilityState.NotNull; + } + else if (attribute.AttributeType.Name == "AllowNullAttribute" && + codeAnalysisWriteState == NullabilityState.Unknown && + !IsValueTypeOrValueTypeByRef(nullability.Type)) + { + codeAnalysisWriteState = NullabilityState.Nullable; + } + } + } + + if (codeAnalysisReadState != NullabilityState.Unknown) + { + nullability.ReadState = codeAnalysisReadState; + } + if (codeAnalysisWriteState != NullabilityState.Unknown) + { + nullability.WriteState = codeAnalysisWriteState; + } + } + + /// + /// Populates for the given . + /// If the nullablePublicOnly feature is set for an assembly, like it does in .NET SDK, the private and/or internal member's + /// nullability attributes are omitted, in this case the API will return NullabilityState.Unknown state. + /// + /// The parameter which nullability info gets populated + /// If the propertyInfo parameter is null + /// + public NullabilityInfo Create(PropertyInfo propertyInfo) + { + + EnsureIsSupported(); + + MethodInfo? getter = propertyInfo.GetGetMethod(true); + MethodInfo? setter = propertyInfo.GetSetMethod(true); + bool annotationsDisabled = (getter == null || IsPrivateOrInternalMethodAndAnnotationDisabled(getter)) + && (setter == null || IsPrivateOrInternalMethodAndAnnotationDisabled(setter)); + NullableAttributeStateParser parser = annotationsDisabled ? NullableAttributeStateParser.Unknown : CreateParser(propertyInfo.GetCustomAttributesData()); + NullabilityInfo nullability = GetNullabilityInfo(propertyInfo, propertyInfo.PropertyType, parser); + + if (getter != null) + { + CheckNullabilityAttributes(nullability, getter.ReturnParameter.GetCustomAttributesData()); + } + else + { + nullability.ReadState = NullabilityState.Unknown; + } + + if (setter != null) + { + CheckNullabilityAttributes(nullability, setter.GetParameters()[^1].GetCustomAttributesData()); + } + else + { + nullability.WriteState = NullabilityState.Unknown; + } + + return nullability; + } + + private bool IsPrivateOrInternalMethodAndAnnotationDisabled(MethodBase method) + { + if ((method.IsPrivate || method.IsFamilyAndAssembly || method.IsAssembly) && + IsPublicOnly(method.IsPrivate, method.IsFamilyAndAssembly, method.IsAssembly, method.Module)) + { + return true; + } + + return false; + } + + /// + /// Populates for the given . + /// If the nullablePublicOnly feature is set for an assembly, like it does in .NET SDK, the private and/or internal member's + /// nullability attributes are omitted, in this case the API will return NullabilityState.Unknown state. + /// + /// The parameter which nullability info gets populated + /// If the eventInfo parameter is null + /// + public NullabilityInfo Create(EventInfo eventInfo) + { + + EnsureIsSupported(); + + return GetNullabilityInfo(eventInfo, eventInfo.EventHandlerType!, CreateParser(eventInfo.GetCustomAttributesData())); + } + + /// + /// Populates for the given + /// If the nullablePublicOnly feature is set for an assembly, like it does in .NET SDK, the private and/or internal member's + /// nullability attributes are omitted, in this case the API will return NullabilityState.Unknown state. + /// + /// The parameter which nullability info gets populated + /// If the fieldInfo parameter is null + /// + public NullabilityInfo Create(FieldInfo fieldInfo) + { + + EnsureIsSupported(); + + IList attributes = fieldInfo.GetCustomAttributesData(); + NullableAttributeStateParser parser = IsPrivateOrInternalFieldAndAnnotationDisabled(fieldInfo) ? NullableAttributeStateParser.Unknown : CreateParser(attributes); + NullabilityInfo nullability = GetNullabilityInfo(fieldInfo, fieldInfo.FieldType, parser); + CheckNullabilityAttributes(nullability, attributes); + return nullability; + } + + private static void EnsureIsSupported() + { + if (!IsSupported) + { + throw new InvalidOperationException("NullabilityInfoContext is not supported"); + } + } + + private bool IsPrivateOrInternalFieldAndAnnotationDisabled(FieldInfo fieldInfo) + { + if ((fieldInfo.IsPrivate || fieldInfo.IsFamilyAndAssembly || fieldInfo.IsAssembly) && + IsPublicOnly(fieldInfo.IsPrivate, fieldInfo.IsFamilyAndAssembly, fieldInfo.IsAssembly, fieldInfo.Module)) + { + return true; + } + + return false; + } + + private bool IsPublicOnly(bool isPrivate, bool isFamilyAndAssembly, bool isAssembly, Module module) + { + if (!_publicOnlyModules.TryGetValue(module, out NotAnnotatedStatus value)) + { + value = PopulateAnnotationInfo(module.GetCustomAttributesData()); + _publicOnlyModules.Add(module, value); + } + + if (value == NotAnnotatedStatus.None) + { + return false; + } + + if ((isPrivate || isFamilyAndAssembly) && value.HasFlag(NotAnnotatedStatus.Private) || + isAssembly && value.HasFlag(NotAnnotatedStatus.Internal)) + { + return true; + } + + return false; + } + + private static NotAnnotatedStatus PopulateAnnotationInfo(IList customAttributes) + { + foreach (CustomAttributeData attribute in customAttributes) + { + if (attribute.AttributeType.Name == "NullablePublicOnlyAttribute" && + attribute.AttributeType.Namespace == CompilerServicesNameSpace && + attribute.ConstructorArguments.Count == 1) + { + if (attribute.ConstructorArguments[0].Value is bool boolValue && boolValue) + { + return NotAnnotatedStatus.Internal | NotAnnotatedStatus.Private; + } + else + { + return NotAnnotatedStatus.Private; + } + } + } + + return NotAnnotatedStatus.None; + } + + private NullabilityInfo GetNullabilityInfo(MemberInfo memberInfo, Type type, NullableAttributeStateParser parser) + { + int index = 0; + NullabilityInfo nullability = GetNullabilityInfo(memberInfo, type, parser, ref index); + + if (nullability.ReadState != NullabilityState.Unknown) + { + TryLoadGenericMetaTypeNullability(memberInfo, nullability); + } + + return nullability; + } + + private NullabilityInfo GetNullabilityInfo(MemberInfo memberInfo, Type type, NullableAttributeStateParser parser, ref int index) + { + NullabilityState state = NullabilityState.Unknown; + NullabilityInfo? elementState = null; + NullabilityInfo[] genericArgumentsState = Array.Empty(); + Type underlyingType = type; + + if (underlyingType.IsByRef || underlyingType.IsPointer) + { + underlyingType = underlyingType.GetElementType()!; + } + + if (underlyingType.IsValueType) + { + if (Nullable.GetUnderlyingType(underlyingType) is { } nullableUnderlyingType) + { + underlyingType = nullableUnderlyingType; + state = NullabilityState.Nullable; + } + else + { + state = NullabilityState.NotNull; + } + + if (underlyingType.IsGenericType) + { + ++index; + } + } + else + { + if (!parser.ParseNullableState(index++, ref state) + && GetNullableContext(memberInfo) is { } contextState) + { + state = contextState; + } + + if (underlyingType.IsArray) + { + elementState = GetNullabilityInfo(memberInfo, underlyingType.GetElementType()!, parser, ref index); + } + } + + if (underlyingType.IsGenericType) + { + Type[] genericArguments = underlyingType.GetGenericArguments(); + genericArgumentsState = new NullabilityInfo[genericArguments.Length]; + + for (int i = 0; i < genericArguments.Length; i++) + { + genericArgumentsState[i] = GetNullabilityInfo(memberInfo, genericArguments[i], parser, ref index); + } + } + + return new NullabilityInfo(type, state, state, elementState, genericArgumentsState); + } + + private static NullableAttributeStateParser CreateParser(IList customAttributes) + { + foreach (CustomAttributeData attribute in customAttributes) + { + if (attribute.AttributeType.Name == "NullableAttribute" && + attribute.AttributeType.Namespace == CompilerServicesNameSpace && + attribute.ConstructorArguments.Count == 1) + { + return new NullableAttributeStateParser(attribute.ConstructorArguments[0].Value); + } + } + + return new NullableAttributeStateParser(null); + } + + private void TryLoadGenericMetaTypeNullability(MemberInfo memberInfo, NullabilityInfo nullability) + { + MemberInfo? metaMember = GetMemberMetadataDefinition(memberInfo); + Type? metaType = null; + if (metaMember is FieldInfo field) + { + metaType = field.FieldType; + } + else if (metaMember is PropertyInfo property) + { + metaType = GetPropertyMetaType(property); + } + + if (metaType != null) + { + CheckGenericParameters(nullability, metaMember!, metaType, memberInfo.ReflectedType); + } + } + + private static MemberInfo GetMemberMetadataDefinition(MemberInfo member) + { + Type? type = member.DeclaringType; + if ((type != null) && type.IsGenericType && !type.IsGenericTypeDefinition) + { + return type.GetGenericTypeDefinition().GetMemberWithSameMetadataDefinitionAs(member); + } + + return member; + } + + private static Type GetPropertyMetaType(PropertyInfo property) + { + if (property.GetGetMethod(true) is MethodInfo method) + { + return method.ReturnType; + } + + return property.GetSetMethod(true)!.GetParameters()[0].ParameterType; + } + + private void CheckGenericParameters(NullabilityInfo nullability, MemberInfo metaMember, Type metaType, Type? reflectedType) + { + if (metaType.IsGenericParameter) + { + if (nullability.ReadState == NullabilityState.NotNull) + { + TryUpdateGenericParameterNullability(nullability, metaType, reflectedType); + } + } + else if (metaType.ContainsGenericParameters) + { + if (nullability.GenericTypeArguments.Length > 0) + { + Type[] genericArguments = metaType.GetGenericArguments(); + + for (int i = 0; i < genericArguments.Length; i++) + { + CheckGenericParameters(nullability.GenericTypeArguments[i], metaMember, genericArguments[i], reflectedType); + } + } + else if (nullability.ElementType is { } elementNullability && metaType.IsArray) + { + CheckGenericParameters(elementNullability, metaMember, metaType.GetElementType()!, reflectedType); + } + // We could also follow this branch for metaType.IsPointer, but since pointers must be unmanaged this + // will be a no-op regardless + else if (metaType.IsByRef) + { + CheckGenericParameters(nullability, metaMember, metaType.GetElementType()!, reflectedType); + } + } + } + + private bool TryUpdateGenericParameterNullability(NullabilityInfo nullability, Type genericParameter, Type? reflectedType) + { + Debug.Assert(genericParameter.IsGenericParameter); + + if (reflectedType is not null + && !genericParameter.IsGenericMethodParameter() + && TryUpdateGenericTypeParameterNullabilityFromReflectedType(nullability, genericParameter, reflectedType, reflectedType)) + { + return true; + } + + if (IsValueTypeOrValueTypeByRef(nullability.Type)) + { + return true; + } + + var state = NullabilityState.Unknown; + if (CreateParser(genericParameter.GetCustomAttributesData()).ParseNullableState(0, ref state)) + { + nullability.ReadState = state; + nullability.WriteState = state; + return true; + } + + if (GetNullableContext(genericParameter) is { } contextState) + { + nullability.ReadState = contextState; + nullability.WriteState = contextState; + return true; + } + + return false; + } + + private bool TryUpdateGenericTypeParameterNullabilityFromReflectedType(NullabilityInfo nullability, Type genericParameter, Type context, Type reflectedType) + { + Debug.Assert(genericParameter.IsGenericParameter && !genericParameter.IsGenericMethodParameter()); + + Type contextTypeDefinition = context.IsGenericType && !context.IsGenericTypeDefinition ? context.GetGenericTypeDefinition() : context; + if (genericParameter.DeclaringType == contextTypeDefinition) + { + return false; + } + + Type? baseType = contextTypeDefinition.BaseType; + if (baseType is null) + { + return false; + } + + if (!baseType.IsGenericType + || (baseType.IsGenericTypeDefinition ? baseType : baseType.GetGenericTypeDefinition()) != genericParameter.DeclaringType) + { + return TryUpdateGenericTypeParameterNullabilityFromReflectedType(nullability, genericParameter, baseType, reflectedType); + } + + Type[] genericArguments = baseType.GetGenericArguments(); + Type genericArgument = genericArguments[genericParameter.GenericParameterPosition]; + if (genericArgument.IsGenericParameter) + { + return TryUpdateGenericParameterNullability(nullability, genericArgument, reflectedType); + } + + NullableAttributeStateParser parser = CreateParser(contextTypeDefinition.GetCustomAttributesData()); + int nullabilityStateIndex = 1; // start at 1 since index 0 is the type itself + for (int i = 0; i < genericParameter.GenericParameterPosition; i++) + { + nullabilityStateIndex += CountNullabilityStates(genericArguments[i]); + } + return TryPopulateNullabilityInfo(nullability, parser, ref nullabilityStateIndex); + + static int CountNullabilityStates(Type type) + { + Type underlyingType = Nullable.GetUnderlyingType(type) ?? type; + if (underlyingType.IsGenericType) + { + int count = 1; + foreach (Type genericArgument in underlyingType.GetGenericArguments()) + { + count += CountNullabilityStates(genericArgument); + } + return count; + } + + if (underlyingType.HasElementType) + { + return (underlyingType.IsArray ? 1 : 0) + CountNullabilityStates(underlyingType.GetElementType()!); + } + + return type.IsValueType ? 0 : 1; + } + } + + private bool TryPopulateNullabilityInfo(NullabilityInfo nullability, NullableAttributeStateParser parser, ref int index) + { + bool isValueType = IsValueTypeOrValueTypeByRef(nullability.Type); + if (!isValueType) + { + var state = NullabilityState.Unknown; + if (!parser.ParseNullableState(index, ref state)) + { + return false; + } + + nullability.ReadState = state; + nullability.WriteState = state; + } + + if (!isValueType || (Nullable.GetUnderlyingType(nullability.Type) ?? nullability.Type).IsGenericType) + { + index++; + } + + if (nullability.GenericTypeArguments.Length > 0) + { + foreach (NullabilityInfo genericTypeArgumentNullability in nullability.GenericTypeArguments) + { + TryPopulateNullabilityInfo(genericTypeArgumentNullability, parser, ref index); + } + } + else if (nullability.ElementType is { } elementTypeNullability) + { + TryPopulateNullabilityInfo(elementTypeNullability, parser, ref index); + } + + return true; + } + + private static NullabilityState TranslateByte(object? value) + { + return value is byte b ? TranslateByte(b) : NullabilityState.Unknown; + } + + private static NullabilityState TranslateByte(byte b) => + b switch + { + 1 => NullabilityState.NotNull, + 2 => NullabilityState.Nullable, + _ => NullabilityState.Unknown + }; + + private static bool IsValueTypeOrValueTypeByRef(Type type) => + type.IsValueType || ((type.IsByRef || type.IsPointer) && type.GetElementType()!.IsValueType); + + private readonly struct NullableAttributeStateParser + { + private static readonly object UnknownByte = (byte)0; + + private readonly object? _nullableAttributeArgument; + + public NullableAttributeStateParser(object? nullableAttributeArgument) + { + this._nullableAttributeArgument = nullableAttributeArgument; + } + + public static NullableAttributeStateParser Unknown => new(UnknownByte); + + public bool ParseNullableState(int index, ref NullabilityState state) + { + switch (this._nullableAttributeArgument) + { + case byte b: + state = TranslateByte(b); + return true; + case ReadOnlyCollection args + when index < args.Count && args[index].Value is byte elementB: + state = TranslateByte(elementB); + return true; + default: + return false; + } + } + } + } +} + +#endif diff --git a/src/Polyfill/Nullability/NullabilityInfoExtensions.cs b/src/Polyfill/Nullability/NullabilityInfoExtensions.cs new file mode 100644 index 00000000..eab48054 --- /dev/null +++ b/src/Polyfill/Nullability/NullabilityInfoExtensions.cs @@ -0,0 +1,143 @@ +// ReSharper disable RedundantUsingDirective +#nullable enable + +using System; +using System.Collections.Concurrent; +using System.Reflection; + +/// +/// Static and thread safe wrapper around . +/// +#if PolyPublic +public +#endif +static partial class PolyfillExtensions +{ + static ConcurrentDictionary parameterCache = new(); + static ConcurrentDictionary propertyCache = new(); + static ConcurrentDictionary eventCache = new(); + static ConcurrentDictionary fieldCache = new(); + + public static NullabilityInfo GetNullabilityInfo(this MemberInfo info) + { + if (info is PropertyInfo propertyInfo) + { + return propertyInfo.GetNullabilityInfo(); + } + + if (info is EventInfo eventInfo) + { + return eventInfo.GetNullabilityInfo(); + } + + if (info is FieldInfo fieldInfo) + { + return fieldInfo.GetNullabilityInfo(); + } + + throw new ArgumentException($"Unsupported type:{info.GetType().FullName}"); + } + + public static NullabilityState GetNullability(this MemberInfo info) => + GetReadOrWriteState(info.GetNullabilityInfo()); + + public static bool IsNullable(this MemberInfo info) + { + var nullability = info.GetNullabilityInfo(); + return IsNullable(info.Name, nullability); + } + + public static NullabilityInfo GetNullabilityInfo(this FieldInfo info) => + fieldCache.GetOrAdd(info, inner => + { + var context = new NullabilityInfoContext(); + return context.Create(inner); + }); + + public static NullabilityState GetNullability(this FieldInfo info) => + GetReadOrWriteState(info.GetNullabilityInfo()); + + public static bool IsNullable(this FieldInfo info) + { + var nullability = info.GetNullabilityInfo(); + return IsNullable(info.Name, nullability); + } + + public static NullabilityInfo GetNullabilityInfo(this EventInfo info) => + eventCache.GetOrAdd(info, inner => + { + var context = new NullabilityInfoContext(); + return context.Create(inner); + }); + + public static NullabilityState GetNullability(this EventInfo info) => + GetReadOrWriteState(info.GetNullabilityInfo()); + + public static bool IsNullable(this EventInfo info) + { + var nullability = info.GetNullabilityInfo(); + return IsNullable(info.Name, nullability); + } + + public static NullabilityInfo GetNullabilityInfo(this PropertyInfo info) => + propertyCache.GetOrAdd(info, inner => + { + var context = new NullabilityInfoContext(); + return context.Create(inner); + }); + + public static NullabilityState GetNullability(this PropertyInfo info) => + GetReadOrWriteState(info.GetNullabilityInfo()); + + public static bool IsNullable(this PropertyInfo info) + { + var nullability = info.GetNullabilityInfo(); + return IsNullable(info.Name, nullability); + } + + public static NullabilityInfo GetNullabilityInfo(this ParameterInfo info) => + parameterCache.GetOrAdd(info, inner => + { + var context = new NullabilityInfoContext(); + return context.Create(inner); + }); + + public static NullabilityState GetNullability(this ParameterInfo info) => + GetReadOrWriteState(info.GetNullabilityInfo()); + + public static bool IsNullable(this ParameterInfo info) + { + var nullability = info.GetNullabilityInfo(); + return IsNullable(info.Name!, nullability); + } + + static NullabilityState GetReadOrWriteState(NullabilityInfo nullability) + { + if (nullability.ReadState == NullabilityState.Unknown) + { + return nullability.WriteState; + } + + return nullability.ReadState; + } + + static NullabilityState GetKnownState(string name, NullabilityInfo nullability) + { + var readState = nullability.ReadState; + if (readState != NullabilityState.Unknown) + { + return readState; + } + + var writeState = nullability.WriteState; + if (writeState != NullabilityState.Unknown) + { + return writeState; + } + + throw new($"The nullability of '{nullability.Type.FullName}.{name}' is unknown. Assembly: {nullability.Type.Assembly.FullName}."); + } + + static bool IsNullable(string name, NullabilityInfo nullability) => + GetKnownState(name, nullability) == NullabilityState.Nullable; +} \ No newline at end of file diff --git a/src/Polyfill/Polyfill.nuspec b/src/Polyfill/Polyfill.nuspec index 108ee41f..a072ac3f 100644 --- a/src/Polyfill/Polyfill.nuspec +++ b/src/Polyfill/Polyfill.nuspec @@ -19,6 +19,8 @@ target="contentFiles/cs/netstandard2.0/Polyfill/"/> + Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs + + Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs @@ -20,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index 5c49fed7..38a8a4ac 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -24,8 +24,13 @@ public void Run() var extensions = module.GetTypes().Single(_ => _.Name == nameof(PolyfillExtensions)); using var writer = File.CreateText(md); - foreach (var type in extensions.Methods.GroupBy(_ => _.Parameters[0].ParameterType).OrderBy(_ => _.Key.Name)) + foreach (var type in extensions.Methods.Where(_ => !_.IsConstructor).GroupBy(_ => _.Parameters[0].ParameterType).OrderBy(_ => _.Key.Name)) { + if (!type.Any(_ => _.IsPublic)) + { + continue; + } + var targetType = type.Key; var targetFullName = targetType.FullName.Replace("`1", "").Replace("`2", ""); writer.WriteLine($"### {SimpleTypeName(targetFullName)}"); @@ -49,10 +54,12 @@ public void Run() .SingleOrDefault(_ => _.AttributeType.Name == "DescriptionAttribute"); if (descriptionAttribute == null) { - throw new($"Description required {method.FullName}"); + writer.WriteLine($" * `{signature}`"); + } + else + { + writer.WriteLine($" * `{signature}` [reference]({descriptionAttribute.ConstructorArguments.Single().Value})"); } - - writer.WriteLine($" * `{signature}` [reference]({descriptionAttribute.ConstructorArguments.Single().Value})"); } writer.WriteLine(); diff --git a/src/Tests/NullabilitySamples.cs b/src/Tests/NullabilitySamples.cs new file mode 100644 index 00000000..4bdb2980 --- /dev/null +++ b/src/Tests/NullabilitySamples.cs @@ -0,0 +1,68 @@ +#pragma warning disable CS0649 +#pragma warning disable CS8618 + +public class NullabilitySamples +{ + #region NullabilityUsage + + [Test] + public void Test() + { + var type = typeof(NullabilityTarget); + var arrayField = type.GetField("ArrayField")!; + var genericField = type.GetField("GenericField")!; + + var context = new NullabilityInfoContext(); + + var arrayInfo = context.Create(arrayField); + + Assert.AreEqual(NullabilityState.NotNull, arrayInfo.ReadState); + Assert.AreEqual(NullabilityState.Nullable, arrayInfo.ElementType!.ReadState); + + var genericInfo = context.Create(genericField); + + Assert.AreEqual(NullabilityState.NotNull, genericInfo.ReadState); + Assert.AreEqual(NullabilityState.NotNull, genericInfo.GenericTypeArguments[0].ReadState); + Assert.AreEqual(NullabilityState.Nullable, genericInfo.GenericTypeArguments[1].ReadState); + } + + #endregion + + #region NullabilityExtension + + [Test] + public void ExtensionTests() + { + var type = typeof(NullabilityTarget); + var field = type.GetField("StringField")!; + Assert.True(field.IsNullable()); + Assert.AreEqual(NullabilityState.Nullable, field.GetNullability()); + Assert.AreEqual(NullabilityState.Nullable, field.GetNullabilityInfo().ReadState); + } + + #endregion + + class PropertyTarget + { + string? write; + public string? ReadWrite { get; set; } + public string? Read { get; } + + public string? Write + { + set => write = value; + } + } + + [Test] + public void Property() + { + var type = typeof(PropertyTarget); + var readWrite = type.GetProperty("ReadWrite")!; + var write = type.GetProperty("Write")!; + var read = type.GetProperty("Read")!; + Assert.True(readWrite.IsNullable()); + Assert.True(write.IsNullable()); + Assert.True(read.IsNullable()); + } +} \ No newline at end of file diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs new file mode 100644 index 00000000..3c767181 --- /dev/null +++ b/src/Tests/NullabilitySync.cs @@ -0,0 +1,80 @@ +#if NET8_0 +using System.Net.Http; +using VerifyTests; + +[TestFixture] +public class NullabilitySync +{ + static string solutionDir = AttributeReader.GetSolutionDirectory(); + static string dir = Path.Combine(solutionDir, "PolyFill", "Nullability"); + + [Test] + public async Task Run() + { + if (!OperatingSystem.IsWindows()) + { + return; + } + + using var client = new HttpClient(); + var infoContext = await client.GetStringAsync("https://raw.githubusercontent.com/dotnet/runtime/main/src/libraries/System.Private.CoreLib/src/System/Reflection/NullabilityInfoContext.cs"); + + infoContext = infoContext + .Replace(".IsGenericMethodParameter", ".IsGenericMethodParameter()") + .Replace("SR.NullabilityInfoContext_NotSupported", "\"NullabilityInfoContext is not supported\""); + + var lines = infoContext.Split('\r', '\n'); + infoContext = string.Join(Environment.NewLine, lines.Where(_ => !_.Contains("ArgumentNullException.ThrowIfNull"))); + + var info = await client.GetStringAsync("https://raw.githubusercontent.com/dotnet/runtime/main/src/libraries/System.Private.CoreLib/src/System/Reflection/NullabilityInfo.cs"); + + var prefix = @" +#if !NET6_0_OR_GREATER + +#nullable enable + +// ReSharper disable All + +using System.Linq; +"; + + var suffix = @" +#endif +"; + + infoContext = prefix + infoContext + suffix; + infoContext = MakeInternal(infoContext); + OverWrite(infoContext, "NullabilityInfoContext.cs"); + + info = prefix + info + suffix; + info = MakeInternal(info); + OverWrite(info, "NullabilityInfo.cs"); + } + + static string MakeInternal(string source) => + source + .Replace( + "public enum", + """ + #if PolyPublic + public + #endif + enum + """) + .Replace( + "public sealed class", + """ + #if PolyPublic + public + #endif + sealed class + """); + + static void OverWrite(string content, string file) + { + var path = Path.Combine(dir, file); + File.Delete(path); + File.WriteAllText(path, content); + } +} +#endif \ No newline at end of file diff --git a/src/Tests/NullabilityTarget.cs b/src/Tests/NullabilityTarget.cs new file mode 100644 index 00000000..e1edcc98 --- /dev/null +++ b/src/Tests/NullabilityTarget.cs @@ -0,0 +1,10 @@ +#pragma warning disable CS0649, CS8618 + +#region NullabilityTarget +class NullabilityTarget +{ + public string? StringField; + public string?[] ArrayField; + public Dictionary GenericField; +} +#endregion \ No newline at end of file diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 46cb8e11..606e4e45 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -10,6 +10,9 @@ Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs + + Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index d180f60e..14f92496 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -11,6 +11,9 @@ Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs + + Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs @@ -20,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 94907aadc1ba870a5f2a836538ec3a411582acef Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 17 Apr 2023 20:13:17 +1000 Subject: [PATCH 065/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 5f2e92a5..d4e97592 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.16.0 + 1.17.0 1.0.0 Polyfill true From aaf6639989a0dc180c1c4e6580df91d5624ab5af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Apr 2023 16:47:05 +1000 Subject: [PATCH 066/313] Bump Mono.Cecil from 0.11.4 to 0.11.5 in /src (#33) Bumps [Mono.Cecil](https://github.com/jbevain/cecil) from 0.11.4 to 0.11.5. - [Release notes](https://github.com/jbevain/cecil/releases) - [Commits](https://github.com/jbevain/cecil/compare/0.11.4...0.11.5) --- updated-dependencies: - dependency-name: Mono.Cecil dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/Tests/Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 606e4e45..c162c1c1 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -22,7 +22,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 57da33f21214fd5eef8a4f2062bdae706a1d277a Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 21 Apr 2023 09:15:28 +1000 Subject: [PATCH 067/313] Update Polyfill.sln --- src/Polyfill.sln | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Polyfill.sln b/src/Polyfill.sln index 5991cb1c..9c644507 100644 --- a/src/Polyfill.sln +++ b/src/Polyfill.sln @@ -26,14 +26,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Consume", "Consume\Consume. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnsafeTests", "UnsafeTests\UnsafeTests.csproj", "{F49A3C33-48A3-4954-9AC0-5C7B30AC2B2B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoRefsTests", "NoRefsTests\NoRefsTests.csproj", "{B46221EE-4806-423A-B21A-36E6B1D50027}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PublicTests", "PublicTests\PublicTests.csproj", "{9FBD54A6-461C-4754-B77A-222E06BF89B6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsumeClassicReferences", "ConsumeClassicReferences\ConsumeClassicReferences.csproj", "{CF7D4778-6A32-4E7D-B80B-3507974B443B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsumeIndirect", "ConsumeIndirect\ConsumeIndirect.csproj", "{955038AF-1073-4BB0-8AF7-D4597B7C2DAB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoRefsTests", "NoRefsTests\NoRefsTests.csproj", "{A9EEAECD-A8B2-45C1-9A9D-94443601CB5F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -56,10 +56,6 @@ Global {F49A3C33-48A3-4954-9AC0-5C7B30AC2B2B}.Debug|Any CPU.Build.0 = Debug|Any CPU {F49A3C33-48A3-4954-9AC0-5C7B30AC2B2B}.Release|Any CPU.ActiveCfg = Release|Any CPU {F49A3C33-48A3-4954-9AC0-5C7B30AC2B2B}.Release|Any CPU.Build.0 = Release|Any CPU - {B46221EE-4806-423A-B21A-36E6B1D50027}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B46221EE-4806-423A-B21A-36E6B1D50027}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B46221EE-4806-423A-B21A-36E6B1D50027}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B46221EE-4806-423A-B21A-36E6B1D50027}.Release|Any CPU.Build.0 = Release|Any CPU {9FBD54A6-461C-4754-B77A-222E06BF89B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9FBD54A6-461C-4754-B77A-222E06BF89B6}.Debug|Any CPU.Build.0 = Debug|Any CPU {9FBD54A6-461C-4754-B77A-222E06BF89B6}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -72,6 +68,10 @@ Global {955038AF-1073-4BB0-8AF7-D4597B7C2DAB}.Debug|Any CPU.Build.0 = Debug|Any CPU {955038AF-1073-4BB0-8AF7-D4597B7C2DAB}.Release|Any CPU.ActiveCfg = Release|Any CPU {955038AF-1073-4BB0-8AF7-D4597B7C2DAB}.Release|Any CPU.Build.0 = Release|Any CPU + {A9EEAECD-A8B2-45C1-9A9D-94443601CB5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A9EEAECD-A8B2-45C1-9A9D-94443601CB5F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A9EEAECD-A8B2-45C1-9A9D-94443601CB5F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A9EEAECD-A8B2-45C1-9A9D-94443601CB5F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 36b983ea2e4936faa6708d5ae29bb4ef23846180 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 21 Apr 2023 09:22:33 +1000 Subject: [PATCH 068/313] Update Polyfill.sln --- src/Polyfill.sln | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Polyfill.sln b/src/Polyfill.sln index 9c644507..b78c54c8 100644 --- a/src/Polyfill.sln +++ b/src/Polyfill.sln @@ -15,22 +15,22 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\readme.md = ..\readme.md EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polyfill", "Polyfill\Polyfill.csproj", "{698FB675-3480-4107-8CAE-51452C6138CE}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Polyfill", "Polyfill\Polyfill.csproj", "{698FB675-3480-4107-8CAE-51452C6138CE}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{CA1869D1-4531-40C7-AE55-5885F4DD8448}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{CA1869D1-4531-40C7-AE55-5885F4DD8448}" ProjectSection(ProjectDependencies) = postProject {32C38E3C-4040-455F-A27D-4EA5DB0F8EFA} = {32C38E3C-4040-455F-A27D-4EA5DB0F8EFA} EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Consume", "Consume\Consume.csproj", "{32C38E3C-4040-455F-A27D-4EA5DB0F8EFA}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Consume", "Consume\Consume.csproj", "{32C38E3C-4040-455F-A27D-4EA5DB0F8EFA}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnsafeTests", "UnsafeTests\UnsafeTests.csproj", "{F49A3C33-48A3-4954-9AC0-5C7B30AC2B2B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnsafeTests", "UnsafeTests\UnsafeTests.csproj", "{F49A3C33-48A3-4954-9AC0-5C7B30AC2B2B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PublicTests", "PublicTests\PublicTests.csproj", "{9FBD54A6-461C-4754-B77A-222E06BF89B6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PublicTests", "PublicTests\PublicTests.csproj", "{9FBD54A6-461C-4754-B77A-222E06BF89B6}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsumeClassicReferences", "ConsumeClassicReferences\ConsumeClassicReferences.csproj", "{CF7D4778-6A32-4E7D-B80B-3507974B443B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeClassicReferences", "ConsumeClassicReferences\ConsumeClassicReferences.csproj", "{CF7D4778-6A32-4E7D-B80B-3507974B443B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsumeIndirect", "ConsumeIndirect\ConsumeIndirect.csproj", "{955038AF-1073-4BB0-8AF7-D4597B7C2DAB}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeIndirect", "ConsumeIndirect\ConsumeIndirect.csproj", "{955038AF-1073-4BB0-8AF7-D4597B7C2DAB}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoRefsTests", "NoRefsTests\NoRefsTests.csproj", "{A9EEAECD-A8B2-45C1-9A9D-94443601CB5F}" EndProject From d1179fc700ef16f58ea44c3b1ec58c4e7ef6426f Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 21 Apr 2023 09:54:50 +1000 Subject: [PATCH 069/313] ConsumeNoRefs --- src/ConsumeNoRefs/ConsumeNoRefs.csproj | 30 ++++++++++++++++++++++++++ src/Polyfill.sln | 6 ++++++ 2 files changed, 36 insertions(+) create mode 100644 src/ConsumeNoRefs/ConsumeNoRefs.csproj diff --git a/src/ConsumeNoRefs/ConsumeNoRefs.csproj b/src/ConsumeNoRefs/ConsumeNoRefs.csproj new file mode 100644 index 00000000..11f743c9 --- /dev/null +++ b/src/ConsumeNoRefs/ConsumeNoRefs.csproj @@ -0,0 +1,30 @@ + + + true + net461;net462;net47;net471;net472;net48;net481;net6.0-windows + $(TargetFrameworks);netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 + + + + + Pollyfill\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs + + + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs + + + Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs + + + + + \ No newline at end of file diff --git a/src/Polyfill.sln b/src/Polyfill.sln index b78c54c8..abca409e 100644 --- a/src/Polyfill.sln +++ b/src/Polyfill.sln @@ -34,6 +34,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeIndirect", "ConsumeI EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoRefsTests", "NoRefsTests\NoRefsTests.csproj", "{A9EEAECD-A8B2-45C1-9A9D-94443601CB5F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeNoRefs", "ConsumeNoRefs\ConsumeNoRefs.csproj", "{B4DC96CA-C700-499F-A9A2-0C767DCF8C30}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -72,6 +74,10 @@ Global {A9EEAECD-A8B2-45C1-9A9D-94443601CB5F}.Debug|Any CPU.Build.0 = Debug|Any CPU {A9EEAECD-A8B2-45C1-9A9D-94443601CB5F}.Release|Any CPU.ActiveCfg = Release|Any CPU {A9EEAECD-A8B2-45C1-9A9D-94443601CB5F}.Release|Any CPU.Build.0 = Release|Any CPU + {B4DC96CA-C700-499F-A9A2-0C767DCF8C30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B4DC96CA-C700-499F-A9A2-0C767DCF8C30}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B4DC96CA-C700-499F-A9A2-0C767DCF8C30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B4DC96CA-C700-499F-A9A2-0C767DCF8C30}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 4b0154bb425c6b446fd8c9074da72a177158ddde Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 21 Apr 2023 10:27:16 +1000 Subject: [PATCH 070/313] Update Consume.cs --- src/Consume/Consume.cs | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 2b9f0c63..ed847da2 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -71,13 +71,19 @@ class Consume var startsWith = "value".StartsWith('a'); var endsWith = "value".EndsWith('a'); - var enumerable = (IEnumerable)new List {"a", "b"}; + var enumerable = (IEnumerable) new List + { + "a", + "b" + }; var append = enumerable.Append("c"); var skipLast = enumerable.SkipLast(1); - var dictionary = new Dictionary + var dictionary = new Dictionary { - {"key", "value"} + { + "key", "value" + } }; dictionary.GetValueOrDefault("key"); @@ -97,9 +103,15 @@ static void Http() new HttpClient().GetStringAsync("", CancellationToken.None); new HttpClient().GetStringAsync(new Uri(""), CancellationToken.None); - new ByteArrayContent(new byte[] { }).ReadAsStreamAsync(CancellationToken.None); - new ByteArrayContent(new byte[] { }).ReadAsByteArrayAsync(CancellationToken.None); - new ByteArrayContent(new byte[] { }).ReadAsStringAsync(CancellationToken.None); + new ByteArrayContent(new byte[] + { + }).ReadAsStreamAsync(CancellationToken.None); + new ByteArrayContent(new byte[] + { + }).ReadAsByteArrayAsync(CancellationToken.None); + new ByteArrayContent(new byte[] + { + }).ReadAsStringAsync(CancellationToken.None); } void KeyValuePairDeconstruct(IEnumerable> variables) @@ -108,9 +120,10 @@ void KeyValuePairDeconstruct(IEnumerable> variables { } } - +#if VALUETUPLEREFERENCED static (string value1, bool value2) NamedTupleMethod() => new("value", false); +#endif async Task StreamReaderReadAsync() { @@ -153,8 +166,8 @@ void SpanSequenceEqual() void SpanStartsWith() { - var startsWith = "value".AsSpan().StartsWith("value"); - startsWith = "value".AsSpan().StartsWith("value", StringComparison.Ordinal); + var startsWith = "value".AsSpan().StartsWith("value"); + startsWith = "value".AsSpan().StartsWith("value", StringComparison.Ordinal); } @@ -162,7 +175,7 @@ void SpanEndsWith() { var result = "value".AsSpan().EndsWith("value"); result = "value".AsSpan().EndsWith("value", StringComparison.Ordinal); - } + } void IsGenericMethodParameter() { @@ -177,7 +190,7 @@ void HasSameMetadataDefinitionAs(MemberInfo info) void GetMemberWithSameMetadataDefinitionAs(MemberInfo info) { var result = typeof(string).GetMemberWithSameMetadataDefinitionAs(info); - } + } void SpanStringBuilderAppend() { From cbf20bfdaf07411e5af8a0b3d51d45502376c064 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 21 Apr 2023 10:28:54 +1000 Subject: [PATCH 071/313] Update Consume.cs --- src/Consume/Consume.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index ed847da2..ac48f0a4 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -94,6 +94,8 @@ class Consume var contains = "a b".Contains(' '); } +#if HTTPREFERENCED + static void Http() { new HttpClient().GetStreamAsync("", CancellationToken.None); @@ -114,15 +116,20 @@ static void Http() }).ReadAsStringAsync(CancellationToken.None); } +#endif + void KeyValuePairDeconstruct(IEnumerable> variables) { foreach (var (name, value) in variables) { } } + #if VALUETUPLEREFERENCED + static (string value1, bool value2) NamedTupleMethod() => new("value", false); + #endif async Task StreamReaderReadAsync() From 1596c4cf9638bf210b1f24fdf6fa8c51c3e1f515 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 21 Apr 2023 10:39:10 +1000 Subject: [PATCH 072/313] Update Consume.cs --- src/Consume/Consume.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index ac48f0a4..c788d344 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -132,20 +132,21 @@ void KeyValuePairDeconstruct(IEnumerable> variables #endif - async Task StreamReaderReadAsync() + async Task StreamReaderReadToEndAsync() { - var result = new char[5]; - var memory = new Memory(result); var reader = new StreamReader(new MemoryStream()); - var read = await reader.ReadAsync(memory); + var read = await reader.ReadToEndAsync(CancellationToken.None); } - async Task StreamReaderReadToEndAsync() +#if MEMORYREFERENCED + + async Task StreamReaderReadAsync() { + var result = new char[5]; + var memory = new Memory(result); var reader = new StreamReader(new MemoryStream()); - var read = await reader.ReadToEndAsync(CancellationToken.None); + var read = await reader.ReadAsync(memory); } - async Task StreamReadAsync() { var input = new byte[] @@ -184,6 +185,8 @@ void SpanEndsWith() result = "value".AsSpan().EndsWith("value", StringComparison.Ordinal); } +#endif + void IsGenericMethodParameter() { var result = typeof(string).IsGenericMethodParameter(); From 0034991f8e298bf2537ecb1874344fbc6799ccf7 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 21 Apr 2023 10:44:25 +1000 Subject: [PATCH 073/313] Update Consume.cs --- src/Consume/Consume.cs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index c788d344..57a802f8 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -40,8 +40,6 @@ class Consume type = typeof(SkipLocalsInitAttribute); type = typeof(TupleElementNamesAttribute); type = typeof(DebuggerNonUserCodeAttribute); - type = typeof(ValueTuple<>); - type = typeof(ValueTuple); type = typeof(UnscopedRefAttribute); type = typeof(InterpolatedStringHandlerArgumentAttribute); type = typeof(InterpolatedStringHandlerAttribute); @@ -185,6 +183,18 @@ void SpanEndsWith() result = "value".AsSpan().EndsWith("value", StringComparison.Ordinal); } + void SpanStringBuilderAppend() + { + var builder = new StringBuilder(); + builder.Append("value".AsSpan()); + } + + void StringEqualsSpan() + { + var builder = new StringBuilder("value"); + var equals = builder.Equals("value".AsSpan()); + } + #endif void IsGenericMethodParameter() @@ -201,16 +211,4 @@ void GetMemberWithSameMetadataDefinitionAs(MemberInfo info) { var result = typeof(string).GetMemberWithSameMetadataDefinitionAs(info); } - - void SpanStringBuilderAppend() - { - var builder = new StringBuilder(); - builder.Append("value".AsSpan()); - } - - void StringEqualsSpan() - { - var builder = new StringBuilder("value"); - var equals = builder.Equals("value".AsSpan()); - } } \ No newline at end of file From e4dfcb2c59f499ab7d84b694be7c66c4a4e3b109 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 21 Apr 2023 10:57:44 +1000 Subject: [PATCH 074/313] Update Consume.cs --- src/Consume/Consume.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 57a802f8..33cce958 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -50,7 +50,8 @@ class Consume type = typeof(RequiresUnreferencedCodeAttribute); type = typeof(UnconditionalSuppressMessageAttribute); type = typeof(CompilerFeatureRequiredAttribute); - type = typeof(AsyncMethodBuilderAttribute); + //TODO: + //type = typeof(AsyncMethodBuilderAttribute); type = typeof(ObsoletedOSPlatformAttribute); type = typeof(SupportedOSPlatformAttribute); type = typeof(SupportedOSPlatformGuardAttribute); From 4a3690e53a1c412ce5b4782efdc9513bee435f41 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 21 Apr 2023 11:06:09 +1000 Subject: [PATCH 075/313] Dont require index in nullability (#34) --- src/Directory.Build.props | 2 +- src/Polyfill/Nullability/NullabilityInfoContext.cs | 4 +++- src/Tests/NullabilitySync.cs | 8 +++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index d4e97592..596c50d2 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.17.0 + 1.17.1 1.0.0 Polyfill true diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs index 7289dea0..0d8bbc61 100644 --- a/src/Polyfill/Nullability/NullabilityInfoContext.cs +++ b/src/Polyfill/Nullability/NullabilityInfoContext.cs @@ -209,7 +209,9 @@ public NullabilityInfo Create(PropertyInfo propertyInfo) if (setter != null) { - CheckNullabilityAttributes(nullability, setter.GetParameters()[^1].GetCustomAttributesData()); + var parameters = setter.GetParameters(); + +CheckNullabilityAttributes(nullability, parameters[parameters.Length-1].GetCustomAttributesData()); } else { diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs index 3c767181..57c3c734 100644 --- a/src/Tests/NullabilitySync.cs +++ b/src/Tests/NullabilitySync.cs @@ -21,7 +21,13 @@ public async Task Run() infoContext = infoContext .Replace(".IsGenericMethodParameter", ".IsGenericMethodParameter()") - .Replace("SR.NullabilityInfoContext_NotSupported", "\"NullabilityInfoContext is not supported\""); + .Replace("SR.NullabilityInfoContext_NotSupported", "\"NullabilityInfoContext is not supported\"") + .Replace( + "CheckNullabilityAttributes(nullability, setter.GetParameters()[^1].GetCustomAttributesData());", + """ + var parameters = setter.GetParameters(); + CheckNullabilityAttributes(nullability, parameters[parameters.Length-1].GetCustomAttributesData()); + """); var lines = infoContext.Split('\r', '\n'); infoContext = string.Join(Environment.NewLine, lines.Where(_ => !_.Contains("ArgumentNullException.ThrowIfNull"))); From 388778f4a005b583a55ad2aa5703d71e8916057b Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 21 Apr 2023 11:09:42 +1000 Subject: [PATCH 076/313] Update Consume.cs --- src/Consume/Consume.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 33cce958..62b231c3 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -64,8 +64,10 @@ class Consume type = typeof(DisableRuntimeMarshallingAttribute); type = typeof(RequiresUnreferencedCodeAttribute); +#if (NET46X && VALUETUPLEREFERENCED) || NET47X || NET48X || NETSTANDARD2_0 || NETCOREAPP2X var range = "value"[1..]; var index = "value"[^2]; +#endif var startsWith = "value".StartsWith('a'); var endsWith = "value".EndsWith('a'); @@ -124,7 +126,7 @@ void KeyValuePairDeconstruct(IEnumerable> variables } } -#if VALUETUPLEREFERENCED +#if (NET46X && VALUETUPLEREFERENCED) || NET47X || NET48X || NETSTANDARD2_0 || NETCOREAPP2X static (string value1, bool value2) NamedTupleMethod() => new("value", false); From 975611d957d8601d63811036263157f351119d27 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 21 Apr 2023 11:14:13 +1000 Subject: [PATCH 077/313] Update appveyor.yml --- src/appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/appveyor.yml b/src/appveyor.yml index b1fa26e0..cb7a6243 100644 --- a/src/appveyor.yml +++ b/src/appveyor.yml @@ -22,8 +22,8 @@ build_script: sudo ./dotnet-install.sh --jsonfile src/global.json --architecture x64 --install-dir '/usr/share/dotnet' } } -- dotnet build src --configuration Release -- dotnet test src --configuration Release --no-build --no-restore +- dotnet build src --configuration Release --verbosity quiet +- dotnet test src --configuration Release --no-build --no-restore --verbosity quiet on_failure: - ps: Get-ChildItem *.received.* -recurse | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name } From c566dd499c626264f6c25edc956079c32a6cbbf9 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 21 Apr 2023 11:26:12 +1000 Subject: [PATCH 078/313] Update Consume.cs --- src/Consume/Consume.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 62b231c3..3d5efccd 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -38,7 +38,8 @@ class Consume type = typeof(RequiredMemberAttribute); type = typeof(SetsRequiredMembersAttribute); type = typeof(SkipLocalsInitAttribute); - type = typeof(TupleElementNamesAttribute); + //TODO: + // type = typeof(TupleElementNamesAttribute); type = typeof(DebuggerNonUserCodeAttribute); type = typeof(UnscopedRefAttribute); type = typeof(InterpolatedStringHandlerArgumentAttribute); From 3b363a45c42bc68d0584bc099219b864730dbffe Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 21 Apr 2023 12:56:36 +1000 Subject: [PATCH 079/313] fix sync --- src/Polyfill/Nullability/NullabilityInfoContext.cs | 2 +- src/Tests/NullabilitySync.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs index 0d8bbc61..85990bc6 100644 --- a/src/Polyfill/Nullability/NullabilityInfoContext.cs +++ b/src/Polyfill/Nullability/NullabilityInfoContext.cs @@ -211,7 +211,7 @@ public NullabilityInfo Create(PropertyInfo propertyInfo) { var parameters = setter.GetParameters(); -CheckNullabilityAttributes(nullability, parameters[parameters.Length-1].GetCustomAttributesData()); + CheckNullabilityAttributes(nullability, parameters[parameters.Length-1].GetCustomAttributesData()); } else { diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs index 57c3c734..6999943c 100644 --- a/src/Tests/NullabilitySync.cs +++ b/src/Tests/NullabilitySync.cs @@ -1,4 +1,4 @@ -#if NET8_0 +#if NET8_0 && DEBUG using System.Net.Http; using VerifyTests; @@ -26,7 +26,7 @@ public async Task Run() "CheckNullabilityAttributes(nullability, setter.GetParameters()[^1].GetCustomAttributesData());", """ var parameters = setter.GetParameters(); - CheckNullabilityAttributes(nullability, parameters[parameters.Length-1].GetCustomAttributesData()); + CheckNullabilityAttributes(nullability, parameters[parameters.Length-1].GetCustomAttributesData()); """); var lines = infoContext.Split('\r', '\n'); From cbc268274f0909a0a9db3b65719959a3da06bfcb Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 24 Apr 2023 12:59:30 +1000 Subject: [PATCH 080/313] extend Text ReaderWriter instead of Stream ReaderWriter (#35) * extend Text ReaderWriter instead of Stream ReaderWriter * Update Directory.Build.props --- api_list.include.md | 20 ++++++++--------- contributing.md | 14 ++++++------ src/Directory.Build.props | 2 +- ...er.cs => PolyfillExtensions_TextReader.cs} | 22 ++++--------------- ...er.cs => PolyfillExtensions_TextWriter.cs} | 8 +++---- 5 files changed, 26 insertions(+), 40 deletions(-) rename src/Polyfill/{PolyfillExtensions_StreamReader.cs => PolyfillExtensions_TextReader.cs} (74%) rename src/Polyfill/{PolyfillExtensions_StreamWriter.cs => PolyfillExtensions_TextWriter.cs} (87%) diff --git a/api_list.include.md b/api_list.include.md index 39ae1a41..d25a64c8 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -110,16 +110,6 @@ * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) -### StreamReader - - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) - * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readtoendasync#system-io-streamreader-readtoendasync(system-threading-cancellationtoken)) - -### StreamWriter - - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writelineasync#system-io-streamwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - ### String * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) @@ -136,6 +126,16 @@ * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) +### TextReader + + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) + * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) + +### TextWriter + + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### TimeSpan * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond) diff --git a/contributing.md b/contributing.md index a3ac3d38..34040bdf 100644 --- a/contributing.md +++ b/contributing.md @@ -186,8 +186,8 @@ Add an extension method to `PolyfillExtensions_TYPE.cs` where `TYPE` is the type Example: - - + + ```cs #if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) @@ -215,9 +215,9 @@ static partial class PolyfillExtensions /// The default value is . /// /// A task that represents the asynchronous write operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] public static ValueTask WriteAsync( - this StreamWriter target, + this TextWriter target, ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { @@ -241,9 +241,9 @@ static partial class PolyfillExtensions /// The default value is . /// /// A task that represents the asynchronous write operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writelineasync#system-io-streamwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] public static ValueTask WriteLineAsync( - this StreamWriter target, + this TextWriter target, ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { @@ -260,7 +260,7 @@ static partial class PolyfillExtensions } #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 596c50d2..90f3da83 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.17.1 + 1.18.0 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_StreamReader.cs b/src/Polyfill/PolyfillExtensions_TextReader.cs similarity index 74% rename from src/Polyfill/PolyfillExtensions_StreamReader.cs rename to src/Polyfill/PolyfillExtensions_TextReader.cs index e3c9793e..d5ba369c 100644 --- a/src/Polyfill/PolyfillExtensions_StreamReader.cs +++ b/src/Polyfill/PolyfillExtensions_TextReader.cs @@ -30,9 +30,9 @@ static partial class PolyfillExtensions /// The number will be less than or equal to the length, depending on whether the data is /// available within the stream. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)")] + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)")] public static ValueTask ReadAsync( - this StreamReader target, + this TextReader target, Memory buffer, CancellationToken cancellationToken = default) { @@ -57,23 +57,9 @@ public static ValueTask ReadAsync( /// The number of characters is larger than . /// The stream reader has been disposed. /// The reader is currently in use by a previous read operation. - /// - /// The following example shows how to read the contents of a file by using the method. - /// - /// using CancellationTokenSource tokenSource = new (TimeSpan.FromSeconds(1)); - /// using StreamReader reader = File.OpenText("existingfile.txt"); - /// - /// Console.WriteLine(await reader.ReadToEndAsync(tokenSource.Token)); - /// - /// - /// - /// If this method is canceled via , some data - /// that has been read from the current but not stored (by the - /// ) or returned (to the caller) may be lost. - /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.streamreader.readtoendasync#system-io-streamreader-readtoendasync(system-threading-cancellationtoken)")] + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)")] public static Task ReadToEndAsync( - this StreamReader target, + this TextReader target, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/Polyfill/PolyfillExtensions_StreamWriter.cs b/src/Polyfill/PolyfillExtensions_TextWriter.cs similarity index 87% rename from src/Polyfill/PolyfillExtensions_StreamWriter.cs rename to src/Polyfill/PolyfillExtensions_TextWriter.cs index be531ad2..b3b2c776 100644 --- a/src/Polyfill/PolyfillExtensions_StreamWriter.cs +++ b/src/Polyfill/PolyfillExtensions_TextWriter.cs @@ -24,9 +24,9 @@ static partial class PolyfillExtensions /// The default value is . /// /// A task that represents the asynchronous write operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writeasync#system-io-streamwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] public static ValueTask WriteAsync( - this StreamWriter target, + this TextWriter target, ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { @@ -50,9 +50,9 @@ public static ValueTask WriteAsync( /// The default value is . /// /// A task that represents the asynchronous write operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.writelineasync#system-io-streamwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] public static ValueTask WriteLineAsync( - this StreamWriter target, + this TextWriter target, ReadOnlyMemory buffer, CancellationToken cancellationToken = default) { From 6e390136202c71b63d92574f3e9f05d29a6e782c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Apr 2023 19:54:09 +1000 Subject: [PATCH 081/313] Bump Verify.DiffPlex from 2.2.0 to 2.2.1 in /src (#37) Bumps [Verify.DiffPlex](https://github.com/VerifyTests/Verify.DiffPlex) from 2.2.0 to 2.2.1. - [Release notes](https://github.com/VerifyTests/Verify.DiffPlex/releases) - [Commits](https://github.com/VerifyTests/Verify.DiffPlex/commits/2.2.1) --- updated-dependencies: - dependency-name: Verify.DiffPlex dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 55954f58..a85bdcb6 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -30,7 +30,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 64ad2ea8..14073f50 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -25,7 +25,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index c162c1c1..e04b250f 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -24,7 +24,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 14f92496..da10a19a 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -25,7 +25,7 @@ - + From 69da1de18bf453c78640485ae9e71c8844d811c0 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 25 Apr 2023 09:47:47 +1000 Subject: [PATCH 082/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index a85bdcb6..1ba9f607 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 14073f50..4595bd0e 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index e04b250f..bae231df 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index da10a19a..4945ceeb 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From fe1859404aedaa6ecd0bc09ef8edb5034a3b84d8 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 26 Apr 2023 11:40:45 +1000 Subject: [PATCH 083/313] Update NullabilityInfoExtensions.cs --- src/Polyfill/Nullability/NullabilityInfoExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Polyfill/Nullability/NullabilityInfoExtensions.cs b/src/Polyfill/Nullability/NullabilityInfoExtensions.cs index eab48054..eea54e78 100644 --- a/src/Polyfill/Nullability/NullabilityInfoExtensions.cs +++ b/src/Polyfill/Nullability/NullabilityInfoExtensions.cs @@ -6,7 +6,7 @@ using System.Reflection; /// -/// Static and thread safe wrapper around . +/// Static and thread safe wrapper around NullabilityInfoContext. /// #if PolyPublic public From 68e12c6e78743f37fe87410615879b5e9a1757a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Apr 2023 19:23:36 +1000 Subject: [PATCH 084/313] Bump Verify.NUnit from 19.13.0 to 19.13.1 in /src (#39) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 19.13.0 to 19.13.1. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/commits/19.13.1) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 1ba9f607..e3c79a40 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 4595bd0e..c6483ea5 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index bae231df..ed3ebeae 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 4945ceeb..f7d2ad2d 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From e2420e98583fe868c2c95111fcf0a9feda072a56 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 28 Apr 2023 11:44:38 +1000 Subject: [PATCH 085/313] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 57b14b37..30ef7980 100644 --- a/readme.md +++ b/readme.md @@ -36,7 +36,7 @@ This project uses features from the current stable SDK and C# language. As such ```json { "sdk": { - "version": "7.0.202", + "version": "7.0.203", "rollForward": "latestFeature" } } From a9f17a6183c24fbdceaede662f02477422d7c9b3 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 28 Apr 2023 11:50:16 +1000 Subject: [PATCH 086/313] Update readme.md --- readme.md | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 30ef7980..7459f642 100644 --- a/readme.md +++ b/readme.md @@ -347,7 +347,153 @@ Reference: [Improvements in native code interop in .NET 5.0](https://devblogs.mi The class `PolyfillExtensions` includes the following extension methods: - +### DateTime + + * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond) + +### DateTimeOffset + + * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond) + +### Reflection.EventInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + +### Reflection.FieldInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + +### HttpClient + + * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) + * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)) + * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) + * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) + +### HttpContent + + * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) + * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) + * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) + +### IEnumerable + + * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) + +### IReadOnlyDictionary + + * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) + +### IReadOnlyDictionary + + * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) + +### KeyValuePair + + * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) + +### Reflection.MemberInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas) + * `Boolean IsNullable()` + +### Reflection.ParameterInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + +### Reflection.PropertyInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + +### ReadOnlySpan + + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) + +### ReadOnlySpan + + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + +### ReadOnlySpan + + * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + +### ReadOnlySpan + + * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + +### Span + + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) + +### Span + + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) + +### Span + + * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) + +### Span + + * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) + +### Stream + + * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) + +### String + + * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) + * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) + * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)) + * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)) + * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + +### StringBuilder + + * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) + * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) + * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) + +### TextReader + + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) + * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) + +### TextWriter + + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + +### TimeSpan + + * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond) + * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) + +### Type + + * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) + ## References From 5ce6c37a9c896db29f0cb123bc0485ecae8e3467 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 16:57:42 +1000 Subject: [PATCH 087/313] Bump Verify.NUnit from 19.13.1 to 19.14.0 in /src (#40) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 19.13.1 to 19.14.0. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/compare/19.13.1...19.14.0) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index e3c79a40..bf9b4e2d 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index c6483ea5..27ba6d23 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index ed3ebeae..4cefd70c 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index f7d2ad2d..5671a036 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From f5d5caaf5e44c1434ffd479ef9845877b33d68cc Mon Sep 17 00:00:00 2001 From: Matt Johnson-Pint Date: Sat, 29 Apr 2023 01:40:02 -0600 Subject: [PATCH 088/313] Update Polyfill.targets (#41) --- src/Polyfill/Polyfill.targets | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Polyfill/Polyfill.targets b/src/Polyfill/Polyfill.targets index 10b139ba..8f64ed65 100644 --- a/src/Polyfill/Polyfill.targets +++ b/src/Polyfill/Polyfill.targets @@ -1,11 +1,11 @@ - $(PrepareForBuildDependsOn);PrintAllDeps + $(PrepareForBuildDependsOn);PreparePolyfill - - - + + + true From a57141e0eae693101cf94474db09cb689dd793d1 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 29 Apr 2023 17:40:48 +1000 Subject: [PATCH 089/313] Update Polyfill.targets --- src/Polyfill/Polyfill.targets | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Polyfill/Polyfill.targets b/src/Polyfill/Polyfill.targets index 8f64ed65..bdac2e17 100644 --- a/src/Polyfill/Polyfill.targets +++ b/src/Polyfill/Polyfill.targets @@ -4,8 +4,6 @@ - - true From 434386eac423113dff0bf026d24740253a748f2b Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 29 Apr 2023 17:41:45 +1000 Subject: [PATCH 090/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 90f3da83..a19e6000 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.18.0 + 1.19.0 1.0.0 Polyfill true From b33bc7c5ba5792b7967c5053b367d34c98746f7c Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 29 Apr 2023 21:15:52 +1000 Subject: [PATCH 091/313] move from targets to props (#42) --- src/Consume/Consume.csproj | 1 - .../ConsumeClassicReferences.csproj | 1 - src/ConsumeIndirect/ConsumeIndirect.csproj | 1 - src/ConsumeNoRefs/ConsumeNoRefs.csproj | 1 - src/Directory.Build.props | 2 +- src/NoRefsTests/NoRefsTests.csproj | 1 - src/Polyfill/Polyfill.nuspec | 2 - src/Polyfill/Polyfill.props | 40 ------------------- src/Polyfill/Polyfill.targets | 37 ++++++++++++++++- src/PublicTests/PublicTests.csproj | 1 - src/Tests/Tests.csproj | 1 - src/UnsafeTests/UnsafeTests.csproj | 1 - 12 files changed, 37 insertions(+), 52 deletions(-) delete mode 100644 src/Polyfill/Polyfill.props diff --git a/src/Consume/Consume.csproj b/src/Consume/Consume.csproj index 117f401e..c57fb899 100644 --- a/src/Consume/Consume.csproj +++ b/src/Consume/Consume.csproj @@ -28,6 +28,5 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - \ No newline at end of file diff --git a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj index d81058b6..d9bae431 100644 --- a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj +++ b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj @@ -29,6 +29,5 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - \ No newline at end of file diff --git a/src/ConsumeIndirect/ConsumeIndirect.csproj b/src/ConsumeIndirect/ConsumeIndirect.csproj index cbec079c..7081b133 100644 --- a/src/ConsumeIndirect/ConsumeIndirect.csproj +++ b/src/ConsumeIndirect/ConsumeIndirect.csproj @@ -26,6 +26,5 @@ - \ No newline at end of file diff --git a/src/ConsumeNoRefs/ConsumeNoRefs.csproj b/src/ConsumeNoRefs/ConsumeNoRefs.csproj index 11f743c9..f8520598 100644 --- a/src/ConsumeNoRefs/ConsumeNoRefs.csproj +++ b/src/ConsumeNoRefs/ConsumeNoRefs.csproj @@ -25,6 +25,5 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props index a19e6000..2d58d8f1 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.19.0 + 1.20.0 1.0.0 Polyfill true diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index bf9b4e2d..03fbf7f6 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -36,6 +36,5 @@ - \ No newline at end of file diff --git a/src/Polyfill/Polyfill.nuspec b/src/Polyfill/Polyfill.nuspec index a072ac3f..4dc1228f 100644 --- a/src/Polyfill/Polyfill.nuspec +++ b/src/Polyfill/Polyfill.nuspec @@ -27,8 +27,6 @@ target="contentFiles/cs/netstandard2.0/Polyfill/Trimming"/> - diff --git a/src/Polyfill/Polyfill.props b/src/Polyfill/Polyfill.props deleted file mode 100644 index 3f82ce4c..00000000 --- a/src/Polyfill/Polyfill.props +++ /dev/null @@ -1,40 +0,0 @@ - - - $(DefineConstants);AllowUnsafeBlocks - - - $(DefineConstants);PolyPublic - - - false - false - false - false - $(TargetFramework.ToLower()) - - - $(DefineConstants);NETCOREAPP2X - - - $(DefineConstants);NETCOREAPP3X - - - $(DefineConstants);NET46X - - - $(DefineConstants);NET47X - - - $(DefineConstants);NET48X - - - $(DefineConstants);NETCOREAPPX - - - - false - - - \ No newline at end of file diff --git a/src/Polyfill/Polyfill.targets b/src/Polyfill/Polyfill.targets index bdac2e17..c6e4070d 100644 --- a/src/Polyfill/Polyfill.targets +++ b/src/Polyfill/Polyfill.targets @@ -1,8 +1,43 @@ $(PrepareForBuildDependsOn);PreparePolyfill + false + false + false + false + $(TargetFramework.ToLower()) - + + $(DefineConstants);AllowUnsafeBlocks + + + $(DefineConstants);PolyPublic + + + $(DefineConstants);NETCOREAPP2X + + + $(DefineConstants);NETCOREAPP3X + + + $(DefineConstants);NET46X + + + $(DefineConstants);NET47X + + + $(DefineConstants);NET48X + + + $(DefineConstants);NETCOREAPPX + + + + false + + - \ No newline at end of file diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 4cefd70c..8c87fa8d 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -35,6 +35,5 @@ - \ No newline at end of file diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 5671a036..805fe9a2 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -35,6 +35,5 @@ - \ No newline at end of file From 2cf0302a1dc26e249ca25b054943e218c99ca290 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 29 Apr 2023 21:19:09 +1000 Subject: [PATCH 092/313] Revert "move from targets to props (#42)" This reverts commit b33bc7c5ba5792b7967c5053b367d34c98746f7c. --- src/Consume/Consume.csproj | 1 + .../ConsumeClassicReferences.csproj | 1 + src/ConsumeIndirect/ConsumeIndirect.csproj | 1 + src/ConsumeNoRefs/ConsumeNoRefs.csproj | 1 + src/Directory.Build.props | 2 +- src/NoRefsTests/NoRefsTests.csproj | 1 + src/Polyfill/Polyfill.nuspec | 2 + src/Polyfill/Polyfill.props | 40 +++++++++++++++++++ src/Polyfill/Polyfill.targets | 37 +---------------- src/PublicTests/PublicTests.csproj | 1 + src/Tests/Tests.csproj | 1 + src/UnsafeTests/UnsafeTests.csproj | 1 + 12 files changed, 52 insertions(+), 37 deletions(-) create mode 100644 src/Polyfill/Polyfill.props diff --git a/src/Consume/Consume.csproj b/src/Consume/Consume.csproj index c57fb899..117f401e 100644 --- a/src/Consume/Consume.csproj +++ b/src/Consume/Consume.csproj @@ -28,5 +28,6 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs + \ No newline at end of file diff --git a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj index d9bae431..d81058b6 100644 --- a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj +++ b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj @@ -29,5 +29,6 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs + \ No newline at end of file diff --git a/src/ConsumeIndirect/ConsumeIndirect.csproj b/src/ConsumeIndirect/ConsumeIndirect.csproj index 7081b133..cbec079c 100644 --- a/src/ConsumeIndirect/ConsumeIndirect.csproj +++ b/src/ConsumeIndirect/ConsumeIndirect.csproj @@ -26,5 +26,6 @@ + \ No newline at end of file diff --git a/src/ConsumeNoRefs/ConsumeNoRefs.csproj b/src/ConsumeNoRefs/ConsumeNoRefs.csproj index f8520598..11f743c9 100644 --- a/src/ConsumeNoRefs/ConsumeNoRefs.csproj +++ b/src/ConsumeNoRefs/ConsumeNoRefs.csproj @@ -25,5 +25,6 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs + \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 2d58d8f1..a19e6000 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.20.0 + 1.19.0 1.0.0 Polyfill true diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 03fbf7f6..bf9b4e2d 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -36,5 +36,6 @@ + \ No newline at end of file diff --git a/src/Polyfill/Polyfill.nuspec b/src/Polyfill/Polyfill.nuspec index 4dc1228f..a072ac3f 100644 --- a/src/Polyfill/Polyfill.nuspec +++ b/src/Polyfill/Polyfill.nuspec @@ -27,6 +27,8 @@ target="contentFiles/cs/netstandard2.0/Polyfill/Trimming"/> + diff --git a/src/Polyfill/Polyfill.props b/src/Polyfill/Polyfill.props new file mode 100644 index 00000000..3f82ce4c --- /dev/null +++ b/src/Polyfill/Polyfill.props @@ -0,0 +1,40 @@ + + + $(DefineConstants);AllowUnsafeBlocks + + + $(DefineConstants);PolyPublic + + + false + false + false + false + $(TargetFramework.ToLower()) + + + $(DefineConstants);NETCOREAPP2X + + + $(DefineConstants);NETCOREAPP3X + + + $(DefineConstants);NET46X + + + $(DefineConstants);NET47X + + + $(DefineConstants);NET48X + + + $(DefineConstants);NETCOREAPPX + + + + false + + + \ No newline at end of file diff --git a/src/Polyfill/Polyfill.targets b/src/Polyfill/Polyfill.targets index c6e4070d..bdac2e17 100644 --- a/src/Polyfill/Polyfill.targets +++ b/src/Polyfill/Polyfill.targets @@ -1,43 +1,8 @@ $(PrepareForBuildDependsOn);PreparePolyfill - false - false - false - false - $(TargetFramework.ToLower()) - - $(DefineConstants);AllowUnsafeBlocks - - - $(DefineConstants);PolyPublic - - - $(DefineConstants);NETCOREAPP2X - - - $(DefineConstants);NETCOREAPP3X - - - $(DefineConstants);NET46X - - - $(DefineConstants);NET47X - - - $(DefineConstants);NET48X - - - $(DefineConstants);NETCOREAPPX - - - - false - - + + \ No newline at end of file diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 8c87fa8d..4cefd70c 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -35,5 +35,6 @@ + \ No newline at end of file diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 805fe9a2..5671a036 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -35,5 +35,6 @@ + \ No newline at end of file From a2ac881754b3cbd4e3a89e880641d45ad00b5220 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 29 Apr 2023 21:21:12 +1000 Subject: [PATCH 093/313] . --- src/Polyfill/Polyfill.props | 3 --- src/Polyfill/Polyfill.targets | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Polyfill/Polyfill.props b/src/Polyfill/Polyfill.props index 3f82ce4c..7f4a67a9 100644 --- a/src/Polyfill/Polyfill.props +++ b/src/Polyfill/Polyfill.props @@ -2,9 +2,6 @@ $(DefineConstants);AllowUnsafeBlocks - - $(DefineConstants);PolyPublic - false false diff --git a/src/Polyfill/Polyfill.targets b/src/Polyfill/Polyfill.targets index bdac2e17..3c520ab7 100644 --- a/src/Polyfill/Polyfill.targets +++ b/src/Polyfill/Polyfill.targets @@ -2,6 +2,9 @@ $(PrepareForBuildDependsOn);PreparePolyfill + + $(DefineConstants);PolyPublic + From c59d8f0a242e35a88cdd795d47bd38cf425840df Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 29 Apr 2023 21:23:30 +1000 Subject: [PATCH 094/313] Update Consume.cs --- src/Consume/Consume.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 3d5efccd..3cb936cb 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -107,15 +107,9 @@ static void Http() new HttpClient().GetStringAsync("", CancellationToken.None); new HttpClient().GetStringAsync(new Uri(""), CancellationToken.None); - new ByteArrayContent(new byte[] - { - }).ReadAsStreamAsync(CancellationToken.None); - new ByteArrayContent(new byte[] - { - }).ReadAsByteArrayAsync(CancellationToken.None); - new ByteArrayContent(new byte[] - { - }).ReadAsStringAsync(CancellationToken.None); + new ByteArrayContent(Array.Empty()).ReadAsStreamAsync(CancellationToken.None); + new ByteArrayContent(Array.Empty()).ReadAsByteArrayAsync(CancellationToken.None); + new ByteArrayContent(Array.Empty()).ReadAsStringAsync(CancellationToken.None); } #endif From 4e7903b59bf83389011248666b13f26e96633922 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 29 Apr 2023 21:57:47 +1000 Subject: [PATCH 095/313] Add TextWriter Write and WriteLine (#43) --- api_list.include.md | 2 + contributing.md | 36 +++++++++++++- readme.md | 2 + src/Polyfill/PolyfillExtensions_TextWriter.cs | 34 +++++++++++++ .../PolyfillExtensionsTests_StreamWriter.cs | 26 ---------- .../PolyfillExtensionsTests_TextWriter.cs | 49 +++++++++++++++++++ 6 files changed, 122 insertions(+), 27 deletions(-) delete mode 100644 src/Tests/PolyfillExtensionsTests_StreamWriter.cs create mode 100644 src/Tests/PolyfillExtensionsTests_TextWriter.cs diff --git a/api_list.include.md b/api_list.include.md index d25a64c8..eb5c7b7a 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -133,7 +133,9 @@ ### TextWriter + * `Void Write(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write?view=net-7.0#system-io-textwriter-write(system-readonlyspan((system-char)))) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Void WriteLine(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline?view=net-7.0#system-io-textwriter-writeline(system-readonlyspan((system-char)))) * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### TimeSpan diff --git a/contributing.md b/contributing.md index 34040bdf..96952f26 100644 --- a/contributing.md +++ b/contributing.md @@ -232,6 +232,23 @@ static partial class PolyfillExtensions return new(target.WriteAsync(segment.Array!, segment.Offset, segment.Count)); } + /// + /// Wwrites a character memory region to the stream. + /// + /// The character memory region to write to the stream. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] + public static void Write( + this TextWriter target, + ReadOnlyMemory buffer) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + + target.Write(segment.Array!, segment.Offset, segment.Count); + } + /// /// Asynchronously writes the text representation of a character memory region to the stream, followed by a line terminator. /// @@ -257,10 +274,27 @@ static partial class PolyfillExtensions return new(target.WriteLineAsync(segment.Array!, segment.Offset, segment.Count)); } + + /// + /// Writes the text representation of a character memory region to the stream, followed by a line terminator. + /// + /// The character memory region to write to the stream. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] + public static void WriteLine( + this TextWriter target, + ReadOnlyMemory buffer) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + + target.WriteLine(segment.Array!, segment.Offset, segment.Count); + } } #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/readme.md b/readme.md index 7459f642..5d1b95ab 100644 --- a/readme.md +++ b/readme.md @@ -482,7 +482,9 @@ The class `PolyfillExtensions` includes the following extension methods: ### TextWriter + * `Void Write(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write?view=net-7.0#system-io-textwriter-write(system-readonlyspan((system-char)))) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Void WriteLine(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline?view=net-7.0#system-io-textwriter-writeline(system-readonlyspan((system-char)))) * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) ### TimeSpan diff --git a/src/Polyfill/PolyfillExtensions_TextWriter.cs b/src/Polyfill/PolyfillExtensions_TextWriter.cs index b3b2c776..c9a61a6c 100644 --- a/src/Polyfill/PolyfillExtensions_TextWriter.cs +++ b/src/Polyfill/PolyfillExtensions_TextWriter.cs @@ -41,6 +41,23 @@ public static ValueTask WriteAsync( return new(target.WriteAsync(segment.Array!, segment.Offset, segment.Count)); } + /// + /// Wwrites a character memory region to the stream. + /// + /// The character memory region to write to the stream. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] + public static void Write( + this TextWriter target, + ReadOnlyMemory buffer) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + + target.Write(segment.Array!, segment.Offset, segment.Count); + } + /// /// Asynchronously writes the text representation of a character memory region to the stream, followed by a line terminator. /// @@ -66,5 +83,22 @@ public static ValueTask WriteLineAsync( return new(target.WriteLineAsync(segment.Array!, segment.Offset, segment.Count)); } + + /// + /// Writes the text representation of a character memory region to the stream, followed by a line terminator. + /// + /// The character memory region to write to the stream. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] + public static void WriteLine( + this TextWriter target, + ReadOnlyMemory buffer) + { + if (!MemoryMarshal.TryGetArray(buffer, out var segment)) + { + segment = new(buffer.ToArray()); + } + + target.WriteLine(segment.Array!, segment.Offset, segment.Count); + } } #endif \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_StreamWriter.cs b/src/Tests/PolyfillExtensionsTests_StreamWriter.cs deleted file mode 100644 index 916c211f..00000000 --- a/src/Tests/PolyfillExtensionsTests_StreamWriter.cs +++ /dev/null @@ -1,26 +0,0 @@ -partial class PolyfillExtensionsTests -{ - [Test] - public async Task StreamWriterWriteAsync() - { - using var stream = new MemoryStream(); - var memory = new Memory("value".ToArray()); - using var writer = new StreamWriter(stream); - await writer.WriteAsync(memory); - await writer.FlushAsync(); - var s = Encoding.UTF8.GetString(stream.ToArray()); - Assert.AreEqual("value", s); - } - - [Test] - public async Task StreamWriterWriteLineAsync() - { - using var stream = new MemoryStream(); - var memory = new Memory("value".ToArray()); - using var writer = new StreamWriter(stream); - await writer.WriteLineAsync(memory); - await writer.FlushAsync(); - var s = Encoding.UTF8.GetString(stream.ToArray()); - Assert.AreEqual("value" + Environment.NewLine, s); - } -} diff --git a/src/Tests/PolyfillExtensionsTests_TextWriter.cs b/src/Tests/PolyfillExtensionsTests_TextWriter.cs new file mode 100644 index 00000000..755ac7c5 --- /dev/null +++ b/src/Tests/PolyfillExtensionsTests_TextWriter.cs @@ -0,0 +1,49 @@ +partial class PolyfillExtensionsTests +{ + [Test] + public async Task TextWriterWriteAsync() + { + using var stream = new MemoryStream(); + var memory = new Memory("value".ToArray()); + using var writer = new StreamWriter(stream); + await writer.WriteAsync(memory); + await writer.FlushAsync(); + var s = Encoding.UTF8.GetString(stream.ToArray()); + Assert.AreEqual("value", s); + } + + [Test] + public async Task TextWriterWriteLineAsync() + { + using var stream = new MemoryStream(); + var memory = new Memory("value".ToArray()); + using var writer = new StreamWriter(stream); + await writer.WriteLineAsync(memory); + await writer.FlushAsync(); + var s = Encoding.UTF8.GetString(stream.ToArray()); + Assert.AreEqual("value" + Environment.NewLine, s); + } + [Test] + public async Task TextWriterWrite() + { + using var stream = new MemoryStream(); + var memory = new Memory("value".ToArray()); + using var writer = new StreamWriter(stream); + writer.Write(memory); + await writer.FlushAsync(); + var s = Encoding.UTF8.GetString(stream.ToArray()); + Assert.AreEqual("value", s); + } + + [Test] + public async Task TextWriterWriteLine() + { + using var stream = new MemoryStream(); + var memory = new Memory("value".ToArray()); + using var writer = new StreamWriter(stream); + writer.WriteLine(memory); + await writer.FlushAsync(); + var s = Encoding.UTF8.GetString(stream.ToArray()); + Assert.AreEqual("value" + Environment.NewLine, s); + } +} From dad64be42029922bda21fe053ca9501154ca55a9 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 30 Apr 2023 07:43:54 +1000 Subject: [PATCH 096/313] docs --- api_list.include.md | 32 ++++++++++++++++++++++++++++++-- readme.md | 32 ++++++++++++++++++++++++++++++-- src/Tests/BuildApiTest.cs | 1 + 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index eb5c7b7a..a4d87865 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -4,24 +4,28 @@ * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond) + ### DateTimeOffset * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond) + ### Reflection.EventInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` + ### Reflection.FieldInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` + ### HttpClient * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) @@ -31,28 +35,34 @@ * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) + ### HttpContent * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) + ### IEnumerable * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) + ### IReadOnlyDictionary * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) + ### IReadOnlyDictionary * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) + ### KeyValuePair * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) + ### Reflection.MemberInfo * `Reflection.NullabilityState GetNullability()` @@ -60,56 +70,68 @@ * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas) * `Boolean IsNullable()` + ### Reflection.ParameterInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` + ### Reflection.PropertyInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` + ### ReadOnlySpan * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) + ### ReadOnlySpan * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + ### ReadOnlySpan * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + ### ReadOnlySpan * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + ### Span * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) + ### Span * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) + ### Span * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) + ### Span * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) + ### Stream * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) + ### String * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) @@ -120,30 +142,36 @@ * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)) * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + ### StringBuilder * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) + ### TextReader * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) + ### TextWriter - * `Void Write(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write?view=net-7.0#system-io-textwriter-write(system-readonlyspan((system-char)))) + * `Void Write(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Void WriteLine(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline?view=net-7.0#system-io-textwriter-writeline(system-readonlyspan((system-char)))) + * `Void WriteLine(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### TimeSpan * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond) * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) + ### Type * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) + diff --git a/readme.md b/readme.md index 5d1b95ab..ed60fca9 100644 --- a/readme.md +++ b/readme.md @@ -353,24 +353,28 @@ The class `PolyfillExtensions` includes the following extension methods: * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond) + ### DateTimeOffset * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond) + ### Reflection.EventInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` + ### Reflection.FieldInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` + ### HttpClient * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) @@ -380,28 +384,34 @@ The class `PolyfillExtensions` includes the following extension methods: * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) + ### HttpContent * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) + ### IEnumerable * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) + ### IReadOnlyDictionary * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) + ### IReadOnlyDictionary * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) + ### KeyValuePair * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) + ### Reflection.MemberInfo * `Reflection.NullabilityState GetNullability()` @@ -409,56 +419,68 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas) * `Boolean IsNullable()` + ### Reflection.ParameterInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` + ### Reflection.PropertyInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` + ### ReadOnlySpan * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) + ### ReadOnlySpan * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + ### ReadOnlySpan * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + ### ReadOnlySpan * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + ### Span * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) + ### Span * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) + ### Span * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) + ### Span * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) + ### Stream * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) + ### String * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) @@ -469,32 +491,38 @@ The class `PolyfillExtensions` includes the following extension methods: * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)) * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + ### StringBuilder * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) + ### TextReader * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) + ### TextWriter - * `Void Write(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write?view=net-7.0#system-io-textwriter-write(system-readonlyspan((system-char)))) + * `Void Write(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Void WriteLine(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline?view=net-7.0#system-io-textwriter-writeline(system-readonlyspan((system-char)))) + * `Void WriteLine(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + ### TimeSpan * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond) * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) + ### Type * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) + diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index 38a8a4ac..c00ac2af 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -63,6 +63,7 @@ public void Run() } writer.WriteLine(); + writer.WriteLine(); } } From 055881608387b796d2e8223ef1a21bea84357c24 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 30 Apr 2023 08:51:22 +1000 Subject: [PATCH 097/313] add CopyTo and TryCopyTo (#44) --- api_list.include.md | 2 ++ readme.md | 2 ++ src/Polyfill/PolyfillExtensions_String.cs | 20 ++++++++++++++++++++ src/Tests/PolyfillExtensionsTests_String.cs | 16 ++++++++++++++++ 4 files changed, 40 insertions(+) diff --git a/api_list.include.md b/api_list.include.md index a4d87865..2774bc85 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -136,11 +136,13 @@ * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Void CopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.copyto) * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)) * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)) * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Boolean TryCopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto) ### StringBuilder diff --git a/readme.md b/readme.md index ed60fca9..bff7c108 100644 --- a/readme.md +++ b/readme.md @@ -485,11 +485,13 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Void CopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.copyto) * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)) * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)) * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Boolean TryCopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto) ### StringBuilder diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/PolyfillExtensions_String.cs index 3160ac03..a03f6800 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/PolyfillExtensions_String.cs @@ -11,6 +11,26 @@ static partial class PolyfillExtensions { +#if (MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP)) || NET5_0 + + /// + /// Copies the contents of this string into the destination span. + /// + /// The span into which to copy this string's contents + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.copyto")] + public static void CopyTo(this string target, Span destination) => + target.AsSpan().CopyTo(destination); + + /// + /// Copies the contents of this string into the destination span. + /// + /// The span into which to copy this string's contents + /// true if the data was copied; false if the destination was too short to fit the contents of the string. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto")] + public static bool TryCopyTo(this string target, Span destination) => + target.AsSpan().TryCopyTo(destination); +#endif + #if NETFRAMEWORK || NETSTANDARD2_0 /// diff --git a/src/Tests/PolyfillExtensionsTests_String.cs b/src/Tests/PolyfillExtensionsTests_String.cs index c897d4a3..688ae62f 100644 --- a/src/Tests/PolyfillExtensionsTests_String.cs +++ b/src/Tests/PolyfillExtensionsTests_String.cs @@ -16,6 +16,22 @@ public void EndsWith() Assert.False("".EndsWith('e')); } + [Test] + public void CopyTo() + { + var span = new Span(new char[1]); + "a".CopyTo(span); + Assert.AreEqual("a", span.ToString()); + } + + [Test] + public void TryCopyTo() + { + var span = new Span(new char[1]); + Assert.IsTrue("a".TryCopyTo(span)); + Assert.AreEqual("a", span.ToString()); + } + [Test] public void StringContainsStringComparison() => Assert.True("value".Contains("E", StringComparison.OrdinalIgnoreCase)); From 76fde8f2dfeeeebbc193070369840a1b750424be Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 30 Apr 2023 18:16:55 +1000 Subject: [PATCH 098/313] Add TryFormat (#45) --- api_list.include.md | 62 ++++ readme.md | 64 +++- src/Polyfill/PolyfillExtensions_TryFormat.cs | 347 ++++++++++++++++++ .../PolyfillExtensionsTests_TryFormat.cs | 181 +++++++++ 4 files changed, 653 insertions(+), 1 deletion(-) create mode 100644 src/Polyfill/PolyfillExtensions_TryFormat.cs create mode 100644 src/Tests/PolyfillExtensionsTests_TryFormat.cs diff --git a/api_list.include.md b/api_list.include.md index 2774bc85..d6c07d83 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -1,8 +1,19 @@ +### Boolean + + * `Boolean TryFormat(Span, Int32&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat) + + +### Byte + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) + + ### DateTime * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryformat) ### DateTimeOffset @@ -10,6 +21,17 @@ * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tryformat) + + +### Decimal + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) + + +### Double + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) ### Reflection.EventInfo @@ -48,6 +70,21 @@ * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) +### Int16 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) + + +### Int32 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat) + + +### Int64 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat) + + ### IReadOnlyDictionary * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) @@ -105,6 +142,16 @@ * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) +### SByte + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat) + + +### Single + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat) + + ### Span * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) @@ -177,3 +224,18 @@ * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) +### UInt16 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat) + + +### UInt32 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat) + + +### UInt64 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat) + + diff --git a/readme.md b/readme.md index bff7c108..1aa197c9 100644 --- a/readme.md +++ b/readme.md @@ -347,11 +347,22 @@ Reference: [Improvements in native code interop in .NET 5.0](https://devblogs.mi The class `PolyfillExtensions` includes the following extension methods: -### DateTime +### Boolean + + * `Boolean TryFormat(Span, Int32&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat) + + +### Byte + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) + + +### DateTime * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryformat) ### DateTimeOffset @@ -359,6 +370,17 @@ The class `PolyfillExtensions` includes the following extension methods: * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tryformat) + + +### Decimal + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) + + +### Double + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) ### Reflection.EventInfo @@ -397,6 +419,21 @@ The class `PolyfillExtensions` includes the following extension methods: * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) +### Int16 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) + + +### Int32 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat) + + +### Int64 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat) + + ### IReadOnlyDictionary * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) @@ -454,6 +491,16 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) +### SByte + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat) + + +### Single + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat) + + ### Span * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) @@ -525,6 +572,21 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) + +### UInt16 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat) + + +### UInt32 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat) + + +### UInt64 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat) + diff --git a/src/Polyfill/PolyfillExtensions_TryFormat.cs b/src/Polyfill/PolyfillExtensions_TryFormat.cs new file mode 100644 index 00000000..5a1d9e88 --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_TryFormat.cs @@ -0,0 +1,347 @@ + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable UnusedMember.Global +// ReSharper disable RedundantAttributeSuffix + +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; + +static partial class PolyfillExtensions +{ + #if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X) + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat")] + public static bool TryFormat(this sbyte target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat")] + public static bool TryFormat(this byte target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat")] + public static bool TryFormat(this short target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat")] + public static bool TryFormat(this ushort target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat")] + public static bool TryFormat(this int target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat")] + public static bool TryFormat(this uint target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat")] + public static bool TryFormat(this long target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat")] + public static bool TryFormat(this ulong target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat")] + public static bool TryFormat(this float target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat")] + public static bool TryFormat(this double target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat")] + public static bool TryFormat(this decimal target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat")] + public static bool TryFormat(this bool target, Span destination, out int charsWritten) + { + var result = target.ToString(); + return CopyToSpan(destination, out charsWritten, result); + } +#endif + +#if (MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X)) || NET6_0 + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tryformat")] + public static bool TryFormat(this DateTimeOffset target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryformat")] + public static bool TryFormat(this DateTime target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + +#endif +#if NET6_0_OR_GREATER + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.dateonly.tryformat")] + public static bool TryFormat(this DateOnly target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + + /// + /// Tries to format the value of the current instance into the provided span of characters. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timeonly.tryformat")] + public static bool TryFormat(this TimeOnly target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(provider); + } + else + { + result = target.ToString(format.ToString(), provider); + } + + return CopyToSpan(destination, out charsWritten, result); + } +#endif + +#if NET6_0_OR_GREATER || (MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X)) + static bool CopyToSpan(Span destination, out int charsWritten, string result) + { + if (result.Length == 0) + { + charsWritten = 0; + return true; + } + + charsWritten = result.Length; + return result.TryCopyTo(destination); + } +#endif +} \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_TryFormat.cs b/src/Tests/PolyfillExtensionsTests_TryFormat.cs new file mode 100644 index 00000000..27b8d772 --- /dev/null +++ b/src/Tests/PolyfillExtensionsTests_TryFormat.cs @@ -0,0 +1,181 @@ +using System.Globalization; + +partial class PolyfillExtensionsTests +{ + [Test] + public void TryFormatSByte() + { + sbyte value = 9; + Span buffer = stackalloc char[1]; + var result = value.TryFormat(buffer, out var written, provider: CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("9", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + + [Test] + public void TryFormatByte() + { + byte value = 9; + Span buffer = stackalloc char[1]; + var result = value.TryFormat(buffer, out var written, provider: CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("9", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + + [Test] + public void TryFormatInt16() + { + short value = 9; + Span buffer = stackalloc char[1]; + var result = value.TryFormat(buffer, out var written, provider: CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("9", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + + [Test] + public void TryFormatUInt16() + { + ushort value = 9; + Span buffer = stackalloc char[1]; + var result = value.TryFormat(buffer, out var written, provider: CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("9", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + + [Test] + public void TryFormatInt32() + { + int value = 9; + Span buffer = stackalloc char[1]; + var result = value.TryFormat(buffer, out var written, provider: CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("9", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + + [Test] + public void TryFormatUInt32() + { + uint value = 9; + Span buffer = stackalloc char[1]; + var result = value.TryFormat(buffer, out var written, provider: CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("9", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + + [Test] + public void TryFormatInt64() + { + long value = 9; + Span buffer = stackalloc char[1]; + var result = value.TryFormat(buffer, out var written, provider: CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("9", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + + [Test] + public void TryFormatUInt64() + { + ulong value = 9; + Span buffer = stackalloc char[1]; + var result = value.TryFormat(buffer, out var written, provider: CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("9", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + + [Test] + public void TryFormatSingle() + { + float value = 9; + Span buffer = stackalloc char[1]; + var result = value.TryFormat(buffer, out var written, provider: CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("9", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + + [Test] + public void TryFormatDouble() + { + double value = 9; + Span buffer = stackalloc char[1]; + var result = value.TryFormat(buffer, out var written, provider: CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("9", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + + [Test] + public void TryFormatDecimal() + { + decimal value = 9; + Span buffer = stackalloc char[1]; + var result = value.TryFormat(buffer, out var written, provider: CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("9", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + + [Test] + public void TryFormatDateTimeOffset() + { + var value = new DateTimeOffset(new DateTime(2001, 10, 1), TimeSpan.Zero); + Span buffer = stackalloc char[29]; + var result = value.TryFormat(buffer, out var written, format: "R".AsSpan(), CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("Mon, 01 Oct 2001 00:00:00 GMT", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + + [Test] + public void TryFormatDateTime() + { + var value = new DateTime(2001, 10, 1); + Span buffer = stackalloc char[29]; + var result = value.TryFormat(buffer, out var written, format: "R".AsSpan(), CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("Mon, 01 Oct 2001 00:00:00 GMT", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + + [Test] + public void TryFormatBoolean() + { + var value = true; + Span buffer = stackalloc char[4]; + var result = value.TryFormat(buffer, out var written); + Assert.True(result); + Assert.AreEqual("True", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + +#if NET6_0_OR_GREATER + [Test] + public void TryFormatDate() + { + var value = new DateOnly(2001,10,1); + Span buffer = stackalloc char[16]; + var result = value.TryFormat(buffer, out var written, format: "R", CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("Mon, 01 Oct 2001", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + [Test] + public void TryFormatTime() + { + var value = new TimeOnly(10,1); + Span buffer = stackalloc char[8]; + var result = value.TryFormat(buffer, out var written, format: "R", CultureInfo.InvariantCulture); + Assert.True(result); + Assert.AreEqual("10:01:00", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } +#endif +} \ No newline at end of file From 0545fd9c4e1748a255abca05263b5df39693e4ab Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 30 Apr 2023 18:17:41 +1000 Subject: [PATCH 099/313] 1.20.0 --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index a19e6000..2d58d8f1 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.19.0 + 1.20.0 1.0.0 Polyfill true From 2b2e7d8348b4ad0216505b3f3f7606cd633367a8 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 1 May 2023 21:36:02 +1000 Subject: [PATCH 100/313] Add TextWriter Write Span (#46) --- api_list.include.md | 2 + contributing.md | 47 ++++++++++++++++++- src/Polyfill/PolyfillExtensions_TextWriter.cs | 45 ++++++++++++++++++ .../PolyfillExtensionsTests_TextWriter.cs | 31 ++++++++++-- 4 files changed, 120 insertions(+), 5 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index d6c07d83..a03f9d00 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -208,8 +208,10 @@ ### TextWriter * `Void Write(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) + * `Void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) * `Void WriteLine(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) + * `Void WriteLine(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/contributing.md b/contributing.md index 96952f26..d1f9dc43 100644 --- a/contributing.md +++ b/contributing.md @@ -197,6 +197,7 @@ Example: // ReSharper disable UnusedMember.Global using System; +using System.Buffers; using System.IO; using System.Runtime.InteropServices; using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; @@ -291,10 +292,54 @@ static partial class PolyfillExtensions target.WriteLine(segment.Array!, segment.Offset, segment.Count); } + + /// + /// Wwrites a character memory region to the stream. + /// + /// The character memory region to write to the stream. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] + public static void Write( + this TextWriter target, + ReadOnlySpan buffer) + { + var array = ArrayPool.Shared.Rent(buffer.Length); + + try + { + buffer.CopyTo(new(array)); + target.Write(array, 0, buffer.Length); + } + finally + { + ArrayPool.Shared.Return(array); + } + } + + /// + /// Writes the text representation of a character memory region to the stream, followed by a line terminator. + /// + /// The character memory region to write to the stream. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] + public static void WriteLine( + this TextWriter target, + ReadOnlySpan buffer) + { + var array = ArrayPool.Shared.Rent(buffer.Length); + + try + { + buffer.CopyTo(new(array)); + target.WriteLine(array, 0, buffer.Length); + } + finally + { + ArrayPool.Shared.Return(array); + } + } } #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Polyfill/PolyfillExtensions_TextWriter.cs b/src/Polyfill/PolyfillExtensions_TextWriter.cs index c9a61a6c..78bbd1ab 100644 --- a/src/Polyfill/PolyfillExtensions_TextWriter.cs +++ b/src/Polyfill/PolyfillExtensions_TextWriter.cs @@ -6,6 +6,7 @@ // ReSharper disable UnusedMember.Global using System; +using System.Buffers; using System.IO; using System.Runtime.InteropServices; using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; @@ -100,5 +101,49 @@ public static void WriteLine( target.WriteLine(segment.Array!, segment.Offset, segment.Count); } + + /// + /// Wwrites a character memory region to the stream. + /// + /// The character memory region to write to the stream. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] + public static void Write( + this TextWriter target, + ReadOnlySpan buffer) + { + var array = ArrayPool.Shared.Rent(buffer.Length); + + try + { + buffer.CopyTo(new(array)); + target.Write(array, 0, buffer.Length); + } + finally + { + ArrayPool.Shared.Return(array); + } + } + + /// + /// Writes the text representation of a character memory region to the stream, followed by a line terminator. + /// + /// The character memory region to write to the stream. + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] + public static void WriteLine( + this TextWriter target, + ReadOnlySpan buffer) + { + var array = ArrayPool.Shared.Rent(buffer.Length); + + try + { + buffer.CopyTo(new(array)); + target.WriteLine(array, 0, buffer.Length); + } + finally + { + ArrayPool.Shared.Return(array); + } + } } #endif \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_TextWriter.cs b/src/Tests/PolyfillExtensionsTests_TextWriter.cs index 755ac7c5..9a5e2f60 100644 --- a/src/Tests/PolyfillExtensionsTests_TextWriter.cs +++ b/src/Tests/PolyfillExtensionsTests_TextWriter.cs @@ -1,7 +1,29 @@ partial class PolyfillExtensionsTests { [Test] - public async Task TextWriterWriteAsync() + public async Task TextWriterWriteSpan() + { + using var stream = new MemoryStream(); + using var writer = new StreamWriter(stream); + writer.Write("value".AsSpan()); + await writer.FlushAsync(); + var s = Encoding.UTF8.GetString(stream.ToArray()); + Assert.AreEqual("value", s); + } + + [Test] + public async Task TextWriterWriteLineSpan() + { + using var stream = new MemoryStream(); + using var writer = new StreamWriter(stream); + writer.WriteLine("value".AsSpan()); + await writer.FlushAsync(); + var s = Encoding.UTF8.GetString(stream.ToArray()); + Assert.AreEqual("value" + Environment.NewLine, s); + } + + [Test] + public async Task TextWriterWriteMemoryAsync() { using var stream = new MemoryStream(); var memory = new Memory("value".ToArray()); @@ -13,7 +35,7 @@ public async Task TextWriterWriteAsync() } [Test] - public async Task TextWriterWriteLineAsync() + public async Task TextWriterWriteLineMemoryAsync() { using var stream = new MemoryStream(); var memory = new Memory("value".ToArray()); @@ -23,8 +45,9 @@ public async Task TextWriterWriteLineAsync() var s = Encoding.UTF8.GetString(stream.ToArray()); Assert.AreEqual("value" + Environment.NewLine, s); } + [Test] - public async Task TextWriterWrite() + public async Task TextWriterWriteMemory() { using var stream = new MemoryStream(); var memory = new Memory("value".ToArray()); @@ -36,7 +59,7 @@ public async Task TextWriterWrite() } [Test] - public async Task TextWriterWriteLine() + public async Task TextWriterWriteLineMemory() { using var stream = new MemoryStream(); var memory = new Memory("value".ToArray()); From 510c8a840d335346c0d65a53091f9fba16108d16 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 1 May 2023 21:42:34 +1000 Subject: [PATCH 101/313] Update PolyfillExtensions_TextWriter.cs --- src/Polyfill/PolyfillExtensions_TextWriter.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_TextWriter.cs b/src/Polyfill/PolyfillExtensions_TextWriter.cs index 78bbd1ab..54afbf51 100644 --- a/src/Polyfill/PolyfillExtensions_TextWriter.cs +++ b/src/Polyfill/PolyfillExtensions_TextWriter.cs @@ -43,7 +43,7 @@ public static ValueTask WriteAsync( } /// - /// Wwrites a character memory region to the stream. + /// Writes a character memory region to the stream. /// /// The character memory region to write to the stream. [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] @@ -103,9 +103,9 @@ public static void WriteLine( } /// - /// Wwrites a character memory region to the stream. + /// Writes a character span to the text stream. /// - /// The character memory region to write to the stream. + /// The character span to write. [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] public static void Write( this TextWriter target, @@ -125,9 +125,9 @@ public static void Write( } /// - /// Writes the text representation of a character memory region to the stream, followed by a line terminator. + /// Writes the text representation of a character span to the text stream, followed by a line terminator. /// - /// The character memory region to write to the stream. + /// The char span value to write to the text stream. [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] public static void WriteLine( this TextWriter target, From 55374fa910049f8117045c2ac509a7f8fcf4f026 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 1 May 2023 22:12:15 +1000 Subject: [PATCH 102/313] remove redundant ReadOnlyMemory overloads for TextWriter Write and WriteLine (#47) --- api_list.include.md | 2 - contributing.md | 44 +++---------------- readme.md | 4 +- src/Polyfill/PolyfillExtensions_TextWriter.cs | 34 -------------- 4 files changed, 7 insertions(+), 77 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index a03f9d00..5ca1d5d3 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -207,10 +207,8 @@ ### TextWriter - * `Void Write(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) * `Void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Void WriteLine(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) * `Void WriteLine(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/contributing.md b/contributing.md index d1f9dc43..56eac37e 100644 --- a/contributing.md +++ b/contributing.md @@ -233,23 +233,6 @@ static partial class PolyfillExtensions return new(target.WriteAsync(segment.Array!, segment.Offset, segment.Count)); } - /// - /// Wwrites a character memory region to the stream. - /// - /// The character memory region to write to the stream. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] - public static void Write( - this TextWriter target, - ReadOnlyMemory buffer) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - - target.Write(segment.Array!, segment.Offset, segment.Count); - } - /// /// Asynchronously writes the text representation of a character memory region to the stream, followed by a line terminator. /// @@ -277,26 +260,9 @@ static partial class PolyfillExtensions } /// - /// Writes the text representation of a character memory region to the stream, followed by a line terminator. - /// - /// The character memory region to write to the stream. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] - public static void WriteLine( - this TextWriter target, - ReadOnlyMemory buffer) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - - target.WriteLine(segment.Array!, segment.Offset, segment.Count); - } - - /// - /// Wwrites a character memory region to the stream. + /// Writes a character span to the text stream. /// - /// The character memory region to write to the stream. + /// The character span to write. [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] public static void Write( this TextWriter target, @@ -316,9 +282,9 @@ static partial class PolyfillExtensions } /// - /// Writes the text representation of a character memory region to the stream, followed by a line terminator. + /// Writes the text representation of a character span to the text stream, followed by a line terminator. /// - /// The character memory region to write to the stream. + /// The char span value to write to the text stream. [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] public static void WriteLine( this TextWriter target, @@ -339,7 +305,7 @@ static partial class PolyfillExtensions } #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/readme.md b/readme.md index 1aa197c9..743cbf5a 100644 --- a/readme.md +++ b/readme.md @@ -556,9 +556,9 @@ The class `PolyfillExtensions` includes the following extension methods: ### TextWriter - * `Void Write(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) + * `Void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Void WriteLine(ReadOnlyMemory)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) + * `Void WriteLine(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) diff --git a/src/Polyfill/PolyfillExtensions_TextWriter.cs b/src/Polyfill/PolyfillExtensions_TextWriter.cs index 54afbf51..f393cf7a 100644 --- a/src/Polyfill/PolyfillExtensions_TextWriter.cs +++ b/src/Polyfill/PolyfillExtensions_TextWriter.cs @@ -42,23 +42,6 @@ public static ValueTask WriteAsync( return new(target.WriteAsync(segment.Array!, segment.Offset, segment.Count)); } - /// - /// Writes a character memory region to the stream. - /// - /// The character memory region to write to the stream. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] - public static void Write( - this TextWriter target, - ReadOnlyMemory buffer) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - - target.Write(segment.Array!, segment.Offset, segment.Count); - } - /// /// Asynchronously writes the text representation of a character memory region to the stream, followed by a line terminator. /// @@ -85,23 +68,6 @@ public static ValueTask WriteLineAsync( return new(target.WriteLineAsync(segment.Array!, segment.Offset, segment.Count)); } - /// - /// Writes the text representation of a character memory region to the stream, followed by a line terminator. - /// - /// The character memory region to write to the stream. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] - public static void WriteLine( - this TextWriter target, - ReadOnlyMemory buffer) - { - if (!MemoryMarshal.TryGetArray(buffer, out var segment)) - { - segment = new(buffer.ToArray()); - } - - target.WriteLine(segment.Array!, segment.Offset, segment.Count); - } - /// /// Writes a character span to the text stream. /// From f7c32f8fc8d736a033b269abeed3ad6353ff11cc Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 1 May 2023 22:13:01 +1000 Subject: [PATCH 103/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 2d58d8f1..cdacca88 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.20.0 + 1.21.0 1.0.0 Polyfill true From bffd5c38c98bab95df6f54b0b502a270e4e14e28 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 2 May 2023 15:28:28 +1000 Subject: [PATCH 104/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index bf9b4e2d..b1ff77e6 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 27ba6d23..d9e6e1f5 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 4cefd70c..e597d158 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 5671a036..0bf80ccb 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From bd38ef00b05caff21ed2bb43968ccfb59c17b75d Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 4 May 2023 20:47:39 +1000 Subject: [PATCH 105/313] Add Task.WaitAsync (#48) --- api_list.include.md | 22 +++++ contributing.md | 12 +-- src/Consume/Consume.cs | 12 +++ src/Directory.Build.props | 2 +- src/Polyfill/PolyfillExtensions_Task.cs | 83 +++++++++++++++++++ src/Polyfill/PolyfillExtensions_TextWriter.cs | 10 ++- 6 files changed, 131 insertions(+), 10 deletions(-) create mode 100644 src/Polyfill/PolyfillExtensions_Task.cs diff --git a/api_list.include.md b/api_list.include.md index 5ca1d5d3..fe72a3ec 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -199,6 +199,28 @@ * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) +### Task + + * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) + * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)) + * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)) + + +### Task + + * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) + + +### Task + + * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)) + + +### Task + + * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)) + + ### TextReader * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) diff --git a/contributing.md b/contributing.md index 56eac37e..a4c4a7e1 100644 --- a/contributing.md +++ b/contributing.md @@ -268,7 +268,8 @@ static partial class PolyfillExtensions this TextWriter target, ReadOnlySpan buffer) { - var array = ArrayPool.Shared.Rent(buffer.Length); + var pool = ArrayPool.Shared; + var array = pool.Rent(buffer.Length); try { @@ -277,7 +278,7 @@ static partial class PolyfillExtensions } finally { - ArrayPool.Shared.Return(array); + pool.Return(array); } } @@ -290,7 +291,8 @@ static partial class PolyfillExtensions this TextWriter target, ReadOnlySpan buffer) { - var array = ArrayPool.Shared.Rent(buffer.Length); + var pool = ArrayPool.Shared; + var array = pool.Rent(buffer.Length); try { @@ -299,13 +301,13 @@ static partial class PolyfillExtensions } finally { - ArrayPool.Shared.Return(array); + pool.Return(array); } } } #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 3cb936cb..62b818c1 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -134,6 +134,18 @@ async Task StreamReaderReadToEndAsync() var read = await reader.ReadToEndAsync(CancellationToken.None); } + void WaitAsync() + { + var action = () => {}; + var func = () => 0; + new Task(action).WaitAsync(CancellationToken.None); + new Task(action).WaitAsync(TimeSpan.Zero); + new Task(action).WaitAsync(TimeSpan.Zero, CancellationToken.None); + new Task(func).WaitAsync(CancellationToken.None); + new Task(func).WaitAsync(TimeSpan.Zero); + new Task(func).WaitAsync(TimeSpan.Zero, CancellationToken.None); + } + #if MEMORYREFERENCED async Task StreamReaderReadAsync() diff --git a/src/Directory.Build.props b/src/Directory.Build.props index cdacca88..ea9e3fe7 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.21.0 + 1.22.0 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/PolyfillExtensions_Task.cs new file mode 100644 index 00000000..507fd037 --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_Task.cs @@ -0,0 +1,83 @@ +#if NETFRAMEWORK || NETSTANDARD || NETCOREAPP || NET5_0 + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable UnusedMember.Global +// ReSharper disable RedundantAttributeSuffix + +using System; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; + +static partial class PolyfillExtensions +{ + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] + public static Task WaitAsync(this Task task, CancellationToken cancellationToken) => + task.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken); + + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)")] + public static async Task WaitAsync(this Task task, TimeSpan timeout) + { + var cancellationSource = new CancellationTokenSource(); + try + { + await task.WaitAsync(timeout, cancellationSource.Token); + } + finally + { + cancellationSource.Cancel(); + cancellationSource.Dispose(); + } + } + + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)")] + public static async Task WaitAsync(this Task task, TimeSpan timeout, CancellationToken cancellationToken) + { + var delayTask = Task.Delay(timeout, cancellationToken); + var completedTask = await Task.WhenAny(task, delayTask); + if (completedTask == delayTask) + { + throw new TimeoutException($"Execution did not complete within the time allotted {timeout.TotalMilliseconds} ms"); + } + + await task; + } + + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] + public static Task WaitAsync(this Task task, CancellationToken cancellationToken) => + task.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken); + + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)")] + public static async Task WaitAsync(this Task task, TimeSpan timeout) + { + var cancellationSource = new CancellationTokenSource(); + try + { + return await task.WaitAsync(timeout, cancellationSource.Token); + } + finally + { + cancellationSource.Cancel(); + cancellationSource.Dispose(); + } + } + + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)")] + public static async Task WaitAsync(this Task task, TimeSpan timeout, CancellationToken cancellationToken) + { + var delayTask = Task.Delay(timeout, cancellationToken); + var completedTask = await Task.WhenAny(task, delayTask); + if (completedTask == delayTask) + { + throw new TimeoutException($"Execution did not complete within the time allotted {timeout.TotalMilliseconds} ms"); + } + + return await task; + } +} + +#endif \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_TextWriter.cs b/src/Polyfill/PolyfillExtensions_TextWriter.cs index f393cf7a..2f2fbbf5 100644 --- a/src/Polyfill/PolyfillExtensions_TextWriter.cs +++ b/src/Polyfill/PolyfillExtensions_TextWriter.cs @@ -77,7 +77,8 @@ public static void Write( this TextWriter target, ReadOnlySpan buffer) { - var array = ArrayPool.Shared.Rent(buffer.Length); + var pool = ArrayPool.Shared; + var array = pool.Rent(buffer.Length); try { @@ -86,7 +87,7 @@ public static void Write( } finally { - ArrayPool.Shared.Return(array); + pool.Return(array); } } @@ -99,7 +100,8 @@ public static void WriteLine( this TextWriter target, ReadOnlySpan buffer) { - var array = ArrayPool.Shared.Rent(buffer.Length); + var pool = ArrayPool.Shared; + var array = pool.Rent(buffer.Length); try { @@ -108,7 +110,7 @@ public static void WriteLine( } finally { - ArrayPool.Shared.Return(array); + pool.Return(array); } } } From f16fe40afeb04dcdf4e053a43483eea5dd0aa591 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 5 May 2023 17:34:05 +1000 Subject: [PATCH 106/313] docs --- api_list.include.md | 2 +- readme.md | 22 +++++++++++++++++++ .../PolyfillExtensions_MicroNanosecond.cs | 2 +- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index fe72a3ec..2e108274 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -237,7 +237,7 @@ ### TimeSpan - * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond) + * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds) * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) diff --git a/readme.md b/readme.md index 743cbf5a..bc1fac66 100644 --- a/readme.md +++ b/readme.md @@ -548,6 +548,28 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) +### Task + + * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) + * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)) + * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)) + + +### Task + + * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) + + +### Task + + * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)) + + +### Task + + * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)) + + ### TextReader * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) diff --git a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs index 62f46d07..4c608279 100644 --- a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs +++ b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs @@ -49,7 +49,7 @@ public static int Nanosecond(this DateTimeOffset target) => /// /// Gets the microsecond component of the time represented by the current object. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond")] + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds")] public static int Microseconds(this TimeSpan target) => #if NET7_0_OR_GREATER target.Microseconds; From d48717858602198c51e94b86cee5e2fd85cf44b9 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 5 May 2023 17:43:57 +1000 Subject: [PATCH 107/313] Update PolyfillExtensions_Task.cs --- src/Polyfill/PolyfillExtensions_Task.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/PolyfillExtensions_Task.cs index 507fd037..ac47e7f7 100644 --- a/src/Polyfill/PolyfillExtensions_Task.cs +++ b/src/Polyfill/PolyfillExtensions_Task.cs @@ -16,16 +16,16 @@ static partial class PolyfillExtensions { [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] - public static Task WaitAsync(this Task task, CancellationToken cancellationToken) => - task.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken); + public static Task WaitAsync(this Task target, CancellationToken cancellationToken) => + target.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken); [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)")] - public static async Task WaitAsync(this Task task, TimeSpan timeout) + public static async Task WaitAsync(this Task target, TimeSpan timeout) { var cancellationSource = new CancellationTokenSource(); try { - await task.WaitAsync(timeout, cancellationSource.Token); + await target.WaitAsync(timeout, cancellationSource.Token); } finally { From 2fa7c4475c9e1cf239e6e95c3dbc0343a14ac162 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 5 May 2023 17:44:51 +1000 Subject: [PATCH 108/313] add CancelAsync (#49) --- src/Consume/Consume.cs | 6 +++++ ...yfillExtensions_CancellationTokenSource.cs | 27 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 62b818c1..c9a6be25 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -128,6 +128,12 @@ void KeyValuePairDeconstruct(IEnumerable> variables #endif + async Task CancellationTokenSource() + { + var source = new CancellationTokenSource(); + await source.CancelAsync(); + } + async Task StreamReaderReadToEndAsync() { var reader = new StreamReader(new MemoryStream()); diff --git a/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs b/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs new file mode 100644 index 00000000..34540644 --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs @@ -0,0 +1,27 @@ + +#pragma warning disable + +// ReSharper disable RedundantUsingDirective +// ReSharper disable PartialTypeWithSinglePart +// ReSharper disable UnusedMember.Global +// ReSharper disable RedundantAttributeSuffix + +using System; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; + +static partial class PolyfillExtensions +{ +#if !NET8_0_OR_GREATER + + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync")] + public static Task CancelAsync(this CancellationTokenSource target) + { + target.Cancel(); + return Task.CompletedTask; + } + +#endif +} From ac9c96bb007818224072d7ec5bc7b497a2968301 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 5 May 2023 17:45:49 +1000 Subject: [PATCH 109/313] cleanup --- src/Polyfill/PolyfillExtensions_HttpClient.cs | 14 ++++---- .../PolyfillExtensions_HttpContent.cs | 8 ++--- .../PolyfillExtensions_IEnumerable.cs | 6 ++-- .../PolyfillExtensions_IReadOnlyDictionary.cs | 6 ++-- .../PolyfillExtensions_KeyValuePair.cs | 4 +-- src/Polyfill/PolyfillExtensions_Memory.cs | 18 +++++----- .../PolyfillExtensions_MicroNanosecond.cs | 18 +++++----- src/Polyfill/PolyfillExtensions_Stream.cs | 8 ++--- src/Polyfill/PolyfillExtensions_String.cs | 20 +++++------ .../PolyfillExtensions_StringBuilder.cs | 8 ++--- src/Polyfill/PolyfillExtensions_Task.cs | 14 ++++---- src/Polyfill/PolyfillExtensions_TextReader.cs | 6 ++-- src/Polyfill/PolyfillExtensions_TextWriter.cs | 10 +++--- src/Polyfill/PolyfillExtensions_TryFormat.cs | 34 +++++++++---------- src/Polyfill/PolyfillExtensions_Type.cs | 8 ++--- 15 files changed, 91 insertions(+), 91 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_HttpClient.cs b/src/Polyfill/PolyfillExtensions_HttpClient.cs index 922b412c..a539e8f0 100644 --- a/src/Polyfill/PolyfillExtensions_HttpClient.cs +++ b/src/Polyfill/PolyfillExtensions_HttpClient.cs @@ -11,7 +11,7 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { @@ -25,7 +25,7 @@ static partial class PolyfillExtensions /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)")] public static async Task GetStreamAsync( this HttpClient httpClient, string requestUri, @@ -63,7 +63,7 @@ public static async Task GetStreamAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)")] public static Task GetStreamAsync( this HttpClient httpClient, Uri requestUri, @@ -80,7 +80,7 @@ public static Task GetStreamAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)")] public static async Task GetByteArrayAsync( this HttpClient httpClient, string requestUri, @@ -117,7 +117,7 @@ public static async Task GetByteArrayAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)")] public static Task GetByteArrayAsync( this HttpClient httpClient, Uri requestUri, @@ -134,7 +134,7 @@ public static Task GetByteArrayAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)")] public static async Task GetStringAsync( this HttpClient httpClient, string requestUri, @@ -171,7 +171,7 @@ public static async Task GetStringAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)")] public static Task GetStringAsync( this HttpClient httpClient, Uri requestUri, diff --git a/src/Polyfill/PolyfillExtensions_HttpContent.cs b/src/Polyfill/PolyfillExtensions_HttpContent.cs index 188d05d3..3e8d7c59 100644 --- a/src/Polyfill/PolyfillExtensions_HttpContent.cs +++ b/src/Polyfill/PolyfillExtensions_HttpContent.cs @@ -10,7 +10,7 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { @@ -25,7 +25,7 @@ static partial class PolyfillExtensions /// The token to monitor for cancellation requests. The default value is . /// /// The task object representing the asynchronous operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)")] public static Task ReadAsStreamAsync( this HttpContent httpContent, CancellationToken cancellationToken = default) @@ -45,7 +45,7 @@ public static Task ReadAsStreamAsync( /// The token to monitor for cancellation requests. The default value is . /// /// The task object representing the asynchronous operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)")] public static Task ReadAsByteArrayAsync( this HttpContent httpContent, CancellationToken cancellationToken = default) @@ -65,7 +65,7 @@ public static Task ReadAsByteArrayAsync( /// The token to monitor for cancellation requests. The default value is . /// /// The task object representing the asynchronous operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)")] public static Task ReadAsStringAsync( this HttpContent httpContent, CancellationToken cancellationToken = default) diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index 112d77e7..bb76deca 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -7,7 +7,7 @@ using System; using System.Collections.Generic; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; using System.Linq; // ReSharper disable RedundantAttributeSuffix @@ -22,7 +22,7 @@ static partial class PolyfillExtensions /// The value to append to source. /// The type of the elements of source. /// A new sequence that ends with element. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.append")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.append")] public static IEnumerable Append( this IEnumerable source, TSource element) @@ -46,7 +46,7 @@ public static IEnumerable Append( /// The type of the elements in the enumerable collection. /// A new enumerable collection that contains the elements from source minus count elements from the end /// of the collection. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast")] public static IEnumerable SkipLast(this IEnumerable source, int count) => source.Reverse().Skip(count).Reverse(); #endif diff --git a/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs b/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs index 59a25038..cbb78d9e 100644 --- a/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs +++ b/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs @@ -8,7 +8,7 @@ using System; using System.Collections.Generic; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; // ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions @@ -24,7 +24,7 @@ static partial class PolyfillExtensions /// A TValue instance. When the method is successful, the returned object is the value associated with /// the specified key. When the method fails, it returns the default value for TValue. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault")] public static TValue? GetValueOrDefault( this IReadOnlyDictionary target, TKey key) @@ -49,7 +49,7 @@ static partial class PolyfillExtensions /// A TValue instance. When the method is successful, the returned object is the value associated with /// the specified key. When the method fails, it returns the default value for TValue. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)")] public static TValue GetValueOrDefault( this IReadOnlyDictionary target, TKey key, diff --git a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs index 39a30b07..93b9b717 100644 --- a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs +++ b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs @@ -9,7 +9,7 @@ using System; using System.Collections.Generic; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { @@ -18,7 +18,7 @@ static partial class PolyfillExtensions /// /// The key of the current . /// The value of the current . - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct")] public static void Deconstruct( this KeyValuePair target, out TKey key, diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index 604caede..7654cffc 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -10,7 +10,7 @@ using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { @@ -19,7 +19,7 @@ static partial class PolyfillExtensions /// /// The value to search for. /// true if found, false otherwise. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)")] public static bool Contains(this ReadOnlySpan target, T value) where T : IEquatable { @@ -39,7 +39,7 @@ public static bool Contains(this ReadOnlySpan target, T value) /// /// The value to search for. /// true if found, false otherwise. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)")] public static bool Contains(this Span target, T value) where T : IEquatable { @@ -54,27 +54,27 @@ public static bool Contains(this Span target, T value) return false; } - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] public static bool SequenceEqual(this ReadOnlySpan target, string other) => target.SequenceEqual(other.AsSpan()); - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))")] public static bool SequenceEqual(this Span target, string other) => target.SequenceEqual(other.AsSpan()); - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] public static bool StartsWith(this ReadOnlySpan target, string other, StringComparison comparison = StringComparison.CurrentCulture) => target.StartsWith(other.AsSpan(), comparison); - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))")] public static bool StartsWith(this Span target, string other) => target.StartsWith(other.AsSpan()); - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] public static bool EndsWith(this ReadOnlySpan target, string other, StringComparison comparison = StringComparison.CurrentCulture) => target.EndsWith(other.AsSpan(), comparison); - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))")] public static bool EndsWith(this Span target, string other) => target.EndsWith(other.AsSpan()); } diff --git a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs index 4c608279..84e2cbf1 100644 --- a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs +++ b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs @@ -6,7 +6,7 @@ // ReSharper disable UnusedMember.Global using System; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; // ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions @@ -16,7 +16,7 @@ static partial class PolyfillExtensions /// /// Gets the nanosecond component of the time represented by the current object. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds")] public static int Nanoseconds(this TimeSpan target) => #if NET7_0_OR_GREATER target.Nanoseconds; @@ -27,7 +27,7 @@ public static int Nanoseconds(this TimeSpan target) => /// /// Gets the nanosecond component of the time represented by the current object. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond")] public static int Nanosecond(this DateTime target) => #if NET7_0_OR_GREATER target.Nanosecond; @@ -38,7 +38,7 @@ public static int Nanosecond(this DateTime target) => /// /// Gets the nanosecond component of the time represented by the current object. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond")] public static int Nanosecond(this DateTimeOffset target) => #if NET7_0_OR_GREATER target.Nanosecond; @@ -49,7 +49,7 @@ public static int Nanosecond(this DateTimeOffset target) => /// /// Gets the microsecond component of the time represented by the current object. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds")] public static int Microseconds(this TimeSpan target) => #if NET7_0_OR_GREATER target.Microseconds; @@ -60,7 +60,7 @@ public static int Microseconds(this TimeSpan target) => /// /// Gets the microsecond component of the time represented by the current object. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond")] public static int Microsecond(this DateTime target) => #if NET7_0_OR_GREATER target.Microsecond; @@ -71,7 +71,7 @@ public static int Microsecond(this DateTime target) => /// /// Gets the microsecond component of the time represented by the current object. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond")] public static int Microsecond(this DateTimeOffset target) => #if NET7_0_OR_GREATER target.Microsecond; @@ -82,7 +82,7 @@ public static int Microsecond(this DateTimeOffset target) => /// /// Returns a new object that adds a specified number of microseconds to the value of this instance.. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds")] public static DateTime AddMicroseconds(this DateTime target, double microseconds) => #if NET7_0_OR_GREATER target.AddMicroseconds(microseconds); @@ -93,7 +93,7 @@ public static DateTime AddMicroseconds(this DateTime target, double microseconds /// /// Returns a new object that adds a specified number of microseconds to the value of this instance.. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds")] public static DateTimeOffset AddMicroseconds(this DateTimeOffset target, double microseconds) => #if NET7_0_OR_GREATER target.AddMicroseconds(microseconds); diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index 7ac2e7ea..dd8b3fff 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; // ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions @@ -29,7 +29,7 @@ static partial class PolyfillExtensions /// the buffer if that many bytes are not currently available, or it can be 0 (zero) if the end of the stream has /// been reached. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)")] public static ValueTask ReadAsync( this Stream target, Memory buffer, @@ -52,7 +52,7 @@ public static ValueTask ReadAsync( /// The token to monitor for cancellation requests. The default value is . /// /// A task that represents the asynchronous write operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)")] public static ValueTask WriteAsync( this Stream target, ReadOnlyMemory buffer, @@ -75,7 +75,7 @@ public static ValueTask WriteAsync( /// The token to monitor for cancellation requests. The default value is . /// /// A task that represents the asynchronous copy operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)")] public static Task CopyToAsync( this Stream target, Stream destination, diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/PolyfillExtensions_String.cs index a03f6800..8dfe9ac5 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/PolyfillExtensions_String.cs @@ -5,7 +5,7 @@ // ReSharper disable PartialTypeWithSinglePart using System; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; using System.Text; // ReSharper disable RedundantAttributeSuffix @@ -17,7 +17,7 @@ static partial class PolyfillExtensions /// Copies the contents of this string into the destination span. /// /// The span into which to copy this string's contents - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.copyto")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.copyto")] public static void CopyTo(this string target, Span destination) => target.AsSpan().CopyTo(destination); @@ -26,7 +26,7 @@ public static void CopyTo(this string target, Span destination) => /// /// The span into which to copy this string's contents /// true if the data was copied; false if the destination was too short to fit the contents of the string. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto")] public static bool TryCopyTo(this string target, Span destination) => target.AsSpan().TryCopyTo(destination); #endif @@ -38,7 +38,7 @@ public static bool TryCopyTo(this string target, Span destination) => /// /// One of the enumeration values that specifies the rules to use in the comparison. /// A 32-bit signed integer hash code. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)")] public static int GetHashCode(this string target, StringComparison comparisonType) => FromComparison(comparisonType).GetHashCode(target); @@ -59,7 +59,7 @@ static StringComparer FromComparison(StringComparison comparison) => /// The string to seek. /// One of the enumeration values that specifies the rules to use in the comparison. /// true if the value parameter occurs within this string, or if value is the empty string (""); otherwise, false. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)")] public static bool Contains(this string target, string value, StringComparison comparisonType) => target.IndexOf(value, comparisonType) >= 0; @@ -69,7 +69,7 @@ public static bool Contains(this string target, string value, StringComparison c /// The character to compare. /// This method performs an ordinal (case-sensitive and culture-insensitive) comparison. /// true if value matches the beginning of this string; otherwise, false. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] public static bool StartsWith(this string target, char value) { if (target.Length == 0) @@ -86,7 +86,7 @@ public static bool StartsWith(this string target, char value) /// The character to seek. /// This method performs an ordinal (case-sensitive and culture-insensitive) comparison. /// true if the value parameter occurs within this string; otherwise, false. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] public static bool EndsWith(this string target, char value) { if (target.Length == 0) @@ -108,7 +108,7 @@ public static bool EndsWith(this string target, char value) /// A bitwise combination of the enumeration values that specifies whether to trim substrings /// and include empty substrings. /// An array that contains at most count substrings from this instance that are delimited by separator. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)")] public static string[] Split(this string target, char separator, StringSplitOptions options = StringSplitOptions.None) => target.Split(new[] {separator}, options); @@ -122,7 +122,7 @@ public static string[] Split(this string target, char separator, StringSplitOpti /// A bitwise combination of the enumeration values that specifies whether to trim substrings /// and include empty substrings. /// An array that contains at most count substrings from this instance that are delimited by separator. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)")] public static string[] Split(this string target, char separator, int count, StringSplitOptions options = StringSplitOptions.None) => target.Split(new[] {separator}, count, options); #endif @@ -134,7 +134,7 @@ public static string[] Split(this string target, char separator, int count, Stri /// This method performs an ordinal (case-sensitive and culture-insensitive) comparison. /// The character to seek. /// true if the value parameter occurs within this string; otherwise, false. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] public static bool Contains(this string target, char value) => target.IndexOf(value) >= 0; #endif diff --git a/src/Polyfill/PolyfillExtensions_StringBuilder.cs b/src/Polyfill/PolyfillExtensions_StringBuilder.cs index 9c686941..99c6ff10 100644 --- a/src/Polyfill/PolyfillExtensions_StringBuilder.cs +++ b/src/Polyfill/PolyfillExtensions_StringBuilder.cs @@ -9,7 +9,7 @@ using System.IO; using System.Runtime.InteropServices; using System.Text; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; // ReSharper disable RedundantAttributeSuffix @@ -22,7 +22,7 @@ static partial class PolyfillExtensions /// The starting position in this instance where characters will be copied from. The index is zero-based. /// The writable span where characters will be copied. /// The number of characters to be copied. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)")] public static void CopyTo( this StringBuilder target, int sourceIndex, @@ -53,7 +53,7 @@ public static void CopyTo( /// /// The read-only character span to append. /// A reference to this instance after the append operation is completed. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))")] public static StringBuilder Append(this StringBuilder target, ReadOnlySpan value) { if (value.Length <= 0) @@ -85,7 +85,7 @@ public static StringBuilder Append(this StringBuilder target, ReadOnlySpan /// and span are equal. /// /// true if the characters in this instance and span are the same; otherwise, false. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))")] public static bool Equals(this StringBuilder target, ReadOnlySpan span) { if (target.Length != span.Length) diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/PolyfillExtensions_Task.cs index ac47e7f7..2c73d34d 100644 --- a/src/Polyfill/PolyfillExtensions_Task.cs +++ b/src/Polyfill/PolyfillExtensions_Task.cs @@ -11,15 +11,15 @@ using System.Reflection; using System.Threading; using System.Threading.Tasks; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] public static Task WaitAsync(this Task target, CancellationToken cancellationToken) => target.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken); - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)")] public static async Task WaitAsync(this Task target, TimeSpan timeout) { var cancellationSource = new CancellationTokenSource(); @@ -34,7 +34,7 @@ public static async Task WaitAsync(this Task target, TimeSpan timeout) } } - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)")] public static async Task WaitAsync(this Task task, TimeSpan timeout, CancellationToken cancellationToken) { var delayTask = Task.Delay(timeout, cancellationToken); @@ -47,11 +47,11 @@ public static async Task WaitAsync(this Task task, TimeSpan timeout, Cancellatio await task; } - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] public static Task WaitAsync(this Task task, CancellationToken cancellationToken) => task.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken); - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)")] public static async Task WaitAsync(this Task task, TimeSpan timeout) { var cancellationSource = new CancellationTokenSource(); @@ -66,7 +66,7 @@ public static async Task WaitAsync(this Task task, Ti } } - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)")] public static async Task WaitAsync(this Task task, TimeSpan timeout, CancellationToken cancellationToken) { var delayTask = Task.Delay(timeout, cancellationToken); diff --git a/src/Polyfill/PolyfillExtensions_TextReader.cs b/src/Polyfill/PolyfillExtensions_TextReader.cs index d5ba369c..7a7d3c4d 100644 --- a/src/Polyfill/PolyfillExtensions_TextReader.cs +++ b/src/Polyfill/PolyfillExtensions_TextReader.cs @@ -6,7 +6,7 @@ using System; using System.IO; using System.Runtime.InteropServices; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; // ReSharper disable RedundantAttributeSuffix @@ -30,7 +30,7 @@ static partial class PolyfillExtensions /// The number will be less than or equal to the length, depending on whether the data is /// available within the stream. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)")] public static ValueTask ReadAsync( this TextReader target, Memory buffer, @@ -57,7 +57,7 @@ public static ValueTask ReadAsync( /// The number of characters is larger than . /// The stream reader has been disposed. /// The reader is currently in use by a previous read operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)")] public static Task ReadToEndAsync( this TextReader target, CancellationToken cancellationToken) diff --git a/src/Polyfill/PolyfillExtensions_TextWriter.cs b/src/Polyfill/PolyfillExtensions_TextWriter.cs index 2f2fbbf5..9cd08176 100644 --- a/src/Polyfill/PolyfillExtensions_TextWriter.cs +++ b/src/Polyfill/PolyfillExtensions_TextWriter.cs @@ -9,7 +9,7 @@ using System.Buffers; using System.IO; using System.Runtime.InteropServices; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; // ReSharper disable RedundantAttributeSuffix @@ -25,7 +25,7 @@ static partial class PolyfillExtensions /// The default value is . /// /// A task that represents the asynchronous write operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] public static ValueTask WriteAsync( this TextWriter target, ReadOnlyMemory buffer, @@ -51,7 +51,7 @@ public static ValueTask WriteAsync( /// The default value is . /// /// A task that represents the asynchronous write operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] public static ValueTask WriteLineAsync( this TextWriter target, ReadOnlyMemory buffer, @@ -72,7 +72,7 @@ public static ValueTask WriteLineAsync( /// Writes a character span to the text stream. /// /// The character span to write. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] public static void Write( this TextWriter target, ReadOnlySpan buffer) @@ -95,7 +95,7 @@ public static void Write( /// Writes the text representation of a character span to the text stream, followed by a line terminator. /// /// The char span value to write to the text stream. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] public static void WriteLine( this TextWriter target, ReadOnlySpan buffer) diff --git a/src/Polyfill/PolyfillExtensions_TryFormat.cs b/src/Polyfill/PolyfillExtensions_TryFormat.cs index 5a1d9e88..27cf7694 100644 --- a/src/Polyfill/PolyfillExtensions_TryFormat.cs +++ b/src/Polyfill/PolyfillExtensions_TryFormat.cs @@ -9,7 +9,7 @@ using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { @@ -18,7 +18,7 @@ static partial class PolyfillExtensions /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat")] public static bool TryFormat(this sbyte target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -38,7 +38,7 @@ public static bool TryFormat(this sbyte target, Span destination, out int /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat")] public static bool TryFormat(this byte target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -58,7 +58,7 @@ public static bool TryFormat(this byte target, Span destination, out int c /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat")] public static bool TryFormat(this short target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -78,7 +78,7 @@ public static bool TryFormat(this short target, Span destination, out int /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat")] public static bool TryFormat(this ushort target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -98,7 +98,7 @@ public static bool TryFormat(this ushort target, Span destination, out int /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat")] public static bool TryFormat(this int target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -118,7 +118,7 @@ public static bool TryFormat(this int target, Span destination, out int ch /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat")] public static bool TryFormat(this uint target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -138,7 +138,7 @@ public static bool TryFormat(this uint target, Span destination, out int c /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat")] public static bool TryFormat(this long target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -158,7 +158,7 @@ public static bool TryFormat(this long target, Span destination, out int c /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat")] public static bool TryFormat(this ulong target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -178,7 +178,7 @@ public static bool TryFormat(this ulong target, Span destination, out int /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat")] public static bool TryFormat(this float target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -198,7 +198,7 @@ public static bool TryFormat(this float target, Span destination, out int /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat")] public static bool TryFormat(this double target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -218,7 +218,7 @@ public static bool TryFormat(this double target, Span destination, out int /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat")] public static bool TryFormat(this decimal target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -238,7 +238,7 @@ public static bool TryFormat(this decimal target, Span destination, out in /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat")] public static bool TryFormat(this bool target, Span destination, out int charsWritten) { var result = target.ToString(); @@ -250,7 +250,7 @@ public static bool TryFormat(this bool target, Span destination, out int c /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tryformat")] public static bool TryFormat(this DateTimeOffset target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -270,7 +270,7 @@ public static bool TryFormat(this DateTimeOffset target, Span destination, /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryformat")] public static bool TryFormat(this DateTime target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -293,7 +293,7 @@ public static bool TryFormat(this DateTime target, Span destination, out i /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.dateonly.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.dateonly.tryformat")] public static bool TryFormat(this DateOnly target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -313,7 +313,7 @@ public static bool TryFormat(this DateOnly target, Span destination, out i /// /// Tries to format the value of the current instance into the provided span of characters. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timeonly.tryformat")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.timeonly.tryformat")] public static bool TryFormat(this TimeOnly target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; diff --git a/src/Polyfill/PolyfillExtensions_Type.cs b/src/Polyfill/PolyfillExtensions_Type.cs index 33ba2e8a..a225183b 100644 --- a/src/Polyfill/PolyfillExtensions_Type.cs +++ b/src/Polyfill/PolyfillExtensions_Type.cs @@ -8,11 +8,11 @@ using System; using System.Reflection; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Description = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas")] public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInfo other) { #if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0 @@ -26,7 +26,7 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter")] public static bool IsGenericMethodParameter(this Type target) { #if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0 @@ -45,7 +45,7 @@ public static bool IsGenericMethodParameter(this Type target) /// The MemberInfo to find on the current Type. /// The MemberInfo to find on the current Type. /// An object representing the member on the current Type that matches the specified member. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.type.getmemberwithsamemetadatadefinitionas")] + [Description("https://learn.microsoft.com/en-us/dotnet/api/system.type.getmemberwithsamemetadatadefinitionas")] internal static MemberInfo GetMemberWithSameMetadataDefinitionAs(this Type type, MemberInfo member) { const BindingFlags all = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; From 68d7949ecd265f07c5a9608a5510412bc3007a9e Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 5 May 2023 17:49:15 +1000 Subject: [PATCH 110/313] cleanup --- contributing.md | 10 +++--- readme.md | 2 +- ...yfillExtensions_CancellationTokenSource.cs | 4 +-- src/Polyfill/PolyfillExtensions_HttpClient.cs | 14 ++++---- .../PolyfillExtensions_HttpContent.cs | 8 ++--- .../PolyfillExtensions_IEnumerable.cs | 6 ++-- .../PolyfillExtensions_IReadOnlyDictionary.cs | 6 ++-- .../PolyfillExtensions_KeyValuePair.cs | 4 +-- src/Polyfill/PolyfillExtensions_Memory.cs | 18 +++++----- .../PolyfillExtensions_MicroNanosecond.cs | 18 +++++----- src/Polyfill/PolyfillExtensions_Stream.cs | 8 ++--- src/Polyfill/PolyfillExtensions_String.cs | 20 +++++------ .../PolyfillExtensions_StringBuilder.cs | 8 ++--- src/Polyfill/PolyfillExtensions_Task.cs | 14 ++++---- src/Polyfill/PolyfillExtensions_TextReader.cs | 6 ++-- src/Polyfill/PolyfillExtensions_TextWriter.cs | 10 +++--- src/Polyfill/PolyfillExtensions_TryFormat.cs | 34 +++++++++---------- src/Polyfill/PolyfillExtensions_Type.cs | 8 ++--- 18 files changed, 99 insertions(+), 99 deletions(-) diff --git a/contributing.md b/contributing.md index a4c4a7e1..f652729f 100644 --- a/contributing.md +++ b/contributing.md @@ -200,7 +200,7 @@ using System; using System.Buffers; using System.IO; using System.Runtime.InteropServices; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; // ReSharper disable RedundantAttributeSuffix @@ -216,7 +216,7 @@ static partial class PolyfillExtensions /// The default value is . /// /// A task that represents the asynchronous write operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] public static ValueTask WriteAsync( this TextWriter target, ReadOnlyMemory buffer, @@ -242,7 +242,7 @@ static partial class PolyfillExtensions /// The default value is . /// /// A task that represents the asynchronous write operation. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] public static ValueTask WriteLineAsync( this TextWriter target, ReadOnlyMemory buffer, @@ -263,7 +263,7 @@ static partial class PolyfillExtensions /// Writes a character span to the text stream. /// /// The character span to write. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] public static void Write( this TextWriter target, ReadOnlySpan buffer) @@ -286,7 +286,7 @@ static partial class PolyfillExtensions /// Writes the text representation of a character span to the text stream, followed by a line terminator. /// /// The char span value to write to the text stream. - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] public static void WriteLine( this TextWriter target, ReadOnlySpan buffer) diff --git a/readme.md b/readme.md index bc1fac66..0d3983c9 100644 --- a/readme.md +++ b/readme.md @@ -586,7 +586,7 @@ The class `PolyfillExtensions` includes the following extension methods: ### TimeSpan - * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond) + * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds) * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) diff --git a/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs b/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs index 34540644..2e6b64ea 100644 --- a/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs +++ b/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs @@ -10,13 +10,13 @@ using System.Reflection; using System.Threading; using System.Threading.Tasks; -using DescriptionAttribute = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { #if !NET8_0_OR_GREATER - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync")] public static Task CancelAsync(this CancellationTokenSource target) { target.Cancel(); diff --git a/src/Polyfill/PolyfillExtensions_HttpClient.cs b/src/Polyfill/PolyfillExtensions_HttpClient.cs index a539e8f0..75f68e2a 100644 --- a/src/Polyfill/PolyfillExtensions_HttpClient.cs +++ b/src/Polyfill/PolyfillExtensions_HttpClient.cs @@ -11,7 +11,7 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { @@ -25,7 +25,7 @@ static partial class PolyfillExtensions /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)")] public static async Task GetStreamAsync( this HttpClient httpClient, string requestUri, @@ -63,7 +63,7 @@ public static async Task GetStreamAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)")] public static Task GetStreamAsync( this HttpClient httpClient, Uri requestUri, @@ -80,7 +80,7 @@ public static Task GetStreamAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)")] public static async Task GetByteArrayAsync( this HttpClient httpClient, string requestUri, @@ -117,7 +117,7 @@ public static async Task GetByteArrayAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)")] public static Task GetByteArrayAsync( this HttpClient httpClient, Uri requestUri, @@ -134,7 +134,7 @@ public static Task GetByteArrayAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)")] public static async Task GetStringAsync( this HttpClient httpClient, string requestUri, @@ -171,7 +171,7 @@ public static async Task GetStringAsync( /// The Uri the request is sent to. /// The cancellation token to cancel the operation. /// The task object representing the asynchronous operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)")] public static Task GetStringAsync( this HttpClient httpClient, Uri requestUri, diff --git a/src/Polyfill/PolyfillExtensions_HttpContent.cs b/src/Polyfill/PolyfillExtensions_HttpContent.cs index 3e8d7c59..ad5239dd 100644 --- a/src/Polyfill/PolyfillExtensions_HttpContent.cs +++ b/src/Polyfill/PolyfillExtensions_HttpContent.cs @@ -10,7 +10,7 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { @@ -25,7 +25,7 @@ static partial class PolyfillExtensions /// The token to monitor for cancellation requests. The default value is . /// /// The task object representing the asynchronous operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)")] public static Task ReadAsStreamAsync( this HttpContent httpContent, CancellationToken cancellationToken = default) @@ -45,7 +45,7 @@ public static Task ReadAsStreamAsync( /// The token to monitor for cancellation requests. The default value is . /// /// The task object representing the asynchronous operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)")] public static Task ReadAsByteArrayAsync( this HttpContent httpContent, CancellationToken cancellationToken = default) @@ -65,7 +65,7 @@ public static Task ReadAsByteArrayAsync( /// The token to monitor for cancellation requests. The default value is . /// /// The task object representing the asynchronous operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)")] public static Task ReadAsStringAsync( this HttpContent httpContent, CancellationToken cancellationToken = default) diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index bb76deca..a77fc6ca 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -7,7 +7,7 @@ using System; using System.Collections.Generic; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; using System.Linq; // ReSharper disable RedundantAttributeSuffix @@ -22,7 +22,7 @@ static partial class PolyfillExtensions /// The value to append to source. /// The type of the elements of source. /// A new sequence that ends with element. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.append")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.append")] public static IEnumerable Append( this IEnumerable source, TSource element) @@ -46,7 +46,7 @@ public static IEnumerable Append( /// The type of the elements in the enumerable collection. /// A new enumerable collection that contains the elements from source minus count elements from the end /// of the collection. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast")] public static IEnumerable SkipLast(this IEnumerable source, int count) => source.Reverse().Skip(count).Reverse(); #endif diff --git a/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs b/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs index cbb78d9e..a4c4ebc5 100644 --- a/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs +++ b/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs @@ -8,7 +8,7 @@ using System; using System.Collections.Generic; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; // ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions @@ -24,7 +24,7 @@ static partial class PolyfillExtensions /// A TValue instance. When the method is successful, the returned object is the value associated with /// the specified key. When the method fails, it returns the default value for TValue. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault")] public static TValue? GetValueOrDefault( this IReadOnlyDictionary target, TKey key) @@ -49,7 +49,7 @@ static partial class PolyfillExtensions /// A TValue instance. When the method is successful, the returned object is the value associated with /// the specified key. When the method fails, it returns the default value for TValue. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)")] public static TValue GetValueOrDefault( this IReadOnlyDictionary target, TKey key, diff --git a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs index 93b9b717..3c2e2455 100644 --- a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs +++ b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs @@ -9,7 +9,7 @@ using System; using System.Collections.Generic; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { @@ -18,7 +18,7 @@ static partial class PolyfillExtensions /// /// The key of the current . /// The value of the current . - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct")] public static void Deconstruct( this KeyValuePair target, out TKey key, diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index 7654cffc..1d6cceea 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -10,7 +10,7 @@ using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { @@ -19,7 +19,7 @@ static partial class PolyfillExtensions /// /// The value to search for. /// true if found, false otherwise. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)")] public static bool Contains(this ReadOnlySpan target, T value) where T : IEquatable { @@ -39,7 +39,7 @@ public static bool Contains(this ReadOnlySpan target, T value) /// /// The value to search for. /// true if found, false otherwise. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)")] public static bool Contains(this Span target, T value) where T : IEquatable { @@ -54,27 +54,27 @@ public static bool Contains(this Span target, T value) return false; } - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] public static bool SequenceEqual(this ReadOnlySpan target, string other) => target.SequenceEqual(other.AsSpan()); - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))")] public static bool SequenceEqual(this Span target, string other) => target.SequenceEqual(other.AsSpan()); - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] public static bool StartsWith(this ReadOnlySpan target, string other, StringComparison comparison = StringComparison.CurrentCulture) => target.StartsWith(other.AsSpan(), comparison); - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))")] public static bool StartsWith(this Span target, string other) => target.StartsWith(other.AsSpan()); - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] public static bool EndsWith(this ReadOnlySpan target, string other, StringComparison comparison = StringComparison.CurrentCulture) => target.EndsWith(other.AsSpan(), comparison); - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))")] public static bool EndsWith(this Span target, string other) => target.EndsWith(other.AsSpan()); } diff --git a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs index 84e2cbf1..034adc32 100644 --- a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs +++ b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs @@ -6,7 +6,7 @@ // ReSharper disable UnusedMember.Global using System; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; // ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions @@ -16,7 +16,7 @@ static partial class PolyfillExtensions /// /// Gets the nanosecond component of the time represented by the current object. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds")] public static int Nanoseconds(this TimeSpan target) => #if NET7_0_OR_GREATER target.Nanoseconds; @@ -27,7 +27,7 @@ public static int Nanoseconds(this TimeSpan target) => /// /// Gets the nanosecond component of the time represented by the current object. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond")] public static int Nanosecond(this DateTime target) => #if NET7_0_OR_GREATER target.Nanosecond; @@ -38,7 +38,7 @@ public static int Nanosecond(this DateTime target) => /// /// Gets the nanosecond component of the time represented by the current object. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond")] public static int Nanosecond(this DateTimeOffset target) => #if NET7_0_OR_GREATER target.Nanosecond; @@ -49,7 +49,7 @@ public static int Nanosecond(this DateTimeOffset target) => /// /// Gets the microsecond component of the time represented by the current object. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds")] public static int Microseconds(this TimeSpan target) => #if NET7_0_OR_GREATER target.Microseconds; @@ -60,7 +60,7 @@ public static int Microseconds(this TimeSpan target) => /// /// Gets the microsecond component of the time represented by the current object. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond")] public static int Microsecond(this DateTime target) => #if NET7_0_OR_GREATER target.Microsecond; @@ -71,7 +71,7 @@ public static int Microsecond(this DateTime target) => /// /// Gets the microsecond component of the time represented by the current object. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond")] public static int Microsecond(this DateTimeOffset target) => #if NET7_0_OR_GREATER target.Microsecond; @@ -82,7 +82,7 @@ public static int Microsecond(this DateTimeOffset target) => /// /// Returns a new object that adds a specified number of microseconds to the value of this instance.. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds")] public static DateTime AddMicroseconds(this DateTime target, double microseconds) => #if NET7_0_OR_GREATER target.AddMicroseconds(microseconds); @@ -93,7 +93,7 @@ public static DateTime AddMicroseconds(this DateTime target, double microseconds /// /// Returns a new object that adds a specified number of microseconds to the value of this instance.. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds")] public static DateTimeOffset AddMicroseconds(this DateTimeOffset target, double microseconds) => #if NET7_0_OR_GREATER target.AddMicroseconds(microseconds); diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index dd8b3fff..1540678e 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; // ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions @@ -29,7 +29,7 @@ static partial class PolyfillExtensions /// the buffer if that many bytes are not currently available, or it can be 0 (zero) if the end of the stream has /// been reached. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)")] public static ValueTask ReadAsync( this Stream target, Memory buffer, @@ -52,7 +52,7 @@ public static ValueTask ReadAsync( /// The token to monitor for cancellation requests. The default value is . /// /// A task that represents the asynchronous write operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)")] public static ValueTask WriteAsync( this Stream target, ReadOnlyMemory buffer, @@ -75,7 +75,7 @@ public static ValueTask WriteAsync( /// The token to monitor for cancellation requests. The default value is . /// /// A task that represents the asynchronous copy operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)")] public static Task CopyToAsync( this Stream target, Stream destination, diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/PolyfillExtensions_String.cs index 8dfe9ac5..684584e8 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/PolyfillExtensions_String.cs @@ -5,7 +5,7 @@ // ReSharper disable PartialTypeWithSinglePart using System; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; using System.Text; // ReSharper disable RedundantAttributeSuffix @@ -17,7 +17,7 @@ static partial class PolyfillExtensions /// Copies the contents of this string into the destination span. /// /// The span into which to copy this string's contents - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.copyto")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.string.copyto")] public static void CopyTo(this string target, Span destination) => target.AsSpan().CopyTo(destination); @@ -26,7 +26,7 @@ public static void CopyTo(this string target, Span destination) => /// /// The span into which to copy this string's contents /// true if the data was copied; false if the destination was too short to fit the contents of the string. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto")] public static bool TryCopyTo(this string target, Span destination) => target.AsSpan().TryCopyTo(destination); #endif @@ -38,7 +38,7 @@ public static bool TryCopyTo(this string target, Span destination) => /// /// One of the enumeration values that specifies the rules to use in the comparison. /// A 32-bit signed integer hash code. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)")] public static int GetHashCode(this string target, StringComparison comparisonType) => FromComparison(comparisonType).GetHashCode(target); @@ -59,7 +59,7 @@ static StringComparer FromComparison(StringComparison comparison) => /// The string to seek. /// One of the enumeration values that specifies the rules to use in the comparison. /// true if the value parameter occurs within this string, or if value is the empty string (""); otherwise, false. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)")] public static bool Contains(this string target, string value, StringComparison comparisonType) => target.IndexOf(value, comparisonType) >= 0; @@ -69,7 +69,7 @@ public static bool Contains(this string target, string value, StringComparison c /// The character to compare. /// This method performs an ordinal (case-sensitive and culture-insensitive) comparison. /// true if value matches the beginning of this string; otherwise, false. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] public static bool StartsWith(this string target, char value) { if (target.Length == 0) @@ -86,7 +86,7 @@ public static bool StartsWith(this string target, char value) /// The character to seek. /// This method performs an ordinal (case-sensitive and culture-insensitive) comparison. /// true if the value parameter occurs within this string; otherwise, false. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] public static bool EndsWith(this string target, char value) { if (target.Length == 0) @@ -108,7 +108,7 @@ public static bool EndsWith(this string target, char value) /// A bitwise combination of the enumeration values that specifies whether to trim substrings /// and include empty substrings. /// An array that contains at most count substrings from this instance that are delimited by separator. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)")] public static string[] Split(this string target, char separator, StringSplitOptions options = StringSplitOptions.None) => target.Split(new[] {separator}, options); @@ -122,7 +122,7 @@ public static string[] Split(this string target, char separator, StringSplitOpti /// A bitwise combination of the enumeration values that specifies whether to trim substrings /// and include empty substrings. /// An array that contains at most count substrings from this instance that are delimited by separator. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)")] public static string[] Split(this string target, char separator, int count, StringSplitOptions options = StringSplitOptions.None) => target.Split(new[] {separator}, count, options); #endif @@ -134,7 +134,7 @@ public static string[] Split(this string target, char separator, int count, Stri /// This method performs an ordinal (case-sensitive and culture-insensitive) comparison. /// The character to seek. /// true if the value parameter occurs within this string; otherwise, false. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)")] public static bool Contains(this string target, char value) => target.IndexOf(value) >= 0; #endif diff --git a/src/Polyfill/PolyfillExtensions_StringBuilder.cs b/src/Polyfill/PolyfillExtensions_StringBuilder.cs index 99c6ff10..cd7d64d6 100644 --- a/src/Polyfill/PolyfillExtensions_StringBuilder.cs +++ b/src/Polyfill/PolyfillExtensions_StringBuilder.cs @@ -9,7 +9,7 @@ using System.IO; using System.Runtime.InteropServices; using System.Text; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; // ReSharper disable RedundantAttributeSuffix @@ -22,7 +22,7 @@ static partial class PolyfillExtensions /// The starting position in this instance where characters will be copied from. The index is zero-based. /// The writable span where characters will be copied. /// The number of characters to be copied. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)")] public static void CopyTo( this StringBuilder target, int sourceIndex, @@ -53,7 +53,7 @@ public static void CopyTo( /// /// The read-only character span to append. /// A reference to this instance after the append operation is completed. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))")] public static StringBuilder Append(this StringBuilder target, ReadOnlySpan value) { if (value.Length <= 0) @@ -85,7 +85,7 @@ public static StringBuilder Append(this StringBuilder target, ReadOnlySpan /// and span are equal. /// /// true if the characters in this instance and span are the same; otherwise, false. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))")] public static bool Equals(this StringBuilder target, ReadOnlySpan span) { if (target.Length != span.Length) diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/PolyfillExtensions_Task.cs index 2c73d34d..78e4cdca 100644 --- a/src/Polyfill/PolyfillExtensions_Task.cs +++ b/src/Polyfill/PolyfillExtensions_Task.cs @@ -11,15 +11,15 @@ using System.Reflection; using System.Threading; using System.Threading.Tasks; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] public static Task WaitAsync(this Task target, CancellationToken cancellationToken) => target.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken); - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)")] public static async Task WaitAsync(this Task target, TimeSpan timeout) { var cancellationSource = new CancellationTokenSource(); @@ -34,7 +34,7 @@ public static async Task WaitAsync(this Task target, TimeSpan timeout) } } - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)")] public static async Task WaitAsync(this Task task, TimeSpan timeout, CancellationToken cancellationToken) { var delayTask = Task.Delay(timeout, cancellationToken); @@ -47,11 +47,11 @@ public static async Task WaitAsync(this Task task, TimeSpan timeout, Cancellatio await task; } - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] public static Task WaitAsync(this Task task, CancellationToken cancellationToken) => task.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken); - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)")] public static async Task WaitAsync(this Task task, TimeSpan timeout) { var cancellationSource = new CancellationTokenSource(); @@ -66,7 +66,7 @@ public static async Task WaitAsync(this Task task, Ti } } - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)")] public static async Task WaitAsync(this Task task, TimeSpan timeout, CancellationToken cancellationToken) { var delayTask = Task.Delay(timeout, cancellationToken); diff --git a/src/Polyfill/PolyfillExtensions_TextReader.cs b/src/Polyfill/PolyfillExtensions_TextReader.cs index 7a7d3c4d..1c3f85fd 100644 --- a/src/Polyfill/PolyfillExtensions_TextReader.cs +++ b/src/Polyfill/PolyfillExtensions_TextReader.cs @@ -6,7 +6,7 @@ using System; using System.IO; using System.Runtime.InteropServices; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; // ReSharper disable RedundantAttributeSuffix @@ -30,7 +30,7 @@ static partial class PolyfillExtensions /// The number will be less than or equal to the length, depending on whether the data is /// available within the stream. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)")] public static ValueTask ReadAsync( this TextReader target, Memory buffer, @@ -57,7 +57,7 @@ public static ValueTask ReadAsync( /// The number of characters is larger than . /// The stream reader has been disposed. /// The reader is currently in use by a previous read operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)")] public static Task ReadToEndAsync( this TextReader target, CancellationToken cancellationToken) diff --git a/src/Polyfill/PolyfillExtensions_TextWriter.cs b/src/Polyfill/PolyfillExtensions_TextWriter.cs index 9cd08176..7967087a 100644 --- a/src/Polyfill/PolyfillExtensions_TextWriter.cs +++ b/src/Polyfill/PolyfillExtensions_TextWriter.cs @@ -9,7 +9,7 @@ using System.Buffers; using System.IO; using System.Runtime.InteropServices; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; // ReSharper disable RedundantAttributeSuffix @@ -25,7 +25,7 @@ static partial class PolyfillExtensions /// The default value is . /// /// A task that represents the asynchronous write operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] public static ValueTask WriteAsync( this TextWriter target, ReadOnlyMemory buffer, @@ -51,7 +51,7 @@ public static ValueTask WriteAsync( /// The default value is . /// /// A task that represents the asynchronous write operation. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] public static ValueTask WriteLineAsync( this TextWriter target, ReadOnlyMemory buffer, @@ -72,7 +72,7 @@ public static ValueTask WriteLineAsync( /// Writes a character span to the text stream. /// /// The character span to write. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))")] public static void Write( this TextWriter target, ReadOnlySpan buffer) @@ -95,7 +95,7 @@ public static void Write( /// Writes the text representation of a character span to the text stream, followed by a line terminator. /// /// The char span value to write to the text stream. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))")] public static void WriteLine( this TextWriter target, ReadOnlySpan buffer) diff --git a/src/Polyfill/PolyfillExtensions_TryFormat.cs b/src/Polyfill/PolyfillExtensions_TryFormat.cs index 27cf7694..f039121d 100644 --- a/src/Polyfill/PolyfillExtensions_TryFormat.cs +++ b/src/Polyfill/PolyfillExtensions_TryFormat.cs @@ -9,7 +9,7 @@ using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { @@ -18,7 +18,7 @@ static partial class PolyfillExtensions /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat")] public static bool TryFormat(this sbyte target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -38,7 +38,7 @@ public static bool TryFormat(this sbyte target, Span destination, out int /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat")] public static bool TryFormat(this byte target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -58,7 +58,7 @@ public static bool TryFormat(this byte target, Span destination, out int c /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat")] public static bool TryFormat(this short target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -78,7 +78,7 @@ public static bool TryFormat(this short target, Span destination, out int /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat")] public static bool TryFormat(this ushort target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -98,7 +98,7 @@ public static bool TryFormat(this ushort target, Span destination, out int /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat")] public static bool TryFormat(this int target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -118,7 +118,7 @@ public static bool TryFormat(this int target, Span destination, out int ch /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat")] public static bool TryFormat(this uint target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -138,7 +138,7 @@ public static bool TryFormat(this uint target, Span destination, out int c /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat")] public static bool TryFormat(this long target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -158,7 +158,7 @@ public static bool TryFormat(this long target, Span destination, out int c /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat")] public static bool TryFormat(this ulong target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -178,7 +178,7 @@ public static bool TryFormat(this ulong target, Span destination, out int /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat")] public static bool TryFormat(this float target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -198,7 +198,7 @@ public static bool TryFormat(this float target, Span destination, out int /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat")] public static bool TryFormat(this double target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -218,7 +218,7 @@ public static bool TryFormat(this double target, Span destination, out int /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat")] public static bool TryFormat(this decimal target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -238,7 +238,7 @@ public static bool TryFormat(this decimal target, Span destination, out in /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat")] public static bool TryFormat(this bool target, Span destination, out int charsWritten) { var result = target.ToString(); @@ -250,7 +250,7 @@ public static bool TryFormat(this bool target, Span destination, out int c /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tryformat")] public static bool TryFormat(this DateTimeOffset target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -270,7 +270,7 @@ public static bool TryFormat(this DateTimeOffset target, Span destination, /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryformat")] public static bool TryFormat(this DateTime target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -293,7 +293,7 @@ public static bool TryFormat(this DateTime target, Span destination, out i /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.dateonly.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.dateonly.tryformat")] public static bool TryFormat(this DateOnly target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; @@ -313,7 +313,7 @@ public static bool TryFormat(this DateOnly target, Span destination, out i /// /// Tries to format the value of the current instance into the provided span of characters. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.timeonly.tryformat")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.timeonly.tryformat")] public static bool TryFormat(this TimeOnly target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; diff --git a/src/Polyfill/PolyfillExtensions_Type.cs b/src/Polyfill/PolyfillExtensions_Type.cs index a225183b..4db2fa07 100644 --- a/src/Polyfill/PolyfillExtensions_Type.cs +++ b/src/Polyfill/PolyfillExtensions_Type.cs @@ -8,11 +8,11 @@ using System; using System.Reflection; -using Description = System.ComponentModel.DescriptionAttribute; +using Link = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas")] public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInfo other) { #if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0 @@ -26,7 +26,7 @@ public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInf /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. /// - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter")] public static bool IsGenericMethodParameter(this Type target) { #if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0 @@ -45,7 +45,7 @@ public static bool IsGenericMethodParameter(this Type target) /// The MemberInfo to find on the current Type. /// The MemberInfo to find on the current Type. /// An object representing the member on the current Type that matches the specified member. - [Description("https://learn.microsoft.com/en-us/dotnet/api/system.type.getmemberwithsamemetadatadefinitionas")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.type.getmemberwithsamemetadatadefinitionas")] internal static MemberInfo GetMemberWithSameMetadataDefinitionAs(this Type type, MemberInfo member) { const BindingFlags all = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; From 2bb9d75c02a0cb3fcb4c1fb5fc68d57478b73a07 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 5 May 2023 17:50:55 +1000 Subject: [PATCH 111/313] Update PolyfillExtensions_Task.cs --- src/Polyfill/PolyfillExtensions_Task.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/PolyfillExtensions_Task.cs index 78e4cdca..fd0557cb 100644 --- a/src/Polyfill/PolyfillExtensions_Task.cs +++ b/src/Polyfill/PolyfillExtensions_Task.cs @@ -6,6 +6,7 @@ // ReSharper disable PartialTypeWithSinglePart // ReSharper disable UnusedMember.Global // ReSharper disable RedundantAttributeSuffix +// ReSharper disable RedundantTypeArgumentsOfMethod using System; using System.Reflection; From c975c179980de8c5ce8b35bb71964f88212bf2ba Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 8 May 2023 21:07:38 +1000 Subject: [PATCH 112/313] Min by and max by (#50) --- api_list.include.md | 25 +++++++ readme.md | 25 +++++++ src/Consume/Consume.cs | 2 + .../PolyfillExtensions_IEnumerable.cs | 74 +++++++++++++++++++ .../PolyfillExtensionsTests_IEnumerable.cs | 16 ++++ 5 files changed, 142 insertions(+) diff --git a/api_list.include.md b/api_list.include.md index 2e108274..c7632446 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -8,6 +8,11 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) +### CancellationTokenSource + + * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) + + ### DateTime * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) @@ -65,6 +70,26 @@ * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) +### IEnumerable + + * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + + +### IEnumerable + + * `TSource MaxBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + + +### IEnumerable + + * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + + +### IEnumerable + + * `TSource MinBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + + ### IEnumerable * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) diff --git a/readme.md b/readme.md index 0d3983c9..f7f340bc 100644 --- a/readme.md +++ b/readme.md @@ -357,6 +357,11 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) +### CancellationTokenSource + + * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) + + ### DateTime * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) @@ -414,6 +419,26 @@ The class `PolyfillExtensions` includes the following extension methods: * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) +### IEnumerable + + * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + + +### IEnumerable + + * `TSource MaxBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + + +### IEnumerable + + * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + + +### IEnumerable + + * `TSource MinBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + + ### IEnumerable * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index c9a6be25..a50224d1 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -79,6 +79,8 @@ class Consume "b" }; var append = enumerable.Append("c"); + var maxBy = enumerable.MaxBy(_=>_); + var minBy = enumerable.MinBy(_=>_); var skipLast = enumerable.SkipLast(1); var dictionary = new Dictionary diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index a77fc6ca..812c806a 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -13,6 +13,80 @@ static partial class PolyfillExtensions { +#if NETSTANDARD || NETCOREAPP || NETFRAMEWORK || NET5_0 + + /// + /// Returns the maximum value in a generic sequence according to a specified key selector function. + /// + /// The type of the elements of . + /// The type of key to compare elements by. + /// A sequence of values to determine the maximum value of. + /// A function to extract the key for each element. + /// The value with the maximum key in the sequence. + /// is . + /// No key extracted from implements the or interface. + /// + /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . + /// + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] + public static TSource? MaxBy(this IEnumerable source, Func keySelector) => + MaxBy(source, keySelector, null); + + /// Returns the maximum value in a generic sequence according to a specified key selector function. + /// The type of the elements of . + /// The type of key to compare elements by. + /// A sequence of values to determine the maximum value of. + /// A function to extract the key for each element. + /// The to compare keys. + /// The value with the maximum key in the sequence. + /// is . + /// No key extracted from implements the or interface. + /// + /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . + /// + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))")] + public static TSource? MaxBy(this IEnumerable source, Func keySelector, IComparer? comparer) => + source + .OrderByDescending(keySelector, comparer) + .FirstOrDefault(); + + /// + /// Returns the minimum value in a generic sequence according to a specified key selector function. + /// + /// The type of the elements of . + /// The type of key to compare elements by. + /// A sequence of values to determine the minby value of. + /// A function to extract the key for each element. + /// The value with the minimum key in the sequence. + /// is . + /// No key extracted from implements the or interface. + /// + /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . + /// + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] + public static TSource? MinBy(this IEnumerable source, Func keySelector) => + MinBy(source, keySelector, null); + + /// Returns the minimum value in a generic sequence according to a specified key selector function. + /// The type of the elements of . + /// The type of key to compare elements by. + /// A sequence of values to determine the minimum value of. + /// A function to extract the key for each element. + /// The to compare keys. + /// The value with the minimum key in the sequence. + /// is . + /// No key extracted from implements the or interface. + /// + /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . + /// + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))")] + public static TSource? MinBy(this IEnumerable source, Func keySelector, IComparer? comparer) => + source + .OrderBy(keySelector, comparer) + .FirstOrDefault(); + +#endif + #if NET46X || NET47 /// diff --git a/src/Tests/PolyfillExtensionsTests_IEnumerable.cs b/src/Tests/PolyfillExtensionsTests_IEnumerable.cs index b5e13ffe..d2a20970 100644 --- a/src/Tests/PolyfillExtensionsTests_IEnumerable.cs +++ b/src/Tests/PolyfillExtensionsTests_IEnumerable.cs @@ -1,5 +1,21 @@ partial class PolyfillExtensionsTests { + [Test] + public void MaxBy() + { + var enumerable = (IEnumerable)new List {1, 2}; + + Assert.AreEqual(2, enumerable.MaxBy(_ => _)); + } + + [Test] + public void MinBy() + { + var enumerable = (IEnumerable)new List {1, 2}; + + Assert.AreEqual(1, enumerable.MinBy(_ => _)); + } + [Test] public void IEnumerableAppend() { From be288816c02bb927e41a7297157d5afde3ef7279 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 8 May 2023 21:09:24 +1000 Subject: [PATCH 113/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index ea9e3fe7..851a21eb 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.22.0 + 1.23.0 1.0.0 Polyfill true From fafdcbca29f185c338e3ec75cf100d0dd29adfb0 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 13 May 2023 18:45:24 +1000 Subject: [PATCH 114/313] Update .gitattributes --- src/.gitattributes | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/.gitattributes b/src/.gitattributes index 44a18354..50e6525b 100644 --- a/src/.gitattributes +++ b/src/.gitattributes @@ -2,6 +2,6 @@ *.snk binary *.png binary -*.verified.txt text eol=lf -*.verified.xml text eol=lf -*.verified.json text eol=lf \ No newline at end of file +*.verified.txt text eol=lf working-tree-encoding=UTF-8 +*.verified.xml text eol=lf working-tree-encoding=UTF-8 +*.verified.json text eol=lf working-tree-encoding=UTF-8 \ No newline at end of file From 820a7b097a10db56456597115483dccc82c275d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 May 2023 19:03:45 +1000 Subject: [PATCH 115/313] Bump Microsoft.NET.Test.Sdk from 17.5.0 to 17.6.0 in /src (#51) Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.5.0 to 17.6.0. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.5.0...v17.6.0) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index b1ff77e6..ed1db27d 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -33,7 +33,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index d9e6e1f5..94f19e04 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index e597d158..e5ffb8cb 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 0bf80ccb..96044da1 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -28,7 +28,7 @@ - + From b62e661452579ebc8efbf900d7fba3da413c927a Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 18 May 2023 16:52:26 +1000 Subject: [PATCH 116/313] Update NullabilitySamples.cs --- src/Tests/NullabilitySamples.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Tests/NullabilitySamples.cs b/src/Tests/NullabilitySamples.cs index 4bdb2980..1281c1ed 100644 --- a/src/Tests/NullabilitySamples.cs +++ b/src/Tests/NullabilitySamples.cs @@ -42,6 +42,7 @@ public void ExtensionTests() #endregion + // ReSharper disable UnusedMember.Local class PropertyTarget { string? write; @@ -53,6 +54,7 @@ public string? Write set => write = value; } } + // ReSharper restore UnusedMember.Local [Test] public void Property() From 2b68f0c106e88168eab19e413566922162ff9424 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 18 May 2023 16:54:52 +1000 Subject: [PATCH 117/313] cleanup --- readme.md | 22 +++++ .../PolyfillExtensions_MicroNanosecond.cs | 91 ++++++++++++------- ...PolyfillExtensionsTests_MicroNanosecond.cs | 26 +++--- src/Tests/PolyfillExtensionsTests_String.cs | 2 + 4 files changed, 97 insertions(+), 44 deletions(-) diff --git a/readme.md b/readme.md index 743cbf5a..bc1fac66 100644 --- a/readme.md +++ b/readme.md @@ -548,6 +548,28 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) +### Task + + * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) + * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)) + * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)) + + +### Task + + * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) + + +### Task + + * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)) + + +### Task + + * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)) + + ### TextReader * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) diff --git a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs index 62f46d07..77a27b37 100644 --- a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs +++ b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs @@ -11,95 +11,123 @@ static partial class PolyfillExtensions { - const long TicksPerMicrosecond = TimeSpan.TicksPerMillisecond * 1000; +#if NET7_0_OR_GREATER /// /// Gets the nanosecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds")] public static int Nanoseconds(this TimeSpan target) => -#if NET7_0_OR_GREATER target.Nanoseconds; -#else - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; -#endif /// /// Gets the nanosecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond")] public static int Nanosecond(this DateTime target) => -#if NET7_0_OR_GREATER target.Nanosecond; -#else - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; -#endif /// /// Gets the nanosecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond")] public static int Nanosecond(this DateTimeOffset target) => -#if NET7_0_OR_GREATER target.Nanosecond; -#else - (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; -#endif /// /// Gets the microsecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond")] public static int Microseconds(this TimeSpan target) => -#if NET7_0_OR_GREATER target.Microseconds; -#else - (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; -#endif /// /// Gets the microsecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond")] public static int Microsecond(this DateTime target) => -#if NET7_0_OR_GREATER target.Microsecond; -#else - (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; -#endif /// /// Gets the microsecond component of the time represented by the current object. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond")] public static int Microsecond(this DateTimeOffset target) => -#if NET7_0_OR_GREATER target.Microsecond; + + /// + /// Returns a new object that adds a specified number of microseconds to the value of this instance.. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds")] + public static DateTime AddMicroseconds(this DateTime target, double microseconds) => + target.AddMicroseconds(microseconds); + + /// + /// Returns a new object that adds a specified number of microseconds to the value of this instance.. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds")] + public static DateTimeOffset AddMicroseconds(this DateTimeOffset target, double microseconds) => + target.AddMicroseconds(microseconds); + #else + + const long TicksPerMicrosecond = TimeSpan.TicksPerMillisecond * 1000; + + /// + /// Gets the nanosecond component of the time represented by the current object. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds")] + public static int Nanoseconds(this TimeSpan target) => + (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + + /// + /// Gets the nanosecond component of the time represented by the current object. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond")] + public static int Nanosecond(this DateTime target) => + (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + + /// + /// Gets the nanosecond component of the time represented by the current object. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond")] + public static int Nanosecond(this DateTimeOffset target) => + (int) (target.TicksComponent() % TicksPerMicrosecond) * 100; + + /// + /// Gets the microsecond component of the time represented by the current object. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond")] + public static int Microseconds(this TimeSpan target) => + (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; + + /// + /// Gets the microsecond component of the time represented by the current object. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond")] + public static int Microsecond(this DateTime target) => + (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; + + /// + /// Gets the microsecond component of the time represented by the current object. + /// + [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond")] + public static int Microsecond(this DateTimeOffset target) => (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; -#endif /// /// Returns a new object that adds a specified number of microseconds to the value of this instance.. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds")] public static DateTime AddMicroseconds(this DateTime target, double microseconds) => -#if NET7_0_OR_GREATER - target.AddMicroseconds(microseconds); -#else target.AddMilliseconds(microseconds / 1000); -#endif /// /// Returns a new object that adds a specified number of microseconds to the value of this instance.. /// [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds")] public static DateTimeOffset AddMicroseconds(this DateTimeOffset target, double microseconds) => -#if NET7_0_OR_GREATER - target.AddMicroseconds(microseconds); -#else target.AddMilliseconds(microseconds / 1000); -#endif static long TicksComponent(this TimeSpan target) { @@ -121,4 +149,5 @@ static long TicksComponent(this DateTimeOffset target) var secondsPart = target - noSeconds; return secondsPart.Ticks; } +#endif } \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_MicroNanosecond.cs b/src/Tests/PolyfillExtensionsTests_MicroNanosecond.cs index 890a5741..0818e56d 100644 --- a/src/Tests/PolyfillExtensionsTests_MicroNanosecond.cs +++ b/src/Tests/PolyfillExtensionsTests_MicroNanosecond.cs @@ -2,9 +2,21 @@ partial class PolyfillExtensionsTests { static DateTimeOffset dateTimeOffset = DateTimeOffset.Now; static DateTime dateTime = DateTime.Now; - static TimeSpan timeSpan = DateTime.Now.TimeOfDay; + + [Test] + public void AddMicroseconds() + { + var fromTicksDateTimeOffset = dateTimeOffset.AddSeconds(1); + var fromMicrosecondsDateTimeOffset = dateTimeOffset.AddMicroseconds(1000000); + Assert.AreEqual(fromTicksDateTimeOffset, fromMicrosecondsDateTimeOffset); + + var fromTicksDateTime = dateTime.AddSeconds(1); + var fromMicrosecondsDateTime = dateTime.AddMicroseconds(1000000); + Assert.AreEqual(fromTicksDateTime, fromMicrosecondsDateTime); + } #if NET7_0_OR_GREATER + static TimeSpan timeSpan = DateTime.Now.TimeOfDay; [Test] public void Nanoseconds() { @@ -21,16 +33,4 @@ public void Microsecond() Assert.AreEqual(dateTime.Microsecond, dateTime.Microsecond()); } #endif - - [Test] - public void AddMicroseconds() - { - var fromTicksDateTimeOffset = dateTimeOffset.AddSeconds(1); - var fromMicrosecondsDateTimeOffset = dateTimeOffset.AddMicroseconds(1000000); - Assert.AreEqual(fromTicksDateTimeOffset, fromMicrosecondsDateTimeOffset); - - var fromTicksDateTime = dateTime.AddSeconds(1); - var fromMicrosecondsDateTime = dateTime.AddMicroseconds(1000000); - Assert.AreEqual(fromTicksDateTime, fromMicrosecondsDateTime); - } } \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_String.cs b/src/Tests/PolyfillExtensionsTests_String.cs index 688ae62f..9546d05f 100644 --- a/src/Tests/PolyfillExtensionsTests_String.cs +++ b/src/Tests/PolyfillExtensionsTests_String.cs @@ -13,6 +13,7 @@ public void GetHashCodeStringComparison() public void EndsWith() { Assert.True("value".EndsWith('e')); + Assert.True("e".EndsWith('e')); Assert.False("".EndsWith('e')); } @@ -40,6 +41,7 @@ public void StringContainsStringComparison() => public void StartsWith() { Assert.True("value".StartsWith('v')); + Assert.True("v".StartsWith('v')); Assert.False("".StartsWith('v')); } From f96cb696221e39b4e9513ffb81faba999c45ea27 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 18 May 2023 18:28:07 +1000 Subject: [PATCH 118/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index ed1db27d..cff9d59b 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 94f19e04..d0cec7b0 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index e5ffb8cb..091c88af 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 96044da1..8a6b7075 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 7c89cc4c5c06f3a8b1abde2feb1fa472cf04034b Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 31 May 2023 11:33:30 +1000 Subject: [PATCH 119/313] fix DescriptionAttribute --- .../PolyfillExtensions_MicroNanosecond.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs index 51e3ebca..d174d398 100644 --- a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs +++ b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs @@ -16,56 +16,56 @@ static partial class PolyfillExtensions /// /// Gets the nanosecond component of the time represented by the current object. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds")] public static int Nanoseconds(this TimeSpan target) => target.Nanoseconds; /// /// Gets the nanosecond component of the time represented by the current object. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond")] public static int Nanosecond(this DateTime target) => target.Nanosecond; /// /// Gets the nanosecond component of the time represented by the current object. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond")] public static int Nanosecond(this DateTimeOffset target) => target.Nanosecond; /// /// Gets the microsecond component of the time represented by the current object. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microsecond")] public static int Microseconds(this TimeSpan target) => target.Microseconds; /// /// Gets the microsecond component of the time represented by the current object. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond")] public static int Microsecond(this DateTime target) => target.Microsecond; /// /// Gets the microsecond component of the time represented by the current object. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond")] public static int Microsecond(this DateTimeOffset target) => target.Microsecond; /// /// Returns a new object that adds a specified number of microseconds to the value of this instance.. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds")] public static DateTime AddMicroseconds(this DateTime target, double microseconds) => target.AddMicroseconds(microseconds); /// /// Returns a new object that adds a specified number of microseconds to the value of this instance.. /// - [DescriptionAttribute("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds")] public static DateTimeOffset AddMicroseconds(this DateTimeOffset target, double microseconds) => target.AddMicroseconds(microseconds); From 03d8fe1e3801a34a1e3404c0b04b65b64bb777c6 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 31 May 2023 12:37:46 +1000 Subject: [PATCH 120/313] Update NullabilityInfo.cs --- src/Polyfill/Nullability/NullabilityInfo.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Polyfill/Nullability/NullabilityInfo.cs b/src/Polyfill/Nullability/NullabilityInfo.cs index 54f37df2..b784425c 100644 --- a/src/Polyfill/Nullability/NullabilityInfo.cs +++ b/src/Polyfill/Nullability/NullabilityInfo.cs @@ -14,7 +14,7 @@ namespace System.Reflection { /// - /// A class that represents nullability info + /// A class that represents nullability info. /// #if PolyPublic public @@ -33,29 +33,29 @@ internal NullabilityInfo(Type type, NullabilityState readState, NullabilityState /// /// The of the member or generic parameter - /// to which this NullabilityInfo belongs + /// to which this NullabilityInfo belongs. /// public Type Type { get; } /// - /// The nullability read state of the member + /// The nullability read state of the member. /// public NullabilityState ReadState { get; internal set; } /// - /// The nullability write state of the member + /// The nullability write state of the member. /// public NullabilityState WriteState { get; internal set; } /// - /// If the member type is an array, gives the of the elements of the array, null otherwise + /// If the member type is an array, gives the of the elements of the array, null otherwise. /// public NullabilityInfo? ElementType { get; } /// - /// If the member type is a generic type, gives the array of for each type parameter + /// If the member type is a generic type, gives the array of for each type parameter. /// public NullabilityInfo[] GenericTypeArguments { get; } } /// - /// An enum that represents nullability state + /// An enum that represents nullability state. /// #if PolyPublic public @@ -63,15 +63,15 @@ internal NullabilityInfo(Type type, NullabilityState readState, NullabilityState enum NullabilityState { /// - /// Nullability context not enabled (oblivious) + /// Nullability context not enabled (oblivious). /// Unknown, /// - /// Non nullable value or reference type + /// Non nullable value or reference type. /// NotNull, /// - /// Nullable value or reference type + /// Nullable value or reference type. /// Nullable } From f874427f9b6188b449fb8c5370da080ad881fa99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 May 2023 17:45:11 +1000 Subject: [PATCH 121/313] Bump NUnit3TestAdapter from 4.4.2 to 4.5.0 in /src (#55) Bumps [NUnit3TestAdapter](https://github.com/nunit/nunit3-vs-adapter) from 4.4.2 to 4.5.0. - [Release notes](https://github.com/nunit/nunit3-vs-adapter/releases) - [Commits](https://github.com/nunit/nunit3-vs-adapter/compare/V4.4.2...V4.5.0) --- updated-dependencies: - dependency-name: NUnit3TestAdapter dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index cff9d59b..74be0996 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index d0cec7b0..d1bbcc7d 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 091c88af..d74ddf2e 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -26,7 +26,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 8a6b7075..6c3db21b 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -27,7 +27,7 @@ - + From dc8f0037e5775b50a48f3c86aec1672d2a2c52ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 May 2023 17:59:08 +1000 Subject: [PATCH 122/313] Bump Verify.NUnit from 20.0.0 to 20.3.0 in /src (#54) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 20.0.0 to 20.3.0. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/compare/20.0.0...20.3.0) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 74be0996..1dc15bdf 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index d1bbcc7d..f8d31e17 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index d74ddf2e..27a3458f 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 6c3db21b..f39b5d7a 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 004ff6a121253071a152e4d642495e94a027c412 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 3 Jun 2023 09:10:57 +1000 Subject: [PATCH 123/313] Bump Microsoft.NET.Test.Sdk from 17.6.0 to 17.6.1 in /src (#56) Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.6.0 to 17.6.1. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.6.0...v17.6.1) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 1dc15bdf..439912ce 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -33,7 +33,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index f8d31e17..60afdf87 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 27a3458f..a916edf1 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index f39b5d7a..d18d5a76 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -28,7 +28,7 @@ - + From 9f13a23189393bb8eedc04dd56f60dd95b5a3d0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 19:33:29 +1000 Subject: [PATCH 124/313] Bump Verify.NUnit from 20.3.0 to 20.3.2 in /src (#58) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 20.3.0 to 20.3.2. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/compare/20.3.0...20.3.2) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 439912ce..c2898f4e 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 60afdf87..ad2fc180 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index a916edf1..2c48cec3 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index d18d5a76..a202bce5 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 8002b1205cd3a6a24222944960051c91701b5cd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jun 2023 21:52:13 +1000 Subject: [PATCH 125/313] Bump Microsoft.NET.Test.Sdk from 17.6.1 to 17.6.2 in /src (#59) Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.6.1 to 17.6.2. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.6.1...v17.6.2) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index c2898f4e..9f03e60f 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -33,7 +33,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index ad2fc180..6ce42ea8 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 2c48cec3..0827b9db 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index a202bce5..856fc937 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -28,7 +28,7 @@ - + From 3182da82aec4e43f7889812f316a30486db83a69 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 13 Jun 2023 20:59:40 +1000 Subject: [PATCH 126/313] Update .editorconfig --- src/.editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/.editorconfig b/src/.editorconfig index 7542ee3a..196bb349 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -84,7 +84,7 @@ resharper_suggest_var_or_type_elsewhere_highlighting = hint resharper_suggest_var_or_type_simple_types_highlighting = hint resharper_unnecessary_whitespace_highlighting = error resharper_use_await_using_highlighting = warning -resharper_use_deconstruction_highlighting = warning +resharper_use_deconstruction_highlighting = error # Sort using and Import directives with System.* appearing first dotnet_sort_system_directives_first = true From ca18a172857248c6d6e02cb1aff89bc119e79a08 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 14 Jun 2023 22:29:39 +1000 Subject: [PATCH 127/313] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index f7f340bc..fa7caa51 100644 --- a/readme.md +++ b/readme.md @@ -36,7 +36,7 @@ This project uses features from the current stable SDK and C# language. As such ```json { "sdk": { - "version": "7.0.203", + "version": "7.0.304", "rollForward": "latestFeature" } } From 3130ec75f921cc200cde9542fde4984b166dc067 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:54:13 +1000 Subject: [PATCH 128/313] Bump ProjectDefaults from 1.0.90 to 1.0.91 in /src (#60) Bumps [ProjectDefaults](https://github.com/SimonCropp/ProjectDefaults) from 1.0.90 to 1.0.91. - [Commits](https://github.com/SimonCropp/ProjectDefaults/commits) --- updated-dependencies: - dependency-name: ProjectDefaults dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/Polyfill/Polyfill.csproj | 4 ++-- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 9f03e60f..16702e43 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -34,7 +34,7 @@ - + diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index 70532cff..be1401f9 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -1,11 +1,11 @@ - + netstandard2.0 Polyfill.nuspec Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 6ce42ea8..cde6be64 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 0827b9db..e84cd2d8 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 856fc937..0f2b0424 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -29,7 +29,7 @@ - + From 9c01f802481724ea2e039a3134a1304546799b44 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 18:22:39 +1000 Subject: [PATCH 129/313] Bump Verify.NUnit from 20.3.2 to 20.4.0 in /src (#61) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 20.3.2 to 20.4.0. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/compare/20.3.2...20.4.0) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 16702e43..8231659e 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index cde6be64..4497f8a5 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index e84cd2d8..22159c97 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 0f2b0424..8acb3451 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From eb722efe7a96980e047f50fa49d6a7f52733fd9f Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 21 Jun 2023 15:34:37 +1000 Subject: [PATCH 130/313] Update NullabilitySamples.cs --- src/Tests/NullabilitySamples.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Tests/NullabilitySamples.cs b/src/Tests/NullabilitySamples.cs index 1281c1ed..e6c5ee21 100644 --- a/src/Tests/NullabilitySamples.cs +++ b/src/Tests/NullabilitySamples.cs @@ -43,6 +43,7 @@ public void ExtensionTests() #endregion // ReSharper disable UnusedMember.Local + // ReSharper disable NotAccessedField.Local class PropertyTarget { string? write; @@ -54,6 +55,7 @@ public string? Write set => write = value; } } + // ReSharper restore NotAccessedField.Local // ReSharper restore UnusedMember.Local [Test] From edc5688ca7142e474c22a7e11c78754884fb632d Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 24 Jun 2023 19:42:51 +1000 Subject: [PATCH 131/313] Update global.json --- src/global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/global.json b/src/global.json index 8b443f2f..0409d240 100644 --- a/src/global.json +++ b/src/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100-preview.2.23157.25", + "version": "8.0.100-preview.5.23303.2", "allowPrerelease": true, "rollForward": "latestFeature" } From 2ea49bc094519e8042a8201869b4034ec4f95bb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Jun 2023 19:57:26 +1000 Subject: [PATCH 132/313] Bump Microsoft.NET.Test.Sdk from 17.6.2 to 17.6.3 in /src (#62) Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.6.2 to 17.6.3. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.6.2...v17.6.3) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 8231659e..ed5b6703 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -33,7 +33,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 4497f8a5..86514b61 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 22159c97..b8bfdb8f 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 8acb3451..ed30e3fd 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -28,7 +28,7 @@ - + From 97fa845a46ea8e007e23812760de90a484d3dea7 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 10 Jul 2023 13:24:49 +1000 Subject: [PATCH 133/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index ed5b6703..8a9a89cb 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 86514b61..18c69bf7 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index b8bfdb8f..af0c8314 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index ed30e3fd..5eb4a5da 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 9f07afdf8ff162b97c2ee4faacc0babb153c197e Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 12 Jul 2023 22:01:53 +1000 Subject: [PATCH 134/313] refs --- readme.md | 2 +- src/global.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index fa7caa51..3fc008f7 100644 --- a/readme.md +++ b/readme.md @@ -36,7 +36,7 @@ This project uses features from the current stable SDK and C# language. As such ```json { "sdk": { - "version": "7.0.304", + "version": "7.0.306", "rollForward": "latestFeature" } } diff --git a/src/global.json b/src/global.json index 0409d240..7dc80be7 100644 --- a/src/global.json +++ b/src/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100-preview.5.23303.2", + "version": "8.0.100-preview.6.23330.14", "allowPrerelease": true, "rollForward": "latestFeature" } From cb990188f729859d373827f04687dcbe24e6e277 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 19:39:51 +1000 Subject: [PATCH 135/313] Bump Verify.NUnit from 20.5.0 to 20.5.1 in /src (#63) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 20.5.0 to 20.5.1. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/compare/20.5.0...20.5.1) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 8a9a89cb..ccca569b 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 18c69bf7..2a782482 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index af0c8314..eafa6603 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 5eb4a5da..9036e593 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From c00114999d708ef38b1612541318eca3aee9ebcc Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 19 Jul 2023 22:10:53 +1000 Subject: [PATCH 136/313] Update Directory.Build.props --- src/Directory.Build.props | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 851a21eb..5a1a21be 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -6,7 +6,8 @@ Polyfill true false - CS1591;NETSDK1138 + CS1591;NETSDK1138;NU1901;NU1902 + false 11 false true From b0395d20fe1299ec43654ef1c1ca6b97e2ceb731 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 19 Jul 2023 22:30:12 +1000 Subject: [PATCH 137/313] Update PolyfillExtensions_String.cs --- src/Polyfill/PolyfillExtensions_String.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/PolyfillExtensions_String.cs index 684584e8..52e33a57 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/PolyfillExtensions_String.cs @@ -51,6 +51,7 @@ static StringComparer FromComparison(StringComparison comparison) => StringComparison.InvariantCultureIgnoreCase => StringComparer.InvariantCultureIgnoreCase, StringComparison.Ordinal => StringComparer.Ordinal, StringComparison.OrdinalIgnoreCase => StringComparer.OrdinalIgnoreCase, + _ => throw new ArgumentOutOfRangeException(nameof(comparison), comparison, null) }; /// From 538a0bac119f81cf238878ccb916e509d0fbb608 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 19 Jul 2023 22:40:42 +1000 Subject: [PATCH 138/313] remove some warning disable --- src/Polyfill/IndexRange/Index.cs | 2 -- src/Polyfill/PolyfillExtensions_String.cs | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/Polyfill/IndexRange/Index.cs b/src/Polyfill/IndexRange/Index.cs index 9cf0638a..383be217 100644 --- a/src/Polyfill/IndexRange/Index.cs +++ b/src/Polyfill/IndexRange/Index.cs @@ -1,7 +1,5 @@ #if (NET46X && VALUETUPLEREFERENCED) || NET47X || NET48X || NETSTANDARD2_0 || NETCOREAPP2X -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global using System.Diagnostics; diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/PolyfillExtensions_String.cs index 52e33a57..dd8c87f4 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/PolyfillExtensions_String.cs @@ -1,6 +1,4 @@ -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable PartialTypeWithSinglePart From dfedfb4b715d9f389ba6a6198506aeda3d8a94b5 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 19 Jul 2023 22:43:19 +1000 Subject: [PATCH 139/313] remove some warning disable --- src/Polyfill/CompilerFeatureRequiredAttribute.cs | 2 -- src/Polyfill/DisableRuntimeMarshallingAttribute.cs | 2 -- src/Polyfill/IndexRange/Range.cs | 2 -- src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs | 2 -- src/Polyfill/InterpolatedStringHandlerAttribute.cs | 2 -- src/Polyfill/IsExternalInit.cs | 2 -- src/Polyfill/Nullable/MaybeNullWhenAttribute.cs | 2 -- src/Polyfill/Nullable/MemberNotNullAttribute.cs | 2 -- src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs | 2 -- 9 files changed, 18 deletions(-) diff --git a/src/Polyfill/CompilerFeatureRequiredAttribute.cs b/src/Polyfill/CompilerFeatureRequiredAttribute.cs index 7ee92224..f36cf542 100644 --- a/src/Polyfill/CompilerFeatureRequiredAttribute.cs +++ b/src/Polyfill/CompilerFeatureRequiredAttribute.cs @@ -1,7 +1,5 @@ #if !NET7_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/DisableRuntimeMarshallingAttribute.cs b/src/Polyfill/DisableRuntimeMarshallingAttribute.cs index b5b6429d..c334141c 100644 --- a/src/Polyfill/DisableRuntimeMarshallingAttribute.cs +++ b/src/Polyfill/DisableRuntimeMarshallingAttribute.cs @@ -1,7 +1,5 @@ #if !NET7_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/IndexRange/Range.cs b/src/Polyfill/IndexRange/Range.cs index 7e1e9a07..0b5d269e 100644 --- a/src/Polyfill/IndexRange/Range.cs +++ b/src/Polyfill/IndexRange/Range.cs @@ -1,7 +1,5 @@ #if (NET46X && VALUETUPLEREFERENCED) || NET47X || NET48X || NETSTANDARD2_0 || NETCOREAPP2X -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs b/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs index 6907b727..6b496014 100644 --- a/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs +++ b/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs @@ -1,7 +1,5 @@ #if !NET6_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedType.Global diff --git a/src/Polyfill/InterpolatedStringHandlerAttribute.cs b/src/Polyfill/InterpolatedStringHandlerAttribute.cs index 36742c9e..9857ac1b 100644 --- a/src/Polyfill/InterpolatedStringHandlerAttribute.cs +++ b/src/Polyfill/InterpolatedStringHandlerAttribute.cs @@ -1,7 +1,5 @@ #if !NET6_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedType.Global diff --git a/src/Polyfill/IsExternalInit.cs b/src/Polyfill/IsExternalInit.cs index efad1be1..00edae1a 100644 --- a/src/Polyfill/IsExternalInit.cs +++ b/src/Polyfill/IsExternalInit.cs @@ -1,7 +1,5 @@ #if !NET5_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/Nullable/MaybeNullWhenAttribute.cs b/src/Polyfill/Nullable/MaybeNullWhenAttribute.cs index 7c65361e..d3ffc190 100644 --- a/src/Polyfill/Nullable/MaybeNullWhenAttribute.cs +++ b/src/Polyfill/Nullable/MaybeNullWhenAttribute.cs @@ -1,7 +1,5 @@ #if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/Nullable/MemberNotNullAttribute.cs b/src/Polyfill/Nullable/MemberNotNullAttribute.cs index 5b2b7c65..12afba4d 100644 --- a/src/Polyfill/Nullable/MemberNotNullAttribute.cs +++ b/src/Polyfill/Nullable/MemberNotNullAttribute.cs @@ -1,7 +1,5 @@ #if NETSTANDARD || NETFRAMEWORK || NETCOREAPPX -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs b/src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs index ea9e1be7..342617f4 100644 --- a/src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs +++ b/src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs @@ -1,7 +1,5 @@ #if NETSTANDARD || NETFRAMEWORK || NETCOREAPPX -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global From 964ed338a618b396ce6649aad6e72e7ad6bf6927 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 19 Jul 2023 22:45:53 +1000 Subject: [PATCH 140/313] remove some warning disable --- contributing.md | 4 +--- src/Polyfill/CallerArgumentExpressionAttribute.cs | 2 -- src/Polyfill/ModuleInitializerAttribute.cs | 2 -- src/Polyfill/Nullable/AllowNullAttribute.cs | 2 -- src/Polyfill/Nullable/DisallowNullAttribute.cs | 2 -- src/Polyfill/Nullable/DoesNotReturnAttribute.cs | 2 -- src/Polyfill/Nullable/DoesNotReturnIfAttribute.cs | 2 -- src/Polyfill/Nullable/MaybeNullAttribute.cs | 2 -- src/Polyfill/Nullable/NotNullAttribute.cs | 2 -- src/Polyfill/Nullable/NotNullIfNotNullAttribute.cs | 2 -- src/Polyfill/Nullable/NotNullWhenAttribute.cs | 2 -- src/Polyfill/PlatformCompatibility/TargetPlatformAttribute.cs | 2 -- 12 files changed, 1 insertion(+), 25 deletions(-) diff --git a/contributing.md b/contributing.md index f652729f..65bdf664 100644 --- a/contributing.md +++ b/contributing.md @@ -131,8 +131,6 @@ Example: ```cs #if !NET5_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global @@ -176,7 +174,7 @@ sealed class ModuleInitializerAttribute : #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Polyfill/CallerArgumentExpressionAttribute.cs b/src/Polyfill/CallerArgumentExpressionAttribute.cs index bd326d54..621a6e00 100644 --- a/src/Polyfill/CallerArgumentExpressionAttribute.cs +++ b/src/Polyfill/CallerArgumentExpressionAttribute.cs @@ -1,7 +1,5 @@ #if NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/ModuleInitializerAttribute.cs b/src/Polyfill/ModuleInitializerAttribute.cs index 7bcd75ac..01058773 100644 --- a/src/Polyfill/ModuleInitializerAttribute.cs +++ b/src/Polyfill/ModuleInitializerAttribute.cs @@ -1,7 +1,5 @@ #if !NET5_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/Nullable/AllowNullAttribute.cs b/src/Polyfill/Nullable/AllowNullAttribute.cs index b91598df..69045184 100644 --- a/src/Polyfill/Nullable/AllowNullAttribute.cs +++ b/src/Polyfill/Nullable/AllowNullAttribute.cs @@ -1,7 +1,5 @@ #if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/Nullable/DisallowNullAttribute.cs b/src/Polyfill/Nullable/DisallowNullAttribute.cs index 4a0fe5c9..9b06ddc4 100644 --- a/src/Polyfill/Nullable/DisallowNullAttribute.cs +++ b/src/Polyfill/Nullable/DisallowNullAttribute.cs @@ -1,7 +1,5 @@ #if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/Nullable/DoesNotReturnAttribute.cs b/src/Polyfill/Nullable/DoesNotReturnAttribute.cs index bed703f1..774edd1b 100644 --- a/src/Polyfill/Nullable/DoesNotReturnAttribute.cs +++ b/src/Polyfill/Nullable/DoesNotReturnAttribute.cs @@ -1,7 +1,5 @@ #if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/Nullable/DoesNotReturnIfAttribute.cs b/src/Polyfill/Nullable/DoesNotReturnIfAttribute.cs index d2928bab..6c21e1f1 100644 --- a/src/Polyfill/Nullable/DoesNotReturnIfAttribute.cs +++ b/src/Polyfill/Nullable/DoesNotReturnIfAttribute.cs @@ -1,7 +1,5 @@ #if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/Nullable/MaybeNullAttribute.cs b/src/Polyfill/Nullable/MaybeNullAttribute.cs index 3464386b..7c365469 100644 --- a/src/Polyfill/Nullable/MaybeNullAttribute.cs +++ b/src/Polyfill/Nullable/MaybeNullAttribute.cs @@ -1,7 +1,5 @@ #if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/Nullable/NotNullAttribute.cs b/src/Polyfill/Nullable/NotNullAttribute.cs index 682aee5a..e4f1406e 100644 --- a/src/Polyfill/Nullable/NotNullAttribute.cs +++ b/src/Polyfill/Nullable/NotNullAttribute.cs @@ -1,7 +1,5 @@ #if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/Nullable/NotNullIfNotNullAttribute.cs b/src/Polyfill/Nullable/NotNullIfNotNullAttribute.cs index 96f8be0f..baa67665 100644 --- a/src/Polyfill/Nullable/NotNullIfNotNullAttribute.cs +++ b/src/Polyfill/Nullable/NotNullIfNotNullAttribute.cs @@ -1,7 +1,5 @@ #if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/Nullable/NotNullWhenAttribute.cs b/src/Polyfill/Nullable/NotNullWhenAttribute.cs index 8e775192..514559c4 100644 --- a/src/Polyfill/Nullable/NotNullWhenAttribute.cs +++ b/src/Polyfill/Nullable/NotNullWhenAttribute.cs @@ -1,7 +1,5 @@ #if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/PlatformCompatibility/TargetPlatformAttribute.cs b/src/Polyfill/PlatformCompatibility/TargetPlatformAttribute.cs index 6830d290..62f235df 100644 --- a/src/Polyfill/PlatformCompatibility/TargetPlatformAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/TargetPlatformAttribute.cs @@ -1,7 +1,5 @@ #if !NET5_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable PartialTypeWithSinglePart From 61e9ff92f81af9cb218a680968b6197992dc5100 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 19 Jul 2023 22:49:40 +1000 Subject: [PATCH 141/313] remove warning disable --- contributing.md | 4 +--- src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs | 2 -- src/Polyfill/PolyfillExtensions_HttpClient.cs | 2 -- src/Polyfill/PolyfillExtensions_HttpContent.cs | 2 -- src/Polyfill/PolyfillExtensions_KeyValuePair.cs | 2 -- src/Polyfill/PolyfillExtensions_Memory.cs | 2 -- src/Polyfill/PolyfillExtensions_MicroNanosecond.cs | 2 -- src/Polyfill/PolyfillExtensions_Stream.cs | 2 -- src/Polyfill/PolyfillExtensions_StringBuilder.cs | 2 -- src/Polyfill/PolyfillExtensions_Task.cs | 2 -- src/Polyfill/PolyfillExtensions_TextReader.cs | 2 -- src/Polyfill/PolyfillExtensions_TextWriter.cs | 2 -- src/Polyfill/PolyfillExtensions_Type.cs | 2 -- src/Polyfill/SetsRequiredMembersAttribute.cs | 2 -- src/Polyfill/SkipLocalsInitAttribute.cs | 2 -- src/Polyfill/StackTraceHiddenAttribute.cs | 2 -- src/Polyfill/SuppressGCTransitionAttribute.cs | 2 -- src/Polyfill/Trimming/DynamicallyAccessedMemberTypes.cs | 2 -- 18 files changed, 1 insertion(+), 37 deletions(-) diff --git a/contributing.md b/contributing.md index 65bdf664..f6493ed1 100644 --- a/contributing.md +++ b/contributing.md @@ -189,8 +189,6 @@ Example: ```cs #if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global @@ -305,7 +303,7 @@ static partial class PolyfillExtensions } #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs b/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs index 2e6b64ea..ba522d41 100644 --- a/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs +++ b/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs @@ -1,6 +1,4 @@ -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable PartialTypeWithSinglePart // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/PolyfillExtensions_HttpClient.cs b/src/Polyfill/PolyfillExtensions_HttpClient.cs index 75f68e2a..68f1710c 100644 --- a/src/Polyfill/PolyfillExtensions_HttpClient.cs +++ b/src/Polyfill/PolyfillExtensions_HttpClient.cs @@ -1,7 +1,5 @@ #if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD || NETCOREAPP2X || NETCOREAPP3X) -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global // ReSharper disable RedundantAttributeSuffix diff --git a/src/Polyfill/PolyfillExtensions_HttpContent.cs b/src/Polyfill/PolyfillExtensions_HttpContent.cs index ad5239dd..37912320 100644 --- a/src/Polyfill/PolyfillExtensions_HttpContent.cs +++ b/src/Polyfill/PolyfillExtensions_HttpContent.cs @@ -1,7 +1,5 @@ #if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD || NETCOREAPP2X || NETCOREAPP3X) -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable RedundantAttributeSuffix // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs index 3c2e2455..ecb1f176 100644 --- a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs +++ b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs @@ -1,7 +1,5 @@ #if NETFRAMEWORK || NETSTANDARD2_0 -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable PartialTypeWithSinglePart // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index 1d6cceea..9cb54031 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -1,7 +1,5 @@ #if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X) -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global // ReSharper disable RedundantAttributeSuffix diff --git a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs index d174d398..5d9a7072 100644 --- a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs +++ b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs @@ -1,6 +1,4 @@ -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable PartialTypeWithSinglePart // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index 1540678e..8bcebe2e 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -1,7 +1,5 @@ #if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/PolyfillExtensions_StringBuilder.cs b/src/Polyfill/PolyfillExtensions_StringBuilder.cs index cd7d64d6..6cd1a011 100644 --- a/src/Polyfill/PolyfillExtensions_StringBuilder.cs +++ b/src/Polyfill/PolyfillExtensions_StringBuilder.cs @@ -1,7 +1,5 @@ #if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/PolyfillExtensions_Task.cs index fd0557cb..98deb6e7 100644 --- a/src/Polyfill/PolyfillExtensions_Task.cs +++ b/src/Polyfill/PolyfillExtensions_Task.cs @@ -1,7 +1,5 @@ #if NETFRAMEWORK || NETSTANDARD || NETCOREAPP || NET5_0 -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable PartialTypeWithSinglePart // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/PolyfillExtensions_TextReader.cs b/src/Polyfill/PolyfillExtensions_TextReader.cs index 1c3f85fd..d756d401 100644 --- a/src/Polyfill/PolyfillExtensions_TextReader.cs +++ b/src/Polyfill/PolyfillExtensions_TextReader.cs @@ -1,5 +1,3 @@ -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/PolyfillExtensions_TextWriter.cs b/src/Polyfill/PolyfillExtensions_TextWriter.cs index 7967087a..894e6e8d 100644 --- a/src/Polyfill/PolyfillExtensions_TextWriter.cs +++ b/src/Polyfill/PolyfillExtensions_TextWriter.cs @@ -1,7 +1,5 @@ #if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/PolyfillExtensions_Type.cs b/src/Polyfill/PolyfillExtensions_Type.cs index 4db2fa07..b0eb413d 100644 --- a/src/Polyfill/PolyfillExtensions_Type.cs +++ b/src/Polyfill/PolyfillExtensions_Type.cs @@ -1,6 +1,4 @@ -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable PartialTypeWithSinglePart // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/SetsRequiredMembersAttribute.cs b/src/Polyfill/SetsRequiredMembersAttribute.cs index 634ad6e1..9ccd7247 100644 --- a/src/Polyfill/SetsRequiredMembersAttribute.cs +++ b/src/Polyfill/SetsRequiredMembersAttribute.cs @@ -1,7 +1,5 @@ #if !NET7_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/SkipLocalsInitAttribute.cs b/src/Polyfill/SkipLocalsInitAttribute.cs index 4e3b2ba1..a84c975f 100644 --- a/src/Polyfill/SkipLocalsInitAttribute.cs +++ b/src/Polyfill/SkipLocalsInitAttribute.cs @@ -1,7 +1,5 @@ #if !NET5_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/StackTraceHiddenAttribute.cs b/src/Polyfill/StackTraceHiddenAttribute.cs index 22e45c99..fdc4430b 100644 --- a/src/Polyfill/StackTraceHiddenAttribute.cs +++ b/src/Polyfill/StackTraceHiddenAttribute.cs @@ -1,7 +1,5 @@ #if !NET6_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/SuppressGCTransitionAttribute.cs b/src/Polyfill/SuppressGCTransitionAttribute.cs index e66fd1ca..98b3b0c0 100644 --- a/src/Polyfill/SuppressGCTransitionAttribute.cs +++ b/src/Polyfill/SuppressGCTransitionAttribute.cs @@ -1,7 +1,5 @@ #if !NET5_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/Trimming/DynamicallyAccessedMemberTypes.cs b/src/Polyfill/Trimming/DynamicallyAccessedMemberTypes.cs index 054e7d78..437ddcf7 100644 --- a/src/Polyfill/Trimming/DynamicallyAccessedMemberTypes.cs +++ b/src/Polyfill/Trimming/DynamicallyAccessedMemberTypes.cs @@ -1,7 +1,5 @@ #if !NET5_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global From e67aba31e6e1a73c82dbdd99081d9a87dfed6895 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 19 Jul 2023 22:51:35 +1000 Subject: [PATCH 142/313] remove some warning disable --- src/Polyfill/PolyfillExtensions.cs | 2 -- src/Polyfill/RequiredMemberAttribute.cs | 2 -- src/Polyfill/ResolveHttpGlobalProblem.cs | 2 -- src/Polyfill/Trimming/DynamicallyAccessedMembersAttribute.cs | 2 -- src/Polyfill/UnscopedRefAttribute.cs | 2 -- 5 files changed, 10 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions.cs b/src/Polyfill/PolyfillExtensions.cs index 1fcfa293..18979245 100644 --- a/src/Polyfill/PolyfillExtensions.cs +++ b/src/Polyfill/PolyfillExtensions.cs @@ -1,5 +1,3 @@ -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable PartialTypeWithSinglePart diff --git a/src/Polyfill/RequiredMemberAttribute.cs b/src/Polyfill/RequiredMemberAttribute.cs index d74a11ea..a3459ba9 100644 --- a/src/Polyfill/RequiredMemberAttribute.cs +++ b/src/Polyfill/RequiredMemberAttribute.cs @@ -1,7 +1,5 @@ #if !NET7_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/ResolveHttpGlobalProblem.cs b/src/Polyfill/ResolveHttpGlobalProblem.cs index 140d0070..174317c0 100644 --- a/src/Polyfill/ResolveHttpGlobalProblem.cs +++ b/src/Polyfill/ResolveHttpGlobalProblem.cs @@ -1,7 +1,5 @@ #if NETFRAMEWORK -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable PartialTypeWithSinglePart // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/Trimming/DynamicallyAccessedMembersAttribute.cs b/src/Polyfill/Trimming/DynamicallyAccessedMembersAttribute.cs index 4bbb2733..7240ad39 100644 --- a/src/Polyfill/Trimming/DynamicallyAccessedMembersAttribute.cs +++ b/src/Polyfill/Trimming/DynamicallyAccessedMembersAttribute.cs @@ -1,7 +1,5 @@ #if !NET5_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global diff --git a/src/Polyfill/UnscopedRefAttribute.cs b/src/Polyfill/UnscopedRefAttribute.cs index 330daefa..caf4c75f 100644 --- a/src/Polyfill/UnscopedRefAttribute.cs +++ b/src/Polyfill/UnscopedRefAttribute.cs @@ -1,7 +1,5 @@ #if !NET7_0_OR_GREATER -#pragma warning disable - // ReSharper disable RedundantUsingDirective // ReSharper disable UnusedMember.Global From cb9f41f805d869c2c46654f02653140a43f8a86e Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 19 Jul 2023 23:03:45 +1000 Subject: [PATCH 143/313] Update UnsupportedOSPlatformAttribute.cs --- .../PlatformCompatibility/UnsupportedOSPlatformAttribute.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformAttribute.cs b/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformAttribute.cs index 8c2b0585..911f8683 100644 --- a/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformAttribute.cs @@ -1,7 +1,5 @@ #if !NET5_0_OR_GREATER -#pragma warning disable - #nullable enable // ReSharper disable RedundantUsingDirective From c2361962a601e10e674ecf740df5711671937ebd Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 19 Jul 2023 23:10:36 +1000 Subject: [PATCH 144/313] remove some warning disable --- src/Polyfill/StringSyntaxAttribute.cs | 1 - src/Polyfill/Trimming/DynamicDependencyAttribute.cs | 1 - src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs | 1 - src/Polyfill/Trimming/UnconditionalSuppressMessageAttribute.cs | 1 - src/Polyfill/UnmanagedCallersOnlyAttribute.cs | 1 - 5 files changed, 5 deletions(-) diff --git a/src/Polyfill/StringSyntaxAttribute.cs b/src/Polyfill/StringSyntaxAttribute.cs index d22488b2..f256710e 100644 --- a/src/Polyfill/StringSyntaxAttribute.cs +++ b/src/Polyfill/StringSyntaxAttribute.cs @@ -1,6 +1,5 @@ #if !NET7_0_OR_GREATER -#pragma warning disable #nullable enable // ReSharper disable RedundantUsingDirective diff --git a/src/Polyfill/Trimming/DynamicDependencyAttribute.cs b/src/Polyfill/Trimming/DynamicDependencyAttribute.cs index a1c0e7e9..9ca4313b 100644 --- a/src/Polyfill/Trimming/DynamicDependencyAttribute.cs +++ b/src/Polyfill/Trimming/DynamicDependencyAttribute.cs @@ -1,6 +1,5 @@ #if !NET5_0_OR_GREATER -#pragma warning disable #nullable enable // ReSharper disable RedundantUsingDirective diff --git a/src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs b/src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs index eff9a41e..1ddba848 100644 --- a/src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs +++ b/src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs @@ -1,6 +1,5 @@ #if !NET7_0_OR_GREATER -#pragma warning disable #nullable enable // ReSharper disable RedundantUsingDirective diff --git a/src/Polyfill/Trimming/UnconditionalSuppressMessageAttribute.cs b/src/Polyfill/Trimming/UnconditionalSuppressMessageAttribute.cs index 8b5262fd..62a17b22 100644 --- a/src/Polyfill/Trimming/UnconditionalSuppressMessageAttribute.cs +++ b/src/Polyfill/Trimming/UnconditionalSuppressMessageAttribute.cs @@ -1,6 +1,5 @@ #if !NET5_0_OR_GREATER -#pragma warning disable #nullable enable // ReSharper disable RedundantUsingDirective diff --git a/src/Polyfill/UnmanagedCallersOnlyAttribute.cs b/src/Polyfill/UnmanagedCallersOnlyAttribute.cs index 889a9638..c10054f9 100644 --- a/src/Polyfill/UnmanagedCallersOnlyAttribute.cs +++ b/src/Polyfill/UnmanagedCallersOnlyAttribute.cs @@ -1,6 +1,5 @@ #if !NET5_0_OR_GREATER -#pragma warning disable #nullable enable // ReSharper disable RedundantUsingDirective From 8aea3183487d95edfccd63fc7f82b7ae86467e33 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 20:46:29 +1000 Subject: [PATCH 145/313] Bump Verify.NUnit from 20.5.1 to 20.6.0 in /src (#66) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 20.5.1 to 20.6.0. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/compare/20.5.1...20.6.0) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index ccca569b..20f3f183 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 2a782482..17dba743 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index eafa6603..7300a4c2 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 9036e593..05f40a8d 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 38dfbb8dad9a728e437bae263004f3edbe14541b Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 28 Jul 2023 10:32:54 +1000 Subject: [PATCH 146/313] suppress CS1573 --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 5a1a21be..474fbad3 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -6,7 +6,7 @@ Polyfill true false - CS1591;NETSDK1138;NU1901;NU1902 + CS1573;CS1591;NETSDK1138;NU1901;NU1902 false 11 false From d8d6fabd59a42b4baecb16c3e2a6babb076874b8 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 28 Jul 2023 10:34:02 +1000 Subject: [PATCH 147/313] Update PolyfillExtensions_HttpClient.cs --- src/Polyfill/PolyfillExtensions_HttpClient.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_HttpClient.cs b/src/Polyfill/PolyfillExtensions_HttpClient.cs index 68f1710c..37b5cc7e 100644 --- a/src/Polyfill/PolyfillExtensions_HttpClient.cs +++ b/src/Polyfill/PolyfillExtensions_HttpClient.cs @@ -17,7 +17,7 @@ static partial class PolyfillExtensions /// Send a GET request to the specified Uri and return the response body as a stream in an asynchronous operation. /// /// - /// This operation will not block. The returned object will complete after the response headers are read. + /// This operation will not block. The returned object will complete after the response headers are read. /// This method does not read nor buffer the response body. /// /// The Uri the request is sent to. @@ -55,7 +55,7 @@ public static async Task GetStreamAsync( /// Send a GET request to the specified Uri and return the response body as a stream in an asynchronous operation. /// /// - /// This operation will not block. The returned object will complete after the response headers are read. + /// This operation will not block. The returned object will complete after the response headers are read. /// This method does not read nor buffer the response body. /// /// The Uri the request is sent to. @@ -72,7 +72,7 @@ public static Task GetStreamAsync( /// Send a GET request to the specified Uri and return the response body as a byte array in an asynchronous operation. /// /// - /// This operation will not block. The returned object will complete after the response headers are read. + /// This operation will not block. The returned Task{Byte[]} object will complete after the response headers are read. /// This method does not read nor buffer the response body. /// /// The Uri the request is sent to. @@ -109,7 +109,7 @@ public static async Task GetByteArrayAsync( /// Send a GET request to the specified Uri and return the response body as a byte array in an asynchronous operation. /// /// - /// This operation will not block. The returned object will complete after the response headers are read. + /// This operation will not block. The returned Task{byte[]} object will complete after the response headers are read. /// This method does not read nor buffer the response body. /// /// The Uri the request is sent to. @@ -126,7 +126,7 @@ public static Task GetByteArrayAsync( /// Send a GET request to the specified Uri and return the response body as a string in an asynchronous operation. /// /// - /// This operation will not block. The returned object will complete after the response headers are read. + /// This operation will not block. The returned object will complete after the response headers are read. /// This method does not read nor buffer the response body. /// /// The Uri the request is sent to. @@ -163,7 +163,7 @@ public static async Task GetStringAsync( /// Send a GET request to the specified Uri and return the response body as a string in an asynchronous operation. /// /// - /// This operation will not block. The returned object will complete after the response headers are read. + /// This operation will not block. The returned object will complete after the response headers are read. /// This method does not read nor buffer the response body. /// /// The Uri the request is sent to. From 3053c170cdfa824bdec554307c8c667bc669c4d7 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 28 Jul 2023 10:34:06 +1000 Subject: [PATCH 148/313] Update PolyfillExtensions_KeyValuePair.cs --- src/Polyfill/PolyfillExtensions_KeyValuePair.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs index ecb1f176..7a63a7e6 100644 --- a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs +++ b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs @@ -12,10 +12,10 @@ static partial class PolyfillExtensions { /// - /// Deconstructs the current + /// Deconstructs the current /// - /// The key of the current . - /// The value of the current . + /// The key of the current . + /// The value of the current . [Link("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct")] public static void Deconstruct( this KeyValuePair target, From 2e363227a845ca77753663270fbb952178201185 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 28 Jul 2023 10:34:19 +1000 Subject: [PATCH 149/313] Update PolyfillExtensions_TextWriter.cs --- src/Polyfill/PolyfillExtensions_TextWriter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_TextWriter.cs b/src/Polyfill/PolyfillExtensions_TextWriter.cs index 894e6e8d..e34b0257 100644 --- a/src/Polyfill/PolyfillExtensions_TextWriter.cs +++ b/src/Polyfill/PolyfillExtensions_TextWriter.cs @@ -20,7 +20,7 @@ static partial class PolyfillExtensions /// The character memory region to write to the stream. /// /// The token to monitor for cancellation requests. - /// The default value is . + /// The default value is . /// /// A task that represents the asynchronous write operation. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] @@ -46,7 +46,7 @@ public static ValueTask WriteAsync( /// The character memory region to write to the stream. /// /// The token to monitor for cancellation requests. - /// The default value is . + /// The default value is . /// /// A task that represents the asynchronous write operation. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] From 396d7a69fd4a160c99da47e6d2d47cb672a1a277 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 28 Jul 2023 10:38:59 +1000 Subject: [PATCH 150/313] suppress CS1591 --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 474fbad3..ea40c292 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -6,7 +6,7 @@ Polyfill true false - CS1573;CS1591;NETSDK1138;NU1901;NU1902 + CS1573;CS1573;CS1591;NETSDK1138;NU1901;NU1902 false 11 false From 98e62ede33f83bf6f3472f2523d07ec20adb4a5f Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 28 Jul 2023 11:00:44 +1000 Subject: [PATCH 151/313] cleanup --- contributing.md | 4 +-- src/Polyfill/PolyfillExtensions_HttpClient.cs | 24 ++++++------- .../PolyfillExtensions_HttpContent.cs | 12 +++---- .../PolyfillExtensions_IEnumerable.cs | 36 ++++++++++++------- src/Polyfill/PolyfillExtensions_Memory.cs | 34 +++++++++++++----- src/Polyfill/PolyfillExtensions_Task.cs | 34 ++++++++++++------ src/Polyfill/PolyfillExtensions_TryFormat.cs | 3 +- src/Polyfill/PolyfillExtensions_Type.cs | 4 ++- 8 files changed, 98 insertions(+), 53 deletions(-) diff --git a/contributing.md b/contributing.md index f6493ed1..dbe61d0a 100644 --- a/contributing.md +++ b/contributing.md @@ -209,7 +209,7 @@ static partial class PolyfillExtensions /// The character memory region to write to the stream. /// /// The token to monitor for cancellation requests. - /// The default value is . + /// The default value is . /// /// A task that represents the asynchronous write operation. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] @@ -235,7 +235,7 @@ static partial class PolyfillExtensions /// The character memory region to write to the stream. /// /// The token to monitor for cancellation requests. - /// The default value is . + /// The default value is . /// /// A task that represents the asynchronous write operation. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)")] diff --git a/src/Polyfill/PolyfillExtensions_HttpClient.cs b/src/Polyfill/PolyfillExtensions_HttpClient.cs index 37b5cc7e..01ac1fdf 100644 --- a/src/Polyfill/PolyfillExtensions_HttpClient.cs +++ b/src/Polyfill/PolyfillExtensions_HttpClient.cs @@ -25,14 +25,14 @@ static partial class PolyfillExtensions /// The task object representing the asynchronous operation. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)")] public static async Task GetStreamAsync( - this HttpClient httpClient, + this HttpClient target, string requestUri, CancellationToken cancellationToken = default) { try { // Must not be disposed for the stream to be usable - var response = await httpClient.GetAsync( + var response = await target.GetAsync( requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken @@ -63,10 +63,10 @@ public static async Task GetStreamAsync( /// The task object representing the asynchronous operation. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)")] public static Task GetStreamAsync( - this HttpClient httpClient, + this HttpClient target, Uri requestUri, CancellationToken cancellationToken = default) => - httpClient.GetStreamAsync(requestUri.ToString(), cancellationToken); + target.GetStreamAsync(requestUri.ToString(), cancellationToken); /// /// Send a GET request to the specified Uri and return the response body as a byte array in an asynchronous operation. @@ -80,13 +80,13 @@ public static Task GetStreamAsync( /// The task object representing the asynchronous operation. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)")] public static async Task GetByteArrayAsync( - this HttpClient httpClient, + this HttpClient target, string requestUri, CancellationToken cancellationToken = default) { try { - using var response = await httpClient.GetAsync( + using var response = await target.GetAsync( requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken @@ -117,10 +117,10 @@ public static async Task GetByteArrayAsync( /// The task object representing the asynchronous operation. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)")] public static Task GetByteArrayAsync( - this HttpClient httpClient, + this HttpClient target, Uri requestUri, CancellationToken cancellationToken = default) => - httpClient.GetByteArrayAsync(requestUri.ToString(), cancellationToken); + target.GetByteArrayAsync(requestUri.ToString(), cancellationToken); /// /// Send a GET request to the specified Uri and return the response body as a string in an asynchronous operation. @@ -134,13 +134,13 @@ public static Task GetByteArrayAsync( /// The task object representing the asynchronous operation. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)")] public static async Task GetStringAsync( - this HttpClient httpClient, + this HttpClient target, string requestUri, CancellationToken cancellationToken = default) { try { - using var response = await httpClient.GetAsync( + using var response = await target.GetAsync( requestUri, HttpCompletionOption.ResponseHeadersRead, cancellationToken @@ -171,9 +171,9 @@ public static async Task GetStringAsync( /// The task object representing the asynchronous operation. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)")] public static Task GetStringAsync( - this HttpClient httpClient, + this HttpClient target, Uri requestUri, CancellationToken cancellationToken = default) => - httpClient.GetStringAsync(requestUri.ToString(), cancellationToken); + target.GetStringAsync(requestUri.ToString(), cancellationToken); } #endif \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_HttpContent.cs b/src/Polyfill/PolyfillExtensions_HttpContent.cs index 37912320..ab0c1d1e 100644 --- a/src/Polyfill/PolyfillExtensions_HttpContent.cs +++ b/src/Polyfill/PolyfillExtensions_HttpContent.cs @@ -25,11 +25,11 @@ static partial class PolyfillExtensions /// The task object representing the asynchronous operation. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)")] public static Task ReadAsStreamAsync( - this HttpContent httpContent, + this HttpContent target, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); - return httpContent.ReadAsStreamAsync(); + return target.ReadAsStreamAsync(); } /// @@ -45,11 +45,11 @@ public static Task ReadAsStreamAsync( /// The task object representing the asynchronous operation. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)")] public static Task ReadAsByteArrayAsync( - this HttpContent httpContent, + this HttpContent target, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); - return httpContent.ReadAsByteArrayAsync(); + return target.ReadAsByteArrayAsync(); } /// @@ -65,11 +65,11 @@ public static Task ReadAsByteArrayAsync( /// The task object representing the asynchronous operation. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)")] public static Task ReadAsStringAsync( - this HttpContent httpContent, + this HttpContent target, CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); - return httpContent.ReadAsStringAsync(); + return target.ReadAsStringAsync(); } } #endif \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index 812c806a..756b86ee 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -29,8 +29,10 @@ static partial class PolyfillExtensions /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . /// [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] - public static TSource? MaxBy(this IEnumerable source, Func keySelector) => - MaxBy(source, keySelector, null); + public static TSource? MaxBy( + this IEnumerable target, + Func keySelector) => + MaxBy(target, keySelector, null); /// Returns the maximum value in a generic sequence according to a specified key selector function. /// The type of the elements of . @@ -45,8 +47,11 @@ static partial class PolyfillExtensions /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . /// [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))")] - public static TSource? MaxBy(this IEnumerable source, Func keySelector, IComparer? comparer) => - source + public static TSource? MaxBy( + this IEnumerable target, + Func keySelector, + IComparer? comparer) => + target .OrderByDescending(keySelector, comparer) .FirstOrDefault(); @@ -64,8 +69,10 @@ static partial class PolyfillExtensions /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . /// [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] - public static TSource? MinBy(this IEnumerable source, Func keySelector) => - MinBy(source, keySelector, null); + public static TSource? MinBy( + this IEnumerable target, + Func keySelector) => + MinBy(target, keySelector, null); /// Returns the minimum value in a generic sequence according to a specified key selector function. /// The type of the elements of . @@ -80,8 +87,11 @@ static partial class PolyfillExtensions /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . /// [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))")] - public static TSource? MinBy(this IEnumerable source, Func keySelector, IComparer? comparer) => - source + public static TSource? MinBy( + this IEnumerable target, + Func keySelector, + IComparer? comparer) => + target .OrderBy(keySelector, comparer) .FirstOrDefault(); @@ -98,10 +108,10 @@ static partial class PolyfillExtensions /// A new sequence that ends with element. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.append")] public static IEnumerable Append( - this IEnumerable source, + this IEnumerable target, TSource element) { - foreach (var item in source) + foreach (var item in target) { yield return item; } @@ -121,7 +131,9 @@ public static IEnumerable Append( /// A new enumerable collection that contains the elements from source minus count elements from the end /// of the collection. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast")] - public static IEnumerable SkipLast(this IEnumerable source, int count) => - source.Reverse().Skip(count).Reverse(); + public static IEnumerable SkipLast( + this IEnumerable target, + int count) => + target.Reverse().Skip(count).Reverse(); #endif } \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index 9cb54031..ccd594c8 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -18,7 +18,9 @@ static partial class PolyfillExtensions /// The value to search for. /// true if found, false otherwise. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)")] - public static bool Contains(this ReadOnlySpan target, T value) + public static bool Contains( + this ReadOnlySpan target, + T value) where T : IEquatable { for (var index = 0; index < target.Length; index++) @@ -38,7 +40,9 @@ public static bool Contains(this ReadOnlySpan target, T value) /// The value to search for. /// true if found, false otherwise. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)")] - public static bool Contains(this Span target, T value) + public static bool Contains( + this Span target, + T value) where T : IEquatable { for (var index = 0; index < target.Length; index++) @@ -53,27 +57,41 @@ public static bool Contains(this Span target, T value) } [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] - public static bool SequenceEqual(this ReadOnlySpan target, string other) => + public static bool SequenceEqual( + this ReadOnlySpan target, + string other) => target.SequenceEqual(other.AsSpan()); [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))")] - public static bool SequenceEqual(this Span target, string other) => + public static bool SequenceEqual( + this Span target, + string other) => target.SequenceEqual(other.AsSpan()); [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] - public static bool StartsWith(this ReadOnlySpan target, string other, StringComparison comparison = StringComparison.CurrentCulture) => + public static bool StartsWith( + this ReadOnlySpan target, + string other, + StringComparison comparison = StringComparison.CurrentCulture) => target.StartsWith(other.AsSpan(), comparison); [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))")] - public static bool StartsWith(this Span target, string other) => + public static bool StartsWith( + this Span target, + string other) => target.StartsWith(other.AsSpan()); [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] - public static bool EndsWith(this ReadOnlySpan target, string other, StringComparison comparison = StringComparison.CurrentCulture) => + public static bool EndsWith( + this ReadOnlySpan target, + string other, + StringComparison comparison = StringComparison.CurrentCulture) => target.EndsWith(other.AsSpan(), comparison); [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))")] - public static bool EndsWith(this Span target, string other) => + public static bool EndsWith( + this Span target, + string other) => target.EndsWith(other.AsSpan()); } #endif \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/PolyfillExtensions_Task.cs index 98deb6e7..d70989b8 100644 --- a/src/Polyfill/PolyfillExtensions_Task.cs +++ b/src/Polyfill/PolyfillExtensions_Task.cs @@ -19,7 +19,9 @@ public static Task WaitAsync(this Task target, CancellationToken cancellationTok target.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken); [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)")] - public static async Task WaitAsync(this Task target, TimeSpan timeout) + public static async Task WaitAsync( + this Task target, + TimeSpan timeout) { var cancellationSource = new CancellationTokenSource(); try @@ -34,29 +36,36 @@ public static async Task WaitAsync(this Task target, TimeSpan timeout) } [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)")] - public static async Task WaitAsync(this Task task, TimeSpan timeout, CancellationToken cancellationToken) + public static async Task WaitAsync( + this Task target, + TimeSpan timeout, + CancellationToken cancellationToken) { var delayTask = Task.Delay(timeout, cancellationToken); - var completedTask = await Task.WhenAny(task, delayTask); + var completedTask = await Task.WhenAny(target, delayTask); if (completedTask == delayTask) { throw new TimeoutException($"Execution did not complete within the time allotted {timeout.TotalMilliseconds} ms"); } - await task; + await target; } [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] - public static Task WaitAsync(this Task task, CancellationToken cancellationToken) => - task.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken); + public static Task WaitAsync( + this Task target, + CancellationToken cancellationToken) => + target.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken); [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)")] - public static async Task WaitAsync(this Task task, TimeSpan timeout) + public static async Task WaitAsync( + this Task target, + TimeSpan timeout) { var cancellationSource = new CancellationTokenSource(); try { - return await task.WaitAsync(timeout, cancellationSource.Token); + return await target.WaitAsync(timeout, cancellationSource.Token); } finally { @@ -66,16 +75,19 @@ public static async Task WaitAsync(this Task task, Ti } [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)")] - public static async Task WaitAsync(this Task task, TimeSpan timeout, CancellationToken cancellationToken) + public static async Task WaitAsync( + this Task target, + TimeSpan timeout, + CancellationToken cancellationToken) { var delayTask = Task.Delay(timeout, cancellationToken); - var completedTask = await Task.WhenAny(task, delayTask); + var completedTask = await Task.WhenAny(target, delayTask); if (completedTask == delayTask) { throw new TimeoutException($"Execution did not complete within the time allotted {timeout.TotalMilliseconds} ms"); } - return await task; + return await target; } } diff --git a/src/Polyfill/PolyfillExtensions_TryFormat.cs b/src/Polyfill/PolyfillExtensions_TryFormat.cs index f039121d..944cf210 100644 --- a/src/Polyfill/PolyfillExtensions_TryFormat.cs +++ b/src/Polyfill/PolyfillExtensions_TryFormat.cs @@ -19,7 +19,8 @@ static partial class PolyfillExtensions /// Tries to format the value of the current instance into the provided span of characters. /// [Link("https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat")] - public static bool TryFormat(this sbyte target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) + public static bool TryFormat( + this sbyte target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? provider = default) { string result; diff --git a/src/Polyfill/PolyfillExtensions_Type.cs b/src/Polyfill/PolyfillExtensions_Type.cs index b0eb413d..ffa6d854 100644 --- a/src/Polyfill/PolyfillExtensions_Type.cs +++ b/src/Polyfill/PolyfillExtensions_Type.cs @@ -44,7 +44,9 @@ public static bool IsGenericMethodParameter(this Type target) /// The MemberInfo to find on the current Type. /// An object representing the member on the current Type that matches the specified member. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.type.getmemberwithsamemetadatadefinitionas")] - internal static MemberInfo GetMemberWithSameMetadataDefinitionAs(this Type type, MemberInfo member) + internal static MemberInfo GetMemberWithSameMetadataDefinitionAs( + this Type type, + MemberInfo member) { const BindingFlags all = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; foreach (var info in type.GetMembers(all)) From 6242174c8626b70987e4467ebe471a9e617aa8eb Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 28 Jul 2023 11:10:53 +1000 Subject: [PATCH 152/313] add ReadLineAsync (#67) * add ReadLineAsync * Update Directory.Build.props --- src/Consume/Consume.cs | 6 ++++++ src/Directory.Build.props | 2 +- src/Polyfill/PolyfillExtensions_TextReader.cs | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index a50224d1..8ed99e35 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -142,6 +142,12 @@ async Task StreamReaderReadToEndAsync() var read = await reader.ReadToEndAsync(CancellationToken.None); } + async Task StreamReaderReadLineAsync() + { + TextReader reader = new StreamReader(new MemoryStream()); + var read = await reader.ReadLineAsync(CancellationToken.None); + } + void WaitAsync() { var action = () => {}; diff --git a/src/Directory.Build.props b/src/Directory.Build.props index ea40c292..7fa5facd 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.23.0 + 1.24.0 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_TextReader.cs b/src/Polyfill/PolyfillExtensions_TextReader.cs index d756d401..3d1d612c 100644 --- a/src/Polyfill/PolyfillExtensions_TextReader.cs +++ b/src/Polyfill/PolyfillExtensions_TextReader.cs @@ -64,5 +64,24 @@ public static Task ReadToEndAsync( return target.ReadToEndAsync(); } + + /// + /// Reads a line of characters asynchronously and returns the data as a string. + /// + /// The token to monitor for cancellation requests. + /// A value task that represents the asynchronous read operation. The value of the TResult + /// parameter contains the next line from the text reader, or is if all of the characters have been read. + /// The number of characters in the next line is larger than . + /// The text reader has been disposed. + /// The reader is currently in use by a previous read operation. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readlineasync(system-threading-cancellationtoken)")] + public static Task ReadLineAsync( + this TextReader target, + CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + + return target.ReadToEndAsync(); + } #endif } \ No newline at end of file From 16811aac55d48b8adef0821ef98391ecab2af155 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 28 Jul 2023 12:26:46 +1000 Subject: [PATCH 153/313] add Auto generated (#68) --- contributing.md | 15 ++++++--------- readme.md | 2 +- src/Polyfill/CallerArgumentExpressionAttribute.cs | 5 ++--- src/Polyfill/CompilerFeatureRequiredAttribute.cs | 5 ++--- .../DisableRuntimeMarshallingAttribute.cs | 5 ++--- src/Polyfill/IndexRange/Index.cs | 4 ++-- src/Polyfill/IndexRange/Range.cs | 5 ++--- .../InterpolatedStringHandlerArgumentAttribute.cs | 5 ++--- .../InterpolatedStringHandlerAttribute.cs | 5 ++--- src/Polyfill/IsExternalInit.cs | 5 ++--- src/Polyfill/ModuleInitializerAttribute.cs | 5 ++--- src/Polyfill/Nullability/NullabilityInfo.cs | 3 +-- .../Nullability/NullabilityInfoContext.cs | 3 +-- .../Nullability/NullabilityInfoExtensions.cs | 3 ++- src/Polyfill/Nullable/AllowNullAttribute.cs | 5 ++--- src/Polyfill/Nullable/DisallowNullAttribute.cs | 5 ++--- src/Polyfill/Nullable/DoesNotReturnAttribute.cs | 5 ++--- src/Polyfill/Nullable/DoesNotReturnIfAttribute.cs | 5 ++--- src/Polyfill/Nullable/MaybeNullAttribute.cs | 5 ++--- src/Polyfill/Nullable/MaybeNullWhenAttribute.cs | 5 ++--- src/Polyfill/Nullable/MemberNotNullAttribute.cs | 5 ++--- .../Nullable/MemberNotNullWhenAttribute.cs | 5 ++--- src/Polyfill/Nullable/NotNullAttribute.cs | 5 ++--- .../Nullable/NotNullIfNotNullAttribute.cs | 5 ++--- src/Polyfill/Nullable/NotNullWhenAttribute.cs | 5 ++--- .../PlatformCompatibility/OSPlatformAttribute.cs | 7 +++---- .../ObsoletedOSPlatformAttribute.cs | 7 +++---- .../SupportedOSPlatformAttribute.cs | 7 +++---- .../SupportedOSPlatformGuardAttribute.cs | 7 +++---- .../TargetPlatformAttribute.cs | 5 ++--- .../UnsupportedOSPlatformAttribute.cs | 7 +++---- .../UnsupportedOSPlatformGuardAttribute.cs | 5 ++--- src/Polyfill/PolyfillExtensions.cs | 3 +-- .../PolyfillExtensions_CancellationTokenSource.cs | 6 +----- src/Polyfill/PolyfillExtensions_HttpClient.cs | 6 ++---- src/Polyfill/PolyfillExtensions_HttpContent.cs | 6 ++---- src/Polyfill/PolyfillExtensions_IEnumerable.cs | 6 +----- .../PolyfillExtensions_IReadOnlyDictionary.cs | 7 ++----- src/Polyfill/PolyfillExtensions_KeyValuePair.cs | 7 ++----- src/Polyfill/PolyfillExtensions_Memory.cs | 6 ++---- .../PolyfillExtensions_MicroNanosecond.cs | 6 +----- src/Polyfill/PolyfillExtensions_Stream.cs | 6 ++---- src/Polyfill/PolyfillExtensions_String.cs | 5 +---- src/Polyfill/PolyfillExtensions_StringBuilder.cs | 6 ++---- src/Polyfill/PolyfillExtensions_Task.cs | 8 ++------ src/Polyfill/PolyfillExtensions_TextReader.cs | 4 +--- src/Polyfill/PolyfillExtensions_TextWriter.cs | 6 ++---- src/Polyfill/PolyfillExtensions_TryFormat.cs | 5 +---- src/Polyfill/PolyfillExtensions_Type.cs | 6 +----- src/Polyfill/RequiredMemberAttribute.cs | 5 ++--- src/Polyfill/ResolveHttpGlobalProblem.cs | 6 ++---- src/Polyfill/SetsRequiredMembersAttribute.cs | 5 ++--- src/Polyfill/SkipLocalsInitAttribute.cs | 5 ++--- src/Polyfill/StackTraceHiddenAttribute.cs | 5 ++--- src/Polyfill/StringSyntaxAttribute.cs | 4 ++-- src/Polyfill/SuppressGCTransitionAttribute.cs | 5 ++--- .../Trimming/DynamicDependencyAttribute.cs | 6 +++--- .../Trimming/DynamicallyAccessedMemberTypes.cs | 5 ++--- .../DynamicallyAccessedMembersAttribute.cs | 5 ++--- .../Trimming/RequiresDynamicCodeAttribute.cs | 6 +++--- .../Trimming/RequiresUnreferencedCodeAttribute.cs | 6 +++--- .../UnconditionalSuppressMessageAttribute.cs | 6 +++--- src/Polyfill/UnmanagedCallersOnlyAttribute.cs | 4 ++-- src/Polyfill/UnscopedRefAttribute.cs | 5 ++--- src/Tests/Guard.cs | 4 ++-- 65 files changed, 132 insertions(+), 219 deletions(-) diff --git a/contributing.md b/contributing.md index dbe61d0a..9d7b79b0 100644 --- a/contributing.md +++ b/contributing.md @@ -129,10 +129,9 @@ Example: ```cs -#if !NET5_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if !NET5_0_OR_GREATER using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -174,7 +173,7 @@ sealed class ModuleInitializerAttribute : #endif ``` -snippet source | anchor +snippet source | anchor @@ -187,10 +186,9 @@ Example: ```cs -#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; using System.Buffers; @@ -199,7 +197,6 @@ using System.Runtime.InteropServices; using Link = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; -// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { @@ -303,7 +300,7 @@ static partial class PolyfillExtensions } #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/readme.md b/readme.md index 3fc008f7..564f9d19 100644 --- a/readme.md +++ b/readme.md @@ -277,7 +277,7 @@ static class GuardUsage } } ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Polyfill/CallerArgumentExpressionAttribute.cs b/src/Polyfill/CallerArgumentExpressionAttribute.cs index 621a6e00..8fa14804 100644 --- a/src/Polyfill/CallerArgumentExpressionAttribute.cs +++ b/src/Polyfill/CallerArgumentExpressionAttribute.cs @@ -1,7 +1,6 @@ -#if NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/CompilerFeatureRequiredAttribute.cs b/src/Polyfill/CompilerFeatureRequiredAttribute.cs index f36cf542..14478d39 100644 --- a/src/Polyfill/CompilerFeatureRequiredAttribute.cs +++ b/src/Polyfill/CompilerFeatureRequiredAttribute.cs @@ -1,7 +1,6 @@ -#if !NET7_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if !NET7_0_OR_GREATER using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/DisableRuntimeMarshallingAttribute.cs b/src/Polyfill/DisableRuntimeMarshallingAttribute.cs index c334141c..2b0f80f2 100644 --- a/src/Polyfill/DisableRuntimeMarshallingAttribute.cs +++ b/src/Polyfill/DisableRuntimeMarshallingAttribute.cs @@ -1,7 +1,6 @@ -#if !NET7_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if !NET7_0_OR_GREATER using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/IndexRange/Index.cs b/src/Polyfill/IndexRange/Index.cs index 383be217..478e9dbe 100644 --- a/src/Polyfill/IndexRange/Index.cs +++ b/src/Polyfill/IndexRange/Index.cs @@ -1,7 +1,7 @@ +// + #if (NET46X && VALUETUPLEREFERENCED) || NET47X || NET48X || NETSTANDARD2_0 || NETCOREAPP2X -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; diff --git a/src/Polyfill/IndexRange/Range.cs b/src/Polyfill/IndexRange/Range.cs index 0b5d269e..30f30909 100644 --- a/src/Polyfill/IndexRange/Range.cs +++ b/src/Polyfill/IndexRange/Range.cs @@ -1,7 +1,6 @@ -#if (NET46X && VALUETUPLEREFERENCED) || NET47X || NET48X || NETSTANDARD2_0 || NETCOREAPP2X +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if (NET46X && VALUETUPLEREFERENCED) || NET47X || NET48X || NETSTANDARD2_0 || NETCOREAPP2X using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs b/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs index 6b496014..1aae1d37 100644 --- a/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs +++ b/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs @@ -1,7 +1,6 @@ -#if !NET6_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedType.Global +#if !NET6_0_OR_GREATER using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/InterpolatedStringHandlerAttribute.cs b/src/Polyfill/InterpolatedStringHandlerAttribute.cs index 9857ac1b..19a71f32 100644 --- a/src/Polyfill/InterpolatedStringHandlerAttribute.cs +++ b/src/Polyfill/InterpolatedStringHandlerAttribute.cs @@ -1,7 +1,6 @@ -#if !NET6_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedType.Global +#if !NET6_0_OR_GREATER using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/IsExternalInit.cs b/src/Polyfill/IsExternalInit.cs index 00edae1a..ee40249e 100644 --- a/src/Polyfill/IsExternalInit.cs +++ b/src/Polyfill/IsExternalInit.cs @@ -1,7 +1,6 @@ -#if !NET5_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if !NET5_0_OR_GREATER using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/ModuleInitializerAttribute.cs b/src/Polyfill/ModuleInitializerAttribute.cs index 01058773..17d50e8b 100644 --- a/src/Polyfill/ModuleInitializerAttribute.cs +++ b/src/Polyfill/ModuleInitializerAttribute.cs @@ -1,7 +1,6 @@ -#if !NET5_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if !NET5_0_OR_GREATER using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Nullability/NullabilityInfo.cs b/src/Polyfill/Nullability/NullabilityInfo.cs index b784425c..62080a8e 100644 --- a/src/Polyfill/Nullability/NullabilityInfo.cs +++ b/src/Polyfill/Nullability/NullabilityInfo.cs @@ -1,10 +1,9 @@ +// #if !NET6_0_OR_GREATER #nullable enable -// ReSharper disable All - using System.Linq; // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs index 85990bc6..dbf983de 100644 --- a/src/Polyfill/Nullability/NullabilityInfoContext.cs +++ b/src/Polyfill/Nullability/NullabilityInfoContext.cs @@ -1,10 +1,9 @@ +// #if !NET6_0_OR_GREATER #nullable enable -// ReSharper disable All - using System.Linq; // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. diff --git a/src/Polyfill/Nullability/NullabilityInfoExtensions.cs b/src/Polyfill/Nullability/NullabilityInfoExtensions.cs index eea54e78..82af6035 100644 --- a/src/Polyfill/Nullability/NullabilityInfoExtensions.cs +++ b/src/Polyfill/Nullability/NullabilityInfoExtensions.cs @@ -1,4 +1,5 @@ -// ReSharper disable RedundantUsingDirective +// + #nullable enable using System; diff --git a/src/Polyfill/Nullable/AllowNullAttribute.cs b/src/Polyfill/Nullable/AllowNullAttribute.cs index 69045184..9035fdbe 100644 --- a/src/Polyfill/Nullable/AllowNullAttribute.cs +++ b/src/Polyfill/Nullable/AllowNullAttribute.cs @@ -1,7 +1,6 @@ -#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Nullable/DisallowNullAttribute.cs b/src/Polyfill/Nullable/DisallowNullAttribute.cs index 9b06ddc4..f609a2d0 100644 --- a/src/Polyfill/Nullable/DisallowNullAttribute.cs +++ b/src/Polyfill/Nullable/DisallowNullAttribute.cs @@ -1,7 +1,6 @@ -#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Nullable/DoesNotReturnAttribute.cs b/src/Polyfill/Nullable/DoesNotReturnAttribute.cs index 774edd1b..38641474 100644 --- a/src/Polyfill/Nullable/DoesNotReturnAttribute.cs +++ b/src/Polyfill/Nullable/DoesNotReturnAttribute.cs @@ -1,7 +1,6 @@ -#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Nullable/DoesNotReturnIfAttribute.cs b/src/Polyfill/Nullable/DoesNotReturnIfAttribute.cs index 6c21e1f1..05d0d779 100644 --- a/src/Polyfill/Nullable/DoesNotReturnIfAttribute.cs +++ b/src/Polyfill/Nullable/DoesNotReturnIfAttribute.cs @@ -1,7 +1,6 @@ -#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Nullable/MaybeNullAttribute.cs b/src/Polyfill/Nullable/MaybeNullAttribute.cs index 7c365469..e1f077d2 100644 --- a/src/Polyfill/Nullable/MaybeNullAttribute.cs +++ b/src/Polyfill/Nullable/MaybeNullAttribute.cs @@ -1,7 +1,6 @@ -#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Nullable/MaybeNullWhenAttribute.cs b/src/Polyfill/Nullable/MaybeNullWhenAttribute.cs index d3ffc190..08271024 100644 --- a/src/Polyfill/Nullable/MaybeNullWhenAttribute.cs +++ b/src/Polyfill/Nullable/MaybeNullWhenAttribute.cs @@ -1,7 +1,6 @@ -#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Nullable/MemberNotNullAttribute.cs b/src/Polyfill/Nullable/MemberNotNullAttribute.cs index 12afba4d..99c12264 100644 --- a/src/Polyfill/Nullable/MemberNotNullAttribute.cs +++ b/src/Polyfill/Nullable/MemberNotNullAttribute.cs @@ -1,7 +1,6 @@ -#if NETSTANDARD || NETFRAMEWORK || NETCOREAPPX +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if NETSTANDARD || NETFRAMEWORK || NETCOREAPPX namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs b/src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs index 342617f4..4f434e83 100644 --- a/src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs +++ b/src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs @@ -1,7 +1,6 @@ -#if NETSTANDARD || NETFRAMEWORK || NETCOREAPPX +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if NETSTANDARD || NETFRAMEWORK || NETCOREAPPX namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Nullable/NotNullAttribute.cs b/src/Polyfill/Nullable/NotNullAttribute.cs index e4f1406e..e468a877 100644 --- a/src/Polyfill/Nullable/NotNullAttribute.cs +++ b/src/Polyfill/Nullable/NotNullAttribute.cs @@ -1,7 +1,6 @@ -#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Nullable/NotNullIfNotNullAttribute.cs b/src/Polyfill/Nullable/NotNullIfNotNullAttribute.cs index baa67665..621fb50d 100644 --- a/src/Polyfill/Nullable/NotNullIfNotNullAttribute.cs +++ b/src/Polyfill/Nullable/NotNullIfNotNullAttribute.cs @@ -1,7 +1,6 @@ -#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Nullable/NotNullWhenAttribute.cs b/src/Polyfill/Nullable/NotNullWhenAttribute.cs index 514559c4..6136e494 100644 --- a/src/Polyfill/Nullable/NotNullWhenAttribute.cs +++ b/src/Polyfill/Nullable/NotNullWhenAttribute.cs @@ -1,7 +1,6 @@ -#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if NETSTANDARD2_0 || NETFRAMEWORK || NETCOREAPP2X namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/PlatformCompatibility/OSPlatformAttribute.cs b/src/Polyfill/PlatformCompatibility/OSPlatformAttribute.cs index f792a846..e3b722b1 100644 --- a/src/Polyfill/PlatformCompatibility/OSPlatformAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/OSPlatformAttribute.cs @@ -1,9 +1,8 @@ -#if !NET7_0_OR_GREATER +// -#pragma warning disable +#if !NET7_0_OR_GREATER -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart +#pragma warning disable using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/PlatformCompatibility/ObsoletedOSPlatformAttribute.cs b/src/Polyfill/PlatformCompatibility/ObsoletedOSPlatformAttribute.cs index 6d8e14a0..942411dc 100644 --- a/src/Polyfill/PlatformCompatibility/ObsoletedOSPlatformAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/ObsoletedOSPlatformAttribute.cs @@ -1,9 +1,8 @@ -#if !NET7_0_OR_GREATER +// -#pragma warning disable +#if !NET7_0_OR_GREATER -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart +#pragma warning disable using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/PlatformCompatibility/SupportedOSPlatformAttribute.cs b/src/Polyfill/PlatformCompatibility/SupportedOSPlatformAttribute.cs index 7f3507ec..e1885da6 100644 --- a/src/Polyfill/PlatformCompatibility/SupportedOSPlatformAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/SupportedOSPlatformAttribute.cs @@ -1,9 +1,8 @@ -#if !NET5_0_OR_GREATER +// -#pragma warning disable +#if !NET5_0_OR_GREATER -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart +#pragma warning disable using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/PlatformCompatibility/SupportedOSPlatformGuardAttribute.cs b/src/Polyfill/PlatformCompatibility/SupportedOSPlatformGuardAttribute.cs index bcc74900..13333f8d 100644 --- a/src/Polyfill/PlatformCompatibility/SupportedOSPlatformGuardAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/SupportedOSPlatformGuardAttribute.cs @@ -1,9 +1,8 @@ -#if !NET6_0_OR_GREATER +// -#pragma warning disable +#if !NET6_0_OR_GREATER -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart +#pragma warning disable using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/PlatformCompatibility/TargetPlatformAttribute.cs b/src/Polyfill/PlatformCompatibility/TargetPlatformAttribute.cs index 62f235df..26e192c1 100644 --- a/src/Polyfill/PlatformCompatibility/TargetPlatformAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/TargetPlatformAttribute.cs @@ -1,7 +1,6 @@ -#if !NET5_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart +#if !NET5_0_OR_GREATER using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformAttribute.cs b/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformAttribute.cs index 911f8683..6af9ea69 100644 --- a/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformAttribute.cs @@ -1,9 +1,8 @@ -#if !NET5_0_OR_GREATER +// -#nullable enable +#if !NET5_0_OR_GREATER -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart +#nullable enable using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformGuardAttribute.cs b/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformGuardAttribute.cs index 57be1a25..aa446f86 100644 --- a/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformGuardAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformGuardAttribute.cs @@ -1,10 +1,9 @@ +// + #if !NET6_0_OR_GREATER #pragma warning disable -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart - using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/PolyfillExtensions.cs b/src/Polyfill/PolyfillExtensions.cs index 18979245..8be5fd04 100644 --- a/src/Polyfill/PolyfillExtensions.cs +++ b/src/Polyfill/PolyfillExtensions.cs @@ -1,5 +1,4 @@ -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart +// using System.ComponentModel; using System.Diagnostics; diff --git a/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs b/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs index ba522d41..ca9283f5 100644 --- a/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs +++ b/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs @@ -1,8 +1,4 @@ - -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart -// ReSharper disable UnusedMember.Global -// ReSharper disable RedundantAttributeSuffix +// using System; using System.Reflection; diff --git a/src/Polyfill/PolyfillExtensions_HttpClient.cs b/src/Polyfill/PolyfillExtensions_HttpClient.cs index 01ac1fdf..96f25cce 100644 --- a/src/Polyfill/PolyfillExtensions_HttpClient.cs +++ b/src/Polyfill/PolyfillExtensions_HttpClient.cs @@ -1,8 +1,6 @@ -#if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD || NETCOREAPP2X || NETCOREAPP3X) +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global -// ReSharper disable RedundantAttributeSuffix +#if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD || NETCOREAPP2X || NETCOREAPP3X) using System; using System.IO; diff --git a/src/Polyfill/PolyfillExtensions_HttpContent.cs b/src/Polyfill/PolyfillExtensions_HttpContent.cs index ab0c1d1e..c4cb75ea 100644 --- a/src/Polyfill/PolyfillExtensions_HttpContent.cs +++ b/src/Polyfill/PolyfillExtensions_HttpContent.cs @@ -1,8 +1,6 @@ -#if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD || NETCOREAPP2X || NETCOREAPP3X) +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable RedundantAttributeSuffix -// ReSharper disable UnusedMember.Global +#if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD || NETCOREAPP2X || NETCOREAPP3X) using System.IO; using System.Net.Http; diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index 756b86ee..e1dd8ecf 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -1,15 +1,11 @@ +// #pragma warning disable -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart -// ReSharper disable UnusedMember.Global - using System; using System.Collections.Generic; using Link = System.ComponentModel.DescriptionAttribute; using System.Linq; -// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { diff --git a/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs b/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs index a4c4ebc5..d30762a7 100644 --- a/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs +++ b/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs @@ -1,15 +1,12 @@ +// + #if NETFRAMEWORK || NETSTANDARD2_0 #pragma warning disable -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart -// ReSharper disable UnusedMember.Global - using System; using System.Collections.Generic; using Link = System.ComponentModel.DescriptionAttribute; -// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { diff --git a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs index 7a63a7e6..3708e598 100644 --- a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs +++ b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs @@ -1,9 +1,6 @@ -#if NETFRAMEWORK || NETSTANDARD2_0 +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart -// ReSharper disable UnusedMember.Global -// ReSharper disable RedundantAttributeSuffix +#if NETFRAMEWORK || NETSTANDARD2_0 using System; using System.Collections.Generic; diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index ccd594c8..f32098e1 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -1,8 +1,6 @@ -#if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X) +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global -// ReSharper disable RedundantAttributeSuffix +#if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X) using System; using System.Collections.Generic; diff --git a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs index 5d9a7072..e8f7ddeb 100644 --- a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs +++ b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs @@ -1,11 +1,7 @@ - -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart -// ReSharper disable UnusedMember.Global +// using System; using Link = System.ComponentModel.DescriptionAttribute; -// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index 8bcebe2e..4424890b 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -1,7 +1,6 @@ -#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; using System.IO; @@ -9,7 +8,6 @@ using System.Threading; using System.Threading.Tasks; using Link = System.ComponentModel.DescriptionAttribute; -// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/PolyfillExtensions_String.cs index dd8c87f4..72d7fdd5 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/PolyfillExtensions_String.cs @@ -1,11 +1,8 @@ - -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart +// using System; using Link = System.ComponentModel.DescriptionAttribute; using System.Text; -// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { diff --git a/src/Polyfill/PolyfillExtensions_StringBuilder.cs b/src/Polyfill/PolyfillExtensions_StringBuilder.cs index 6cd1a011..cb85e5de 100644 --- a/src/Polyfill/PolyfillExtensions_StringBuilder.cs +++ b/src/Polyfill/PolyfillExtensions_StringBuilder.cs @@ -1,7 +1,6 @@ -#if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; using System.IO; @@ -10,7 +9,6 @@ using Link = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; -// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/PolyfillExtensions_Task.cs index d70989b8..51cdb0a5 100644 --- a/src/Polyfill/PolyfillExtensions_Task.cs +++ b/src/Polyfill/PolyfillExtensions_Task.cs @@ -1,10 +1,6 @@ -#if NETFRAMEWORK || NETSTANDARD || NETCOREAPP || NET5_0 +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart -// ReSharper disable UnusedMember.Global -// ReSharper disable RedundantAttributeSuffix -// ReSharper disable RedundantTypeArgumentsOfMethod +#if NETFRAMEWORK || NETSTANDARD || NETCOREAPP || NET5_0 using System; using System.Reflection; diff --git a/src/Polyfill/PolyfillExtensions_TextReader.cs b/src/Polyfill/PolyfillExtensions_TextReader.cs index 3d1d612c..765e8ebb 100644 --- a/src/Polyfill/PolyfillExtensions_TextReader.cs +++ b/src/Polyfill/PolyfillExtensions_TextReader.cs @@ -1,5 +1,4 @@ -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +// using System; using System.IO; @@ -7,7 +6,6 @@ using Link = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; -// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { diff --git a/src/Polyfill/PolyfillExtensions_TextWriter.cs b/src/Polyfill/PolyfillExtensions_TextWriter.cs index e34b0257..e4cb3ab9 100644 --- a/src/Polyfill/PolyfillExtensions_TextWriter.cs +++ b/src/Polyfill/PolyfillExtensions_TextWriter.cs @@ -1,7 +1,6 @@ -#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; using System.Buffers; @@ -10,7 +9,6 @@ using Link = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; -// ReSharper disable RedundantAttributeSuffix static partial class PolyfillExtensions { diff --git a/src/Polyfill/PolyfillExtensions_TryFormat.cs b/src/Polyfill/PolyfillExtensions_TryFormat.cs index 944cf210..25184383 100644 --- a/src/Polyfill/PolyfillExtensions_TryFormat.cs +++ b/src/Polyfill/PolyfillExtensions_TryFormat.cs @@ -1,10 +1,7 @@ +// #pragma warning disable -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global -// ReSharper disable RedundantAttributeSuffix - using System; using System.Collections.Generic; using System.Text; diff --git a/src/Polyfill/PolyfillExtensions_Type.cs b/src/Polyfill/PolyfillExtensions_Type.cs index ffa6d854..ec346273 100644 --- a/src/Polyfill/PolyfillExtensions_Type.cs +++ b/src/Polyfill/PolyfillExtensions_Type.cs @@ -1,8 +1,4 @@ - -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart -// ReSharper disable UnusedMember.Global -// ReSharper disable RedundantAttributeSuffix +// using System; using System.Reflection; diff --git a/src/Polyfill/RequiredMemberAttribute.cs b/src/Polyfill/RequiredMemberAttribute.cs index a3459ba9..3b245bf0 100644 --- a/src/Polyfill/RequiredMemberAttribute.cs +++ b/src/Polyfill/RequiredMemberAttribute.cs @@ -1,7 +1,6 @@ -#if !NET7_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if !NET7_0_OR_GREATER using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/ResolveHttpGlobalProblem.cs b/src/Polyfill/ResolveHttpGlobalProblem.cs index 174317c0..9c05a616 100644 --- a/src/Polyfill/ResolveHttpGlobalProblem.cs +++ b/src/Polyfill/ResolveHttpGlobalProblem.cs @@ -1,8 +1,6 @@ -#if NETFRAMEWORK +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable PartialTypeWithSinglePart -// ReSharper disable UnusedMember.Global +#if NETFRAMEWORK using System.ComponentModel; diff --git a/src/Polyfill/SetsRequiredMembersAttribute.cs b/src/Polyfill/SetsRequiredMembersAttribute.cs index 9ccd7247..1af9596a 100644 --- a/src/Polyfill/SetsRequiredMembersAttribute.cs +++ b/src/Polyfill/SetsRequiredMembersAttribute.cs @@ -1,7 +1,6 @@ -#if !NET7_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if !NET7_0_OR_GREATER namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/SkipLocalsInitAttribute.cs b/src/Polyfill/SkipLocalsInitAttribute.cs index a84c975f..df042fb1 100644 --- a/src/Polyfill/SkipLocalsInitAttribute.cs +++ b/src/Polyfill/SkipLocalsInitAttribute.cs @@ -1,7 +1,6 @@ -#if !NET5_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if !NET5_0_OR_GREATER using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/StackTraceHiddenAttribute.cs b/src/Polyfill/StackTraceHiddenAttribute.cs index fdc4430b..2634e040 100644 --- a/src/Polyfill/StackTraceHiddenAttribute.cs +++ b/src/Polyfill/StackTraceHiddenAttribute.cs @@ -1,7 +1,6 @@ -#if !NET6_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if !NET6_0_OR_GREATER using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/StringSyntaxAttribute.cs b/src/Polyfill/StringSyntaxAttribute.cs index f256710e..99c1aaa9 100644 --- a/src/Polyfill/StringSyntaxAttribute.cs +++ b/src/Polyfill/StringSyntaxAttribute.cs @@ -1,9 +1,9 @@ +// + #if !NET7_0_OR_GREATER #nullable enable -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/SuppressGCTransitionAttribute.cs b/src/Polyfill/SuppressGCTransitionAttribute.cs index 98b3b0c0..b64687d3 100644 --- a/src/Polyfill/SuppressGCTransitionAttribute.cs +++ b/src/Polyfill/SuppressGCTransitionAttribute.cs @@ -1,7 +1,6 @@ -#if !NET5_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if !NET5_0_OR_GREATER using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Trimming/DynamicDependencyAttribute.cs b/src/Polyfill/Trimming/DynamicDependencyAttribute.cs index 9ca4313b..14c07b24 100644 --- a/src/Polyfill/Trimming/DynamicDependencyAttribute.cs +++ b/src/Polyfill/Trimming/DynamicDependencyAttribute.cs @@ -1,9 +1,9 @@ -#if !NET5_0_OR_GREATER +// + +#if !NET5_0_OR_GREATER #nullable enable -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Trimming/DynamicallyAccessedMemberTypes.cs b/src/Polyfill/Trimming/DynamicallyAccessedMemberTypes.cs index 437ddcf7..01c035cc 100644 --- a/src/Polyfill/Trimming/DynamicallyAccessedMemberTypes.cs +++ b/src/Polyfill/Trimming/DynamicallyAccessedMemberTypes.cs @@ -1,7 +1,6 @@ -#if !NET5_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if !NET5_0_OR_GREATER namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Trimming/DynamicallyAccessedMembersAttribute.cs b/src/Polyfill/Trimming/DynamicallyAccessedMembersAttribute.cs index 7240ad39..e036a6e2 100644 --- a/src/Polyfill/Trimming/DynamicallyAccessedMembersAttribute.cs +++ b/src/Polyfill/Trimming/DynamicallyAccessedMembersAttribute.cs @@ -1,7 +1,6 @@ -#if !NET5_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if !NET5_0_OR_GREATER namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs b/src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs index 1ddba848..700d1159 100644 --- a/src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs +++ b/src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs @@ -1,9 +1,9 @@ -#if !NET7_0_OR_GREATER +// + +#if !NET7_0_OR_GREATER #nullable enable -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Trimming/RequiresUnreferencedCodeAttribute.cs b/src/Polyfill/Trimming/RequiresUnreferencedCodeAttribute.cs index 35b1ba52..ea72c04e 100644 --- a/src/Polyfill/Trimming/RequiresUnreferencedCodeAttribute.cs +++ b/src/Polyfill/Trimming/RequiresUnreferencedCodeAttribute.cs @@ -1,10 +1,10 @@ -#if !NET5_0_OR_GREATER +// + +#if !NET5_0_OR_GREATER #pragma warning disable #nullable enable -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Trimming/UnconditionalSuppressMessageAttribute.cs b/src/Polyfill/Trimming/UnconditionalSuppressMessageAttribute.cs index 62a17b22..c9780d81 100644 --- a/src/Polyfill/Trimming/UnconditionalSuppressMessageAttribute.cs +++ b/src/Polyfill/Trimming/UnconditionalSuppressMessageAttribute.cs @@ -1,9 +1,9 @@ -#if !NET5_0_OR_GREATER +// + +#if !NET5_0_OR_GREATER #nullable enable -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global namespace System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/UnmanagedCallersOnlyAttribute.cs b/src/Polyfill/UnmanagedCallersOnlyAttribute.cs index c10054f9..6b8a09db 100644 --- a/src/Polyfill/UnmanagedCallersOnlyAttribute.cs +++ b/src/Polyfill/UnmanagedCallersOnlyAttribute.cs @@ -1,9 +1,9 @@ +// + #if !NET5_0_OR_GREATER #nullable enable -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/UnscopedRefAttribute.cs b/src/Polyfill/UnscopedRefAttribute.cs index caf4c75f..f8c3134d 100644 --- a/src/Polyfill/UnscopedRefAttribute.cs +++ b/src/Polyfill/UnscopedRefAttribute.cs @@ -1,7 +1,6 @@ -#if !NET7_0_OR_GREATER +// -// ReSharper disable RedundantUsingDirective -// ReSharper disable UnusedMember.Global +#if !NET7_0_OR_GREATER using System.Diagnostics; diff --git a/src/Tests/Guard.cs b/src/Tests/Guard.cs index aa5e0aae..742d5e49 100644 --- a/src/Tests/Guard.cs +++ b/src/Tests/Guard.cs @@ -1,4 +1,5 @@ -// ReSharper disable RedundantUsingDirective +// + #region CallerArgumentExpression using System.IO; @@ -14,7 +15,6 @@ public static void FileExists(string path, [CallerArgumentExpression("path")] st } } - static class GuardUsage { public static string[] Method(string path) From 04ae09ef8a0a903be65c71e11f32396de1040278 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 28 Jul 2023 13:39:31 +1000 Subject: [PATCH 154/313] Update Directory.Build.props --- src/Directory.Build.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 7fa5facd..385f2774 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,12 +1,12 @@ - 1.24.0 + 1.24.1 1.0.0 Polyfill true false - CS1573;CS1573;CS1591;NETSDK1138;NU1901;NU1902 + CS1591;NETSDK1138;NU1901;NU1902 false 11 false From 6209502daa219e63efe59ae4d090f845eeb040c9 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 28 Jul 2023 14:01:15 +1000 Subject: [PATCH 155/313] fix some wanrings --- contributing.md | 4 +++- src/Polyfill/PolyfillExtensions_HttpClient.cs | 2 ++ src/Polyfill/PolyfillExtensions_HttpContent.cs | 2 ++ src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs | 4 ++-- src/Polyfill/PolyfillExtensions_KeyValuePair.cs | 2 ++ src/Polyfill/PolyfillExtensions_Memory.cs | 2 ++ src/Polyfill/PolyfillExtensions_MicroNanosecond.cs | 2 ++ src/Polyfill/PolyfillExtensions_Stream.cs | 2 ++ src/Polyfill/PolyfillExtensions_String.cs | 2 ++ src/Polyfill/PolyfillExtensions_StringBuilder.cs | 2 ++ src/Polyfill/PolyfillExtensions_Task.cs | 2 ++ src/Polyfill/PolyfillExtensions_TextReader.cs | 2 ++ src/Polyfill/PolyfillExtensions_TextWriter.cs | 2 ++ src/Polyfill/PolyfillExtensions_Type.cs | 2 ++ src/Polyfill/StringSyntaxAttribute.cs | 1 - src/Polyfill/Trimming/DynamicDependencyAttribute.cs | 1 - src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs | 1 - src/Polyfill/Trimming/RequiresUnreferencedCodeAttribute.cs | 2 -- .../Trimming/UnconditionalSuppressMessageAttribute.cs | 1 - 19 files changed, 29 insertions(+), 9 deletions(-) diff --git a/contributing.md b/contributing.md index 9d7b79b0..24410003 100644 --- a/contributing.md +++ b/contributing.md @@ -188,6 +188,8 @@ Example: ```cs // +#pragma warning disable + #if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; @@ -300,7 +302,7 @@ static partial class PolyfillExtensions } #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Polyfill/PolyfillExtensions_HttpClient.cs b/src/Polyfill/PolyfillExtensions_HttpClient.cs index 96f25cce..95663d00 100644 --- a/src/Polyfill/PolyfillExtensions_HttpClient.cs +++ b/src/Polyfill/PolyfillExtensions_HttpClient.cs @@ -1,5 +1,7 @@ // +#pragma warning disable + #if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD || NETCOREAPP2X || NETCOREAPP3X) using System; diff --git a/src/Polyfill/PolyfillExtensions_HttpContent.cs b/src/Polyfill/PolyfillExtensions_HttpContent.cs index c4cb75ea..2a17255e 100644 --- a/src/Polyfill/PolyfillExtensions_HttpContent.cs +++ b/src/Polyfill/PolyfillExtensions_HttpContent.cs @@ -1,5 +1,7 @@ // +#pragma warning disable + #if ((NETFRAMEWORK && HTTPREFERENCED) || NETSTANDARD || NETCOREAPP2X || NETCOREAPP3X) using System.IO; diff --git a/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs b/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs index d30762a7..9d10c259 100644 --- a/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs +++ b/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs @@ -1,9 +1,9 @@ // -#if NETFRAMEWORK || NETSTANDARD2_0 - #pragma warning disable +#if NETFRAMEWORK || NETSTANDARD2_0 + using System; using System.Collections.Generic; using Link = System.ComponentModel.DescriptionAttribute; diff --git a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs index 3708e598..dcb09a70 100644 --- a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs +++ b/src/Polyfill/PolyfillExtensions_KeyValuePair.cs @@ -1,5 +1,7 @@ // +#pragma warning disable + #if NETFRAMEWORK || NETSTANDARD2_0 using System; diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index f32098e1..e7ad2ce1 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -1,5 +1,7 @@ // +#pragma warning disable + #if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X) using System; diff --git a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs index e8f7ddeb..2d2ba8f9 100644 --- a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs +++ b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs @@ -1,5 +1,7 @@ // +#pragma warning disable + using System; using Link = System.ComponentModel.DescriptionAttribute; diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index 4424890b..ed0ebb88 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -1,5 +1,7 @@ // +#pragma warning disable + #if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/PolyfillExtensions_String.cs index 72d7fdd5..a3565b0f 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/PolyfillExtensions_String.cs @@ -1,5 +1,7 @@ // +#pragma warning disable + using System; using Link = System.ComponentModel.DescriptionAttribute; using System.Text; diff --git a/src/Polyfill/PolyfillExtensions_StringBuilder.cs b/src/Polyfill/PolyfillExtensions_StringBuilder.cs index cb85e5de..901e13cb 100644 --- a/src/Polyfill/PolyfillExtensions_StringBuilder.cs +++ b/src/Polyfill/PolyfillExtensions_StringBuilder.cs @@ -1,5 +1,7 @@ // +#pragma warning disable + #if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/PolyfillExtensions_Task.cs index 51cdb0a5..536353da 100644 --- a/src/Polyfill/PolyfillExtensions_Task.cs +++ b/src/Polyfill/PolyfillExtensions_Task.cs @@ -1,5 +1,7 @@ // +#pragma warning disable + #if NETFRAMEWORK || NETSTANDARD || NETCOREAPP || NET5_0 using System; diff --git a/src/Polyfill/PolyfillExtensions_TextReader.cs b/src/Polyfill/PolyfillExtensions_TextReader.cs index 765e8ebb..125951cb 100644 --- a/src/Polyfill/PolyfillExtensions_TextReader.cs +++ b/src/Polyfill/PolyfillExtensions_TextReader.cs @@ -1,5 +1,7 @@ // +#pragma warning disable + using System; using System.IO; using System.Runtime.InteropServices; diff --git a/src/Polyfill/PolyfillExtensions_TextWriter.cs b/src/Polyfill/PolyfillExtensions_TextWriter.cs index e4cb3ab9..2634d435 100644 --- a/src/Polyfill/PolyfillExtensions_TextWriter.cs +++ b/src/Polyfill/PolyfillExtensions_TextWriter.cs @@ -1,5 +1,7 @@ // +#pragma warning disable + #if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; diff --git a/src/Polyfill/PolyfillExtensions_Type.cs b/src/Polyfill/PolyfillExtensions_Type.cs index ec346273..7830297b 100644 --- a/src/Polyfill/PolyfillExtensions_Type.cs +++ b/src/Polyfill/PolyfillExtensions_Type.cs @@ -1,5 +1,7 @@ // +#pragma warning disable + using System; using System.Reflection; using Link = System.ComponentModel.DescriptionAttribute; diff --git a/src/Polyfill/StringSyntaxAttribute.cs b/src/Polyfill/StringSyntaxAttribute.cs index 99c1aaa9..feeda19d 100644 --- a/src/Polyfill/StringSyntaxAttribute.cs +++ b/src/Polyfill/StringSyntaxAttribute.cs @@ -4,7 +4,6 @@ #nullable enable - using System.Diagnostics; using System.Diagnostics.CodeAnalysis; diff --git a/src/Polyfill/Trimming/DynamicDependencyAttribute.cs b/src/Polyfill/Trimming/DynamicDependencyAttribute.cs index 14c07b24..33b1722b 100644 --- a/src/Polyfill/Trimming/DynamicDependencyAttribute.cs +++ b/src/Polyfill/Trimming/DynamicDependencyAttribute.cs @@ -4,7 +4,6 @@ #nullable enable - namespace System.Diagnostics.CodeAnalysis; using Targets = AttributeTargets; diff --git a/src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs b/src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs index 700d1159..0db5e8a3 100644 --- a/src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs +++ b/src/Polyfill/Trimming/RequiresDynamicCodeAttribute.cs @@ -4,7 +4,6 @@ #nullable enable - namespace System.Diagnostics.CodeAnalysis; using Targets = AttributeTargets; diff --git a/src/Polyfill/Trimming/RequiresUnreferencedCodeAttribute.cs b/src/Polyfill/Trimming/RequiresUnreferencedCodeAttribute.cs index ea72c04e..6157fc9b 100644 --- a/src/Polyfill/Trimming/RequiresUnreferencedCodeAttribute.cs +++ b/src/Polyfill/Trimming/RequiresUnreferencedCodeAttribute.cs @@ -2,10 +2,8 @@ #if !NET5_0_OR_GREATER -#pragma warning disable #nullable enable - namespace System.Diagnostics.CodeAnalysis; using Targets = AttributeTargets; diff --git a/src/Polyfill/Trimming/UnconditionalSuppressMessageAttribute.cs b/src/Polyfill/Trimming/UnconditionalSuppressMessageAttribute.cs index c9780d81..54d77ef9 100644 --- a/src/Polyfill/Trimming/UnconditionalSuppressMessageAttribute.cs +++ b/src/Polyfill/Trimming/UnconditionalSuppressMessageAttribute.cs @@ -4,7 +4,6 @@ #nullable enable - namespace System.Diagnostics.CodeAnalysis; /// From d65d6156e42e30a9672b4cecd20311155c05fc9c Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 31 Jul 2023 08:55:33 +1000 Subject: [PATCH 156/313] Update PolyfillExtensions_IEnumerable.cs --- src/Polyfill/PolyfillExtensions_IEnumerable.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index e1dd8ecf..bc6a3afa 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -14,7 +14,7 @@ static partial class PolyfillExtensions /// /// Returns the maximum value in a generic sequence according to a specified key selector function. /// - /// The type of the elements of . + /// The type of the elements of . /// The type of key to compare elements by. /// A sequence of values to determine the maximum value of. /// A function to extract the key for each element. @@ -31,7 +31,7 @@ static partial class PolyfillExtensions MaxBy(target, keySelector, null); /// Returns the maximum value in a generic sequence according to a specified key selector function. - /// The type of the elements of . + /// The type of the elements of . /// The type of key to compare elements by. /// A sequence of values to determine the maximum value of. /// A function to extract the key for each element. @@ -54,7 +54,7 @@ static partial class PolyfillExtensions /// /// Returns the minimum value in a generic sequence according to a specified key selector function. /// - /// The type of the elements of . + /// The type of the elements of . /// The type of key to compare elements by. /// A sequence of values to determine the minby value of. /// A function to extract the key for each element. @@ -71,14 +71,14 @@ static partial class PolyfillExtensions MinBy(target, keySelector, null); /// Returns the minimum value in a generic sequence according to a specified key selector function. - /// The type of the elements of . + /// The type of the elements of . /// The type of key to compare elements by. /// A sequence of values to determine the minimum value of. /// A function to extract the key for each element. /// The to compare keys. /// The value with the minimum key in the sequence. /// is . - /// No key extracted from implements the or interface. + /// No key extracted from implements the or interface. /// /// If is a reference type and the source sequence is empty or contains only values that are , this method returns . /// @@ -99,7 +99,7 @@ static partial class PolyfillExtensions /// Appends a value to the end of the sequence. /// /// A sequence of values. - /// The value to append to source. + /// The value to append to . /// The type of the elements of source. /// A new sequence that ends with element. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.append")] From 0c4de27e76c40392b13dbcf8e3353ec59d1c56c9 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 31 Jul 2023 08:56:35 +1000 Subject: [PATCH 157/313] Add single item Enumerable.Except (#69) --- src/Directory.Build.props | 2 +- .../PolyfillExtensions_IEnumerable.cs | 35 +++++++++++++++++++ .../PolyfillExtensionsTests_IEnumerable.cs | 7 ++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 385f2774..8ed6ef5c 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.24.1 + 1.25.0 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index bc6a3afa..43a78da7 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -9,6 +9,41 @@ static partial class PolyfillExtensions { + /// + /// Produces the set difference of two sequences by using the default equality comparer to compare values. + /// + /// An whose elements that are not equal to will be returned. + /// An that is elements equal it will cause those elements to be removed from the returned sequence. + /// The type of the elements of . + /// A sequence that contains the items of but excluding . + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] + public static IEnumerable Except(this IEnumerable target, TSource item) + { + return Except(target, item, null); + } + + /// + /// Produces the set difference of two sequences by using the default equality comparer to compare values. + /// + /// An whose elements that are not equal to will be returned. + /// An that is elements equal it will cause those elements to be removed from the returned sequence. + /// An to compare values. + /// The type of the elements of . + /// A sequence that contains the items of but excluding . + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] + public static IEnumerable Except(this IEnumerable target, TSource item, IEqualityComparer? comparer) + { + var set = new HashSet(comparer); + set.Add(item); + foreach (TSource element in target) + { + if (set.Add(element)) + { + yield return element; + } + } + } + #if NETSTANDARD || NETCOREAPP || NETFRAMEWORK || NET5_0 /// diff --git a/src/Tests/PolyfillExtensionsTests_IEnumerable.cs b/src/Tests/PolyfillExtensionsTests_IEnumerable.cs index d2a20970..963580c2 100644 --- a/src/Tests/PolyfillExtensionsTests_IEnumerable.cs +++ b/src/Tests/PolyfillExtensionsTests_IEnumerable.cs @@ -8,6 +8,13 @@ public void MaxBy() Assert.AreEqual(2, enumerable.MaxBy(_ => _)); } + [Test] + public void Except() + { + var enumerable = new List {1, 2}; + Assert.AreEqual(1, enumerable.Except(2).Single()); + } + [Test] public void MinBy() { From 8f9aaf4d07e98d24d442a3e5ddd876a4c68d066e Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 31 Jul 2023 09:58:14 +1000 Subject: [PATCH 158/313] Update api_list.include.md --- api_list.include.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/api_list.include.md b/api_list.include.md index c7632446..731e2d90 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -70,6 +70,16 @@ * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) +### IEnumerable + + * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + + +### IEnumerable + + * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + + ### IEnumerable * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) @@ -249,6 +259,7 @@ ### TextReader * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) + * `Task ReadLineAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readlineasync(system-threading-cancellationtoken)) * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) From e013a6c032450efeb9d6a3d1c6f29d56a1edbcc1 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 31 Jul 2023 10:07:47 +1000 Subject: [PATCH 159/313] docs --- readme.md | 11 ++++++++++ src/Polyfill/Nullability/NullabilityInfo.cs | 21 ++++++++++--------- .../Nullability/NullabilityInfoContext.cs | 3 ++- src/Tests/BuildApiTest.cs | 2 +- src/Tests/NullabilitySync.cs | 21 +++++++++++-------- 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/readme.md b/readme.md index 564f9d19..1fddfde8 100644 --- a/readme.md +++ b/readme.md @@ -419,6 +419,16 @@ The class `PolyfillExtensions` includes the following extension methods: * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) +### IEnumerable + + * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + + +### IEnumerable + + * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + + ### IEnumerable * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) @@ -598,6 +608,7 @@ The class `PolyfillExtensions` includes the following extension methods: ### TextReader * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) + * `Task ReadLineAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readlineasync(system-threading-cancellationtoken)) * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) diff --git a/src/Polyfill/Nullability/NullabilityInfo.cs b/src/Polyfill/Nullability/NullabilityInfo.cs index 62080a8e..fab30c11 100644 --- a/src/Polyfill/Nullability/NullabilityInfo.cs +++ b/src/Polyfill/Nullability/NullabilityInfo.cs @@ -1,3 +1,4 @@ + // #if !NET6_0_OR_GREATER @@ -13,7 +14,7 @@ namespace System.Reflection { /// - /// A class that represents nullability info. + /// A class that represents nullability info /// #if PolyPublic public @@ -32,29 +33,29 @@ internal NullabilityInfo(Type type, NullabilityState readState, NullabilityState /// /// The of the member or generic parameter - /// to which this NullabilityInfo belongs. + /// to which this NullabilityInfo belongs /// public Type Type { get; } /// - /// The nullability read state of the member. + /// The nullability read state of the member /// public NullabilityState ReadState { get; internal set; } /// - /// The nullability write state of the member. + /// The nullability write state of the member /// public NullabilityState WriteState { get; internal set; } /// - /// If the member type is an array, gives the of the elements of the array, null otherwise. + /// If the member type is an array, gives the of the elements of the array, null otherwise /// public NullabilityInfo? ElementType { get; } /// - /// If the member type is a generic type, gives the array of for each type parameter. + /// If the member type is a generic type, gives the array of for each type parameter /// public NullabilityInfo[] GenericTypeArguments { get; } } /// - /// An enum that represents nullability state. + /// An enum that represents nullability state /// #if PolyPublic public @@ -62,15 +63,15 @@ internal NullabilityInfo(Type type, NullabilityState readState, NullabilityState enum NullabilityState { /// - /// Nullability context not enabled (oblivious). + /// Nullability context not enabled (oblivious) /// Unknown, /// - /// Non nullable value or reference type. + /// Non nullable value or reference type /// NotNull, /// - /// Nullable value or reference type. + /// Nullable value or reference type /// Nullable } diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs index dbf983de..2fa66849 100644 --- a/src/Polyfill/Nullability/NullabilityInfoContext.cs +++ b/src/Polyfill/Nullability/NullabilityInfoContext.cs @@ -1,3 +1,4 @@ + // #if !NET6_0_OR_GREATER @@ -581,7 +582,7 @@ static int CountNullabilityStates(Type type) } } - private bool TryPopulateNullabilityInfo(NullabilityInfo nullability, NullableAttributeStateParser parser, ref int index) + private static bool TryPopulateNullabilityInfo(NullabilityInfo nullability, NullableAttributeStateParser parser, ref int index) { bool isValueType = IsValueTypeOrValueTypeByRef(nullability.Type); if (!isValueType) diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index c00ac2af..95c7a0dc 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -10,7 +10,7 @@ class BuildApiTest "System.Net.Http.", "System.Text.", "System.IO.", - "System.", + "System." }; [Test] diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs index 6999943c..3f5b64cb 100644 --- a/src/Tests/NullabilitySync.cs +++ b/src/Tests/NullabilitySync.cs @@ -34,19 +34,22 @@ public async Task Run() var info = await client.GetStringAsync("https://raw.githubusercontent.com/dotnet/runtime/main/src/libraries/System.Private.CoreLib/src/System/Reflection/NullabilityInfo.cs"); - var prefix = @" -#if !NET6_0_OR_GREATER + var prefix = """ + // -#nullable enable + #if !NET6_0_OR_GREATER -// ReSharper disable All + #nullable enable -using System.Linq; -"; + using System.Linq; - var suffix = @" -#endif -"; + """; + + var suffix = """ + + #endif + + """; infoContext = prefix + infoContext + suffix; infoContext = MakeInternal(infoContext); From 0d12b2a22ab1c3b822aeb8ed6740d68e57430cb4 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 31 Jul 2023 11:19:42 +1000 Subject: [PATCH 160/313] cleanup --- src/Polyfill/Nullability/NullabilityInfo.cs | 3 +-- src/Polyfill/Nullability/NullabilityInfoContext.cs | 3 +-- src/Tests/NullabilitySync.cs | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Polyfill/Nullability/NullabilityInfo.cs b/src/Polyfill/Nullability/NullabilityInfo.cs index fab30c11..81113c72 100644 --- a/src/Polyfill/Nullability/NullabilityInfo.cs +++ b/src/Polyfill/Nullability/NullabilityInfo.cs @@ -1,4 +1,3 @@ - // #if !NET6_0_OR_GREATER @@ -77,4 +76,4 @@ enum NullabilityState } } -#endif +#endif \ No newline at end of file diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs index 2fa66849..a0200dd0 100644 --- a/src/Polyfill/Nullability/NullabilityInfoContext.cs +++ b/src/Polyfill/Nullability/NullabilityInfoContext.cs @@ -1,4 +1,3 @@ - // #if !NET6_0_OR_GREATER @@ -665,4 +664,4 @@ public bool ParseNullableState(int index, ref NullabilityState state) } } -#endif +#endif \ No newline at end of file diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs index 3f5b64cb..7587127f 100644 --- a/src/Tests/NullabilitySync.cs +++ b/src/Tests/NullabilitySync.cs @@ -83,7 +83,7 @@ static void OverWrite(string content, string file) { var path = Path.Combine(dir, file); File.Delete(path); - File.WriteAllText(path, content); + File.WriteAllText(path, content.Trim()); } } #endif \ No newline at end of file From df090956ab91e0bef076b41ea3fbe43e4542d472 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 31 Jul 2023 11:21:42 +1000 Subject: [PATCH 161/313] Update api_list.include.md --- api_list.include.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/api_list.include.md b/api_list.include.md index 731e2d90..9b4ee3ca 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -75,6 +75,11 @@ * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) +### IEnumerable + + * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + + ### IEnumerable * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) From b802f15cafc54c2d848862292cb92d7d0cc3a20e Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 31 Jul 2023 11:45:58 +1000 Subject: [PATCH 162/313] fix docs --- api_list.include.md | 199 ++++++++++++++------------------------ readme.md | 196 ++++++++++++++----------------------- src/Tests/BuildApiTest.cs | 4 +- 3 files changed, 146 insertions(+), 253 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index 9b4ee3ca..2551ce55 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -8,9 +8,26 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) -### CancellationTokenSource +### IEnumerable - * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) + * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `TSource MaxBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `TSource MinBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) + + +### IReadOnlyDictionary + + * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) + * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) + + +### KeyValuePair + + * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) ### DateTime @@ -39,105 +56,84 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) -### Reflection.EventInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean IsNullable()` - - -### Reflection.FieldInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean IsNullable()` - - -### HttpClient - - * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) - * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) - * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)) - * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)) - * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) - * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) - - -### HttpContent - - * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) - * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) - * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) - - -### IEnumerable - - * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) - - -### IEnumerable - - * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) - - -### IEnumerable +### Int16 - * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) -### IEnumerable +### Int32 - * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat) -### IEnumerable +### Int64 - * `TSource MaxBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat) -### IEnumerable +### Stream - * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) -### IEnumerable +### TextReader - * `TSource MinBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) + * `Task ReadLineAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readlineasync(system-threading-cancellationtoken)) + * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) -### IEnumerable +### TextWriter - * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) + * `Void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Void WriteLine(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) + * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) -### Int16 +### HttpClient - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) + * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) + * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)) + * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) + * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) -### Int32 +### HttpContent - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat) + * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) + * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) + * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) -### Int64 +### ReadOnlySpan - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat) + * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) -### IReadOnlyDictionary +### ReadOnlySpan - * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) -### IReadOnlyDictionary +### Reflection.EventInfo - * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` -### KeyValuePair +### Reflection.FieldInfo - * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` ### Reflection.MemberInfo @@ -162,26 +158,6 @@ * `Boolean IsNullable()` -### ReadOnlySpan - - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) - - -### ReadOnlySpan - - * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - - -### ReadOnlySpan - - * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - - -### ReadOnlySpan - - * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - - ### SByte * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat) @@ -192,31 +168,16 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat) -### Span - - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) - - ### Span + * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) - - -### Span - * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) -### Span - - * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) - - -### Stream +### Span - * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) ### String @@ -239,6 +200,11 @@ * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) +### CancellationTokenSource + + * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) + + ### Task * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) @@ -249,33 +215,10 @@ ### Task * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) - - -### Task - * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)) - - -### Task - * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)) -### TextReader - - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) - * `Task ReadLineAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readlineasync(system-threading-cancellationtoken)) - * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) - - -### TextWriter - - * `Void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Void WriteLine(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) - * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - - ### TimeSpan * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds) diff --git a/readme.md b/readme.md index 1fddfde8..1f8bff37 100644 --- a/readme.md +++ b/readme.md @@ -357,9 +357,28 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) -### CancellationTokenSource +### IEnumerable - * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) + * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `IEnumerable Except(IEqualityComparer, TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `TSource MaxBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `TSource MinBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) + + +### IReadOnlyDictionary + + * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) + * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) + + +### KeyValuePair + + * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) ### DateTime @@ -388,100 +407,84 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) -### Reflection.EventInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean IsNullable()` - - -### Reflection.FieldInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean IsNullable()` - - -### HttpClient - - * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) - * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) - * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)) - * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)) - * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) - * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) - - -### HttpContent - - * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) - * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) - * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) - - -### IEnumerable - - * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) - - -### IEnumerable +### Int16 - * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) -### IEnumerable +### Int32 - * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat) -### IEnumerable +### Int64 - * `TSource MaxBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat) -### IEnumerable +### Stream - * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) -### IEnumerable +### TextReader - * `TSource MinBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) + * `Task ReadLineAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readlineasync(system-threading-cancellationtoken)) + * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) -### IEnumerable +### TextWriter - * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) + * `Void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Void WriteLine(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) + * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) -### Int16 +### HttpClient - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) + * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) + * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)) + * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) + * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) -### Int32 +### HttpContent - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat) + * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) + * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) + * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) -### Int64 +### ReadOnlySpan - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat) + * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) -### IReadOnlyDictionary +### ReadOnlySpan - * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) -### IReadOnlyDictionary +### Reflection.EventInfo - * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` -### KeyValuePair +### Reflection.FieldInfo - * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` ### Reflection.MemberInfo @@ -506,26 +509,6 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean IsNullable()` -### ReadOnlySpan - - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) - - -### ReadOnlySpan - - * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - - -### ReadOnlySpan - - * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - - -### ReadOnlySpan - - * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - - ### SByte * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat) @@ -536,31 +519,16 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat) -### Span - - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) - - ### Span + * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) - - -### Span - * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) -### Span - - * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) - - -### Stream +### Span - * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) ### String @@ -583,6 +551,11 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) +### CancellationTokenSource + + * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) + + ### Task * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) @@ -593,33 +566,10 @@ The class `PolyfillExtensions` includes the following extension methods: ### Task * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) - - -### Task - * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)) - - -### Task - * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)) -### TextReader - - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) - * `Task ReadLineAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readlineasync(system-threading-cancellationtoken)) - * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) - - -### TextWriter - - * `Void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Void WriteLine(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) - * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - - ### TimeSpan * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds) diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index 95c7a0dc..c7cfdd3c 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -24,7 +24,7 @@ public void Run() var extensions = module.GetTypes().Single(_ => _.Name == nameof(PolyfillExtensions)); using var writer = File.CreateText(md); - foreach (var type in extensions.Methods.Where(_ => !_.IsConstructor).GroupBy(_ => _.Parameters[0].ParameterType).OrderBy(_ => _.Key.Name)) + foreach (var type in extensions.Methods.Where(_ => !_.IsConstructor).GroupBy(_ => _.Parameters[0].ParameterType.FullName).OrderBy(_ => _.Key)) { if (!type.Any(_ => _.IsPublic)) { @@ -32,7 +32,7 @@ public void Run() } var targetType = type.Key; - var targetFullName = targetType.FullName.Replace("`1", "").Replace("`2", ""); + var targetFullName = targetType.Replace("`1", "").Replace("`2", ""); writer.WriteLine($"### {SimpleTypeName(targetFullName)}"); writer.WriteLine(); foreach (var method in type.OrderBy(_ => _.Name)) From 2605a4a87f40eb8e3c07dca7762183b5469bce7d Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 31 Jul 2023 11:50:39 +1000 Subject: [PATCH 163/313] Add params based Enumerable.Except (#70) * Update PolyfillExtensions_IEnumerable.cs * Update api_list.include.md * Update Directory.Build.props --- api_list.include.md | 2 + src/Directory.Build.props | 2 +- .../PolyfillExtensions_IEnumerable.cs | 43 +++++++++++++++++-- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index 2551ce55..0d79f8c3 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -11,7 +11,9 @@ ### IEnumerable * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `IEnumerable Except(IEqualityComparer, TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) * `TSource MaxBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 8ed6ef5c..ee2cc11e 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.25.0 + 1.26.0 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index 43a78da7..a6e8ad1e 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -10,14 +10,16 @@ static partial class PolyfillExtensions { /// - /// Produces the set difference of two sequences by using the default equality comparer to compare values. + /// Produces a set items excluding by using the default equality comparer to compare values. /// /// An whose elements that are not equal to will be returned. /// An that is elements equal it will cause those elements to be removed from the returned sequence. /// The type of the elements of . /// A sequence that contains the items of but excluding . [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] - public static IEnumerable Except(this IEnumerable target, TSource item) + public static IEnumerable Except( + this IEnumerable target, + TSource item) { return Except(target, item, null); } @@ -27,11 +29,29 @@ public static IEnumerable Except(this IEnumerable tar /// /// An whose elements that are not equal to will be returned. /// An that is elements equal it will cause those elements to be removed from the returned sequence. + /// The type of the elements of . + /// A sequence that contains the items of but excluding . + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] + public static IEnumerable Except( + this IEnumerable target, + params TSource[] items) + { + return target.Except((IEnumerable)items); + } + + /// + /// Produces a set items excluding by using to compare values. + /// + /// An whose elements that are not equal to will be returned. + /// An that is elements equal it will cause those elements to be removed from the returned sequence. /// An to compare values. /// The type of the elements of . /// A sequence that contains the items of but excluding . [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] - public static IEnumerable Except(this IEnumerable target, TSource item, IEqualityComparer? comparer) + public static IEnumerable Except( + this IEnumerable target, + TSource item, + IEqualityComparer? comparer) { var set = new HashSet(comparer); set.Add(item); @@ -44,6 +64,23 @@ public static IEnumerable Except(this IEnumerable tar } } + /// + /// Produces the set difference of two sequences by to compare values. + /// + /// An whose elements that are not equal to will be returned. + /// An that is elements equal it will cause those elements to be removed from the returned sequence. + /// The type of the elements of . + /// A sequence that contains the items of but excluding . + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] + public static IEnumerable Except( + this IEnumerable target, + IEqualityComparer comparer, + params TSource[] items) + { + return target.Except((IEnumerable)items, comparer); + } + + #if NETSTANDARD || NETCOREAPP || NETFRAMEWORK || NET5_0 /// From a9d7fc6e6479a806cae83c38ac56dad6bc09e2f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 16:21:50 +1000 Subject: [PATCH 164/313] Bump MarkdownSnippets.MsBuild from 24.5.1 to 25.0.1 in /src (#71) Bumps [MarkdownSnippets.MsBuild](https://github.com/SimonCropp/MarkdownSnippets) from 24.5.1 to 25.0.1. - [Release notes](https://github.com/SimonCropp/MarkdownSnippets/releases) - [Commits](https://github.com/SimonCropp/MarkdownSnippets/compare/24.5.1...25.0.1) --- updated-dependencies: - dependency-name: MarkdownSnippets.MsBuild dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/Tests/Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 7300a4c2..59c023a7 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -28,7 +28,7 @@ - + From 8a7df1324cd12385c474b5597ac65abb7650fad6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Aug 2023 16:22:56 +1000 Subject: [PATCH 165/313] Bump Microsoft.NET.Test.Sdk from 17.6.3 to 17.7.0 in /src (#72) Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.6.3 to 17.7.0. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.6.3...v17.7.0) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 20f3f183..b325782b 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -33,7 +33,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 17dba743..b5c542b5 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 59c023a7..3b935307 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 05f40a8d..c21c5c3c 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -28,7 +28,7 @@ - + From 25396fa1852b894bea6c8f405ea09a262a910382 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 10 Aug 2023 18:26:07 +1000 Subject: [PATCH 166/313] Update Polyfill.targets --- src/Polyfill/Polyfill.targets | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Polyfill/Polyfill.targets b/src/Polyfill/Polyfill.targets index 3c520ab7..5e1c07b9 100644 --- a/src/Polyfill/Polyfill.targets +++ b/src/Polyfill/Polyfill.targets @@ -12,14 +12,17 @@ Condition="@(PackageDependencies->WithMetadataValue('Identity', 'System.ValueTuple')->Count()) != 0">true $(DefineConstants);VALUETUPLEREFERENCED + true $(DefineConstants);MEMORYREFERENCED + true $(DefineConstants);TASKSEXTENSIONSREFERENCED + true Date: Thu, 10 Aug 2023 18:27:52 +1000 Subject: [PATCH 167/313] Update Tests.csproj --- src/Tests/Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 3b935307..f2dd0ab8 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -28,7 +28,7 @@ - + From 6b4081dcdafcd2e4169ece7bd316ba17242fe33a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Aug 2023 16:36:11 +1000 Subject: [PATCH 168/313] Bump Verify.NUnit from 20.6.0 to 20.7.0 in /src (#74) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 20.6.0 to 20.7.0. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/compare/20.6.0...20.7.0) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index b325782b..225f6f02 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index b5c542b5..3417c923 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index f2dd0ab8..b627b0a0 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index c21c5c3c..3a4ed0dd 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 0868befa308149649841b945ddf0edb0a0f582b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 19:16:03 +1000 Subject: [PATCH 169/313] Bump MarkdownSnippets.MsBuild from 25.0.1 to 25.1.0 in /src (#76) Bumps [MarkdownSnippets.MsBuild](https://github.com/SimonCropp/MarkdownSnippets) from 25.0.1 to 25.1.0. - [Release notes](https://github.com/SimonCropp/MarkdownSnippets/releases) - [Commits](https://github.com/SimonCropp/MarkdownSnippets/compare/25.0.1...25.1.0) --- updated-dependencies: - dependency-name: MarkdownSnippets.MsBuild dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/Tests/Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index b627b0a0..b9de3223 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -28,7 +28,7 @@ - + From ee44e7667cfc19b343a7a443e12b8f9db4352c05 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 19:16:07 +1000 Subject: [PATCH 170/313] Bump Verify.NUnit from 20.7.0 to 20.8.0 in /src (#75) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 20.7.0 to 20.8.0. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/compare/20.7.0...20.8.0) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 225f6f02..8ee1edea 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 3417c923..f27fb272 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index b9de3223..f28496ca 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 3a4ed0dd..eb88c02c 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From a49c89a0494569ff5fbb0c2e12c01fbd1c6fa342 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Aug 2023 17:04:46 +1000 Subject: [PATCH 171/313] Bump Microsoft.NET.Test.Sdk from 17.7.0 to 17.7.1 in /src (#77) Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.7.0 to 17.7.1. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.7.0...v17.7.1) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 8ee1edea..9727d751 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -33,7 +33,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index f27fb272..efc1fab4 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index f28496ca..e216da0e 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index eb88c02c..3a2cf207 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -28,7 +28,7 @@ - + From dafa45b4b2edf2b424497e826596fb7153b4e7a4 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 21 Aug 2023 20:26:23 +1000 Subject: [PATCH 172/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 9727d751..23e29fb2 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index efc1fab4..76bc88a8 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index e216da0e..2bc6b689 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 3a2cf207..2675de62 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From f0cf97688d7b47dd4de6c4dec7043f27b32bbc89 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 23 Aug 2023 13:56:32 +1000 Subject: [PATCH 173/313] Update readme.md --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 1f8bff37..07ea8b69 100644 --- a/readme.md +++ b/readme.md @@ -347,7 +347,7 @@ Reference: [Improvements in native code interop in .NET 5.0](https://devblogs.mi The class `PolyfillExtensions` includes the following extension methods: -### Boolean +### Boolean * `Boolean TryFormat(Span, Int32&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat) @@ -595,7 +595,7 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat) - + ## References From 845b90f9e1f671c4c202026c4799a9324d860f2d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Aug 2023 20:24:03 +1000 Subject: [PATCH 174/313] Bump Verify.NUnit from 20.8.1 to 20.8.2 in /src (#80) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 20.8.1 to 20.8.2. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/compare/20.8.1...20.8.2) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 23e29fb2..de532647 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 76bc88a8..f43f31ae 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 2bc6b689..7ee3b2fa 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 2675de62..828502a8 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 1c55286d82c9b312a7b13babced15bf96c65ca4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Mon, 28 Aug 2023 13:07:03 +0200 Subject: [PATCH 175/313] Added `IEnumerable Chunk (this IEnumerable source, int size)`, which was introduced in .NET 6 (#79) * Added `IEnumerable Chunk (this System.Collections.Generic.IEnumerable source, int size)`, which was introduced in .NET 6 * chore: Added missing tests for `IEnumerable Chunk(Int32)` * chore: Added missing `[Link]` and additional tests --- api_list.include.md | 1 + readme.md | 1 + .../PolyfillExtensions_IEnumerable.cs | 87 +++++++++++++++++++ .../PolyfillExtensionsTests_IEnumerable.cs | 44 +++++++++- 4 files changed, 131 insertions(+), 2 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index 0d79f8c3..ef93acad 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -10,6 +10,7 @@ ### IEnumerable + * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) diff --git a/readme.md b/readme.md index 07ea8b69..b601eca4 100644 --- a/readme.md +++ b/readme.md @@ -359,6 +359,7 @@ The class `PolyfillExtensions` includes the following extension methods: ### IEnumerable + * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index a6e8ad1e..8c5d1f43 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -83,6 +83,93 @@ public static IEnumerable Except( #if NETSTANDARD || NETCOREAPP || NETFRAMEWORK || NET5_0 + /// + /// Split the elements of a sequence into chunks of size at most . + /// + /// + /// Every chunk except the last will be of size . + /// The last chunk will contain the remaining elements and may be of a smaller size. + /// + /// An whose elements to chunk. + /// Maximum size of each chunk. + /// The type of the elements of source. + /// + /// An that contains the elements the input sequence split into chunks of size . + /// + /// is null. + /// is below 1. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk")] + public static IEnumerable Chunk(this IEnumerable source, int size) + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (size < 1) + { + throw new ArgumentOutOfRangeException(nameof(size), size, "Size must be greater than 0."); + } + + return ChunkIterator(source, size); + + static IEnumerable ChunkIterator(IEnumerable source, int size) + { + using IEnumerator e = source.GetEnumerator(); + + // Before allocating anything, make sure there's at least one element. + if (e.MoveNext()) + { + // Now that we know we have at least one item, allocate an initial storage array. This is not + // the array we'll yield. It starts out small in order to avoid significantly overallocating + // when the source has many fewer elements than the chunk size. + int arraySize = Math.Min(size, 4); + int i; + do + { + var array = new TSource[arraySize]; + + // Store the first item. + array[0] = e.Current; + i = 1; + + if (size != array.Length) + { + // This is the first chunk. As we fill the array, grow it as needed. + for (; i < size && e.MoveNext(); i++) + { + if (i >= array.Length) + { + arraySize = (int)Math.Min((uint)size, 2 * (uint)array.Length); + Array.Resize(ref array, arraySize); + } + + array[i] = e.Current; + } + } + else + { + // For all but the first chunk, the array will already be correctly sized. + // We can just store into it until either it's full or MoveNext returns false. + TSource[] local = array; // avoid bounds checks by using cached local (`array` is lifted to iterator object as a field) + for (; (uint)i < (uint)local.Length && e.MoveNext(); i++) + { + local[i] = e.Current; + } + } + + if (i != array.Length) + { + Array.Resize(ref array, i); + } + + yield return array; + } + while (i >= size && e.MoveNext()); + } + } + } + /// /// Returns the maximum value in a generic sequence according to a specified key selector function. /// diff --git a/src/Tests/PolyfillExtensionsTests_IEnumerable.cs b/src/Tests/PolyfillExtensionsTests_IEnumerable.cs index 963580c2..c1a19bf0 100644 --- a/src/Tests/PolyfillExtensionsTests_IEnumerable.cs +++ b/src/Tests/PolyfillExtensionsTests_IEnumerable.cs @@ -34,8 +34,48 @@ public void IEnumerableAppend() [Test] public void IEnumerableSkipLast() { - var enumerable = (IEnumerable)new List {"a", "b"}; + var enumerable = (IEnumerable)new List { "a", "b" }; + + Assert.IsTrue(enumerable.SkipLast(1).SequenceEqual(new List { "a" })); + } + + [Test] + public void Chunk_SizeOf3() + { + var enumerable = Enumerable.Range(1, 11).ToList(); + + var chunks = enumerable.Chunk(3).ToList(); + + Assert.AreEqual(new int[] { 1, 2, 3 }, chunks[0]); + Assert.AreEqual(new int[] { 4, 5, 6 }, chunks[1]); + Assert.AreEqual(new int[] { 7, 8, 9 }, chunks[2]); + Assert.AreEqual(new int[] { 10, 11 }, chunks[3]); + } + + [Test] + public void Chunk_SizeOf8() + { + var enumerable = Enumerable.Range(1, 11).ToList(); + + var chunks = enumerable.Chunk(8).ToList(); + + Assert.AreEqual(new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }, chunks[0]); + Assert.AreEqual(new int[] { 9, 10, 11 }, chunks[1]); + } + + [Test] + public void Chunk_SizeOfZero_ExpectedException() + { + var enumerable = Enumerable.Range(1, 11).ToList(); + + Assert.Throws(() => enumerable.Chunk(0).ToList()); + } + + [Test] + public void Chunk_Null_ExpectedException() + { + IEnumerable values = null!; - Assert.IsTrue(enumerable.SkipLast(1).SequenceEqual(new List {"a"})); + Assert.Throws(() => values.Chunk(1).ToList()); } } From ec2ec72edb6ef17ec470407727dfc248e5ce8266 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 28 Aug 2023 21:17:23 +1000 Subject: [PATCH 176/313] Update Consume.cs --- src/Consume/Consume.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 8ed99e35..0050514c 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -80,6 +80,7 @@ class Consume }; var append = enumerable.Append("c"); var maxBy = enumerable.MaxBy(_=>_); + var chunk = enumerable.Chunk(3); var minBy = enumerable.MinBy(_=>_); var skipLast = enumerable.SkipLast(1); From dcf3172668ffe181dc5acc84bdcb089ca60090ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Mon, 28 Aug 2023 13:36:00 +0200 Subject: [PATCH 177/313] Add `UnreachableException`, which was introduced in .NET 7 (#78) * Add `UnreachableException`, which was introduced in .NET 7 * Added test to check targetframework compatiblity --- src/Polyfill/UnreachableException.cs | 57 ++++++++++++++++++++++++++ src/Tests/UnreachableExceptionTests.cs | 11 +++++ 2 files changed, 68 insertions(+) create mode 100644 src/Polyfill/UnreachableException.cs create mode 100644 src/Tests/UnreachableExceptionTests.cs diff --git a/src/Polyfill/UnreachableException.cs b/src/Polyfill/UnreachableException.cs new file mode 100644 index 00000000..0de4e6ca --- /dev/null +++ b/src/Polyfill/UnreachableException.cs @@ -0,0 +1,57 @@ +// + +#if !NET7_0_OR_GREATER + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text; + +namespace System.Diagnostics; + +/// +/// Exception thrown when the program executes an instruction that was thought to be unreachable. +/// +/// +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +#if PolyPublic +public +#endif +sealed class UnreachableException : Exception +{ + /// + /// Initializes a new instance of the class with the default error message. + /// + public UnreachableException() + : base("The program executed an instruction that was thought to be unreachable.") + { + } + + /// + /// Initializes a new instance of the + /// class with a specified error message. + /// + /// The error message that explains the reason for the exception. + public UnreachableException(string? message) + : base(message) + { + } + + /// + /// Initializes a new instance of the + /// class with a specified error message and a reference to the inner exception that is the cause of + /// this exception. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. + public UnreachableException(string? message, Exception? innerException) + : base(message, innerException) + { + } +} + +#endif \ No newline at end of file diff --git a/src/Tests/UnreachableExceptionTests.cs b/src/Tests/UnreachableExceptionTests.cs new file mode 100644 index 00000000..6b879660 --- /dev/null +++ b/src/Tests/UnreachableExceptionTests.cs @@ -0,0 +1,11 @@ +namespace Tests; + +[TestFixture] +public class UnreachableExceptionTests +{ + [Test] + public void UnreachableException_Compatiblity_with_all_TargetFrameworks() + { + _ = Assert.Throws(() => throw new UnreachableException()); + } +} From 6fb267ce9640c2f23a64105fc3ea383cb233a4c2 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 28 Aug 2023 21:39:16 +1000 Subject: [PATCH 178/313] Update Consume.cs --- src/Consume/Consume.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 0050514c..b3da7956 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -64,6 +64,7 @@ class Consume type = typeof(SuppressGCTransitionAttribute); type = typeof(DisableRuntimeMarshallingAttribute); type = typeof(RequiresUnreferencedCodeAttribute); + type = typeof(UnreachableException); #if (NET46X && VALUETUPLEREFERENCED) || NET47X || NET48X || NETSTANDARD2_0 || NETCOREAPP2X var range = "value"[1..]; From f56b507efcf7aeccbbec9746d6d9abaa8c4409f1 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 28 Aug 2023 22:09:14 +1000 Subject: [PATCH 179/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index ee2cc11e..3a3e4f40 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.26.0 + 1.27.0 1.0.0 Polyfill true From 9435ff91c60f3bc90d60596159f758d22bc01a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Tue, 29 Aug 2023 12:20:18 +0200 Subject: [PATCH 180/313] fix: Added missing `ExcludeFromCodeCoverage` on nullability objects (#81) to reduce the code coverage impact, when Polyfill is used. --- src/Polyfill/Nullability/NullabilityInfo.cs | 6 ++++-- src/Polyfill/Nullability/NullabilityInfoContext.cs | 7 +++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Polyfill/Nullability/NullabilityInfo.cs b/src/Polyfill/Nullability/NullabilityInfo.cs index 81113c72..5c3dd4cd 100644 --- a/src/Polyfill/Nullability/NullabilityInfo.cs +++ b/src/Polyfill/Nullability/NullabilityInfo.cs @@ -9,16 +9,18 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; namespace System.Reflection { /// /// A class that represents nullability info /// - #if PolyPublic + [ExcludeFromCodeCoverage] +#if PolyPublic public #endif -sealed class NullabilityInfo + sealed class NullabilityInfo { internal NullabilityInfo(Type type, NullabilityState readState, NullabilityState writeState, NullabilityInfo? elementType, NullabilityInfo[] typeArguments) diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs index a0200dd0..51e417e9 100644 --- a/src/Polyfill/Nullability/NullabilityInfoContext.cs +++ b/src/Polyfill/Nullability/NullabilityInfoContext.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace System.Reflection { @@ -18,10 +19,11 @@ namespace System.Reflection /// Provides APIs for populating nullability information/context from reflection members: /// , , and . /// - #if PolyPublic + [ExcludeFromCodeCoverage] +#if PolyPublic public #endif -sealed class NullabilityInfoContext + sealed class NullabilityInfoContext { private const string CompilerServicesNameSpace = "System.Runtime.CompilerServices"; private readonly Dictionary _publicOnlyModules = new(); @@ -632,6 +634,7 @@ private static NullabilityState TranslateByte(byte b) => private static bool IsValueTypeOrValueTypeByRef(Type type) => type.IsValueType || ((type.IsByRef || type.IsPointer) && type.GetElementType()!.IsValueType); + [ExcludeFromCodeCoverage] private readonly struct NullableAttributeStateParser { private static readonly object UnknownByte = (byte)0; From 34ddacf603fedbed8fcf5c550fae9bd2be2e63fc Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 29 Aug 2023 20:33:26 +1000 Subject: [PATCH 181/313] Update NullabilityInfoExtensions.cs --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 3a3e4f40..e0a38b7f 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -6,7 +6,7 @@ Polyfill true false - CS1591;NETSDK1138;NU1901;NU1902 + CS1591;NETSDK1138;NU1901;NU1902;NU1903 false 11 false From 9fbbc0cfa776c1260ab8e1008415865f6e1b839b Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 29 Aug 2023 20:36:21 +1000 Subject: [PATCH 182/313] cleanup --- src/Tests/PolyfillExtensionsTests_IEnumerable.cs | 12 ++++++------ src/Tests/UnreachableExceptionTests.cs | 4 +--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Tests/PolyfillExtensionsTests_IEnumerable.cs b/src/Tests/PolyfillExtensionsTests_IEnumerable.cs index c1a19bf0..73f8c82f 100644 --- a/src/Tests/PolyfillExtensionsTests_IEnumerable.cs +++ b/src/Tests/PolyfillExtensionsTests_IEnumerable.cs @@ -46,10 +46,10 @@ public void Chunk_SizeOf3() var chunks = enumerable.Chunk(3).ToList(); - Assert.AreEqual(new int[] { 1, 2, 3 }, chunks[0]); - Assert.AreEqual(new int[] { 4, 5, 6 }, chunks[1]); - Assert.AreEqual(new int[] { 7, 8, 9 }, chunks[2]); - Assert.AreEqual(new int[] { 10, 11 }, chunks[3]); + Assert.AreEqual(new[] { 1, 2, 3 }, chunks[0]); + Assert.AreEqual(new[] { 4, 5, 6 }, chunks[1]); + Assert.AreEqual(new[] { 7, 8, 9 }, chunks[2]); + Assert.AreEqual(new[] { 10, 11 }, chunks[3]); } [Test] @@ -59,8 +59,8 @@ public void Chunk_SizeOf8() var chunks = enumerable.Chunk(8).ToList(); - Assert.AreEqual(new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }, chunks[0]); - Assert.AreEqual(new int[] { 9, 10, 11 }, chunks[1]); + Assert.AreEqual(new[] { 1, 2, 3, 4, 5, 6, 7, 8 }, chunks[0]); + Assert.AreEqual(new[] { 9, 10, 11 }, chunks[1]); } [Test] diff --git a/src/Tests/UnreachableExceptionTests.cs b/src/Tests/UnreachableExceptionTests.cs index 6b879660..93ede359 100644 --- a/src/Tests/UnreachableExceptionTests.cs +++ b/src/Tests/UnreachableExceptionTests.cs @@ -4,8 +4,6 @@ namespace Tests; public class UnreachableExceptionTests { [Test] - public void UnreachableException_Compatiblity_with_all_TargetFrameworks() - { + public void UnreachableException_Compatibility_with_all_TargetFrameworks() => _ = Assert.Throws(() => throw new UnreachableException()); - } } From c26695e52a8deff764237d2e2e4b4b40366df2f1 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 29 Aug 2023 20:39:17 +1000 Subject: [PATCH 183/313] cleanup --- src/Polyfill/Nullability/NullabilityInfo.cs | 4 ++-- src/Polyfill/Nullability/NullabilityInfoContext.cs | 5 ++--- src/Tests/NullabilitySync.cs | 2 ++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Polyfill/Nullability/NullabilityInfo.cs b/src/Polyfill/Nullability/NullabilityInfo.cs index 5c3dd4cd..65b3d0db 100644 --- a/src/Polyfill/Nullability/NullabilityInfo.cs +++ b/src/Polyfill/Nullability/NullabilityInfo.cs @@ -5,11 +5,11 @@ #nullable enable using System.Linq; +using System.Diagnostics.CodeAnalysis; // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.ObjectModel; -using System.Diagnostics.CodeAnalysis; namespace System.Reflection { @@ -20,7 +20,7 @@ namespace System.Reflection #if PolyPublic public #endif - sealed class NullabilityInfo +sealed class NullabilityInfo { internal NullabilityInfo(Type type, NullabilityState readState, NullabilityState writeState, NullabilityInfo? elementType, NullabilityInfo[] typeArguments) diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs index 51e417e9..18964394 100644 --- a/src/Polyfill/Nullability/NullabilityInfoContext.cs +++ b/src/Polyfill/Nullability/NullabilityInfoContext.cs @@ -5,13 +5,13 @@ #nullable enable using System.Linq; +using System.Diagnostics.CodeAnalysis; // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; namespace System.Reflection { @@ -23,7 +23,7 @@ namespace System.Reflection #if PolyPublic public #endif - sealed class NullabilityInfoContext +sealed class NullabilityInfoContext { private const string CompilerServicesNameSpace = "System.Runtime.CompilerServices"; private readonly Dictionary _publicOnlyModules = new(); @@ -634,7 +634,6 @@ private static NullabilityState TranslateByte(byte b) => private static bool IsValueTypeOrValueTypeByRef(Type type) => type.IsValueType || ((type.IsByRef || type.IsPointer) && type.GetElementType()!.IsValueType); - [ExcludeFromCodeCoverage] private readonly struct NullableAttributeStateParser { private static readonly object UnknownByte = (byte)0; diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs index 7587127f..fff2e87a 100644 --- a/src/Tests/NullabilitySync.cs +++ b/src/Tests/NullabilitySync.cs @@ -42,6 +42,7 @@ public async Task Run() #nullable enable using System.Linq; + using System.Diagnostics.CodeAnalysis; """; @@ -73,6 +74,7 @@ static string MakeInternal(string source) => .Replace( "public sealed class", """ + [ExcludeFromCodeCoverage] #if PolyPublic public #endif From 540ee913bb58aadbff62e757e1326bfbf1918035 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 29 Aug 2023 20:44:09 +1000 Subject: [PATCH 184/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index e0a38b7f..8467f118 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.27.0 + 1.27.1 1.0.0 Polyfill true From 44633e500b4ddd42b7ae442e61d6544a35257bb2 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 30 Aug 2023 09:32:18 +1000 Subject: [PATCH 185/313] Update global.json --- src/global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/global.json b/src/global.json index 7dc80be7..4b1e4f13 100644 --- a/src/global.json +++ b/src/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100-preview.6.23330.14", + "version": "8.0.100-preview.7.23376.3", "allowPrerelease": true, "rollForward": "latestFeature" } From 15ec8a2baf1a0e0c5d11b7955e6160eec4d8a671 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Aug 2023 16:50:05 +1000 Subject: [PATCH 186/313] Bump Microsoft.NET.Test.Sdk from 17.7.1 to 17.7.2 in /src (#82) Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.7.1 to 17.7.2. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.7.1...v17.7.2) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index de532647..8ccc2e4b 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -33,7 +33,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index f43f31ae..3dc8cb6f 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 7ee3b2fa..234937d3 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 828502a8..de7c75ad 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -28,7 +28,7 @@ - + From 20fbaba340c80964805ee06bd6145659f2ef045a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Sep 2023 07:18:07 +1000 Subject: [PATCH 187/313] Bump Verify.NUnit from 20.8.2 to 21.0.0 in /src (#83) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 20.8.2 to 21.0.0. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/compare/20.8.2...21.0.0) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 8ccc2e4b..a994be51 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 3dc8cb6f..bc0d3227 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 234937d3..9b40c019 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index de7c75ad..b59138b4 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From d1f64c785747ddc38a65edecad0c70ad0ec73241 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 1 Sep 2023 18:51:41 +1000 Subject: [PATCH 188/313] Update Directory.Build.props --- src/Directory.Build.props | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 8467f118..210c96ac 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -11,5 +11,6 @@ 11 false true + true \ No newline at end of file From 8f273f18ec3f8b7f32b574c8d53b0bce3ae9c0d1 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 4 Sep 2023 20:29:41 +1000 Subject: [PATCH 189/313] Revert "Bump Verify.NUnit from 20.8.2 to 21.0.0 in /src (#83)" This reverts commit 20fbaba340c80964805ee06bd6145659f2ef045a. --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index a994be51..8ccc2e4b 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index bc0d3227..3dc8cb6f 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 9b40c019..234937d3 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index b59138b4..de7c75ad 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 7616816d159d5e209e58a1baf190538b27b3cef0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Sep 2023 16:59:33 +1000 Subject: [PATCH 190/313] Bump ProjectDefaults from 1.0.91 to 1.0.93 in /src (#85) Bumps [ProjectDefaults](https://github.com/SimonCropp/ProjectDefaults) from 1.0.91 to 1.0.93. - [Commits](https://github.com/SimonCropp/ProjectDefaults/commits) --- updated-dependencies: - dependency-name: ProjectDefaults dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/Polyfill/Polyfill.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 8ccc2e4b..c3bad1dd 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -34,7 +34,7 @@ - + diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index be1401f9..0e35fb14 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 3dc8cb6f..c9158c32 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 234937d3..f76f197e 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index de7c75ad..c512a26f 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -29,7 +29,7 @@ - + From 1e7adf30fbae5748e2200edcca129f95c1dd973c Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 6 Sep 2023 20:00:09 +1000 Subject: [PATCH 191/313] refs --- src/.editorconfig | 57 +++++++------- src/Shared.sln.DotSettings | 157 +++++++++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+), 30 deletions(-) create mode 100644 src/Shared.sln.DotSettings diff --git a/src/.editorconfig b/src/.editorconfig index 196bb349..b367202d 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -13,21 +13,18 @@ charset = utf-8 # Microsoft .NET properties +trim_trailing_whitespace = true csharp_preferred_modifier_order = public, private, protected, internal, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async:suggestion -csharp_style_namespace_declarations = file_scoped:error -dotnet_naming_rule.private_constants_rule.import_to_resharper = as_predefined +resharper_namespace_body = file_scoped dotnet_naming_rule.private_constants_rule.severity = warning dotnet_naming_rule.private_constants_rule.style = upper_camel_case_style dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols -dotnet_naming_rule.private_instance_fields_rule.import_to_resharper = as_predefined dotnet_naming_rule.private_instance_fields_rule.severity = warning dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols -dotnet_naming_rule.private_static_fields_rule.import_to_resharper = as_predefined dotnet_naming_rule.private_static_fields_rule.severity = warning dotnet_naming_rule.private_static_fields_rule.style = lower_camel_case_style dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols -dotnet_naming_rule.private_static_readonly_rule.import_to_resharper = as_predefined dotnet_naming_rule.private_static_readonly_rule.severity = warning dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style dotnet_naming_rule.private_static_readonly_rule.symbols = private_static_readonly_symbols @@ -49,8 +46,6 @@ dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none # ReSharper properties -resharper_apply_on_completion = true -resharper_csharp_wrap_lines = false resharper_object_creation_when_type_not_evident = target_typed # ReSharper inspection severities @@ -79,12 +74,12 @@ resharper_redundant_suppress_nullable_warning_expression_highlighting = error resharper_redundant_using_directive_highlighting = error resharper_redundant_verbatim_string_prefix_highlighting = error resharper_replace_substring_with_range_indexer_highlighting = warning -resharper_suggest_var_or_type_built_in_types_highlighting = hint -resharper_suggest_var_or_type_elsewhere_highlighting = hint -resharper_suggest_var_or_type_simple_types_highlighting = hint +resharper_suggest_var_or_type_built_in_types_highlighting = error +resharper_suggest_var_or_type_elsewhere_highlighting = error +resharper_suggest_var_or_type_simple_types_highlighting = error resharper_unnecessary_whitespace_highlighting = error resharper_use_await_using_highlighting = warning -resharper_use_deconstruction_highlighting = error +resharper_use_deconstruction_highlighting = warning # Sort using and Import directives with System.* appearing first dotnet_sort_system_directives_first = true @@ -113,9 +108,10 @@ csharp_style_var_elsewhere = true:error # Prefer method-like constructs to have a block body csharp_style_expression_bodied_methods = true:error +csharp_style_expression_bodied_local_functions = true:error csharp_style_expression_bodied_constructors = true:error csharp_style_expression_bodied_operators = true:error -csharp_place_expr_method_on_single_line = false +resharper_place_expr_method_on_single_line = false # Prefer property-like constructs to have an expression-body csharp_style_expression_bodied_properties = true:error @@ -128,42 +124,43 @@ csharp_style_pattern_matching_over_as_with_null_check = true:error csharp_style_inlined_variable_declaration = true:suggestion csharp_style_throw_expression = true:suggestion csharp_style_conditional_delegate_call = true:suggestion -csharp_style_prefer_switch_expression = true:suggestion # Newline settings #csharp_new_line_before_open_brace = all:error -max_array_initializer_elements_on_line = 1 +resharper_max_array_initializer_elements_on_line = 1 csharp_new_line_before_else = true csharp_new_line_before_catch = true csharp_new_line_before_finally = true csharp_new_line_before_members_in_object_initializers = true csharp_new_line_before_members_in_anonymous_types = true -csharp_place_type_constraints_on_same_line = false:error -csharp_wrap_before_first_type_parameter_constraint = true:error -csharp_wrap_extends_list_style = true:error -csharp_wrap_after_dot_in_method_calls false -csharp_wrap_before_binary_pattern_op false -resharper_csharp_wrap_object_and_collection_initializer_style = chop_always -resharper_csharp_place_simple_initializer_on_single_line = false +resharper_wrap_before_first_type_parameter_constraint = true +resharper_wrap_extends_list_style = chop_always +resharper_wrap_after_dot_in_method_calls = false +resharper_wrap_before_binary_pattern_op = false +resharper_wrap_object_and_collection_initializer_style = chop_always +resharper_place_simple_initializer_on_single_line = false dotnet_style_require_accessibility_modifiers = never:error resharper_place_type_constraints_on_same_line = false +resharper_blank_lines_inside_namespace = 0 +resharper_blank_lines_after_file_scoped_namespace_directive = 1 +resharper_blank_lines_inside_type = 0 #braces https://www.jetbrains.com/help/resharper/EditorConfig_CSHARP_CSharpCodeStylePageImplSchema.html#Braces -braces_for_ifelse = required -braces_for_foreach = required -braces_for_while = required -braces_for_dowhile = required -braces_for_lock = required -braces_for_fixed = required -braces_for_for = required +resharper_braces_for_ifelse = required +resharper_braces_for_foreach = required +resharper_braces_for_while = required +resharper_braces_for_dowhile = required +resharper_braces_for_lock = required +resharper_braces_for_fixed = required +resharper_braces_for_for = required # Xml files [*.{xml,config,nuspec,resx,vsixmanifest,csproj,targets,props}] indent_size = 2 # https://www.jetbrains.com/help/resharper/EditorConfig_XML_XmlCodeStylePageSchema.html#resharper_xml_blank_line_after_pi -blank_line_after_pi = false -space_before_self_closing = true +resharper_blank_line_after_pi = false +resharper_space_before_self_closing = true [*.json] indent_size = 2 \ No newline at end of file diff --git a/src/Shared.sln.DotSettings b/src/Shared.sln.DotSettings new file mode 100644 index 00000000..bc43fc96 --- /dev/null +++ b/src/Shared.sln.DotSettings @@ -0,0 +1,157 @@ + + True + True + True + DO_NOT_SHOW + ERROR + ERROR + ERROR + WARNING + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + DO_NOT_SHOW + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + C90+,E79+,S14+ + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + ERROR + DO_NOT_SHOW + *.received.* + *.verified.* + ERROR + ERROR + DO_NOT_SHOW + ECMAScript 2016 + <?xml version="1.0" encoding="utf-16"?><Profile name="c# Cleanup"><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><CSCodeStyleAttributes ArrangeVarStyle="True" ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeCodeBodyStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" /><CssAlphabetizeProperties>True</CssAlphabetizeProperties><JSStringLiteralQuotesDescriptor>True</JSStringLiteralQuotesDescriptor><CorrectVariableKindsDescriptor>True</CorrectVariableKindsDescriptor><VariablesToInnerScopesDescriptor>True</VariablesToInnerScopesDescriptor><StringToTemplatesDescriptor>True</StringToTemplatesDescriptor><JsInsertSemicolon>True</JsInsertSemicolon><RemoveRedundantQualifiersTs>True</RemoveRedundantQualifiersTs><OptimizeImportsTs>True</OptimizeImportsTs><OptimizeReferenceCommentsTs>True</OptimizeReferenceCommentsTs><PublicModifierStyleTs>True</PublicModifierStyleTs><ExplicitAnyTs>True</ExplicitAnyTs><TypeAnnotationStyleTs>True</TypeAnnotationStyleTs><RelativePathStyleTs>True</RelativePathStyleTs><AsInsteadOfCastTs>True</AsInsteadOfCastTs><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CssReformatCode>True</CssReformatCode><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><HtmlReformatCode>True</HtmlReformatCode><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags><IDEA_SETTINGS>&lt;profile version="1.0"&gt; + &lt;option name="myName" value="c# Cleanup" /&gt; +&lt;/profile&gt;</IDEA_SETTINGS><RIDER_SETTINGS>&lt;profile&gt; + &lt;Language id="EditorConfig"&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="HTML"&gt; + &lt;OptimizeImports&gt;false&lt;/OptimizeImports&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; + &lt;Rearrange&gt;false&lt;/Rearrange&gt; + &lt;/Language&gt; + &lt;Language id="JSON"&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="RELAX-NG"&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; + &lt;/Language&gt; + &lt;Language id="XML"&gt; + &lt;OptimizeImports&gt;false&lt;/OptimizeImports&gt; + &lt;Reformat&gt;false&lt;/Reformat&gt; + &lt;Rearrange&gt;false&lt;/Rearrange&gt; + &lt;/Language&gt; +&lt;/profile&gt;</RIDER_SETTINGS></Profile> + ExpressionBody + ExpressionBody + ExpressionBody + False + NEVER + NEVER + False + False + False + False + RemoveIndent + RemoveIndent + False + True + True + True + True + True + ERROR + \ No newline at end of file From 51c1405b9457052fd1dcaf20edba69a996c284d5 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 6 Sep 2023 20:31:23 +1000 Subject: [PATCH 192/313] docs --- api_list.include.md | 8 ++++---- readme.md | 8 ++++---- src/Polyfill/PolyfillExtensions_IEnumerable.cs | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index ef93acad..99cd4422 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -11,10 +11,10 @@ ### IEnumerable * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) - * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) - * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) - * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) - * `IEnumerable Except(IEqualityComparer, TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) + * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) + * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) + * `IEnumerable Except(IEqualityComparer, TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) * `TSource MaxBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) diff --git a/readme.md b/readme.md index b601eca4..319d2c2d 100644 --- a/readme.md +++ b/readme.md @@ -360,10 +360,10 @@ The class `PolyfillExtensions` includes the following extension methods: ### IEnumerable * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) - * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) - * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) - * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) - * `IEnumerable Except(IEqualityComparer, TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) + * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) + * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) + * `IEnumerable Except(IEqualityComparer, TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) * `TSource MaxBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index 8c5d1f43..dc692066 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -16,7 +16,7 @@ static partial class PolyfillExtensions /// An that is elements equal it will cause those elements to be removed from the returned sequence. /// The type of the elements of . /// A sequence that contains the items of but excluding . - [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))")] public static IEnumerable Except( this IEnumerable target, TSource item) @@ -31,7 +31,7 @@ public static IEnumerable Except( /// An that is elements equal it will cause those elements to be removed from the returned sequence. /// The type of the elements of . /// A sequence that contains the items of but excluding . - [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))")] public static IEnumerable Except( this IEnumerable target, params TSource[] items) @@ -47,7 +47,7 @@ public static IEnumerable Except( /// An to compare values. /// The type of the elements of . /// A sequence that contains the items of but excluding . - [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))")] public static IEnumerable Except( this IEnumerable target, TSource item, @@ -71,7 +71,7 @@ public static IEnumerable Except( /// An that is elements equal it will cause those elements to be removed from the returned sequence. /// The type of the elements of . /// A sequence that contains the items of but excluding . - [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))")] + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))")] public static IEnumerable Except( this IEnumerable target, IEqualityComparer comparer, From 025e4de39f4a138f4547aad964a1f4a8ee7d8d96 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 6 Sep 2023 21:03:53 +1000 Subject: [PATCH 193/313] Fix some incorrect tfm matches (#86) --- readme.md | 6 +++- src/Consume/UnscopedRefUsage.cs | 8 ++++-- src/Directory.Build.props | 2 +- .../PolyfillExtensions_IEnumerable.cs | 2 +- .../PolyfillExtensions_MicroNanosecond.cs | 28 ------------------- .../PolyfillExtensions_MicroNanosecondAdd.cs | 28 +++++++++++++++++++ src/Polyfill/PolyfillExtensions_Task.cs | 2 +- src/Polyfill/PolyfillExtensions_TryFormat.cs | 4 +-- src/Polyfill/PolyfillExtensions_Type.cs | 6 ++-- 9 files changed, 46 insertions(+), 40 deletions(-) create mode 100644 src/Polyfill/PolyfillExtensions_MicroNanosecondAdd.cs diff --git a/readme.md b/readme.md index 319d2c2d..985e8172 100644 --- a/readme.md +++ b/readme.md @@ -233,6 +233,8 @@ Reference: [Low Level Struct Improvements](https://github.com/dotnet/csharplang/ ```cs +#if !NET7_0_OR_GREATER + using System.Diagnostics.CodeAnalysis; struct UnscopedRefUsage @@ -241,8 +243,10 @@ struct UnscopedRefUsage [UnscopedRef] ref int Prop1 => ref field; } + +#endif ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Consume/UnscopedRefUsage.cs b/src/Consume/UnscopedRefUsage.cs index f6552db5..dce73822 100644 --- a/src/Consume/UnscopedRefUsage.cs +++ b/src/Consume/UnscopedRefUsage.cs @@ -1,8 +1,12 @@ -using System.Diagnostics.CodeAnalysis; +#if !NET7_0_OR_GREATER + +using System.Diagnostics.CodeAnalysis; struct UnscopedRefUsage { int field; [UnscopedRef] ref int Prop1 => ref field; -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 210c96ac..1625f57d 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.27.1 + 1.27.2 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index dc692066..128724af 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -81,7 +81,7 @@ public static IEnumerable Except( } -#if NETSTANDARD || NETCOREAPP || NETFRAMEWORK || NET5_0 +#if NETSTANDARD || NETCOREAPPX || NETFRAMEWORK || NET5_0 /// /// Split the elements of a sequence into chunks of size at most . diff --git a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs index 2d2ba8f9..6c093641 100644 --- a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs +++ b/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs @@ -51,20 +51,6 @@ public static int Microsecond(this DateTime target) => public static int Microsecond(this DateTimeOffset target) => target.Microsecond; - /// - /// Returns a new object that adds a specified number of microseconds to the value of this instance.. - /// - [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds")] - public static DateTime AddMicroseconds(this DateTime target, double microseconds) => - target.AddMicroseconds(microseconds); - - /// - /// Returns a new object that adds a specified number of microseconds to the value of this instance.. - /// - [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds")] - public static DateTimeOffset AddMicroseconds(this DateTimeOffset target, double microseconds) => - target.AddMicroseconds(microseconds); - #else const long TicksPerMicrosecond = TimeSpan.TicksPerMillisecond * 1000; @@ -111,20 +97,6 @@ public static int Microsecond(this DateTime target) => public static int Microsecond(this DateTimeOffset target) => (int) (target.TicksComponent() % TicksPerMicrosecond) * 1000; - /// - /// Returns a new object that adds a specified number of microseconds to the value of this instance.. - /// - [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds")] - public static DateTime AddMicroseconds(this DateTime target, double microseconds) => - target.AddMilliseconds(microseconds / 1000); - - /// - /// Returns a new object that adds a specified number of microseconds to the value of this instance.. - /// - [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds")] - public static DateTimeOffset AddMicroseconds(this DateTimeOffset target, double microseconds) => - target.AddMilliseconds(microseconds / 1000); - static long TicksComponent(this TimeSpan target) { var noSeconds = new TimeSpan(target.Days, target.Hours, target.Minutes, 0); diff --git a/src/Polyfill/PolyfillExtensions_MicroNanosecondAdd.cs b/src/Polyfill/PolyfillExtensions_MicroNanosecondAdd.cs new file mode 100644 index 00000000..d70f4bcb --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_MicroNanosecondAdd.cs @@ -0,0 +1,28 @@ +// + +#pragma warning disable + +using System; +using Link = System.ComponentModel.DescriptionAttribute; + +static partial class PolyfillExtensions +{ + +#if !NET7_0_OR_GREATER + + /// + /// Returns a new object that adds a specified number of microseconds to the value of this instance.. + /// + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds")] + public static DateTime AddMicroseconds(this DateTime target, double microseconds) => + target.AddMilliseconds(microseconds / 1000); + + /// + /// Returns a new object that adds a specified number of microseconds to the value of this instance.. + /// + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds")] + public static DateTimeOffset AddMicroseconds(this DateTimeOffset target, double microseconds) => + target.AddMilliseconds(microseconds / 1000); + +#endif +} \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/PolyfillExtensions_Task.cs index 536353da..85a9fb2a 100644 --- a/src/Polyfill/PolyfillExtensions_Task.cs +++ b/src/Polyfill/PolyfillExtensions_Task.cs @@ -2,7 +2,7 @@ #pragma warning disable -#if NETFRAMEWORK || NETSTANDARD || NETCOREAPP || NET5_0 +#if NETFRAMEWORK || NETSTANDARD || NETCOREAPPX || NET5_0 using System; using System.Reflection; diff --git a/src/Polyfill/PolyfillExtensions_TryFormat.cs b/src/Polyfill/PolyfillExtensions_TryFormat.cs index 25184383..6c568e8b 100644 --- a/src/Polyfill/PolyfillExtensions_TryFormat.cs +++ b/src/Polyfill/PolyfillExtensions_TryFormat.cs @@ -286,7 +286,7 @@ public static bool TryFormat(this DateTime target, Span destination, out i } #endif -#if NET6_0_OR_GREATER +#if NET6_0 /// /// Tries to format the value of the current instance into the provided span of characters. @@ -329,7 +329,7 @@ public static bool TryFormat(this TimeOnly target, Span destination, out i } #endif -#if NET6_0_OR_GREATER || (MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X)) +#if NET6_0 || (MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X)) static bool CopyToSpan(Span destination, out int charsWritten, string result) { if (result.Length == 0) diff --git a/src/Polyfill/PolyfillExtensions_Type.cs b/src/Polyfill/PolyfillExtensions_Type.cs index 7830297b..f5285aee 100644 --- a/src/Polyfill/PolyfillExtensions_Type.cs +++ b/src/Polyfill/PolyfillExtensions_Type.cs @@ -8,16 +8,14 @@ static partial class PolyfillExtensions { +#if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0 [Link("https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas")] public static bool HasSameMetadataDefinitionAs(this MemberInfo target, MemberInfo other) { -#if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0 return target.MetadataToken == other.MetadataToken && target.Module.Equals(other.Module); -#else - return target.HasSameMetadataDefinitionAs(other); -#endif } +#endif /// /// Gets a value that indicates whether the current Type represents a type parameter in the definition of a generic method. From c76a1005768e08e19b157094afb076d6db7b0a86 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 6 Sep 2023 21:26:20 +1000 Subject: [PATCH 194/313] Update PolyfillExtensions_IEnumerable.cs --- src/Polyfill/PolyfillExtensions_IEnumerable.cs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index 128724af..938ef0aa 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -19,10 +19,8 @@ static partial class PolyfillExtensions [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))")] public static IEnumerable Except( this IEnumerable target, - TSource item) - { - return Except(target, item, null); - } + TSource item) => + Except(target, item, null); /// /// Produces the set difference of two sequences by using the default equality comparer to compare values. @@ -34,10 +32,8 @@ public static IEnumerable Except( [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))")] public static IEnumerable Except( this IEnumerable target, - params TSource[] items) - { - return target.Except((IEnumerable)items); - } + params TSource[] items) => + target.Except((IEnumerable)items); /// /// Produces a set items excluding by using to compare values. @@ -75,10 +71,8 @@ public static IEnumerable Except( public static IEnumerable Except( this IEnumerable target, IEqualityComparer comparer, - params TSource[] items) - { - return target.Except((IEnumerable)items, comparer); - } + params TSource[] items) => + target.Except((IEnumerable)items, comparer); #if NETSTANDARD || NETCOREAPPX || NETFRAMEWORK || NET5_0 From 8bdaccb7b21cedc25f958c8b6f8033673a8ca46d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Sep 2023 19:16:57 +1000 Subject: [PATCH 195/313] Bump ProjectDefaults from 1.0.93 to 1.0.94 in /src (#87) Bumps [ProjectDefaults](https://github.com/SimonCropp/ProjectDefaults) from 1.0.93 to 1.0.94. - [Commits](https://github.com/SimonCropp/ProjectDefaults/commits) --- updated-dependencies: - dependency-name: ProjectDefaults dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/Polyfill/Polyfill.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index c3bad1dd..aab0fa12 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -34,7 +34,7 @@ - + diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index 0e35fb14..f9f36fc3 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index c9158c32..783429ba 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index f76f197e..01a5f928 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index c512a26f..360609d6 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -29,7 +29,7 @@ - + From 51923f508b38d7b5acc960ed44e14b8e79783359 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 10 Sep 2023 23:25:51 +1000 Subject: [PATCH 196/313] Update .gitattributes --- src/.gitattributes | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/.gitattributes b/src/.gitattributes index 50e6525b..4f905c91 100644 --- a/src/.gitattributes +++ b/src/.gitattributes @@ -4,4 +4,7 @@ *.verified.txt text eol=lf working-tree-encoding=UTF-8 *.verified.xml text eol=lf working-tree-encoding=UTF-8 -*.verified.json text eol=lf working-tree-encoding=UTF-8 \ No newline at end of file +*.verified.json text eol=lf working-tree-encoding=UTF-8 + +.editorconfig text eol=lf working-tree-encoding=UTF-8 +Shared.sln.DotSettings text eol=lf working-tree-encoding=UTF-8 \ No newline at end of file From 6d9a3c99484dfcbd9a47dd7be5ccafa7476e968b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 20:07:15 +1000 Subject: [PATCH 197/313] Bump Verify.NUnit from 20.8.2 to 21.1.1 in /src (#88) Bumps [Verify.NUnit](https://github.com/VerifyTests/Verify) from 20.8.2 to 21.1.1. - [Release notes](https://github.com/VerifyTests/Verify/releases) - [Commits](https://github.com/VerifyTests/Verify/compare/20.8.2...21.1.1) --- updated-dependencies: - dependency-name: Verify.NUnit dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index aab0fa12..75947839 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 783429ba..6881c9aa 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 01a5f928..f69b92f4 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 360609d6..27d29ba2 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From b79e1e0aa640c98f24ca6810e0db1994cab41130 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Sep 2023 16:26:20 +1000 Subject: [PATCH 198/313] Bump ProjectDefaults from 1.0.94 to 1.0.96 in /src (#89) Bumps [ProjectDefaults](https://github.com/SimonCropp/ProjectDefaults) from 1.0.94 to 1.0.96. - [Commits](https://github.com/SimonCropp/ProjectDefaults/commits) --- updated-dependencies: - dependency-name: ProjectDefaults dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/Polyfill/Polyfill.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 75947839..03782a45 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -34,7 +34,7 @@ - + diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index f9f36fc3..11453abb 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 6881c9aa..b17f1976 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index f69b92f4..d4306747 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 27d29ba2..9031384c 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -29,7 +29,7 @@ - + From 62fdf3496bc5d4f3ca1f1e2fd062d6b9eda9c382 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 13 Sep 2023 10:35:42 +1000 Subject: [PATCH 199/313] refs --- src/.editorconfig | 3 +++ src/Shared.sln.DotSettings | 2 ++ src/Tests/PolyfillExtensionsTests_TryFormat.cs | 2 +- src/global.json | 2 +- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/.editorconfig b/src/.editorconfig index b367202d..bb59b63e 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -140,6 +140,9 @@ resharper_wrap_before_binary_pattern_op = false resharper_wrap_object_and_collection_initializer_style = chop_always resharper_place_simple_initializer_on_single_line = false +# space +resharper_space_around_lambda_arrow = true + dotnet_style_require_accessibility_modifiers = never:error resharper_place_type_constraints_on_same_line = false resharper_blank_lines_inside_namespace = 0 diff --git a/src/Shared.sln.DotSettings b/src/Shared.sln.DotSettings index bc43fc96..cd7dcac1 100644 --- a/src/Shared.sln.DotSettings +++ b/src/Shared.sln.DotSettings @@ -12,6 +12,7 @@ ERROR ERROR ERROR + ERROR ERROR ERROR ERROR @@ -29,6 +30,7 @@ ERROR ERROR ERROR + ERROR ERROR DO_NOT_SHOW ERROR diff --git a/src/Tests/PolyfillExtensionsTests_TryFormat.cs b/src/Tests/PolyfillExtensionsTests_TryFormat.cs index 27b8d772..df2e6bf0 100644 --- a/src/Tests/PolyfillExtensionsTests_TryFormat.cs +++ b/src/Tests/PolyfillExtensionsTests_TryFormat.cs @@ -49,7 +49,7 @@ public void TryFormatUInt16() [Test] public void TryFormatInt32() { - int value = 9; + var value = 9; Span buffer = stackalloc char[1]; var result = value.TryFormat(buffer, out var written, provider: CultureInfo.InvariantCulture); Assert.True(result); diff --git a/src/global.json b/src/global.json index 4b1e4f13..979c2be4 100644 --- a/src/global.json +++ b/src/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100-preview.7.23376.3", + "version": "8.0.100-rc.1.23455.8", "allowPrerelease": true, "rollForward": "latestFeature" } From b525f1e421f61712e40ad13f3e837ce53e5ba51c Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 13 Sep 2023 16:00:13 +1000 Subject: [PATCH 200/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 4 ++-- src/Polyfill/Polyfill.csproj | 2 +- src/PublicTests/PublicTests.csproj | 4 ++-- src/Shared.sln.DotSettings | 1 + src/Tests/Tests.csproj | 4 ++-- src/UnsafeTests/UnsafeTests.csproj | 4 ++-- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 03782a45..5d28372e 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,12 +29,12 @@ - + - + diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index 11453abb..c6686f19 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index b17f1976..ed5c4a95 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,12 +24,12 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + - + diff --git a/src/Shared.sln.DotSettings b/src/Shared.sln.DotSettings index cd7dcac1..f9d0a1a2 100644 --- a/src/Shared.sln.DotSettings +++ b/src/Shared.sln.DotSettings @@ -25,6 +25,7 @@ ERROR ERROR ERROR + DO_NOT_SHOW ERROR ERROR ERROR diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index d4306747..46218b76 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,13 +23,13 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 9031384c..04195e6a 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,12 +24,12 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + - + From ceb9664cd10e07f00ca7ab9b0890a125d5872f7d Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 13 Sep 2023 16:13:40 +1000 Subject: [PATCH 201/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 5d28372e..7bc8aef9 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index ed5c4a95..4864e241 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 46218b76..488fef84 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 04195e6a..bc1b1296 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 6e2a9dcd7910a52f7928c1aae233860bc6e3eec7 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 13 Sep 2023 23:09:21 +1000 Subject: [PATCH 202/313] cleanup --- .github/workflows/merge-dependabot.yml | 2 +- src/Directory.Build.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/merge-dependabot.yml b/.github/workflows/merge-dependabot.yml index a6902544..6715a04f 100644 --- a/.github/workflows/merge-dependabot.yml +++ b/.github/workflows/merge-dependabot.yml @@ -7,7 +7,7 @@ jobs: if: github.actor == 'dependabot[bot]' steps: - name: Dependabot Auto Merge - uses: ahmadnassri/action-dependabot-auto-merge@v2.3.1 + uses: ahmadnassri/action-dependabot-auto-merge@v2.6.6 with: target: minor github-token: ${{ secrets.dependabot }} diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 1625f57d..43683c22 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -8,7 +8,7 @@ false CS1591;NETSDK1138;NU1901;NU1902;NU1903 false - 11 + preview false true true From a955ad619643c80d4b42baf023c14af2dfa3f64b Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 15 Sep 2023 06:39:17 +1000 Subject: [PATCH 203/313] cleanup --- src/Consume/Consume.cs | 4 ++-- src/Tests/PolyfillExtensionsTests.cs | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index b3da7956..d4162431 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -80,9 +80,9 @@ class Consume "b" }; var append = enumerable.Append("c"); - var maxBy = enumerable.MaxBy(_=>_); + var maxBy = enumerable.MaxBy(_ => _); var chunk = enumerable.Chunk(3); - var minBy = enumerable.MinBy(_=>_); + var minBy = enumerable.MinBy(_ => _); var skipLast = enumerable.SkipLast(1); var dictionary = new Dictionary diff --git a/src/Tests/PolyfillExtensionsTests.cs b/src/Tests/PolyfillExtensionsTests.cs index 526a150b..78d8148a 100644 --- a/src/Tests/PolyfillExtensionsTests.cs +++ b/src/Tests/PolyfillExtensionsTests.cs @@ -2,6 +2,4 @@ [TestFixture] [DebuggerNonUserCode] -partial class PolyfillExtensionsTests -{ -} +partial class PolyfillExtensionsTests; From ea2c5da829b9cdc3edc7b22083fafcb1fde260cb Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 15 Sep 2023 06:52:14 +1000 Subject: [PATCH 204/313] Update UnreachableExceptionTests.cs --- src/Tests/UnreachableExceptionTests.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Tests/UnreachableExceptionTests.cs b/src/Tests/UnreachableExceptionTests.cs index 93ede359..732dfbc3 100644 --- a/src/Tests/UnreachableExceptionTests.cs +++ b/src/Tests/UnreachableExceptionTests.cs @@ -1,5 +1,3 @@ -namespace Tests; - [TestFixture] public class UnreachableExceptionTests { From 736c75b534ad909d9f107c0dae22f884415aed23 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 15 Sep 2023 12:31:10 +1000 Subject: [PATCH 205/313] remove Verify --- src/NoRefsTests/NoRefsTests.csproj | 2 -- src/PublicTests/PublicTests.csproj | 2 -- src/Tests/BuildApiTest.cs | 2 +- src/Tests/ModuleInitializer.cs | 8 ------- src/Tests/NullabilitySync.cs | 3 +-- src/Tests/SolutionDirectoryFinder.cs | 36 ++++++++++++++++++++++++++++ src/Tests/Tests.csproj | 2 -- src/UnsafeTests/UnsafeTests.csproj | 2 -- 8 files changed, 38 insertions(+), 19 deletions(-) delete mode 100644 src/Tests/ModuleInitializer.cs create mode 100644 src/Tests/SolutionDirectoryFinder.cs diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 7bc8aef9..cfe601fb 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,8 +29,6 @@ - - diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 4864e241..cdf7e2b3 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,8 +24,6 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - - diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index c7cfdd3c..c0c92d22 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -16,7 +16,7 @@ class BuildApiTest [Test] public void Run() { - var solutionDirectory = VerifyTests.AttributeReader.GetSolutionDirectory(); + var solutionDirectory = SolutionDirectoryFinder.Find(); var path = Path.Combine(solutionDirectory, @"Consume\bin\Debug\netstandard2.0\Consume.dll"); var md = Path.Combine(solutionDirectory, @"..\api_list.include.md"); File.Delete(md); diff --git a/src/Tests/ModuleInitializer.cs b/src/Tests/ModuleInitializer.cs deleted file mode 100644 index e5187346..00000000 --- a/src/Tests/ModuleInitializer.cs +++ /dev/null @@ -1,8 +0,0 @@ -using VerifyTests; - -public static class ModuleInitializer -{ - [ModuleInitializer] - public static void Initialize() => - VerifyDiffPlex.Initialize(); -} \ No newline at end of file diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs index fff2e87a..77fe972e 100644 --- a/src/Tests/NullabilitySync.cs +++ b/src/Tests/NullabilitySync.cs @@ -1,11 +1,10 @@ #if NET8_0 && DEBUG using System.Net.Http; -using VerifyTests; [TestFixture] public class NullabilitySync { - static string solutionDir = AttributeReader.GetSolutionDirectory(); + static string solutionDir = SolutionDirectoryFinder.Find(); static string dir = Path.Combine(solutionDir, "PolyFill", "Nullability"); [Test] diff --git a/src/Tests/SolutionDirectoryFinder.cs b/src/Tests/SolutionDirectoryFinder.cs new file mode 100644 index 00000000..872a1768 --- /dev/null +++ b/src/Tests/SolutionDirectoryFinder.cs @@ -0,0 +1,36 @@ +using System.Diagnostics.CodeAnalysis; + +static class SolutionDirectoryFinder +{ + public static string Find([CallerFilePath] string sourceFile = "") + { + if (!TryFind(sourceFile, out var solutionDirectory)) + { + throw new("Could not find solution directory"); + } + + return solutionDirectory; + } + + public static bool TryFind(string sourceFile, [NotNullWhen(true)] out string? path) + { + var currentDirectory = sourceFile; + do + { + if (Directory.GetFiles(currentDirectory, "*.sln").Any()) + { + path = currentDirectory; + return true; + } + + var parent = Directory.GetParent(currentDirectory); + if (parent == null) + { + path = null; + return false; + } + + currentDirectory = parent.FullName; + } while (true); + } +} \ No newline at end of file diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 488fef84..509f6e48 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,8 +23,6 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - - diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index bc1b1296..13eaa480 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,8 +24,6 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - - From 4d1c687927d9a521f9e3406316e758448908b9d5 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 15 Sep 2023 12:59:43 +1000 Subject: [PATCH 206/313] Update Polyfill.sln --- src/Polyfill.sln | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Polyfill.sln b/src/Polyfill.sln index abca409e..281d2726 100644 --- a/src/Polyfill.sln +++ b/src/Polyfill.sln @@ -18,9 +18,6 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Polyfill", "Polyfill\Polyfill.csproj", "{698FB675-3480-4107-8CAE-51452C6138CE}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{CA1869D1-4531-40C7-AE55-5885F4DD8448}" - ProjectSection(ProjectDependencies) = postProject - {32C38E3C-4040-455F-A27D-4EA5DB0F8EFA} = {32C38E3C-4040-455F-A27D-4EA5DB0F8EFA} - EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Consume", "Consume\Consume.csproj", "{32C38E3C-4040-455F-A27D-4EA5DB0F8EFA}" EndProject From fb264b284233fe3203d9c59473c36091e0b632b4 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 15 Sep 2023 13:06:54 +1000 Subject: [PATCH 207/313] Update Tests.csproj --- src/Tests/Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 509f6e48..ad98b4f1 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -28,7 +28,7 @@ - + From 9b4838a39ed3f19ecbbc2de0b3496d74704f7530 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 15 Sep 2023 13:12:43 +1000 Subject: [PATCH 208/313] fix build --- src/Consume/Consume.csproj | 2 +- src/ConsumeClassicReferences/ConsumeClassicReferences.csproj | 2 +- src/ConsumeIndirect/ConsumeIndirect.csproj | 4 ++++ src/PublicTests/PublicTests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Consume/Consume.csproj b/src/Consume/Consume.csproj index 117f401e..da38f4e1 100644 --- a/src/Consume/Consume.csproj +++ b/src/Consume/Consume.csproj @@ -5,7 +5,7 @@ $(TargetFrameworks);netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 - + diff --git a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj index d81058b6..3e13577b 100644 --- a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj +++ b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj @@ -5,7 +5,7 @@ $(TargetFrameworks);netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 - + diff --git a/src/ConsumeIndirect/ConsumeIndirect.csproj b/src/ConsumeIndirect/ConsumeIndirect.csproj index cbec079c..3ee3c796 100644 --- a/src/ConsumeIndirect/ConsumeIndirect.csproj +++ b/src/ConsumeIndirect/ConsumeIndirect.csproj @@ -5,6 +5,10 @@ $(TargetFrameworks);netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 + + + + Pollyfill\%(RecursiveDir)%(Filename).cs diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index cdf7e2b3..85f75ed1 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 13eaa480..720003a4 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -28,7 +28,7 @@ - + From fe519364dca2c7c5c4b94a5d346cf77819f46b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Havl=C3=AD=C4=8Dek?= Date: Sat, 16 Sep 2023 08:24:12 +0200 Subject: [PATCH 209/313] Add support for `Dictionary(TKey key, out TValue value) Remove` (#93) --- api_list.include.md | 5 +++ readme.md | 5 +++ src/Polyfill/PolyfillExtensions_Dictionary.cs | 35 +++++++++++++++++++ .../PolyfillExtensionsTests_Dictionary.cs | 27 ++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 src/Polyfill/PolyfillExtensions_Dictionary.cs create mode 100644 src/Tests/PolyfillExtensionsTests_Dictionary.cs diff --git a/api_list.include.md b/api_list.include.md index 99cd4422..c8ca2f07 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -54,6 +54,11 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) +### Dictionary + + * `Boolean Remove(TKey, out TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) + + ### Double * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) diff --git a/readme.md b/readme.md index 985e8172..efdd4a94 100644 --- a/readme.md +++ b/readme.md @@ -407,6 +407,11 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) +### Dictionary + + * `Boolean Remove(TKey, out TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) + + ### Double * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) diff --git a/src/Polyfill/PolyfillExtensions_Dictionary.cs b/src/Polyfill/PolyfillExtensions_Dictionary.cs new file mode 100644 index 00000000..a3d9b67e --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_Dictionary.cs @@ -0,0 +1,35 @@ +// + +#pragma warning disable + +#if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2X + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using Link = System.ComponentModel.DescriptionAttribute; + +static partial class PolyfillExtensions +{ + /// + /// Removes the value with the specified key from the , and copies the element + /// to the value parameter. + /// + /// A dictionary with keys of type TKey and values of type TValue. + /// The key of the element to remove. + /// The removed element. + /// The type of the keys in the dictionary. + /// The type of the values in the dictionary. + /// true if the element is successfully found and removed; otherwise, false. + /// is null. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove")] + public static bool Remove( + this Dictionary target, + TKey key, + [MaybeNullWhen(false)] out TValue value) + { + target.TryGetValue(key, out value); + return target.Remove(key); + } +} +#endif \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_Dictionary.cs b/src/Tests/PolyfillExtensionsTests_Dictionary.cs new file mode 100644 index 00000000..6df1930d --- /dev/null +++ b/src/Tests/PolyfillExtensionsTests_Dictionary.cs @@ -0,0 +1,27 @@ +partial class PolyfillExtensionsTests +{ + [Test] + public void Dictionary_Remove() + { + var dictionary = new Dictionary { {"key", "value"} }; + + Assert.True(dictionary.Remove("key", out var value)); + Assert.AreEqual("value", value); + } + + [Test] + public void Dictionary_Remove_DoesntThrowOnMissingKey() + { + var dictionary = new Dictionary(); + + Assert.False(dictionary.Remove("non-existent key", out var value)); + Assert.AreEqual(default, value); + } + + [Test] + public void Dictionary_Remove_ThrowsOnNull() + { + var dictionary = new Dictionary(); + Assert.Throws(() => dictionary.Remove(null!, out _)); + } +} From 3b68184b2e7a25cab01de535d9cf01a5b8b7acfc Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 16 Sep 2023 16:25:02 +1000 Subject: [PATCH 210/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 43683c22..7d907adf 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.27.2 + 1.28.0 1.0.0 Polyfill true From 17a02afc8a734974c772eaf4aeda12321d77cab6 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 21 Sep 2023 22:18:42 +1000 Subject: [PATCH 211/313] milestones for release --- .github/workflows/on-tag-do-release.yml | 19 ------------------- readme.md | 2 ++ 2 files changed, 2 insertions(+), 19 deletions(-) delete mode 100644 .github/workflows/on-tag-do-release.yml diff --git a/.github/workflows/on-tag-do-release.yml b/.github/workflows/on-tag-do-release.yml deleted file mode 100644 index f8422955..00000000 --- a/.github/workflows/on-tag-do-release.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: on-tag-do-release -on: - push: - tags: - - '[0-9]+\.[0-9]+\.[0-9]+' -jobs: - release: - runs-on: windows-latest - steps: - - name: Run - run: | - dotnet tool install --global GitReleaseManager.Tool - tag="${GITHUB_REF:10}" - owner="${GITHUB_REPOSITORY%/*}" - repo="${GITHUB_REPOSITORY#*/}" - dotnet-gitreleasemanager create -m ${tag} --token ${{secrets.GITHUB_TOKEN}} -o ${owner} -r ${repo} - dotnet-gitreleasemanager close -m ${tag} --token ${{secrets.GITHUB_TOKEN}} -o ${owner} -r ${repo} - dotnet-gitreleasemanager publish -t ${tag} --token ${{secrets.GITHUB_TOKEN}} -o ${owner} -r ${repo} - shell: bash \ No newline at end of file diff --git a/readme.md b/readme.md index efdd4a94..7829e9e6 100644 --- a/readme.md +++ b/readme.md @@ -12,6 +12,8 @@ The package targets `netstandard2.0` and is designed to support the following ru * `net5.0`, `net6.0`, `net7.0`, `net8.0` +**See [Milestones](../../milestones?state=closed) for release notes.** + ## Nuget https://nuget.org/packages/Polyfill/ From 057465a6e218a8b942f0e55c8a2ae29b312b5318 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 26 Sep 2023 12:23:24 +1000 Subject: [PATCH 212/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/Polyfill/Polyfill.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Shared.sln.DotSettings | 4 +++- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 6 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index cfe601fb..50e2ec62 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index c6686f19..f4bde3da 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 85f75ed1..0479e482 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/Shared.sln.DotSettings b/src/Shared.sln.DotSettings index f9d0a1a2..4a05ac25 100644 --- a/src/Shared.sln.DotSettings +++ b/src/Shared.sln.DotSettings @@ -25,14 +25,16 @@ ERROR ERROR ERROR - DO_NOT_SHOW ERROR ERROR ERROR + ERROR + ERROR ERROR ERROR ERROR ERROR + ERROR DO_NOT_SHOW ERROR ERROR diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index ad98b4f1..89235318 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 720003a4..db8b8c8e 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -27,7 +27,7 @@ - + From 17beb8b8ea67bec7b14ae1e7b89bea9bcd703fd1 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 26 Sep 2023 16:11:29 +1000 Subject: [PATCH 213/313] cleanup --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/Polyfill/Polyfill.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Shared.sln.DotSettings | 1 + src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 50e2ec62..a2e15b4c 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index f4bde3da..1afb95d5 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 0479e482..44b797f9 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/Shared.sln.DotSettings b/src/Shared.sln.DotSettings index 4a05ac25..38d0d527 100644 --- a/src/Shared.sln.DotSettings +++ b/src/Shared.sln.DotSettings @@ -44,6 +44,7 @@ ERROR ERROR ERROR + ERROR ERROR C90+,E79+,S14+ ERROR diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 89235318..bd42a507 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index db8b8c8e..832f5693 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -27,7 +27,7 @@ - + From aca830421925f3c9060293c168dc3e8c52cd1894 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 1 Oct 2023 15:14:05 +1100 Subject: [PATCH 214/313] fix dir finding --- src/Tests/NullabilitySync.cs | 9 +++++++-- src/Tests/SolutionDirectoryFinder.cs | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs index 77fe972e..20496089 100644 --- a/src/Tests/NullabilitySync.cs +++ b/src/Tests/NullabilitySync.cs @@ -4,8 +4,13 @@ [TestFixture] public class NullabilitySync { - static string solutionDir = SolutionDirectoryFinder.Find(); - static string dir = Path.Combine(solutionDir, "PolyFill", "Nullability"); + static string dir; + + static NullabilitySync() + { + var solutionDir = SolutionDirectoryFinder.Find(); + dir = Path.Combine(solutionDir, "PolyFill", "Nullability"); + } [Test] public async Task Run() diff --git a/src/Tests/SolutionDirectoryFinder.cs b/src/Tests/SolutionDirectoryFinder.cs index 872a1768..d648b3c1 100644 --- a/src/Tests/SolutionDirectoryFinder.cs +++ b/src/Tests/SolutionDirectoryFinder.cs @@ -14,7 +14,7 @@ public static string Find([CallerFilePath] string sourceFile = "") public static bool TryFind(string sourceFile, [NotNullWhen(true)] out string? path) { - var currentDirectory = sourceFile; + var currentDirectory = Directory.GetParent(sourceFile)!.FullName; do { if (Directory.GetFiles(currentDirectory, "*.sln").Any()) From b7c8630da5bb41df97754702721c08bc48e594ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 19:21:35 +1100 Subject: [PATCH 215/313] Bump ProjectDefaults from 1.0.99 to 1.0.100 in /src (#96) Bumps [ProjectDefaults](https://github.com/SimonCropp/ProjectDefaults) from 1.0.99 to 1.0.100. - [Commits](https://github.com/SimonCropp/ProjectDefaults/commits) --- updated-dependencies: - dependency-name: ProjectDefaults dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/Polyfill/Polyfill.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index a2e15b4c..6a820f80 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index 1afb95d5..6218bff0 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 44b797f9..babf5225 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index bd42a507..acb45e43 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 832f5693..184fccba 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -27,7 +27,7 @@ - + From b88fdafaaf3dc6ede54c7e3537dc454d8f3c015b Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 3 Oct 2023 08:40:21 +1100 Subject: [PATCH 216/313] Re sync nullability code (#95) --- api_list.include.md | 10 +- readme.md | 10 +- src/Directory.Build.props | 2 +- .../Nullability/NullabilityInfoContext.cs | 58 +++--- src/Tests/NullabilitySync.cs | 6 +- src/editorconfig.txt | 169 ++++++++++++++++++ 6 files changed, 219 insertions(+), 36 deletions(-) create mode 100644 src/editorconfig.txt diff --git a/api_list.include.md b/api_list.include.md index c8ca2f07..02f7218c 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -8,6 +8,11 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) +### Dictionary + + * `Boolean Remove(TKey, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) + + ### IEnumerable * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) @@ -54,11 +59,6 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) -### Dictionary - - * `Boolean Remove(TKey, out TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) - - ### Double * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) diff --git a/readme.md b/readme.md index 7829e9e6..f9827642 100644 --- a/readme.md +++ b/readme.md @@ -363,6 +363,11 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) +### Dictionary + + * `Boolean Remove(TKey, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) + + ### IEnumerable * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) @@ -409,11 +414,6 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) -### Dictionary - - * `Boolean Remove(TKey, out TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) - - ### Double * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 7d907adf..15e15feb 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.28.0 + 1.29.0 1.0.0 Polyfill true diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs index 18964394..a2939cdb 100644 --- a/src/Polyfill/Nullability/NullabilityInfoContext.cs +++ b/src/Polyfill/Nullability/NullabilityInfoContext.cs @@ -97,35 +97,47 @@ public NullabilityInfo Create(ParameterInfo parameterInfo) private void CheckParameterMetadataType(ParameterInfo parameter, NullabilityInfo nullability) { - if (parameter.Member is MethodInfo method) + ParameterInfo? metaParameter; + MemberInfo metaMember; + + switch (parameter.Member) { - MethodInfo metaMethod = GetMethodMetadataDefinition(method); - ParameterInfo? metaParameter = null; - if (string.IsNullOrEmpty(parameter.Name)) - { - metaParameter = metaMethod.ReturnParameter; - } - else - { - ParameterInfo[] parameters = metaMethod.GetParameters(); - for (int i = 0; i < parameters.Length; i++) - { - if (parameter.Position == i && - parameter.Name == parameters[i].Name) - { - metaParameter = parameters[i]; - break; - } - } - } + case ConstructorInfo ctor: + var metaCtor = (ConstructorInfo)GetMemberMetadataDefinition(ctor); + metaMember = metaCtor; + metaParameter = GetMetaParameter(metaCtor, parameter); + break; + + case MethodInfo method: + MethodInfo metaMethod = GetMethodMetadataDefinition(method); + metaMember = metaMethod; + metaParameter = string.IsNullOrEmpty(parameter.Name) ? metaMethod.ReturnParameter : GetMetaParameter(metaMethod, parameter); + break; + + default: + return; + } + + if (metaParameter != null) + { + CheckGenericParameters(nullability, metaMember, metaParameter.ParameterType, parameter.Member.ReflectedType); + } + } - if (metaParameter != null) + private static ParameterInfo? GetMetaParameter(MethodBase metaMethod, ParameterInfo parameter) + { + var parameters = metaMethod.GetParameters(); + for (int i = 0; i < parameters.Length; i++) + { + if (parameter.Position == i && + parameter.Name == parameters[i].Name) { - CheckGenericParameters(nullability, metaMethod, metaParameter.ParameterType, parameter.Member.ReflectedType); + return parameters[i]; } } - } + return null; + } private static MethodInfo GetMethodMetadataDefinition(MethodInfo method) { if (method.IsGenericMethod && !method.IsGenericMethodDefinition) diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs index 20496089..ceab6b5a 100644 --- a/src/Tests/NullabilitySync.cs +++ b/src/Tests/NullabilitySync.cs @@ -27,11 +27,13 @@ public async Task Run() .Replace(".IsGenericMethodParameter", ".IsGenericMethodParameter()") .Replace("SR.NullabilityInfoContext_NotSupported", "\"NullabilityInfoContext is not supported\"") .Replace( - "CheckNullabilityAttributes(nullability, setter.GetParameters()[^1].GetCustomAttributesData());", + "CheckNullabilityAttributes(nullability, setter.GetParametersAsSpan()[^1].GetCustomAttributesData());", """ var parameters = setter.GetParameters(); CheckNullabilityAttributes(nullability, parameters[parameters.Length-1].GetCustomAttributesData()); - """); + """) + .Replace("ReadOnlySpan parameters = metaMethod.GetParametersAsSpan();", "var parameters = metaMethod.GetParameters();") + .Replace(".GetParametersAsSpan()", ".GetParameters()"); var lines = infoContext.Split('\r', '\n'); infoContext = string.Join(Environment.NewLine, lines.Where(_ => !_.Contains("ArgumentNullException.ThrowIfNull"))); diff --git a/src/editorconfig.txt b/src/editorconfig.txt new file mode 100644 index 00000000..bb59b63e --- /dev/null +++ b/src/editorconfig.txt @@ -0,0 +1,169 @@ +root = true +# EditorConfig: http://EditorConfig.org + +# top-most EditorConfig file + +[*] +indent_style = space + + +[*.cs] +indent_size = 4 +charset = utf-8 + + +# Microsoft .NET properties +trim_trailing_whitespace = true +csharp_preferred_modifier_order = public, private, protected, internal, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async:suggestion +resharper_namespace_body = file_scoped +dotnet_naming_rule.private_constants_rule.severity = warning +dotnet_naming_rule.private_constants_rule.style = upper_camel_case_style +dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols +dotnet_naming_rule.private_instance_fields_rule.severity = warning +dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style +dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols +dotnet_naming_rule.private_static_fields_rule.severity = warning +dotnet_naming_rule.private_static_fields_rule.style = lower_camel_case_style +dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols +dotnet_naming_rule.private_static_readonly_rule.severity = warning +dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style +dotnet_naming_rule.private_static_readonly_rule.symbols = private_static_readonly_symbols +dotnet_naming_style.lower_camel_case_style.capitalization = camel_case +dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case +dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private +dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field +dotnet_naming_symbols.private_constants_symbols.required_modifiers = const +dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private +dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field +dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private +dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field +dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static +dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private +dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field +dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static, readonly +dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none +dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none + +# ReSharper properties +resharper_object_creation_when_type_not_evident = target_typed + +# ReSharper inspection severities +resharper_arrange_object_creation_when_type_evident_highlighting = error +resharper_arrange_object_creation_when_type_not_evident_highlighting = error +resharper_arrange_redundant_parentheses_highlighting = error +resharper_arrange_static_member_qualifier_highlighting = error +resharper_arrange_this_qualifier_highlighting = hint +resharper_arrange_type_member_modifiers_highlighting = none +resharper_built_in_type_reference_style_for_member_access_highlighting = hint +resharper_built_in_type_reference_style_highlighting = hint +resharper_check_namespace_highlighting = none +resharper_convert_to_using_declaration_highlighting = error +resharper_css_not_resolved_highlighting = warning +resharper_field_can_be_made_read_only_local_highlighting = none +resharper_merge_into_logical_pattern_highlighting = warning +resharper_merge_into_pattern_highlighting = error +resharper_method_has_async_overload_highlighting = warning +resharper_partial_type_with_single_part_highlighting = error +resharper_redundant_base_qualifier_highlighting = warning +resharper_redundant_cast_highlighting = error +resharper_redundant_empty_object_creation_argument_list_highlighting = error +resharper_redundant_empty_object_or_collection_initializer_highlighting = error +resharper_redundant_name_qualifier_highlighting = error +resharper_redundant_suppress_nullable_warning_expression_highlighting = error +resharper_redundant_using_directive_highlighting = error +resharper_redundant_verbatim_string_prefix_highlighting = error +resharper_replace_substring_with_range_indexer_highlighting = warning +resharper_suggest_var_or_type_built_in_types_highlighting = error +resharper_suggest_var_or_type_elsewhere_highlighting = error +resharper_suggest_var_or_type_simple_types_highlighting = error +resharper_unnecessary_whitespace_highlighting = error +resharper_use_await_using_highlighting = warning +resharper_use_deconstruction_highlighting = warning + +# Sort using and Import directives with System.* appearing first +dotnet_sort_system_directives_first = true + +# Avoid "this." and "Me." if not necessary +dotnet_style_qualification_for_field = false:error +dotnet_style_qualification_for_property = false:error +dotnet_style_qualification_for_method = false:error +dotnet_style_qualification_for_event = false:error + +# Use language keywords instead of framework type names for type references +dotnet_style_predefined_type_for_locals_parameters_members = true:error +dotnet_style_predefined_type_for_member_access = true:error + +# Suggest more modern language features when available +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_coalesce_expression = false:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion + +# Prefer "var" everywhere +csharp_style_var_for_built_in_types = true:error +csharp_style_var_when_type_is_apparent = true:error +csharp_style_var_elsewhere = true:error + +# Prefer method-like constructs to have a block body +csharp_style_expression_bodied_methods = true:error +csharp_style_expression_bodied_local_functions = true:error +csharp_style_expression_bodied_constructors = true:error +csharp_style_expression_bodied_operators = true:error +resharper_place_expr_method_on_single_line = false + +# Prefer property-like constructs to have an expression-body +csharp_style_expression_bodied_properties = true:error +csharp_style_expression_bodied_indexers = true:error +csharp_style_expression_bodied_accessors = true:error + +# Suggest more modern language features when available +csharp_style_pattern_matching_over_is_with_cast_check = true:error +csharp_style_pattern_matching_over_as_with_null_check = true:error +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion + +# Newline settings +#csharp_new_line_before_open_brace = all:error +resharper_max_array_initializer_elements_on_line = 1 +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +resharper_wrap_before_first_type_parameter_constraint = true +resharper_wrap_extends_list_style = chop_always +resharper_wrap_after_dot_in_method_calls = false +resharper_wrap_before_binary_pattern_op = false +resharper_wrap_object_and_collection_initializer_style = chop_always +resharper_place_simple_initializer_on_single_line = false + +# space +resharper_space_around_lambda_arrow = true + +dotnet_style_require_accessibility_modifiers = never:error +resharper_place_type_constraints_on_same_line = false +resharper_blank_lines_inside_namespace = 0 +resharper_blank_lines_after_file_scoped_namespace_directive = 1 +resharper_blank_lines_inside_type = 0 + +#braces https://www.jetbrains.com/help/resharper/EditorConfig_CSHARP_CSharpCodeStylePageImplSchema.html#Braces +resharper_braces_for_ifelse = required +resharper_braces_for_foreach = required +resharper_braces_for_while = required +resharper_braces_for_dowhile = required +resharper_braces_for_lock = required +resharper_braces_for_fixed = required +resharper_braces_for_for = required + +# Xml files +[*.{xml,config,nuspec,resx,vsixmanifest,csproj,targets,props}] +indent_size = 2 +# https://www.jetbrains.com/help/resharper/EditorConfig_XML_XmlCodeStylePageSchema.html#resharper_xml_blank_line_after_pi +resharper_blank_line_after_pi = false +resharper_space_before_self_closing = true + +[*.json] +indent_size = 2 \ No newline at end of file From b6e851bd508f7b5abf9f9965784958d679de0f61 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 9 Oct 2023 13:58:22 +1100 Subject: [PATCH 217/313] Update .editorconfig --- src/.editorconfig | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/.editorconfig b/src/.editorconfig index bb59b63e..c9db1cb9 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -140,15 +140,17 @@ resharper_wrap_before_binary_pattern_op = false resharper_wrap_object_and_collection_initializer_style = chop_always resharper_place_simple_initializer_on_single_line = false -# space -resharper_space_around_lambda_arrow = true - dotnet_style_require_accessibility_modifiers = never:error resharper_place_type_constraints_on_same_line = false resharper_blank_lines_inside_namespace = 0 resharper_blank_lines_after_file_scoped_namespace_directive = 1 resharper_blank_lines_inside_type = 0 +insert_final_newline = false +resharper_place_attribute_on_same_line = false +resharper_space_around_lambda_arrow = true +resharper_place_constructor_initializer_on_same_line = false + #braces https://www.jetbrains.com/help/resharper/EditorConfig_CSHARP_CSharpCodeStylePageImplSchema.html#Braces resharper_braces_for_ifelse = required resharper_braces_for_foreach = required From b22d72f197d3082bd3e3e0043569a4840a11b94f Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 11 Oct 2023 10:06:46 +1100 Subject: [PATCH 218/313] Update global.json --- src/global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/global.json b/src/global.json index 979c2be4..edb92397 100644 --- a/src/global.json +++ b/src/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100-rc.1.23455.8", + "version": "8.0.100-rc.2.23502.2", "allowPrerelease": true, "rollForward": "latestFeature" } From 558f4b730b7fc4ed827dc7dd4fccf5e02e54e8ca Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 16 Oct 2023 21:18:39 +1100 Subject: [PATCH 219/313] Update Directory.Build.props --- src/Directory.Build.props | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 15e15feb..44889b75 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -12,5 +12,6 @@ false true true + true \ No newline at end of file From a0107a768dd6a0caede98775279dd215a6942b4b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 19 Oct 2023 19:58:19 +1100 Subject: [PATCH 220/313] Bump ProjectDefaults from 1.0.100 to 1.0.101 in /src (#97) Bumps [ProjectDefaults](https://github.com/SimonCropp/ProjectDefaults) from 1.0.100 to 1.0.101. - [Commits](https://github.com/SimonCropp/ProjectDefaults/commits) --- updated-dependencies: - dependency-name: ProjectDefaults dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/Polyfill/Polyfill.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 6a820f80..8b7ff12d 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index 6218bff0..a82eff1b 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index babf5225..250da833 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index acb45e43..11d5e29f 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 184fccba..4dcefd0f 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -27,7 +27,7 @@ - + From ef3f0c4d5b94c1580ac892487a8cd4c2226e15e1 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 20 Oct 2023 18:07:47 +1100 Subject: [PATCH 221/313] Update Shared.sln.DotSettings --- src/Shared.sln.DotSettings | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Shared.sln.DotSettings b/src/Shared.sln.DotSettings index 38d0d527..e4b91714 100644 --- a/src/Shared.sln.DotSettings +++ b/src/Shared.sln.DotSettings @@ -118,6 +118,8 @@ ERROR DO_NOT_SHOW ECMAScript 2016 + False + False <?xml version="1.0" encoding="utf-16"?><Profile name="c# Cleanup"><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><CSCodeStyleAttributes ArrangeVarStyle="True" ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeCodeBodyStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" /><CssAlphabetizeProperties>True</CssAlphabetizeProperties><JSStringLiteralQuotesDescriptor>True</JSStringLiteralQuotesDescriptor><CorrectVariableKindsDescriptor>True</CorrectVariableKindsDescriptor><VariablesToInnerScopesDescriptor>True</VariablesToInnerScopesDescriptor><StringToTemplatesDescriptor>True</StringToTemplatesDescriptor><JsInsertSemicolon>True</JsInsertSemicolon><RemoveRedundantQualifiersTs>True</RemoveRedundantQualifiersTs><OptimizeImportsTs>True</OptimizeImportsTs><OptimizeReferenceCommentsTs>True</OptimizeReferenceCommentsTs><PublicModifierStyleTs>True</PublicModifierStyleTs><ExplicitAnyTs>True</ExplicitAnyTs><TypeAnnotationStyleTs>True</TypeAnnotationStyleTs><RelativePathStyleTs>True</RelativePathStyleTs><AsInsteadOfCastTs>True</AsInsteadOfCastTs><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CssReformatCode>True</CssReformatCode><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><HtmlReformatCode>True</HtmlReformatCode><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags><IDEA_SETTINGS>&lt;profile version="1.0"&gt; &lt;option name="myName" value="c# Cleanup" /&gt; &lt;/profile&gt;</IDEA_SETTINGS><RIDER_SETTINGS>&lt;profile&gt; From 8e21197ca313cf2ed709bf10a556bb47ca7a1b0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 20:01:14 +1100 Subject: [PATCH 222/313] Bump NUnit from 3.13.3 to 3.14.0 in /src (#98) Bumps [NUnit](https://github.com/nunit/nunit) from 3.13.3 to 3.14.0. - [Release notes](https://github.com/nunit/nunit/releases) - [Changelog](https://github.com/nunit/nunit/blob/master/CHANGES.md) - [Commits](https://github.com/nunit/nunit/compare/v3.13.3...v3.14.0) --- updated-dependencies: - dependency-name: NUnit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 8b7ff12d..fba7d3fa 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 250da833..c381075e 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 11d5e29f..53a1af73 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 4dcefd0f..eac0f221 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From e364d1845af5122ee703e63c14edb63c3f4ef8c9 Mon Sep 17 00:00:00 2001 From: Scott Beca Date: Tue, 7 Nov 2023 11:00:45 +1100 Subject: [PATCH 223/313] Implement some more extension functions (#99) --- api_list.include.md | 12 ++ readme.md | 12 ++ src/Consume/Consume.cs | 14 ++ .../PolyfillExtensions_CancellationToken.cs | 137 ++++++++++++++++++ ...yfillExtensions_CancellationTokenSource.cs | 41 +++++- src/Polyfill/PolyfillExtensions_Process.cs | 117 +++++++++++++++ src/Tests/BuildApiTest.cs | 5 +- ...lyfillExtensionsTests_CancellationToken.cs | 69 +++++++++ ...ExtensionsTests_CancellationTokenSource.cs | 69 +++++++++ src/Tests/PolyfillExtensionsTests_Process.cs | 27 ++++ 10 files changed, 499 insertions(+), 4 deletions(-) create mode 100644 src/Polyfill/PolyfillExtensions_CancellationToken.cs create mode 100644 src/Polyfill/PolyfillExtensions_Process.cs create mode 100644 src/Tests/PolyfillExtensionsTests_CancellationToken.cs create mode 100644 src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs create mode 100644 src/Tests/PolyfillExtensionsTests_Process.cs diff --git a/api_list.include.md b/api_list.include.md index 02f7218c..c44d606e 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -59,6 +59,11 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) +### Process + + * `Task WaitForExitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.waitforexitasync) + + ### Double * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) @@ -208,6 +213,13 @@ * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) +### CancellationToken + + * `CancellationTokenRegistration Register(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.register#system-threading-cancellationtoken-register(system-action((system-object-system-threading-cancellationtoken))-system-object)) + * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object))-system-object)) + * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object-system-threading-cancellationtoken))-system-object)) + + ### CancellationTokenSource * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) diff --git a/readme.md b/readme.md index f9827642..cb91a334 100644 --- a/readme.md +++ b/readme.md @@ -414,6 +414,11 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) +### Process + + * `Task WaitForExitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.waitforexitasync) + + ### Double * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) @@ -563,6 +568,13 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) +### CancellationToken + + * `CancellationTokenRegistration Register(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.register#system-threading-cancellationtoken-register(system-action((system-object-system-threading-cancellationtoken))-system-object)) + * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object))-system-object)) + * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object-system-threading-cancellationtoken))-system-object)) + + ### CancellationTokenSource * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index d4162431..97c4923e 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -138,6 +138,20 @@ async Task CancellationTokenSource() await source.CancelAsync(); } + void CancellationTokenUnsafeRegister() + { + var source = new CancellationTokenSource(); + var token = source.Token; + token.UnsafeRegister((state) => {}, null); + token.UnsafeRegister((state, token) => {}, null); + } + + async Task ProcessWaitForExitAsync() + { + var process = new Process(); + await process.WaitForExitAsync(); + } + async Task StreamReaderReadToEndAsync() { var reader = new StreamReader(new MemoryStream()); diff --git a/src/Polyfill/PolyfillExtensions_CancellationToken.cs b/src/Polyfill/PolyfillExtensions_CancellationToken.cs new file mode 100644 index 00000000..bff06e5a --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_CancellationToken.cs @@ -0,0 +1,137 @@ +// + +#nullable enable + +#pragma warning disable + +using System; +using System.Threading; +using Link = System.ComponentModel.DescriptionAttribute; + +static partial class PolyfillExtensions +{ + +#if !NETCOREAPP3_0_OR_GREATER + + /// + /// Registers a delegate that will be called when this + /// CancellationToken is canceled. + /// + /// + /// + /// If this token is already in the canceled state, the delegate will be run immediately and synchronously. + /// Any exception the delegate generates will be propagated out of this method call. + /// + /// + /// ExecutionContext is not captured nor flowed + /// to the callback's invocation. + /// + /// + /// The delegate to be executed when the CancellationToken is canceled. + /// The state to pass to the when the delegate is invoked. This may be null. + /// The instance that can + /// be used to unregister the callback. + /// is null. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object))-system-object)")] + public static CancellationTokenRegistration UnsafeRegister(this CancellationToken target, Action callback, object? state) + { + if (callback is null) + { + throw new ArgumentNullException(nameof(callback)); + } + + // The main difference between UnsafeRegister and Register appears to be that UnsafeRegister callbacks don't capture and use the execution context. + // So to emulate that here, let's suppress the execution context if needed before calling Register. + // This idea was taken from UniTask and how they implemented their RegisterWithoutCaptureExecutionContext extension methods: + // https://github.com/Cysharp/UniTask/blob/master/src/UniTask/Assets/Plugins/UniTask/Runtime/CancellationTokenExtensions.cs + + var restoreFlow = false; + if (!ExecutionContext.IsFlowSuppressed()) + { + ExecutionContext.SuppressFlow(); + restoreFlow = true; + } + + try + { + return target.Register(callback, state, false); + } + finally + { + if (restoreFlow) + { + ExecutionContext.RestoreFlow(); + } + } + } + +#endif + +#if !NET6_0_OR_GREATER + + /// Registers a delegate that will be called when this CancellationToken is canceled. + /// + /// If this token is already in the canceled state, the delegate will be run immediately and synchronously. Any exception the delegate + /// generates will be propagated out of this method call. The current ExecutionContext, if one exists, + /// will be captured along with the delegate and will be used when executing it. The current is not captured. + /// + /// The delegate to be executed when the CancellationToken is canceled. + /// The state to pass to the when the delegate is invoked. This may be null. + /// The instance that can be used to unregister the callback. + /// is null. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.register#system-threading-cancellationtoken-register(system-action((system-object-system-threading-cancellationtoken))-system-object)")] + public static CancellationTokenRegistration Register(this CancellationToken target, Action callback, object? state) + { + if (callback is null) + { + throw new ArgumentNullException(nameof(callback)); + } + + return target.Register((data) => callback(data, target), state, useSynchronizationContext: false); + } + + /// Registers a delegate that will be called when this CancellationToken is canceled. + /// + /// If this token is already in the canceled state, the delegate will be run immediately and synchronously. Any exception the delegate + /// generates will be propagated out of this method call. is not captured nor flowed to the callback's invocation. + /// + /// The delegate to be executed when the CancellationToken is canceled. + /// The state to pass to the when the delegate is invoked. This may be null. + /// The instance that can be used to unregister the callback. + /// is null. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object-system-threading-cancellationtoken))-system-object)")] + public static CancellationTokenRegistration UnsafeRegister(this CancellationToken target, Action callback, object? state) + { + if (callback is null) + { + throw new ArgumentNullException(nameof(callback)); + } + + // The main difference between UnsafeRegister and Register appears to be that UnsafeRegister callbacks don't capture and use the execution context. + // So to emulate that here, let's suppress the execution context if needed before calling Register. + // This idea was taken from UniTask and how they implemented their RegisterWithoutCaptureExecutionContext extension methods: + // https://github.com/Cysharp/UniTask/blob/master/src/UniTask/Assets/Plugins/UniTask/Runtime/CancellationTokenExtensions.cs + + var restoreFlow = false; + if (!ExecutionContext.IsFlowSuppressed()) + { + ExecutionContext.SuppressFlow(); + restoreFlow = true; + } + + try + { + Action internalCallback = (data) => callback(data, target); + return target.Register(internalCallback, state, false); + } + finally + { + if (restoreFlow) + { + ExecutionContext.RestoreFlow(); + } + } + } + +#endif +} diff --git a/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs b/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs index ca9283f5..121c0728 100644 --- a/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs +++ b/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs @@ -10,11 +10,48 @@ static partial class PolyfillExtensions { #if !NET8_0_OR_GREATER + /// Communicates a request for cancellation asynchronously. + /// + /// + /// The associated will be notified of the cancellation + /// and will synchronously transition to a state where returns true. + /// Any callbacks or cancelable operations registered with the will be executed asynchronously, + /// with the returned representing their eventual completion. + /// + /// + /// Callbacks registered with the token should not throw exceptions. + /// However, any such exceptions that are thrown will be aggregated into an , + /// such that one callback throwing an exception will not prevent other registered callbacks from being executed. + /// + /// + /// The that was captured when each callback was registered + /// will be reestablished when the callback is invoked. + /// + /// + /// This has been disposed. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync")] public static Task CancelAsync(this CancellationTokenSource target) { - target.Cancel(); - return Task.CompletedTask; + if (target.IsCancellationRequested) + { + // If cancellation has already been requested then we can just return immediately + return Task.CompletedTask; + } + else + { + // Run sync Cancel call in Task to avoid possible deadlock. + // As an example, the CancellationTokenSource_CancelAsync_CallbacksInvokedAsynchronously test + // will hit a deadlock if we try to just call Cancel directly without it being run in a task + Task task = Task.Run(() => target.Cancel()); + + while (!target.IsCancellationRequested) + { + // Don't return until we know that the cancellation request has started, to match the + // state that the real implemenation for CancelAsync would be in after being called + } + + return task; + } } #endif diff --git a/src/Polyfill/PolyfillExtensions_Process.cs b/src/Polyfill/PolyfillExtensions_Process.cs new file mode 100644 index 00000000..11031172 --- /dev/null +++ b/src/Polyfill/PolyfillExtensions_Process.cs @@ -0,0 +1,117 @@ +// + +#pragma warning disable + +#if !NET5_0_OR_GREATER + +using System; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; +using Link = System.ComponentModel.DescriptionAttribute; + +static partial class PolyfillExtensions +{ + /// + /// Instructs the Process component to wait for the associated process to exit, or + /// for the to be canceled. + /// + /// + /// Calling this method will set to . + /// + /// + /// A task that will complete when the process has exited, cancellation has been requested, + /// or an error occurs. + /// + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.waitforexitasync")] + public static async Task WaitForExitAsync(this Process target, CancellationToken cancellationToken = default) + { + // Because the process has already started by the time this method is called, + // we're in a race against the process to set up our exit handlers before the process + // exits. As a result, there are several different flows that must be handled: + // + // CASE 1: WE ENABLE EVENTS + // This is the "happy path". In this case we enable events. + // + // CASE 1.1: PROCESS EXITS OR IS CANCELED AFTER REGISTERING HANDLER + // This case continues the "happy path". The process exits or waiting is canceled after + // registering the handler and no special cases are needed. + // + // CASE 1.2: PROCESS EXITS BEFORE REGISTERING HANDLER + // It's possible that the process can exit after we enable events but before we register + // the handler. In that case we must check for exit after registering the handler. + // + // + // CASE 2: PROCESS EXITS BEFORE ENABLING EVENTS + // The process may exit before we attempt to enable events. In that case EnableRaisingEvents + // will throw an exception like this: + // System.InvalidOperationException : Cannot process request because the process (42) has exited. + // In this case we catch the InvalidOperationException. If the process has exited, our work + // is done and we return. If for any reason (now or in the future) enabling events fails + // and the process has not exited, bubble the exception up to the user. + // + // + // CASE 3: USER ALREADY ENABLED EVENTS + // In this case the user has already enabled raising events. Re-enabling events is a no-op + // as the value hasn't changed. However, no-op also means that if the process has already + // exited, EnableRaisingEvents won't throw an exception. + // + // CASE 3.1: PROCESS EXITS OR IS CANCELED AFTER REGISTERING HANDLER + // (See CASE 1.1) + // + // CASE 3.2: PROCESS EXITS BEFORE REGISTERING HANDLER + // (See CASE 1.2) + + if (!target.HasExited) + { + // Early out for cancellation before doing more expensive work + cancellationToken.ThrowIfCancellationRequested(); + } + + try + { + // CASE 1: We enable events + // CASE 2: Process exits before enabling events (and throws an exception) + // CASE 3: User already enabled events (no-op) + target.EnableRaisingEvents = true; + } + catch (InvalidOperationException) + { + // CASE 2: If the process has exited, our work is done, otherwise bubble the + // exception up to the user + if (target.HasExited) + { + return; + } + + throw; + } + + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + + EventHandler handler = (_, _) => tcs.TrySetResult(null); + target.Exited += handler; + + try + { + if (target.HasExited) + { + // CASE 1.2 & CASE 3.2: Handle race where the process exits before registering the handler + } + else + { + // CASE 1.1 & CASE 3.1: Process exits or is canceled here + using (cancellationToken.UnsafeRegister(static (s, cancellationToken) => ((TaskCompletionSource)s!).TrySetCanceled(cancellationToken), tcs)) + { + await tcs.Task.ConfigureAwait(false); + } + } + } + finally + { + target.Exited -= handler; + } + } +} + +#endif diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index c0c92d22..43b36f85 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -4,6 +4,7 @@ class BuildApiTest { static string[] namespacesToClean = { + "System.Diagnostics.", "System.Collections.Generic.", "System.Threading.Tasks.", "System.Threading.", @@ -17,8 +18,8 @@ class BuildApiTest public void Run() { var solutionDirectory = SolutionDirectoryFinder.Find(); - var path = Path.Combine(solutionDirectory, @"Consume\bin\Debug\netstandard2.0\Consume.dll"); - var md = Path.Combine(solutionDirectory, @"..\api_list.include.md"); + var path = Path.Combine(solutionDirectory, "Consume", "bin", "Debug", "netstandard2.0", "Consume.dll"); + var md = Path.Combine(solutionDirectory, "..", "api_list.include.md"); File.Delete(md); using var module = Mono.Cecil.ModuleDefinition.ReadModule(path); var extensions = module.GetTypes().Single(_ => _.Name == nameof(PolyfillExtensions)); diff --git a/src/Tests/PolyfillExtensionsTests_CancellationToken.cs b/src/Tests/PolyfillExtensionsTests_CancellationToken.cs new file mode 100644 index 00000000..d0fc66de --- /dev/null +++ b/src/Tests/PolyfillExtensionsTests_CancellationToken.cs @@ -0,0 +1,69 @@ +partial class PolyfillExtensionsTests +{ + [Test] + public void CancellationToken_Register_Exceptions() + { + CancellationToken token = default; + +#nullable disable + Assert.Throws(() => token.Register((Action)null, null)); + + Assert.Throws(() => token.UnsafeRegister((Action)null, null)); + Assert.Throws(() => token.UnsafeRegister((Action)null, null)); +#nullable enable + } + + [Test] + [TestCase(false)] + [TestCase(true)] + public static void CancellationToken_Register_ExecutionContextFlowsIfExpected(bool callbackWithToken) + { + var cts = new CancellationTokenSource(); + + const int Iters = 5; + int invoked = 0; + + AsyncLocal al = new AsyncLocal(); + for (int i = 1; i <= Iters; i++) + { + bool flowExecutionContext = i % 2 == 0; + + al.Value = i; + Action callback = s => + { + invoked++; + Assert.AreEqual(flowExecutionContext ? (int)s! : 0, al.Value); + }; + + CancellationToken ct = cts.Token; + if (flowExecutionContext && callbackWithToken) + { + ct.Register((s, t) => + { + Assert.AreEqual(ct, t); + callback(s); + }, i); + } + else if (flowExecutionContext) + { + ct.Register(callback, i); + } + else if (callbackWithToken) + { + ct.UnsafeRegister((s, t) => + { + Assert.AreEqual(ct, t); + callback(s); + }, i); + } + else + { + ct.UnsafeRegister(callback, i); + } + } + al.Value = 0; + + cts.Cancel(); + Assert.AreEqual(Iters, invoked); + } +} diff --git a/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs b/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs new file mode 100644 index 00000000..ffc04e73 --- /dev/null +++ b/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs @@ -0,0 +1,69 @@ +partial class PolyfillExtensionsTests +{ + private static bool IsCompletedSuccessfully(Task task) + { +#if NETFRAMEWORK || NETSTANDARD + return task.Status == TaskStatus.RanToCompletion; +#else + return task.IsCompletedSuccessfully; +#endif + } + + [Test] + [Ignore("This test is taken directly from the .NET repo but we can't match the real CancelAsync logic exactly, so differ slightly and can't pass this test")] + public static void CancellationTokenSource_CancelAsync_NoRegistrations_CallbackCompletesImmediately() + { + var cts = new CancellationTokenSource(); + Assert.True(IsCompletedSuccessfully(cts.CancelAsync())); + Assert.True(cts.IsCancellationRequested); + + cts = new CancellationTokenSource(); + cts.Token.Register(() => { }).Dispose(); + Assert.True(IsCompletedSuccessfully(cts.CancelAsync())); + Assert.True(cts.IsCancellationRequested); + } + + [Test] + public static async Task CancellationTokenSource_CancelAsync_CallbacksInvokedAsynchronously() + { + var cts = new CancellationTokenSource(); + + var mres = new ManualResetEventSlim(); + cts.Token.Register(mres.Wait); + + Task t = cts.CancelAsync(); + Assert.False(t.IsCompleted); + Assert.True(cts.IsCancellationRequested); + + Assert.True(IsCompletedSuccessfully(cts.CancelAsync())); // secondary call completes immediately + + mres.Set(); + await t; + } + + [Test] + public static void CancellationTokenSource_CancelAsync_AllCallbacksInvoked() + { + const int Iters = 1000; + + int sum = 0; + int callingThreadId = Environment.CurrentManagedThreadId; + + var cts = new CancellationTokenSource(); + for (int i = 1; i <= Iters; i++) + { + cts.Token.Register(s => + { + sum += (int)s!; + }, i); + } + + Task t = cts.CancelAsync(); + Assert.True(cts.IsCancellationRequested); + + ((IAsyncResult)t).AsyncWaitHandle.WaitOne(); // synchronously block without inlining to ensure this thread isn't reused + t.Wait(); // propagate any exceptions + + Assert.AreEqual(Iters * (Iters + 1) / 2, sum); + } +} diff --git a/src/Tests/PolyfillExtensionsTests_Process.cs b/src/Tests/PolyfillExtensionsTests_Process.cs new file mode 100644 index 00000000..9410fd6f --- /dev/null +++ b/src/Tests/PolyfillExtensionsTests_Process.cs @@ -0,0 +1,27 @@ +partial class PolyfillExtensionsTests +{ + [Test, RequiresThread] + [TestCase(0)] // poll + [TestCase(10)] // real timeout + public void Process_CurrentProcess_WaitAsyncNeverCompletes(int milliseconds) + { + using (var cts = new CancellationTokenSource(milliseconds)) + { + CancellationToken token = cts.Token; + Process process = Process.GetCurrentProcess(); + + OperationCanceledException? ex = Assert.CatchAsync(async () => await process.WaitForExitAsync(token)) as OperationCanceledException; + + Assert.IsNotNull(ex); + Assert.AreEqual(token, ex!.CancellationToken); + Assert.False(process.HasExited); + } + } + + [Test, RequiresThread] + public void Process_WaitForExitAsync_NotDirected_ThrowsInvalidOperationException() + { + var process = new Process(); + Assert.ThrowsAsync(async () => await process.WaitForExitAsync()); + } +} From c003fb02021d3860256b94b8ff4835b356fff862 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 7 Nov 2023 11:24:07 +1100 Subject: [PATCH 224/313] cleanup --- contributing.md | 4 +- src/Consume/Consume.cs | 2 +- .../CallerArgumentExpressionAttribute.cs | 14 ++++ .../CompilerFeatureRequiredAttribute.cs | 3 + .../DisableRuntimeMarshallingAttribute.cs | 2 + ...erpolatedStringHandlerArgumentAttribute.cs | 2 + .../InterpolatedStringHandlerAttribute.cs | 6 +- src/Polyfill/ModuleInitializerAttribute.cs | 2 + .../PolyfillExtensions_IEnumerable.cs | 3 +- src/Polyfill/PolyfillExtensions_Task.cs | 16 ++--- ...lyfillExtensionsTests_CancellationToken.cs | 62 ++++++++++-------- ...ExtensionsTests_CancellationTokenSource.cs | 64 ++++++++++--------- src/Tests/PolyfillExtensionsTests_Process.cs | 16 ++--- 13 files changed, 118 insertions(+), 78 deletions(-) diff --git a/contributing.md b/contributing.md index 24410003..cf958675 100644 --- a/contributing.md +++ b/contributing.md @@ -135,6 +135,7 @@ Example: using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using Link = System.ComponentModel.DescriptionAttribute; namespace System.Runtime.CompilerServices; @@ -158,6 +159,7 @@ namespace System.Runtime.CompilerServices; /// The specification for module initializers in the .NET runtime can be found here: /// https://github.com/dotnet/runtime/blob/master/docs/design/specs/Ecma-335-Augments.md#module-initializer /// +[Link("https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.moduleinitializerattribute?view=net-7.0")] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] [AttributeUsage( @@ -173,7 +175,7 @@ sealed class ModuleInitializerAttribute : #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 97c4923e..36e60cd7 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -142,7 +142,7 @@ void CancellationTokenUnsafeRegister() { var source = new CancellationTokenSource(); var token = source.Token; - token.UnsafeRegister((state) => {}, null); + token.UnsafeRegister(state => {}, null); token.UnsafeRegister((state, token) => {}, null); } diff --git a/src/Polyfill/CallerArgumentExpressionAttribute.cs b/src/Polyfill/CallerArgumentExpressionAttribute.cs index 8fa14804..bf174414 100644 --- a/src/Polyfill/CallerArgumentExpressionAttribute.cs +++ b/src/Polyfill/CallerArgumentExpressionAttribute.cs @@ -4,21 +4,35 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using Link = System.ComponentModel.DescriptionAttribute; namespace System.Runtime.CompilerServices; +/// +/// Indicates that a parameter captures the expression passed for another parameter as a string. +/// [ExcludeFromCodeCoverage] [DebuggerNonUserCode] [AttributeUsage(AttributeTargets.Parameter)] +[Link("https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerargumentexpressionattribute")] #if PolyPublic public #endif sealed class CallerArgumentExpressionAttribute : Attribute { + /// + /// Initializes a new instance of the class. + /// + /// + /// The name of the parameter whose expression should be captured as a string. + /// public CallerArgumentExpressionAttribute(string parameterName) => ParameterName = parameterName; + /// + /// Gets the name of the parameter whose expression should be captured as a string. + /// public string ParameterName { get; } } diff --git a/src/Polyfill/CompilerFeatureRequiredAttribute.cs b/src/Polyfill/CompilerFeatureRequiredAttribute.cs index 14478d39..9d39b5fe 100644 --- a/src/Polyfill/CompilerFeatureRequiredAttribute.cs +++ b/src/Polyfill/CompilerFeatureRequiredAttribute.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using Link = System.ComponentModel.DescriptionAttribute; namespace System.Runtime.CompilerServices; @@ -16,6 +17,7 @@ namespace System.Runtime.CompilerServices; validOn: AttributeTargets.All, AllowMultiple = true, Inherited = false)] +[Link("https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.compilerfeaturerequiredattribute")] #if PolyPublic public #endif @@ -25,6 +27,7 @@ sealed class CompilerFeatureRequiredAttribute : /// /// Initialize a new instance of /// + /// The name of the required compiler feature. public CompilerFeatureRequiredAttribute(string featureName) => FeatureName = featureName; diff --git a/src/Polyfill/DisableRuntimeMarshallingAttribute.cs b/src/Polyfill/DisableRuntimeMarshallingAttribute.cs index 2b0f80f2..4d611658 100644 --- a/src/Polyfill/DisableRuntimeMarshallingAttribute.cs +++ b/src/Polyfill/DisableRuntimeMarshallingAttribute.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using Link = System.ComponentModel.DescriptionAttribute; namespace System.Runtime.CompilerServices; @@ -27,6 +28,7 @@ namespace System.Runtime.CompilerServices; [ExcludeFromCodeCoverage] [DebuggerNonUserCode] [AttributeUsage(AttributeTargets.Assembly)] +[Link("https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.disableruntimemarshallingattribute")] #if PolyPublic public #endif diff --git a/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs b/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs index 1aae1d37..94b5583e 100644 --- a/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs +++ b/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using Link = System.ComponentModel.DescriptionAttribute; namespace System.Runtime.CompilerServices; @@ -13,6 +14,7 @@ namespace System.Runtime.CompilerServices; [ExcludeFromCodeCoverage] [DebuggerNonUserCode] [AttributeUsage(AttributeTargets.Parameter)] +[Link("https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.interpolatedstringhandlerargumentattribute")] #if PolyPublic public #endif diff --git a/src/Polyfill/InterpolatedStringHandlerAttribute.cs b/src/Polyfill/InterpolatedStringHandlerAttribute.cs index 19a71f32..4486b5dc 100644 --- a/src/Polyfill/InterpolatedStringHandlerAttribute.cs +++ b/src/Polyfill/InterpolatedStringHandlerAttribute.cs @@ -4,12 +4,16 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using Link = System.ComponentModel.DescriptionAttribute; namespace System.Runtime.CompilerServices; using Targets = AttributeTargets; -/// Indicates the attributed type is to be used as an interpolated string handler. +/// +/// Indicates the attributed type is to be used as an interpolated string handler. +/// +[Link("https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.interpolatedstringhandlerargumentattribute")] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] [AttributeUsage( diff --git a/src/Polyfill/ModuleInitializerAttribute.cs b/src/Polyfill/ModuleInitializerAttribute.cs index 17d50e8b..7889a399 100644 --- a/src/Polyfill/ModuleInitializerAttribute.cs +++ b/src/Polyfill/ModuleInitializerAttribute.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using Link = System.ComponentModel.DescriptionAttribute; namespace System.Runtime.CompilerServices; @@ -27,6 +28,7 @@ namespace System.Runtime.CompilerServices; /// The specification for module initializers in the .NET runtime can be found here: /// https://github.com/dotnet/runtime/blob/master/docs/design/specs/Ecma-335-Augments.md#module-initializer /// +[Link("https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.moduleinitializerattribute?view=net-7.0")] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] [AttributeUsage( diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index 938ef0aa..7a650704 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -145,7 +145,8 @@ static IEnumerable ChunkIterator(IEnumerable source { // For all but the first chunk, the array will already be correctly sized. // We can just store into it until either it's full or MoveNext returns false. - TSource[] local = array; // avoid bounds checks by using cached local (`array` is lifted to iterator object as a field) + // avoid bounds checks by using cached local (`array` is lifted to iterator object as a field) + TSource[] local = array; for (; (uint)i < (uint)local.Length && e.MoveNext(); i++) { local[i] = e.Current; diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/PolyfillExtensions_Task.cs index 85a9fb2a..55e3b8f2 100644 --- a/src/Polyfill/PolyfillExtensions_Task.cs +++ b/src/Polyfill/PolyfillExtensions_Task.cs @@ -21,15 +21,15 @@ public static async Task WaitAsync( this Task target, TimeSpan timeout) { - var cancellationSource = new CancellationTokenSource(); + var cancelSource = new CancellationTokenSource(); try { - await target.WaitAsync(timeout, cancellationSource.Token); + await target.WaitAsync(timeout, cancelSource.Token); } finally { - cancellationSource.Cancel(); - cancellationSource.Dispose(); + cancelSource.Cancel(); + cancelSource.Dispose(); } } @@ -60,15 +60,15 @@ public static async Task WaitAsync( this Task target, TimeSpan timeout) { - var cancellationSource = new CancellationTokenSource(); + var cancelSource = new CancellationTokenSource(); try { - return await target.WaitAsync(timeout, cancellationSource.Token); + return await target.WaitAsync(timeout, cancelSource.Token); } finally { - cancellationSource.Cancel(); - cancellationSource.Dispose(); + cancelSource.Cancel(); + cancelSource.Dispose(); } } diff --git a/src/Tests/PolyfillExtensionsTests_CancellationToken.cs b/src/Tests/PolyfillExtensionsTests_CancellationToken.cs index d0fc66de..eb329708 100644 --- a/src/Tests/PolyfillExtensionsTests_CancellationToken.cs +++ b/src/Tests/PolyfillExtensionsTests_CancellationToken.cs @@ -6,10 +6,11 @@ public void CancellationToken_Register_Exceptions() CancellationToken token = default; #nullable disable - Assert.Throws(() => token.Register((Action)null, null)); + Assert.Throws(() => token.Register((Action) null, null)); - Assert.Throws(() => token.UnsafeRegister((Action)null, null)); - Assert.Throws(() => token.UnsafeRegister((Action)null, null)); + // ReSharper disable once RedundantCast + Assert.Throws(() => token.UnsafeRegister((Action) null, null)); + Assert.Throws(() => token.UnsafeRegister((Action) null, null)); #nullable enable } @@ -18,52 +19,57 @@ public void CancellationToken_Register_Exceptions() [TestCase(true)] public static void CancellationToken_Register_ExecutionContextFlowsIfExpected(bool callbackWithToken) { - var cts = new CancellationTokenSource(); + var cancelSource = new CancellationTokenSource(); - const int Iters = 5; - int invoked = 0; + const int iterations = 5; + var invoked = 0; - AsyncLocal al = new AsyncLocal(); - for (int i = 1; i <= Iters; i++) + var asyncLocal = new AsyncLocal(); + for (var i = 1; i <= iterations; i++) { - bool flowExecutionContext = i % 2 == 0; + var flowExecutionContext = i % 2 == 0; - al.Value = i; + asyncLocal.Value = i; Action callback = s => { invoked++; - Assert.AreEqual(flowExecutionContext ? (int)s! : 0, al.Value); + Assert.AreEqual(flowExecutionContext ? (int) s! : 0, asyncLocal.Value); }; - CancellationToken ct = cts.Token; + var token = cancelSource.Token; if (flowExecutionContext && callbackWithToken) { - ct.Register((s, t) => - { - Assert.AreEqual(ct, t); - callback(s); - }, i); + token.Register( + (s, t) => + { + Assert.AreEqual(token, t); + callback(s); + }, + i); } else if (flowExecutionContext) { - ct.Register(callback, i); + token.Register(callback, i); } else if (callbackWithToken) { - ct.UnsafeRegister((s, t) => - { - Assert.AreEqual(ct, t); - callback(s); - }, i); + token.UnsafeRegister( + (s, t) => + { + Assert.AreEqual(token, t); + callback(s); + }, + i); } else { - ct.UnsafeRegister(callback, i); + token.UnsafeRegister(callback, i); } } - al.Value = 0; - cts.Cancel(); - Assert.AreEqual(Iters, invoked); + asyncLocal.Value = 0; + + cancelSource.Cancel(); + Assert.AreEqual(iterations, invoked); } -} +} \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs b/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs index ffc04e73..9230051e 100644 --- a/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs +++ b/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs @@ -13,57 +13,63 @@ private static bool IsCompletedSuccessfully(Task task) [Ignore("This test is taken directly from the .NET repo but we can't match the real CancelAsync logic exactly, so differ slightly and can't pass this test")] public static void CancellationTokenSource_CancelAsync_NoRegistrations_CallbackCompletesImmediately() { - var cts = new CancellationTokenSource(); - Assert.True(IsCompletedSuccessfully(cts.CancelAsync())); - Assert.True(cts.IsCancellationRequested); + var cancelSource = new CancellationTokenSource(); + Assert.True(IsCompletedSuccessfully(cancelSource.CancelAsync())); + Assert.True(cancelSource.IsCancellationRequested); - cts = new CancellationTokenSource(); - cts.Token.Register(() => { }).Dispose(); - Assert.True(IsCompletedSuccessfully(cts.CancelAsync())); - Assert.True(cts.IsCancellationRequested); + cancelSource = new(); + cancelSource.Token.Register(() => + { + }).Dispose(); + Assert.True(IsCompletedSuccessfully(cancelSource.CancelAsync())); + Assert.True(cancelSource.IsCancellationRequested); } [Test] public static async Task CancellationTokenSource_CancelAsync_CallbacksInvokedAsynchronously() { - var cts = new CancellationTokenSource(); + var cancelSource = new CancellationTokenSource(); - var mres = new ManualResetEventSlim(); - cts.Token.Register(mres.Wait); + var resetEventSlim = new ManualResetEventSlim(); + cancelSource.Token.Register(resetEventSlim.Wait); - Task t = cts.CancelAsync(); + var t = cancelSource.CancelAsync(); Assert.False(t.IsCompleted); - Assert.True(cts.IsCancellationRequested); + Assert.True(cancelSource.IsCancellationRequested); - Assert.True(IsCompletedSuccessfully(cts.CancelAsync())); // secondary call completes immediately + // secondary call completes immediately + Assert.True(IsCompletedSuccessfully(cancelSource.CancelAsync())); - mres.Set(); + resetEventSlim.Set(); await t; } [Test] public static void CancellationTokenSource_CancelAsync_AllCallbacksInvoked() { - const int Iters = 1000; + const int iterations = 1000; - int sum = 0; - int callingThreadId = Environment.CurrentManagedThreadId; + var sum = 0; - var cts = new CancellationTokenSource(); - for (int i = 1; i <= Iters; i++) + var cancelSource = new CancellationTokenSource(); + for (var i = 1; i <= iterations; i++) { - cts.Token.Register(s => - { - sum += (int)s!; - }, i); + cancelSource.Token.Register( + s => + { + sum += (int) s!; + }, + i); } - Task t = cts.CancelAsync(); - Assert.True(cts.IsCancellationRequested); + var t = cancelSource.CancelAsync(); + Assert.True(cancelSource.IsCancellationRequested); - ((IAsyncResult)t).AsyncWaitHandle.WaitOne(); // synchronously block without inlining to ensure this thread isn't reused - t.Wait(); // propagate any exceptions + // synchronously block without inlining to ensure this thread isn't reused + ((IAsyncResult) t).AsyncWaitHandle.WaitOne(); + // propagate any exceptions + t.Wait(cancelSource.Token); - Assert.AreEqual(Iters * (Iters + 1) / 2, sum); + Assert.AreEqual(iterations * (iterations + 1) / 2, sum); } -} +} \ No newline at end of file diff --git a/src/Tests/PolyfillExtensionsTests_Process.cs b/src/Tests/PolyfillExtensionsTests_Process.cs index 9410fd6f..a901d870 100644 --- a/src/Tests/PolyfillExtensionsTests_Process.cs +++ b/src/Tests/PolyfillExtensionsTests_Process.cs @@ -5,17 +5,15 @@ partial class PolyfillExtensionsTests [TestCase(10)] // real timeout public void Process_CurrentProcess_WaitAsyncNeverCompletes(int milliseconds) { - using (var cts = new CancellationTokenSource(milliseconds)) - { - CancellationToken token = cts.Token; - Process process = Process.GetCurrentProcess(); + using var cancelSource = new CancellationTokenSource(milliseconds); + var token = cancelSource.Token; + var process = Process.GetCurrentProcess(); - OperationCanceledException? ex = Assert.CatchAsync(async () => await process.WaitForExitAsync(token)) as OperationCanceledException; + var ex = Assert.CatchAsync(() => process.WaitForExitAsync(token)) as OperationCanceledException; - Assert.IsNotNull(ex); - Assert.AreEqual(token, ex!.CancellationToken); - Assert.False(process.HasExited); - } + Assert.IsNotNull(ex); + Assert.AreEqual(token, ex!.CancellationToken); + Assert.False(process.HasExited); } [Test, RequiresThread] From 1558e46ad7cd48cdf47b6e6d55839fdfec35671e Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 7 Nov 2023 11:25:38 +1100 Subject: [PATCH 225/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 44889b75..253c838e 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.29.0 + 1.30.0 1.0.0 Polyfill true From e31cc3ba88a4845b0a3adc80fef42c95ded6f7d5 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 8 Nov 2023 09:51:32 +1100 Subject: [PATCH 226/313] Update BuildApiTest.cs --- src/Tests/BuildApiTest.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index 43b36f85..01ba2538 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -25,7 +25,10 @@ public void Run() var extensions = module.GetTypes().Single(_ => _.Name == nameof(PolyfillExtensions)); using var writer = File.CreateText(md); - foreach (var type in extensions.Methods.Where(_ => !_.IsConstructor).GroupBy(_ => _.Parameters[0].ParameterType.FullName).OrderBy(_ => _.Key)) + foreach (var type in extensions.Methods + .Where(_ => !_.IsConstructor) + .GroupBy(_ => _.Parameters[0].ParameterType.FullName) + .OrderBy(_ => _.Key)) { if (!type.Any(_ => _.IsPublic)) { From fd4b85f59cd865a253f28d5aaab2d10f960864e0 Mon Sep 17 00:00:00 2001 From: Scott Beca Date: Wed, 8 Nov 2023 13:26:07 +1100 Subject: [PATCH 227/313] Add more docs and tests (#100) --- api_list.include.md | 2 +- readme.md | 2 +- src/Polyfill/PolyfillExtensions_Memory.cs | 45 +++- src/Polyfill/PolyfillExtensions_Task.cs | 124 ++++++---- src/Tests/PolyfillExtensionsTests_Memory.cs | 244 +++++++++++++++++++- src/Tests/PolyfillExtensionsTests_Task.cs | 131 +++++++++++ 6 files changed, 492 insertions(+), 56 deletions(-) create mode 100644 src/Tests/PolyfillExtensionsTests_Task.cs diff --git a/api_list.include.md b/api_list.include.md index c44d606e..fa8c9163 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -235,7 +235,7 @@ ### Task * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) - * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)) + * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan)) * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)) diff --git a/readme.md b/readme.md index cb91a334..d383ab06 100644 --- a/readme.md +++ b/readme.md @@ -590,7 +590,7 @@ The class `PolyfillExtensions` includes the following extension methods: ### Task * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) - * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)) + * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan)) * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)) diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/PolyfillExtensions_Memory.cs index e7ad2ce1..65e06ab0 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/PolyfillExtensions_Memory.cs @@ -16,7 +16,7 @@ static partial class PolyfillExtensions /// Indicates whether a specified value is found in a read-only span. Values are compared using IEquatable{T}.Equals(T). /// /// The value to search for. - /// true if found, false otherwise. + /// true if found, false otherwise. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)")] public static bool Contains( this ReadOnlySpan target, @@ -38,7 +38,7 @@ public static bool Contains( /// Indicates whether a specified value is found in a only span. Values are compared using IEquatable{T}.Equals(T). /// /// The value to search for. - /// true if found, false otherwise. + /// true if found, false otherwise. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)")] public static bool Contains( this Span target, @@ -56,18 +56,37 @@ public static bool Contains( return false; } + /// + /// Determines whether two sequences are equal by comparing the elements using IEquatable{T}.Equals(T). + /// + /// The first sequence to compare. + /// The second sequence to compare. + /// true if the two sequences are equal; otherwise, false. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] public static bool SequenceEqual( this ReadOnlySpan target, string other) => target.SequenceEqual(other.AsSpan()); + /// + /// Determines whether two sequences are equal by comparing the elements using IEquatable{T}.Equals(T). + /// + /// The first sequence to compare. + /// The second sequence to compare. + /// true if the two sequences are equal; otherwise, false. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))")] public static bool SequenceEqual( this Span target, string other) => target.SequenceEqual(other.AsSpan()); + /// + /// Determines whether a read-only character span begins with a specified value when compared using a specified value. + /// + /// The source span. + /// The sequence to compare to the beginning of the source span. + /// An enumeration value that determines how span and value are compared. + /// true if value matches the beginning of span; otherwise, false. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] public static bool StartsWith( this ReadOnlySpan target, @@ -75,12 +94,25 @@ public static bool StartsWith( StringComparison comparison = StringComparison.CurrentCulture) => target.StartsWith(other.AsSpan(), comparison); + /// + /// Determines whether a specified sequence appears at the start of a span. + /// + /// The source span. + /// The sequence to compare to the beginning of the source span. + /// true if value matches the beginning of span; otherwise, false. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))")] public static bool StartsWith( this Span target, string other) => target.StartsWith(other.AsSpan()); + /// + /// Determines whether the end of the span matches the specified value when compared using the specified option. + /// + /// The source span. + /// The sequence to compare to the end of the source span. + /// An enumeration value that determines how span and value are compared. + /// true if value matches the end of span; otherwise, false. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))")] public static bool EndsWith( this ReadOnlySpan target, @@ -88,10 +120,17 @@ public static bool EndsWith( StringComparison comparison = StringComparison.CurrentCulture) => target.EndsWith(other.AsSpan(), comparison); + /// + /// Determines whether the specified sequence appears at the end of a span. + /// + /// The source span. + /// The sequence to compare to the end of the source span. + /// true if value matches the end of span; otherwise, false. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))")] public static bool EndsWith( this Span target, string other) => target.EndsWith(other.AsSpan()); } -#endif \ No newline at end of file + +#endif diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/PolyfillExtensions_Task.cs index 55e3b8f2..9ea05f28 100644 --- a/src/Polyfill/PolyfillExtensions_Task.cs +++ b/src/Polyfill/PolyfillExtensions_Task.cs @@ -12,81 +12,117 @@ static partial class PolyfillExtensions { + // Copied from .NET library const Timer.MaxSupportedTimeout + private const uint MaxSupportedTimeout = 0xfffffffe; + + /// Gets a that will complete when this completes or when the specified has cancellation requested. + /// The to monitor for a cancellation request. + /// The representing the asynchronous wait. It may or may not be the same instance as the current instance. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] public static Task WaitAsync(this Task target, CancellationToken cancellationToken) => target.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken); + /// Gets a that will complete when this completes or when the specified timeout expires. + /// The timeout after which the should be faulted with a if it hasn't otherwise completed. + /// The representing the asynchronous wait. It may or may not be the same instance as the current instance. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)")] - public static async Task WaitAsync( + public static Task WaitAsync( this Task target, - TimeSpan timeout) - { - var cancelSource = new CancellationTokenSource(); - try - { - await target.WaitAsync(timeout, cancelSource.Token); - } - finally - { - cancelSource.Cancel(); - cancelSource.Dispose(); - } - } + TimeSpan timeout) => + target.WaitAsync(timeout, default); + /// Gets a that will complete when this completes, when the specified timeout expires, or when the specified has cancellation requested. + /// The timeout after which the should be faulted with a if it hasn't otherwise completed. + /// The to monitor for a cancellation request. + /// The representing the asynchronous wait. It may or may not be the same instance as the current instance. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)")] - public static async Task WaitAsync( + public static Task WaitAsync( this Task target, TimeSpan timeout, CancellationToken cancellationToken) { - var delayTask = Task.Delay(timeout, cancellationToken); - var completedTask = await Task.WhenAny(target, delayTask); - if (completedTask == delayTask) + if (target is null) { - throw new TimeoutException($"Execution did not complete within the time allotted {timeout.TotalMilliseconds} ms"); + throw new ArgumentNullException(nameof(target)); } - await target; + long totalMilliseconds = (long)timeout.TotalMilliseconds; + if (totalMilliseconds < -1 || totalMilliseconds > MaxSupportedTimeout) + { + throw new ArgumentOutOfRangeException(nameof(timeout)); + } + + if (target.IsCompleted || (!cancellationToken.CanBeCanceled && timeout == Timeout.InfiniteTimeSpan)) + { + return target; + } + + if (cancellationToken.IsCancellationRequested) + { + return Task.FromCanceled(cancellationToken); + } + + if (timeout == TimeSpan.Zero) + { + return Task.FromException(new TimeoutException()); + } + + var delayTask = Task.Delay(timeout, cancellationToken); + + Func, Task> continueFunc = completedTask => + { + if (cancellationToken.IsCancellationRequested) + { + throw new TaskCanceledException(); + } + else if (completedTask.Result == delayTask) + { + throw new TimeoutException($"Execution did not complete within the time allotted {timeout.TotalMilliseconds} ms"); + } + + return target; + }; + + return Task.WhenAny(target, delayTask).ContinueWith(continueFunc, TaskContinuationOptions.OnlyOnRanToCompletion); } + /// + /// Gets a that will complete when this completes, or when the specified has cancellation requested. + /// + /// The to monitor for a cancellation request. + /// The representing the asynchronous wait. It may or may not be the same instance as the current instance. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)")] public static Task WaitAsync( this Task target, CancellationToken cancellationToken) => target.WaitAsync(Timeout.InfiniteTimeSpan, cancellationToken); - [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-threading-cancellationtoken)")] - public static async Task WaitAsync( + /// + /// Gets a that will complete when this completes, or when the specified timeout expires. + /// + /// The timeout after which the should be faulted with a if it hasn't otherwise completed. + /// The representing the asynchronous wait. It may or may not be the same instance as the current instance. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan)")] + public static Task WaitAsync( this Task target, - TimeSpan timeout) - { - var cancelSource = new CancellationTokenSource(); - try - { - return await target.WaitAsync(timeout, cancelSource.Token); - } - finally - { - cancelSource.Cancel(); - cancelSource.Dispose(); - } - } + TimeSpan timeout) => + target.WaitAsync(timeout, default); + /// + /// Gets a that will complete when this completes, when the specified timeout expires, or when the specified has cancellation requested. + /// + /// The timeout after which the should be faulted with a if it hasn't otherwise completed. + /// The to monitor for a cancellation request. + /// The representing the asynchronous wait. It may or may not be the same instance as the current instance. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)")] public static async Task WaitAsync( this Task target, TimeSpan timeout, CancellationToken cancellationToken) { - var delayTask = Task.Delay(timeout, cancellationToken); - var completedTask = await Task.WhenAny(target, delayTask); - if (completedTask == delayTask) - { - throw new TimeoutException($"Execution did not complete within the time allotted {timeout.TotalMilliseconds} ms"); - } - - return await target; + await ((Task)target).WaitAsync(timeout, cancellationToken); + return target.Result; } } -#endif \ No newline at end of file +#endif diff --git a/src/Tests/PolyfillExtensionsTests_Memory.cs b/src/Tests/PolyfillExtensionsTests_Memory.cs index 77783f9d..3b84de9d 100644 --- a/src/Tests/PolyfillExtensionsTests_Memory.cs +++ b/src/Tests/PolyfillExtensionsTests_Memory.cs @@ -1,15 +1,245 @@ partial class PolyfillExtensionsTests { [Test] - public void SpanContains() + public void ReadOnlySpan_ZeroLengthContains() { - Assert.True("value".AsSpan().Contains('e')); - var span = new Span("value".ToCharArray()); - Assert.True(span.Contains('e')); + ReadOnlySpan span = new ReadOnlySpan(Array.Empty()); + + bool found = span.Contains(0); + Assert.False(found); + } + + [Test] + public void ReadOnlySpan_TestContains() + { + for (int length = 0; length < 32; length++) + { + int[] a = new int[length]; + for (int i = 0; i < length; i++) + { + a[i] = 10 * (i + 1); + } + ReadOnlySpan span = new ReadOnlySpan(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + int target = a[targetIndex]; + bool found = span.Contains(target); + Assert.True(found); + } + } + } + + [Test] + public void ReadOnlySpan_TestMultipleContains() + { + for (int length = 2; length < 32; length++) + { + int[] a = new int[length]; + for (int i = 0; i < length; i++) + { + a[i] = 10 * (i + 1); + } + + a[length - 1] = 5555; + a[length - 2] = 5555; + + ReadOnlySpan span = new ReadOnlySpan(a); + bool found = span.Contains(5555); + Assert.True(found); + } + } + + [Test] + public void ReadOnlySpan_ZeroLengthContains_String() + { + ReadOnlySpan span = new ReadOnlySpan(Array.Empty()); + bool found = span.Contains("a"); + Assert.False(found); + } + + [Test] + public void ReadOnlySpan_TestMatchContains_String() + { + for (int length = 0; length < 32; length++) + { + string[] a = new string[length]; + for (int i = 0; i < length; i++) + { + a[i] = (10 * (i + 1)).ToString(); + } + ReadOnlySpan span = new ReadOnlySpan(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + string target = a[targetIndex]; + bool found = span.Contains(target); + Assert.True(found); + } + } + } + + [Test] + public void ReadOnlySpan_TestNoMatchContains_String() + { + var rnd = new Random(42); + for (int length = 0; length <= byte.MaxValue; length++) + { + string[] a = new string[length]; + string target = (rnd.Next(0, 256)).ToString(); + for (int i = 0; i < length; i++) + { + string val = (i + 1).ToString(); + a[i] = val == target ? (target + 1) : val; + } + ReadOnlySpan span = new ReadOnlySpan(a); + + bool found = span.Contains(target); + Assert.False(found); + } + } + + [Test] + public void ReadOnlySpan_TestMultipleMatchContains_String() + { + for (int length = 2; length < 32; length++) + { + string[] a = new string[length]; + for (int i = 0; i < length; i++) + { + a[i] = (10 * (i + 1)).ToString(); + } + + a[length - 1] = "5555"; + a[length - 2] = "5555"; + + ReadOnlySpan span = new ReadOnlySpan(a); + bool found = span.Contains("5555"); + Assert.True(found); + } + } + + [Test] + public void Span_ZeroLengthContains() + { + Span span = new Span(Array.Empty()); + + bool found = span.Contains(0); + Assert.False(found); + } + + [Test] + public void Span_TestContains() + { + for (int length = 0; length < 32; length++) + { + int[] a = new int[length]; + for (int i = 0; i < length; i++) + { + a[i] = 10 * (i + 1); + } + Span span = new Span(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + int target = a[targetIndex]; + bool found = span.Contains(target); + Assert.True(found); + } + } + } + + [Test] + public void Span_TestMultipleContains() + { + for (int length = 2; length < 32; length++) + { + int[] a = new int[length]; + for (int i = 0; i < length; i++) + { + a[i] = 10 * (i + 1); + } + + a[length - 1] = 5555; + a[length - 2] = 5555; + + Span span = new Span(a); + bool found = span.Contains(5555); + Assert.True(found); + } + } + + [Test] + public void Span_ZeroLengthContains_String() + { + Span span = new Span(Array.Empty()); + bool found = span.Contains("a"); + Assert.False(found); + } + + [Test] + public void Span_TestMatchContains_String() + { + for (int length = 0; length < 32; length++) + { + string[] a = new string[length]; + for (int i = 0; i < length; i++) + { + a[i] = (10 * (i + 1)).ToString(); + } + Span span = new Span(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + string target = a[targetIndex]; + bool found = span.Contains(target); + Assert.True(found); + } + } + } + + [Test] + public void Span_TestNoMatchContains_String() + { + var rnd = new Random(42); + for (int length = 0; length <= byte.MaxValue; length++) + { + string[] a = new string[length]; + string target = (rnd.Next(0, 256)).ToString(); + for (int i = 0; i < length; i++) + { + string val = (i + 1).ToString(); + a[i] = val == target ? (target + 1) : val; + } + Span span = new Span(a); + + bool found = span.Contains(target); + Assert.False(found); + } + } + + [Test] + public void Span_TestMultipleMatchContains_String() + { + for (int length = 2; length < 32; length++) + { + string[] a = new string[length]; + for (int i = 0; i < length; i++) + { + a[i] = (10 * (i + 1)).ToString(); + } + + a[length - 1] = "5555"; + a[length - 2] = "5555"; + + Span span = new Span(a); + bool found = span.Contains("5555"); + Assert.True(found); + } } [Test] - public void SpanSequenceEqual() + public void Span_SequenceEqual() { Assert.True("value".AsSpan().SequenceEqual("value")); Assert.False("value".AsSpan().SequenceEqual("value2")); @@ -21,7 +251,7 @@ public void SpanSequenceEqual() } [Test] - public void SpanStartsWith() + public void Span_StartsWith() { Assert.True("value".AsSpan().StartsWith("value")); Assert.False("value".AsSpan().StartsWith("value2")); @@ -33,7 +263,7 @@ public void SpanStartsWith() } [Test] - public void SpanEndsWith() + public void Span_EndsWith() { Assert.True("value".AsSpan().EndsWith("value")); Assert.False("value".AsSpan().EndsWith("value2")); diff --git a/src/Tests/PolyfillExtensionsTests_Task.cs b/src/Tests/PolyfillExtensionsTests_Task.cs new file mode 100644 index 00000000..7b7622bb --- /dev/null +++ b/src/Tests/PolyfillExtensionsTests_Task.cs @@ -0,0 +1,131 @@ +partial class PolyfillExtensionsTests +{ + private static T? AssertThrowsAsync(string expectedParamName, AsyncTestDelegate action) + where T : ArgumentException + { + T? exception = Assert.ThrowsAsync(action); + + Assert.AreEqual(expectedParamName, exception?.ParamName); + + return exception; + } + + [Test] + public void Task_WaitAsync_InvalidTimeout_Throws() + { + foreach (TimeSpan timeout in new[] { TimeSpan.FromMilliseconds(-2), TimeSpan.MaxValue, TimeSpan.MinValue }) + { +#if NET5_0_OR_GREATER + AssertThrowsAsync("timeout", async () => await new TaskCompletionSource().Task.WaitAsync(timeout)); + AssertThrowsAsync("timeout", async () => await new TaskCompletionSource().Task.WaitAsync(timeout, CancellationToken.None)); + AssertThrowsAsync("timeout", async () => await new TaskCompletionSource().Task.WaitAsync(timeout, new CancellationToken(true))); +#endif + + AssertThrowsAsync("timeout", async () => await new TaskCompletionSource().Task.WaitAsync(timeout)); + AssertThrowsAsync("timeout", async () => await new TaskCompletionSource().Task.WaitAsync(timeout, CancellationToken.None)); + AssertThrowsAsync("timeout", async () => await new TaskCompletionSource().Task.WaitAsync(timeout, new CancellationToken(true))); + + AssertThrowsAsync("timeout", async () => await Task.CompletedTask.WaitAsync(timeout)); + AssertThrowsAsync("timeout", async () => await Task.CompletedTask.WaitAsync(timeout, CancellationToken.None)); + AssertThrowsAsync("timeout", async () => await Task.CompletedTask.WaitAsync(timeout, new CancellationToken(true))); + + AssertThrowsAsync("timeout", async () => await Task.FromResult(42).WaitAsync(timeout)); + AssertThrowsAsync("timeout", async () => await Task.FromResult(42).WaitAsync(timeout, CancellationToken.None)); + AssertThrowsAsync("timeout", async () => await Task.FromResult(42).WaitAsync(timeout, new CancellationToken(true))); + + AssertThrowsAsync("timeout", async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(timeout)); + AssertThrowsAsync("timeout", async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(timeout, CancellationToken.None)); + AssertThrowsAsync("timeout", async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(timeout, new CancellationToken(true))); + + AssertThrowsAsync("timeout", async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(timeout)); + AssertThrowsAsync("timeout", async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(timeout, CancellationToken.None)); + AssertThrowsAsync("timeout", async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(timeout, new CancellationToken(true))); + + AssertThrowsAsync("timeout", async () => await Task.FromException(new FormatException()).WaitAsync(timeout)); + AssertThrowsAsync("timeout", async () => await Task.FromException(new FormatException()).WaitAsync(timeout, CancellationToken.None)); + AssertThrowsAsync("timeout", async () => await Task.FromException(new FormatException()).WaitAsync(timeout, new CancellationToken(true))); + + AssertThrowsAsync("timeout", async () => await Task.FromException(new FormatException()).WaitAsync(timeout)); + AssertThrowsAsync("timeout", async () => await Task.FromException(new FormatException()).WaitAsync(timeout, CancellationToken.None)); + AssertThrowsAsync("timeout", async () => await Task.FromException(new FormatException()).WaitAsync(timeout, new CancellationToken(true))); + } + } + + [Test] + public async Task Task_WaitAsync_CanceledAndTimedOut_AlreadyCompleted_UsesTaskResult() + { + await Task.CompletedTask.WaitAsync(TimeSpan.Zero); + await Task.CompletedTask.WaitAsync(new CancellationToken(true)); + await Task.CompletedTask.WaitAsync(TimeSpan.Zero, new CancellationToken(true)); + + Assert.AreEqual(42, await Task.FromResult(42).WaitAsync(TimeSpan.Zero)); + Assert.AreEqual(42, await Task.FromResult(42).WaitAsync(new CancellationToken(true))); + Assert.AreEqual(42, await Task.FromResult(42).WaitAsync(TimeSpan.Zero, new CancellationToken(true))); + + Assert.ThrowsAsync(async () => await Task.FromException(new FormatException()).WaitAsync(TimeSpan.Zero)); + Assert.ThrowsAsync(async () => await Task.FromException(new FormatException()).WaitAsync(new CancellationToken(true))); + Assert.ThrowsAsync(async () => await Task.FromException(new FormatException()).WaitAsync(TimeSpan.Zero, new CancellationToken(true))); + + Assert.ThrowsAsync(async () => await Task.FromException(new FormatException()).WaitAsync(TimeSpan.Zero)); + Assert.ThrowsAsync(async () => await Task.FromException(new FormatException()).WaitAsync(new CancellationToken(true))); + Assert.ThrowsAsync(async () => await Task.FromException(new FormatException()).WaitAsync(TimeSpan.Zero, new CancellationToken(true))); + + Assert.ThrowsAsync(async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(TimeSpan.Zero)); + Assert.ThrowsAsync(async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(new CancellationToken(true))); + Assert.ThrowsAsync(async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(TimeSpan.Zero, new CancellationToken(true))); + + Assert.ThrowsAsync(async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(TimeSpan.Zero)); + Assert.ThrowsAsync(async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(new CancellationToken(true))); + Assert.ThrowsAsync(async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(TimeSpan.Zero, new CancellationToken(true))); + } + + [Test] + public void Task_WaitAsync_TimeoutOrCanceled_Throws() + { + var tcs = new TaskCompletionSource(); + var cts = new CancellationTokenSource(); + + Assert.ThrowsAsync(async () => await ((Task)tcs.Task).WaitAsync(TimeSpan.Zero)); + Assert.ThrowsAsync(async () => await ((Task)tcs.Task).WaitAsync(TimeSpan.FromMilliseconds(1))); + Assert.ThrowsAsync(async () => await ((Task)tcs.Task).WaitAsync(TimeSpan.FromMilliseconds(1), cts.Token)); + + Assert.ThrowsAsync(async () => await tcs.Task.WaitAsync(TimeSpan.Zero)); + Assert.ThrowsAsync(async () => await tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(1))); + Assert.ThrowsAsync(async () => await tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(1), cts.Token)); + + Task assert1 = ((Task)tcs.Task).WaitAsync(cts.Token); + Task assert2 = ((Task)tcs.Task).WaitAsync(Timeout.InfiniteTimeSpan, cts.Token); + Task assert3 = tcs.Task.WaitAsync(cts.Token); + Task assert4 = tcs.Task.WaitAsync(Timeout.InfiniteTimeSpan, cts.Token); + Assert.False(assert1.IsCompleted); + Assert.False(assert2.IsCompleted); + Assert.False(assert3.IsCompleted); + Assert.False(assert4.IsCompleted); + + cts.Cancel(); + Assert.ThrowsAsync(async () => await assert1); + Assert.ThrowsAsync(async () => await assert2); + Assert.ThrowsAsync(async () => await assert3); + Assert.ThrowsAsync(async () => await assert4); + } + + [Test] + public async Task Task_WaitAsync_NoCancellationOrTimeoutOccurs_Success() + { + CancellationTokenSource cts = new CancellationTokenSource(); + +#if NET5_0_OR_GREATER + var tcs = new TaskCompletionSource(); + Task t = tcs.Task.WaitAsync(TimeSpan.FromDays(1), cts.Token); + Assert.False(t.IsCompleted); + tcs.SetResult(); + await t; +#endif + + var tcsg = new TaskCompletionSource(); + Task tg = tcsg.Task.WaitAsync(TimeSpan.FromDays(1), cts.Token); + Assert.False(tg.IsCompleted); + tcsg.SetResult(42); + Assert.AreEqual(42, await tg); + } +} From 25dc4a9b3c8cc545692f6f3787005993740ec630 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 8 Nov 2023 13:27:21 +1100 Subject: [PATCH 228/313] version --- src/Directory.Build.props | 2 +- src/Polyfill/PolyfillExtensions_Task.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 253c838e..876f4e9d 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.30.0 + 1.31.0 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/PolyfillExtensions_Task.cs index 9ea05f28..02bd8d2a 100644 --- a/src/Polyfill/PolyfillExtensions_Task.cs +++ b/src/Polyfill/PolyfillExtensions_Task.cs @@ -46,7 +46,7 @@ public static Task WaitAsync( throw new ArgumentNullException(nameof(target)); } - long totalMilliseconds = (long)timeout.TotalMilliseconds; + long totalMilliseconds = (long) timeout.TotalMilliseconds; if (totalMilliseconds < -1 || totalMilliseconds > MaxSupportedTimeout) { throw new ArgumentOutOfRangeException(nameof(timeout)); @@ -120,7 +120,7 @@ public static async Task WaitAsync( TimeSpan timeout, CancellationToken cancellationToken) { - await ((Task)target).WaitAsync(timeout, cancellationToken); + await ((Task) target).WaitAsync(timeout, cancellationToken); return target.Result; } } From 0ae3cf2cde94af8a5a79d6bf979f09a702df466c Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 8 Nov 2023 16:21:02 +1100 Subject: [PATCH 229/313] Update editorconfig.txt --- src/editorconfig.txt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/editorconfig.txt b/src/editorconfig.txt index bb59b63e..c9db1cb9 100644 --- a/src/editorconfig.txt +++ b/src/editorconfig.txt @@ -140,15 +140,17 @@ resharper_wrap_before_binary_pattern_op = false resharper_wrap_object_and_collection_initializer_style = chop_always resharper_place_simple_initializer_on_single_line = false -# space -resharper_space_around_lambda_arrow = true - dotnet_style_require_accessibility_modifiers = never:error resharper_place_type_constraints_on_same_line = false resharper_blank_lines_inside_namespace = 0 resharper_blank_lines_after_file_scoped_namespace_directive = 1 resharper_blank_lines_inside_type = 0 +insert_final_newline = false +resharper_place_attribute_on_same_line = false +resharper_space_around_lambda_arrow = true +resharper_place_constructor_initializer_on_same_line = false + #braces https://www.jetbrains.com/help/resharper/EditorConfig_CSHARP_CSharpCodeStylePageImplSchema.html#Braces resharper_braces_for_ifelse = required resharper_braces_for_foreach = required From 0eae76c7836002d86cecb76f213c116dc4e8519b Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 8 Nov 2023 16:26:15 +1100 Subject: [PATCH 230/313] experimental-attribute (#102) --- src/Consume/Consume.cs | 9 ++++ src/Directory.Build.props | 2 +- src/Polyfill/ExperimentalAttribute.cs | 72 +++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/Polyfill/ExperimentalAttribute.cs diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 36e60cd7..7aabcae1 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -132,6 +132,15 @@ void KeyValuePairDeconstruct(IEnumerable> variables #endif + #pragma warning disable ExperimentalMethod + static void ExperimentalMethodUsage() => + ExperimentalMethod(); + + [Experimental("ExperimentalMethod")] + static void ExperimentalMethod() + { + } + async Task CancellationTokenSource() { var source = new CancellationTokenSource(); diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 876f4e9d..ec3be25a 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.31.0 + 1.32.0 1.0.0 Polyfill true diff --git a/src/Polyfill/ExperimentalAttribute.cs b/src/Polyfill/ExperimentalAttribute.cs new file mode 100644 index 00000000..ec549f38 --- /dev/null +++ b/src/Polyfill/ExperimentalAttribute.cs @@ -0,0 +1,72 @@ +// + +#nullable enable + +#if !NET8_0_OR_GREATER + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using Link = System.ComponentModel.DescriptionAttribute; + +namespace System.Diagnostics.CodeAnalysis; + +/// +/// Indicates that a parameter captures the expression passed for another parameter as a string. +/// +/// +/// Indicates that an API is experimental and it may change in the future. +/// +/// +/// This attribute allows call sites to be flagged with a diagnostic that indicates that an experimental +/// feature is used. Authors can use this attribute to ship preview features in their assemblies. +/// +[AttributeUsage(AttributeTargets.Assembly | + AttributeTargets.Module | + AttributeTargets.Class | + AttributeTargets.Struct | + AttributeTargets.Enum | + AttributeTargets.Constructor | + AttributeTargets.Method | + AttributeTargets.Property | + AttributeTargets.Field | + AttributeTargets.Event | + AttributeTargets.Interface | + AttributeTargets.Delegate, Inherited = false)] +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[Link("https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.codeanalysis.experimentalattribute?view=net-8.0")] +#if PolyPublic +public +#endif +sealed class ExperimentalAttribute : Attribute +{ + /// + /// Initializes a new instance of the class, specifying the ID that the compiler will use + /// when reporting a use of the API the attribute applies to. + /// + /// The ID that the compiler will use when reporting a use of the API the attribute applies to. + public ExperimentalAttribute(string diagnosticId) + { + DiagnosticId = diagnosticId; + } + + /// + /// Gets the ID that the compiler will use when reporting a use of the API the attribute applies to. + /// + /// The unique diagnostic ID. + /// + /// The diagnostic ID is shown in build output for warnings and errors. + /// This property represents the unique ID that can be used to suppress the warnings or errors, if needed. + /// + public string DiagnosticId { get; } + + /// + /// Gets or sets the URL for corresponding documentation. + /// The API accepts a format string instead of an actual URL, creating a generic URL that includes the diagnostic ID. + /// + /// The format string that represents a URL to corresponding documentation. + /// An example format string is https://contoso.com/obsoletion-warnings/{0}. + public string? UrlFormat { get; set; } +} + +#endif \ No newline at end of file From 8148f988108993b47b731700af390aca4c38c017 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 8 Nov 2023 22:10:12 +1100 Subject: [PATCH 231/313] cleanup --- src/Tests/PolyfillExtensionsTests_Memory.cs | 145 ++++++++++---------- src/Tests/PolyfillExtensionsTests_Task.cs | 16 ++- 2 files changed, 82 insertions(+), 79 deletions(-) diff --git a/src/Tests/PolyfillExtensionsTests_Memory.cs b/src/Tests/PolyfillExtensionsTests_Memory.cs index 3b84de9d..9a9f5d72 100644 --- a/src/Tests/PolyfillExtensionsTests_Memory.cs +++ b/src/Tests/PolyfillExtensionsTests_Memory.cs @@ -3,28 +3,28 @@ partial class PolyfillExtensionsTests [Test] public void ReadOnlySpan_ZeroLengthContains() { - ReadOnlySpan span = new ReadOnlySpan(Array.Empty()); + var span = new ReadOnlySpan(Array.Empty()); - bool found = span.Contains(0); + var found = span.Contains(0); Assert.False(found); } [Test] public void ReadOnlySpan_TestContains() { - for (int length = 0; length < 32; length++) + for (var length = 0; length < 32; length++) { - int[] a = new int[length]; - for (int i = 0; i < length; i++) + var a = new int[length]; + for (var i = 0; i < length; i++) { a[i] = 10 * (i + 1); } - ReadOnlySpan span = new ReadOnlySpan(a); + var span = new ReadOnlySpan(a); - for (int targetIndex = 0; targetIndex < length; targetIndex++) + for (var targetIndex = 0; targetIndex < length; targetIndex++) { - int target = a[targetIndex]; - bool found = span.Contains(target); + var target = a[targetIndex]; + var found = span.Contains(target); Assert.True(found); } } @@ -33,10 +33,10 @@ public void ReadOnlySpan_TestContains() [Test] public void ReadOnlySpan_TestMultipleContains() { - for (int length = 2; length < 32; length++) + for (var length = 2; length < 32; length++) { - int[] a = new int[length]; - for (int i = 0; i < length; i++) + var a = new int[length]; + for (var i = 0; i < length; i++) { a[i] = 10 * (i + 1); } @@ -44,8 +44,8 @@ public void ReadOnlySpan_TestMultipleContains() a[length - 1] = 5555; a[length - 2] = 5555; - ReadOnlySpan span = new ReadOnlySpan(a); - bool found = span.Contains(5555); + var span = new ReadOnlySpan(a); + var found = span.Contains(5555); Assert.True(found); } } @@ -53,27 +53,28 @@ public void ReadOnlySpan_TestMultipleContains() [Test] public void ReadOnlySpan_ZeroLengthContains_String() { - ReadOnlySpan span = new ReadOnlySpan(Array.Empty()); - bool found = span.Contains("a"); + var span = new ReadOnlySpan(Array.Empty()); + var found = span.Contains("a"); Assert.False(found); } [Test] public void ReadOnlySpan_TestMatchContains_String() { - for (int length = 0; length < 32; length++) + for (var length = 0; length < 32; length++) { - string[] a = new string[length]; - for (int i = 0; i < length; i++) + var a = new string[length]; + for (var i = 0; i < length; i++) { a[i] = (10 * (i + 1)).ToString(); } - ReadOnlySpan span = new ReadOnlySpan(a); - for (int targetIndex = 0; targetIndex < length; targetIndex++) + var span = new ReadOnlySpan(a); + + for (var targetIndex = 0; targetIndex < length; targetIndex++) { - string target = a[targetIndex]; - bool found = span.Contains(target); + var target = a[targetIndex]; + var found = span.Contains(target); Assert.True(found); } } @@ -83,18 +84,18 @@ public void ReadOnlySpan_TestMatchContains_String() public void ReadOnlySpan_TestNoMatchContains_String() { var rnd = new Random(42); - for (int length = 0; length <= byte.MaxValue; length++) + for (var length = 0; length <= byte.MaxValue; length++) { - string[] a = new string[length]; - string target = (rnd.Next(0, 256)).ToString(); - for (int i = 0; i < length; i++) + var a = new string[length]; + var target = rnd.Next(0, 256).ToString(); + for (var i = 0; i < length; i++) { - string val = (i + 1).ToString(); - a[i] = val == target ? (target + 1) : val; + var val = (i + 1).ToString(); + a[i] = val == target ? target + 1 : val; } - ReadOnlySpan span = new ReadOnlySpan(a); + var span = new ReadOnlySpan(a); - bool found = span.Contains(target); + var found = span.Contains(target); Assert.False(found); } } @@ -102,10 +103,10 @@ public void ReadOnlySpan_TestNoMatchContains_String() [Test] public void ReadOnlySpan_TestMultipleMatchContains_String() { - for (int length = 2; length < 32; length++) + for (var length = 2; length < 32; length++) { - string[] a = new string[length]; - for (int i = 0; i < length; i++) + var a = new string[length]; + for (var i = 0; i < length; i++) { a[i] = (10 * (i + 1)).ToString(); } @@ -113,8 +114,8 @@ public void ReadOnlySpan_TestMultipleMatchContains_String() a[length - 1] = "5555"; a[length - 2] = "5555"; - ReadOnlySpan span = new ReadOnlySpan(a); - bool found = span.Contains("5555"); + var span = new ReadOnlySpan(a); + var found = span.Contains("5555"); Assert.True(found); } } @@ -122,28 +123,28 @@ public void ReadOnlySpan_TestMultipleMatchContains_String() [Test] public void Span_ZeroLengthContains() { - Span span = new Span(Array.Empty()); + var span = new Span(Array.Empty()); - bool found = span.Contains(0); + var found = span.Contains(0); Assert.False(found); } [Test] public void Span_TestContains() { - for (int length = 0; length < 32; length++) + for (var length = 0; length < 32; length++) { - int[] a = new int[length]; - for (int i = 0; i < length; i++) + var a = new int[length]; + for (var i = 0; i < length; i++) { a[i] = 10 * (i + 1); } - Span span = new Span(a); + var span = new Span(a); - for (int targetIndex = 0; targetIndex < length; targetIndex++) + for (var targetIndex = 0; targetIndex < length; targetIndex++) { - int target = a[targetIndex]; - bool found = span.Contains(target); + var target = a[targetIndex]; + var found = span.Contains(target); Assert.True(found); } } @@ -152,10 +153,10 @@ public void Span_TestContains() [Test] public void Span_TestMultipleContains() { - for (int length = 2; length < 32; length++) + for (var length = 2; length < 32; length++) { - int[] a = new int[length]; - for (int i = 0; i < length; i++) + var a = new int[length]; + for (var i = 0; i < length; i++) { a[i] = 10 * (i + 1); } @@ -163,8 +164,8 @@ public void Span_TestMultipleContains() a[length - 1] = 5555; a[length - 2] = 5555; - Span span = new Span(a); - bool found = span.Contains(5555); + var span = new Span(a); + var found = span.Contains(5555); Assert.True(found); } } @@ -172,27 +173,27 @@ public void Span_TestMultipleContains() [Test] public void Span_ZeroLengthContains_String() { - Span span = new Span(Array.Empty()); - bool found = span.Contains("a"); + var span = new Span(Array.Empty()); + var found = span.Contains("a"); Assert.False(found); } [Test] public void Span_TestMatchContains_String() { - for (int length = 0; length < 32; length++) + for (var length = 0; length < 32; length++) { - string[] a = new string[length]; - for (int i = 0; i < length; i++) + var a = new string[length]; + for (var i = 0; i < length; i++) { a[i] = (10 * (i + 1)).ToString(); } - Span span = new Span(a); + var span = new Span(a); - for (int targetIndex = 0; targetIndex < length; targetIndex++) + for (var targetIndex = 0; targetIndex < length; targetIndex++) { - string target = a[targetIndex]; - bool found = span.Contains(target); + var target = a[targetIndex]; + var found = span.Contains(target); Assert.True(found); } } @@ -202,18 +203,18 @@ public void Span_TestMatchContains_String() public void Span_TestNoMatchContains_String() { var rnd = new Random(42); - for (int length = 0; length <= byte.MaxValue; length++) + for (var length = 0; length <= byte.MaxValue; length++) { - string[] a = new string[length]; - string target = (rnd.Next(0, 256)).ToString(); - for (int i = 0; i < length; i++) + var a = new string[length]; + var target = rnd.Next(0, 256).ToString(); + for (var i = 0; i < length; i++) { - string val = (i + 1).ToString(); - a[i] = val == target ? (target + 1) : val; + var val = (i + 1).ToString(); + a[i] = val == target ? target + 1 : val; } - Span span = new Span(a); + var span = new Span(a); - bool found = span.Contains(target); + var found = span.Contains(target); Assert.False(found); } } @@ -221,10 +222,10 @@ public void Span_TestNoMatchContains_String() [Test] public void Span_TestMultipleMatchContains_String() { - for (int length = 2; length < 32; length++) + for (var length = 2; length < 32; length++) { - string[] a = new string[length]; - for (int i = 0; i < length; i++) + var a = new string[length]; + for (var i = 0; i < length; i++) { a[i] = (10 * (i + 1)).ToString(); } @@ -232,8 +233,8 @@ public void Span_TestMultipleMatchContains_String() a[length - 1] = "5555"; a[length - 2] = "5555"; - Span span = new Span(a); - bool found = span.Contains("5555"); + var span = new Span(a); + var found = span.Contains("5555"); Assert.True(found); } } diff --git a/src/Tests/PolyfillExtensionsTests_Task.cs b/src/Tests/PolyfillExtensionsTests_Task.cs index 7b7622bb..f8f14cf6 100644 --- a/src/Tests/PolyfillExtensionsTests_Task.cs +++ b/src/Tests/PolyfillExtensionsTests_Task.cs @@ -1,9 +1,11 @@ +// ReSharper disable ArrangeObjectCreationWhenTypeNotEvident +// ReSharper disable MethodSupportsCancellation partial class PolyfillExtensionsTests { private static T? AssertThrowsAsync(string expectedParamName, AsyncTestDelegate action) where T : ArgumentException { - T? exception = Assert.ThrowsAsync(action); + var exception = Assert.ThrowsAsync(action); Assert.AreEqual(expectedParamName, exception?.ParamName); @@ -13,7 +15,7 @@ partial class PolyfillExtensionsTests [Test] public void Task_WaitAsync_InvalidTimeout_Throws() { - foreach (TimeSpan timeout in new[] { TimeSpan.FromMilliseconds(-2), TimeSpan.MaxValue, TimeSpan.MinValue }) + foreach (var timeout in new[] { TimeSpan.FromMilliseconds(-2), TimeSpan.MaxValue, TimeSpan.MinValue }) { #if NET5_0_OR_GREATER AssertThrowsAsync("timeout", async () => await new TaskCompletionSource().Task.WaitAsync(timeout)); @@ -93,8 +95,8 @@ public void Task_WaitAsync_TimeoutOrCanceled_Throws() Assert.ThrowsAsync(async () => await tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(1))); Assert.ThrowsAsync(async () => await tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(1), cts.Token)); - Task assert1 = ((Task)tcs.Task).WaitAsync(cts.Token); - Task assert2 = ((Task)tcs.Task).WaitAsync(Timeout.InfiniteTimeSpan, cts.Token); + var assert1 = ((Task)tcs.Task).WaitAsync(cts.Token); + var assert2 = ((Task)tcs.Task).WaitAsync(Timeout.InfiniteTimeSpan, cts.Token); Task assert3 = tcs.Task.WaitAsync(cts.Token); Task assert4 = tcs.Task.WaitAsync(Timeout.InfiniteTimeSpan, cts.Token); Assert.False(assert1.IsCompleted); @@ -112,18 +114,18 @@ public void Task_WaitAsync_TimeoutOrCanceled_Throws() [Test] public async Task Task_WaitAsync_NoCancellationOrTimeoutOccurs_Success() { - CancellationTokenSource cts = new CancellationTokenSource(); + var cts = new CancellationTokenSource(); #if NET5_0_OR_GREATER var tcs = new TaskCompletionSource(); - Task t = tcs.Task.WaitAsync(TimeSpan.FromDays(1), cts.Token); + var t = tcs.Task.WaitAsync(TimeSpan.FromDays(1), cts.Token); Assert.False(t.IsCompleted); tcs.SetResult(); await t; #endif var tcsg = new TaskCompletionSource(); - Task tg = tcsg.Task.WaitAsync(TimeSpan.FromDays(1), cts.Token); + var tg = tcsg.Task.WaitAsync(TimeSpan.FromDays(1), cts.Token); Assert.False(tg.IsCompleted); tcsg.SetResult(42); Assert.AreEqual(42, await tg); From f42003212f8bfdd2677b2d38c289bffc950c6688 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Nov 2023 18:56:54 +1100 Subject: [PATCH 232/313] Bump Microsoft.NET.Test.Sdk from 17.7.2 to 17.8.0 in /src (#104) Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.7.2 to 17.8.0. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.7.2...v17.8.0) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index fba7d3fa..796837ce 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -31,7 +31,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index c381075e..7fd65708 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -26,7 +26,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 53a1af73..619c2cab 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -25,7 +25,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index eac0f221..18014557 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -26,7 +26,7 @@ - + From fcce29a6dc26dd896a3578cec700fab4a37248a3 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 13 Nov 2023 15:41:04 +1100 Subject: [PATCH 233/313] fix ReadLineAsync fixes #105 --- src/Directory.Build.props | 2 +- src/Polyfill/PolyfillExtensions_TextReader.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index ec3be25a..eeb6ed58 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.32.0 + 1.32.1 1.0.0 Polyfill true diff --git a/src/Polyfill/PolyfillExtensions_TextReader.cs b/src/Polyfill/PolyfillExtensions_TextReader.cs index 125951cb..c697986d 100644 --- a/src/Polyfill/PolyfillExtensions_TextReader.cs +++ b/src/Polyfill/PolyfillExtensions_TextReader.cs @@ -81,7 +81,7 @@ public static Task ReadLineAsync( { cancellationToken.ThrowIfCancellationRequested(); - return target.ReadToEndAsync(); + return target.ReadLineAsync(); } #endif } \ No newline at end of file From 4372a2e1b168136387d090ffe3a689da46c40cbf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 20:42:58 +1100 Subject: [PATCH 234/313] Bump Microsoft.SourceLink.GitHub from 1.1.1 to 8.0.0 in /src (#107) Bumps [Microsoft.SourceLink.GitHub](https://github.com/dotnet/sourcelink) from 1.1.1 to 8.0.0. - [Release notes](https://github.com/dotnet/sourcelink/releases) - [Commits](https://github.com/dotnet/sourcelink/commits) --- updated-dependencies: - dependency-name: Microsoft.SourceLink.GitHub dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/Polyfill/Polyfill.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index a82eff1b..e597dd49 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -6,7 +6,7 @@ - + From 346b1ac0d2171dcfa235a1480c6c6946f2ce8417 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 17 Nov 2023 16:12:46 +1100 Subject: [PATCH 235/313] Bump ProjectDefaults from 1.0.101 to 1.0.102 in /src (#108) Bumps [ProjectDefaults](https://github.com/SimonCropp/ProjectDefaults) from 1.0.101 to 1.0.102. - [Commits](https://github.com/SimonCropp/ProjectDefaults/commits) --- updated-dependencies: - dependency-name: ProjectDefaults dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/Polyfill/Polyfill.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 796837ce..7025d919 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index e597dd49..6d09c7cb 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 7fd65708..2a13ff31 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 619c2cab..4b25a03f 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 18014557..8e2d6edd 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -27,7 +27,7 @@ - + From c20aabe79be089c8f6fe3c425a4540aba5cd4003 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 17 Nov 2023 16:35:55 +1100 Subject: [PATCH 236/313] Update global.json --- src/global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/global.json b/src/global.json index edb92397..1f98ce1a 100644 --- a/src/global.json +++ b/src/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100-rc.2.23502.2", + "version": "8.0.100", "allowPrerelease": true, "rollForward": "latestFeature" } From 752270607d5d2858f931d0bfd1e4aba39e8e973a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Nov 2023 12:25:32 +1100 Subject: [PATCH 237/313] Bump NUnit from 3.14.0 to 4.0.0 in /src (#109) Bumps [NUnit](https://github.com/nunit/nunit) from 3.14.0 to 4.0.0. - [Release notes](https://github.com/nunit/nunit/releases) - [Changelog](https://github.com/nunit/nunit/blob/master/CHANGES.md) - [Commits](https://github.com/nunit/nunit/compare/v3.14.0...v4.0.0) --- updated-dependencies: - dependency-name: NUnit dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 7025d919..fc4e154b 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 2a13ff31..2167f75d 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 4b25a03f..63a2bcdf 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 8e2d6edd..b52d76d5 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From 43ae56ddd0fb4651a08414d6914941d2a3c8ea6b Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 29 Nov 2023 18:55:52 +1100 Subject: [PATCH 238/313] Revert "Bump NUnit from 3.14.0 to 4.0.0 in /src (#109)" This reverts commit 752270607d5d2858f931d0bfd1e4aba39e8e973a. --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index fc4e154b..7025d919 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 2167f75d..2a13ff31 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 63a2bcdf..4b25a03f 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -23,7 +23,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index b52d76d5..8e2d6edd 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -24,7 +24,7 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + From f3a773d1dcfcedc3b13f3edc094f735fcb13fe73 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 1 Dec 2023 07:36:50 +1100 Subject: [PATCH 239/313] Update DynamicallyAccessedMembersAttribute.cs (#111) --- .../Trimming/DynamicallyAccessedMembersAttribute.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Polyfill/Trimming/DynamicallyAccessedMembersAttribute.cs b/src/Polyfill/Trimming/DynamicallyAccessedMembersAttribute.cs index e036a6e2..610449ec 100644 --- a/src/Polyfill/Trimming/DynamicallyAccessedMembersAttribute.cs +++ b/src/Polyfill/Trimming/DynamicallyAccessedMembersAttribute.cs @@ -27,12 +27,15 @@ namespace System.Diagnostics.CodeAnalysis; [ExcludeFromCodeCoverage] [DebuggerNonUserCode] [AttributeUsage( - validOn: Targets.Field | - Targets.ReturnValue | + validOn: Targets.Class | + Targets.Field | Targets.GenericParameter | + Targets.Interface | + Targets.Method | Targets.Parameter | Targets.Property | - Targets.Method, + Targets.ReturnValue | + Targets.Struct, Inherited = false)] #if PolyPublic public From 2ba6e6fe344f7e39454ed04aa1095d990e66493f Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 1 Dec 2023 07:37:14 +1100 Subject: [PATCH 240/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index eeb6ed58..006664d4 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.32.1 + 1.33.0 1.0.0 Polyfill true From 2c9187c56583f40ecbe58d628e5731d2488be91a Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 1 Dec 2023 08:01:29 +1100 Subject: [PATCH 241/313] Update PolyfillExtensions_Dictionary.cs --- src/Polyfill/PolyfillExtensions_Dictionary.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_Dictionary.cs b/src/Polyfill/PolyfillExtensions_Dictionary.cs index a3d9b67e..1ae05283 100644 --- a/src/Polyfill/PolyfillExtensions_Dictionary.cs +++ b/src/Polyfill/PolyfillExtensions_Dictionary.cs @@ -23,9 +23,9 @@ static partial class PolyfillExtensions /// true if the element is successfully found and removed; otherwise, false. /// is null. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove")] - public static bool Remove( - this Dictionary target, - TKey key, + public static bool Remove( + this Dictionary target, + TKey key, [MaybeNullWhen(false)] out TValue value) { target.TryGetValue(key, out value); From a055ccb3bfc5a6151996d6614178cfa62f3f9977 Mon Sep 17 00:00:00 2001 From: Scott Beca Date: Sun, 3 Dec 2023 19:02:46 +1100 Subject: [PATCH 242/313] Fix bad XML causing Except function doc comments to not work (#112) --- src/Polyfill/PolyfillExtensions_IEnumerable.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/PolyfillExtensions_IEnumerable.cs index 7a650704..2655c353 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/PolyfillExtensions_IEnumerable.cs @@ -12,7 +12,7 @@ static partial class PolyfillExtensions /// /// Produces a set items excluding by using the default equality comparer to compare values. /// - /// An whose elements that are not equal to will be returned. + /// An whose elements that are not equal to will be returned. /// An that is elements equal it will cause those elements to be removed from the returned sequence. /// The type of the elements of . /// A sequence that contains the items of but excluding . @@ -25,7 +25,7 @@ public static IEnumerable Except( /// /// Produces the set difference of two sequences by using the default equality comparer to compare values. /// - /// An whose elements that are not equal to will be returned. + /// An whose elements that are not equal to will be returned. /// An that is elements equal it will cause those elements to be removed from the returned sequence. /// The type of the elements of . /// A sequence that contains the items of but excluding . @@ -38,9 +38,9 @@ public static IEnumerable Except( /// /// Produces a set items excluding by using to compare values. /// - /// An whose elements that are not equal to will be returned. + /// An whose elements that are not equal to will be returned. /// An that is elements equal it will cause those elements to be removed from the returned sequence. - /// An to compare values. + /// An to compare values. /// The type of the elements of . /// A sequence that contains the items of but excluding . [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))")] @@ -63,7 +63,7 @@ public static IEnumerable Except( /// /// Produces the set difference of two sequences by to compare values. /// - /// An whose elements that are not equal to will be returned. + /// An whose elements that are not equal to will be returned. /// An that is elements equal it will cause those elements to be removed from the returned sequence. /// The type of the elements of . /// A sequence that contains the items of but excluding . From 98b9434a710e2dd19e570888cb002f4583cefd17 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 3 Dec 2023 19:21:50 +1100 Subject: [PATCH 243/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 006664d4..db362809 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.33.0 + 1.33.1 1.0.0 Polyfill true From f4b1a02e0dce7d8a0a64406d87ed848fa52ee7b4 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 5 Dec 2023 14:07:08 +1100 Subject: [PATCH 244/313] Update PolyfillExtensionsTests_Task.cs --- src/Tests/PolyfillExtensionsTests_Task.cs | 102 +++++++++++----------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/Tests/PolyfillExtensionsTests_Task.cs b/src/Tests/PolyfillExtensionsTests_Task.cs index f8f14cf6..a5123d9e 100644 --- a/src/Tests/PolyfillExtensionsTests_Task.cs +++ b/src/Tests/PolyfillExtensionsTests_Task.cs @@ -2,7 +2,7 @@ // ReSharper disable MethodSupportsCancellation partial class PolyfillExtensionsTests { - private static T? AssertThrowsAsync(string expectedParamName, AsyncTestDelegate action) + static T? AssertThrowsAsync(string expectedParamName, AsyncTestDelegate action) where T : ArgumentException { var exception = Assert.ThrowsAsync(action); @@ -18,38 +18,38 @@ public void Task_WaitAsync_InvalidTimeout_Throws() foreach (var timeout in new[] { TimeSpan.FromMilliseconds(-2), TimeSpan.MaxValue, TimeSpan.MinValue }) { #if NET5_0_OR_GREATER - AssertThrowsAsync("timeout", async () => await new TaskCompletionSource().Task.WaitAsync(timeout)); - AssertThrowsAsync("timeout", async () => await new TaskCompletionSource().Task.WaitAsync(timeout, CancellationToken.None)); - AssertThrowsAsync("timeout", async () => await new TaskCompletionSource().Task.WaitAsync(timeout, new CancellationToken(true))); + AssertThrowsAsync("timeout", () => new TaskCompletionSource().Task.WaitAsync(timeout)); + AssertThrowsAsync("timeout", () => new TaskCompletionSource().Task.WaitAsync(timeout, Cancel.None)); + AssertThrowsAsync("timeout", () => new TaskCompletionSource().Task.WaitAsync(timeout, new Cancel(true))); #endif - AssertThrowsAsync("timeout", async () => await new TaskCompletionSource().Task.WaitAsync(timeout)); - AssertThrowsAsync("timeout", async () => await new TaskCompletionSource().Task.WaitAsync(timeout, CancellationToken.None)); - AssertThrowsAsync("timeout", async () => await new TaskCompletionSource().Task.WaitAsync(timeout, new CancellationToken(true))); + AssertThrowsAsync("timeout", () => new TaskCompletionSource().Task.WaitAsync(timeout)); + AssertThrowsAsync("timeout", () => new TaskCompletionSource().Task.WaitAsync(timeout, Cancel.None)); + AssertThrowsAsync("timeout", () => new TaskCompletionSource().Task.WaitAsync(timeout, new Cancel(true))); - AssertThrowsAsync("timeout", async () => await Task.CompletedTask.WaitAsync(timeout)); - AssertThrowsAsync("timeout", async () => await Task.CompletedTask.WaitAsync(timeout, CancellationToken.None)); - AssertThrowsAsync("timeout", async () => await Task.CompletedTask.WaitAsync(timeout, new CancellationToken(true))); + AssertThrowsAsync("timeout", () => Task.CompletedTask.WaitAsync(timeout)); + AssertThrowsAsync("timeout", () => Task.CompletedTask.WaitAsync(timeout, Cancel.None)); + AssertThrowsAsync("timeout", () => Task.CompletedTask.WaitAsync(timeout, new Cancel(true))); - AssertThrowsAsync("timeout", async () => await Task.FromResult(42).WaitAsync(timeout)); - AssertThrowsAsync("timeout", async () => await Task.FromResult(42).WaitAsync(timeout, CancellationToken.None)); - AssertThrowsAsync("timeout", async () => await Task.FromResult(42).WaitAsync(timeout, new CancellationToken(true))); + AssertThrowsAsync("timeout", () => Task.FromResult(42).WaitAsync(timeout)); + AssertThrowsAsync("timeout", () => Task.FromResult(42).WaitAsync(timeout, Cancel.None)); + AssertThrowsAsync("timeout", () => Task.FromResult(42).WaitAsync(timeout, new Cancel(true))); - AssertThrowsAsync("timeout", async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(timeout)); - AssertThrowsAsync("timeout", async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(timeout, CancellationToken.None)); - AssertThrowsAsync("timeout", async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(timeout, new CancellationToken(true))); + AssertThrowsAsync("timeout", () => Task.FromCanceled(new Cancel(true)).WaitAsync(timeout)); + AssertThrowsAsync("timeout", () => Task.FromCanceled(new Cancel(true)).WaitAsync(timeout, Cancel.None)); + AssertThrowsAsync("timeout", () => Task.FromCanceled(new Cancel(true)).WaitAsync(timeout, new Cancel(true))); - AssertThrowsAsync("timeout", async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(timeout)); - AssertThrowsAsync("timeout", async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(timeout, CancellationToken.None)); - AssertThrowsAsync("timeout", async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(timeout, new CancellationToken(true))); + AssertThrowsAsync("timeout", () => Task.FromCanceled(new Cancel(true)).WaitAsync(timeout)); + AssertThrowsAsync("timeout", () => Task.FromCanceled(new Cancel(true)).WaitAsync(timeout, Cancel.None)); + AssertThrowsAsync("timeout", () => Task.FromCanceled(new Cancel(true)).WaitAsync(timeout, new Cancel(true))); - AssertThrowsAsync("timeout", async () => await Task.FromException(new FormatException()).WaitAsync(timeout)); - AssertThrowsAsync("timeout", async () => await Task.FromException(new FormatException()).WaitAsync(timeout, CancellationToken.None)); - AssertThrowsAsync("timeout", async () => await Task.FromException(new FormatException()).WaitAsync(timeout, new CancellationToken(true))); + AssertThrowsAsync("timeout", () => Task.FromException(new FormatException()).WaitAsync(timeout)); + AssertThrowsAsync("timeout", () => Task.FromException(new FormatException()).WaitAsync(timeout, Cancel.None)); + AssertThrowsAsync("timeout", () => Task.FromException(new FormatException()).WaitAsync(timeout, new Cancel(true))); - AssertThrowsAsync("timeout", async () => await Task.FromException(new FormatException()).WaitAsync(timeout)); - AssertThrowsAsync("timeout", async () => await Task.FromException(new FormatException()).WaitAsync(timeout, CancellationToken.None)); - AssertThrowsAsync("timeout", async () => await Task.FromException(new FormatException()).WaitAsync(timeout, new CancellationToken(true))); + AssertThrowsAsync("timeout", () => Task.FromException(new FormatException()).WaitAsync(timeout)); + AssertThrowsAsync("timeout", () => Task.FromException(new FormatException()).WaitAsync(timeout, Cancel.None)); + AssertThrowsAsync("timeout", () => Task.FromException(new FormatException()).WaitAsync(timeout, new Cancel(true))); } } @@ -57,28 +57,28 @@ public void Task_WaitAsync_InvalidTimeout_Throws() public async Task Task_WaitAsync_CanceledAndTimedOut_AlreadyCompleted_UsesTaskResult() { await Task.CompletedTask.WaitAsync(TimeSpan.Zero); - await Task.CompletedTask.WaitAsync(new CancellationToken(true)); - await Task.CompletedTask.WaitAsync(TimeSpan.Zero, new CancellationToken(true)); + await Task.CompletedTask.WaitAsync(new Cancel(true)); + await Task.CompletedTask.WaitAsync(TimeSpan.Zero, new Cancel(true)); Assert.AreEqual(42, await Task.FromResult(42).WaitAsync(TimeSpan.Zero)); - Assert.AreEqual(42, await Task.FromResult(42).WaitAsync(new CancellationToken(true))); - Assert.AreEqual(42, await Task.FromResult(42).WaitAsync(TimeSpan.Zero, new CancellationToken(true))); + Assert.AreEqual(42, await Task.FromResult(42).WaitAsync(new Cancel(true))); + Assert.AreEqual(42, await Task.FromResult(42).WaitAsync(TimeSpan.Zero, new Cancel(true))); - Assert.ThrowsAsync(async () => await Task.FromException(new FormatException()).WaitAsync(TimeSpan.Zero)); - Assert.ThrowsAsync(async () => await Task.FromException(new FormatException()).WaitAsync(new CancellationToken(true))); - Assert.ThrowsAsync(async () => await Task.FromException(new FormatException()).WaitAsync(TimeSpan.Zero, new CancellationToken(true))); + Assert.ThrowsAsync(() => Task.FromException(new FormatException()).WaitAsync(TimeSpan.Zero)); + Assert.ThrowsAsync(() => Task.FromException(new FormatException()).WaitAsync(new Cancel(true))); + Assert.ThrowsAsync(() => Task.FromException(new FormatException()).WaitAsync(TimeSpan.Zero, new Cancel(true))); - Assert.ThrowsAsync(async () => await Task.FromException(new FormatException()).WaitAsync(TimeSpan.Zero)); - Assert.ThrowsAsync(async () => await Task.FromException(new FormatException()).WaitAsync(new CancellationToken(true))); - Assert.ThrowsAsync(async () => await Task.FromException(new FormatException()).WaitAsync(TimeSpan.Zero, new CancellationToken(true))); + Assert.ThrowsAsync(() => Task.FromException(new FormatException()).WaitAsync(TimeSpan.Zero)); + Assert.ThrowsAsync(() => Task.FromException(new FormatException()).WaitAsync(new Cancel(true))); + Assert.ThrowsAsync(() => Task.FromException(new FormatException()).WaitAsync(TimeSpan.Zero, new Cancel(true))); - Assert.ThrowsAsync(async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(TimeSpan.Zero)); - Assert.ThrowsAsync(async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(new CancellationToken(true))); - Assert.ThrowsAsync(async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(TimeSpan.Zero, new CancellationToken(true))); + Assert.ThrowsAsync(() => Task.FromCanceled(new Cancel(true)).WaitAsync(TimeSpan.Zero)); + Assert.ThrowsAsync(() => Task.FromCanceled(new Cancel(true)).WaitAsync(new Cancel(true))); + Assert.ThrowsAsync(() => Task.FromCanceled(new Cancel(true)).WaitAsync(TimeSpan.Zero, new Cancel(true))); - Assert.ThrowsAsync(async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(TimeSpan.Zero)); - Assert.ThrowsAsync(async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(new CancellationToken(true))); - Assert.ThrowsAsync(async () => await Task.FromCanceled(new CancellationToken(true)).WaitAsync(TimeSpan.Zero, new CancellationToken(true))); + Assert.ThrowsAsync(() => Task.FromCanceled(new Cancel(true)).WaitAsync(TimeSpan.Zero)); + Assert.ThrowsAsync(() => Task.FromCanceled(new Cancel(true)).WaitAsync(new Cancel(true))); + Assert.ThrowsAsync(() => Task.FromCanceled(new Cancel(true)).WaitAsync(TimeSpan.Zero, new Cancel(true))); } [Test] @@ -87,13 +87,13 @@ public void Task_WaitAsync_TimeoutOrCanceled_Throws() var tcs = new TaskCompletionSource(); var cts = new CancellationTokenSource(); - Assert.ThrowsAsync(async () => await ((Task)tcs.Task).WaitAsync(TimeSpan.Zero)); - Assert.ThrowsAsync(async () => await ((Task)tcs.Task).WaitAsync(TimeSpan.FromMilliseconds(1))); - Assert.ThrowsAsync(async () => await ((Task)tcs.Task).WaitAsync(TimeSpan.FromMilliseconds(1), cts.Token)); + Assert.ThrowsAsync(() => ((Task)tcs.Task).WaitAsync(TimeSpan.Zero)); + Assert.ThrowsAsync(() => ((Task)tcs.Task).WaitAsync(TimeSpan.FromMilliseconds(1))); + Assert.ThrowsAsync(() => ((Task)tcs.Task).WaitAsync(TimeSpan.FromMilliseconds(1), cts.Token)); - Assert.ThrowsAsync(async () => await tcs.Task.WaitAsync(TimeSpan.Zero)); - Assert.ThrowsAsync(async () => await tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(1))); - Assert.ThrowsAsync(async () => await tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(1), cts.Token)); + Assert.ThrowsAsync(() => tcs.Task.WaitAsync(TimeSpan.Zero)); + Assert.ThrowsAsync(() => tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(1))); + Assert.ThrowsAsync(() => tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(1), cts.Token)); var assert1 = ((Task)tcs.Task).WaitAsync(cts.Token); var assert2 = ((Task)tcs.Task).WaitAsync(Timeout.InfiniteTimeSpan, cts.Token); @@ -105,10 +105,10 @@ public void Task_WaitAsync_TimeoutOrCanceled_Throws() Assert.False(assert4.IsCompleted); cts.Cancel(); - Assert.ThrowsAsync(async () => await assert1); - Assert.ThrowsAsync(async () => await assert2); - Assert.ThrowsAsync(async () => await assert3); - Assert.ThrowsAsync(async () => await assert4); + Assert.ThrowsAsync(() => assert1); + Assert.ThrowsAsync(() => assert2); + Assert.ThrowsAsync(() => assert3); + Assert.ThrowsAsync(() => assert4); } [Test] From 3a21d862ea67c7008204d29a3632a25c2f4fb32e Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 5 Dec 2023 14:07:15 +1100 Subject: [PATCH 245/313] Update Shared.sln.DotSettings --- src/Shared.sln.DotSettings | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Shared.sln.DotSettings b/src/Shared.sln.DotSettings index e4b91714..500b0d7a 100644 --- a/src/Shared.sln.DotSettings +++ b/src/Shared.sln.DotSettings @@ -42,6 +42,7 @@ ERROR ERROR ERROR + ERROR ERROR ERROR ERROR From 8442ae8a24321a2739b9efcfa318fd1f395ad6da Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 5 Dec 2023 14:14:56 +1100 Subject: [PATCH 246/313] cleanup --- ...lyfillExtensionsTests_CancellationToken.cs | 8 +++--- ...ExtensionsTests_CancellationTokenSource.cs | 12 ++++---- .../PolyfillExtensionsTests_HttpClient.cs | 28 +++++++++---------- src/Tests/PolyfillExtensionsTests_Process.cs | 8 +++--- .../PolyfillExtensionsTests_StreamReader.cs | 2 +- src/Tests/PolyfillExtensionsTests_Task.cs | 22 +++++++-------- 6 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/Tests/PolyfillExtensionsTests_CancellationToken.cs b/src/Tests/PolyfillExtensionsTests_CancellationToken.cs index eb329708..974d6acd 100644 --- a/src/Tests/PolyfillExtensionsTests_CancellationToken.cs +++ b/src/Tests/PolyfillExtensionsTests_CancellationToken.cs @@ -3,14 +3,14 @@ partial class PolyfillExtensionsTests [Test] public void CancellationToken_Register_Exceptions() { - CancellationToken token = default; + Cancel token = default; #nullable disable - Assert.Throws(() => token.Register((Action) null, null)); + Assert.Throws(() => token.Register((Action) null, null)); // ReSharper disable once RedundantCast Assert.Throws(() => token.UnsafeRegister((Action) null, null)); - Assert.Throws(() => token.UnsafeRegister((Action) null, null)); + Assert.Throws(() => token.UnsafeRegister((Action) null, null)); #nullable enable } @@ -19,7 +19,7 @@ public void CancellationToken_Register_Exceptions() [TestCase(true)] public static void CancellationToken_Register_ExecutionContextFlowsIfExpected(bool callbackWithToken) { - var cancelSource = new CancellationTokenSource(); + var cancelSource = new CancelSource(); const int iterations = 5; var invoked = 0; diff --git a/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs b/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs index 9230051e..8d3fb6e2 100644 --- a/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs +++ b/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs @@ -11,9 +11,9 @@ private static bool IsCompletedSuccessfully(Task task) [Test] [Ignore("This test is taken directly from the .NET repo but we can't match the real CancelAsync logic exactly, so differ slightly and can't pass this test")] - public static void CancellationTokenSource_CancelAsync_NoRegistrations_CallbackCompletesImmediately() + public static void CancelSource_CancelAsync_NoRegistrations_CallbackCompletesImmediately() { - var cancelSource = new CancellationTokenSource(); + var cancelSource = new CancelSource(); Assert.True(IsCompletedSuccessfully(cancelSource.CancelAsync())); Assert.True(cancelSource.IsCancellationRequested); @@ -26,9 +26,9 @@ public static void CancellationTokenSource_CancelAsync_NoRegistrations_CallbackC } [Test] - public static async Task CancellationTokenSource_CancelAsync_CallbacksInvokedAsynchronously() + public static async Task CancelSource_CancelAsync_CallbacksInvokedAsynchronously() { - var cancelSource = new CancellationTokenSource(); + var cancelSource = new CancelSource(); var resetEventSlim = new ManualResetEventSlim(); cancelSource.Token.Register(resetEventSlim.Wait); @@ -45,13 +45,13 @@ public static async Task CancellationTokenSource_CancelAsync_CallbacksInvokedAsy } [Test] - public static void CancellationTokenSource_CancelAsync_AllCallbacksInvoked() + public static void CancelSource_CancelAsync_AllCallbacksInvoked() { const int iterations = 1000; var sum = 0; - var cancelSource = new CancellationTokenSource(); + var cancelSource = new CancelSource(); for (var i = 1; i <= iterations; i++) { cancelSource.Token.Register( diff --git a/src/Tests/PolyfillExtensionsTests_HttpClient.cs b/src/Tests/PolyfillExtensionsTests_HttpClient.cs index a05acc91..7e7816b7 100644 --- a/src/Tests/PolyfillExtensionsTests_HttpClient.cs +++ b/src/Tests/PolyfillExtensionsTests_HttpClient.cs @@ -9,7 +9,7 @@ class FakeHttpMessageHandler : HttpMessageHandler { protected override Task SendAsync( HttpRequestMessage request, - CancellationToken cancellation) + Cancel cancellation) { cancellation.ThrowIfCancellationRequested(); @@ -27,13 +27,13 @@ protected override Task SendAsync( public async Task HttpClientGetStreamAsync_Positive() { // Arrange - var cancellation = new CancellationToken(); + var cancel = new Cancel(); using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); // Act - using var stream = await httpClient.GetStreamAsync("https://example.com", cancellation); + using var stream = await httpClient.GetStreamAsync("https://example.com", cancel); using var reader = new StreamReader(stream); - var content = await reader.ReadToEndAsync(cancellation); + var content = await reader.ReadToEndAsync(cancel); // Assert Assert.AreEqual("Fake Content", content); @@ -43,13 +43,13 @@ public async Task HttpClientGetStreamAsync_Positive() public async Task HttpClientGetStreamAsync_Negative() { // Arrange - var cancellation = new CancellationToken(true); + var cancel = new Cancel(true); using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); // Act try { - await httpClient.GetStreamAsync("https://example.com", cancellation); + await httpClient.GetStreamAsync("https://example.com", cancel); Assert.Fail(); } catch (OperationCanceledException exception) @@ -63,11 +63,11 @@ public async Task HttpClientGetStreamAsync_Negative() public async Task HttpClientGetByteArrayAsync_Positive() { // Arrange - var cancellation = new CancellationToken(); + var cancel = new Cancel(); using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); // Act - var bytes = await httpClient.GetByteArrayAsync("https://example.com", cancellation); + var bytes = await httpClient.GetByteArrayAsync("https://example.com", cancel); var content = Encoding.UTF8.GetString(bytes); // Assert @@ -78,13 +78,13 @@ public async Task HttpClientGetByteArrayAsync_Positive() public async Task HttpClientGetByteArrayAsync_Negative() { // Arrange - var cancellation = new CancellationToken(true); + var cancel = new Cancel(true); using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); // Act try { - await httpClient.GetByteArrayAsync("https://example.com", cancellation); + await httpClient.GetByteArrayAsync("https://example.com", cancel); Assert.Fail(); } catch (OperationCanceledException exception) @@ -98,11 +98,11 @@ public async Task HttpClientGetByteArrayAsync_Negative() public async Task HttpClientGetStringAsync_Positive() { // Arrange - var cancellationToken = new CancellationToken(); + var cancel = new Cancel(); using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); // Act - var content = await httpClient.GetStringAsync("https://example.com", cancellationToken); + var content = await httpClient.GetStringAsync("https://example.com", cancel); // Assert Assert.AreEqual("Fake Content", content); @@ -112,13 +112,13 @@ public async Task HttpClientGetStringAsync_Positive() public async Task HttpClientGetStringAsync_Negative() { // Arrange - var cancellation = new CancellationToken(true); + var cancel = new Cancel(true); using var httpClient = new HttpClient(new FakeHttpMessageHandler(), true); // Act try { - await httpClient.GetStringAsync("https://example.com", cancellation); + await httpClient.GetStringAsync("https://example.com", cancel); Assert.Fail(); } catch (OperationCanceledException exception) diff --git a/src/Tests/PolyfillExtensionsTests_Process.cs b/src/Tests/PolyfillExtensionsTests_Process.cs index a901d870..ed50c547 100644 --- a/src/Tests/PolyfillExtensionsTests_Process.cs +++ b/src/Tests/PolyfillExtensionsTests_Process.cs @@ -5,14 +5,14 @@ partial class PolyfillExtensionsTests [TestCase(10)] // real timeout public void Process_CurrentProcess_WaitAsyncNeverCompletes(int milliseconds) { - using var cancelSource = new CancellationTokenSource(milliseconds); - var token = cancelSource.Token; + using var cancelSource = new CancelSource(milliseconds); + var cancel = cancelSource.Token; var process = Process.GetCurrentProcess(); - var ex = Assert.CatchAsync(() => process.WaitForExitAsync(token)) as OperationCanceledException; + var ex = Assert.CatchAsync(() => process.WaitForExitAsync(cancel)) as OperationCanceledException; Assert.IsNotNull(ex); - Assert.AreEqual(token, ex!.CancellationToken); + Assert.AreEqual(cancel, ex!.CancellationToken); Assert.False(process.HasExited); } diff --git a/src/Tests/PolyfillExtensionsTests_StreamReader.cs b/src/Tests/PolyfillExtensionsTests_StreamReader.cs index 239c85b3..ca9c0b57 100644 --- a/src/Tests/PolyfillExtensionsTests_StreamReader.cs +++ b/src/Tests/PolyfillExtensionsTests_StreamReader.cs @@ -17,7 +17,7 @@ public async Task StreamReaderReadToEndAsync() { using var stream = new MemoryStream("value"u8.ToArray()); using var reader = new StreamReader(stream); - var read = await reader.ReadToEndAsync(CancellationToken.None); + var read = await reader.ReadToEndAsync(Cancel.None); Assert.AreEqual("value", read); } } diff --git a/src/Tests/PolyfillExtensionsTests_Task.cs b/src/Tests/PolyfillExtensionsTests_Task.cs index a5123d9e..01bfd458 100644 --- a/src/Tests/PolyfillExtensionsTests_Task.cs +++ b/src/Tests/PolyfillExtensionsTests_Task.cs @@ -85,26 +85,26 @@ public async Task Task_WaitAsync_CanceledAndTimedOut_AlreadyCompleted_UsesTaskRe public void Task_WaitAsync_TimeoutOrCanceled_Throws() { var tcs = new TaskCompletionSource(); - var cts = new CancellationTokenSource(); + var cancelSource = new CancelSource(); Assert.ThrowsAsync(() => ((Task)tcs.Task).WaitAsync(TimeSpan.Zero)); Assert.ThrowsAsync(() => ((Task)tcs.Task).WaitAsync(TimeSpan.FromMilliseconds(1))); - Assert.ThrowsAsync(() => ((Task)tcs.Task).WaitAsync(TimeSpan.FromMilliseconds(1), cts.Token)); + Assert.ThrowsAsync(() => ((Task)tcs.Task).WaitAsync(TimeSpan.FromMilliseconds(1), cancelSource.Token)); Assert.ThrowsAsync(() => tcs.Task.WaitAsync(TimeSpan.Zero)); Assert.ThrowsAsync(() => tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(1))); - Assert.ThrowsAsync(() => tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(1), cts.Token)); + Assert.ThrowsAsync(() => tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(1), cancelSource.Token)); - var assert1 = ((Task)tcs.Task).WaitAsync(cts.Token); - var assert2 = ((Task)tcs.Task).WaitAsync(Timeout.InfiniteTimeSpan, cts.Token); - Task assert3 = tcs.Task.WaitAsync(cts.Token); - Task assert4 = tcs.Task.WaitAsync(Timeout.InfiniteTimeSpan, cts.Token); + var assert1 = ((Task)tcs.Task).WaitAsync(cancelSource.Token); + var assert2 = ((Task)tcs.Task).WaitAsync(Timeout.InfiniteTimeSpan, cancelSource.Token); + Task assert3 = tcs.Task.WaitAsync(cancelSource.Token); + Task assert4 = tcs.Task.WaitAsync(Timeout.InfiniteTimeSpan, cancelSource.Token); Assert.False(assert1.IsCompleted); Assert.False(assert2.IsCompleted); Assert.False(assert3.IsCompleted); Assert.False(assert4.IsCompleted); - cts.Cancel(); + cancelSource.Cancel(); Assert.ThrowsAsync(() => assert1); Assert.ThrowsAsync(() => assert2); Assert.ThrowsAsync(() => assert3); @@ -114,18 +114,18 @@ public void Task_WaitAsync_TimeoutOrCanceled_Throws() [Test] public async Task Task_WaitAsync_NoCancellationOrTimeoutOccurs_Success() { - var cts = new CancellationTokenSource(); + var cancelSource = new CancelSource(); #if NET5_0_OR_GREATER var tcs = new TaskCompletionSource(); - var t = tcs.Task.WaitAsync(TimeSpan.FromDays(1), cts.Token); + var t = tcs.Task.WaitAsync(TimeSpan.FromDays(1), cancelSource.Token); Assert.False(t.IsCompleted); tcs.SetResult(); await t; #endif var tcsg = new TaskCompletionSource(); - var tg = tcsg.Task.WaitAsync(TimeSpan.FromDays(1), cts.Token); + var tg = tcsg.Task.WaitAsync(TimeSpan.FromDays(1), cancelSource.Token); Assert.False(tg.IsCompleted); tcsg.SetResult(42); Assert.AreEqual(42, await tg); From e70f63208a611e9107f4fd57e355b7221307f860 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 5 Dec 2023 14:16:22 +1100 Subject: [PATCH 247/313] Update contributing.md --- contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributing.md b/contributing.md index cf958675..81764fe7 100644 --- a/contributing.md +++ b/contributing.md @@ -336,7 +336,7 @@ partial class PolyfillExtensionsTests { using var stream = new MemoryStream("value"u8.ToArray()); using var reader = new StreamReader(stream); - var read = await reader.ReadToEndAsync(CancellationToken.None); + var read = await reader.ReadToEndAsync(Cancel.None); Assert.AreEqual("value", read); } } From d0366327359fa998e323bfb2f7c0d295f292f371 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 5 Dec 2023 14:16:33 +1100 Subject: [PATCH 248/313] collection expressions --- .../InterpolatedStringHandlerArgumentAttribute.cs | 2 +- src/Polyfill/Nullability/NullabilityInfoExtensions.cs | 8 ++++---- src/Polyfill/Nullable/MemberNotNullAttribute.cs | 2 +- src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs | 2 +- src/Polyfill/PolyfillExtensions_String.cs | 4 ++-- .../PolyfillExtensionsTests_CancellationTokenSource.cs | 9 ++++++--- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs b/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs index 94b5583e..c2ab3559 100644 --- a/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs +++ b/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs @@ -26,7 +26,7 @@ sealed class InterpolatedStringHandlerArgumentAttribute : /// /// The name of the argument that should be passed to the handler. /// may be used as the name of the receiver in an instance method. - public InterpolatedStringHandlerArgumentAttribute(string argument) => Arguments = new[] { argument }; + public InterpolatedStringHandlerArgumentAttribute(string argument) => Arguments = [argument]; /// /// Initializes a new instance of the class. diff --git a/src/Polyfill/Nullability/NullabilityInfoExtensions.cs b/src/Polyfill/Nullability/NullabilityInfoExtensions.cs index 82af6035..a1dcf842 100644 --- a/src/Polyfill/Nullability/NullabilityInfoExtensions.cs +++ b/src/Polyfill/Nullability/NullabilityInfoExtensions.cs @@ -14,10 +14,10 @@ #endif static partial class PolyfillExtensions { - static ConcurrentDictionary parameterCache = new(); - static ConcurrentDictionary propertyCache = new(); - static ConcurrentDictionary eventCache = new(); - static ConcurrentDictionary fieldCache = new(); + static ConcurrentDictionary parameterCache = []; + static ConcurrentDictionary propertyCache = []; + static ConcurrentDictionary eventCache = []; + static ConcurrentDictionary fieldCache = []; public static NullabilityInfo GetNullabilityInfo(this MemberInfo info) { diff --git a/src/Polyfill/Nullable/MemberNotNullAttribute.cs b/src/Polyfill/Nullable/MemberNotNullAttribute.cs index 99c12264..bfbde6a8 100644 --- a/src/Polyfill/Nullable/MemberNotNullAttribute.cs +++ b/src/Polyfill/Nullable/MemberNotNullAttribute.cs @@ -35,7 +35,7 @@ sealed class MemberNotNullAttribute : /// The field or property member that is promised to be not-null. /// public MemberNotNullAttribute(string member) => - Members = new[] { member }; + Members = [member]; /// /// Initializes the attribute with the list of field and property members. diff --git a/src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs b/src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs index 4f434e83..b9fbd538 100644 --- a/src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs +++ b/src/Polyfill/Nullable/MemberNotNullWhenAttribute.cs @@ -46,7 +46,7 @@ sealed class MemberNotNullWhenAttribute : public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; - Members = new[] { member }; + Members = [member]; } /// diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/PolyfillExtensions_String.cs index a3565b0f..790dd9c5 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/PolyfillExtensions_String.cs @@ -108,7 +108,7 @@ public static bool EndsWith(this string target, char value) /// An array that contains at most count substrings from this instance that are delimited by separator. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)")] public static string[] Split(this string target, char separator, StringSplitOptions options = StringSplitOptions.None) => - target.Split(new[] {separator}, options); + target.Split([separator], options); /// /// Splits a string into a maximum number of substrings based on a specified delimiting character and, optionally, @@ -122,7 +122,7 @@ public static string[] Split(this string target, char separator, StringSplitOpti /// An array that contains at most count substrings from this instance that are delimited by separator. [Link("https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)")] public static string[] Split(this string target, char separator, int count, StringSplitOptions options = StringSplitOptions.None) => - target.Split(new[] {separator}, count, options); + target.Split([separator], count, options); #endif #if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0 diff --git a/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs b/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs index 8d3fb6e2..8c455fc7 100644 --- a/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs +++ b/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs @@ -18,9 +18,12 @@ public static void CancelSource_CancelAsync_NoRegistrations_CallbackCompletesImm Assert.True(cancelSource.IsCancellationRequested); cancelSource = new(); - cancelSource.Token.Register(() => - { - }).Dispose(); + cancelSource.Token + .Register( + () => + { + }) + .Dispose(); Assert.True(IsCompletedSuccessfully(cancelSource.CancelAsync())); Assert.True(cancelSource.IsCancellationRequested); } From 51c326a5ffc4e851aab4a5ba1da1160d7f305808 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 5 Dec 2023 14:17:46 +1100 Subject: [PATCH 249/313] cleanup --- readme.md | 10 ++-------- src/Tests/MyRecord.cs | 8 +------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/readme.md b/readme.md index d383ab06..67c28d26 100644 --- a/readme.md +++ b/readme.md @@ -105,16 +105,10 @@ Reference: [init (C# Reference)](https://learn.microsoft.com/en-us/dotnet/csharp ```cs class InitExample { - private int member; - - public int Member - { - get => member; - init => member = value; - } + public int Member { get; init; } } ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Tests/MyRecord.cs b/src/Tests/MyRecord.cs index bfefc7bd..a4df030e 100644 --- a/src/Tests/MyRecord.cs +++ b/src/Tests/MyRecord.cs @@ -2,13 +2,7 @@ class InitExample { - private int member; - - public int Member - { - get => member; - init => member = value; - } + public int Member { get; init; } } #endregion \ No newline at end of file From 991f50b0ca3043d30d9243962e1cd2a2d6e63c9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 21:54:45 +1100 Subject: [PATCH 250/313] Bump ProjectDefaults from 1.0.102 to 1.0.106 in /src (#113) Bumps [ProjectDefaults](https://github.com/SimonCropp/ProjectDefaults) from 1.0.102 to 1.0.106. - [Commits](https://github.com/SimonCropp/ProjectDefaults/commits) --- updated-dependencies: - dependency-name: ProjectDefaults dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/Polyfill/Polyfill.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index 6d09c7cb..913f4940 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + From c8d86ff4dd630179aa0f273229b7093d2160ee07 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 7 Dec 2023 23:14:22 +1100 Subject: [PATCH 251/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 4 ++-- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 7025d919..236c40b2 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -32,7 +32,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 2a13ff31..b472ae0e 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -27,7 +27,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 4b25a03f..3739e9c2 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -26,8 +26,8 @@ - - + + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 8e2d6edd..5e10e4e4 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -27,7 +27,7 @@ - + From b32bdd8abfb0282b488c3da74c15e0100987b27f Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 10 Dec 2023 18:13:01 +1100 Subject: [PATCH 252/313] cleanup --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- src/.editorconfig | 5 +++-- src/Shared.sln.DotSettings | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 50eb5f98..6e733e45 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -34,4 +34,4 @@ Ensure you have replicated the bug in a minimal solution with the fewest moving #### Submit a PR that fixes the bug -Submit a [Pull Request (PR)](https://help.github.com/articles/about-pull-requests/) that fixes the bug. Include in this PR a test that verifies the fix. If you were not able to fix the bug, a PR that illustrates your partial progress will suffice. \ No newline at end of file +Submit a [Pull Request (PR)](https://help.github.com/articles/about-pull-requests/) that fixes the bug. Include in this PR a test that verifies the fix. If you were not able to fix the bug, a PR that illustrates your partial progress will suffice. diff --git a/src/.editorconfig b/src/.editorconfig index c9db1cb9..99a756c1 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -134,7 +134,7 @@ csharp_new_line_before_finally = true csharp_new_line_before_members_in_object_initializers = true csharp_new_line_before_members_in_anonymous_types = true resharper_wrap_before_first_type_parameter_constraint = true -resharper_wrap_extends_list_style = chop_always +resharper_wrap_extends_list_style = chop_always resharper_wrap_after_dot_in_method_calls = false resharper_wrap_before_binary_pattern_op = false resharper_wrap_object_and_collection_initializer_style = chop_always @@ -161,11 +161,12 @@ resharper_braces_for_fixed = required resharper_braces_for_for = required # Xml files -[*.{xml,config,nuspec,resx,vsixmanifest,csproj,targets,props}] +[*.{xml,config,nuspec,resx,vsixmanifest,csproj,targets,props,fsproj}] indent_size = 2 # https://www.jetbrains.com/help/resharper/EditorConfig_XML_XmlCodeStylePageSchema.html#resharper_xml_blank_line_after_pi resharper_blank_line_after_pi = false resharper_space_before_self_closing = true +ij_xml_space_inside_empty_tag = true [*.json] indent_size = 2 \ No newline at end of file diff --git a/src/Shared.sln.DotSettings b/src/Shared.sln.DotSettings index 500b0d7a..b0a1a6f3 100644 --- a/src/Shared.sln.DotSettings +++ b/src/Shared.sln.DotSettings @@ -36,6 +36,7 @@ ERROR ERROR DO_NOT_SHOW + DO_NOT_SHOW ERROR ERROR ERROR @@ -151,7 +152,10 @@ NEVER NEVER False + True + CHOP_ALWAYS False + CHOP_ALWAYS False False RemoveIndent From 10fba746b3a98907341cb212c13a36f3560ea6ec Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 10 Dec 2023 19:05:11 +1100 Subject: [PATCH 253/313] move to only using a targest file (#116) --- src/Consume/Consume.csproj | 1 - .../ConsumeClassicReferences.csproj | 1 - src/ConsumeIndirect/ConsumeIndirect.csproj | 1 - src/ConsumeNoRefs/ConsumeNoRefs.csproj | 1 - src/Directory.Build.props | 2 +- src/NoRefsTests/NoRefsTests.csproj | 1 - src/Polyfill/Polyfill.nuspec | 2 - src/Polyfill/Polyfill.props | 37 ------------------- src/Polyfill/Polyfill.targets | 34 ++++++++++++++++- src/PublicTests/PublicTests.csproj | 1 - src/Tests/Tests.csproj | 1 - src/UnsafeTests/UnsafeTests.csproj | 1 - 12 files changed, 34 insertions(+), 49 deletions(-) delete mode 100644 src/Polyfill/Polyfill.props diff --git a/src/Consume/Consume.csproj b/src/Consume/Consume.csproj index da38f4e1..0cc26315 100644 --- a/src/Consume/Consume.csproj +++ b/src/Consume/Consume.csproj @@ -28,6 +28,5 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - \ No newline at end of file diff --git a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj index 3e13577b..113f07e8 100644 --- a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj +++ b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj @@ -29,6 +29,5 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - \ No newline at end of file diff --git a/src/ConsumeIndirect/ConsumeIndirect.csproj b/src/ConsumeIndirect/ConsumeIndirect.csproj index 3ee3c796..726b4707 100644 --- a/src/ConsumeIndirect/ConsumeIndirect.csproj +++ b/src/ConsumeIndirect/ConsumeIndirect.csproj @@ -30,6 +30,5 @@ - \ No newline at end of file diff --git a/src/ConsumeNoRefs/ConsumeNoRefs.csproj b/src/ConsumeNoRefs/ConsumeNoRefs.csproj index 11f743c9..f8520598 100644 --- a/src/ConsumeNoRefs/ConsumeNoRefs.csproj +++ b/src/ConsumeNoRefs/ConsumeNoRefs.csproj @@ -25,6 +25,5 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - \ No newline at end of file diff --git a/src/Directory.Build.props b/src/Directory.Build.props index db362809..55129f16 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.33.1 + 1.33.2 1.0.0 Polyfill true diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 236c40b2..3b81a1ce 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -34,6 +34,5 @@ - \ No newline at end of file diff --git a/src/Polyfill/Polyfill.nuspec b/src/Polyfill/Polyfill.nuspec index a072ac3f..4dc1228f 100644 --- a/src/Polyfill/Polyfill.nuspec +++ b/src/Polyfill/Polyfill.nuspec @@ -27,8 +27,6 @@ target="contentFiles/cs/netstandard2.0/Polyfill/Trimming"/> - diff --git a/src/Polyfill/Polyfill.props b/src/Polyfill/Polyfill.props deleted file mode 100644 index 7f4a67a9..00000000 --- a/src/Polyfill/Polyfill.props +++ /dev/null @@ -1,37 +0,0 @@ - - - $(DefineConstants);AllowUnsafeBlocks - - - false - false - false - false - $(TargetFramework.ToLower()) - - - $(DefineConstants);NETCOREAPP2X - - - $(DefineConstants);NETCOREAPP3X - - - $(DefineConstants);NET46X - - - $(DefineConstants);NET47X - - - $(DefineConstants);NET48X - - - $(DefineConstants);NETCOREAPPX - - - - false - - - \ No newline at end of file diff --git a/src/Polyfill/Polyfill.targets b/src/Polyfill/Polyfill.targets index 5e1c07b9..da9b2421 100644 --- a/src/Polyfill/Polyfill.targets +++ b/src/Polyfill/Polyfill.targets @@ -1,11 +1,37 @@ $(PrepareForBuildDependsOn);PreparePolyfill + false + false + false + false + $(TargetFramework.ToLower()) + + + $(DefineConstants);AllowUnsafeBlocks $(DefineConstants);PolyPublic - + + $(DefineConstants);NETCOREAPP2X + + + $(DefineConstants);NETCOREAPP3X + + + $(DefineConstants);NET46X + + + $(DefineConstants);NET47X + + + $(DefineConstants);NET48X + + + $(DefineConstants);NETCOREAPPX + $(DefineConstants);HTTPREFERENCED + + + false + + \ No newline at end of file diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index b472ae0e..95e2b340 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -33,6 +33,5 @@ - \ No newline at end of file diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 3739e9c2..55bdd613 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -33,6 +33,5 @@ - \ No newline at end of file diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 5e10e4e4..28f325ce 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -33,6 +33,5 @@ - \ No newline at end of file From f3ce71a2c72e6658cfecec60cc64f09baada8cb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabr=C3=ADcio=20Godoy?= Date: Wed, 13 Dec 2023 21:03:16 -0300 Subject: [PATCH 254/313] feat: support string and string builder interpolation (#114) --- api_list.include.md | 4 + readme.md | 13 +- src/Consume/Consume.csproj | 3 + .../ConsumeClassicReferences.csproj | 3 + src/ConsumeIndirect/ConsumeIndirect.csproj | 3 + src/ConsumeNoRefs/ConsumeNoRefs.csproj | 3 + src/NoRefsTests/NoRefsTests.csproj | 3 + src/Polyfill/Polyfill.nuspec | 2 + src/Polyfill/Polyfill.targets | 13 + src/Polyfill/PolyfillExtensions_String.cs | 2 +- .../PolyfillExtensions_StringBuilder.cs | 95 +- .../AppendInterpolatedStringHandler.cs | 348 ++++++++ .../DefaultInterpolatedStringHandler.cs | 814 ++++++++++++++++++ .../StringInterpolation/ISpanFormattable.cs | 32 + ...erpolatedStringHandlerArgumentAttribute.cs | 0 .../InterpolatedStringHandlerAttribute.cs | 0 src/PublicTests/PublicTests.csproj | 3 + src/Tests/SanityChecks.cs | 4 +- src/Tests/StringInterpolationTests.cs | 28 + src/Tests/Tests.csproj | 3 + src/UnsafeTests/UnsafeTests.csproj | 3 + 21 files changed, 1368 insertions(+), 11 deletions(-) create mode 100644 src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs create mode 100644 src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs create mode 100644 src/Polyfill/StringInterpolation/ISpanFormattable.cs rename src/Polyfill/{ => StringInterpolation}/InterpolatedStringHandlerArgumentAttribute.cs (100%) rename src/Polyfill/{ => StringInterpolation}/InterpolatedStringHandlerAttribute.cs (100%) create mode 100644 src/Tests/StringInterpolationTests.cs diff --git a/api_list.include.md b/api_list.include.md index fa8c9163..7b66f248 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -209,6 +209,10 @@ ### StringBuilder * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) + * `StringBuilder Append(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder Append(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendLine(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendLine(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) diff --git a/readme.md b/readme.md index 67c28d26..dbd8ec89 100644 --- a/readme.md +++ b/readme.md @@ -67,7 +67,7 @@ Then all consuming projects, like tests, will not need to use the Polyfill nuget If Polyfill is being consumed in a solution that produce a library (and usually a nuget), then the Polyfill nuget can be added to all projects. -If, however, `InternalsVisibileTo` is being used to expose APIs (for example to test projects), then the Polyfill nuget should be added only to the root library project. +If, however, `InternalsVisibleTo` is being used to expose APIs (for example to test projects), then the Polyfill nuget should be added only to the root library project. ## Included polyfills @@ -283,10 +283,13 @@ static class GuardUsage ### InterpolatedStringHandler + * [AppendInterpolatedStringHandler](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendinterpolatedstringhandler) + * [DefaultInterpolatedStringHandler](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.defaultinterpolatedstringhandler) * [InterpolatedStringHandlerAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.interpolatedstringhandlerattribute) * [InterpolatedStringHandlerArgumentAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.interpolatedstringhandlerargumentattribute) + * [ISpanFormattable](https://learn.microsoft.com/en-us/dotnet/api/system.ispanformattable) -Reference: [Write a custom string interpolation handler](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/interpolated-string-handler) +References: [String Interpolation in C# 10 and .NET 6](https://devblogs.microsoft.com/dotnet/string-interpolation-in-c-10-and-net-6/), [Write a custom string interpolation handler](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/interpolated-string-handler) ### StringSyntaxAttribute @@ -558,9 +561,15 @@ The class `PolyfillExtensions` includes the following extension methods: ### StringBuilder * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) + * `StringBuilder Append(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder Append(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendLine(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendLine(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) +> [!IMPORTANT] +> The methods using `AppendInterpolatedStringHandler` parameter are not extensions because the compiler prefers to use the overload with `string` parameter instead. ### CancellationToken diff --git a/src/Consume/Consume.csproj b/src/Consume/Consume.csproj index 0cc26315..1a628e17 100644 --- a/src/Consume/Consume.csproj +++ b/src/Consume/Consume.csproj @@ -21,6 +21,9 @@ Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs diff --git a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj index 113f07e8..c609c5b0 100644 --- a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj +++ b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj @@ -22,6 +22,9 @@ Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs diff --git a/src/ConsumeIndirect/ConsumeIndirect.csproj b/src/ConsumeIndirect/ConsumeIndirect.csproj index 726b4707..d0bd1013 100644 --- a/src/ConsumeIndirect/ConsumeIndirect.csproj +++ b/src/ConsumeIndirect/ConsumeIndirect.csproj @@ -22,6 +22,9 @@ Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs diff --git a/src/ConsumeNoRefs/ConsumeNoRefs.csproj b/src/ConsumeNoRefs/ConsumeNoRefs.csproj index f8520598..cbbfe582 100644 --- a/src/ConsumeNoRefs/ConsumeNoRefs.csproj +++ b/src/ConsumeNoRefs/ConsumeNoRefs.csproj @@ -18,6 +18,9 @@ Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 3b81a1ce..88354bbf 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -16,6 +16,9 @@ Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs diff --git a/src/Polyfill/Polyfill.nuspec b/src/Polyfill/Polyfill.nuspec index 4dc1228f..9d340323 100644 --- a/src/Polyfill/Polyfill.nuspec +++ b/src/Polyfill/Polyfill.nuspec @@ -23,6 +23,8 @@ target="contentFiles/cs/netstandard2.0/Polyfill/Nullability"/> + $(DefineConstants);HTTPREFERENCED + + $(DefineConstants);HAS_SPAN + $(DefineConstants);HAS_SPAN + $(DefineConstants);HAS_SPAN + $(DefineConstants);HAS_SPAN + $(DefineConstants);HAS_SPAN + $(DefineConstants);HAS_SPAN + $(DefineConstants);HAS_SPAN + $(DefineConstants);HAS_SPAN + $(DefineConstants);HAS_SPAN + $(DefineConstants) + $(DefineConstants) + diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/PolyfillExtensions_String.cs index 790dd9c5..2d885e2f 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/PolyfillExtensions_String.cs @@ -8,7 +8,7 @@ static partial class PolyfillExtensions { -#if (MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP)) || NET5_0 +#if HAS_SPAN && !NET6_0_OR_GREATER /// /// Copies the contents of this string into the destination span. diff --git a/src/Polyfill/PolyfillExtensions_StringBuilder.cs b/src/Polyfill/PolyfillExtensions_StringBuilder.cs index 901e13cb..1a64debd 100644 --- a/src/Polyfill/PolyfillExtensions_StringBuilder.cs +++ b/src/Polyfill/PolyfillExtensions_StringBuilder.cs @@ -2,18 +2,19 @@ #pragma warning disable -#if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) - using System; using System.IO; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; -using Link = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; +using Link = System.ComponentModel.DescriptionAttribute; static partial class PolyfillExtensions { +#if HAS_SPAN && (!NETSTANDARD2_1_OR_GREATER && !NETCOREAPP2_1_OR_GREATER) + /// /// Copies the characters from a specified segment of this instance to a destination Char span. /// @@ -62,13 +63,13 @@ public static StringBuilder Append(this StringBuilder target, ReadOnlySpan #if AllowUnsafeBlocks unsafe { - fixed (char* valueChars = &MemoryMarshal.GetReference(value)) + fixed (char* valueChars = value) { target.Append(valueChars, value.Length); } } #else - target.Append(value.ToArray()); + target.Append(value.ToString()); #endif return target; } @@ -103,5 +104,85 @@ public static bool Equals(this StringBuilder target, ReadOnlySpan span) return true; } -} -#endif \ No newline at end of file + +#endif +#if HAS_SPAN && !NET6_0_OR_GREATER + /// Appends the specified interpolated string to this instance. + /// The interpolated string to append. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)")] + public static StringBuilder Append( + StringBuilder target, + [InterpolatedStringHandlerArgument(nameof(target))] ref AppendInterpolatedStringHandler handler) => target; + + /// Appends the specified interpolated string to this instance. + /// An object that supplies culture-specific formatting information. + /// The interpolated string to append. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)")] + public static StringBuilder Append( + StringBuilder target, + IFormatProvider? provider, + [InterpolatedStringHandlerArgument(nameof(target), nameof(provider))] ref AppendInterpolatedStringHandler handler) => target; + + /// Appends the specified interpolated string followed by the default line terminator to the end of the current StringBuilder object. + /// The interpolated string to append. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)")] + public static StringBuilder AppendLine( + StringBuilder target, + [InterpolatedStringHandlerArgument(nameof(target))] ref AppendInterpolatedStringHandler handler) => + target.AppendLine(); + + /// Appends the specified interpolated string followed by the default line terminator to the end of the current StringBuilder object. + /// An object that supplies culture-specific formatting information. + /// The interpolated string to append. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)")] + public static StringBuilder AppendLine( + StringBuilder target, + IFormatProvider? provider, + [InterpolatedStringHandlerArgument(nameof(target), nameof(provider))] ref AppendInterpolatedStringHandler handler) => + target.AppendLine(); +#elif NET6_0_OR_GREATER + /// Appends the specified interpolated string to this instance. + /// The interpolated string to append. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)")] + public static StringBuilder Append( + StringBuilder target, + [InterpolatedStringHandlerArgument(nameof(target))] ref StringBuilder.AppendInterpolatedStringHandler handler) => + target.Append(ref handler); + + /// Appends the specified interpolated string to this instance. + /// An object that supplies culture-specific formatting information. + /// The interpolated string to append. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)")] + public static StringBuilder Append( + StringBuilder target, + IFormatProvider? provider, + [InterpolatedStringHandlerArgument(nameof(target), nameof(provider))] ref StringBuilder.AppendInterpolatedStringHandler handler) => + target.Append(provider, ref handler); + + /// Appends the specified interpolated string followed by the default line terminator to the end of the current StringBuilder object. + /// The interpolated string to append. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)")] + public static StringBuilder AppendLine( + StringBuilder target, + [InterpolatedStringHandlerArgument(nameof(target))] ref StringBuilder.AppendInterpolatedStringHandler handler) => + target.AppendLine(ref handler); + + /// Appends the specified interpolated string followed by the default line terminator to the end of the current StringBuilder object. + /// An object that supplies culture-specific formatting information. + /// The interpolated string to append. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)")] + public static StringBuilder AppendLine( + StringBuilder target, + IFormatProvider? provider, + [InterpolatedStringHandlerArgument(nameof(target), nameof(provider))] ref StringBuilder.AppendInterpolatedStringHandler handler) => + target.AppendLine(provider, ref handler); +#endif +} \ No newline at end of file diff --git a/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs b/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs new file mode 100644 index 00000000..cc593eb7 --- /dev/null +++ b/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs @@ -0,0 +1,348 @@ +// + +#if HAS_SPAN && !NET6_0_OR_GREATER + +using System.ComponentModel; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +#nullable enable + +namespace System.Text; + +/// Provides a handler used by the language compiler to append interpolated strings into instances. +[EditorBrowsable(EditorBrowsableState.Never)] +[InterpolatedStringHandler] +#if PolyPublic +public +#endif +struct AppendInterpolatedStringHandler +{ + // Implementation note: + // As this type is only intended to be targeted by the compiler, public APIs eschew argument validation logic + // in a variety of places, e.g. allowing a null input when one isn't expected to produce a NullReferenceException rather + // than an ArgumentNullException. + + private const int StackallocCharBufferSizeLimit = 256; + + /// The associated StringBuilder to which to append. + private readonly StringBuilder _stringBuilder; + + /// Optional provider to pass to IFormattable.ToString or ISpanFormattable.TryFormat calls. + private readonly IFormatProvider? _provider; + + /// Whether provides an ICustomFormatter. + /// + /// Custom formatters are very rare. We want to support them, but it's ok if we make them more expensive + /// in order to make them as pay-for-play as possible. So, we avoid adding another reference type field + /// to reduce the size of the handler and to reduce required zero'ing, by only storing whether the provider + /// provides a formatter, rather than actually storing the formatter. This in turn means, if there is a + /// formatter, we pay for the extra interface call on each AppendFormatted that needs it. + /// + private readonly bool _hasCustomFormatter; + + /// Creates a handler used to append an interpolated string into a . + /// The number of constant characters outside of interpolation expressions in the interpolated string. + /// The number of interpolation expressions in the interpolated string. + /// The associated StringBuilder to which to append. + /// This is intended to be called only by compiler-generated code. Arguments are not validated as they'd otherwise be for members intended to be used directly. + public AppendInterpolatedStringHandler(int literalLength, int formattedCount, StringBuilder stringBuilder) + { + _stringBuilder = stringBuilder; + _provider = null; + _hasCustomFormatter = false; + } + + /// Creates a handler used to translate an interpolated string into a . + /// The number of constant characters outside of interpolation expressions in the interpolated string. + /// The number of interpolation expressions in the interpolated string. + /// The associated StringBuilder to which to append. + /// An object that supplies culture-specific formatting information. + /// This is intended to be called only by compiler-generated code. Arguments are not validated as they'd otherwise be for members intended to be used directly. + public AppendInterpolatedStringHandler(int literalLength, int formattedCount, StringBuilder stringBuilder, IFormatProvider? provider) + { + _stringBuilder = stringBuilder; + _provider = provider; + _hasCustomFormatter = provider is not null && DefaultInterpolatedStringHandler.HasCustomFormatter(provider); + } + + /// Writes the specified string to the handler. + /// The string to write. + public void AppendLiteral(string value) => _stringBuilder.Append(value); + + #region AppendFormatted + + // Design note: + // This provides the same set of overloads and semantics as DefaultInterpolatedStringHandler. + + #region AppendFormatted T + + /// Writes the specified value to the handler. + /// The value to write. + /// The type of the value to write. + public void AppendFormatted(T value) + { + // This method could delegate to AppendFormatted with a null format, but explicitly passing + // default as the format to TryFormat helps to improve code quality in some cases when TryFormat is inlined, + // e.g. for Int32 it enables the JIT to eliminate code in the inlined method based on a length check on the format. + + if (_hasCustomFormatter) + { + // If there's a custom formatter, always use it. + AppendCustomFormatter(value, format: null); + } + else if (value is IFormattable fValue) + { + // Check first for IFormattable, even though we'll prefer to use ISpanFormattable, as the latter + // requires the former. For value types, it won't matter as the type checks devolve into + // JIT-time constants. For reference types, they're more likely to implement IFormattable + // than they are to implement ISpanFormattable: if they don't implement either, we save an + // interface check over first checking for ISpanFormattable and then for IFormattable, and + // if it only implements IFormattable, we come out even: only if it implements both do we + // end up paying for an extra interface check. + + if (typeof(T).IsEnum || HasTryFormatExtension(typeof(T)) || fValue is ISpanFormattable) + { + // Formats into temporary space and then copies the result into the StringBuilder. + AppendFormattedWithTempSpace(value, 0, format: null); + } + else + { + // constrained call avoiding boxing for value types + _stringBuilder.Append(fValue.ToString(format: null, _provider)); + } + } + else if (value is not null) + { + _stringBuilder.Append(value.ToString()); + } + } + + /// Writes the specified value to the handler. + /// The value to write. + /// The format string. + /// The type of the value to write. + public void AppendFormatted(T value, string? format) + { + if (_hasCustomFormatter) + { + // If there's a custom formatter, always use it. + AppendCustomFormatter(value, format); + } + else if (value is IFormattable fValue) + { + // Check first for IFormattable, even though we'll prefer to use ISpanFormattable, as the latter + // requires the former. For value types, it won't matter as the type checks devolve into + // JIT-time constants. For reference types, they're more likely to implement IFormattable + // than they are to implement ISpanFormattable: if they don't implement either, we save an + // interface check over first checking for ISpanFormattable and then for IFormattable, and + // if it only implements IFormattable, we come out even: only if it implements both do we + // end up paying for an extra interface check. + + if (typeof(T).IsEnum || HasTryFormatExtension(typeof(T)) || fValue is ISpanFormattable) + { + // Formats into temporary space and then copies the result into the StringBuilder. + AppendFormattedWithTempSpace(value, 0, format); + } + else + { + // constrained call avoiding boxing for value types + _stringBuilder.Append(fValue.ToString(format, _provider)); + } + } + else if (value is not null) + { + _stringBuilder.Append(value.ToString()); + } + } + + /// Writes the specified value to the handler. + /// The value to write. + /// + /// 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. + /// + /// The type of the value to write. + public void AppendFormatted(T value, int alignment) => + AppendFormatted(value, alignment, format: null); + + /// Writes the specified value to the handler. + /// The value to write. + /// The format string. + /// + /// 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. + /// + /// The type of the value to write. + public void AppendFormatted(T value, int alignment, string? format) + { + if (alignment == 0) + { + // This overload is used as a fallback from several disambiguation overloads, so special-case 0. + AppendFormatted(value, format); + } + else if (alignment < 0) + { + // Left aligned: format into the handler, then append any additional padding required. + var start = _stringBuilder.Length; + AppendFormatted(value, format); + var paddingRequired = -alignment - (_stringBuilder.Length - start); + if (paddingRequired > 0) + { + _stringBuilder.Append(' ', paddingRequired); + } + } + else + { + // Right aligned: format into temporary space and then copy that into the handler, appropriately aligned. + AppendFormattedWithTempSpace(value, alignment, format); + } + } + + /// Formats into temporary space and then appends the result into the StringBuilder. + private void AppendFormattedWithTempSpace(T value, int alignment, string? format) + { + // It's expected that either there's not enough space in the current chunk to store this formatted value, + // or we have a non-0 alignment that could require padding inserted. So format into temporary space and + // then append that written span into the StringBuilder: StringBuilder.Append(span) is able to split the + // span across the current chunk and any additional chunks required. + + var handler = new DefaultInterpolatedStringHandler(0, 0, _provider, stackalloc char[StackallocCharBufferSizeLimit]); + handler.AppendFormatted(value, format); + AppendFormatted(handler.Text, alignment); + handler.Clear(); + } + + #endregion + + #region AppendFormatted ReadOnlySpan + + /// Writes the specified character span to the handler. + /// The span to write. + public void AppendFormatted(ReadOnlySpan value) => _stringBuilder.Append(value); + + /// Writes the specified string of chars to the handler. + /// The span to write. + /// + /// 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. + /// + /// The format string. + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) + { + if (alignment == 0) + { + _stringBuilder.Append(value); + } + else + { + var leftAlign = false; + if (alignment < 0) + { + leftAlign = true; + alignment = -alignment; + } + + var paddingRequired = alignment - value.Length; + if (paddingRequired <= 0) + { + _stringBuilder.Append(value); + } + else if (leftAlign) + { + _stringBuilder.Append(value); + _stringBuilder.Append(' ', paddingRequired); + } + else + { + _stringBuilder.Append(' ', paddingRequired); + _stringBuilder.Append(value); + } + } + } + + #endregion + + #region AppendFormatted string + + /// Writes the specified value to the handler. + /// The value to write. + public void AppendFormatted(string? value) + { + if (!_hasCustomFormatter) + { + _stringBuilder.Append(value); + } + else + { + AppendFormatted(value); + } + } + + /// Writes the specified value to the handler. + /// The value to write. + /// + /// 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. + /// + /// The format string. + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => + // Format is meaningless for strings and doesn't make sense for someone to specify. We have the overload + // simply to disambiguate between ROS and object, just in case someone does specify a format, as + // string is implicitly convertible to both. Just delegate to the T-based implementation. + AppendFormatted(value, alignment, format); + + #endregion + + #region AppendFormatted object + + /// Writes the specified value to the handler. + /// The value to write. + /// + /// 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. + /// + /// The format string. + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => + // This overload is expected to be used rarely, only if either a) something strongly typed as object is + // formatted with both an alignment and a format, or b) the compiler is unable to target type to T. It + // exists purely to help make cases from (b) compile. Just delegate to the T-based implementation. + AppendFormatted(value, alignment, format); + + #endregion + + #endregion + + /// Formats the value using the custom formatter from the provider. + /// The value to write. + /// The format string. + /// The type of the value to write. + [MethodImpl(MethodImplOptions.NoInlining)] + private void AppendCustomFormatter(T value, string? format) + { + // This case is very rare, but we need to handle it prior to the other checks in case + // a provider was used that supplied an ICustomFormatter which wanted to intercept the particular value. + // We do the cast here rather than in the ctor, even though this could be executed multiple times per + // formatting, to make the cast pay for play. + Debug.Assert(_hasCustomFormatter); + Debug.Assert(_provider != null); + + var formatter = (ICustomFormatter?)_provider!.GetFormat(typeof(ICustomFormatter)); + Debug.Assert(formatter != null, "An incorrectly written provider said it implemented ICustomFormatter, and then didn't"); + + if (formatter is not null) + { + _stringBuilder.Append(formatter.Format(format, value, _provider)); + } + } + + private static bool HasTryFormatExtension(Type type) + { + return type == typeof(int) || type == typeof(bool) || type == typeof(byte) || type == typeof(float) || + type == typeof(double) || type == typeof(DateTime) || type == typeof(DateTimeOffset) || + type == typeof(decimal) || type == typeof(long) || type == typeof(short) || type == typeof(ushort) || + type == typeof(uint) || type == typeof(ulong) || type == typeof(sbyte); + } +} + +#endif \ No newline at end of file diff --git a/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs b/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs new file mode 100644 index 00000000..e0fd9580 --- /dev/null +++ b/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs @@ -0,0 +1,814 @@ +// + +#if HAS_SPAN && !NET6_0_OR_GREATER + +using System; +using System.Buffers; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Runtime.CompilerServices; +using Link = System.ComponentModel.DescriptionAttribute; + +#nullable enable + +namespace System.Runtime.CompilerServices; + +/// Provides a handler used by the language compiler to process interpolated strings into instances. +[InterpolatedStringHandler] +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[Link("https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.defaultinterpolatedstringhandler")] +#if PolyPublic +public +#endif +ref struct DefaultInterpolatedStringHandler +{ + // Implementation note: + // As this type lives in CompilerServices and is only intended to be targeted by the compiler, + // public APIs eschew argument validation logic in a variety of places, e.g. allowing a null input + // when one isn't expected to produce a NullReferenceException rather than an ArgumentNullException. + + /// Expected average length of formatted data used for an individual interpolation expression result. + /// + /// This is inherited from string.Format, and could be changed based on further data. + /// string.Format actually uses `format.Length + args.Length * 8`, but format.Length + /// includes the format items themselves, e.g. "{0}", and since it's rare to have double-digit + /// numbers of items, we bump the 8 up to 11 to account for the three extra characters in "{d}", + /// since the compiler-provided base length won't include the equivalent character count. + /// + private const int GuessedLengthPerHole = 11; + /// Minimum size array to rent from the pool. + /// Same as stack-allocation size used today by string.Format. + private const int MinimumArrayPoolLength = 256; + + /// Maximum length allowed for a string. + /// Keep in sync with AllocateString in gchelpers.cpp. + private const int StringMaxLength = 0x3FFFFFDF; + + /// Optional provider to pass to IFormattable.ToString or ISpanFormattable.TryFormat calls. + private readonly IFormatProvider? _provider; + /// Array rented from the array pool and used to back . + private char[]? _arrayToReturnToPool; + /// The span to write into. + private Span _chars; + /// Position at which to write the next character. + private int _pos; + /// Whether provides an ICustomFormatter. + /// + /// Custom formatters are very rare. We want to support them, but it's ok if we make them more expensive + /// in order to make them as pay-for-play as possible. So, we avoid adding another reference type field + /// to reduce the size of the handler and to reduce required zero'ing, by only storing whether the provider + /// provides a formatter, rather than actually storing the formatter. This in turn means, if there is a + /// formatter, we pay for the extra interface call on each AppendFormatted that needs it. + /// + private readonly bool _hasCustomFormatter; + + /// Creates a handler used to translate an interpolated string into a . + /// The number of constant characters outside of interpolation expressions in the interpolated string. + /// The number of interpolation expressions in the interpolated string. + /// This is intended to be called only by compiler-generated code. Arguments are not validated as they'd otherwise be for members intended to be used directly. + public DefaultInterpolatedStringHandler(int literalLength, int formattedCount) + { + _provider = null; + _chars = _arrayToReturnToPool = ArrayPool.Shared.Rent(GetDefaultLength(literalLength, formattedCount)); + _pos = 0; + _hasCustomFormatter = false; + } + + /// Creates a handler used to translate an interpolated string into a . + /// The number of constant characters outside of interpolation expressions in the interpolated string. + /// The number of interpolation expressions in the interpolated string. + /// An object that supplies culture-specific formatting information. + /// This is intended to be called only by compiler-generated code. Arguments are not validated as they'd otherwise be for members intended to be used directly. + public DefaultInterpolatedStringHandler(int literalLength, int formattedCount, IFormatProvider? provider) + { + _provider = provider; + _chars = _arrayToReturnToPool = ArrayPool.Shared.Rent(GetDefaultLength(literalLength, formattedCount)); + _pos = 0; + _hasCustomFormatter = provider is not null && HasCustomFormatter(provider); + } + + /// Creates a handler used to translate an interpolated string into a . + /// The number of constant characters outside of interpolation expressions in the interpolated string. + /// The number of interpolation expressions in the interpolated string. + /// An object that supplies culture-specific formatting information. + /// A buffer temporarily transferred to the handler for use as part of its formatting. Contents may be overwritten. + /// This is intended to be called only by compiler-generated code. Arguments are not validated as they'd otherwise be for members intended to be used directly. + public DefaultInterpolatedStringHandler(int literalLength, int formattedCount, IFormatProvider? provider, Span initialBuffer) + { + _provider = provider; + _chars = initialBuffer; + _arrayToReturnToPool = null; + _pos = 0; + _hasCustomFormatter = provider is not null && HasCustomFormatter(provider); + } + + /// Derives a default length with which to seed the handler. + /// The number of constant characters outside of interpolation expressions in the interpolated string. + /// The number of interpolation expressions in the interpolated string. + [MethodImpl(MethodImplOptions.AggressiveInlining)] // becomes a constant when inputs are constant + internal static int GetDefaultLength(int literalLength, int formattedCount) => + Math.Max(MinimumArrayPoolLength, literalLength + formattedCount * GuessedLengthPerHole); + + /// Gets the built . + /// The built string. + public override string ToString() => Text.ToString(); + + /// Gets the built and clears the handler. + /// The built string. + /// + /// This releases any resources used by the handler. The method should be invoked only + /// once and as the last thing performed on the handler. Subsequent use is erroneous, ill-defined, + /// and may destabilize the process, as may using any other copies of the handler after ToStringAndClear + /// is called on any one of them. + /// + public string ToStringAndClear() + { + var result = Text.ToString(); + Clear(); + return result; + } + + /// Clears the handler, returning any rented array to the pool. + [MethodImpl(MethodImplOptions.AggressiveInlining)] // used only on a few hot paths + internal void Clear() + { + var toReturn = _arrayToReturnToPool; + this = default; // defensive clear + if (toReturn is not null) + { + ArrayPool.Shared.Return(toReturn); + } + } + + /// Gets a span of the written characters thus far. + internal ReadOnlySpan Text => _chars.Slice(0, _pos); + + /// Writes the specified string to the handler. + /// The string to write. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void AppendLiteral(string value) + { + if (value.TryCopyTo(_chars.Slice(_pos))) + { + _pos += value.Length; + } + else + { + GrowThenCopyString(value); + } + } + + #region AppendFormatted + // Design note: + // The compiler requires a AppendFormatted overload for anything that might be within an interpolation expression; + // if it can't find an appropriate overload, for handlers in general it'll simply fail to compile. + // (For target-typing to string where it uses DefaultInterpolatedStringHandler implicitly, it'll instead fall back to + // its other mechanisms, e.g. using string.Format. This fallback has the benefit that if we miss a case, + // interpolated strings will still work, but it has the downside that a developer generally won't know + // if the fallback is happening and they're paying more.) + // + // At a minimum, then, we would need an overload that accepts: + // (object value, int alignment = 0, string? format = null) + // Such an overload would provide the same expressiveness as string.Format. However, this has several + // shortcomings: + // - Every value type in an interpolation expression would be boxed. + // - ReadOnlySpan could not be used in interpolation expressions. + // - Every AppendFormatted call would have three arguments at the call site, bloating the IL further. + // - Every invocation would be more expensive, due to lack of specialization, every call needing to account + // for alignment and format, etc. + // + // To address that, we could just have overloads for T and ReadOnlySpan: + // (T) + // (T, int alignment) + // (T, string? format) + // (T, int alignment, string? format) + // (ReadOnlySpan) + // (ReadOnlySpan, int alignment) + // (ReadOnlySpan, string? format) + // (ReadOnlySpan, int alignment, string? format) + // but this also has shortcomings: + // - Some expressions that would have worked with an object overload will now force a fallback to string.Format + // (or fail to compile if the handler is used in places where the fallback isn't provided), because the compiler + // can't always target type to T, e.g. `b switch { true => 1, false => null }` where `b` is a bool can successfully + // be passed as an argument of type `object` but not of type `T`. + // - Reference types get no benefit from going through the generic code paths, and actually incur some overheads + // from doing so. + // - Nullable value types also pay a heavy price, in particular around interface checks that would generally evaporate + // at compile time for value types but don't (currently) if the Nullable goes through the same code paths + // (see https://github.com/dotnet/runtime/issues/50915). + // + // We could try to take a more elaborate approach for DefaultInterpolatedStringHandler, since it is the most common + // handler and we want to minimize overheads both at runtime and in IL size, e.g. have a complete set of overloads + // for each of: + // (T, ...) where T : struct + // (T?, ...) where T : struct + // (object, ...) + // (ReadOnlySpan, ...) + // (string, ...) + // but this also has shortcomings, most importantly: + // - If you have an unconstrained T that happens to be a value type, it'll now end up getting boxed to use the object + // overload. This also necessitates the T? overload, since nullable value types don't meet a T : struct constraint, + // so without those they'd all map to the object overloads as well. + // - Any reference type with an implicit cast to ROS will fail to compile due to ambiguities between the + // overloads. string is one such type, hence needing dedicated overloads for it that can be bound to more tightly. + // + // A middle ground we've settled on, which is likely to be the right approach for most other handlers as well, + // would be the set: + // (T, ...) with no constraint + // (ReadOnlySpan) and (ReadOnlySpan, int) + // (object, int alignment = 0, string? format = null) + // (string) and (string, int) + // This would address most of the concerns, at the expense of: + // - Most reference types going through the generic code paths and so being a bit more expensive. + // - Nullable types being more expensive until https://github.com/dotnet/runtime/issues/50915 is addressed. + // We could choose to add a T? where T : struct set of overloads if necessary. + // Strings don't require their own overloads here, but as they're expected to be very common and as we can + // optimize them in several ways (can copy the contents directly, don't need to do any interface checks, don't + // need to pay the shared generic overheads, etc.) we can add overloads specifically to optimize for them. + // + // Hole values are formatted according to the following policy: + // 1. If an IFormatProvider was supplied and it provides an ICustomFormatter, use ICustomFormatter.Format (even if + // the value is null). + // 2. If the type implements ISpanFormattable, use ISpanFormattable.TryFormat. + // 3. If the type implements IFormattable, use IFormattable.ToString. + // 4. Otherwise, use object.ToString. + // This matches the behavior of string.Format, StringBuilder.AppendFormat, etc. The only overloads for which this + // doesn't apply is ReadOnlySpan, which isn't supported by either string.Format nor StringBuilder.AppendFormat, + // but more importantly which can't be boxed to be passed to ICustomFormatter.Format. + + #region AppendFormatted T + /// Writes the specified value to the handler. + /// The value to write. + /// The type of the value to write. + public void AppendFormatted(T value) + { + // This method could delegate to AppendFormatted with a null format, but explicitly passing + // default as the format to TryFormat helps to improve code quality in some cases when TryFormat is inlined, + // e.g. for Int32 it enables the JIT to eliminate code in the inlined method based on a length check on the format. + + // If there's a custom formatter, always use it. + if (_hasCustomFormatter) + { + AppendCustomFormatter(value, format: null); + return; + } + + // Check first for IFormattable, even though we'll prefer to use ISpanFormattable, as the latter + // requires the former. For value types, it won't matter as the type checks devolve into + // JIT-time constants. For reference types, they're more likely to implement IFormattable + // than they are to implement ISpanFormattable: if they don't implement either, we save an + // interface check over first checking for ISpanFormattable and then for IFormattable, and + // if it only implements IFormattable, we come out even: only if it implements both do we + // end up paying for an extra interface check. + string? s; + if (value is IFormattable fValue) + { + // If the value can format itself directly into our buffer, do so. + + if (TryFormatWithExtensions(value, default)) + { + return; + } + else if (fValue is ISpanFormattable sfValue) + { + int charsWritten; + // constrained call avoiding boxing for value types + while (!sfValue.TryFormat(_chars.Slice(_pos), out charsWritten, default, _provider)) + { + Grow(); + } + + _pos += charsWritten; + return; + } + + s = fValue.ToString(format: null, _provider); // constrained call avoiding boxing for value types + } + else + { + s = value?.ToString(); + } + + if (s is not null) + { + AppendLiteral(s); + } + } + + /// Writes the specified value to the handler. + /// The value to write. + /// The format string. + /// The type of the value to write. + public void AppendFormatted(T value, string? format) + { + // If there's a custom formatter, always use it. + if (_hasCustomFormatter) + { + AppendCustomFormatter(value, format); + return; + } + + // Check first for IFormattable, even though we'll prefer to use ISpanFormattable, as the latter + // requires the former. For value types, it won't matter as the type checks devolve into + // JIT-time constants. For reference types, they're more likely to implement IFormattable + // than they are to implement ISpanFormattable: if they don't implement either, we save an + // interface check over first checking for ISpanFormattable and then for IFormattable, and + // if it only implements IFormattable, we come out even: only if it implements both do we + // end up paying for an extra interface check. + string? s; + if (value is IFormattable fValue) + { + // If the value can format itself directly into our buffer, do so. + + if (TryFormatWithExtensions(value, format.AsSpan())) + { + return; + } + else if (fValue is ISpanFormattable sfValue) + { + int charsWritten; + // constrained call avoiding boxing for value types + while (!sfValue.TryFormat(_chars.Slice(_pos), out charsWritten, format.AsSpan(), _provider)) + { + Grow(); + } + + _pos += charsWritten; + return; + } + + s = fValue.ToString(format, _provider); // constrained call avoiding boxing for value types + } + else + { + s = value?.ToString(); + } + + if (s is not null) + { + AppendLiteral(s); + } + } + + /// Writes the specified value to the handler. + /// The value to write. + /// + /// 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. + /// + /// The type of the value to write. + public void AppendFormatted(T value, int alignment) + { + var startingPos = _pos; + AppendFormatted(value); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + + /// Writes the specified value to the handler. + /// The value to write. + /// The format string. + /// + /// 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. + /// + /// The type of the value to write. + public void AppendFormatted(T value, int alignment, string? format) + { + var startingPos = _pos; + AppendFormatted(value, format); + if (alignment != 0) + { + AppendOrInsertAlignmentIfNeeded(startingPos, alignment); + } + } + #endregion + + #region AppendFormatted ReadOnlySpan + /// Writes the specified character span to the handler. + /// The span to write. + public void AppendFormatted(scoped ReadOnlySpan value) + { + // Fast path for when the value fits in the current buffer + if (value.TryCopyTo(_chars.Slice(_pos))) + { + _pos += value.Length; + } + else + { + GrowThenCopySpan(value); + } + } + + /// Writes the specified string of chars to the handler. + /// The span to write. + /// + /// 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. + /// + /// The format string. + public void AppendFormatted(scoped ReadOnlySpan value, int alignment = 0, string? format = null) + { + var leftAlign = false; + if (alignment < 0) + { + leftAlign = true; + alignment = -alignment; + } + + var paddingRequired = alignment - value.Length; + if (paddingRequired <= 0) + { + // The value is as large or larger than the required amount of padding, + // so just write the value. + AppendFormatted(value); + return; + } + + // Write the value along with the appropriate padding. + EnsureCapacityForAdditionalChars(value.Length + paddingRequired); + if (leftAlign) + { + value.CopyTo(_chars.Slice(_pos)); + _pos += value.Length; + _chars.Slice(_pos, paddingRequired).Fill(' '); + _pos += paddingRequired; + } + else + { + _chars.Slice(_pos, paddingRequired).Fill(' '); + _pos += paddingRequired; + value.CopyTo(_chars.Slice(_pos)); + _pos += value.Length; + } + } + #endregion + + #region AppendFormatted string + /// Writes the specified value to the handler. + /// The value to write. + public void AppendFormatted(string? value) + { + // Fast-path for no custom formatter and a non-null string that fits in the current destination buffer. + if (!_hasCustomFormatter && + value is not null && + value.TryCopyTo(_chars.Slice(_pos))) + { + _pos += value.Length; + } + else + { + AppendFormattedSlow(value); + } + } + + /// Writes the specified value to the handler. + /// The value to write. + /// + /// Slow path to handle a custom formatter, potentially null value, + /// or a string that doesn't fit in the current buffer. + /// + [MethodImpl(MethodImplOptions.NoInlining)] + private void AppendFormattedSlow(string? value) + { + if (_hasCustomFormatter) + { + AppendCustomFormatter(value, format: null); + } + else if (value is not null) + { + EnsureCapacityForAdditionalChars(value.Length); + value.CopyTo(_chars.Slice(_pos)); + _pos += value.Length; + } + } + + /// Writes the specified value to the handler. + /// The value to write. + /// + /// 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. + /// + /// The format string. + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => + // Format is meaningless for strings and doesn't make sense for someone to specify. We have the overload + // simply to disambiguate between ROS and object, just in case someone does specify a format, as + // string is implicitly convertible to both. Just delegate to the T-based implementation. + AppendFormatted(value, alignment, format); + #endregion + + #region AppendFormatted object + /// Writes the specified value to the handler. + /// The value to write. + /// + /// 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. + /// + /// The format string. + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => + // This overload is expected to be used rarely, only if either a) something strongly typed as object is + // formatted with both an alignment and a format, or b) the compiler is unable to target type to T. It + // exists purely to help make cases from (b) compile. Just delegate to the T-based implementation. + AppendFormatted(value, alignment, format); + #endregion + #endregion + + /// Gets whether the provider provides a custom formatter. + [MethodImpl(MethodImplOptions.AggressiveInlining)] // only used in a few hot path call sites + internal static bool HasCustomFormatter(IFormatProvider provider) + { + Debug.Assert(provider is not null); + Debug.Assert( + provider is not CultureInfo || provider.GetFormat(typeof(ICustomFormatter)) is null, + "Expected CultureInfo to not provide a custom formatter"); + + return + provider!.GetType() != typeof(CultureInfo) && // optimization to avoid GetFormat in the majority case + provider.GetFormat(typeof(ICustomFormatter)) != null; + } + + /// Formats the value using the custom formatter from the provider. + /// The value to write. + /// The format string. + /// The type of the value to write. + [MethodImpl(MethodImplOptions.NoInlining)] + private void AppendCustomFormatter(T value, string? format) + { + // This case is very rare, but we need to handle it prior to the other checks in case + // a provider was used that supplied an ICustomFormatter which wanted to intercept the particular value. + // We do the cast here rather than in the ctor, even though this could be executed multiple times per + // formatting, to make the cast pay for play. + Debug.Assert(_hasCustomFormatter); + Debug.Assert(_provider != null); + + var formatter = (ICustomFormatter?)_provider!.GetFormat(typeof(ICustomFormatter)); + Debug.Assert( + formatter != null, + "An incorrectly written provider said it implemented ICustomFormatter, and then didn't"); + + if (formatter?.Format(format, value, _provider) is { } customFormatted) + { + AppendLiteral(customFormatted); + } + } + + /// Handles adding any padding required for aligning a formatted value in an interpolation expression. + /// The position at which the written value started. + /// + /// Non-zero 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. + /// + private void AppendOrInsertAlignmentIfNeeded(int startingPos, int alignment) + { + Debug.Assert(startingPos >= 0 && startingPos <= _pos); + Debug.Assert(alignment != 0); + + var charsWritten = _pos - startingPos; + + var leftAlign = false; + if (alignment < 0) + { + leftAlign = true; + alignment = -alignment; + } + + var paddingNeeded = alignment - charsWritten; + if (paddingNeeded > 0) + { + EnsureCapacityForAdditionalChars(paddingNeeded); + + if (leftAlign) + { + _chars.Slice(_pos, paddingNeeded).Fill(' '); + } + else + { + _chars.Slice(startingPos, charsWritten).CopyTo(_chars.Slice(startingPos + paddingNeeded)); + _chars.Slice(startingPos, paddingNeeded).Fill(' '); + } + + _pos += paddingNeeded; + } + } + + /// + /// Ensures has the capacity to store beyond . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void EnsureCapacityForAdditionalChars(int additionalChars) + { + if (_chars.Length - _pos < additionalChars) + { + Grow(additionalChars); + } + } + + /// + /// Fallback for fast path in when there's not enough space in the destination. + /// + /// The string to write. + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowThenCopyString(string value) + { + Grow(value.Length); + value.CopyTo(_chars.Slice(_pos)); + _pos += value.Length; + } + + /// + /// Fallback for for when not enough space exists in the current buffer. + /// + /// The span to write. + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowThenCopySpan(scoped ReadOnlySpan value) + { + Grow(value.Length); + value.CopyTo(_chars.Slice(_pos)); + _pos += value.Length; + } + + /// + /// Grows to have the capacity to store at least + /// beyond . + /// + [MethodImpl(MethodImplOptions.NoInlining)] // keep consumers as streamlined as possible + private void Grow(int additionalChars) + { + // This method is called when the remaining space (_chars.Length - _pos) is + // insufficient to store a specific number of additional characters. Thus, we + // need to grow to at least that new total. GrowCore will handle growing by more + // than that if possible. + Debug.Assert(additionalChars > _chars.Length - _pos); + GrowCore((uint)_pos + (uint)additionalChars); + } + + /// Grows the size of . + [MethodImpl(MethodImplOptions.NoInlining)] // keep consumers as streamlined as possible + private void Grow() => + // This method is called when the remaining space in _chars isn't sufficient to continue + // the operation. Thus, we need at least one character beyond _chars.Length. GrowCore + // will handle growing by more than that if possible. + GrowCore((uint)_chars.Length + 1); + + /// + /// Grow the size of to at least the specified . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] // but reuse this grow logic directly in both of the above grow routines + private void GrowCore(uint requiredMinCapacity) + { + // We want the max of how much space we actually required and doubling our capacity (without going beyond + // the max allowed length). We also want to avoid asking for small arrays, to reduce the number of times we + // need to grow, and since we're working with unsigned ints that could technically overflow if someone tried + // to, for example, append a huge string to a huge string, we also clamp to int.MaxValue. + // Even if the array creation fails in such a case, we may later fail in ToStringAndClear. + + var newCapacity = Math.Max(requiredMinCapacity, Math.Min((uint)_chars.Length * 2, StringMaxLength)); + var arraySize = (int)InternalMath.Clamp(newCapacity, MinimumArrayPoolLength, int.MaxValue); + + var newArray = ArrayPool.Shared.Rent(arraySize); + _chars.Slice(0, _pos).CopyTo(newArray); + + var toReturn = _arrayToReturnToPool; + _chars = _arrayToReturnToPool = newArray; + + if (toReturn is not null) + { + ArrayPool.Shared.Return(toReturn); + } + } + + private bool TryFormatWithExtensions(T value, ReadOnlySpan format) + { + int charsWritten; + switch (value) + { + case int cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider)) + { + Grow(); + } + break; + case bool cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten)) + { + Grow(); + } + break; + case byte cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider)) + { + Grow(); + } + break; + case float cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider)) + { + Grow(); + } + break; + case double cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider)) + { + Grow(); + } + break; + case DateTime cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider)) + { + Grow(); + } + break; + case DateTimeOffset cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider)) + { + Grow(); + } + break; + case decimal cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider)) + { + Grow(); + } + break; + case long cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider)) + { + Grow(); + } + break; + case short cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider)) + { + Grow(); + } + break; + case ushort cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider)) + { + Grow(); + } + break; + case uint cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider)) + { + Grow(); + } + break; + case ulong cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider)) + { + Grow(); + } + break; + case sbyte cval: + while (!cval.TryFormat(_chars.Slice(_pos), out charsWritten, format, _provider)) + { + Grow(); + } + break; + default: + return false; + } + + _pos += charsWritten; + return true; + } +} + +static file class InternalMath +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint Clamp(uint value, uint min, uint max) + { + if (min > max) + { + ThrowMinMaxException(min, max); + } + + if (value < min) + { + return min; + } + else if (value > max) + { + return max; + } + + return value; + } + + [DoesNotReturn] + private static void ThrowMinMaxException(T min, T max) => + throw new ArgumentException(string.Format(SR.Argument_MinMaxValue, min, max)); +} + +static file class SR +{ + public const string Argument_MinMaxValue = "'{0}' cannot be greater than {1}."; +} + +#endif \ No newline at end of file diff --git a/src/Polyfill/StringInterpolation/ISpanFormattable.cs b/src/Polyfill/StringInterpolation/ISpanFormattable.cs new file mode 100644 index 00000000..329c3c39 --- /dev/null +++ b/src/Polyfill/StringInterpolation/ISpanFormattable.cs @@ -0,0 +1,32 @@ +// + +#if HAS_SPAN && !NET6_0_OR_GREATER + +using Link = System.ComponentModel.DescriptionAttribute; + +#nullable enable + +namespace System; + +/// Provides functionality to format the string representation of an object into a span. +[Link("https://learn.microsoft.com/en-us/dotnet/api/system.ispanformattable")] +#if PolyPublic +public +#endif +interface ISpanFormattable : IFormattable +{ + /// Tries to format the value of the current instance into the provided span of characters. + /// When this method returns, this instance's value formatted as a span of characters. + /// When this method returns, the number of characters that were written in . + /// A span containing the characters that represent a standard or custom format string that defines the acceptable format for . + /// An optional object that supplies culture-specific formatting information for . + /// if the formatting was successful; otherwise, . + /// + /// An implementation of this interface should produce the same string of characters as an implementation of + /// on the same type. + /// TryFormat should return false only if there is not enough space in the destination buffer. Any other failures should throw an exception. + /// + bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan format, IFormatProvider? provider); +} + +#endif \ No newline at end of file diff --git a/src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs b/src/Polyfill/StringInterpolation/InterpolatedStringHandlerArgumentAttribute.cs similarity index 100% rename from src/Polyfill/InterpolatedStringHandlerArgumentAttribute.cs rename to src/Polyfill/StringInterpolation/InterpolatedStringHandlerArgumentAttribute.cs diff --git a/src/Polyfill/InterpolatedStringHandlerAttribute.cs b/src/Polyfill/StringInterpolation/InterpolatedStringHandlerAttribute.cs similarity index 100% rename from src/Polyfill/InterpolatedStringHandlerAttribute.cs rename to src/Polyfill/StringInterpolation/InterpolatedStringHandlerAttribute.cs diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 95e2b340..98325892 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -17,6 +17,9 @@ Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs diff --git a/src/Tests/SanityChecks.cs b/src/Tests/SanityChecks.cs index 9bc98c87..4bc222a2 100644 --- a/src/Tests/SanityChecks.cs +++ b/src/Tests/SanityChecks.cs @@ -35,7 +35,9 @@ public void Attributes() name == "NullableAttribute" || name == "NullableContextAttribute" || name == "IsReadOnlyAttribute" || - name == "RefSafetyRulesAttribute") + name == "RefSafetyRulesAttribute" || + name == "ScopedRefAttribute" || + name == "IsByRefLikeAttribute") { continue; } diff --git a/src/Tests/StringInterpolationTests.cs b/src/Tests/StringInterpolationTests.cs new file mode 100644 index 00000000..fb4b21d4 --- /dev/null +++ b/src/Tests/StringInterpolationTests.cs @@ -0,0 +1,28 @@ +#if HAS_SPAN + +[TestFixture] +public class StringInterpolationTests +{ + [Test] + public void ShouldInterpolateString() + { + Span buffer = stackalloc char[] { 'H', 'e', 'l', 'l', 'o' }; + var number = 15; + var result = $"{buffer}, you're {number} years old"; + + Assert.AreEqual("Hello, you're 15 years old", result); + } + + [Test] + public void ShouldInterpolateStringBuilder() + { + var sb = new StringBuilder(); + Span buffer = stackalloc char[] { 'H', 'e', 'l', 'l', 'o' }; + var number = 15; + PolyfillExtensions.Append(sb, $"{buffer}, you're {number} years old {sb.ToString()}"); + var result = sb.ToString(); + + Assert.AreEqual("Hello, you're 15 years old Hello, you're 15 years old ", result); + } +} +#endif \ No newline at end of file diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 55bdd613..44f8bcad 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -16,6 +16,9 @@ Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 28f325ce..9b38c707 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -17,6 +17,9 @@ Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs From eb23c57d510febb4a9cdb77de6271a13b3539b42 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 14 Dec 2023 11:05:43 +1100 Subject: [PATCH 255/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 55129f16..df85c178 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.33.2 + 1.34.0 1.0.0 Polyfill true From 87df636e272428dd4f73030060a45c30bc173c12 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 14 Dec 2023 15:57:14 +1100 Subject: [PATCH 256/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/Polyfill/Polyfill.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Shared.sln.DotSettings | 1 + src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 88354bbf..eeec6d0c 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -35,7 +35,7 @@ - + \ No newline at end of file diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index 913f4940..c0392a82 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 98325892..80b60e7d 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -30,7 +30,7 @@ - + diff --git a/src/Shared.sln.DotSettings b/src/Shared.sln.DotSettings index b0a1a6f3..93612561 100644 --- a/src/Shared.sln.DotSettings +++ b/src/Shared.sln.DotSettings @@ -27,6 +27,7 @@ ERROR ERROR ERROR + ERROR ERROR ERROR ERROR diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 44f8bcad..62d6b20b 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -30,7 +30,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 9b38c707..9e4b65d9 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -30,7 +30,7 @@ - + From 6de2cd037ead8d6d41bf43f001806b84267d42be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 18:28:40 +1100 Subject: [PATCH 257/313] Bump ProjectDefaults from 1.0.107 to 1.0.108 in /src (#117) Bumps [ProjectDefaults](https://github.com/SimonCropp/ProjectDefaults) from 1.0.107 to 1.0.108. - [Commits](https://github.com/SimonCropp/ProjectDefaults/commits) --- updated-dependencies: - dependency-name: ProjectDefaults dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- src/Polyfill/Polyfill.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index c0392a82..a6bdf8dd 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + From f7203365cef5413aeb3275baec3eb0a0f1fb3e63 Mon Sep 17 00:00:00 2001 From: OwnageIsMagic Date: Wed, 27 Dec 2023 16:09:55 +0300 Subject: [PATCH 258/313] Add alternative package (#119) --- readme.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index dbd8ec89..1f91ed72 100644 --- a/readme.md +++ b/readme.md @@ -732,12 +732,15 @@ public void Test() ## Alternatives +### Theraot.Core + +Backports package aimed to full modern .NET API coverage for legacy TFMs. +https://github.com/theraot/Theraot ### PolySharp https://github.com/Sergio0694/PolySharp - ### Combination of * https://github.com/manuelroemer/Nullable From 5b4d08ebdac006e5812d8f067642a9602fe5139e Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 31 Dec 2023 10:37:23 +1100 Subject: [PATCH 259/313] Update readme.md --- readme.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 1f91ed72..c023185b 100644 --- a/readme.md +++ b/readme.md @@ -732,15 +732,22 @@ public void Test() ## Alternatives -### Theraot.Core -Backports package aimed to full modern .NET API coverage for legacy TFMs. -https://github.com/theraot/Theraot +### PolyShim + +https://github.com/Tyrrrz/PolyShim + ### PolySharp https://github.com/Sergio0694/PolySharp + +### Theraot.Core + +https://github.com/theraot/Theraot + + ### Combination of * https://github.com/manuelroemer/Nullable From a00dc388a7da70195d0817a180f35db7cdf2e381 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 3 Jan 2024 10:03:43 +1100 Subject: [PATCH 260/313] Update BuildApiTest.cs --- src/Tests/BuildApiTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index 01ba2538..2ee25342 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -3,7 +3,7 @@ class BuildApiTest { static string[] namespacesToClean = - { + [ "System.Diagnostics.", "System.Collections.Generic.", "System.Threading.Tasks.", @@ -12,7 +12,7 @@ class BuildApiTest "System.Text.", "System.IO.", "System." - }; + ]; [Test] public void Run() From cb526280b7e92fce757ab78910b12a0464136bf8 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 7 Jan 2024 19:34:46 +1100 Subject: [PATCH 261/313] Update PolyfillExtensionsTests_StringBuilder.cs --- .../PolyfillExtensionsTests_StringBuilder.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Tests/PolyfillExtensionsTests_StringBuilder.cs b/src/Tests/PolyfillExtensionsTests_StringBuilder.cs index f0344114..6af79769 100644 --- a/src/Tests/PolyfillExtensionsTests_StringBuilder.cs +++ b/src/Tests/PolyfillExtensionsTests_StringBuilder.cs @@ -23,4 +23,24 @@ public void StringBuilderCopyTo() builder.CopyTo(0, span, 5); Assert.True(span.SequenceEqual("value")); } + + [Test] + public void Append() + { + var builder = new StringBuilder(); + + var x = 10; + PolyfillExtensions.Append(builder, $"value{x}"); + Assert.AreEqual("value10", builder.ToString()); + } + + [Test] + public void AppendWithFormat() + { + var builder = new StringBuilder(); + + var x = 10; + PolyfillExtensions.Append(builder, null, $"value{x}"); + Assert.AreEqual("value10", builder.ToString()); + } } \ No newline at end of file From 3b11ce5dda630eed4c97159ea095035e01ed3bc7 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 7 Jan 2024 19:37:59 +1100 Subject: [PATCH 262/313] Update readme.md --- readme.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index c023185b..15bd2ddf 100644 --- a/readme.md +++ b/readme.md @@ -350,6 +350,10 @@ Reference: [Improvements in native code interop in .NET 5.0](https://devblogs.mi The class `PolyfillExtensions` includes the following extension methods: +> [!IMPORTANT] +> The methods using `AppendInterpolatedStringHandler` parameter are not extensions because the compiler prefers to use the overload with `string` parameter instead. + + ### Boolean * `Boolean TryFormat(Span, Int32&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat) @@ -568,8 +572,6 @@ The class `PolyfillExtensions` includes the following extension methods: * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) -> [!IMPORTANT] -> The methods using `AppendInterpolatedStringHandler` parameter are not extensions because the compiler prefers to use the overload with `string` parameter instead. ### CancellationToken From 18a8a7016613448d0c678d41935f3c098eb4c328 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 7 Jan 2024 19:43:31 +1100 Subject: [PATCH 263/313] cleanup --- src/NoRefsTests/NoRefsTests.csproj | 3 ++- src/Tests/{PolyfillExtensionsTests.cs => PolyfillTests.cs} | 2 +- ...CancellationToken.cs => PolyfillTests_CancellationToken.cs} | 2 +- ...TokenSource.cs => PolyfillTests_CancellationTokenSource.cs} | 2 +- ...tensionsTests_Dictionary.cs => PolyfillTests_Dictionary.cs} | 2 +- ...tensionsTests_HttpClient.cs => PolyfillTests_HttpClient.cs} | 2 +- ...nsionsTests_IEnumerable.cs => PolyfillTests_IEnumerable.cs} | 2 +- ...dOnlyDictionary.cs => PolyfillTests_IReadOnlyDictionary.cs} | 2 +- ...lyfillExtensionsTests_Memory.cs => PolyfillTests_Memory.cs} | 2 +- ...sts_MicroNanosecond.cs => PolyfillTests_MicroNanosecond.cs} | 2 +- ...fillExtensionsTests_Process.cs => PolyfillTests_Process.cs} | 2 +- ...lyfillExtensionsTests_Stream.cs => PolyfillTests_Stream.cs} | 2 +- ...ionsTests_StreamReader.cs => PolyfillTests_StreamReader.cs} | 2 +- ...lyfillExtensionsTests_String.cs => PolyfillTests_String.cs} | 2 +- ...nsTests_StringBuilder.cs => PolyfillTests_StringBuilder.cs} | 2 +- .../{PolyfillExtensionsTests_Task.cs => PolyfillTests_Task.cs} | 2 +- ...tensionsTests_TextWriter.cs => PolyfillTests_TextWriter.cs} | 2 +- ...ExtensionsTests_TryFormat.cs => PolyfillTests_TryFormat.cs} | 2 +- 18 files changed, 19 insertions(+), 18 deletions(-) rename src/Tests/{PolyfillExtensionsTests.cs => PolyfillTests.cs} (68%) rename src/Tests/{PolyfillExtensionsTests_CancellationToken.cs => PolyfillTests_CancellationToken.cs} (98%) rename src/Tests/{PolyfillExtensionsTests_CancellationTokenSource.cs => PolyfillTests_CancellationTokenSource.cs} (98%) rename src/Tests/{PolyfillExtensionsTests_Dictionary.cs => PolyfillTests_Dictionary.cs} (95%) rename src/Tests/{PolyfillExtensionsTests_HttpClient.cs => PolyfillTests_HttpClient.cs} (98%) rename src/Tests/{PolyfillExtensionsTests_IEnumerable.cs => PolyfillTests_IEnumerable.cs} (98%) rename src/Tests/{PolyfillExtensionsTests_IReadOnlyDictionary.cs => PolyfillTests_IReadOnlyDictionary.cs} (91%) rename src/Tests/{PolyfillExtensionsTests_Memory.cs => PolyfillTests_Memory.cs} (99%) rename src/Tests/{PolyfillExtensionsTests_MicroNanosecond.cs => PolyfillTests_MicroNanosecond.cs} (97%) rename src/Tests/{PolyfillExtensionsTests_Process.cs => PolyfillTests_Process.cs} (95%) rename src/Tests/{PolyfillExtensionsTests_Stream.cs => PolyfillTests_Stream.cs} (90%) rename src/Tests/{PolyfillExtensionsTests_StreamReader.cs => PolyfillTests_StreamReader.cs} (94%) rename src/Tests/{PolyfillExtensionsTests_String.cs => PolyfillTests_String.cs} (97%) rename src/Tests/{PolyfillExtensionsTests_StringBuilder.cs => PolyfillTests_StringBuilder.cs} (96%) rename src/Tests/{PolyfillExtensionsTests_Task.cs => PolyfillTests_Task.cs} (99%) rename src/Tests/{PolyfillExtensionsTests_TextWriter.cs => PolyfillTests_TextWriter.cs} (98%) rename src/Tests/{PolyfillExtensionsTests_TryFormat.cs => PolyfillTests_TryFormat.cs} (99%) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index eeec6d0c..51a09736 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -31,7 +31,8 @@ - + + diff --git a/src/Tests/PolyfillExtensionsTests.cs b/src/Tests/PolyfillTests.cs similarity index 68% rename from src/Tests/PolyfillExtensionsTests.cs rename to src/Tests/PolyfillTests.cs index 78d8148a..ab0ace44 100644 --- a/src/Tests/PolyfillExtensionsTests.cs +++ b/src/Tests/PolyfillTests.cs @@ -2,4 +2,4 @@ [TestFixture] [DebuggerNonUserCode] -partial class PolyfillExtensionsTests; +partial class PolyfillTests; diff --git a/src/Tests/PolyfillExtensionsTests_CancellationToken.cs b/src/Tests/PolyfillTests_CancellationToken.cs similarity index 98% rename from src/Tests/PolyfillExtensionsTests_CancellationToken.cs rename to src/Tests/PolyfillTests_CancellationToken.cs index 974d6acd..d82880d3 100644 --- a/src/Tests/PolyfillExtensionsTests_CancellationToken.cs +++ b/src/Tests/PolyfillTests_CancellationToken.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsTests +partial class PolyfillTests { [Test] public void CancellationToken_Register_Exceptions() diff --git a/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs b/src/Tests/PolyfillTests_CancellationTokenSource.cs similarity index 98% rename from src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs rename to src/Tests/PolyfillTests_CancellationTokenSource.cs index 8c455fc7..e2e8884e 100644 --- a/src/Tests/PolyfillExtensionsTests_CancellationTokenSource.cs +++ b/src/Tests/PolyfillTests_CancellationTokenSource.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsTests +partial class PolyfillTests { private static bool IsCompletedSuccessfully(Task task) { diff --git a/src/Tests/PolyfillExtensionsTests_Dictionary.cs b/src/Tests/PolyfillTests_Dictionary.cs similarity index 95% rename from src/Tests/PolyfillExtensionsTests_Dictionary.cs rename to src/Tests/PolyfillTests_Dictionary.cs index 6df1930d..118802d7 100644 --- a/src/Tests/PolyfillExtensionsTests_Dictionary.cs +++ b/src/Tests/PolyfillTests_Dictionary.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsTests +partial class PolyfillTests { [Test] public void Dictionary_Remove() diff --git a/src/Tests/PolyfillExtensionsTests_HttpClient.cs b/src/Tests/PolyfillTests_HttpClient.cs similarity index 98% rename from src/Tests/PolyfillExtensionsTests_HttpClient.cs rename to src/Tests/PolyfillTests_HttpClient.cs index 7e7816b7..2a13c77a 100644 --- a/src/Tests/PolyfillExtensionsTests_HttpClient.cs +++ b/src/Tests/PolyfillTests_HttpClient.cs @@ -3,7 +3,7 @@ using System.Net; using System.Net.Http; -partial class PolyfillExtensionsTests +partial class PolyfillTests { class FakeHttpMessageHandler : HttpMessageHandler { diff --git a/src/Tests/PolyfillExtensionsTests_IEnumerable.cs b/src/Tests/PolyfillTests_IEnumerable.cs similarity index 98% rename from src/Tests/PolyfillExtensionsTests_IEnumerable.cs rename to src/Tests/PolyfillTests_IEnumerable.cs index 73f8c82f..cbeb15ec 100644 --- a/src/Tests/PolyfillExtensionsTests_IEnumerable.cs +++ b/src/Tests/PolyfillTests_IEnumerable.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsTests +partial class PolyfillTests { [Test] public void MaxBy() diff --git a/src/Tests/PolyfillExtensionsTests_IReadOnlyDictionary.cs b/src/Tests/PolyfillTests_IReadOnlyDictionary.cs similarity index 91% rename from src/Tests/PolyfillExtensionsTests_IReadOnlyDictionary.cs rename to src/Tests/PolyfillTests_IReadOnlyDictionary.cs index 4c52bf96..02323aa2 100644 --- a/src/Tests/PolyfillExtensionsTests_IReadOnlyDictionary.cs +++ b/src/Tests/PolyfillTests_IReadOnlyDictionary.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsTests +partial class PolyfillTests { [Test] public void IReadOnlyDictionaryGetValueOrDefault() diff --git a/src/Tests/PolyfillExtensionsTests_Memory.cs b/src/Tests/PolyfillTests_Memory.cs similarity index 99% rename from src/Tests/PolyfillExtensionsTests_Memory.cs rename to src/Tests/PolyfillTests_Memory.cs index 9a9f5d72..ef5fca80 100644 --- a/src/Tests/PolyfillExtensionsTests_Memory.cs +++ b/src/Tests/PolyfillTests_Memory.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsTests +partial class PolyfillTests { [Test] public void ReadOnlySpan_ZeroLengthContains() diff --git a/src/Tests/PolyfillExtensionsTests_MicroNanosecond.cs b/src/Tests/PolyfillTests_MicroNanosecond.cs similarity index 97% rename from src/Tests/PolyfillExtensionsTests_MicroNanosecond.cs rename to src/Tests/PolyfillTests_MicroNanosecond.cs index 0818e56d..8c4af238 100644 --- a/src/Tests/PolyfillExtensionsTests_MicroNanosecond.cs +++ b/src/Tests/PolyfillTests_MicroNanosecond.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsTests +partial class PolyfillTests { static DateTimeOffset dateTimeOffset = DateTimeOffset.Now; static DateTime dateTime = DateTime.Now; diff --git a/src/Tests/PolyfillExtensionsTests_Process.cs b/src/Tests/PolyfillTests_Process.cs similarity index 95% rename from src/Tests/PolyfillExtensionsTests_Process.cs rename to src/Tests/PolyfillTests_Process.cs index ed50c547..026e2f90 100644 --- a/src/Tests/PolyfillExtensionsTests_Process.cs +++ b/src/Tests/PolyfillTests_Process.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsTests +partial class PolyfillTests { [Test, RequiresThread] [TestCase(0)] // poll diff --git a/src/Tests/PolyfillExtensionsTests_Stream.cs b/src/Tests/PolyfillTests_Stream.cs similarity index 90% rename from src/Tests/PolyfillExtensionsTests_Stream.cs rename to src/Tests/PolyfillTests_Stream.cs index e0fc417b..5450ec50 100644 --- a/src/Tests/PolyfillExtensionsTests_Stream.cs +++ b/src/Tests/PolyfillTests_Stream.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsTests +partial class PolyfillTests { [Test] public async Task StreamReadAsyncMemory() diff --git a/src/Tests/PolyfillExtensionsTests_StreamReader.cs b/src/Tests/PolyfillTests_StreamReader.cs similarity index 94% rename from src/Tests/PolyfillExtensionsTests_StreamReader.cs rename to src/Tests/PolyfillTests_StreamReader.cs index ca9c0b57..9d483420 100644 --- a/src/Tests/PolyfillExtensionsTests_StreamReader.cs +++ b/src/Tests/PolyfillTests_StreamReader.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsTests +partial class PolyfillTests { [Test] public async Task StreamReaderReadAsync() diff --git a/src/Tests/PolyfillExtensionsTests_String.cs b/src/Tests/PolyfillTests_String.cs similarity index 97% rename from src/Tests/PolyfillExtensionsTests_String.cs rename to src/Tests/PolyfillTests_String.cs index 9546d05f..df100f1a 100644 --- a/src/Tests/PolyfillExtensionsTests_String.cs +++ b/src/Tests/PolyfillTests_String.cs @@ -1,6 +1,6 @@ // ReSharper disable PartialTypeWithSinglePart -partial class PolyfillExtensionsTests +partial class PolyfillTests { [Test] public void GetHashCodeStringComparison() diff --git a/src/Tests/PolyfillExtensionsTests_StringBuilder.cs b/src/Tests/PolyfillTests_StringBuilder.cs similarity index 96% rename from src/Tests/PolyfillExtensionsTests_StringBuilder.cs rename to src/Tests/PolyfillTests_StringBuilder.cs index 6af79769..7369e929 100644 --- a/src/Tests/PolyfillExtensionsTests_StringBuilder.cs +++ b/src/Tests/PolyfillTests_StringBuilder.cs @@ -1,6 +1,6 @@ // ReSharper disable PartialTypeWithSinglePart -partial class PolyfillExtensionsTests +partial class PolyfillTests { [Test] public void StringBuilderCopyTo() diff --git a/src/Tests/PolyfillExtensionsTests_Task.cs b/src/Tests/PolyfillTests_Task.cs similarity index 99% rename from src/Tests/PolyfillExtensionsTests_Task.cs rename to src/Tests/PolyfillTests_Task.cs index 01bfd458..fc888fff 100644 --- a/src/Tests/PolyfillExtensionsTests_Task.cs +++ b/src/Tests/PolyfillTests_Task.cs @@ -1,6 +1,6 @@ // ReSharper disable ArrangeObjectCreationWhenTypeNotEvident // ReSharper disable MethodSupportsCancellation -partial class PolyfillExtensionsTests +partial class PolyfillTests { static T? AssertThrowsAsync(string expectedParamName, AsyncTestDelegate action) where T : ArgumentException diff --git a/src/Tests/PolyfillExtensionsTests_TextWriter.cs b/src/Tests/PolyfillTests_TextWriter.cs similarity index 98% rename from src/Tests/PolyfillExtensionsTests_TextWriter.cs rename to src/Tests/PolyfillTests_TextWriter.cs index 9a5e2f60..2df80b79 100644 --- a/src/Tests/PolyfillExtensionsTests_TextWriter.cs +++ b/src/Tests/PolyfillTests_TextWriter.cs @@ -1,4 +1,4 @@ -partial class PolyfillExtensionsTests +partial class PolyfillTests { [Test] public async Task TextWriterWriteSpan() diff --git a/src/Tests/PolyfillExtensionsTests_TryFormat.cs b/src/Tests/PolyfillTests_TryFormat.cs similarity index 99% rename from src/Tests/PolyfillExtensionsTests_TryFormat.cs rename to src/Tests/PolyfillTests_TryFormat.cs index df2e6bf0..925c492c 100644 --- a/src/Tests/PolyfillExtensionsTests_TryFormat.cs +++ b/src/Tests/PolyfillTests_TryFormat.cs @@ -1,6 +1,6 @@ using System.Globalization; -partial class PolyfillExtensionsTests +partial class PolyfillTests { [Test] public void TryFormatSByte() From 67d1375371dd978be817b3fc29fff4973d074858 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 7 Jan 2024 20:00:47 +1100 Subject: [PATCH 264/313] Update contributing.md --- contributing.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contributing.md b/contributing.md index 81764fe7..d1602130 100644 --- a/contributing.md +++ b/contributing.md @@ -312,9 +312,9 @@ static partial class PolyfillExtensions Add a for the new API to the Tests project. -Extension method tests to `PolyfillExtensionsTests_TYPE.cs` where `TYPE` is the type the method extending. So, for example, APIs that target `StreamWriter` go in `PolyfillExtensionsTests_StreamWriter.cs`. For example: +Extension method tests to `PolyfillTests_TYPE.cs` where `TYPE` is the type the method extending. So, for example, APIs that target `StreamWriter` go in `PolyfillExtensionsTests_StreamWriter.cs`. For example: - + ```cs partial class PolyfillExtensionsTests From ec41db070dccbb09e1df0c868ba5042f6800dee1 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 7 Jan 2024 20:17:12 +1100 Subject: [PATCH 265/313] Update contributing.md --- contributing.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contributing.md b/contributing.md index d1602130..b0cd689a 100644 --- a/contributing.md +++ b/contributing.md @@ -315,9 +315,9 @@ Add a for the new API to the Tests project. Extension method tests to `PolyfillTests_TYPE.cs` where `TYPE` is the type the method extending. So, for example, APIs that target `StreamWriter` go in `PolyfillExtensionsTests_StreamWriter.cs`. For example: - + ```cs -partial class PolyfillExtensionsTests +partial class PolyfillTests { [Test] public async Task StreamReaderReadAsync() @@ -341,7 +341,7 @@ partial class PolyfillExtensionsTests } } ``` -snippet source | anchor +snippet source | anchor From 759f3402e1d35a243affca724c13c9fa08b73423 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 7 Jan 2024 20:32:30 +1100 Subject: [PATCH 266/313] rename PolyfillExtensions to Polyfill (#120) --- contributing.md | 12 ++++++------ readme.md | 2 +- src/Directory.Build.props | 2 +- .../Nullability/NullabilityInfoExtensions.cs | 2 +- src/Polyfill/{PolyfillExtensions.cs => Polyfill.cs} | 2 +- ...llationToken.cs => Polyfill_CancellationToken.cs} | 2 +- ...Source.cs => Polyfill_CancellationTokenSource.cs} | 2 +- ...tensions_Dictionary.cs => Polyfill_Dictionary.cs} | 2 +- ...tensions_HttpClient.cs => Polyfill_HttpClient.cs} | 2 +- ...nsions_HttpContent.cs => Polyfill_HttpContent.cs} | 2 +- ...nsions_IEnumerable.cs => Polyfill_IEnumerable.cs} | 2 +- ...Dictionary.cs => Polyfill_IReadOnlyDictionary.cs} | 2 +- ...ions_KeyValuePair.cs => Polyfill_KeyValuePair.cs} | 2 +- ...lyfillExtensions_Memory.cs => Polyfill_Memory.cs} | 2 +- ...icroNanosecond.cs => Polyfill_MicroNanosecond.cs} | 2 +- ...nosecondAdd.cs => Polyfill_MicroNanosecondAdd.cs} | 2 +- ...fillExtensions_Process.cs => Polyfill_Process.cs} | 2 +- ...lyfillExtensions_Stream.cs => Polyfill_Stream.cs} | 2 +- ...lyfillExtensions_String.cs => Polyfill_String.cs} | 2 +- ...ns_StringBuilder.cs => Polyfill_StringBuilder.cs} | 2 +- .../{PolyfillExtensions_Task.cs => Polyfill_Task.cs} | 2 +- ...tensions_TextReader.cs => Polyfill_TextReader.cs} | 2 +- ...tensions_TextWriter.cs => Polyfill_TextWriter.cs} | 2 +- ...Extensions_TryFormat.cs => Polyfill_TryFormat.cs} | 2 +- .../{PolyfillExtensions_Type.cs => Polyfill_Type.cs} | 2 +- src/Tests/BuildApiTest.cs | 2 +- src/Tests/PolyfillTests_StringBuilder.cs | 4 ++-- src/Tests/StringInterpolationTests.cs | 2 +- 28 files changed, 34 insertions(+), 34 deletions(-) rename src/Polyfill/{PolyfillExtensions.cs => Polyfill.cs} (85%) rename src/Polyfill/{PolyfillExtensions_CancellationToken.cs => Polyfill_CancellationToken.cs} (99%) rename src/Polyfill/{PolyfillExtensions_CancellationTokenSource.cs => Polyfill_CancellationTokenSource.cs} (98%) rename src/Polyfill/{PolyfillExtensions_Dictionary.cs => Polyfill_Dictionary.cs} (97%) rename src/Polyfill/{PolyfillExtensions_HttpClient.cs => Polyfill_HttpClient.cs} (99%) rename src/Polyfill/{PolyfillExtensions_HttpContent.cs => Polyfill_HttpContent.cs} (98%) rename src/Polyfill/{PolyfillExtensions_IEnumerable.cs => Polyfill_IEnumerable.cs} (99%) rename src/Polyfill/{PolyfillExtensions_IReadOnlyDictionary.cs => Polyfill_IReadOnlyDictionary.cs} (98%) rename src/Polyfill/{PolyfillExtensions_KeyValuePair.cs => Polyfill_KeyValuePair.cs} (95%) rename src/Polyfill/{PolyfillExtensions_Memory.cs => Polyfill_Memory.cs} (99%) rename src/Polyfill/{PolyfillExtensions_MicroNanosecond.cs => Polyfill_MicroNanosecond.cs} (99%) rename src/Polyfill/{PolyfillExtensions_MicroNanosecondAdd.cs => Polyfill_MicroNanosecondAdd.cs} (96%) rename src/Polyfill/{PolyfillExtensions_Process.cs => Polyfill_Process.cs} (99%) rename src/Polyfill/{PolyfillExtensions_Stream.cs => Polyfill_Stream.cs} (99%) rename src/Polyfill/{PolyfillExtensions_String.cs => Polyfill_String.cs} (99%) rename src/Polyfill/{PolyfillExtensions_StringBuilder.cs => Polyfill_StringBuilder.cs} (99%) rename src/Polyfill/{PolyfillExtensions_Task.cs => Polyfill_Task.cs} (99%) rename src/Polyfill/{PolyfillExtensions_TextReader.cs => Polyfill_TextReader.cs} (99%) rename src/Polyfill/{PolyfillExtensions_TextWriter.cs => Polyfill_TextWriter.cs} (99%) rename src/Polyfill/{PolyfillExtensions_TryFormat.cs => Polyfill_TryFormat.cs} (99%) rename src/Polyfill/{PolyfillExtensions_Type.cs => Polyfill_Type.cs} (98%) diff --git a/contributing.md b/contributing.md index b0cd689a..bbf0a8b1 100644 --- a/contributing.md +++ b/contributing.md @@ -181,12 +181,12 @@ sealed class ModuleInitializerAttribute : #### If the API is a missing instance method -Add an extension method to `PolyfillExtensions_TYPE.cs` where `TYPE` is the type the method extending. So, for example, APIs that target `StreamWriter` go in `PolyfillExtensions_StreamWriter.cs`. +Add an extension method to `Polyfill_TYPE.cs` where `TYPE` is the type the method extending. So, for example, APIs that target `StreamWriter` go in `Polyfill_StreamWriter.cs`. Example: - - + + ```cs // @@ -202,7 +202,7 @@ using Link = System.ComponentModel.DescriptionAttribute; using System.Threading; using System.Threading.Tasks; -static partial class PolyfillExtensions +static partial class Polyfill { /// /// Asynchronously writes a character memory region to the stream. @@ -304,7 +304,7 @@ static partial class PolyfillExtensions } #endif ``` -snippet source | anchor +snippet source | anchor @@ -312,7 +312,7 @@ static partial class PolyfillExtensions Add a for the new API to the Tests project. -Extension method tests to `PolyfillTests_TYPE.cs` where `TYPE` is the type the method extending. So, for example, APIs that target `StreamWriter` go in `PolyfillExtensionsTests_StreamWriter.cs`. For example: +Extension method tests to `PolyfillTests_TYPE.cs` where `TYPE` is the type the method extending. So, for example, APIs that target `StreamWriter` go in `PolyfillTests_StreamWriter.cs`. For example: diff --git a/readme.md b/readme.md index 15bd2ddf..a3007a27 100644 --- a/readme.md +++ b/readme.md @@ -348,7 +348,7 @@ Reference: [Improvements in native code interop in .NET 5.0](https://devblogs.mi ## Extensions -The class `PolyfillExtensions` includes the following extension methods: +The class `Polyfill` includes the following extension methods: > [!IMPORTANT] > The methods using `AppendInterpolatedStringHandler` parameter are not extensions because the compiler prefers to use the overload with `string` parameter instead. diff --git a/src/Directory.Build.props b/src/Directory.Build.props index df85c178..5aff20b8 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.34.0 + 2.0.0 1.0.0 Polyfill true diff --git a/src/Polyfill/Nullability/NullabilityInfoExtensions.cs b/src/Polyfill/Nullability/NullabilityInfoExtensions.cs index a1dcf842..f3c1f464 100644 --- a/src/Polyfill/Nullability/NullabilityInfoExtensions.cs +++ b/src/Polyfill/Nullability/NullabilityInfoExtensions.cs @@ -12,7 +12,7 @@ #if PolyPublic public #endif -static partial class PolyfillExtensions +static partial class Polyfill { static ConcurrentDictionary parameterCache = []; static ConcurrentDictionary propertyCache = []; diff --git a/src/Polyfill/PolyfillExtensions.cs b/src/Polyfill/Polyfill.cs similarity index 85% rename from src/Polyfill/PolyfillExtensions.cs rename to src/Polyfill/Polyfill.cs index 8be5fd04..3ae77888 100644 --- a/src/Polyfill/PolyfillExtensions.cs +++ b/src/Polyfill/Polyfill.cs @@ -10,6 +10,6 @@ #if PolyPublic public #endif -static partial class PolyfillExtensions +static partial class Polyfill { } \ No newline at end of file diff --git a/src/Polyfill/PolyfillExtensions_CancellationToken.cs b/src/Polyfill/Polyfill_CancellationToken.cs similarity index 99% rename from src/Polyfill/PolyfillExtensions_CancellationToken.cs rename to src/Polyfill/Polyfill_CancellationToken.cs index bff06e5a..2e4dc550 100644 --- a/src/Polyfill/PolyfillExtensions_CancellationToken.cs +++ b/src/Polyfill/Polyfill_CancellationToken.cs @@ -8,7 +8,7 @@ using System.Threading; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { #if !NETCOREAPP3_0_OR_GREATER diff --git a/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs b/src/Polyfill/Polyfill_CancellationTokenSource.cs similarity index 98% rename from src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs rename to src/Polyfill/Polyfill_CancellationTokenSource.cs index 121c0728..83980b66 100644 --- a/src/Polyfill/PolyfillExtensions_CancellationTokenSource.cs +++ b/src/Polyfill/Polyfill_CancellationTokenSource.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { #if !NET8_0_OR_GREATER diff --git a/src/Polyfill/PolyfillExtensions_Dictionary.cs b/src/Polyfill/Polyfill_Dictionary.cs similarity index 97% rename from src/Polyfill/PolyfillExtensions_Dictionary.cs rename to src/Polyfill/Polyfill_Dictionary.cs index 1ae05283..772a8680 100644 --- a/src/Polyfill/PolyfillExtensions_Dictionary.cs +++ b/src/Polyfill/Polyfill_Dictionary.cs @@ -9,7 +9,7 @@ using System.Diagnostics.CodeAnalysis; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { /// /// Removes the value with the specified key from the , and copies the element diff --git a/src/Polyfill/PolyfillExtensions_HttpClient.cs b/src/Polyfill/Polyfill_HttpClient.cs similarity index 99% rename from src/Polyfill/PolyfillExtensions_HttpClient.cs rename to src/Polyfill/Polyfill_HttpClient.cs index 95663d00..39b940af 100644 --- a/src/Polyfill/PolyfillExtensions_HttpClient.cs +++ b/src/Polyfill/Polyfill_HttpClient.cs @@ -11,7 +11,7 @@ using System.Threading.Tasks; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { /// /// Send a GET request to the specified Uri and return the response body as a stream in an asynchronous operation. diff --git a/src/Polyfill/PolyfillExtensions_HttpContent.cs b/src/Polyfill/Polyfill_HttpContent.cs similarity index 98% rename from src/Polyfill/PolyfillExtensions_HttpContent.cs rename to src/Polyfill/Polyfill_HttpContent.cs index 2a17255e..24715e98 100644 --- a/src/Polyfill/PolyfillExtensions_HttpContent.cs +++ b/src/Polyfill/Polyfill_HttpContent.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { /// /// Serializes the HTTP content and returns a stream that represents the content. diff --git a/src/Polyfill/PolyfillExtensions_IEnumerable.cs b/src/Polyfill/Polyfill_IEnumerable.cs similarity index 99% rename from src/Polyfill/PolyfillExtensions_IEnumerable.cs rename to src/Polyfill/Polyfill_IEnumerable.cs index 2655c353..d433f9b1 100644 --- a/src/Polyfill/PolyfillExtensions_IEnumerable.cs +++ b/src/Polyfill/Polyfill_IEnumerable.cs @@ -7,7 +7,7 @@ using Link = System.ComponentModel.DescriptionAttribute; using System.Linq; -static partial class PolyfillExtensions +static partial class Polyfill { /// /// Produces a set items excluding by using the default equality comparer to compare values. diff --git a/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs b/src/Polyfill/Polyfill_IReadOnlyDictionary.cs similarity index 98% rename from src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs rename to src/Polyfill/Polyfill_IReadOnlyDictionary.cs index 9d10c259..fc6d8e16 100644 --- a/src/Polyfill/PolyfillExtensions_IReadOnlyDictionary.cs +++ b/src/Polyfill/Polyfill_IReadOnlyDictionary.cs @@ -8,7 +8,7 @@ using System.Collections.Generic; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { /// /// Tries to get the value associated with the specified key in the dictionary. diff --git a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs b/src/Polyfill/Polyfill_KeyValuePair.cs similarity index 95% rename from src/Polyfill/PolyfillExtensions_KeyValuePair.cs rename to src/Polyfill/Polyfill_KeyValuePair.cs index dcb09a70..cc218aa1 100644 --- a/src/Polyfill/PolyfillExtensions_KeyValuePair.cs +++ b/src/Polyfill/Polyfill_KeyValuePair.cs @@ -8,7 +8,7 @@ using System.Collections.Generic; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { /// /// Deconstructs the current diff --git a/src/Polyfill/PolyfillExtensions_Memory.cs b/src/Polyfill/Polyfill_Memory.cs similarity index 99% rename from src/Polyfill/PolyfillExtensions_Memory.cs rename to src/Polyfill/Polyfill_Memory.cs index 65e06ab0..827c1bee 100644 --- a/src/Polyfill/PolyfillExtensions_Memory.cs +++ b/src/Polyfill/Polyfill_Memory.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { /// /// Indicates whether a specified value is found in a read-only span. Values are compared using IEquatable{T}.Equals(T). diff --git a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs b/src/Polyfill/Polyfill_MicroNanosecond.cs similarity index 99% rename from src/Polyfill/PolyfillExtensions_MicroNanosecond.cs rename to src/Polyfill/Polyfill_MicroNanosecond.cs index 6c093641..90435ede 100644 --- a/src/Polyfill/PolyfillExtensions_MicroNanosecond.cs +++ b/src/Polyfill/Polyfill_MicroNanosecond.cs @@ -5,7 +5,7 @@ using System; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { #if NET7_0_OR_GREATER diff --git a/src/Polyfill/PolyfillExtensions_MicroNanosecondAdd.cs b/src/Polyfill/Polyfill_MicroNanosecondAdd.cs similarity index 96% rename from src/Polyfill/PolyfillExtensions_MicroNanosecondAdd.cs rename to src/Polyfill/Polyfill_MicroNanosecondAdd.cs index d70f4bcb..43c5e56f 100644 --- a/src/Polyfill/PolyfillExtensions_MicroNanosecondAdd.cs +++ b/src/Polyfill/Polyfill_MicroNanosecondAdd.cs @@ -5,7 +5,7 @@ using System; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { #if !NET7_0_OR_GREATER diff --git a/src/Polyfill/PolyfillExtensions_Process.cs b/src/Polyfill/Polyfill_Process.cs similarity index 99% rename from src/Polyfill/PolyfillExtensions_Process.cs rename to src/Polyfill/Polyfill_Process.cs index 11031172..76d3fb70 100644 --- a/src/Polyfill/PolyfillExtensions_Process.cs +++ b/src/Polyfill/Polyfill_Process.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { /// /// Instructs the Process component to wait for the associated process to exit, or diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/Polyfill_Stream.cs similarity index 99% rename from src/Polyfill/PolyfillExtensions_Stream.cs rename to src/Polyfill/Polyfill_Stream.cs index ed0ebb88..75ed585c 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/Polyfill_Stream.cs @@ -11,7 +11,7 @@ using System.Threading.Tasks; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { /// /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by diff --git a/src/Polyfill/PolyfillExtensions_String.cs b/src/Polyfill/Polyfill_String.cs similarity index 99% rename from src/Polyfill/PolyfillExtensions_String.cs rename to src/Polyfill/Polyfill_String.cs index 2d885e2f..e71ae9e1 100644 --- a/src/Polyfill/PolyfillExtensions_String.cs +++ b/src/Polyfill/Polyfill_String.cs @@ -6,7 +6,7 @@ using Link = System.ComponentModel.DescriptionAttribute; using System.Text; -static partial class PolyfillExtensions +static partial class Polyfill { #if HAS_SPAN && !NET6_0_OR_GREATER diff --git a/src/Polyfill/PolyfillExtensions_StringBuilder.cs b/src/Polyfill/Polyfill_StringBuilder.cs similarity index 99% rename from src/Polyfill/PolyfillExtensions_StringBuilder.cs rename to src/Polyfill/Polyfill_StringBuilder.cs index 1a64debd..378d006b 100644 --- a/src/Polyfill/PolyfillExtensions_StringBuilder.cs +++ b/src/Polyfill/Polyfill_StringBuilder.cs @@ -11,7 +11,7 @@ using System.Threading.Tasks; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { #if HAS_SPAN && (!NETSTANDARD2_1_OR_GREATER && !NETCOREAPP2_1_OR_GREATER) diff --git a/src/Polyfill/PolyfillExtensions_Task.cs b/src/Polyfill/Polyfill_Task.cs similarity index 99% rename from src/Polyfill/PolyfillExtensions_Task.cs rename to src/Polyfill/Polyfill_Task.cs index 02bd8d2a..7453a3d0 100644 --- a/src/Polyfill/PolyfillExtensions_Task.cs +++ b/src/Polyfill/Polyfill_Task.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { // Copied from .NET library const Timer.MaxSupportedTimeout private const uint MaxSupportedTimeout = 0xfffffffe; diff --git a/src/Polyfill/PolyfillExtensions_TextReader.cs b/src/Polyfill/Polyfill_TextReader.cs similarity index 99% rename from src/Polyfill/PolyfillExtensions_TextReader.cs rename to src/Polyfill/Polyfill_TextReader.cs index c697986d..2f4737bd 100644 --- a/src/Polyfill/PolyfillExtensions_TextReader.cs +++ b/src/Polyfill/Polyfill_TextReader.cs @@ -9,7 +9,7 @@ using System.Threading; using System.Threading.Tasks; -static partial class PolyfillExtensions +static partial class Polyfill { #if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) /// diff --git a/src/Polyfill/PolyfillExtensions_TextWriter.cs b/src/Polyfill/Polyfill_TextWriter.cs similarity index 99% rename from src/Polyfill/PolyfillExtensions_TextWriter.cs rename to src/Polyfill/Polyfill_TextWriter.cs index 2634d435..1fcd650e 100644 --- a/src/Polyfill/PolyfillExtensions_TextWriter.cs +++ b/src/Polyfill/Polyfill_TextWriter.cs @@ -12,7 +12,7 @@ using System.Threading; using System.Threading.Tasks; -static partial class PolyfillExtensions +static partial class Polyfill { /// /// Asynchronously writes a character memory region to the stream. diff --git a/src/Polyfill/PolyfillExtensions_TryFormat.cs b/src/Polyfill/Polyfill_TryFormat.cs similarity index 99% rename from src/Polyfill/PolyfillExtensions_TryFormat.cs rename to src/Polyfill/Polyfill_TryFormat.cs index 6c568e8b..e7c64ca8 100644 --- a/src/Polyfill/PolyfillExtensions_TryFormat.cs +++ b/src/Polyfill/Polyfill_TryFormat.cs @@ -8,7 +8,7 @@ using System.Runtime.InteropServices; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { #if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X) diff --git a/src/Polyfill/PolyfillExtensions_Type.cs b/src/Polyfill/Polyfill_Type.cs similarity index 98% rename from src/Polyfill/PolyfillExtensions_Type.cs rename to src/Polyfill/Polyfill_Type.cs index f5285aee..d8e79ce5 100644 --- a/src/Polyfill/PolyfillExtensions_Type.cs +++ b/src/Polyfill/Polyfill_Type.cs @@ -6,7 +6,7 @@ using System.Reflection; using Link = System.ComponentModel.DescriptionAttribute; -static partial class PolyfillExtensions +static partial class Polyfill { #if NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0 [Link("https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas")] diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index 2ee25342..34a9ade6 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -22,7 +22,7 @@ public void Run() var md = Path.Combine(solutionDirectory, "..", "api_list.include.md"); File.Delete(md); using var module = Mono.Cecil.ModuleDefinition.ReadModule(path); - var extensions = module.GetTypes().Single(_ => _.Name == nameof(PolyfillExtensions)); + var extensions = module.GetTypes().Single(_ => _.Name == nameof(Polyfill)); using var writer = File.CreateText(md); foreach (var type in extensions.Methods diff --git a/src/Tests/PolyfillTests_StringBuilder.cs b/src/Tests/PolyfillTests_StringBuilder.cs index 7369e929..5368e9e7 100644 --- a/src/Tests/PolyfillTests_StringBuilder.cs +++ b/src/Tests/PolyfillTests_StringBuilder.cs @@ -30,7 +30,7 @@ public void Append() var builder = new StringBuilder(); var x = 10; - PolyfillExtensions.Append(builder, $"value{x}"); + Polyfill.Append(builder, $"value{x}"); Assert.AreEqual("value10", builder.ToString()); } @@ -40,7 +40,7 @@ public void AppendWithFormat() var builder = new StringBuilder(); var x = 10; - PolyfillExtensions.Append(builder, null, $"value{x}"); + Polyfill.Append(builder, null, $"value{x}"); Assert.AreEqual("value10", builder.ToString()); } } \ No newline at end of file diff --git a/src/Tests/StringInterpolationTests.cs b/src/Tests/StringInterpolationTests.cs index fb4b21d4..a39d1443 100644 --- a/src/Tests/StringInterpolationTests.cs +++ b/src/Tests/StringInterpolationTests.cs @@ -19,7 +19,7 @@ public void ShouldInterpolateStringBuilder() var sb = new StringBuilder(); Span buffer = stackalloc char[] { 'H', 'e', 'l', 'l', 'o' }; var number = 15; - PolyfillExtensions.Append(sb, $"{buffer}, you're {number} years old {sb.ToString()}"); + Polyfill.Append(sb, $"{buffer}, you're {number} years old {sb.ToString()}"); var result = sb.ToString(); Assert.AreEqual("Hello, you're 15 years old Hello, you're 15 years old ", result); From d1fd9c29fcec736c3941b2112d0c1bfc70cd2c3a Mon Sep 17 00:00:00 2001 From: Scott Beca Date: Mon, 8 Jan 2024 20:22:50 +1100 Subject: [PATCH 267/313] Fix some compiler errors that can occur with specific project setups (#122) --- src/Consume/Consume.cs | 4 +++ src/Consume/Debug.cs | 29 +++++++++++++++++++ src/Polyfill/Nullability/NullabilityInfo.cs | 1 + .../Nullability/NullabilityInfoContext.cs | 5 ++++ .../AppendInterpolatedStringHandler.cs | 4 +++ .../DefaultInterpolatedStringHandler.cs | 4 +++ src/Tests/NullabilitySync.cs | 15 ++++++++++ 7 files changed, 62 insertions(+) create mode 100644 src/Consume/Debug.cs diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 7aabcae1..a7074f5d 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -98,6 +98,10 @@ class Consume var split = "a b".Split(' ', StringSplitOptions.RemoveEmptyEntries); split = "a b".Split(' ', 2, StringSplitOptions.RemoveEmptyEntries); var contains = "a b".Contains(' '); + + // Test to make sure there are no clashes in the Polyfill code with classes that + // might be defined in user code. See comments in Debug.cs for more details. + Debug.Log("Test log to make sure this is working"); } #if HTTPREFERENCED diff --git a/src/Consume/Debug.cs b/src/Consume/Debug.cs new file mode 100644 index 00000000..0b05cf42 --- /dev/null +++ b/src/Consume/Debug.cs @@ -0,0 +1,29 @@ +using System; + +// Test to make sure there are no clashes in the Polyfill code with classes that might be defined in user code. +// +// Some codebases, for better or for worse, define classes with names that match common classes in the base +// .NET libraries, like "Debug". This works find in those codebases because they are usually contained in the +// same namespace, or are guarded in some other way. But if a Polyfill attribute is imported and uses code like: +// Debug.Assert(genericParameter.IsGenericParameter); +// instead of a fully qualified name like: +// System.Debug.Assert(genericParameter.IsGenericParameter); +// then users of Polyfill will get errors like the following, which they can't easily fix: +// 'Debug' does not contain a definition for 'Assert' +// +// So, this file defines a custom Debug class to make sure that Polyfill code doesn't clash with user code. + +class Debug +{ + public static void Log(string content) => Console.WriteLine(content); + + public static void Log(ConsoleColor color, string content) + { + Console.ForegroundColor = color; + Console.WriteLine(content); + Console.ResetColor(); + } + + public static void LogWarning(string content) => Log(ConsoleColor.Yellow, content); + public static void LogError(string content) => Log(ConsoleColor.Red, content); +} diff --git a/src/Polyfill/Nullability/NullabilityInfo.cs b/src/Polyfill/Nullability/NullabilityInfo.cs index 65b3d0db..5fc4d8b5 100644 --- a/src/Polyfill/Nullability/NullabilityInfo.cs +++ b/src/Polyfill/Nullability/NullabilityInfo.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Diagnostics.CodeAnalysis; + // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs index a2939cdb..4ac7d429 100644 --- a/src/Polyfill/Nullability/NullabilityInfoContext.cs +++ b/src/Polyfill/Nullability/NullabilityInfoContext.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Diagnostics.CodeAnalysis; + // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. @@ -15,6 +16,10 @@ namespace System.Reflection { + // Some codebases define their own Debug class, which can cause clashes and compile errors if we aren't explicit here. + // See comments in Debug.cs in Consume project for more details. + using Debug = System.Diagnostics.Debug; + /// /// Provides APIs for populating nullability information/context from reflection members: /// , , and . diff --git a/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs b/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs index cc593eb7..574923bf 100644 --- a/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs +++ b/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs @@ -10,6 +10,10 @@ namespace System.Text; +// Some codebases define their own Debug class, which can cause clashes and compile errors if we aren't explicit here. +// See comments in Debug.cs in Consume project for more details. +using Debug = System.Diagnostics.Debug; + /// Provides a handler used by the language compiler to append interpolated strings into instances. [EditorBrowsable(EditorBrowsableState.Never)] [InterpolatedStringHandler] diff --git a/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs b/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs index e0fd9580..2850af42 100644 --- a/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs +++ b/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs @@ -14,6 +14,10 @@ namespace System.Runtime.CompilerServices; +// Some codebases define their own Debug class, which can cause clashes and compile errors if we aren't explicit here. +// See comments in Debug.cs in Consume project for more details. +using Debug = System.Diagnostics.Debug; + /// Provides a handler used by the language compiler to process interpolated strings into instances. [InterpolatedStringHandler] [ExcludeFromCodeCoverage] diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs index ceab6b5a..569e6ab8 100644 --- a/src/Tests/NullabilitySync.cs +++ b/src/Tests/NullabilitySync.cs @@ -50,6 +50,7 @@ public async Task Run() using System.Linq; using System.Diagnostics.CodeAnalysis; + """; var suffix = """ @@ -60,6 +61,7 @@ public async Task Run() infoContext = prefix + infoContext + suffix; infoContext = MakeInternal(infoContext); + infoContext = AddDebugClassFix(infoContext); OverWrite(infoContext, "NullabilityInfoContext.cs"); info = prefix + info + suffix; @@ -87,6 +89,19 @@ static string MakeInternal(string source) => sealed class """); + static string AddDebugClassFix(string source) => + source + .Replace( + "namespace System.Reflection\r\n{", + """ + namespace System.Reflection + { + // Some codebases define their own Debug class, which can cause clashes and compile errors if we aren't explicit here. + // See comments in Debug.cs in Consume project for more details. + using Debug = System.Diagnostics.Debug; + + """); + static void OverWrite(string content, string file) { var path = Path.Combine(dir, file); From 2f73ec53c465f93f131f766600b678b582b91b67 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 8 Jan 2024 20:41:51 +1100 Subject: [PATCH 268/313] Update Tests.csproj --- src/Tests/Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 62d6b20b..4d20e1c5 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -29,7 +29,7 @@ - + From 1e76aca4b05da33f37cc2c7ca02f19bfdffe7c74 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 8 Jan 2024 21:38:27 +1100 Subject: [PATCH 269/313] Simplify namespaces (#123) --- contributing.md | 4 +-- .../CallerArgumentExpressionAttribute.cs | 4 +-- .../CompilerFeatureRequiredAttribute.cs | 4 +-- .../DisableRuntimeMarshallingAttribute.cs | 4 +-- src/Polyfill/ExperimentalAttribute.cs | 4 +-- src/Polyfill/IndexRange/Index.cs | 4 +-- src/Polyfill/IndexRange/Range.cs | 4 +-- src/Polyfill/IsExternalInit.cs | 4 +-- src/Polyfill/ModuleInitializerAttribute.cs | 4 +-- src/Polyfill/Nullability/NullabilityInfo.cs | 6 ++++ .../Nullability/NullabilityInfoContext.cs | 8 +++-- .../OSPlatformAttribute.cs | 4 +-- .../ObsoletedOSPlatformAttribute.cs | 6 ++-- .../SupportedOSPlatformAttribute.cs | 4 +-- .../SupportedOSPlatformGuardAttribute.cs | 4 +-- .../TargetPlatformAttribute.cs | 4 +-- .../UnsupportedOSPlatformAttribute.cs | 4 +-- .../UnsupportedOSPlatformGuardAttribute.cs | 4 +-- src/Polyfill/RequiredMemberAttribute.cs | 4 +-- src/Polyfill/SkipLocalsInitAttribute.cs | 4 +-- src/Polyfill/StackTraceHiddenAttribute.cs | 4 +-- .../AppendInterpolatedStringHandler.cs | 10 ++----- .../DefaultInterpolatedStringHandler.cs | 12 +++----- ...erpolatedStringHandlerArgumentAttribute.cs | 4 +-- .../InterpolatedStringHandlerAttribute.cs | 4 +-- src/Polyfill/StringSyntaxAttribute.cs | 4 +-- src/Polyfill/SuppressGCTransitionAttribute.cs | 4 +-- src/Polyfill/UnmanagedCallersOnlyAttribute.cs | 7 ++--- src/Polyfill/UnreachableException.cs | 4 +-- src/Polyfill/UnscopedRefAttribute.cs | 4 +-- src/Tests/NullabilitySync.cs | 30 +++++++++++-------- 31 files changed, 90 insertions(+), 85 deletions(-) diff --git a/contributing.md b/contributing.md index bbf0a8b1..0954aa92 100644 --- a/contributing.md +++ b/contributing.md @@ -133,12 +133,12 @@ Example: #if !NET5_0_OR_GREATER +namespace System.Runtime.CompilerServices; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Link = System.ComponentModel.DescriptionAttribute; -namespace System.Runtime.CompilerServices; - /// /// Used to indicate to the compiler that a method should be called /// in its containing module's initializer. diff --git a/src/Polyfill/CallerArgumentExpressionAttribute.cs b/src/Polyfill/CallerArgumentExpressionAttribute.cs index bf174414..34eaf643 100644 --- a/src/Polyfill/CallerArgumentExpressionAttribute.cs +++ b/src/Polyfill/CallerArgumentExpressionAttribute.cs @@ -2,12 +2,12 @@ #if NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X +namespace System.Runtime.CompilerServices; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Link = System.ComponentModel.DescriptionAttribute; -namespace System.Runtime.CompilerServices; - /// /// Indicates that a parameter captures the expression passed for another parameter as a string. /// diff --git a/src/Polyfill/CompilerFeatureRequiredAttribute.cs b/src/Polyfill/CompilerFeatureRequiredAttribute.cs index 9d39b5fe..28fb64c7 100644 --- a/src/Polyfill/CompilerFeatureRequiredAttribute.cs +++ b/src/Polyfill/CompilerFeatureRequiredAttribute.cs @@ -2,12 +2,12 @@ #if !NET7_0_OR_GREATER +namespace System.Runtime.CompilerServices; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Link = System.ComponentModel.DescriptionAttribute; -namespace System.Runtime.CompilerServices; - /// /// Indicates that compiler support for a particular feature is required for the location where this attribute is applied. /// diff --git a/src/Polyfill/DisableRuntimeMarshallingAttribute.cs b/src/Polyfill/DisableRuntimeMarshallingAttribute.cs index 4d611658..34b36cbd 100644 --- a/src/Polyfill/DisableRuntimeMarshallingAttribute.cs +++ b/src/Polyfill/DisableRuntimeMarshallingAttribute.cs @@ -2,12 +2,12 @@ #if !NET7_0_OR_GREATER +namespace System.Runtime.CompilerServices; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Link = System.ComponentModel.DescriptionAttribute; -namespace System.Runtime.CompilerServices; - /// /// Disables the built-in runtime managed/unmanaged marshalling subsystem for /// P/Invokes, Delegate types, and unmanaged function pointer invocations. diff --git a/src/Polyfill/ExperimentalAttribute.cs b/src/Polyfill/ExperimentalAttribute.cs index ec549f38..87cd4376 100644 --- a/src/Polyfill/ExperimentalAttribute.cs +++ b/src/Polyfill/ExperimentalAttribute.cs @@ -4,12 +4,12 @@ #if !NET8_0_OR_GREATER +namespace System.Diagnostics.CodeAnalysis; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Link = System.ComponentModel.DescriptionAttribute; -namespace System.Diagnostics.CodeAnalysis; - /// /// Indicates that a parameter captures the expression passed for another parameter as a string. /// diff --git a/src/Polyfill/IndexRange/Index.cs b/src/Polyfill/IndexRange/Index.cs index 478e9dbe..51910924 100644 --- a/src/Polyfill/IndexRange/Index.cs +++ b/src/Polyfill/IndexRange/Index.cs @@ -2,12 +2,12 @@ #if (NET46X && VALUETUPLEREFERENCED) || NET47X || NET48X || NETSTANDARD2_0 || NETCOREAPP2X +namespace System; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; -namespace System; - /// Represent a type can be used to index a collection either from the start or the end. /// /// Index is used by the C# compiler to support the new index syntax diff --git a/src/Polyfill/IndexRange/Range.cs b/src/Polyfill/IndexRange/Range.cs index 30f30909..1c59e07d 100644 --- a/src/Polyfill/IndexRange/Range.cs +++ b/src/Polyfill/IndexRange/Range.cs @@ -2,12 +2,12 @@ #if (NET46X && VALUETUPLEREFERENCED) || NET47X || NET48X || NETSTANDARD2_0 || NETCOREAPP2X +namespace System; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; -namespace System; - /// Represent a range has start and end indexes. /// /// Range is used by the C# compiler to support the range syntax. diff --git a/src/Polyfill/IsExternalInit.cs b/src/Polyfill/IsExternalInit.cs index ee40249e..35a7e7c4 100644 --- a/src/Polyfill/IsExternalInit.cs +++ b/src/Polyfill/IsExternalInit.cs @@ -2,11 +2,11 @@ #if !NET5_0_OR_GREATER +namespace System.Runtime.CompilerServices; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -namespace System.Runtime.CompilerServices; - /// /// Reserved to be used by the compiler for tracking metadata. This class should not be used by developers in source code. /// diff --git a/src/Polyfill/ModuleInitializerAttribute.cs b/src/Polyfill/ModuleInitializerAttribute.cs index 7889a399..df30f2d3 100644 --- a/src/Polyfill/ModuleInitializerAttribute.cs +++ b/src/Polyfill/ModuleInitializerAttribute.cs @@ -2,12 +2,12 @@ #if !NET5_0_OR_GREATER +namespace System.Runtime.CompilerServices; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Link = System.ComponentModel.DescriptionAttribute; -namespace System.Runtime.CompilerServices; - /// /// Used to indicate to the compiler that a method should be called /// in its containing module's initializer. diff --git a/src/Polyfill/Nullability/NullabilityInfo.cs b/src/Polyfill/Nullability/NullabilityInfo.cs index 5fc4d8b5..54888271 100644 --- a/src/Polyfill/Nullability/NullabilityInfo.cs +++ b/src/Polyfill/Nullability/NullabilityInfo.cs @@ -14,6 +14,12 @@ namespace System.Reflection { + using System.Linq; + using System.Diagnostics.CodeAnalysis; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Diagnostics; + /// /// A class that represents nullability info /// diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs index 4ac7d429..764bdbed 100644 --- a/src/Polyfill/Nullability/NullabilityInfoContext.cs +++ b/src/Polyfill/Nullability/NullabilityInfoContext.cs @@ -16,9 +16,11 @@ namespace System.Reflection { - // Some codebases define their own Debug class, which can cause clashes and compile errors if we aren't explicit here. - // See comments in Debug.cs in Consume project for more details. - using Debug = System.Diagnostics.Debug; + using System.Linq; + using System.Diagnostics.CodeAnalysis; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Diagnostics; /// /// Provides APIs for populating nullability information/context from reflection members: diff --git a/src/Polyfill/PlatformCompatibility/OSPlatformAttribute.cs b/src/Polyfill/PlatformCompatibility/OSPlatformAttribute.cs index e3b722b1..048f7421 100644 --- a/src/Polyfill/PlatformCompatibility/OSPlatformAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/OSPlatformAttribute.cs @@ -4,11 +4,11 @@ #pragma warning disable +namespace System.Runtime.Versioning; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -namespace System.Runtime.Versioning; - /// /// Base type for all platform-specific API attributes. /// diff --git a/src/Polyfill/PlatformCompatibility/ObsoletedOSPlatformAttribute.cs b/src/Polyfill/PlatformCompatibility/ObsoletedOSPlatformAttribute.cs index 942411dc..2854ca96 100644 --- a/src/Polyfill/PlatformCompatibility/ObsoletedOSPlatformAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/ObsoletedOSPlatformAttribute.cs @@ -4,13 +4,13 @@ #pragma warning disable -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; - #nullable enable namespace System.Runtime.Versioning; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + using Targets = AttributeTargets; /// diff --git a/src/Polyfill/PlatformCompatibility/SupportedOSPlatformAttribute.cs b/src/Polyfill/PlatformCompatibility/SupportedOSPlatformAttribute.cs index e1885da6..11655f12 100644 --- a/src/Polyfill/PlatformCompatibility/SupportedOSPlatformAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/SupportedOSPlatformAttribute.cs @@ -4,11 +4,11 @@ #pragma warning disable +namespace System.Runtime.Versioning; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -namespace System.Runtime.Versioning; - using Targets = AttributeTargets; /// diff --git a/src/Polyfill/PlatformCompatibility/SupportedOSPlatformGuardAttribute.cs b/src/Polyfill/PlatformCompatibility/SupportedOSPlatformGuardAttribute.cs index 13333f8d..f8d109e1 100644 --- a/src/Polyfill/PlatformCompatibility/SupportedOSPlatformGuardAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/SupportedOSPlatformGuardAttribute.cs @@ -4,11 +4,11 @@ #pragma warning disable +namespace System.Runtime.Versioning; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -namespace System.Runtime.Versioning; - using Targets = AttributeTargets; /// diff --git a/src/Polyfill/PlatformCompatibility/TargetPlatformAttribute.cs b/src/Polyfill/PlatformCompatibility/TargetPlatformAttribute.cs index 26e192c1..d340b45c 100644 --- a/src/Polyfill/PlatformCompatibility/TargetPlatformAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/TargetPlatformAttribute.cs @@ -2,11 +2,11 @@ #if !NET5_0_OR_GREATER +namespace System.Runtime.Versioning; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -namespace System.Runtime.Versioning; - /// /// Records the platform that the project targeted. /// diff --git a/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformAttribute.cs b/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformAttribute.cs index 6af9ea69..ffc26bef 100644 --- a/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformAttribute.cs @@ -4,11 +4,11 @@ #nullable enable +namespace System.Runtime.Versioning; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -namespace System.Runtime.Versioning; - using Targets = AttributeTargets; /// diff --git a/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformGuardAttribute.cs b/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformGuardAttribute.cs index aa446f86..21835579 100644 --- a/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformGuardAttribute.cs +++ b/src/Polyfill/PlatformCompatibility/UnsupportedOSPlatformGuardAttribute.cs @@ -4,11 +4,11 @@ #pragma warning disable +namespace System.Runtime.Versioning; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -namespace System.Runtime.Versioning; - using Targets = AttributeTargets; /// diff --git a/src/Polyfill/RequiredMemberAttribute.cs b/src/Polyfill/RequiredMemberAttribute.cs index 3b245bf0..144e1218 100644 --- a/src/Polyfill/RequiredMemberAttribute.cs +++ b/src/Polyfill/RequiredMemberAttribute.cs @@ -2,11 +2,11 @@ #if !NET7_0_OR_GREATER +namespace System.Runtime.CompilerServices; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -namespace System.Runtime.CompilerServices; - using Targets = AttributeTargets; /// diff --git a/src/Polyfill/SkipLocalsInitAttribute.cs b/src/Polyfill/SkipLocalsInitAttribute.cs index df042fb1..7f64aa8b 100644 --- a/src/Polyfill/SkipLocalsInitAttribute.cs +++ b/src/Polyfill/SkipLocalsInitAttribute.cs @@ -2,11 +2,11 @@ #if !NET5_0_OR_GREATER +namespace System.Runtime.CompilerServices; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -namespace System.Runtime.CompilerServices; - using Targets = AttributeTargets; /// diff --git a/src/Polyfill/StackTraceHiddenAttribute.cs b/src/Polyfill/StackTraceHiddenAttribute.cs index 2634e040..028b9bab 100644 --- a/src/Polyfill/StackTraceHiddenAttribute.cs +++ b/src/Polyfill/StackTraceHiddenAttribute.cs @@ -2,10 +2,10 @@ #if !NET6_0_OR_GREATER -using System.Diagnostics.CodeAnalysis; - namespace System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + using Targets = AttributeTargets; /// diff --git a/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs b/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs index 574923bf..d088b3c0 100644 --- a/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs +++ b/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs @@ -2,17 +2,13 @@ #if HAS_SPAN && !NET6_0_OR_GREATER -using System.ComponentModel; -using System.Diagnostics; -using System.Runtime.CompilerServices; - #nullable enable namespace System.Text; -// Some codebases define their own Debug class, which can cause clashes and compile errors if we aren't explicit here. -// See comments in Debug.cs in Consume project for more details. -using Debug = System.Diagnostics.Debug; +using System.ComponentModel; +using System.Diagnostics; +using System.Runtime.CompilerServices; /// Provides a handler used by the language compiler to append interpolated strings into instances. [EditorBrowsable(EditorBrowsableState.Never)] diff --git a/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs b/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs index 2850af42..b15eec55 100644 --- a/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs +++ b/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs @@ -2,6 +2,10 @@ #if HAS_SPAN && !NET6_0_OR_GREATER +#nullable enable + +namespace System.Runtime.CompilerServices; + using System; using System.Buffers; using System.Diagnostics; @@ -10,14 +14,6 @@ using System.Runtime.CompilerServices; using Link = System.ComponentModel.DescriptionAttribute; -#nullable enable - -namespace System.Runtime.CompilerServices; - -// Some codebases define their own Debug class, which can cause clashes and compile errors if we aren't explicit here. -// See comments in Debug.cs in Consume project for more details. -using Debug = System.Diagnostics.Debug; - /// Provides a handler used by the language compiler to process interpolated strings into instances. [InterpolatedStringHandler] [ExcludeFromCodeCoverage] diff --git a/src/Polyfill/StringInterpolation/InterpolatedStringHandlerArgumentAttribute.cs b/src/Polyfill/StringInterpolation/InterpolatedStringHandlerArgumentAttribute.cs index c2ab3559..04ee127e 100644 --- a/src/Polyfill/StringInterpolation/InterpolatedStringHandlerArgumentAttribute.cs +++ b/src/Polyfill/StringInterpolation/InterpolatedStringHandlerArgumentAttribute.cs @@ -2,12 +2,12 @@ #if !NET6_0_OR_GREATER +namespace System.Runtime.CompilerServices; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Link = System.ComponentModel.DescriptionAttribute; -namespace System.Runtime.CompilerServices; - /// /// Indicates which arguments to a method involving an interpolated string handler should be passed to that handler. /// diff --git a/src/Polyfill/StringInterpolation/InterpolatedStringHandlerAttribute.cs b/src/Polyfill/StringInterpolation/InterpolatedStringHandlerAttribute.cs index 4486b5dc..23b0b661 100644 --- a/src/Polyfill/StringInterpolation/InterpolatedStringHandlerAttribute.cs +++ b/src/Polyfill/StringInterpolation/InterpolatedStringHandlerAttribute.cs @@ -2,12 +2,12 @@ #if !NET6_0_OR_GREATER +namespace System.Runtime.CompilerServices; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Link = System.ComponentModel.DescriptionAttribute; -namespace System.Runtime.CompilerServices; - using Targets = AttributeTargets; /// diff --git a/src/Polyfill/StringSyntaxAttribute.cs b/src/Polyfill/StringSyntaxAttribute.cs index feeda19d..f773986f 100644 --- a/src/Polyfill/StringSyntaxAttribute.cs +++ b/src/Polyfill/StringSyntaxAttribute.cs @@ -4,11 +4,11 @@ #nullable enable +namespace System.Diagnostics.CodeAnalysis; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -namespace System.Diagnostics.CodeAnalysis; - using Targets = AttributeTargets; /// diff --git a/src/Polyfill/SuppressGCTransitionAttribute.cs b/src/Polyfill/SuppressGCTransitionAttribute.cs index b64687d3..2ae81cfb 100644 --- a/src/Polyfill/SuppressGCTransitionAttribute.cs +++ b/src/Polyfill/SuppressGCTransitionAttribute.cs @@ -2,11 +2,11 @@ #if !NET5_0_OR_GREATER +namespace System.Runtime.InteropServices; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -namespace System.Runtime.InteropServices; - /// /// An attribute used to indicate a GC transition should be skipped when making an unmanaged function call. /// diff --git a/src/Polyfill/UnmanagedCallersOnlyAttribute.cs b/src/Polyfill/UnmanagedCallersOnlyAttribute.cs index 6b8a09db..b8856808 100644 --- a/src/Polyfill/UnmanagedCallersOnlyAttribute.cs +++ b/src/Polyfill/UnmanagedCallersOnlyAttribute.cs @@ -4,14 +4,13 @@ #nullable enable - -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; - #pragma warning disable CS0649 namespace System.Runtime.InteropServices; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + /// /// Any method marked with can be directly called from /// native code. The function token can be loaded to a local variable using the address-of operator diff --git a/src/Polyfill/UnreachableException.cs b/src/Polyfill/UnreachableException.cs index 0de4e6ca..7c03178a 100644 --- a/src/Polyfill/UnreachableException.cs +++ b/src/Polyfill/UnreachableException.cs @@ -4,13 +4,13 @@ #nullable enable +namespace System.Diagnostics; + using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text; -namespace System.Diagnostics; - /// /// Exception thrown when the program executes an instruction that was thought to be unreachable. /// diff --git a/src/Polyfill/UnscopedRefAttribute.cs b/src/Polyfill/UnscopedRefAttribute.cs index f8c3134d..a61ed71f 100644 --- a/src/Polyfill/UnscopedRefAttribute.cs +++ b/src/Polyfill/UnscopedRefAttribute.cs @@ -2,10 +2,10 @@ #if !NET7_0_OR_GREATER -using System.Diagnostics; - namespace System.Diagnostics.CodeAnalysis; +using System.Diagnostics; + using Targets = AttributeTargets; /// diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs index 569e6ab8..09f12ad1 100644 --- a/src/Tests/NullabilitySync.cs +++ b/src/Tests/NullabilitySync.cs @@ -66,6 +66,7 @@ public async Task Run() info = prefix + info + suffix; info = MakeInternal(info); + info = AddDebugClassFix(info); OverWrite(info, "NullabilityInfo.cs"); } @@ -89,18 +90,23 @@ static string MakeInternal(string source) => sealed class """); - static string AddDebugClassFix(string source) => - source - .Replace( - "namespace System.Reflection\r\n{", - """ - namespace System.Reflection - { - // Some codebases define their own Debug class, which can cause clashes and compile errors if we aren't explicit here. - // See comments in Debug.cs in Consume project for more details. - using Debug = System.Diagnostics.Debug; - - """); + static string AddDebugClassFix(string source) + { + var newValue = """ + namespace System.Reflection + { + using System.Linq; + using System.Diagnostics.CodeAnalysis; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Diagnostics; + + """; + return source + .Replace("namespace System.Reflection\r\n{", newValue) + .Replace("namespace System.Reflection\n{", newValue) + .Replace("namespace System.Reflection\r{", newValue); + } static void OverWrite(string content, string file) { From f179c389319232fcb541d7c8683aa8ba7e49fd6c Mon Sep 17 00:00:00 2001 From: Scott Beca Date: Mon, 8 Jan 2024 21:40:10 +1100 Subject: [PATCH 270/313] Fix some compiler errors that can occur with specific project setups (#103) --- contributing.md | 2 +- .../ConsumeTasksWithNoMemory.csproj | 30 +++++++++++++++++++ src/Polyfill.sln | 6 ++++ src/Polyfill/Polyfill_Stream.cs | 4 +++ src/Polyfill/Polyfill_TextReader.cs | 2 +- src/Polyfill/Polyfill_TextWriter.cs | 2 +- 6 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj diff --git a/contributing.md b/contributing.md index 0954aa92..81acdb08 100644 --- a/contributing.md +++ b/contributing.md @@ -192,7 +192,7 @@ Example: #pragma warning disable -#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) +#if TASKSEXTENSIONSREFERENCED && MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; using System.Buffers; diff --git a/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj b/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj new file mode 100644 index 00000000..aaefa644 --- /dev/null +++ b/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj @@ -0,0 +1,30 @@ + + + true + netstandard2.0 + + + + + + + Pollyfill\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs + + + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs + + + Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs + + + + \ No newline at end of file diff --git a/src/Polyfill.sln b/src/Polyfill.sln index 281d2726..f4df45fe 100644 --- a/src/Polyfill.sln +++ b/src/Polyfill.sln @@ -33,6 +33,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoRefsTests", "NoRefsTests\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeNoRefs", "ConsumeNoRefs\ConsumeNoRefs.csproj", "{B4DC96CA-C700-499F-A9A2-0C767DCF8C30}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeTasksWithNoMemory", "ConsumeTasksWithNoMemory\ConsumeTasksWithNoMemory.csproj", "{96EF1E04-5862-4D9E-B800-A6402F1ADF7A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -75,6 +77,10 @@ Global {B4DC96CA-C700-499F-A9A2-0C767DCF8C30}.Debug|Any CPU.Build.0 = Debug|Any CPU {B4DC96CA-C700-499F-A9A2-0C767DCF8C30}.Release|Any CPU.ActiveCfg = Release|Any CPU {B4DC96CA-C700-499F-A9A2-0C767DCF8C30}.Release|Any CPU.Build.0 = Release|Any CPU + {96EF1E04-5862-4D9E-B800-A6402F1ADF7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96EF1E04-5862-4D9E-B800-A6402F1ADF7A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96EF1E04-5862-4D9E-B800-A6402F1ADF7A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96EF1E04-5862-4D9E-B800-A6402F1ADF7A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Polyfill/Polyfill_Stream.cs b/src/Polyfill/Polyfill_Stream.cs index 75ed585c..b1e875f6 100644 --- a/src/Polyfill/Polyfill_Stream.cs +++ b/src/Polyfill/Polyfill_Stream.cs @@ -13,6 +13,8 @@ static partial class Polyfill { +#if MEMORYREFERENCED + /// /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by /// the number of bytes read, and monitors cancellation requests. @@ -64,6 +66,8 @@ public static ValueTask WriteAsync( return new(target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken)); } +#endif + /// /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified /// cancellation token. Both streams positions are advanced by the number of bytes copied. diff --git a/src/Polyfill/Polyfill_TextReader.cs b/src/Polyfill/Polyfill_TextReader.cs index 2f4737bd..f642ea49 100644 --- a/src/Polyfill/Polyfill_TextReader.cs +++ b/src/Polyfill/Polyfill_TextReader.cs @@ -11,7 +11,7 @@ static partial class Polyfill { -#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) +#if TASKSEXTENSIONSREFERENCED && MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) /// /// Asynchronously reads the characters from the current stream into a memory block. /// diff --git a/src/Polyfill/Polyfill_TextWriter.cs b/src/Polyfill/Polyfill_TextWriter.cs index 1fcd650e..99227cdb 100644 --- a/src/Polyfill/Polyfill_TextWriter.cs +++ b/src/Polyfill/Polyfill_TextWriter.cs @@ -2,7 +2,7 @@ #pragma warning disable -#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) +#if TASKSEXTENSIONSREFERENCED && MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; using System.Buffers; From 9724ca84187bd39a42570706c7f8e42164ba2788 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 8 Jan 2024 21:42:58 +1100 Subject: [PATCH 271/313] Update ConsumeTasksWithNoMemory.csproj --- src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj b/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj index aaefa644..bae3691f 100644 --- a/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj +++ b/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj @@ -4,8 +4,7 @@ netstandard2.0 - - + Pollyfill\%(RecursiveDir)%(Filename).cs From 05b2f6ed7a7626f8cab9a76ef161ef657b34e022 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 8 Jan 2024 21:49:11 +1100 Subject: [PATCH 272/313] Update ConsumeTasksWithNoMemory.csproj --- src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj b/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj index bae3691f..a6dd9ad0 100644 --- a/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj +++ b/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj @@ -5,7 +5,7 @@ - + Pollyfill\%(RecursiveDir)%(Filename).cs From 7fba2cefbab556afdeeec107c3d4554e098f782e Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 8 Jan 2024 21:55:22 +1100 Subject: [PATCH 273/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 5aff20b8..8c170141 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 2.0.0 + 2.0.1 1.0.0 Polyfill true From c9072d6cb2f676f36975d1196aacc83421d7cb95 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 9 Jan 2024 16:29:20 +1100 Subject: [PATCH 274/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Shared.sln.DotSettings | 1 + src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 51a09736..39d5549e 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -36,7 +36,7 @@ - + \ No newline at end of file diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 80b60e7d..9f62e8d2 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -30,7 +30,7 @@ - + diff --git a/src/Shared.sln.DotSettings b/src/Shared.sln.DotSettings index 93612561..f2dd1f39 100644 --- a/src/Shared.sln.DotSettings +++ b/src/Shared.sln.DotSettings @@ -45,6 +45,7 @@ ERROR ERROR ERROR + ERROR ERROR ERROR ERROR diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 4d20e1c5..99158943 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -30,7 +30,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 9e4b65d9..53241946 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -30,7 +30,7 @@ - + From 1fb1fd3dbf1c5194291517f808f46c8c91776d95 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 10 Jan 2024 10:36:25 +1100 Subject: [PATCH 275/313] Update global.json --- src/global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/global.json b/src/global.json index 1f98ce1a..b8219f86 100644 --- a/src/global.json +++ b/src/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100", + "version": "8.0.101", "allowPrerelease": true, "rollForward": "latestFeature" } From ebf9c0c5404ab4ea27b4b9a85c53ce3da4262512 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 13 Jan 2024 20:51:37 +1100 Subject: [PATCH 276/313] Add StringBuilder.AppendJoin (#124) --- api_list.include.md | 6 ++ src/Directory.Build.props | 2 +- src/Polyfill/Polyfill_StringBuilder.cs | 73 ++++++++++++++++++++++++ src/Tests/PolyfillTests_StringBuilder.cs | 25 ++++++++ 4 files changed, 105 insertions(+), 1 deletion(-) diff --git a/api_list.include.md b/api_list.include.md index 7b66f248..372715f6 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -211,6 +211,12 @@ * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) * `StringBuilder Append(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) * `StringBuilder Append(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendJoin(String, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-string())) + * `StringBuilder AppendJoin(String, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-object())) + * `StringBuilder AppendJoin(Char, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-string())) + * `StringBuilder AppendJoin(Char, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-object())) + * `StringBuilder AppendJoin(Char, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0)))) + * `StringBuilder AppendJoin(String, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0)))) * `StringBuilder AppendLine(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) * `StringBuilder AppendLine(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 8c170141..4582668a 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 2.0.1 + 2.1.0 1.0.0 Polyfill true diff --git a/src/Polyfill/Polyfill_StringBuilder.cs b/src/Polyfill/Polyfill_StringBuilder.cs index 378d006b..54b50a1e 100644 --- a/src/Polyfill/Polyfill_StringBuilder.cs +++ b/src/Polyfill/Polyfill_StringBuilder.cs @@ -106,6 +106,7 @@ public static bool Equals(this StringBuilder target, ReadOnlySpan span) } #endif + #if HAS_SPAN && !NET6_0_OR_GREATER /// Appends the specified interpolated string to this instance. /// The interpolated string to append. @@ -144,7 +145,9 @@ public static StringBuilder AppendLine( IFormatProvider? provider, [InterpolatedStringHandlerArgument(nameof(target), nameof(provider))] ref AppendInterpolatedStringHandler handler) => target.AppendLine(); + #elif NET6_0_OR_GREATER + /// Appends the specified interpolated string to this instance. /// The interpolated string to append. /// A reference to this instance after the append operation has completed. @@ -184,5 +187,75 @@ public static StringBuilder AppendLine( IFormatProvider? provider, [InterpolatedStringHandlerArgument(nameof(target), nameof(provider))] ref StringBuilder.AppendInterpolatedStringHandler handler) => target.AppendLine(provider, ref handler); +#endif + + #if NETSTANDARD2_0|| NETFRAMEWORK + + /// Concatenates the strings of the provided array, using the specified separator between each string, then appends the result to the current instance of the string builder. + /// The string to use as a separator. separator is included in the joined strings only if values has more than one element. + /// An array that contains the strings to concatenate and append to the current instance of the string builder. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-string())")] + public static StringBuilder AppendJoin( + this StringBuilder target, + string separator, + params string[] values) => + target.Append(string.Join(separator, values)); + + /// Concatenates the string representations of the elements in the provided array of objects, using the specified separator between each member, then appends the result to the current instance of the string builder. + /// The string to use as a separator. separator is included in the joined strings only if values has more than one element. + /// An array that contains the strings to concatenate and append to the current instance of the string builder. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-object())")] + public static StringBuilder AppendJoin( + this StringBuilder target, + string separator, + params Object[] values) => + target.Append(string.Join(separator, values)); + + /// Concatenates the strings of the provided array, using the specified char separator between each string, then appends the result to the current instance of the string builder. + /// The character to use as a separator. separator is included in the joined strings only if values has more than one element. + /// An array that contains the strings to concatenate and append to the current instance of the string builder. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-string())")] + public static StringBuilder AppendJoin( + this StringBuilder target, + char separator, + params string[] values) => + target.Append(string.Join(separator.ToString(), values)); + + /// Concatenates the string representations of the elements in the provided array of objects, using the specified char separator between each member, then appends the result to the current instance of the string builder. + /// The character to use as a separator. separator is included in the joined strings only if values has more than one element. + /// An array that contains the strings to concatenate and append to the current instance of the string builder. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-object())")] + public static StringBuilder AppendJoin( + this StringBuilder target, + char separator, + params object[] values) => + target.Append(string.Join(separator.ToString(), values)); + + /// Concatenates and appends the members of a collection, using the specified char separator between each member. + /// The character to use as a separator. separator is included in the joined strings only if values has more than one element. + /// A collection that contains the objects to concatenate and append to the current instance of the string builder. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0)))")] + public static StringBuilder AppendJoin( + this StringBuilder target, + char separator, + params T[] values) => + target.Append(string.Join(separator.ToString(), values)); + + /// Concatenates and appends the members of a collection, using the specified char separator between each member. + /// The string to use as a separator. separator is included in the concatenated and appended strings only if values has more than one element. + /// A collection that contains the objects to concatenate and append to the current instance of the string builder. + /// A reference to this instance after the append operation has completed. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0)))")] + public static StringBuilder AppendJoin( + this StringBuilder target, + string separator, + params T[] values) => + target.Append(string.Join(separator.ToString(), values)); + #endif } \ No newline at end of file diff --git a/src/Tests/PolyfillTests_StringBuilder.cs b/src/Tests/PolyfillTests_StringBuilder.cs index 5368e9e7..adfa4592 100644 --- a/src/Tests/PolyfillTests_StringBuilder.cs +++ b/src/Tests/PolyfillTests_StringBuilder.cs @@ -43,4 +43,29 @@ public void AppendWithFormat() Polyfill.Append(builder, null, $"value{x}"); Assert.AreEqual("value10", builder.ToString()); } + + [Test] + public void AppendJoin() + { + var builder = new StringBuilder(); + + builder.AppendJoin(",", ["value1", "value2"]); + Assert(); + builder.AppendJoin(",", new object[]{"value1", "value2"}); + Assert(); + builder.AppendJoin(',', ["value1", "value2"]); + Assert(); + builder.AppendJoin(',', new object[]{"value1", "value2"}); + Assert(); + builder.AppendJoin(',', ["value1", "value2"]); + Assert(); + builder.AppendJoin(",", new[]{"value1", "value2"}); + Assert(); + + void Assert() + { + NUnit.Framework.Assert.AreEqual("value1,value2", builder.ToString()); + builder.Clear(); + } + } } \ No newline at end of file From f18dcfe009402dbde924710f65d57c437978952c Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 13 Jan 2024 21:21:16 +1100 Subject: [PATCH 277/313] add IEnumerable.ToHashSet (#125) --- src/Polyfill/Polyfill_IEnumerable.cs | 17 +++++++++++++++++ src/Tests/PolyfillTests_IEnumerable.cs | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/Polyfill/Polyfill_IEnumerable.cs b/src/Polyfill/Polyfill_IEnumerable.cs index d433f9b1..f5e211ac 100644 --- a/src/Polyfill/Polyfill_IEnumerable.cs +++ b/src/Polyfill/Polyfill_IEnumerable.cs @@ -286,4 +286,21 @@ public static IEnumerable SkipLast( int count) => target.Reverse().Skip(count).Reverse(); #endif + +#if NET471 || NET46X || NETSTANDARD2_0 + + /// + /// Creates a HashSet from an IEnumerable using the comparer to compare keys. + /// + /// An IEnumerable to create a HashSet from. + /// An IEqualityComparer to compare keys. + /// The type of the elements of source. + /// A HashSet that contains values of type TSource selected from the input sequence. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.tohashset#system-linq-enumerable-tohashset-1(system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))")] + public static HashSet ToHashSet( + this IEnumerable target, + IEqualityComparer? comparer = null) => + new HashSet(target, comparer); + +#endif } \ No newline at end of file diff --git a/src/Tests/PolyfillTests_IEnumerable.cs b/src/Tests/PolyfillTests_IEnumerable.cs index cbeb15ec..c230ec31 100644 --- a/src/Tests/PolyfillTests_IEnumerable.cs +++ b/src/Tests/PolyfillTests_IEnumerable.cs @@ -39,6 +39,16 @@ public void IEnumerableSkipLast() Assert.IsTrue(enumerable.SkipLast(1).SequenceEqual(new List { "a" })); } + [Test] + public void ToHashSet () + { + var enumerable = (IEnumerable)new List { "a", "b" }; + + var hashSet = enumerable.ToHashSet(); + Assert.IsTrue(hashSet.Contains("a")); + Assert.IsTrue(hashSet.Contains("b")); + } + [Test] public void Chunk_SizeOf3() { From 58936a61796c21e8326fc6d7b718048017da071c Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 13 Jan 2024 21:24:08 +1100 Subject: [PATCH 278/313] Update readme.md --- readme.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/readme.md b/readme.md index a3007a27..6b947832 100644 --- a/readme.md +++ b/readme.md @@ -567,6 +567,12 @@ The class `Polyfill` includes the following extension methods: * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) * `StringBuilder Append(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) * `StringBuilder Append(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendJoin(String, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-string())) + * `StringBuilder AppendJoin(String, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-object())) + * `StringBuilder AppendJoin(Char, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-string())) + * `StringBuilder AppendJoin(Char, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-object())) + * `StringBuilder AppendJoin(Char, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0)))) + * `StringBuilder AppendJoin(String, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0)))) * `StringBuilder AppendLine(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) * `StringBuilder AppendLine(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) From f0331e0328869e00dc3d8d75fb879afac42a56f3 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 13 Jan 2024 21:36:47 +1100 Subject: [PATCH 279/313] docs --- api_list.include.md | 1 + readme.md | 1 + 2 files changed, 2 insertions(+) diff --git a/api_list.include.md b/api_list.include.md index 372715f6..3600be0c 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -25,6 +25,7 @@ * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) * `TSource MinBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) + * `HashSet ToHashSet(IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.tohashset#system-linq-enumerable-tohashset-1(system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) ### IReadOnlyDictionary diff --git a/readme.md b/readme.md index 6b947832..1fda1170 100644 --- a/readme.md +++ b/readme.md @@ -381,6 +381,7 @@ The class `Polyfill` includes the following extension methods: * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) * `TSource MinBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) + * `HashSet ToHashSet(IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.tohashset#system-linq-enumerable-tohashset-1(system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) ### IReadOnlyDictionary From ff2858112f11e174a5159eaefc5923196023b69b Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 15 Jan 2024 22:31:46 +1100 Subject: [PATCH 280/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 4582668a..01fb13f8 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -8,7 +8,7 @@ false CS1591;NETSDK1138;NU1901;NU1902;NU1903 false - preview + 12 false true true From 8035a636440e3091b78ce3bb5bdf2fbb6225bf86 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 16 Jan 2024 12:45:22 +1100 Subject: [PATCH 281/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 2 +- .../Nullability/NullabilityInfoExtensions.cs | 12 +++++++----- src/Polyfill/Polyfill.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Shared.sln.DotSettings | 1 + src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 7 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 39d5549e..c4ba16a1 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -36,7 +36,7 @@ - + \ No newline at end of file diff --git a/src/Polyfill/Nullability/NullabilityInfoExtensions.cs b/src/Polyfill/Nullability/NullabilityInfoExtensions.cs index f3c1f464..66c188b1 100644 --- a/src/Polyfill/Nullability/NullabilityInfoExtensions.cs +++ b/src/Polyfill/Nullability/NullabilityInfoExtensions.cs @@ -81,11 +81,13 @@ public static bool IsNullable(this EventInfo info) } public static NullabilityInfo GetNullabilityInfo(this PropertyInfo info) => - propertyCache.GetOrAdd(info, inner => - { - var context = new NullabilityInfoContext(); - return context.Create(inner); - }); + propertyCache.GetOrAdd( + info, + inner => + { + var context = new NullabilityInfoContext(); + return context.Create(inner); + }); public static NullabilityState GetNullability(this PropertyInfo info) => GetReadOrWriteState(info.GetNullabilityInfo()); diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index a6bdf8dd..3e35efad 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 9f62e8d2..a8c280ec 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -30,7 +30,7 @@ - + diff --git a/src/Shared.sln.DotSettings b/src/Shared.sln.DotSettings index f2dd1f39..7a4ed9eb 100644 --- a/src/Shared.sln.DotSettings +++ b/src/Shared.sln.DotSettings @@ -8,6 +8,7 @@ ERROR WARNING ERROR + ERROR ERROR ERROR ERROR diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 99158943..dec14669 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -30,7 +30,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 53241946..c0fdec48 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -30,7 +30,7 @@ - + From 3214e90e64c889f9431ddd2178d1f6d6e0c9da89 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 21 Jan 2024 20:34:58 +1100 Subject: [PATCH 282/313] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 1fda1170..baa3b4d3 100644 --- a/readme.md +++ b/readme.md @@ -165,7 +165,7 @@ public class Person * [SkipLocalsInitAttribute](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.skiplocalsinitattribute) -Reference: (SkipLocalsInit attribute)(https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/general#skiplocalsinit-attribute) +Reference: [SkipLocalsInitAttribute](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/general#skiplocalsinit-attribute) > the SkipLocalsInit attribute prevents the compiler from setting the .locals init flag when emitting to metadata. The SkipLocalsInit attribute is a single-use attribute and can be applied to a method, a property, a class, a struct, an interface, or a module, but not to an assembly. SkipLocalsInit is an alias for SkipLocalsInitAttribute. From 7b9c906715a1cf927d4ff08d80eb2aeadbd78233 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 21 Jan 2024 20:35:32 +1100 Subject: [PATCH 283/313] Update PolyfillTests_StringBuilder.cs --- src/Tests/PolyfillTests_StringBuilder.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Tests/PolyfillTests_StringBuilder.cs b/src/Tests/PolyfillTests_StringBuilder.cs index adfa4592..e4fde2bc 100644 --- a/src/Tests/PolyfillTests_StringBuilder.cs +++ b/src/Tests/PolyfillTests_StringBuilder.cs @@ -9,19 +9,19 @@ public void StringBuilderCopyTo() var span = new Span(new char[1]); builder.CopyTo(0, span, 1); - Assert.True(span.SequenceEqual("v")); + Assert.True(span is "v"); span = new(new char[1]); builder.CopyTo(1, span, 1); - Assert.True(span.SequenceEqual("a")); + Assert.True(span is "a"); span = new(new char[2]); builder.CopyTo(1, span, 2); - Assert.True(span.SequenceEqual("al")); + Assert.True(span is "al"); span = new(new char[5]); builder.CopyTo(0, span, 5); - Assert.True(span.SequenceEqual("value")); + Assert.True(span is "value"); } [Test] From 904812d113af6f1de9c4f526feaa561f6a2e7cc3 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 21 Jan 2024 20:36:24 +1100 Subject: [PATCH 284/313] Update PolyfillTests_StringBuilder.cs --- src/Tests/PolyfillTests_StringBuilder.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Tests/PolyfillTests_StringBuilder.cs b/src/Tests/PolyfillTests_StringBuilder.cs index e4fde2bc..521c5142 100644 --- a/src/Tests/PolyfillTests_StringBuilder.cs +++ b/src/Tests/PolyfillTests_StringBuilder.cs @@ -59,8 +59,6 @@ public void AppendJoin() Assert(); builder.AppendJoin(',', ["value1", "value2"]); Assert(); - builder.AppendJoin(",", new[]{"value1", "value2"}); - Assert(); void Assert() { From 64771087f20f2c576ec56cca476ce85887741767 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 30 Jan 2024 20:10:02 +1100 Subject: [PATCH 285/313] remove SourceLink --- src/Polyfill/Polyfill.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index 3e35efad..b34a5e3e 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -6,7 +6,6 @@ - From 137884e21d226643b391669fc4223f68e9843631 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 6 Feb 2024 13:51:36 +1100 Subject: [PATCH 286/313] add enum polyfill (#127) --- src/Directory.Build.props | 2 +- src/Polyfill/EnumPolyfill.cs | 46 +++++++++++++++++++++++++++++++++ src/Tests/PolyfillTests_Enum.cs | 16 ++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/Polyfill/EnumPolyfill.cs create mode 100644 src/Tests/PolyfillTests_Enum.cs diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 01fb13f8..edb04e53 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 2.1.0 + 2.2.0 1.0.0 Polyfill true diff --git a/src/Polyfill/EnumPolyfill.cs b/src/Polyfill/EnumPolyfill.cs new file mode 100644 index 00000000..6fc36ddd --- /dev/null +++ b/src/Polyfill/EnumPolyfill.cs @@ -0,0 +1,46 @@ +// + +#pragma warning disable + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using Link = System.ComponentModel.DescriptionAttribute; + +#if PolyPublic +public +#endif +static partial class EnumPolyfill +{ + /// + /// Retrieves an array of the values of the constants in a specified enumeration type. + /// + /// An array that contains the values of the constants in TEnum. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.enum.getvalues")] + public static TEnum[] GetValues() + where TEnum : struct, Enum + { +#if NETCOREAPPX || NETFRAMEWORK || NETSTANDARD + var values = Enum.GetValues(typeof(TEnum)); + var result = new TEnum[values.Length]; + Array.Copy(values, result, values.Length); + return result; +#else + return Enum.GetValues(); +#endif + } + /// + /// Retrieves an array of the names of the constants in a specified enumeration type. + /// + /// A string array of the names of the constants in TEnum. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.enum.getnames")] + public static string[] GetNames() + where TEnum : struct, Enum + { +#if NETCOREAPPX || NETFRAMEWORK || NETSTANDARD + return Enum.GetNames(typeof(TEnum)); +#else + return Enum.GetNames(); +#endif + } +} diff --git a/src/Tests/PolyfillTests_Enum.cs b/src/Tests/PolyfillTests_Enum.cs new file mode 100644 index 00000000..a9f85c88 --- /dev/null +++ b/src/Tests/PolyfillTests_Enum.cs @@ -0,0 +1,16 @@ +partial class PolyfillTests +{ + [Test] + public void EnumGetValues() + { + var dayOfWeeks = EnumPolyfill.GetValues(); + Assert.AreEqual(DayOfWeek.Sunday, dayOfWeeks[0]); + } + + [Test] + public void EnumGetNames() + { + var dayOfWeeks = EnumPolyfill.GetNames(); + Assert.AreEqual("Sunday", dayOfWeeks[0]); + } +} From 8997c5a97677d68bc74dfbe68e6c3f3b874a260a Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 7 Feb 2024 11:22:30 +1100 Subject: [PATCH 287/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 2 +- src/PublicTests/PublicTests.csproj | 2 +- src/Tests/Tests.csproj | 2 +- src/UnsafeTests/UnsafeTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index c4ba16a1..6525cde2 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -35,7 +35,7 @@ - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index a8c280ec..d01e8da4 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -29,7 +29,7 @@ - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index dec14669..279442b8 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -28,7 +28,7 @@ - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index c0fdec48..92ec509b 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -29,7 +29,7 @@ - + From e0d71ecdc1e383bedb726a30cfecd6569ff7c9da Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 10 Feb 2024 19:10:31 +1100 Subject: [PATCH 288/313] fix TextWriter not exposing Write (#128) --- contributing.md | 9 +++++++-- src/Directory.Build.props | 2 +- src/Polyfill/Polyfill_TextWriter.cs | 7 ++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/contributing.md b/contributing.md index 81acdb08..54dead81 100644 --- a/contributing.md +++ b/contributing.md @@ -192,7 +192,7 @@ Example: #pragma warning disable -#if TASKSEXTENSIONSREFERENCED && MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) +#if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; using System.Buffers; @@ -204,6 +204,9 @@ using System.Threading.Tasks; static partial class Polyfill { + +#if TASKSEXTENSIONSREFERENCED + /// /// Asynchronously writes a character memory region to the stream. /// @@ -256,6 +259,8 @@ static partial class Polyfill return new(target.WriteLineAsync(segment.Array!, segment.Offset, segment.Count)); } +#endif + /// /// Writes a character span to the text stream. /// @@ -304,7 +309,7 @@ static partial class Polyfill } #endif ``` -snippet source | anchor +snippet source | anchor diff --git a/src/Directory.Build.props b/src/Directory.Build.props index edb04e53..9e2ca106 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 2.2.0 + 2.2.1 1.0.0 Polyfill true diff --git a/src/Polyfill/Polyfill_TextWriter.cs b/src/Polyfill/Polyfill_TextWriter.cs index 99227cdb..8ccd9d6d 100644 --- a/src/Polyfill/Polyfill_TextWriter.cs +++ b/src/Polyfill/Polyfill_TextWriter.cs @@ -2,7 +2,7 @@ #pragma warning disable -#if TASKSEXTENSIONSREFERENCED && MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) +#if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; using System.Buffers; @@ -14,6 +14,9 @@ static partial class Polyfill { + +#if TASKSEXTENSIONSREFERENCED + /// /// Asynchronously writes a character memory region to the stream. /// @@ -66,6 +69,8 @@ public static ValueTask WriteLineAsync( return new(target.WriteLineAsync(segment.Array!, segment.Offset, segment.Count)); } +#endif + /// /// Writes a character span to the text stream. /// From c07380182252aa6a86256638487ff06547696d18 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 10 Feb 2024 20:18:35 +1100 Subject: [PATCH 289/313] add TimeSpan TryFormat (#129) --- src/Polyfill/Polyfill_TryFormat.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/Polyfill/Polyfill_TryFormat.cs b/src/Polyfill/Polyfill_TryFormat.cs index e7c64ca8..fe03c9ef 100644 --- a/src/Polyfill/Polyfill_TryFormat.cs +++ b/src/Polyfill/Polyfill_TryFormat.cs @@ -12,6 +12,26 @@ static partial class Polyfill { #if MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD || NETCOREAPP2X) + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.timespan.tryformat#system-timespan-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider)")] + public static bool TryFormat(this TimeSpan target, Span destination, out int charsWritten, ReadOnlySpan format = default, IFormatProvider? formatProvider = null) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(null, formatProvider); + } + else + { + result = target.ToString(format.ToString(), formatProvider); + } + + return CopyToSpan(destination, out charsWritten, result); + } + /// /// Tries to format the value of the current instance into the provided span of characters. /// From 5ae146efbdd7fb956cf36ae6128aed9a329d6458 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 10 Feb 2024 20:22:27 +1100 Subject: [PATCH 290/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 9e2ca106..da5a74b2 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 2.2.1 + 2.2.2 1.0.0 Polyfill true From c0f41c699e9dc0b0e55cd8d3186215a5aae08f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20St=C3=BChmer?= Date: Tue, 13 Feb 2024 00:03:32 +0100 Subject: [PATCH 291/313] fix: Added missing `ExcludeFromCodeCoverageAttribute` (#130) * fix: Added missing `ExcludeFromCodeCoverageAttribute` * fix: Added missing using --- src/Polyfill/EnumPolyfill.cs | 1 + .../StringInterpolation/AppendInterpolatedStringHandler.cs | 2 ++ .../StringInterpolation/DefaultInterpolatedStringHandler.cs | 2 ++ 3 files changed, 5 insertions(+) diff --git a/src/Polyfill/EnumPolyfill.cs b/src/Polyfill/EnumPolyfill.cs index 6fc36ddd..c7beb00a 100644 --- a/src/Polyfill/EnumPolyfill.cs +++ b/src/Polyfill/EnumPolyfill.cs @@ -7,6 +7,7 @@ using System.Diagnostics.CodeAnalysis; using Link = System.ComponentModel.DescriptionAttribute; +[ExcludeFromCodeCoverage] #if PolyPublic public #endif diff --git a/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs b/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs index d088b3c0..fa58329e 100644 --- a/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs +++ b/src/Polyfill/StringInterpolation/AppendInterpolatedStringHandler.cs @@ -8,11 +8,13 @@ namespace System.Text; using System.ComponentModel; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; /// Provides a handler used by the language compiler to append interpolated strings into instances. [EditorBrowsable(EditorBrowsableState.Never)] [InterpolatedStringHandler] +[ExcludeFromCodeCoverage] #if PolyPublic public #endif diff --git a/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs b/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs index b15eec55..6120c3b2 100644 --- a/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs +++ b/src/Polyfill/StringInterpolation/DefaultInterpolatedStringHandler.cs @@ -779,6 +779,7 @@ private bool TryFormatWithExtensions(T value, ReadOnlySpan format) } } +[ExcludeFromCodeCoverage] static file class InternalMath { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -806,6 +807,7 @@ private static void ThrowMinMaxException(T min, T max) => throw new ArgumentException(string.Format(SR.Argument_MinMaxValue, min, max)); } +[ExcludeFromCodeCoverage] static file class SR { public const string Argument_MinMaxValue = "'{0}' cannot be greater than {1}."; From 9c7b9fd75592004bd7d31cc53dcb59105a098f80 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 13 Feb 2024 22:33:22 +1100 Subject: [PATCH 292/313] add Guid.TryFormat (#131) --- src/Polyfill/Polyfill_TryFormat.cs | 19 +++++++++++++++++++ src/Tests/PolyfillTests_TryFormat.cs | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/Polyfill/Polyfill_TryFormat.cs b/src/Polyfill/Polyfill_TryFormat.cs index fe03c9ef..f88b8e42 100644 --- a/src/Polyfill/Polyfill_TryFormat.cs +++ b/src/Polyfill/Polyfill_TryFormat.cs @@ -31,6 +31,25 @@ public static bool TryFormat(this TimeSpan target, Span destination, out i return CopyToSpan(destination, out charsWritten, result); } + /// + /// Tries to format the value of the current instance as UTF-8 into the provided span of bytes. + /// + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.guid.tryformat#system-guid-tryformat(system-span((system-char))-system-int32@-system-readonlyspan((system-char)))")] + public static bool TryFormat(this Guid target, Span destination, out int charsWritten, ReadOnlySpan format = default) + { + string result; + + if (format.Length == 0) + { + result = target.ToString(null); + } + else + { + result = target.ToString(format.ToString()); + } + + return CopyToSpan(destination, out charsWritten, result); + } /// /// Tries to format the value of the current instance into the provided span of characters. diff --git a/src/Tests/PolyfillTests_TryFormat.cs b/src/Tests/PolyfillTests_TryFormat.cs index 925c492c..989ddff5 100644 --- a/src/Tests/PolyfillTests_TryFormat.cs +++ b/src/Tests/PolyfillTests_TryFormat.cs @@ -101,6 +101,17 @@ public void TryFormatSingle() Assert.AreEqual(buffer.Length, written); } + [Test] + public void TryFormatGuid() + { + var value = new Guid("97008c2d-2114-4396-ae19-392c8e6f8f1b"); + Span buffer = stackalloc char[36]; + var result = value.TryFormat(buffer, out var written); + Assert.True(result); + Assert.AreEqual("97008c2d-2114-4396-ae19-392c8e6f8f1b", buffer.ToString()); + Assert.AreEqual(buffer.Length, written); + } + [Test] public void TryFormatDouble() { From 750d4293f898f666cb18b463f95e7f5220d88781 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 13 Feb 2024 22:33:48 +1100 Subject: [PATCH 293/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index da5a74b2..34e123c5 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 2.2.2 + 2.3.0 1.0.0 Polyfill true From babc3d7065781fa5a5b9c034f439aa0b655db2a2 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 15 Feb 2024 10:39:57 +1100 Subject: [PATCH 294/313] refs --- src/NoRefsTests/NoRefsTests.csproj | 4 ++-- src/Polyfill/Polyfill.csproj | 2 +- src/PublicTests/PublicTests.csproj | 4 ++-- src/Tests/Tests.csproj | 4 ++-- src/UnsafeTests/UnsafeTests.csproj | 4 ++-- src/global.json | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 6525cde2..caabb2be 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -33,10 +33,10 @@ - + - + \ No newline at end of file diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index b34a5e3e..0bb921e7 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index d01e8da4..3238a158 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -27,10 +27,10 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 279442b8..1c5dd17d 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -26,11 +26,11 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 92ec509b..79edaa84 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -27,10 +27,10 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + - + diff --git a/src/global.json b/src/global.json index b8219f86..450f2b9a 100644 --- a/src/global.json +++ b/src/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.101", + "version": "8.0.200", "allowPrerelease": true, "rollForward": "latestFeature" } From 2323d6eab0dc0a58748819ecbf2eb28cf4984e7d Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 18 Feb 2024 10:11:58 +1100 Subject: [PATCH 295/313] Revert "refs" This reverts commit babc3d7065781fa5a5b9c034f439aa0b655db2a2. --- src/NoRefsTests/NoRefsTests.csproj | 4 ++-- src/Polyfill/Polyfill.csproj | 2 +- src/PublicTests/PublicTests.csproj | 4 ++-- src/Tests/Tests.csproj | 4 ++-- src/UnsafeTests/UnsafeTests.csproj | 4 ++-- src/global.json | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index caabb2be..6525cde2 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -33,10 +33,10 @@ - + - + \ No newline at end of file diff --git a/src/Polyfill/Polyfill.csproj b/src/Polyfill/Polyfill.csproj index 0bb921e7..b34a5e3e 100644 --- a/src/Polyfill/Polyfill.csproj +++ b/src/Polyfill/Polyfill.csproj @@ -5,7 +5,7 @@ Source only packages that exposes newer .net and C# features to older runtimes. - + diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index 3238a158..d01e8da4 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -27,10 +27,10 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + - + diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 1c5dd17d..279442b8 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -26,11 +26,11 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + - + diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 79edaa84..92ec509b 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -27,10 +27,10 @@ Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - + - + diff --git a/src/global.json b/src/global.json index 450f2b9a..b8219f86 100644 --- a/src/global.json +++ b/src/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.200", + "version": "8.0.101", "allowPrerelease": true, "rollForward": "latestFeature" } From 60c41a0e102fea4d7265ac6109ba5298cf5ec4fd Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 18 Feb 2024 14:15:23 +1100 Subject: [PATCH 296/313] add regex IsMatch (#132) --- api_list.include.md | 12 +++++++ readme.md | 6 ++++ src/Directory.Build.props | 2 +- src/Polyfill/Polyfill_RegeEx.cs | 37 +++++++++++++++++++++ src/Polyfill/RegexPolyfill.cs | 59 +++++++++++++++++++++++++++++++++ 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 src/Polyfill/Polyfill_RegeEx.cs create mode 100644 src/Polyfill/RegexPolyfill.cs diff --git a/api_list.include.md b/api_list.include.md index 3600be0c..f078101c 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -70,6 +70,11 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) +### Guid + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.tryformat#system-guid-tryformat(system-span((system-char))-system-int32@-system-readonlyspan((system-char)))) + + ### Int16 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) @@ -207,6 +212,12 @@ * `Boolean TryCopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto) +### RegularExpressions.Regex + + * `Boolean IsMatch(ReadOnlySpan, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-int32)) + * `Boolean IsMatch(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char)))) + + ### StringBuilder * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) @@ -254,6 +265,7 @@ * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds) * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.tryformat#system-timespan-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider)) ### Type diff --git a/readme.md b/readme.md index baa3b4d3..c80e2342 100644 --- a/readme.md +++ b/readme.md @@ -426,6 +426,11 @@ The class `Polyfill` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) +### Guid + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.tryformat#system-guid-tryformat(system-span((system-char))-system-int32@-system-readonlyspan((system-char)))) + + ### Int16 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) @@ -610,6 +615,7 @@ The class `Polyfill` includes the following extension methods: * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds) * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.tryformat#system-timespan-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider)) ### Type diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 34e123c5..f1808941 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 2.3.0 + 2.4.0 1.0.0 Polyfill true diff --git a/src/Polyfill/Polyfill_RegeEx.cs b/src/Polyfill/Polyfill_RegeEx.cs new file mode 100644 index 00000000..48021391 --- /dev/null +++ b/src/Polyfill/Polyfill_RegeEx.cs @@ -0,0 +1,37 @@ +// + +#pragma warning disable + +#if (MEMORYREFERENCED && !NET7_0_OR_GREATER) + +using System; +using System.IO; +using System.Net.Http; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using Link = System.ComponentModel.DescriptionAttribute; + +static partial class Polyfill +{ + /// + /// Indicates whether the regular expression specified in the Regex constructor finds a match in a specified input span. + /// + /// true if the regular expression finds a match; otherwise, false. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-int32)")] + public static bool IsMatch(this Regex target, ReadOnlySpan input, int startat) + { + return target.IsMatch(input.ToString(), startat); + } + + /// + /// Indicates whether the regular expression specified in the Regex constructor finds a match in a specified input span. + /// + /// true if the regular expression finds a match; otherwise, false. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char)))")] + public static bool IsMatch(this Regex target, ReadOnlySpan input) + { + return target.IsMatch(input.ToString()); + } +} +#endif \ No newline at end of file diff --git a/src/Polyfill/RegexPolyfill.cs b/src/Polyfill/RegexPolyfill.cs new file mode 100644 index 00000000..d2373ad2 --- /dev/null +++ b/src/Polyfill/RegexPolyfill.cs @@ -0,0 +1,59 @@ +// + +#pragma warning disable +#if MEMORYREFERENCED +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text.RegularExpressions; +using Link = System.ComponentModel.DescriptionAttribute; + +[ExcludeFromCodeCoverage] +#if PolyPublic +public +#endif +static partial class RegexPolyfill +{ + /// + /// Indicates whether the specified regular expression finds a match in the specified input span, using the specified matching options and time-out interval. + /// + /// true if the regular expression finds a match; otherwise, false. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions-system-timespan)")] + public static bool IsMatch(ReadOnlySpan input, string pattern, RegexOptions options, TimeSpan matchTimeout) + { +#if NET7_0_OR_GREATER + return Regex.IsMatch(input, pattern, options, matchTimeout); +#else + return Regex.IsMatch(input.ToString(), pattern, options, matchTimeout); +#endif + } + + /// + /// Indicates whether the specified regular expression finds a match in the specified input span, using the specified matching options. + /// + /// true if the regular expression finds a match; otherwise, false. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions)")] + public static bool IsMatch(ReadOnlySpan input, string pattern, System.Text.RegularExpressions.RegexOptions options) + { +#if NET7_0_OR_GREATER + return Regex.IsMatch(input, pattern, options); +#else + return Regex.IsMatch(input.ToString(), pattern, options); +#endif + } + + /// + /// Indicates whether the specified regular expression finds a match in the specified input span. + /// + /// true if the regular expression finds a match; otherwise, false. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string)")] + public static bool IsMatch(ReadOnlySpan input, string pattern) + { +#if NET7_0_OR_GREATER + return Regex.IsMatch(input, pattern); +#else + return Regex.IsMatch(input.ToString(), pattern); +#endif + } +} +#endif From bbfd85f32ef97f9b8a22fe7be373dfac7bbda614 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 18 Feb 2024 23:11:24 +1100 Subject: [PATCH 297/313] docs --- api_list.include.md | 379 ++++++++++++++++++++++++++++++++----- readme.md | 383 +++++++++++++++++++++++++++++++++----- src/Tests/BuildApiTest.cs | 109 ++++++++--- 3 files changed, 758 insertions(+), 113 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index f078101c..d4e3b5c6 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -1,19 +1,312 @@ -### Boolean +### Extension methods + +#### Boolean + + * `Boolean TryFormat(Span, Int32&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat) + + +#### Byte + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) + + +#### Dictionary + + * `Boolean Remove(TKey, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) + + +#### IEnumerable + + * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) + * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) + * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) + * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) + * `IEnumerable Except(IEqualityComparer, TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) + * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `TSource MaxBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `TSource MinBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) + * `HashSet ToHashSet(IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.tohashset#system-linq-enumerable-tohashset-1(system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) + + +#### IReadOnlyDictionary + + * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) + * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) + + +#### KeyValuePair + + * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) + + +#### DateTime + + * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryformat) + + +#### DateTimeOffset + + * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tryformat) + + +#### Decimal + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) + + +#### Process + + * `Task WaitForExitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.waitforexitasync) + + +#### Double + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) + + +#### Guid + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.tryformat#system-guid-tryformat(system-span((system-char))-system-int32@-system-readonlyspan((system-char)))) + + +#### Int16 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) + + +#### Int32 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat) + + +#### Int64 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat) + + +#### Stream + + * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) + + +#### TextReader + + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) + * `Task ReadLineAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readlineasync(system-threading-cancellationtoken)) + * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) + + +#### TextWriter + + * `Void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Void WriteLine(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) + * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + + +#### HttpClient + + * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) + * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)) + * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) + * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) + + +#### HttpContent + + * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) + * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) + * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) + + +#### ReadOnlySpan + + * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + + +#### ReadOnlySpan + + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) + + +#### Reflection.EventInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + + +#### Reflection.FieldInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + + +#### Reflection.MemberInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas) + * `Boolean IsNullable()` + + +#### Reflection.ParameterInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + + +#### Reflection.PropertyInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + + +#### SByte + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat) + + +#### Single + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat) + + +#### Span + + * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) + * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) + + +#### Span + + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) + + +#### String + + * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) + * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Void CopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.copyto) + * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) + * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)) + * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)) + * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Boolean TryCopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto) + + +#### RegularExpressions.Regex + + * `Boolean IsMatch(ReadOnlySpan, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-int32)) + * `Boolean IsMatch(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char)))) + + +#### StringBuilder + + * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) + * `StringBuilder Append(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder Append(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendJoin(String, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-string())) + * `StringBuilder AppendJoin(String, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-object())) + * `StringBuilder AppendJoin(Char, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-string())) + * `StringBuilder AppendJoin(Char, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-object())) + * `StringBuilder AppendJoin(Char, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0)))) + * `StringBuilder AppendJoin(String, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0)))) + * `StringBuilder AppendLine(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendLine(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) + * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) + + +#### CancellationToken + + * `CancellationTokenRegistration Register(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.register#system-threading-cancellationtoken-register(system-action((system-object-system-threading-cancellationtoken))-system-object)) + * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object))-system-object)) + * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object-system-threading-cancellationtoken))-system-object)) + + +#### CancellationTokenSource + + * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) + + +#### Task + + * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) + * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)) + * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)) + + +#### Task + + * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) + * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan)) + * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)) + + +#### TimeSpan + + * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds) + * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.tryformat#system-timespan-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider)) + + +#### Type + + * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) + + +#### UInt16 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat) + + +#### UInt32 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat) + + +#### UInt64 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat) + + +### Static helpers +#### Boolean * `Boolean TryFormat(Span, Int32&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat) -### Byte +#### Byte * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) -### Dictionary +#### Dictionary * `Boolean Remove(TKey, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) -### IEnumerable +#### IEnumerable * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) @@ -28,18 +321,18 @@ * `HashSet ToHashSet(IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.tohashset#system-linq-enumerable-tohashset-1(system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) -### IReadOnlyDictionary +#### IReadOnlyDictionary * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) -### KeyValuePair +#### KeyValuePair * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) -### DateTime +#### DateTime * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) @@ -47,7 +340,7 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryformat) -### DateTimeOffset +#### DateTimeOffset * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) @@ -55,56 +348,56 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tryformat) -### Decimal +#### Decimal * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) -### Process +#### Process * `Task WaitForExitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.waitforexitasync) -### Double +#### Double * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) -### Guid +#### Guid * `Boolean TryFormat(Span, Int32&, ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.tryformat#system-guid-tryformat(system-span((system-char))-system-int32@-system-readonlyspan((system-char)))) -### Int16 +#### Int16 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) -### Int32 +#### Int32 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat) -### Int64 +#### Int64 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat) -### Stream +#### Stream * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) -### TextReader +#### TextReader * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) * `Task ReadLineAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readlineasync(system-threading-cancellationtoken)) * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) -### TextWriter +#### TextWriter * `Void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) @@ -112,7 +405,7 @@ * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) -### HttpClient +#### HttpClient * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) @@ -122,40 +415,40 @@ * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) -### HttpContent +#### HttpContent * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) -### ReadOnlySpan +#### ReadOnlySpan * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) -### ReadOnlySpan +#### ReadOnlySpan * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) -### Reflection.EventInfo +#### Reflection.EventInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` -### Reflection.FieldInfo +#### Reflection.FieldInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` -### Reflection.MemberInfo +#### Reflection.MemberInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` @@ -163,43 +456,43 @@ * `Boolean IsNullable()` -### Reflection.ParameterInfo +#### Reflection.ParameterInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` -### Reflection.PropertyInfo +#### Reflection.PropertyInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` -### SByte +#### SByte * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat) -### Single +#### Single * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat) -### Span +#### Span * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) -### Span +#### Span * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) -### String +#### String * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) @@ -212,13 +505,13 @@ * `Boolean TryCopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto) -### RegularExpressions.Regex +#### RegularExpressions.Regex * `Boolean IsMatch(ReadOnlySpan, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-int32)) * `Boolean IsMatch(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char)))) -### StringBuilder +#### StringBuilder * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) * `StringBuilder Append(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) @@ -235,55 +528,55 @@ * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) -### CancellationToken +#### CancellationToken * `CancellationTokenRegistration Register(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.register#system-threading-cancellationtoken-register(system-action((system-object-system-threading-cancellationtoken))-system-object)) * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object))-system-object)) * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object-system-threading-cancellationtoken))-system-object)) -### CancellationTokenSource +#### CancellationTokenSource * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) -### Task +#### Task * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)) * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)) -### Task +#### Task * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan)) * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)) -### TimeSpan +#### TimeSpan * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds) * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.tryformat#system-timespan-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider)) -### Type +#### Type * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) -### UInt16 +#### UInt16 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat) -### UInt32 +#### UInt32 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat) -### UInt64 +#### UInt64 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat) diff --git a/readme.md b/readme.md index c80e2342..d3e6ac6f 100644 --- a/readme.md +++ b/readme.md @@ -354,22 +354,24 @@ The class `Polyfill` includes the following extension methods: > The methods using `AppendInterpolatedStringHandler` parameter are not extensions because the compiler prefers to use the overload with `string` parameter instead. -### Boolean +### Extension methods + +#### Boolean * `Boolean TryFormat(Span, Int32&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat) -### Byte +#### Byte * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) -### Dictionary +#### Dictionary * `Boolean Remove(TKey, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) -### IEnumerable +#### IEnumerable * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) @@ -384,18 +386,18 @@ The class `Polyfill` includes the following extension methods: * `HashSet ToHashSet(IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.tohashset#system-linq-enumerable-tohashset-1(system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) -### IReadOnlyDictionary +#### IReadOnlyDictionary * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) -### KeyValuePair +#### KeyValuePair * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) -### DateTime +#### DateTime * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) @@ -403,7 +405,7 @@ The class `Polyfill` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryformat) -### DateTimeOffset +#### DateTimeOffset * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) @@ -411,56 +413,56 @@ The class `Polyfill` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tryformat) -### Decimal +#### Decimal * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) -### Process +#### Process * `Task WaitForExitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.waitforexitasync) -### Double +#### Double * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) -### Guid +#### Guid * `Boolean TryFormat(Span, Int32&, ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.tryformat#system-guid-tryformat(system-span((system-char))-system-int32@-system-readonlyspan((system-char)))) -### Int16 +#### Int16 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) -### Int32 +#### Int32 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat) -### Int64 +#### Int64 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat) -### Stream +#### Stream * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) -### TextReader +#### TextReader * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) * `Task ReadLineAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readlineasync(system-threading-cancellationtoken)) * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) -### TextWriter +#### TextWriter * `Void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) @@ -468,7 +470,7 @@ The class `Polyfill` includes the following extension methods: * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) -### HttpClient +#### HttpClient * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) @@ -478,40 +480,40 @@ The class `Polyfill` includes the following extension methods: * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) -### HttpContent +#### HttpContent * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) -### ReadOnlySpan +#### ReadOnlySpan * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) -### ReadOnlySpan +#### ReadOnlySpan * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) -### Reflection.EventInfo +#### Reflection.EventInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` -### Reflection.FieldInfo +#### Reflection.FieldInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` -### Reflection.MemberInfo +#### Reflection.MemberInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` @@ -519,43 +521,43 @@ The class `Polyfill` includes the following extension methods: * `Boolean IsNullable()` -### Reflection.ParameterInfo +#### Reflection.ParameterInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` -### Reflection.PropertyInfo +#### Reflection.PropertyInfo * `Reflection.NullabilityState GetNullability()` * `Reflection.NullabilityInfo GetNullabilityInfo()` * `Boolean IsNullable()` -### SByte +#### SByte * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat) -### Single +#### Single * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat) -### Span +#### Span * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) -### Span +#### Span * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) -### String +#### String * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) @@ -568,7 +570,304 @@ The class `Polyfill` includes the following extension methods: * `Boolean TryCopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto) -### StringBuilder +#### RegularExpressions.Regex + + * `Boolean IsMatch(ReadOnlySpan, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-int32)) + * `Boolean IsMatch(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char)))) + + +#### StringBuilder + + * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) + * `StringBuilder Append(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder Append(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendJoin(String, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-string())) + * `StringBuilder AppendJoin(String, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-object())) + * `StringBuilder AppendJoin(Char, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-string())) + * `StringBuilder AppendJoin(Char, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-object())) + * `StringBuilder AppendJoin(Char, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0)))) + * `StringBuilder AppendJoin(String, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0)))) + * `StringBuilder AppendLine(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendLine(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) + * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) + + +#### CancellationToken + + * `CancellationTokenRegistration Register(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.register#system-threading-cancellationtoken-register(system-action((system-object-system-threading-cancellationtoken))-system-object)) + * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object))-system-object)) + * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object-system-threading-cancellationtoken))-system-object)) + + +#### CancellationTokenSource + + * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) + + +#### Task + + * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) + * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)) + * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)) + + +#### Task + + * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) + * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan)) + * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)) + + +#### TimeSpan + + * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds) + * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.tryformat#system-timespan-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider)) + + +#### Type + + * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) + + +#### UInt16 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat) + + +#### UInt32 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat) + + +#### UInt64 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat) + + +### Static helpers +#### Boolean + + * `Boolean TryFormat(Span, Int32&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat) + + +#### Byte + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) + + +#### Dictionary + + * `Boolean Remove(TKey, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) + + +#### IEnumerable + + * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) + * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) + * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) + * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) + * `IEnumerable Except(IEqualityComparer, TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) + * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `TSource MaxBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) + * `TSource MinBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) + * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) + * `HashSet ToHashSet(IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.tohashset#system-linq-enumerable-tohashset-1(system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) + + +#### IReadOnlyDictionary + + * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) + * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) + + +#### KeyValuePair + + * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) + + +#### DateTime + + * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryformat) + + +#### DateTimeOffset + + * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) + * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) + * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond) + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tryformat) + + +#### Decimal + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) + + +#### Process + + * `Task WaitForExitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.waitforexitasync) + + +#### Double + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) + + +#### Guid + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.tryformat#system-guid-tryformat(system-span((system-char))-system-int32@-system-readonlyspan((system-char)))) + + +#### Int16 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) + + +#### Int32 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat) + + +#### Int64 + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat) + + +#### Stream + + * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) + + +#### TextReader + + * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) + * `Task ReadLineAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readlineasync(system-threading-cancellationtoken)) + * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) + + +#### TextWriter + + * `Void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) + * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + * `Void WriteLine(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) + * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) + + +#### HttpClient + + * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) + * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)) + * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)) + * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) + * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) + + +#### HttpContent + + * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) + * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) + * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) + + +#### ReadOnlySpan + + * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) + + +#### ReadOnlySpan + + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) + + +#### Reflection.EventInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + + +#### Reflection.FieldInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + + +#### Reflection.MemberInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas) + * `Boolean IsNullable()` + + +#### Reflection.ParameterInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + + +#### Reflection.PropertyInfo + + * `Reflection.NullabilityState GetNullability()` + * `Reflection.NullabilityInfo GetNullabilityInfo()` + * `Boolean IsNullable()` + + +#### SByte + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat) + + +#### Single + + * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat) + + +#### Span + + * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) + * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) + * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) + + +#### Span + + * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) + + +#### String + + * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) + * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Void CopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.copyto) + * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) + * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)) + * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)) + * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) + * `Boolean TryCopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto) + + +#### RegularExpressions.Regex + + * `Boolean IsMatch(ReadOnlySpan, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-int32)) + * `Boolean IsMatch(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char)))) + + +#### StringBuilder * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) * `StringBuilder Append(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) @@ -585,55 +884,55 @@ The class `Polyfill` includes the following extension methods: * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) -### CancellationToken +#### CancellationToken * `CancellationTokenRegistration Register(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.register#system-threading-cancellationtoken-register(system-action((system-object-system-threading-cancellationtoken))-system-object)) * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object))-system-object)) * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object-system-threading-cancellationtoken))-system-object)) -### CancellationTokenSource +#### CancellationTokenSource * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) -### Task +#### Task * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)) * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)) -### Task +#### Task * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan)) * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)) -### TimeSpan +#### TimeSpan * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds) * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.tryformat#system-timespan-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider)) -### Type +#### Type * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) -### UInt16 +#### UInt16 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat) -### UInt32 +#### UInt32 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat) -### UInt64 +#### UInt64 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat) diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index 34a9ade6..258d6eb4 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -1,3 +1,6 @@ +using System.Diagnostics.CodeAnalysis; +using Mono.Cecil; + #if NET8_0 && DEBUG [TestFixture] class BuildApiTest @@ -21,10 +24,12 @@ public void Run() var path = Path.Combine(solutionDirectory, "Consume", "bin", "Debug", "netstandard2.0", "Consume.dll"); var md = Path.Combine(solutionDirectory, "..", "api_list.include.md"); File.Delete(md); - using var module = Mono.Cecil.ModuleDefinition.ReadModule(path); + using var module = ModuleDefinition.ReadModule(path); var extensions = module.GetTypes().Single(_ => _.Name == nameof(Polyfill)); using var writer = File.CreateText(md); + writer.WriteLine($"### Extension methods"); + writer.WriteLine(); foreach (var type in extensions.Methods .Where(_ => !_.IsConstructor) .GroupBy(_ => _.Parameters[0].ParameterType.FullName) @@ -37,33 +42,33 @@ public void Run() var targetType = type.Key; var targetFullName = targetType.Replace("`1", "").Replace("`2", ""); - writer.WriteLine($"### {SimpleTypeName(targetFullName)}"); + writer.WriteLine($"#### {GetTypeName(targetFullName)}"); + writer.WriteLine(); + foreach (var method in PublicMethods(type)) + { + WriteSignature(method, writer); + } + + writer.WriteLine(); + writer.WriteLine(); + } + writer.WriteLine($"### Static helpers"); + foreach (var type in extensions.Methods + .Where(_ => !_.IsConstructor) + .GroupBy(_ => _.Parameters[0].ParameterType.FullName) + .OrderBy(_ => _.Key)) + { + if (!type.Any(_ => _.IsPublic)) + { + continue; + } + + var targetType = type.Key; + writer.WriteLine($"#### {GetTypeName(targetType)}"); writer.WriteLine(); - foreach (var method in type.OrderBy(_ => _.Name)) + foreach (var method in PublicMethods(type)) { - if (!method.IsPublic) - { - continue; - } - - var parameters = string.Join(", ", method.Parameters.Skip(1).Select(_ => SimpleTypeName(_.ParameterType.FullName))); - var typeArgs = ""; - if (method.HasGenericParameters) - { - typeArgs = $"<{string.Join(", ", method.GenericParameters.Select(_ => _.Name))}>"; - } - - var signature = $"{SimpleTypeName(method.ReturnType.FullName)} {method.Name}{typeArgs}({parameters})"; - var descriptionAttribute = method.CustomAttributes - .SingleOrDefault(_ => _.AttributeType.Name == "DescriptionAttribute"); - if (descriptionAttribute == null) - { - writer.WriteLine($" * `{signature}`"); - } - else - { - writer.WriteLine($" * `{signature}` [reference]({descriptionAttribute.ConstructorArguments.Single().Value})"); - } + WriteSignature(method, writer); } writer.WriteLine(); @@ -71,9 +76,10 @@ public void Run() } } - static string SimpleTypeName(string fullName) + static string GetTypeName(string targetType) { - var name = fullName.Replace("`1", "").Replace("`2", ""); + var targetFullName = targetType.Replace("`1", "").Replace("`2", ""); + var name = targetFullName.Replace("`1", "").Replace("`2", ""); foreach (var toClean in namespacesToClean) { name = name.Replace(toClean, ""); @@ -81,5 +87,52 @@ static string SimpleTypeName(string fullName) return name; } + + static IEnumerable PublicMethods(IEnumerable type) => + type.Where(_=>_.IsPublic) + .OrderBy(_ => _.Name); + + static void WriteSignature(MethodDefinition method, StreamWriter writer) + { + var parameters = BuildParameters(method); + var typeArgs = BuildTypeArgs(method); + var signature = $"{GetTypeName(method.ReturnType.FullName)} {method.Name}{typeArgs}({parameters})"; + if (TryGetReference(method, out var reference)) + { + writer.WriteLine($" * `{signature}` [reference]({reference})"); + } + else + { + writer.WriteLine($" * `{signature}`"); + } + } + + static string BuildParameters(MethodDefinition method) => + string.Join(", ", method.Parameters.Skip(1).Select(_ => GetTypeName(_.ParameterType.FullName))); + + static string BuildTypeArgs(MethodDefinition method) + { + var typeArgs = ""; + if (method.HasGenericParameters) + { + typeArgs = $"<{string.Join(", ", method.GenericParameters.Select(_ => _.Name))}>"; + } + + return typeArgs; + } + + static bool TryGetReference(MethodDefinition method,[NotNullWhen(true)] out string? reference) + { + var descriptionAttribute = method.CustomAttributes + .SingleOrDefault(_ => _.AttributeType.Name == "DescriptionAttribute"); + if (descriptionAttribute == null) + { + reference = null; + return false; + } + + reference = (string) descriptionAttribute.ConstructorArguments.Single().Value!; + return true; + } } #endif \ No newline at end of file From 5f8e6da3130426ed9854ee5db25acce5f3cb88d2 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 18 Feb 2024 23:14:48 +1100 Subject: [PATCH 298/313] docs --- api_list.include.md | 291 -------------------------------------- readme.md | 291 -------------------------------------- src/Tests/BuildApiTest.cs | 38 +---- 3 files changed, 4 insertions(+), 616 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index d4e3b5c6..46e0db11 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -290,294 +290,3 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat) -### Static helpers -#### Boolean - - * `Boolean TryFormat(Span, Int32&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat) - - -#### Byte - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) - - -#### Dictionary - - * `Boolean Remove(TKey, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) - - -#### IEnumerable - - * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) - * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) - * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) - * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) - * `IEnumerable Except(IEqualityComparer, TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) - * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) - * `TSource MaxBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) - * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) - * `TSource MinBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) - * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) - * `HashSet ToHashSet(IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.tohashset#system-linq-enumerable-tohashset-1(system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) - - -#### IReadOnlyDictionary - - * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) - * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) - - -#### KeyValuePair - - * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) - - -#### DateTime - - * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) - * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) - * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond) - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryformat) - - -#### DateTimeOffset - - * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) - * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) - * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond) - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tryformat) - - -#### Decimal - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) - - -#### Process - - * `Task WaitForExitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.waitforexitasync) - - -#### Double - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) - - -#### Guid - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.tryformat#system-guid-tryformat(system-span((system-char))-system-int32@-system-readonlyspan((system-char)))) - - -#### Int16 - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) - - -#### Int32 - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat) - - -#### Int64 - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat) - - -#### Stream - - * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) - - -#### TextReader - - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) - * `Task ReadLineAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readlineasync(system-threading-cancellationtoken)) - * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) - - -#### TextWriter - - * `Void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Void WriteLine(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) - * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - - -#### HttpClient - - * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) - * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) - * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)) - * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)) - * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) - * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) - - -#### HttpContent - - * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) - * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) - * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) - - -#### ReadOnlySpan - - * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - - -#### ReadOnlySpan - - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) - - -#### Reflection.EventInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean IsNullable()` - - -#### Reflection.FieldInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean IsNullable()` - - -#### Reflection.MemberInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas) - * `Boolean IsNullable()` - - -#### Reflection.ParameterInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean IsNullable()` - - -#### Reflection.PropertyInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean IsNullable()` - - -#### SByte - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat) - - -#### Single - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat) - - -#### Span - - * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) - * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) - * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) - - -#### Span - - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) - - -#### String - - * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) - * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) - * `Void CopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.copyto) - * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) - * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) - * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)) - * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)) - * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) - * `Boolean TryCopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto) - - -#### RegularExpressions.Regex - - * `Boolean IsMatch(ReadOnlySpan, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-int32)) - * `Boolean IsMatch(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char)))) - - -#### StringBuilder - - * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) - * `StringBuilder Append(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) - * `StringBuilder Append(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) - * `StringBuilder AppendJoin(String, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-string())) - * `StringBuilder AppendJoin(String, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-object())) - * `StringBuilder AppendJoin(Char, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-string())) - * `StringBuilder AppendJoin(Char, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-object())) - * `StringBuilder AppendJoin(Char, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0)))) - * `StringBuilder AppendJoin(String, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0)))) - * `StringBuilder AppendLine(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) - * `StringBuilder AppendLine(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) - * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) - * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) - - -#### CancellationToken - - * `CancellationTokenRegistration Register(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.register#system-threading-cancellationtoken-register(system-action((system-object-system-threading-cancellationtoken))-system-object)) - * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object))-system-object)) - * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object-system-threading-cancellationtoken))-system-object)) - - -#### CancellationTokenSource - - * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) - - -#### Task - - * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) - * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)) - * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)) - - -#### Task - - * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) - * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan)) - * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)) - - -#### TimeSpan - - * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds) - * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.tryformat#system-timespan-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider)) - - -#### Type - - * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) - - -#### UInt16 - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat) - - -#### UInt32 - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat) - - -#### UInt64 - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat) - - diff --git a/readme.md b/readme.md index d3e6ac6f..669b2fd4 100644 --- a/readme.md +++ b/readme.md @@ -641,297 +641,6 @@ The class `Polyfill` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat) -#### UInt64 - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat) - - -### Static helpers -#### Boolean - - * `Boolean TryFormat(Span, Int32&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.boolean.tryformat) - - -#### Byte - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) - - -#### Dictionary - - * `Boolean Remove(TKey, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) - - -#### IEnumerable - - * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) - * `IEnumerable Except(TSource)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) - * `IEnumerable Except(TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except?view=net-8.0#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0)))) - * `IEnumerable Except(TSource, IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) - * `IEnumerable Except(IEqualityComparer, TSource[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.except#system-linq-enumerable-except-1(system-collections-generic-ienumerable((-0))-system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) - * `TSource MaxBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) - * `TSource MaxBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.maxby?view=net-8.0#system-linq-enumerable-maxby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) - * `TSource MinBy(Func)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1)))) - * `TSource MinBy(Func, IComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.minby?view=net-8.0#system-linq-enumerable-minby-2(system-collections-generic-ienumerable((-0))-system-func((-0-1))-system-collections-generic-icomparer((-1)))) - * `IEnumerable SkipLast(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast) - * `HashSet ToHashSet(IEqualityComparer)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.tohashset#system-linq-enumerable-tohashset-1(system-collections-generic-ienumerable((-0))-system-collections-generic-iequalitycomparer((-0)))) - - -#### IReadOnlyDictionary - - * `TValue GetValueOrDefault(TKey)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault) - * `TValue GetValueOrDefault(TKey, TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.collectionextensions.getvalueordefault#system-collections-generic-collectionextensions-getvalueordefault-2(system-collections-generic-ireadonlydictionary((-0-1))-0-1)) - - -#### KeyValuePair - - * `Void Deconstruct(TKey&, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct) - - -#### DateTime - - * `DateTime AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.addmicroseconds) - * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.microsecond) - * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.nanosecond) - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.tryformat) - - -#### DateTimeOffset - - * `DateTimeOffset AddMicroseconds(Double)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.addmicroseconds) - * `Int32 Microsecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.microsecond) - * `Int32 Nanosecond()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.nanosecond) - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset.tryformat) - - -#### Decimal - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) - - -#### Process - - * `Task WaitForExitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.waitforexitasync) - - -#### Double - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) - - -#### Guid - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.guid.tryformat#system-guid-tryformat(system-span((system-char))-system-int32@-system-readonlyspan((system-char)))) - - -#### Int16 - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int16.tryformat) - - -#### Int32 - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int32.tryformat) - - -#### Int64 - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.int64.tryformat) - - -#### Stream - - * `Task CopyToAsync(Stream, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.copytoasync#system-io-stream-copytoasync(system-io-stream-system-threading-cancellationtoken)) - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.readasync#system-io-stream-readasync(system-memory((system-byte))-system-threading-cancellationtoken)) - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.stream.writeasync#system-io-stream-writeasync(system-readonlymemory((system-byte))-system-threading-cancellationtoken)) - - -#### TextReader - - * `ValueTask ReadAsync(Memory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readasync#system-io-textreader-readasync(system-memory((system-char))-system-threading-cancellationtoken)) - * `Task ReadLineAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readlineasync(system-threading-cancellationtoken)) - * `Task ReadToEndAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textreader.readtoendasync#system-io-textreader-readtoendasync(system-threading-cancellationtoken)) - - -#### TextWriter - - * `Void Write(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.write#system-io-textwriter-write(system-readonlyspan((system-char)))) - * `ValueTask WriteAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeasync#system-io-textwriter-writeasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - * `Void WriteLine(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writeline#system-io-textwriter-writeline(system-readonlyspan((system-char)))) - * `ValueTask WriteLineAsync(ReadOnlyMemory, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.io.textwriter.writelineasync#system-io-textwriter-writelineasync(system-readonlymemory((system-char))-system-threading-cancellationtoken)) - - -#### HttpClient - - * `Task GetByteArrayAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-string-system-threading-cancellationtoken)) - * `Task GetByteArrayAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getbytearrayasync#system-net-http-httpclient-getbytearrayasync(system-uri-system-threading-cancellationtoken)) - * `Task GetStreamAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-string-system-threading-cancellationtoken)) - * `Task GetStreamAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstreamasync#system-net-http-httpclient-getstreamasync(system-uri-system-threading-cancellationtoken)) - * `Task GetStringAsync(String, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-string-system-threading-cancellationtoken)) - * `Task GetStringAsync(Uri, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclient.getstringasync#system-net-http-httpclient-getstringasync(system-uri-system-threading-cancellationtoken)) - - -#### HttpContent - - * `Task ReadAsByteArrayAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasbytearrayasync#system-net-http-httpcontent-readasbytearrayasync(system-threading-cancellationtoken)) - * `Task ReadAsStreamAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstreamasync#system-net-http-httpcontent-readasstreamasync(system-threading-cancellationtoken)) - * `Task ReadAsStringAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpcontent.readasstringasync#system-net-http-httpcontent-readasstringasync(system-threading-cancellationtoken)) - - -#### ReadOnlySpan - - * `Boolean EndsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - * `Boolean StartsWith(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-readonlyspan((-0))-system-readonlyspan((-0)))) - - -#### ReadOnlySpan - - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-readonlyspan((-0))-0)) - - -#### Reflection.EventInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean IsNullable()` - - -#### Reflection.FieldInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean IsNullable()` - - -#### Reflection.MemberInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean HasSameMetadataDefinitionAs(Reflection.MemberInfo)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.reflection.memberinfo.hassamemetadatadefinitionas) - * `Boolean IsNullable()` - - -#### Reflection.ParameterInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean IsNullable()` - - -#### Reflection.PropertyInfo - - * `Reflection.NullabilityState GetNullability()` - * `Reflection.NullabilityInfo GetNullabilityInfo()` - * `Boolean IsNullable()` - - -#### SByte - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.sbyte.tryformat) - - -#### Single - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.single.tryformat) - - -#### Span - - * `Boolean EndsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.endswith#system-memoryextensions-endswith-1(system-span((-0))-system-readonlyspan((-0)))) - * `Boolean SequenceEqual(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sequenceequal#system-memoryextensions-sequenceequal-1(system-span((-0))-system-readonlyspan((-0)))) - * `Boolean StartsWith(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.startswith#system-memoryextensions-startswith-1(system-span((-0))-system-readonlyspan((-0)))) - - -#### Span - - * `Boolean Contains(T)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains#system-memoryextensions-contains-1(system-span((-0))-0)) - - -#### String - - * `Boolean Contains(String, StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-string-system-stringcomparison)) - * `Boolean Contains(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) - * `Void CopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.copyto) - * `Boolean EndsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) - * `Int32 GetHashCode(StringComparison)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.gethashcode#system-string-gethashcode(system-stringcomparison)) - * `String[] Split(Char, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-stringsplitoptions)) - * `String[] Split(Char, Int32, StringSplitOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.split#system-string-split(system-char-system-int32-system-stringsplitoptions)) - * `Boolean StartsWith(Char)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.contains#system-string-contains(system-char)) - * `Boolean TryCopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto) - - -#### RegularExpressions.Regex - - * `Boolean IsMatch(ReadOnlySpan, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-int32)) - * `Boolean IsMatch(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char)))) - - -#### StringBuilder - - * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) - * `StringBuilder Append(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) - * `StringBuilder Append(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) - * `StringBuilder AppendJoin(String, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-string())) - * `StringBuilder AppendJoin(String, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-object())) - * `StringBuilder AppendJoin(Char, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-string())) - * `StringBuilder AppendJoin(Char, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-object())) - * `StringBuilder AppendJoin(Char, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0)))) - * `StringBuilder AppendJoin(String, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0)))) - * `StringBuilder AppendLine(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) - * `StringBuilder AppendLine(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) - * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) - * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) - - -#### CancellationToken - - * `CancellationTokenRegistration Register(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.register#system-threading-cancellationtoken-register(system-action((system-object-system-threading-cancellationtoken))-system-object)) - * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object))-system-object)) - * `CancellationTokenRegistration UnsafeRegister(Action, Object)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.unsaferegister#system-threading-cancellationtoken-unsaferegister(system-action((system-object-system-threading-cancellationtoken))-system-object)) - - -#### CancellationTokenSource - - * `Task CancelAsync()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtokensource.cancelasync) - - -#### Task - - * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) - * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan)) - * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-timespan-system-threading-cancellationtoken)) - - -#### Task - - * `Task WaitAsync(CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.waitasync#system-threading-tasks-task-waitasync(system-threading-cancellationtoken)) - * `Task WaitAsync(TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan)) - * `Task WaitAsync(TimeSpan, CancellationToken)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1.waitasync#system-threading-tasks-task-1-waitasync(system-timespan-system-threading-cancellationtoken)) - - -#### TimeSpan - - * `Int32 Microseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.microseconds) - * `Int32 Nanoseconds()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.nanoseconds) - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.timespan.tryformat#system-timespan-tryformat(system-span((system-byte))-system-int32@-system-readonlyspan((system-char))-system-iformatprovider)) - - -#### Type - - * `Boolean IsGenericMethodParameter()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.type.isgenericmethodparameter) - - -#### UInt16 - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint16.tryformat) - - -#### UInt32 - - * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint32.tryformat) - - #### UInt64 * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat) diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index 258d6eb4..582708c6 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -30,43 +30,14 @@ public void Run() writer.WriteLine($"### Extension methods"); writer.WriteLine(); - foreach (var type in extensions.Methods + foreach (var type in PublicMethods(extensions.Methods) .Where(_ => !_.IsConstructor) .GroupBy(_ => _.Parameters[0].ParameterType.FullName) .OrderBy(_ => _.Key)) { - if (!type.Any(_ => _.IsPublic)) - { - continue; - } - - var targetType = type.Key; - var targetFullName = targetType.Replace("`1", "").Replace("`2", ""); - writer.WriteLine($"#### {GetTypeName(targetFullName)}"); - writer.WriteLine(); - foreach (var method in PublicMethods(type)) - { - WriteSignature(method, writer); - } - - writer.WriteLine(); - writer.WriteLine(); - } - writer.WriteLine($"### Static helpers"); - foreach (var type in extensions.Methods - .Where(_ => !_.IsConstructor) - .GroupBy(_ => _.Parameters[0].ParameterType.FullName) - .OrderBy(_ => _.Key)) - { - if (!type.Any(_ => _.IsPublic)) - { - continue; - } - - var targetType = type.Key; - writer.WriteLine($"#### {GetTypeName(targetType)}"); + writer.WriteLine($"#### {GetTypeName(type.Key)}"); writer.WriteLine(); - foreach (var method in PublicMethods(type)) + foreach (var method in type) { WriteSignature(method, writer); } @@ -78,8 +49,7 @@ public void Run() static string GetTypeName(string targetType) { - var targetFullName = targetType.Replace("`1", "").Replace("`2", ""); - var name = targetFullName.Replace("`1", "").Replace("`2", ""); + var name = targetType.Replace("`1", "").Replace("`2", ""); foreach (var toClean in namespacesToClean) { name = name.Replace(toClean, ""); From 797362fc86968a639068467258a30d1d70509191 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 18 Feb 2024 23:16:09 +1100 Subject: [PATCH 299/313] Update BuildApiTest.cs --- src/Tests/BuildApiTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index 582708c6..5fc39ee8 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -31,7 +31,6 @@ public void Run() writer.WriteLine($"### Extension methods"); writer.WriteLine(); foreach (var type in PublicMethods(extensions.Methods) - .Where(_ => !_.IsConstructor) .GroupBy(_ => _.Parameters[0].ParameterType.FullName) .OrderBy(_ => _.Key)) { @@ -59,7 +58,7 @@ static string GetTypeName(string targetType) } static IEnumerable PublicMethods(IEnumerable type) => - type.Where(_=>_.IsPublic) + type.Where(_=>_ is {IsPublic: true, IsConstructor: false}) .OrderBy(_ => _.Name); static void WriteSignature(MethodDefinition method, StreamWriter writer) From 2a4b91af972a4798135c2a333dd81e2eedcfcc3e Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 18 Feb 2024 23:33:07 +1100 Subject: [PATCH 300/313] docs --- api_list.include.md | 15 +++++++++++++++ readme.md | 15 +++++++++++++++ src/Tests/BuildApiTest.cs | 22 +++++++++++++++++++++- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/api_list.include.md b/api_list.include.md index 46e0db11..0582421f 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -290,3 +290,18 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat) +### Static helpers + +#### EnumPolyfill + + * `String[] GetNames()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.enum.getnames) + * `TEnum[] GetValues()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.enum.getvalues) + + +#### RegexPolyfill + + * `Boolean IsMatch(String, RegularExpressions.RegexOptions, TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions-system-timespan)) + * `Boolean IsMatch(String, RegularExpressions.RegexOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions)) + * `Boolean IsMatch(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string)) + + diff --git a/readme.md b/readme.md index 669b2fd4..31528d5a 100644 --- a/readme.md +++ b/readme.md @@ -645,6 +645,21 @@ The class `Polyfill` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.uint64.tryformat) + +### Static helpers + +#### EnumPolyfill + + * `String[] GetNames()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.enum.getnames) + * `TEnum[] GetValues()` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.enum.getvalues) + + +#### RegexPolyfill + + * `Boolean IsMatch(String, RegularExpressions.RegexOptions, TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions-system-timespan)) + * `Boolean IsMatch(String, RegularExpressions.RegexOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions)) + * `Boolean IsMatch(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string)) + diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index 5fc39ee8..9691521e 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -25,7 +25,8 @@ public void Run() var md = Path.Combine(solutionDirectory, "..", "api_list.include.md"); File.Delete(md); using var module = ModuleDefinition.ReadModule(path); - var extensions = module.GetTypes().Single(_ => _.Name == nameof(Polyfill)); + var types = module.GetTypes().ToList(); + var extensions = types.Single(_ => _.Name == nameof(Polyfill)); using var writer = File.CreateText(md); writer.WriteLine($"### Extension methods"); @@ -44,6 +45,25 @@ public void Run() writer.WriteLine(); writer.WriteLine(); } + writer.WriteLine($"### Static helpers"); + writer.WriteLine(); + + WriteHelper(types, nameof(EnumPolyfill), writer); + WriteHelper(types, "RegexPolyfill", writer); + } + + static void WriteHelper(List types, string name, StreamWriter writer) + { + var helper = types.Single(_ => _.Name == name); + + writer.WriteLine($"#### {helper.Name}"); + writer.WriteLine(); + foreach (var method in PublicMethods(helper.Methods)) + { + WriteSignature(method, writer); + } + writer.WriteLine(); + writer.WriteLine(); } static string GetTypeName(string targetType) From d9b4ec8c8ee60450c1b9bff97eb80237054ec314 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 19 Feb 2024 18:36:34 +1100 Subject: [PATCH 301/313] cleanup --- src/Consume/Consume.csproj | 24 ++---------------- .../ConsumeClassicReferences.csproj | 24 ++---------------- src/ConsumeIndirect/ConsumeIndirect.csproj | 25 ++----------------- src/ConsumeNoRefs/ConsumeNoRefs.csproj | 24 ++---------------- .../ConsumeTasksWithNoMemory.csproj | 21 ++-------------- src/NoRefsTests/NoRefsTests.csproj | 24 ++---------------- src/PublicTests/PublicTests.csproj | 24 ++---------------- src/TestIncludes.targets | 25 +++++++++++++++++++ src/Tests/Tests.csproj | 24 ++---------------- src/UnsafeTests/UnsafeTests.csproj | 24 ++---------------- 10 files changed, 43 insertions(+), 196 deletions(-) create mode 100644 src/TestIncludes.targets diff --git a/src/Consume/Consume.csproj b/src/Consume/Consume.csproj index 1a628e17..cf5c25bf 100644 --- a/src/Consume/Consume.csproj +++ b/src/Consume/Consume.csproj @@ -9,27 +9,7 @@ - - Pollyfill\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs - - - Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs - - - Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs - - - Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - - + + \ No newline at end of file diff --git a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj index c609c5b0..0d6d46da 100644 --- a/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj +++ b/src/ConsumeClassicReferences/ConsumeClassicReferences.csproj @@ -10,27 +10,7 @@ - - Pollyfill\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs - - - Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs - - - Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs - - - Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - - + + \ No newline at end of file diff --git a/src/ConsumeIndirect/ConsumeIndirect.csproj b/src/ConsumeIndirect/ConsumeIndirect.csproj index d0bd1013..e121f76f 100644 --- a/src/ConsumeIndirect/ConsumeIndirect.csproj +++ b/src/ConsumeIndirect/ConsumeIndirect.csproj @@ -10,28 +10,7 @@ - - Pollyfill\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs - - - Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs - - - Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs - - - Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - - - + + \ No newline at end of file diff --git a/src/ConsumeNoRefs/ConsumeNoRefs.csproj b/src/ConsumeNoRefs/ConsumeNoRefs.csproj index cbbfe582..b3ff55de 100644 --- a/src/ConsumeNoRefs/ConsumeNoRefs.csproj +++ b/src/ConsumeNoRefs/ConsumeNoRefs.csproj @@ -6,27 +6,7 @@ - - Pollyfill\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs - - - Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs - - - Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs - - - Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - - + + \ No newline at end of file diff --git a/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj b/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj index a6dd9ad0..60ebae2e 100644 --- a/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj +++ b/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj @@ -6,24 +6,7 @@ - - Pollyfill\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs - - - Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs - - - Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - - + + \ No newline at end of file diff --git a/src/NoRefsTests/NoRefsTests.csproj b/src/NoRefsTests/NoRefsTests.csproj index 6525cde2..f99e76b0 100644 --- a/src/NoRefsTests/NoRefsTests.csproj +++ b/src/NoRefsTests/NoRefsTests.csproj @@ -4,27 +4,6 @@ $(TargetFrameworks);netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 - - Pollyfill\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs - - - Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs - - - Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs - - - Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - @@ -38,5 +17,6 @@ - + + \ No newline at end of file diff --git a/src/PublicTests/PublicTests.csproj b/src/PublicTests/PublicTests.csproj index d01e8da4..bcf11617 100644 --- a/src/PublicTests/PublicTests.csproj +++ b/src/PublicTests/PublicTests.csproj @@ -5,27 +5,6 @@ true - - Pollyfill\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs - - - Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs - - - Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs - - - Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - @@ -36,5 +15,6 @@ - + + \ No newline at end of file diff --git a/src/TestIncludes.targets b/src/TestIncludes.targets new file mode 100644 index 00000000..31485367 --- /dev/null +++ b/src/TestIncludes.targets @@ -0,0 +1,25 @@ + + + + Pollyfill\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs + + + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + + Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs + + + Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs + + + \ No newline at end of file diff --git a/src/Tests/Tests.csproj b/src/Tests/Tests.csproj index 279442b8..e9b8d65e 100644 --- a/src/Tests/Tests.csproj +++ b/src/Tests/Tests.csproj @@ -4,27 +4,6 @@ $(TargetFrameworks);netcoreapp3.1;net5.0;net6.0;net7.0;net8.0 - - Pollyfill\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs - - - Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs - - - Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs - - - Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - @@ -36,5 +15,6 @@ - + + \ No newline at end of file diff --git a/src/UnsafeTests/UnsafeTests.csproj b/src/UnsafeTests/UnsafeTests.csproj index 92ec509b..4bb9022d 100644 --- a/src/UnsafeTests/UnsafeTests.csproj +++ b/src/UnsafeTests/UnsafeTests.csproj @@ -5,27 +5,6 @@ True - - Pollyfill\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs - - - Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs - - - Pollyfill\StringInterpolation\%(RecursiveDir)%(Filename).cs - - - Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs - - - Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs - @@ -36,5 +15,6 @@ - + + \ No newline at end of file From 194a93b25beb75d6087dc92cafbb82458ed792d5 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 19 Feb 2024 18:44:06 +1100 Subject: [PATCH 302/313] move regex --- src/Consume/Consume.cs | 8 ++++++++ src/Polyfill/Polyfill.nuspec | 2 ++ .../{Polyfill_RegeEx.cs => Regex/Polyfill_Regeex.cs} | 0 src/Polyfill/{ => Regex}/RegexPolyfill.cs | 0 src/TestIncludes.targets | 3 +++ 5 files changed, 13 insertions(+) rename src/Polyfill/{Polyfill_RegeEx.cs => Regex/Polyfill_Regeex.cs} (100%) rename src/Polyfill/{ => Regex}/RegexPolyfill.cs (100%) diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index a7074f5d..9eb2745d 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -13,6 +13,7 @@ using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; #pragma warning disable CS4014 @@ -198,6 +199,13 @@ async Task StreamReaderReadAsync() var reader = new StreamReader(new MemoryStream()); var read = await reader.ReadAsync(memory); } + + void RegexIsMatch() + { + var regex = new Regex("result"); + regex.IsMatch("value".AsSpan()); + } + async Task StreamReadAsync() { var input = new byte[] diff --git a/src/Polyfill/Polyfill.nuspec b/src/Polyfill/Polyfill.nuspec index 9d340323..b447dd2e 100644 --- a/src/Polyfill/Polyfill.nuspec +++ b/src/Polyfill/Polyfill.nuspec @@ -27,6 +27,8 @@ target="contentFiles/cs/netstandard2.0/Polyfill/StringInterpolation"/> + Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs + + Pollyfill\Regex\%(RecursiveDir)%(Filename).cs + \ No newline at end of file From 5e740a7855336023c06168e39ec704e5b430e7d6 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 19 Feb 2024 19:53:43 +1100 Subject: [PATCH 303/313] . --- src/Polyfill/Regex/{Polyfill_Regeex.cs => Polyfill_Regex.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Polyfill/Regex/{Polyfill_Regeex.cs => Polyfill_Regex.cs} (100%) diff --git a/src/Polyfill/Regex/Polyfill_Regeex.cs b/src/Polyfill/Regex/Polyfill_Regex.cs similarity index 100% rename from src/Polyfill/Regex/Polyfill_Regeex.cs rename to src/Polyfill/Regex/Polyfill_Regex.cs From 579510fde0be00209f3da32c8435ad6061161896 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 19 Feb 2024 20:40:52 +1100 Subject: [PATCH 304/313] Update appveyor.yml --- src/appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/appveyor.yml b/src/appveyor.yml index cb7a6243..7e32c89e 100644 --- a/src/appveyor.yml +++ b/src/appveyor.yml @@ -1,7 +1,7 @@ image: - Visual Studio 2022 -- macOS -- Ubuntu +#- macOS +#- Ubuntu environment: DOTNET_NOLOGO: true DOTNET_CLI_TELEMETRY_OPTOUT: true From 5635e3fd6ef423066bd8ca4e0d778ac4bb8bf104 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 19 Feb 2024 21:18:24 +1100 Subject: [PATCH 305/313] Update Polyfill_StringBuilder.cs --- src/Polyfill/Polyfill_StringBuilder.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Polyfill/Polyfill_StringBuilder.cs b/src/Polyfill/Polyfill_StringBuilder.cs index 54b50a1e..8863614f 100644 --- a/src/Polyfill/Polyfill_StringBuilder.cs +++ b/src/Polyfill/Polyfill_StringBuilder.cs @@ -7,8 +7,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; -using System.Threading; -using System.Threading.Tasks; using Link = System.ComponentModel.DescriptionAttribute; static partial class Polyfill From 76ba7f8dbacb9b61d1fcc7861da547aba17a3850 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 19 Feb 2024 21:29:00 +1100 Subject: [PATCH 306/313] Update TestIncludes.targets --- src/TestIncludes.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TestIncludes.targets b/src/TestIncludes.targets index 29069cc0..1b349f16 100644 --- a/src/TestIncludes.targets +++ b/src/TestIncludes.targets @@ -1,7 +1,7 @@ - Pollyfill\%(RecursiveDir)%(Filename).cs + Pollyfill\%(Filename).cs Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs From 2c775330cc4f8b12912011da5a15dc5312a43e7d Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 19 Feb 2024 22:01:20 +1100 Subject: [PATCH 307/313] Add Regex.EnumerateMatches (#134) --- api_list.include.md | 8 ++- readme.md | 8 ++- src/Polyfill/Regex/Polyfill_Regex.cs | 46 +++++++++++-- src/Polyfill/Regex/RegexPolyfill.cs | 5 +- src/Polyfill/Regex/ValueMatch.cs | 50 ++++++++++++++ src/Polyfill/Regex/ValueMatchEnumerator.cs | 79 ++++++++++++++++++++++ src/Tests/BuildApiTest.cs | 3 +- src/Tests/PolyfillTests_Regex.cs | 28 ++++++++ 8 files changed, 212 insertions(+), 15 deletions(-) create mode 100644 src/Polyfill/Regex/ValueMatch.cs create mode 100644 src/Polyfill/Regex/ValueMatchEnumerator.cs create mode 100644 src/Tests/PolyfillTests_Regex.cs diff --git a/api_list.include.md b/api_list.include.md index 0582421f..f7f06628 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -214,8 +214,10 @@ * `Boolean TryCopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto) -#### RegularExpressions.Regex +#### Regex + * `ValueMatchEnumerator EnumerateMatches(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.enumeratematches#system-text-regularexpressions-regex-enumeratematches(system-readonlyspan((system-char)))) + * `ValueMatchEnumerator EnumerateMatches(ReadOnlySpan, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.enumeratematches#system-text-regularexpressions-regex-enumeratematches(system-readonlyspan((system-char))-system-int32)) * `Boolean IsMatch(ReadOnlySpan, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-int32)) * `Boolean IsMatch(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char)))) @@ -300,8 +302,8 @@ #### RegexPolyfill - * `Boolean IsMatch(String, RegularExpressions.RegexOptions, TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions-system-timespan)) - * `Boolean IsMatch(String, RegularExpressions.RegexOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions)) + * `Boolean IsMatch(String, RegexOptions, TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions-system-timespan)) + * `Boolean IsMatch(String, RegexOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions)) * `Boolean IsMatch(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string)) diff --git a/readme.md b/readme.md index 31528d5a..76d69028 100644 --- a/readme.md +++ b/readme.md @@ -570,8 +570,10 @@ The class `Polyfill` includes the following extension methods: * `Boolean TryCopyTo(Span)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.string.trycopyto) -#### RegularExpressions.Regex +#### Regex + * `ValueMatchEnumerator EnumerateMatches(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.enumeratematches#system-text-regularexpressions-regex-enumeratematches(system-readonlyspan((system-char)))) + * `ValueMatchEnumerator EnumerateMatches(ReadOnlySpan, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.enumeratematches#system-text-regularexpressions-regex-enumeratematches(system-readonlyspan((system-char))-system-int32)) * `Boolean IsMatch(ReadOnlySpan, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-int32)) * `Boolean IsMatch(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char)))) @@ -656,8 +658,8 @@ The class `Polyfill` includes the following extension methods: #### RegexPolyfill - * `Boolean IsMatch(String, RegularExpressions.RegexOptions, TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions-system-timespan)) - * `Boolean IsMatch(String, RegularExpressions.RegexOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions)) + * `Boolean IsMatch(String, RegexOptions, TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions-system-timespan)) + * `Boolean IsMatch(String, RegexOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions)) * `Boolean IsMatch(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string)) diff --git a/src/Polyfill/Regex/Polyfill_Regex.cs b/src/Polyfill/Regex/Polyfill_Regex.cs index 48021391..8be2f191 100644 --- a/src/Polyfill/Regex/Polyfill_Regex.cs +++ b/src/Polyfill/Regex/Polyfill_Regex.cs @@ -2,14 +2,10 @@ #pragma warning disable -#if (MEMORYREFERENCED && !NET7_0_OR_GREATER) +#if !NET7_0_OR_GREATER && HAS_SPAN using System; -using System.IO; -using System.Net.Http; using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; using Link = System.ComponentModel.DescriptionAttribute; static partial class Polyfill @@ -33,5 +29,45 @@ public static bool IsMatch(this Regex target, ReadOnlySpan input) { return target.IsMatch(input.ToString()); } + + /// + /// Searches an input span for all occurrences of a regular expression and returns a Regex.ValueMatchEnumerator to iterate over the matches. + /// + /// A Regex.ValueMatchEnumerator to iterate over the matches. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.enumeratematches#system-text-regularexpressions-regex-enumeratematches(system-readonlyspan((system-char)))")] + public static ValueMatchEnumerator EnumerateMatches (this Regex target, ReadOnlySpan input) => + new(target, input, target.RightToLeft ? input.Length : 0); + + /// + /// Searches an input span for all occurrences of a regular expression and returns a Regex.ValueMatchEnumerator to iterate over the matches. + /// + /// A Regex.ValueMatchEnumerator to iterate over the matches. + [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.enumeratematches#system-text-regularexpressions-regex-enumeratematches(system-readonlyspan((system-char))-system-int32)")] + public static ValueMatchEnumerator EnumerateMatches (this Regex target, ReadOnlySpan input, int startat) => + new(target, input, startat); + // + // /// + // /// Searches an input span for all occurrences of a regular expression and returns a Regex.ValueMatchEnumerator to iterate over the matches. + // /// + // /// A Regex.ValueMatchEnumerator to iterate over the matches. + // [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.enumeratematches#system-text-regularexpressions-regex-enumeratematches(system-readonlyspan((system-char))-system-string)")] + // public static ValueMatchEnumerator EnumerateMatches (this Regex target, ReadOnlySpan input, string pattern) => + // new(target, input, target.RightToLeft ? input.Length : 0); + // + // /// + // /// Searches an input span for all occurrences of a regular expression and returns a Regex.ValueMatchEnumerator to iterate over the matches. + // /// + // /// A Regex.ValueMatchEnumerator to iterate over the matches. + // [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.enumeratematches#system-text-regularexpressions-regex-enumeratematches(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions)")] + // public static ValueMatchEnumerator EnumerateMatches (this Regex target, ReadOnlySpan input, string pattern, System.Text.RegularExpressions.RegexOptions options) => + // new(target, input, target.RightToLeft ? input.Length : 0); + // + // /// + // /// Searches an input span for all occurrences of a regular expression and returns a Regex.ValueMatchEnumerator to iterate over the matches. + // /// + // /// A Regex.ValueMatchEnumerator to iterate over the matches. + // [Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.enumeratematches#system-text-regularexpressions-regex-enumeratematches(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions-system-timespan)")] + // public static ValueMatchEnumerator EnumerateMatches (this Regex target, ReadOnlySpan input, string pattern, System.Text.RegularExpressions.RegexOptions options, TimeSpan matchTimeout) => + // new(target, input, target.RightToLeft ? input.Length : 0); } #endif \ No newline at end of file diff --git a/src/Polyfill/Regex/RegexPolyfill.cs b/src/Polyfill/Regex/RegexPolyfill.cs index d2373ad2..e618a13b 100644 --- a/src/Polyfill/Regex/RegexPolyfill.cs +++ b/src/Polyfill/Regex/RegexPolyfill.cs @@ -1,9 +1,7 @@ // #pragma warning disable -#if MEMORYREFERENCED using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text.RegularExpressions; using Link = System.ComponentModel.DescriptionAttribute; @@ -14,6 +12,7 @@ #endif static partial class RegexPolyfill { +#if HAS_SPAN /// /// Indicates whether the specified regular expression finds a match in the specified input span, using the specified matching options and time-out interval. /// @@ -55,5 +54,5 @@ public static bool IsMatch(ReadOnlySpan input, string pattern) return Regex.IsMatch(input.ToString(), pattern); #endif } -} #endif +} diff --git a/src/Polyfill/Regex/ValueMatch.cs b/src/Polyfill/Regex/ValueMatch.cs new file mode 100644 index 00000000..94fd453f --- /dev/null +++ b/src/Polyfill/Regex/ValueMatch.cs @@ -0,0 +1,50 @@ +// + +#pragma warning disable + +#if !NET7_0_OR_GREATER && HAS_SPAN + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace System.Text.RegularExpressions; + +/// +/// Represents the results from a single regular expression match. +/// +/// +/// The type is immutable and has no public constructor. An instance of the struct is returned by the +/// method when iterating over the results from calling . +/// +[ExcludeFromCodeCoverage] +#if PolyPublic +public +#endif +readonly ref struct ValueMatch +{ + private readonly int _index; + private readonly int _length; + + /// + /// Crates an instance of the type based on the passed in and . + /// + /// The position in the original span where the first character of the captured sliced span is found. + /// The length of the captured sliced span. + internal ValueMatch(int index, int length) + { + _index = index; + _length = length; + } + + /// + /// Gets the position in the original span where the first character of the captured sliced span is found. + /// + public int Index => _index; + + /// + /// Gets the length of the captured sliced span. + /// + public int Length => _length; +} + +#endif \ No newline at end of file diff --git a/src/Polyfill/Regex/ValueMatchEnumerator.cs b/src/Polyfill/Regex/ValueMatchEnumerator.cs new file mode 100644 index 00000000..8c079ba3 --- /dev/null +++ b/src/Polyfill/Regex/ValueMatchEnumerator.cs @@ -0,0 +1,79 @@ +// + +#pragma warning disable + +#if !NET7_0_OR_GREATER && HAS_SPAN + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace System.Text.RegularExpressions; + +/// +/// Represents an enumerator containing the set of successful matches found by iteratively applying a regular expression pattern to the input span. +/// +/// +/// The enumerator has no public constructor. The method returns a +/// object.The enumerator will lazily iterate over zero or more objects. If there is at least one successful match in the span, then +/// returns and will contain the first . If there are no successful matches, +/// then returns and throws an . +/// +/// This type is a ref struct since it stores the input span as a field in order to be able to lazily iterate over it. +/// +[ExcludeFromCodeCoverage] +#if PolyPublic +public +#endif +ref struct ValueMatchEnumerator +{ + ReadOnlySpan _input; + ValueMatch _current; + MatchCollection matchCollection; + int index = 0; + + /// + /// Creates an instance of the for the passed in which iterates over . + /// + /// The to use for finding matches. + /// The input span to iterate over. + /// The position where the engine should start looking for matches from. + internal ValueMatchEnumerator(Regex regex, ReadOnlySpan input, int startAt) + { + matchCollection = regex.Matches(input.ToString(), startAt); + _input = input; + _current = default; + } + + /// + /// Provides an enumerator that iterates through the matches in the input span. + /// + /// A copy of this enumerator. + public readonly ValueMatchEnumerator GetEnumerator() => this; + + /// + /// Advances the enumerator to the next match in the span. + /// + /// + /// if the enumerator was successfully advanced to the next element; if the enumerator cannot find additional matches. + /// + public bool MoveNext() + { + if (index == matchCollection.Count) + { + return false; + } + + var match = matchCollection[index]; + _current = new ValueMatch(match.Index, match.Length); + index++; + return true; + } + + /// + /// Gets the element at the current position of the enumerator. + /// + /// Enumeration has either not started or has already finished. + public readonly ValueMatch Current => _current; +} + +#endif \ No newline at end of file diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index 9691521e..421915e0 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -1,12 +1,13 @@ +#if NET8_0 && DEBUG using System.Diagnostics.CodeAnalysis; using Mono.Cecil; -#if NET8_0 && DEBUG [TestFixture] class BuildApiTest { static string[] namespacesToClean = [ + "System.Text.RegularExpressions.", "System.Diagnostics.", "System.Collections.Generic.", "System.Threading.Tasks.", diff --git a/src/Tests/PolyfillTests_Regex.cs b/src/Tests/PolyfillTests_Regex.cs new file mode 100644 index 00000000..f122740d --- /dev/null +++ b/src/Tests/PolyfillTests_Regex.cs @@ -0,0 +1,28 @@ +using System.Text.RegularExpressions; + +partial class PolyfillTests +{ + [Test] + public void RegexIsMatch() + { + var regex = new Regex(@"\d+"); + var match = regex.Match("a55a"); + Assert.IsTrue(match.Success); + } + + [Test] + public void EnumerateMatches() + { + var regex = new Regex(@"\d+"); + var span = "a55a".AsSpan(); + var found = false; + foreach (var match in regex.EnumerateMatches(span)) + { + found = true; + Assert.AreEqual(1, match.Index); + Assert.AreEqual(2, match.Length); + } + + Assert.IsTrue(found); + } +} From 43a2f485304f2a28ed98b109070feb2fa337b88e Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 19 Feb 2024 22:03:23 +1100 Subject: [PATCH 308/313] Update Directory.Build.props --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index f1808941..d12a618a 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 2.4.0 + 2.5.0 1.0.0 Polyfill true From a6a3cdbb268e0c64abf1a10eafcc7fb7236f16f6 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 20 Feb 2024 08:49:12 +1100 Subject: [PATCH 309/313] Update Polyfill.sln --- src/Polyfill.sln | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Polyfill.sln b/src/Polyfill.sln index f4df45fe..82f829b8 100644 --- a/src/Polyfill.sln +++ b/src/Polyfill.sln @@ -15,25 +15,28 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\readme.md = ..\readme.md EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Polyfill", "Polyfill\Polyfill.csproj", "{698FB675-3480-4107-8CAE-51452C6138CE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Polyfill", "Polyfill\Polyfill.csproj", "{698FB675-3480-4107-8CAE-51452C6138CE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{CA1869D1-4531-40C7-AE55-5885F4DD8448}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tests", "Tests\Tests.csproj", "{CA1869D1-4531-40C7-AE55-5885F4DD8448}" + ProjectSection(ProjectDependencies) = postProject + {32C38E3C-4040-455F-A27D-4EA5DB0F8EFA} = {32C38E3C-4040-455F-A27D-4EA5DB0F8EFA} + EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Consume", "Consume\Consume.csproj", "{32C38E3C-4040-455F-A27D-4EA5DB0F8EFA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Consume", "Consume\Consume.csproj", "{32C38E3C-4040-455F-A27D-4EA5DB0F8EFA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnsafeTests", "UnsafeTests\UnsafeTests.csproj", "{F49A3C33-48A3-4954-9AC0-5C7B30AC2B2B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnsafeTests", "UnsafeTests\UnsafeTests.csproj", "{F49A3C33-48A3-4954-9AC0-5C7B30AC2B2B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PublicTests", "PublicTests\PublicTests.csproj", "{9FBD54A6-461C-4754-B77A-222E06BF89B6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PublicTests", "PublicTests\PublicTests.csproj", "{9FBD54A6-461C-4754-B77A-222E06BF89B6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeClassicReferences", "ConsumeClassicReferences\ConsumeClassicReferences.csproj", "{CF7D4778-6A32-4E7D-B80B-3507974B443B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsumeClassicReferences", "ConsumeClassicReferences\ConsumeClassicReferences.csproj", "{CF7D4778-6A32-4E7D-B80B-3507974B443B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeIndirect", "ConsumeIndirect\ConsumeIndirect.csproj", "{955038AF-1073-4BB0-8AF7-D4597B7C2DAB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsumeIndirect", "ConsumeIndirect\ConsumeIndirect.csproj", "{955038AF-1073-4BB0-8AF7-D4597B7C2DAB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoRefsTests", "NoRefsTests\NoRefsTests.csproj", "{A9EEAECD-A8B2-45C1-9A9D-94443601CB5F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NoRefsTests", "NoRefsTests\NoRefsTests.csproj", "{A9EEAECD-A8B2-45C1-9A9D-94443601CB5F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeNoRefs", "ConsumeNoRefs\ConsumeNoRefs.csproj", "{B4DC96CA-C700-499F-A9A2-0C767DCF8C30}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsumeNoRefs", "ConsumeNoRefs\ConsumeNoRefs.csproj", "{B4DC96CA-C700-499F-A9A2-0C767DCF8C30}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeTasksWithNoMemory", "ConsumeTasksWithNoMemory\ConsumeTasksWithNoMemory.csproj", "{96EF1E04-5862-4D9E-B800-A6402F1ADF7A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsumeTasksWithNoMemory", "ConsumeTasksWithNoMemory\ConsumeTasksWithNoMemory.csproj", "{96EF1E04-5862-4D9E-B800-A6402F1ADF7A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 0200f3a037ecb7adf9ef7e427bc695711ceb5aa2 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 20 Feb 2024 08:54:47 +1100 Subject: [PATCH 310/313] docs --- api_list.include.md | 14 +++++++------- readme.md | 14 +++++++------- src/Tests/BuildApiTest.cs | 25 ++++++++++++++++++++----- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/api_list.include.md b/api_list.include.md index f7f06628..98b58ef1 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -225,16 +225,16 @@ #### StringBuilder * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) - * `StringBuilder Append(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) - * `StringBuilder Append(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder Append(StringBuilder, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder Append(StringBuilder, IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) * `StringBuilder AppendJoin(String, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-string())) * `StringBuilder AppendJoin(String, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-object())) * `StringBuilder AppendJoin(Char, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-string())) * `StringBuilder AppendJoin(Char, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-object())) * `StringBuilder AppendJoin(Char, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0)))) * `StringBuilder AppendJoin(String, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0)))) - * `StringBuilder AppendLine(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) - * `StringBuilder AppendLine(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendLine(StringBuilder, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendLine(StringBuilder, IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) @@ -302,8 +302,8 @@ #### RegexPolyfill - * `Boolean IsMatch(String, RegexOptions, TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions-system-timespan)) - * `Boolean IsMatch(String, RegexOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions)) - * `Boolean IsMatch(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string)) + * `Boolean IsMatch(ReadOnlySpan, String, RegexOptions, TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions-system-timespan)) + * `Boolean IsMatch(ReadOnlySpan, String, RegexOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions)) + * `Boolean IsMatch(ReadOnlySpan, String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string)) diff --git a/readme.md b/readme.md index 76d69028..de894c15 100644 --- a/readme.md +++ b/readme.md @@ -581,16 +581,16 @@ The class `Polyfill` includes the following extension methods: #### StringBuilder * `StringBuilder Append(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-readonlyspan((system-char)))) - * `StringBuilder Append(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) - * `StringBuilder Append(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder Append(StringBuilder, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder Append(StringBuilder, IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.append#system-text-stringbuilder-append(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) * `StringBuilder AppendJoin(String, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-string())) * `StringBuilder AppendJoin(String, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-string-system-object())) * `StringBuilder AppendJoin(Char, String[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-string())) * `StringBuilder AppendJoin(Char, Object[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin(system-char-system-object())) * `StringBuilder AppendJoin(Char, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-char-system-collections-generic-ienumerable((-0)))) * `StringBuilder AppendJoin(String, T[])` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendjoin?view=netcore-2.0#system-text-stringbuilder-appendjoin-1(system-string-system-collections-generic-ienumerable((-0)))) - * `StringBuilder AppendLine(AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) - * `StringBuilder AppendLine(IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendLine(StringBuilder, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-text-stringbuilder-appendinterpolatedstringhandler@)) + * `StringBuilder AppendLine(StringBuilder, IFormatProvider, AppendInterpolatedStringHandler&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.appendline#system-text-stringbuilder-appendline(system-iformatprovider-system-text-stringbuilder-appendinterpolatedstringhandler@)) * `Void CopyTo(Int32, Span, Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.copyto#system-text-stringbuilder-copyto(system-int32-system-span((system-char))-system-int32)) * `Boolean Equals(ReadOnlySpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.stringbuilder.equals#system-text-stringbuilder-equals(system-readonlyspan((system-char)))) @@ -658,9 +658,9 @@ The class `Polyfill` includes the following extension methods: #### RegexPolyfill - * `Boolean IsMatch(String, RegexOptions, TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions-system-timespan)) - * `Boolean IsMatch(String, RegexOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions)) - * `Boolean IsMatch(String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string)) + * `Boolean IsMatch(ReadOnlySpan, String, RegexOptions, TimeSpan)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions-system-timespan)) + * `Boolean IsMatch(ReadOnlySpan, String, RegexOptions)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string-system-text-regularexpressions-regexoptions)) + * `Boolean IsMatch(ReadOnlySpan, String)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.ismatch#system-text-regularexpressions-regex-ismatch(system-readonlyspan((system-char))-system-string)) diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index 421915e0..d8f0159f 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -97,18 +97,33 @@ static void WriteSignature(MethodDefinition method, StreamWriter writer) } } - static string BuildParameters(MethodDefinition method) => - string.Join(", ", method.Parameters.Skip(1).Select(_ => GetTypeName(_.ParameterType.FullName))); + static string BuildParameters(MethodDefinition method) + { + IEnumerable parameters; + if (IsExtensionMethod(method)) + { + parameters = method.Parameters.Skip(1); + } + else + { + + parameters = method.Parameters; + } + + return string.Join(", ", parameters.Select(_ => GetTypeName(_.ParameterType.FullName))); + } + + static bool IsExtensionMethod(MethodDefinition method) => + method.CustomAttributes.Any(_ => _.AttributeType.Name == "ExtensionAttribute"); static string BuildTypeArgs(MethodDefinition method) { - var typeArgs = ""; if (method.HasGenericParameters) { - typeArgs = $"<{string.Join(", ", method.GenericParameters.Select(_ => _.Name))}>"; + return $"<{string.Join(", ", method.GenericParameters.Select(_ => _.Name))}>"; } - return typeArgs; + return ""; } static bool TryGetReference(MethodDefinition method,[NotNullWhen(true)] out string? reference) From fae91b81d1b7a94026ea645cb5ae32db89786e52 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 20 Feb 2024 10:16:23 +1100 Subject: [PATCH 311/313] Update BuildApiTest.cs --- src/Tests/BuildApiTest.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index d8f0159f..7f8a1817 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -30,7 +30,7 @@ public void Run() var extensions = types.Single(_ => _.Name == nameof(Polyfill)); using var writer = File.CreateText(md); - writer.WriteLine($"### Extension methods"); + writer.WriteLine("### Extension methods"); writer.WriteLine(); foreach (var type in PublicMethods(extensions.Methods) .GroupBy(_ => _.Parameters[0].ParameterType.FullName) @@ -46,7 +46,7 @@ public void Run() writer.WriteLine(); writer.WriteLine(); } - writer.WriteLine($"### Static helpers"); + writer.WriteLine("### Static helpers"); writer.WriteLine(); WriteHelper(types, nameof(EnumPolyfill), writer); @@ -106,7 +106,6 @@ static string BuildParameters(MethodDefinition method) } else { - parameters = method.Parameters; } From 01f3c43b5a3bd17ba561f7fcfdbba4f4c98ccda5 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 20 Feb 2024 10:16:56 +1100 Subject: [PATCH 312/313] Update BuildApiTest.cs --- src/Tests/BuildApiTest.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index 7f8a1817..bc5c30bb 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -46,6 +46,7 @@ public void Run() writer.WriteLine(); writer.WriteLine(); } + writer.WriteLine("### Static helpers"); writer.WriteLine(); @@ -63,6 +64,7 @@ static void WriteHelper(List types, string name, StreamWriter wr { WriteSignature(method, writer); } + writer.WriteLine(); writer.WriteLine(); } @@ -79,7 +81,7 @@ static string GetTypeName(string targetType) } static IEnumerable PublicMethods(IEnumerable type) => - type.Where(_=>_ is {IsPublic: true, IsConstructor: false}) + type.Where(_ => _ is {IsPublic: true, IsConstructor: false}) .OrderBy(_ => _.Name); static void WriteSignature(MethodDefinition method, StreamWriter writer) @@ -125,7 +127,7 @@ static string BuildTypeArgs(MethodDefinition method) return ""; } - static bool TryGetReference(MethodDefinition method,[NotNullWhen(true)] out string? reference) + static bool TryGetReference(MethodDefinition method, [NotNullWhen(true)] out string? reference) { var descriptionAttribute = method.CustomAttributes .SingleOrDefault(_ => _.AttributeType.Name == "DescriptionAttribute"); From 29485828506127002a8579f351da45aedaf4e850 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 20 Feb 2024 10:18:05 +1100 Subject: [PATCH 313/313] Update BuildApiTest.cs --- src/Tests/BuildApiTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/BuildApiTest.cs b/src/Tests/BuildApiTest.cs index bc5c30bb..66939f0a 100644 --- a/src/Tests/BuildApiTest.cs +++ b/src/Tests/BuildApiTest.cs @@ -71,7 +71,7 @@ static void WriteHelper(List types, string name, StreamWriter wr static string GetTypeName(string targetType) { - var name = targetType.Replace("`1", "").Replace("`2", ""); + var name = targetType.Replace("`1", "").Replace("`2", "").Replace("`3", ""); foreach (var toClean in namespacesToClean) { name = name.Replace(toClean, "");