Skip to content

Commit be8790a

Browse files
committed
derive __text_signature__ from definition
1 parent 3034aea commit be8790a

3 files changed

Lines changed: 50 additions & 8 deletions

File tree

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

derive/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ proc-macro = true
1212

1313
[dependencies]
1414
syn = { version = "1.0", features = ["full", "extra-traits"] }
15-
syn-ext = { version = "0.2.1", features = ["full"] }
15+
syn-ext = { version = "0.2.3", features = ["full"] }
1616
quote = "1.0"
1717
proc-macro2 = "1.0"
1818
rustpython-compiler = { path = "../compiler/porcelain", version = "0.1.1" }

derive/src/pyclass.rs

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,55 @@ where
337337

338338
let item_attr = args.attrs.remove(self.index());
339339
let item_meta = MethodItemMeta::from_attr(ident.clone(), &item_attr)?;
340-
341340
let py_name = item_meta.method_name()?;
341+
342+
let sig_doc = args.item.function_or_method_impl().ok().map(|item| {
343+
let sig = item.sig();
344+
let mut _has_args = false;
345+
let mut _has_kwargs = false;
346+
let args: Vec<_> = sig
347+
.inputs
348+
.iter()
349+
.filter_map(|arg| {
350+
use syn::FnArg::*;
351+
let arg = match arg {
352+
Receiver(_) => return Some("$self".to_owned()),
353+
Typed(typed) => typed,
354+
};
355+
let ty = arg.ty.as_ref();
356+
let ty = quote!(#ty).to_string();
357+
if ty == "FuncArgs" {
358+
_has_args = true;
359+
_has_kwargs = true;
360+
return Some("*args, **kwargs".to_owned());
361+
}
362+
if ty == "& VirtualMachine" {
363+
return None;
364+
}
365+
let ident = match arg.pat.as_ref() {
366+
syn::Pat::Ident(p) => p.ident.to_string(),
367+
// FIXME: other => unreachable!("function arg pattern must be ident but found `{}`", quote!(fn #ident(.. #other ..))),
368+
other => quote!(#other).to_string(),
369+
};
370+
if ident == "zelf" {
371+
return Some("$self".to_owned());
372+
}
373+
if ident == "vm" {
374+
unreachable!("type &VirtualMachine(`{}`) must be filtered already", ty);
375+
}
376+
Some(ident)
377+
})
378+
.collect();
379+
format!("{}({})", py_name, args.join(", "))
380+
});
381+
342382
let tokens = {
343-
let doc = args.attrs.doc().map_or_else(
344-
TokenStream::new,
345-
|doc| quote!(.with_doc(#doc.to_owned(), ctx)),
346-
);
383+
let doc = args.attrs.doc().map_or_else(TokenStream::new, |mut doc| {
384+
if let Some(sig_doc) = sig_doc {
385+
doc = format!("{}\n--\n\n{}", sig_doc, doc);
386+
}
387+
quote!(.with_doc(#doc.to_owned(), ctx))
388+
});
347389
let build_func = match self.method_type.as_str() {
348390
"method" => quote!(.build_method(ctx, class.clone())),
349391
"classmethod" => quote!(.build_classmethod(ctx, class.clone())),

0 commit comments

Comments
 (0)