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 crashes if duplicate context class names used #66851

Closed canton7 closed 2 years ago

canton7 commented 2 years ago

Description

System.Text.Json.SourceGeneration.JsonSourceGenerator does not make sure that the hintNames it uses are unique. If you pass it two different JsonSerializerContext subclasses with the same name in different namespaces (or within different parent classes) it will crash, and will not generate any sources. E.g.:

warning CS8785: Generator 'JsonSourceGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type 'ArgumentException' with message 'The hintName '\<Context>.g.cs' of the added source file must be unique within a generator.

Reproduction Steps

Create a new project targetting .NET 6. Add the following code:

public class Model
{
}

namespace Test
{
    [JsonSerializable(typeof(Model))]
    internal partial class MyJsonContext : JsonSerializerContext
    {
    }
}

namespace Test2
{
    [JsonSerializable(typeof(Model))]
    internal partial class MyJsonContext : JsonSerializerContext
    {
    }
}

Or:

public partial class Test
{
    [JsonSerializable(typeof(Model))]
    internal partial class MyJsonContext : JsonSerializerContext
    {
    }
}

public partial class Test2
{
    [JsonSerializable(typeof(Model))]
    internal partial class MyJsonContext : JsonSerializerContext
    {
    }
}

Observe that JsonSourceGenerator crashes, and does not generate source.

Expected behavior

JsonSourceGenerator copes with two contexts which have the same name but are in different namespaces (or are inner types of different parent types).

Actual behavior

JsonSourceGenerator crashes with the following message, and does not generate source

warning CS8785: Generator 'JsonSourceGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type 'ArgumentException' with message 'The hintName 'MyJsonContext.g.cs' of the added source file must be unique within a generator.

Regression?

No response

Known Workarounds

No response

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 System.Text.Json.SourceGeneration.JsonSourceGenerator does not make sure that the hintNames it uses are unique. If you pass it two different `JsonSerializerContext` subclasses with the same name in different namespaces (or within different parent classes) it will crash, and will not generate any sources. E.g.: > warning CS8785: Generator 'JsonSourceGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type 'ArgumentException' with message 'The hintName '\.g.cs' of the added source file must be unique within a generator. ### Reproduction Steps Create a new project targetting .NET 6. Add the following code: ```cs public class Model { } namespace Test { [JsonSerializable(typeof(Model))] internal partial class MyJsonContext : JsonSerializerContext { } } namespace Test2 { [JsonSerializable(typeof(Model))] internal partial class MyJsonContext : JsonSerializerContext { } } ``` Or: ```cs public partial class Test { [JsonSerializable(typeof(Model))] internal partial class MyJsonContext : JsonSerializerContext { } } public partial class Test2 { [JsonSerializable(typeof(Model))] internal partial class MyJsonContext : JsonSerializerContext { } } ``` Observe that JsonSourceGenerator crashes, and does not generate source. ### Expected behavior JsonSourceGenerator copes with two contexts which have the same name but are in different namespaces (or are inner types of different parent types). ### Actual behavior JsonSourceGenerator crashes with the following message, and does not generate source > warning CS8785: Generator 'JsonSourceGenerator' failed to generate source. It will not contribute to the output and compilation errors may occur as a result. Exception was of type 'ArgumentException' with message 'The hintName 'MyJsonContext.g.cs' of the added source file must be unique within a generator. ### Regression? _No response_ ### Known Workarounds _No response_ ### Configuration .NET 6, Visual Studio 17.2.0 Preview 1.0. ### Other information _No response_
Author: canton7
Assignees: -
Labels: `area-System.Text.Json`
Milestone: -
danmoseley commented 2 years ago

Thanks @canton7 . Are you interested in offering a PR?

canton7 commented 2 years ago

Potentially. I had the same issue reported in one of my source generators, and wondered how Microsoft were handling it. Turns out, you don't, hence this issue.

I've started a conversation around changing the behaviour of Roslyn here, as almost every SG will run into this problem. It's not too bad to fix in non-incremental SGs, but the only way I can come up with of fixing it for incremental SGs is just ugly.

eiriktsarpalis commented 2 years ago

Duplicate of #58198.