Files
rippled/docs/DOCUMENTATION_STANDARDS.md
2026-05-14 10:10:38 +02:00

193 lines
6.5 KiB
Markdown

# XRPLD Documentation Standards
This document defines the canonical format for inline code documentation in the
xrpld codebase. All new and updated code must follow these standards.
## Comment Style
Use Javadoc-style Doxygen comments (`/** ... */`). This matches the dominant
convention in the codebase: ~5,200 existing instances across 569 files.
```cpp
/** Brief description of the entity. */
```
For multi-line documentation, each line is prefixed with ` * ` (space, asterisk,
space):
```cpp
/** Brief description of the entity.
*
* Extended description with behavioral details, invariants,
* and constraints that are not obvious from the signature.
*/
```
`JAVADOC_AUTOBRIEF = YES` is enabled in the Doxyfile, so the first sentence
of any `/** */` block is automatically treated as the brief. An explicit
`@brief` tag is accepted but not required.
The `///` triple-slash style appears in ~37 files (340 instances). It is
valid Doxygen and will not be removed where it exists, but new code should
use `/** */` for consistency with the majority style.
## What to Document
### File-Level (Optional)
The `@file` tag is not currently used anywhere in the codebase. Adding
file-level documentation is encouraged for complex modules where a
high-level overview helps, but it is not required:
```cpp
/** @file
* Defines the Payment transactor for the XRP Ledger.
*
* The Payment transactor handles direct XRP transfers, cross-currency
* payments via the pathfinding engine, and partial payments.
*/
```
Module-level READMEs (e.g., `src/xrpld/peerfinder/README.md`) remain the
primary place for architectural documentation.
### Class / Struct Level
Every class and struct gets a doc block describing:
- What it does (1-2 sentences)
- Key invariants or constraints, if any
- Thread-safety guarantees, if relevant
- Lifecycle notes, if relevant
```cpp
/** Executes a Payment transaction on the XRP Ledger.
*
* Supports direct XRP payments, cross-currency payments via RippleCalc,
* and partial payments (tfPartialPayment). Path count is limited to 6
* with max path length of 8.
*/
class Payment : public Transactor { ... };
```
Target: 2-5 lines for most classes. Complex classes may need more.
### Public Methods and Free Functions
Every public method and free function in headers gets:
- Brief description of behavior (not a restatement of the signature)
- `@param` for each parameter
- `@return` describing what is returned
- `@throw` if it can throw (either `@throw` or `@throws` is acceptable —
the codebase uses both)
- `@note` for non-obvious constraints or edge cases
When a `@param` description wraps, continuation lines are indented with
4 spaces from the `*`:
```cpp
/** Round a Number value to the precision of a given asset.
*
* For IOUs, rounds to the IOU's scale. For XRP and MPT, no rounding
* is performed.
*
* @param asset The relevant asset
* @param value The value to be rounded
* @param scale An exponent value to establish the precision limit of
* `value`. Should be larger than `value.exponent()`.
* @return The rounded Number.
*/
[[nodiscard]] Number
roundToAsset(Asset const& asset, Number const& value, int scale);
```
Target: 1-3 lines of description plus `@param`/`@return`.
### Private Methods
Document private methods only when the logic is non-obvious. A brief
one-line comment is sufficient.
### Enums and Constants
All enums get a brief class-level description. Individual enum values get
inline documentation when the meaning is not self-evident:
```cpp
/** Result codes for transaction processing. */
enum TERCode
{
tesSUCCESS = 0, /**< Transaction succeeded. */
tecCLAIM = 100, /**< Fee claimed; transaction failed. */
tecPATH_PARTIAL = 101, /**< Path could not deliver full amount. */
};
```
## What NOT to Document
- Do not paraphrase the function signature. `/** Returns the account ID. */`
on `AccountID getAccountID()` adds zero information.
- Do not document what is obvious from well-named identifiers.
- Do not reference specific issues, PRs, or task numbers. These belong in
commit messages and rot as the codebase evolves.
- Do not add multi-paragraph docstrings. If it takes that long to explain,
the code may need restructuring.
- Do not document `.cpp` implementation files exhaustively. Focus docs on
headers where the public interface is defined.
## Quality Over Quantity
Wrong documentation is worse than no documentation. Every doc comment must
accurately describe the current behavior. When in doubt:
- Read the implementation before writing the doc
- Cross-reference against test files for edge cases
- Use `@note` to flag subtle behavior that has caught contributors before
## Doxygen Tags Reference
Tags in regular use across the codebase:
| Tag | Codebase Usage | Purpose |
|-----|----------------|---------|
| `@brief` | ~2,500 instances | Brief description (optional — autobrief is enabled) |
| `@param` | ~2,400 instances | Function parameter description |
| `@return` | ~2,200 instances | Return value description |
| `@note` | ~270 instances | Important behavioral note or caveat |
| `@throw` / `@throws` | ~450 instances combined | Exception specification |
| `@see` | ~64 instances | Cross-reference to related entities |
| `@tparam` | ~43 instances | Template parameter description |
Tags used rarely but accepted:
| Tag | Codebase Usage | Purpose |
|-----|----------------|---------|
| `@invariant` | ~13 instances | Property that must always hold |
| `@pre` | ~3 instances | Precondition |
| `@file` | 0 instances | File-level description (new convention, optional) |
## Enforcement
Documentation coverage is measured by [coverxygen](https://github.com/psycofdj/coverxygen)
and enforced in CI:
- PRs cannot decrease documentation coverage (`no_decrease` ratchet mode)
- New files added in a PR require >= 80% doc coverage
- Module-specific thresholds increase quarterly
- The doc-review GitHub Action checks whether code changes invalidate
existing documentation
Coverage is measured against public API surface: classes, structs,
functions, enums, typedefs, and variables. Private implementation details
are not counted.
## Style Notes
- Doc comments go immediately before the entity they describe (no blank
line between the comment and the declaration)
- Keep `@param` descriptions on a single line when possible
- For wrapped `@param` descriptions, indent continuation lines 4 spaces
from the `*`
- Use `@see` sparingly — only when the relationship is non-obvious
- Code style (braces, line width, formatting) is governed by `.clang-format`
and is independent of these documentation standards