diff --git a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.cs b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.cs index 4cd8fcd0569ac..2ffa60d02794c 100644 --- a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.cs +++ b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.cs @@ -8,45 +8,66 @@ namespace System.Net.Http.Json { public static partial class HttpClientJsonExtensions { - public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, System.Type type, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type type, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, System.Type type, System.Text.Json.Serialization.JsonSerializerContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, System.Type type, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Type type, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type type, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type type, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Type type, System.Text.Json.Serialization.JsonSerializerContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Type type, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type type, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task GetFromJsonAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this System.Net.Http.HttpClient client, string? requestUri, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task GetFromJsonAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this System.Net.Http.HttpClient client, string? requestUri, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task GetFromJsonAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task PostAsJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task GetFromJsonAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task PostAsJsonAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this System.Net.Http.HttpClient client, string? requestUri, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task PostAsJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, TValue value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task PostAsJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, TValue value, System.Threading.CancellationToken cancellationToken) { throw null; } - public static System.Threading.Tasks.Task PostAsJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task PostAsJsonAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this System.Net.Http.HttpClient client, string? requestUri, TValue value, System.Threading.CancellationToken cancellationToken) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task PostAsJsonAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this System.Net.Http.HttpClient client, System.Uri? requestUri, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task PostAsJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, TValue value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task PostAsJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, TValue value, System.Threading.CancellationToken cancellationToken) { throw null; } - public static System.Threading.Tasks.Task PutAsJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task PostAsJsonAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this System.Net.Http.HttpClient client, System.Uri? requestUri, TValue value, System.Threading.CancellationToken cancellationToken) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task PutAsJsonAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this System.Net.Http.HttpClient client, string? requestUri, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task PutAsJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, TValue value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task PutAsJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, TValue value, System.Threading.CancellationToken cancellationToken) { throw null; } - public static System.Threading.Tasks.Task PutAsJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task PutAsJsonAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this System.Net.Http.HttpClient client, string? requestUri, TValue value, System.Threading.CancellationToken cancellationToken) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task PutAsJsonAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this System.Net.Http.HttpClient client, System.Uri? requestUri, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task PutAsJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, TValue value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task PutAsJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, TValue value, System.Threading.CancellationToken cancellationToken) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task PutAsJsonAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this System.Net.Http.HttpClient client, System.Uri? requestUri, TValue value, System.Threading.CancellationToken cancellationToken) { throw null; } } public static partial class HttpContentJsonExtensions { - public static System.Threading.Tasks.Task ReadFromJsonAsync(this System.Net.Http.HttpContent content, System.Type type, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task ReadFromJsonAsync(this System.Net.Http.HttpContent content, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type type, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task ReadFromJsonAsync(this System.Net.Http.HttpContent content, System.Type type, System.Text.Json.Serialization.JsonSerializerContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static System.Threading.Tasks.Task ReadFromJsonAsync(this System.Net.Http.HttpContent content, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task ReadFromJsonAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] T>(this System.Net.Http.HttpContent content, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task ReadFromJsonAsync(this System.Net.Http.HttpContent content, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } public sealed partial class JsonContent : System.Net.Http.HttpContent { internal JsonContent() { } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] public System.Type ObjectType { get { throw null; } } public object? Value { get { throw null; } } - public static System.Net.Http.Json.JsonContent Create(object? inputValue, System.Type inputType, System.Net.Http.Headers.MediaTypeHeaderValue? mediaType = null, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static System.Net.Http.Json.JsonContent Create(T inputValue, System.Net.Http.Headers.MediaTypeHeaderValue? mediaType = null, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Net.Http.Json.JsonContent Create(object? inputValue, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type inputType, System.Net.Http.Headers.MediaTypeHeaderValue? mediaType = null, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved.")] + public static System.Net.Http.Json.JsonContent Create<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] T>(T inputValue, System.Net.Http.Headers.MediaTypeHeaderValue? mediaType = null, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context) { throw null; } protected override bool TryComputeLength(out long length) { throw null; } } diff --git a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj index 54b524e874c05..9e23fb4e09236 100644 --- a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj +++ b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);net5.0;netstandard2.0;net461 true @@ -13,6 +13,11 @@ + + + + + diff --git a/src/libraries/System.Net.Http.Json/src/ILLink/ILLink.Suppressions.xml b/src/libraries/System.Net.Http.Json/src/ILLink/ILLink.Suppressions.xml deleted file mode 100644 index accf0f2438a6b..0000000000000 --- a/src/libraries/System.Net.Http.Json/src/ILLink/ILLink.Suppressions.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - ILLink - IL2072 - member - M:System.Net.Http.Json.JsonContent.<SerializeToStreamAsyncCore>d__13.MoveNext - - - ILLink - IL2077 - member - M:System.Net.Http.Json.HttpContentJsonExtensions.<ReadFromJsonAsyncCore>d__2.MoveNext - - - ILLink - IL2091 - member - M:System.Net.Http.Json.HttpContentJsonExtensions.<ReadFromJsonAsyncCore>d__3`1.MoveNext - - - \ No newline at end of file diff --git a/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj b/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj index a0b6916073f66..120c77f330d3e 100644 --- a/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj +++ b/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);net5.0;netstandard2.0;net461 true @@ -23,6 +23,10 @@ + + + + diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Get.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Get.cs index f141bcefc28ce..bb71807e91e89 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Get.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Get.cs @@ -1,12 +1,30 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; +[assembly: UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Target = "M:System.Net.Http.Json.HttpClientJsonExtensions.d__12.MoveNext()", + Scope = "member", + Justification = "Workaround for https://github.com/mono/linker/issues/1416. The outer method is marked as RequiresUnreferencedCode.")] +[assembly: UnconditionalSuppressMessage("ReflectionAnalysis", "IL2077:UnrecognizedReflectionPattern", + Target = "M:System.Net.Http.Json.HttpClientJsonExtensions.d__12.MoveNext()", + Scope = "member", + Justification = "Workaround for https://github.com/mono/linker/issues/1416. The outer method is marked as RequiresUnreferencedCode.")] +[assembly: UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Target = "M:System.Net.Http.Json.HttpClientJsonExtensions.d__13`1.MoveNext()", + Scope = "member", + Justification = "Workaround for https://github.com/mono/linker/issues/1416. The outer method is marked as RequiresUnreferencedCode.")] +[assembly: UnconditionalSuppressMessage("ReflectionAnalysis", "IL2091:UnrecognizedReflectionPattern", + Target = "M:System.Net.Http.Json.HttpClientJsonExtensions.d__13`1.MoveNext()", + Scope = "member", + Justification = "Workaround for https://github.com/mono/linker/issues/1416. The outer method is marked as RequiresUnreferencedCode.")] + namespace System.Net.Http.Json { /// @@ -14,7 +32,8 @@ namespace System.Net.Http.Json /// public static partial class HttpClientJsonExtensions { - public static Task GetFromJsonAsync(this HttpClient client, string? requestUri, Type type, JsonSerializerOptions? options, CancellationToken cancellationToken = default) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task GetFromJsonAsync(this HttpClient client, string? requestUri, [DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] Type type, JsonSerializerOptions? options, CancellationToken cancellationToken = default) { if (client == null) { @@ -25,7 +44,8 @@ public static partial class HttpClientJsonExtensions return GetFromJsonAsyncCore(taskResponse, type, options, cancellationToken); } - public static Task GetFromJsonAsync(this HttpClient client, Uri? requestUri, Type type, JsonSerializerOptions? options, CancellationToken cancellationToken = default) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task GetFromJsonAsync(this HttpClient client, Uri? requestUri, [DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] Type type, JsonSerializerOptions? options, CancellationToken cancellationToken = default) { if (client == null) { @@ -36,7 +56,8 @@ public static partial class HttpClientJsonExtensions return GetFromJsonAsyncCore(taskResponse, type, options, cancellationToken); } - public static Task GetFromJsonAsync(this HttpClient client, string? requestUri, JsonSerializerOptions? options, CancellationToken cancellationToken = default) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task GetFromJsonAsync<[DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] TValue>(this HttpClient client, string? requestUri, JsonSerializerOptions? options, CancellationToken cancellationToken = default) { if (client == null) { @@ -47,7 +68,8 @@ public static partial class HttpClientJsonExtensions return GetFromJsonAsyncCore(taskResponse, options, cancellationToken); } - public static Task GetFromJsonAsync(this HttpClient client, Uri? requestUri, JsonSerializerOptions? options, CancellationToken cancellationToken = default) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task GetFromJsonAsync<[DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] TValue>(this HttpClient client, Uri? requestUri, JsonSerializerOptions? options, CancellationToken cancellationToken = default) { if (client == null) { @@ -102,19 +124,24 @@ public static partial class HttpClientJsonExtensions return GetFromJsonAsyncCore(taskResponse, jsonTypeInfo, cancellationToken); } - public static Task GetFromJsonAsync(this HttpClient client, string? requestUri, Type type, CancellationToken cancellationToken = default) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task GetFromJsonAsync(this HttpClient client, string? requestUri, [DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] Type type, CancellationToken cancellationToken = default) => client.GetFromJsonAsync(requestUri, type, options: null, cancellationToken); - public static Task GetFromJsonAsync(this HttpClient client, Uri? requestUri, Type type, CancellationToken cancellationToken = default) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task GetFromJsonAsync(this HttpClient client, Uri? requestUri, [DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] Type type, CancellationToken cancellationToken = default) => client.GetFromJsonAsync(requestUri, type, options: null, cancellationToken); - public static Task GetFromJsonAsync(this HttpClient client, string? requestUri, CancellationToken cancellationToken = default) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task GetFromJsonAsync<[DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] TValue>(this HttpClient client, string? requestUri, CancellationToken cancellationToken = default) => client.GetFromJsonAsync(requestUri, options: null, cancellationToken); - public static Task GetFromJsonAsync(this HttpClient client, Uri? requestUri, CancellationToken cancellationToken = default) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task GetFromJsonAsync<[DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] TValue>(this HttpClient client, Uri? requestUri, CancellationToken cancellationToken = default) => client.GetFromJsonAsync(requestUri, options: null, cancellationToken); - private static async Task GetFromJsonAsyncCore(Task taskResponse, Type type, JsonSerializerOptions? options, CancellationToken cancellationToken) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + private static async Task GetFromJsonAsyncCore(Task taskResponse, [DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] Type type, JsonSerializerOptions? options, CancellationToken cancellationToken) { using (HttpResponseMessage response = await taskResponse.ConfigureAwait(false)) { @@ -126,7 +153,8 @@ public static partial class HttpClientJsonExtensions } } - private static async Task GetFromJsonAsyncCore(Task taskResponse, JsonSerializerOptions? options, CancellationToken cancellationToken) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + private static async Task GetFromJsonAsyncCore<[DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] T>(Task taskResponse, JsonSerializerOptions? options, CancellationToken cancellationToken) { using (HttpResponseMessage response = await taskResponse.ConfigureAwait(false)) { diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Post.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Post.cs index 324fa61f76c7e..7b4b789d190c4 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Post.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Post.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization.Metadata; using System.Threading; @@ -10,7 +11,8 @@ namespace System.Net.Http.Json { public static partial class HttpClientJsonExtensions { - public static Task PostAsJsonAsync(this HttpClient client, string? requestUri, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task PostAsJsonAsync<[DynamicallyAccessedMembers(JsonContent.SerializationMemberTypes)] TValue>(this HttpClient client, string? requestUri, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { if (client == null) { @@ -21,7 +23,8 @@ public static Task PostAsJsonAsync(this HttpClient return client.PostAsync(requestUri, content, cancellationToken); } - public static Task PostAsJsonAsync(this HttpClient client, Uri? requestUri, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task PostAsJsonAsync<[DynamicallyAccessedMembers(JsonContent.SerializationMemberTypes)] TValue>(this HttpClient client, Uri? requestUri, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { if (client == null) { @@ -32,10 +35,12 @@ public static Task PostAsJsonAsync(this HttpClient return client.PostAsync(requestUri, content, cancellationToken); } - public static Task PostAsJsonAsync(this HttpClient client, string? requestUri, TValue value, CancellationToken cancellationToken) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task PostAsJsonAsync<[DynamicallyAccessedMembers(JsonContent.SerializationMemberTypes)] TValue>(this HttpClient client, string? requestUri, TValue value, CancellationToken cancellationToken) => client.PostAsJsonAsync(requestUri, value, options: null, cancellationToken); - public static Task PostAsJsonAsync(this HttpClient client, Uri? requestUri, TValue value, CancellationToken cancellationToken) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task PostAsJsonAsync<[DynamicallyAccessedMembers(JsonContent.SerializationMemberTypes)] TValue>(this HttpClient client, Uri? requestUri, TValue value, CancellationToken cancellationToken) => client.PostAsJsonAsync(requestUri, value, options: null, cancellationToken); public static Task PostAsJsonAsync(this HttpClient client, string? requestUri, TValue value, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Put.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Put.cs index e04d6ec027f22..e8b0e17b0bf8c 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Put.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Put.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization.Metadata; using System.Threading; @@ -10,7 +11,8 @@ namespace System.Net.Http.Json { public static partial class HttpClientJsonExtensions { - public static Task PutAsJsonAsync(this HttpClient client, string? requestUri, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task PutAsJsonAsync<[DynamicallyAccessedMembers(JsonContent.SerializationMemberTypes)] TValue>(this HttpClient client, string? requestUri, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { if (client == null) { @@ -21,7 +23,8 @@ public static Task PutAsJsonAsync(this HttpClient c return client.PutAsync(requestUri, content, cancellationToken); } - public static Task PutAsJsonAsync(this HttpClient client, Uri? requestUri, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task PutAsJsonAsync<[DynamicallyAccessedMembers(JsonContent.SerializationMemberTypes)] TValue>(this HttpClient client, Uri? requestUri, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { if (client == null) { @@ -32,10 +35,12 @@ public static Task PutAsJsonAsync(this HttpClient c return client.PutAsync(requestUri, content, cancellationToken); } - public static Task PutAsJsonAsync(this HttpClient client, string? requestUri, TValue value, CancellationToken cancellationToken) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task PutAsJsonAsync<[DynamicallyAccessedMembers(JsonContent.SerializationMemberTypes)] TValue>(this HttpClient client, string? requestUri, TValue value, CancellationToken cancellationToken) => client.PutAsJsonAsync(requestUri, value, options: null, cancellationToken); - public static Task PutAsJsonAsync(this HttpClient client, Uri? requestUri, TValue value, CancellationToken cancellationToken) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task PutAsJsonAsync<[DynamicallyAccessedMembers(JsonContent.SerializationMemberTypes)] TValue>(this HttpClient client, Uri? requestUri, TValue value, CancellationToken cancellationToken) => client.PutAsJsonAsync(requestUri, value, options: null, cancellationToken); public static Task PutAsJsonAsync(this HttpClient client, string? requestUri, TValue value, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs index 503b4eedf2299..060ad56cbc21b 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpContentJsonExtensions.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text; using System.Text.Json; @@ -9,11 +10,31 @@ using System.Threading; using System.Threading.Tasks; +[assembly: UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Target = "M:System.Net.Http.Json.HttpContentJsonExtensions.d__3.MoveNext()", + Scope = "member", + Justification = "Workaround for https://github.com/mono/linker/issues/1416. The outer method is marked as RequiresUnreferencedCode.")] +[assembly: UnconditionalSuppressMessage("ReflectionAnalysis", "IL2077:UnrecognizedReflectionPattern", + Target = "M:System.Net.Http.Json.HttpContentJsonExtensions.d__3.MoveNext()", + Scope = "member", + Justification = "Workaround for https://github.com/mono/linker/issues/1416. The outer method is marked as RequiresUnreferencedCode.")] +[assembly: UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Target = "M:System.Net.Http.Json.HttpContentJsonExtensions.d__4`1.MoveNext()", + Scope = "member", + Justification = "Workaround for https://github.com/mono/linker/issues/1416. The outer method is marked as RequiresUnreferencedCode.")] +[assembly: UnconditionalSuppressMessage("ReflectionAnalysis", "IL2091:UnrecognizedReflectionPattern", + Target = "M:System.Net.Http.Json.HttpContentJsonExtensions.d__4`1.MoveNext()", + Scope = "member", + Justification = "Workaround for https://github.com/mono/linker/issues/1416. The outer method is marked as RequiresUnreferencedCode.")] + namespace System.Net.Http.Json { public static partial class HttpContentJsonExtensions { - public static Task ReadFromJsonAsync(this HttpContent content, Type type, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) + internal const string SerializationUnreferencedCodeMessage = "Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overloads that take a JsonTypeInfo, or make sure all of the required types are preserved."; + + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] + public static Task ReadFromJsonAsync(this HttpContent content, [DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] Type type, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { if (content == null) { @@ -25,7 +46,8 @@ public static partial class HttpContentJsonExtensions return ReadFromJsonAsyncCore(content, type, sourceEncoding, options, cancellationToken); } - public static Task ReadFromJsonAsync(this HttpContent content, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] + public static Task ReadFromJsonAsync<[DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] T>(this HttpContent content, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { if (content == null) { @@ -37,7 +59,8 @@ public static partial class HttpContentJsonExtensions return ReadFromJsonAsyncCore(content, sourceEncoding, options, cancellationToken); } - private static async Task ReadFromJsonAsyncCore(HttpContent content, Type type, Encoding? sourceEncoding, JsonSerializerOptions? options, CancellationToken cancellationToken) + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] + private static async Task ReadFromJsonAsyncCore(HttpContent content, [DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] Type type, Encoding? sourceEncoding, JsonSerializerOptions? options, CancellationToken cancellationToken) { using (Stream contentStream = await GetContentStream(content, sourceEncoding, cancellationToken).ConfigureAwait(false)) { @@ -45,7 +68,8 @@ public static partial class HttpContentJsonExtensions } } - private static async Task ReadFromJsonAsyncCore(HttpContent content, Encoding? sourceEncoding, JsonSerializerOptions? options, CancellationToken cancellationToken) + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] + private static async Task ReadFromJsonAsyncCore<[DynamicallyAccessedMembers(JsonContent.DeserializationMemberTypes)] T>(HttpContent content, Encoding? sourceEncoding, JsonSerializerOptions? options, CancellationToken cancellationToken) { using (Stream contentStream = await GetContentStream(content, sourceEncoding, cancellationToken).ConfigureAwait(false)) { diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/JsonContent.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/JsonContent.cs index fdbae1b51cae3..880239a4fbca5 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/JsonContent.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/JsonContent.cs @@ -4,6 +4,7 @@ #if !NETCOREAPP using System.Diagnostics; #endif +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Net.Http.Headers; using System.Text; @@ -11,17 +12,30 @@ using System.Threading; using System.Threading.Tasks; +[assembly: UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Target = "M:System.Net.Http.Json.JsonContent.d__15.MoveNext()", + Scope = "member", + Justification = "Workaround for https://github.com/mono/linker/issues/1416. The outer method is marked as UnconditionalSuppressMessage.")] + namespace System.Net.Http.Json { public sealed partial class JsonContent : HttpContent { internal static readonly JsonSerializerOptions s_defaultSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web); + internal const DynamicallyAccessedMemberTypes SerializationMemberTypes = DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties; + internal const DynamicallyAccessedMemberTypes DeserializationMemberTypes = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties; private readonly JsonSerializerOptions? _jsonSerializerOptions; + [DynamicallyAccessedMembers(SerializationMemberTypes)] public Type ObjectType { get; } public object? Value { get; } - private JsonContent(object? inputValue, Type inputType, MediaTypeHeaderValue? mediaType, JsonSerializerOptions? options) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + private JsonContent( + object? inputValue, + [DynamicallyAccessedMembers(SerializationMemberTypes)] Type inputType, + MediaTypeHeaderValue? mediaType, + JsonSerializerOptions? options) { if (inputType == null) { @@ -39,10 +53,12 @@ private JsonContent(object? inputValue, Type inputType, MediaTypeHeaderValue? me _jsonSerializerOptions = options ?? s_defaultSerializerOptions; } - public static JsonContent Create(T inputValue, MediaTypeHeaderValue? mediaType = null, JsonSerializerOptions? options = null) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static JsonContent Create<[DynamicallyAccessedMembers(SerializationMemberTypes)] T>(T inputValue, MediaTypeHeaderValue? mediaType = null, JsonSerializerOptions? options = null) => Create(inputValue, typeof(T), mediaType, options); - public static JsonContent Create(object? inputValue, Type inputType, MediaTypeHeaderValue? mediaType = null, JsonSerializerOptions? options = null) + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static JsonContent Create(object? inputValue, [DynamicallyAccessedMembers(SerializationMemberTypes)] Type inputType, MediaTypeHeaderValue? mediaType = null, JsonSerializerOptions? options = null) => new JsonContent(inputValue, inputType, mediaType, options); protected override Task SerializeToStreamAsync(Stream stream, TransportContext? context) @@ -54,6 +70,8 @@ protected override bool TryComputeLength(out long length) return false; } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "The ctor is annotated with RequiresUnreferencedCode.")] private async Task SerializeToStreamAsyncCore(Stream targetStream, bool async, CancellationToken cancellationToken) { Encoding? targetEncoding = JsonHelpers.GetEncoding(Headers.ContentType?.CharSet); diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/JsonContentOfT.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/JsonContentOfT.cs index 5f786f8607af1..5225f412d0610 100644 --- a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/JsonContentOfT.cs +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/JsonContentOfT.cs @@ -39,7 +39,7 @@ protected override bool TryComputeLength(out long length) /// Based on . /// The difference is that this implementation calls overloads of that take type metadata directly. /// This is done to avoid rooting unused, built-in s and reflection-based - /// warm-up logic (to reduce app size and be ILLinker-friendly), post ILLinker trimming. + /// warm-up logic (to reduce app size and be trim-friendly), post trimming. /// private async Task SerializeToStreamAsyncCore(Stream targetStream, bool async, CancellationToken cancellationToken) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationReader.cs index 82897e2ce6301..4e7b4e8e6e92d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationReader.cs @@ -14,12 +14,12 @@ // UnconditionalSuppressMessage that specify a Target need to be at the assembly or module level for now. Also, // they won't consider Target unless you also specify Scope to be either "member" or "type" -[assembly: UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:MakeGenericMethod", - Target = "M:System.Xml.Serialization.ReflectionXmlSerializationReader.#cctor", - Justification = "The reason why this warns is because the two static properties call GetTypeDesc() which internally will call " + +[assembly: UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Target = "M:System.Xml.Serialization.ReflectionXmlSerializationReader.#cctor", + Scope = "member", + Justification = "The reason why this warns is because the two static properties call GetTypeDesc() which internally will call " + "ImportTypeDesc() when the passed in type is not considered a primitive type. That said, for both properties here we are passing in string " + - "and XmlQualifiedName which are considered primitive, so they are trim safe.", - Scope = "member")] + "and XmlQualifiedName which are considered primitive, so they are trim safe.")] namespace System.Xml.Serialization { diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index 1c45d26490b0c..62fdc5e25d626 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -186,41 +186,60 @@ public partial struct JsonReaderState } public static partial class JsonSerializer { + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static object? Deserialize(System.ReadOnlySpan utf8Json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize(System.ReadOnlySpan utf8Json, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static object? Deserialize(System.ReadOnlySpan json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize(System.ReadOnlySpan json, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static object? Deserialize(string json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize(string json, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.Serialization.JsonSerializerContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Collections.Generic.IAsyncEnumerable DeserializeAsyncEnumerable<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Threading.Tasks.ValueTask DeserializeAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static TValue? Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static TValue? Deserialize(System.ReadOnlySpan utf8Json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static TValue? Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(System.ReadOnlySpan json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static TValue? Deserialize(System.ReadOnlySpan json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static TValue? Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static TValue? Deserialize(string json, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static TValue? Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static TValue? Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static string Serialize(object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static string Serialize(object? value, System.Type inputType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { } public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, System.Type inputType, System.Text.Json.Serialization.JsonSerializerContext context) { } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type inputType, System.Text.Json.Serialization.JsonSerializerContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Threading.Tasks.Task SerializeAsync<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(System.IO.Stream utf8Json, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, TValue value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static byte[] SerializeToUtf8Bytes(object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static byte[] SerializeToUtf8Bytes(object? value, System.Type inputType, System.Text.Json.Serialization.JsonSerializerContext context) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static byte[] SerializeToUtf8Bytes<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static byte[] SerializeToUtf8Bytes(TValue value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static void Serialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.JsonSerializerOptions? options = null) { } public static void Serialize(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved.")] public static string Serialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } public static string Serialize(TValue value, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) { throw null; } } diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj index 3a9a9cb736cda..6d4d4a9b77bb5 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);netcoreapp3.0;netstandard2.0;net461 enable @@ -10,6 +10,7 @@ + diff --git a/src/libraries/System.Text.Json/src/ILLink/ILLink.Suppressions.Debug.xml b/src/libraries/System.Text.Json/src/ILLink/ILLink.Suppressions.Debug.xml deleted file mode 100644 index ac15216187b6c..0000000000000 --- a/src/libraries/System.Text.Json/src/ILLink/ILLink.Suppressions.Debug.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - ILLink - IL2075 - member - M:System.Text.Json.Serialization.Metadata.ReflectionEmitMemberAccessor.CreateParameterizedConstructor(System.Reflection.ConstructorInfo,System.Type,System.Type,System.Type,System.Type) - - - ILLink - IL2075 - member - M:System.Text.Json.Serialization.Metadata.ReflectionEmitMemberAccessor.CreateParameterizedConstructor(System.Reflection.ConstructorInfo) - - - ILLink - IL2090 - member - M:System.Text.Json.Serialization.Metadata.ReflectionMemberAccessor.CreateParameterizedConstructor(System.Reflection.ConstructorInfo) - - - diff --git a/src/libraries/System.Text.Json/src/ILLink/ILLink.Suppressions.xml b/src/libraries/System.Text.Json/src/ILLink/ILLink.Suppressions.xml index cdc055a743e34..6925c2ab32e4b 100644 --- a/src/libraries/System.Text.Json/src/ILLink/ILLink.Suppressions.xml +++ b/src/libraries/System.Text.Json/src/ILLink/ILLink.Suppressions.xml @@ -5,97 +5,13 @@ ILLink IL2026 member - M:System.Text.Json.Serialization.IEnumerableConverterFactoryHelpers.GetImmutableDictionaryConstructingType(System.Type) + M:System.Text.Json.Node.JsonValue`1.WriteTo(System.Text.Json.Utf8JsonWriter,System.Text.Json.JsonSerializerOptions) ILLink - IL2026 - member - M:System.Text.Json.Serialization.IEnumerableConverterFactoryHelpers.GetImmutableEnumerableConstructingType(System.Type) - - - ILLink - IL2057 - member - M:System.Text.Json.Serialization.IEnumerableConverterFactoryHelpers.GetTypeIfExists(System.String) - - - ILLink - IL2060 - member - M:System.Text.Json.Serialization.IEnumerableConverterFactoryHelpers.GetImmutableDictionaryCreateRangeMethod(System.Type,System.Type,System.Type) - - - ILLink - IL2060 - member - M:System.Text.Json.Serialization.IEnumerableConverterFactoryHelpers.GetImmutableEnumerableCreateRangeMethod(System.Type,System.Type) - - - ILLink - IL2070 - member - M:System.Text.Json.Serialization.Metadata.JsonTypeInfo.#ctor(System.Type,System.Text.Json.Serialization.JsonConverter,System.Type,System.Text.Json.JsonSerializerOptions) - - - ILLink - IL2070 - member - M:System.Text.Json.Serialization.Converters.ObjectConverterFactory.GetDeserializationConstructor(System.Type) - - - ILLink - IL2070 - member - M:System.Text.Json.Serialization.Metadata.ReflectionEmitMemberAccessor.CreateAddMethodDelegate(System.Type) - - - ILLink - IL2070 - member - M:System.Text.Json.Serialization.Metadata.ReflectionEmitMemberAccessor.CreateConstructor(System.Type) - - - ILLink - IL2075 - member - M:System.Text.Json.Serialization.IEnumerableConverterFactoryHelpers.GetImmutableDictionaryCreateRangeMethod(System.Type,System.Type,System.Type) - - - ILLink - IL2075 - member - M:System.Text.Json.Serialization.IEnumerableConverterFactoryHelpers.GetImmutableEnumerableCreateRangeMethod(System.Type,System.Type) - - - ILLink - IL2077 - member - M:System.Text.Json.Serialization.Metadata.ReflectionMemberAccessor.<>c__DisplayClass0_0.<CreateConstructor>b__0 - - - ILLink - IL2080 - member - M:System.Text.Json.Serialization.Metadata.ReflectionMemberAccessor.CreateConstructor(System.Type) - - - ILLink - IL2090 - member - M:System.Text.Json.Serialization.Metadata.ReflectionMemberAccessor.CreateAddMethodDelegate``1 - - - ILLink - IL2090 - member - M:System.Text.Json.Serialization.Metadata.ReflectionMemberAccessor.CreateParameterizedConstructor``1(System.Reflection.ConstructorInfo) - - - ILLink - IL2090 + IL2072 member - M:System.Text.Json.Serialization.Metadata.ReflectionMemberAccessor.CreateParameterizedConstructor``5(System.Reflection.ConstructorInfo) + M:System.Text.Json.Node.JsonValue`1.WriteTo(System.Text.Json.Utf8JsonWriter,System.Text.Json.JsonSerializerOptions) diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index b3cb77ef44f8d..da3e843491517 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -264,6 +264,7 @@ + diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonValueOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonValueOfT.cs index 7687b9b1a48c0..62a5b98fc34df 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonValueOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonValueOfT.cs @@ -73,8 +73,6 @@ public TValue Value return false; } - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2072:ystem.Text.Json.Node.JsonValue.WriteTo(Utf8JsonWriter,JsonSerializerOptions): 'inputType' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicFields', 'DynamicallyAccessedMemberTypes.PublicProperties' in call to 'System.Text.Json.JsonSerializer.Serialize(Utf8JsonWriter,Object,Type,JsonSerializerOptions)'. The return value of method 'System.Object.GetType()' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.", - Justification = "The 'inputType' parameter if obtained by calling System.Object.GetType().")] public override void WriteTo(Utf8JsonWriter writer, JsonSerializerOptions? options = null) { if (writer == null) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactory.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactory.cs index 1805f402a93ed..d90b9c1d0c83e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactory.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactory.cs @@ -5,6 +5,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace System.Text.Json.Serialization.Converters @@ -18,11 +19,16 @@ internal sealed class IEnumerableConverterFactory : JsonConverterFactory private static readonly IEnumerableConverter s_converterForIEnumerable = new IEnumerableConverter(); private static readonly IListConverter s_converterForIList = new IListConverter(); + [RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)] + public IEnumerableConverterFactory() { } + public override bool CanConvert(Type typeToConvert) { return typeof(IEnumerable).IsAssignableFrom(typeToConvert); } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "The ctor is marked RequiresUnreferencedCode.")] public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { Type converterType; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactoryHelpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactoryHelpers.cs index 99a1521137469..52553806172fb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactoryHelpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableConverterFactoryHelpers.cs @@ -10,6 +10,10 @@ namespace System.Text.Json.Serialization { internal static class IEnumerableConverterFactoryHelpers { + // System.Text.Json doesn't take a direct reference to System.Collections.Immutable so + // any netstandard2.0 consumers don't need to reference System.Collections.Immutable. + // So instead, implement a "weak reference" by using strings to check for Immutable types. + // Immutable collection types. private const string ImmutableArrayGenericTypeName = "System.Collections.Immutable.ImmutableArray`1"; private const string ImmutableListGenericTypeName = "System.Collections.Immutable.ImmutableList`1"; @@ -148,6 +152,10 @@ public static bool IsImmutableEnumerableType(this Type type) [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableQueueTypeName, ImmutableCollectionsAssembly)] [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableSortedSetTypeName, ImmutableCollectionsAssembly)] [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableHashSetTypeName, ImmutableCollectionsAssembly)] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern", + Justification = "The CreateRange method is preserved by the DynamicDependency attribute.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2060:MakeGenericMethod", + Justification = "Immutable collections don't have trimming annotations.")] public static MethodInfo GetImmutableEnumerableCreateRangeMethod(this Type type, Type elementType) { Type? constructingType = GetImmutableEnumerableConstructingType(type); @@ -172,6 +180,10 @@ public static MethodInfo GetImmutableEnumerableCreateRangeMethod(this Type type, [DynamicDependency(CreateRangeMethodNameForDictionary, ImmutableDictionaryTypeName, ImmutableCollectionsAssembly)] [DynamicDependency(CreateRangeMethodNameForDictionary, ImmutableSortedDictionaryTypeName, ImmutableCollectionsAssembly)] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern", + Justification = "The CreateRange method is preserved by the DynamicDependency attribute.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2060:MakeGenericMethod", + Justification = "Immutable collections don't have trimming annotations.")] public static MethodInfo GetImmutableDictionaryCreateRangeMethod(this Type type, Type keyType, Type valueType) { Type? constructingType = GetImmutableDictionaryConstructingType(type); @@ -194,6 +206,9 @@ public static MethodInfo GetImmutableDictionaryCreateRangeMethod(this Type type, return null!; } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "Json can't take a direct dependency on Collections.Immutable." + + "The types used here will be preserved by the DynamicDependency attributes on the only caller - GetImmutableEnumerableCreateRangeMethod.")] private static Type? GetImmutableEnumerableConstructingType(Type type) { Debug.Assert(type.IsImmutableEnumerableType()); @@ -237,6 +252,9 @@ public static MethodInfo GetImmutableDictionaryCreateRangeMethod(this Type type, return underlyingType.Assembly.GetType(constructingTypeName); } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "Json can't take a direct dependency on Collections.Immutable." + + "The types used here will be preserved by the DynamicDependency attributes on the only caller - GetImmutableDictionaryCreateRangeMethod.")] private static Type? GetImmutableDictionaryConstructingType(Type type) { Debug.Assert(type.IsImmutableDictionaryType()); @@ -293,6 +311,9 @@ public static bool IsNonGenericStackOrQueue(this Type type) // This method takes an unannotated string which makes linker reflection analysis lose track of the type we are // looking for. This indirection allows the removal of the type if it is not used in the calling application. + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2057:TypeGetType", + Justification = "This method exists to allow for 'weak references' to the Stack and Queue types. If those types are used in the app, " + + "they will be preserved by the app and Type.GetType will return them. If those types are not used in the app, we don't want to preserve them here.")] private static Type? GetTypeIfExists(string name) => Type.GetType(name, false); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableWithAddMethodConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableWithAddMethodConverter.cs index d9d66d9681f44..6aa72b315887b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableWithAddMethodConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableWithAddMethodConverter.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization.Metadata; namespace System.Text.Json.Serialization.Converters @@ -11,6 +12,9 @@ internal sealed class IEnumerableWithAddMethodConverter : IEnumerableDefaultConverter where TCollection : IEnumerable { + [RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)] + public IEnumerableWithAddMethodConverter() { } + protected override void Add(in object? value, ref ReadStack state) { var addMethodDelegate = ((Action?)state.Current.JsonTypeInfo.AddMethodDelegate); @@ -18,6 +22,8 @@ protected override void Add(in object? value, ref ReadStack state) addMethodDelegate((TCollection)state.Current.ReturnValue!, value); } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2091:UnrecognizedReflectionPattern", + Justification = "The ctor is marked RequiresUnreferencedCode.")] protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) { JsonTypeInfo typeInfo = state.Current.JsonTypeInfo; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectConverterFactory.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectConverterFactory.cs index f2c6c9c98b7f6..1a3903a5327b0 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectConverterFactory.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectConverterFactory.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text.Json.Serialization.Metadata; @@ -14,6 +15,9 @@ namespace System.Text.Json.Serialization.Converters /// internal sealed class ObjectConverterFactory : JsonConverterFactory { + [RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)] + public ObjectConverterFactory() { } + public override bool CanConvert(Type typeToConvert) { // This is the last built-in factory converter, so if the IEnumerableConverterFactory doesn't @@ -22,6 +26,8 @@ public override bool CanConvert(Type typeToConvert) return true; } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2067:UnrecognizedReflectionPattern", + Justification = "The ctor is marked RequiresUnreferencedCode.")] public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { if (IsKeyValuePair(typeToConvert)) @@ -109,7 +115,8 @@ private JsonConverter CreateKeyValuePairConverter(Type type, JsonSerializerOptio return converter; } - private ConstructorInfo? GetDeserializationConstructor(Type type) + private ConstructorInfo? GetDeserializationConstructor( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type) { ConstructorInfo? ctorWithAttribute = null; ConstructorInfo? publicParameterlessCtor = null; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Helpers.cs index f7165a3ac734a..975c97b4b3968 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Helpers.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Metadata; @@ -9,6 +10,9 @@ namespace System.Text.Json { public static partial class JsonSerializer { + internal const string SerializationUnreferencedCodeMessage = "Json Serialization and Deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo/JsonSerializerContext, or make sure all of the required types are preserved."; + + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] private static JsonTypeInfo GetTypeInfo(Type runtimeType, JsonSerializerOptions? options) { options ??= JsonSerializerOptions.s_defaultOptions; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs index 9fb2b1dc2f155..4fbdb1aa30642 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Span.cs @@ -24,6 +24,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static TValue? Deserialize<[DynamicallyAccessedMembers(JsonHelpers.MembersAccessedOnRead)] TValue>(ReadOnlySpan utf8Json, JsonSerializerOptions? options = null) => ReadUsingOptions(utf8Json, typeof(TValue), options); @@ -46,6 +47,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static object? Deserialize(ReadOnlySpan utf8Json, [DynamicallyAccessedMembers(JsonHelpers.MembersAccessedOnRead)] Type returnType, JsonSerializerOptions? options = null) { if (returnType == null) @@ -119,6 +121,7 @@ public static partial class JsonSerializer return ReadUsingMetadata(utf8Json, GetTypeInfo(context, returnType)); } + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] private static TValue? ReadUsingOptions(ReadOnlySpan utf8Json, Type returnType, JsonSerializerOptions? options) { options ??= JsonSerializerOptions.s_defaultOptions; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs index 74ed83c0def71..05d06d04426e8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs @@ -13,6 +13,11 @@ using System.Threading; using System.Threading.Tasks; +[assembly: UnconditionalSuppressMessage("ReflectionAnalysis", "IL2091:UnrecognizedReflectionPattern", + Target = "M:System.Text.Json.JsonSerializer.<g__CreateAsyncEnumerableDeserializer|27_0>d`1.MoveNext()", + Scope = "member", + Justification = "Workaround for https://github.com/mono/linker/issues/1416. The outer method is marked as RequiresUnreferencedCode.")] + namespace System.Text.Json { public static partial class JsonSerializer @@ -39,6 +44,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static ValueTask DeserializeAsync<[DynamicallyAccessedMembers(JsonHelpers.MembersAccessedOnRead)] TValue>( Stream utf8Json, JsonSerializerOptions? options = null, @@ -75,6 +81,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static ValueTask DeserializeAsync( Stream utf8Json, [DynamicallyAccessedMembers(JsonHelpers.MembersAccessedOnRead)] Type returnType, @@ -197,6 +204,7 @@ public static partial class JsonSerializer /// /// is . /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static IAsyncEnumerable DeserializeAsyncEnumerable<[DynamicallyAccessedMembers(JsonHelpers.MembersAccessedOnRead)] TValue>( Stream utf8Json, JsonSerializerOptions? options = null, @@ -212,6 +220,7 @@ public static partial class JsonSerializer return CreateAsyncEnumerableDeserializer(utf8Json, options, cancellationToken); + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] static async IAsyncEnumerable CreateAsyncEnumerableDeserializer( Stream utf8Json, JsonSerializerOptions options, @@ -220,7 +229,7 @@ static async IAsyncEnumerable CreateAsyncEnumerableDeserializer( var bufferState = new ReadAsyncBufferState(options.DefaultBufferSize); // Hardcode the queue converter to avoid accidental use of custom converters JsonConverter converter = QueueOfTConverter, TValue>.Instance; - JsonTypeInfo jsonTypeInfo = new JsonTypeInfo(typeof(Queue), converter, typeof(Queue), options); + JsonTypeInfo jsonTypeInfo = CreateQueueJsonTypeInfo(converter, options); ReadStack readStack = default; readStack.Initialize(jsonTypeInfo, supportContinuation: true); var jsonReaderState = new JsonReaderState(options.GetReaderOptions()); @@ -246,6 +255,11 @@ static async IAsyncEnumerable CreateAsyncEnumerableDeserializer( bufferState.Dispose(); } } + + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "Workaround for https://github.com/mono/linker/issues/1416. All usages are marked as unsafe.")] + static JsonTypeInfo CreateQueueJsonTypeInfo(JsonConverter queueConverter, JsonSerializerOptions queueOptions) => + new JsonTypeInfo(typeof(Queue), queueConverter, typeof(Queue), queueOptions); } internal static async ValueTask ReadAllAsync( @@ -389,6 +403,7 @@ internal static TValue ContinueDeserialize( return value; } + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] private static ValueTask ReadAllUsingOptionsAsync( Stream utf8Json, Type returnType, diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs index e6fea92c19dae..ff97a099739b4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.String.cs @@ -40,6 +40,7 @@ public static partial class JsonSerializer /// Using a is not as efficient as using the /// UTF-8 methods since the implementation natively uses UTF-8. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static TValue? Deserialize<[DynamicallyAccessedMembers(JsonHelpers.MembersAccessedOnRead)] TValue>(string json, JsonSerializerOptions? options = null) { if (json == null) @@ -73,6 +74,7 @@ public static partial class JsonSerializer /// Using a UTF-16 span is not as efficient as using the /// UTF-8 methods since the implementation natively uses UTF-8. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static TValue? Deserialize<[DynamicallyAccessedMembers(JsonHelpers.MembersAccessedOnRead)] TValue>(ReadOnlySpan json, JsonSerializerOptions? options = null) { // default/null span is treated as empty @@ -107,6 +109,7 @@ public static partial class JsonSerializer /// Using a is not as efficient as using the /// UTF-8 methods since the implementation natively uses UTF-8. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static object? Deserialize(string json, [DynamicallyAccessedMembers(JsonHelpers.MembersAccessedOnRead)] Type returnType, JsonSerializerOptions? options = null) { if (json == null) @@ -149,6 +152,7 @@ public static partial class JsonSerializer /// Using a UTF-16 span is not as efficient as using the /// UTF-8 methods since the implementation natively uses UTF-8. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static object? Deserialize(ReadOnlySpan json, [DynamicallyAccessedMembers(JsonHelpers.MembersAccessedOnRead)] Type returnType, JsonSerializerOptions? options = null) { // default/null span is treated as empty @@ -345,6 +349,7 @@ public static partial class JsonSerializer return ReadUsingMetadata(json, GetTypeInfo(context, returnType)); } + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] private static TValue? ReadUsingOptions(ReadOnlySpan json, Type returnType, JsonSerializerOptions? options) => ReadUsingMetadata(json, GetTypeInfo(returnType, options)); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs index e5a3d0ba5e244..1c9bd5dae17d6 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Utf8JsonReader.cs @@ -53,6 +53,7 @@ public static partial class JsonSerializer /// Hence, , , and are used while reading. /// /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static TValue? Deserialize<[DynamicallyAccessedMembers(JsonHelpers.MembersAccessedOnRead)] TValue>(ref Utf8JsonReader reader, JsonSerializerOptions? options = null) => ReadUsingOptions(ref reader, typeof(TValue), options); @@ -101,6 +102,7 @@ public static partial class JsonSerializer /// Hence, , , and are used while reading. /// /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static object? Deserialize(ref Utf8JsonReader reader, [DynamicallyAccessedMembers(JsonHelpers.MembersAccessedOnRead)] Type returnType, JsonSerializerOptions? options = null) { if (returnType == null) @@ -227,6 +229,7 @@ public static partial class JsonSerializer return ReadUsingMetadata(ref reader, GetTypeInfo(context, returnType)); } + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] private static TValue? ReadUsingOptions(ref Utf8JsonReader reader, Type returnType, JsonSerializerOptions? options) { JsonTypeInfo jsonTypeInfo = GetTypeInfo(returnType, options); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.ByteArray.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.ByteArray.cs index 068a6b6936555..ffab612ce1967 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.ByteArray.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.ByteArray.cs @@ -19,6 +19,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static byte[] SerializeToUtf8Bytes<[DynamicallyAccessedMembers(MembersAccessedOnWrite)] TValue>( TValue value, JsonSerializerOptions? options = null) @@ -43,6 +44,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static byte[] SerializeToUtf8Bytes( object? value, [DynamicallyAccessedMembers(MembersAccessedOnWrite)] Type inputType, @@ -109,6 +111,7 @@ public static byte[] SerializeToUtf8Bytes(object? value, Type inputType, JsonSer return WriteCoreBytes(value!, GetTypeInfo(context, runtimeType)); } + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] private static byte[] WriteCoreBytes(in TValue value, Type runtimeType, JsonSerializerOptions? options) { JsonTypeInfo jsonTypeInfo = GetTypeInfo(runtimeType, options); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs index 6d9724a5976a6..ee6c0f7fba9b4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Stream.cs @@ -27,6 +27,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static Task SerializeAsync<[DynamicallyAccessedMembers(MembersAccessedOnWrite)] TValue>( Stream utf8Json, TValue value, @@ -65,6 +66,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static Task SerializeAsync( Stream utf8Json, object? value, @@ -159,6 +161,7 @@ public static Task SerializeAsync( cancellationToken); } + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] private static Task WriteAsync( Stream utf8Json, in TValue value, diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs index 2d433da3de36b..de03bc8ad9f91 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs @@ -23,6 +23,7 @@ public static partial class JsonSerializer /// encoding since the implementation internally uses UTF-8. See also /// and . /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static string Serialize<[DynamicallyAccessedMembers(MembersAccessedOnWrite)] TValue>(TValue value, JsonSerializerOptions? options = null) { return Write(value, GetRuntimeType(value), options); @@ -46,6 +47,7 @@ public static partial class JsonSerializer /// encoding since the implementation internally uses UTF-8. See also /// and . /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static string Serialize( object? value, [DynamicallyAccessedMembers(MembersAccessedOnWrite)] Type inputType, @@ -109,6 +111,7 @@ public static string Serialize(object? value, Type inputType, JsonSerializerCont return WriteUsingMetadata(value, GetTypeInfo(context, runtimeType)); } + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] private static string Write(in TValue value, Type runtimeType, JsonSerializerOptions? options) { JsonTypeInfo typeInfo = GetTypeInfo(runtimeType, options); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Utf8JsonWriter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Utf8JsonWriter.cs index 1732d8ac9a6ff..57d9c4796669a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Utf8JsonWriter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Utf8JsonWriter.cs @@ -22,6 +22,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static void Serialize<[DynamicallyAccessedMembers(MembersAccessedOnWrite)] TValue>( Utf8JsonWriter writer, TValue value, @@ -47,6 +48,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] public static void Serialize( Utf8JsonWriter writer, object? value, @@ -125,6 +127,7 @@ public static void Serialize(Utf8JsonWriter writer, object? value, Type inputTyp WriteUsingMetadata(writer, value, GetTypeInfo(context, runtimeType)); } + [RequiresUnreferencedCode(SerializationUnreferencedCodeMessage)] private static void Serialize(Utf8JsonWriter writer, in TValue value, Type runtimeType, JsonSerializerOptions? options) { if (writer == null) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs index 90f1321d7ffd6..200ad85724a60 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs @@ -4,6 +4,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text.Json.Serialization; using System.Text.Json.Serialization.Converters; @@ -25,6 +26,7 @@ public sealed partial class JsonSerializerOptions // The cached converters (custom or built-in). private readonly ConcurrentDictionary _converters = new ConcurrentDictionary(); + [RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)] internal void RootBuiltInConvertersAndTypeInfoCreator() { s_defaultSimpleConverters ??= GetDefaultSimpleConverters(); @@ -44,7 +46,10 @@ internal void RootBuiltInConvertersAndTypeInfoCreator() new ObjectConverterFactory() }; - _typeInfoCreationFunc ??= static (type, options) => new JsonTypeInfo(type, options); + _typeInfoCreationFunc ??= CreateJsonTypeInfo; + + [RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)] + static JsonTypeInfo CreateJsonTypeInfo(Type type, JsonSerializerOptions options) => new JsonTypeInfo(type, options); } private static Dictionary GetDefaultSimpleConverters() diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs index a7c5e64923f85..e97f94abf22d8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs @@ -4,6 +4,7 @@ using System.Collections.Concurrent; using System.ComponentModel; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Text.Encodings.Web; using System.Text.Json.Node; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs index ff095db662b4e..2f7e7614430ab 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonTypeInfo.cs @@ -162,6 +162,7 @@ internal JsonTypeInfo(Type type, JsonSerializerOptions options, ConverterStrateg PropertyInfoForTypeInfo = null!; } + [RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)] internal JsonTypeInfo(Type type, JsonSerializerOptions options) : this( type, @@ -176,6 +177,7 @@ internal JsonTypeInfo(Type type, JsonSerializerOptions options) : { } + [RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)] internal JsonTypeInfo(Type type, JsonConverter converter, Type runtimeType, JsonSerializerOptions options) { Type = type; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/MemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/MemberAccessor.cs index 20706bbf73198..f4f934ccf7e9a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/MemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/MemberAccessor.cs @@ -2,20 +2,22 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace System.Text.Json.Serialization.Metadata { internal abstract class MemberAccessor { - public abstract JsonTypeInfo.ConstructorDelegate? CreateConstructor(Type classType); + public abstract JsonTypeInfo.ConstructorDelegate? CreateConstructor( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type classType); public abstract JsonTypeInfo.ParameterizedConstructorDelegate? CreateParameterizedConstructor(ConstructorInfo constructor); public abstract JsonTypeInfo.ParameterizedConstructorDelegate? CreateParameterizedConstructor(ConstructorInfo constructor); - public abstract Action CreateAddMethodDelegate(); + public abstract Action CreateAddMethodDelegate<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TCollection>(); public abstract Func, TCollection> CreateImmutableEnumerableCreateRangeDelegate(); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs index 40d3163b719dd..24e0b20927b73 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionEmitMemberAccessor.cs @@ -12,7 +12,8 @@ namespace System.Text.Json.Serialization.Metadata { internal sealed class ReflectionEmitMemberAccessor : MemberAccessor { - public override JsonTypeInfo.ConstructorDelegate? CreateConstructor(Type type) + public override JsonTypeInfo.ConstructorDelegate? CreateConstructor( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) { Debug.Assert(type != null); ConstructorInfo? realMethod = type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, binder: null, Type.EmptyTypes, modifiers: null); @@ -64,7 +65,7 @@ internal sealed class ReflectionEmitMemberAccessor : MemberAccessor Debug.Assert(type != null); Debug.Assert(!type.IsAbstract); - Debug.Assert(Array.IndexOf(type.GetConstructors(BindingFlags.Public | BindingFlags.Instance), constructor) >= 0); + Debug.Assert(constructor.IsPublic && !constructor.IsStatic); ParameterInfo[] parameters = constructor.GetParameters(); int parameterCount = parameters.Length; @@ -110,7 +111,7 @@ public override JsonTypeInfo.ParameterizedConstructorDelegate= 0); + Debug.Assert(constructor.IsPublic && !constructor.IsStatic); ParameterInfo[] parameters = constructor.GetParameters(); int parameterCount = parameters.Length; @@ -145,10 +146,11 @@ public override JsonTypeInfo.ParameterizedConstructorDelegate CreateAddMethodDelegate() => + public override Action CreateAddMethodDelegate<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TCollection>() => CreateDelegate>(CreateAddMethodDelegate(typeof(TCollection))); - private static DynamicMethod CreateAddMethodDelegate(Type collectionType) + private static DynamicMethod CreateAddMethodDelegate( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] Type collectionType) { // We verified this won't be null when we created the converter that calls this method. MethodInfo realMethod = (collectionType.GetMethod("Push") ?? collectionType.GetMethod("Enqueue"))!; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs index 4ad93ea383591..b2e7e961bb26d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/ReflectionMemberAccessor.cs @@ -3,13 +3,15 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace System.Text.Json.Serialization.Metadata { internal sealed class ReflectionMemberAccessor : MemberAccessor { - public override JsonTypeInfo.ConstructorDelegate? CreateConstructor(Type type) + public override JsonTypeInfo.ConstructorDelegate? CreateConstructor( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) { Debug.Assert(type != null); ConstructorInfo? realMethod = type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, binder: null, Type.EmptyTypes, modifiers: null); @@ -32,7 +34,7 @@ internal sealed class ReflectionMemberAccessor : MemberAccessor Type type = typeof(T); Debug.Assert(!type.IsAbstract); - Debug.Assert(Array.IndexOf(type.GetConstructors(BindingFlags.Public | BindingFlags.Instance), constructor) >= 0); + Debug.Assert(constructor.DeclaringType == type && constructor.IsPublic && !constructor.IsStatic); int parameterCount = constructor.GetParameters().Length; @@ -72,7 +74,7 @@ public override JsonTypeInfo.ParameterizedConstructorDelegate= 0); + Debug.Assert(constructor.DeclaringType == type && constructor.IsPublic && !constructor.IsStatic); int parameterCount = constructor.GetParameters().Length; @@ -108,7 +110,7 @@ public override JsonTypeInfo.ParameterizedConstructorDelegate CreateAddMethodDelegate() + public override Action CreateAddMethodDelegate<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)] TCollection>() { Type collectionType = typeof(TCollection); Type elementType = JsonTypeInfo.ObjectType;