dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.96k stars 4.65k forks source link

System.Text.Json SourceGenerator behaves oddly if context is generic #66880

Closed canton7 closed 2 years ago

canton7 commented 2 years ago

Description

If the JsonSerializerContext given to the System.Text.Json source generator is generic, the source generator generates some very odd code.

Reproduction Steps

Create a .NET 6 project containing the following, and look at the source generated by the System.Text.Json source generator:

public class Model
{
}

[JsonSerializable(typeof(Model))]
internal partial class MyJsonContext<T> : JsonSerializerContext
{
}

Expected behavior

The source generator either produces a diagnostic saying that generic contexts aren't supported (and does not attempt to generate source), or the source generated is valid C#.

Actual behavior

It's a mix of things.

The class declaration itself is non-generic:

internal partial class MyJsonContext

The default context is sort-of generic, but is confused about what a generic type parameter is:

        private static global::MyJsonContext<global::MyJsonContext.T>? s_defaultContext;
        public static global::MyJsonContext<global::MyJsonContext.T> Default => s_defaultContext ??= new global::MyJsonContext<global::MyJsonContext.T>(new global::System.Text.Json.JsonSerializerOptions(s_defaultOptions));

The constructors are invalid C#:

        public MyJsonContext`1() : base(null)
        {
        }

        public MyJsonContext`1(global::System.Text.Json.JsonSerializerOptions options) : base(options)
        {
        }

Regression?

No

Known Workarounds

None

Configuration

.NET 6, Visual Studio 17.2.0 Preview 1.0.

Other information

No response

ghost commented 2 years ago

Tagging subscribers to this area: @dotnet/area-system-text-json See info in area-owners.md if you want to be subscribed.

Issue Details
### Description If the `JsonSerializerContext` given to the System.Text.Json source generator is generic, the source generator generates some very odd code. ### Reproduction Steps Create a .NET 6 project containing the following, and look at the source generated by the System.Text.Json source generator: ```cs public class Model { } [JsonSerializable(typeof(Model))] internal partial class MyJsonContext : JsonSerializerContext { } ``` ### Expected behavior The source generator either produces a diagnostic saying that generic contexts aren't supported (and does not attempt to generate source), or the source generated is valid C#. ### Actual behavior It's a mix of things. The class declaration itself is non-generic: ```cs internal partial class MyJsonContext ``` The default context is sort-of generic, but is confused about what a generic type parameter is: ```cs private static global::MyJsonContext? s_defaultContext; public static global::MyJsonContext Default => s_defaultContext ??= new global::MyJsonContext(new global::System.Text.Json.JsonSerializerOptions(s_defaultOptions)); ``` The constructors are invalid C#: ```cs public MyJsonContext`1() : base(null) { } public MyJsonContext`1(global::System.Text.Json.JsonSerializerOptions options) : base(options) { } ``` ### Regression? No ### Known Workarounds None ### Configuration .NET 6, Visual Studio 17.2.0 Preview 1.0. ### Other information _No response_
Author: canton7
Assignees: -
Labels: `area-System.Text.Json`, `untriaged`
Milestone: -
layomia commented 2 years ago

This is a bug since the generator is produced invalid syntax. Do you have any scenario/reason for making your context type generic?

layomia commented 2 years ago

Same underlying issue as https://github.com/dotnet/runtime/issues/62762.