From 99ac19cd8d6494ffd3f6b35ddd3024518d2b86e2 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 4 Jan 2024 12:06:21 -0700 Subject: [PATCH] skip automatic indentation inside comments This fixes broken indentation due to e.g. `wasi:io/streams#output-stream.blocking-write-and-flush`, which has a doc comment that contains curly brackets. This isn't generally a problem for Rust, which uses `rustfmt` if available, but leads to headaches for C if `clang-format` isn't handy. Signed-off-by: Joel Dice --- crates/core/src/source.rs | 35 +++++++++++++++++++++++------------ crates/go/src/interface.rs | 1 - 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/crates/core/src/source.rs b/crates/core/src/source.rs index 36a5b56e9..1b85620fa 100644 --- a/crates/core/src/source.rs +++ b/crates/core/src/source.rs @@ -37,36 +37,46 @@ impl Files { pub struct Source { s: String, indent: usize, + in_line_comment: bool, } impl Source { pub fn append_src(&mut self, src: &Source) { self.s.push_str(&src.s); self.indent += src.indent; + self.in_line_comment = src.in_line_comment; } pub fn push_str(&mut self, src: &str) { let lines = src.lines().collect::>(); for (i, line) in lines.iter().enumerate() { let trimmed = line.trim(); - if trimmed.starts_with('}') && self.s.ends_with(" ") { - self.s.pop(); - self.s.pop(); + if trimmed.starts_with("//") { + self.in_line_comment = true; + } + + if !self.in_line_comment { + if trimmed.starts_with('}') && self.s.ends_with(" ") { + self.s.pop(); + self.s.pop(); + } } self.s.push_str(if lines.len() == 1 { line } else { line.trim_start() }); - if trimmed.ends_with('{') { - self.indent += 1; - } - if trimmed.starts_with('}') { - // Note that a `saturating_sub` is used here to prevent a panic - // here in the case of invalid code being generated in debug - // mode. It's typically easier to debug those issues through - // looking at the source code rather than getting a panic. - self.indent = self.indent.saturating_sub(1); + if !self.in_line_comment { + if trimmed.ends_with('{') { + self.indent += 1; + } + if trimmed.starts_with('}') { + // Note that a `saturating_sub` is used here to prevent a panic + // here in the case of invalid code being generated in debug + // mode. It's typically easier to debug those issues through + // looking at the source code rather than getting a panic. + self.indent = self.indent.saturating_sub(1); + } } if i != lines.len() - 1 || src.ends_with('\n') { self.newline(); @@ -83,6 +93,7 @@ impl Source { } fn newline(&mut self) { + self.in_line_comment = false; self.s.push('\n'); for _ in 0..self.indent { self.s.push_str(" "); diff --git a/crates/go/src/interface.rs b/crates/go/src/interface.rs index f2270c329..918932f32 100644 --- a/crates/go/src/interface.rs +++ b/crates/go/src/interface.rs @@ -1073,7 +1073,6 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> { self.preamble .push_str(&format!("// typedef struct {c_typedef_target} ")); self.preamble.push_str("{"); - self.preamble.deindent(1); self.preamble.push_str("\n"); self.preamble.push_str("// int32_t __handle; \n"); self.preamble.push_str("// ");