From f9e8d91590a75f1f711164999f244c121c6f96eb Mon Sep 17 00:00:00 2001 From: Dmitry Samoylov Date: Tue, 4 Feb 2020 19:56:22 +0700 Subject: [PATCH] Use actual spans instead of Span::call_site() --- yaserde_derive/src/de/build_default_value.rs | 7 ++- yaserde_derive/src/de/expand_enum.rs | 32 +++++++------- yaserde_derive/src/de/expand_struct.rs | 45 +++++++++++--------- yaserde_derive/src/de/mod.rs | 7 +-- yaserde_derive/src/field_type.rs | 8 ++-- yaserde_derive/src/ser/element.rs | 8 +++- yaserde_derive/src/ser/expand_enum.rs | 5 ++- yaserde_derive/src/ser/expand_struct.rs | 31 +++++++------- yaserde_derive/src/ser/mod.rs | 7 +-- 9 files changed, 83 insertions(+), 67 deletions(-) diff --git a/yaserde_derive/src/de/build_default_value.rs b/yaserde_derive/src/de/build_default_value.rs index 19843cc..39561e4 100644 --- a/yaserde_derive/src/de/build_default_value.rs +++ b/yaserde_derive/src/de/build_default_value.rs @@ -8,7 +8,12 @@ pub fn build_default_value( default: &Option, ) -> Option { if let Some(d) = default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new( + &d, + label + .as_ref() + .map_or(Span::call_site(), |ident| ident.span()), + ); Some(quote! { #[allow(unused_mut)] diff --git a/yaserde_derive/src/de/expand_enum.rs b/yaserde_derive/src/de/expand_enum.rs index b65b8d1..6f6d210 100644 --- a/yaserde_derive/src/de/expand_enum.rs +++ b/yaserde_derive/src/de/expand_enum.rs @@ -1,7 +1,8 @@ use attribute::*; use field_type::*; -use proc_macro2::{Span, TokenStream}; +use proc_macro2::TokenStream; use std::collections::BTreeMap; +use syn::spanned::Spanned; use syn::DataEnum; use syn::Fields; use syn::Ident; @@ -133,21 +134,22 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream { .iter() .enumerate() .map(|(idx, field)| { - let visitor_label = Ident::new(&format!("__Visitor_{}", idx), Span::call_site()); + let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.span()); - let make_visitor = |visitor: &Ident, field_type: &TokenStream, fn_body: &TokenStream| { - Some(quote! { - #[allow(non_snake_case, non_camel_case_types)] - struct #visitor_label; - impl<'de> Visitor<'de> for #visitor_label { - type Value = #field_type; + let make_visitor = + |visitor: &TokenStream, field_type: &TokenStream, fn_body: &TokenStream| { + Some(quote! { + #[allow(non_snake_case, non_camel_case_types)] + struct #visitor_label; + impl<'de> Visitor<'de> for #visitor_label { + type Value = #field_type; - fn #visitor(self, v: &str) -> Result { - #fn_body + fn #visitor(self, v: &str) -> Result { + #fn_body + } } - } - }) - }; + }) + }; let simple_type_visitor = |simple_type| { let field_type = get_simple_type_token(&simple_type); @@ -169,7 +171,7 @@ fn build_unnamed_field_visitors(fields: &syn::FieldsUnnamed) -> TokenStream { .collect(); make_visitor( - &Ident::new("visit_str", Span::call_site()), + "e! { visit_str }, "e! { #struct_name }, "e! { let content = "<".to_string() + #struct_id + ">" + v + ""; @@ -200,7 +202,7 @@ fn build_unnamed_visitor_calls( .iter() .enumerate() .map(|(idx, field)| { - let visitor_label = Ident::new(&format!("__Visitor_{}", idx), Span::call_site()); + let visitor_label = Ident::new(&format!("__Visitor_{}", idx), field.span()); let call_simple_type_visitor = |simple_type, action| { let field_type = get_simple_type_token(&simple_type); diff --git a/yaserde_derive/src/de/expand_struct.rs b/yaserde_derive/src/de/expand_struct.rs index 44faa44..f18664f 100644 --- a/yaserde_derive/src/de/expand_struct.rs +++ b/yaserde_derive/src/de/expand_struct.rs @@ -4,6 +4,7 @@ use field_type::*; use proc_macro2::{Span, TokenStream}; use quote::ToTokens; use std::collections::BTreeMap; +use syn::spanned::Spanned; use syn::DataStruct; use syn::Ident; @@ -34,7 +35,7 @@ pub fn parse( let label = &get_value_label(&field.ident); let field_attrs = YaSerdeAttribute::parse(&field.attrs); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeStruct { struct_name } => build_default_value( label, "e! {#struct_name}, @@ -43,7 +44,7 @@ pub fn parse( ), FieldType::FieldTypeOption { .. } => { if let Some(d) = &field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { #[allow(unused_mut, non_snake_case, non_camel_case_types)] @@ -100,16 +101,16 @@ pub fn parse( .rename .unwrap_or_else(|| field.ident.as_ref().unwrap().to_string()); - let visitor_label = build_visitor_ident(&label_name, None); + let visitor_label = build_visitor_ident(&label_name, field.span(), None); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeStruct { struct_name } => { let struct_id: String = struct_name .segments .iter() .map(|s| s.ident.to_string()) .collect(); - let struct_ident = build_visitor_ident(&label_name, Some(&struct_id)); + let struct_ident = build_visitor_ident(&label_name, field.span(), Some(&struct_id)); Some(quote! { #[allow(non_snake_case, non_camel_case_types)] @@ -129,7 +130,7 @@ pub fn parse( FieldType::FieldTypeStruct { ref struct_name } => { let struct_ident = Ident::new( &format!("{}", struct_name.into_token_stream()), - Span::call_site(), + field.span(), ); Some(quote! { #[allow(non_snake_case, non_camel_case_types)] @@ -150,7 +151,7 @@ pub fn parse( FieldType::FieldTypeStruct { ref struct_name } => { let struct_ident = Ident::new( &format!("{}", struct_name.into_token_stream()), - Span::call_site(), + field.span(), ); Some(quote! { #[allow(non_snake_case, non_camel_case_types)] @@ -194,7 +195,7 @@ pub fn parse( .clone() .unwrap_or_else(|| label.as_ref().unwrap().to_string()); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeStruct { struct_name } => Some(quote! { #label_name => { reader.set_map_value(); @@ -213,7 +214,7 @@ pub fn parse( FieldType::FieldTypeStruct { ref struct_name } => { let struct_ident = Ident::new( &format!("{}", struct_name.into_token_stream()), - Span::call_site(), + field.span(), ); Some(quote! { #label_name => { @@ -238,13 +239,14 @@ pub fn parse( &field_attrs, label, &namespaces, + field.span(), ), }, FieldType::FieldTypeVec { data_type } => match *data_type { FieldType::FieldTypeStruct { ref struct_name } => { let struct_ident = Ident::new( &format!("{}", struct_name.into_token_stream()), - Span::call_site(), + field.span(), ); Some(quote! { #label_name => { @@ -269,6 +271,7 @@ pub fn parse( &field_attrs, label, &namespaces, + field.span(), ), }, simple_type => build_call_visitor( @@ -278,6 +281,7 @@ pub fn parse( &field_attrs, label, &namespaces, + field.span(), ), }) }) @@ -299,9 +303,9 @@ pub fn parse( .rename .unwrap_or_else(|| field.ident.as_ref().unwrap().to_string()); - let visitor_label = build_visitor_ident(&label_name, None); + let visitor_label = build_visitor_ident(&label_name, field.span(), None); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeString => Some(quote! { for attr in attributes { if attr.name.local_name == #label_name { @@ -332,7 +336,7 @@ pub fn parse( label_name, struct_name.into_token_stream() ), - Span::call_site(), + field.span(), ); Some(quote! { @@ -371,7 +375,7 @@ pub fn parse( let label = &get_value_label(&field.ident); let field_attrs = YaSerdeAttribute::parse(&field.attrs); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeString => { build_set_text_to_value(&field_attrs, label, "e! {text_content.to_owned()}) } @@ -475,7 +479,7 @@ pub fn parse( fn build_declare_visitor( field_type: &TokenStream, - visitor: &Ident, + visitor: &TokenStream, visitor_label: &Ident, ) -> Option { Some(quote! { @@ -493,11 +497,12 @@ fn build_declare_visitor( fn build_call_visitor( field_type: &TokenStream, - visitor: &Ident, + visitor: &TokenStream, action: &TokenStream, field_attrs: &YaSerdeAttribute, label: &Option, namespaces: &BTreeMap, + span: Span, ) -> Option { let prefix = field_attrs.prefix.clone(); @@ -508,7 +513,7 @@ fn build_call_visitor( .clone() .unwrap_or_else(|| label.as_ref().unwrap().to_string()); - let visitor_label = build_visitor_ident(&label_name, None); + let visitor_label = build_visitor_ident(&label_name, span, None); let namespaces_matches: TokenStream = namespaces .iter() @@ -562,7 +567,7 @@ fn build_call_visitor_for_attribute( label: &Option, label_name: &str, action: &TokenStream, - visitor: &Ident, + visitor: &TokenStream, visitor_label: &Ident, ) -> Option { Some(quote! { @@ -598,13 +603,13 @@ fn get_value_label(ident: &Option) -> Option { .map(|ident| syn::Ident::new(&format!("__{}_value", ident.to_string()), ident.span())) } -fn build_visitor_ident(label: &str, struct_id: Option<&str>) -> Ident { +fn build_visitor_ident(label: &str, span: Span, struct_id: Option<&str>) -> Ident { Ident::new( &format!( "__Visitor_{}_{}", label.replace(".", "_"), struct_id.unwrap_or("") ), - Span::call_site(), + span, ) } diff --git a/yaserde_derive/src/de/mod.rs b/yaserde_derive/src/de/mod.rs index 617df1f..455303b 100644 --- a/yaserde_derive/src/de/mod.rs +++ b/yaserde_derive/src/de/mod.rs @@ -3,7 +3,7 @@ pub mod expand_enum; pub mod expand_struct; use attribute; -use proc_macro2::{Span, TokenStream}; +use proc_macro2::TokenStream; use syn; use syn::Ident; @@ -29,10 +29,7 @@ pub fn expand_derive_deserialize(ast: &syn::DeriveInput) -> Result unimplemented!(), }; - let dummy_const = Ident::new( - &format!("_IMPL_YA_DESERIALIZE_FOR_{}", name), - Span::call_site(), - ); + let dummy_const = Ident::new(&format!("_IMPL_YA_DESERIALIZE_FOR_{}", name), name.span()); let generated = quote! { #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] diff --git a/yaserde_derive/src/field_type.rs b/yaserde_derive/src/field_type.rs index 8f563ea..fb245b8 100644 --- a/yaserde_derive/src/field_type.rs +++ b/yaserde_derive/src/field_type.rs @@ -92,11 +92,13 @@ pub fn get_simple_type_token(field_type: &FieldType) -> proc_macro2::TokenStream } } -pub fn get_simple_type_visitor(field_type: &FieldType) -> syn::Ident { - format_ident!( +pub fn get_simple_type_visitor(field_type: &FieldType) -> proc_macro2::TokenStream { + let ident = format_ident!( "visit_{}", get_simple_type_token(field_type) .to_string() .replace("String", "str") - ) + ); + + quote! {#ident} } diff --git a/yaserde_derive/src/ser/element.rs b/yaserde_derive/src/ser/element.rs index aa53b94..69a77c1 100644 --- a/yaserde_derive/src/ser/element.rs +++ b/yaserde_derive/src/ser/element.rs @@ -50,7 +50,13 @@ pub fn serialize_element( let inner = enclose_characters(label, label_name); if let Some(ref d) = default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new( + &d, + label + .as_ref() + .map_or(Span::call_site(), |ident| ident.span()), + ); + Some(quote! { if self.#label != #default_function() { #inner diff --git a/yaserde_derive/src/ser/expand_enum.rs b/yaserde_derive/src/ser/expand_enum.rs index 3fc1d41..dadd224 100644 --- a/yaserde_derive/src/ser/expand_enum.rs +++ b/yaserde_derive/src/ser/expand_enum.rs @@ -1,7 +1,8 @@ use attribute::*; use field_type::*; -use proc_macro2::{Span, TokenStream}; +use proc_macro2::TokenStream; use std::collections::BTreeMap; +use syn::spanned::Spanned; use syn::DataEnum; use syn::Fields; use syn::Ident; @@ -53,7 +54,7 @@ pub fn serialize( } let renamed_field_label = match field_attrs.rename { - Some(value) => Some(Ident::new(&value.replace("\"", ""), Span::call_site())), + Some(value) => Some(Ident::new(&value.replace("\"", ""), field.span())), None => field.ident.clone(), }; let field_label_name = renamed_field_label.unwrap().to_string(); diff --git a/yaserde_derive/src/ser/expand_struct.rs b/yaserde_derive/src/ser/expand_struct.rs index 470151f..0ecd409 100644 --- a/yaserde_derive/src/ser/expand_struct.rs +++ b/yaserde_derive/src/ser/expand_struct.rs @@ -1,8 +1,9 @@ use attribute::*; use field_type::*; -use proc_macro2::{Span, TokenStream}; +use proc_macro2::TokenStream; use std::collections::BTreeMap; use std::string::ToString; +use syn::spanned::Spanned; use syn::DataStruct; use syn::Ident; @@ -27,7 +28,7 @@ pub fn serialize( let label_name = build_label_name(&field, &field_attrs); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeString | FieldType::FieldTypeBool | FieldType::FieldTypeI8 @@ -41,7 +42,7 @@ pub fn serialize( | FieldType::FieldTypeF32 | FieldType::FieldTypeF64 => { if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { let struct_start_event = if self.#label != #default_function() { @@ -75,7 +76,7 @@ pub fn serialize( FieldType::FieldTypeOption { data_type } => match *data_type { FieldType::FieldTypeString => { if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { let struct_start_event = if self.#label != #default_function() { @@ -111,7 +112,7 @@ pub fn serialize( | FieldType::FieldTypeF32 | FieldType::FieldTypeF64 => { if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { let struct_start_event = if self.#label != #default_function() { @@ -152,11 +153,11 @@ pub fn serialize( } } FieldType::FieldTypeVec { .. } => { - let item_ident = Ident::new("yas_item", Span::call_site()); + let item_ident = Ident::new("yas_item", field.span()); let inner = enclose_formatted_characters(&item_ident, label_name); if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { if self.#label != #default_function() { @@ -179,7 +180,7 @@ pub fn serialize( }, FieldType::FieldTypeStruct { .. } => { if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { let struct_start_event = if self.#label != #default_function() { @@ -253,7 +254,7 @@ pub fn serialize( let label_name = build_label_name(&field, &field_attrs); - get_field_type(field).and_then(|field| match field { + get_field_type(field).and_then(|f| match f { FieldType::FieldTypeString | FieldType::FieldTypeBool | FieldType::FieldTypeI8 @@ -279,11 +280,11 @@ pub fn serialize( | FieldType::FieldTypeU64 | FieldType::FieldTypeF32 | FieldType::FieldTypeF64 => { - let item_ident = Ident::new("yas_item", Span::call_site()); + let item_ident = Ident::new("yas_item", field.span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { if self.#label != #default_function() { @@ -301,11 +302,11 @@ pub fn serialize( } } FieldType::FieldTypeVec { .. } => { - let item_ident = Ident::new("yas_item", Span::call_site()); + let item_ident = Ident::new("yas_item", field.span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); if let Some(ref d) = field_attrs.default { - let default_function = Ident::new(&d, Span::call_site()); + let default_function = Ident::new(&d, field.span()); Some(quote! { if self.#label != #default_function() { @@ -342,7 +343,7 @@ pub fn serialize( }), FieldType::FieldTypeVec { data_type } => match *data_type { FieldType::FieldTypeString => { - let item_ident = Ident::new("yas_item", Span::call_site()); + let item_ident = Ident::new("yas_item", field.span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); Some(quote! { @@ -362,7 +363,7 @@ pub fn serialize( | FieldType::FieldTypeU64 | FieldType::FieldTypeF32 | FieldType::FieldTypeF64 => { - let item_ident = Ident::new("yas_item", Span::call_site()); + let item_ident = Ident::new("yas_item", field.span()); let inner = enclose_formatted_characters_for_value(&item_ident, label_name); Some(quote! { diff --git a/yaserde_derive/src/ser/mod.rs b/yaserde_derive/src/ser/mod.rs index edeabfe..ff8ecff 100644 --- a/yaserde_derive/src/ser/mod.rs +++ b/yaserde_derive/src/ser/mod.rs @@ -3,7 +3,7 @@ pub mod expand_enum; pub mod expand_struct; use attribute; -use proc_macro2::{Span, TokenStream}; +use proc_macro2::TokenStream; use syn; use syn::Ident; @@ -31,10 +31,7 @@ pub fn expand_derive_serialize(ast: &syn::DeriveInput) -> Result unimplemented!(), }; - let dummy_const = Ident::new( - &format!("_IMPL_YA_SERIALIZE_FOR_{}", name), - Span::call_site(), - ); + let dummy_const = Ident::new(&format!("_IMPL_YA_SERIALIZE_FOR_{}", name), name.span()); let generated = quote! { #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]