Skip to content
Merged
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
4 changes: 2 additions & 2 deletions crates/macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ edition = "2018"
proc-macro = true

[dependencies]
syn = { version = "1.0.68", features = ["full", "extra-traits", "printing"] }
darling = "0.14"
syn = { version = "2.0.100", features = ["full", "extra-traits", "printing"] }
darling = "0.20"
ident_case = "1.0.1"
quote = "1.0.9"
proc-macro2 = "1.0.26"
Expand Down
31 changes: 19 additions & 12 deletions crates/macros/src/class.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use darling::ast::NestedMeta;
use darling::{FromMeta, ToTokens};
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::parse::ParseStream;
use syn::{Attribute, AttributeArgs, Expr, Fields, ItemStruct, LitStr, Token};
use syn::{Attribute, Expr, Fields, ItemStruct, LitStr, Meta, Token};

use crate::helpers::get_docs;
use crate::prelude::*;
Expand Down Expand Up @@ -34,7 +35,9 @@ impl ClassAttrs {
let mut unparsed = vec![];
unparsed.append(attrs);
for attr in unparsed {
if attr.path.is_ident("extends") {
let path = attr.path();

if path.is_ident("extends") {
if self.extends.is_some() {
bail!(attr => "Only one `#[extends]` attribute is valid per struct.");
}
Expand All @@ -43,7 +46,7 @@ impl ClassAttrs {
Err(_) => bail!(attr => "Invalid arguments passed to extends attribute."),
};
self.extends = Some(extends);
} else if attr.path.is_ident("implements") {
} else if path.is_ident("implements") {
let implements: syn::Expr = match attr.parse_args() {
Ok(extends) => extends,
Err(_) => bail!(attr => "Invalid arguments passed to implements attribute."),
Expand All @@ -58,9 +61,10 @@ impl ClassAttrs {
}
}

pub fn parser(args: AttributeArgs, mut input: ItemStruct) -> Result<TokenStream> {
pub fn parser(args: TokenStream, mut input: ItemStruct) -> Result<TokenStream> {
let ident = &input.ident;
let args = match StructArgs::from_list(&args) {
let meta = NestedMeta::parse_meta_list(args)?;
let args = match StructArgs::from_list(&meta) {
Ok(args) => args,
Err(e) => bail!("Failed to parse struct arguments: {:?}", e),
};
Expand Down Expand Up @@ -189,7 +193,7 @@ pub enum ParsedAttribute {
}

pub fn parse_attribute(attr: &Attribute) -> Result<Option<ParsedAttribute>> {
let name = attr.path.to_token_stream().to_string();
let name = attr.path().to_token_stream().to_string();

Ok(match name.as_ref() {
"doc" => {
Expand All @@ -203,16 +207,19 @@ pub fn parse_attribute(attr: &Attribute) -> Result<Option<ParsedAttribute>> {
}
}

let comment: DocComment = syn::parse2(attr.tokens.clone())
let comment: DocComment = syn::parse2(attr.to_token_stream())
.map_err(|e| err!(attr => "Failed to parse doc comment {}", e))?;
Some(ParsedAttribute::Comment(comment.0))
}
"prop" | "property" => {
let attr = if attr.tokens.is_empty() {
PropertyAttr::default()
} else {
attr.parse_args()
.map_err(|e| err!(attr => "Unable to parse `#[{}]` attribute: {}", name, e))?
let attr = match attr.meta {
Meta::Path(_) => PropertyAttr::default(),
Meta::List(_) => attr
.parse_args()
.map_err(|e| err!(attr => "Unable to parse `#[{}]` attribute: {}", name, e))?,
_ => {
bail!(attr => "Invalid attribute format for `#[{}]`", name);
}
};

Some(ParsedAttribute::Property(attr))
Expand Down
8 changes: 5 additions & 3 deletions crates/macros/src/function.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::collections::HashMap;

use darling::ast::NestedMeta;
use darling::{FromMeta, ToTokens};
use proc_macro2::{Ident, Span, TokenStream};
use quote::{format_ident, quote};
use syn::spanned::Spanned as _;
use syn::PatType;
use syn::{AttributeArgs, FnArg, GenericArgument, ItemFn, Lit, PathArguments, Type, TypePath};
use syn::{FnArg, GenericArgument, ItemFn, Lit, PathArguments, Type, TypePath};

use crate::helpers::get_docs;
use crate::prelude::*;
Expand Down Expand Up @@ -33,8 +34,9 @@ pub struct FnArgs {
defaults: HashMap<Ident, Lit>,
}

pub fn parser(opts: AttributeArgs, input: ItemFn) -> Result<TokenStream> {
let opts = match FnArgs::from_list(&opts) {
pub fn parser(opts: TokenStream, input: ItemFn) -> Result<TokenStream> {
let meta = NestedMeta::parse_meta_list(opts)?;
let opts = match FnArgs::from_list(&meta) {
Ok(opts) => opts,
Err(e) => bail!("Failed to parse attribute options: {:?}", e),
};
Expand Down
44 changes: 22 additions & 22 deletions crates/macros/src/impl_.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use darling::ast::NestedMeta;
use darling::FromMeta;
use proc_macro2::TokenStream;
use quote::quote;
use std::collections::HashMap;
use syn::{AttributeArgs, Ident, ItemImpl, Lit};
use syn::{Ident, ItemImpl, Lit};

use crate::function::{Args, CallType, Function, MethodReceiver};
use crate::helpers::get_docs;
Expand Down Expand Up @@ -96,8 +97,9 @@ pub struct ImplArgs {
rename_methods: RenameRule,
}

pub fn parser(args: AttributeArgs, mut input: ItemImpl) -> Result<TokenStream> {
let args = match ImplArgs::from_list(&args) {
pub fn parser(args: TokenStream, mut input: ItemImpl) -> Result<TokenStream> {
let meta = NestedMeta::parse_meta_list(args)?;
let args = match ImplArgs::from_list(&meta) {
Ok(args) => args,
Err(e) => bail!(input => "Failed to parse impl attribute arguments: {:?}", e),
};
Expand Down Expand Up @@ -153,49 +155,47 @@ impl MethodArgs {
let mut unparsed = vec![];
unparsed.append(attrs);
for attr in unparsed {
if attr.path.is_ident("optional") {
let path = &attr.path();

if path.is_ident("optional") {
// x
if self.optional.is_some() {
bail!(attr => "Only one `#[optional]` attribute is valid per method.");
}
let optional = attr.parse_args().map_err(
|e| err!(attr => "Invalid arguments passed to `#[optional]` attribute. {}", e),
|e| err!(e.span() => "Invalid arguments passed to `#[optional]` attribute. {}", e),
)?;
self.optional = Some(optional);
} else if attr.path.is_ident("defaults") {
// x
let meta = attr
.parse_meta()
.map_err(|e| err!(attr => "Failed to parse metadata from attribute. {}", e))?;
let defaults = HashMap::from_meta(&meta).map_err(
|e| err!(attr => "Invalid arguments passed to `#[defaults]` attribute. {}", e),
} else if path.is_ident("defaults") {
let defaults = HashMap::from_meta(&attr.meta).map_err(
|e| err!(e.span() => "Invalid arguments passed to `#[defaults]` attribute. {}", e),
)?;
self.defaults = defaults;
} else if attr.path.is_ident("public") {
} else if path.is_ident("public") {
// x
self.vis = MethodVis::Public;
} else if attr.path.is_ident("protected") {
} else if path.is_ident("protected") {
// x
self.vis = MethodVis::Protected;
} else if attr.path.is_ident("private") {
} else if path.is_ident("private") {
// x
self.vis = MethodVis::Private;
} else if attr.path.is_ident("rename") {
} else if path.is_ident("rename") {
let lit: syn::Lit = attr.parse_args().map_err(|e| err!(attr => "Invalid arguments passed to the `#[rename]` attribute. {}", e))?;
match lit {
Lit::Str(name) => self.name = name.value(),
_ => bail!(attr => "Only strings are valid method names."),
};
} else if attr.path.is_ident("getter") {
} else if path.is_ident("getter") {
// x
self.ty = MethodTy::Getter;
} else if attr.path.is_ident("setter") {
} else if path.is_ident("setter") {
// x
self.ty = MethodTy::Setter;
} else if attr.path.is_ident("constructor") {
} else if path.is_ident("constructor") {
// x
self.ty = MethodTy::Constructor;
} else if attr.path.is_ident("abstract_method") {
} else if path.is_ident("abstract_method") {
// x
self.ty = MethodTy::Abstract;
} else {
Expand Down Expand Up @@ -261,7 +261,7 @@ impl<'a> ParsedImpl<'a> {
let mut unparsed = vec![];
unparsed.append(&mut c.attrs);
for attr in unparsed {
if attr.path.is_ident("rename") {
if attr.path().is_ident("rename") {
let lit: syn::Lit = attr.parse_args().map_err(|e| err!(attr => "Invalid arguments passed to the `#[rename]` attribute. {}", e))?;
match lit {
Lit::Str(str) => name = Some(str.value()),
Expand All @@ -279,7 +279,7 @@ impl<'a> ParsedImpl<'a> {
docs,
});
}
syn::ImplItem::Method(method) => {
syn::ImplItem::Fn(method) => {
let name = self.rename.rename(method.sig.ident.to_string());
let docs = get_docs(&method.attrs);
let mut opts = MethodArgs::new(name);
Expand Down
15 changes: 5 additions & 10 deletions crates/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ mod zval;

use proc_macro::TokenStream;
use syn::{
parse_macro_input, AttributeArgs, DeriveInput, ItemConst, ItemFn, ItemForeignMod, ItemImpl,
ItemStruct,
parse_macro_input, DeriveInput, ItemConst, ItemFn, ItemForeignMod, ItemImpl, ItemStruct,
};

extern crate proc_macro;
Expand Down Expand Up @@ -195,10 +194,9 @@ extern crate proc_macro;
/// ````
#[proc_macro_attribute]
pub fn php_class(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as AttributeArgs);
let input = parse_macro_input!(input as ItemStruct);

class::parser(args, input)
class::parser(args.into(), input)
.unwrap_or_else(|e| e.to_compile_error())
.into()
}
Expand Down Expand Up @@ -357,10 +355,9 @@ pub fn php_class(args: TokenStream, input: TokenStream) -> TokenStream {
/// [exceptions](../exceptions.md) for more details.
#[proc_macro_attribute]
pub fn php_function(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as AttributeArgs);
let input = parse_macro_input!(input as ItemFn);

function::parser(args, input)
function::parser(args.into(), input)
.unwrap_or_else(|e| e.to_compile_error())
.into()
}
Expand Down Expand Up @@ -478,10 +475,9 @@ pub fn php_const(_args: TokenStream, input: TokenStream) -> TokenStream {
/// ```
#[proc_macro_attribute]
pub fn php_module(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as AttributeArgs);
let input = parse_macro_input!(input as ItemFn);

module::parser(args, input)
module::parser(args.into(), input)
.unwrap_or_else(|e| e.to_compile_error())
.into()
}
Expand Down Expand Up @@ -661,10 +657,9 @@ pub fn php_module(args: TokenStream, input: TokenStream) -> TokenStream {
/// [`php_async_impl`]: ./async_impl.md
#[proc_macro_attribute]
pub fn php_impl(args: TokenStream, input: TokenStream) -> TokenStream {
let args = parse_macro_input!(args as AttributeArgs);
let input = parse_macro_input!(input as ItemImpl);

impl_::parser(args, input)
impl_::parser(args.into(), input)
.unwrap_or_else(|e| e.to_compile_error())
.into()
}
Expand Down
9 changes: 5 additions & 4 deletions crates/macros/src/module.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use darling::FromMeta;
use darling::{ast::NestedMeta, FromMeta};
use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::{AttributeArgs, ItemFn, Signature};
use syn::{ItemFn, Signature};

use crate::prelude::*;

Expand All @@ -12,8 +12,9 @@ pub struct ModuleArgs {
startup: Option<Ident>,
}

pub fn parser(args: AttributeArgs, input: ItemFn) -> Result<TokenStream> {
let opts = match ModuleArgs::from_list(&args) {
pub fn parser(args: TokenStream, input: ItemFn) -> Result<TokenStream> {
let meta = NestedMeta::parse_meta_list(args)?;
let opts = match ModuleArgs::from_list(&meta) {
Ok(opts) => opts,
Err(e) => bail!(input => "Failed to parse attribute options: {:?}", e),
};
Expand Down
5 changes: 3 additions & 2 deletions crates/macros/src/syn_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,10 @@ impl DropLifetimes for syn::PathSegment {
.filter_map(|mut i| {
match &mut i {
syn::GenericArgument::Type(t) => t.drop_lifetimes(),
syn::GenericArgument::Binding(t) => t.drop_lifetimes(),
syn::GenericArgument::AssocType(t) => t.drop_lifetimes(),
syn::GenericArgument::Constraint(t) => t.drop_lifetimes(),
syn::GenericArgument::Const(_) => {}
syn::GenericArgument::AssocConst(_) => {}
_ => return None,
};
Some(i)
Expand All @@ -113,7 +114,7 @@ impl DropLifetimes for syn::PathSegment {
}
}

impl DropLifetimes for syn::Binding {
impl DropLifetimes for syn::AssocType {
fn drop_lifetimes(&mut self) {
self.ty.drop_lifetimes();
}
Expand Down
4 changes: 2 additions & 2 deletions crates/macros/src/zval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::{
token::Where, DataEnum, DataStruct, DeriveInput, GenericParam, Generics, Ident, ImplGenerics,
Lifetime, LifetimeDef, TypeGenerics, Variant, WhereClause,
Lifetime, LifetimeParam, TypeGenerics, Variant, WhereClause,
};

use crate::prelude::*;
Expand Down Expand Up @@ -31,7 +31,7 @@ pub fn parser(input: DeriveInput) -> Result<TokenStream> {
let mut parsed: Generics = syn::parse2(tokens).expect("couldn't reparse generics");
parsed
.params
.push(GenericParam::Lifetime(LifetimeDef::new(Lifetime::new(
.push(GenericParam::Lifetime(LifetimeParam::new(Lifetime::new(
"'_zval",
Span::call_site(),
))));
Expand Down
Loading