Skip to content

Commit 374f263

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

3 files changed

Lines changed: 51 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: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,56 @@ 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 args: Vec<_> = sig
346+
.inputs
347+
.iter()
348+
.filter_map(|arg| {
349+
use syn::FnArg::*;
350+
let arg = match arg {
351+
Receiver(_) => return Some("$self".to_owned()),
352+
Typed(typed) => typed,
353+
};
354+
let ty = arg.ty.as_ref();
355+
let ty = quote!(#ty).to_string();
356+
if ty == "FuncArgs" {
357+
has_args = true;
358+
return Some("*args, **kwargs".to_owned());
359+
}
360+
if ty == "& VirtualMachine" {
361+
return None;
362+
}
363+
let ident = match arg.pat.as_ref() {
364+
syn::Pat::Ident(p) => p.ident.to_string(),
365+
// FIXME: other => unreachable!("function arg pattern must be ident but found `{}`", quote!(fn #ident(.. #other ..))),
366+
other => quote!(#other).to_string(),
367+
};
368+
if ident == "zelf" {
369+
return Some("$self".to_owned());
370+
}
371+
if ident == "vm" {
372+
unreachable!("type &VirtualMachine(`{}`) must be filtered already", ty);
373+
}
374+
Some(ident)
375+
})
376+
.collect();
377+
if !has_args {
378+
args.push("/".to_owned());
379+
}
380+
format!("{}({})", py_name, args.join(", "))
381+
});
382+
342383
let tokens = {
343-
let doc = args.attrs.doc().map_or_else(
344-
TokenStream::new,
345-
|doc| quote!(.with_doc(#doc.to_owned(), ctx)),
346-
);
384+
let doc = args.attrs.doc().map_or_else(TokenStream::new, |mut doc| {
385+
if let Some(sig_doc) = sig_doc {
386+
doc = format!("{}\n--\n\n{}", sig_doc, doc);
387+
}
388+
quote!(.with_doc(#doc.to_owned(), ctx))
389+
});
347390
let build_func = match self.method_type.as_str() {
348391
"method" => quote!(.build_method(ctx, class.clone())),
349392
"classmethod" => quote!(.build_classmethod(ctx, class.clone())),

0 commit comments

Comments
 (0)