From 56b3720f03fc5eb62f871b1da8bd39043e1ae46e Mon Sep 17 00:00:00 2001 From: Luiz Strobelt Date: Sun, 10 Oct 2021 18:47:42 -0300 Subject: [PATCH 1/6] Add API entry for JsonDocument converter --- .../Serialization/JsonSerializerOptions.Converters.cs | 2 +- .../Metadata/JsonMetadataServices.Converters.cs | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs index f79659f8d91f85..e21e7cb648ed80 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs @@ -112,7 +112,7 @@ private static Dictionary GetDefaultSimpleConverters() Add(JsonMetadataServices.Int32Converter); Add(JsonMetadataServices.Int64Converter); Add(new JsonElementConverter()); - Add(new JsonDocumentConverter()); + Add(JsonMetadataServices.DocumentConverter); Add(JsonMetadataServices.ObjectConverter); Add(JsonMetadataServices.SByteConverter); Add(JsonMetadataServices.SingleConverter); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Converters.cs index 7a2536650553c4..b20151e1000b59 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Converters.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Converters.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Collections.Generic; using System.Text.Json.Nodes; using System.Text.Json.Serialization.Converters; @@ -202,6 +201,13 @@ public static partial class JsonMetadataServices public static JsonConverter VersionConverter => s_versionConverter ??= new VersionConverter(); private static JsonConverter? s_versionConverter; + /// + /// Returns a instance that converts values. + /// + /// This API is for use by the output of the System.Text.Json source generator and should not be called directly. + public static JsonConverter DocumentConverter => s_documentConverter ??= new JsonDocumentConverter(); + private static JsonConverter? s_documentConverter; + /// /// Creates a instance that throws . /// From 857693feafda05e83e55968ce9dc7fbb4222b907 Mon Sep 17 00:00:00 2001 From: Luiz Strobelt Date: Sun, 10 Oct 2021 19:34:24 -0300 Subject: [PATCH 2/6] Add reference to System.Text.Json --- src/libraries/System.Text.Json/ref/System.Text.Json.cs | 1 + 1 file changed, 1 insertion(+) 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 874d8789c7886d..3a4c2858767f09 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -1040,6 +1040,7 @@ public static partial class JsonMetadataServices public static System.Text.Json.Serialization.JsonConverter UInt64Converter { get { throw null; } } public static System.Text.Json.Serialization.JsonConverter UriConverter { get { throw null; } } public static System.Text.Json.Serialization.JsonConverter VersionConverter { get { throw null; } } + public static System.Text.Json.Serialization.JsonConverter DocumentConverter { get { throw null; } } public static System.Text.Json.Serialization.Metadata.JsonTypeInfo CreateArrayInfo(System.Text.Json.JsonSerializerOptions options, System.Text.Json.Serialization.Metadata.JsonCollectionInfoValues collectionInfo) { throw null; } public static System.Text.Json.Serialization.Metadata.JsonTypeInfo CreateConcurrentQueueInfo(System.Text.Json.JsonSerializerOptions options, System.Text.Json.Serialization.Metadata.JsonCollectionInfoValues collectionInfo) where TCollection : System.Collections.Concurrent.ConcurrentQueue { throw null; } public static System.Text.Json.Serialization.Metadata.JsonTypeInfo CreateConcurrentStackInfo(System.Text.Json.JsonSerializerOptions options, System.Text.Json.Serialization.Metadata.JsonCollectionInfoValues collectionInfo) where TCollection : System.Collections.Concurrent.ConcurrentStack { throw null; } From 3408c931692a59a6f688f1b0b255d1ee61e9cf55 Mon Sep 17 00:00:00 2001 From: Luiz Strobelt Date: Mon, 11 Oct 2021 22:44:12 -0300 Subject: [PATCH 3/6] Add JsonElementConverter from MetadataServices --- .../Text/Json/Serialization/JsonSerializerOptions.Converters.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs index e21e7cb648ed80..b2c761b6319137 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs @@ -111,7 +111,7 @@ private static Dictionary GetDefaultSimpleConverters() Add(JsonMetadataServices.Int16Converter); Add(JsonMetadataServices.Int32Converter); Add(JsonMetadataServices.Int64Converter); - Add(new JsonElementConverter()); + Add(JsonMetadataServices.JsonElementConverter); Add(JsonMetadataServices.DocumentConverter); Add(JsonMetadataServices.ObjectConverter); Add(JsonMetadataServices.SByteConverter); From 13975b47a385eee91f2d16a942e6150d2dd0b0f6 Mon Sep 17 00:00:00 2001 From: Luiz Strobelt Date: Mon, 11 Oct 2021 22:51:51 -0300 Subject: [PATCH 4/6] Correct converter naming --- .../System.Text.Json/ref/System.Text.Json.cs | 2 +- .../JsonSerializerOptions.Converters.cs | 2 +- .../Metadata/JsonMetadataServices.Converters.cs | 14 +++++++------- 3 files changed, 9 insertions(+), 9 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 3a4c2858767f09..6dd9befb4893ce 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -1026,6 +1026,7 @@ public static partial class JsonMetadataServices public static System.Text.Json.Serialization.JsonConverter JsonNodeConverter { get { throw null; } } public static System.Text.Json.Serialization.JsonConverter JsonObjectConverter { get { throw null; } } public static System.Text.Json.Serialization.JsonConverter JsonValueConverter { get { throw null; } } + public static System.Text.Json.Serialization.JsonConverter JsonDocumentConverter { get { throw null; } } public static System.Text.Json.Serialization.JsonConverter ObjectConverter { get { throw null; } } [System.CLSCompliantAttribute(false)] public static System.Text.Json.Serialization.JsonConverter SByteConverter { get { throw null; } } @@ -1040,7 +1041,6 @@ public static partial class JsonMetadataServices public static System.Text.Json.Serialization.JsonConverter UInt64Converter { get { throw null; } } public static System.Text.Json.Serialization.JsonConverter UriConverter { get { throw null; } } public static System.Text.Json.Serialization.JsonConverter VersionConverter { get { throw null; } } - public static System.Text.Json.Serialization.JsonConverter DocumentConverter { get { throw null; } } public static System.Text.Json.Serialization.Metadata.JsonTypeInfo CreateArrayInfo(System.Text.Json.JsonSerializerOptions options, System.Text.Json.Serialization.Metadata.JsonCollectionInfoValues collectionInfo) { throw null; } public static System.Text.Json.Serialization.Metadata.JsonTypeInfo CreateConcurrentQueueInfo(System.Text.Json.JsonSerializerOptions options, System.Text.Json.Serialization.Metadata.JsonCollectionInfoValues collectionInfo) where TCollection : System.Collections.Concurrent.ConcurrentQueue { throw null; } public static System.Text.Json.Serialization.Metadata.JsonTypeInfo CreateConcurrentStackInfo(System.Text.Json.JsonSerializerOptions options, System.Text.Json.Serialization.Metadata.JsonCollectionInfoValues collectionInfo) where TCollection : System.Collections.Concurrent.ConcurrentStack { throw null; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs index b2c761b6319137..829ceeeb09213a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs @@ -112,7 +112,7 @@ private static Dictionary GetDefaultSimpleConverters() Add(JsonMetadataServices.Int32Converter); Add(JsonMetadataServices.Int64Converter); Add(JsonMetadataServices.JsonElementConverter); - Add(JsonMetadataServices.DocumentConverter); + Add(JsonMetadataServices.JsonDocumentConverter); Add(JsonMetadataServices.ObjectConverter); Add(JsonMetadataServices.SByteConverter); Add(JsonMetadataServices.SingleConverter); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Converters.cs index b20151e1000b59..8bb7c29aec7561 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Converters.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonMetadataServices.Converters.cs @@ -127,6 +127,13 @@ public static partial class JsonMetadataServices public static JsonConverter JsonValueConverter => s_jsonValueConverter ??= new JsonValueConverter(); private static JsonConverter? s_jsonValueConverter; + /// + /// Returns a instance that converts values. + /// + /// This API is for use by the output of the System.Text.Json source generator and should not be called directly. + public static JsonConverter JsonDocumentConverter => s_jsonDocumentConverter ??= new JsonDocumentConverter(); + private static JsonConverter? s_jsonDocumentConverter; + /// /// Returns a instance that converts values. /// @@ -201,13 +208,6 @@ public static partial class JsonMetadataServices public static JsonConverter VersionConverter => s_versionConverter ??= new VersionConverter(); private static JsonConverter? s_versionConverter; - /// - /// Returns a instance that converts values. - /// - /// This API is for use by the output of the System.Text.Json source generator and should not be called directly. - public static JsonConverter DocumentConverter => s_documentConverter ??= new JsonDocumentConverter(); - private static JsonConverter? s_documentConverter; - /// /// Creates a instance that throws . /// From 8f09f7c7987a923f711ce61c2bf9a41bcacc6cb5 Mon Sep 17 00:00:00 2001 From: Luiz Strobelt Date: Mon, 11 Oct 2021 23:05:32 -0300 Subject: [PATCH 5/6] Add JsonDocument type to source generation --- .../System.Text.Json/gen/JsonSourceGenerator.Parser.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs index dcf508fc90c825..4473dec387236e 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs @@ -34,6 +34,7 @@ private sealed class Parser private const string JsonNodeFullName = "System.Text.Json.Nodes.JsonNode"; private const string JsonObjectFullName = "System.Text.Json.Nodes.JsonObject"; private const string JsonValueFullName = "System.Text.Json.Nodes.JsonValue"; + private const string JsonDocumentFullName = "System.Text.Json.JsonDocument"; private const string JsonIgnoreAttributeFullName = "System.Text.Json.Serialization.JsonIgnoreAttribute"; private const string JsonIgnoreConditionFullName = "System.Text.Json.Serialization.JsonIgnoreCondition"; private const string JsonIncludeAttributeFullName = "System.Text.Json.Serialization.JsonIncludeAttribute"; @@ -92,6 +93,7 @@ private sealed class Parser private readonly Type? _jsonNodeType; private readonly Type? _jsonObjectType; private readonly Type? _jsonValueType; + private readonly Type? _jsonDocumentType; // Unsupported types private readonly Type _delegateType; @@ -229,6 +231,7 @@ public Parser(Compilation compilation, in JsonSourceGenerationContext sourceGene _jsonNodeType = _metadataLoadContext.Resolve(JsonNodeFullName); _jsonObjectType = _metadataLoadContext.Resolve(JsonObjectFullName); _jsonValueType = _metadataLoadContext.Resolve(JsonValueFullName); + _jsonDocumentType = _metadataLoadContext.Resolve(JsonDocumentFullName); // Unsupported types. _delegateType = _metadataLoadContext.Resolve(SpecialType.System_Delegate); @@ -1556,6 +1559,7 @@ private void PopulateKnownTypes() AddTypeIfNotNull(_knownTypes, _jsonNodeType); AddTypeIfNotNull(_knownTypes, _jsonObjectType); AddTypeIfNotNull(_knownTypes, _jsonValueType); + AddTypeIfNotNull(_knownTypes, _jsonDocumentType); _knownUnsupportedTypes.Add(_typeType); _knownUnsupportedTypes.Add(_serializationInfoType); From 9acc45db2ff00d888b8c8913206733f03ccc3b21 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Wed, 20 Apr 2022 16:11:32 +0100 Subject: [PATCH 6/6] include testing --- .../tests/Common/JsonTestHelper.cs | 13 ++++--- .../ContextClasses.cs | 2 ++ .../MetadataAndSerializationContextTests.cs | 5 +++ .../MetadataContextTests.cs | 10 ++++++ .../MixedModeContextTests.cs | 5 +++ .../RealWorldContextTests.cs | 34 +++++++++++++++++++ .../SerializationContextTests.cs | 12 +++++++ 7 files changed, 77 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Text.Json/tests/Common/JsonTestHelper.cs b/src/libraries/System.Text.Json/tests/Common/JsonTestHelper.cs index 45c3428b498092..56656e180530de 100644 --- a/src/libraries/System.Text.Json/tests/Common/JsonTestHelper.cs +++ b/src/libraries/System.Text.Json/tests/Common/JsonTestHelper.cs @@ -18,10 +18,15 @@ public static void AssertJsonEqual(string expected, string actual) { using JsonDocument expectedDom = JsonDocument.Parse(expected); using JsonDocument actualDom = JsonDocument.Parse(actual); - AssertJsonEqual(expectedDom.RootElement, actualDom.RootElement, new()); + AssertJsonEqual(expectedDom.RootElement, actualDom.RootElement); } - private static void AssertJsonEqual(JsonElement expected, JsonElement actual, Stack path) + public static void AssertJsonEqual(JsonElement expected, JsonElement actual) + { + AssertJsonEqualCore(expected, actual, new()); + } + + private static void AssertJsonEqualCore(JsonElement expected, JsonElement actual, Stack path) { JsonValueKind valueKind = expected.ValueKind; AssertTrue(passCondition: valueKind == actual.ValueKind); @@ -54,7 +59,7 @@ private static void AssertJsonEqual(JsonElement expected, JsonElement actual, St foreach (string name in expectedProperties) { path.Push(name); - AssertJsonEqual(expected.GetProperty(name), actual.GetProperty(name), path); + AssertJsonEqualCore(expected.GetProperty(name), actual.GetProperty(name), path); path.Pop(); } break; @@ -67,7 +72,7 @@ private static void AssertJsonEqual(JsonElement expected, JsonElement actual, St { AssertTrue(passCondition: actualEnumerator.MoveNext(), "Actual array contains fewer elements."); path.Push(i++); - AssertJsonEqual(expectedEnumerator.Current, actualEnumerator.Current, path); + AssertJsonEqualCore(expectedEnumerator.Current, actualEnumerator.Current, path); path.Pop(); } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs index 49c4ac299e3b22..496fd2968053ba 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/ContextClasses.cs @@ -34,6 +34,8 @@ public interface ITestContext public JsonTypeInfo ByteArray { get; } public JsonTypeInfo String { get; } public JsonTypeInfo<(string Label1, int Label2, bool)> ValueTupleStringInt32Boolean { get; } + public JsonTypeInfo JsonDocument { get; } + public JsonTypeInfo JsonElement { get; } public JsonTypeInfo ClassWithEnumAndNullable { get; } public JsonTypeInfo ClassWithNullableProperties { get; } public JsonTypeInfo ClassWithCustomConverter { get; } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs index 802023061e1965..077e9e65edfe50 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataAndSerializationContextTests.cs @@ -30,6 +30,8 @@ namespace System.Text.Json.SourceGeneration.Tests [JsonSerializable(typeof(object[]))] [JsonSerializable(typeof(string))] [JsonSerializable(typeof((string Label1, int Label2, bool)))] + [JsonSerializable(typeof(JsonDocument))] + [JsonSerializable(typeof(JsonElement))] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable))] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties))] [JsonSerializable(typeof(ClassWithCustomConverter))] @@ -81,6 +83,8 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Null(MetadataAndSerializationContext.Default.SampleEnum.SerializeHandler); Assert.Null(MetadataAndSerializationContext.Default.String.SerializeHandler); Assert.NotNull(MetadataAndSerializationContext.Default.ValueTupleStringInt32Boolean.SerializeHandler); + Assert.Null(MetadataAndSerializationContext.Default.JsonDocument.SerializeHandler); + Assert.Null(MetadataAndSerializationContext.Default.JsonElement.SerializeHandler); Assert.NotNull(MetadataAndSerializationContext.Default.ClassWithEnumAndNullable.SerializeHandler); Assert.NotNull(MetadataAndSerializationContext.Default.ClassWithNullableProperties.SerializeHandler); Assert.NotNull(MetadataAndSerializationContext.Default.ClassWithCustomConverter); @@ -97,6 +101,7 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.NotNull(MetadataAndSerializationContext.Default.PersonStruct.SerializeHandler); Assert.NotNull(MetadataAndSerializationContext.Default.TypeWithValidationAttributes.SerializeHandler); Assert.NotNull(MetadataAndSerializationContext.Default.TypeWithDerivedAttribute.SerializeHandler); + Assert.Null(MetadataAndSerializationContext.Default.PolymorphicClass.SerializeHandler); } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs index b4d0c08a2cc802..daea2f1b8bcd55 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MetadataContextTests.cs @@ -29,6 +29,8 @@ namespace System.Text.Json.SourceGeneration.Tests [JsonSerializable(typeof(byte[]), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(string), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof((string Label1, int Label2, bool)), GenerationMode = JsonSourceGenerationMode.Metadata)] + [JsonSerializable(typeof(JsonDocument), GenerationMode = JsonSourceGenerationMode.Metadata)] + [JsonSerializable(typeof(JsonElement), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(ClassWithCustomConverter), GenerationMode = JsonSourceGenerationMode.Metadata)] @@ -79,6 +81,8 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Null(MetadataWithPerTypeAttributeContext.Default.SampleEnum.SerializeHandler); Assert.Null(MetadataWithPerTypeAttributeContext.Default.String.SerializeHandler); Assert.Null(MetadataWithPerTypeAttributeContext.Default.ValueTupleStringInt32Boolean.SerializeHandler); + Assert.Null(MetadataWithPerTypeAttributeContext.Default.JsonDocument.SerializeHandler); + Assert.Null(MetadataWithPerTypeAttributeContext.Default.JsonElement.SerializeHandler); Assert.Null(MetadataWithPerTypeAttributeContext.Default.ClassWithEnumAndNullable.SerializeHandler); Assert.Null(MetadataWithPerTypeAttributeContext.Default.ClassWithNullableProperties.SerializeHandler); Assert.Null(MetadataWithPerTypeAttributeContext.Default.ClassWithCustomConverter.SerializeHandler); @@ -95,6 +99,7 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Null(MetadataWithPerTypeAttributeContext.Default.PersonStruct.SerializeHandler); Assert.Null(MetadataWithPerTypeAttributeContext.Default.TypeWithValidationAttributes.SerializeHandler); Assert.Null(MetadataWithPerTypeAttributeContext.Default.TypeWithDerivedAttribute.SerializeHandler); + Assert.Null(MetadataWithPerTypeAttributeContext.Default.PolymorphicClass.SerializeHandler); } } @@ -121,6 +126,8 @@ public override void EnsureFastPathGeneratedAsExpected() [JsonSerializable(typeof(byte[]))] [JsonSerializable(typeof(string))] [JsonSerializable(typeof((string Label1, int Label2, bool)))] + [JsonSerializable(typeof(JsonDocument))] + [JsonSerializable(typeof(JsonElement))] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable))] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties))] [JsonSerializable(typeof(ClassWithCustomConverter))] @@ -194,6 +201,8 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Null(MetadataContext.Default.SampleEnum.SerializeHandler); Assert.Null(MetadataContext.Default.String.SerializeHandler); Assert.Null(MetadataContext.Default.ValueTupleStringInt32Boolean.SerializeHandler); + Assert.Null(MetadataContext.Default.JsonDocument.SerializeHandler); + Assert.Null(MetadataContext.Default.JsonElement.SerializeHandler); Assert.Null(MetadataContext.Default.ClassWithEnumAndNullable.SerializeHandler); Assert.Null(MetadataContext.Default.ClassWithNullableProperties.SerializeHandler); Assert.Null(MetadataContext.Default.ClassWithCustomConverter.SerializeHandler); @@ -210,6 +219,7 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Null(MetadataContext.Default.PersonStruct.SerializeHandler); Assert.Null(MetadataContext.Default.TypeWithValidationAttributes.SerializeHandler); Assert.Null(MetadataContext.Default.TypeWithDerivedAttribute.SerializeHandler); + Assert.Null(MetadataContext.Default.PolymorphicClass.SerializeHandler); } [Fact] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs index f872099b5483dd..d1cacf7e35e0c0 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/MixedModeContextTests.cs @@ -30,6 +30,8 @@ namespace System.Text.Json.SourceGeneration.Tests [JsonSerializable(typeof(byte[]), GenerationMode = JsonSourceGenerationMode.Metadata)] [JsonSerializable(typeof(string), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof((string Label1, int Label2, bool)), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] + [JsonSerializable(typeof(JsonDocument), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] + [JsonSerializable(typeof(JsonElement), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(ClassWithCustomConverter), GenerationMode = JsonSourceGenerationMode.Metadata | JsonSourceGenerationMode.Serialization)] @@ -81,6 +83,8 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Null(MixedModeContext.Default.SampleEnum.SerializeHandler); Assert.Null(MixedModeContext.Default.String.SerializeHandler); Assert.NotNull(MixedModeContext.Default.ValueTupleStringInt32Boolean.SerializeHandler); + Assert.Null(MixedModeContext.Default.JsonDocument.SerializeHandler); + Assert.Null(MixedModeContext.Default.JsonElement.SerializeHandler); Assert.NotNull(MixedModeContext.Default.ClassWithEnumAndNullable.SerializeHandler); Assert.NotNull(MixedModeContext.Default.ClassWithNullableProperties.SerializeHandler); Assert.Null(MixedModeContext.Default.ClassWithCustomConverter.SerializeHandler); @@ -97,6 +101,7 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.NotNull(MixedModeContext.Default.PersonStruct.SerializeHandler); Assert.NotNull(MixedModeContext.Default.TypeWithValidationAttributes.SerializeHandler); Assert.NotNull(MixedModeContext.Default.TypeWithDerivedAttribute.SerializeHandler); + Assert.Null(MixedModeContext.Default.PolymorphicClass.SerializeHandler); } [Fact] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs index 6506f9427be6b3..6ce888280d9971 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs @@ -111,6 +111,40 @@ public virtual void RoundTripTypeNameClash() VerifyRepeatedLocation(expected, obj); } + [Theory] + [InlineData("0")] + [InlineData("false")] + [InlineData("\"str\"")] + [InlineData("[1,2,3]")] + [InlineData("{ \"key\" : \"value\" }")] + public void RoundtripJsonDocument(string json) + { + JsonDocument jsonDocument = JsonDocument.Parse(json); + + string actualJson = JsonSerializer.Serialize(jsonDocument, DefaultContext.JsonDocument); + JsonTestHelper.AssertJsonEqual(json, actualJson); + + JsonDocument actualJsonDocument = JsonSerializer.Deserialize(actualJson, DefaultContext.JsonDocument); + JsonTestHelper.AssertJsonEqual(jsonDocument.RootElement, actualJsonDocument.RootElement); + } + + [Theory] + [InlineData("0")] + [InlineData("false")] + [InlineData("\"str\"")] + [InlineData("[1,2,3]")] + [InlineData("{ \"key\" : \"value\" }")] + public void RoundtripJsonElement(string json) + { + JsonElement jsonElement = JsonDocument.Parse(json).RootElement; + + string actualJson = JsonSerializer.Serialize(jsonElement, DefaultContext.JsonElement); + JsonTestHelper.AssertJsonEqual(json, actualJson); + + JsonElement actualJsonElement = JsonSerializer.Deserialize(actualJson, DefaultContext.JsonElement); + JsonTestHelper.AssertJsonEqual(jsonElement, actualJsonElement); + } + [Fact] public virtual void RoundTripValueTuple() { diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs index f20b85b33eff08..c8b8f0f802e900 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/SerializationContextTests.cs @@ -30,6 +30,8 @@ namespace System.Text.Json.SourceGeneration.Tests [JsonSerializable(typeof(byte[]))] [JsonSerializable(typeof(string))] [JsonSerializable(typeof((string Label1, int Label2, bool)))] + [JsonSerializable(typeof(JsonDocument))] + [JsonSerializable(typeof(JsonElement))] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable))] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties))] [JsonSerializable(typeof(ClassWithCustomConverter))] @@ -74,6 +76,8 @@ internal partial class SerializationContext : JsonSerializerContext, ITestContex [JsonSerializable(typeof(byte[]), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(string), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof((string Label1, int Label2, bool)), GenerationMode = JsonSourceGenerationMode.Serialization)] + [JsonSerializable(typeof(JsonDocument), GenerationMode = JsonSourceGenerationMode.Serialization)] + [JsonSerializable(typeof(JsonElement), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(ClassWithCustomConverter), GenerationMode = JsonSourceGenerationMode.Serialization)] @@ -119,6 +123,8 @@ internal partial class SerializationWithPerTypeAttributeContext : JsonSerializer [JsonSerializable(typeof(byte[]), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(string), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof((string Label1, int Label2, bool)), GenerationMode = JsonSourceGenerationMode.Serialization)] + [JsonSerializable(typeof(JsonDocument), GenerationMode = JsonSourceGenerationMode.Serialization)] + [JsonSerializable(typeof(JsonElement), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithEnumAndNullable), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(RealWorldContextTests.ClassWithNullableProperties), GenerationMode = JsonSourceGenerationMode.Serialization)] [JsonSerializable(typeof(ClassWithCustomConverter), GenerationMode = JsonSourceGenerationMode.Serialization)] @@ -175,6 +181,8 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Null(SerializationContext.Default.ByteArray.SerializeHandler); Assert.Null(SerializationContext.Default.String.SerializeHandler); Assert.NotNull(SerializationContext.Default.ValueTupleStringInt32Boolean.SerializeHandler); + Assert.Null(SerializationContext.Default.JsonDocument.SerializeHandler); + Assert.Null(SerializationContext.Default.JsonElement.SerializeHandler); Assert.NotNull(SerializationContext.Default.ClassWithEnumAndNullable.SerializeHandler); Assert.Null(SerializationContext.Default.ClassWithCustomConverter.SerializeHandler); Assert.Null(SerializationContext.Default.StructWithCustomConverter.SerializeHandler); @@ -188,6 +196,7 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.NotNull(SerializationContext.Default.PersonStruct.SerializeHandler); Assert.NotNull(SerializationContext.Default.TypeWithValidationAttributes.SerializeHandler); Assert.NotNull(SerializationContext.Default.TypeWithDerivedAttribute.SerializeHandler); + Assert.Null(SerializationContext.Default.PolymorphicClass.SerializeHandler); } [Fact] @@ -511,6 +520,8 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.Null(SerializationWithPerTypeAttributeContext.Default.SampleEnum.SerializeHandler); Assert.Null(SerializationWithPerTypeAttributeContext.Default.String.SerializeHandler); Assert.NotNull(SerializationWithPerTypeAttributeContext.Default.ValueTupleStringInt32Boolean.SerializeHandler); + Assert.Null(SerializationWithPerTypeAttributeContext.Default.JsonDocument.SerializeHandler); + Assert.Null(SerializationWithPerTypeAttributeContext.Default.JsonElement.SerializeHandler); Assert.NotNull(SerializationWithPerTypeAttributeContext.Default.ClassWithEnumAndNullable.SerializeHandler); Assert.Null(SerializationWithPerTypeAttributeContext.Default.ClassWithCustomConverter.SerializeHandler); Assert.Null(SerializationWithPerTypeAttributeContext.Default.StructWithCustomConverter.SerializeHandler); @@ -526,6 +537,7 @@ public override void EnsureFastPathGeneratedAsExpected() Assert.NotNull(SerializationWithPerTypeAttributeContext.Default.PersonStruct.SerializeHandler); Assert.NotNull(SerializationWithPerTypeAttributeContext.Default.TypeWithValidationAttributes.SerializeHandler); Assert.NotNull(SerializationWithPerTypeAttributeContext.Default.TypeWithDerivedAttribute.SerializeHandler); + Assert.Null(SerializationWithPerTypeAttributeContext.Default.PolymorphicClass.SerializeHandler); } } }