Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 26, 2025

main PR

Description

JsonSourceGenerator emitted bare C# keywords instead of verbatim identifiers (@elseelse) when generating property initializers for init-only properties, causing compilation errors.

Root cause: PropertyInitializerGenerationSpec.Name was set to MemberName (raw identifier) instead of NameSpecifiedInSourceCode (includes @ prefix for reserved keywords).

Fix: Single line change in JsonSourceGenerator.Parser.cs:

// Before
Name = property.MemberName,
// After  
Name = property.NameSpecifiedInSourceCode,

Repro:

record A { public A? @else { get; init; } }

[JsonSerializable(typeof(A))]
partial class Ctx : JsonSerializerContext;

Previously generated invalid code: new A(){ else = ... } instead of new A(){ @else = ... }.

Customer Impact

Any type with init-only properties using C# reserved keywords as names fails to compile with source generation.

Regression

No, this is a long-standing bug in the source generator.

Testing

  • Added unit test InitOnlyPropertyWithReservedKeywordName_CompilesSuccessfully
  • All 153 source generator unit tests pass

Risk

Low. Single line change affecting only the name used in generated property initializers. The fix uses the same NameSpecifiedInSourceCode property already used elsewhere in the generator for the same purpose.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

Original prompt

This section details on the original issue you should resolve

<issue_title>JsonSourceGenerator misinterprets @ verbatim identifiers.</issue_title>
<issue_description>### Description

JsonSourceGenerator does not correctly handle C# verbatim identifiers and confuses them during code generation.

Reproduction Steps

$ cat <<EOF | dotnet run -
using System.Text.Json;
using System.Text.Json.Serialization;
Console.Write(JsonSerializer.Deserialize("""{"else":{}}""",Ctx.Default.A));
[JsonSerializable(typeof(A))] partial class Ctx : JsonSerializerContext;
record A { public A? @else { get; init; } }
EOF
~/System.Text.Json.SourceGeneration/System.Text.Json.SourceGeneration.JsonSourceGenerator/Ctx.A.g.cs(41,9): error CS8802: Only one compilation unit can have top-level statements.

The build failed. Fix the build errors and run again.

Expected behavior

$ cat <<EOF | dotnet run -
using System.Text.Json;
using System.Text.Json.Serialization;
Console.Write(JsonSerializer.Deserialize("""{"else":{}}""",Ctx.Default.A));
[JsonSerializable(typeof(A))] partial class Ctx : JsonSerializerContext;
record A { public A? @else { get; init; } }
EOF
A { else = A { else =  } }

Actual behavior

.

Regression?

No response

Known Workarounds

$ cat <<EOF | dotnet run -
#:property PublishAot=false
using System.Text.Json;
Console.Write(JsonSerializer.Deserialize<A>("""{"else":{}}"""));
record A { public A? @else { get; init; } }
EOF
A { else = A { else =  } }
$ cat <<EOF | dotnet run -
using System.Text.Json;
using System.Text.Json.Serialization;
Console.Write(JsonSerializer.Deserialize("""{"else":{}}""",Ctx.Default.A));
[JsonSerializable(typeof(A))] partial class Ctx : JsonSerializerContext;
record A { [JsonPropertyName("else")] public A? Else { get; init; } }
EOF
A { Else = A { Else =  } }

Configuration

$ dotnet --version
10.0.100

Other information

No response</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

…ializers

Fix #116507: C# verbatim identifiers like @else are now correctly handled
when generating property initializers for init-only properties. The fix
changes PropertyInitializerGenerationSpec.Name to use NameSpecifiedInSourceCode
(which includes the @ prefix for reserved keywords) instead of MemberName.

Also added a unit test to verify this scenario works correctly.

Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix JsonSourceGenerator handling of verbatim identifiers Fix JsonSourceGenerator verbatim identifier handling in property initializers Dec 26, 2025
Copilot AI requested a review from stephentoub December 26, 2025 02:57
@stephentoub stephentoub marked this pull request as ready for review December 26, 2025 03:26
Copilot AI review requested due to automatic review settings December 26, 2025 03:26
@dotnet-policy-service
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.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug in the JsonSourceGenerator where verbatim identifiers (e.g., @else) for C# reserved keywords were not properly handled when generating property initializers for init-only properties, causing compilation errors.

Key changes:

  • Changed PropertyInitializerGenerationSpec.Name to use NameSpecifiedInSourceCode instead of MemberName to preserve the @ prefix for reserved keywords
  • Added regression test for init-only properties with reserved keyword names

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs Fixed property initializer generation to use NameSpecifiedInSourceCode which includes the @ prefix for verbatim identifiers
src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorTests.cs Added regression test InitOnlyPropertyWithReservedKeywordName_CompilesSuccessfully to verify the fix

[Fact]
public void InitOnlyPropertyWithReservedKeywordName_CompilesSuccessfully()
{
// Regression test for https://github.com/dotnet/runtime/issues/116507
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue number in this comment (116507) doesn't match the issue number mentioned in the PR description (122732). Please verify which issue number is correct and update the comment accordingly.

Suggested change
// Regression test for https://github.com/dotnet/runtime/issues/116507
// Regression test for https://github.com/dotnet/runtime/issues/122732

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JsonSourceGenerator misinterprets @ verbatim identifiers.

2 participants