17e2e9c0cSopenharmony_ciuse crate::internals::respan::respan; 27e2e9c0cSopenharmony_ciuse proc_macro2::Span; 37e2e9c0cSopenharmony_ciuse quote::ToTokens; 47e2e9c0cSopenharmony_ciuse std::mem; 57e2e9c0cSopenharmony_ciuse syn::punctuated::Punctuated; 67e2e9c0cSopenharmony_ciuse syn::{ 77e2e9c0cSopenharmony_ci parse_quote, Data, DeriveInput, Expr, ExprPath, GenericArgument, GenericParam, Generics, Macro, 87e2e9c0cSopenharmony_ci Path, PathArguments, QSelf, ReturnType, Token, Type, TypeParamBound, TypePath, WherePredicate, 97e2e9c0cSopenharmony_ci}; 107e2e9c0cSopenharmony_ci 117e2e9c0cSopenharmony_cipub fn replace_receiver(input: &mut DeriveInput) { 127e2e9c0cSopenharmony_ci let self_ty = { 137e2e9c0cSopenharmony_ci let ident = &input.ident; 147e2e9c0cSopenharmony_ci let ty_generics = input.generics.split_for_impl().1; 157e2e9c0cSopenharmony_ci parse_quote!(#ident #ty_generics) 167e2e9c0cSopenharmony_ci }; 177e2e9c0cSopenharmony_ci let mut visitor = ReplaceReceiver(&self_ty); 187e2e9c0cSopenharmony_ci visitor.visit_generics_mut(&mut input.generics); 197e2e9c0cSopenharmony_ci visitor.visit_data_mut(&mut input.data); 207e2e9c0cSopenharmony_ci} 217e2e9c0cSopenharmony_ci 227e2e9c0cSopenharmony_cistruct ReplaceReceiver<'a>(&'a TypePath); 237e2e9c0cSopenharmony_ci 247e2e9c0cSopenharmony_ciimpl ReplaceReceiver<'_> { 257e2e9c0cSopenharmony_ci fn self_ty(&self, span: Span) -> TypePath { 267e2e9c0cSopenharmony_ci let tokens = self.0.to_token_stream(); 277e2e9c0cSopenharmony_ci let respanned = respan(tokens, span); 287e2e9c0cSopenharmony_ci syn::parse2(respanned).unwrap() 297e2e9c0cSopenharmony_ci } 307e2e9c0cSopenharmony_ci 317e2e9c0cSopenharmony_ci fn self_to_qself(&self, qself: &mut Option<QSelf>, path: &mut Path) { 327e2e9c0cSopenharmony_ci if path.leading_colon.is_some() || path.segments[0].ident != "Self" { 337e2e9c0cSopenharmony_ci return; 347e2e9c0cSopenharmony_ci } 357e2e9c0cSopenharmony_ci 367e2e9c0cSopenharmony_ci if path.segments.len() == 1 { 377e2e9c0cSopenharmony_ci self.self_to_expr_path(path); 387e2e9c0cSopenharmony_ci return; 397e2e9c0cSopenharmony_ci } 407e2e9c0cSopenharmony_ci 417e2e9c0cSopenharmony_ci let span = path.segments[0].ident.span(); 427e2e9c0cSopenharmony_ci *qself = Some(QSelf { 437e2e9c0cSopenharmony_ci lt_token: Token, 447e2e9c0cSopenharmony_ci ty: Box::new(Type::Path(self.self_ty(span))), 457e2e9c0cSopenharmony_ci position: 0, 467e2e9c0cSopenharmony_ci as_token: None, 477e2e9c0cSopenharmony_ci gt_token: Token, 487e2e9c0cSopenharmony_ci }); 497e2e9c0cSopenharmony_ci 507e2e9c0cSopenharmony_ci path.leading_colon = Some(**path.segments.pairs().next().unwrap().punct().unwrap()); 517e2e9c0cSopenharmony_ci 527e2e9c0cSopenharmony_ci let segments = mem::replace(&mut path.segments, Punctuated::new()); 537e2e9c0cSopenharmony_ci path.segments = segments.into_pairs().skip(1).collect(); 547e2e9c0cSopenharmony_ci } 557e2e9c0cSopenharmony_ci 567e2e9c0cSopenharmony_ci fn self_to_expr_path(&self, path: &mut Path) { 577e2e9c0cSopenharmony_ci let self_ty = self.self_ty(path.segments[0].ident.span()); 587e2e9c0cSopenharmony_ci let variant = mem::replace(path, self_ty.path); 597e2e9c0cSopenharmony_ci for segment in &mut path.segments { 607e2e9c0cSopenharmony_ci if let PathArguments::AngleBracketed(bracketed) = &mut segment.arguments { 617e2e9c0cSopenharmony_ci if bracketed.colon2_token.is_none() && !bracketed.args.is_empty() { 627e2e9c0cSopenharmony_ci bracketed.colon2_token = Some(<Token![::]>::default()); 637e2e9c0cSopenharmony_ci } 647e2e9c0cSopenharmony_ci } 657e2e9c0cSopenharmony_ci } 667e2e9c0cSopenharmony_ci if variant.segments.len() > 1 { 677e2e9c0cSopenharmony_ci path.segments.push_punct(<Token![::]>::default()); 687e2e9c0cSopenharmony_ci path.segments.extend(variant.segments.into_pairs().skip(1)); 697e2e9c0cSopenharmony_ci } 707e2e9c0cSopenharmony_ci } 717e2e9c0cSopenharmony_ci} 727e2e9c0cSopenharmony_ci 737e2e9c0cSopenharmony_ciimpl ReplaceReceiver<'_> { 747e2e9c0cSopenharmony_ci // `Self` -> `Receiver` 757e2e9c0cSopenharmony_ci fn visit_type_mut(&mut self, ty: &mut Type) { 767e2e9c0cSopenharmony_ci let span = if let Type::Path(node) = ty { 777e2e9c0cSopenharmony_ci if node.qself.is_none() && node.path.is_ident("Self") { 787e2e9c0cSopenharmony_ci node.path.segments[0].ident.span() 797e2e9c0cSopenharmony_ci } else { 807e2e9c0cSopenharmony_ci self.visit_type_path_mut(node); 817e2e9c0cSopenharmony_ci return; 827e2e9c0cSopenharmony_ci } 837e2e9c0cSopenharmony_ci } else { 847e2e9c0cSopenharmony_ci self.visit_type_mut_impl(ty); 857e2e9c0cSopenharmony_ci return; 867e2e9c0cSopenharmony_ci }; 877e2e9c0cSopenharmony_ci *ty = self.self_ty(span).into(); 887e2e9c0cSopenharmony_ci } 897e2e9c0cSopenharmony_ci 907e2e9c0cSopenharmony_ci // `Self::Assoc` -> `<Receiver>::Assoc` 917e2e9c0cSopenharmony_ci fn visit_type_path_mut(&mut self, ty: &mut TypePath) { 927e2e9c0cSopenharmony_ci if ty.qself.is_none() { 937e2e9c0cSopenharmony_ci self.self_to_qself(&mut ty.qself, &mut ty.path); 947e2e9c0cSopenharmony_ci } 957e2e9c0cSopenharmony_ci self.visit_type_path_mut_impl(ty); 967e2e9c0cSopenharmony_ci } 977e2e9c0cSopenharmony_ci 987e2e9c0cSopenharmony_ci // `Self::method` -> `<Receiver>::method` 997e2e9c0cSopenharmony_ci fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) { 1007e2e9c0cSopenharmony_ci if expr.qself.is_none() { 1017e2e9c0cSopenharmony_ci self.self_to_qself(&mut expr.qself, &mut expr.path); 1027e2e9c0cSopenharmony_ci } 1037e2e9c0cSopenharmony_ci self.visit_expr_path_mut_impl(expr); 1047e2e9c0cSopenharmony_ci } 1057e2e9c0cSopenharmony_ci 1067e2e9c0cSopenharmony_ci // Everything below is simply traversing the syntax tree. 1077e2e9c0cSopenharmony_ci 1087e2e9c0cSopenharmony_ci fn visit_type_mut_impl(&mut self, ty: &mut Type) { 1097e2e9c0cSopenharmony_ci match ty { 1107e2e9c0cSopenharmony_ci #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] 1117e2e9c0cSopenharmony_ci Type::Array(ty) => { 1127e2e9c0cSopenharmony_ci self.visit_type_mut(&mut ty.elem); 1137e2e9c0cSopenharmony_ci self.visit_expr_mut(&mut ty.len); 1147e2e9c0cSopenharmony_ci } 1157e2e9c0cSopenharmony_ci Type::BareFn(ty) => { 1167e2e9c0cSopenharmony_ci for arg in &mut ty.inputs { 1177e2e9c0cSopenharmony_ci self.visit_type_mut(&mut arg.ty); 1187e2e9c0cSopenharmony_ci } 1197e2e9c0cSopenharmony_ci self.visit_return_type_mut(&mut ty.output); 1207e2e9c0cSopenharmony_ci } 1217e2e9c0cSopenharmony_ci Type::Group(ty) => self.visit_type_mut(&mut ty.elem), 1227e2e9c0cSopenharmony_ci Type::ImplTrait(ty) => { 1237e2e9c0cSopenharmony_ci for bound in &mut ty.bounds { 1247e2e9c0cSopenharmony_ci self.visit_type_param_bound_mut(bound); 1257e2e9c0cSopenharmony_ci } 1267e2e9c0cSopenharmony_ci } 1277e2e9c0cSopenharmony_ci Type::Macro(ty) => self.visit_macro_mut(&mut ty.mac), 1287e2e9c0cSopenharmony_ci Type::Paren(ty) => self.visit_type_mut(&mut ty.elem), 1297e2e9c0cSopenharmony_ci Type::Path(ty) => { 1307e2e9c0cSopenharmony_ci if let Some(qself) = &mut ty.qself { 1317e2e9c0cSopenharmony_ci self.visit_type_mut(&mut qself.ty); 1327e2e9c0cSopenharmony_ci } 1337e2e9c0cSopenharmony_ci self.visit_path_mut(&mut ty.path); 1347e2e9c0cSopenharmony_ci } 1357e2e9c0cSopenharmony_ci Type::Ptr(ty) => self.visit_type_mut(&mut ty.elem), 1367e2e9c0cSopenharmony_ci Type::Reference(ty) => self.visit_type_mut(&mut ty.elem), 1377e2e9c0cSopenharmony_ci Type::Slice(ty) => self.visit_type_mut(&mut ty.elem), 1387e2e9c0cSopenharmony_ci Type::TraitObject(ty) => { 1397e2e9c0cSopenharmony_ci for bound in &mut ty.bounds { 1407e2e9c0cSopenharmony_ci self.visit_type_param_bound_mut(bound); 1417e2e9c0cSopenharmony_ci } 1427e2e9c0cSopenharmony_ci } 1437e2e9c0cSopenharmony_ci Type::Tuple(ty) => { 1447e2e9c0cSopenharmony_ci for elem in &mut ty.elems { 1457e2e9c0cSopenharmony_ci self.visit_type_mut(elem); 1467e2e9c0cSopenharmony_ci } 1477e2e9c0cSopenharmony_ci } 1487e2e9c0cSopenharmony_ci 1497e2e9c0cSopenharmony_ci Type::Infer(_) | Type::Never(_) | Type::Verbatim(_) => {} 1507e2e9c0cSopenharmony_ci 1517e2e9c0cSopenharmony_ci _ => {} 1527e2e9c0cSopenharmony_ci } 1537e2e9c0cSopenharmony_ci } 1547e2e9c0cSopenharmony_ci 1557e2e9c0cSopenharmony_ci fn visit_type_path_mut_impl(&mut self, ty: &mut TypePath) { 1567e2e9c0cSopenharmony_ci if let Some(qself) = &mut ty.qself { 1577e2e9c0cSopenharmony_ci self.visit_type_mut(&mut qself.ty); 1587e2e9c0cSopenharmony_ci } 1597e2e9c0cSopenharmony_ci self.visit_path_mut(&mut ty.path); 1607e2e9c0cSopenharmony_ci } 1617e2e9c0cSopenharmony_ci 1627e2e9c0cSopenharmony_ci fn visit_expr_path_mut_impl(&mut self, expr: &mut ExprPath) { 1637e2e9c0cSopenharmony_ci if let Some(qself) = &mut expr.qself { 1647e2e9c0cSopenharmony_ci self.visit_type_mut(&mut qself.ty); 1657e2e9c0cSopenharmony_ci } 1667e2e9c0cSopenharmony_ci self.visit_path_mut(&mut expr.path); 1677e2e9c0cSopenharmony_ci } 1687e2e9c0cSopenharmony_ci 1697e2e9c0cSopenharmony_ci fn visit_path_mut(&mut self, path: &mut Path) { 1707e2e9c0cSopenharmony_ci for segment in &mut path.segments { 1717e2e9c0cSopenharmony_ci self.visit_path_arguments_mut(&mut segment.arguments); 1727e2e9c0cSopenharmony_ci } 1737e2e9c0cSopenharmony_ci } 1747e2e9c0cSopenharmony_ci 1757e2e9c0cSopenharmony_ci fn visit_path_arguments_mut(&mut self, arguments: &mut PathArguments) { 1767e2e9c0cSopenharmony_ci match arguments { 1777e2e9c0cSopenharmony_ci PathArguments::None => {} 1787e2e9c0cSopenharmony_ci PathArguments::AngleBracketed(arguments) => { 1797e2e9c0cSopenharmony_ci for arg in &mut arguments.args { 1807e2e9c0cSopenharmony_ci match arg { 1817e2e9c0cSopenharmony_ci #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] 1827e2e9c0cSopenharmony_ci GenericArgument::Type(arg) => self.visit_type_mut(arg), 1837e2e9c0cSopenharmony_ci GenericArgument::AssocType(arg) => self.visit_type_mut(&mut arg.ty), 1847e2e9c0cSopenharmony_ci GenericArgument::Lifetime(_) 1857e2e9c0cSopenharmony_ci | GenericArgument::Const(_) 1867e2e9c0cSopenharmony_ci | GenericArgument::AssocConst(_) 1877e2e9c0cSopenharmony_ci | GenericArgument::Constraint(_) => {} 1887e2e9c0cSopenharmony_ci _ => {} 1897e2e9c0cSopenharmony_ci } 1907e2e9c0cSopenharmony_ci } 1917e2e9c0cSopenharmony_ci } 1927e2e9c0cSopenharmony_ci PathArguments::Parenthesized(arguments) => { 1937e2e9c0cSopenharmony_ci for argument in &mut arguments.inputs { 1947e2e9c0cSopenharmony_ci self.visit_type_mut(argument); 1957e2e9c0cSopenharmony_ci } 1967e2e9c0cSopenharmony_ci self.visit_return_type_mut(&mut arguments.output); 1977e2e9c0cSopenharmony_ci } 1987e2e9c0cSopenharmony_ci } 1997e2e9c0cSopenharmony_ci } 2007e2e9c0cSopenharmony_ci 2017e2e9c0cSopenharmony_ci fn visit_return_type_mut(&mut self, return_type: &mut ReturnType) { 2027e2e9c0cSopenharmony_ci match return_type { 2037e2e9c0cSopenharmony_ci ReturnType::Default => {} 2047e2e9c0cSopenharmony_ci ReturnType::Type(_, output) => self.visit_type_mut(output), 2057e2e9c0cSopenharmony_ci } 2067e2e9c0cSopenharmony_ci } 2077e2e9c0cSopenharmony_ci 2087e2e9c0cSopenharmony_ci fn visit_type_param_bound_mut(&mut self, bound: &mut TypeParamBound) { 2097e2e9c0cSopenharmony_ci match bound { 2107e2e9c0cSopenharmony_ci #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] 2117e2e9c0cSopenharmony_ci TypeParamBound::Trait(bound) => self.visit_path_mut(&mut bound.path), 2127e2e9c0cSopenharmony_ci TypeParamBound::Lifetime(_) | TypeParamBound::Verbatim(_) => {} 2137e2e9c0cSopenharmony_ci _ => {} 2147e2e9c0cSopenharmony_ci } 2157e2e9c0cSopenharmony_ci } 2167e2e9c0cSopenharmony_ci 2177e2e9c0cSopenharmony_ci fn visit_generics_mut(&mut self, generics: &mut Generics) { 2187e2e9c0cSopenharmony_ci for param in &mut generics.params { 2197e2e9c0cSopenharmony_ci match param { 2207e2e9c0cSopenharmony_ci GenericParam::Type(param) => { 2217e2e9c0cSopenharmony_ci for bound in &mut param.bounds { 2227e2e9c0cSopenharmony_ci self.visit_type_param_bound_mut(bound); 2237e2e9c0cSopenharmony_ci } 2247e2e9c0cSopenharmony_ci } 2257e2e9c0cSopenharmony_ci GenericParam::Lifetime(_) | GenericParam::Const(_) => {} 2267e2e9c0cSopenharmony_ci } 2277e2e9c0cSopenharmony_ci } 2287e2e9c0cSopenharmony_ci if let Some(where_clause) = &mut generics.where_clause { 2297e2e9c0cSopenharmony_ci for predicate in &mut where_clause.predicates { 2307e2e9c0cSopenharmony_ci match predicate { 2317e2e9c0cSopenharmony_ci #![cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))] 2327e2e9c0cSopenharmony_ci WherePredicate::Type(predicate) => { 2337e2e9c0cSopenharmony_ci self.visit_type_mut(&mut predicate.bounded_ty); 2347e2e9c0cSopenharmony_ci for bound in &mut predicate.bounds { 2357e2e9c0cSopenharmony_ci self.visit_type_param_bound_mut(bound); 2367e2e9c0cSopenharmony_ci } 2377e2e9c0cSopenharmony_ci } 2387e2e9c0cSopenharmony_ci WherePredicate::Lifetime(_) => {} 2397e2e9c0cSopenharmony_ci _ => {} 2407e2e9c0cSopenharmony_ci } 2417e2e9c0cSopenharmony_ci } 2427e2e9c0cSopenharmony_ci } 2437e2e9c0cSopenharmony_ci } 2447e2e9c0cSopenharmony_ci 2457e2e9c0cSopenharmony_ci fn visit_data_mut(&mut self, data: &mut Data) { 2467e2e9c0cSopenharmony_ci match data { 2477e2e9c0cSopenharmony_ci Data::Struct(data) => { 2487e2e9c0cSopenharmony_ci for field in &mut data.fields { 2497e2e9c0cSopenharmony_ci self.visit_type_mut(&mut field.ty); 2507e2e9c0cSopenharmony_ci } 2517e2e9c0cSopenharmony_ci } 2527e2e9c0cSopenharmony_ci Data::Enum(data) => { 2537e2e9c0cSopenharmony_ci for variant in &mut data.variants { 2547e2e9c0cSopenharmony_ci for field in &mut variant.fields { 2557e2e9c0cSopenharmony_ci self.visit_type_mut(&mut field.ty); 2567e2e9c0cSopenharmony_ci } 2577e2e9c0cSopenharmony_ci } 2587e2e9c0cSopenharmony_ci } 2597e2e9c0cSopenharmony_ci Data::Union(_) => {} 2607e2e9c0cSopenharmony_ci } 2617e2e9c0cSopenharmony_ci } 2627e2e9c0cSopenharmony_ci 2637e2e9c0cSopenharmony_ci fn visit_expr_mut(&mut self, expr: &mut Expr) { 2647e2e9c0cSopenharmony_ci match expr { 2657e2e9c0cSopenharmony_ci Expr::Binary(expr) => { 2667e2e9c0cSopenharmony_ci self.visit_expr_mut(&mut expr.left); 2677e2e9c0cSopenharmony_ci self.visit_expr_mut(&mut expr.right); 2687e2e9c0cSopenharmony_ci } 2697e2e9c0cSopenharmony_ci Expr::Call(expr) => { 2707e2e9c0cSopenharmony_ci self.visit_expr_mut(&mut expr.func); 2717e2e9c0cSopenharmony_ci for arg in &mut expr.args { 2727e2e9c0cSopenharmony_ci self.visit_expr_mut(arg); 2737e2e9c0cSopenharmony_ci } 2747e2e9c0cSopenharmony_ci } 2757e2e9c0cSopenharmony_ci Expr::Cast(expr) => { 2767e2e9c0cSopenharmony_ci self.visit_expr_mut(&mut expr.expr); 2777e2e9c0cSopenharmony_ci self.visit_type_mut(&mut expr.ty); 2787e2e9c0cSopenharmony_ci } 2797e2e9c0cSopenharmony_ci Expr::Field(expr) => self.visit_expr_mut(&mut expr.base), 2807e2e9c0cSopenharmony_ci Expr::Index(expr) => { 2817e2e9c0cSopenharmony_ci self.visit_expr_mut(&mut expr.expr); 2827e2e9c0cSopenharmony_ci self.visit_expr_mut(&mut expr.index); 2837e2e9c0cSopenharmony_ci } 2847e2e9c0cSopenharmony_ci Expr::Paren(expr) => self.visit_expr_mut(&mut expr.expr), 2857e2e9c0cSopenharmony_ci Expr::Path(expr) => self.visit_expr_path_mut(expr), 2867e2e9c0cSopenharmony_ci Expr::Unary(expr) => self.visit_expr_mut(&mut expr.expr), 2877e2e9c0cSopenharmony_ci _ => {} 2887e2e9c0cSopenharmony_ci } 2897e2e9c0cSopenharmony_ci } 2907e2e9c0cSopenharmony_ci 2917e2e9c0cSopenharmony_ci fn visit_macro_mut(&mut self, _mac: &mut Macro) {} 2927e2e9c0cSopenharmony_ci} 293