Emit inline source comments inside Typed Jerboa Rust bodies
ober
f1f3ad6a2fa87b8c9c2e29b1829045de5ddcf4f6
--- a/docs/jerboa-to-rust.md +++ b/docs/jerboa-to-rust.md @@ -108,7 +108,10 @@ Done in subsequent phases: ordinary `T` parameter positions (conservative). - Generated Rust source comments tied to typed source spans. Records, variants, resources, and defs emit `// source: path:line:column` comments above each - declaration when the parsed datum carries a source-location. + declaration when the parsed datum carries a source-location. Inside function + bodies, every `let`, `if`, and `match` IR node also emits an inline + `/* source: path:line:column */` block comment so the compiler-reported Rust + line can be mapped back to typed source. Still open: @@ -116,8 +119,6 @@ Still open: inlines all modules into a single `lib.rs`. - Direct `rustc` / static binary integration polish and eventual LLVM parity tests. Today the build goes through `cargo build` only. -- Expression-level source comments inside function bodies (only the - declaration headers carry source spans today). - Cross-module `use` declarations and per-module Rust files for richer workspaces. @@ -548,12 +549,13 @@ pub fn rope_insert(...) -> Rope { ... } ``` Current landing: records, variants, resources, and defs each emit a -`// source: path:line:column` comment above their generated declaration. The -checker already threads spans through `typed-check-error-source`, so future -work can wire expression-level spans into intra-body comments as well as -richer source maps. When Rust compilation fails, a developer can map the -reported file to the typed source through these comments. Mapping cargo -errors directly back to typed source line and column remains future work. +`// source: path:line:column` comment above their generated declaration, and +inside function bodies every `let`, `if`, and `match` IR node emits an inline +`/* source: path:line:column */` block comment so the compiler-reported Rust +line maps back to typed source. The checker already threads spans through +`typed-check-error-source` so future work can wire even finer expression-level +maps (call sites, let-binding right-hand sides) and richer cargo-error +remapping. ## Build Integration --- a/lib/jerboa/typed/rust.ss +++ b/lib/jerboa/typed/rust.ss @@ -86,6 +86,19 @@ (when text (write-line port level text)))) + (def (rust-inline-source-comment source) + (cond + [(source-location? source) + (string-append + "/* source: " + (or (source-location-path source) "<unknown>") + ":" + (number->string (source-location-line source)) + ":" + (number->string (source-location-column source)) + " */ ")] + [else ""])) + (def rust-keywords '("as" "break" "const" "continue" "crate" "else" "enum" "extern" "false" "fn" "for" "if" "impl" "in" "let" "loop" "match" "mod" @@ -1369,6 +1382,7 @@ (def (emit-ir-let ir) (string-append "{ " + (rust-inline-source-comment (typed-ir-node-source ir)) (join-strings (append (map (lambda (binding) @@ -1385,6 +1399,7 @@ (def (emit-ir-if ir) (string-append + (rust-inline-source-comment (typed-ir-node-source ir)) "if " (emit-expression (typed-ir-if-test ir)) " { " @@ -1419,6 +1434,7 @@ (and default (string-append "_ => " (emit-begin default) ","))]) (string-append + (rust-inline-source-comment (typed-ir-node-source ir)) "match " (emit-expression target) " { " --- a/tests/test-typed-rust.ss +++ b/tests/test-typed-rust.ss @@ -575,6 +575,21 @@ (not (substring? calc-rust "// source:")) #t) +(define annotated-control-form + (car (jerboa-read-file "tests/fixtures/typed/valid-split-tree.ss"))) + +(define annotated-control-rust + (typed-library-form->rust-string annotated-control-form)) + +(test "rust emits inline source comments above match/if/let in bodies" + (and + (substring? annotated-control-rust + "/* source: tests/fixtures/typed/valid-split-tree.ss:") + (or (substring? annotated-control-rust "*/ match ") + (substring? annotated-control-rust "*/ if ") + (substring? annotated-control-rust "*/ {"))) + #t) + (printf "~%Typed Rust emitter: ~a passed, ~a failed~%" pass fail) (when (> fail 0) (exit 1))