Stable Genius 31b9af3da3
fix(csharp-codegen): escape C# reserved keywords in generated identifiers (#4535)
## Summary

This PR fixes an issue where C# reserved keywords (like `params`,
`class`, `event`, etc.) used as field or parameter names in SpacetimeDB
types would cause compilation errors in the generated code.

## Problem

When a user defines a table or reducer with a field named using a C#
reserved keyword:

```csharp
[SpacetimeDB.Table]
public partial struct MyTable
{
    public int @params;  // User escapes it in their code
    public string @class;
}
```

The codegen would generate invalid C# like:

```csharp
// Generated code (broken)
public int params;  // Error: keyword used as identifier
public void Read(BinaryReader reader) {
    params = ...;  // Error
}
```

## Solution

1. Added an `Identifier` property to `MemberDeclaration` in the codegen
that automatically detects C# reserved keywords using
`SyntaxFacts.GetKeywordKind()` and prefixes them with `@` when needed.

2. Updated all code generation sites to use `Identifier` instead of
`Name` when generating:
   - Field declarations
   - Property accessors
   - Constructor parameters
   - BSATN serialization code
   - Index accessors
   - Reducer/procedure parameters

3. Added a regression test that verifies tables, reducers, and
procedures with keyword field names compile successfully.

## Test Plan

- Added `CSharpKeywordIdentifiersAreEscapedInGeneratedCode` test that
creates a table with `@class` and `@params` fields, plus a reducer and
procedure with keyword parameters
- Existing tests continue to pass (verified locally with
`FormerlyForbiddenFieldNames` fixture which already tests edge cases
like `Read`, `Write`, `GetAlgebraicType`)

Fixes #4529

---------

Co-authored-by: Stable Genius <259448942+stablegenius49@users.noreply.github.com>
Co-authored-by: Ryan <r.ekhoff@clockworklabs.io>
2026-03-19 21:54:50 +00:00
..
2026-03-03 11:06:52 +00:00
2026-03-19 17:47:00 +00:00
2026-03-03 11:06:52 +00:00
2026-03-19 17:47:00 +00:00
2026-03-19 17:47:00 +00:00
2026-03-19 17:47:00 +00:00
2026-03-19 17:47:00 +00:00
2026-03-03 11:06:52 +00:00
2026-03-03 11:06:52 +00:00
2026-03-19 16:50:28 +00:00
2026-03-03 11:06:52 +00:00
2026-03-03 11:06:52 +00:00
2026-03-03 11:06:52 +00:00
2026-03-19 17:47:00 +00:00
2026-03-03 11:06:52 +00:00
2026-03-03 11:06:52 +00:00