From: Matt Corallo <649246+TheBlueMatt@users.noreply.github.com> Date: Mon, 26 Apr 2021 16:01:51 +0000 (+0000) Subject: Merge pull request #16 from afilini/cleanup X-Git-Tag: v0.0.98~12 X-Git-Url: http://git.bitcoin.ninja/index.cgi?p=ldk-c-bindings;a=commitdiff_plain;h=29298fd16d3c535cb9d3bfb64fb9854e50998901;hp=99d22ba053fc347d8116572f20ef1431fc05dee9 Merge pull request #16 from afilini/cleanup Minor cleanup/refactoring --- diff --git a/c-bindings-gen/.gitignore b/c-bindings-gen/.gitignore new file mode 100644 index 0000000..fa8d85a --- /dev/null +++ b/c-bindings-gen/.gitignore @@ -0,0 +1,2 @@ +Cargo.lock +target diff --git a/c-bindings-gen/Cargo.toml b/c-bindings-gen/Cargo.toml index d963e43..d5f8089 100644 --- a/c-bindings-gen/Cargo.toml +++ b/c-bindings-gen/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [dependencies] syn = { version = "1", features = ["full", "extra-traits"] } proc-macro2 = "1" +quote = "1" [profile.release] incremental = true diff --git a/c-bindings-gen/src/blocks.rs b/c-bindings-gen/src/blocks.rs index bbb41e0..5626779 100644 --- a/c-bindings-gen/src/blocks.rs +++ b/c-bindings-gen/src/blocks.rs @@ -11,7 +11,9 @@ use std::fs::File; use std::io::Write; -use proc_macro2::{TokenTree, Span}; + +use proc_macro2::TokenTree; +use quote::format_ident; use crate::types::*; @@ -502,7 +504,7 @@ pub fn write_method_params(w: &mut W, sig: &syn::Signature, t /// mut ret = " assuming the next print will be the unmapped Rust function to call followed by the /// parameters we mapped to/from C here. pub fn write_method_var_decl_body(w: &mut W, sig: &syn::Signature, extra_indent: &str, types: &TypeResolver, generics: Option<&GenericTypes>, to_c: bool) { - let mut num_unused = 0; + let mut num_unused = 0u32; for inp in sig.inputs.iter() { match inp { syn::FnArg::Receiver(_) => {}, @@ -531,7 +533,7 @@ pub fn write_method_var_decl_body(w: &mut W, sig: &syn::Signa }, syn::Pat::Wild(w) => { if !w.attrs.is_empty() { unimplemented!(); } - write_new_var!(syn::Ident::new(&format!("unused_{}", num_unused), Span::call_site()), *arg.ty); + write_new_var!(format_ident!("unused_{}", num_unused), *arg.ty); num_unused += 1; }, _ => unimplemented!(), @@ -624,7 +626,7 @@ pub fn write_method_call_params(w: &mut W, sig: &syn::Signatu // If we're returning "Self" (and not "Self::X"), just do it manually write!(w, "{} {{ inner: Box::into_raw(Box::new(ret)), is_owned: true }}", this_type).unwrap(); } else if to_c { - let new_var = types.write_from_c_conversion_new_var(w, &syn::Ident::new("ret", Span::call_site()), rtype, generics); + let new_var = types.write_from_c_conversion_new_var(w, &format_ident!("ret"), rtype, generics); if new_var { write!(w, "\n\t{}", extra_indent).unwrap(); } @@ -633,7 +635,7 @@ pub fn write_method_call_params(w: &mut W, sig: &syn::Signatu types.write_from_c_conversion_suffix(w, &*rtype, generics); } else { let ret_returned = if let syn::Type::Reference(_) = &**rtype { true } else { false }; - let new_var = types.write_to_c_conversion_new_var(w, &syn::Ident::new("ret", Span::call_site()), &rtype, generics, true); + let new_var = types.write_to_c_conversion_new_var(w, &format_ident!("ret"), &rtype, generics, true); if new_var { write!(w, "\n\t{}", extra_indent).unwrap(); } diff --git a/c-bindings-gen/src/main.rs b/c-bindings-gen/src/main.rs index e217bab..d107f3e 100644 --- a/c-bindings-gen/src/main.rs +++ b/c-bindings-gen/src/main.rs @@ -25,6 +25,8 @@ use std::io::{Read, Write}; use std::process; use proc_macro2::Span; +use quote::format_ident; +use syn::parse_quote; mod types; mod blocks; @@ -63,10 +65,8 @@ fn maybe_convert_trait_impl(w: &mut W, trait_path: &syn::Path writeln!(w, "/// Serialize the {} object into a byte array which can be read by {}_read", for_obj, for_obj).unwrap(); writeln!(w, "pub extern \"C\" fn {}_write(obj: &{}) -> crate::c_types::derived::CVec_u8Z {{", for_obj, full_obj_path).unwrap(); - let ref_type = syn::Type::Reference(syn::TypeReference { - and_token: syn::Token!(&)(Span::call_site()), lifetime: None, mutability: None, - elem: Box::new(for_ty.clone()) }); - assert!(!types.write_from_c_conversion_new_var(w, &syn::Ident::new("obj", Span::call_site()), &ref_type, Some(generics))); + let ref_type: syn::Type = syn::parse_quote!(&#for_ty); + assert!(!types.write_from_c_conversion_new_var(w, &format_ident!("obj"), &ref_type, Some(generics))); write!(w, "\tcrate::c_types::serialize_obj(").unwrap(); types.write_from_c_conversion_prefix(w, &ref_type, Some(generics)); @@ -84,26 +84,7 @@ fn maybe_convert_trait_impl(w: &mut W, trait_path: &syn::Path }, "lightning::util::ser::Readable"|"lightning::util::ser::ReadableArgs" => { // Create the Result syn::Type - let mut err_segs = syn::punctuated::Punctuated::new(); - err_segs.push(syn::PathSegment { ident: syn::Ident::new("ln", Span::call_site()), arguments: syn::PathArguments::None }); - err_segs.push(syn::PathSegment { ident: syn::Ident::new("msgs", Span::call_site()), arguments: syn::PathArguments::None }); - err_segs.push(syn::PathSegment { ident: syn::Ident::new("DecodeError", Span::call_site()), arguments: syn::PathArguments::None }); - let mut args = syn::punctuated::Punctuated::new(); - args.push(syn::GenericArgument::Type(for_ty.clone())); - args.push(syn::GenericArgument::Type(syn::Type::Path(syn::TypePath { - qself: None, path: syn::Path { - leading_colon: Some(syn::Token![::](Span::call_site())), segments: err_segs, - } - }))); - let mut res_segs = syn::punctuated::Punctuated::new(); - res_segs.push(syn::PathSegment { - ident: syn::Ident::new("Result", 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()), - }) - }); - let res_ty = syn::Type::Path(syn::TypePath { qself: None, path: syn::Path { - leading_colon: None, segments: res_segs } }); + let res_ty: syn::Type = parse_quote!(Result<#for_ty, ::ln::msgs::DecodeError>); writeln!(w, "#[no_mangle]").unwrap(); writeln!(w, "/// Read a {} from a byte array, created by {}_write", for_obj, for_obj).unwrap(); @@ -120,7 +101,7 @@ fn maybe_convert_trait_impl(w: &mut W, trait_path: &syn::Path if let syn::GenericArgument::Type(args_ty) = args.args.iter().next().unwrap() { types.write_c_type(w, args_ty, Some(generics), false); - assert!(!types.write_from_c_conversion_new_var(&mut arg_conv, &syn::Ident::new("arg", Span::call_site()), &args_ty, Some(generics))); + assert!(!types.write_from_c_conversion_new_var(&mut arg_conv, &format_ident!("arg"), &args_ty, Some(generics))); write!(&mut arg_conv, "\tlet arg_conv = ").unwrap(); types.write_from_c_conversion_prefix(&mut arg_conv, &args_ty, Some(generics)); @@ -143,7 +124,7 @@ fn maybe_convert_trait_impl(w: &mut W, trait_path: &syn::Path writeln!(w, "\tlet res = crate::c_types::deserialize_obj(ser);").unwrap(); } write!(w, "\t").unwrap(); - if types.write_to_c_conversion_new_var(w, &syn::Ident::new("res", Span::call_site()), &res_ty, Some(generics), false) { + if types.write_to_c_conversion_new_var(w, &format_ident!("res"), &res_ty, Some(generics), false) { write!(w, "\n\t").unwrap(); } types.write_to_c_conversion_inline_prefix(w, &res_ty, Some(generics), false); @@ -622,7 +603,7 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct, write!(w, "#[no_mangle]\npub extern \"C\" fn {}_get_{}(this_ptr: &{}) -> ", struct_name, ident, struct_name).unwrap(); types.write_c_type(w, &ref_type, Some(&gen_types), true); write!(w, " {{\n\tlet mut inner_val = &mut unsafe {{ &mut *this_ptr.inner }}.{};\n\t", ident).unwrap(); - let local_var = types.write_to_c_conversion_new_var(w, &syn::Ident::new("inner_val", Span::call_site()), &ref_type, Some(&gen_types), true); + let local_var = types.write_to_c_conversion_new_var(w, &format_ident!("inner_val"), &ref_type, Some(&gen_types), true); if local_var { write!(w, "\n\t").unwrap(); } types.write_to_c_conversion_inline_prefix(w, &ref_type, Some(&gen_types), true); if local_var { @@ -639,7 +620,7 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct, write!(w, "#[no_mangle]\npub extern \"C\" fn {}_set_{}(this_ptr: &mut {}, mut val: ", struct_name, ident, struct_name).unwrap(); types.write_c_type(w, &field.ty, Some(&gen_types), false); write!(w, ") {{\n\t").unwrap(); - let local_var = types.write_from_c_conversion_new_var(w, &syn::Ident::new("val", Span::call_site()), &field.ty, Some(&gen_types)); + let local_var = types.write_from_c_conversion_new_var(w, &format_ident!("val"), &field.ty, Some(&gen_types)); if local_var { write!(w, "\n\t").unwrap(); } write!(w, "unsafe {{ &mut *this_ptr.inner }}.{} = ", ident).unwrap(); types.write_from_c_conversion_prefix(w, &field.ty, Some(&gen_types)); @@ -662,8 +643,8 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct, } write!(w, ") -> {} {{\n\t", struct_name).unwrap(); for field in fields.named.iter() { - let field_name = format!("{}_arg", field.ident.as_ref().unwrap()); - if types.write_from_c_conversion_new_var(w, &syn::Ident::new(&field_name, Span::call_site()), &field.ty, Some(&gen_types)) { + let field_ident = format_ident!("{}_arg", field.ident.as_ref().unwrap()); + if types.write_from_c_conversion_new_var(w, &field_ident, &field.ty, Some(&gen_types)) { write!(w, "\n\t").unwrap(); } } @@ -1185,7 +1166,7 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type if $ref { write!(w, "let mut {}_nonref = (*{}).clone();\n\t\t\t\t", $field_ident, $field_ident).unwrap(); if new_var { - let nonref_ident = syn::Ident::new(&format!("{}_nonref", $field_ident), Span::call_site()); + let nonref_ident = format_ident!("{}_nonref", $field_ident); if $to_c { types.write_to_c_conversion_new_var(w, &nonref_ident, &$field.ty, None, false); } else { @@ -1207,7 +1188,7 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type } else if let syn::Fields::Unnamed(fields) = &var.fields { write!(w, " {{\n\t\t\t\t").unwrap(); for (idx, field) in fields.unnamed.iter().enumerate() { - handle_field_a!(field, &syn::Ident::new(&(('a' as u8 + idx as u8) as char).to_string(), Span::call_site())); + handle_field_a!(field, &format_ident!("{}", ('a' as u8 + idx as u8) as char)); } } else { write!(w, " ").unwrap(); } @@ -1245,7 +1226,7 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type write!(w, " (").unwrap(); for (idx, field) in fields.unnamed.iter().enumerate() { write!(w, "\n\t\t\t\t\t").unwrap(); - handle_field_b!(field, &syn::Ident::new(&(('a' as u8 + idx as u8) as char).to_string(), Span::call_site())); + handle_field_b!(field, &format_ident!("{}", ('a' as u8 + idx as u8) as char)); } writeln!(w, "\n\t\t\t\t)").unwrap(); write!(w, "\t\t\t}}").unwrap(); @@ -1505,20 +1486,17 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a if process_alias { match &*t.ty { syn::Type::Path(p) => { + let t_ident = &t.ident; + // If its a path with no generics, assume we don't map the aliased type and map it opaque - let mut segments = syn::punctuated::Punctuated::new(); - segments.push(syn::PathSegment { - ident: t.ident.clone(), - arguments: syn::PathArguments::None, - }); - let path_obj = syn::Path { leading_colon: None, segments }; + let path_obj = parse_quote!(#t_ident); let args_obj = p.path.segments.last().unwrap().arguments.clone(); match crate_types.reverse_alias_map.entry(import_resolver.maybe_resolve_path(&p.path, None).unwrap()) { hash_map::Entry::Occupied(mut e) => { e.get_mut().push((path_obj, args_obj)); }, hash_map::Entry::Vacant(e) => { e.insert(vec![(path_obj, args_obj)]); }, } - crate_types.opaques.insert(type_path.clone(), &t.ident); + crate_types.opaques.insert(type_path, t_ident); }, _ => { crate_types.type_aliases.insert(type_path, import_resolver.resolve_imported_refs((*t.ty).clone())); diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index 80ad2af..c8b71d6 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. @@ -341,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 { @@ -383,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 { @@ -1457,15 +1460,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 } } @@ -1858,7 +1853,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(); } @@ -1983,7 +1978,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) { @@ -2397,15 +2392,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 } }, diff --git a/lightning-c-bindings/src/c_types/mod.rs b/lightning-c-bindings/src/c_types/mod.rs index 14e3722..ee7660c 100644 --- a/lightning-c-bindings/src/c_types/mod.rs +++ b/lightning-c-bindings/src/c_types/mod.rs @@ -3,7 +3,6 @@ /// Auto-generated C-mapped types for templated containers pub mod derived; -use bitcoin::Script as BitcoinScript; use bitcoin::Transaction as BitcoinTransaction; use bitcoin::hashes::Hash; use bitcoin::secp256k1::key::PublicKey as SecpPublicKey;