@@ -91,7 +91,7 @@ pub fn function_introspection_code(
9191 ( "name" , IntrospectionNode :: String ( name. into ( ) ) ) ,
9292 (
9393 "arguments" ,
94- arguments_introspection_data ( signature, first_argument) ,
94+ arguments_introspection_data ( signature, first_argument, parent ) ,
9595 ) ,
9696 ] ) ;
9797 if let Some ( ident) = ident {
@@ -119,6 +119,7 @@ pub fn function_introspection_code(
119119fn arguments_introspection_data < ' a > (
120120 signature : & ' a FunctionSignature < ' a > ,
121121 first_argument : Option < & ' a str > ,
122+ class_type : Option < & Type > ,
122123) -> IntrospectionNode < ' a > {
123124 let mut argument_desc = signature. arguments . iter ( ) . filter_map ( |arg| {
124125 if let FnArg :: Regular ( arg) = arg {
@@ -151,7 +152,7 @@ fn arguments_introspection_data<'a>(
151152 } else {
152153 panic ! ( "Less arguments than in python signature" ) ;
153154 } ;
154- let arg = argument_introspection_data ( param, arg_desc) ;
155+ let arg = argument_introspection_data ( param, arg_desc, class_type ) ;
155156 if i < signature. python_signature . positional_only_parameters {
156157 posonlyargs. push ( arg) ;
157158 } else {
@@ -171,7 +172,7 @@ fn arguments_introspection_data<'a>(
171172 } else {
172173 panic ! ( "Less arguments than in python signature" ) ;
173174 } ;
174- kwonlyargs. push ( argument_introspection_data ( param, arg_desc) ) ;
175+ kwonlyargs. push ( argument_introspection_data ( param, arg_desc, class_type ) ) ;
175176 }
176177
177178 if let Some ( param) = & signature. python_signature . kwargs {
@@ -206,6 +207,7 @@ fn arguments_introspection_data<'a>(
206207fn argument_introspection_data < ' a > (
207208 name : & ' a str ,
208209 desc : & ' a RegularArg < ' _ > ,
210+ class_type : Option < & Type > ,
209211) -> IntrospectionNode < ' a > {
210212 let mut params: HashMap < _ , _ > = [ ( "name" , IntrospectionNode :: String ( name. into ( ) ) ) ] . into ( ) ;
211213 if desc. default_value . is_some ( ) {
@@ -218,7 +220,11 @@ fn argument_introspection_data<'a>(
218220 // If from_py_with is set we don't know anything on the input type
219221 if let Some ( ty) = desc. option_wrapped_type {
220222 // Special case to properly generate a `T | None` annotation
221- let ty = ty. clone ( ) . elide_lifetimes ( ) ;
223+ let mut ty = ty. clone ( ) ;
224+ if let Some ( class_type) = class_type {
225+ replace_self ( & mut ty, class_type) ;
226+ }
227+ ty = ty. elide_lifetimes ( ) ;
222228 params. insert (
223229 "annotation" ,
224230 IntrospectionNode :: InputType {
@@ -227,7 +233,11 @@ fn argument_introspection_data<'a>(
227233 } ,
228234 ) ;
229235 } else {
230- let ty = desc. ty . clone ( ) . elide_lifetimes ( ) ;
236+ let mut ty = desc. ty . clone ( ) ;
237+ if let Some ( class_type) = class_type {
238+ replace_self ( & mut ty, class_type) ;
239+ }
240+ ty = ty. elide_lifetimes ( ) ;
231241 params. insert (
232242 "annotation" ,
233243 IntrospectionNode :: InputType {
@@ -417,3 +427,64 @@ fn ident_to_type(ident: &Ident) -> Cow<'static, Type> {
417427 . into ( ) ,
418428 )
419429}
430+
431+ // Replace Self in types with the given type
432+ fn replace_self ( ty : & mut Type , self_target : & Type ) {
433+ match ty {
434+ syn:: Type :: Path ( type_path) => {
435+ if type_path. qself . is_none ( )
436+ && type_path. path . segments . len ( ) == 1
437+ && type_path. path . segments [ 0 ] . ident == "Self"
438+ && type_path. path . segments [ 0 ] . arguments . is_empty ( )
439+ {
440+ // It is Self
441+ * ty = self_target. clone ( ) ;
442+ return ;
443+ }
444+
445+ // We look recursively
446+ if let Some ( qself) = & mut type_path. qself {
447+ replace_self ( & mut qself. ty , self_target)
448+ }
449+ for seg in & mut type_path. path . segments {
450+ if let syn:: PathArguments :: AngleBracketed ( args) = & mut seg. arguments {
451+ for generic_arg in & mut args. args {
452+ match generic_arg {
453+ syn:: GenericArgument :: Type ( ty) => replace_self ( ty, self_target) ,
454+ syn:: GenericArgument :: AssocType ( assoc) => {
455+ replace_self ( & mut assoc. ty , self_target)
456+ }
457+ syn:: GenericArgument :: Lifetime ( _)
458+ | syn:: GenericArgument :: Const ( _)
459+ | syn:: GenericArgument :: AssocConst ( _)
460+ | syn:: GenericArgument :: Constraint ( _)
461+ | _ => { }
462+ }
463+ }
464+ }
465+ }
466+ }
467+ syn:: Type :: Reference ( type_ref) => {
468+ replace_self ( & mut type_ref. elem , self_target) ;
469+ }
470+ syn:: Type :: Tuple ( type_tuple) => {
471+ for ty in & mut type_tuple. elems {
472+ replace_self ( ty, self_target) ;
473+ }
474+ }
475+ syn:: Type :: Array ( type_array) => replace_self ( & mut type_array. elem , self_target) ,
476+ syn:: Type :: Slice ( ty) => replace_self ( & mut ty. elem , self_target) ,
477+ syn:: Type :: Group ( ty) => replace_self ( & mut ty. elem , self_target) ,
478+ syn:: Type :: Paren ( ty) => replace_self ( & mut ty. elem , self_target) ,
479+ syn:: Type :: Ptr ( ty) => replace_self ( & mut ty. elem , self_target) ,
480+
481+ syn:: Type :: BareFn ( _)
482+ | syn:: Type :: ImplTrait ( _)
483+ | syn:: Type :: Infer ( _)
484+ | syn:: Type :: Macro ( _)
485+ | syn:: Type :: Never ( _)
486+ | syn:: Type :: TraitObject ( _)
487+ | syn:: Type :: Verbatim ( _)
488+ | _ => { }
489+ }
490+ }
0 commit comments