Skip to content

Commit

Permalink
Fix printing of the preamble in generated Rust code. (#1087)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sunfishcode authored Nov 15, 2024
1 parent af2d6e8 commit 14ff1c8
Showing 1 changed file with 64 additions and 12 deletions.
76 changes: 64 additions & 12 deletions crates/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct InterfaceName {
#[derive(Default)]
struct RustWasm {
types: Types,
src_preamble: Source,
src: Source,
opts: Opts,
import_modules: Vec<(String, Vec<String>)>,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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());

Expand Down

0 comments on commit 14ff1c8

Please sign in to comment.