Skip to content

Restore switch expression in EscapeIdentifier and add test coverage - #151

Merged
paulirwin merged 1 commit into
masterfrom
escape-identifier-tests
Aug 14, 2026
Merged

paulirwin merged 1 commit into
masterfrom
escape-identifier-tests

Conversation

@paulirwin

Copy link
Copy Markdown
Owner

Follow-up to #142 (thanks @lordmilko!), which fixed the crash on identifiers named after C# keywords (#147) but converted the switch expression into a switch statement.

Changes

Restore the switch expression. Same 77 keywords as merged in #142 — verified identical by diffing the extracted keyword sets — just written back as a switch expression with the or patterns split across lines so the list stays readable.

Add EscapeIdentifierTests. #142 had no tests, so this adds them:

  • Exhaustive keyword coverage — drives every reserved keyword from SyntaxFacts.GetReservedKeywordKinds() rather than a hand-maintained list, asserting each one is escaped and that the result parses back as an IdentifierToken. This is the test that matters: it fails if the language ever gains a keyword we don't escape, so the list can't silently drift.
  • Negative cases — non-keywords pass through unchanged, including contextual keywords like var, record and value, which are legal identifiers and must not be escaped.
  • End-to-end regression tests for MethodDeclarationVisitor.VisitInternal Crashing Processing Parameter Named "struct" #147 — method parameters (the original Structure struct crash), constructor parameters, lambda parameters and field accesses named after keywords, plus a check that the emitted C# parses with zero diagnostics.

Confirmed the tests are meaningful: against the pre-#142 keyword list they produce 113 failures; against master they all pass.

Note

The exhaustive check excludes the four undocumented typed-reference keywords (__arglist, __makeref, __reftype, __refvalue). Roslyn reports them as reserved, but they aren't on the MS keywords page and aren't valid Java identifiers, so they can't reach EscapeIdentifier from a parsed source file. @-escaping them doesn't produce an identifier token either, so treating them as escapable would be wrong.

Full suite: 247 passing.

🤖 Generated with Claude Code

Follow-up to #142, which fixed the crash on identifiers named after C#
keywords (#147) but converted the switch expression to a switch statement.

Convert it back to a switch expression with the new cases included, with
the `or` patterns wrapped across lines for readability. The keyword set is
unchanged (verified identical, 77 keywords).

Add EscapeIdentifierTests covering:

- every reserved keyword Roslyn knows about, asserting both that it gets
  escaped and that the result parses back as an IdentifierToken, so the
  list cannot silently drift from the language
- non-keywords, including contextual keywords like `var` and `record`,
  which must not be escaped
- end-to-end conversion of method, constructor and lambda parameters and
  field accesses named after keywords, plus a check that the emitted C#
  parses without diagnostics

The undocumented typed-reference keywords (__arglist, __makeref, __reftype,
__refvalue) are excluded from the exhaustive check, as they are not valid
Java identifiers and so cannot reach EscapeIdentifier from parsed source.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@paulirwin
paulirwin merged commit 0040a82 into master Aug 14, 2026
5 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.

1 participant