derive: Upgrade syn/quote/proc_macro dependencies to 1.0 (#413)

This commit is contained in:
theduke 2019-08-18 18:12:25 +02:00 committed by Christian Legnitto
parent 752584fbbd
commit a3caf126b0
6 changed files with 63 additions and 89 deletions

View file

@ -15,9 +15,9 @@ edition = "2018"
proc-macro = true proc-macro = true
[dependencies] [dependencies]
proc-macro2 = "0.4" proc-macro2 = "1.0.1"
syn = { version = "0.15.28", features = ["full", "extra-traits", "parsing"] } syn = { version = "1.0.3", features = ["full", "extra-traits", "parsing"] }
quote = "0.6" quote = "1.0.2"
regex = "1" regex = "1"
lazy_static = "1.0.0" lazy_static = "1.0.0"

View file

@ -223,7 +223,7 @@ pub fn impl_enum(ast: &syn::DeriveInput, is_internal: bool) -> TokenStream {
where __S: 'r, where __S: 'r,
{ {
let meta = registry.build_enum_type::<#ident>(&(), &[ let meta = registry.build_enum_type::<#ident>(&(), &[
#(#values)* #values
]); ]);
#meta_description #meta_description
meta.into_meta() meta.into_meta()
@ -236,7 +236,7 @@ pub fn impl_enum(ast: &syn::DeriveInput, is_internal: bool) -> TokenStream {
_: &#juniper_path::Executor<Self::Context, __S> _: &#juniper_path::Executor<Self::Context, __S>
) -> #juniper_path::Value<__S> { ) -> #juniper_path::Value<__S> {
match self { match self {
#(#resolves)* #resolves
} }
} }
} }
@ -248,7 +248,7 @@ pub fn impl_enum(ast: &syn::DeriveInput, is_internal: bool) -> TokenStream {
match v.as_enum_value().or_else(|| { match v.as_enum_value().or_else(|| {
v.as_scalar_value::<String>().map(|s| s as &str) v.as_scalar_value::<String>().map(|s| s as &str)
}) { }) {
#(#from_inputs)* #from_inputs
_ => None, _ => None,
} }
} }
@ -257,7 +257,7 @@ pub fn impl_enum(ast: &syn::DeriveInput, is_internal: bool) -> TokenStream {
impl<__S: #juniper_path::ScalarValue> #juniper_path::ToInputValue<__S> for #ident { impl<__S: #juniper_path::ScalarValue> #juniper_path::ToInputValue<__S> for #ident {
fn to_input_value(&self) -> #juniper_path::InputValue<__S> { fn to_input_value(&self) -> #juniper_path::InputValue<__S> {
match self { match self {
#(#to_inputs)* #to_inputs
} }
} }
} }

View file

@ -103,8 +103,8 @@ impl ObjFieldAttrs {
} }
match item { match item {
NestedMeta::Meta(Meta::Word(ref ident)) => { NestedMeta::Meta(Meta::Path(ref path)) => {
if ident == "default" { if path.is_ident("default") {
res.default = true; res.default = true;
continue; continue;
} }
@ -294,7 +294,7 @@ pub fn impl_input_object(ast: &syn::DeriveInput, is_internal: bool) -> TokenStre
where #scalar: 'r where #scalar: 'r
{ {
let fields = &[ let fields = &[
#(#meta_fields)* #meta_fields
]; ];
let meta = registry.build_input_object_type::<#ident>(&(), fields); let meta = registry.build_input_object_type::<#ident>(&(), fields);
#meta_description #meta_description
@ -311,7 +311,7 @@ pub fn impl_input_object(ast: &syn::DeriveInput, is_internal: bool) -> TokenStre
{ {
if let Some(obj) = value.to_object_value() { if let Some(obj) = value.to_object_value() {
let item = #ident { let item = #ident {
#(#from_inputs)* #from_inputs
}; };
Some(item) Some(item)
} }
@ -326,7 +326,7 @@ pub fn impl_input_object(ast: &syn::DeriveInput, is_internal: bool) -> TokenStre
{ {
fn to_input_value(&self) -> #juniper_path::InputValue<#scalar> { fn to_input_value(&self) -> #juniper_path::InputValue<#scalar> {
#juniper_path::InputValue::object(vec![ #juniper_path::InputValue::object(vec![
#(#to_inputs)* #to_inputs
].into_iter().collect()) ].into_iter().collect())
} }
} }

View file

@ -20,31 +20,28 @@ impl syn::parse::Parse for TransparentAttributes {
description: None, description: None,
}; };
let content; while !input.is_empty() {
syn::parenthesized!(content in input); let ident: syn::Ident = input.parse()?;
while !content.is_empty() {
let ident: syn::Ident = content.parse()?;
match ident.to_string().as_str() { match ident.to_string().as_str() {
"name" => { "name" => {
content.parse::<syn::Token![=]>()?; input.parse::<syn::Token![=]>()?;
let val = content.parse::<syn::LitStr>()?; let val = input.parse::<syn::LitStr>()?;
output.name = Some(val.value()); output.name = Some(val.value());
} }
"description" => { "description" => {
content.parse::<syn::Token![=]>()?; input.parse::<syn::Token![=]>()?;
let val = content.parse::<syn::LitStr>()?; let val = input.parse::<syn::LitStr>()?;
output.description = Some(val.value()); output.description = Some(val.value());
} }
"transparent" => { "transparent" => {
output.transparent = Some(true); output.transparent = Some(true);
} }
other => { other => {
return Err(content.error(format!("Unknown attribute: {}", other))); return Err(input.error(format!("Unknown attribute: {}", other)));
} }
} }
if content.lookahead1().peek(syn::Token![,]) { if input.lookahead1().peek(syn::Token![,]) {
content.parse::<syn::Token![,]>()?; input.parse::<syn::Token![,]>()?;
} }
} }
@ -56,7 +53,7 @@ impl TransparentAttributes {
fn from_attrs(attrs: &Vec<syn::Attribute>) -> syn::parse::Result<Self> { fn from_attrs(attrs: &Vec<syn::Attribute>) -> syn::parse::Result<Self> {
match util::find_graphql_attr(attrs) { match util::find_graphql_attr(attrs) {
Some(attr) => { Some(attr) => {
let mut parsed: TransparentAttributes = syn::parse(attr.tts.clone().into())?; let mut parsed: TransparentAttributes = attr.parse_args()?;
if parsed.description.is_none() { if parsed.description.is_none() {
parsed.description = util::get_doc_comment(attrs); parsed.description = util::get_doc_comment(attrs);
} }
@ -86,7 +83,7 @@ fn impl_scalar_struct(
) -> TokenStream { ) -> TokenStream {
let field = match data.fields { let field = match data.fields {
syn::Fields::Unnamed(ref fields) if fields.unnamed.len() == 1 => { syn::Fields::Unnamed(ref fields) if fields.unnamed.len() == 1 => {
fields.unnamed.first().unwrap().into_value() fields.unnamed.first().unwrap()
} }
_ => { _ => {
panic!("#[derive(GraphQLScalarValue)] may only be applied to enums or tuple structs with a single field"); panic!("#[derive(GraphQLScalarValue)] may only be applied to enums or tuple structs with a single field");
@ -254,7 +251,7 @@ where
fn derive_from_variant(variant: &Variant, ident: &Ident) -> Result<TokenStream, String> { fn derive_from_variant(variant: &Variant, ident: &Ident) -> Result<TokenStream, String> {
let ty = match variant.fields { let ty = match variant.fields {
Fields::Unnamed(ref u) if u.unnamed.len() == 1 => &u.unnamed.first().unwrap().value().ty, Fields::Unnamed(ref u) if u.unnamed.len() == 1 => &u.unnamed.first().unwrap().ty,
_ => { _ => {
return Err(String::from( return Err(String::from(

View file

@ -91,7 +91,7 @@ pub fn build_object(args: TokenStream, body: TokenStream, is_internal: bool) ->
for item in _impl.items { for item in _impl.items {
match item { match item {
syn::ImplItem::Method(method) => { syn::ImplItem::Method(method) => {
let _type = match &method.sig.decl.output { let _type = match &method.sig.output {
syn::ReturnType::Type(_, ref t) => (**t).clone(), syn::ReturnType::Type(_, ref t) => (**t).clone(),
syn::ReturnType::Default => { syn::ReturnType::Default => {
panic!( panic!(
@ -115,21 +115,18 @@ pub fn build_object(args: TokenStream, body: TokenStream, is_internal: bool) ->
let mut args = Vec::new(); let mut args = Vec::new();
let mut resolve_parts = Vec::new(); let mut resolve_parts = Vec::new();
for arg in method.sig.decl.inputs { for arg in method.sig.inputs {
match arg { match arg {
_self @ syn::FnArg::SelfRef(_) => { syn::FnArg::Receiver(rec) => {
// Can be ignored. if rec.reference.is_none() || rec.mutability.is_some() {
// "self" will already be in scope.
// resolve_args.push(quote!(self));
}
syn::FnArg::SelfValue(_) => {
panic!( panic!(
"Invalid method receiver {}(self, ...): did you mean '&self'?", "Invalid method receiver {}(self, ...): did you mean '&self'?",
method.sig.ident method.sig.ident
); );
} }
syn::FnArg::Captured(ref captured) => { }
let (arg_ident, is_mut) = match &captured.pat { syn::FnArg::Typed(ref captured) => {
let (arg_ident, is_mut) = match &*captured.pat {
syn::Pat::Ident(ref pat_ident) => { syn::Pat::Ident(ref pat_ident) => {
(&pat_ident.ident, pat_ident.mutability.is_some()) (&pat_ident.ident, pat_ident.mutability.is_some())
} }
@ -161,7 +158,7 @@ pub fn build_object(args: TokenStream, body: TokenStream, is_internal: bool) ->
// without a reference. (&Context) // without a reference. (&Context)
else if context_type else if context_type
.clone() .clone()
.map(|ctx| ctx == &captured.ty) .map(|ctx| ctx == &*captured.ty)
.unwrap_or(false) .unwrap_or(false)
{ {
panic!( panic!(
@ -193,12 +190,11 @@ pub fn build_object(args: TokenStream, body: TokenStream, is_internal: bool) ->
}) })
} }
} }
_ => panic!("Invalid argument type in method {}", method.sig.ident),
} }
} }
let body = &method.block; let body = &method.block;
let return_ty = &method.sig.decl.output; let return_ty = &method.sig.output;
let resolver_code = quote!( let resolver_code = quote!(
(|| #return_ty { (|| #return_ty {
#( #resolve_parts )* #( #resolve_parts )*

View file

@ -60,11 +60,11 @@ pub fn find_graphql_attr(attrs: &Vec<Attribute>) -> Option<&Attribute> {
pub fn get_deprecated(attrs: &Vec<Attribute>) -> Option<DeprecationAttr> { pub fn get_deprecated(attrs: &Vec<Attribute>) -> Option<DeprecationAttr> {
for attr in attrs { for attr in attrs {
match attr.interpret_meta() { match attr.parse_meta() {
Some(Meta::List(ref list)) if list.ident == "deprecated" => { Ok(Meta::List(ref list)) if list.path.is_ident("deprecated") => {
return Some(get_deprecated_meta_list(list)); return Some(get_deprecated_meta_list(list));
} }
Some(Meta::Word(ref ident)) if ident == "deprecated" => { Ok(Meta::Path(ref path)) if path.is_ident("deprecated") => {
return Some(DeprecationAttr { reason: None }); return Some(DeprecationAttr { reason: None });
} }
_ => {} _ => {}
@ -77,7 +77,7 @@ fn get_deprecated_meta_list(list: &MetaList) -> DeprecationAttr {
for meta in &list.nested { for meta in &list.nested {
match meta { match meta {
&NestedMeta::Meta(Meta::NameValue(ref nv)) => { &NestedMeta::Meta(Meta::NameValue(ref nv)) => {
if nv.ident == "note" { if nv.path.is_ident("note") {
match &nv.lit { match &nv.lit {
&Lit::Str(ref strlit) => { &Lit::Str(ref strlit) => {
return DeprecationAttr { return DeprecationAttr {
@ -88,8 +88,8 @@ fn get_deprecated_meta_list(list: &MetaList) -> DeprecationAttr {
} }
} else { } else {
panic!( panic!(
"Unrecognized setting on #[deprecated(..)] attribute: {}", "Unrecognized setting on #[deprecated(..)] attribute: {:?}",
nv.ident nv.path,
); );
} }
} }
@ -147,7 +147,7 @@ fn get_doc_strings(items: &Vec<MetaNameValue>) -> Option<Vec<String>> {
let comments = items let comments = items
.iter() .iter()
.filter_map(|item| { .filter_map(|item| {
if item.ident == "doc" { if item.path.is_ident("doc") {
match item.lit { match item.lit {
Lit::Str(ref strlit) => Some(strlit.value().to_string()), Lit::Str(ref strlit) => Some(strlit.value().to_string()),
_ => panic!("doc attributes only have string literal"), _ => panic!("doc attributes only have string literal"),
@ -168,8 +168,8 @@ fn get_doc_strings(items: &Vec<MetaNameValue>) -> Option<Vec<String>> {
fn get_doc_attr(attrs: &Vec<Attribute>) -> Option<Vec<MetaNameValue>> { fn get_doc_attr(attrs: &Vec<Attribute>) -> Option<Vec<MetaNameValue>> {
let mut docs = Vec::new(); let mut docs = Vec::new();
for attr in attrs { for attr in attrs {
match attr.interpret_meta() { match attr.parse_meta() {
Some(Meta::NameValue(ref nv)) if nv.ident == "doc" => docs.push(nv.clone()), Ok(Meta::NameValue(ref nv)) if nv.path.is_ident("doc") => docs.push(nv.clone()),
_ => {} _ => {}
} }
} }
@ -182,8 +182,8 @@ fn get_doc_attr(attrs: &Vec<Attribute>) -> Option<Vec<MetaNameValue>> {
// Get the nested items of a a #[graphql(...)] attribute. // Get the nested items of a a #[graphql(...)] attribute.
pub fn get_graphql_attr(attrs: &Vec<Attribute>) -> Option<Vec<NestedMeta>> { pub fn get_graphql_attr(attrs: &Vec<Attribute>) -> Option<Vec<NestedMeta>> {
for attr in attrs { for attr in attrs {
match attr.interpret_meta() { match attr.parse_meta() {
Some(Meta::List(ref list)) if list.ident == "graphql" => { Ok(Meta::List(ref list)) if list.path.is_ident("graphql") => {
return Some(list.nested.iter().map(|x| x.clone()).collect()); return Some(list.nested.iter().map(|x| x.clone()).collect());
} }
_ => {} _ => {}
@ -199,7 +199,7 @@ pub fn keyed_item_value(
) -> Option<AttributeValue> { ) -> Option<AttributeValue> {
match item { match item {
// Attributes in the form of `#[graphql(name = "value")]`. // Attributes in the form of `#[graphql(name = "value")]`.
&NestedMeta::Meta(Meta::NameValue(ref nameval)) if nameval.ident == name => { &NestedMeta::Meta(Meta::NameValue(ref nameval)) if nameval.path.is_ident(name) => {
match &nameval.lit { match &nameval.lit {
// We have a string attribute value. // We have a string attribute value.
&Lit::Str(ref strlit) => match validation { &Lit::Str(ref strlit) => match validation {
@ -215,7 +215,7 @@ pub fn keyed_item_value(
} }
} }
// Attributes in the form of `#[graphql(name)]`. // Attributes in the form of `#[graphql(name)]`.
&NestedMeta::Meta(Meta::Word(ref ident)) if ident.to_string() == name => match validation { &NestedMeta::Meta(Meta::Path(ref path)) if path.is_ident(name) => match validation {
AttributeValidation::String => { AttributeValidation::String => {
panic!(format!( panic!(format!(
"Invalid format for attribute \"{:?}\": expected a string value", "Invalid format for attribute \"{:?}\": expected a string value",
@ -304,18 +304,6 @@ impl syn::parse::Parse for ObjectAttributes {
interfaces: Vec::new(), interfaces: Vec::new(),
}; };
// Skip potential parantheses which are present for regular attributes but not for proc macro
// attributes.
let inner = (|| {
let content;
syn::parenthesized!(content in input);
Ok(content)
})();
let input = match inner.as_ref() {
Ok(content) => content,
Err(_) => input,
};
while !input.is_empty() { while !input.is_empty() {
let ident: syn::Ident = input.parse()?; let ident: syn::Ident = input.parse()?;
match ident.to_string().as_str() { match ident.to_string().as_str() {
@ -377,7 +365,7 @@ impl ObjectAttributes {
// Need to unwrap outer (), which are not present for proc macro attributes, // Need to unwrap outer (), which are not present for proc macro attributes,
// but are present for regular ones. // but are present for regular ones.
let mut a = syn::parse::<Self>(attr.tts.clone().into())?; let mut a: Self = attr.parse_args()?;
if a.description.is_none() { if a.description.is_none() {
a.description = get_doc_comment(attrs); a.description = get_doc_comment(attrs);
} }
@ -409,7 +397,6 @@ impl parse::Parse for FieldAttributeArgument {
let content; let content;
syn::parenthesized!(content in input); syn::parenthesized!(content in input);
while !content.is_empty() { while !content.is_empty() {
let name = content.parse::<syn::Ident>()?; let name = content.parse::<syn::Ident>()?;
content.parse::<Token![=]>()?; content.parse::<Token![=]>()?;
@ -514,11 +501,7 @@ pub struct FieldAttributes {
impl parse::Parse for FieldAttributes { impl parse::Parse for FieldAttributes {
fn parse(input: syn::parse::ParseStream) -> syn::parse::Result<Self> { fn parse(input: syn::parse::ParseStream) -> syn::parse::Result<Self> {
// Remove wrapping parantheses. let items = Punctuated::<FieldAttribute, Token![,]>::parse_terminated(&input)?;
let content;
syn::parenthesized!(content in input);
let items = Punctuated::<FieldAttribute, Token![,]>::parse_terminated(&content)?;
let mut output = Self { let mut output = Self {
name: None, name: None,
@ -548,8 +531,8 @@ impl parse::Parse for FieldAttributes {
} }
} }
if !content.is_empty() { if !input.is_empty() {
Err(content.error("Unexpected input")) Err(input.error("Unexpected input"))
} else { } else {
Ok(output) Ok(output)
} }
@ -564,12 +547,10 @@ impl FieldAttributes {
let doc_comment = get_doc_comment(&attrs); let doc_comment = get_doc_comment(&attrs);
let deprecation = get_deprecated(&attrs); let deprecation = get_deprecated(&attrs);
let attr_opt = attrs let attr_opt = attrs.into_iter().find(|attr| attr.path.is_ident("graphql"));
.into_iter()
.find(|attr| path_eq_single(&attr.path, "graphql"));
let mut output = match attr_opt { let mut output = match attr_opt {
Some(attr) => syn::parse(attr.tts.into())?, Some(attr) => attr.parse_args()?,
None => Self::default(), None => Self::default(),
}; };
@ -594,7 +575,7 @@ pub struct GraphQLTypeDefinitionFieldArg {
pub name: String, pub name: String,
pub description: Option<String>, pub description: Option<String>,
pub default: Option<syn::Expr>, pub default: Option<syn::Expr>,
pub _type: syn::Type, pub _type: Box<syn::Type>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -864,7 +845,7 @@ mod test {
} }
fn ident(s: &str) -> Ident { fn ident(s: &str) -> Ident {
Ident::new(s, Span::call_site()) quote::format_ident!("{}", s)
} }
mod test_get_doc_strings { mod test_get_doc_strings {
@ -873,7 +854,7 @@ mod test {
#[test] #[test]
fn test_single() { fn test_single() {
let result = get_doc_strings(&vec![MetaNameValue { let result = get_doc_strings(&vec![MetaNameValue {
ident: ident("doc").into(), path: ident("doc").into(),
eq_token: Default::default(), eq_token: Default::default(),
lit: litstr("foo"), lit: litstr("foo"),
}]); }]);
@ -887,17 +868,17 @@ mod test {
fn test_many() { fn test_many() {
let result = get_doc_strings(&vec![ let result = get_doc_strings(&vec![
MetaNameValue { MetaNameValue {
ident: ident("doc").into(), path: ident("doc").into(),
eq_token: Default::default(), eq_token: Default::default(),
lit: litstr("foo"), lit: litstr("foo"),
}, },
MetaNameValue { MetaNameValue {
ident: ident("doc").into(), path: ident("doc").into(),
eq_token: Default::default(), eq_token: Default::default(),
lit: litstr("\n"), lit: litstr("\n"),
}, },
MetaNameValue { MetaNameValue {
ident: ident("doc").into(), path: ident("doc").into(),
eq_token: Default::default(), eq_token: Default::default(),
lit: litstr("bar"), lit: litstr("bar"),
}, },
@ -911,7 +892,7 @@ mod test {
#[test] #[test]
fn test_not_doc() { fn test_not_doc() {
let result = get_doc_strings(&vec![MetaNameValue { let result = get_doc_strings(&vec![MetaNameValue {
ident: ident("blah").into(), path: ident("blah").into(),
eq_token: Default::default(), eq_token: Default::default(),
lit: litstr("foo"), lit: litstr("foo"),
}]); }]);