X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=c-bindings-gen%2Fsrc%2Ftypes.rs;h=ad21b4c6bca53917685979c846021a03cdb45d7e;hb=c42ea50cc703f03465d52b5fccfc4a90466d9fea;hp=cba9407ae1200b2b693cf7b8ac169b1b918b2e10;hpb=3bbecbef21ec3bf3f4f665128cbf254d85374e6e;p=rust-lightning diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index cba9407a..ad21b4c6 100644 --- a/c-bindings-gen/src/types.rs +++ b/c-bindings-gen/src/types.rs @@ -114,16 +114,20 @@ pub fn assert_simple_bound(bound: &syn::TraitBound) { /// type), otherwise it is mapped into a transparent, C-compatible version of itself. pub fn is_enum_opaque(e: &syn::ItemEnum) -> bool { for var in e.variants.iter() { - if let syn::Fields::Unit = var.fields { - } else if let syn::Fields::Named(fields) = &var.fields { + if let syn::Fields::Named(fields) = &var.fields { for field in fields.named.iter() { match export_status(&field.attrs) { ExportStatus::Export|ExportStatus::TestOnly => {}, ExportStatus::NoExport => return true, } } - } else { - return true; + } else if let syn::Fields::Unnamed(fields) = &var.fields { + for field in fields.unnamed.iter() { + match export_status(&field.attrs) { + ExportStatus::Export|ExportStatus::TestOnly => {}, + ExportStatus::NoExport => return true, + } + } } } false @@ -302,6 +306,7 @@ pub struct ImportResolver<'mod_lifetime, 'crate_lft: 'mod_lifetime> { module_path: &'mod_lifetime str, imports: HashMap, declared: HashMap>, + priv_modules: HashSet, } impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'crate_lft> { fn process_use_intern(imports: &mut HashMap, u: &syn::UseTree, partial_path: &str, mut path: syn::punctuated::Punctuated) { @@ -368,6 +373,7 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr Self::insert_primitive(&mut imports, "Option"); let mut declared = HashMap::new(); + let mut priv_modules = HashSet::new(); for item in contents.iter() { match item { @@ -381,6 +387,21 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr } } }, + syn::Item::Type(t) if export_status(&t.attrs) == ExportStatus::Export => { + if let syn::Visibility::Public(_) = t.vis { + let mut process_alias = true; + for tok in t.generics.params.iter() { + if let syn::GenericParam::Lifetime(_) = tok {} + else { process_alias = false; } + } + if process_alias { + match &*t.ty { + syn::Type::Path(_) => { declared.insert(t.ident.clone(), DeclType::StructImported); }, + _ => {}, + } + } + } + }, syn::Item::Enum(e) => { if let syn::Visibility::Public(_) = e.vis { match export_status(&e.attrs) { @@ -395,11 +416,14 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr declared.insert(t.ident.clone(), DeclType::Trait(t)); } }, + syn::Item::Mod(m) => { + priv_modules.insert(m.ident.clone()); + }, _ => {}, } } - Self { module_path, imports, declared } + Self { module_path, imports, declared, priv_modules } } pub fn get_declared_type(&self, ident: &syn::Ident) -> Option<&DeclType<'crate_lft>> { @@ -458,6 +482,8 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr } else { Some(imp.clone()) } + } else if let Some(_) = self.priv_modules.get(&first_seg.ident) { + Some(format!("{}::{}{}", self.module_path, first_seg.ident, remaining)) } else { None } } } @@ -507,6 +533,8 @@ pub struct CrateTypes<'a> { pub traits: HashMap, /// Aliases from paths to some other Type pub type_aliases: HashMap, + /// Value is an alias to Key (maybe with some generics) + pub reverse_alias_map: HashMap>, /// Template continer types defined, map from mangled type name -> whether a destructor fn /// exists. /// @@ -517,6 +545,8 @@ pub struct CrateTypes<'a> { pub template_file: &'a mut File, /// Set of containers which are clonable pub clonable_types: HashSet, + /// Key impls Value + pub trait_impls: HashMap>, } /// A struct which tracks resolving rust types into C-mapped equivalents, exists for one specific @@ -557,7 +587,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { /// Returns true we if can just skip passing this to C entirely fn no_arg_path_to_rust(&self, full_path: &str) -> &str { if full_path == "bitcoin::secp256k1::Secp256k1" { - "&bitcoin::secp256k1::Secp256k1::new()" + "secp256k1::SECP256K1" } else { unimplemented!(); } } @@ -586,7 +616,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } /// Gets the C-mapped type for types which are outside of the crate, or which are manually /// ignored by for some reason need mapping anyway. - fn c_type_from_path<'b>(&self, full_path: &'b str, is_ref: bool, ptr_for_ref: bool) -> Option<&'b str> { + fn c_type_from_path<'b>(&self, full_path: &'b str, is_ref: bool, _ptr_for_ref: bool) -> Option<&'b str> { if self.is_primitive(full_path) { return Some(full_path); } @@ -640,10 +670,6 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { // Override the default since Records contain an fmt with a lifetime: "util::logger::Record" => Some("*const std::os::raw::c_char"), - // List of structs we map that aren't detected: - "ln::features::InitFeatures" if is_ref && ptr_for_ref => Some("crate::ln::features::InitFeatures"), - "ln::features::InitFeatures" if is_ref => Some("*const crate::ln::features::InitFeatures"), - "ln::features::InitFeatures" => Some("crate::ln::features::InitFeatures"), _ => None, } } @@ -703,9 +729,6 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "ln::channelmanager::PaymentPreimage" if is_ref => Some("&::lightning::ln::channelmanager::PaymentPreimage(unsafe { *"), "ln::channelmanager::PaymentSecret" => Some("::lightning::ln::channelmanager::PaymentSecret("), - // List of structs we map (possibly during processing of other files): - "ln::features::InitFeatures" if !is_ref => Some("*unsafe { Box::from_raw("), - // List of traits we map (possibly during processing of other files): "crate::util::logger::Logger" => Some(""), @@ -758,10 +781,6 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "ln::channelmanager::PaymentPreimage" if is_ref => Some(" })"), "ln::channelmanager::PaymentSecret" => Some(".data)"), - // List of structs we map (possibly during processing of other files): - "ln::features::InitFeatures" if is_ref => Some(".inner) }"), - "ln::features::InitFeatures" if !is_ref => Some(".take_inner()) }"), - // List of traits we map (possibly during processing of other files): "crate::util::logger::Logger" => Some(""), @@ -789,7 +808,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { _ => None, }.map(|s| s.to_owned()) } - fn to_c_conversion_inline_prefix_from_path(&self, full_path: &str, is_ref: bool, ptr_for_ref: bool) -> Option { + fn to_c_conversion_inline_prefix_from_path(&self, full_path: &str, is_ref: bool, _ptr_for_ref: bool) -> Option { if self.is_primitive(full_path) { return Some("".to_owned()); } @@ -823,6 +842,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "bitcoin::blockdata::transaction::Transaction" => Some("crate::c_types::Transaction::from_vec(local_"), "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("), "bitcoin::blockdata::block::BlockHeader" if is_ref => Some("&local_"), "bitcoin::blockdata::block::Block" if is_ref => Some("crate::c_types::u8slice::from_slice(&local_"), @@ -842,15 +862,10 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { // Override the default since Records contain an fmt with a lifetime: "util::logger::Record" => Some("local_"), - // List of structs we map (possibly during processing of other files): - "ln::features::InitFeatures" if is_ref && ptr_for_ref => Some("crate::ln::features::InitFeatures { inner: &mut "), - "ln::features::InitFeatures" if is_ref => Some("Box::into_raw(Box::new(crate::ln::features::InitFeatures { inner: &mut "), - "ln::features::InitFeatures" if !is_ref => Some("crate::ln::features::InitFeatures { inner: Box::into_raw(Box::new("), - _ => None, }.map(|s| s.to_owned()) } - fn to_c_conversion_inline_suffix_from_path(&self, full_path: &str, is_ref: bool, ptr_for_ref: bool) -> Option { + fn to_c_conversion_inline_suffix_from_path(&self, full_path: &str, is_ref: bool, _ptr_for_ref: bool) -> Option { if self.is_primitive(full_path) { return Some("".to_owned()); } @@ -885,6 +900,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "bitcoin::blockdata::transaction::Transaction" => Some(")"), "bitcoin::blockdata::transaction::OutPoint" => Some(")"), "bitcoin::blockdata::transaction::TxOut" if !is_ref => Some(")"), + "bitcoin::network::constants::Network" => Some(")"), "bitcoin::blockdata::block::BlockHeader" if is_ref => Some(""), "bitcoin::blockdata::block::Block" if is_ref => Some(")"), @@ -904,11 +920,6 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { // Override the default since Records contain an fmt with a lifetime: "util::logger::Record" => Some(".as_ptr()"), - // List of structs we map (possibly during processing of other files): - "ln::features::InitFeatures" if is_ref && ptr_for_ref => Some(", is_owned: false }"), - "ln::features::InitFeatures" if is_ref => Some(", is_owned: false }))"), - "ln::features::InitFeatures" => Some(")), is_owned: true }"), - _ => None, }.map(|s| s.to_owned()) } @@ -958,7 +969,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { ").into() }")) }, "Vec" if !is_ref => { - Some(("Vec::new(); for item in ", vec![(format!(".drain(..) {{ local_{}.push(", var_name), "item".to_string())], "); }")) + Some(("Vec::new(); for mut item in ", vec![(format!(".drain(..) {{ local_{}.push(", var_name), "item".to_string())], "); }")) }, "Slice" => { Some(("Vec::new(); for item in ", vec![(format!(".iter() {{ local_{}.push(", var_name), "**item".to_string())], "); }")) @@ -999,8 +1010,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { match full_path { "Result" if !is_ref => { Some(("match ", - vec![(".result_ok { true => Ok(".to_string(), format!("(*unsafe {{ Box::from_raw(<*mut _>::take_ptr(&mut {}.contents.result)) }})", var_name)), - ("), false => Err(".to_string(), format!("(*unsafe {{ Box::from_raw(<*mut _>::take_ptr(&mut {}.contents.err)) }})", var_name))], + vec![(".result_ok { true => Ok(".to_string(), format!("(*unsafe {{ Box::from_raw(<*mut _>::take_ptr(&mut {}.contents.result)) }})", var_access)), + ("), false => Err(".to_string(), format!("(*unsafe {{ Box::from_raw(<*mut _>::take_ptr(&mut {}.contents.err)) }})", var_access))], ")}")) }, "Vec"|"Slice" if !is_ref => { @@ -1013,9 +1024,9 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { if let Some(syn::Type::Path(p)) = single_contained { if self.c_type_has_inner_from_path(&self.resolve_path(&p.path, generics)) { if is_ref { - return Some(("if ", vec![(".inner.is_null() { None } else { Some((*".to_string(), format!("{}", var_name))], ").clone()) }")) + return Some(("if ", vec![(".inner.is_null() { None } else { Some((*".to_string(), format!("{}", var_access))], ").clone()) }")) } else { - return Some(("if ", vec![(".inner.is_null() { None } else { Some(".to_string(), format!("{}", var_name))], ") }")); + return Some(("if ", vec![(".inner.is_null() { None } else { Some(".to_string(), format!("{}", var_access))], ") }")); } } } @@ -1935,11 +1946,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { if !self.write_c_path_intern(w, &$p_arg.path, generics, true, true, true) { return false; } } } else { - if $p_arg.path.segments.len() == 1 { - write!(w, "{}", $p_arg.path.segments.iter().next().unwrap().ident).unwrap(); - } else { - return false; - } + write!(w, "{}", $p_arg.path.segments.last().unwrap().ident).unwrap(); } } else if self.is_known_container(&subtype, is_ref) || self.is_transparent_container(&subtype, is_ref) { if !self.write_c_mangled_container_path_intern(w, Self::path_to_generic_args(&$p_arg.path), generics,