about summary refs log tree commit diff
path: root/tvix/eval/builtin-macros/src/lib.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-12-19T10·23+0300
committertazjin <tazjin@tvl.su>2022-12-21T23·05+0000
commit908cebf35c4e9be1fa91cb558389b7e80b6d0b77 (patch)
treefe5eab3dc31b963e799104983bddfac2eaddc4c0 /tvix/eval/builtin-macros/src/lib.rs
parent270b1084e890d2c69456d342e6e2cad7e13ad9a7 (diff)
fix(tvix/builtin-macros): parse multi-line docstrings correctly r/5468
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
Diffstat (limited to 'tvix/eval/builtin-macros/src/lib.rs')
-rw-r--r--tvix/eval/builtin-macros/src/lib.rs20
1 files changed, 17 insertions, 3 deletions
diff --git a/tvix/eval/builtin-macros/src/lib.rs b/tvix/eval/builtin-macros/src/lib.rs
index e815749ec62c..ac994954ba60 100644
--- a/tvix/eval/builtin-macros/src/lib.rs
+++ b/tvix/eval/builtin-macros/src/lib.rs
@@ -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.