Skip to content

Commit

Permalink
Upgrade to syn 2.x and bump minor version
Browse files Browse the repository at this point in the history
  • Loading branch information
upsuper committed Sep 17, 2023
1 parent 82ba351 commit 064d001
Show file tree
Hide file tree
Showing 37 changed files with 102 additions and 108 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "delegate-attr"
description = "Attribute proc-macro to delegate method to a field"
version = "0.2.9"
version = "0.3.0"
authors = ["Xidorn Quan <[email protected]>"]
edition = "2018"
repository = "https://github.com/upsuper/delegate-attr"
Expand All @@ -16,7 +16,7 @@ proc-macro = true
[dependencies]
quote = "1.0.5"
proc-macro2 = "1.0.13"
syn = { version = "1.0.22", features = ["full", "extra-traits"] }
syn = { version = "2", features = ["full"] }

[dev-dependencies]
trybuild = "1.0.27"
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ struct Foo(String);

#[delegate(self.0)]
impl Foo {
fn as_str(&self) -> &str;
fn into_bytes(self) -> Vec<u8>;
fn as_str(&self) -> &str {}
fn into_bytes(self) -> Vec<u8> {}
}

let foo = Foo("hello".to_owned());
Expand All @@ -36,10 +36,10 @@ struct Iter(std::vec::IntoIter<u8>);
#[delegate(self.0)]
impl Iterator for Iter {
type Item = u8;
fn next(&mut self) -> Option<u8>;
fn count(self) -> usize;
fn size_hint(&self) -> (usize, Option<usize>);
fn last(self) -> Option<u8>;
fn next(&mut self) -> Option<u8> {}
fn count(self) -> usize {}
fn size_hint(&self) -> (usize, Option<usize>) {}
fn last(self) -> Option<u8> {}
}

let iter = Iter(vec![1, 2, 4, 8].into_iter());
Expand All @@ -59,17 +59,17 @@ struct Foo<T> {

#[delegate(self.inner.borrow())]
impl<T> Foo<T> {
fn len(&self) -> usize;
fn len(&self) -> usize {}
}

#[delegate(self.inner.borrow_mut())]
impl<T> Foo<T> {
fn push(&self, value: T);
fn push(&self, value: T) {}
}

#[delegate(self.inner.into_inner())]
impl<T> Foo<T> {
fn into_boxed_slice(self) -> Box<[T]>;
fn into_boxed_slice(self) -> Box<[T]> {}
}

let foo = Foo { inner: RefCell::new(vec![1]) };
Expand All @@ -93,11 +93,11 @@ struct Wrapper { inner: Inner }
impl Wrapper {
// calls method, converts result to u64
#[into]
pub fn method(&self, num: u32) -> u64;
pub fn method(&self, num: u32) -> u64 {}

// calls method, returns ()
#[call(method)]
pub fn method_noreturn(&self, num: u32);
pub fn method_noreturn(&self, num: u32) {}
}
```

Expand All @@ -108,7 +108,7 @@ struct Foo<T>(Vec<T>);

impl<T> Foo<T> {
#[delegate(self.0)]
fn len(&self) -> usize;
fn len(&self) -> usize {}
}

let foo = Foo(vec![1]);
Expand Down
100 changes: 47 additions & 53 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
//!
//! #[delegate(self.0)]
//! impl Foo {
//! fn as_str(&self) -> &str;
//! fn into_bytes(self) -> Vec<u8>;
//! fn as_str(&self) -> &str {}
//! fn into_bytes(self) -> Vec<u8> {}
//! }
//!
//! let foo = Foo("hello".to_owned());
Expand All @@ -30,10 +30,10 @@
//! #[delegate(self.0)]
//! impl Iterator for Iter {
//! type Item = u8;
//! fn next(&mut self) -> Option<u8>;
//! fn count(self) -> usize;
//! fn size_hint(&self) -> (usize, Option<usize>);
//! fn last(self) -> Option<u8>;
//! fn next(&mut self) -> Option<u8> {}
//! fn count(self) -> usize {}
//! fn size_hint(&self) -> (usize, Option<usize>) {}
//! fn last(self) -> Option<u8> {}
//! }
//!
//! let iter = Iter(vec![1, 2, 4, 8].into_iter());
Expand All @@ -55,17 +55,17 @@
//!
//! #[delegate(self.inner.borrow())]
//! impl<T> Foo<T> {
//! fn len(&self) -> usize;
//! fn len(&self) -> usize {}
//! }
//!
//! #[delegate(self.inner.borrow_mut())]
//! impl<T> Foo<T> {
//! fn push(&self, value: T);
//! fn push(&self, value: T) {}
//! }
//!
//! #[delegate(self.inner.into_inner())]
//! impl<T> Foo<T> {
//! fn into_boxed_slice(self) -> Box<[T]>;
//! fn into_boxed_slice(self) -> Box<[T]> {}
//! }
//!
//! let foo = Foo { inner: RefCell::new(vec![1]) };
Expand All @@ -90,11 +90,11 @@
//! impl Wrapper {
//! // calls method, converts result to u64
//! #[into]
//! pub fn method(&self, num: u32) -> u64;
//! pub fn method(&self, num: u32) -> u64 {}
//!
//! // calls method, returns ()
//! #[call(method)]
//! pub fn method_noreturn(&self, num: u32);
//! pub fn method_noreturn(&self, num: u32) {}
//! }
//! ```
//!
Expand All @@ -106,7 +106,7 @@
//!
//! impl<T> Foo<T> {
//! #[delegate(self.0)]
//! fn len(&self) -> usize;
//! fn len(&self) -> usize {}
//! }
//!
//! let foo = Foo(vec![1]);
Expand All @@ -116,12 +116,10 @@
extern crate proc_macro;

use proc_macro::TokenStream as RawTokenStream;
use proc_macro2::{Group, Span, TokenStream, TokenTree};
use proc_macro2::{Group, Ident, TokenStream, TokenTree};
use quote::{quote, quote_spanned, ToTokens};
use syn::spanned::Spanned;
use syn::{
parse_macro_input, Expr, ExprParen, FnArg, ImplItem, ImplItemMethod, ItemImpl, Pat, ReturnType,
};
use syn::{parse_macro_input, Expr, FnArg, ImplItem, ImplItemFn, ItemImpl, Meta, Pat, ReturnType};

#[proc_macro_attribute]
pub fn delegate(attr: RawTokenStream, item: RawTokenStream) -> RawTokenStream {
Expand All @@ -133,8 +131,8 @@ fn delegate_input(input: TokenStream, receiver: &Expr) -> TokenStream {
if let Ok(input) = syn::parse2::<ItemImpl>(input.clone()) {
return delegate_impl_block(input, receiver);
}
if let Ok(input) = syn::parse2::<ImplItemMethod>(input.clone()) {
return delegate_method(input, receiver);
if let Ok(input) = syn::parse2::<ImplItemFn>(input.clone()) {
return delegate_fn(input, receiver);
}
let mut tokens = input.into_iter();
let first_non_attr_token = 'outer: loop {
Expand Down Expand Up @@ -179,11 +177,11 @@ fn delegate_impl_block(input: ItemImpl, receiver: &Expr) -> TokenStream {
let where_clause = generics.where_clause.take();
let trait_ = trait_.map(|(bang, path, for_)| quote!(#bang #path #for_));
let items = items.into_iter().map(|item| {
let method = match item {
ImplItem::Method(m) => m,
let func = match item {
ImplItem::Fn(f) => f,
_ => return item.into_token_stream(),
};
delegate_method(method, receiver)
delegate_fn(func, receiver)
});

quote! {
Expand All @@ -193,57 +191,53 @@ fn delegate_impl_block(input: ItemImpl, receiver: &Expr) -> TokenStream {
}
}

fn delegate_method(input: ImplItemMethod, receiver: &Expr) -> TokenStream {
let ImplItemMethod {
fn delegate_fn(input: ImplItemFn, receiver: &Expr) -> TokenStream {
let ImplItemFn {
mut attrs,
vis,
defaultness,
sig,
block: _,
} = input;
let mut errors = TokenStream::new();
let mut push_error = |span: Span, msg: &'static str| {
errors.extend(quote_spanned! { span => compile_error!(#msg); });
};
macro_rules! push_error {
($error: expr) => {
errors.extend($error.into_compile_error())
};
($span: expr, $msg: expr) => {
push_error!(syn::Error::new($span, $msg))
};
}
// Parse attributes.
let mut has_inline = false;
let mut has_into = false;
let mut call_name = None;
attrs.retain(|attr| {
let path = &attr.path;
let path = attr.path();
if path.is_ident("inline") {
has_inline = true;
} else if path.is_ident("into") {
if !attr.tokens.is_empty() {
push_error(attr.tokens.span(), "unexpected argument");
match &attr.meta {
Meta::List(meta) => {
push_error!(meta.delimiter.span().join(), "unexpected argument")
}
Meta::NameValue(meta) => push_error!(meta.eq_token.span, "unexpected argument"),
Meta::Path(_) => {}
}
if has_into {
push_error(attr.span(), "duplicate #[into] attribute");
push_error!(attr.span(), "duplicate #[into] attribute");
}
has_into = true;
return false;
} else if path.is_ident("call") {
match syn::parse2::<ExprParen>(attr.tokens.clone()) {
Ok(expr) if expr.attrs.is_empty() => {
let inner = expr.expr;
match &*inner {
Expr::Path(path) if path.attrs.is_empty() && path.qself.is_none() => {
if let Some(ident) = path.path.get_ident() {
if call_name.is_some() {
push_error(attr.span(), "duplicate #[call] attribute");
}
call_name = Some(ident.clone());
} else {
push_error(
inner.span(),
"invalid argument, expected an identifier",
);
}
}
_ => push_error(inner.span(), "invalid argument, expected an identifier"),
match attr.parse_args::<Ident>() {
Ok(ident) => {
if call_name.is_some() {
push_error!(attr.span(), "duplicate #[call] attribute");
}
call_name = Some(ident);
}
_ => push_error(attr.tokens.span(), "invalid argument"),
Err(e) => push_error!(e),
}
return false;
}
Expand All @@ -262,12 +256,12 @@ fn delegate_method(input: ImplItemMethod, receiver: &Expr) -> TokenStream {
Some(FnArg::Typed(pat)) => match &*pat.pat {
Pat::Ident(ident) if ident.ident == "self" => ident.ident.to_token_stream(),
_ => {
push_error(pat.span(), "expected self");
push_error!(pat.span(), "expected self");
TokenStream::new()
}
},
None => {
push_error(sig.paren_token.span, "expected self");
push_error!(sig.paren_token.span.join(), "expected self");
TokenStream::new()
}
};
Expand All @@ -277,12 +271,12 @@ fn delegate_method(input: ImplItemMethod, receiver: &Expr) -> TokenStream {
FnArg::Typed(pat) => match &*pat.pat {
Pat::Ident(ident) => Some(ident.to_token_stream()),
_ => {
push_error(pat.pat.span(), "expect an identifier");
push_error!(pat.pat.span(), "expect an identifier");
None
}
},
_ => {
push_error(arg.span(), "unexpected argument");
push_error!(arg.span(), "unexpected argument");
None
}
})
Expand Down
4 changes: 2 additions & 2 deletions tests/compile_fail/call-eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ struct Foo(Vec<u8>);

#[delegate(self.0)]
impl Foo {
#[call = "len"]
fn size(&self) -> usize;
#[call = len]
fn size(&self) -> usize {}
}

fn main() {}
4 changes: 2 additions & 2 deletions tests/compile_fail/call-eq.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: invalid argument
error: expected parentheses: #[call(...)]
--> $DIR/call-eq.rs:7:12
|
7 | #[call = "len"]
7 | #[call = len]
| ^
2 changes: 1 addition & 1 deletion tests/compile_fail/call-path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ struct Foo(Vec<u8>);
#[delegate(self.0)]
impl Foo {
#[call(self.len)]
fn size(&self) -> usize;
fn size(&self) -> usize {}
}

fn main() {}
2 changes: 1 addition & 1 deletion tests/compile_fail/call-path.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: invalid argument, expected an identifier
error: expected identifier, found keyword `self`
--> $DIR/call-path.rs:7:12
|
7 | #[call(self.len)]
Expand Down
2 changes: 1 addition & 1 deletion tests/compile_fail/call-str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ struct Foo(Vec<u8>);
#[delegate(self.0)]
impl Foo {
#[call("len")]
fn size(&self) -> usize;
fn size(&self) -> usize {}
}

fn main() {}
2 changes: 1 addition & 1 deletion tests/compile_fail/call-str.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: invalid argument, expected an identifier
error: expected identifier
--> $DIR/call-str.rs:7:12
|
7 | #[call("len")]
Expand Down
2 changes: 1 addition & 1 deletion tests/compile_fail/delegate-empty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ struct Foo(Vec<u8>);

#[delegate]
impl Foo {
fn len(&self) -> usize;
fn len(&self) -> usize {}
}

fn main() {}
2 changes: 1 addition & 1 deletion tests/compile_fail/delegate-empty.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: unexpected end of input, expected expression
error: unexpected end of input, expected an expression
--> $DIR/delegate-empty.rs:5:1
|
5 | #[delegate]
Expand Down
2 changes: 1 addition & 1 deletion tests/compile_fail/duplicate-call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ struct Foo(Vec<u8>);
impl Foo {
#[call(len)]
#[call(capacity)]
fn size(&self) -> usize;
fn size(&self) -> usize {}
}

fn main() {}
2 changes: 1 addition & 1 deletion tests/compile_fail/duplicate-into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct Wrapper(Inner);
impl Wrapper {
#[into]
#[into]
fn answer(&self) -> u64;
fn answer(&self) -> u64 {}
}

fn main() {}
Loading

0 comments on commit 064d001

Please sign in to comment.