From cd1731aac1007f848b34504b13822a9cd1895ea2 Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Tue, 28 Nov 2023 18:19:22 +0000 Subject: [PATCH] Add regression testing for the v8 source generator. --- ...ratedContext.ClassWithCustomConverter.g.cs | 42 ++++ .../Net80GeneratedContext.DateTimeOffset.g.cs | 41 ++++ ...dContext.DictionaryStringHighLowTemps.g.cs | 69 ++++++ ...Net80GeneratedContext.GetJsonTypeInfo.g.cs | 72 ++++++ .../Net80GeneratedContext.HighLowTemps.g.cs | 114 +++++++++ .../Net80/Net80GeneratedContext.Int32.g.cs | 41 ++++ ...80GeneratedContext.ListDateTimeOffset.g.cs | 68 ++++++ .../Net80GeneratedContext.MyLinkedList.g.cs | 140 ++++++++++++ .../Net80GeneratedContext.PropertyNames.g.cs | 31 +++ .../Net80/Net80GeneratedContext.String.g.cs | 41 ++++ .../Net80GeneratedContext.StringArray.g.cs | 68 ++++++ ...ratedContext.WeatherForecastWithPOCOs.g.cs | 216 ++++++++++++++++++ .../Net80/Net80GeneratedContext.cs | 61 +++++ .../Net80/Net80GeneratedContext.g.cs | 89 ++++++++ .../Net80RegressionTests.cs | 177 ++++++++++++++ .../System.Text.Json.Tests.csproj | 15 ++ 16 files changed, 1285 insertions(+) create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.ClassWithCustomConverter.g.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.DateTimeOffset.g.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.DictionaryStringHighLowTemps.g.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.GetJsonTypeInfo.g.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.HighLowTemps.g.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.Int32.g.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.ListDateTimeOffset.g.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.MyLinkedList.g.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.PropertyNames.g.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.String.g.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.StringArray.g.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.WeatherForecastWithPOCOs.g.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.g.cs create mode 100644 src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80RegressionTests.cs diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.ClassWithCustomConverter.g.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.ClassWithCustomConverter.g.cs new file mode 100644 index 0000000000000..2f2466fd80a0f --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.ClassWithCustomConverter.g.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + public partial class Net80GeneratedContext + { + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo? _ClassWithCustomConverter; + + /// + /// Defines the source generated JSON serialization contract metadata for a given type. + /// + public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo ClassWithCustomConverter + { + get => _ClassWithCustomConverter ??= (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)Options.GetTypeInfo(typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.ClassWithCustomConverter)); + } + + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo Create_ClassWithCustomConverter(global::System.Text.Json.JsonSerializerOptions options) + { + if (!TryGetTypeInfoForRuntimeCustomConverter(options, out global::System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo)) + { + global::System.Text.Json.Serialization.JsonConverter converter = ExpandConverter(typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.ClassWithCustomConverter), new global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.ClassWithCustomConverter.CustomConverter(), options); + jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateValueInfo (options, converter); + } + + jsonTypeInfo.OriginatingResolver = this; + return jsonTypeInfo; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.DateTimeOffset.g.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.DateTimeOffset.g.cs new file mode 100644 index 0000000000000..6630ccf006874 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.DateTimeOffset.g.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + public partial class Net80GeneratedContext + { + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo? _DateTimeOffset; + + /// + /// Defines the source generated JSON serialization contract metadata for a given type. + /// + public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo DateTimeOffset + { + get => _DateTimeOffset ??= (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)Options.GetTypeInfo(typeof(global::System.DateTimeOffset)); + } + + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo Create_DateTimeOffset(global::System.Text.Json.JsonSerializerOptions options) + { + if (!TryGetTypeInfoForRuntimeCustomConverter(options, out global::System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo)) + { + jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateValueInfo(options, global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.DateTimeOffsetConverter); + } + + jsonTypeInfo.OriginatingResolver = this; + return jsonTypeInfo; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.DictionaryStringHighLowTemps.g.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.DictionaryStringHighLowTemps.g.cs new file mode 100644 index 0000000000000..bee463c2eef2d --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.DictionaryStringHighLowTemps.g.cs @@ -0,0 +1,69 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + public partial class Net80GeneratedContext + { + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo>? _DictionaryStringHighLowTemps; + + /// + /// Defines the source generated JSON serialization contract metadata for a given type. + /// + public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo> DictionaryStringHighLowTemps + { + get => _DictionaryStringHighLowTemps ??= (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo>)Options.GetTypeInfo(typeof(global::System.Collections.Generic.Dictionary)); + } + + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo> Create_DictionaryStringHighLowTemps(global::System.Text.Json.JsonSerializerOptions options) + { + if (!TryGetTypeInfoForRuntimeCustomConverter>(options, out global::System.Text.Json.Serialization.Metadata.JsonTypeInfo> jsonTypeInfo)) + { + var info = new global::System.Text.Json.Serialization.Metadata.JsonCollectionInfoValues> + { + ObjectCreator = () => new global::System.Collections.Generic.Dictionary(), + SerializeHandler = DictionaryStringHighLowTempsSerializeHandler + }; + + jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateDictionaryInfo, string, global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps>(options, info); + jsonTypeInfo.NumberHandling = null; + } + + jsonTypeInfo.OriginatingResolver = this; + return jsonTypeInfo; + } + + // Intentionally not a static method because we create a delegate to it. Invoking delegates to instance + // methods is almost as fast as virtual calls. Static methods need to go through a shuffle thunk. + private void DictionaryStringHighLowTempsSerializeHandler(global::System.Text.Json.Utf8JsonWriter writer, global::System.Collections.Generic.Dictionary? value) + { + if (value == null) + { + writer.WriteNullValue(); + return; + } + + writer.WriteStartObject(); + + foreach (global::System.Collections.Generic.KeyValuePair entry in value) + { + writer.WritePropertyName(entry.Key); + HighLowTempsSerializeHandler(writer, entry.Value); + } + + writer.WriteEndObject(); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.GetJsonTypeInfo.g.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.GetJsonTypeInfo.g.cs new file mode 100644 index 0000000000000..2d75f2b2e6a82 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.GetJsonTypeInfo.g.cs @@ -0,0 +1,72 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + public partial class Net80GeneratedContext : global::System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver + { + /// + public override global::System.Text.Json.Serialization.Metadata.JsonTypeInfo? GetTypeInfo(global::System.Type type) + { + Options.TryGetTypeInfo(type, out global::System.Text.Json.Serialization.Metadata.JsonTypeInfo? typeInfo); + return typeInfo; + } + + global::System.Text.Json.Serialization.Metadata.JsonTypeInfo? global::System.Text.Json.Serialization.Metadata.IJsonTypeInfoResolver.GetTypeInfo(global::System.Type type, global::System.Text.Json.JsonSerializerOptions options) + { + if (type == typeof(global::System.Collections.Generic.Dictionary)) + { + return Create_DictionaryStringHighLowTemps(options); + } + if (type == typeof(global::System.Collections.Generic.List)) + { + return Create_ListDateTimeOffset(options); + } + if (type == typeof(global::System.DateTimeOffset)) + { + return Create_DateTimeOffset(options); + } + if (type == typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.ClassWithCustomConverter)) + { + return Create_ClassWithCustomConverter(options); + } + if (type == typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps)) + { + return Create_HighLowTemps(options); + } + if (type == typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList)) + { + return Create_MyLinkedList(options); + } + if (type == typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)) + { + return Create_WeatherForecastWithPOCOs(options); + } + if (type == typeof(int)) + { + return Create_Int32(options); + } + if (type == typeof(string)) + { + return Create_String(options); + } + if (type == typeof(string[])) + { + return Create_StringArray(options); + } + return null; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.HighLowTemps.g.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.HighLowTemps.g.cs new file mode 100644 index 0000000000000..48ab885cd41a0 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.HighLowTemps.g.cs @@ -0,0 +1,114 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + public partial class Net80GeneratedContext + { + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo? _HighLowTemps; + + /// + /// Defines the source generated JSON serialization contract metadata for a given type. + /// + public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo HighLowTemps + { + get => _HighLowTemps ??= (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)Options.GetTypeInfo(typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps)); + } + + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo Create_HighLowTemps(global::System.Text.Json.JsonSerializerOptions options) + { + if (!TryGetTypeInfoForRuntimeCustomConverter(options, out global::System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo)) + { + var objectInfo = new global::System.Text.Json.Serialization.Metadata.JsonObjectInfoValues + { + ObjectCreator = () => new global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps(), + ObjectWithParameterizedConstructorCreator = null, + PropertyMetadataInitializer = _ => HighLowTempsPropInit(options), + ConstructorParameterMetadataInitializer = null, + SerializeHandler = HighLowTempsSerializeHandler + }; + + jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateObjectInfo(options, objectInfo); + jsonTypeInfo.NumberHandling = null; + } + + jsonTypeInfo.OriginatingResolver = this; + return jsonTypeInfo; + } + + private static global::System.Text.Json.Serialization.Metadata.JsonPropertyInfo[] HighLowTempsPropInit(global::System.Text.Json.JsonSerializerOptions options) + { + var properties = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfo[2]; + + var info0 = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues + { + IsProperty = true, + IsPublic = true, + IsVirtual = false, + DeclaringType = typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps), + Converter = null, + Getter = static obj => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps)obj).High, + Setter = static (obj, value) => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps)obj).High = value!, + IgnoreCondition = null, + HasJsonInclude = false, + IsExtensionData = false, + NumberHandling = null, + PropertyName = "High", + JsonPropertyName = null + }; + + properties[0] = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreatePropertyInfo(options, info0); + + var info1 = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues + { + IsProperty = true, + IsPublic = true, + IsVirtual = false, + DeclaringType = typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps), + Converter = null, + Getter = static obj => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps)obj).Low, + Setter = static (obj, value) => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps)obj).Low = value!, + IgnoreCondition = null, + HasJsonInclude = false, + IsExtensionData = false, + NumberHandling = null, + PropertyName = "Low", + JsonPropertyName = null + }; + + properties[1] = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreatePropertyInfo(options, info1); + + return properties; + } + + // Intentionally not a static method because we create a delegate to it. Invoking delegates to instance + // methods is almost as fast as virtual calls. Static methods need to go through a shuffle thunk. + private void HighLowTempsSerializeHandler(global::System.Text.Json.Utf8JsonWriter writer, global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps? value) + { + if (value == null) + { + writer.WriteNullValue(); + return; + } + + writer.WriteStartObject(); + + writer.WriteNumber(PropName_High, ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps)value).High); + writer.WriteNumber(PropName_Low, ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps)value).Low); + + writer.WriteEndObject(); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.Int32.g.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.Int32.g.cs new file mode 100644 index 0000000000000..332894c6fdb9d --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.Int32.g.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + public partial class Net80GeneratedContext + { + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo? _Int32; + + /// + /// Defines the source generated JSON serialization contract metadata for a given type. + /// + public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo Int32 + { + get => _Int32 ??= (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)Options.GetTypeInfo(typeof(int)); + } + + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo Create_Int32(global::System.Text.Json.JsonSerializerOptions options) + { + if (!TryGetTypeInfoForRuntimeCustomConverter(options, out global::System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo)) + { + jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateValueInfo(options, global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.Int32Converter); + } + + jsonTypeInfo.OriginatingResolver = this; + return jsonTypeInfo; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.ListDateTimeOffset.g.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.ListDateTimeOffset.g.cs new file mode 100644 index 0000000000000..2f922c332f54e --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.ListDateTimeOffset.g.cs @@ -0,0 +1,68 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + public partial class Net80GeneratedContext + { + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo>? _ListDateTimeOffset; + + /// + /// Defines the source generated JSON serialization contract metadata for a given type. + /// + public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo> ListDateTimeOffset + { + get => _ListDateTimeOffset ??= (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo>)Options.GetTypeInfo(typeof(global::System.Collections.Generic.List)); + } + + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo> Create_ListDateTimeOffset(global::System.Text.Json.JsonSerializerOptions options) + { + if (!TryGetTypeInfoForRuntimeCustomConverter>(options, out global::System.Text.Json.Serialization.Metadata.JsonTypeInfo> jsonTypeInfo)) + { + var info = new global::System.Text.Json.Serialization.Metadata.JsonCollectionInfoValues> + { + ObjectCreator = () => new global::System.Collections.Generic.List(), + SerializeHandler = ListDateTimeOffsetSerializeHandler + }; + + jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateListInfo, global::System.DateTimeOffset>(options, info); + jsonTypeInfo.NumberHandling = null; + } + + jsonTypeInfo.OriginatingResolver = this; + return jsonTypeInfo; + } + + // Intentionally not a static method because we create a delegate to it. Invoking delegates to instance + // methods is almost as fast as virtual calls. Static methods need to go through a shuffle thunk. + private void ListDateTimeOffsetSerializeHandler(global::System.Text.Json.Utf8JsonWriter writer, global::System.Collections.Generic.List? value) + { + if (value == null) + { + writer.WriteNullValue(); + return; + } + + writer.WriteStartArray(); + + for (int i = 0; i < value.Count; i++) + { + writer.WriteStringValue(value[i]); + } + + writer.WriteEndArray(); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.MyLinkedList.g.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.MyLinkedList.g.cs new file mode 100644 index 0000000000000..d2705fc63ad37 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.MyLinkedList.g.cs @@ -0,0 +1,140 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + public partial class Net80GeneratedContext + { + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo? _MyLinkedList; + + /// + /// Defines the source generated JSON serialization contract metadata for a given type. + /// + public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo MyLinkedList + { + get => _MyLinkedList ??= (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)Options.GetTypeInfo(typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList)); + } + + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo Create_MyLinkedList(global::System.Text.Json.JsonSerializerOptions options) + { + if (!TryGetTypeInfoForRuntimeCustomConverter(options, out global::System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo)) + { + var objectInfo = new global::System.Text.Json.Serialization.Metadata.JsonObjectInfoValues + { + ObjectCreator = null, + ObjectWithParameterizedConstructorCreator = static args => new global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList((int)args[0], (global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList)args[1]), + PropertyMetadataInitializer = _ => MyLinkedListPropInit(options), + ConstructorParameterMetadataInitializer = MyLinkedListCtorParamInit, + SerializeHandler = MyLinkedListSerializeHandler + }; + + jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateObjectInfo(options, objectInfo); + jsonTypeInfo.NumberHandling = null; + } + + jsonTypeInfo.OriginatingResolver = this; + return jsonTypeInfo; + } + + private static global::System.Text.Json.Serialization.Metadata.JsonPropertyInfo[] MyLinkedListPropInit(global::System.Text.Json.JsonSerializerOptions options) + { + var properties = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfo[2]; + + var info0 = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues + { + IsProperty = true, + IsPublic = true, + IsVirtual = false, + DeclaringType = typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList), + Converter = null, + Getter = static obj => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList)obj).Value, + Setter = static (obj, value) => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList)obj).Value = value!, + IgnoreCondition = null, + HasJsonInclude = false, + IsExtensionData = false, + NumberHandling = null, + PropertyName = "Value", + JsonPropertyName = null + }; + + properties[0] = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreatePropertyInfo(options, info0); + + var info1 = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues + { + IsProperty = true, + IsPublic = true, + IsVirtual = false, + DeclaringType = typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList), + Converter = null, + Getter = static obj => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList)obj).Nested, + Setter = static (obj, value) => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList)obj).Nested = value!, + IgnoreCondition = null, + HasJsonInclude = false, + IsExtensionData = false, + NumberHandling = null, + PropertyName = "Nested", + JsonPropertyName = null + }; + + properties[1] = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreatePropertyInfo(options, info1); + + return properties; + } + + // Intentionally not a static method because we create a delegate to it. Invoking delegates to instance + // methods is almost as fast as virtual calls. Static methods need to go through a shuffle thunk. + private void MyLinkedListSerializeHandler(global::System.Text.Json.Utf8JsonWriter writer, global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList? value) + { + if (value == null) + { + writer.WriteNullValue(); + return; + } + + writer.WriteStartObject(); + + writer.WriteNumber(PropName_Value, ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList)value).Value); + writer.WritePropertyName(PropName_Nested); + MyLinkedListSerializeHandler(writer, ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList)value).Nested); + + writer.WriteEndObject(); + } + + private static global::System.Text.Json.Serialization.Metadata.JsonParameterInfoValues[] MyLinkedListCtorParamInit() + { + var parameters = new global::System.Text.Json.Serialization.Metadata.JsonParameterInfoValues[2]; + + parameters[0] = new() + { + Name = "value", + ParameterType = typeof(int), + Position = 0, + HasDefaultValue = false, + DefaultValue = default(int) + }; + + parameters[1] = new() + { + Name = "nested", + ParameterType = typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList), + Position = 1, + HasDefaultValue = false, + DefaultValue = default(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.MyLinkedList) + }; + + return parameters; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.PropertyNames.g.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.PropertyNames.g.cs new file mode 100644 index 0000000000000..8e24422904452 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.PropertyNames.g.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + public partial class Net80GeneratedContext + { + private static readonly global::System.Text.Json.JsonEncodedText PropName_High = global::System.Text.Json.JsonEncodedText.Encode("High"); + private static readonly global::System.Text.Json.JsonEncodedText PropName_Low = global::System.Text.Json.JsonEncodedText.Encode("Low"); + private static readonly global::System.Text.Json.JsonEncodedText PropName_Value = global::System.Text.Json.JsonEncodedText.Encode("Value"); + private static readonly global::System.Text.Json.JsonEncodedText PropName_Nested = global::System.Text.Json.JsonEncodedText.Encode("Nested"); + private static readonly global::System.Text.Json.JsonEncodedText PropName_Date = global::System.Text.Json.JsonEncodedText.Encode("Date"); + private static readonly global::System.Text.Json.JsonEncodedText PropName_TemperatureCelsius = global::System.Text.Json.JsonEncodedText.Encode("TemperatureCelsius"); + private static readonly global::System.Text.Json.JsonEncodedText PropName_Summary = global::System.Text.Json.JsonEncodedText.Encode("Summary"); + private static readonly global::System.Text.Json.JsonEncodedText PropName_DatesAvailable = global::System.Text.Json.JsonEncodedText.Encode("DatesAvailable"); + private static readonly global::System.Text.Json.JsonEncodedText PropName_TemperatureRanges = global::System.Text.Json.JsonEncodedText.Encode("TemperatureRanges"); + private static readonly global::System.Text.Json.JsonEncodedText PropName_SummaryWords = global::System.Text.Json.JsonEncodedText.Encode("SummaryWords"); + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.String.g.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.String.g.cs new file mode 100644 index 0000000000000..01b2196de822f --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.String.g.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + public partial class Net80GeneratedContext + { + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo? _String; + + /// + /// Defines the source generated JSON serialization contract metadata for a given type. + /// + public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo String + { + get => _String ??= (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)Options.GetTypeInfo(typeof(string)); + } + + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo Create_String(global::System.Text.Json.JsonSerializerOptions options) + { + if (!TryGetTypeInfoForRuntimeCustomConverter(options, out global::System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo)) + { + jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateValueInfo(options, global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.StringConverter); + } + + jsonTypeInfo.OriginatingResolver = this; + return jsonTypeInfo; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.StringArray.g.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.StringArray.g.cs new file mode 100644 index 0000000000000..4eabcf89c7ce0 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.StringArray.g.cs @@ -0,0 +1,68 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + public partial class Net80GeneratedContext + { + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo? _StringArray; + + /// + /// Defines the source generated JSON serialization contract metadata for a given type. + /// + public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo StringArray + { + get => _StringArray ??= (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)Options.GetTypeInfo(typeof(string[])); + } + + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo Create_StringArray(global::System.Text.Json.JsonSerializerOptions options) + { + if (!TryGetTypeInfoForRuntimeCustomConverter(options, out global::System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo)) + { + var info = new global::System.Text.Json.Serialization.Metadata.JsonCollectionInfoValues + { + ObjectCreator = null, + SerializeHandler = StringArraySerializeHandler + }; + + jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateArrayInfo(options, info); + jsonTypeInfo.NumberHandling = null; + } + + jsonTypeInfo.OriginatingResolver = this; + return jsonTypeInfo; + } + + // Intentionally not a static method because we create a delegate to it. Invoking delegates to instance + // methods is almost as fast as virtual calls. Static methods need to go through a shuffle thunk. + private void StringArraySerializeHandler(global::System.Text.Json.Utf8JsonWriter writer, string[]? value) + { + if (value == null) + { + writer.WriteNullValue(); + return; + } + + writer.WriteStartArray(); + + for (int i = 0; i < value.Length; i++) + { + writer.WriteStringValue(value[i]); + } + + writer.WriteEndArray(); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.WeatherForecastWithPOCOs.g.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.WeatherForecastWithPOCOs.g.cs new file mode 100644 index 0000000000000..a00cf402f4cdb --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.WeatherForecastWithPOCOs.g.cs @@ -0,0 +1,216 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + public partial class Net80GeneratedContext + { + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo? _WeatherForecastWithPOCOs; + + /// + /// Defines the source generated JSON serialization contract metadata for a given type. + /// + public global::System.Text.Json.Serialization.Metadata.JsonTypeInfo WeatherForecastWithPOCOs + { + get => _WeatherForecastWithPOCOs ??= (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)Options.GetTypeInfo(typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)); + } + + private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo Create_WeatherForecastWithPOCOs(global::System.Text.Json.JsonSerializerOptions options) + { + if (!TryGetTypeInfoForRuntimeCustomConverter(options, out global::System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo)) + { + var objectInfo = new global::System.Text.Json.Serialization.Metadata.JsonObjectInfoValues + { + ObjectCreator = () => new global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs(), + ObjectWithParameterizedConstructorCreator = null, + PropertyMetadataInitializer = _ => WeatherForecastWithPOCOsPropInit(options), + ConstructorParameterMetadataInitializer = null, + SerializeHandler = WeatherForecastWithPOCOsSerializeHandler + }; + + jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateObjectInfo(options, objectInfo); + jsonTypeInfo.NumberHandling = null; + } + + jsonTypeInfo.OriginatingResolver = this; + return jsonTypeInfo; + } + + private static global::System.Text.Json.Serialization.Metadata.JsonPropertyInfo[] WeatherForecastWithPOCOsPropInit(global::System.Text.Json.JsonSerializerOptions options) + { + var properties = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfo[7]; + + var info0 = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues + { + IsProperty = true, + IsPublic = true, + IsVirtual = false, + DeclaringType = typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs), + Converter = null, + Getter = static obj => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).Date, + Setter = static (obj, value) => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).Date = value!, + IgnoreCondition = null, + HasJsonInclude = false, + IsExtensionData = false, + NumberHandling = null, + PropertyName = "Date", + JsonPropertyName = null + }; + + properties[0] = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreatePropertyInfo(options, info0); + + var info1 = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues + { + IsProperty = true, + IsPublic = true, + IsVirtual = false, + DeclaringType = typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs), + Converter = null, + Getter = static obj => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).TemperatureCelsius, + Setter = static (obj, value) => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).TemperatureCelsius = value!, + IgnoreCondition = null, + HasJsonInclude = false, + IsExtensionData = false, + NumberHandling = null, + PropertyName = "TemperatureCelsius", + JsonPropertyName = null + }; + + properties[1] = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreatePropertyInfo(options, info1); + + var info2 = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues + { + IsProperty = true, + IsPublic = true, + IsVirtual = false, + DeclaringType = typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs), + Converter = null, + Getter = static obj => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).Summary, + Setter = static (obj, value) => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).Summary = value!, + IgnoreCondition = null, + HasJsonInclude = false, + IsExtensionData = false, + NumberHandling = null, + PropertyName = "Summary", + JsonPropertyName = null + }; + + properties[2] = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreatePropertyInfo(options, info2); + + var info3 = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues> + { + IsProperty = true, + IsPublic = true, + IsVirtual = false, + DeclaringType = typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs), + Converter = null, + Getter = static obj => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).DatesAvailable, + Setter = static (obj, value) => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).DatesAvailable = value!, + IgnoreCondition = null, + HasJsonInclude = false, + IsExtensionData = false, + NumberHandling = null, + PropertyName = "DatesAvailable", + JsonPropertyName = null + }; + + properties[3] = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreatePropertyInfo>(options, info3); + + var info4 = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues> + { + IsProperty = true, + IsPublic = true, + IsVirtual = false, + DeclaringType = typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs), + Converter = null, + Getter = static obj => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).TemperatureRanges, + Setter = static (obj, value) => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).TemperatureRanges = value!, + IgnoreCondition = null, + HasJsonInclude = false, + IsExtensionData = false, + NumberHandling = null, + PropertyName = "TemperatureRanges", + JsonPropertyName = null + }; + + properties[4] = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreatePropertyInfo>(options, info4); + + var info5 = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues + { + IsProperty = true, + IsPublic = true, + IsVirtual = false, + DeclaringType = typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs), + Converter = null, + Getter = static obj => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).SummaryWords, + Setter = static (obj, value) => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).SummaryWords = value!, + IgnoreCondition = null, + HasJsonInclude = false, + IsExtensionData = false, + NumberHandling = null, + PropertyName = "SummaryWords", + JsonPropertyName = null + }; + + properties[5] = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreatePropertyInfo(options, info5); + + var info6 = new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues + { + IsProperty = false, + IsPublic = true, + IsVirtual = false, + DeclaringType = typeof(global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs), + Converter = null, + Getter = static obj => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).SummaryField, + Setter = static (obj, value) => ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)obj).SummaryField = value!, + IgnoreCondition = null, + HasJsonInclude = false, + IsExtensionData = false, + NumberHandling = null, + PropertyName = "SummaryField", + JsonPropertyName = null + }; + + properties[6] = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreatePropertyInfo(options, info6); + + return properties; + } + + // Intentionally not a static method because we create a delegate to it. Invoking delegates to instance + // methods is almost as fast as virtual calls. Static methods need to go through a shuffle thunk. + private void WeatherForecastWithPOCOsSerializeHandler(global::System.Text.Json.Utf8JsonWriter writer, global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs? value) + { + if (value == null) + { + writer.WriteNullValue(); + return; + } + + writer.WriteStartObject(); + + writer.WriteString(PropName_Date, ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)value).Date); + writer.WriteNumber(PropName_TemperatureCelsius, ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)value).TemperatureCelsius); + writer.WriteString(PropName_Summary, ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)value).Summary); + writer.WritePropertyName(PropName_DatesAvailable); + ListDateTimeOffsetSerializeHandler(writer, ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)value).DatesAvailable); + writer.WritePropertyName(PropName_TemperatureRanges); + DictionaryStringHighLowTempsSerializeHandler(writer, ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)value).TemperatureRanges); + writer.WritePropertyName(PropName_SummaryWords); + StringArraySerializeHandler(writer, ((global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs)value).SummaryWords); + + writer.WriteEndObject(); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.cs new file mode 100644 index 0000000000000..7db55625abc7b --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.cs @@ -0,0 +1,61 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + //[JsonSerializable(typeof(WeatherForecastWithPOCOs))] + //[JsonSerializable(typeof(ClassWithCustomConverter))] + //[JsonSerializable(typeof(MyLinkedList))] + public partial class Net80GeneratedContext : JsonSerializerContext {} + + public class WeatherForecastWithPOCOs + { + public DateTimeOffset Date { get; set; } + public int TemperatureCelsius { get; set; } + public string? Summary { get; set; } + public string? SummaryField; + public List? DatesAvailable { get; set; } + public Dictionary? TemperatureRanges { get; set; } + public string[]? SummaryWords { get; set; } + } + + public class HighLowTemps + { + public int High { get; set; } + public int Low { get; set; } + } + + public class MyLinkedList + { + public MyLinkedList(int value, MyLinkedList? nested) + { + Value = value; + Nested = nested; + } + + public int Value { get; set; } + public MyLinkedList? Nested { get; set; } + } + + [JsonConverter(typeof(CustomConverter))] + public class ClassWithCustomConverter + { + public int Value { get; set; } + + public class CustomConverter : JsonConverter + { + public override ClassWithCustomConverter? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => new ClassWithCustomConverter { Value = reader.GetInt32() - 1 }; + + public override void Write(Utf8JsonWriter writer, ClassWithCustomConverter value, JsonSerializerOptions options) + => writer.WriteNumberValue(value.Value + 1); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.g.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.g.cs new file mode 100644 index 0000000000000..981a7f77c41ec --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80/Net80GeneratedContext.g.cs @@ -0,0 +1,89 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Source files represent a source generated JsonSerializerContext as produced by the .NET 8 SDK. +// Used to validate correctness of contexts generated by previous SDKs against the current System.Text.Json runtime components. +// Unless absolutely necessary DO NOT MODIFY any of these files -- it would invalidate the purpose of the regression tests. + +// + +#nullable enable annotations +#nullable disable warnings + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0612, CS0618 + +namespace System.Text.Json.Tests.SourceGenRegressionTests.Net80 +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Text.Json.SourceGeneration", "8.0.9.3103")] + public partial class Net80GeneratedContext + { + private readonly static global::System.Text.Json.JsonSerializerOptions s_defaultOptions = new(); + + /// + /// The default associated with a default instance. + /// + public static global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.Net80GeneratedContext Default { get; } = new global::System.Text.Json.Tests.SourceGenRegressionTests.Net80.Net80GeneratedContext(new global::System.Text.Json.JsonSerializerOptions(s_defaultOptions)); + + /// + /// The source-generated options associated with this context. + /// + protected override global::System.Text.Json.JsonSerializerOptions? GeneratedSerializerOptions { get; } = s_defaultOptions; + + /// + public Net80GeneratedContext() : base(null) + { + } + + /// + public Net80GeneratedContext(global::System.Text.Json.JsonSerializerOptions options) : base(options) + { + } + + private static bool TryGetTypeInfoForRuntimeCustomConverter(global::System.Text.Json.JsonSerializerOptions options, out global::System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo) + { + global::System.Text.Json.Serialization.JsonConverter? converter = GetRuntimeConverterForType(typeof(TJsonMetadataType), options); + if (converter != null) + { + jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateValueInfo(options, converter); + return true; + } + + jsonTypeInfo = null; + return false; + } + + private static global::System.Text.Json.Serialization.JsonConverter? GetRuntimeConverterForType(global::System.Type type, global::System.Text.Json.JsonSerializerOptions options) + { + for (int i = 0; i < options.Converters.Count; i++) + { + global::System.Text.Json.Serialization.JsonConverter? converter = options.Converters[i]; + if (converter?.CanConvert(type) == true) + { + return ExpandConverter(type, converter, options, validateCanConvert: false); + } + } + + return null; + } + + private static global::System.Text.Json.Serialization.JsonConverter ExpandConverter(global::System.Type type, global::System.Text.Json.Serialization.JsonConverter converter, global::System.Text.Json.JsonSerializerOptions options, bool validateCanConvert = true) + { + if (validateCanConvert && !converter.CanConvert(type)) + { + throw new global::System.InvalidOperationException(string.Format("The converter '{0}' is not compatible with the type '{1}'.", converter.GetType(), type)); + } + + if (converter is global::System.Text.Json.Serialization.JsonConverterFactory factory) + { + converter = factory.CreateConverter(type, options); + if (converter is null || converter is global::System.Text.Json.Serialization.JsonConverterFactory) + { + throw new global::System.InvalidOperationException(string.Format("The converter '{0}' cannot return null or a JsonConverterFactory instance.", factory.GetType())); + } + } + + return converter; + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80RegressionTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80RegressionTests.cs new file mode 100644 index 0000000000000..933af3f137dd1 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/SourceGenRegressionTests/Net80RegressionTests.cs @@ -0,0 +1,177 @@ +// 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.Serialization.Metadata; +using System.Text.Json.Tests.SourceGenRegressionTests.Net80; +using Xunit; +using HighLowTemps = System.Text.Json.Tests.SourceGenRegressionTests.Net80.HighLowTemps; +using WeatherForecastWithPOCOs = System.Text.Json.Tests.SourceGenRegressionTests.Net80.WeatherForecastWithPOCOs; + +namespace System.Text.Json.Tests.SourceGenRegressionTests +{ + public static class Net80RegressionTests + { + [Theory] + [MemberData(nameof(GetSupportedTypeRoundtripData))] + public static void SupportedTypeRoundtrip(JsonTypeInfo jsonTypeInfo, T value, string expectedJson) + { + string json = JsonSerializer.Serialize(value, jsonTypeInfo); + JsonTestHelper.AssertJsonEqual(expectedJson, json); + + T deserializedValue = JsonSerializer.Deserialize(json, jsonTypeInfo); + json = JsonSerializer.Serialize(deserializedValue, jsonTypeInfo); + JsonTestHelper.AssertJsonEqual(expectedJson, json); + } + + public static IEnumerable GetSupportedTypeRoundtripData() + { + var ctx = Net80GeneratedContext.Default; + yield return Wrap(ctx.Int32, 42, "42"); + yield return Wrap(ctx.DateTimeOffset, DateTimeOffset.MinValue, "\"0001-01-01T00:00:00+00:00\""); + yield return Wrap(ctx.String, "I am a string", "\"I am a string\""); + yield return Wrap(ctx.HighLowTemps, new HighLowTemps { Low = 0, High = 5 }, """{"Low":0,"High":5}"""); + yield return Wrap(ctx.ListDateTimeOffset, new List { DateTimeOffset.MinValue }, "[\"0001-01-01T00:00:00+00:00\"]"); + yield return Wrap(ctx.ClassWithCustomConverter, new ClassWithCustomConverter { Value = 41 }, "42"); + yield return Wrap(ctx.WeatherForecastWithPOCOs, new WeatherForecastWithPOCOs + { + Date = DateTimeOffset.MinValue, + TemperatureCelsius = 10, + Summary = "I am a string", + DatesAvailable = new List { DateTimeOffset.MinValue }, + TemperatureRanges = new Dictionary + { + ["key"] = new HighLowTemps { Low = 0, High = 5 } + }, + SummaryWords = new[] { "word1", "word2" }, + }, + """ + { + "Date" : "0001-01-01T00:00:00+00:00", + "TemperatureCelsius" : 10, + "Summary" : "I am a string", + "DatesAvailable" : [ "0001-01-01T00:00:00+00:00" ], + "TemperatureRanges" : + { + "key" : { "Low" : 0, "High" : 5 } + }, + "SummaryWords" : [ "word1", "word2" ] + } + """); + + static object[] Wrap(JsonTypeInfo jsonTypeInfo, T value, string expectedJson) => new object[] { jsonTypeInfo, value, expectedJson }; + } + + [Theory] + [MemberData(nameof(GetSupportedTypeRoundtripData_OptionsBased))] + public static void SupportedTypeRoundtrip_OptionsBased(T value, string expectedJson) + { + string json = JsonSerializer.Serialize(value, Net80GeneratedContext.Default.Options); + JsonTestHelper.AssertJsonEqual(expectedJson, json); + + T deserializedValue = JsonSerializer.Deserialize(json, Net80GeneratedContext.Default.Options); + json = JsonSerializer.Serialize(deserializedValue, Net80GeneratedContext.Default.Options); + JsonTestHelper.AssertJsonEqual(expectedJson, json); + } + + [Fact] + public static void UnsupportedType_ThrowsInvalidOperationException() + { + DateTime value = DateTime.MinValue; + string json = JsonSerializer.Serialize(value); + + Assert.Throws(() => JsonSerializer.Serialize(value, value.GetType(), Net80GeneratedContext.Default)); + Assert.Throws(() => JsonSerializer.Deserialize(json, value.GetType(), Net80GeneratedContext.Default)); + } + + public static IEnumerable GetSupportedTypeRoundtripData_OptionsBased() + { + yield return Wrap(new ClassWithCustomConverter { Value = 41 }, "42"); + yield return Wrap(new WeatherForecastWithPOCOs + { + Date = DateTimeOffset.MinValue, + TemperatureCelsius = 10, + Summary = "I am a string", + DatesAvailable = new List { DateTimeOffset.MinValue }, + TemperatureRanges = new Dictionary + { + ["key"] = new HighLowTemps { Low = 0, High = 5 } + }, + SummaryWords = new[] { "word1", "word2" }, + }, + """ + { + "Date" : "0001-01-01T00:00:00+00:00", + "TemperatureCelsius" : 10, + "Summary" : "I am a string", + "DatesAvailable" : [ "0001-01-01T00:00:00+00:00" ], + "TemperatureRanges" : + { + "key" : { "Low" : 0, "High" : 5 } + }, + "SummaryWords" : [ "word1", "word2" ] + } + """); + + static object[] Wrap(T value, string expectedJson) => new object[] { value, expectedJson }; + } + + [Fact] + public static void HighLowTemps_ContextReportsCorrectMetadata() + { + JsonTypeInfo jsonTypeInfo = Net80GeneratedContext.Default.HighLowTemps; + + HighLowTemps instance = jsonTypeInfo.CreateObject(); + Assert.Equal(0, instance.Low); + Assert.Equal(0, instance.High); + + Assert.Equal(2, jsonTypeInfo.Properties.Count); + + JsonPropertyInfo jsonPropertyInfo = jsonTypeInfo.Properties[0]; + Assert.Equal("High", jsonPropertyInfo.Name); + jsonPropertyInfo.Set(instance, 1); + Assert.Equal(1, instance.High); + Assert.Equal(1, jsonPropertyInfo.Get(instance)); + + jsonPropertyInfo = jsonTypeInfo.Properties[1]; + Assert.Equal("Low", jsonPropertyInfo.Name); + jsonPropertyInfo.Set(instance, 2); + Assert.Equal(2, instance.Low); + Assert.Equal(2, jsonPropertyInfo.Get(instance)); + } + + [Fact] + public static void SupportsRecursiveTypeSerialization() + { + JsonTypeInfo jsonTypeInfo = Net80GeneratedContext.Default.MyLinkedList; + + MyLinkedList linkedList = new( + value: 0, + nested: new( + value: 1, + nested: new( + value: 2, + nested: null))); + + string json = JsonSerializer.Serialize(linkedList, jsonTypeInfo); + Assert.Equal("""{"Value":0,"Nested":{"Value":1,"Nested":{"Value":2,"Nested":null}}}""", json); + + linkedList = JsonSerializer.Deserialize(json, jsonTypeInfo); + Assert.Equal(2, linkedList.Nested.Nested.Value); + } + + [Fact] + public static void CombinedContexts_WorksAsExpected() + { + var options = new JsonSerializerOptions + { + TypeInfoResolver = JsonTypeInfoResolver.Combine(Net80GeneratedContext.Default, new DefaultJsonTypeInfoResolver()) + }; + + // Unlike v6, v7 Contexts do implement IJsonTypeInfoResolver so combined resolvers will produce the expected output. + string expected = JsonSerializer.Serialize(new HighLowTemps(), Net80GeneratedContext.Default.HighLowTemps); + string actual = JsonSerializer.Serialize(new HighLowTemps(), options); + Assert.Equal(expected, actual); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj index a0f7a9151d343..ac55c6341fc77 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/System.Text.Json.Tests.csproj @@ -249,6 +249,21 @@ + + + + + + + + + + + + + + +