From 1fff04f58240cc6d3501d5f3b797ae1bcc1a140c Mon Sep 17 00:00:00 2001 From: bluebear94 Date: Sat, 25 May 2024 11:33:37 -0400 Subject: [PATCH] Improve macro docs (+ Native*Data docs) (#4240) --- crates/typst-macros/src/elem.rs | 38 +++++++++++++++++++++++ crates/typst-macros/src/func.rs | 39 ++++++++++++++++++++++++ crates/typst-macros/src/lib.rs | 40 +++++++++++++++++-------- crates/typst-macros/src/ty.rs | 6 ++++ crates/typst/src/foundations/element.rs | 13 ++++++++ crates/typst/src/foundations/func.rs | 8 +++++ crates/typst/src/foundations/ty.rs | 5 ++++ 7 files changed, 137 insertions(+), 12 deletions(-) diff --git a/crates/typst-macros/src/elem.rs b/crates/typst-macros/src/elem.rs index 455a883ed19f..ffc4d8c26843 100644 --- a/crates/typst-macros/src/elem.rs +++ b/crates/typst-macros/src/elem.rs @@ -18,14 +18,23 @@ pub fn elem(stream: TokenStream, body: syn::ItemStruct) -> Result { /// Details about an element. struct Elem { + /// The element's name as exposed to Typst. name: String, + /// The element's title case name. title: String, + /// Whether this element has an associated scope defined by the `#[scope]` macro. scope: bool, + /// A list of alternate search terms for this element. keywords: Vec, + /// The documentation for this element as a string. docs: String, + /// The element's visibility. vis: syn::Visibility, + /// The struct name for this element given in Rust. ident: Ident, + /// The list of capabilities for this element. capabilities: Vec, + /// The fields of this element. fields: Vec, } @@ -97,30 +106,59 @@ impl Elem { } } +/// A field of an [element definition][`Elem`]. struct Field { + /// The name of this field. ident: Ident, + /// The identifier `{ident}_in`. ident_in: Ident, + /// The identifier `with_{ident}`. with_ident: Ident, + /// The identifier `push_{ident}`. push_ident: Ident, + /// The identifier `set_{ident}`. set_ident: Ident, + /// The upper camel-case version of `ident`, used for the enum variant name. enum_ident: Ident, + /// The all-caps snake-case version of `ident`, used for the constant name. const_ident: Ident, + /// The visibility of this field. vis: syn::Visibility, + /// The type of this field. ty: syn::Type, + /// The type returned by accessor methods for this field. + /// + /// Usually, this is the same as `ty`, but this might be different + /// if this field has a `#[resolve]` attribute. output: syn::Type, + /// The field's identifier as exposed to Typst. name: String, + /// The documentation for this field as a string. docs: String, + /// Whether this field is positional (as opposed to named). positional: bool, + /// Whether this field is required. required: bool, + /// Whether this field is variadic; that is, has its values + /// taken from a variable number of arguments. variadic: bool, + /// Whether this field has a `#[resolve]` attribute. resolve: bool, + /// Whether this field has a `#[fold]` attribute. fold: bool, + /// Whether this field is excluded from documentation. internal: bool, + /// Whether this field exists only in documentation. external: bool, + /// Whether this field has a `#[borrowed]` attribute. borrowed: bool, + /// Whether this field has a `#[ghost]` attribute. ghost: bool, + /// Whether this field has a `#[synthesized]` attribute. synthesized: bool, + /// The contents of the `#[parse({..})]` attribute, if any. parse: Option, + /// The contents of the `#[default(..)]` attribute, if any. default: Option, } diff --git a/crates/typst-macros/src/func.rs b/crates/typst-macros/src/func.rs index b7a7ac63c110..8d3fd4394f04 100644 --- a/crates/typst-macros/src/func.rs +++ b/crates/typst-macros/src/func.rs @@ -18,41 +18,71 @@ pub fn func(stream: TokenStream, item: &syn::ItemFn) -> Result { /// Details about a function. struct Func { + /// The function's name as exposed to Typst. name: String, + /// The function's title case name. title: String, + /// Whether this function has an associated scope defined by the `#[scope]` macro. scope: bool, + /// Whether this function is a constructor. constructor: bool, + /// A list of alternate search terms for this element. keywords: Vec, + /// The parent type of this function. + /// + /// Used for functions in a scope. parent: Option, + /// Whether this function is contextual. contextual: bool, + /// The documentation for this element as a string. docs: String, + /// The element's visibility. vis: syn::Visibility, + /// The name for this function given in Rust. ident: Ident, + /// Special parameters provided by the runtime. special: SpecialParams, + /// The list of parameters for this function. params: Vec, + /// The return type of this function. returns: syn::Type, } /// Special parameters provided by the runtime. #[derive(Default)] struct SpecialParams { + /// The receiver (`self`) parameter. self_: Option, + /// The parameter named `engine`, of type `&mut Engine`. engine: bool, + /// The parameter named `context`, of type `Tracked`. context: bool, + /// The parameter named `args`, of type `&mut Args`. args: bool, + /// The parameter named `span`, of type `Span`. span: bool, } /// Details about a function parameter. struct Param { + /// The binding for this parameter. binding: Binding, + /// The name of the parameter as defined in Rust. ident: Ident, + /// The type of the parameter. ty: syn::Type, + /// The name of the parameter as defined in Typst. name: String, + /// The documentation for this parameter as a string. docs: String, + /// Whether this parameter is named. named: bool, + /// Whether this parameter is variadic; that is, has its values + /// taken from a variable number of arguments. variadic: bool, + /// Whether this parameter exists only in documentation. external: bool, + /// The default value for this parameter. default: Option, } @@ -68,12 +98,21 @@ enum Binding { /// The `..` in `#[func(..)]`. pub struct Meta { + /// Whether this function has an associated scope defined by the `#[scope]` macro. pub scope: bool, + /// Whether this function is contextual. pub contextual: bool, + /// The function's name as exposed to Typst. pub name: Option, + /// The function's title case name. pub title: Option, + /// Whether this function is a constructor. pub constructor: bool, + /// A list of alternate search terms for this element. pub keywords: Vec, + /// The parent type of this function. + /// + /// Used for functions in a scope. pub parent: Option, } diff --git a/crates/typst-macros/src/lib.rs b/crates/typst-macros/src/lib.rs index 58d963863e84..c37af237fb26 100644 --- a/crates/typst-macros/src/lib.rs +++ b/crates/typst-macros/src/lib.rs @@ -42,10 +42,12 @@ use syn::DeriveInput; /// the `#[scope]` macro. /// - `contextual`: Indicates that the function makes use of context. This has /// no effect on the behaviour itself, but is used for the docs. -/// - `name`: The functions's normal name (e.g. `min`). Defaults to the Rust -/// name in kebab-case. +/// - `name`: The functions's normal name (e.g. `min`), as exposed to Typst. +/// Defaults to the Rust name in kebab-case. /// - `title`: The functions's title case name (e.g. `Minimum`). Defaults to the /// normal name in title case. +/// - `keywords = [..]`: A list of alternate search terms for this function. +/// - `constructor`: Indicates that the function is a constructor. /// /// # Arguments /// By default, function arguments are positional and required. You can use @@ -91,6 +93,15 @@ use syn::DeriveInput; /// in the documentation. The first line of documentation should be concise and /// self-contained as it is the designated short description, which is used in /// overviews in the documentation (and for autocompletion). +/// +/// Additionally, some arguments are treated specially by this macro: +/// +/// - `engine`: The compilation context (`Engine`). +/// - `context`: The introspection context (`Tracked`). +/// - `args`: The rest of the arguments passed into this function (`&mut Args`). +/// - `span`: The span of the function call (`Span`). +/// +/// These should always come after `self`, in the order specified. #[proc_macro_attribute] pub fn func(stream: BoundaryStream, item: BoundaryStream) -> BoundaryStream { let item = syn::parse_macro_input!(item as syn::ItemFn); @@ -120,8 +131,8 @@ pub fn func(stream: BoundaryStream, item: BoundaryStream) -> BoundaryStream { /// `#[scope]` macro /// - `cast`: Indicates that the type has a custom `cast!` implementation. /// The macro will then not autogenerate one. -/// - `name`: The type's normal name (e.g. `str`). Defaults to the Rust name in -/// kebab-case. +/// - `name`: The type's normal name (e.g. `str`), as exposed to Typst. +/// Defaults to the Rust name in kebab-case. /// - `title`: The type's title case name (e.g. `String`). Defaults to the /// normal name in title case. #[proc_macro_attribute] @@ -153,11 +164,13 @@ pub fn ty(stream: BoundaryStream, item: BoundaryStream) -> BoundaryStream { /// # Properties /// You can customize some properties of the resulting type: /// - `scope`: Indicates that the type has an associated scope defined by the -/// `#[scope]` macro -/// - `name`: The element's normal name (e.g. `str`). Defaults to the Rust name -/// in kebab-case. -/// - `title`: The type's title case name (e.g. `String`). Defaults to the long +/// `#[scope]` macro. +/// - `name = ""`: The element's normal name (e.g. `align`), as exposed to Typst. +/// Defaults to the Rust name in kebab-case. +/// - `title = ""`: The type's title case name (e.g. `Align`). Defaults to the long /// name in title case. +/// - `keywords = [..]`: A list of alternate search terms for this element. +/// Defaults to the empty list. /// - The remaining entries in the `elem` macros list are traits the element /// is capable of. These can be dynamically accessed. /// @@ -181,6 +194,9 @@ pub fn ty(stream: BoundaryStream, item: BoundaryStream) -> BoundaryStream { /// are folded together into one. E.g. `set rect(stroke: 2pt)` and /// `set rect(stroke: red)` are combined into the equivalent of /// `set rect(stroke: 2pt + red)` instead of having `red` override `2pt`. +/// - `#[borrowed]`: For fields that are accessed through the style chain, +/// indicates that accessor methods to this field should return references +/// to the value instead of cloning. /// - `#[internal]`: The field does not appear in the documentation. /// - `#[external]`: The field appears in the documentation, but is otherwise /// ignored. Can be useful if you want to do something manually for more @@ -348,18 +364,18 @@ pub fn symbols(stream: BoundaryStream) -> BoundaryStream { .into() } -/// Times the function invokations. +/// Times function invocations. /// /// When tracing is enabled in the typst-cli, this macro will record the -/// invokations of the function and store them in a global map. The map can be +/// invocations of the function and store them in a global map. The map can be /// accessed through the `typst_trace::RECORDER` static. /// -/// You can also specify the span of the function invokation: +/// You can also specify the span of the function invocation: /// - `#[time(span = ..)]` to record the span, which will be used for the /// `EventKey`. /// /// By default, all tracing is omitted using the `wasm32` target flag. -/// This is done to avoid bloating the web app which doesn't need tracing. +/// This is done to avoid bloating the web app, which doesn't need tracing. /// /// ```ignore /// #[time] diff --git a/crates/typst-macros/src/ty.rs b/crates/typst-macros/src/ty.rs index a6ae3f1c9072..200798af0611 100644 --- a/crates/typst-macros/src/ty.rs +++ b/crates/typst-macros/src/ty.rs @@ -29,16 +29,22 @@ pub fn ty(stream: TokenStream, item: syn::Item) -> Result<TokenStream> { /// Holds all relevant parsed data about a type. struct Type { meta: Meta, + /// The name for this type given in Rust. ident: Ident, + /// The type's identifier as exposed to Typst. name: String, long: String, + /// The type's title case name. title: String, + /// The documentation for this type as a string. docs: String, } /// The `..` in `#[ty(..)]`. struct Meta { + /// Whether this element has an associated scope defined by the `#[scope]` macro. scope: bool, + /// Whether a custom cast implementation will be defined for this type. cast: bool, name: Option<String>, title: Option<String>, diff --git a/crates/typst/src/foundations/element.rs b/crates/typst/src/foundations/element.rs index 47077eb8c4bd..e58fc89ed82a 100644 --- a/crates/typst/src/foundations/element.rs +++ b/crates/typst/src/foundations/element.rs @@ -261,18 +261,31 @@ pub trait Set { /// Defines a native element. #[derive(Debug)] pub struct NativeElementData { + /// The element's normal name (e.g. `align`), as exposed to Typst. pub name: &'static str, + /// The element's title case name (e.g. `Align`). pub title: &'static str, + /// The documentation for this element as a string. pub docs: &'static str, + /// A list of alternate search terms for this element. pub keywords: &'static [&'static str], + /// The constructor for this element (see [`Construct`]). pub construct: fn(&mut Engine, &mut Args) -> SourceResult<Content>, + /// Executes this element's set rule (see [`Set`]). pub set: fn(&mut Engine, &mut Args) -> SourceResult<Styles>, + /// Gets the vtable for one of this element's capabilities + /// (see [`Capable`]). pub vtable: fn(capability: TypeId) -> Option<*const ()>, + /// Gets the numeric index of this field by its name. pub field_id: fn(name: &str) -> Option<u8>, + /// Gets the name of a field by its numeric index. pub field_name: fn(u8) -> Option<&'static str>, + /// Get the field with the given ID in the presence of styles (see [`Fields`]). pub field_from_styles: fn(u8, StyleChain) -> Option<Value>, + /// Gets the localized name for this element (see [`LocalName`][crate::text::LocalName]). pub local_name: Option<fn(Lang, Option<Region>) -> &'static str>, pub scope: Lazy<Scope>, + /// A list of parameter information for each field. pub params: Lazy<Vec<ParamInfo>>, } diff --git a/crates/typst/src/foundations/func.rs b/crates/typst/src/foundations/func.rs index 75abc7ad1dbb..21ded1f2a24a 100644 --- a/crates/typst/src/foundations/func.rs +++ b/crates/typst/src/foundations/func.rs @@ -446,14 +446,22 @@ pub trait NativeFunc { /// Defines a native function. #[derive(Debug)] pub struct NativeFuncData { + /// Invokes the function from Typst. pub function: fn(&mut Engine, Tracked<Context>, &mut Args) -> SourceResult<Value>, + /// The function's normal name (e.g. `align`), as exposed to Typst. pub name: &'static str, + /// The function's title case name (e.g. `Align`). pub title: &'static str, + /// The documentation for this function as a string. pub docs: &'static str, + /// A list of alternate search terms for this function. pub keywords: &'static [&'static str], + /// Whether this function makes use of context. pub contextual: bool, pub scope: Lazy<Scope>, + /// A list of parameter information for each parameter. pub params: Lazy<Vec<ParamInfo>>, + /// Information about the return value of this function. pub returns: Lazy<CastInfo>, } diff --git a/crates/typst/src/foundations/ty.rs b/crates/typst/src/foundations/ty.rs index f199b85ea1a9..b34393b3e26a 100644 --- a/crates/typst/src/foundations/ty.rs +++ b/crates/typst/src/foundations/ty.rs @@ -189,11 +189,16 @@ pub trait NativeType { /// Defines a native type. #[derive(Debug)] pub struct NativeTypeData { + /// The type's normal name (e.g. `str`), as exposed to Typst. pub name: &'static str, pub long_name: &'static str, + /// The function's title case name (e.g. `String`). pub title: &'static str, + /// The documentation for this type as a string. pub docs: &'static str, + /// A list of alternate search terms for this type. pub keywords: &'static [&'static str], + /// The constructor for this type. pub constructor: Lazy<Option<&'static NativeFuncData>>, pub scope: Lazy<Scope>, }