Skip to content

Conversation

@gennaroprota
Copy link
Collaborator

@gennaroprota gennaroprota commented Dec 9, 2025

This introduces Boost.Describe and Boost.Mp11 and applies them across metadata types (symbols, enums, inline elements) to replace hand-written sequences of io.map() calls with reflection-based code. This improves maintainability without altering the public API or user-facing features.

@alandefreitas: Please have a look at normalizeMemberName() in SymbolDescribeMapper.hpp: Some names are special-cased there. If you prefer, I can remove the special cases and modify the Handlebars templates to use the canonical names.

@github-actions
Copy link

github-actions bot commented Dec 9, 2025

🚧 Danger.js checks for MrDocs are experimental; expect some rough edges while we tune the rules.

⚠️ Warnings

Warning

Add a brief note about how this change was tested (or why tests are not needed).

🧾 Changes by Scope

Scope Lines Δ Lines + Lines - Files Δ Files + Files ~ Files ↔ Files -
🛠️ Source 1978 1424 554 54 8 46 - -
🤝 Third-party 168 168 - 6 6 - - -
⚙️ CI 42 41 1 1 - 1 - -
📄 Docs 8 8 - 1 - 1 - -
🏗️ Build / Toolchain 5 5 - 1 - 1 - -
Total 2201 1646 555 63 14 49 - -

Legend: Files + (added), Files ~ (modified), Files ↔ (renamed), Files - (removed)

🔝 Top Files

  • src/lib/Support/Reflection/Reflection.cpp (Source): 507 lines Δ (+507 / -0)
  • src/lib/Support/Reflection/MapReflectedType.hpp (Source): 259 lines Δ (+259 / -0)
  • include/mrdocs/Dom/LazyObject.hpp (Source): 234 lines Δ (+138 / -96)

Generated by 🚫 dangerJS against 1425bdf

@gennaroprota gennaroprota force-pushed the develop branch 6 times, most recently from d8c7267 to f3274f4 Compare December 9, 2025 19:06
Copy link
Collaborator

@alandefreitas alandefreitas left a comment

Choose a reason for hiding this comment

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

Great job! 👏😀🎉

uses: alandefreitas/cpp-actions/cmake-workflow@v1.8.12
with:
source-dir: ../third-party/boost_describe
git-repository: https://github.com/boostorg/describe
Copy link
Collaborator

Choose a reason for hiding this comment

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

Setting the url is cheaper in this case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What do you mean?

@alandefreitas alandefreitas changed the title refactor(metadata): integrate Boost.Describe to remove manual mapping boilerplate refactor(metadata): integrate Boost.Describe Dec 9, 2025
@alandefreitas
Copy link
Collaborator

@alandefreitas: Please have a look at normalizeMemberName() in SymbolDescribeMapper.hpp: Some names are special-cased there. If you prefer, I can remove the special cases and modify the Handlebars templates to use the canonical names.

Sorry. I forgot to answer this one. 😬

Yes. We're going to use canonical names for everything sooner or later. Since you already made the effort to split this into two tasks, we can do that later rather than sooner. Reflection will enable all kinds of simplifications in the code from now on.

I leave it up to you, though.

@gennaroprota gennaroprota marked this pull request as draft December 10, 2025 14:09
@gennaroprota gennaroprota force-pushed the develop branch 2 times, most recently from 6bfe8ac to 394c55a Compare December 11, 2025 19:09
@alandefreitas
Copy link
Collaborator

Sometimes we get conflicts if we don't rename things for Handlebars, as you notice with "class" and "functionClass", etc. This is because of how handlebars works with recursion, and it's very annoying. I don't know if it solves your problem, but one solution I was going to propose at some point is adding an "@meta" key to all objects to describe the class name, etc (this can also help with other problems we've been having). This way, we would have the proper information to make the distinction in handlebars.

@gennaroprota gennaroprota force-pushed the develop branch 2 times, most recently from adf50c8 to 7485284 Compare December 24, 2025 11:49
@codecov
Copy link

codecov bot commented Dec 24, 2025

Codecov Report

❌ Patch coverage is 91.82390% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.49%. Comparing base (6cee4af) to head (1425bdf).

Files with missing lines Patch % Lines
src/lib/Support/Reflection/Reflection.cpp 83.87% 10 Missing ⚠️
include/mrdocs/Dom/LazyObject.hpp 95.45% 1 Missing ⚠️
src/lib/Support/Reflection/EnumToString.hpp 85.71% 1 Missing ⚠️
src/lib/Support/Reflection/MapReflectedType.hpp 97.50% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1130      +/-   ##
===========================================
+ Coverage    86.43%   86.49%   +0.06%     
===========================================
  Files          323      326       +3     
  Lines        23958    23828     -130     
===========================================
- Hits         20707    20609      -98     
+ Misses        3251     3219      -32     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gennaroprota gennaroprota force-pushed the develop branch 9 times, most recently from ba65b54 to 45cde41 Compare January 5, 2026 16:24
@gennaroprota gennaroprota force-pushed the develop branch 10 times, most recently from ef512c3 to f66b5b7 Compare January 7, 2026 11:16
@gennaroprota gennaroprota marked this pull request as ready for review January 7, 2026 13:00
@cppalliance-bot
Copy link

cppalliance-bot commented Jan 7, 2026

An automated preview of the documentation is available at https://1130.mrdocs.prtest2.cppalliance.org/index.html

If more commits are pushed to the pull request, the docs will rebuild at the same URL.

2026-01-16 17:32:44 UTC

Copy link
Collaborator

@alandefreitas alandefreitas left a comment

Choose a reason for hiding this comment

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

That's really nice. Most comments I left are either compliments or suggestions for future issues. Regarding your question about generalizing the process and variable names, I would also leave that to another smaller issue.

{
MRDOCS_ASSERT(domCorpus);
mapReflectedType(io, I, domCorpus);
io.map("class", std::string("symbol"));
Copy link
Collaborator

Choose a reason for hiding this comment

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

We're going to need another proper solution to this (another issue). Handlebars often need information about the class and so on, and these often clash with object members no matter what name we decide for the key. I was thinking of something like "@meta" where we would always provide a lazy representation of the class name, etc, to handlebars.

doc::ImageInline const& I,
DomCorpus const* domCorpus)
{
tag_invoke(t, io, dynamic_cast<doc::Inline const&>(I), domCorpus);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Boost.Describe can also iterate the base classes in the function.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, done.

Copy link
Collaborator

Choose a reason for hiding this comment

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

That's really nice. Is there a way to reduce compile time (or address another issue) so that any TU that includes this header doesn't have to parse all metadata-related headers? I don't know if there's a reasonable way to forward declare the struct descriptions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hmm, I'm pretty sure the BOOST_DESCRIBE_xxx() macros require a defining declaration. Or did you have something specific in mind to work around this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure I understand. Do you mean a forward declaration for the specializations those macros define is something that wouldn't work? I was thinking just of forward declarations so everything could be encapsulated. And of course we would replicate the macro that generates the forward declarations we need. Instead of completely describing something, we would just forward declare the classes that describing something generates. We could also have a macro that forward declares whatever classes describing would create. Doesn't that work?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've not dug into the implementation details of Boost.Describe, but I guess it generates hidden internal structures that use pointers to members, and one cannot take a pointer to member of an incomplete type.

However, the current design already provides, I think, the separation you are asking about:

  • The struct definitions live in public headers.

  • The BOOST_DESCRIBE_STRUCT() invocations live in Reflection.hpp, which is private (src/lib/).

  • Only .cpp files in src/lib/ include Reflection.hpp. And there are only four of them (not one, but a small number anyway :-)).

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, the requirements are met. My concern was only about compilation time. We can open an issue and just refer to the comment. We can investigate this later because it's not going to be that simple anyway.

@gennaroprota gennaroprota force-pushed the develop branch 4 times, most recently from 2de4d9d to dd3fb73 Compare January 12, 2026 17:13
@gennaroprota gennaroprota force-pushed the develop branch 3 times, most recently from e5fe9a8 to cd9b8ca Compare January 16, 2026 16:41
… boilerplate

This introduces Boost.Describe and Boost.Mp11 and applies them across
metadata types (symbols, enums, inline elements) to replace hand-written
io.map() calls with reflection-based code. This improves maintainability
without altering the public API or user-facing features.

Boost.Describe and Boost.Mp11 are *private* dependencies, i.e. they are
not used in any public Mr. Docs include.
Reason: Avoiding timeouts in the Clang 21 + MSan tests.
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.

5 participants