Skip to content

Commit

Permalink
Upgrade to syn2 (#542)
Browse files Browse the repository at this point in the history
Make necessary changes to the `utoipa-gen` in order to work with syn2.
  • Loading branch information
juhaku authored Mar 25, 2023
1 parent fed0226 commit ee88c75
Show file tree
Hide file tree
Showing 15 changed files with 127 additions and 78 deletions.
2 changes: 1 addition & 1 deletion utoipa-gen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ proc-macro = true

[dependencies]
proc-macro2 = "1.0"
syn = { version = "1.0", features = ["full"] }
syn = { version = "2.0", features = ["full"] }
quote = "1.0"
proc-macro-error = "1.0"
regex = { version = "1.7", optional = true }
Expand Down
18 changes: 10 additions & 8 deletions utoipa-gen/src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn is_default(container_rules: &Option<&SerdeContainer>, field_rule: &Option<&Se
fn get_deprecated(attributes: &[Attribute]) -> Option<Deprecated> {
attributes.iter().find_map(|attribute| {
if attribute
.path
.path()
.get_ident()
.map(|ident| *ident == "deprecated")
.unwrap_or(false)
Expand Down Expand Up @@ -74,7 +74,7 @@ enum TypeTreeValue<'t> {
Path(&'t Path),
/// Slice and array types need to be manually defined, since they cannot be recognized from
/// generic arguments.
Array(Vec<TypeTreeValue<'t>>, &'t Span),
Array(Vec<TypeTreeValue<'t>>, Span),
UnitType,
}

Expand Down Expand Up @@ -118,16 +118,18 @@ impl<'t> TypeTree<'t> {
tuple.elems.iter().flat_map(Self::get_type_paths).collect()
},
Type::Group(group) => Self::get_type_paths(group.elem.as_ref()),
Type::Slice(slice) => vec![TypeTreeValue::Array(Self::get_type_paths(&slice.elem), &slice.bracket_token.span)],
Type::Array(array) => vec![TypeTreeValue::Array(Self::get_type_paths(&array.elem), &array.bracket_token.span)],
Type::Slice(slice) => vec![TypeTreeValue::Array(Self::get_type_paths(&slice.elem), slice.bracket_token.span.join())],
Type::Array(array) => vec![TypeTreeValue::Array(Self::get_type_paths(&array.elem), array.bracket_token.span.join())],
Type::TraitObject(trait_object) => {
trait_object
.bounds
.iter()
.find_map(|bound| {
match bound {
match &bound {
syn::TypeParamBound::Trait(trait_bound) => Some(&trait_bound.path),
syn::TypeParamBound::Lifetime(_) => None
syn::TypeParamBound::Lifetime(_) => None,
syn::TypeParamBound::Verbatim(_) => None,
_ => todo!("TypeTree trait object found unrecognized TypeParamBound"),
}
})
.map(|path| vec![TypeTreeValue::Path(path)]).unwrap_or_else(Vec::new)
Expand Down Expand Up @@ -159,7 +161,7 @@ impl<'t> TypeTree<'t> {
TypeTreeValue::TypePath(type_path) => &type_path.path,
TypeTreeValue::Path(path) => path,
TypeTreeValue::Array(value, span) => {
let array: Path = Ident::new("Array", *span).into();
let array: Path = Ident::new("Array", span).into();
return TypeTree {
path: Some(Cow::Owned(array)),
value_type: ValueType::Object,
Expand Down Expand Up @@ -782,7 +784,7 @@ impl<'c> ComponentSchema {
})
.unwrap_or_else(|| quote!(utoipa::openapi::schema::empty()))
.to_tokens(tokens);
tokens.extend(features.to_token_stream());
tokens.extend(features.to_token_stream());
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions utoipa-gen/src/component/into_params.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::borrow::Cow;

use proc_macro2::TokenStream;
use proc_macro_error::{abort, ResultExt};
use proc_macro_error::abort;
use quote::{quote, ToTokens};
use syn::{
parse::Parse, punctuated::Punctuated, token::Comma, Attribute, Data, Field, Generics, Ident,
Expand All @@ -19,7 +19,7 @@ use crate::{
FieldRename,
},
doc_comment::CommentAttributes,
Array, Required,
Array, Required, ResultExt,
};

use super::{
Expand Down Expand Up @@ -69,7 +69,7 @@ impl ToTokens for IntoParams {
let mut into_params_features = self
.attrs
.iter()
.filter(|attr| attr.path.is_ident("into_params"))
.filter(|attr| attr.path().is_ident("into_params"))
.map(|attribute| {
attribute
.parse_args::<IntoParamsFeatures>()
Expand All @@ -80,7 +80,7 @@ impl ToTokens for IntoParams {
let serde_container = serde::parse_container(&self.attrs);

// #[param] is only supported over fields
if self.attrs.iter().any(|attr| attr.path.is_ident("param")) {
if self.attrs.iter().any(|attr| attr.path().is_ident("param")) {
abort! {
ident,
"found `param` attribute in unsupported context";
Expand Down Expand Up @@ -272,7 +272,7 @@ impl Param<'_> {
.field
.attrs
.iter()
.filter(|attribute| attribute.path.is_ident("param"))
.filter(|attribute| attribute.path().is_ident("param"))
.map(|attribute| {
attribute
.parse_args::<FieldFeatures>()
Expand Down
18 changes: 11 additions & 7 deletions utoipa-gen/src/component/schema.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
use std::borrow::Cow;

use proc_macro2::{Ident, Span, TokenStream};
use proc_macro_error::{abort, ResultExt};
use proc_macro_error::abort;
use quote::{format_ident, quote, ToTokens};
use syn::{
parse::Parse, punctuated::Punctuated, token::Comma, Attribute, Data, Field, Fields,
FieldsNamed, FieldsUnnamed, GenericParam, Generics, Lifetime, LifetimeDef, Path, PathArguments,
Token, Variant, Visibility,
FieldsNamed, FieldsUnnamed, GenericParam, Generics, Lifetime, LifetimeParam, Path,
PathArguments, Token, Variant, Visibility,
};

use crate::{component::features::{Rename, Example}, doc_comment::CommentAttributes, Array};
use crate::{
component::features::{Example, Rename},
doc_comment::CommentAttributes,
Array, ResultExt,
};

use self::{
enum_variant::{
Expand Down Expand Up @@ -127,7 +131,7 @@ impl ToTokens for Schema<'_> {
ident.to_string()
};

let schema_lifetime: GenericParam = LifetimeDef::new(life.clone()).into();
let schema_lifetime: GenericParam = LifetimeParam::new(life.clone()).into();
let schema_generics = Generics {
params: [schema_lifetime.clone()].into_iter().collect(),
..Default::default()
Expand Down Expand Up @@ -609,7 +613,7 @@ impl<'e> EnumSchema<'e> {
attributes
.iter()
.find_map(|attribute| {
if attribute.path.is_ident("repr") {
if attribute.path().is_ident("repr") {
attribute.parse_args::<syn::TypePath>().ok()
} else {
None
Expand Down Expand Up @@ -1539,7 +1543,7 @@ impl Parse for AliasSchema {
fn parse_aliases(attributes: &[Attribute]) -> Option<Punctuated<AliasSchema, Comma>> {
attributes
.iter()
.find(|attribute| attribute.path.is_ident("aliases"))
.find(|attribute| attribute.path().is_ident("aliases"))
.map(|aliases| {
aliases
.parse_args_with(Punctuated::<AliasSchema, Comma>::parse_terminated)
Expand Down
32 changes: 23 additions & 9 deletions utoipa-gen/src/component/schema/features.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
use proc_macro_error::ResultExt;
use syn::{
parse::{Parse, ParseBuffer, ParseStream},
Attribute,
};

use crate::component::features::{
impl_into_inner, impl_merge, parse_features, AdditionalProperites, As, Default, Example,
ExclusiveMaximum, ExclusiveMinimum, Feature, Format, Inline, IntoInner, MaxItems, MaxLength,
MaxProperties, Maximum, Merge, MinItems, MinLength, MinProperties, Minimum, MultipleOf,
Nullable, Pattern, ReadOnly, Rename, RenameAll, Required, SchemaWith, Title, ValueType,
WriteOnly, XmlAttr,
use crate::{
component::features::{
impl_into_inner, impl_merge, parse_features, AdditionalProperites, As, Default, Example,
ExclusiveMaximum, ExclusiveMinimum, Feature, Format, Inline, IntoInner, MaxItems,
MaxLength, MaxProperties, Maximum, Merge, MinItems, MinLength, MinProperties, Minimum,
MultipleOf, Nullable, Pattern, ReadOnly, Rename, RenameAll, Required, SchemaWith, Title,
ValueType, WriteOnly, XmlAttr,
},
ResultExt,
};

#[cfg_attr(feature = "debug", derive(Debug))]
Expand Down Expand Up @@ -185,7 +187,13 @@ impl_merge!(
pub fn parse_schema_features<T: Sized + Parse + Merge<T>>(attributes: &[Attribute]) -> Option<T> {
attributes
.iter()
.filter(|attribute| attribute.path.get_ident().map(|ident| *ident == "schema").unwrap_or(false))
.filter(|attribute| {
attribute
.path()
.get_ident()
.map(|ident| *ident == "schema")
.unwrap_or(false)
})
.map(|attribute| attribute.parse_args::<T>().unwrap_or_abort())
.reduce(|acc, item| acc.merge(item))
}
Expand All @@ -199,7 +207,13 @@ pub fn parse_schema_features_with<
) -> Option<T> {
attributes
.iter()
.filter(|attribute| attribute.path.get_ident().map(|ident| *ident == "schema").unwrap_or(false))
.filter(|attribute| {
attribute
.path()
.get_ident()
.map(|ident| *ident == "schema")
.unwrap_or(false)
})
.map(|attributes| attributes.parse_args_with(parser).unwrap_or_abort())
.reduce(|acc, item| acc.merge(item))
}
8 changes: 5 additions & 3 deletions utoipa-gen/src/component/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
use std::str::FromStr;

use proc_macro2::{Ident, Span, TokenTree};
use proc_macro_error::{abort, ResultExt};
use proc_macro_error::abort;
use syn::{buffer::Cursor, Attribute, Error};

use crate::ResultExt;

#[inline]
fn parse_next_lit_str(next: Cursor) -> Option<(String, Span)> {
match next.token_tree() {
Expand Down Expand Up @@ -209,7 +211,7 @@ impl SerdeContainer {
pub fn parse_value(attributes: &[Attribute]) -> Option<SerdeValue> {
attributes
.iter()
.filter(|attribute| attribute.path.is_ident("serde"))
.filter(|attribute| attribute.path().is_ident("serde"))
.map(|serde_attribute| {
serde_attribute
.parse_args_with(SerdeValue::parse)
Expand Down Expand Up @@ -244,7 +246,7 @@ pub fn parse_value(attributes: &[Attribute]) -> Option<SerdeValue> {
pub fn parse_container(attributes: &[Attribute]) -> Option<SerdeContainer> {
attributes
.iter()
.filter(|attribute| attribute.path.is_ident("serde"))
.filter(|attribute| attribute.path().is_ident("serde"))
.map(|serde_attribute| {
serde_attribute
.parse_args_with(SerdeContainer::parse)
Expand Down
24 changes: 11 additions & 13 deletions utoipa-gen/src/doc_comment.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::ops::Deref;

use proc_macro2::{Ident, Span};
use proc_macro_error::{abort_call_site, emit_warning, ResultExt};
use syn::{Attribute, Lit, Meta};
use proc_macro2::Ident;
use proc_macro_error::abort_call_site;
use syn::{Attribute, Expr, Lit, Meta};

const DOC_ATTRIBUTE_TYPE: &str = "doc";

Expand All @@ -27,7 +27,7 @@ impl CommentAttributes {
}

fn get_attribute_ident(attribute: &Attribute) -> Option<&Ident> {
attribute.path.get_ident()
attribute.path().get_ident()
}

fn as_string_vec<'a, I: Iterator<Item = &'a Attribute>>(attributes: I) -> Vec<String> {
Expand All @@ -38,17 +38,15 @@ impl CommentAttributes {
}

fn parse_doc_comment(attribute: &Attribute) -> Option<String> {
let meta = attribute.parse_meta().unwrap_or_abort();

match meta {
match &attribute.meta {
Meta::NameValue(name_value) => {
if let Lit::Str(doc_comment) = name_value.lit {
Some(doc_comment.value().trim().to_string())
if let Expr::Lit(ref doc_comment) = name_value.value {
if let Lit::Str(ref comment) = doc_comment.lit {
Some(comment.value().trim().to_string())
} else {
None
}
} else {
emit_warning!(
Span::call_site(),
"Expected Lit::Str types for types in meta, ignoring value"
);
None
}
}
Expand Down
2 changes: 1 addition & 1 deletion utoipa-gen/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ pub mod fn_arg {
}).collect::<Vec<_>>())
},
syn::Pat::TupleStruct(tuple_struct) => {
get_pat_fn_arg_type(tuple_struct.pat.elems.first().as_ref().expect(
get_pat_fn_arg_type(tuple_struct.elems.first().as_ref().expect(
"PatTuple expected to have at least one element, cannot get fn argument",
))
},
Expand Down
9 changes: 4 additions & 5 deletions utoipa-gen/src/ext/actix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ impl ArgumentResolver for PathOperations {
Option<Vec<super::ValueArgument<'_>>>,
Option<Vec<super::IntoParamsType<'_>>>,
) {
let (into_params_args, value_args): (Vec<FnArg>, Vec<FnArg>) = fn_arg::get_fn_args(fn_args)
.into_iter()
.partition(fn_arg::is_into_params);
let (into_params_args, value_args): (Vec<FnArg>, Vec<FnArg>) =
fn_arg::get_fn_args(fn_args).partition(fn_arg::is_into_params);

if let Some(macro_args) = macro_args {
let primitive_args = get_primitive_args(value_args);
Expand Down Expand Up @@ -98,12 +97,12 @@ fn into_value_argument((macro_arg, primitive_arg): (MacroArg, TypeTree)) -> Valu
impl PathOperationResolver for PathOperations {
fn resolve_operation(item_fn: &ItemFn) -> Option<ResolvedOperation> {
item_fn.attrs.iter().find_map(|attribute| {
if is_valid_request_type(attribute.path.get_ident()) {
if is_valid_request_type(attribute.path().get_ident()) {
match attribute.parse_args::<Path>() {
Ok(path) => Some(ResolvedOperation {
path: path.0,
path_operation: PathOperation::from_ident(
attribute.path.get_ident().unwrap(),
attribute.path().get_ident().unwrap(),
),
}),
Err(error) => abort!(
Expand Down
4 changes: 2 additions & 2 deletions utoipa-gen/src/ext/rocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ fn is_anonymous_arg(arg: &MacroArg) -> bool {
impl PathOperationResolver for PathOperations {
fn resolve_operation(ast_fn: &syn::ItemFn) -> Option<super::ResolvedOperation> {
ast_fn.attrs.iter().find_map(|attribute| {
if is_valid_route_type(attribute.path.get_ident()) {
if is_valid_route_type(attribute.path().get_ident()) {
let Path(path, operation) = match attribute.parse_args::<Path>() {
Ok(path) => path,
Err(error) => abort!(
Expand All @@ -162,7 +162,7 @@ impl PathOperationResolver for PathOperations {
} else {
Some(ResolvedOperation {
path_operation: PathOperation::from_ident(
attribute.path.get_ident().unwrap(),
attribute.path().get_ident().unwrap(),
),
path,
})
Expand Down
Loading

0 comments on commit ee88c75

Please sign in to comment.