Move CppName's namespace into Pair
diff --git a/gen/src/namespace.rs b/gen/src/namespace.rs
index a8b049f..7343875 100644
--- a/gen/src/namespace.rs
+++ b/gen/src/namespace.rs
@@ -4,10 +4,10 @@
impl Api {
pub fn namespace(&self) -> &Namespace {
match self {
- Api::CxxFunction(efn) | Api::RustFunction(efn) => &efn.ident.cxx.namespace,
- Api::CxxType(ety) | Api::RustType(ety) => &ety.ident.cxx.namespace,
- Api::Enum(enm) => &enm.ident.cxx.namespace,
- Api::Struct(strct) => &strct.ident.cxx.namespace,
+ Api::CxxFunction(efn) | Api::RustFunction(efn) => &efn.ident.namespace,
+ Api::CxxType(ety) | Api::RustType(ety) => &ety.ident.namespace,
+ Api::Enum(enm) => &enm.ident.namespace,
+ Api::Struct(strct) => &strct.ident.namespace,
Api::Impl(_) | Api::Include(_) | Api::TypeAlias(_) => Default::default(),
}
}
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 1cd6d07..7c16e81 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -5,8 +5,8 @@
use crate::syntax::atom::Atom::{self, *};
use crate::syntax::symbol::Symbol;
use crate::syntax::{
- mangle, Api, CppName, Enum, ExternFn, ExternType, ResolvableName, Signature, Struct, Type,
- Types, Var,
+ mangle, Api, Enum, ExternFn, ExternType, Pair, ResolvableName, Signature, Struct, Type, Types,
+ Var,
};
use proc_macro2::Ident;
use std::collections::HashMap;
@@ -47,10 +47,10 @@
for api in apis {
write!(out, "{:1$}", "", indent);
match api {
- Api::Struct(strct) => write_struct_decl(out, &strct.ident.cxx.ident),
+ Api::Struct(strct) => write_struct_decl(out, &strct.ident.cxx),
Api::Enum(enm) => write_enum_decl(out, enm),
- Api::CxxType(ety) => write_struct_using(out, &ety.ident.cxx),
- Api::RustType(ety) => write_struct_decl(out, &ety.ident.cxx.ident),
+ Api::CxxType(ety) => write_struct_using(out, &ety.ident),
+ Api::RustType(ety) => write_struct_decl(out, &ety.ident.cxx),
_ => unreachable!(),
}
}
@@ -106,7 +106,7 @@
for api in apis {
if let Api::TypeAlias(ety) = api {
if out.types.required_trivial.contains_key(&ety.ident.rust) {
- check_trivial_extern_type(out, &ety.ident.cxx)
+ check_trivial_extern_type(out, &ety.ident)
}
}
}
@@ -193,14 +193,14 @@
}
fn write_struct<'a>(out: &mut OutFile<'a>, strct: &'a Struct) {
- out.set_namespace(&strct.ident.cxx.namespace);
- let guard = format!("CXXBRIDGE05_STRUCT_{}", strct.ident.cxx.to_symbol());
+ out.set_namespace(&strct.ident.namespace);
+ let guard = format!("CXXBRIDGE05_STRUCT_{}", strct.ident.to_symbol());
writeln!(out, "#ifndef {}", guard);
writeln!(out, "#define {}", guard);
for line in strct.doc.to_string().lines() {
writeln!(out, "//{}", line);
}
- writeln!(out, "struct {} final {{", strct.ident.cxx.ident);
+ writeln!(out, "struct {} final {{", strct.ident.cxx);
for field in &strct.fields {
write!(out, " ");
write_type_space(out, &field.ty);
@@ -215,18 +215,13 @@
}
fn write_enum_decl(out: &mut OutFile, enm: &Enum) {
- write!(out, "enum class {} : ", enm.ident.cxx.ident);
+ write!(out, "enum class {} : ", enm.ident.cxx);
write_atom(out, enm.repr);
writeln!(out, ";");
}
-fn write_struct_using(out: &mut OutFile, ident: &CppName) {
- writeln!(
- out,
- "using {} = {};",
- ident.ident,
- ident.to_fully_qualified()
- );
+fn write_struct_using(out: &mut OutFile, ident: &Pair) {
+ writeln!(out, "using {} = {};", ident.cxx, ident.to_fully_qualified());
}
fn write_struct_with_methods<'a>(
@@ -234,24 +229,24 @@
ety: &'a ExternType,
methods: &[&ExternFn],
) {
- out.set_namespace(&ety.ident.cxx.namespace);
- let guard = format!("CXXBRIDGE05_STRUCT_{}", ety.ident.cxx.to_symbol());
+ out.set_namespace(&ety.ident.namespace);
+ let guard = format!("CXXBRIDGE05_STRUCT_{}", ety.ident.to_symbol());
writeln!(out, "#ifndef {}", guard);
writeln!(out, "#define {}", guard);
for line in ety.doc.to_string().lines() {
writeln!(out, "//{}", line);
}
- writeln!(out, "struct {} final {{", ety.ident.cxx.ident);
- writeln!(out, " {}() = delete;", ety.ident.cxx.ident);
+ writeln!(out, "struct {} final {{", ety.ident.cxx);
+ writeln!(out, " {}() = delete;", ety.ident.cxx);
writeln!(
out,
" {}(const {} &) = delete;",
- ety.ident.cxx.ident, ety.ident.cxx.ident
+ ety.ident.cxx, ety.ident.cxx,
);
for method in methods {
write!(out, " ");
let sig = &method.sig;
- let local_name = method.ident.cxx.ident.to_string();
+ let local_name = method.ident.cxx.to_string();
write_rust_function_shim_decl(out, &local_name, sig, false);
writeln!(out, ";");
}
@@ -260,14 +255,14 @@
}
fn write_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) {
- out.set_namespace(&enm.ident.cxx.namespace);
- let guard = format!("CXXBRIDGE05_ENUM_{}", enm.ident.cxx.to_symbol());
+ out.set_namespace(&enm.ident.namespace);
+ let guard = format!("CXXBRIDGE05_ENUM_{}", enm.ident.to_symbol());
writeln!(out, "#ifndef {}", guard);
writeln!(out, "#define {}", guard);
for line in enm.doc.to_string().lines() {
writeln!(out, "//{}", line);
}
- write!(out, "enum class {} : ", enm.ident.cxx.ident);
+ write!(out, "enum class {} : ", enm.ident.cxx);
write_atom(out, enm.repr);
writeln!(out, " {{");
for variant in &enm.variants {
@@ -278,12 +273,8 @@
}
fn check_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) {
- out.set_namespace(&enm.ident.cxx.namespace);
- write!(
- out,
- "static_assert(sizeof({}) == sizeof(",
- enm.ident.cxx.ident
- );
+ out.set_namespace(&enm.ident.namespace);
+ write!(out, "static_assert(sizeof({}) == sizeof(", enm.ident.cxx);
write_atom(out, enm.repr);
writeln!(out, "), \"incorrect size\");");
for variant in &enm.variants {
@@ -292,12 +283,12 @@
writeln!(
out,
">({}::{}) == {}, \"disagrees with the value in #[cxx::bridge]\");",
- enm.ident.cxx.ident, variant.ident, variant.discriminant,
+ enm.ident.cxx, variant.ident, variant.discriminant,
);
}
}
-fn check_trivial_extern_type(out: &mut OutFile, id: &CppName) {
+fn check_trivial_extern_type(out: &mut OutFile, id: &Pair) {
// NOTE: The following two static assertions are just nice-to-have and not
// necessary for soundness. That's because triviality is always declared by
// the user in the form of an unsafe impl of cxx::ExternType:
@@ -340,7 +331,7 @@
fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
out.next_section();
- out.set_namespace(&efn.ident.cxx.namespace);
+ out.set_namespace(&efn.ident.namespace);
out.begin_block(Block::ExternC);
if let Some(annotation) = &out.opt.cxx_impl_annotations {
write!(out, "{} ", annotation);
@@ -360,7 +351,7 @@
write!(
out,
"{} &self",
- out.types.resolve(&receiver.ty).to_fully_qualified()
+ out.types.resolve(&receiver.ty).to_fully_qualified(),
);
}
for (i, arg) in efn.args.iter().enumerate() {
@@ -391,7 +382,7 @@
out,
"({}::*{}$)(",
out.types.resolve(&receiver.ty).to_fully_qualified(),
- efn.ident.rust
+ efn.ident.rust,
),
}
for (i, arg) in efn.args.iter().enumerate() {
@@ -408,12 +399,12 @@
}
write!(out, " = ");
match &efn.receiver {
- None => write!(out, "{}", efn.ident.cxx.to_fully_qualified()),
+ None => write!(out, "{}", efn.ident.to_fully_qualified()),
Some(receiver) => write!(
out,
"&{}::{}",
out.types.resolve(&receiver.ty).to_fully_qualified(),
- efn.ident.cxx.ident
+ efn.ident.cxx,
),
}
writeln!(out, ";");
@@ -542,7 +533,7 @@
}
fn write_rust_function_decl<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
- out.set_namespace(&efn.ident.cxx.namespace);
+ out.set_namespace(&efn.ident.namespace);
out.begin_block(Block::ExternC);
let link_name = mangle::extern_fn(efn, out.types);
let indirect_call = false;
@@ -572,7 +563,7 @@
write!(
out,
"{} &self",
- out.types.resolve(&receiver.ty).to_fully_qualified()
+ out.types.resolve(&receiver.ty).to_fully_qualified(),
);
needs_comma = true;
}
@@ -601,17 +592,13 @@
}
fn write_rust_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
- out.set_namespace(&efn.ident.cxx.namespace);
+ out.set_namespace(&efn.ident.namespace);
for line in efn.doc.to_string().lines() {
writeln!(out, "//{}", line);
}
let local_name = match &efn.sig.receiver {
- None => efn.ident.cxx.ident.to_string(),
- Some(receiver) => format!(
- "{}::{}",
- out.types.resolve(&receiver.ty).ident,
- efn.ident.cxx.ident
- ),
+ None => efn.ident.cxx.to_string(),
+ Some(receiver) => format!("{}::{}", out.types.resolve(&receiver.ty).cxx, efn.ident.cxx),
};
let invoke = mangle::extern_fn(efn, out.types);
let indirect_call = false;
@@ -1041,7 +1028,7 @@
out.end_block(Block::Namespace("rust"));
}
-fn write_rust_box_extern(out: &mut OutFile, ident: &CppName) {
+fn write_rust_box_extern(out: &mut OutFile, ident: &Pair) {
let inner = ident.to_fully_qualified();
let instance = ident.to_symbol();
@@ -1095,7 +1082,7 @@
writeln!(out, "#endif // CXXBRIDGE05_RUST_VEC_{}", instance);
}
-fn write_rust_box_impl(out: &mut OutFile, ident: &CppName) {
+fn write_rust_box_impl(out: &mut OutFile, ident: &Pair) {
let inner = ident.to_fully_qualified();
let instance = ident.to_symbol();
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index b25d830..026ec43 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -4,7 +4,7 @@
use crate::syntax::report::Errors;
use crate::syntax::symbol::Symbol;
use crate::syntax::{
- self, check, mangle, Api, CppName, Enum, ExternFn, ExternType, Impl, ResolvableName, Signature,
+ self, check, mangle, Api, Enum, ExternFn, ExternType, Impl, Pair, ResolvableName, Signature,
Struct, Type, TypeAlias, Types,
};
use proc_macro2::{Ident, Span, TokenStream};
@@ -125,11 +125,10 @@
}
fn expand_struct(strct: &Struct) -> TokenStream {
- let ident = &strct.ident.rust;
- let cxx_ident = &strct.ident.cxx;
+ let ident = &strct.ident;
let doc = &strct.doc;
let derives = DeriveAttribute(&strct.derives);
- let type_id = type_id(cxx_ident);
+ let type_id = type_id(&strct.ident);
let fields = strct.fields.iter().map(|field| {
// This span on the pub makes "private type in public interface" errors
// appear in the right place.
@@ -153,11 +152,10 @@
}
fn expand_enum(enm: &Enum) -> TokenStream {
- let ident = &enm.ident.rust;
- let cxx_ident = &enm.ident.cxx;
+ let ident = &enm.ident;
let doc = &enm.doc;
let repr = enm.repr;
- let type_id = type_id(cxx_ident);
+ let type_id = type_id(&enm.ident);
let variants = enm.variants.iter().map(|variant| {
let variant_ident = &variant.ident;
let discriminant = &variant.discriminant;
@@ -187,10 +185,9 @@
}
fn expand_cxx_type(ety: &ExternType) -> TokenStream {
- let ident = &ety.ident.rust;
- let cxx_ident = &ety.ident.cxx;
+ let ident = &ety.ident;
let doc = &ety.doc;
- let type_id = type_id(&cxx_ident);
+ let type_id = type_id(&ety.ident);
quote! {
#doc
@@ -423,7 +420,7 @@
if unsafety.is_none() {
dispatch = quote!(unsafe { #dispatch });
}
- let ident = &efn.ident.rust;
+ let ident = &efn.ident;
let function_shim = quote! {
#doc
pub #unsafety fn #ident(#(#all_args,)*) #ret {
@@ -688,7 +685,7 @@
fn expand_type_alias_verify(alias: &TypeAlias, types: &Types) -> TokenStream {
let ident = &alias.ident;
- let type_id = type_id(&ident.cxx);
+ let type_id = type_id(ident);
let begin_span = alias.type_token.span;
let end_span = alias.semi_token.span;
let begin = quote_spanned!(begin_span=> ::cxx::private::verify_extern_type::<);
@@ -708,8 +705,8 @@
verify
}
-fn type_id(ident: &CppName) -> TokenStream {
- let path = ident.to_fully_qualified();
+fn type_id(name: &Pair) -> TokenStream {
+ let path = name.to_fully_qualified();
quote! {
::cxx::type_id!(#path)
}
diff --git a/syntax/ident.rs b/syntax/ident.rs
index 03c4380..bb2fe46 100644
--- a/syntax/ident.rs
+++ b/syntax/ident.rs
@@ -1,5 +1,5 @@
use crate::syntax::check::Check;
-use crate::syntax::{error, Api, CppName};
+use crate::syntax::{error, Api, Pair};
use proc_macro2::Ident;
fn check(cx: &mut Check, ident: &Ident) {
@@ -12,11 +12,11 @@
}
}
-fn check_ident(cx: &mut Check, ident: &CppName) {
- for segment in &ident.namespace {
+fn check_ident(cx: &mut Check, name: &Pair) {
+ for segment in &name.namespace {
check(cx, segment);
}
- check(cx, &ident.ident);
+ check(cx, &name.cxx);
}
pub(crate) fn check_all(cx: &mut Check, apis: &[Api]) {
@@ -24,19 +24,19 @@
match api {
Api::Include(_) | Api::Impl(_) => {}
Api::Struct(strct) => {
- check_ident(cx, &strct.ident.cxx);
+ check_ident(cx, &strct.ident);
for field in &strct.fields {
check(cx, &field.ident);
}
}
Api::Enum(enm) => {
- check_ident(cx, &enm.ident.cxx);
+ check_ident(cx, &enm.ident);
for variant in &enm.variants {
check(cx, &variant.ident);
}
}
Api::CxxType(ety) | Api::RustType(ety) => {
- check_ident(cx, &ety.ident.cxx);
+ check_ident(cx, &ety.ident);
}
Api::CxxFunction(efn) | Api::RustFunction(efn) => {
check(cx, &efn.ident.rust);
@@ -45,7 +45,7 @@
}
}
Api::TypeAlias(alias) => {
- check_ident(cx, &alias.ident.cxx);
+ check_ident(cx, &alias.ident);
}
}
}
diff --git a/syntax/mangle.rs b/syntax/mangle.rs
index d1f3adc..55ffca5 100644
--- a/syntax/mangle.rs
+++ b/syntax/mangle.rs
@@ -15,13 +15,13 @@
Some(receiver) => {
let receiver_ident = types.resolve(&receiver.ty);
join!(
- efn.ident.cxx.namespace,
+ efn.ident.namespace,
CXXBRIDGE,
- receiver_ident.ident,
+ receiver_ident.cxx,
efn.ident.rust
)
}
- None => join!(efn.ident.cxx.namespace, CXXBRIDGE, efn.ident.rust),
+ None => join!(efn.ident.namespace, CXXBRIDGE, efn.ident.rust),
}
}
diff --git a/syntax/mod.rs b/syntax/mod.rs
index b12d72b..6684b6a 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -188,17 +188,9 @@
// qualified C++ name.
#[derive(Clone)]
pub struct Pair {
- pub cxx: CppName,
- pub rust: Ident,
-}
-
-// A C++ identifier in a particular namespace. It is intentional that this does
-// not impl Display, because we want to force users actively to decide whether
-// to output it as a qualified name or as an unqualfied name.
-#[derive(Clone)]
-pub struct CppName {
pub namespace: Namespace,
- pub ident: Ident,
+ pub cxx: Ident,
+ pub rust: Ident,
}
// Wrapper for a type which needs to be resolved before it can be printed in
diff --git a/syntax/names.rs b/syntax/names.rs
index ee010a9..25ae9f4 100644
--- a/syntax/names.rs
+++ b/syntax/names.rs
@@ -1,29 +1,51 @@
-use crate::syntax::{CppName, Namespace, Pair, ResolvableName, Symbol, Types};
+use crate::syntax::{Namespace, Pair, ResolvableName, Symbol, Types};
use proc_macro2::{Ident, Span};
+use std::iter;
use syn::Token;
impl Pair {
- /// Use this constructor when the item can't have a different
- /// name in Rust and C++.
+ // Use this constructor when the item can't have a different name in Rust
+ // and C++.
pub fn new(namespace: Namespace, ident: Ident) -> Self {
Self {
- rust: ident.clone(),
- cxx: CppName::new(namespace, ident),
+ namespace,
+ cxx: ident.clone(),
+ rust: ident,
}
}
- /// Use this constructor when attributes such as #[rust_name]
- /// can be used to potentially give a different name in Rust vs C++.
+ // Use this constructor when attributes such as #[rust_name] can be used to
+ // potentially give a different name in Rust vs C++.
pub fn new_from_differing_names(
namespace: Namespace,
cxx_ident: Ident,
rust_ident: Ident,
) -> Self {
Self {
+ namespace,
+ cxx: cxx_ident,
rust: rust_ident,
- cxx: CppName::new(namespace, cxx_ident),
}
}
+
+ pub fn to_symbol(&self) -> Symbol {
+ Symbol::from_idents(self.iter_all_segments())
+ }
+
+ pub fn to_fully_qualified(&self) -> String {
+ format!("::{}", self.join("::"))
+ }
+
+ fn iter_all_segments(&self) -> impl Iterator<Item = &Ident> {
+ self.namespace.iter().chain(iter::once(&self.cxx))
+ }
+
+ fn join(&self, sep: &str) -> String {
+ self.iter_all_segments()
+ .map(|s| s.to_string())
+ .collect::<Vec<_>>()
+ .join(sep)
+ }
}
impl ResolvableName {
@@ -49,28 +71,3 @@
types.resolve(self).to_symbol()
}
}
-
-impl CppName {
- pub fn new(namespace: Namespace, ident: Ident) -> Self {
- Self { namespace, ident }
- }
-
- fn iter_all_segments(&self) -> impl Iterator<Item = &Ident> {
- self.namespace.iter().chain(std::iter::once(&self.ident))
- }
-
- fn join(&self, sep: &str) -> String {
- self.iter_all_segments()
- .map(|s| s.to_string())
- .collect::<Vec<_>>()
- .join(sep)
- }
-
- pub fn to_symbol(&self) -> Symbol {
- Symbol::from_idents(self.iter_all_segments())
- }
-
- pub fn to_fully_qualified(&self) -> String {
- format!("::{}", self.join("::"))
- }
-}
diff --git a/syntax/symbol.rs b/syntax/symbol.rs
index c849a62..253f57d 100644
--- a/syntax/symbol.rs
+++ b/syntax/symbol.rs
@@ -1,5 +1,5 @@
use crate::syntax::namespace::Namespace;
-use crate::syntax::CppName;
+use crate::syntax::Pair;
use proc_macro2::{Ident, TokenStream};
use quote::ToTokens;
use std::fmt::{self, Display, Write};
@@ -79,10 +79,10 @@
}
}
-impl Segment for CppName {
+impl Segment for Pair {
fn write(&self, symbol: &mut Symbol) {
self.namespace.write(symbol);
- self.ident.write(symbol);
+ self.cxx.write(symbol);
}
}
diff --git a/syntax/types.rs b/syntax/types.rs
index 178da3e..d9d6361 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -2,8 +2,7 @@
use crate::syntax::report::Errors;
use crate::syntax::set::OrderedSet as Set;
use crate::syntax::{
- Api, CppName, Derive, Enum, ExternFn, ExternType, Impl, Pair, ResolvableName, Struct, Type,
- TypeAlias,
+ Api, Derive, Enum, ExternFn, ExternType, Impl, Pair, ResolvableName, Struct, Type, TypeAlias,
};
use proc_macro2::Ident;
use quote::ToTokens;
@@ -19,7 +18,7 @@
pub untrusted: Map<&'a Ident, &'a ExternType>,
pub required_trivial: Map<&'a Ident, TrivialReason<'a>>,
pub explicit_impls: Set<&'a Impl>,
- pub resolutions: Map<&'a Ident, &'a CppName>,
+ pub resolutions: Map<&'a Ident, &'a Pair>,
}
impl<'a> Types<'a> {
@@ -56,7 +55,7 @@
}
let mut add_resolution = |pair: &'a Pair| {
- resolutions.insert(&pair.rust, &pair.cxx);
+ resolutions.insert(&pair.rust, pair);
};
let mut type_names = UnorderedSet::new();
@@ -228,7 +227,7 @@
false
}
- pub fn resolve(&self, ident: &ResolvableName) -> &CppName {
+ pub fn resolve(&self, ident: &ResolvableName) -> &Pair {
self.resolutions
.get(&ident.rust)
.expect("Unable to resolve type")