From e317b96705f74a5108c61c2fa4eacc814b302630 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Thu, 25 Jun 2020 18:55:51 -0700 Subject: [PATCH 01/10] Add linker annotations for System.Text.Json --- .../Attributes/JsonConverterAttribute.cs | 5 +- .../Collection/IEnumerableConverterFactory.cs | 18 -- .../IEnumerableConverterFactoryHelpers.cs | 2 + .../Object/ObjectConverterFactory.cs | 5 - .../Converters/Value/EnumConverterFactory.cs | 4 - .../JsonSerializer.Read.Helpers.cs | 3 + .../Serialization/JsonSerializer.Read.Span.cs | 4 +- .../JsonSerializer.Read.Stream.cs | 5 +- .../JsonSerializer.Read.String.cs | 4 +- .../JsonSerializer.Read.Utf8JsonReader.cs | 4 +- .../JsonSerializer.Write.ByteArray.cs | 11 +- .../JsonSerializer.Write.Helpers.cs | 4 + .../JsonSerializer.Write.Stream.cs | 5 +- .../JsonSerializer.Write.String.cs | 9 +- .../JsonSerializer.Write.Utf8JsonWriter.cs | 14 +- .../Serialization/JsonStringEnumConverter.cs | 4 - .../TrimmingTests/CollectionConvertersTest.cs | 157 ++++++++++++++++++ .../tests/TrimmingTests/EnumConverterTest.cs | 28 ++++ .../tests/TrimmingTests/Helper.cs | 121 ++++++++++++++ .../JsonConstructorAttributeTest.cs | 29 ++++ .../TrimmingTests/ObjectConvertersTest.cs | 62 +++++++ .../Deserialize.FromReader.BoxedObject.cs | 39 +++++ .../Deserialize.FromReader.TypedObject.cs | 39 +++++ .../Deserialize.FromSpan.BoxedObject.cs | 37 +++++ .../Deserialize.FromSpan.TypedObject.cs | 37 +++++ .../Deserialize.FromString.BoxedObject.cs | 36 ++++ .../Deserialize.FromString.TypedObject.cs | 36 ++++ ...DeserializeAsync.FromStream.BoxedObject.cs | 54 ++++++ ...DeserializeAsync.FromStream.TypedObject.cs | 54 ++++++ .../Serialize.ToByteArray.BoxedObject.cs | 38 +++++ .../Serialize.ToByteArray.TypedObject.cs | 38 +++++ ...rialize.ToString.BoxedObject.WithWriter.cs | 47 ++++++ .../Serialize.ToString.BoxedObject.cs | 34 ++++ ...rialize.ToString.TypedObject.WithWriter.cs | 47 ++++++ .../Serialize.ToString.TypedObject.cs | 34 ++++ .../SerializeAsync.ToStream.BoxedObject.cs | 56 +++++++ .../SerializeAsync.ToStream.TypedObject.cs | 56 +++++++ .../StackOrQueueNotRootedTest.cs | 1 - .../System.Text.Json.TrimmingTests.proj | 59 +++++++ 39 files changed, 1190 insertions(+), 50 deletions(-) create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConvertersTest.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/EnumConverterTest.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/JsonConstructorAttributeTest.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/ObjectConvertersTest.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.BoxedObject.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.TypedObject.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.WithWriter.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.WithWriter.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.BoxedObject.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.TypedObject.cs diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonConverterAttribute.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonConverterAttribute.cs index 51095cd5c7b125..32a380fee0af9f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonConverterAttribute.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonConverterAttribute.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; + namespace System.Text.Json.Serialization { /// @@ -21,7 +23,7 @@ public class JsonConverterAttribute : JsonAttribute /// Initializes a new instance of with the specified converter type. /// /// The type of the converter. - public JsonConverterAttribute(Type converterType) + public JsonConverterAttribute([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type converterType) { ConverterType = converterType; } @@ -34,6 +36,7 @@ protected JsonConverterAttribute() { } /// /// The type of the converter to create, or null if should be used to obtain the converter. /// + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] public Type? ConverterType { get; private set; } /// 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 56012689bc5e66..1cae8aec1f2ad0 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 @@ -6,7 +6,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace System.Text.Json.Serialization.Converters @@ -25,23 +24,6 @@ public override bool CanConvert(Type typeToConvert) return typeof(IEnumerable).IsAssignableFrom(typeToConvert); } - [DynamicDependency("#ctor", typeof(ArrayConverter<,>))] - [DynamicDependency("#ctor", typeof(ConcurrentQueueOfTConverter<,>))] - [DynamicDependency("#ctor", typeof(ConcurrentStackOfTConverter<,>))] - [DynamicDependency("#ctor", typeof(DictionaryOfStringTValueConverter<,>))] - [DynamicDependency("#ctor", typeof(ICollectionOfTConverter<,>))] - [DynamicDependency("#ctor", typeof(IDictionaryOfStringTValueConverter<,>))] - [DynamicDependency("#ctor", typeof(IEnumerableOfTConverter<,>))] - [DynamicDependency("#ctor", typeof(IEnumerableWithAddMethodConverter<>))] - [DynamicDependency("#ctor", typeof(IListConverter<>))] - [DynamicDependency("#ctor", typeof(IListOfTConverter<,>))] - [DynamicDependency("#ctor", typeof(ImmutableDictionaryOfStringTValueConverter<,>))] - [DynamicDependency("#ctor", typeof(ImmutableEnumerableOfTConverter<,>))] - [DynamicDependency("#ctor", typeof(IReadOnlyDictionaryOfStringTValueConverter<,>))] - [DynamicDependency("#ctor", typeof(ISetOfTConverter<,>))] - [DynamicDependency("#ctor", typeof(ListOfTConverter<,>))] - [DynamicDependency("#ctor", typeof(QueueOfTConverter<,>))] - [DynamicDependency("#ctor", typeof(StackOfTConverter<,>))] public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { Type converterType = null!; 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 b12f99f9aa0bb9..2e10216d103e87 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 @@ -139,6 +139,7 @@ public static bool IsImmutableEnumerableType(this Type type) } } + // TODO: https://github.com/dotnet/runtime/issues/38593. public static MethodInfo GetImmutableEnumerableCreateRangeMethod(this Type type, Type elementType) { Type constructingType = GetImmutableEnumerableConstructingType(type); @@ -159,6 +160,7 @@ public static MethodInfo GetImmutableEnumerableCreateRangeMethod(this Type type, return null!; } + // TODO: https://github.com/dotnet/runtime/issues/38593. public static MethodInfo GetImmutableDictionaryCreateRangeMethod(this Type type, Type elementType) { Type constructingType = GetImmutableDictionaryConstructingType(type); 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 3a9db46fa8d929..ca1dda48f2dade 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 @@ -5,7 +5,6 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace System.Text.Json.Serialization.Converters @@ -23,10 +22,6 @@ public override bool CanConvert(Type typeToConvert) return true; } - [DynamicDependency("#ctor", typeof(KeyValuePairConverter<,>))] - [DynamicDependency("#ctor", typeof(LargeObjectWithParameterizedConstructorConverter<>))] - [DynamicDependency("#ctor", typeof(ObjectDefaultConverter<>))] - [DynamicDependency("#ctor", typeof(SmallObjectWithParameterizedConstructorConverter<,,,,>))] public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { if (IsKeyValuePair(typeToConvert)) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverterFactory.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverterFactory.cs index 49abb0e2cb6d04..90835d5bd3086e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverterFactory.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/EnumConverterFactory.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Reflection; -using System.Diagnostics.CodeAnalysis; namespace System.Text.Json.Serialization.Converters { @@ -18,9 +17,6 @@ public override bool CanConvert(Type type) return type.IsEnum; } - [DynamicDependency( - "#ctor(System.Text.Json.Serialization.Converters.EnumConverterOptions,System.Text.Json.JsonSerializerOptions)", - typeof(EnumConverter<>))] public override JsonConverter CreateConverter(Type type, JsonSerializerOptions options) { JsonConverter converter = (JsonConverter)Activator.CreateInstance( diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs index bfdbd5993c65b4..821a999639c118 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs @@ -10,6 +10,9 @@ namespace System.Text.Json { public static partial class JsonSerializer { + // Members accessed by the serializer when deserializing. + private const DynamicallyAccessedMemberTypes MembersAccessedOnRead = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicProperties; + [return: MaybeNull] private static TValue ReadCore(ref Utf8JsonReader reader, Type returnType, JsonSerializerOptions options) { 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 3aacdc8839b403..b840279540cc84 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,7 +24,7 @@ public static partial class JsonSerializer /// for or its serializable members. /// [return: MaybeNull] - public static TValue Deserialize(ReadOnlySpan utf8Json, JsonSerializerOptions? options = null) + public static TValue Deserialize<[DynamicallyAccessedMembers(MembersAccessedOnRead)] TValue>(ReadOnlySpan utf8Json, JsonSerializerOptions? options = null) { if (options == null) { @@ -56,7 +56,7 @@ public static TValue Deserialize(ReadOnlySpan utf8Json, JsonSerial /// There is no compatible /// for or its serializable members. /// - public static object? Deserialize(ReadOnlySpan utf8Json, Type returnType, JsonSerializerOptions? options = null) + public static object? Deserialize(ReadOnlySpan utf8Json, [DynamicallyAccessedMembers(MembersAccessedOnRead)] Type returnType, JsonSerializerOptions? options = null) { if (returnType == null) { 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 4bd48ea447bb09..35a607ed8b79a9 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 @@ -4,6 +4,7 @@ using System.Buffers; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text.Json.Serialization; using System.Threading; @@ -35,7 +36,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// - public static ValueTask DeserializeAsync( + public static ValueTask DeserializeAsync<[DynamicallyAccessedMembers(MembersAccessedOnRead)] TValue>( Stream utf8Json, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) @@ -73,7 +74,7 @@ public static ValueTask DeserializeAsync( /// public static ValueTask DeserializeAsync( Stream utf8Json, - Type returnType, + [DynamicallyAccessedMembers(MembersAccessedOnRead)] Type returnType, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { 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 082c49645379ea..adc5c2753a2285 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 @@ -36,7 +36,7 @@ public static partial class JsonSerializer /// UTF-8 methods since the implementation natively uses UTF-8. /// [return: MaybeNull] - public static TValue Deserialize(string json, JsonSerializerOptions? options = null) + public static TValue Deserialize<[DynamicallyAccessedMembers(MembersAccessedOnRead)] TValue>(string json, JsonSerializerOptions? options = null) { if (json == null) { @@ -68,7 +68,7 @@ public static TValue Deserialize(string json, JsonSerializerOptions? opt /// Using a is not as efficient as using the /// UTF-8 methods since the implementation natively uses UTF-8. /// - public static object? Deserialize(string json, Type returnType, JsonSerializerOptions? options = null) + public static object? Deserialize(string json, [DynamicallyAccessedMembers(MembersAccessedOnRead)] Type returnType, JsonSerializerOptions? options = null) { if (json == null) { 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 b6395bd5c9ee25..4cc19526b24990 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 @@ -54,7 +54,7 @@ public static partial class JsonSerializer /// /// [return: MaybeNull] - public static TValue Deserialize(ref Utf8JsonReader reader, JsonSerializerOptions? options = null) + public static TValue Deserialize<[DynamicallyAccessedMembers(MembersAccessedOnRead)] TValue>(ref Utf8JsonReader reader, JsonSerializerOptions? options = null) { if (options == null) { @@ -112,7 +112,7 @@ public static TValue Deserialize(ref Utf8JsonReader reader, JsonSerializ /// Hence, , , are used while reading. /// /// - public static object? Deserialize(ref Utf8JsonReader reader, Type returnType, JsonSerializerOptions? options = null) + public static object? Deserialize(ref Utf8JsonReader reader, [DynamicallyAccessedMembers(MembersAccessedOnRead)] Type returnType, JsonSerializerOptions? options = null) { if (returnType == null) { 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 cf948b2a694452..4cbdcfe76f7981 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 @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; + namespace System.Text.Json { public static partial class JsonSerializer @@ -16,7 +18,9 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// - public static byte[] SerializeToUtf8Bytes(TValue value, JsonSerializerOptions? options = null) + public static byte[] SerializeToUtf8Bytes<[DynamicallyAccessedMembers(MembersAccessedOnWrite)] TValue>( + TValue value, + JsonSerializerOptions? options = null) { return WriteCoreBytes(value, typeof(TValue), options); } @@ -38,7 +42,10 @@ public static byte[] SerializeToUtf8Bytes(TValue value, JsonSerializerOp /// There is no compatible /// for or its serializable members. /// - public static byte[] SerializeToUtf8Bytes(object? value, Type inputType, JsonSerializerOptions? options = null) + public static byte[] SerializeToUtf8Bytes( + object? value, + [DynamicallyAccessedMembers(MembersAccessedOnWrite)] Type inputType, + JsonSerializerOptions? options = null) { if (inputType == null) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs index 1b8c7929e6cc18..27258abb972c6b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.Helpers.cs @@ -3,12 +3,16 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; namespace System.Text.Json { public static partial class JsonSerializer { + // Members accessed by the serializer when serializing. + private const DynamicallyAccessedMemberTypes MembersAccessedOnWrite = DynamicallyAccessedMemberTypes.PublicProperties; + private static void WriteCore( Utf8JsonWriter writer, in TValue value, 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 07856fed8faf62..8b9bf61c3d13f0 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 @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Text.Json.Serialization; using System.Threading; @@ -26,7 +27,7 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// - public static Task SerializeAsync( + public static Task SerializeAsync<[DynamicallyAccessedMembers(MembersAccessedOnWrite)] TValue>( Stream utf8Json, TValue value, JsonSerializerOptions? options = null, @@ -60,7 +61,7 @@ public static Task SerializeAsync( public static Task SerializeAsync( Stream utf8Json, object? value, - Type inputType, + [DynamicallyAccessedMembers(MembersAccessedOnWrite)] Type inputType, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default) { 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 b09b1e68e618b9..a20e732f51ed6c 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 @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics.CodeAnalysis; + namespace System.Text.Json { public static partial class JsonSerializer @@ -20,7 +22,7 @@ public static partial class JsonSerializer /// encoding since the implementation internally uses UTF-8. See also /// and . /// - public static string Serialize(TValue value, JsonSerializerOptions? options = null) + public static string Serialize<[DynamicallyAccessedMembers(MembersAccessedOnWrite)] TValue>(TValue value, JsonSerializerOptions? options = null) { return Serialize(value, typeof(TValue), options); } @@ -43,7 +45,10 @@ public static string Serialize(TValue value, JsonSerializerOptions? opti /// encoding since the implementation internally uses UTF-8. See also /// and . /// - public static string Serialize(object? value, Type inputType, JsonSerializerOptions? options = null) + public static string Serialize( + object? value, + [DynamicallyAccessedMembers(MembersAccessedOnWrite)] Type inputType, + JsonSerializerOptions? options = null) { if (inputType == null) { 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 c9a5c31dea02bc..729bbc2bff269b 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 @@ -2,8 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Text.Json.Serialization; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; namespace System.Text.Json { @@ -22,7 +23,10 @@ public static partial class JsonSerializer /// There is no compatible /// for or its serializable members. /// - public static void Serialize(Utf8JsonWriter writer, TValue value, JsonSerializerOptions? options = null) + public static void Serialize<[DynamicallyAccessedMembers(MembersAccessedOnWrite)] TValue>( + Utf8JsonWriter writer, + TValue value, + JsonSerializerOptions? options = null) { Serialize(writer, value, typeof(TValue), options); } @@ -44,7 +48,11 @@ public static void Serialize(Utf8JsonWriter writer, TValue value, JsonSe /// There is no compatible /// for or its serializable members. /// - public static void Serialize(Utf8JsonWriter writer, object? value, Type inputType, JsonSerializerOptions? options = null) + public static void Serialize( + Utf8JsonWriter writer, + object? value, + [DynamicallyAccessedMembers(MembersAccessedOnWrite)] Type inputType, + JsonSerializerOptions? options = null) { if (inputType == null) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs index fa9e10bfd7a65b..55e59178270755 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonStringEnumConverter.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text.Json.Serialization.Converters; @@ -54,9 +53,6 @@ public override bool CanConvert(Type typeToConvert) } /// - [DynamicDependency( - "#ctor(System.Text.Json.Serialization.Converters.EnumConverterOptions,System.Text.Json.JsonNamingPolicy,System.Text.Json.JsonSerializerOptions)", - typeof(EnumConverter<>))] public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) { JsonConverter converter = (JsonConverter)Activator.CreateInstance( diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConvertersTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConvertersTest.cs new file mode 100644 index 00000000000000..26dc654ba9a0f8 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConvertersTest.cs @@ -0,0 +1,157 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections; +using System.Collections.ObjectModel; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SerializerTrimmingTest +{ + /// + /// Tests the serializer (de)serializes collections appropriately, + /// and that the collection converter factory is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(int[])); // ArrayConverter + if (!AssertCollectionAndSerialize(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(ConcurrentQueue)); // ConcurrentQueueOfTConverter + if (!AssertCollectionAndSerialize>(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(ConcurrentStack)); // ConcurrentStackOfTConverter + if (!AssertCollectionAndSerialize>(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(LinkedList)); // ICollectionOfTConverter + if (!AssertCollectionAndSerialize>(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(IEnumerable)); // IEnumerableConverter + if (!AssertCollectionAndSerialize(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(IEnumerable)); // IEnumerableOfTConverter + if (!AssertCollectionAndSerialize>(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(Queue)); // IEnumerableWithAddMethodConverter + if (!AssertCollectionAndSerialize(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(ArrayList)); // IListConverter + if (!AssertCollectionAndSerialize(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(Collection)); // IListOfTConverter + if (!AssertCollectionAndSerialize>(obj, json)) + { + return -1; + } + + // TODO: instantiate this with the serializer - https://github.com/dotnet/runtime/issues/38593. + obj = ImmutableList.CreateRange(new[] { 1 }); + if (!(AssertCollectionAndSerialize>(obj, json))) // ImmutableEnumerableOfTConverter + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(HashSet)); // ISetOfTConverter + if (!AssertCollectionAndSerialize>(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(List)); // ListOfTConverter + if (!AssertCollectionAndSerialize>(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(Queue)); // QueueOfTConverter + if (!AssertCollectionAndSerialize>(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(Stack)); // StackOfTConverter + if (!AssertCollectionAndSerialize>(obj, json)) + { + return -1; + } + + json = @"{""Key"":1}"; + obj = JsonSerializer.Deserialize(json, typeof(Dictionary)); // DictionaryOfTKeyTValueConverter + if (!AssertCollectionAndSerialize>(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(Hashtable)); // IDictionaryConverter + if (!AssertCollectionAndSerialize(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(ConcurrentDictionary)); // IDictionaryOfTKeyTValueConverter + if (!AssertCollectionAndSerialize>(obj, json)) + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(IDictionary)); // IDictionaryOfTKeyTValueConverter + if (!AssertCollectionAndSerialize>(obj, json)) + { + return -1; + } + + // TODO: instantiate this with the serializer - https://github.com/dotnet/runtime/issues/38593. + obj = ImmutableDictionary.CreateRange(new Dictionary { ["Key"] = 1 }); + if (!(AssertCollectionAndSerialize>(obj, json))) // ImmutableDictionaryTKeyTValueOfTConverter + { + return -1; + } + + obj = JsonSerializer.Deserialize(json, typeof(IReadOnlyDictionary)); // IReadOnlyDictionaryOfTKeyTValueConverter + if (!AssertCollectionAndSerialize>(obj, json)) + { + return -1; + } + + return 100; + } + + private static bool AssertCollectionAndSerialize(object obj, string json) + { + return obj is T && JsonSerializer.Serialize(obj) == json; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/EnumConverterTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/EnumConverterTest.cs new file mode 100644 index 00000000000000..36f8e95906e3f3 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/EnumConverterTest.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SerializerTrimmingTest +{ + /// + /// Tests the serializer (de)serializes enums appropriately, + /// and that the enum converter factory is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = JsonSerializer.Serialize(new ClassWithDay()); + return json == @"{""Day"":5}" ? 100 : -1; + } + } + + internal class ClassWithDay + { + public DayOfWeek Day { get; set; } = DayOfWeek.Friday; + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs new file mode 100644 index 00000000000000..7c8304b12f7ba1 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs @@ -0,0 +1,121 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SerializerTrimmingTest +{ + internal static class TestHelper + { + // Used when comparing JSON payloads with more than two properties. + // We cannot check for string equality since property ordering depends + // on reflection ordering which is not guaranteed. + public static bool JsonEqual(string expected, string actual) + { + using JsonDocument expectedDom = JsonDocument.Parse(expected); + using JsonDocument actualDom = JsonDocument.Parse(actual); + return JsonEqual(expectedDom.RootElement, actualDom.RootElement); + } + + private static bool JsonEqual(JsonElement expected, JsonElement actual) + { + JsonValueKind valueKind = expected.ValueKind; + if (valueKind != actual.ValueKind) + { + return false; + } + + switch (valueKind) + { + case JsonValueKind.Object: + var propertyNames = new HashSet(); + + foreach (JsonProperty property in expected.EnumerateObject()) + { + propertyNames.Add(property.Name); + } + + foreach (JsonProperty property in actual.EnumerateObject()) + { + propertyNames.Add(property.Name); + } + + foreach (string name in propertyNames) + { + if (!JsonEqual(expected.GetProperty(name), actual.GetProperty(name))) + { + return false; + } + } + + return true; + case JsonValueKind.Array: + JsonElement.ArrayEnumerator expectedEnumerator = actual.EnumerateArray(); + JsonElement.ArrayEnumerator actualEnumerator = expected.EnumerateArray(); + + while (expectedEnumerator.MoveNext()) + { + if (!actualEnumerator.MoveNext()) + { + return false; + } + + if (!JsonEqual(expectedEnumerator.Current, actualEnumerator.Current)) + { + return false; + } + } + + return !actualEnumerator.MoveNext(); + case JsonValueKind.String: + return expected.GetString() == actual.GetString(); + case JsonValueKind.Number: + case JsonValueKind.True: + case JsonValueKind.False: + case JsonValueKind.Null: + return expected.GetRawText() == actual.GetRawText(); + default: + throw new NotSupportedException($"Unexpected JsonValueKind: JsonValueKind.{valueKind}."); + } + } + } + + internal class MyClass + { + public int X { get; set; } + public int Y { get; set; } + } + + internal struct MyStruct + { + public int X { get; } + public int Y { get; } + + [JsonConstructor] + public MyStruct(int x, int y) => (X, Y) = (x, y); + } + + internal class MyBigClass + { + public string A { get; } + public string B { get; } + public string C { get; } + public int One { get; } + public int Two { get; } + public int Three { get; } + + public MyBigClass(string a, string b, string c, int one, int two, int three) + { + A = a; + B = b; + C = c; + One = one; + Two = two; + Three = three; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/JsonConstructorAttributeTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/JsonConstructorAttributeTest.cs new file mode 100644 index 00000000000000..6bf51a23557f27 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/JsonConstructorAttributeTest.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the public parameterless ctor of the ConverterType property on + /// JsonConstructorAttribute is preserved when needed in a trimmed application. + /// + internal class Program + { + static int Main(string[] args) + { + string json = JsonSerializer.Serialize(new ClassWithDay()); + return json == @"{""Day"":""Friday""}" ? 100 : -1; + } + } + + internal class ClassWithDay + { + [JsonConverterAttribute(typeof(JsonStringEnumConverter))] + public DayOfWeek Day { get; set; } = DayOfWeek.Friday; + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/ObjectConvertersTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/ObjectConvertersTest.cs new file mode 100644 index 00000000000000..b4333e92717b13 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/ObjectConvertersTest.cs @@ -0,0 +1,62 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections; +using System.Collections.ObjectModel; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace SerializerTrimmingTest +{ + /// + /// Tests the serializer (de)serializes objects appropriately, + /// and that the object converter factory is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = @"{""X"":1,""Y"":2}"; + + MyClass @class = JsonSerializer.Deserialize(json); // ObjectDefaultConverter + if (@class.X != 1 || @class.Y != 2 || !TestHelper.JsonEqual(json, JsonSerializer.Serialize(@class))) + { + return -1; + } + + MyStruct @struct = JsonSerializer.Deserialize(json); // SmallObjectWithParameterizedConstructorConverter + if (@struct.X != 1 || @struct.Y != 2 || !TestHelper.JsonEqual(json, JsonSerializer.Serialize(@struct))) + { + return -1; + } + + json = @"{""A"":""A"",""B"":""B"",""C"":""C"",""One"":1,""Two"":2,""Three"":3}"; + MyBigClass bigClass = JsonSerializer.Deserialize(json); // LargeObjectWithParameterizedConstructorConverter + if (bigClass.A != "A" || + bigClass.B != "B" || + bigClass.C != "C" || + bigClass.One != 1 || + bigClass.Two != 2 || + bigClass.Three != 3 || + !TestHelper.JsonEqual(json, JsonSerializer.Serialize(bigClass))) + { + return -1; + } + + json = @"{""Key"":1,""Value"":2}"; + KeyValuePair kvp = JsonSerializer.Deserialize>(json); // KeyValuePairConverter + if (kvp.Key != 1 || kvp.Value != 2 || !TestHelper.JsonEqual(json, JsonSerializer.Serialize(kvp))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs new file mode 100644 index 00000000000000..b61e429ac35022 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.Deserialize(ref Utf8JsonReader reader, Type returnType, JsonSerializerOptions options) + /// overload has the appropriate linker annotations. + /// A collection and a POCO are used. Public constructors and public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + Utf8JsonReader reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); + int[] arr = (int[])JsonSerializer.Deserialize(ref reader, typeof(int[])); + if (arr[0] != 1) + { + return -1; + } + + json = @"{""X"":1,""Y"":2}"; + reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); + MyStruct obj = (MyStruct)JsonSerializer.Deserialize(json, typeof(MyStruct)); + if (obj.X != 1 || obj.Y != 2) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs new file mode 100644 index 00000000000000..7b878924b84b8e --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs @@ -0,0 +1,39 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.Deserialize(ref Utf8JsonReader reader, JsonSerializerOptions options) + /// overload has the appropriate linker annotations. + /// A collection and a POCO are used. Public constructors and public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + Utf8JsonReader reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); + int[] arr = JsonSerializer.Deserialize(ref reader); + if (arr[0] != 1) + { + return -1; + } + + json = @"{""X"":1,""Y"":2}"; + reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); + MyStruct obj = JsonSerializer.Deserialize(ref reader); + if (obj.X != 1 || obj.Y != 2) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs new file mode 100644 index 00000000000000..83d7aac5e07bd7 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.Deserialize(ReadOnlySpan utf8Json, Type returnType, JsonSerializerOptions options) + /// overload has the appropriate linker annotations. + /// A collection and a POCO are used. Public constructors and public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + int[] arr = (int[])JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json), typeof(int[])); + if (arr[0] != 1) + { + return -1; + } + + json = @"{""X"":1,""Y"":2}"; + MyStruct obj = (MyStruct)JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json), typeof(MyStruct)); + if (obj.X != 1 || obj.Y != 2) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs new file mode 100644 index 00000000000000..1bf9db2cfc7aa2 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.Deserialize(ReadOnlySpan utf8Json, JsonSerializerOptions options) + /// overload has the appropriate linker annotations. + /// A collection and a POCO are used. Public constructors and public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + int[] arr = JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json)); + if (arr[0] != 1) + { + return -1; + } + + json = @"{""X"":1,""Y"":2}"; + MyStruct obj = JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json)); + if (obj.X != 1 || obj.Y != 2) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs new file mode 100644 index 00000000000000..501243f55416da --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.Deserialize(string json, Type returnType, JsonSerializerOptions options) + /// overload has the appropriate linker annotations. + /// A collection and a POCO are used. Public constructors and public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + int[] arr = (int[])JsonSerializer.Deserialize(json, typeof(int[])); + if (arr[0] != 1) + { + return -1; + } + + json = @"{""X"":1,""Y"":2}"; + MyStruct obj = (MyStruct)JsonSerializer.Deserialize(json, typeof(MyStruct)); + if (obj.X != 1 || obj.Y != 2) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs new file mode 100644 index 00000000000000..7ec02c2b7f051f --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.Deserialize(string json, JsonSerializerOptions options) + /// overload has the appropriate linker annotations. + /// A collection and a POCO are used. Public constructors and public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + int[] arr = JsonSerializer.Deserialize(json); + if (arr[0] != 1) + { + return -1; + } + + json = @"{""X"":1,""Y"":2}"; + MyStruct obj = JsonSerializer.Deserialize(json); + if (obj.X != 1 || obj.Y != 2) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs new file mode 100644 index 00000000000000..2459587725db19 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.DeserializeAsync(Stream utf8Json, Type returnType, JsonSerializerOptions options, CancellationToken cancellationToken) + /// overload has the appropriate linker annotations. + /// A collection and a POCO are used. Public constructors properties and public are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + + int[] arr = (int[])Task.Run(async () => + { + using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + { + return await JsonSerializer.DeserializeAsync(stream, typeof(int[])); + } + }).GetAwaiter().GetResult(); + + if (arr[0] != 1) + { + return -1; + } + + json = @"{""X"":1,""Y"":2}"; + MyStruct obj = (MyStruct)Task.Run(async () => + { + using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + { + return await JsonSerializer.DeserializeAsync(stream, typeof(MyStruct)); + } + }).GetAwaiter().GetResult(); + + if (obj.X != 1 || obj.Y != 2) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs new file mode 100644 index 00000000000000..fd367099347fd9 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.DeserializeAsync(Stream utf8Json, JsonSerializerOptions options, CancellationToken cancellationToken) + /// overload has the appropriate linker annotations. + /// A collection and a POCO are used. Public constructors and public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + + int[] arr = (int[])Task.Run(async () => + { + using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + { + return await JsonSerializer.DeserializeAsync(stream); + } + }).GetAwaiter().GetResult(); + + if (arr[0] != 1) + { + return -1; + } + + json = @"{""X"":1,""Y"":2}"; + MyStruct obj = (MyStruct)Task.Run(async () => + { + using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + { + return await JsonSerializer.DeserializeAsync(stream); + } + }).GetAwaiter().GetResult(); + + if (obj.X != 1 || obj.Y != 2) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.BoxedObject.cs new file mode 100644 index 00000000000000..344f887607b79b --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.BoxedObject.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.SerializeToUtf8Bytes(object value, Type inputType, JsonSerializerOptions options) + /// overload has the appropriate linker annotations. A collection and a POCO are used. Public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + int[] arr = new [] { 1 }; + string expected = "[1]"; + string actual = Encoding.UTF8.GetString(JsonSerializer.SerializeToUtf8Bytes(arr, typeof(int[]))); + if (actual != expected) + { + return -1; + } + + MyStruct obj = new MyStruct(1, 2); + expected = @"{""X"":1,""Y"":2}"; + actual = Encoding.UTF8.GetString(JsonSerializer.SerializeToUtf8Bytes(obj, typeof(MyStruct))); + if (!TestHelper.JsonEqual(expected, actual)) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.TypedObject.cs new file mode 100644 index 00000000000000..0e45662a188051 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.TypedObject.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.SerializeToUtf8Bytes(T value, JsonSerializerOptions options) + /// overload has the appropriate linker annotations. A collection and a POCO are used. Public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + int[] arr = new [] { 1 }; + string expected = "[1]"; + string actual = Encoding.UTF8.GetString(JsonSerializer.SerializeToUtf8Bytes(arr)); + if (actual != expected) + { + return -1; + } + + MyStruct obj = new MyStruct(1, 2); + expected = @"{""X"":1,""Y"":2}"; + actual = Encoding.UTF8.GetString(JsonSerializer.SerializeToUtf8Bytes(obj)); + if (!TestHelper.JsonEqual(expected, actual)) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.WithWriter.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.WithWriter.cs new file mode 100644 index 00000000000000..3fbfad2da660bc --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.WithWriter.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using System.Text; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.Serialize(Utf8JsonWriter writer, object value, Type inputType, JsonSerializerOptions options) + /// overload has the appropriate linker annotations. A collection and a POCO are used. Public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + { + int[] arr = new [] { 1 }; + using var stream = new MemoryStream(); + using var writer = new Utf8JsonWriter(stream); + JsonSerializer.Serialize(writer, arr, typeof(int[])); + string actual = Encoding.UTF8.GetString(stream.ToArray()); + if (actual != "[1]") + { + return -1; + } + } + + { + MyStruct obj = new MyStruct(1, 2); + using var stream = new MemoryStream(); + using var writer = new Utf8JsonWriter(stream); + JsonSerializer.Serialize(writer, obj, typeof(MyStruct)); + string actual = Encoding.UTF8.GetString(stream.ToArray()); + if (!TestHelper.JsonEqual(@"{""X"":1,""Y"":2}", actual)) + { + return -1; + } + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.cs new file mode 100644 index 00000000000000..fcfbf2539d108a --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests the serializer's JsonSerializer.Serialize(object value, Type inputType, JsonSerializerOptions options) + /// overload has the appropriate linker annotations. A collection and a POCO are used. Public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + int[] arr = new [] { 1 }; + if (JsonSerializer.Serialize(arr, typeof(int[])) != "[1]") + { + return -1; + } + + MyStruct obj = new MyStruct(1, 2); + if (!TestHelper.JsonEqual(@"{""X"":1,""Y"":2}", JsonSerializer.Serialize(obj, typeof(MyStruct)))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.WithWriter.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.WithWriter.cs new file mode 100644 index 00000000000000..a959e9406dd31f --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.WithWriter.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using System.Text; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.Serialize(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + /// overload has the appropriate linker annotations. A collection and a POCO are used. Public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + { + int[] arr = new [] { 1 }; + using var stream = new MemoryStream(); + using var writer = new Utf8JsonWriter(stream); + JsonSerializer.Serialize(writer, arr); + string actual = Encoding.UTF8.GetString(stream.ToArray()); + if (actual != "[1]") + { + return -1; + } + } + + { + MyStruct obj = new MyStruct(1, 2); + using var stream = new MemoryStream(); + using var writer = new Utf8JsonWriter(stream); + JsonSerializer.Serialize(writer, obj); + string actual = Encoding.UTF8.GetString(stream.ToArray()); + if (!TestHelper.JsonEqual(@"{""X"":1,""Y"":2}", actual)) + { + return -1; + } + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.cs new file mode 100644 index 00000000000000..ca33ff4c00b7d3 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Text; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.Deserialize(ref Utf8JsonReader reader, JsonSerializerOptions options) + /// overload has the appropriate linker annotations. A collection and a POCO are used. Public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + int[] arr = new [] { 1 }; + if (JsonSerializer.Serialize(arr) != "[1]") + { + return -1; + } + + MyStruct obj = new MyStruct(1, 2); + if (!TestHelper.JsonEqual(@"{""X"":1,""Y"":2}", JsonSerializer.Serialize(obj))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.BoxedObject.cs new file mode 100644 index 00000000000000..cfaaa1dbcc7fe4 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.BoxedObject.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.SerializeAsync(Stream utf8Json, object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken) + /// overload has the appropriate linker annotations. A collection and a POCO are used. Public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + { + int[] arr = new [] { 1 }; + + string actual = Task.Run(async () => + { + using var stream = new MemoryStream(); + await JsonSerializer.SerializeAsync(stream, arr, typeof(int[])); + return Encoding.UTF8.GetString(stream.ToArray()); + }).GetAwaiter().GetResult(); + + if ("[1]" != actual) + { + return -1; + } + } + + { + MyStruct obj = new MyStruct(1, 2); + + string actual = Task.Run(async () => + { + using var stream = new MemoryStream(); + await JsonSerializer.SerializeAsync(stream, obj, typeof(MyStruct)); + return Encoding.UTF8.GetString(stream.ToArray()); + }).GetAwaiter().GetResult(); + + if (!TestHelper.JsonEqual(@"{""X"":1,""Y"":2}", actual)) + { + return -1; + } + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.TypedObject.cs new file mode 100644 index 00000000000000..00385006837e17 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.TypedObject.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.IO; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's JsonSerializer.SerializeAsync(Stream utf8Json, T value, JsonSerializerOptions options, CancellationToken cancellationToken) + /// overload has the appropriate linker annotations. A collection and a POCO are used. Public properties are expected to be preserved. + /// + internal class Program + { + static int Main(string[] args) + { + { + int[] arr = new [] { 1 }; + + string actual = Task.Run(async () => + { + using var stream = new MemoryStream(); + await JsonSerializer.SerializeAsync(stream, arr); + return Encoding.UTF8.GetString(stream.ToArray()); + }).GetAwaiter().GetResult(); + + if (actual != "[1]") + { + return -1; + } + } + + { + MyStruct obj = new MyStruct(1, 2); + + string actual = Task.Run(async () => + { + using var stream = new MemoryStream(); + await JsonSerializer.SerializeAsync(stream, obj); + return Encoding.UTF8.GetString(stream.ToArray()); + }).GetAwaiter().GetResult(); + + if (!TestHelper.JsonEqual(@"{""X"":1,""Y"":2}", actual)) + { + return -1; + } + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/StackOrQueueNotRootedTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/StackOrQueueNotRootedTest.cs index e94dd33583e6c7..262330a4bfe91d 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/StackOrQueueNotRootedTest.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/StackOrQueueNotRootedTest.cs @@ -40,4 +40,3 @@ static int Main(string[] args) private static Type GetTypeIfExists(string name) => Type.GetType(name, false); } - diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj b/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj index da4a46f2ae141a..aec8fa069b15cf 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj @@ -1,5 +1,64 @@ + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + + + Helper.cs + + + From b550bf6cb9154a3b7a64ea7f79d4ea95bbde74c4 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Tue, 30 Jun 2020 08:57:01 -0700 Subject: [PATCH 02/10] Review feedback - don't use property accessors in tests and use normal await pattern --- .../TrimmingTests/CollectionConvertersTest.cs | 3 +- .../tests/TrimmingTests/EnumConverterTest.cs | 7 ++--- .../tests/TrimmingTests/Helper.cs | 18 ++++++++++-- .../JsonConstructorAttributeTest.cs | 4 +-- .../TrimmingTests/ObjectConvertersTest.cs | 17 ++++------- .../Deserialize.FromReader.BoxedObject.cs | 4 +-- .../Deserialize.FromReader.TypedObject.cs | 4 +-- .../Deserialize.FromSpan.BoxedObject.cs | 4 +-- .../Deserialize.FromSpan.TypedObject.cs | 4 +-- .../Deserialize.FromString.BoxedObject.cs | 4 +-- .../Deserialize.FromString.TypedObject.cs | 4 +-- ...DeserializeAsync.FromStream.BoxedObject.cs | 27 +++++++----------- ...DeserializeAsync.FromStream.TypedObject.cs | 27 ++++++------------ .../Serialize.ToByteArray.BoxedObject.cs | 4 +-- .../Serialize.ToByteArray.TypedObject.cs | 4 +-- ...rialize.ToString.BoxedObject.WithWriter.cs | 4 +-- .../Serialize.ToString.BoxedObject.cs | 4 +-- ...rialize.ToString.TypedObject.WithWriter.cs | 4 +-- .../Serialize.ToString.TypedObject.cs | 4 +-- .../SerializeAsync.ToStream.BoxedObject.cs | 28 ++++++------------- .../SerializeAsync.ToStream.TypedObject.cs | 28 ++++++------------- .../System.Text.Json.TrimmingTests.proj | 1 + 22 files changed, 88 insertions(+), 120 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConvertersTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConvertersTest.cs index 26dc654ba9a0f8..787bfb97cfb0e5 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConvertersTest.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConvertersTest.cs @@ -15,8 +15,7 @@ namespace SerializerTrimmingTest { /// - /// Tests the serializer (de)serializes collections appropriately, - /// and that the collection converter factory is linker-safe. + /// Tests that the collection converter factory is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/EnumConverterTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/EnumConverterTest.cs index 36f8e95906e3f3..66f962f981752c 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/EnumConverterTest.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/EnumConverterTest.cs @@ -9,20 +9,19 @@ namespace SerializerTrimmingTest { /// - /// Tests the serializer (de)serializes enums appropriately, - /// and that the enum converter factory is linker-safe. + /// Tests that the enum converter factory is linker-safe. /// internal class Program { static int Main(string[] args) { string json = JsonSerializer.Serialize(new ClassWithDay()); - return json == @"{""Day"":5}" ? 100 : -1; + return json == @"{""Day"":0}" ? 100 : -1; } } internal class ClassWithDay { - public DayOfWeek Day { get; set; } = DayOfWeek.Friday; + public DayOfWeek Day { get; set; } } } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs index 7c8304b12f7ba1..f630ff96ed9d68 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs @@ -11,9 +11,11 @@ namespace SerializerTrimmingTest { internal static class TestHelper { - // Used when comparing JSON payloads with more than two properties. - // We cannot check for string equality since property ordering depends - // on reflection ordering which is not guaranteed. + /// + /// Used when comparing JSON payloads with more than two properties. + /// We cannot check for string equality since property ordering depends + /// on reflection ordering which is not guaranteed. + /// public static bool JsonEqual(string expected, string actual) { using JsonDocument expectedDom = JsonDocument.Parse(expected); @@ -82,6 +84,16 @@ private static bool JsonEqual(JsonElement expected, JsonElement actual) throw new NotSupportedException($"Unexpected JsonValueKind: JsonValueKind.{valueKind}."); } } + + /// + /// Verifies the result of deserialization by serializing and comparing the output + /// with the expected payload. With this call pattern, the serialize should preserve + /// properties on typeof(object), but that would not be helpful to the calling test. + /// + public static bool VerifyWithSerialize(object obj, string expected) + { + return JsonEqual(expected, JsonSerializer.Serialize(obj)); + } } internal class MyClass diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/JsonConstructorAttributeTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/JsonConstructorAttributeTest.cs index 6bf51a23557f27..50ee0948be7738 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/JsonConstructorAttributeTest.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/JsonConstructorAttributeTest.cs @@ -17,13 +17,13 @@ internal class Program static int Main(string[] args) { string json = JsonSerializer.Serialize(new ClassWithDay()); - return json == @"{""Day"":""Friday""}" ? 100 : -1; + return json == @"{""Day"":""Sunday""}" ? 100 : -1; } } internal class ClassWithDay { [JsonConverterAttribute(typeof(JsonStringEnumConverter))] - public DayOfWeek Day { get; set; } = DayOfWeek.Friday; + public DayOfWeek Day { get; set; } } } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/ObjectConvertersTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/ObjectConvertersTest.cs index b4333e92717b13..4a57a6f57f304c 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/ObjectConvertersTest.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/ObjectConvertersTest.cs @@ -15,8 +15,7 @@ namespace SerializerTrimmingTest { /// - /// Tests the serializer (de)serializes objects appropriately, - /// and that the object converter factory is linker-safe. + /// Tests that the object converter factory is linker-safe. /// internal class Program { @@ -25,33 +24,27 @@ static int Main(string[] args) string json = @"{""X"":1,""Y"":2}"; MyClass @class = JsonSerializer.Deserialize(json); // ObjectDefaultConverter - if (@class.X != 1 || @class.Y != 2 || !TestHelper.JsonEqual(json, JsonSerializer.Serialize(@class))) + if (!TestHelper.JsonEqual(json, JsonSerializer.Serialize(@class))) { return -1; } MyStruct @struct = JsonSerializer.Deserialize(json); // SmallObjectWithParameterizedConstructorConverter - if (@struct.X != 1 || @struct.Y != 2 || !TestHelper.JsonEqual(json, JsonSerializer.Serialize(@struct))) + if (!TestHelper.JsonEqual(json, JsonSerializer.Serialize(@struct))) { return -1; } json = @"{""A"":""A"",""B"":""B"",""C"":""C"",""One"":1,""Two"":2,""Three"":3}"; MyBigClass bigClass = JsonSerializer.Deserialize(json); // LargeObjectWithParameterizedConstructorConverter - if (bigClass.A != "A" || - bigClass.B != "B" || - bigClass.C != "C" || - bigClass.One != 1 || - bigClass.Two != 2 || - bigClass.Three != 3 || - !TestHelper.JsonEqual(json, JsonSerializer.Serialize(bigClass))) + if (!TestHelper.JsonEqual(json, JsonSerializer.Serialize(bigClass))) { return -1; } json = @"{""Key"":1,""Value"":2}"; KeyValuePair kvp = JsonSerializer.Deserialize>(json); // KeyValuePairConverter - if (kvp.Key != 1 || kvp.Value != 2 || !TestHelper.JsonEqual(json, JsonSerializer.Serialize(kvp))) + if (!TestHelper.JsonEqual(json, JsonSerializer.Serialize(kvp))) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs index b61e429ac35022..b8c806ec166336 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs @@ -20,7 +20,7 @@ static int Main(string[] args) string json = "[1]"; Utf8JsonReader reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); int[] arr = (int[])JsonSerializer.Deserialize(ref reader, typeof(int[])); - if (arr[0] != 1) + if (!TestHelper.VerifyWithSerialize(arr, json)) { return -1; } @@ -28,7 +28,7 @@ static int Main(string[] args) json = @"{""X"":1,""Y"":2}"; reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); MyStruct obj = (MyStruct)JsonSerializer.Deserialize(json, typeof(MyStruct)); - if (obj.X != 1 || obj.Y != 2) + if (!TestHelper.VerifyWithSerialize(obj, json)) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs index 7b878924b84b8e..61a97d167b249b 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs @@ -20,7 +20,7 @@ static int Main(string[] args) string json = "[1]"; Utf8JsonReader reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); int[] arr = JsonSerializer.Deserialize(ref reader); - if (arr[0] != 1) + if (!TestHelper.VerifyWithSerialize(arr, json)) { return -1; } @@ -28,7 +28,7 @@ static int Main(string[] args) json = @"{""X"":1,""Y"":2}"; reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); MyStruct obj = JsonSerializer.Deserialize(ref reader); - if (obj.X != 1 || obj.Y != 2) + if (!TestHelper.VerifyWithSerialize(obj, json)) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs index 83d7aac5e07bd7..c375857ec684b9 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs @@ -19,14 +19,14 @@ static int Main(string[] args) { string json = "[1]"; int[] arr = (int[])JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json), typeof(int[])); - if (arr[0] != 1) + if (!TestHelper.VerifyWithSerialize(arr, json)) { return -1; } json = @"{""X"":1,""Y"":2}"; MyStruct obj = (MyStruct)JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json), typeof(MyStruct)); - if (obj.X != 1 || obj.Y != 2) + if (!TestHelper.VerifyWithSerialize(obj, json)) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs index 1bf9db2cfc7aa2..20482b3aa805e4 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs @@ -19,14 +19,14 @@ static int Main(string[] args) { string json = "[1]"; int[] arr = JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json)); - if (arr[0] != 1) + if (!TestHelper.VerifyWithSerialize(arr, json)) { return -1; } json = @"{""X"":1,""Y"":2}"; MyStruct obj = JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json)); - if (obj.X != 1 || obj.Y != 2) + if (!TestHelper.VerifyWithSerialize(obj, json)) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs index 501243f55416da..e901129830cd0a 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs @@ -18,14 +18,14 @@ static int Main(string[] args) { string json = "[1]"; int[] arr = (int[])JsonSerializer.Deserialize(json, typeof(int[])); - if (arr[0] != 1) + if (!TestHelper.VerifyWithSerialize(arr, json)) { return -1; } json = @"{""X"":1,""Y"":2}"; MyStruct obj = (MyStruct)JsonSerializer.Deserialize(json, typeof(MyStruct)); - if (obj.X != 1 || obj.Y != 2) + if (!TestHelper.VerifyWithSerialize(obj, json)) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs index 7ec02c2b7f051f..694ba93d655785 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs @@ -18,14 +18,14 @@ static int Main(string[] args) { string json = "[1]"; int[] arr = JsonSerializer.Deserialize(json); - if (arr[0] != 1) + if (!TestHelper.VerifyWithSerialize(arr, json)) { return -1; } json = @"{""X"":1,""Y"":2}"; MyStruct obj = JsonSerializer.Deserialize(json); - if (obj.X != 1 || obj.Y != 2) + if (!TestHelper.VerifyWithSerialize(obj, json)) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs index 2459587725db19..cc7c6e82c67698 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs @@ -17,35 +17,28 @@ namespace SerializerTrimmingTest /// internal class Program { - static int Main(string[] args) + static async Task Main(string[] args) { string json = "[1]"; - int[] arr = (int[])Task.Run(async () => + using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { - using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + int[] arr = (int[])(await JsonSerializer.DeserializeAsync(stream, typeof(int[]))); + if (!TestHelper.VerifyWithSerialize(arr, json)) { - return await JsonSerializer.DeserializeAsync(stream, typeof(int[])); + return -1; } - }).GetAwaiter().GetResult(); - - if (arr[0] != 1) - { - return -1; } json = @"{""X"":1,""Y"":2}"; - MyStruct obj = (MyStruct)Task.Run(async () => + + using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { - using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + MyStruct obj = (MyStruct)(await JsonSerializer.DeserializeAsync(stream, typeof(MyStruct))); + if (!TestHelper.VerifyWithSerialize(obj, json)) { - return await JsonSerializer.DeserializeAsync(stream, typeof(MyStruct)); + return -1; } - }).GetAwaiter().GetResult(); - - if (obj.X != 1 || obj.Y != 2) - { - return -1; } return 100; diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs index fd367099347fd9..93a224beafc3f4 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs @@ -17,35 +17,26 @@ namespace SerializerTrimmingTest /// internal class Program { - static int Main(string[] args) + static async Task Main(string[] args) { string json = "[1]"; - - int[] arr = (int[])Task.Run(async () => + using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { - using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + int[] arr = (int[])(await JsonSerializer.DeserializeAsync(stream)); + if (!TestHelper.VerifyWithSerialize(arr, json)) { - return await JsonSerializer.DeserializeAsync(stream); + return -1; } - }).GetAwaiter().GetResult(); - - if (arr[0] != 1) - { - return -1; } json = @"{""X"":1,""Y"":2}"; - MyStruct obj = (MyStruct)Task.Run(async () => + using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { - using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) + MyStruct obj = (MyStruct)(await JsonSerializer.DeserializeAsync(stream)); + if (!TestHelper.VerifyWithSerialize(obj, json)) { - return await JsonSerializer.DeserializeAsync(stream); + return -1; } - }).GetAwaiter().GetResult(); - - if (obj.X != 1 || obj.Y != 2) - { - return -1; } return 100; diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.BoxedObject.cs index 344f887607b79b..18de37d307f1b1 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.BoxedObject.cs @@ -24,8 +24,8 @@ static int Main(string[] args) return -1; } - MyStruct obj = new MyStruct(1, 2); - expected = @"{""X"":1,""Y"":2}"; + MyStruct obj = default; + expected = @"{""X"":0,""Y"":0}"; actual = Encoding.UTF8.GetString(JsonSerializer.SerializeToUtf8Bytes(obj, typeof(MyStruct))); if (!TestHelper.JsonEqual(expected, actual)) { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.TypedObject.cs index 0e45662a188051..8ccf6cde59ea98 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToByteArray.TypedObject.cs @@ -24,8 +24,8 @@ static int Main(string[] args) return -1; } - MyStruct obj = new MyStruct(1, 2); - expected = @"{""X"":1,""Y"":2}"; + MyStruct obj = default; + expected = @"{""X"":0,""Y"":0}"; actual = Encoding.UTF8.GetString(JsonSerializer.SerializeToUtf8Bytes(obj)); if (!TestHelper.JsonEqual(expected, actual)) { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.WithWriter.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.WithWriter.cs index 3fbfad2da660bc..70b9a360e74bd1 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.WithWriter.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.WithWriter.cs @@ -30,12 +30,12 @@ static int Main(string[] args) } { - MyStruct obj = new MyStruct(1, 2); + MyStruct obj = default; using var stream = new MemoryStream(); using var writer = new Utf8JsonWriter(stream); JsonSerializer.Serialize(writer, obj, typeof(MyStruct)); string actual = Encoding.UTF8.GetString(stream.ToArray()); - if (!TestHelper.JsonEqual(@"{""X"":1,""Y"":2}", actual)) + if (!TestHelper.JsonEqual(@"{""X"":0,""Y"":0}", actual)) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.cs index fcfbf2539d108a..242cc7c4aa7894 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.BoxedObject.cs @@ -22,8 +22,8 @@ static int Main(string[] args) return -1; } - MyStruct obj = new MyStruct(1, 2); - if (!TestHelper.JsonEqual(@"{""X"":1,""Y"":2}", JsonSerializer.Serialize(obj, typeof(MyStruct)))) + MyStruct obj = default; + if (!TestHelper.JsonEqual(@"{""X"":0,""Y"":0}", JsonSerializer.Serialize(obj, typeof(MyStruct)))) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.WithWriter.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.WithWriter.cs index a959e9406dd31f..b0e0bb75db47b7 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.WithWriter.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.WithWriter.cs @@ -30,12 +30,12 @@ static int Main(string[] args) } { - MyStruct obj = new MyStruct(1, 2); + MyStruct obj = default; using var stream = new MemoryStream(); using var writer = new Utf8JsonWriter(stream); JsonSerializer.Serialize(writer, obj); string actual = Encoding.UTF8.GetString(stream.ToArray()); - if (!TestHelper.JsonEqual(@"{""X"":1,""Y"":2}", actual)) + if (!TestHelper.JsonEqual(@"{""X"":0,""Y"":0}", actual)) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.cs index ca33ff4c00b7d3..5365c89818491d 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Serialize.ToString.TypedObject.cs @@ -22,8 +22,8 @@ static int Main(string[] args) return -1; } - MyStruct obj = new MyStruct(1, 2); - if (!TestHelper.JsonEqual(@"{""X"":1,""Y"":2}", JsonSerializer.Serialize(obj))) + MyStruct obj = default; + if (!TestHelper.JsonEqual(@"{""X"":0,""Y"":0}", JsonSerializer.Serialize(obj))) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.BoxedObject.cs index cfaaa1dbcc7fe4..e5069c29f52607 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.BoxedObject.cs @@ -16,35 +16,25 @@ namespace SerializerTrimmingTest /// internal class Program { - static int Main(string[] args) + static async Task Main(string[] args) { + using (var stream = new MemoryStream()) { int[] arr = new [] { 1 }; - - string actual = Task.Run(async () => - { - using var stream = new MemoryStream(); - await JsonSerializer.SerializeAsync(stream, arr, typeof(int[])); - return Encoding.UTF8.GetString(stream.ToArray()); - }).GetAwaiter().GetResult(); - + await JsonSerializer.SerializeAsync(stream, arr, typeof(int[])); + string actual = Encoding.UTF8.GetString(stream.ToArray()); if ("[1]" != actual) { return -1; } } + using (var stream = new MemoryStream()) { - MyStruct obj = new MyStruct(1, 2); - - string actual = Task.Run(async () => - { - using var stream = new MemoryStream(); - await JsonSerializer.SerializeAsync(stream, obj, typeof(MyStruct)); - return Encoding.UTF8.GetString(stream.ToArray()); - }).GetAwaiter().GetResult(); - - if (!TestHelper.JsonEqual(@"{""X"":1,""Y"":2}", actual)) + MyStruct obj = default; + await JsonSerializer.SerializeAsync(stream, obj, typeof(MyStruct)); + string actual = Encoding.UTF8.GetString(stream.ToArray()); + if (!TestHelper.JsonEqual(@"{""X"":0,""Y"":0}", actual)) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.TypedObject.cs index 00385006837e17..37e4b36f3fc258 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/SerializeAsync.ToStream.TypedObject.cs @@ -16,35 +16,25 @@ namespace SerializerTrimmingTest /// internal class Program { - static int Main(string[] args) + static async Task Main(string[] args) { + using (var stream = new MemoryStream()) { int[] arr = new [] { 1 }; - - string actual = Task.Run(async () => - { - using var stream = new MemoryStream(); - await JsonSerializer.SerializeAsync(stream, arr); - return Encoding.UTF8.GetString(stream.ToArray()); - }).GetAwaiter().GetResult(); - + await JsonSerializer.SerializeAsync(stream, arr); + string actual = Encoding.UTF8.GetString(stream.ToArray()); if (actual != "[1]") { return -1; } } + using (var stream = new MemoryStream()) { - MyStruct obj = new MyStruct(1, 2); - - string actual = Task.Run(async () => - { - using var stream = new MemoryStream(); - await JsonSerializer.SerializeAsync(stream, obj); - return Encoding.UTF8.GetString(stream.ToArray()); - }).GetAwaiter().GetResult(); - - if (!TestHelper.JsonEqual(@"{""X"":1,""Y"":2}", actual)) + MyStruct obj = default; + await JsonSerializer.SerializeAsync(stream, obj); + string actual = Encoding.UTF8.GetString(stream.ToArray()); + if (!TestHelper.JsonEqual(@"{""X"":0,""Y"":0}", actual)) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj b/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj index aec8fa069b15cf..277710d65f5921 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj @@ -58,6 +58,7 @@ Helper.cs + From 94ce9ec59c5e0e1af3a3bec65cf61a44eddbc95e Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Wed, 1 Jul 2020 11:44:46 -0700 Subject: [PATCH 03/10] Add annotations to ref & fix immutable collections --- .../DynamicallyAccessedMembersAttribute.cs | 7 +- .../System.Text.Json/ref/System.Text.Json.cs | 22 ----- .../ref/System.Text.Json.csproj | 6 ++ .../ref/System.Text.Json.netcoreapp.cs | 34 +++++++ .../ref/System.Text.Json.non-netcoreapp.cs | 32 +++++++ .../src/System.Text.Json.csproj | 1 + .../IEnumerableConverterFactoryHelpers.cs | 89 ++++++++++--------- ...tionConvertersTest.IImmutableDictionary.cs | 27 ++++++ ...CollectionConvertersTest.IImmutableList.cs | 27 ++++++ ...ollectionConvertersTest.IImmutableQueue.cs | 27 ++++++ .../CollectionConvertersTest.IImmutableSet.cs | 27 ++++++ ...ollectionConvertersTest.IImmutableStack.cs | 27 ++++++ ...CollectionConvertersTest.ImmutableArray.cs | 27 ++++++ ...ctionConvertersTest.ImmutableDictionary.cs | 27 ++++++ ...llectionConvertersTest.ImmutableHashSet.cs | 27 ++++++ .../CollectionConvertersTest.ImmutableList.cs | 27 ++++++ ...CollectionConvertersTest.ImmutableQueue.cs | 27 ++++++ ...onvertersTest.ImmutableSortedDictionary.cs | 27 ++++++ ...ectionConvertersTest.ImmutableSortedSet.cs | 27 ++++++ ...CollectionConvertersTest.ImmutableStack.cs | 27 ++++++ .../CollectionConvertersTest.cs | 58 ++++-------- .../tests/TrimmingTests/EnumConverterTest.cs | 1 - .../tests/TrimmingTests/Helper.cs | 5 ++ ...eTest.cs => JsonConverterAttributeTest.cs} | 0 .../TrimmingTests/ObjectConvertersTest.cs | 7 -- .../System.Text.Json.TrimmingTests.proj | 47 +++++++++- 26 files changed, 543 insertions(+), 117 deletions(-) create mode 100644 src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs create mode 100644 src/libraries/System.Text.Json/ref/System.Text.Json.non-netcoreapp.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableDictionary.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableList.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableQueue.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableSet.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableStack.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableArray.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableDictionary.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableHashSet.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableList.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableQueue.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedDictionary.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedSet.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableStack.cs rename src/libraries/System.Text.Json/tests/TrimmingTests/{ => CollectionConverters}/CollectionConvertersTest.cs (61%) rename src/libraries/System.Text.Json/tests/TrimmingTests/{JsonConstructorAttributeTest.cs => JsonConverterAttributeTest.cs} (100%) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMembersAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMembersAttribute.cs index 988bd0147bd0b6..ea261dfd45892e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMembersAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMembersAttribute.cs @@ -26,7 +26,12 @@ namespace System.Diagnostics.CodeAnalysis AttributeTargets.Field | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.Method, Inherited = false)] - public sealed class DynamicallyAccessedMembersAttribute : Attribute +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class DynamicallyAccessedMembersAttribute : Attribute { /// /// Initializes a new instance of the class 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 bcc2ffec78ceed..fb421d68df6924 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -183,28 +183,6 @@ public partial struct JsonReaderState public JsonReaderState(System.Text.Json.JsonReaderOptions options = default(System.Text.Json.JsonReaderOptions)) { throw null; } public System.Text.Json.JsonReaderOptions Options { get { throw null; } } } - public static partial class JsonSerializer - { - public static object? Deserialize(System.ReadOnlySpan utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static object? Deserialize(string json, 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.JsonSerializerOptions? options = null) { throw null; } - public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, 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.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNull] - public static TValue Deserialize(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNull] - public static TValue Deserialize(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNull] - public static TValue Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static string Serialize(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { } - public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, 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, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static byte[] SerializeToUtf8Bytes(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static byte[] SerializeToUtf8Bytes(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static void Serialize(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.JsonSerializerOptions? options = null) { } - public static string Serialize(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - } public sealed partial class JsonSerializerOptions { public JsonSerializerOptions() { } 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 b06efdcf9ac2ed..500313fbf95b53 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj @@ -17,6 +17,12 @@ + + + + + + diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs new file mode 100644 index 00000000000000..c02d880afdd872 --- /dev/null +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// ------------------------------------------------------------------------------ +// Changes to this file must follow the https://aka.ms/api-review process. +// ------------------------------------------------------------------------------ + +namespace System.Text.Json +{ + public static partial class JsonSerializer + { + private const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MembersAccessedOnRead = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties; + private const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MembersAccessedOnWrite = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties; + public static object? Deserialize(System.ReadOnlySpan utf8Json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static object? Deserialize(string json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] 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.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] + public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] + public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] + public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static string Serialize(object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { } + public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] 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.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] 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 byte[] SerializeToUtf8Bytes(object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static byte[] SerializeToUtf8Bytes<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] TValue>(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static void Serialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] TValue>(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.JsonSerializerOptions? options = null) { } + public static string Serialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] TValue>(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + } +} diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.non-netcoreapp.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.non-netcoreapp.cs new file mode 100644 index 00000000000000..d3f88b2e86b559 --- /dev/null +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.non-netcoreapp.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// ------------------------------------------------------------------------------ +// Changes to this file must follow the https://aka.ms/api-review process. +// ------------------------------------------------------------------------------ + +namespace System.Text.Json +{ + public static partial class JsonSerializer + { + public static object? Deserialize(System.ReadOnlySpan utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static object? Deserialize(string json, 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.JsonSerializerOptions? options = null) { throw null; } + public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, 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.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] + public static TValue Deserialize(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] + public static TValue Deserialize(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] + public static TValue Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static string Serialize(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { } + public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, 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, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static byte[] SerializeToUtf8Bytes(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static byte[] SerializeToUtf8Bytes(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static void Serialize(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.JsonSerializerOptions? options = null) { } + public static string Serialize(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + } +} 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 f09a442249bba7..69a019a4f407c4 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -238,6 +238,7 @@ + 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 2e10216d103e87..63af7761171c9e 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 @@ -3,40 +3,37 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace System.Text.Json.Serialization { internal static class IEnumerableConverterFactoryHelpers { - private const string ImmutableArrayTypeName = "System.Collections.Immutable.ImmutableArray"; + // Immutable collection types. private const string ImmutableArrayGenericTypeName = "System.Collections.Immutable.ImmutableArray`1"; - - private const string ImmutableListTypeName = "System.Collections.Immutable.ImmutableList"; private const string ImmutableListGenericTypeName = "System.Collections.Immutable.ImmutableList`1"; private const string ImmutableListGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableList`1"; - - private const string ImmutableStackTypeName = "System.Collections.Immutable.ImmutableStack"; private const string ImmutableStackGenericTypeName = "System.Collections.Immutable.ImmutableStack`1"; private const string ImmutableStackGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableStack`1"; - - private const string ImmutableQueueTypeName = "System.Collections.Immutable.ImmutableQueue"; private const string ImmutableQueueGenericTypeName = "System.Collections.Immutable.ImmutableQueue`1"; private const string ImmutableQueueGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableQueue`1"; - - private const string ImmutableSortedSetTypeName = "System.Collections.Immutable.ImmutableSortedSet"; private const string ImmutableSortedSetGenericTypeName = "System.Collections.Immutable.ImmutableSortedSet`1"; - - private const string ImmutableHashSetTypeName = "System.Collections.Immutable.ImmutableHashSet"; private const string ImmutableHashSetGenericTypeName = "System.Collections.Immutable.ImmutableHashSet`1"; private const string ImmutableSetGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableSet`1"; - - private const string ImmutableDictionaryTypeName = "System.Collections.Immutable.ImmutableDictionary"; private const string ImmutableDictionaryGenericTypeName = "System.Collections.Immutable.ImmutableDictionary`2"; private const string ImmutableDictionaryGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableDictionary`2"; + private const string ImmutableSortedDictionaryGenericTypeName = "System.Collections.Immutable.ImmutableSortedDictionary`2"; + // Immutable collection builder types. + private const string ImmutableArrayTypeName = "System.Collections.Immutable.ImmutableArray"; + private const string ImmutableListTypeName = "System.Collections.Immutable.ImmutableList"; + private const string ImmutableStackTypeName = "System.Collections.Immutable.ImmutableStack"; + private const string ImmutableQueueTypeName = "System.Collections.Immutable.ImmutableQueue"; + private const string ImmutableSortedSetTypeName = "System.Collections.Immutable.ImmutableSortedSet"; + private const string ImmutableHashSetTypeName = "System.Collections.Immutable.ImmutableHashSet"; + private const string ImmutableDictionaryTypeName = "System.Collections.Immutable.ImmutableDictionary"; private const string ImmutableSortedDictionaryTypeName = "System.Collections.Immutable.ImmutableSortedDictionary"; - private const string ImmutableSortedDictionaryGenericTypeName = "System.Collections.Immutable.ImmutableSortedDictionary`2"; internal static Type? GetCompatibleGenericBaseClass(this Type type, Type baseType) { @@ -139,20 +136,27 @@ public static bool IsImmutableEnumerableType(this Type type) } } - // TODO: https://github.com/dotnet/runtime/issues/38593. + [DynamicDependency("CreateRange`1", "System.Collections.Immutable.ImmutableArray", "System.Collections.Immutable")] + [DynamicDependency("CreateRange`1", "System.Collections.Immutable.ImmutableList", "System.Collections.Immutable")] + [DynamicDependency("CreateRange`1", "System.Collections.Immutable.ImmutableStack", "System.Collections.Immutable")] + [DynamicDependency("CreateRange`1", "System.Collections.Immutable.ImmutableQueue", "System.Collections.Immutable")] + [DynamicDependency("CreateRange`1", "System.Collections.Immutable.ImmutableSortedSet", "System.Collections.Immutable")] + [DynamicDependency("CreateRange`1", "System.Collections.Immutable.ImmutableHashSet", "System.Collections.Immutable")] public static MethodInfo GetImmutableEnumerableCreateRangeMethod(this Type type, Type elementType) { - Type constructingType = GetImmutableEnumerableConstructingType(type); - - MethodInfo[] constructingTypeMethods = constructingType.GetMethods(); - foreach (MethodInfo method in constructingTypeMethods) + Type? constructingType = GetImmutableEnumerableConstructingType(type); + if (constructingType != null) { - if (method.Name == "CreateRange" - && method.GetParameters().Length == 1 - && method.IsGenericMethod - && method.GetGenericArguments().Length == 1) + MethodInfo[] constructingTypeMethods = constructingType.GetMethods(); + foreach (MethodInfo method in constructingTypeMethods) { - return method.MakeGenericMethod(elementType); + if (method.Name == "CreateRange" && + method.GetParameters().Length == 1 && + method.IsGenericMethod && + method.GetGenericArguments().Length == 1) + { + return method.MakeGenericMethod(elementType); + } } } @@ -160,20 +164,23 @@ public static MethodInfo GetImmutableEnumerableCreateRangeMethod(this Type type, return null!; } - // TODO: https://github.com/dotnet/runtime/issues/38593. + [DynamicDependency("CreateRange`2", "System.Collections.Immutable.ImmutableDictionary", "System.Collections.Immutable")] + [DynamicDependency("CreateRange`2", "System.Collections.Immutable.ImmutableSortedDictionary", "System.Collections.Immutable")] public static MethodInfo GetImmutableDictionaryCreateRangeMethod(this Type type, Type elementType) { - Type constructingType = GetImmutableDictionaryConstructingType(type); - - MethodInfo[] constructingTypeMethods = constructingType.GetMethods(); - foreach (MethodInfo method in constructingTypeMethods) + Type? constructingType = GetImmutableDictionaryConstructingType(type); + if (constructingType != null) { - if (method.Name == "CreateRange" - && method.GetParameters().Length == 1 - && method.IsGenericMethod - && method.GetGenericArguments().Length == 2) + MethodInfo[] constructingTypeMethods = constructingType.GetMethods(); + foreach (MethodInfo method in constructingTypeMethods) { - return method.MakeGenericMethod(typeof(string), elementType); + if (method.Name == "CreateRange" && + method.GetParameters().Length == 1 && + method.IsGenericMethod && + method.GetGenericArguments().Length == 2) + { + return method.MakeGenericMethod(typeof(string), elementType); + } } } @@ -181,7 +188,7 @@ public static MethodInfo GetImmutableDictionaryCreateRangeMethod(this Type type, return null!; } - private static Type GetImmutableEnumerableConstructingType(Type type) + private static Type? GetImmutableEnumerableConstructingType(Type type) { Debug.Assert(type.IsImmutableEnumerableType()); @@ -218,14 +225,13 @@ private static Type GetImmutableEnumerableConstructingType(Type type) default: // We verified that the type is an immutable collection, so the // generic definition is one of the above. - return null!; + return null; } - // This won't be null because we verified the assembly is actually System.Collections.Immutable. - return underlyingType.Assembly.GetType(constructingTypeName)!; + return underlyingType.Assembly.GetType(constructingTypeName); } - private static Type GetImmutableDictionaryConstructingType(Type type) + private static Type? GetImmutableDictionaryConstructingType(Type type) { Debug.Assert(type.IsImmutableDictionaryType()); @@ -247,11 +253,10 @@ private static Type GetImmutableDictionaryConstructingType(Type type) default: // We verified that the type is an immutable collection, so the // generic definition is one of the above. - return null!; + return null; } - // This won't be null because we verified the assembly is actually System.Collections.Immutable. - return underlyingType.Assembly.GetType(constructingTypeName)!; + return underlyingType.Assembly.GetType(constructingTypeName); } public static bool IsNonGenericStackOrQueue(this Type type) diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableDictionary.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableDictionary.cs new file mode 100644 index 00000000000000..9c674eceb8cbac --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableDictionary.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that (de)serializing IImmutableDictionary is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = @"{""Key"":1}"; + object obj = JsonSerializer.Deserialize(json, typeof(IImmutableDictionary)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableList.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableList.cs new file mode 100644 index 00000000000000..db6e1beb714b7f --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableList.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that (de)serializing IImmutableList is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(IImmutableList)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableQueue.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableQueue.cs new file mode 100644 index 00000000000000..9285cb0b3df3d2 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableQueue.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that (de)serializing IImmutableQueue is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(IImmutableQueue)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableSet.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableSet.cs new file mode 100644 index 00000000000000..3804ca32bfa279 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableSet.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that (de)serializing IImmutableSet is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(IImmutableSet)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableStack.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableStack.cs new file mode 100644 index 00000000000000..8c9a0905eca444 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableStack.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that (de)serializing IImmutableStack is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(IImmutableStack)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableArray.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableArray.cs new file mode 100644 index 00000000000000..08069912c898db --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableArray.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that (de)serializing ImmutableArray is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(ImmutableArray)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableDictionary.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableDictionary.cs new file mode 100644 index 00000000000000..21317912f92343 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableDictionary.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that (de)serializing ImmutableDictionary is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = @"{""Key"":1}"; + object obj = JsonSerializer.Deserialize(json, typeof(ImmutableDictionary)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableHashSet.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableHashSet.cs new file mode 100644 index 00000000000000..de4ba0ed292295 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableHashSet.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that (de)serializing ImmutableHashSet is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(ImmutableHashSet)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableList.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableList.cs new file mode 100644 index 00000000000000..e2b89da6d95436 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableList.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that (de)serializing ImmutableList is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(ImmutableList)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableQueue.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableQueue.cs new file mode 100644 index 00000000000000..280f5b57e0dd04 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableQueue.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that (de)serializing ImmutableQueue is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(ImmutableQueue)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedDictionary.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedDictionary.cs new file mode 100644 index 00000000000000..d3a35e949a283d --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedDictionary.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that (de)serializing ImmutableSortedDictionary is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = @"{""Key"":1}"; + object obj = JsonSerializer.Deserialize(json, typeof(ImmutableSortedDictionary)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedSet.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedSet.cs new file mode 100644 index 00000000000000..bfa34ce95825ad --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedSet.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that (de)serializing ImmutableSortedSet is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(ImmutableSortedSet)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableStack.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableStack.cs new file mode 100644 index 00000000000000..fa09a6f92e2466 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableStack.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that (de)serializing ImmutableStack is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(ImmutableStack)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConvertersTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.cs similarity index 61% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConvertersTest.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.cs index 787bfb97cfb0e5..b68415a3adc7c7 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConvertersTest.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.cs @@ -2,13 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Collections; using System.Collections.ObjectModel; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Collections.Immutable; -using System.Text; using System.Text.Json; using System.Text.Json.Serialization; @@ -23,134 +20,115 @@ static int Main(string[] args) { string json = "[1]"; object obj = JsonSerializer.Deserialize(json, typeof(int[])); // ArrayConverter - if (!AssertCollectionAndSerialize(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(ConcurrentQueue)); // ConcurrentQueueOfTConverter - if (!AssertCollectionAndSerialize>(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(ConcurrentStack)); // ConcurrentStackOfTConverter - if (!AssertCollectionAndSerialize>(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(LinkedList)); // ICollectionOfTConverter - if (!AssertCollectionAndSerialize>(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(IEnumerable)); // IEnumerableConverter - if (!AssertCollectionAndSerialize(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(IEnumerable)); // IEnumerableOfTConverter - if (!AssertCollectionAndSerialize>(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(Queue)); // IEnumerableWithAddMethodConverter - if (!AssertCollectionAndSerialize(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(ArrayList)); // IListConverter - if (!AssertCollectionAndSerialize(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(Collection)); // IListOfTConverter - if (!AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - // TODO: instantiate this with the serializer - https://github.com/dotnet/runtime/issues/38593. - obj = ImmutableList.CreateRange(new[] { 1 }); - if (!(AssertCollectionAndSerialize>(obj, json))) // ImmutableEnumerableOfTConverter + if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(HashSet)); // ISetOfTConverter - if (!AssertCollectionAndSerialize>(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(List)); // ListOfTConverter - if (!AssertCollectionAndSerialize>(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(Queue)); // QueueOfTConverter - if (!AssertCollectionAndSerialize>(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(Stack)); // StackOfTConverter - if (!AssertCollectionAndSerialize>(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) { return -1; } json = @"{""Key"":1}"; obj = JsonSerializer.Deserialize(json, typeof(Dictionary)); // DictionaryOfTKeyTValueConverter - if (!AssertCollectionAndSerialize>(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(Hashtable)); // IDictionaryConverter - if (!AssertCollectionAndSerialize(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(ConcurrentDictionary)); // IDictionaryOfTKeyTValueConverter - if (!AssertCollectionAndSerialize>(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(IDictionary)); // IDictionaryOfTKeyTValueConverter - if (!AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - // TODO: instantiate this with the serializer - https://github.com/dotnet/runtime/issues/38593. - obj = ImmutableDictionary.CreateRange(new Dictionary { ["Key"] = 1 }); - if (!(AssertCollectionAndSerialize>(obj, json))) // ImmutableDictionaryTKeyTValueOfTConverter + if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) { return -1; } obj = JsonSerializer.Deserialize(json, typeof(IReadOnlyDictionary)); // IReadOnlyDictionaryOfTKeyTValueConverter - if (!AssertCollectionAndSerialize>(obj, json)) + if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) { return -1; } return 100; } - - private static bool AssertCollectionAndSerialize(object obj, string json) - { - return obj is T && JsonSerializer.Serialize(obj) == json; - } } } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/EnumConverterTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/EnumConverterTest.cs index 66f962f981752c..ec7d6687a434ed 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/EnumConverterTest.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/EnumConverterTest.cs @@ -4,7 +4,6 @@ using System; using System.Text.Json; -using System.Text.Json.Serialization; namespace SerializerTrimmingTest { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs index f630ff96ed9d68..83128dc266a687 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs @@ -94,6 +94,11 @@ public static bool VerifyWithSerialize(object obj, string expected) { return JsonEqual(expected, JsonSerializer.Serialize(obj)); } + + public static bool AssertCollectionAndSerialize(object obj, string json) + { + return obj is T && JsonSerializer.Serialize(obj) == json; + } } internal class MyClass diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/JsonConstructorAttributeTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/JsonConverterAttributeTest.cs similarity index 100% rename from src/libraries/System.Text.Json/tests/TrimmingTests/JsonConstructorAttributeTest.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/JsonConverterAttributeTest.cs diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/ObjectConvertersTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/ObjectConvertersTest.cs index 4a57a6f57f304c..c77db580954cbf 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/ObjectConvertersTest.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/ObjectConvertersTest.cs @@ -2,15 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; -using System.Collections; -using System.Collections.ObjectModel; -using System.Collections.Concurrent; using System.Collections.Generic; -using System.Collections.Immutable; -using System.Text; using System.Text.Json; -using System.Text.Json.Serialization; namespace SerializerTrimmingTest { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj b/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj index 277710d65f5921..939cc3a77755b2 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj @@ -2,6 +2,48 @@ + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + Helper.cs @@ -50,11 +92,8 @@ Helper.cs - - Helper.cs - - + Helper.cs From 2f14a0b1d59d502553d36b4ba5bdcb32a93fae09 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Sun, 5 Jul 2020 23:39:11 -0700 Subject: [PATCH 04/10] Address review feedback --- .../System.Text.Json/ref/System.Text.Json.cs | 52 +++++++ .../ref/System.Text.Json.csproj | 10 +- .../ref/System.Text.Json.netcoreapp.cs | 34 ----- .../ref/System.Text.Json.non-netcoreapp.cs | 32 ----- .../IEnumerableConverterFactoryHelpers.cs | 26 ++-- .../CollectionConvertersTest.cs | 134 ------------------ .../tests/TrimmingTests/Collections/Array.cs | 26 ++++ .../Collections/ConcurrentDictionary.cs | 27 ++++ .../Collections/ConcurrentQueue.cs | 27 ++++ .../Collections/ConcurrentStack.cs | 27 ++++ .../Collections/DictionaryOfTKeyTValue.cs | 27 ++++ .../TrimmingTests/Collections/HashSetOfT.cs | 27 ++++ .../TrimmingTests/Collections/HashTable.cs | 27 ++++ .../TrimmingTests/Collections/ICollection.cs | 27 ++++ .../Collections/ICollectionOfT.cs | 27 ++++ .../TrimmingTests/Collections/IDictionary.cs | 27 ++++ .../Collections/IDictionaryOfTKeyTValue.cs | 27 ++++ .../TrimmingTests/Collections/IEnumerable.cs | 27 ++++ .../Collections/IEnumerableOfT.cs | 27 ++++ .../IImmutableDictionary.cs} | 2 +- .../IImmutableList.cs} | 2 +- .../IImmutableQueue.cs} | 2 +- .../IImmutableSet.cs} | 2 +- .../IImmutableStack.cs} | 2 +- .../tests/TrimmingTests/Collections/IList.cs | 27 ++++ .../TrimmingTests/Collections/IListOfT.cs | 27 ++++ .../IReadOnlyDictionaryOfTKeyTValue.cs | 27 ++++ .../TrimmingTests/Collections/ISetOfT.cs | 27 ++++ .../ImmutableArray.cs} | 2 +- .../ImmutableDictionary.cs} | 2 +- .../ImmutableHashSet.cs} | 2 +- .../ImmutableList.cs} | 2 +- .../ImmutableQueue.cs} | 2 +- .../ImmutableSortedDictionary.cs} | 2 +- .../ImmutableSortedSet.cs} | 2 +- .../ImmutableStack.cs} | 2 +- .../TrimmingTests/Collections/ListOfT.cs | 27 ++++ .../tests/TrimmingTests/Collections/Queue.cs | 27 ++++ .../TrimmingTests/Collections/QueueOfT.cs | 27 ++++ .../tests/TrimmingTests/Collections/Stack.cs | 27 ++++ .../TrimmingTests/Collections/StackOfT.cs | 27 ++++ .../System.Text.Json.TrimmingTests.proj | 82 +++++++++-- 42 files changed, 746 insertions(+), 243 deletions(-) delete mode 100644 src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs delete mode 100644 src/libraries/System.Text.Json/ref/System.Text.Json.non-netcoreapp.cs delete mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Array.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ConcurrentDictionary.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ConcurrentQueue.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ConcurrentStack.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/DictionaryOfTKeyTValue.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/HashSetOfT.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/HashTable.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ICollection.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ICollectionOfT.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IDictionary.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IDictionaryOfTKeyTValue.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IEnumerable.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IEnumerableOfT.cs rename src/libraries/System.Text.Json/tests/TrimmingTests/{CollectionConverters/CollectionConvertersTest.IImmutableDictionary.cs => Collections/IImmutableDictionary.cs} (86%) rename src/libraries/System.Text.Json/tests/TrimmingTests/{CollectionConverters/CollectionConvertersTest.IImmutableList.cs => Collections/IImmutableList.cs} (87%) rename src/libraries/System.Text.Json/tests/TrimmingTests/{CollectionConverters/CollectionConvertersTest.IImmutableQueue.cs => Collections/IImmutableQueue.cs} (87%) rename src/libraries/System.Text.Json/tests/TrimmingTests/{CollectionConverters/CollectionConvertersTest.IImmutableSet.cs => Collections/IImmutableSet.cs} (87%) rename src/libraries/System.Text.Json/tests/TrimmingTests/{CollectionConverters/CollectionConvertersTest.IImmutableStack.cs => Collections/IImmutableStack.cs} (87%) create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IList.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IListOfT.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IReadOnlyDictionaryOfTKeyTValue.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ISetOfT.cs rename src/libraries/System.Text.Json/tests/TrimmingTests/{CollectionConverters/CollectionConvertersTest.ImmutableArray.cs => Collections/ImmutableArray.cs} (87%) rename src/libraries/System.Text.Json/tests/TrimmingTests/{CollectionConverters/CollectionConvertersTest.ImmutableDictionary.cs => Collections/ImmutableDictionary.cs} (86%) rename src/libraries/System.Text.Json/tests/TrimmingTests/{CollectionConverters/CollectionConvertersTest.ImmutableHashSet.cs => Collections/ImmutableHashSet.cs} (87%) rename src/libraries/System.Text.Json/tests/TrimmingTests/{CollectionConverters/CollectionConvertersTest.ImmutableList.cs => Collections/ImmutableList.cs} (87%) rename src/libraries/System.Text.Json/tests/TrimmingTests/{CollectionConverters/CollectionConvertersTest.ImmutableQueue.cs => Collections/ImmutableQueue.cs} (87%) rename src/libraries/System.Text.Json/tests/TrimmingTests/{CollectionConverters/CollectionConvertersTest.ImmutableSortedDictionary.cs => Collections/ImmutableSortedDictionary.cs} (85%) rename src/libraries/System.Text.Json/tests/TrimmingTests/{CollectionConverters/CollectionConvertersTest.ImmutableSortedSet.cs => Collections/ImmutableSortedSet.cs} (87%) rename src/libraries/System.Text.Json/tests/TrimmingTests/{CollectionConverters/CollectionConvertersTest.ImmutableStack.cs => Collections/ImmutableStack.cs} (87%) create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ListOfT.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Queue.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/QueueOfT.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Stack.cs create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/StackOfT.cs 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 fb421d68df6924..3504dc6e38bb1b 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -183,6 +183,52 @@ public partial struct JsonReaderState public JsonReaderState(System.Text.Json.JsonReaderOptions options = default(System.Text.Json.JsonReaderOptions)) { throw null; } public System.Text.Json.JsonReaderOptions Options { get { throw null; } } } + public static partial class JsonSerializer + { +#if NETCOREAPPCURRENT + private const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MembersAccessedOnRead = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties; + private const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MembersAccessedOnWrite = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties; + public static object? Deserialize(System.ReadOnlySpan utf8Json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static object? Deserialize(string json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] 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.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] + public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] + public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] + public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static string Serialize(object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { } + public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] 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.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] 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 byte[] SerializeToUtf8Bytes(object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static byte[] SerializeToUtf8Bytes<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] TValue>(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static void Serialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] TValue>(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.JsonSerializerOptions? options = null) { } + public static string Serialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] TValue>(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } +#else + public static object? Deserialize(System.ReadOnlySpan utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static object? Deserialize(string json, 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.JsonSerializerOptions? options = null) { throw null; } + public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, 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.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] + public static TValue Deserialize(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] + public static TValue Deserialize(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + [return: System.Diagnostics.CodeAnalysis.MaybeNull] + public static TValue Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static string Serialize(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { } + public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, 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, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static byte[] SerializeToUtf8Bytes(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static byte[] SerializeToUtf8Bytes(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } + public static void Serialize(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.JsonSerializerOptions? options = null) { } + public static string Serialize(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } +#endif + } public sealed partial class JsonSerializerOptions { public JsonSerializerOptions() { } @@ -461,8 +507,14 @@ internal JsonConverter() { } public partial class JsonConverterAttribute : System.Text.Json.Serialization.JsonAttribute { protected JsonConverterAttribute() { } +#if NETCOREAPPCURRENT + public JsonConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] System.Type converterType) { } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + public System.Type? ConverterType { get { throw null; } } +#else public JsonConverterAttribute(System.Type converterType) { } public System.Type? ConverterType { get { throw null; } } +#endif public virtual System.Text.Json.Serialization.JsonConverter? CreateConverter(System.Type typeToConvert) { throw null; } } public abstract partial class JsonConverterFactory : System.Text.Json.Serialization.JsonConverter 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 500313fbf95b53..08cd04253f567e 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj @@ -3,6 +3,10 @@ $(NetCoreAppCurrent);netstandard2.0;$(NetFrameworkCurrent) enable + + + $(DefineConstants);NETCOREAPPCURRENT + @@ -17,12 +21,6 @@ - - - - - - diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs deleted file mode 100644 index c02d880afdd872..00000000000000 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.netcoreapp.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -// ------------------------------------------------------------------------------ -// Changes to this file must follow the https://aka.ms/api-review process. -// ------------------------------------------------------------------------------ - -namespace System.Text.Json -{ - public static partial class JsonSerializer - { - private const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MembersAccessedOnRead = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties; - private const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MembersAccessedOnWrite = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties; - public static object? Deserialize(System.ReadOnlySpan utf8Json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static object? Deserialize(string json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static object? Deserialize(ref System.Text.Json.Utf8JsonReader reader, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] 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.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNull] - public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNull] - public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNull] - public static TValue Deserialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] TValue>(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static string Serialize(object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { } - public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] 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.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] 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 byte[] SerializeToUtf8Bytes(object? value, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static byte[] SerializeToUtf8Bytes<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] TValue>(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static void Serialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] TValue>(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.JsonSerializerOptions? options = null) { } - public static string Serialize<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnWrite)] TValue>(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - } -} diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.non-netcoreapp.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.non-netcoreapp.cs deleted file mode 100644 index d3f88b2e86b559..00000000000000 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.non-netcoreapp.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -// ------------------------------------------------------------------------------ -// Changes to this file must follow the https://aka.ms/api-review process. -// ------------------------------------------------------------------------------ - -namespace System.Text.Json -{ - public static partial class JsonSerializer - { - public static object? Deserialize(System.ReadOnlySpan utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static object? Deserialize(string json, 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.JsonSerializerOptions? options = null) { throw null; } - public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, 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.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNull] - public static TValue Deserialize(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNull] - public static TValue Deserialize(string json, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - [return: System.Diagnostics.CodeAnalysis.MaybeNull] - public static TValue Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static string Serialize(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { } - public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object? value, 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, TValue value, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static byte[] SerializeToUtf8Bytes(object? value, System.Type inputType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static byte[] SerializeToUtf8Bytes(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - public static void Serialize(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.JsonSerializerOptions? options = null) { } - public static string Serialize(TValue value, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } - } -} 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 63af7761171c9e..59d5dda2d2f8b7 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 @@ -35,6 +35,12 @@ internal static class IEnumerableConverterFactoryHelpers private const string ImmutableDictionaryTypeName = "System.Collections.Immutable.ImmutableDictionary"; private const string ImmutableSortedDictionaryTypeName = "System.Collections.Immutable.ImmutableSortedDictionary"; + private const string CreateRangeMethodName = "CreateRange"; + private const string CreateRangeMethodNameForEnumerable = "CreateRange`1"; + private const string CreateRangeMethodNameForDictionary = "CreateRange`2"; + + private const string ImmutableCollectionsNamespace = "System.Collections.Immutable"; + internal static Type? GetCompatibleGenericBaseClass(this Type type, Type baseType) { Debug.Assert(baseType.IsGenericType); @@ -136,12 +142,12 @@ public static bool IsImmutableEnumerableType(this Type type) } } - [DynamicDependency("CreateRange`1", "System.Collections.Immutable.ImmutableArray", "System.Collections.Immutable")] - [DynamicDependency("CreateRange`1", "System.Collections.Immutable.ImmutableList", "System.Collections.Immutable")] - [DynamicDependency("CreateRange`1", "System.Collections.Immutable.ImmutableStack", "System.Collections.Immutable")] - [DynamicDependency("CreateRange`1", "System.Collections.Immutable.ImmutableQueue", "System.Collections.Immutable")] - [DynamicDependency("CreateRange`1", "System.Collections.Immutable.ImmutableSortedSet", "System.Collections.Immutable")] - [DynamicDependency("CreateRange`1", "System.Collections.Immutable.ImmutableHashSet", "System.Collections.Immutable")] + [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableArrayTypeName, ImmutableCollectionsNamespace)] + [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableListTypeName, ImmutableCollectionsNamespace)] + [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableStackTypeName, ImmutableCollectionsNamespace)] + [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableQueueTypeName, ImmutableCollectionsNamespace)] + [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableSortedSetTypeName, ImmutableCollectionsNamespace)] + [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableHashSetTypeName, ImmutableCollectionsNamespace)] public static MethodInfo GetImmutableEnumerableCreateRangeMethod(this Type type, Type elementType) { Type? constructingType = GetImmutableEnumerableConstructingType(type); @@ -150,7 +156,7 @@ public static MethodInfo GetImmutableEnumerableCreateRangeMethod(this Type type, MethodInfo[] constructingTypeMethods = constructingType.GetMethods(); foreach (MethodInfo method in constructingTypeMethods) { - if (method.Name == "CreateRange" && + if (method.Name == CreateRangeMethodName && method.GetParameters().Length == 1 && method.IsGenericMethod && method.GetGenericArguments().Length == 1) @@ -164,8 +170,8 @@ public static MethodInfo GetImmutableEnumerableCreateRangeMethod(this Type type, return null!; } - [DynamicDependency("CreateRange`2", "System.Collections.Immutable.ImmutableDictionary", "System.Collections.Immutable")] - [DynamicDependency("CreateRange`2", "System.Collections.Immutable.ImmutableSortedDictionary", "System.Collections.Immutable")] + [DynamicDependency(CreateRangeMethodNameForDictionary, ImmutableDictionaryTypeName, ImmutableCollectionsNamespace)] + [DynamicDependency(CreateRangeMethodNameForDictionary, ImmutableSortedDictionaryTypeName, ImmutableCollectionsNamespace)] public static MethodInfo GetImmutableDictionaryCreateRangeMethod(this Type type, Type elementType) { Type? constructingType = GetImmutableDictionaryConstructingType(type); @@ -174,7 +180,7 @@ public static MethodInfo GetImmutableDictionaryCreateRangeMethod(this Type type, MethodInfo[] constructingTypeMethods = constructingType.GetMethods(); foreach (MethodInfo method in constructingTypeMethods) { - if (method.Name == "CreateRange" && + if (method.Name == CreateRangeMethodName && method.GetParameters().Length == 1 && method.IsGenericMethod && method.GetGenericArguments().Length == 2) diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.cs deleted file mode 100644 index b68415a3adc7c7..00000000000000 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.cs +++ /dev/null @@ -1,134 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections; -using System.Collections.ObjectModel; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace SerializerTrimmingTest -{ - /// - /// Tests that the collection converter factory is linker-safe. - /// - internal class Program - { - static int Main(string[] args) - { - string json = "[1]"; - object obj = JsonSerializer.Deserialize(json, typeof(int[])); // ArrayConverter - if (!TestHelper.AssertCollectionAndSerialize(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(ConcurrentQueue)); // ConcurrentQueueOfTConverter - if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(ConcurrentStack)); // ConcurrentStackOfTConverter - if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(LinkedList)); // ICollectionOfTConverter - if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(IEnumerable)); // IEnumerableConverter - if (!TestHelper.AssertCollectionAndSerialize(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(IEnumerable)); // IEnumerableOfTConverter - if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(Queue)); // IEnumerableWithAddMethodConverter - if (!TestHelper.AssertCollectionAndSerialize(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(ArrayList)); // IListConverter - if (!TestHelper.AssertCollectionAndSerialize(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(Collection)); // IListOfTConverter - if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(HashSet)); // ISetOfTConverter - if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(List)); // ListOfTConverter - if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(Queue)); // QueueOfTConverter - if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(Stack)); // StackOfTConverter - if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - json = @"{""Key"":1}"; - obj = JsonSerializer.Deserialize(json, typeof(Dictionary)); // DictionaryOfTKeyTValueConverter - if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(Hashtable)); // IDictionaryConverter - if (!TestHelper.AssertCollectionAndSerialize(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(ConcurrentDictionary)); // IDictionaryOfTKeyTValueConverter - if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(IDictionary)); // IDictionaryOfTKeyTValueConverter - if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - obj = JsonSerializer.Deserialize(json, typeof(IReadOnlyDictionary)); // IReadOnlyDictionaryOfTKeyTValueConverter - if (!TestHelper.AssertCollectionAndSerialize>(obj, json)) - { - return -1; - } - - return 100; - } - } -} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Array.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Array.cs new file mode 100644 index 00000000000000..6ba4950d4cf855 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Array.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing Array is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(int[])); + if (!(TestHelper.AssertCollectionAndSerialize(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ConcurrentDictionary.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ConcurrentDictionary.cs new file mode 100644 index 00000000000000..23f433f4dbb7d9 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ConcurrentDictionary.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Concurrent; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing ConcurrentDictionary is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = @"{""Key"":1}"; + object obj = JsonSerializer.Deserialize(json, typeof(ConcurrentDictionary)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ConcurrentQueue.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ConcurrentQueue.cs new file mode 100644 index 00000000000000..ff624deea7cabd --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ConcurrentQueue.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Concurrent; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing ConcurrentQueue is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(ConcurrentQueue)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ConcurrentStack.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ConcurrentStack.cs new file mode 100644 index 00000000000000..2c0b396405f323 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ConcurrentStack.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Concurrent; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing ConcurrentStack is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(ConcurrentStack)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/DictionaryOfTKeyTValue.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/DictionaryOfTKeyTValue.cs new file mode 100644 index 00000000000000..b98e2c8d51e328 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/DictionaryOfTKeyTValue.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing Dictionary is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = @"{""Key"":1}"; + object obj = JsonSerializer.Deserialize(json, typeof(Dictionary)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/HashSetOfT.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/HashSetOfT.cs new file mode 100644 index 00000000000000..45c468c6b69211 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/HashSetOfT.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing HashSet is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(HashSet)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/HashTable.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/HashTable.cs new file mode 100644 index 00000000000000..684837f1dbbb4e --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/HashTable.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing Hashtable is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = @"{""Key"":1}"; + object obj = JsonSerializer.Deserialize(json, typeof(Hashtable)); + if (!(TestHelper.AssertCollectionAndSerialize(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ICollection.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ICollection.cs new file mode 100644 index 00000000000000..aacd989306d333 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ICollection.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing ICollection is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(ICollection>)); + if (!(TestHelper.AssertCollectionAndSerialize(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ICollectionOfT.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ICollectionOfT.cs new file mode 100644 index 00000000000000..3ede4f68397425 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ICollectionOfT.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing ICollection is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(ICollection)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IDictionary.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IDictionary.cs new file mode 100644 index 00000000000000..5f4da2a9f940a3 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IDictionary.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing IDictionary is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = @"{""Key"":1}"; + object obj = JsonSerializer.Deserialize(json, typeof(IDictionary)); + if (!(TestHelper.AssertCollectionAndSerialize(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IDictionaryOfTKeyTValue.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IDictionaryOfTKeyTValue.cs new file mode 100644 index 00000000000000..0f107fbe515c2d --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IDictionaryOfTKeyTValue.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing IDictionary is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = @"{""Key"":1}"; + object obj = JsonSerializer.Deserialize(json, typeof(IDictionary)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IEnumerable.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IEnumerable.cs new file mode 100644 index 00000000000000..e6af50148e98f0 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IEnumerable.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing IEnumerable is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(IEnumerable)); + if (!(TestHelper.AssertCollectionAndSerialize(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IEnumerableOfT.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IEnumerableOfT.cs new file mode 100644 index 00000000000000..83cc0a9d811ebe --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IEnumerableOfT.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing IEnumerable is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(IEnumerable)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableDictionary.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableDictionary.cs similarity index 86% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableDictionary.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableDictionary.cs index 9c674eceb8cbac..259f9ce3e76b50 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableDictionary.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableDictionary.cs @@ -8,7 +8,7 @@ namespace SerializerTrimmingTest { /// - /// Tests that (de)serializing IImmutableDictionary is linker-safe. + /// Tests that the serializer's warm up routine for (de)serializing IImmutableDictionary is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableList.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableList.cs similarity index 87% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableList.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableList.cs index db6e1beb714b7f..29f05c4b54ca8b 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableList.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableList.cs @@ -8,7 +8,7 @@ namespace SerializerTrimmingTest { /// - /// Tests that (de)serializing IImmutableList is linker-safe. + /// Tests that the serializer's warm up routine for (de)serializing IImmutableList is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableQueue.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableQueue.cs similarity index 87% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableQueue.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableQueue.cs index 9285cb0b3df3d2..c8b6d7681c44a7 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableQueue.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableQueue.cs @@ -8,7 +8,7 @@ namespace SerializerTrimmingTest { /// - /// Tests that (de)serializing IImmutableQueue is linker-safe. + /// Tests that the serializer's warm up routine for (de)serializing IImmutableQueue is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableSet.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableSet.cs similarity index 87% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableSet.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableSet.cs index 3804ca32bfa279..668ee52cd99fae 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableSet.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableSet.cs @@ -8,7 +8,7 @@ namespace SerializerTrimmingTest { /// - /// Tests that (de)serializing IImmutableSet is linker-safe. + /// Tests that the serializer's warm up routine for (de)serializing IImmutableSet is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableStack.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableStack.cs similarity index 87% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableStack.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableStack.cs index 8c9a0905eca444..d91ddbf5a1df00 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.IImmutableStack.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IImmutableStack.cs @@ -8,7 +8,7 @@ namespace SerializerTrimmingTest { /// - /// Tests that (de)serializing IImmutableStack is linker-safe. + /// Tests that the serializer's warm up routine for (de)serializing IImmutableStack is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IList.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IList.cs new file mode 100644 index 00000000000000..ea29d188bdf750 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IList.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing IList is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(IList)); + if (!(TestHelper.AssertCollectionAndSerialize(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IListOfT.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IListOfT.cs new file mode 100644 index 00000000000000..870a26a09efac0 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IListOfT.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing IList is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(IList)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IReadOnlyDictionaryOfTKeyTValue.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IReadOnlyDictionaryOfTKeyTValue.cs new file mode 100644 index 00000000000000..b2c49a70b85e2d --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/IReadOnlyDictionaryOfTKeyTValue.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing IReadOnlyDictionary is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = @"{""Key"":1}"; + object obj = JsonSerializer.Deserialize(json, typeof(IReadOnlyDictionary)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ISetOfT.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ISetOfT.cs new file mode 100644 index 00000000000000..74c715c39c1d11 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ISetOfT.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing ISet is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(ISet)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableArray.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableArray.cs similarity index 87% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableArray.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableArray.cs index 08069912c898db..fbf9c020f2daff 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableArray.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableArray.cs @@ -8,7 +8,7 @@ namespace SerializerTrimmingTest { /// - /// Tests that (de)serializing ImmutableArray is linker-safe. + /// Tests that the serializer's warm up routine for (de)serializing ImmutableArray is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableDictionary.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableDictionary.cs similarity index 86% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableDictionary.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableDictionary.cs index 21317912f92343..cdd919095b4734 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableDictionary.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableDictionary.cs @@ -8,7 +8,7 @@ namespace SerializerTrimmingTest { /// - /// Tests that (de)serializing ImmutableDictionary is linker-safe. + /// Tests that the serializer's warm up routine for (de)serializing ImmutableDictionary is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableHashSet.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableHashSet.cs similarity index 87% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableHashSet.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableHashSet.cs index de4ba0ed292295..59d0a43cd3e57d 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableHashSet.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableHashSet.cs @@ -8,7 +8,7 @@ namespace SerializerTrimmingTest { /// - /// Tests that (de)serializing ImmutableHashSet is linker-safe. + /// Tests that the serializer's warm up routine for (de)serializing ImmutableHashSet is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableList.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableList.cs similarity index 87% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableList.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableList.cs index e2b89da6d95436..9f784804c8fa89 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableList.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableList.cs @@ -8,7 +8,7 @@ namespace SerializerTrimmingTest { /// - /// Tests that (de)serializing ImmutableList is linker-safe. + /// Tests that the serializer's warm up routine for (de)serializing ImmutableList is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableQueue.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableQueue.cs similarity index 87% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableQueue.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableQueue.cs index 280f5b57e0dd04..ffbd5a9371c143 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableQueue.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableQueue.cs @@ -8,7 +8,7 @@ namespace SerializerTrimmingTest { /// - /// Tests that (de)serializing ImmutableQueue is linker-safe. + /// Tests that the serializer's warm up routine for (de)serializing ImmutableQueue is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedDictionary.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableSortedDictionary.cs similarity index 85% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedDictionary.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableSortedDictionary.cs index d3a35e949a283d..4c06d425bb1489 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedDictionary.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableSortedDictionary.cs @@ -8,7 +8,7 @@ namespace SerializerTrimmingTest { /// - /// Tests that (de)serializing ImmutableSortedDictionary is linker-safe. + /// Tests that the serializer's warm up routine for (de)serializing ImmutableSortedDictionary is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedSet.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableSortedSet.cs similarity index 87% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedSet.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableSortedSet.cs index bfa34ce95825ad..c19f2425a80d5c 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableSortedSet.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableSortedSet.cs @@ -8,7 +8,7 @@ namespace SerializerTrimmingTest { /// - /// Tests that (de)serializing ImmutableSortedSet is linker-safe. + /// Tests that the serializer's warm up routine for (de)serializing ImmutableSortedSet is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableStack.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableStack.cs similarity index 87% rename from src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableStack.cs rename to src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableStack.cs index fa09a6f92e2466..1642fc4db0a542 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/CollectionConverters/CollectionConvertersTest.ImmutableStack.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ImmutableStack.cs @@ -8,7 +8,7 @@ namespace SerializerTrimmingTest { /// - /// Tests that (de)serializing ImmutableStack is linker-safe. + /// Tests that the serializer's warm up routine for (de)serializing ImmutableStack is linker-safe. /// internal class Program { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ListOfT.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ListOfT.cs new file mode 100644 index 00000000000000..6446c47a504f2d --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ListOfT.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing List is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = @"{""Key"":1}"; + object obj = JsonSerializer.Deserialize(json, typeof(List)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Queue.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Queue.cs new file mode 100644 index 00000000000000..aba39cd93dd239 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Queue.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing Queue is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(Queue)); + if (!(TestHelper.AssertCollectionAndSerialize(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/QueueOfT.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/QueueOfT.cs new file mode 100644 index 00000000000000..7fcf72f105b252 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/QueueOfT.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing Queue is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = @"{""Key"":1}"; + object obj = JsonSerializer.Deserialize(json, typeof(Queue)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Stack.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Stack.cs new file mode 100644 index 00000000000000..abf0cfbfabf61b --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Stack.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing Stack is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(Stack)); + if (!(TestHelper.AssertCollectionAndSerialize(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/StackOfT.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/StackOfT.cs new file mode 100644 index 00000000000000..d82a0ab6163d06 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/StackOfT.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Immutable; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing Stack is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = "[1]"; + object obj = JsonSerializer.Deserialize(json, typeof(Stack)); + if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) + { + return -1; + } + + return 100; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj b/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj index 939cc3a77755b2..ae1307bd108f26 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/System.Text.Json.TrimmingTests.proj @@ -2,46 +2,100 @@ - + Helper.cs - + Helper.cs - + Helper.cs - + Helper.cs - + Helper.cs - + Helper.cs - + Helper.cs - + Helper.cs - + Helper.cs - + Helper.cs - + Helper.cs - + Helper.cs - + Helper.cs - + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + + Helper.cs + + Helper.cs From e202f5399cc72e848c35c34a10887dd1d6977fb2 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Mon, 6 Jul 2020 07:36:33 -0700 Subject: [PATCH 05/10] Clean up linker tests --- .../System.Text.Json/tests/TrimmingTests/Collections/ListOfT.cs | 2 +- .../tests/TrimmingTests/Collections/QueueOfT.cs | 2 +- .../tests/TrimmingTests/Collections/StackOfT.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ListOfT.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ListOfT.cs index 6446c47a504f2d..b038d827296acd 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ListOfT.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/ListOfT.cs @@ -14,7 +14,7 @@ internal class Program { static int Main(string[] args) { - string json = @"{""Key"":1}"; + string json = "[1]"; object obj = JsonSerializer.Deserialize(json, typeof(List)); if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/QueueOfT.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/QueueOfT.cs index 7fcf72f105b252..c2b90b17f3e805 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/QueueOfT.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/QueueOfT.cs @@ -14,7 +14,7 @@ internal class Program { static int Main(string[] args) { - string json = @"{""Key"":1}"; + string json = "[1]"; object obj = JsonSerializer.Deserialize(json, typeof(Queue)); if (!(TestHelper.AssertCollectionAndSerialize>(obj, json))) { diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/StackOfT.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/StackOfT.cs index d82a0ab6163d06..dd08c4be8f07a6 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/StackOfT.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/StackOfT.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Collections.Immutable; +using System.Collections.Generic; using System.Text.Json; namespace SerializerTrimmingTest From 2ec1df2ceaf7b96434606949875905396c32fe9e Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Mon, 6 Jul 2020 07:48:47 -0700 Subject: [PATCH 06/10] Fix ref file #if directives --- src/libraries/System.Text.Json/ref/System.Text.Json.cs | 4 ++-- src/libraries/System.Text.Json/ref/System.Text.Json.csproj | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) 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 3504dc6e38bb1b..df7879f7e05012 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -185,7 +185,7 @@ public partial struct JsonReaderState } public static partial class JsonSerializer { -#if NETCOREAPPCURRENT +#if NETCOREAPP private const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MembersAccessedOnRead = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties; private const System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MembersAccessedOnWrite = System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties; public static object? Deserialize(System.ReadOnlySpan utf8Json, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(MembersAccessedOnRead)] System.Type returnType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; } @@ -507,7 +507,7 @@ internal JsonConverter() { } public partial class JsonConverterAttribute : System.Text.Json.Serialization.JsonAttribute { protected JsonConverterAttribute() { } -#if NETCOREAPPCURRENT +#if NETCOREAPP public JsonConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] System.Type converterType) { } [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] public System.Type? ConverterType { get { 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 08cd04253f567e..b06efdcf9ac2ed 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.csproj @@ -3,10 +3,6 @@ $(NetCoreAppCurrent);netstandard2.0;$(NetFrameworkCurrent) enable - - - $(DefineConstants);NETCOREAPPCURRENT - From 9e34bd000b87c0c72378521525efd3983908cf35 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Mon, 6 Jul 2020 08:36:39 -0700 Subject: [PATCH 07/10] Clean up --- .../IEnumerableConverterFactoryHelpers.cs | 18 ++++++------- .../TrimmingTests/Collections/HashTable.cs | 27 ------------------- 2 files changed, 9 insertions(+), 36 deletions(-) delete mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/HashTable.cs 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 59d5dda2d2f8b7..c00bed8f4ab807 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 @@ -39,7 +39,7 @@ internal static class IEnumerableConverterFactoryHelpers private const string CreateRangeMethodNameForEnumerable = "CreateRange`1"; private const string CreateRangeMethodNameForDictionary = "CreateRange`2"; - private const string ImmutableCollectionsNamespace = "System.Collections.Immutable"; + private const string ImmutableCollectionsAssembly = "System.Collections.Immutable"; internal static Type? GetCompatibleGenericBaseClass(this Type type, Type baseType) { @@ -142,12 +142,12 @@ public static bool IsImmutableEnumerableType(this Type type) } } - [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableArrayTypeName, ImmutableCollectionsNamespace)] - [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableListTypeName, ImmutableCollectionsNamespace)] - [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableStackTypeName, ImmutableCollectionsNamespace)] - [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableQueueTypeName, ImmutableCollectionsNamespace)] - [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableSortedSetTypeName, ImmutableCollectionsNamespace)] - [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableHashSetTypeName, ImmutableCollectionsNamespace)] + [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableArrayTypeName, ImmutableCollectionsAssembly)] + [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableListTypeName, ImmutableCollectionsAssembly)] + [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableStackTypeName, ImmutableCollectionsAssembly)] + [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableQueueTypeName, ImmutableCollectionsAssembly)] + [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableSortedSetTypeName, ImmutableCollectionsAssembly)] + [DynamicDependency(CreateRangeMethodNameForEnumerable, ImmutableHashSetTypeName, ImmutableCollectionsAssembly)] public static MethodInfo GetImmutableEnumerableCreateRangeMethod(this Type type, Type elementType) { Type? constructingType = GetImmutableEnumerableConstructingType(type); @@ -170,8 +170,8 @@ public static MethodInfo GetImmutableEnumerableCreateRangeMethod(this Type type, return null!; } - [DynamicDependency(CreateRangeMethodNameForDictionary, ImmutableDictionaryTypeName, ImmutableCollectionsNamespace)] - [DynamicDependency(CreateRangeMethodNameForDictionary, ImmutableSortedDictionaryTypeName, ImmutableCollectionsNamespace)] + [DynamicDependency(CreateRangeMethodNameForDictionary, ImmutableDictionaryTypeName, ImmutableCollectionsAssembly)] + [DynamicDependency(CreateRangeMethodNameForDictionary, ImmutableSortedDictionaryTypeName, ImmutableCollectionsAssembly)] public static MethodInfo GetImmutableDictionaryCreateRangeMethod(this Type type, Type elementType) { Type? constructingType = GetImmutableDictionaryConstructingType(type); diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/HashTable.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/HashTable.cs deleted file mode 100644 index 684837f1dbbb4e..00000000000000 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/HashTable.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Collections; -using System.Text.Json; - -namespace SerializerTrimmingTest -{ - /// - /// Tests that the serializer's warm up routine for (de)serializing Hashtable is linker-safe. - /// - internal class Program - { - static int Main(string[] args) - { - string json = @"{""Key"":1}"; - object obj = JsonSerializer.Deserialize(json, typeof(Hashtable)); - if (!(TestHelper.AssertCollectionAndSerialize(obj, json))) - { - return -1; - } - - return 100; - } - } -} From 8630e433e763fa5647edd2b110c315d5bfdb0c00 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Mon, 6 Jul 2020 08:37:48 -0700 Subject: [PATCH 08/10] Re-add Hastable.cs --- .../TrimmingTests/Collections/Hashtable.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Hashtable.cs diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Hashtable.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Hashtable.cs new file mode 100644 index 00000000000000..684837f1dbbb4e --- /dev/null +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Collections/Hashtable.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections; +using System.Text.Json; + +namespace SerializerTrimmingTest +{ + /// + /// Tests that the serializer's warm up routine for (de)serializing Hashtable is linker-safe. + /// + internal class Program + { + static int Main(string[] args) + { + string json = @"{""Key"":1}"; + object obj = JsonSerializer.Deserialize(json, typeof(Hashtable)); + if (!(TestHelper.AssertCollectionAndSerialize(obj, json))) + { + return -1; + } + + return 100; + } + } +} From bf7a89b6ac41d1e5f263145ec4dd3d89e4d7cef8 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Mon, 6 Jul 2020 09:50:18 -0700 Subject: [PATCH 09/10] Remove serialization code from Deserialize overload tests --- .../tests/TrimmingTests/Helper.cs | 18 ++++++++---------- .../Deserialize.FromReader.BoxedObject.cs | 6 +++--- .../Deserialize.FromReader.TypedObject.cs | 6 +++--- .../Deserialize.FromSpan.BoxedObject.cs | 6 +++--- .../Deserialize.FromSpan.TypedObject.cs | 6 +++--- .../Deserialize.FromString.BoxedObject.cs | 6 +++--- .../Deserialize.FromString.TypedObject.cs | 6 +++--- .../DeserializeAsync.FromStream.BoxedObject.cs | 6 +++--- .../DeserializeAsync.FromStream.TypedObject.cs | 6 +++--- 9 files changed, 32 insertions(+), 34 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs index 83128dc266a687..470f244e496c64 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/Helper.cs @@ -85,16 +85,6 @@ private static bool JsonEqual(JsonElement expected, JsonElement actual) } } - /// - /// Verifies the result of deserialization by serializing and comparing the output - /// with the expected payload. With this call pattern, the serialize should preserve - /// properties on typeof(object), but that would not be helpful to the calling test. - /// - public static bool VerifyWithSerialize(object obj, string expected) - { - return JsonEqual(expected, JsonSerializer.Serialize(obj)); - } - public static bool AssertCollectionAndSerialize(object obj, string json) { return obj is T && JsonSerializer.Serialize(obj) == json; @@ -116,6 +106,14 @@ internal struct MyStruct public MyStruct(int x, int y) => (X, Y) = (x, y); } + internal class MyClassWithParameterizedCtor + { + public int X { get; set; } + public int Y { get; set; } + + public MyClassWithParameterizedCtor(int x, int y) => (X, Y) = (x, y); + } + internal class MyBigClass { public string A { get; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs index b8c806ec166336..fba446c89fbb2e 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs @@ -20,15 +20,15 @@ static int Main(string[] args) string json = "[1]"; Utf8JsonReader reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); int[] arr = (int[])JsonSerializer.Deserialize(ref reader, typeof(int[])); - if (!TestHelper.VerifyWithSerialize(arr, json)) + if (arr == null) { return -1; } json = @"{""X"":1,""Y"":2}"; reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); - MyStruct obj = (MyStruct)JsonSerializer.Deserialize(json, typeof(MyStruct)); - if (!TestHelper.VerifyWithSerialize(obj, json)) + var obj = (MyClassWithParameterizedCtor)JsonSerializer.Deserialize(json, typeof(MyClassWithParameterizedCtor)); + if (obj == null) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs index 61a97d167b249b..732f69646cb510 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs @@ -20,15 +20,15 @@ static int Main(string[] args) string json = "[1]"; Utf8JsonReader reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); int[] arr = JsonSerializer.Deserialize(ref reader); - if (!TestHelper.VerifyWithSerialize(arr, json)) + if (arr == null) { return -1; } json = @"{""X"":1,""Y"":2}"; reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); - MyStruct obj = JsonSerializer.Deserialize(ref reader); - if (!TestHelper.VerifyWithSerialize(obj, json)) + MyClassWithParameterizedCtor obj = JsonSerializer.Deserialize(ref reader); + if (obj == null) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs index c375857ec684b9..9141072fcc69ef 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs @@ -19,14 +19,14 @@ static int Main(string[] args) { string json = "[1]"; int[] arr = (int[])JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json), typeof(int[])); - if (!TestHelper.VerifyWithSerialize(arr, json)) + if (arr == null) { return -1; } json = @"{""X"":1,""Y"":2}"; - MyStruct obj = (MyStruct)JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json), typeof(MyStruct)); - if (!TestHelper.VerifyWithSerialize(obj, json)) + var obj = (MyClassWithParameterizedCtor)JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json), typeof(MyClassWithParameterizedCtor)); + if (obj == null) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs index 20482b3aa805e4..87509765af0920 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs @@ -19,14 +19,14 @@ static int Main(string[] args) { string json = "[1]"; int[] arr = JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json)); - if (!TestHelper.VerifyWithSerialize(arr, json)) + if (arr == null) { return -1; } json = @"{""X"":1,""Y"":2}"; - MyStruct obj = JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json)); - if (!TestHelper.VerifyWithSerialize(obj, json)) + MyClassWithParameterizedCtor obj = JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json)); + if (obj == null) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs index e901129830cd0a..54da5b41402643 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs @@ -18,14 +18,14 @@ static int Main(string[] args) { string json = "[1]"; int[] arr = (int[])JsonSerializer.Deserialize(json, typeof(int[])); - if (!TestHelper.VerifyWithSerialize(arr, json)) + if (arr == null) { return -1; } json = @"{""X"":1,""Y"":2}"; - MyStruct obj = (MyStruct)JsonSerializer.Deserialize(json, typeof(MyStruct)); - if (!TestHelper.VerifyWithSerialize(obj, json)) + var obj = (MyClassWithParameterizedCtor)JsonSerializer.Deserialize(json, typeof(MyClassWithParameterizedCtor)); + if (obj == null) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs index 694ba93d655785..fcc79df3147fec 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs @@ -18,14 +18,14 @@ static int Main(string[] args) { string json = "[1]"; int[] arr = JsonSerializer.Deserialize(json); - if (!TestHelper.VerifyWithSerialize(arr, json)) + if (arr == null) { return -1; } json = @"{""X"":1,""Y"":2}"; - MyStruct obj = JsonSerializer.Deserialize(json); - if (!TestHelper.VerifyWithSerialize(obj, json)) + MyClassWithParameterizedCtor obj = JsonSerializer.Deserialize(json); + if (obj == null) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs index cc7c6e82c67698..97d23d9d1a421a 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs @@ -24,7 +24,7 @@ static async Task Main(string[] args) using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { int[] arr = (int[])(await JsonSerializer.DeserializeAsync(stream, typeof(int[]))); - if (!TestHelper.VerifyWithSerialize(arr, json)) + if (arr == null) { return -1; } @@ -34,8 +34,8 @@ static async Task Main(string[] args) using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { - MyStruct obj = (MyStruct)(await JsonSerializer.DeserializeAsync(stream, typeof(MyStruct))); - if (!TestHelper.VerifyWithSerialize(obj, json)) + var obj = (MyClassWithParameterizedCtor)(await JsonSerializer.DeserializeAsync(stream, typeof(MyClassWithParameterizedCtor))); + if (obj == null) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs index 93a224beafc3f4..e5526501e84d8c 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs @@ -23,7 +23,7 @@ static async Task Main(string[] args) using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { int[] arr = (int[])(await JsonSerializer.DeserializeAsync(stream)); - if (!TestHelper.VerifyWithSerialize(arr, json)) + if (arr == null) { return -1; } @@ -32,8 +32,8 @@ static async Task Main(string[] args) json = @"{""X"":1,""Y"":2}"; using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { - MyStruct obj = (MyStruct)(await JsonSerializer.DeserializeAsync(stream)); - if (!TestHelper.VerifyWithSerialize(obj, json)) + var obj = (MyClassWithParameterizedCtor)(await JsonSerializer.DeserializeAsync(stream)); + if (obj == null) { return -1; } From 1b67842f8e9b4996b949f816f20221bfbbd76b36 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Mon, 6 Jul 2020 11:45:26 -0700 Subject: [PATCH 10/10] Verify collection deserialization is correct --- .../SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs | 2 +- .../SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs | 2 +- .../SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs | 2 +- .../SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs | 2 +- .../SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs | 2 +- .../SerializerEntryPoint/Deserialize.FromString.TypedObject.cs | 2 +- .../DeserializeAsync.FromStream.BoxedObject.cs | 2 +- .../DeserializeAsync.FromStream.TypedObject.cs | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs index fba446c89fbb2e..4f435e60da05ce 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.BoxedObject.cs @@ -20,7 +20,7 @@ static int Main(string[] args) string json = "[1]"; Utf8JsonReader reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); int[] arr = (int[])JsonSerializer.Deserialize(ref reader, typeof(int[])); - if (arr == null) + if (arr == null || arr.Length != 1 || arr[0] != 1) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs index 732f69646cb510..5b4c08ea88757a 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromReader.TypedObject.cs @@ -20,7 +20,7 @@ static int Main(string[] args) string json = "[1]"; Utf8JsonReader reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); int[] arr = JsonSerializer.Deserialize(ref reader); - if (arr == null) + if (arr == null || arr.Length != 1 || arr[0] != 1) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs index 9141072fcc69ef..2c849e49703aa5 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.BoxedObject.cs @@ -19,7 +19,7 @@ static int Main(string[] args) { string json = "[1]"; int[] arr = (int[])JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json), typeof(int[])); - if (arr == null) + if (arr == null || arr.Length != 1 || arr[0] != 1) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs index 87509765af0920..cf2ec8bd0f64f5 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromSpan.TypedObject.cs @@ -19,7 +19,7 @@ static int Main(string[] args) { string json = "[1]"; int[] arr = JsonSerializer.Deserialize(Encoding.UTF8.GetBytes(json)); - if (arr == null) + if (arr == null || arr.Length != 1 || arr[0] != 1) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs index 54da5b41402643..6223ca80dc7438 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.BoxedObject.cs @@ -18,7 +18,7 @@ static int Main(string[] args) { string json = "[1]"; int[] arr = (int[])JsonSerializer.Deserialize(json, typeof(int[])); - if (arr == null) + if (arr == null || arr.Length != 1 || arr[0] != 1) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs index fcc79df3147fec..997959d006945a 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/Deserialize.FromString.TypedObject.cs @@ -18,7 +18,7 @@ static int Main(string[] args) { string json = "[1]"; int[] arr = JsonSerializer.Deserialize(json); - if (arr == null) + if (arr == null || arr.Length != 1 || arr[0] != 1) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs index 97d23d9d1a421a..07825653353c7e 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.BoxedObject.cs @@ -24,7 +24,7 @@ static async Task Main(string[] args) using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { int[] arr = (int[])(await JsonSerializer.DeserializeAsync(stream, typeof(int[]))); - if (arr == null) + if (arr == null || arr.Length != 1 || arr[0] != 1) { return -1; } diff --git a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs index e5526501e84d8c..7222ffb2600f91 100644 --- a/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs +++ b/src/libraries/System.Text.Json/tests/TrimmingTests/SerializerEntryPoint/DeserializeAsync.FromStream.TypedObject.cs @@ -23,7 +23,7 @@ static async Task Main(string[] args) using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) { int[] arr = (int[])(await JsonSerializer.DeserializeAsync(stream)); - if (arr == null) + if (arr == null || arr.Length != 1 || arr[0] != 1) { return -1; }