Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Make transactional attribute less scope dependent #7112

Merged
merged 2 commits into from
Sep 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions frame/support/procedural/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// tag::description[]
//! Proc macro of Support code for the runtime.
// end::description[]

#![recursion_limit="512"]

Expand Down Expand Up @@ -296,7 +294,7 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream {
/// The return type of the annotated function must be `Result`. All changes to storage performed
/// by the annotated function are discarded if it returns `Err`, or committed if `Ok`.
///
/// #Example
/// # Example
///
/// ```nocompile
/// #[transactional]
Expand All @@ -313,5 +311,5 @@ pub fn construct_runtime(input: TokenStream) -> TokenStream {
/// ```
#[proc_macro_attribute]
pub fn transactional(attr: TokenStream, input: TokenStream) -> TokenStream {
transactional::transactional(attr, input)
transactional::transactional(attr, input).unwrap_or_else(|e| e.to_compile_error().into())
}
gui1117 marked this conversation as resolved.
Show resolved Hide resolved
19 changes: 11 additions & 8 deletions frame/support/procedural/src/transactional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@

use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, ItemFn};
use syn::{ItemFn, Result};
use frame_support_procedural_tools::generate_crate_access_2018;

pub fn transactional(_attr: TokenStream, input: TokenStream) -> TokenStream {
let ItemFn { attrs, vis, sig, block } = parse_macro_input!(input as ItemFn);
pub fn transactional(_attr: TokenStream, input: TokenStream) -> Result<TokenStream> {
let ItemFn { attrs, vis, sig, block } = syn::parse(input)?;

let crate_ = generate_crate_access_2018()?;
let output = quote! {
#(#attrs)*
#vis #sig {
use frame_support::storage::{with_transaction, TransactionOutcome};
#vis #sig {
use #crate_::storage::{with_transaction, TransactionOutcome};
with_transaction(|| {
let r = #block;
if r.is_ok() {
Expand All @@ -34,7 +36,8 @@ pub fn transactional(_attr: TokenStream, input: TokenStream) -> TokenStream {
TransactionOutcome::Rollback(r)
}
})
}
};
output.into()
}
};

Ok(output.into())
}
19 changes: 19 additions & 0 deletions frame/support/procedural/tools/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@ pub fn generate_crate_access(unique_id: &str, def_crate: &str) -> TokenStream {
}
}

/// Generate the crate access for the `frame-support` crate using 2018 syntax.
///
/// Output will for example be `frame_support`.
pub fn generate_crate_access_2018() -> Result<TokenStream, Error> {
if std::env::var("CARGO_PKG_NAME").unwrap() == "frame-support" {
Ok(quote::quote!( frame_support ))
} else {
match crate_name("frame-support") {
Ok(name) => {
let name = Ident::new(&name, Span::call_site());
Ok(quote!( #name ))
},
Err(e) => {
Err(Error::new(Span::call_site(), &e))
}
}
}
}

/// Generates the hidden includes that are required to make the macro independent from its scope.
pub fn generate_hidden_includes(unique_id: &str, def_crate: &str) -> TokenStream {
if std::env::var("CARGO_PKG_NAME").unwrap() == def_crate {
Expand Down