Skip to content

Commit

Permalink
Deprecation info support in RuntimeMetadataIR (#4851)
Browse files Browse the repository at this point in the history
### Description: 
* Adds `DeprecationStatusIR` enum to sp_metadata_ir.
Deprecation info for simple items.
* Adds `DeprecationInfoIR` enum to sp_metadata_ir.
It is a deprecation info for an enums/errors/calls. Contains
`DeprecationStatusIR`.
Denotes full/partial deprecation of the type or its variants/calls
* Adds `deprecation_info` field to 
       - `RuntimeApiMetadataIR`
       - `RuntimeApiMethodMetadataIR`
       - `StorageEntryMetadataIR`
       - `PalletConstantMetadataIR`
       - `PalletCallMetadataIR`
       - `PalletMetadataIR`
       - `PalletEventMetadataIR`
       - `PalletErrorMetadataIR`

### Testing done: 
- Unit tests to check whether or not correct `note`/`since` texts are
getting propagated to the metadata structs.
- UI test to check for error message in case of incorrect attribute
usage.
There's also some test updates to make sure that deprecation attributes
are getting propagated to the relevant structs.

see: #4098, Solution: A

### Examples of produced deprecation info metadata
They can be found in:
 - Tests for `frame-support`
 - hackmd link https://hackmd.io/@Zett98/Bys0YgbcR

---------

Co-authored-by: GitHub Action <[email protected]>
Co-authored-by: command-bot <>
Co-authored-by: Bastian Köcher <[email protected]>
  • Loading branch information
3 people authored Sep 11, 2024
1 parent 8f6699b commit ec9a734
Show file tree
Hide file tree
Showing 44 changed files with 1,319 additions and 207 deletions.
40 changes: 40 additions & 0 deletions prdoc/pr_4851.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json

title: Add support for deprecation metadata in `RuntimeMetadataIr` entries.

doc:
- audience:
- Runtime dev
- Runtime user
description: |
Changes introduced are listed below.
Adds `DeprecationStatusIR` enum to sp_metadata_ir.
- Is a deprecation info for simple items.
Adds `DeprecationInfoIR` enum to sp_metadata_ir.
- It is a deprecation info for an enums/errors/calls. Contains `DeprecationStatusIR`.
Also denotes full/partial deprecation of the type or its variants/calls.
Adds `deprecation_info` field to
- `RuntimeApiMetadataIR`
- `RuntimeApiMethodMetadataIR`
- `StorageEntryMetadataIR`
- `PalletConstantMetadataIR`
- `PalletCallMetadataIR`
- `PalletMetadataIR`
- `PalletEventMetadataIR`
- `PalletErrorMetadataIR`
Examples of the deprecation info produced can be seen inside
- Tests for `frame-support`
- hackmd link https://hackmd.io/@Zett98/Bys0YgbcR

crates:
- name: frame-support-procedural
bump: patch
- name: frame-support
bump: major
- name: sp-api-proc-macro
bump: patch
- name: sp-api
bump: patch
- name: sp-metadata-ir
bump: major
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ fn derive_impl_works_with_no_aggregated_types() {
type Block = super::Block;
type AccountId = super::AccountId;
type PalletInfo = super::PalletInfo;
type ExampleConstant = ();
}

assert_type_eq_all!(<DummyRuntime as Config>::RuntimeOrigin, ());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![allow(deprecated, clippy::deprecated_semver)]

use super::{frame_system, Block};
use crate::derive_impl;
Expand Down Expand Up @@ -121,6 +122,7 @@ mod runtime {
// Ensure that the runtime does not export the calls from the pallet
#[runtime::pallet_index(4)]
#[runtime::disable_call]
#[deprecated = "example"]
pub type PalletWithDisabledCall = pallet_with_disabled_call::Pallet<Runtime>;

// Ensure that the runtime does not export the unsigned calls from the pallet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub fn expand_runtime_metadata(
let index = &decl.index;
let storage = expand_pallet_metadata_storage(&filtered_names, runtime, decl);
let calls = expand_pallet_metadata_calls(&filtered_names, runtime, decl);
let event = expand_pallet_metadata_events(&filtered_names, runtime, scrate, decl);
let event = expand_pallet_metadata_events(&filtered_names, runtime, decl);
let constants = expand_pallet_metadata_constants(runtime, decl);
let errors = expand_pallet_metadata_errors(runtime, decl);
let docs = expand_pallet_metadata_docs(runtime, decl);
Expand All @@ -58,7 +58,7 @@ pub fn expand_runtime_metadata(
#attr
}
});

let deprecation_info = expand_pallet_metadata_deprecation(runtime, decl);
quote! {
#attr
#scrate::__private::metadata_ir::PalletMetadataIR {
Expand All @@ -70,6 +70,7 @@ pub fn expand_runtime_metadata(
constants: #constants,
error: #errors,
docs: #docs,
deprecation_info: #deprecation_info,
}
}
})
Expand Down Expand Up @@ -200,7 +201,6 @@ fn expand_pallet_metadata_calls(
fn expand_pallet_metadata_events(
filtered_names: &[&'static str],
runtime: &Ident,
scrate: &TokenStream,
decl: &Pallet,
) -> TokenStream {
if filtered_names.contains(&"Event") {
Expand All @@ -220,16 +220,21 @@ fn expand_pallet_metadata_events(

quote! {
Some(
#scrate::__private::metadata_ir::PalletEventMetadataIR {
ty: #scrate::__private::scale_info::meta_type::<#pallet_event>()
}
#pallet_event::event_metadata::<#pallet_event>()
)
}
} else {
quote!(None)
}
}

fn expand_pallet_metadata_deprecation(runtime: &Ident, decl: &Pallet) -> TokenStream {
let path = &decl.path;
let instance = decl.instance.as_ref().into_iter();

quote! { #path::Pallet::<#runtime #(, #path::#instance)*>::deprecation_info() }
}

fn expand_pallet_metadata_constants(runtime: &Ident, decl: &Pallet) -> TokenStream {
let path = &decl.path;
let instance = decl.instance.as_ref().into_iter();
Expand Down
35 changes: 19 additions & 16 deletions substrate/frame/support/procedural/src/construct_runtime/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ impl Parse for WhereSection {
definitions.push(definition);
if !input.peek(Token![,]) {
if !input.peek(token::Brace) {
return Err(input.error("Expected `,` or `{`"))
return Err(input.error("Expected `,` or `{`"));
}
break
break;
}
input.parse::<Token![,]>()?;
}
Expand All @@ -144,7 +144,7 @@ impl Parse for WhereSection {
"`{:?}` was declared above. Please use exactly one declaration for `{:?}`.",
kind, kind
);
return Err(Error::new(*kind_span, msg))
return Err(Error::new(*kind_span, msg));
}
Ok(Self { span: input.span() })
}
Expand Down Expand Up @@ -173,7 +173,7 @@ impl Parse for WhereDefinition {
} else if lookahead.peek(keyword::UncheckedExtrinsic) {
(input.parse::<keyword::UncheckedExtrinsic>()?.span(), WhereKind::UncheckedExtrinsic)
} else {
return Err(lookahead.error())
return Err(lookahead.error());
};

let _: Token![=] = input.parse()?;
Expand Down Expand Up @@ -270,7 +270,7 @@ impl Parse for PalletDeclaration {
{
return Err(input.error(
"Unexpected tokens, expected one of `::{`, `exclude_parts`, `use_parts`, `=`, `,`",
))
));
} else {
is_expanded.then_some(extra_parts)
};
Expand All @@ -283,7 +283,7 @@ impl Parse for PalletDeclaration {
let _: keyword::use_parts = input.parse()?;
SpecifiedParts::Use(parse_pallet_parts_no_generic(input)?)
} else if !input.peek(Token![=]) && !input.peek(Token![,]) && !input.is_empty() {
return Err(input.error("Unexpected tokens, expected one of `exclude_parts`, `=`, `,`"))
return Err(input.error("Unexpected tokens, expected one of `exclude_parts`, `=`, `,`"));
} else {
SpecifiedParts::All
};
Expand All @@ -295,7 +295,7 @@ impl Parse for PalletDeclaration {
let index = index.base10_parse::<u8>()?;
Some(index)
} else if !input.peek(Token![,]) && !input.is_empty() {
return Err(input.error("Unexpected tokens, expected one of `=`, `,`"))
return Err(input.error("Unexpected tokens, expected one of `=`, `,`"));
} else {
None
};
Expand Down Expand Up @@ -339,7 +339,7 @@ impl Parse for PalletPath {
let ident = input.call(Ident::parse_any)?;
res.inner.segments.push(ident.into());
} else {
return Err(lookahead.error())
return Err(lookahead.error());
}

while input.peek(Token![::]) && input.peek3(Ident) {
Expand Down Expand Up @@ -370,7 +370,7 @@ fn parse_pallet_parts(input: ParseStream) -> Result<Vec<PalletPart>> {
"`{}` was already declared before. Please remove the duplicate declaration",
part.name(),
);
return Err(Error::new(part.keyword.span(), msg))
return Err(Error::new(part.keyword.span(), msg));
}
}

Expand Down Expand Up @@ -505,7 +505,7 @@ impl Parse for PalletPart {
keyword.name(),
valid_generics,
);
return Err(syn::Error::new(keyword.span(), msg))
return Err(syn::Error::new(keyword.span(), msg));
}

Ok(Self { keyword, generics })
Expand Down Expand Up @@ -566,7 +566,7 @@ fn parse_pallet_parts_no_generic(input: ParseStream) -> Result<Vec<PalletPartNoG
"`{}` was already declared before. Please remove the duplicate declaration",
part.keyword.name(),
);
return Err(Error::new(part.keyword.span(), msg))
return Err(Error::new(part.keyword.span(), msg));
}
}

Expand All @@ -592,6 +592,8 @@ pub struct Pallet {
pub cfg_pattern: Vec<cfg_expr::Expression>,
/// The doc literals
pub docs: Vec<syn::Expr>,
/// attributes
pub attrs: Vec<syn::Attribute>,
}

impl Pallet {
Expand Down Expand Up @@ -650,7 +652,7 @@ enum PalletsConversion {
/// incrementally from last explicit or 0.
fn convert_pallets(pallets: Vec<PalletDeclaration>) -> syn::Result<PalletsConversion> {
if pallets.iter().any(|pallet| pallet.pallet_parts.is_none()) {
return Ok(PalletsConversion::Implicit(pallets))
return Ok(PalletsConversion::Implicit(pallets));
}

let mut indices = HashMap::new();
Expand Down Expand Up @@ -678,15 +680,15 @@ fn convert_pallets(pallets: Vec<PalletDeclaration>) -> syn::Result<PalletsConver
);
let mut err = syn::Error::new(used_pallet.span(), &msg);
err.combine(syn::Error::new(pallet.name.span(), msg));
return Err(err)
return Err(err);
}

if let Some(used_pallet) = names.insert(pallet.name.clone(), pallet.name.span()) {
let msg = "Two pallets with the same name!";

let mut err = syn::Error::new(used_pallet, &msg);
err.combine(syn::Error::new(pallet.name.span(), &msg));
return Err(err)
return Err(err);
}

let mut pallet_parts = pallet.pallet_parts.expect("Checked above");
Expand All @@ -712,7 +714,7 @@ fn convert_pallets(pallets: Vec<PalletDeclaration>) -> syn::Result<PalletsConver
}
})
);
return Err(syn::Error::new(part.keyword.span(), msg))
return Err(syn::Error::new(part.keyword.span(), msg));
}
},
SpecifiedParts::All => (),
Expand All @@ -738,7 +740,7 @@ fn convert_pallets(pallets: Vec<PalletDeclaration>) -> syn::Result<PalletsConver
if attr.path().segments.first().map_or(false, |s| s.ident != "cfg") {
let msg = "Unsupported attribute, only #[cfg] is supported on pallet \
declarations in `construct_runtime`";
return Err(syn::Error::new(attr.span(), msg))
return Err(syn::Error::new(attr.span(), msg));
}

attr.parse_args_with(|input: syn::parse::ParseStream| {
Expand All @@ -762,6 +764,7 @@ fn convert_pallets(pallets: Vec<PalletDeclaration>) -> syn::Result<PalletsConver
cfg_pattern,
pallet_parts,
docs: vec![],
attrs: pallet.attrs.clone(),
})
})
.collect::<Result<Vec<_>>>()?;
Expand Down
Loading

0 comments on commit ec9a734

Please sign in to comment.