fix(codegen): emit valid, bindable WIT — kebab idents + defined types (#254)#255
Open
avrabe wants to merge 2 commits into
Open
fix(codegen): emit valid, bindable WIT — kebab idents + defined types (#254)#255avrabe wants to merge 2 commits into
avrabe wants to merge 2 commits into
Conversation
…#254) `spar codegen --format wit` emitted WIT that wasm-tools / wit-bindgen reject, so the generated interface could not be bound. Two causes: 1. Invalid identifiers. The WIT generator reused `sanitize_ident`, which produces Rust `snake_case` (underscores) — invalid in WIT, which is kebab-case. Package `wohl_matter:matter` and funcs like `on-message_in` (hyphen+underscore) failed `wasm-tools component wit` outright. 2. Undefined types. Ports referenced data types (`mattermessage`, …) that were never defined, and used `bytes`, which is not a WIT primitive. Fix: - Add `wit_ident()` — kebab-case WIT identifiers (separators -> hyphens, leading-digit words letter-prefixed, WIT keywords `%`-escaped) — and use it for package / interface / world / func / type / export names. - Emit a `type <name> = list<u8>;` alias for every data type a port references, so the interface resolves. Untyped ports use `list<u8>` (a valid primitive) instead of the non-primitive `bytes`. Per-type scalar-size refinement (8 bytes -> u64, etc.) needs scope access and is a tracked follow-up. - Add a regression guard that parses the generated WIT with `wit-parser` (Resolve::push_str — errors on bad idents OR undefined types), plus kebab-case unit tests for the exact #254 identifiers. Verified end-to-end: `wasm-tools 1.243.0 component wit` now round-trips the generated file (was: `error: invalid character in identifier '_'`). Closes #254. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rivet verification gate✅ 20/20 passed
Filter: Failed artifacts(none) Updated automatically by |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
cargo fmt — no behavior change. (Format CI check.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Fixes #254 —
spar codegen --format witemitted WIT thatwasm-tools/wit-bindgenreject, so the generated interface couldn't be bound (broke the spar-generates-WIT workflow on the wohl Matter seam).Root causes
sanitize_ident, which produces Rustsnake_case— but WIT is kebab-case. Packagewohl_matter:matterwas the first hard error; funcs likeon-message_inmix a hyphen prefix with an underscore (doubly invalid).mattermessage,monotonictime, …) that were never defined, and emittedbytes, which isn't a WIT primitive.Fix
wit_ident(): kebab-case WIT identifiers — separators → hyphens, leading-digit words letter-prefixed (WIT words must start with a letter), WIT keywords%-escaped. Used for package / interface / world / func / type / export names.type <name> = list<u8>;for every data type a port references so the interface resolves; untyped ports uselist<u8>(valid primitive) instead of non-primitivebytes.wit-parser(Resolve::push_strerrors on bad idents or undefined types), pluswit_identunit tests covering the exact codegen --format wit emits unbindable WIT: invalid identifiers (underscores) + undefined types #254 identifiers.Before → after (same model)
Verification
cargo test -p spar-codegen— 46 lib + 21 golden, 0 failures; newgenerated_wit_is_valid_and_bindable+wit_ident_kebab_casespass.wasm-tools 1.243.0 component wit(exact tool/version from codegen --format wit emits unbindable WIT: invalid identifiers (underscores) + undefined types #254) now round-trips the generated file — theinvalid character in identifier '_'error is gone.Follow-up (noted, out of scope)
Per-type scalar-size fidelity (8-byte
Data_Size→u64, etc., rather thanlist<u8>for everything) needsscopeaccess threaded into the generator; tracked for a later change. This PR makes the output valid and bindable, which is the blocking issue.🤖 Generated with Claude Code