From 7e9211b9e15cc6773a0b7a54b99573d3f327ff19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 16 Oct 2019 11:03:45 +0200 Subject: [PATCH 1/3] Update syn, quote & proc-macro2 --- derive/Cargo.toml | 8 +++---- derive/src/rpc_attr.rs | 44 ++++++++++++++++++++++++++------------- derive/src/to_client.rs | 22 ++++++++++---------- derive/src/to_delegate.rs | 9 +++----- 4 files changed, 47 insertions(+), 36 deletions(-) diff --git a/derive/Cargo.toml b/derive/Cargo.toml index a1635413b..579772b6f 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -13,10 +13,10 @@ version = "14.0.0" proc-macro = true [dependencies] -syn = { version = "^0.15.22", features = ["full", "extra-traits", "visit", "fold"] } -proc-macro2 = "0.4" -quote = "0.6" -proc-macro-crate = "0.1.3" +syn = { version = "1.0", features = ["full", "extra-traits", "visit", "fold"] } +proc-macro2 = "1.0" +quote = "1.0" +proc-macro-crate = "0.1.4" [dev-dependencies] jsonrpc-core = { version = "14.0", path = "../core" } diff --git a/derive/src/rpc_attr.rs b/derive/src/rpc_attr.rs index 7633c669c..9f554e60d 100644 --- a/derive/src/rpc_attr.rs +++ b/derive/src/rpc_attr.rs @@ -51,7 +51,7 @@ const NEITHER_SUB_OR_UNSUB_ERR: &str = "pubsub attribute not annotated with eith impl RpcMethodAttribute { pub fn parse_attr(method: &syn::TraitItemMethod) -> Result> { - let output = &method.sig.decl.output; + let output = &method.sig.output; let attrs = method .attrs .iter() @@ -68,9 +68,15 @@ impl RpcMethodAttribute { fn parse_meta(attr: &syn::Attribute, output: &syn::ReturnType) -> Option> { match attr.parse_meta().and_then(validate_attribute_meta) { Ok(ref meta) => { - let attr_kind = match meta.name().to_string().as_ref() { - RPC_ATTR_NAME => Some(Self::parse_rpc(meta, output)), - PUB_SUB_ATTR_NAME => Some(Self::parse_pubsub(meta)), + let attr_kind = match meta + .path() + .get_ident() + .map(|i| i.to_string()) + .as_ref() + .map(|i| i.as_str()) + { + Some(RPC_ATTR_NAME) => Some(Self::parse_rpc(meta, output)), + Some(PUB_SUB_ATTR_NAME) => Some(Self::parse_pubsub(meta)), _ => None, }; attr_kind.map(|kind| { @@ -162,10 +168,13 @@ fn validate_attribute_meta(meta: syn::Meta) -> Result { } impl<'a> Visit<'a> for Visitor { fn visit_meta(&mut self, meta: &syn::Meta) { + let ident = meta.path().get_ident().map(|i| i.to_string()) + // TODO [ToDr] Maybe better fail? + .unwrap_or_else(|| "Unknown".into()); match meta { - syn::Meta::List(list) => self.meta_list_names.push(list.ident.to_string()), - syn::Meta::Word(ident) => self.meta_words.push(ident.to_string()), - syn::Meta::NameValue(nv) => self.name_value_names.push(nv.ident.to_string()), + syn::Meta::Path(_) => self.meta_words.push(ident), + syn::Meta::List(_) => self.meta_list_names.push(ident), + syn::Meta::NameValue(_) => self.name_value_names.push(ident), } } } @@ -173,13 +182,14 @@ fn validate_attribute_meta(meta: syn::Meta) -> Result { let mut visitor = Visitor::default(); visit::visit_meta(&mut visitor, &meta); - match meta.name().to_string().as_ref() { - RPC_ATTR_NAME => { + let ident = meta.path().get_ident().map(|i| i.to_string()); + match ident.as_ref().map(|i| i.as_str()) { + Some(RPC_ATTR_NAME) => { validate_idents(&meta, &visitor.meta_words, &[METADATA_META_WORD, RAW_PARAMS_META_WORD])?; validate_idents(&meta, &visitor.name_value_names, &[RPC_NAME_KEY, RETURNS_META_WORD])?; validate_idents(&meta, &visitor.meta_list_names, &[ALIASES_KEY]) } - PUB_SUB_ATTR_NAME => { + Some(PUB_SUB_ATTR_NAME) => { validate_idents( &meta, &visitor.meta_words, @@ -223,7 +233,7 @@ fn get_meta_list(meta: &syn::Meta) -> Option<&syn::MetaList> { fn get_name_value(key: &str, ml: &syn::MetaList) -> Option { ml.nested.iter().find_map(|nested| { if let syn::NestedMeta::Meta(syn::Meta::NameValue(mnv)) = nested { - if mnv.ident == key { + if path_eq_str(&mnv.path, key) { if let syn::Lit::Str(ref lit) = mnv.lit { Some(lit.value()) } else { @@ -240,8 +250,8 @@ fn get_name_value(key: &str, ml: &syn::MetaList) -> Option { fn has_meta_word(word: &str, ml: &syn::MetaList) -> bool { ml.nested.iter().any(|nested| { - if let syn::NestedMeta::Meta(syn::Meta::Word(w)) = nested { - w == word + if let syn::NestedMeta::Meta(syn::Meta::Path(p)) = nested { + path_eq_str(&p, word) } else { false } @@ -253,7 +263,7 @@ fn get_aliases(ml: &syn::MetaList) -> Vec { .iter() .find_map(|nested| { if let syn::NestedMeta::Meta(syn::Meta::List(list)) = nested { - if list.ident == ALIASES_KEY { + if path_eq_str(&list.path, ALIASES_KEY) { Some(list) } else { None @@ -266,7 +276,7 @@ fn get_aliases(ml: &syn::MetaList) -> Vec { list.nested .iter() .filter_map(|nm| { - if let syn::NestedMeta::Literal(syn::Lit::Str(alias)) = nm { + if let syn::NestedMeta::Lit(syn::Lit::Str(alias)) = nm { Some(alias.value()) } else { None @@ -275,3 +285,7 @@ fn get_aliases(ml: &syn::MetaList) -> Vec { .collect() }) } + +fn path_eq_str(path: &syn::Path, s: &str) -> bool { + path.get_ident().map(|i| i == s).unwrap_or(false) +} diff --git a/derive/src/to_client.rs b/derive/src/to_client.rs index af920414c..4de04ac2b 100644 --- a/derive/src/to_client.rs +++ b/derive/src/to_client.rs @@ -173,14 +173,14 @@ fn get_doc_comments(attrs: &[syn::Attribute]) -> Vec { fn compute_args(method: &syn::TraitItemMethod) -> Punctuated { let mut args = Punctuated::new(); - for arg in &method.sig.decl.inputs { + for arg in &method.sig.inputs { let ty = match arg { - syn::FnArg::Captured(syn::ArgCaptured { ty, .. }) => ty, + syn::FnArg::Typed(syn::PatType { ty, .. }) => ty, _ => continue, }; - let segments = match ty { + let segments = match &**ty { syn::Type::Path(syn::TypePath { - path: syn::Path { segments, .. }, + path: syn::Path { ref segments, .. }, .. }) => segments, _ => continue, @@ -200,12 +200,12 @@ fn compute_arg_identifiers(args: &Punctuated) -> let mut arg_names = vec![]; for arg in args { let pat = match arg { - syn::FnArg::Captured(syn::ArgCaptured { pat, .. }) => pat, + syn::FnArg::Typed(syn::PatType { pat, .. }) => pat, _ => continue, }; - let ident = match pat { - syn::Pat::Ident(syn::PatIdent { ident, .. }) => ident, - syn::Pat::Wild(wild) => { + let ident = match **pat { + syn::Pat::Ident(syn::PatIdent { ref ident, .. }) => ident, + syn::Pat::Wild(ref wild) => { let span = wild.underscore_token.spans[0]; let msg = "No wildcard patterns allowed in rpc trait."; return Err(syn::Error::new(span, msg)); @@ -223,7 +223,7 @@ fn compute_returns(method: &syn::TraitItemMethod, returns: &Option) -> R None => None, }; let returns = match returns { - None => try_infer_returns(&method.sig.decl.output), + None => try_infer_returns(&method.sig.output), _ => returns, }; let returns = match returns { @@ -276,8 +276,8 @@ fn get_first_type_argument(args: &syn::PathArguments) -> Option { fn compute_subscription_type(arg: &syn::FnArg) -> syn::Type { let ty = match arg { - syn::FnArg::Captured(cap) => match &cap.ty { - syn::Type::Path(path) => { + syn::FnArg::Typed(cap) => match *cap.ty { + syn::Type::Path(ref path) => { let last = &path.path.segments[&path.path.segments.len() - 1]; get_first_type_argument(&last.arguments) } diff --git a/derive/src/to_delegate.rs b/derive/src/to_delegate.rs index 55967dc81..101e303d7 100644 --- a/derive/src/to_delegate.rs +++ b/derive/src/to_delegate.rs @@ -144,7 +144,6 @@ pub fn generate_trait_item_method( let mut method = method.clone(); method .sig - .decl .generics .make_where_clause() .predicates @@ -183,13 +182,11 @@ impl RpcMethod { let mut param_types: Vec<_> = self .trait_item .sig - .decl .inputs .iter() .cloned() .filter_map(|arg| match arg { - syn::FnArg::Captured(arg_captured) => Some(arg_captured.ty), - syn::FnArg::Ignored(ty) => Some(ty), + syn::FnArg::Typed(ty) => Some(*ty.ty), _ => None, }) .collect(); @@ -225,7 +222,7 @@ impl RpcMethod { }; let method_ident = self.ident(); - let result = &self.trait_item.sig.decl.output; + let result = &self.trait_item.sig.output; let extra_closure_args: &Vec<_> = &special_args.iter().cloned().map(|arg| arg.0).collect(); let extra_method_types: &Vec<_> = &special_args.iter().cloned().map(|arg| arg.1).collect(); @@ -383,7 +380,7 @@ fn is_option_type(ty: &syn::Type) -> bool { path.path .segments .first() - .map(|t| t.value().ident == "Option") + .map(|t| t.ident == "Option") .unwrap_or(false) } else { false From ecd8831f7a718ae9ef8014b4ddde893829996caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 16 Oct 2019 15:24:32 +0200 Subject: [PATCH 2/3] Apply review suggestions. --- derive/src/rpc_attr.rs | 31 ++++++++++++++----------------- derive/src/to_delegate.rs | 3 +-- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/derive/src/rpc_attr.rs b/derive/src/rpc_attr.rs index 9f554e60d..95a7c1286 100644 --- a/derive/src/rpc_attr.rs +++ b/derive/src/rpc_attr.rs @@ -68,13 +68,7 @@ impl RpcMethodAttribute { fn parse_meta(attr: &syn::Attribute, output: &syn::ReturnType) -> Option> { match attr.parse_meta().and_then(validate_attribute_meta) { Ok(ref meta) => { - let attr_kind = match meta - .path() - .get_ident() - .map(|i| i.to_string()) - .as_ref() - .map(|i| i.as_str()) - { + let attr_kind = match path_to_str(meta.path()).as_ref().map(String::as_str) { Some(RPC_ATTR_NAME) => Some(Self::parse_rpc(meta, output)), Some(PUB_SUB_ATTR_NAME) => Some(Self::parse_pubsub(meta)), _ => None, @@ -168,13 +162,12 @@ fn validate_attribute_meta(meta: syn::Meta) -> Result { } impl<'a> Visit<'a> for Visitor { fn visit_meta(&mut self, meta: &syn::Meta) { - let ident = meta.path().get_ident().map(|i| i.to_string()) - // TODO [ToDr] Maybe better fail? - .unwrap_or_else(|| "Unknown".into()); - match meta { - syn::Meta::Path(_) => self.meta_words.push(ident), - syn::Meta::List(_) => self.meta_list_names.push(ident), - syn::Meta::NameValue(_) => self.name_value_names.push(ident), + if let Some(ident) = path_to_str(meta.path()) { + match meta { + syn::Meta::Path(_) => self.meta_words.push(ident), + syn::Meta::List(_) => self.meta_list_names.push(ident), + syn::Meta::NameValue(_) => self.name_value_names.push(ident), + } } } } @@ -182,8 +175,8 @@ fn validate_attribute_meta(meta: syn::Meta) -> Result { let mut visitor = Visitor::default(); visit::visit_meta(&mut visitor, &meta); - let ident = meta.path().get_ident().map(|i| i.to_string()); - match ident.as_ref().map(|i| i.as_str()) { + let ident = path_to_str(meta.path()); + match ident.as_ref().map(String::as_str) { Some(RPC_ATTR_NAME) => { validate_idents(&meta, &visitor.meta_words, &[METADATA_META_WORD, RAW_PARAMS_META_WORD])?; validate_idents(&meta, &visitor.name_value_names, &[RPC_NAME_KEY, RETURNS_META_WORD])?; @@ -287,5 +280,9 @@ fn get_aliases(ml: &syn::MetaList) -> Vec { } fn path_eq_str(path: &syn::Path, s: &str) -> bool { - path.get_ident().map(|i| i == s).unwrap_or(false) + path.get_ident().map_or(false, |i| i == s) +} + +fn path_to_str(path: &syn::Path) -> Option { + Some(path.get_ident()?.to_string()) } diff --git a/derive/src/to_delegate.rs b/derive/src/to_delegate.rs index 101e303d7..eaa6688ec 100644 --- a/derive/src/to_delegate.rs +++ b/derive/src/to_delegate.rs @@ -380,8 +380,7 @@ fn is_option_type(ty: &syn::Type) -> bool { path.path .segments .first() - .map(|t| t.ident == "Option") - .unwrap_or(false) + .map_or(false, |t| t.ident == "Option") } else { false } From 373259732a6860280d50c70a0a438bdd69d75e0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 16 Oct 2019 15:24:47 +0200 Subject: [PATCH 3/3] Re-format. --- derive/src/to_delegate.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/derive/src/to_delegate.rs b/derive/src/to_delegate.rs index eaa6688ec..9ee396cc7 100644 --- a/derive/src/to_delegate.rs +++ b/derive/src/to_delegate.rs @@ -142,12 +142,7 @@ pub fn generate_trait_item_method( let predicates = generate_where_clause_serialization_predicates(&trait_item, false); let mut method = method.clone(); - method - .sig - .generics - .make_where_clause() - .predicates - .extend(predicates); + method.sig.generics.make_where_clause().predicates.extend(predicates); Ok(method) } @@ -377,10 +372,7 @@ fn ident(s: &str) -> syn::Ident { fn is_option_type(ty: &syn::Type) -> bool { if let syn::Type::Path(path) = ty { - path.path - .segments - .first() - .map_or(false, |t| t.ident == "Option") + path.path.segments.first().map_or(false, |t| t.ident == "Option") } else { false }