Skip to content

vex-doc Reference

This document describes vex-doc — the documentation generator for Vex projects.


Purpose

vex-doc generates API documentation from Vex source files (.vx). It supports:

  • JSON — Machine-readable documentation model
  • Markdown — Single-page human-readable docs
  • Multi-page — Per-type pages with index
  • VitePress — Multi-page + sidebar.json + config.mts
  • Docusaurus — Multi-page + sidebars.js + category.json

Command Usage

bash
# Single-page markdown (default)
vex doc src/main.vx

# JSON output
vex doc --format json src/main.vx

# Multi-page to directory
vex doc --format multipage -o docs/api src/

# VitePress-ready docs
vex doc --format vitepress -o docs/api src/

# Docusaurus-ready docs
vex doc --format docusaurus -o docs/api src/

CLI Flags

FlagDescriptionDefault
INPUTSource file or directoryrequired
-o, --outputOutput file or directorystdout / docs/api
-f, --formatOutput formatmarkdown
--jsonShorthand for --format json

Supported Formats

FormatOutputUse Case
jsonSingle JSON fileCI/CD pipelines, custom renderers
markdown / mdSingle .md fileREADME integration, quick preview
multipageDirectory of .md filesStatic site hosting
vitepress.md + .vitepress/ configVitePress documentation sites
docusaurus.md + sidebars.jsDocusaurus documentation sites

Architecture

Pipeline

.vx source → Parser (Rowan CST) → Generator → DocModel (JSON) → Composer

                                                    ┌───────────────┼───────────────┐
                                                    ↓               ↓               ↓
                                               Markdown       VitePress       Docusaurus
                                             (single page)   (multi-page)    (multi-page)

Crate Structure

tools/vex-doc/src/
├── lib.rs              # Public API: generate_json_model(), generate_markdown_content()
├── generator.rs        # Raw Rowan CST → DocModel extraction (core engine)
├── doc_model.rs        # Data model: DocItem, DocType, FieldItem, GenericParam, etc.
├── markdown.rs         # Single-page markdown composer
├── multi_page.rs       # Multi-page + VitePress + Docusaurus composers
├── parser.rs           # Doc comment parser (@param, @return, @example, etc.)
├── naming.rs           # Name resolution utilities
└── rowan_generator.rs  # Thin delegate to generator.rs

DocModel Schema

The DocModel is the central data structure passed from generator to composers.

DocItem Fields

FieldTypeDescription
idStringUnique identifier (e.g., Point, Point.new)
kindStringItem kind: fn, struct, enum, contract, const, type, policy
nameStringDisplay name (e.g., Point.new)
locationLocationSource file, line, col, end_line, end_col
signatureStringFull signature string
docsParsedCommentParsed doc comments (summary, details, @param, @return, etc.)
parent_idOption<String>Parent type for methods (e.g., "Point")
relationsVec<String>Contract implementations
paramsVec<TypedParam>Function parameters with types
return_typeOption<DocType>Return type
fieldsVec<FieldItem>Struct fields (name, type, visibility, doc, tag)
variantsVec<VariantItem>Enum variants (name, payload types, doc)
receiverOption<ReceiverInfo>Method receiver (self_name, type_name, is_ref, is_mut)
visibilityOption<String>"export", "public", "private"
generic_paramsVec<GenericParam>Type parameters with bounds and defaults
where_clausesVec<WhereClause>Where clause predicates
is_asyncOption<bool>Async function flag
is_gpuOption<bool>GPU function flag
is_unsafeOption<bool>Unsafe function flag
is_constOption<bool>Const function flag

GenericParam

FieldTypeDescription
nameStringParameter name (e.g., T)
boundsVec<String>Contract bounds (e.g., ["Display", "Clone"])
defaultOption<String>Default type (e.g., "i32")
is_constboolWhether this is a const generic
const_typeOption<String>Type for const params (e.g., "usize")

TypedParam

FieldTypeDescription
nameStringParameter name
tyDocTypeType information
default_valueOption<String>Default value expression
is_variadicboolWhether parameter is variadic (...)

Doc Comment Syntax

vex-doc recognizes the following doc comment tags:

vex
/// Summary line
///
/// Detailed description paragraph.
///
/// @param name - Parameter description
/// @return Description of return value
/// @example
/// let x = Point.new(1.0, 2.0);
/// @deprecated Use NewThing instead
/// @see OtherType
/// @throws ErrorType - When something fails
/// @since 1.2.0
/// @note Important information

Supported Tags

TagDescription
@paramParameter documentation
@return / @returnsReturn value description
@exampleCode example block
@deprecatedDeprecation notice
@seeCross-reference
@throws / @raisesError documentation
@sinceVersion introduced
@noteAdditional notes
@linkInline reference to another item

Generator Details

CST Traversal Strategy

The generator uses raw Rowan CST traversal (not typed AST wrappers) because:

  1. The typed AST wrappers had SyntaxKind mismatches (FUNCTION vs NODE_FUNCTION)
  2. Type extraction needed to handle both keyword tokens (KW_I32) and node types (NODE_PATH_TYPE)
  3. Receiver patterns in Vex (fn (self: &Type) method()) require custom traversal

Key Helper Functions

FunctionPurpose
get_fn_name()Extracts function name, handling receivers and qualified names (Vec.new)
get_type_text_any()Extracts type text after : — handles both keyword tokens and type nodes
extract_return_type()Finds return type after R_PAREN → COLON
extract_receiver()Parses NODE_RECEIVER for self name, type, ref/mut
extract_type_params()Extracts generic params with bounds from NODE_TYPE_PARAMS
extract_where_clauses()Extracts where predicates from NODE_WHERE_CLAUSE
extract_fn_flags()Detects async, gpu, unsafe, const keywords before fn
extract_default_value()Parses = expr for param/type param defaults

Multi-Page Output Structure

output_dir/
├── index.md                    # API overview with cross-links
├── container.md                # One page per struct
├── shape.md                    # One page per enum  
├── iterator.md                 # One page per contract
├── functions.md                # All standalone functions
├── constants.md                # All constants (if any)
├── types.md                    # All type aliases (if any)

├── .vitepress/                 # VitePress only
│   ├── sidebar.json            # Auto-generated sidebar
│   └── config.mts              # Ready-to-use VitePress config

├── sidebars.js                 # Docusaurus only
└── _category_.json             # Docusaurus only

Extension Points

WhatWhere
Add new item kindgenerator.rs — add SyntaxKind::NODE_* match + extractor
Add new DocItem fielddoc_model.rs — add field, update all initializers in generator.rs
Add new doc tagparser.rs — add tag pattern matching
New output formatmulti_page.rs — add generate_*() function, wire in doc.rs CLI
Custom page templatemulti_page.rs — modify generate_type_page() / generate_category_page()

Released under the MIT License.