Why
Follow-ups from review of #29. Individually small, collectively they make the codegen path fragile for external extension authors:
- Empty
prewarm generates non-compiling guest Rust. generate_rust_code emits let modules = {:?}; (boomslang-hostgen/src/lib.rs:529); with no prewarm entries that's let modules = [];, which fails type inference (E0282) against pyo3's generic Python::import. The DSL makes prewarm optional and demo_async has none, so this is one include! away from a user hitting it. Fix: emit let modules: [&str; N] or skip the loop when empty.
- Validation gaps in
validate_manifest (lib.rs:306-344). No duplicate-function-name check, no duplicate-param check, no cross-convention collision check (foo_bar vs fooBar both map to Java fooBar / Rust foo_bar_handler), no collision check against generated identifiers (register, prewarm, MAX_RESULT, the py_ wrapper prefix). All pass validation and explode later as confusing compile errors.
- Inconsistent panic behavior in the library API.
generate_rust_host_code validates; generate_rust_code/generate_java_code don't and hit panic!/.expect on bad input (lib.rs:692-696, lib.rs:1087) depending on entry point. Safe via Build::generate() and the CLI, but the library surface shouldn't panic on user data.
- Async Java template indentation + zero compiled coverage.
{% if has_async -%} at templates/java_host_functions.java:47,58 strips indentation, so async-only members land at column 0 (valid Java, fails prettier). There is no compiled or golden coverage of async Java output — only contains assertions (src/tests.rs:223-235). The stock golden test can't catch it because the stock extension has no async functions.
- Java/Rust host semantic divergence. (a) Java
cancel() still delivers a completion if the canceled future finishes (AsyncHostRegistry.java:124-127), Rust suppresses it (templates/rust_host.rs:286-297). (b) On async handler error, generated Java propagates the real message via startFailed(e) while generated Rust returns -1 and the guest sees only "async host call failed" (lib.rs:920-925). (c) Generated Java reads params outside the try (trap on bad ptr/len) where the Rust host maps the same failure to -1. Pick one behavior per case.
- Docs nit:
examples/custom-python-build/README.md suggests emit_java_host("../../core/src/main/java", ...) from build.rs — writing into another module's source tree during cargo build, which breaks read-only checkouts (e.g. Nix) and build caching. Document the CLI-after-build flow as the supported path.
Why
Follow-ups from review of #29. Individually small, collectively they make the codegen path fragile for external extension authors:
prewarmgenerates non-compiling guest Rust.generate_rust_codeemitslet modules = {:?};(boomslang-hostgen/src/lib.rs:529); with no prewarm entries that'slet modules = [];, which fails type inference (E0282) against pyo3's genericPython::import. The DSL makesprewarmoptional anddemo_asynchas none, so this is oneinclude!away from a user hitting it. Fix: emitlet modules: [&str; N]or skip the loop when empty.validate_manifest(lib.rs:306-344). No duplicate-function-name check, no duplicate-param check, no cross-convention collision check (foo_barvsfooBarboth map to JavafooBar/ Rustfoo_bar_handler), no collision check against generated identifiers (register,prewarm,MAX_RESULT, thepy_wrapper prefix). All pass validation and explode later as confusing compile errors.generate_rust_host_codevalidates;generate_rust_code/generate_java_codedon't and hitpanic!/.expecton bad input (lib.rs:692-696,lib.rs:1087) depending on entry point. Safe viaBuild::generate()and the CLI, but the library surface shouldn't panic on user data.{% if has_async -%}attemplates/java_host_functions.java:47,58strips indentation, so async-only members land at column 0 (valid Java, fails prettier). There is no compiled or golden coverage of async Java output — onlycontainsassertions (src/tests.rs:223-235). The stock golden test can't catch it because the stock extension has no async functions.cancel()still delivers a completion if the canceled future finishes (AsyncHostRegistry.java:124-127), Rust suppresses it (templates/rust_host.rs:286-297). (b) On async handler error, generated Java propagates the real message viastartFailed(e)while generated Rust returns-1and the guest sees only "async host call failed" (lib.rs:920-925). (c) Generated Java reads params outside thetry(trap on bad ptr/len) where the Rust host maps the same failure to-1. Pick one behavior per case.examples/custom-python-build/README.mdsuggestsemit_java_host("../../core/src/main/java", ...)frombuild.rs— writing into another module's source tree duringcargo build, which breaks read-only checkouts (e.g. Nix) and build caching. Document the CLI-after-build flow as the supported path.