Merge pull request #399 from dtolnay/block
Preserve meaning of block boundaries
diff --git a/gen/src/block.rs b/gen/src/block.rs
new file mode 100644
index 0000000..e7f7c63
--- /dev/null
+++ b/gen/src/block.rs
@@ -0,0 +1,44 @@
+use proc_macro2::Ident;
+
+pub enum Block {
+ AnonymousNamespace,
+ Namespace(&'static str),
+ UserDefinedNamespace(Ident),
+ InlineNamespace(&'static str),
+ ExternC,
+}
+
+impl Block {
+ pub fn write_begin(&self, out: &mut String) {
+ if let Block::InlineNamespace(_) = self {
+ out.push_str("inline ");
+ }
+ self.write_common(out);
+ out.push_str(" {\n");
+ }
+
+ pub fn write_end(&self, out: &mut String) {
+ out.push_str("} // ");
+ self.write_common(out);
+ out.push('\n');
+ }
+
+ fn write_common(&self, out: &mut String) {
+ match self {
+ Block::AnonymousNamespace => out.push_str("namespace"),
+ Block::Namespace(name) => {
+ out.push_str("namespace ");
+ out.push_str(name);
+ }
+ Block::UserDefinedNamespace(name) => {
+ out.push_str("namespace ");
+ out.push_str(&name.to_string());
+ }
+ Block::InlineNamespace(name) => {
+ out.push_str("namespace ");
+ out.push_str(name);
+ }
+ Block::ExternC => out.push_str("extern \"C\""),
+ }
+ }
+}
diff --git a/gen/src/builtin.rs b/gen/src/builtin.rs
index 448b6f8..e755e10 100644
--- a/gen/src/builtin.rs
+++ b/gen/src/builtin.rs
@@ -1,3 +1,4 @@
+use crate::gen::block::Block;
use crate::gen::ifndef;
use crate::gen::out::{Content, OutFile};
@@ -39,8 +40,8 @@
let builtin = &mut out.builtin;
let out = &mut builtin.content;
- out.begin_block("namespace rust");
- out.begin_block("inline namespace cxxbridge05");
+ out.begin_block(Block::Namespace("rust"));
+ out.begin_block(Block::InlineNamespace("cxxbridge05"));
writeln!(out, "// #include \"rust/cxx.h\"");
ifndef::write(out, builtin.panic, "CXXBRIDGE05_PANIC");
@@ -51,10 +52,10 @@
}
if builtin.rust_error {
- out.begin_block("namespace");
+ out.begin_block(Block::AnonymousNamespace);
writeln!(out, "template <typename T>");
writeln!(out, "class impl;");
- out.end_block("namespace");
+ out.end_block(Block::AnonymousNamespace);
}
ifndef::write(out, builtin.rust_string, "CXXBRIDGE05_RUST_STRING");
@@ -91,15 +92,15 @@
writeln!(out, "}};");
}
- out.begin_block("namespace");
+ out.begin_block(Block::AnonymousNamespace);
if builtin.ptr_len {
- out.begin_block("namespace repr");
+ out.begin_block(Block::Namespace("repr"));
writeln!(out, "struct PtrLen final {{");
writeln!(out, " const void *ptr;");
writeln!(out, " size_t len;");
writeln!(out, "}};");
- out.end_block("namespace repr");
+ out.end_block(Block::Namespace("repr"));
}
if builtin.rust_str_new_unchecked || builtin.rust_str_repr {
@@ -167,11 +168,11 @@
writeln!(out, "}};");
}
- out.end_block("namespace");
- out.end_block("namespace cxxbridge05");
+ out.end_block(Block::AnonymousNamespace);
+ out.end_block(Block::InlineNamespace("cxxbridge05"));
if builtin.trycatch {
- out.begin_block("namespace behavior");
+ out.begin_block(Block::Namespace("behavior"));
include.exception = true;
include.type_traits = true;
include.utility = true;
@@ -190,8 +191,8 @@
writeln!(out, "}} catch (const ::std::exception &e) {{");
writeln!(out, " fail(e.what());");
writeln!(out, "}}");
- out.end_block("namespace behavior");
+ out.end_block(Block::Namespace("behavior"));
}
- out.end_block("namespace rust");
+ out.end_block(Block::Namespace("rust"));
}
diff --git a/gen/src/mod.rs b/gen/src/mod.rs
index a4a159d..8626058 100644
--- a/gen/src/mod.rs
+++ b/gen/src/mod.rs
@@ -2,6 +2,7 @@
// the cxxbridge CLI command.
mod alphasort;
+mod block;
mod builtin;
mod check;
pub(super) mod error;
diff --git a/gen/src/out.rs b/gen/src/out.rs
index 6ba44aa..606a586 100644
--- a/gen/src/out.rs
+++ b/gen/src/out.rs
@@ -1,3 +1,4 @@
+use crate::gen::block::Block;
use crate::gen::builtin::Builtins;
use crate::gen::include::Includes;
use crate::gen::Opt;
@@ -18,7 +19,7 @@
pub struct Content {
bytes: String,
section_pending: bool,
- blocks_pending: Vec<String>,
+ blocks_pending: Vec<Block>,
}
impl<'a> OutFile<'a> {
@@ -38,11 +39,11 @@
self.content.get_mut().next_section();
}
- pub fn begin_block(&mut self, block: &str) {
+ pub fn begin_block(&mut self, block: Block) {
self.content.get_mut().begin_block(block);
}
- pub fn end_block(&mut self, block: &str) {
+ pub fn end_block(&mut self, block: Block) {
self.content.get_mut().end_block(block);
}
@@ -95,15 +96,13 @@
self.section_pending = true;
}
- pub fn begin_block(&mut self, block: &str) {
- self.blocks_pending.push(block.to_owned());
+ pub fn begin_block(&mut self, block: Block) {
+ self.blocks_pending.push(block);
}
- pub fn end_block(&mut self, block: &str) {
+ pub fn end_block(&mut self, block: Block) {
if self.blocks_pending.pop().is_none() {
- self.bytes.push_str("} // ");
- self.bytes.push_str(block);
- self.bytes.push('\n');
+ Block::write_end(&block, &mut self.bytes);
self.section_pending = true;
}
}
@@ -119,8 +118,7 @@
self.bytes.push('\n');
}
for block in self.blocks_pending.drain(..) {
- self.bytes.push_str(&block);
- self.bytes.push_str(" {\n");
+ Block::write_begin(&block, &mut self.bytes);
}
self.section_pending = false;
} else if self.section_pending {
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 57c699c..a1f168f 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -1,4 +1,5 @@
use crate::gen::alphasort::NamespaceEntries;
+use crate::gen::block::Block;
use crate::gen::out::OutFile;
use crate::gen::{builtin, include, Opt};
use crate::syntax::atom::Atom::{self, *};
@@ -107,7 +108,7 @@
}
if !out.header {
- out.begin_block("extern \"C\"");
+ out.begin_block(Block::ExternC);
write_exception_glue(out, apis);
for api in apis {
match api {
@@ -116,7 +117,7 @@
_ => {}
}
}
- out.end_block("extern \"C\"");
+ out.end_block(Block::ExternC);
}
for api in apis {
@@ -127,10 +128,9 @@
}
for (namespace, nested_ns_entries) in ns_entries.nested_content() {
- let block = format!("namespace {}", namespace);
- out.begin_block(&block);
+ out.begin_block(Block::UserDefinedNamespace(namespace.clone()));
gen_namespace_contents(out, nested_ns_entries);
- out.end_block(&block);
+ out.end_block(Block::UserDefinedNamespace(namespace.clone()));
}
}
@@ -973,7 +973,7 @@
}
fn write_generic_instantiations(out: &mut OutFile) {
- out.begin_block("extern \"C\"");
+ out.begin_block(Block::ExternC);
for ty in out.types {
if let Type::RustBox(ty) = ty {
if let Type::Ident(inner) = &ty.inner {
@@ -1009,10 +1009,10 @@
}
}
}
- out.end_block("extern \"C\"");
+ out.end_block(Block::ExternC);
- out.begin_block("namespace rust");
- out.begin_block("inline namespace cxxbridge05");
+ out.begin_block(Block::Namespace("rust"));
+ out.begin_block(Block::InlineNamespace("cxxbridge05"));
for ty in out.types {
if let Type::RustBox(ty) = ty {
if let Type::Ident(inner) = &ty.inner {
@@ -1026,8 +1026,8 @@
}
}
}
- out.end_block("namespace cxxbridge05");
- out.end_block("namespace rust");
+ out.end_block(Block::InlineNamespace("cxxbridge05"));
+ out.end_block(Block::Namespace("rust"));
}
fn write_rust_box_extern(out: &mut OutFile, ident: &CppName) {