fix(tvix/builtin-macros): parse multi-line docstrings correctly
Having a multi-line docstring yields multiple doc-attributes in order, however we were previously discarding all but the first one. This reduces them into a single string instead, which can then be displayed as multi-line documentation. Change-Id: I1f237956cdea2e4c746d3f13744e0373c1c645a6 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7594 Reviewed-by: grfn <grfn@gws.fyi> Autosubmit: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
This commit is contained in:
parent
270b1084e8
commit
908cebf35c
2 changed files with 28 additions and 5 deletions
|
@ -22,11 +22,14 @@ impl Parse for BuiltinArgs {
|
|||
}
|
||||
}
|
||||
|
||||
fn extract_docstring(attrs: &[Attribute]) -> Option<LitStr> {
|
||||
fn extract_docstring(attrs: &[Attribute]) -> Option<String> {
|
||||
// Rust docstrings are transparently written pre-macro expansion into an attribute that looks
|
||||
// like:
|
||||
//
|
||||
// #[doc = "docstring here"]
|
||||
//
|
||||
// Multi-line docstrings yield multiple attributes in order, which we assemble into a single
|
||||
// string below.
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
|
@ -47,8 +50,19 @@ fn extract_docstring(attrs: &[Attribute]) -> Option<LitStr> {
|
|||
attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.path.get_ident().into_iter().any(|id| id == "doc"))
|
||||
.find_map(|attr| parse2::<Docstring>(attr.tokens.clone()).ok())
|
||||
.map(|docstring| docstring.doc)
|
||||
.filter_map(|attr| parse2::<Docstring>(attr.tokens.clone()).ok())
|
||||
.map(|docstring| docstring.doc.value())
|
||||
.reduce(|mut fst, snd| {
|
||||
if snd.is_empty() {
|
||||
// An empty string represents a spacing newline that was added in the
|
||||
// original doc comment.
|
||||
fst.push_str("\n\n");
|
||||
} else {
|
||||
fst.push_str(&snd);
|
||||
}
|
||||
|
||||
fst
|
||||
})
|
||||
}
|
||||
|
||||
/// Mark the annotated module as a module for defining Nix builtins.
|
||||
|
|
|
@ -7,7 +7,9 @@ mod builtins {
|
|||
use tvix_eval::internal::VM;
|
||||
use tvix_eval::{ErrorKind, Value};
|
||||
|
||||
/// Test docstring
|
||||
/// Test docstring.
|
||||
///
|
||||
/// It has multiple lines!
|
||||
#[builtin("identity")]
|
||||
pub fn builtin_identity(_vm: &mut VM, x: Value) -> Result<Value, ErrorKind> {
|
||||
Ok(x)
|
||||
|
@ -25,5 +27,12 @@ fn builtins() {
|
|||
assert_eq!(builtins.len(), 2);
|
||||
|
||||
let identity = builtins.iter().find(|b| b.name() == "identity").unwrap();
|
||||
assert_eq!(identity.documentation(), Some(" Test docstring"));
|
||||
assert_eq!(
|
||||
identity.documentation(),
|
||||
Some(
|
||||
r#" Test docstring.
|
||||
|
||||
It has multiple lines!"#
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue