+/// A public module
+pub struct ASTModule {
+ pub attrs: Vec<syn::Attribute>,
+ pub items: Vec<syn::Item>,
+ pub submods: Vec<String>,
+}
+/// A struct containing the syn::File AST for each file in the crate.
+pub struct FullLibraryAST {
+ pub modules: HashMap<String, ASTModule, NonRandomHash>,
+ pub dependencies: HashSet<syn::Ident>,
+}
+impl FullLibraryAST {
+ fn load_module(&mut self, module: String, attrs: Vec<syn::Attribute>, mut items: Vec<syn::Item>) {
+ let mut non_mod_items = Vec::with_capacity(items.len());
+ let mut submods = Vec::with_capacity(items.len());
+ for item in items.drain(..) {
+ match item {
+ syn::Item::Mod(m) if m.content.is_some() => {
+ if export_status(&m.attrs) == ExportStatus::Export {
+ if let syn::Visibility::Public(_) = m.vis {
+ let modident = format!("{}", m.ident);
+ let modname = if module != "" {
+ module.clone() + "::" + &modident
+ } else {
+ self.dependencies.insert(m.ident);
+ modident.clone()
+ };
+ self.load_module(modname, m.attrs, m.content.unwrap().1);
+ submods.push(modident);
+ } else {
+ non_mod_items.push(syn::Item::Mod(m));
+ }
+ }
+ },
+ syn::Item::Mod(_) => panic!("--pretty=expanded output should never have non-body modules"),
+ syn::Item::ExternCrate(c) => {
+ if export_status(&c.attrs) == ExportStatus::Export {
+ self.dependencies.insert(c.ident);
+ }
+ },
+ _ => { non_mod_items.push(item); }
+ }
+ }
+ self.modules.insert(module, ASTModule { attrs, items: non_mod_items, submods });
+ }
+
+ pub fn load_lib(lib: syn::File) -> Self {
+ assert_eq!(export_status(&lib.attrs), ExportStatus::Export);
+ let mut res = Self { modules: HashMap::default(), dependencies: HashSet::new() };
+ res.load_module("".to_owned(), lib.attrs, lib.items);
+ res
+ }
+}
+
+/// List of manually-generated types which are clonable
+fn initial_clonable_types() -> HashSet<String> {
+ let mut res = HashSet::new();
+ res.insert("crate::c_types::u5".to_owned());
+ res.insert("crate::c_types::FourBytes".to_owned());
+ res.insert("crate::c_types::TwelveBytes".to_owned());
+ res.insert("crate::c_types::SixteenBytes".to_owned());
+ res.insert("crate::c_types::TwentyBytes".to_owned());
+ res.insert("crate::c_types::ThirtyTwoBytes".to_owned());
+ res.insert("crate::c_types::SecretKey".to_owned());
+ res.insert("crate::c_types::PublicKey".to_owned());
+ res.insert("crate::c_types::Transaction".to_owned());
+ res.insert("crate::c_types::TxOut".to_owned());
+ res.insert("crate::c_types::Signature".to_owned());
+ res.insert("crate::c_types::RecoverableSignature".to_owned());
+ res.insert("crate::c_types::Bech32Error".to_owned());
+ res.insert("crate::c_types::Secp256k1Error".to_owned());
+ res.insert("crate::c_types::IOError".to_owned());
+ res.insert("crate::c_types::Error".to_owned());
+ res.insert("crate::c_types::Str".to_owned());
+
+ // Because some types are manually-mapped to CVec_u8Z we may end up checking if its clonable
+ // before we ever get to constructing the type fully via
+ // `write_c_mangled_container_path_intern` (which will add it here too), so we have to manually
+ // add it on startup.
+ res.insert("crate::c_types::derived::CVec_u8Z".to_owned());
+ res
+}
+