summaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-03-26 17:39:27 +0200
committerHampusM <hampus@hampusmat.com>2023-03-26 17:39:27 +0200
commit1628732d6514670fe2108e5063e9d5ba7166ad94 (patch)
tree4e54f68ed3869b8b50adceba6e8c95b3db53d41e /macros
parent7f9294869afd07e096e73a45e6a101b8970a0e6e (diff)
fix: replace Self in generics
Diffstat (limited to 'macros')
-rw-r--r--macros/src/lib.rs116
1 files changed, 106 insertions, 10 deletions
diff --git a/macros/src/lib.rs b/macros/src/lib.rs
index bcb4449..13037e4 100644
--- a/macros/src/lib.rs
+++ b/macros/src/lib.rs
@@ -10,6 +10,8 @@ use syn::{
Block,
FnArg,
GenericArgument,
+ GenericParam,
+ Generics,
ImplItem,
ImplItemMethod,
ItemTrait,
@@ -22,6 +24,7 @@ use syn::{
TypeBareFn,
TypeParamBound,
Visibility,
+ WherePredicate,
};
use crate::expectation::Expectation;
@@ -174,6 +177,13 @@ fn get_type_replaced_impl_item_methods(
mock_ident: &Ident,
) -> Vec<ImplItemMethod>
{
+ let target_path = create_path!(Self);
+
+ let replacement_path = Path::new(
+ WithLeadingColons::No,
+ [PathSegment::new(mock_ident.clone(), None)],
+ );
+
impl_items
.into_iter()
.filter_map(|item| match item {
@@ -186,11 +196,8 @@ fn get_type_replaced_impl_item_methods(
FnArg::Typed(mut typed_arg) => {
typed_arg.ty = Box::new(replace_path_in_type(
*typed_arg.ty,
- &create_path!(Self),
- &Path::new(
- WithLeadingColons::No,
- [PathSegment::new(mock_ident.clone(), None)],
- ),
+ &target_path,
+ &replacement_path,
));
FnArg::Typed(typed_arg)
@@ -205,16 +212,19 @@ fn get_type_replaced_impl_item_methods(
r_arrow,
Box::new(replace_path_in_type(
*return_type,
- &create_path!(Self),
- &Path::new(
- WithLeadingColons::No,
- [PathSegment::new(mock_ident.clone(), None)],
- ),
+ &target_path,
+ &replacement_path,
)),
),
ReturnType::Default => ReturnType::Default,
};
+ item_method.sig.generics = replace_path_in_generics(
+ item_method.sig.generics,
+ &target_path,
+ &replacement_path,
+ );
+
Some(item_method)
}
_ => None,
@@ -222,6 +232,71 @@ fn get_type_replaced_impl_item_methods(
.collect()
}
+fn replace_path_in_generics(
+ mut generics: Generics,
+ target_path: &Path,
+ replacement_path: &Path,
+) -> Generics
+{
+ generics.params = generics
+ .params
+ .into_iter()
+ .map(|generic_param| match generic_param {
+ GenericParam::Type(mut type_param) => {
+ type_param.bounds = type_param
+ .bounds
+ .into_iter()
+ .map(|bound| {
+ replace_type_param_bound_paths(
+ bound,
+ target_path,
+ replacement_path,
+ )
+ })
+ .collect();
+
+ GenericParam::Type(type_param)
+ }
+ generic_param => generic_param,
+ })
+ .collect();
+
+ generics.where_clause = generics.where_clause.map(|mut where_clause| {
+ where_clause.predicates = where_clause
+ .predicates
+ .into_iter()
+ .map(|predicate| match predicate {
+ WherePredicate::Type(mut predicate_type) => {
+ predicate_type.bounded_ty = replace_path_in_type(
+ predicate_type.bounded_ty,
+ target_path,
+ replacement_path,
+ );
+
+ predicate_type.bounds = predicate_type
+ .bounds
+ .into_iter()
+ .map(|bound| {
+ replace_type_param_bound_paths(
+ bound,
+ target_path,
+ replacement_path,
+ )
+ })
+ .collect();
+
+ WherePredicate::Type(predicate_type)
+ }
+ predicate => predicate,
+ })
+ .collect();
+
+ where_clause
+ });
+
+ generics
+}
+
fn replace_path_in_type(ty: Type, target_path: &Path, replacement_path: &Path) -> Type
{
match ty {
@@ -426,3 +501,24 @@ fn replace_type_bare_fn_type_paths(
type_bare_fn
}
+
+fn replace_type_param_bound_paths(
+ type_param_bound: TypeParamBound,
+ target_path: &Path,
+ replacement_path: &Path,
+) -> TypeParamBound
+{
+ match type_param_bound {
+ TypeParamBound::Trait(mut trait_bound) => {
+ if &trait_bound.path == target_path {
+ trait_bound.path = replacement_path.clone();
+ } else {
+ trait_bound.path =
+ replace_path_args(trait_bound.path, target_path, replacement_path);
+ }
+
+ TypeParamBound::Trait(trait_bound)
+ }
+ TypeParamBound::Lifetime(lifetime) => TypeParamBound::Lifetime(lifetime),
+ }
+}