Skip to content

Fix markdown param docs and overload - #1258

Open
ligurio wants to merge 2 commits into
EmmyLuaLs:mainfrom
ligurio:ligurio/gh-xxxx-fix-markdown-param-docs
Open

ligurio wants to merge 2 commits into
EmmyLuaLs:mainfrom
ligurio:ligurio/gh-xxxx-fix-markdown-param-docs

Conversation

@ligurio

@ligurio ligurio commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Needed for luafun/luafun#100

The markdown generator ignored the parameter and return-value
documentation that the HTML generator renders as a dedicated
"Parameters" / "Returns" table:

- for a function whose type is a `Signature`, `render_signature_type`
  appended raw `@param `name` - description` / `@return  - description`
  lines to the signature;
- for a function member declared with `---@field name fun(...)`
  (`DocFunction`) the `@param` descriptions were not attached to the
  member and were dropped completely.

Add `MemberParam` rows to `MemberDoc` and fill them from the function
type in `typ_gen` / `mod_gen`, mirroring the HTML generator's
`function_details_html`, and render a `**Parameters**` / `**Returns**`
block from the markdown templates.  Drop the raw `@param` / `@return`
lines from `render_signature_type`.

Add an integration test covering a documented function member.

Needed for luafun/luafun#100
The HTML generator renders `---@overload` declarations in a
dedicated "Overloads" block (`signature_overloads_html`), but the
markdown generator ignored them completely: `MemberDoc` had no
`overloads` field and the templates had no block for it.

Add `MemberDoc.overloads`, fill it from the function signature in
`typ_gen` / `mod_gen` (mirroring the HTML generator) and render a
`**Overloads**` block from the markdown templates.

Add an integration test covering a function with an `---@overload`.

Needed for luafun/luafun#100

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Overall this is a clean, well-structured change that mirrors the HTML generator's behavior in the markdown generator. The Default derive + ..Default::default() pattern is idiomatic, and the new tests are a good addition. A few issues worth addressing:

1. function_details_md silently drops undocumented params/returns (behavioral concern)

In render.rs, the function returns None unless at least one param/return has a description:

let has_description = params.iter().any(|p| p.description.is_some())
    || returns.iter().any(|r| r.description.is_some());
has_description.then_some((params, returns))

This means a function with documented types but no descriptions (e.g. ---@param a number with no @text) will render no Parameters/Returns block at all. That's a regression relative to the previous behavior, which at least rendered the signature. If the intent is only to suppress empty tables, consider returning the rows whenever there is at least one param or return, and letting the template decide. At minimum, document this trade-off explicitly (the doc comment mentions it, but the consequence — losing type-only params — isn't obvious).

2. render_param_type can return None for a valid empty render, but returns in the DocFunction branch is unconditional

In the DocFunction branch:

let returns = vec![MemberParam {
    name: String::new(),
    type_text: Some(render_typ(db, func.get_ret(), RenderLevel::Documentation)),
    description: None,
}];

Unlike render_param_type, this does not guard against an empty string. If render_typ returns "", you'll get type_text: Some(""), and the template will emit (** **) — an empty italic span. Use render_param_type(db, Some(func.get_ret())) here for consistency.

3. function_overloads_md ignores the DocFunction case

function_details_md handles both LuaType::Signature and LuaType::DocFunction, but function_overloads_md only handles Signature:

let LuaType::Signature(signature_id) = typ else {
    return Vec::new();
};

This is probably fine (overloads only exist on signatures), but the asymmetry is worth a comment, since a reader may expect parity with the sibling function.

4. Template duplication

The Parameters/Returns/Overloads block is copy-pasted verbatim across four locations (lua_module_template.tl ×2, lua_type_template.tl ×2). Consider extracting it into a Tera macro/include (e.g. {% include "member_details.tl" %}) to avoid drift when the markup changes.

5. Minor: MemberParam derives

MemberParam derives Clone but MemberDoc does not. If MemberDoc is ever cloned (e.g. for the index), the inconsistency will bite. Not blocking, but worth aligning.

6. Test robustness

Both new tests assert pages.len() == 1 and read pages[0]. This is fine for the fixture, but the filter_map(|entry| entry.ok()) silently swallows IO errors — a read_dir failure on one entry would just reduce the count and produce a confusing assertion failure. Prefer entry.unwrap() or propagate the error.

7. Test duplication

markdown_overloads.rs and markdown_params.rs share ~40 lines of identical fixture/runner code. Consider a shared tests/common/mod.rs helper.

Positive notes

  • Removing the raw @param/@return text dump from render_signature_type is the right call and is covered by the new assertion.
  • skip_serializing_if = "Vec::is_empty" keeps the JSON index clean.
  • Doc comments on the new fields are helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant