Repository: paritytech/substrate
File: frame/support/procedural/src/construct_runtime/mod.rs (Rust)

Code before:
use std::{collections::HashSet, str::FromStr};
use syn::{spanned::Spanned, Ident, Result};

/// The fixed name of the system pallet.
const SYSTEM_PALLET_NAME: &str = "System";

/// Implementation of `construct_runtime` macro. Either expand to some code which will call
/// `construct_runtime` again, or expand to the final runtime definition.
pub fn construct_runtime(input: TokenStream) -> TokenStream {
	let input_copy = input.clone();
	let definition = syn::parse_macro_input!(input as RuntimeDeclaration);

	let res = match definition {
		RuntimeDeclaration::Implicit(implicit_def) =>
			check_pallet_number(input_copy.clone().into(), implicit_def.pallets.len()).and_then(
				|_| construct_runtime_intermediary_expansion(input_copy.into(), implicit_def),
			),
		RuntimeDeclaration::Explicit(explicit_decl) =>
			check_pallet_number(input_copy.into(), explicit_decl.pallets.len())
				.and_then(|_| construct_runtime_final_expansion(explicit_decl)),
	};

	let res = res.unwrap_or_else(|e| e.to_compile_error());

	let res = expander::Expander::new("construct_runtime")
		.dry(std::env::var("SP_API_EXPAND").is_err())
		.verbose(true)
		.write_to_out_dir(res)
		.expect("Does not fail because of IO in OUT_DIR; qed");

	res.into()
}

/// When some pallet have implicit parts definition then the macro will expand into a macro call to
/// `construct_runtime_args` of each pallets, see root documentation.
fn construct_runtime_intermediary_expansion(
	input: TokenStream2,
	definition: ImplicitRuntimeDeclaration,
) -> Result<TokenStream2> {
	let frame_support = generate_crate_access_2018("frame-support")?;
	let mut expansion = quote::quote!(
		#frame_support::construct_runtime! { #input }
	);
	for pallet in definition.pallets.iter().filter(|pallet| pallet.pallet_parts.is_none()) {
		let pallet_path = &pallet.path;
		let pallet_name = &pallet.name;
		let pallet_instance = pallet.instance.as_ref().map(|instance| quote::quote!(::<#instance>));
		expansion = quote::quote!(
			#frame_support::tt_call! {
				macro = [{ #pallet_path::tt_default_parts }]
				frame_support = [{ #frame_support }]

Review comment (refactor):
```suggestion
		.dry(std::env::var("FRAME_EXPAND").is_err())
```

Or something similar. The current naming was "exclusively" for `sp-api`.

Code after:
use std::{collections::HashSet, str::FromStr};
use syn::{spanned::Spanned, Ident, Result};

/// The fixed name of the system pallet.
const SYSTEM_PALLET_NAME: &str = "System";

/// Implementation of `construct_runtime` macro. Either expand to some code which will call
/// `construct_runtime` again, or expand to the final runtime definition.
pub fn construct_runtime(input: TokenStream) -> TokenStream {
	let input_copy = input.clone();
	let definition = syn::parse_macro_input!(input as RuntimeDeclaration);

	let res = match definition {
		RuntimeDeclaration::Implicit(implicit_def) =>
			check_pallet_number(input_copy.clone().into(), implicit_def.pallets.len()).and_then(
				|_| construct_runtime_intermediary_expansion(input_copy.into(), implicit_def),
			),
		RuntimeDeclaration::Explicit(explicit_decl) =>
			check_pallet_number(input_copy.into(), explicit_decl.pallets.len())
				.and_then(|_| construct_runtime_final_expansion(explicit_decl)),
	};

	let res = res.unwrap_or_else(|e| e.to_compile_error());

	let res = expander::Expander::new("construct_runtime")
		.dry(std::env::var("FRAME_EXPAND").is_err())
		.verbose(true)
		.write_to_out_dir(res)
		.expect("Does not fail because of IO in OUT_DIR; qed");

	res.into()
}

/// When some pallet have implicit parts definition then the macro will expand into a macro call to
/// `construct_runtime_args` of each pallets, see root documentation.
fn construct_runtime_intermediary_expansion(
	input: TokenStream2,
	definition: ImplicitRuntimeDeclaration,
) -> Result<TokenStream2> {
	let frame_support = generate_crate_access_2018("frame-support")?;
	let mut expansion = quote::quote!(
		#frame_support::construct_runtime! { #input }
	);
	for pallet in definition.pallets.iter().filter(|pallet| pallet.pallet_parts.is_none()) {
		let pallet_path = &pallet.path;
		let pallet_name = &pallet.name;
		let pallet_instance = pallet.instance.as_ref().map(|instance| quote::quote!(::<#instance>));
		expansion = quote::quote!(
			#frame_support::tt_call! {
				macro = [{ #pallet_path::tt_default_parts }]
				frame_support = [{ #frame_support }]