-
Notifications
You must be signed in to change notification settings - Fork 20
Description
Note: content from https://cppalliance.org/alan/2025/10/28/Alan.html#reflection
The corpus keeps drifting out of sync because every important path in MrDocs duplicates representation by hand. Almost every subsystem reflects data from one format to another, and almost every internal operation traverses those structures. Each time we adjust a field we have to edit dozens of call sites, and even small mistakes create inconsistent state—different copies of the “truth” that evolve independently. Reflection eliminates this churn. If we can describe the corpus once and let the code iterate over those descriptions, the boilerplate disappears, the traversals remain correct, and we stop fighting the same battle.
A lightweight option would be to enforce the corpus from JSON the way we treat configuration, but the volume of metadata in AST makes that impractical. Instead, we lean on compile-time reflection utilities such as Boost.Describe and Boost.mp11. With those libraries we can convert the corpus to any representation, and each generator—including future binary or JSON targets—sees the same schema automatically. MrDocs can even emit the schema that powers each generator, keeping the schema, DOM, and documentation in sync. This approach also fixes the long-standing lag in the XML generator, where updates have historically been manual and error-prone.
sequenceDiagram
participant AST as Clang AST
participant Corpus as Typed Corpus
participant Traits as Reflect Traits
participant DOM as Corpus DOM
participant Generators as Generators
participant Clients as Integrations
AST->>Corpus: Extract symbols
Corpus->>Traits: Publish descriptors
Traits->>DOM: Build type-erased nodes
DOM->>Generators: Supply normalized schema
Generators->>Clients: Deliver outputs
Clients->>Generators: Provide feedback
Generators->>Traits: Request updates
Process: We can start by describing the Symbols, Javadoc, and related classes, shipping each refactor as a dedicated PR so reviews stay contained. Each description removes custom specializations, reverts to = default where possible, and replaces old logic with static asserts that enforce invariants. We generalize the main merge logic first, then update callers such as the AST visitor that walks RecordTranche, ensuring the comments data structure matches the new descriptions. A MRDOCS_DESCRIBE_DERIVED helper can enumerate derived classes so every visit routine becomes generic. Once the C++ side is described, we rebuild the lazy DOM objects on top of Describe so their types mirror the DOM layout directly.
Use cases: Redundant non-member functions like tag_invoke, operator⇔, toString, and merge collapse into shared implementations that use traits unless real customization is required. New generators—binary, JSON, or otherwise—drop in with minimal code because the schema and traversal logic already exist. The XML generator stops maintaining a private representation and simply reads the described elements. We can finally standardize naming conventions (kebab-case or camelCase) because the schema enforces them. Generating the Relax NG Compact file becomes just another output produced from the same description. A metadata walker can then discover auxiliary objects and emit DOM documentation automatically. As a side effect of integrating Boost.mp11, we can extend the tag_invoke context protocol with tuple-based helpers for mrdocs::FromValue, further narrowing the gap between concrete and DOM objects.