Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JsonSerializerContext generated source breaks for property named "@event" #109854

Open
burtonrodman opened this issue Nov 15, 2024 · 4 comments
Open
Labels
area-System.Text.Json source-generator Indicates an issue with a source generator feature
Milestone

Comments

@burtonrodman
Copy link

Description

Json source generator generates invalid code when a property name is a keyword, like @event

Reproduction Steps

  1. create a class that has a property call @event
  2. create a JsonSerializerContext class that references above class
  3. build and notice compiler errors in generated code
public class ClickEvent {
  public required string @event { get; set; }
}

[JsonSerializable(typeof(ClickEvent))]
public partial class ClientEventContext : JsonSerializerContext { }

Expected behavior

generated code does not cause compile errors

Actual behavior

        private global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::TwentyTenSolutions.ContentManagement.Editing.ViewModels.ClickEvent> Create_ClickEvent(global::System.Text.Json.JsonSerializerOptions options)
        {
            if (!TryGetTypeInfoForRuntimeCustomConverter<global::TwentyTenSolutions.ContentManagement.Editing.ViewModels.ClickEvent>(options, out global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::TwentyTenSolutions.ContentManagement.Editing.ViewModels.ClickEvent> jsonTypeInfo))
            {
                var objectInfo = new global::System.Text.Json.Serialization.Metadata.JsonObjectInfoValues<global::TwentyTenSolutions.ContentManagement.Editing.ViewModels.ClickEvent>
                {
                    ObjectCreator = null,
                    ObjectWithParameterizedConstructorCreator = static args => new global::TwentyTenSolutions.ContentManagement.Editing.ViewModels.ClickEvent(){ event = (string)args[0] },
                    PropertyMetadataInitializer = _ => ClickEventPropInit(options),
                    ConstructorParameterMetadataInitializer = ClickEventCtorParamInit,
                    SerializeHandler = ClickEventSerializeHandler
                };
                
                jsonTypeInfo = global::System.Text.Json.Serialization.Metadata.JsonMetadataServices.CreateObjectInfo<global::TwentyTenSolutions.ContentManagement.Editing.ViewModels.ClickEvent>(options, objectInfo);
                jsonTypeInfo.NumberHandling = null;
            }
        
            jsonTypeInfo.OriginatingResolver = this;
            return jsonTypeInfo;
        }

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Nov 15, 2024
Copy link
Contributor

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

@burtonrodman
Copy link
Author

 *  Executing task in folder MyFirm.ContentManagement: C:\Program Files\dotnet\dotnet.exe build D:\source\MyFirm\Internal\MyFirm.ContentManagement/MyFirm.ContentManagement.sln /property:GenerateFullPaths=true /consoleloggerparameters:NoSummary;ForceNoAlign 

  Determining projects to restore...
  All projects are up-to-date for restore.
  MyFirm.ContentManagement.Editing.Domain -> D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing.Domain\bin\Debug\net8.0\MyFirm.ContentManagement.Editing.Domain.dll
  MyFirm.ContentManagement.Data -> D:\source\MyFirm\Internal\MyFirm.ContentManagement\data\MyFirm.ContentManagement.Data\bin\Debug\net8.0\MyFirm.ContentManagement.Data.dll
  MyFirm.ContentManagement.Editing.Api -> D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing.Api\bin\Debug\net8.0\MyFirm.ContentManagement.Editing.Api.dll
  MyFirm.ContentManagement.Rendering -> D:\source\MyFirm\Internal\MyFirm.ContentManagement\rendering\MyFirm.ContentManagement.Rendering\bin\Debug\net8.0\MyFirm.ContentManagement.Rendering.dll
  MyFirm.ContentManagement.Rendering.Tests -> D:\source\MyFirm\Internal\MyFirm.ContentManagement\rendering\MyFirm.ContentManagement.Rendering.Tests\bin\Debug\net8.0\MyFirm.ContentManagement.Rendering.Tests.dll
  sampleSite -> D:\source\MyFirm\Internal\MyFirm.ContentManagement\samples\site\sampleSite\bin\Debug\net8.0\sampleSite.dll
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\PickImageEventContext.PickImageEvent.g.cs(36,17): error CS8802: Only one compilation unit can have top-level statements. [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\SlotEditorsInitEventContext.SlotEditorsInitEvent.g.cs(36,17): error CS8802: Only one compilation unit can have top-level statements. [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\SlotInsertBlockEventContext.SlotInsertBlockEvent.g.cs(36,17): error CS8802: Only one compilation unit can have top-level statements. [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\BlockActionMenuClickEventContext.BlockActionMenuClickEvent.g.cs(36,17): error CS8802: Only one compilation unit can have top-level statements. [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\ClientEventContext.ClickEvent.g.cs(36,17): error CS8802: Only one compilation unit can have top-level statements. [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\ClientEventContext.ClickEvent.g.cs(30,168): error CS0065: 'ClientEventContext.': event property must have both add and remove accessors [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\BlockEditableInputEventContext.BlockEditableInputEvent.g.cs(30,214): error CS0065: 'BlockEditableInputEventContext.': event property must have both add and remove accessors [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\PickImageEventContext.PickImageEvent.g.cs(30,172): error CS0065: 'PickImageEventContext.': event property must have both add and remove accessors [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\SlotEditorsInitEventContext.SlotEditorsInitEvent.g.cs(30,178): error CS0065: 'SlotEditorsInitEventContext.': event property must have both add and remove accessors [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]  
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\BlockEditableInputEventContext.BlockEditableInputEvent.g.cs(31,56): error CS1520: Method must have a return type [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\BlockEditableInputEventContext.BlockEditableInputEvent.g.cs(31,56): error CS0501: '<invalid-global-code>.<invalid-global-code>(options)' must declare a body because it is not marked abstract, extern, or partial [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\PickImageEventContext.PickImageEvent.g.cs(31,56): error CS1520: Method must have a return type [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\PickImageEventContext.PickImageEvent.g.cs(31,56): error CS0501: '<invalid-global-code>.<invalid-global-code>(options)' must declare a body because it is not marked abstract, extern, or partial [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\SlotEditorsInitEventContext.SlotEditorsInitEvent.g.cs(31,56): error CS1520: Method must have a return type [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\SlotEditorsInitEventContext.SlotEditorsInitEvent.g.cs(31,56): error CS0501: '<invalid-global-code>.<invalid-global-code>(options)' must declare a body because it is not marked abstract, extern, or partial [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\SlotInsertBlockEventContext.SlotInsertBlockEvent.g.cs(31,56): error CS1520: Method must have a return type [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\SlotInsertBlockEventContext.SlotInsertBlockEvent.g.cs(31,56): error CS0501: '<invalid-global-code>.<invalid-global-code>(options)' must declare a body because it is not marked abstract, extern, or partial [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\BlockActionMenuClickEventContext.BlockActionMenuClickEvent.g.cs(31,56): error CS1520: Method must have a return type [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\BlockActionMenuClickEventContext.BlockActionMenuClickEvent.g.cs(31,56): error CS0501: '<invalid-global-code>.<invalid-global-code>(options)' must declare a body because it is not marked abstract, extern, or partial [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\ClientEventContext.ClickEvent.g.cs(31,56): error CS1520: Method must have a return type [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\ClientEventContext.ClickEvent.g.cs(31,56): error CS0501: '<invalid-global-code>.<invalid-global-code>(options)' must declare a body because it is not marked abstract, extern, or partial [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\BlockActionMenuClickEventContext.BlockActionMenuClickEvent.g.cs(30,209): error CS0065: 'BlockActionMenuClickEventContext.': event property must have both add and remove accessors [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\SlotInsertBlockEventContext.SlotInsertBlockEvent.g.cs(30,206): error CS0065: 'SlotInsertBlockEventContext.': event property must have both add and remove accessors [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]  
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\BlockEditableInputEventContext.BlockEditableInputEvent.g.cs(31,88): error CS0246: The type or namespace name 'options' could not be found (are you missing a using directive or an assembly reference?) [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\PickImageEventContext.PickImageEvent.g.cs(31,79): error CS0246: The type or namespace name 'options' could not be found (are you missing a using directive or an assembly reference?) [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\SlotEditorsInitEventContext.SlotEditorsInitEvent.g.cs(31,85): error CS0246: The type or namespace name 'options' could not be found (are you missing a using directive or an assembly reference?) [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\SlotInsertBlockEventContext.SlotInsertBlockEvent.g.cs(31,85): error CS0246: The type or namespace name 'options' could not be found (are you missing a using directive or an assembly reference?) [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\BlockActionMenuClickEventContext.BlockActionMenuClickEvent.g.cs(31,90): error CS0246: The type or namespace name 'options' could not be found (are you missing a using directive or an assembly reference?) [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\obj\Debug\net8.0\generated\System.Text.Json.SourceGeneration\System.Text.Json.SourceGeneration.JsonSourceGenerator\ClientEventContext.ClickEvent.g.cs(31,75): error CS0246: The type or namespace name 'options' could not be found (are you missing a using directive or an assembly reference?) [D:\source\MyFirm\Internal\MyFirm.ContentManagement\editing\MyFirm.ContentManagement.Editing\MyFirm.ContentManagement.Editing.csproj]
  sample.Client -> D:\source\MyFirm\Internal\MyFirm.ContentManagement\samples\sample\sample.Client\bin\Debug\net8.0\sample.Client.dll
  sample.Client (Blazor output) -> D:\source\MyFirm\Internal\MyFirm.ContentManagement\samples\sample\sample.Client\bin\Debug\net8.0\wwwroot
  sample -> D:\source\MyFirm\Internal\MyFirm.ContentManagement\samples\sample\sample\bin\Debug\net8.0\sample.dll

Workload updates are available. Run `dotnet workload list` for more information.

 *  The terminal process "C:\Program Files\dotnet\dotnet.exe 'build', 'D:\source\MyFirm\Internal\MyFirm.ContentManagement/MyFirm.ContentManagement.sln', '/property:GenerateFullPaths=true', '/consoleloggerparameters:NoSummary;ForceNoAlign'" terminated with exit code: 1. 
 *  Terminal will be reused by tasks, press any key to close it. 

@eiriktsarpalis
Copy link
Member

Can confirm this is a bug which impacts all members using keyword identifiers. Here's a more involved example:

public class @class
{
    public @class(string @string) 
    {
        this.@string = @string;
    }

    public string @string { get; set; }
}

[JsonSerializable(typeof(@class))]
public partial class MyContext : JsonSerializerContext;

We should eventually try to update the generator so that it handles escaped identifiers more comprehensively. In the meantime, it should be possible to work around the issue by doing something like:

public class ClickEvent
{
  [JsonPropertyName("event")]
  public required string Event { get; set; }
}

@eiriktsarpalis eiriktsarpalis added this to the Future milestone Nov 15, 2024
@eiriktsarpalis eiriktsarpalis added source-generator Indicates an issue with a source generator feature and removed untriaged New issue has not been triaged by the area owner labels Nov 15, 2024
@burtonrodman
Copy link
Author

fortunately i controlled both side of the protocol so i was able to work around by renaming the property. thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-System.Text.Json source-generator Indicates an issue with a source generator feature
Projects
None yet
Development

No branches or pull requests

2 participants