diff --git a/tasks/ast_codegen/src/generators/ast_kind.rs b/tasks/ast_codegen/src/generators/ast_kind.rs index af9cc8ecb253d..a43112c6fb2f3 100644 --- a/tasks/ast_codegen/src/generators/ast_kind.rs +++ b/tasks/ast_codegen/src/generators/ast_kind.rs @@ -94,32 +94,26 @@ pub fn process_types(def: &TypeDef, _: &LateCtx) -> Vec<(Ident, Type)> { TypeDef::Enum(enum_) => enum_ .variants .iter() - // .map(|it| (it, get_visit_markers(&it.attrs).transpose().unwrap())) - .filter(|it| it.markers.visit.as_ref().is_some_and(|mk| mk.visit_as.is_some())) - .filter_map(|var| { - var.markers.visit.as_ref().map(|markers| { - let field = var.fields.first().unwrap(); - let type_name = field.typ.name().inner_name(); - ( - markers.visit_as.clone().expect("Already checked"), - parse_quote!(#type_name<'a>), - ) - }) + .filter(|it| it.markers.visit.visit_as.is_some()) + .map(|var| { + let field = var.fields.first().unwrap(); + let type_name = field.typ.name().inner_name(); + ( + var.markers.visit.visit_as.clone().expect("Already checked"), + parse_quote!(#type_name<'a>), + ) }) .collect_vec(), TypeDef::Struct(struct_) => struct_ .fields .iter() - // .map(|it| (it, get_visit_markers(&it.attrs).transpose().unwrap())) - .filter(|it| it.markers.visit.as_ref().is_some_and(|mk| mk.visit_as.is_some())) - .filter_map(|field| { - field.markers.visit.as_ref().map(|markers| { - let type_name = field.typ.name().inner_name().to_ident(); - ( - markers.visit_as.clone().expect("Already checked"), - parse_quote!(#type_name<'a>), - ) - }) + .filter(|it| it.markers.visit.visit_as.is_some()) + .map(|field| { + let type_name = field.typ.name().inner_name().to_ident(); + ( + field.markers.visit.visit_as.clone().expect("Already checked"), + parse_quote!(#type_name<'a>), + ) }) .collect_vec(), }; diff --git a/tasks/ast_codegen/src/generators/visit.rs b/tasks/ast_codegen/src/generators/visit.rs index b97f49b41cb57..e861904a3fbdb 100644 --- a/tasks/ast_codegen/src/generators/visit.rs +++ b/tasks/ast_codegen/src/generators/visit.rs @@ -9,7 +9,7 @@ use syn::{parse_quote, Ident}; use crate::{ codegen::LateCtx, generators::ast_kind::BLACK_LIST as KIND_BLACK_LIST, - markers::{ScopeMarkers, VisitArg, VisitMarkers}, + markers::VisitArg, output, schema::{EnumDef, GetIdent, StructDef, ToType, TypeDef}, util::{StrExt, ToIdent, TokenStreamExt, TypeWrapper}, @@ -331,7 +331,7 @@ impl<'a> VisitBuilder<'a> { .variants .iter() .filter(|var| { - if var.markers.visit.as_ref().is_some_and(|mk| mk.ignore) { + if var.markers.visit.ignore { // We are ignoring some variants so the match is no longer exhaustive. non_exhaustive = true; false @@ -356,10 +356,10 @@ impl<'a> VisitBuilder<'a> { let (args_def, args) = var .markers .visit - .as_ref() - .map(|mk| mk.visit_args.clone().unwrap_or_default()) + .visit_args + .clone() + .unwrap_or_default() .into_iter() - .flatten() .fold((Vec::new(), Vec::new()), Self::visit_args_fold); let body = quote!(visitor.#visit(it #(#args)*)); let body = if args_def.is_empty() { @@ -507,17 +507,11 @@ impl<'a> VisitBuilder<'a> { } let typ_wrapper = &analysis.wrapper; let markers = &field.markers; - let visit_as = markers.visit.as_ref().and_then(|mk| mk.visit_as.clone()); - let visit_args = markers.visit.as_ref().and_then(|mk| mk.visit_args.clone()); + let visit_as = markers.visit.visit_as.clone(); + let visit_args = markers.visit.visit_args.clone(); - let have_enter_scope = markers - .scope - .as_ref() - .is_some_and(|it| matches!(it, ScopeMarkers { enter_before: true })); - let have_enter_node = markers - .visit - .as_ref() - .is_some_and(|it| matches!(it, VisitMarkers { enter_before: true, .. })); + let have_enter_scope = markers.scope.enter_before; + let have_enter_node = markers.visit.enter_before; let (args_def, args) = visit_args .map(|it| it.into_iter().fold((Vec::new(), Vec::new()), Self::visit_args_fold)) diff --git a/tasks/ast_codegen/src/markers.rs b/tasks/ast_codegen/src/markers.rs index 719b6d3fe402e..fb3c383debb10 100644 --- a/tasks/ast_codegen/src/markers.rs +++ b/tasks/ast_codegen/src/markers.rs @@ -60,20 +60,20 @@ pub struct VisitMarkers { } /// A struct representing `#[scope(...)]` markers -#[derive(Debug)] +#[derive(Default, Debug)] pub struct ScopeMarkers { pub enter_before: bool, } /// A struct representing the `#[scope(...)]` attribute. #[derive(Debug, Default)] -pub struct ScopeAttr { +pub struct ScopeAttribute { pub r#if: Option, pub flags: Option, pub strict_if: Option, } -impl Parse for ScopeAttr { +impl Parse for ScopeAttribute { fn parse(input: ParseStream) -> Result { let parsed = input.parse_terminated(CommonAttribute::parse, Token![,])?; Ok(parsed.into_iter().fold(Self::default(), |mut acc, CommonAttribute { ident, args }| { @@ -110,7 +110,7 @@ impl Parse for CommonAttribute { } } -pub fn get_visit_markers<'a, I>(attrs: I) -> Option> +pub fn get_visit_markers<'a, I>(attrs: I) -> crate::Result where I: IntoIterator, { @@ -127,36 +127,39 @@ where "For now we only accept one `#[visit]` marker per field/variant, Please merge them together!" ); - attr.map(|attr| { - let mut visit_as = None; - let mut visit_args = None; - let mut enter_before = false; - let mut ignore = false; - let nested = - attr.parse_args_with(Punctuated::::parse_terminated); - nested - .map(|nested| { - for com in nested { - if com.ident == "args" { - visit_args = Some(parse2(com.args).unwrap()); - } else if com.ident == "as" { - visit_as = - Some(parse2(com.args).expect("Invalid `#[visit[as(...)]]` input!")); - } else if com.ident == "enter_before" { - enter_before = true; - } else if com.ident == "ignore" { - ignore = true; - } else { - panic!("Invalid `#[visit(...)]` input!") + attr.map_or_else( + || Ok(VisitMarkers::default()), + |attr| { + let mut visit_as = None; + let mut visit_args = None; + let mut enter_before = false; + let mut ignore = false; + let nested = + attr.parse_args_with(Punctuated::::parse_terminated); + nested + .map(|nested| { + for com in nested { + if com.ident == "args" { + visit_args = Some(parse2(com.args).unwrap()); + } else if com.ident == "as" { + visit_as = + Some(parse2(com.args).expect("Invalid `#[visit[as(...)]]` input!")); + } else if com.ident == "enter_before" { + enter_before = true; + } else if com.ident == "ignore" { + ignore = true; + } else { + panic!("Invalid `#[visit(...)]` input!") + } } - } - }) - .map(|()| VisitMarkers { visit_as, visit_args, enter_before, ignore }) - .normalize() - }) + }) + .map(|()| VisitMarkers { visit_as, visit_args, enter_before, ignore }) + .normalize() + }, + ) } -pub fn get_scope_markers<'a, I>(attrs: I) -> Option> +pub fn get_scope_markers<'a, I>(attrs: I) -> crate::Result where I: IntoIterator, { @@ -173,14 +176,17 @@ where "For now we only accept one `#[scope]` marker per field/variant, Please merge them together!" ); - attr.map(|attr| { - attr.parse_args_with(Ident::parse) - .map(|id| ScopeMarkers { enter_before: id == "enter_before" }) - .normalize() - }) + attr.map_or_else( + || Ok(ScopeMarkers::default()), + |attr| { + attr.parse_args_with(Ident::parse) + .map(|id| ScopeMarkers { enter_before: id == "enter_before" }) + .normalize() + }, + ) } -pub fn get_scope_attr<'a, I>(attrs: I) -> Option> +pub fn get_scope_attribute<'a, I>(attrs: I) -> Option> where I: IntoIterator, { @@ -189,9 +195,9 @@ where debug_assert!(attr.path().is_ident("scope")); let result = if matches!(attr.meta, Meta::Path(_)) { // empty `#[scope]`. - Ok(ScopeAttr::default()) + Ok(ScopeAttribute::default()) } else { - attr.parse_args_with(ScopeAttr::parse) + attr.parse_args_with(ScopeAttribute::parse) }; result.normalize() diff --git a/tasks/ast_codegen/src/schema/defs.rs b/tasks/ast_codegen/src/schema/defs.rs index 7505de33ba125..f6e1463484128 100644 --- a/tasks/ast_codegen/src/schema/defs.rs +++ b/tasks/ast_codegen/src/schema/defs.rs @@ -1,7 +1,7 @@ use serde::Serialize; use crate::{ - markers::{ScopeAttr, ScopeMarkers, VisitMarkers}, + markers::{ScopeAttribute, ScopeMarkers, VisitMarkers}, util::{ToIdent, TypeAnalysis, TypeWrapper}, TypeId, }; @@ -220,7 +220,7 @@ impl TypeRef { #[derive(Debug)] pub struct OuterMarkers { - pub scope: Option, + pub scope: Option, } #[derive(Debug, Serialize)] @@ -228,7 +228,7 @@ pub struct InnerMarkers { /// marker that hints to fold span in here pub span: bool, #[serde(skip)] - pub visit: Option, + pub visit: VisitMarkers, #[serde(skip)] - pub scope: Option, + pub scope: ScopeMarkers, } diff --git a/tasks/ast_codegen/src/schema/mod.rs b/tasks/ast_codegen/src/schema/mod.rs index 74d1dea0a988f..a74bfcdb74774 100644 --- a/tasks/ast_codegen/src/schema/mod.rs +++ b/tasks/ast_codegen/src/schema/mod.rs @@ -4,7 +4,7 @@ use serde::Serialize; use crate::{ codegen, layout::KnownLayout, - markers::{get_scope_attr, get_scope_markers, get_visit_markers}, + markers::{get_scope_attribute, get_scope_markers, get_visit_markers}, rust_ast as rust, util::{unexpanded_macro_err, TypeExt}, Result, TypeId, @@ -103,14 +103,14 @@ impl<'a> IntoIterator for &'a Schema { } fn parse_outer_markers(attrs: &Vec) -> Result { - Ok(OuterMarkers { scope: get_scope_attr(attrs).transpose()? }) + Ok(OuterMarkers { scope: get_scope_attribute(attrs).transpose()? }) } fn parse_inner_markers(attrs: &Vec) -> Result { Ok(InnerMarkers { span: attrs.iter().any(|a| a.path().is_ident("span")), - visit: get_visit_markers(attrs).transpose()?, - scope: get_scope_markers(attrs).transpose()?, + visit: get_visit_markers(attrs)?, + scope: get_scope_markers(attrs)?, }) }