[NS 1] Add sub-module mounts support + codegen#5167
Conversation
a5dfaf5 to
c8cac1d
Compare
gefjon
left a comment
There was a problem hiding this comment.
I'm really unhappy with the codegen changes in both TypeScript and C++ here. The TypeScript changes seem very complicated and finnickey, and the C++ changes are an obviously brittle special case. I don't understand why we don't just move to generating a single file for the whole module, if generating individual files and importing across them is causing so many problems.
f9b867e to
048cb53
Compare
048cb53 to
785a446
Compare
JasonAtClockwork
left a comment
There was a problem hiding this comment.
The C++ side is working, I've also come up with two options to make it cleaner when we fully integrate the C++ sub-modules.
|
|
||
| export type ModuleDef = { | ||
| [S in RawModuleDefV10Section as Uncapitalize<S['tag']>]: S['value']; | ||
| typespace: Typespace; |
There was a problem hiding this comment.
check if this is still necessary
| fn write_type_builder_field( | ||
| module: &ModuleDef, | ||
| out: &mut Indenter, | ||
| type_name: &str, |
|
|
||
| if needs_getter { | ||
| writeln!(out, "get {name}() {{"); | ||
| if type_name == "RawModuleMountV10" && name == "module" { |
There was a problem hiding this comment.
Move this to crates/codegen/examples/regen-typescript-moduledef.rs
|
|
||
| for mount in mounts { | ||
| if let Err(e) = Identifier::new(mount.namespace.clone().into()) { | ||
| errors.push(ValidationError::IdentifierError { error: e }); |
There was a problem hiding this comment.
Use the new validation function
| raw_module_def_version: RawModuleDefVersion, | ||
|
|
||
| /// Mounted submodules, keyed by the namespace they are mounted under. | ||
| mounts: IndexMap<String, ModuleDef>, |
There was a problem hiding this comment.
Rename mounts -> submodules everywhere
cloutiertyler
left a comment
There was a problem hiding this comment.
Alessandro and I went over this in person. I think this looks good. There's a few nits we talked about.
I would also like to add any new syntax we have to module-test-ts.
Description of Changes
Add a new recursive "mounts" field to add submodules to module def. Handle code generation for each language.
Handle identifiers with "/" or "." in the name to handle namespaced reducers (e.g. lib/reducer) and namespaced tables (lib.table).
Handle code generation for the recursive type. This needed some special handling in code generation for typescript and c++.
Typescript codegen in particular is quite complex as it tries to handle circular dependency generically. C++ on the other hand is a lot simpler because it hard-codes a special handling of the V10 definition but doesn't solve circular dependencies in general.
I would advice against solving circular dependencies in a generic way for C++ however we could consider modifying the typescript code gen to just have special handling for the V10 recursive definition which would simplify the code quite a lot. I went down the rabbit hole of handling this generically and came out on the other side, but if there is strong opinion to keep the codegen code simple, I am happy to revisit and align to the C++ way.
API and ABI breaking changes
The change is purely additive and newer host versions will accept older module defs. However older host versions will not accept new module defs.
Expected complexity level and risk
5 - While this specific PR is maybe a 4, the overall namespace change is definitely 5. This is a pretty significant change. It's a large diff which touches the module def and changes code that hasn't been touched in a long time (e.g. Identifier).
Testing
Beyond the rust tests defined in this PR, the following tests were done on the full PR sequence once the entire namespace feature was implemented for typescript:
Feature Test Checklist
Module:
Client
CLI
Migration
Commit Log