Just realized I can just serialize the tokenstream :)

This commit is contained in:
Thelie 2022-03-02 18:14:48 +01:00
parent be39277042
commit 2d2602b057
4 changed files with 272 additions and 44 deletions

View file

@ -22,4 +22,4 @@ bench = false
[dependencies] [dependencies]
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
syn = { version = "1.0", features = ["full"] } syn = { version = "1.0", features = ["full"] }
proc-macro2 = "1.0"

View file

@ -79,7 +79,6 @@ pub fn my_derive(input: proc_macro::TokenStream, annotated_item: proc_macro::To
let trait_state = load_trait_state().unwrap(); let trait_state = load_trait_state().unwrap();
save_trait_state(trait_state).unwrap(); save_trait_state(trait_state).unwrap();
// Build the output, possibly using quasi-quotation // Build the output, possibly using quasi-quotation

View file

@ -1,20 +1,20 @@
use core::fmt::Debug; use core::fmt::Debug;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use serde_wrapper::ImplItemMethodWrapper; use serde_wrapper::TokenStreamWrapper;
mod serde_wrapper; mod serde_wrapper;
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
struct TraitProfile{ struct TraitProfile{
//functions: HashMap<String, FunctionProfile>, //functions: HashMap<String, FunctionProfile>,
functions: Vec<ImplItemMethodWrapper>, functions: Vec<TokenStreamWrapper>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum DeduplicatedFunctionProfile { enum DeduplicatedFunctionProfile {
Single(String, ImplItemMethodWrapper), Single(String, TokenStreamWrapper),
Multiple(Vec<String>, ImplItemMethodWrapper), Multiple(Vec<String>, TokenStreamWrapper),
} }
/*impl<T> Evaluator<T> { /*impl<T> Evaluator<T> {

View file

@ -1,5 +1,6 @@
use serde::{Serialize, Deserialize, Serializer, Deserializer, ser::SerializeStruct}; use proc_macro2::TokenStream;
use syn::{ImplItemMethod, Visibility, Signature, Pat, FnArg, Type, PatIdent, Ident, __private::Span, Receiver, ReturnType, Generics}; use serde::{Serialize, Deserialize, Serializer, Deserializer, ser::{SerializeStruct, SerializeTupleVariant, SerializeStructVariant}};
use syn::{ImplItemMethod, Visibility, Signature, Pat, FnArg, Type, PatIdent, Ident, __private::{Span, ToTokens}, Receiver, ReturnType, Generics, GenericParam, QSelf, Path, Lifetime, TraitBound, TypeParamBound};
use core::fmt::{Debug, Formatter}; use core::fmt::{Debug, Formatter};
use std::error::Error; use std::error::Error;
@ -45,22 +46,15 @@ impl Serialize for VisibilityWrapper<'_> {
S: Serializer S: Serializer
{ {
match &self.0 { match &self.0 {
Visibility::Public(_) => serializer.serialize_str("pub"), Visibility::Public(_) => serializer.serialize_unit_variant("Visibility", 0, "Pub"),
Visibility::Crate(_) => serializer.serialize_str("crate"), Visibility::Crate(_) => serializer.serialize_unit_variant("Visibility", 1, "Crate"),
Visibility::Restricted(r) => { Visibility::Restricted(r) => serializer.serialize_newtype_variant(
let mut path_str = String::from(""); "Visibility",
2,
for seg in &r.path.segments { "Restricted",
// There should be no arguments in the paths passed here. &PathWrapper(*r.path),
path_str.push_str(seg.ident.to_string().as_str()); ),
path_str.push_str("::"); Visibility::Inherited => serializer.serialize_unit_variant("Visibility", 3, "Inherited"),
}
serializer.serialize_str(
format!("pub ({})", path_str).as_str()
)
},
Visibility::Inherited => serializer.serialize_str("inherited"),
} }
} }
} }
@ -104,13 +98,13 @@ impl Serialize for SignatureWrapper<'_> {
}?; }?;
// No need to serialize the Fn token // No need to serialize the Fn token
state.serialize_field("ident", &inner.ident.to_string()); state.serialize_field("ident", &inner.ident.to_string())?;
state.serialize_field("generics", &GenericsWrapper(&inner.generics)); state.serialize_field("generics", &GenericsWrapper(inner.generics))?;
// Parentheses do not need to be serialized either // Parentheses do not need to be serialized either
serialize_iterator( serialize_iterator_struct(
&mut state, &mut state,
Box::new(inner Box::new(inner
.inputs .inputs
@ -129,25 +123,46 @@ impl Serialize for SignatureWrapper<'_> {
state.serialize_field("variadic", match inner.variadic{ state.serialize_field("variadic", match inner.variadic{
Some(_) => "...", Some(_) => "...",
None => "", None => "",
}); })?;
match &inner.output{ match &inner.output{
ReturnType::Default => {state.serialize_field("output", "()");}, ReturnType::Default => {state.serialize_field("output", "()")?;},
ReturnType::Type(_, t) => {(state.serialize_field("output", &TypeWrapper(*t.clone())));} ReturnType::Type(_, t) => {(state.serialize_field("output", &TypeWrapper(*t.clone())))?;}
}; };
state.end() state.end()
} }
} }
struct GenericsWrapper<'a>(&'a Generics); struct GenericsWrapper(Generics);
impl Serialize for GenericsWrapper<'_> { impl Serialize for GenericsWrapper {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error> fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where where
S: Serializer S: Serializer
{ {
todo!() todo!()
/*let inner = &self.0;
let mut state = serializer.serialize_struct("Signature", 7)?;
serialize_iterator(
&mut state,
Box::new(inner
.params
.clone()
.into_iter()
),
"params",
| inp: &GenericParam | -> Result<(PatWrapper, Option<TypeWrapper>), Box<dyn Error>> {
match inp {
GenericParam::Type(t) => t,
GenericParam::Lifetime() => {},
GenericParam::Const() => {},
}
}
);
state.end()*/
} }
} }
@ -158,7 +173,106 @@ impl Serialize for PatWrapper {
where where
S: Serializer S: Serializer
{ {
todo!() let inner = &self.0;
match inner {
Pat::Box(b) => serializer.serialize_newtype_variant("Pat", 0, "Box", &PatWrapper(*b.pat.clone())),
Pat::Ident(i) => {
let mut state = serializer.serialize_struct_variant("Pat", 1, "Ident", 4)?;
if i.by_ref.is_some() {
state.serialize_field("by_ref", &Some(String::from("ref")));
} else {
state.serialize_field("by_ref", &None::<String>);
}
if i.mutability.is_some() {
state.serialize_field("mutability", &Some(String::from("mut")));
} else {
state.serialize_field("mutability", &None::<String>);
}
state.serialize_field("ident", &i.ident.to_string());
if let Some((_, s)) = &i.subpat {
state.serialize_field("subpat", &PatWrapper(*s.clone()));
} else {
state.serialize_field("subpat", &None::<PatWrapper>);
}
state.end()
}
Pat::Path(p) => {
let mut state = serializer.serialize_struct_variant("Pat", 5, "Path", 2)?;
if let Some(q) = &p.qself {
state.serialize_field("QSelf", &Some(QSelfWrapper(q.clone())));
} else {
state.serialize_field("QSelf", &None::<QSelfWrapper>);
}
state.serialize_field("Path", &PathWrapper(p.path.clone()));
state.end()
}
Pat::Reference(r) => {
let mut state = serializer.serialize_struct_variant("Pat", 7, "Reference", 2)?;
if r.mutability.is_some() {
state.serialize_field("mutability", &Some(String::from("mut")));
} else {
state.serialize_field("mutability", &None::<String>);
}
state.serialize_field("pat", &PatWrapper(*r.pat.clone()));
state.end()
}
Pat::Slice(s) => {
let mut state = serializer.serialize_struct_variant("Pat", 9, "Slice", 1)?;
serialize_iterator_struct_variant(
&mut state,
Box::new(
s.elems
.clone()
.into_iter()
),
"elems",
|p: &Pat| -> Result<PatWrapper, Box<dyn Error>> {Ok(PatWrapper(p.clone()))}
);
state.end()
}
Pat::Tuple(t) => {
let mut state = serializer.serialize_struct_variant("Pat", 11, "Tuple", 1)?;
serialize_iterator_struct_variant(
&mut state,
Box::new(
t.elems
.clone()
.into_iter()
),
"elems",
|p: &Pat| -> Result<PatWrapper, Box<dyn Error>> {Ok(PatWrapper(p.clone()))}
);
state.end()
}
Pat::Type(t) => {
let mut state = serializer.serialize_struct_variant("Pat", 13, "Type", 2)?;
state.serialize_field("pat", &PatWrapper(*t.pat.clone()));
state.serialize_field("ty", &TypeWrapper(*t.ty.clone()));
state.end()
}
Pat::Verbatim(t) => serializer.serialize_newtype_variant("Pat", 14, "Verbatim", &t.to_string()),
Pat::Wild(_) => serializer.serialize_unit_variant("Pat", 15, "Wild"),
// The rest can't be used in function arguments.
_ => unimplemented!()
}
} }
} }
@ -169,30 +283,128 @@ impl Serialize for TypeWrapper {
where where
S: Serializer S: Serializer
{ {
let inner = &self.0;
match inner {
Type::Array(a) => {
let mut state = serializer.serialize_struct_variant("Pat", 0, "Type", 2)?;
state.serialize_field("elem", &TypeWrapper(*a.elem.clone()));
// TODO: this is somewhat inelegant:
state.serialize_field("len", &a.len.to_token_stream().to_string());
state.end()
}
Type::Group(g) => serializer.serialize_newtype_variant("Type", 2, "Group", &TypeWrapper(*g.elem.clone())),
Type::ImplTrait(t) => {
let mut state = serializer.serialize_struct_variant("Pat", 11, "Tuple", 1)?;
serialize_iterator_struct_variant(
&mut state,
Box::new(
t.bounds
.clone()
.into_iter()
),
"elems",
|p: &TypeParamBound| -> Result<PatWrapper, Box<dyn Error>> {Ok(PatWrapper(p.clone()))}
);
state.end()
}
// The rest can't be used in function arguments.
_ => unimplemented!()
}
}
}
struct PathWrapper(Path);
impl Serialize for PathWrapper {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer
{
/*let mut path_str = String::from("");
for seg in &r.path.segments {
// There should be no arguments in the paths passed here.
path_str.push_str(seg.ident.to_string().as_str());
path_str.push_str("::");
}
serializer.serialize_str(
format!("pub ({})", path_str).as_str()
)*/
todo!() todo!()
} }
} }
struct QSelfWrapper(QSelf);
impl Serialize for QSelfWrapper {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer
{
todo!()
}
}
struct LifetimeWrapper(Lifetime);
impl Serialize for LifetimeWrapper {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer
{
let inner = &self.0;
serializer.serialize_newtype_struct("Lifetime", &inner.ident.to_string())
}
}
pub struct TokenStreamWrapper(TokenStream);
impl Serialize for TokenStreamWrapper {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer
{
let inner = &self.0;
serializer.serialize_newtype_struct("Lifetime", &inner.to_string())
}
}
struct TraitBoundWrapper(TraitBound);
impl Serialize for TraitBoundWrapper {
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where
S: Serializer
{
let inner = &self.0;
todo!();
}
}
fn patopt_from_receiver(r: Receiver) -> (PatWrapper, Option<TypeWrapper>) { fn patopt_from_receiver(r: Receiver) -> (PatWrapper, Option<TypeWrapper>) {
let mut ident = String::from(""); let mut ident = String::from("");
match &r.reference { if let Some((_, lt)) = &r.reference {
Some((_, lt)) => { ident.push('&');
ident.push_str("&");
match lt { match lt {
Some(l) => ident.push_str( Some(l) => ident.push_str(
&l.ident l.ident
.to_string() .to_string()
.as_str() .as_str()
), ),
None => {}, None => {},
} }
ident.push_str(" "); ident.push(' ');
}, }
None => {},
}
(PatWrapper(Pat::Ident(PatIdent{ (PatWrapper(Pat::Ident(PatIdent{
attrs: vec!(), attrs: vec!(),
@ -203,16 +415,33 @@ fn patopt_from_receiver(r: Receiver) -> (PatWrapper, Option<TypeWrapper>) {
})), None) })), None)
} }
fn serialize_iterator<S, T, F, U> (serializer: &mut S, iterator: Box<dyn Iterator<Item = T>>, field_name: &'static str, get_string_fun: F) fn serialize_iterator_struct<S, T, F, U> (serializer: &mut S, iterator: Box<dyn Iterator<Item = T>>, field_name: &'static str, item_fun: F)
-> Result<(), Box<dyn Error>> -> Result<(), Box<dyn Error>>
where where
F: Fn(&T) -> Result<U, Box<dyn Error>>, F: Fn(&T) -> Result<U, Box<dyn Error>>,
S: SerializeStruct, S: SerializeStruct ,
U: Serialize, U: Serialize,
{ {
let mut p_vec = vec!(); let mut p_vec = vec!();
for item in iterator { for item in iterator {
p_vec.push(get_string_fun(&item)?); p_vec.push(item_fun(&item)?);
}
serializer.serialize_field(field_name, &p_vec);
Ok(())
}
// Thanks to weird traits in Serde we need to duplicate code here…
// TODO: Maybe to this as a macro
fn serialize_iterator_struct_variant<S, T, F, U> (serializer: &mut S, iterator: Box<dyn Iterator<Item = T>>, field_name: &'static str, item_fun: F)
-> Result<(), Box<dyn Error>>
where
F: Fn(&T) -> Result<U, Box<dyn Error>>,
S: SerializeStructVariant ,
U: Serialize,
{
let mut p_vec = vec!();
for item in iterator {
p_vec.push(item_fun(&item)?);
} }
serializer.serialize_field(field_name, &p_vec); serializer.serialize_field(field_name, &p_vec);
Ok(()) Ok(())