Type alias code generation
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 6eac0d9..e3026ba 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -3,7 +3,7 @@
use crate::syntax::report::Errors;
use crate::syntax::symbol::Symbol;
use crate::syntax::{
- self, check, mangle, Api, Enum, ExternFn, ExternType, Signature, Struct, Type, Types,
+ self, check, mangle, Api, Enum, ExternFn, ExternType, Signature, Struct, Type, TypeAlias, Types,
};
use proc_macro2::{Ident, Span, TokenStream};
use quote::{format_ident, quote, quote_spanned, ToTokens};
@@ -46,7 +46,7 @@
Api::Enum(enm) => expanded.extend(expand_enum(enm)),
Api::CxxType(ety) => {
if !types.enums.contains_key(&ety.ident) {
- expanded.extend(expand_cxx_type(ety));
+ expanded.extend(expand_cxx_type(namespace, ety));
}
}
Api::CxxFunction(efn) => {
@@ -55,7 +55,10 @@
Api::RustFunction(efn) => {
hidden.extend(expand_rust_function_shim(namespace, efn, types))
}
- Api::TypeAlias(_alias) => unimplemented!(),
+ Api::TypeAlias(alias) => {
+ expanded.extend(expand_type_alias(alias));
+ hidden.extend(expand_type_alias_verify(namespace, alias));
+ }
}
}
@@ -162,15 +165,21 @@
}
}
-fn expand_cxx_type(ety: &ExternType) -> TokenStream {
+fn expand_cxx_type(namespace: &Namespace, ety: &ExternType) -> TokenStream {
let ident = &ety.ident;
let doc = &ety.doc;
+ let type_id = type_id(namespace, ident);
+
quote! {
#doc
#[repr(C)]
pub struct #ident {
_private: ::cxx::private::Opaque,
}
+
+ unsafe impl ::cxx::ExternType for #ident {
+ type Id = #type_id;
+ }
}
}
@@ -555,6 +564,35 @@
}
}
+fn expand_type_alias(alias: &TypeAlias) -> TokenStream {
+ let ident = &alias.ident;
+ let ty = &alias.ty;
+ quote! {
+ pub type #ident = #ty;
+ }
+}
+
+fn expand_type_alias_verify(namespace: &Namespace, alias: &TypeAlias) -> TokenStream {
+ let ident = &alias.ident;
+ let type_id = type_id(namespace, ident);
+ quote! {
+ const _: fn() = ::cxx::private::verify_extern_type::<#ident, #type_id>;
+ }
+}
+
+fn type_id(namespace: &Namespace, ident: &Ident) -> TokenStream {
+ let mut path = String::new();
+ for name in namespace {
+ path += &name.to_string();
+ path += "::";
+ }
+ path += &ident.to_string();
+
+ quote! {
+ ::cxx::type_id!(#path)
+ }
+}
+
fn expand_rust_box(namespace: &Namespace, ident: &Ident) -> TokenStream {
let link_prefix = format!("cxxbridge03$box${}{}$", namespace, ident);
let link_uninit = format!("{}uninit", link_prefix);