Skip to content

Commit 65dd911

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

3 files changed

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

0 commit comments

Comments
 (0)