Skip to content

fix(csharp-codegen): escape C# reserved keywords in generated identifiers#4535

Merged
rekhoff merged 4 commits intoclockworklabs:masterfrom
stablegenius49:fix/csharp-escape-keywords-4529
Mar 20, 2026
Merged

fix(csharp-codegen): escape C# reserved keywords in generated identifiers#4535
rekhoff merged 4 commits intoclockworklabs:masterfrom
stablegenius49:fix/csharp-escape-keywords-4529

Conversation

@stablegenius49
Copy link
Contributor

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:

[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:

// 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

@CLAassistant
Copy link

CLAassistant commented Mar 3, 2026

CLA assistant check
All committers have signed the CLA.

@bfops bfops requested a review from rekhoff March 3, 2026 18:06
@bfops
Copy link
Collaborator

bfops commented Mar 3, 2026

Thank you for opening a PR for this! We'll work on getting it reviewed.

…iers

- Add Identifier property to MemberDeclaration that prefixes C# keywords with @

- Use SyntaxFacts.GetKeywordKind to detect reserved keywords

- Update all code generation sites to use Identifier instead of Name

- Add test for keyword field names (class, params) in tables/reducers/procedures

Fixes clockworklabs#4529
@stablegenius49 stablegenius49 force-pushed the fix/csharp-escape-keywords-4529 branch from 0bd05ba to e49364a Compare March 5, 2026 20:00
@stablegenius49
Copy link
Contributor Author

I’ve pushed an update that rebases this PR onto current and resolves merge conflicts while preserving the C# keyword-escaping changes.\n\nWould appreciate a fresh pass when you have a moment. Thanks!

@stablegenius49
Copy link
Contributor Author

Follow-up correction: rebased onto latest master and resolved conflicts.

@stablegenius49
Copy link
Contributor Author

CLA is now signed ✅. Could a maintainer please re-run/approve the PR workflows? The latest workflow runs are currently in action_required state from the fork-trigger guard.

rekhoff added 2 commits March 16, 2026 14:29
… and lint issues

* Changed `IEquatable<{ShortName}>` to `IEquatable<{ShortNameIdentifier}`> to handle keyword type names.
* Fixed `GenerateReadOnlyAccessorFilters()` to use `identifierName` (escaped) instead of raw `name`
* Used different reserved keywords `event` and `params` in test to avoid `CS0542` and `CS0229` errors for duplicate accessor names.
* Corrected some lint issues.
Copy link
Contributor

@rekhoff rekhoff left a comment

Choose a reason for hiding this comment

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

Reviewed and tested changes. Looks good to me. I have pushed a few changes on some issues, and now all CI jobs are passing. I am marking this PR as approved to merge. I apricate the test being included, thanks for the submission!

@rekhoff rekhoff added this pull request to the merge queue Mar 19, 2026
Merged via the queue into clockworklabs:master with commit 31b9af3 Mar 20, 2026
47 of 48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[C#] Parameter with name params and class should be prefixed with @

4 participants