Use actual spans instead of Span::call_site()

This commit is contained in:
Dmitry Samoylov 2020-02-04 19:56:22 +07:00
parent 65838ced80
commit f9e8d91590
9 changed files with 83 additions and 67 deletions

View File

@ -8,7 +8,12 @@ pub fn build_default_value(
default: &Option<String>,
) -> Option<TokenStream> {
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)]

View File

@ -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<Self::Value, String> {
#fn_body
fn #visitor(self, v: &str) -> Result<Self::Value, String> {
#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()),
&quote! { visit_str },
&quote! { #struct_name },
&quote! {
let content = "<".to_string() + #struct_id + ">" + v + "</" + #struct_id + ">";
@ -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);

View File

@ -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,
&quote! {#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, &quote! {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<TokenStream> {
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<Ident>,
namespaces: &BTreeMap<String, String>,
span: Span,
) -> Option<TokenStream> {
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<Ident>,
label_name: &str,
action: &TokenStream,
visitor: &Ident,
visitor: &TokenStream,
visitor_label: &Ident,
) -> Option<TokenStream> {
Some(quote! {
@ -598,13 +603,13 @@ fn get_value_label(ident: &Option<syn::Ident>) -> Option<syn::Ident> {
.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,
)
}

View File

@ -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<TokenStream,
syn::Data::Union(ref _data_union) => 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)]

View File

@ -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}
}

View File

@ -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

View File

@ -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();

View File

@ -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! {

View File

@ -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<TokenStream, St
syn::Data::Union(ref _data_union) => 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)]