Generate all explicit and implicit impls based on one map
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 96592b3..6679076 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -3,13 +3,14 @@
use crate::gen::out::OutFile;
use crate::gen::{builtin, include, Opt};
use crate::syntax::atom::Atom::{self, *};
+use crate::syntax::instantiate::ImplKey;
use crate::syntax::map::UnorderedMap as Map;
use crate::syntax::set::UnorderedSet;
use crate::syntax::symbol::Symbol;
use crate::syntax::trivial::{self, TrivialReason};
use crate::syntax::{
- derive, mangle, Api, Enum, ExternFn, ExternType, NamedType, Pair, Signature, Struct, Trait,
- Type, TypeAlias, Types, Var,
+ derive, mangle, Api, Enum, ExternFn, ExternType, Pair, Signature, Struct, Trait, Type,
+ TypeAlias, Types, Var,
};
use proc_macro2::Ident;
@@ -1284,15 +1285,15 @@
#[derive(Copy, Clone)]
enum UniquePtr<'a> {
- Ident(&'a NamedType),
- CxxVector(&'a NamedType),
+ Ident(&'a Ident),
+ CxxVector(&'a Ident),
}
trait ToTypename {
fn to_typename(&self, types: &Types) -> String;
}
-impl ToTypename for NamedType {
+impl ToTypename for Ident {
fn to_typename(&self, types: &Types) -> String {
types.resolve(self).to_fully_qualified()
}
@@ -1313,7 +1314,7 @@
fn to_mangled(&self, types: &Types) -> Symbol;
}
-impl ToMangled for NamedType {
+impl ToMangled for Ident {
fn to_mangled(&self, types: &Types) -> Symbol {
types.resolve(self).to_symbol()
}
@@ -1336,109 +1337,36 @@
out.next_section();
out.set_namespace(Default::default());
out.begin_block(Block::ExternC);
- for ty in out.types {
- let impl_key = match ty.impl_key() {
- Some(impl_key) => impl_key,
- None => continue,
- };
- if let Type::RustBox(ptr) = ty {
- if let Type::Ident(inner) = &ptr.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- out.next_section();
- write_rust_box_extern(out, &out.types.resolve(&inner));
- }
- }
- } else if let Type::RustVec(vec) = ty {
- if let Type::Ident(inner) = &vec.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- out.next_section();
- write_rust_vec_extern(out, inner);
- }
- }
- } else if let Type::UniquePtr(ptr) = ty {
- if let Type::Ident(inner) = &ptr.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- out.next_section();
- write_unique_ptr(out, inner);
- }
- }
- } else if let Type::SharedPtr(ptr) = ty {
- if let Type::Ident(inner) = &ptr.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- out.next_section();
- write_shared_ptr(out, inner);
- }
- }
- } else if let Type::WeakPtr(ptr) = ty {
- if let Type::Ident(inner) = &ptr.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- out.next_section();
- write_weak_ptr(out, inner);
- }
- }
- } else if let Type::CxxVector(vector) = ty {
- if let Type::Ident(inner) = &vector.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- out.next_section();
- write_cxx_vector(out, inner);
- }
- }
+ for impl_key in out.types.impls.keys() {
+ out.next_section();
+ match impl_key {
+ ImplKey::RustBox(ident) => write_rust_box_extern(out, ident),
+ ImplKey::RustVec(ident) => write_rust_vec_extern(out, ident),
+ ImplKey::UniquePtr(ident) => write_unique_ptr(out, ident),
+ ImplKey::SharedPtr(ident) => write_shared_ptr(out, ident),
+ ImplKey::WeakPtr(ident) => write_weak_ptr(out, ident),
+ ImplKey::CxxVector(ident) => write_cxx_vector(out, ident),
}
}
out.end_block(Block::ExternC);
out.begin_block(Block::Namespace("rust"));
out.begin_block(Block::InlineNamespace("cxxbridge1"));
- for ty in out.types {
- let impl_key = match ty.impl_key() {
- Some(impl_key) => impl_key,
- None => continue,
- };
- if let Type::RustBox(ptr) = ty {
- if let Type::Ident(inner) = &ptr.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- write_rust_box_impl(out, &out.types.resolve(&inner));
- }
- }
- } else if let Type::RustVec(vec) = ty {
- if let Type::Ident(inner) = &vec.inner {
- if Atom::from(&inner.rust).is_none()
- && (!out.types.aliases.contains_key(&inner.rust)
- || out.types.explicit_impls.contains_key(&impl_key))
- {
- write_rust_vec_impl(out, inner);
- }
- }
+ for impl_key in out.types.impls.keys() {
+ match impl_key {
+ ImplKey::RustBox(ident) => write_rust_box_impl(out, ident),
+ ImplKey::RustVec(ident) => write_rust_vec_impl(out, ident),
+ _ => {}
}
}
out.end_block(Block::InlineNamespace("cxxbridge1"));
out.end_block(Block::Namespace("rust"));
}
-fn write_rust_box_extern(out: &mut OutFile, ident: &Pair) {
- let inner = ident.to_fully_qualified();
- let instance = ident.to_symbol();
+fn write_rust_box_extern(out: &mut OutFile, ident: &Ident) {
+ let resolve = out.types.resolve(ident);
+ let inner = resolve.to_fully_qualified();
+ let instance = resolve.to_symbol();
writeln!(
out,
@@ -1457,7 +1385,7 @@
);
}
-fn write_rust_vec_extern(out: &mut OutFile, element: &NamedType) {
+fn write_rust_vec_extern(out: &mut OutFile, element: &Ident) {
let inner = element.to_typename(out.types);
let instance = element.to_mangled(out.types);
@@ -1500,9 +1428,10 @@
);
}
-fn write_rust_box_impl(out: &mut OutFile, ident: &Pair) {
- let inner = ident.to_fully_qualified();
- let instance = ident.to_symbol();
+fn write_rust_box_impl(out: &mut OutFile, ident: &Ident) {
+ let resolve = out.types.resolve(ident);
+ let inner = resolve.to_fully_qualified();
+ let instance = resolve.to_symbol();
writeln!(out, "template <>");
begin_function_definition(out);
@@ -1531,7 +1460,7 @@
writeln!(out, "}}");
}
-fn write_rust_vec_impl(out: &mut OutFile, element: &NamedType) {
+fn write_rust_vec_impl(out: &mut OutFile, element: &Ident) {
let inner = element.to_typename(out.types);
let instance = element.to_mangled(out.types);
@@ -1608,7 +1537,7 @@
writeln!(out, "}}");
}
-fn write_unique_ptr(out: &mut OutFile, ident: &NamedType) {
+fn write_unique_ptr(out: &mut OutFile, ident: &Ident) {
let ty = UniquePtr::Ident(ident);
write_unique_ptr_common(out, ty);
}
@@ -1626,17 +1555,16 @@
// bindings for a "new" method anyway. But the Rust code can't be called
// for Opaque types because the 'new' method is not implemented.
UniquePtr::Ident(ident) => {
- out.types.structs.contains_key(&ident.rust)
- || out.types.enums.contains_key(&ident.rust)
- || out.types.aliases.contains_key(&ident.rust)
+ out.types.structs.contains_key(ident)
+ || out.types.enums.contains_key(ident)
+ || out.types.aliases.contains_key(ident)
}
UniquePtr::CxxVector(_) => false,
};
let conditional_delete = match ty {
UniquePtr::Ident(ident) => {
- !out.types.structs.contains_key(&ident.rust)
- && !out.types.enums.contains_key(&ident.rust)
+ !out.types.structs.contains_key(ident) && !out.types.enums.contains_key(ident)
}
UniquePtr::CxxVector(_) => false,
};
@@ -1725,7 +1653,7 @@
writeln!(out, "}}");
}
-fn write_shared_ptr(out: &mut OutFile, ident: &NamedType) {
+fn write_shared_ptr(out: &mut OutFile, ident: &Ident) {
let resolve = out.types.resolve(ident);
let inner = resolve.to_fully_qualified();
let instance = resolve.to_symbol();
@@ -1737,9 +1665,9 @@
// know at code generation time, so we generate both C++ and Rust side
// bindings for a "new" method anyway. But the Rust code can't be called for
// Opaque types because the 'new' method is not implemented.
- let can_construct_from_value = out.types.structs.contains_key(&ident.rust)
- || out.types.enums.contains_key(&ident.rust)
- || out.types.aliases.contains_key(&ident.rust);
+ let can_construct_from_value = out.types.structs.contains_key(ident)
+ || out.types.enums.contains_key(ident)
+ || out.types.aliases.contains_key(ident);
writeln!(
out,
@@ -1797,7 +1725,7 @@
writeln!(out, "}}");
}
-fn write_weak_ptr(out: &mut OutFile, ident: &NamedType) {
+fn write_weak_ptr(out: &mut OutFile, ident: &Ident) {
let resolve = out.types.resolve(ident);
let inner = resolve.to_fully_qualified();
let instance = resolve.to_symbol();
@@ -1856,7 +1784,7 @@
writeln!(out, "}}");
}
-fn write_cxx_vector(out: &mut OutFile, element: &NamedType) {
+fn write_cxx_vector(out: &mut OutFile, element: &Ident) {
let inner = element.to_typename(out.types);
let instance = element.to_mangled(out.types);