feat(docs): group framework functions by visibility#11537
Conversation
| include_dep_diagrams: false | ||
| include_call_diagrams: false | ||
| include_module_toc: true | ||
| snapshot_kind: text |
There was a problem hiding this comment.
to get rid of these snapshot_kind: text changes you should update your cargo-insta with cargo install cargo-insta --force
80554c5 to
9b3f6fd
Compare
9b3f6fd to
5f5328c
Compare
# Description of change
The Move framework reference docs hosted at docs.iota.org/references/iota-move
are generated by `move-docgen` from the Move sources of the system packages.
Today, every function in a module is rendered as a flat list under the module
heading, so `public(package)` helpers, `entry` admin functions, and the
genuinely-public consumer API all sit side by side. For modules like
`iota::coin` or `iota_system`, that makes it tedious to figure out what part
of the surface is actually meant to be called by a downstream developer.
This change makes `move-docgen` group functions by visibility and tunes the
output for the Docusaurus site that consumes it.
## What changed
**`move-docgen` (`external-crates/move/crates/move-docgen/src/docgen.rs`)**
- Functions in each module are now emitted in five buckets, in this order:
1. `Public Functions` – the surface most consumers care about.
2. `Entry Functions` – everything tagged `entry` (PTB-callable).
3. `Public Package Functions` – `public(package)` cross-module helpers.
4. `Public Friend Functions` – legacy `public(friend)`.
5. `Private Functions` – module-internal.
Each non-empty bucket becomes its own `H2` section with a heading anchor,
and individual function headings inside the bucket are `H3`. Definition
order is preserved within a bucket.
- Buckets 3–5 are wrapped in a collapsed `<details>` block, so the public
surface is what's open by default and the internals do not push it below
the fold on large modules.
- The redundant `Function` / `Macro function` prefix on per-function
headings has been dropped. The parent bucket already conveys the kind,
so `### Function \`join\`` is now just `### \`join\``. Macros are marked
as `### \`name\` (macro)`.
- New `DocgenFlags::include_module_toc` (default `true`, preserving plain
markdown rendering). When the output is hosted by a renderer that builds
its own heading sidebar (Docusaurus, in our case), the in-page TOC is
pure duplication.
**`move-package` (`external-crates/move/crates/move-package/src/...`)**
- `BuildConfig` gains a `docgen_flags: DocgenFlags` field (skip from clap;
consumers driving the build programmatically can override the defaults).
This replaces a long-standing `TODO this should be configurable` in
`compiled_package.rs` and lets the framework build opt out of the
in-page TOC without further plumbing.
**`iota-framework` build (`crates/iota-framework/tests/build-system-packages.rs`)**
- Sets `docgen_flags: DocgenFlags { include_module_toc: false, .. }` when
building the system packages, so the published docs no longer carry the
duplicate in-page table of contents next to Docusaurus's auto-generated
one.
**Tests**
- Every `move-docgen-tests` insta snapshot has been refreshed to reflect
the new heading layout. The 12 docgen tests cover annotations, code
blocks, constants, all visibility levels, enums, and root templates.
## Motivation
This is the fix for the `move-docgen` improvement Alexander Sporn asked for
in #6261: today `public(package)` functions are interleaved with public and
entry functions, which makes it hard for a developer browsing the system
package docs to quickly understand the module's public API. Grouping by
visibility and collapsing internals addresses the first half of that
request. The second half of the issue — surfacing dot-syntax callable
methods next to their struct, and optionally splitting each module across
multiple pages — is a larger change and will be a separate follow-up.
## Links to any relevant issues
Refs #6261
## How the change has been tested
- [x] Basic tests (linting, compilation, formatting, unit/integration tests)
- [x] Patch-specific tests (correctness, functionality coverage)
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] I have checked that new and existing unit tests pass locally with my changes
Specifically:
- `cargo test -p move-docgen-tests` — all 12 snapshots pass after the
heading-format/grouping/collapse changes.
- `cargo clippy -p move-docgen --no-deps` — clean.
- `cargo check -p iota-framework` and `cargo check -p move-docgen
-p move-package` — clean.
- `UPDATE=1 cargo test -p iota-framework --test build-system-packages` —
regenerates `docs/generated-docs/framework/` end-to-end; inspected
`iota/coin.mdx` and `iota_system/iota_system.mdx` show the five
visibility buckets in the new order, with Public/Entry expanded and
Package/Private wrapped in `<details>`. No in-page TOC.
- Local Docusaurus dev server (`pnpm iota-docs dev`): the regenerated
framework pages render without MDX errors (the 4 pre-existing MDX
failures on `IotaSystemStateSummaryV1/V2.md` are unrelated — they come
from `super::...` rustdoc-style links in the TS SDK's JSDoc).
### Release Notes
- [ ] Protocol:
- [ ] Nodes (Validators and Full nodes):
- [ ] Indexer:
- [ ] JSON-RPC:
- [ ] GraphQL:
- [ ] CLI:
- [ ] Rust SDK:
- [ ] gRPC:
5f5328c to
f146e96
Compare
Yes, but needs a change in the docs folder to trigger: iota/.github/workflows/preview_wiki.yml Line 16 in 11940e2 |
|
I ran the wiki-preview action manually from this branch but it seems to not re-generate the files: |
…TOC sections - Alphabetize functions within each visibility bucket. - Stop wrapping Public Package and Private buckets in <details>; only the legacy Public Friend bucket stays collapsed. - Emit dot-syntax methods (functions whose first parameter is an in-module datatype) as section headers directly under their struct/enum. - Wrap all structs and enums in top-level "Structs" and "Enums" sections so the right-hand TOC has explicit categories alongside Constants and the function buckets. - Bump per-module frontmatter to `toc_max_heading_level: 4` so per-struct method headings surface in Docusaurus's right-nav. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ntmatter
Per-file `toc_max_heading_level: 4` in the generated framework MDX
broke MDX compilation ("Expected component Details to be defined")
on every framework page. Move the setting into themeConfig in
docusaurus.config.js so methods (H4) appear in the right-hand TOC
without poisoning the per-file frontmatter.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
✅ Vercel Preview Deployment is ready! |
`move-docgen` emits framework reference code as raw `<pre><code>` with `<b>` keywords and inline `<a>` cross-references. Adding `class` or `className` to these tags breaks MDX's HTML mode on the multi-line content, so syntax styling has to live in the docs site stylesheet instead. Adds rules in `docs/site/src/css/custom.css` that: - give the keyword `<b>` tags the primary color so `public`, `fun`, `struct`, etc. pop visually, - strip the spurious `<p>` margin MDX adds inside `<code>`, - style inline cross-reference `<a>` links with a subtle dashed underline that becomes solid on hover, - give the block a proper background, padding, and rounded border. The selectors use `:has(> code > b)` so they only match the docgen flavor of code blocks — Prism-rendered fenced ```move blocks elsewhere in the site are untouched. Also picks up two missed `move-docgen-tests` snapshot updates in `const_string/` left over from the `DocgenFlags` change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
✅ Vercel Preview Deployment is ready! |
MDX strips leading whitespace from each line inside `<code>` because it parses the content as a paragraph, which silently dropped the 4-space indent from every Move implementation body. Encode the leading spaces as ` ` in the framework MDX post-processing so the browser still renders them as regular spaces. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
✅ Vercel Preview Deployment is ready! |
`clippy::uninlined_format_args` enforced as deny in CI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
✅ Vercel Preview Deployment is ready! |
Methods listed under each struct/enum now appear in the same order as the module's free-function buckets (Public, Entry, Public(package), Public(friend), Private), alphabetized within each visibility group. Same ordering shows up directly in the right-hand TOC. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
✅ Vercel Preview Deployment is ready! |
Methods on a struct/enum now get the same visibility-bucket sub-sections as free functions (Public, Entry, Public(package), Public(friend), Private), each non-empty bucket emitted as its own heading under the datatype. Public(friend) stays in a collapsed `<details>` like the module-level bucket; the others render inline. Docusaurus TOC max heading level bumped from 4 to 5 so the deeper method headings show in the right-hand navigation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
✅ Vercel Preview Deployment is ready! |
Drop the per-visibility section headers (Public Functions / Entry Functions / …) and flatten every function/method into a single sorted list. Each function heading carries an inline color-coded visibility marker — `pub`, `entry`, `pub-pkg`, `pub-friend`, `prv` — which the right-hand TOC picks up automatically because Docusaurus extracts the full heading content. - `move-docgen`: every function heading now ends in `<span class="move-vis move-vis-<vis>">…</span>` and the module's free functions live under one `Module Functions` heading. - `docs/site/src/css/custom.css`: stylesheet hooks color each marker (blue for public, green for entry, purple for package, gray for friend, orange for private) and the same colors carry over into the TOC entries. - `docs/site/docusaurus.config.js`: TOC max heading level back to 4 (one level shallower now that the visibility sub-headers are gone). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
✅ Vercel Preview Deployment is ready! |
…unctions - Constants named `E[A-Z]…` (the Move convention for abort codes, e.g. `EMaximumSupplyReached`) are emitted as section headers with a red `err` tag and appear in the right-hand TOC under `Constants`. Non-error constants stay as flat code blocks under the heading so the TOC doesn't fill up with numeric / config constants. - Free module functions get an additional yellow `module` tag next to the visibility tag, so a reader scanning the TOC can tell a free function from a struct/enum method at a glance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Every named constant now gets a section header so it appears in the right-hand TOC, with an inline tag indicating its role: - `err` (red) for error abort codes (`E[A-Z]…`). - `const` (teal) for everything else. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
✅ Vercel Preview Deployment is ready! |
Each struct heading gets a green `struct` tag and each enum heading a magenta `enum` tag, matching the visibility/role tag pattern already used for functions and constants. Helps the right-hand TOC stay self-describing now that the per-visibility section headers are gone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
✅ Vercel Preview Deployment is ready! |
…he top - Move the visibility / role tag to the front of each heading (`pub module \`create_currency\`` instead of `\`create_currency\` pub module`). Easier to skim a long TOC when the tag is the leftmost element. - Reorder module sections so `Module Functions` is the first H2 in the page, followed by `Structs`, `Enums`, `Constants`. Modules usually have only a handful of free functions but many struct methods, so keeping the free functions at the top of the right-hand TOC keeps the scannable surface above the long datatype lists. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
✅ Vercel Preview Deployment is ready! |
- Remove the yellow `module` tag from free module functions; the visibility tag alone is enough now that Module Functions is the first section in the page. Cleans up the `extra_marker` parameter that fell out of use. - Rename `pub-pkg` → `pub(pkg)` and `pub-friend` → `pub(friend)` so the inline tag matches the actual Move source-level visibility syntax. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ions `public` and `entry` are orthogonal in Move: `public` controls cross-module callability, `entry` controls top-level PTB callability. A `public entry fun` is reachable both ways, so emit both tags side by side instead of collapsing the function into a single `entry` bucket. - `public entry fun` → `pub entry` - `public(pkg) entry fun` → `pub(pkg) entry` - `entry fun` (private+entry) → `entry` only (the `prv` tag would be noise since `entry` already conveys PTB-callability). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
✅ Vercel Preview Deployment is ready! |

Description of change
Restructures the generated Move framework reference docs (rendered at docs.iota.org/references/iota-move) so the public surface of each module is easier to scan.
What changed
move-docgen(external-crates/move/crates/move-docgen/src/docgen.rs)public(friend)bucket stays in a collapsed<details>.StructsandEnumssections so the page has clear categories alongsideConstantsand the function buckets.Function/Macro functionheading prefix is dropped (the parent bucket conveys the kind); macros are marked### \name` (macro)`.DocgenFlags::include_module_toc(defaulttrue) lets renderers that build their own heading sidebar (Docusaurus) skip the duplicate in-page TOC.move-package—BuildConfiggains adocgen_flags: DocgenFlagsfield, replacing a long-standingTODO this should be configurableand letting the framework build opt out of the in-page TOC.iota-frameworkbuild (crates/iota-framework/tests/build-system-packages.rs) — setsdocgen_flags.include_module_toc = falsewhen building the system packages, and addstoc_max_heading_level: 4to each module's frontmatter so per-struct method headings surface in Docusaurus's right-nav.iota-genesis-builder— adds the newdocgen_flagsfield to its exhaustiveMoveBuildConfigconstruction (irrelevant in that path;generate_docs: false).Tests —
move-docgen-testssnapshots and themove-stdlib/iota-frameworkgenerated docs are refreshed.Motivation
Addresses #6261: today
public(package)helpers,entryadmin functions, and the public consumer API are rendered as one flat list, making it hard to tell a module's actual API surface (iota::coin,iota_system) from its internals. Grouping by visibility and surfacing dot-syntax methods next to their struct directly mirrors what Alex asked for.How the change has been tested
Specifically:
cargo test -p move-docgen-tests— all 12 snapshots pass.cargo clippy -p move-docgen -p iota-framework --all-targets -- -D warnings— clean.UPDATE=1 cargo test -p iota-framework --test build-system-packagesandUPDATE=1 cargo test -p move-stdlib check_that_docs_are_updated— regeneratesdocs/generated-docs/framework/and the in-treemove-stdlib/docs/std/*.md; inspectediota/coin.mdx,iota_system/iota_system.mdx, andstd/vector.mdconfirm the new layout (visibility buckets, alphabetized, per-struct method sections).Structs/Enums/Constants/Public Functions/ … as top-level categories with method names nested under each struct.No protocol, node, indexer, RPC, GraphQL, CLI, SDK, or gRPC behaviour changes — purely affects the build-time documentation generator and the markdown it emits, so no Release Notes section.