diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index b4886e492..cd69fe352 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -17,5 +17,5 @@ proc-macro2 = "1.0.46" quote = "1.0.21" regex = "1.5.4" serde_json = "1.0.73" -syn = { version = "1.0.101", features = ["full"] } +syn = { version = "2.0.0", features = ["full"] } tempfile = "3.2.0" diff --git a/xtask/src/device_path/field.rs b/xtask/src/device_path/field.rs index a209c12c4..095f75e69 100644 --- a/xtask/src/device_path/field.rs +++ b/xtask/src/device_path/field.rs @@ -1,10 +1,7 @@ use crate::device_path::util::is_doc_attr; use proc_macro2::{Span, TokenStream}; use quote::{quote, ToTokens, TokenStreamExt}; -use syn::{ - Attribute, Expr, ExprLit, Field, Ident, Lit, Meta, MetaList, MetaNameValue, NestedMeta, Path, - Type, TypeArray, -}; +use syn::{Attribute, Expr, ExprLit, Field, Ident, Lit, Path, Type, TypeArray}; /// A fixed-size non-array type. /// @@ -344,58 +341,44 @@ impl FieldNodeAttr { /// readme. Returns `None` if the attribute does not exactly match /// the expected format. fn from_attr(attr: &Attribute) -> Option { - let meta = attr.parse_meta().ok()?; - - if let Meta::List(MetaList { path, nested, .. }) = meta { - if path.get_ident()? != "node" { - return None; - } + if !attr.path().is_ident("node") { + return None; + } - let mut out = Self::default(); - - for nested in nested.iter() { - match nested { - NestedMeta::Meta(Meta::Path(path)) => { - let ident = path.get_ident()?; - if ident == "no_get_func" { - out.get_func = GetFunc::None; - } else if ident == "custom_get_impl" { - out.get_func = GetFunc::Custom; - } else if ident == "custom_build_impl" { - out.custom_build_impl = true; - } else if ident == "custom_build_size_impl" { - out.custom_build_size_impl = true; - } else { - return None; - } + let mut out = Self::default(); + + attr.parse_nested_meta(|meta| { + let path = &meta.path; + if path.is_ident("no_get_func") { + out.get_func = GetFunc::None; + } else if path.is_ident("custom_get_impl") { + out.get_func = GetFunc::Custom; + } else if path.is_ident("custom_build_impl") { + out.custom_build_impl = true; + } else if path.is_ident("custom_build_size_impl") { + out.custom_build_size_impl = true; + } else if path.is_ident("build_type") { + let value = meta.value()?; + let lit: Lit = value.parse()?; + + match lit { + Lit::Str(s) => { + out.build_type = BuildType::Custom(syn::parse_str(&s.value())?); } - NestedMeta::Meta(Meta::NameValue(MetaNameValue { path, lit, .. })) => { - if path.get_ident()? != "build_type" { - return None; - } - - match lit { - Lit::Str(s) => { - out.build_type = - BuildType::Custom(syn::parse_str(&s.value()).ok()?); - } - Lit::Bool(b) if !b.value() => { - out.build_type = BuildType::None; - } - _ => { - return None; - } - } + Lit::Bool(b) if !b.value() => { + out.build_type = BuildType::None; } _ => { - return None; + return Err(meta.error("invalid build_type")); } } + } else { + return Err(meta.error("invalid field node attribute")); } + Ok(()) + }) + .ok()?; - Some(out) - } else { - None - } + Some(out) } } diff --git a/xtask/src/device_path/group.rs b/xtask/src/device_path/group.rs index fd607e21b..9ed85a7fd 100644 --- a/xtask/src/device_path/group.rs +++ b/xtask/src/device_path/group.rs @@ -2,7 +2,7 @@ use super::node::{is_node_attr, Node}; use heck::ToUpperCamelCase; use proc_macro2::{Span, TokenStream}; use quote::quote; -use syn::{Attribute, Ident, Item, ItemMod, ItemStruct, Meta}; +use syn::{Attribute, Ident, Item, ItemMod, ItemStruct}; #[derive(Clone)] pub struct DeviceType(Ident); @@ -170,14 +170,7 @@ impl NodeGroup { } fn is_build_attr(attr: &Attribute) -> bool { - if let Ok(Meta::Path(path)) = attr.parse_meta() { - if let Some(ident) = path.get_ident() { - if ident == "build" { - return true; - } - } - } - false + attr.path().is_ident("build") } fn has_build_attr(item: &Item) -> bool { diff --git a/xtask/src/device_path/node.rs b/xtask/src/device_path/node.rs index 9d0b97683..a6aa8a7ef 100644 --- a/xtask/src/device_path/node.rs +++ b/xtask/src/device_path/node.rs @@ -5,7 +5,7 @@ use heck::ToShoutySnakeCase; use proc_macro2::Span; use proc_macro2::TokenStream; use quote::quote; -use syn::{Attribute, Fields, Ident, ItemStruct, Lit, Meta, MetaList, MetaNameValue, NestedMeta}; +use syn::{Attribute, Fields, Ident, ItemStruct, LitInt, LitStr}; /// Device path node specification. pub struct Node { @@ -467,44 +467,34 @@ struct NodeAttr { /// Parse a `node` attribute. Returns `None` for any other attribute, or /// if the contents don't match the expected format. fn parse_node_attr(attr: &Attribute) -> Option { - let meta = attr.parse_meta().ok()?; - - if let Meta::List(MetaList { path, nested, .. }) = meta { - if path.get_ident()? != "node" { - return None; - } - - let mut static_size = None; - let mut sub_type = None; - - for nested in nested.iter() { - if let NestedMeta::Meta(Meta::NameValue(MetaNameValue { path, lit, .. })) = nested { - let ident = path.get_ident()?; + if !attr.path().is_ident("node") { + return None; + } - match lit { - Lit::Int(lit) if ident == "static_size" => { - let lit = lit.base10_parse().ok()?; - static_size = Some(lit); - } - Lit::Str(lit) if ident == "sub_type" => { - sub_type = Some(lit.value()); - } - _ => { - return None; - } - } - } else { - return None; - } + let mut static_size = None; + let mut sub_type = None; + attr.parse_nested_meta(|meta| { + if meta.path.is_ident("static_size") { + let value = meta.value()?; + let lit: LitInt = value.parse()?; + let lit = lit.base10_parse()?; + static_size = Some(lit); + Ok(()) + } else if meta.path.is_ident("sub_type") { + let value = meta.value()?; + let lit: LitStr = value.parse()?; + sub_type = Some(lit.value()); + Ok(()) + } else { + Err(meta.error("invalid struct node attribute")) } + }) + .ok()?; - Some(NodeAttr { - static_size: static_size?, - sub_type, - }) - } else { - None - } + Some(NodeAttr { + static_size: static_size?, + sub_type, + }) } /// Returns `true` if the attribute is a valid `node` attribute, false diff --git a/xtask/src/device_path/util.rs b/xtask/src/device_path/util.rs index 485a4f541..7acf5d49d 100644 --- a/xtask/src/device_path/util.rs +++ b/xtask/src/device_path/util.rs @@ -2,18 +2,12 @@ use anyhow::{bail, Context, Result}; use std::io::Write; use std::process::{Command, Stdio}; use std::thread; -use syn::{Attribute, Meta}; +use syn::Attribute; /// Returns true if the attribute is a `#[doc = "..."]` attribute, /// otherwise returns false. pub fn is_doc_attr(attr: &Attribute) -> bool { - if let Ok(Meta::NameValue(nv)) = attr.parse_meta() { - if let Some(ident) = nv.path.get_ident() { - return ident == "doc"; - } - } - - false + attr.path().is_ident("doc") } /// Run `rustfmt` on the `input` string and return the formatted code.