C1: Kotlin identifier utilities - #12
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a first-class set of Kotlin identifier utilities to kotlin-codegen so generators can reliably validate, sanitize, and escape names derived from external sources (Rust fields, C symbols, JSON keys) without each consumer reimplementing the logic.
Changes:
- Introduces
src/ident.rsimplementing hard-keyword detection, identifier/package validation, deterministic idempotent mangling, and backtick escaping. - Exposes the new identifier utilities from the crate root (
src/lib.rs) as part of the public API.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/lib.rs | Adds the ident module and re-exports the new identifier/public keyword APIs. |
| src/ident.rs | Implements Kotlin identifier/package helpers with doctests and unit tests for keyword behavior and mangling/escaping properties. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This was referenced Aug 6, 2026
A program generating Kotlin gets its names from somewhere else — a Rust
field, a C symbol, a JSON key — and some of those are never legal
Kotlin. This crate writes the file but offered nothing for dealing with
that, so every consumer has to reimplement it.
Add the primitives:
* is_valid_kotlin_ident / is_kotlin_hard_keyword / KOTLIN_HARD_KEYWORDS
* mangle_kotlin_ident — deterministic, idempotent
* mangle_kotlin_package, is_valid_kotlin_package
* escape_kotlin_ident — the back-tick strategy, which keeps the name
instead of changing it
Soft and modifier keywords (`data`, `value`, `inline`, `operator`) are
deliberately absent from the keyword list: they are contextual and are
valid identifiers, so mangling them would be wrong. A test pins that.
Two properties are tested rather than assumed: mangling always yields a
valid identifier, and is idempotent, over a table of awkward inputs.
Every function carries a doctest.
milyin
force-pushed
the
step/a5-external-body
branch
from
August 6, 2026 11:40
75908e0 to
d1c977f
Compare
milyin
force-pushed
the
step/c1-ident-utilities
branch
from
August 6, 2026 11:40
a84bed6 to
00a7282
Compare
milyin
changed the base branch from
step/a5-external-body
to
docs/validation-umbrella
August 6, 2026 11:41
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Step C1 of #6. Stacked on #11 — Part C begins.
A program generating Kotlin gets its names from somewhere else — a Rust field, a
C symbol, a JSON key — and some are never legal Kotlin. This crate writes the
file but offered nothing for dealing with that, so every consumer reimplements
it.
prebindgen-jnihas private copies of three of these today.is_valid_kotlin_identis_kotlin_hard_keyword/KOTLIN_HARD_KEYWORDSmangle_kotlin_identmy-name→my_name,2fast→_2fast,object→object_,""→_mangle_kotlin_package/is_valid_kotlin_packageescape_kotlin_ident`object`— keeps the name instead of changing itTwo decisions worth reviewing
Soft keywords are deliberately absent from the keyword list.
data,value,sealed,inline,operator,companionare contextual in Kotlinand are valid identifiers — mangling them would be wrong. A test pins that,
because it is the easy mistake to make when transcribing a keyword list.
Escaping is offered alongside mangling, not instead of it. Mangling changes
the name; back-ticks keep it. Which one a generator wants is its own business,
so both are available.
escape_kotlin_identalso strips the characters that areillegal even inside back-ticks (
`, line breaks, and the JVM's.;[]/<>:\), which is the part that is easy to get wrong.Verification
Two properties are tested rather than assumed, over a table of awkward inputs
(empty, leading digit, punctuation-only, non-ASCII, keywords): mangling always
produces a valid identifier, and mangling is idempotent. Same for packages.
Every public function carries a doctest — 6 doctests, 59 tests, clippy clean.