Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade syn to 2.0 #404

Closed
wants to merge 1 commit into from
Closed
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
2 changes: 1 addition & 1 deletion zbus_macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ proc-macro = true

[dependencies]
proc-macro2 = "1.0"
syn = { version = "1.0.103", features = ["extra-traits", "fold", "full"] }
syn = { version = "2.0.25", features = ["extra-traits", "fold", "full"] }
quote = "1.0.21"
proc-macro-crate = "1.2.1"
regex = "1.6.0"
Expand Down
109 changes: 80 additions & 29 deletions zbus_macros/src/iface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use std::collections::BTreeMap;
use syn::{
self, parse_quote, punctuated::Punctuated, spanned::Spanned, AngleBracketedGenericArguments,
AttributeArgs, Error, FnArg, GenericArgument, ImplItem, ItemImpl, Lit::Str, Meta,
Meta::NameValue, MetaList, MetaNameValue, NestedMeta, PatType, PathArguments, ReturnType,
Signature, Token, Type, TypePath,
self,
parse::{Parse, ParseStream},
parse_quote,
punctuated::Punctuated,
spanned::Spanned,
AngleBracketedGenericArguments, Attribute, Error, Expr, ExprLit, FnArg, GenericArgument,
ImplItem, ImplItemFn, ItemImpl, Lit, Meta, MetaNameValue, PatType, PathArguments, ReturnType,
Signature, Token, Type, TypePath, Visibility,
};
use zvariant_utils::{case, def_attrs};

Expand Down Expand Up @@ -64,7 +68,7 @@ impl<'a> Property<'a> {
}
}

pub fn expand(args: AttributeArgs, mut input: ItemImpl) -> syn::Result<TokenStream> {
pub fn expand(args: Punctuated<Meta, Token![,]>, mut input: ItemImpl) -> syn::Result<TokenStream> {
let zbus = zbus_path();

let self_ty = &input.self_ty;
Expand Down Expand Up @@ -92,7 +96,7 @@ pub fn expand(args: AttributeArgs, mut input: ItemImpl) -> syn::Result<TokenStre

let iface_name =
{
let TraitAttributes { name, interface } = TraitAttributes::parse_nested_metas(&args)?;
let TraitAttributes { name, interface } = TraitAttributes::parse_nested_metas(args)?;

match (name, interface) {
(Some(name), None) | (None, Some(name)) => name,
Expand All @@ -104,9 +108,27 @@ pub fn expand(args: AttributeArgs, mut input: ItemImpl) -> syn::Result<TokenStre
}
};

for method in &mut input.items {
let method = match method {
ImplItem::Method(m) => m,
for item in &mut input.items {
let (method, is_signal) = match item {
ImplItem::Fn(m) => (m, false),
// Since signals do not have a function body, they don't parse as ImplItemFn…
ImplItem::Verbatim(tokens) => {
// … thus parse them ourselves and construct an ImplItemFn from that
let decl = syn::parse2::<ImplItemSignal>(tokens.clone())?;
Comment on lines +114 to +117
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the hardest piece to find out. Apparently syn 1.x just accepted ImplItemMethods without a body, but syn 2.x does not. The error message when re-emitting this ImplItem::Verbatim was plenty confusing (it was "expected impl" on the first token of the item).

let ImplItemSignal { attrs, vis, sig } = decl;
*item = ImplItem::Fn(ImplItemFn {
attrs,
vis,
defaultness: None,
sig,
// This empty block will be replaced below.
block: parse_quote!({}),
});
match item {
ImplItem::Fn(m) => (m, true),
_ => unreachable!(),
}
}
_ => continue,
};

Expand All @@ -122,24 +144,36 @@ pub fn expand(args: AttributeArgs, mut input: ItemImpl) -> syn::Result<TokenStre
let attrs = MethodAttributes::parse(&method.attrs)?;
method
.attrs
.retain(|attr| !attr.path.is_ident("dbus_interface"));
.retain(|attr| !attr.path().is_ident("dbus_interface"));

if is_signal && !attrs.signal {
return Err(syn::Error::new_spanned(
item,
"methods that are not signals must have a body",
));
}

let docs = get_doc_attrs(&method.attrs)
.iter()
.filter_map(|attr| {
if let Ok(NameValue(MetaNameValue { lit: Str(s), .. })) = attr.parse_meta() {
Some(s.value())
} else {
match attr.meta.require_name_value() {
// #[doc = "..."] attribute
Ok(MetaNameValue {
value:
Expr::Lit(ExprLit {
lit: Lit::Str(s), ..
}),
..
}) => Some(s.value()),
// non #[doc = "..."] attributes are not our concern
// we leave them for rustc to handle
None
_ => None,
}
})
.collect();

let doc_comments = to_xml_docs(docs);
let is_property = attrs.property;
let is_signal = attrs.signal;
let out_args = attrs.out_args.as_deref();
assert!(!is_property || !is_signal);

Expand Down Expand Up @@ -672,7 +706,7 @@ fn get_args_from_inputs(
fn clean_input_args(inputs: &mut Punctuated<FnArg, Token![,]>) {
for input in inputs {
if let FnArg::Typed(t) = input {
t.attrs.retain(|attr| !attr.path.is_ident("zbus"));
t.attrs.retain(|attr| !attr.path().is_ident("zbus"));
}
}
}
Expand Down Expand Up @@ -707,25 +741,24 @@ fn introspect_input_args(
.iter()
.filter_map(move |pat_type @ PatType { ty, attrs, .. }| {
let is_special_arg = attrs.iter().any(|attr| {
if !attr.path.is_ident("zbus") {
if !attr.path().is_ident("zbus") {
return false;
}

let meta = match attr.parse_meta() {
::std::result::Result::Ok(meta) => meta,
::std::result::Result::Err(_) => return false,
};

let nested = match meta {
Meta::List(MetaList { nested, .. }) => nested,
_ => return false,
};
let meta =
match attr.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated) {
Ok(meta) => meta,
Err(_) => return false,
};

let res = nested.iter().any(|nested_meta| {
let res = meta.iter().any(|nested_meta| {
matches!(
nested_meta,
NestedMeta::Meta(Meta::Path(path))
if path.is_ident("object_server") || path.is_ident("connection") || path.is_ident("header") || path.is_ident("signal_context")
Meta::Path(path)
if path.is_ident("object_server") ||
path.is_ident("connection") ||
path.is_ident("header") ||
path.is_ident("signal_context")
)
});

Expand Down Expand Up @@ -904,3 +937,21 @@ pub fn to_xml_docs(lines: Vec<String>) -> TokenStream {

docs
}

// Like ImplItemFn, but with a semicolon at the end instead of a body block
struct ImplItemSignal {
attrs: Vec<Attribute>,
vis: Visibility,
sig: Signature,
}

impl Parse for ImplItemSignal {
fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
let attrs = input.call(Attribute::parse_outer)?;
let vis = input.parse()?;
let sig = input.parse()?;
let _: Token![;] = input.parse()?;

Ok(ImplItemSignal { attrs, vis, sig })
}
}
10 changes: 5 additions & 5 deletions zbus_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
)))]

use proc_macro::TokenStream;
use syn::{parse_macro_input, AttributeArgs, DeriveInput, ItemImpl, ItemTrait};
use syn::{parse_macro_input, punctuated::Punctuated, DeriveInput};

mod error;
mod iface;
Expand Down Expand Up @@ -192,8 +192,8 @@ mod utils;
/// [dbus_emits_changed_signal]: https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
#[proc_macro_attribute]
pub fn dbus_proxy(attr: TokenStream, item: TokenStream) -> TokenStream {
let args = parse_macro_input!(attr as AttributeArgs);
let input = parse_macro_input!(item as ItemTrait);
let args = parse_macro_input!(attr with Punctuated::parse_terminated);
let input = parse_macro_input!(item);
proxy::expand(args, input)
.unwrap_or_else(|err| err.to_compile_error())
.into()
Expand Down Expand Up @@ -323,8 +323,8 @@ pub fn dbus_proxy(attr: TokenStream, item: TokenStream) -> TokenStream {
/// [`Interface`]: https://docs.rs/zbus/latest/zbus/object_server/trait.Interface.html
#[proc_macro_attribute]
pub fn dbus_interface(attr: TokenStream, item: TokenStream) -> TokenStream {
let args = parse_macro_input!(attr as AttributeArgs);
let input = syn::parse_macro_input!(item as ItemImpl);
let args = parse_macro_input!(attr with Punctuated::parse_terminated);
let input = syn::parse_macro_input!(item);
iface::expand(args, input)
.unwrap_or_else(|err| err.to_compile_error())
.into()
Expand Down
24 changes: 12 additions & 12 deletions zbus_macros/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use proc_macro2::{Literal, Span, TokenStream};
use quote::{format_ident, quote, quote_spanned, ToTokens};
use regex::Regex;
use syn::{
self, fold::Fold, parse_quote, parse_str, spanned::Spanned, AttributeArgs, Error, FnArg, Ident,
ItemTrait, Path, ReturnType, TraitItemMethod,
self, fold::Fold, parse_quote, parse_str, punctuated::Punctuated, spanned::Spanned, Error,
FnArg, Ident, ItemTrait, Meta, Path, ReturnType, Token, TraitItemFn,
};
use zvariant_utils::{case, def_attrs};

Expand Down Expand Up @@ -62,7 +62,7 @@ impl AsyncOpts {
}
}

pub fn expand(args: AttributeArgs, input: ItemTrait) -> Result<TokenStream, Error> {
pub fn expand(args: Punctuated<Meta, Token![,]>, input: ItemTrait) -> Result<TokenStream, Error> {
let ImplAttributes {
interface,
name,
Expand All @@ -73,7 +73,7 @@ pub fn expand(args: AttributeArgs, input: ItemTrait) -> Result<TokenStream, Erro
blocking_name,
gen_async,
gen_blocking,
} = ImplAttributes::parse_nested_metas(&args)?;
} = ImplAttributes::parse_nested_metas(args)?;

let iface_name = match (interface, name) {
(Some(name), None) | (None, Some(name)) => Ok(Some(name)),
Expand Down Expand Up @@ -163,7 +163,7 @@ pub fn create_proxy(
let other_attrs: Vec<_> = input
.attrs
.iter()
.filter(|a| !a.path.is_ident("dbus_proxy"))
.filter(|a| !a.path().is_ident("dbus_proxy"))
.collect();
let proxy_name = Ident::new(proxy_name, Span::call_site());
let ident = input.ident.to_string();
Expand Down Expand Up @@ -192,7 +192,7 @@ pub fn create_proxy(
let async_opts = AsyncOpts::new(blocking);

for i in input.items.iter() {
if let syn::TraitItem::Method(m) = i {
if let syn::TraitItem::Fn(m) = i {
let mut attrs = MethodAttributes::parse(&m.attrs)?;

let method_name = m.sig.ident.to_string();
Expand Down Expand Up @@ -448,7 +448,7 @@ pub fn create_proxy(
fn gen_proxy_method_call(
method_name: &str,
snake_case_name: &str,
m: &TraitItemMethod,
m: &TraitItemFn,
attrs: &MethodAttributes,
async_opts: &AsyncOpts,
) -> Result<TokenStream, Error> {
Expand All @@ -461,7 +461,7 @@ fn gen_proxy_method_call(
let other_attrs: Vec<_> = m
.attrs
.iter()
.filter(|a| !a.path.is_ident("dbus_proxy"))
.filter(|a| !a.path().is_ident("dbus_proxy"))
.collect();
let args: Vec<_> = m
.sig
Expand Down Expand Up @@ -666,7 +666,7 @@ impl PropertyEmitsChangedSignal {
fn gen_proxy_property(
property_name: &str,
method_name: &str,
m: &TraitItemMethod,
m: &TraitItemFn,
async_opts: &AsyncOpts,
emits_changed_signal: PropertyEmitsChangedSignal,
) -> TokenStream {
Expand All @@ -679,7 +679,7 @@ fn gen_proxy_property(
let other_attrs: Vec<_> = m
.attrs
.iter()
.filter(|a| !a.path.is_ident("dbus_proxy"))
.filter(|a| !a.path().is_ident("dbus_proxy"))
.collect();
let signature = &m.sig;
if signature.inputs.len() > 1 {
Expand Down Expand Up @@ -795,7 +795,7 @@ fn gen_proxy_signal(
iface_name: &str,
signal_name: &str,
snake_case_name: &str,
method: &TraitItemMethod,
method: &TraitItemFn,
async_opts: &AsyncOpts,
gen_sig_args: bool,
) -> (TokenStream, TokenStream) {
Expand All @@ -808,7 +808,7 @@ fn gen_proxy_signal(
let other_attrs: Vec<_> = method
.attrs
.iter()
.filter(|a| !a.path.is_ident("dbus_proxy"))
.filter(|a| !a.path().is_ident("dbus_proxy"))
.collect();
let input_types: Vec<_> = method
.sig
Expand Down
2 changes: 1 addition & 1 deletion zbus_macros/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub fn pat_ident(pat: &PatType) -> Option<&Ident> {
}

pub fn get_doc_attrs(attrs: &[Attribute]) -> Vec<&Attribute> {
attrs.iter().filter(|x| x.path.is_ident("doc")).collect()
attrs.iter().filter(|x| x.path().is_ident("doc")).collect()
}

// Convert to pascal case, assuming snake case.
Expand Down
2 changes: 1 addition & 1 deletion zvariant_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ proc-macro = true

[dependencies]
proc-macro2 = "1.0"
syn = { version = "1.0.103", features = ["extra-traits", "full"] }
syn = { version = "2.0.25", features = ["extra-traits", "full"] }
quote = "1.0.21"
proc-macro-crate = "1.2.1"
zvariant_utils = { path = "../zvariant_utils", version = "=1.0.1" }
Expand Down
2 changes: 1 addition & 1 deletion zvariant_derive/src/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ pub fn expand_deserialize_derive(input: DeriveInput) -> Result<TokenStream, Erro

let (_, ty_generics, _) = input.generics.split_for_impl();
let mut generics = input.generics.clone();
let def = syn::LifetimeDef {
let def = syn::LifetimeParam {
attrs: Vec::new(),
lifetime: syn::Lifetime::new("'de", Span::call_site()),
colon_token: None,
Expand Down
2 changes: 1 addition & 1 deletion zvariant_derive/src/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ fn signature_for_variant(
attrs: &[Attribute],
zv: &TokenStream,
) -> Result<TokenStream, Error> {
let repr = attrs.iter().find(|attr| attr.path.is_ident("repr"));
let repr = attrs.iter().find(|attr| attr.path().is_ident("repr"));
match &variant.fields {
Fields::Unit => {
let repr = match repr {
Expand Down
6 changes: 3 additions & 3 deletions zvariant_derive/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use proc_macro2::{Span, TokenStream};
use quote::{quote, ToTokens};
use syn::{
self, spanned::Spanned, Attribute, Data, DataEnum, DeriveInput, Error, Expr, Fields, Generics,
Ident, Lifetime, LifetimeDef,
Ident, Lifetime, LifetimeParam,
};

use crate::utils::*;
Expand Down Expand Up @@ -51,7 +51,7 @@ fn impl_struct(
signature: Option<String>,
zv: &TokenStream,
) -> Result<TokenStream, Error> {
let statc_lifetime = LifetimeDef::new(Lifetime::new("'static", Span::call_site()));
let statc_lifetime = LifetimeParam::new(Lifetime::new("'static", Span::call_site()));
let (value_type, value_lifetime) = match value_type {
ValueType::Value => {
let mut lifetimes = generics.lifetimes();
Expand Down Expand Up @@ -207,7 +207,7 @@ fn impl_enum(
data: &DataEnum,
zv: &TokenStream,
) -> Result<TokenStream, Error> {
let repr: TokenStream = match attrs.iter().find(|attr| attr.path.is_ident("repr")) {
let repr: TokenStream = match attrs.iter().find(|attr| attr.path().is_ident("repr")) {
Some(repr_attr) => repr_attr.parse_args()?,
None => quote! { u32 },
};
Expand Down
2 changes: 1 addition & 1 deletion zvariant_utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ readme = "README.md"

[dependencies]
proc-macro2 = "1.0"
syn = { version = "1.0.103", features = ["extra-traits", "full"] }
syn = { version = "2.0.25", features = ["extra-traits", "full"] }
quote = "1.0.21"
Loading
Loading