From 14ff1c8584e88abb4a9289a1d6921f79876c099b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 15 Nov 2024 14:34:38 -0800 Subject: [PATCH] Fix printing of the preamble in generated Rust code. (#1087) In the generated Rust bindings, Generate the preamble comments in a separate string, because `prettyplease` does not preserve comments. Also, add several more options to the preamble printing code. Fixes #1086. --- crates/rust/src/lib.rs | 76 +++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/crates/rust/src/lib.rs b/crates/rust/src/lib.rs index 6edb6be27..e68994878 100644 --- a/crates/rust/src/lib.rs +++ b/crates/rust/src/lib.rs @@ -27,6 +27,7 @@ struct InterfaceName { #[derive(Default)] struct RustWasm { types: Types, + src_preamble: Source, src: Source, opts: Opts, import_modules: Vec<(String, Vec)>, @@ -837,44 +838,90 @@ macro_rules! __export_{world_name}_impl {{ impl WorldGenerator for RustWasm { fn preprocess(&mut self, resolve: &Resolve, world: WorldId) { - wit_bindgen_core::generated_preamble(&mut self.src, env!("CARGO_PKG_VERSION")); + wit_bindgen_core::generated_preamble(&mut self.src_preamble, env!("CARGO_PKG_VERSION")); // Render some generator options to assist with debugging and/or to help // recreate it if the original generation command is lost. - uwriteln!(self.src, "// Options used:"); + uwriteln!(self.src_preamble, "// Options used:"); if self.opts.std_feature { - uwriteln!(self.src, "// * std_feature"); + uwriteln!(self.src_preamble, "// * std_feature"); } if self.opts.raw_strings { - uwriteln!(self.src, "// * raw_strings"); + uwriteln!(self.src_preamble, "// * raw_strings"); } if !self.opts.skip.is_empty() { - uwriteln!(self.src, "// * skip: {:?}", self.opts.skip); + uwriteln!(self.src_preamble, "// * skip: {:?}", self.opts.skip); + } + if self.opts.stubs { + uwriteln!(self.src_preamble, "// * stubs"); + } + if let Some(export_prefix) = &self.opts.export_prefix { + uwriteln!( + self.src_preamble, + "// * export_prefix: {:?}", + export_prefix + ); + } + if let Some(runtime_path) = &self.opts.runtime_path { + uwriteln!(self.src_preamble, "// * runtime_path: {:?}", runtime_path); + } + if let Some(bitflags_path) = &self.opts.bitflags_path { + uwriteln!( + self.src_preamble, + "// * bitflags_path: {:?}", + bitflags_path + ); } if !matches!(self.opts.ownership, Ownership::Owning) { - uwriteln!(self.src, "// * ownership: {:?}", self.opts.ownership); + uwriteln!( + self.src_preamble, + "// * ownership: {:?}", + self.opts.ownership + ); } if !self.opts.additional_derive_attributes.is_empty() { uwriteln!( - self.src, + self.src_preamble, "// * additional derives {:?}", self.opts.additional_derive_attributes ); } for (k, v) in self.opts.with.iter() { - uwriteln!(self.src, "// * with {k:?} = {v}"); + uwriteln!(self.src_preamble, "// * with {k:?} = {v}"); + } + if let Some(type_section_suffix) = &self.opts.type_section_suffix { + uwriteln!( + self.src_preamble, + "// * type_section_suffix: {:?}", + type_section_suffix + ); } if let Some(default) = &self.opts.default_bindings_module { - uwriteln!(self.src, "// * default-bindings-module: {default:?}"); + uwriteln!( + self.src_preamble, + "// * default-bindings-module: {default:?}" + ); } if self.opts.disable_run_ctors_once_workaround { - uwriteln!(self.src, "// * disable-run-ctors-once-workaround"); + uwriteln!( + self.src_preamble, + "// * disable-run-ctors-once-workaround" + ); } if let Some(s) = &self.opts.export_macro_name { - uwriteln!(self.src, "// * export-macro-name: {s}"); + uwriteln!(self.src_preamble, "// * export-macro-name: {s}"); } if self.opts.pub_export_macro { - uwriteln!(self.src, "// * pub-export-macro"); + uwriteln!(self.src_preamble, "// * pub-export-macro"); + } + if self.opts.generate_unused_types { + uwriteln!(self.src_preamble, "// * generate_unused_types"); + } + if self.opts.disable_custom_section_link_helpers { + uwriteln!( + self.src_preamble, + "// * disable_custom_section_link_helpers" + ); } self.types.analyze(resolve); self.world = Some(world); @@ -1101,6 +1148,11 @@ impl WorldGenerator for RustWasm { *src.as_mut_string() = prettyplease::unparse(&syntax_tree); } + // Prepend the preamble. We do this after formatting because + // `syn::parse_file` + `prettyplease::unparse` does not preserve comments. + let src_preamble = mem::take(&mut self.src_preamble); + *src.as_mut_string() = format!("{}{}", src_preamble.as_str(), src.as_str()); + let module_name = name.to_snake_case(); files.push(&format!("{module_name}.rs"), src.as_bytes());