X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=c-bindings-gen%2Fsrc%2Fmain.rs;fp=c-bindings-gen%2Fsrc%2Fmain.rs;h=4edad55d1fb9ff9ae071802e76ba5287e77b46dc;hb=304471b1c185ed25ce8fdefa51fdfc5844caf94e;hp=ecbd947baa8fb7dfd72231ee39b73716632842a2;hpb=8f10a1d33d8c4ec38cc39c9e013da24386e13f85;p=rust-lightning diff --git a/c-bindings-gen/src/main.rs b/c-bindings-gen/src/main.rs index ecbd947b..4edad55d 100644 --- a/c-bindings-gen/src/main.rs +++ b/c-bindings-gen/src/main.rs @@ -148,6 +148,9 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty } writeln_docs(w, &t.attrs, ""); + let mut gen_types = GenericTypes::new(); + assert!(gen_types.learn_generics(&t.generics, types)); + writeln!(w, "#[repr(C)]\npub struct {} {{", trait_name).unwrap(); writeln!(w, "\tpub this_arg: *mut c_void,").unwrap(); let associated_types = learn_associated_types(t); @@ -158,15 +161,17 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty match export_status(&m.attrs) { ExportStatus::NoExport => { // NoExport in this context means we'll hit an unimplemented!() at runtime, - // so add a comment noting that this needs to change in the output. - writeln!(w, "\t//XXX: Need to export {}", m.sig.ident).unwrap(); - continue; + // so bail out. + unimplemented!(); }, ExportStatus::Export => {}, ExportStatus::TestOnly => continue, } if m.default.is_some() { unimplemented!(); } + gen_types.push_ctx(); + assert!(gen_types.learn_generics(&m.sig.generics, types)); + writeln_docs(w, &m.attrs, "\t"); if let syn::ReturnType::Type(_, rtype) = &m.sig.output { @@ -183,7 +188,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty // called when the trait method is called which allows updating on the fly. write!(w, "\tpub {}: ", m.sig.ident).unwrap(); generated_fields.push(format!("{}", m.sig.ident)); - types.write_c_type(w, &*r.elem, None, false); + types.write_c_type(w, &*r.elem, Some(&gen_types), false); writeln!(w, ",").unwrap(); writeln!(w, "\t/// Fill in the {} field as a reference to it will be given to Rust after this returns", m.sig.ident).unwrap(); writeln!(w, "\t/// Note that this takes a pointer to this object, not the this_ptr like other methods do").unwrap(); @@ -195,6 +200,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty // which does not compile since Thing is not defined before it is used. writeln!(extra_headers, "struct LDK{};", trait_name).unwrap(); writeln!(extra_headers, "typedef struct LDK{} LDK{};", trait_name, trait_name).unwrap(); + gen_types.pop_ctx(); continue; } // Sadly, this currently doesn't do what we want, but it should be easy to get @@ -204,8 +210,10 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty write!(w, "\tpub {}: extern \"C\" fn (", m.sig.ident).unwrap(); generated_fields.push(format!("{}", m.sig.ident)); - write_method_params(w, &m.sig, &associated_types, "c_void", types, None, true, false); + write_method_params(w, &m.sig, &associated_types, "c_void", types, Some(&gen_types), true, false); writeln!(w, ",").unwrap(); + + gen_types.pop_ctx(); }, &syn::TraitItem::Type(_) => {}, _ => unimplemented!(), @@ -284,8 +292,10 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty m.sig.abi.is_some() || m.sig.variadic.is_some() { unimplemented!(); } + gen_types.push_ctx(); + assert!(gen_types.learn_generics(&m.sig.generics, types)); write!(w, "\tfn {}", m.sig.ident).unwrap(); - types.write_rust_generic_param(w, m.sig.generics.params.iter()); + types.write_rust_generic_param(w, Some(&gen_types), m.sig.generics.params.iter()); write!(w, "(").unwrap(); for inp in m.sig.inputs.iter() { match inp { @@ -309,11 +319,11 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty ident.mutability.is_some() || ident.subpat.is_some() { unimplemented!(); } - write!(w, ", {}{}: ", if types.skip_arg(&*arg.ty, None) { "_" } else { "" }, ident.ident).unwrap(); + write!(w, ", {}{}: ", if types.skip_arg(&*arg.ty, Some(&gen_types)) { "_" } else { "" }, ident.ident).unwrap(); } _ => unimplemented!(), } - types.write_rust_type(w, &*arg.ty); + types.write_rust_type(w, Some(&gen_types), &*arg.ty); } } } @@ -321,15 +331,14 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty match &m.sig.output { syn::ReturnType::Type(_, rtype) => { write!(w, " -> ").unwrap(); - types.write_rust_type(w, &*rtype) + types.write_rust_type(w, Some(&gen_types), &*rtype) }, _ => {}, } write!(w, " {{\n\t\t").unwrap(); match export_status(&m.attrs) { ExportStatus::NoExport => { - writeln!(w, "unimplemented!();\n\t}}").unwrap(); - continue; + unimplemented!(); }, _ => {}, } @@ -339,25 +348,27 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty writeln!(w, "if let Some(f) = self.set_{} {{", m.sig.ident).unwrap(); writeln!(w, "\t\t\t(f)(self);").unwrap(); write!(w, "\t\t}}\n\t\t").unwrap(); - types.write_from_c_conversion_to_ref_prefix(w, &*r.elem, None); + types.write_from_c_conversion_to_ref_prefix(w, &*r.elem, Some(&gen_types)); write!(w, "self.{}", m.sig.ident).unwrap(); - types.write_from_c_conversion_to_ref_suffix(w, &*r.elem, None); + types.write_from_c_conversion_to_ref_suffix(w, &*r.elem, Some(&gen_types)); writeln!(w, "\n\t}}").unwrap(); + gen_types.pop_ctx(); continue; } } - write_method_var_decl_body(w, &m.sig, "\t", types, None, true); + write_method_var_decl_body(w, &m.sig, "\t", types, Some(&gen_types), true); write!(w, "(self.{})(", m.sig.ident).unwrap(); - write_method_call_params(w, &m.sig, &associated_types, "\t", types, None, "", true); + write_method_call_params(w, &m.sig, &associated_types, "\t", types, Some(&gen_types), "", true); writeln!(w, "\n\t}}").unwrap(); + gen_types.pop_ctx(); }, &syn::TraitItem::Type(ref t) => { if t.default.is_some() || t.generics.lt_token.is_some() { unimplemented!(); } let mut bounds_iter = t.bounds.iter(); match bounds_iter.next().unwrap() { syn::TypeParamBound::Trait(tr) => { - writeln!(w, "\ttype {} = crate::{};", t.ident, types.resolve_path(&tr.path, None)).unwrap(); + writeln!(w, "\ttype {} = crate::{};", t.ident, types.resolve_path(&tr.path, Some(&gen_types))).unwrap(); }, _ => unimplemented!(), }