X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=c-bindings-gen%2Fsrc%2Ftypes.rs;h=e88133818cca6ae1a8584c3ef417a5c7d90983af;hb=f1f2ff0c395671d1e4f0c566836ae290d2c85113;hp=edd993f9be137fa45d752dc51d01ba6538fc30eb;hpb=6bc13e0b08c637fa381718aefd6a34637beb3b0d;p=ldk-c-bindings diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index edd993f..e881338 100644 --- a/c-bindings-gen/src/types.rs +++ b/c-bindings-gen/src/types.rs @@ -15,6 +15,8 @@ use std::hash; use crate::blocks::*; use proc_macro2::{TokenTree, Span}; +use quote::format_ident; +use syn::parse_quote; // The following utils are used purely to build our known types maps - they break down all the // types we need to resolve to include the given object, and no more. @@ -194,6 +196,7 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { assert_simple_bound(&trait_bound); if let Some(mut path) = types.maybe_resolve_path(&trait_bound.path, None) { if types.skip_path(&path) { continue; } + if path == "Sized" { continue; } if non_lifetimes_processed { return false; } non_lifetimes_processed = true; let new_ident = if path != "std::ops::Deref" { @@ -223,6 +226,9 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { let mut non_lifetimes_processed = false; for bound in t.bounds.iter() { if let syn::TypeParamBound::Trait(trait_bound) = bound { + if let Some(id) = trait_bound.path.get_ident() { + if format!("{}", id) == "Sized" { continue; } + } if non_lifetimes_processed { return false; } non_lifetimes_processed = true; assert_simple_bound(&trait_bound); @@ -337,11 +343,13 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr ($ident: expr, $path_suffix: expr) => { if partial_path == "" && !dependencies.contains(&$ident) { new_path = format!("{}::{}{}", crate_name, $ident, $path_suffix); - path.push(syn::PathSegment { ident: syn::Ident::new(crate_name, Span::call_site()), arguments: syn::PathArguments::None }); + let crate_name_ident = format_ident!("{}", crate_name); + path.push(parse_quote!(#crate_name_ident)); } else { new_path = format!("{}{}{}", partial_path, $ident, $path_suffix); } - path.push(syn::PathSegment { ident: $ident.clone(), arguments: syn::PathArguments::None }); + let ident = &$ident; + path.push(parse_quote!(#ident)); } } match u { @@ -379,10 +387,9 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr } fn insert_primitive(imports: &mut HashMap, id: &str) { - let ident = syn::Ident::new(id, Span::call_site()); - let mut path = syn::punctuated::Punctuated::new(); - path.push(syn::PathSegment { ident: ident.clone(), arguments: syn::PathArguments::None }); - imports.insert(ident, (id.to_owned(), syn::Path { leading_colon: None, segments: path })); + let ident = format_ident!("{}", id); + let path = parse_quote!(#ident); + imports.insert(ident, (id.to_owned(), path)); } pub fn new(crate_name: &'mod_lifetime str, dependencies: &'mod_lifetime HashSet, module_path: &'mod_lifetime str, contents: &'crate_lft [syn::Item]) -> Self { @@ -509,7 +516,10 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr let remaining: String = seg_iter.map(|seg| { format!("::{}", seg.ident) }).collect(); - if let Some((imp, _)) = self.imports.get(&first_seg.ident) { + let first_seg_str = format!("{}", first_seg.ident); + if first_seg_str == "std" { + Some(first_seg_str + &remaining) + } else if let Some((imp, _)) = self.imports.get(&first_seg.ident) { if remaining != "" { Some(imp.clone() + &remaining) } else { @@ -771,11 +781,15 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "String" if is_ref => Some("crate::c_types::Str"), "std::time::Duration" => Some("u64"), + "std::io::Error" => Some("crate::c_types::IOError"), - "bitcoin::secp256k1::key::PublicKey" => Some("crate::c_types::PublicKey"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some("crate::c_types::PublicKey"), "bitcoin::secp256k1::Signature" => Some("crate::c_types::Signature"), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some("*const [u8; 32]"), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some("crate::c_types::SecretKey"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some("*const [u8; 32]"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some("crate::c_types::SecretKey"), "bitcoin::secp256k1::Error" if !is_ref => Some("crate::c_types::Secp256k1Error"), "bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice"), "bitcoin::blockdata::script::Script" if !is_ref => Some("crate::c_types::derived::CVec_u8Z"), @@ -836,12 +850,16 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some("std::time::Duration::from_secs("), - "bitcoin::secp256k1::key::PublicKey" if is_ref => Some("&"), - "bitcoin::secp256k1::key::PublicKey" => Some(""), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + if is_ref => Some("&"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some(""), "bitcoin::secp256k1::Signature" if is_ref => Some("&"), "bitcoin::secp256k1::Signature" => Some(""), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some("&::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *"), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some(""), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some("&::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some(""), "bitcoin::blockdata::script::Script" if is_ref => Some("&::bitcoin::blockdata::script::Script::from(Vec::from("), "bitcoin::blockdata::script::Script" if !is_ref => Some("::bitcoin::blockdata::script::Script::from("), "bitcoin::blockdata::transaction::Transaction" if is_ref => Some("&"), @@ -891,10 +909,13 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some(")"), - "bitcoin::secp256k1::key::PublicKey" => Some(".into_rust()"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some(".into_rust()"), "bitcoin::secp256k1::Signature" => Some(".into_rust()"), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some(".into_rust()"), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some("}[..]).unwrap()"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some(".into_rust()"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some("}[..]).unwrap()"), "bitcoin::blockdata::script::Script" if is_ref => Some(".to_slice()))"), "bitcoin::blockdata::script::Script" if !is_ref => Some(".into_rust())"), "bitcoin::blockdata::transaction::Transaction" => Some(".into_bitcoin()"), @@ -928,8 +949,6 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "[u8]" if is_ref => Some(("crate::c_types::u8slice::from_slice(", ")")), "[usize]" if is_ref => Some(("crate::c_types::usizeslice::from_slice(", ")")), - "bitcoin::blockdata::transaction::Transaction" if is_ref => Some(("::bitcoin::consensus::encode::serialize(", ")")), - "bitcoin::blockdata::transaction::Transaction" if !is_ref => Some(("::bitcoin::consensus::encode::serialize(&", ")")), "bitcoin::blockdata::block::BlockHeader" if is_ref => Some(("{ let mut s = [0u8; 80]; s[..].copy_from_slice(&::bitcoin::consensus::encode::serialize(", ")); s }")), "bitcoin::blockdata::block::Block" if is_ref => Some(("::bitcoin::consensus::encode::serialize(", ")")), "bitcoin::hash_types::Txid" => None, @@ -950,11 +969,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "Option" => Some("local_"), "[u8; 32]" if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "), - "[u8; 32]" if is_ref => Some("&"), + "[u8; 32]" if is_ref => Some(""), "[u8; 16]" if !is_ref => Some("crate::c_types::SixteenBytes { data: "), "[u8; 10]" if !is_ref => Some("crate::c_types::TenBytes { data: "), "[u8; 4]" if !is_ref => Some("crate::c_types::FourBytes { data: "), - "[u8; 3]" if is_ref => Some("&"), + "[u8; 3]" if is_ref => Some(""), "[u8]" if is_ref => Some("local_"), "[usize]" if is_ref => Some("local_"), @@ -963,15 +982,20 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "String" => Some(""), "std::time::Duration" => Some(""), + "std::io::Error" if !is_ref => Some("crate::c_types::IOError::from_rust("), - "bitcoin::secp256k1::key::PublicKey" => Some("crate::c_types::PublicKey::from_rust(&"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some("crate::c_types::PublicKey::from_rust(&"), "bitcoin::secp256k1::Signature" => Some("crate::c_types::Signature::from_rust(&"), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some(""), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some("crate::c_types::SecretKey::from_rust("), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some(""), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some("crate::c_types::SecretKey::from_rust("), "bitcoin::secp256k1::Error" if !is_ref => Some("crate::c_types::Secp256k1Error::from_rust("), "bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice::from_slice(&"), "bitcoin::blockdata::script::Script" if !is_ref => Some(""), - "bitcoin::blockdata::transaction::Transaction" => Some("crate::c_types::Transaction::from_vec(local_"), + "bitcoin::blockdata::transaction::Transaction" if is_ref => Some("crate::c_types::Transaction::from_bitcoin("), + "bitcoin::blockdata::transaction::Transaction" => Some("crate::c_types::Transaction::from_bitcoin(&"), "bitcoin::blockdata::transaction::OutPoint" => Some("crate::c_types::bitcoin_to_C_outpoint("), "bitcoin::blockdata::transaction::TxOut" if !is_ref => Some("crate::c_types::TxOut::from_rust("), "bitcoin::network::constants::Network" => Some("crate::bitcoin::network::Network::from_bitcoin("), @@ -1021,11 +1045,15 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "String" if is_ref => Some(".as_str().into()"), "std::time::Duration" => Some(".as_secs()"), + "std::io::Error" if !is_ref => Some(")"), - "bitcoin::secp256k1::key::PublicKey" => Some(")"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some(")"), "bitcoin::secp256k1::Signature" => Some(")"), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some(")"), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some(".as_ref()"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some(")"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some(".as_ref()"), "bitcoin::secp256k1::Error" if !is_ref => Some(")"), "bitcoin::blockdata::script::Script" if is_ref => Some("[..])"), "bitcoin::blockdata::script::Script" if !is_ref => Some(".into_bytes().into()"), @@ -1431,15 +1459,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { let tail_str = split.next().unwrap(); assert!(split.next().is_none()); let len = &tail_str[..tail_str.len() - 1]; - Some(syn::Type::Array(syn::TypeArray { - bracket_token: syn::token::Bracket { span: Span::call_site() }, - elem: Box::new(syn::Type::Path(syn::TypePath { - qself: None, - path: syn::Path::from(syn::PathSegment::from(syn::Ident::new("u8", Span::call_site()))), - })), - semi_token: syn::Token!(;)(Span::call_site()), - len: syn::Expr::Lit(syn::ExprLit { attrs: Vec::new(), lit: syn::Lit::Int(syn::LitInt::new(len, Span::call_site())) }), - })) + Some(parse_quote!([u8; #len])) } else { None } } else { None } } @@ -1562,6 +1582,10 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { let resolved_path = self.resolve_path(&p.path, generics); if let Some(aliased_type) = self.crate_types.type_aliases.get(&resolved_path) { return self.write_conversion_inline_intern(w, aliased_type, None, is_ref, is_mut, ptr_for_ref, tupleconv, prefix, sliceconv, path_lookup, decl_lookup); + } else if self.is_primitive(&resolved_path) { + if is_ref && prefix { + write!(w, "*").unwrap(); + } } else if let Some(c_type) = path_lookup(&resolved_path, is_ref, ptr_for_ref) { write!(w, "{}", c_type).unwrap(); } else if self.crate_types.opaques.get(&resolved_path).is_some() { @@ -1643,20 +1667,20 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { |a, b, c| self.to_c_conversion_inline_prefix_from_path(a, b, c), |w, decl_type, decl_path, is_ref, _is_mut| { match decl_type { - DeclType::MirroredEnum if is_ref && ptr_for_ref => write!(w, "crate::{}::from_native(&", decl_path).unwrap(), - DeclType::MirroredEnum if is_ref => write!(w, "&crate::{}::from_native(&", decl_path).unwrap(), + DeclType::MirroredEnum if is_ref && ptr_for_ref => write!(w, "crate::{}::from_native(", decl_path).unwrap(), + DeclType::MirroredEnum if is_ref => write!(w, "&crate::{}::from_native(", decl_path).unwrap(), DeclType::MirroredEnum => write!(w, "crate::{}::native_into(", decl_path).unwrap(), DeclType::EnumIgnored|DeclType::StructImported if is_ref && ptr_for_ref && from_ptr => write!(w, "crate::{} {{ inner: unsafe {{ (", decl_path).unwrap(), DeclType::EnumIgnored|DeclType::StructImported if is_ref && ptr_for_ref => - write!(w, "crate::{} {{ inner: unsafe {{ ( (&(", decl_path).unwrap(), + write!(w, "crate::{} {{ inner: unsafe {{ ( (&(*", decl_path).unwrap(), DeclType::EnumIgnored|DeclType::StructImported if is_ref => write!(w, "&crate::{} {{ inner: unsafe {{ (", decl_path).unwrap(), DeclType::EnumIgnored|DeclType::StructImported if !is_ref && from_ptr => write!(w, "crate::{} {{ inner: ", decl_path).unwrap(), DeclType::EnumIgnored|DeclType::StructImported if !is_ref => write!(w, "crate::{} {{ inner: Box::into_raw(Box::new(", decl_path).unwrap(), - DeclType::Trait(_) if is_ref => write!(w, "&").unwrap(), + DeclType::Trait(_) if is_ref => write!(w, "").unwrap(), DeclType::Trait(_) if !is_ref => {}, _ => panic!("{:?}", decl_path), } @@ -1832,7 +1856,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { write!(w, "{} {{ ", pfx).unwrap(); let new_var_name = format!("{}_{}", ident, idx); - let new_var = self.write_conversion_new_var_intern(w, &syn::Ident::new(&new_var_name, Span::call_site()), + let new_var = self.write_conversion_new_var_intern(w, &format_ident!("{}", new_var_name), &var_access, conv_ty, generics, contains_slice || (is_ref && ty_has_inner), ptr_for_ref, to_c, path_lookup, container_lookup, var_prefix, var_suffix); if new_var { write!(w, " ").unwrap(); } @@ -1957,7 +1981,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { for (idx, elem) in t.elems.iter().enumerate() { if let syn::Type::Path(p) = elem { let v_name = format!("orig_{}_{}", ident, idx); - let tuple_elem_ident = syn::Ident::new(&v_name, Span::call_site()); + let tuple_elem_ident = format_ident!("{}", &v_name); if self.write_conversion_new_var_intern(w, &tuple_elem_ident, &v_name, elem, generics, false, ptr_for_ref, to_c, path_lookup, container_lookup, var_prefix, var_suffix) { @@ -2371,15 +2395,10 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { self.check_create_container(mangled_container, "Vec", vec![&*r.elem], generics, false) } else { false } } else if let syn::Type::Tuple(_) = &*s.elem { - let mut args = syn::punctuated::Punctuated::new(); + let mut args = syn::punctuated::Punctuated::<_, syn::token::Comma>::new(); args.push(syn::GenericArgument::Type((*s.elem).clone())); let mut segments = syn::punctuated::Punctuated::new(); - segments.push(syn::PathSegment { - ident: syn::Ident::new("Vec", Span::call_site()), - arguments: syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { - colon2_token: None, lt_token: syn::Token![<](Span::call_site()), args, gt_token: syn::Token![>](Span::call_site()), - }) - }); + segments.push(parse_quote!(Vec<#args>)); self.write_c_type_intern(w, &syn::Type::Path(syn::TypePath { qself: None, path: syn::Path { leading_colon: None, segments } }), generics, false, is_mut, ptr_for_ref) } else { false } },