frame_support_procedural_tools/
lib.rs
1pub use frame_support_procedural_tools_derive::*;
24
25use proc_macro_crate::{crate_name, FoundCrate};
26use quote::quote;
27use syn::parse::Error;
28
29pub mod syn_ext;
30
31use proc_macro2::{Span, TokenStream};
33use syn::Ident;
34
35fn generate_hidden_includes_mod_name(unique_id: &str) -> Ident {
36 Ident::new(&format!("sp_api_hidden_includes_{}", unique_id), Span::call_site())
37}
38
39pub fn generate_crate_access(unique_id: &str, def_crate: &str) -> TokenStream {
41 if std::env::var("CARGO_PKG_NAME").unwrap() == def_crate {
42 let frame_support = match generate_access_from_frame_or_crate("frame-support") {
43 Ok(c) => c,
44 Err(e) => return e.into_compile_error().into(),
45 };
46 quote::quote!(#frame_support)
47 } else {
48 let mod_name = generate_hidden_includes_mod_name(unique_id);
49 quote::quote!( self::#mod_name::hidden_include )
50 }
51}
52
53pub fn is_using_frame_crate(path: &syn::Path) -> bool {
60 path.segments
61 .first()
62 .map(|s| s.ident == "polkadot_sdk_frame" || s.ident == "frame")
63 .unwrap_or(false)
64}
65
66pub fn generate_access_from_frame_or_crate(def_crate: &str) -> Result<syn::Path, Error> {
71 if let Some(path) = get_frame_crate_path(def_crate) {
72 Ok(path)
73 } else if let Some(path) = get_sdk_crate_path(def_crate) {
74 Ok(path)
75 } else {
76 let ident = match crate_name(def_crate) {
77 Ok(FoundCrate::Itself) => {
78 let name = def_crate.to_string().replace("-", "_");
79 Ok(syn::Ident::new(&name, Span::call_site()))
80 },
81 Ok(FoundCrate::Name(name)) => Ok(Ident::new(&name, Span::call_site())),
82 Err(e) => Err(Error::new(Span::call_site(), e)),
83 }?;
84
85 Ok(syn::Path::from(ident))
86 }
87}
88
89pub fn generate_hidden_includes(unique_id: &str, def_crate: &str) -> TokenStream {
91 let mod_name = generate_hidden_includes_mod_name(unique_id);
92
93 if let Some(path) = get_frame_crate_path(def_crate) {
94 quote::quote!(
95 #[doc(hidden)]
96 mod #mod_name {
97 pub use #path as hidden_include;
98 }
99 )
100 } else if let Some(path) = get_sdk_crate_path(def_crate) {
101 quote::quote!(
102 #[doc(hidden)]
103 mod #mod_name {
104 pub use #path as hidden_include;
105 }
106 )
107 } else {
108 match crate_name(def_crate) {
109 Ok(FoundCrate::Itself) => quote!(),
110 Ok(FoundCrate::Name(name)) => {
111 let name = Ident::new(&name, Span::call_site());
112 quote::quote!(
113 #[doc(hidden)]
114 mod #mod_name {
115 pub use #name as hidden_include;
116 }
117 )
118 },
119 Err(e) => {
120 let err = Error::new(Span::call_site(), e).to_compile_error();
121 quote!( #err )
122 },
123 }
124 }
125}
126
127fn get_frame_crate_path(def_crate: &str) -> Option<syn::Path> {
129 if let Ok(FoundCrate::Name(name)) =
131 crate_name(&"polkadot-sdk-frame").or_else(|_| crate_name(&"frame"))
132 {
133 let path = format!("{}::deps::{}", name, def_crate.to_string().replace("-", "_"));
134 Some(syn::parse_str::<syn::Path>(&path).expect("is a valid path; qed"))
135 } else {
136 None
137 }
138}
139
140fn get_sdk_crate_path(def_crate: &str) -> Option<syn::Path> {
141 if let Ok(FoundCrate::Name(name)) = crate_name(&"polkadot-sdk") {
142 let path = format!("{}::{}", name, def_crate.to_string()).replace("-", "_");
143 Some(syn::parse_str::<syn::Path>(&path).expect("is a valid path; qed"))
144 } else {
145 None
146 }
147}
148
149pub fn clean_type_string(input: &str) -> String {
152 input
153 .replace(" ::", "::")
154 .replace(":: ", "::")
155 .replace(" ,", ",")
156 .replace(" ;", ";")
157 .replace(" [", "[")
158 .replace("[ ", "[")
159 .replace(" ]", "]")
160 .replace(" (", "(")
161 .replace("( ", "(")
162 .replace(" )", ")")
163 .replace(" <", "<")
164 .replace("< ", "<")
165 .replace(" >", ">")
166}
167
168pub fn get_doc_literals(attrs: &[syn::Attribute]) -> Vec<syn::Expr> {
170 attrs
171 .iter()
172 .filter_map(|attr| {
173 if let syn::Meta::NameValue(meta) = &attr.meta {
174 meta.path
175 .get_ident()
176 .filter(|ident| *ident == "doc")
177 .map(|_| meta.value.clone())
178 } else {
179 None
180 }
181 })
182 .collect()
183}
184
185pub fn get_cfg_attributes(attrs: &[syn::Attribute]) -> Vec<syn::Attribute> {
187 attrs
188 .iter()
189 .filter_map(|attr| {
190 if let syn::Meta::List(meta) = &attr.meta {
191 meta.path.get_ident().filter(|ident| *ident == "cfg").map(|_| attr.clone())
192 } else {
193 None
194 }
195 })
196 .collect()
197}