feat(tvix/eval): Add docstrings as documentation for builtins
Add a new `documentation: Option<&'static str>` field to Builtin, and populate it in the `#[builtins]` macro with the docstring of the builtin function, if any. Change-Id: Ic68fdf9b314d15a780731974234e2ae43f6a44b0 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7205 Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su>
This commit is contained in:
parent
a1015ba1d7
commit
76d7671c8a
5 changed files with 54 additions and 2 deletions
|
|
@ -2,11 +2,12 @@ extern crate proc_macro;
|
|||
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::Span;
|
||||
use quote::{quote_spanned, ToTokens};
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
use syn::parse::Parse;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{
|
||||
parse_macro_input, parse_quote, FnArg, Ident, Item, ItemMod, LitStr, Pat, PatIdent, PatType,
|
||||
parse2, parse_macro_input, parse_quote, Attribute, FnArg, Ident, Item, ItemMod, LitStr, Pat,
|
||||
PatIdent, PatType, Token,
|
||||
};
|
||||
|
||||
struct BuiltinArgs {
|
||||
|
|
@ -21,6 +22,35 @@ impl Parse for BuiltinArgs {
|
|||
}
|
||||
}
|
||||
|
||||
fn extract_docstring(attrs: &[Attribute]) -> Option<LitStr> {
|
||||
// Rust docstrings are transparently written pre-macro expansion into an attribute that looks
|
||||
// like:
|
||||
//
|
||||
// #[doc = "docstring here"]
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
struct Docstring {
|
||||
eq: Token![=],
|
||||
doc: LitStr,
|
||||
}
|
||||
|
||||
impl Parse for Docstring {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
|
||||
Ok(Self {
|
||||
eq: input.parse()?,
|
||||
doc: input.parse()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
/// Mark the annotated module as a module for defining Nix builtins.
|
||||
///
|
||||
/// A function `fn builtins() -> Vec<Builtin>` will be defined within the annotated module,
|
||||
|
|
@ -144,10 +174,16 @@ pub fn builtins(_args: TokenStream, item: TokenStream) -> TokenStream {
|
|||
let mut reversed_args = args.clone();
|
||||
reversed_args.reverse();
|
||||
|
||||
let docstring = match extract_docstring(&f.attrs) {
|
||||
Some(docs) => quote!(Some(#docs)),
|
||||
None => quote!(None),
|
||||
};
|
||||
|
||||
builtins.push(quote_spanned! { builtin_attr.span() => {
|
||||
crate::internal::Builtin::new(
|
||||
#name,
|
||||
&[#(#builtin_arguments),*],
|
||||
#docstring,
|
||||
|mut args: Vec<crate::Value>, vm: &mut crate::internal::VM| {
|
||||
#(let #reversed_args = args.pop().unwrap();)*
|
||||
#fn_name(vm, #(#args),*)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue