X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=c-bindings-gen%2Fsrc%2Ftypes.rs;h=a45cf2b16f7abbb55e3b53f898e1bfdfa379bd39;hb=95fa736720b362322b7b6a010b4c3f517c11e701;hp=835e6c02323a92eff2d2df0f070b04b21e7ebadc;hpb=1f9a169c7e376baad24015ecf775e1adcf9d5967;p=ldk-c-bindings diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index 835e6c0..a45cf2b 100644 --- a/c-bindings-gen/src/types.rs +++ b/c-bindings-gen/src/types.rs @@ -164,19 +164,20 @@ pub fn is_enum_opaque(e: &syn::ItemEnum) -> bool { /// concrete C container struct, etc). #[must_use] pub struct GenericTypes<'a, 'b> { + self_ty: Option<(String, &'a syn::Path)>, parent: Option<&'b GenericTypes<'b, 'b>>, typed_generics: HashMap<&'a syn::Ident, (String, Option<&'a syn::Path>)>, } impl<'a, 'p: 'a> GenericTypes<'a, 'p> { - pub fn new() -> Self { - Self { parent: None, typed_generics: HashMap::new(), } + pub fn new(self_ty: Option<(String, &'a syn::Path)>) -> Self { + Self { self_ty, parent: None, typed_generics: HashMap::new(), } } /// push a new context onto the stack, allowing for a new set of generics to be learned which /// will override any lower contexts, but which will still fall back to resoltion via lower /// contexts. pub fn push_ctx<'c>(&'c self) -> GenericTypes<'a, 'c> { - GenericTypes { parent: Some(self), typed_generics: HashMap::new(), } + GenericTypes { self_ty: None, parent: Some(self), typed_generics: HashMap::new(), } } /// Learn the generics in generics in the current context, given a TypeResolver. @@ -281,6 +282,11 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { /// Attempt to resolve an Ident as a generic parameter and return the full path. pub fn maybe_resolve_ident<'b>(&'b self, ident: &syn::Ident) -> Option<&'b String> { + if let Some(ty) = &self.self_ty { + if format!("{}", ident) == "Self" { + return Some(&ty.0); + } + } if let Some(res) = self.typed_generics.get(ident).map(|(a, _)| a) { return Some(res); } @@ -294,6 +300,11 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { /// and syn::Path. pub fn maybe_resolve_path<'b>(&'b self, path: &syn::Path) -> Option<(&'b String, &'a syn::Path)> { if let Some(ident) = path.get_ident() { + if let Some(ty) = &self.self_ty { + if format!("{}", ident) == "Self" { + return Some((&ty.0, ty.1)); + } + } if let Some(res) = self.typed_generics.get(ident).map(|(a, b)| (a, b.unwrap())) { return Some(res); } @@ -335,13 +346,22 @@ pub struct ImportResolver<'mod_lifetime, 'crate_lft: 'mod_lifetime> { priv_modules: HashSet, } impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'crate_lft> { - fn process_use_intern(crate_name: &str, dependencies: &HashSet, imports: &mut HashMap, + fn process_use_intern(crate_name: &str, module_path: &str, dependencies: &HashSet, imports: &mut HashMap, u: &syn::UseTree, partial_path: &str, mut path: syn::punctuated::Punctuated) { let new_path; macro_rules! push_path { ($ident: expr, $path_suffix: expr) => { - if partial_path == "" && !dependencies.contains(&$ident) { + if partial_path == "" && format!("{}", $ident) == "super" { + let mut mod_iter = module_path.rsplitn(2, "::"); + mod_iter.next().unwrap(); + let super_mod = mod_iter.next().unwrap(); + new_path = format!("{}{}", super_mod, $path_suffix); + assert_eq!(path.len(), 0); + for module in super_mod.split("::") { + path.push(syn::PathSegment { ident: syn::Ident::new(module, Span::call_site()), arguments: syn::PathArguments::None }); + } + } else if partial_path == "" && !dependencies.contains(&$ident) { new_path = format!("{}::{}{}", crate_name, $ident, $path_suffix); let crate_name_ident = format_ident!("{}", crate_name); path.push(parse_quote!(#crate_name_ident)); @@ -355,7 +375,7 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr match u { syn::UseTree::Path(p) => { push_path!(p.ident, "::"); - Self::process_use_intern(crate_name, dependencies, imports, &p.tree, &new_path, path); + Self::process_use_intern(crate_name, module_path, dependencies, imports, &p.tree, &new_path, path); }, syn::UseTree::Name(n) => { push_path!(n.ident, ""); @@ -363,7 +383,7 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr }, syn::UseTree::Group(g) => { for i in g.items.iter() { - Self::process_use_intern(crate_name, dependencies, imports, i, partial_path, path.clone()); + Self::process_use_intern(crate_name, module_path, dependencies, imports, i, partial_path, path.clone()); } }, syn::UseTree::Rename(r) => { @@ -376,14 +396,14 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr } } - fn process_use(crate_name: &str, dependencies: &HashSet, imports: &mut HashMap, u: &syn::ItemUse) { + fn process_use(crate_name: &str, module_path: &str, dependencies: &HashSet, imports: &mut HashMap, u: &syn::ItemUse) { if let syn::Visibility::Public(_) = u.vis { // We actually only use these for #[cfg(fuzztarget)] eprintln!("Ignoring pub(use) tree!"); return; } if u.leading_colon.is_some() { eprintln!("Ignoring leading-colon use!"); return; } - Self::process_use_intern(crate_name, dependencies, imports, &u.tree, "", syn::punctuated::Punctuated::new()); + Self::process_use_intern(crate_name, module_path, dependencies, imports, &u.tree, "", syn::punctuated::Punctuated::new()); } fn insert_primitive(imports: &mut HashMap, id: &str) { @@ -393,6 +413,9 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr } pub fn new(crate_name: &'mod_lifetime str, dependencies: &'mod_lifetime HashSet, module_path: &'mod_lifetime str, contents: &'crate_lft [syn::Item]) -> Self { + Self::from_borrowed_items(crate_name, dependencies, module_path, &contents.iter().map(|a| a).collect::>()) + } + pub fn from_borrowed_items(crate_name: &'mod_lifetime str, dependencies: &'mod_lifetime HashSet, module_path: &'mod_lifetime str, contents: &[&'crate_lft syn::Item]) -> Self { let mut imports = HashMap::new(); // Add primitives to the "imports" list: Self::insert_primitive(&mut imports, "bool"); @@ -415,7 +438,7 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr for item in contents.iter() { match item { - syn::Item::Use(u) => Self::process_use(crate_name, dependencies, &mut imports, &u), + syn::Item::Use(u) => Self::process_use(crate_name, module_path, dependencies, &mut imports, &u), syn::Item::Struct(s) => { if let syn::Visibility::Public(_) = s.vis { match export_status(&s.attrs) { @@ -525,7 +548,7 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr } } else if let Some(_) = self.priv_modules.get(&first_seg.ident) { Some(format!("{}::{}{}", self.module_path, first_seg.ident, remaining)) - } else if first_seg_str == "std" || self.dependencies.contains(&first_seg.ident) { + } else if first_seg_str == "std" || first_seg_str == "core" || self.dependencies.contains(&first_seg.ident) { Some(first_seg_str + &remaining) } else { None } } @@ -789,6 +812,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "String" if is_ref => Some("crate::c_types::Str"), "std::time::Duration" => Some("u64"), + "std::time::SystemTime" => Some("u64"), "std::io::Error" => Some("crate::c_types::IOError"), "bech32::u5" => Some("crate::c_types::u5"), @@ -861,6 +885,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { // cannot create a &String. "std::time::Duration" => Some("std::time::Duration::from_secs("), + "std::time::SystemTime" => Some("(::std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs("), "bech32::u5" => Some(""), @@ -923,6 +948,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "String" if !is_ref => Some(".into_rust()).unwrap()"), "std::time::Duration" => Some(")"), + "std::time::SystemTime" => Some("))"), "bech32::u5" => Some(".into()"), @@ -1000,6 +1026,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "String" => Some(""), "std::time::Duration" => Some(""), + "std::time::SystemTime" => Some(""), "std::io::Error" if !is_ref => Some("crate::c_types::IOError::from_rust("), "bech32::u5" => Some(""), @@ -1068,6 +1095,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "String" if is_ref => Some(".as_str().into()"), "std::time::Duration" => Some(".as_secs()"), + "std::time::SystemTime" => Some(".duration_since(::std::time::SystemTime::UNIX_EPOCH).expect(\"Times must be post-1970\").as_secs()"), "std::io::Error" if !is_ref => Some(")"), "bech32::u5" => Some(".into()"), @@ -2340,6 +2368,13 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } self.write_c_mangled_container_path_intern(w, args, generics, ident, is_ref, is_mut, ptr_for_ref, false) } + pub fn get_c_mangled_container_type(&self, args: Vec<&syn::Type>, generics: Option<&GenericTypes>, template_name: &str) -> Option { + let mut out = Vec::new(); + if !self.write_c_mangled_container_path(&mut out, args, generics, template_name, false, false, false) { + return None; + } + Some(String::from_utf8(out).unwrap()) + } // ********************************** // *** C Type Equivalent Printing ***