mirror of
https://github.com/serde-rs/serde.git
synced 2025-10-02 23:35:26 +00:00
Remove dependency on syn/visit-mut feature
This commit is contained in:
parent
1f423580a5
commit
e5efb6ad93
@ -22,7 +22,7 @@ proc-macro = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = { version = "1.0.60", features = ["visit-mut"] }
|
syn = "1.0.60"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde = { version = "1.0", path = "../serde" }
|
serde = { version = "1.0", path = "../serde" }
|
||||||
|
@ -3,8 +3,10 @@ use proc_macro2::Span;
|
|||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use syn::punctuated::Punctuated;
|
use syn::punctuated::Punctuated;
|
||||||
use syn::visit_mut::{self, VisitMut};
|
use syn::{
|
||||||
use syn::{parse_quote, DeriveInput, ExprPath, Path, PathArguments, QSelf, Type, TypePath};
|
parse_quote, Data, DeriveInput, Expr, ExprPath, GenericArgument, GenericParam, Generics, Macro,
|
||||||
|
Path, PathArguments, QSelf, ReturnType, Type, TypeParamBound, TypePath, WherePredicate,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn replace_receiver(input: &mut DeriveInput) {
|
pub fn replace_receiver(input: &mut DeriveInput) {
|
||||||
let self_ty = {
|
let self_ty = {
|
||||||
@ -68,7 +70,7 @@ impl ReplaceReceiver<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VisitMut for ReplaceReceiver<'_> {
|
impl ReplaceReceiver<'_> {
|
||||||
// `Self` -> `Receiver`
|
// `Self` -> `Receiver`
|
||||||
fn visit_type_mut(&mut self, ty: &mut Type) {
|
fn visit_type_mut(&mut self, ty: &mut Type) {
|
||||||
let span = if let Type::Path(node) = ty {
|
let span = if let Type::Path(node) = ty {
|
||||||
@ -79,7 +81,7 @@ impl VisitMut for ReplaceReceiver<'_> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
visit_mut::visit_type_mut(self, ty);
|
self.visit_type_mut_impl(ty);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
*ty = self.self_ty(span).into();
|
*ty = self.self_ty(span).into();
|
||||||
@ -90,7 +92,7 @@ impl VisitMut for ReplaceReceiver<'_> {
|
|||||||
if ty.qself.is_none() {
|
if ty.qself.is_none() {
|
||||||
self.self_to_qself(&mut ty.qself, &mut ty.path);
|
self.self_to_qself(&mut ty.qself, &mut ty.path);
|
||||||
}
|
}
|
||||||
visit_mut::visit_type_path_mut(self, ty);
|
self.visit_type_path_mut_impl(ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// `Self::method` -> `<Receiver>::method`
|
// `Self::method` -> `<Receiver>::method`
|
||||||
@ -98,6 +100,188 @@ impl VisitMut for ReplaceReceiver<'_> {
|
|||||||
if expr.qself.is_none() {
|
if expr.qself.is_none() {
|
||||||
self.self_to_qself(&mut expr.qself, &mut expr.path);
|
self.self_to_qself(&mut expr.qself, &mut expr.path);
|
||||||
}
|
}
|
||||||
visit_mut::visit_expr_path_mut(self, expr);
|
self.visit_expr_path_mut_impl(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everything below is simply traversing the syntax tree.
|
||||||
|
|
||||||
|
fn visit_type_mut_impl(&mut self, ty: &mut Type) {
|
||||||
|
match ty {
|
||||||
|
Type::Array(ty) => {
|
||||||
|
self.visit_type_mut(&mut ty.elem);
|
||||||
|
self.visit_expr_mut(&mut ty.len);
|
||||||
|
}
|
||||||
|
Type::BareFn(ty) => {
|
||||||
|
for arg in &mut ty.inputs {
|
||||||
|
self.visit_type_mut(&mut arg.ty);
|
||||||
|
}
|
||||||
|
self.visit_return_type_mut(&mut ty.output);
|
||||||
|
}
|
||||||
|
Type::Group(ty) => self.visit_type_mut(&mut ty.elem),
|
||||||
|
Type::ImplTrait(ty) => {
|
||||||
|
for bound in &mut ty.bounds {
|
||||||
|
self.visit_type_param_bound_mut(bound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Type::Macro(ty) => self.visit_macro_mut(&mut ty.mac),
|
||||||
|
Type::Paren(ty) => self.visit_type_mut(&mut ty.elem),
|
||||||
|
Type::Path(ty) => {
|
||||||
|
if let Some(qself) = &mut ty.qself {
|
||||||
|
self.visit_type_mut(&mut qself.ty);
|
||||||
|
}
|
||||||
|
self.visit_path_mut(&mut ty.path);
|
||||||
|
}
|
||||||
|
Type::Ptr(ty) => self.visit_type_mut(&mut ty.elem),
|
||||||
|
Type::Reference(ty) => self.visit_type_mut(&mut ty.elem),
|
||||||
|
Type::Slice(ty) => self.visit_type_mut(&mut ty.elem),
|
||||||
|
Type::TraitObject(ty) => {
|
||||||
|
for bound in &mut ty.bounds {
|
||||||
|
self.visit_type_param_bound_mut(bound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Type::Tuple(ty) => {
|
||||||
|
for elem in &mut ty.elems {
|
||||||
|
self.visit_type_mut(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Type::Infer(_) | Type::Never(_) | Type::Verbatim(_) => {}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
Type::__TestExhaustive(_) => unimplemented!(),
|
||||||
|
#[cfg(not(test))]
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_type_path_mut_impl(&mut self, ty: &mut TypePath) {
|
||||||
|
if let Some(qself) = &mut ty.qself {
|
||||||
|
self.visit_type_mut(&mut qself.ty);
|
||||||
|
}
|
||||||
|
self.visit_path_mut(&mut ty.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_expr_path_mut_impl(&mut self, expr: &mut ExprPath) {
|
||||||
|
if let Some(qself) = &mut expr.qself {
|
||||||
|
self.visit_type_mut(&mut qself.ty);
|
||||||
|
}
|
||||||
|
self.visit_path_mut(&mut expr.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_path_mut(&mut self, path: &mut Path) {
|
||||||
|
for segment in &mut path.segments {
|
||||||
|
self.visit_path_arguments_mut(&mut segment.arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_path_arguments_mut(&mut self, arguments: &mut PathArguments) {
|
||||||
|
match arguments {
|
||||||
|
PathArguments::None => {}
|
||||||
|
PathArguments::AngleBracketed(arguments) => {
|
||||||
|
for arg in &mut arguments.args {
|
||||||
|
match arg {
|
||||||
|
GenericArgument::Type(arg) => self.visit_type_mut(arg),
|
||||||
|
GenericArgument::Binding(arg) => self.visit_type_mut(&mut arg.ty),
|
||||||
|
GenericArgument::Lifetime(_)
|
||||||
|
| GenericArgument::Constraint(_)
|
||||||
|
| GenericArgument::Const(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PathArguments::Parenthesized(arguments) => {
|
||||||
|
for argument in &mut arguments.inputs {
|
||||||
|
self.visit_type_mut(argument);
|
||||||
|
}
|
||||||
|
self.visit_return_type_mut(&mut arguments.output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_return_type_mut(&mut self, return_type: &mut ReturnType) {
|
||||||
|
match return_type {
|
||||||
|
ReturnType::Default => {}
|
||||||
|
ReturnType::Type(_, output) => self.visit_type_mut(output),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_type_param_bound_mut(&mut self, bound: &mut TypeParamBound) {
|
||||||
|
match bound {
|
||||||
|
TypeParamBound::Trait(bound) => self.visit_path_mut(&mut bound.path),
|
||||||
|
TypeParamBound::Lifetime(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_generics_mut(&mut self, generics: &mut Generics) {
|
||||||
|
for param in &mut generics.params {
|
||||||
|
match param {
|
||||||
|
GenericParam::Type(param) => {
|
||||||
|
for bound in &mut param.bounds {
|
||||||
|
self.visit_type_param_bound_mut(bound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GenericParam::Lifetime(_) | GenericParam::Const(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(where_clause) = &mut generics.where_clause {
|
||||||
|
for predicate in &mut where_clause.predicates {
|
||||||
|
match predicate {
|
||||||
|
WherePredicate::Type(predicate) => {
|
||||||
|
self.visit_type_mut(&mut predicate.bounded_ty);
|
||||||
|
for bound in &mut predicate.bounds {
|
||||||
|
self.visit_type_param_bound_mut(bound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WherePredicate::Lifetime(_) | WherePredicate::Eq(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_data_mut(&mut self, data: &mut Data) {
|
||||||
|
match data {
|
||||||
|
Data::Struct(data) => {
|
||||||
|
for field in &mut data.fields {
|
||||||
|
self.visit_type_mut(&mut field.ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Data::Enum(data) => {
|
||||||
|
for variant in &mut data.variants {
|
||||||
|
for field in &mut variant.fields {
|
||||||
|
self.visit_type_mut(&mut field.ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Data::Union(_) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_expr_mut(&mut self, expr: &mut Expr) {
|
||||||
|
match expr {
|
||||||
|
Expr::Binary(expr) => {
|
||||||
|
self.visit_expr_mut(&mut expr.left);
|
||||||
|
self.visit_expr_mut(&mut expr.right);
|
||||||
|
}
|
||||||
|
Expr::Call(expr) => {
|
||||||
|
self.visit_expr_mut(&mut expr.func);
|
||||||
|
for arg in &mut expr.args {
|
||||||
|
self.visit_expr_mut(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expr::Cast(expr) => {
|
||||||
|
self.visit_expr_mut(&mut expr.expr);
|
||||||
|
self.visit_type_mut(&mut expr.ty);
|
||||||
|
}
|
||||||
|
Expr::Field(expr) => self.visit_expr_mut(&mut expr.base),
|
||||||
|
Expr::Index(expr) => {
|
||||||
|
self.visit_expr_mut(&mut expr.expr);
|
||||||
|
self.visit_expr_mut(&mut expr.index);
|
||||||
|
}
|
||||||
|
Expr::Paren(expr) => self.visit_expr_mut(&mut expr.expr),
|
||||||
|
Expr::Path(expr) => self.visit_expr_path_mut(expr),
|
||||||
|
Expr::Unary(expr) => self.visit_expr_mut(&mut expr.expr),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_macro_mut(&mut self, _mac: &mut Macro) {}
|
||||||
|
}
|
||||||
|
@ -16,7 +16,7 @@ path = "lib.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = { version = "1.0.60", default-features = false, features = ["derive", "parsing", "printing", "clone-impls", "visit-mut"] }
|
syn = { version = "1.0.60", default-features = false, features = ["derive", "parsing", "printing", "clone-impls"] }
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
targets = ["x86_64-unknown-linux-gnu"]
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user