pub use frame_support_procedural_tools_derive::*;
use proc_macro_crate::{crate_name, FoundCrate};
use quote::quote;
use syn::parse::Error;
pub mod syn_ext;
use proc_macro2::{Span, TokenStream};
use syn::Ident;
fn generate_hidden_includes_mod_name(unique_id: &str) -> Ident {
Ident::new(&format!("sp_api_hidden_includes_{}", unique_id), Span::call_site())
}
pub fn generate_crate_access(unique_id: &str, def_crate: &str) -> TokenStream {
if std::env::var("CARGO_PKG_NAME").unwrap() == def_crate {
let frame_support = match generate_access_from_frame_or_crate("frame-support") {
Ok(c) => c,
Err(e) => return e.into_compile_error().into(),
};
quote::quote!(#frame_support)
} else {
let mod_name = generate_hidden_includes_mod_name(unique_id);
quote::quote!( self::#mod_name::hidden_include )
}
}
pub fn is_using_frame_crate(path: &syn::Path) -> bool {
path.segments
.first()
.map(|s| s.ident == "polkadot_sdk_frame" || s.ident == "frame")
.unwrap_or(false)
}
pub fn generate_access_from_frame_or_crate(def_crate: &str) -> Result<syn::Path, Error> {
if let Some(path) = get_frame_crate_path(def_crate) {
Ok(path)
} else if let Some(path) = get_sdk_crate_path(def_crate) {
Ok(path)
} else {
let ident = match crate_name(def_crate) {
Ok(FoundCrate::Itself) => {
let name = def_crate.to_string().replace("-", "_");
Ok(syn::Ident::new(&name, Span::call_site()))
},
Ok(FoundCrate::Name(name)) => Ok(Ident::new(&name, Span::call_site())),
Err(e) => Err(Error::new(Span::call_site(), e)),
}?;
Ok(syn::Path::from(ident))
}
}
pub fn generate_hidden_includes(unique_id: &str, def_crate: &str) -> TokenStream {
let mod_name = generate_hidden_includes_mod_name(unique_id);
if let Some(path) = get_frame_crate_path(def_crate) {
quote::quote!(
#[doc(hidden)]
mod #mod_name {
pub use #path as hidden_include;
}
)
} else if let Some(path) = get_sdk_crate_path(def_crate) {
quote::quote!(
#[doc(hidden)]
mod #mod_name {
pub use #path as hidden_include;
}
)
} else {
match crate_name(def_crate) {
Ok(FoundCrate::Itself) => quote!(),
Ok(FoundCrate::Name(name)) => {
let name = Ident::new(&name, Span::call_site());
quote::quote!(
#[doc(hidden)]
mod #mod_name {
pub use #name as hidden_include;
}
)
},
Err(e) => {
let err = Error::new(Span::call_site(), e).to_compile_error();
quote!( #err )
},
}
}
}
fn get_frame_crate_path(def_crate: &str) -> Option<syn::Path> {
if let Ok(FoundCrate::Name(name)) =
crate_name(&"polkadot-sdk-frame").or_else(|_| crate_name(&"frame"))
{
let path = format!("{}::deps::{}", name, def_crate.to_string().replace("-", "_"));
Some(syn::parse_str::<syn::Path>(&path).expect("is a valid path; qed"))
} else {
None
}
}
fn get_sdk_crate_path(def_crate: &str) -> Option<syn::Path> {
if let Ok(FoundCrate::Name(name)) = crate_name(&"polkadot-sdk") {
let path = format!("{}::{}", name, def_crate.to_string()).replace("-", "_");
Some(syn::parse_str::<syn::Path>(&path).expect("is a valid path; qed"))
} else {
None
}
}
pub fn clean_type_string(input: &str) -> String {
input
.replace(" ::", "::")
.replace(":: ", "::")
.replace(" ,", ",")
.replace(" ;", ";")
.replace(" [", "[")
.replace("[ ", "[")
.replace(" ]", "]")
.replace(" (", "(")
.replace("( ", "(")
.replace(" )", ")")
.replace(" <", "<")
.replace("< ", "<")
.replace(" >", ">")
}
pub fn get_doc_literals(attrs: &[syn::Attribute]) -> Vec<syn::Expr> {
attrs
.iter()
.filter_map(|attr| {
if let syn::Meta::NameValue(meta) = &attr.meta {
meta.path
.get_ident()
.filter(|ident| *ident == "doc")
.map(|_| meta.value.clone())
} else {
None
}
})
.collect()
}