diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b735644c2..4b8423e106 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -432,6 +432,38 @@ jobs: run: | rm -r ../third-party/llvm-project + - name: Install Boost.Describe + uses: alandefreitas/cpp-actions/cmake-workflow@v1.8.12 + with: + source-dir: build/third-party/source/boost_describe + git-repository: https://github.com/boostorg/describe + git-tag: boost-1.89.0 + build-dir: ${sourceDir}/build + cc: ${{ steps.setup-cpp.outputs.cc }} + cxx: ${{ steps.setup-cpp.outputs.cxx }} + build-type: Release + shared: false + install: true + install-prefix: ${sourceDir}/install + run-tests: false + trace-commands: true + + - name: Install Boost.Mp11 + uses: alandefreitas/cpp-actions/cmake-workflow@v1.8.12 + with: + source-dir: build/third-party/source/boost_mp11 + git-repository: https://github.com/boostorg/mp11 + git-tag: boost-1.89.0 + build-dir: ${sourceDir}/build + cc: ${{ steps.setup-cpp.outputs.cc }} + cxx: ${{ steps.setup-cpp.outputs.cxx }} + build-type: Release + shared: false + install: true + install-prefix: ${sourceDir}/install + run-tests: false + trace-commands: true + - name: Install Duktape uses: alandefreitas/cpp-actions/cmake-workflow@v1.8.12 with: @@ -804,6 +836,24 @@ jobs: modules-exclude-paths: '' trace-commands: true + - name: Clone Boost.Describe + uses: alandefreitas/cpp-actions/boost-clone@v1.8.12 + id: boost-describe-clone + with: + branch: develop + modules: describe + boost-dir: boost + trace-commands: true + + - name: Clone Boost.Mp11 + uses: alandefreitas/cpp-actions/boost-clone@v1.8.12 + id: boost-mp11-clone + with: + branch: develop + modules: mp11 + boost-dir: boost + trace-commands: true + - name: Set up llvm-symbolizer if: ${{ runner.os != 'Windows' }} run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index cd2db0f870..8dc4341ab7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -171,6 +171,20 @@ else() ) endif() +# Boost.Describe + Boost.Mp11 (header-only, fetched via bootstrap.py recipes) +set(BOOST_DESCRIBE_ROOT "${CMAKE_SOURCE_DIR}/build/third-party/source/boost_describe") +set(BOOST_MP11_ROOT "${CMAKE_SOURCE_DIR}/build/third-party/source/boost_mp11") + +add_library(boost_mp11 INTERFACE) +target_include_directories(boost_mp11 INTERFACE "${BOOST_MP11_ROOT}/include") + +add_library(boost_describe INTERFACE) +target_include_directories(boost_describe INTERFACE "${BOOST_DESCRIBE_ROOT}/include") +target_link_libraries(boost_describe INTERFACE boost_mp11) +set_target_properties(boost_describe boost_mp11 PROPERTIES + EXPORT_NAME "" +) + #------------------------------------------------- # # Docs build @@ -208,6 +222,8 @@ if (MRDOCS_DOCUMENTATION_BUILD) "${BIN_INCLUDE_DIR}" ) + target_link_libraries(mrdocs-documentation-build PRIVATE boost_describe boost_mp11) + # Other defines so headers compile standalone target_compile_definitions(mrdocs-documentation-build PRIVATE MRDOCS_STATIC_LINK) @@ -322,6 +338,8 @@ target_include_directories(mrdocs-core PUBLIC "$" "$" + "$" + "$" "$" PRIVATE "${PROJECT_SOURCE_DIR}/src" diff --git a/docs/mrdocs.yml b/docs/mrdocs.yml index 7692b1090e..22d50a84d9 100644 --- a/docs/mrdocs.yml +++ b/docs/mrdocs.yml @@ -13,6 +13,14 @@ implementation-defined: - 'mrdocs::detail' - 'mrdocs::report::detail' - 'mrdocs::dom::detail' +exclude-symbols: + # Symbols defined when using the Boost.Describe macros. + - '**::boost_base_descriptor_fn' + - '**::boost_public_member_descriptor_fn' + - '**::boost_protected_member_descriptor_fn' + - '**::boost_private_member_descriptor_fn' + - '**::boost_enum_descriptor_fn' + - '**::should_use_BOOST_DESCRIBE_NESTED_ENUM' multipage: true generator: adoc cmake: '-D MRDOCS_DOCUMENTATION_BUILD=ON' diff --git a/include/mrdocs/Dom/LazyArray.hpp b/include/mrdocs/Dom/LazyArray.hpp index 88d8f9039c..bad0a8696b 100644 --- a/include/mrdocs/Dom/LazyArray.hpp +++ b/include/mrdocs/Dom/LazyArray.hpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2024 Alan de Freitas (alandefreitas@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -211,6 +212,26 @@ TransformArray(T const& arr, F const& f) } } // dom + +class DomCorpus; + +/** Map a vector of strings to a @ref dom::Value object. + + @param v The output parameter to receive the dom::Value. + @param elems The vector of T's to convert. + @param domCorpus The DomCorpus used to resolve references. + */ +template +void +tag_invoke( + dom::ValueFromTag, + dom::Value& v, + std::vector const& elems, + DomCorpus const* domCorpus) +{ + v = dom::LazyArray(elems, domCorpus); +} + } // mrdocs diff --git a/include/mrdocs/Metadata/DocComment/Inline/ImageInline.hpp b/include/mrdocs/Metadata/DocComment/Inline/ImageInline.hpp index 3a9c441e3c..d465c98fae 100644 --- a/include/mrdocs/Metadata/DocComment/Inline/ImageInline.hpp +++ b/include/mrdocs/Metadata/DocComment/Inline/ImageInline.hpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2025 Alan de Freitas (alandefreitas@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -12,9 +13,11 @@ #ifndef MRDOCS_API_METADATA_DOCCOMMENT_INLINE_IMAGEINLINE_HPP #define MRDOCS_API_METADATA_DOCCOMMENT_INLINE_IMAGEINLINE_HPP +#include #include #include #include +#include #include namespace mrdocs::doc { @@ -52,6 +55,12 @@ struct ImageInline final bool operator==(ImageInline const&) const noexcept = default; }; +BOOST_DESCRIBE_STRUCT( + ImageInline, + (InlineCommonBase, InlineContainer), + (src, alt) +) + /** Map the @ref ImageInline to a @ref dom::Object. @param t The tag. @@ -69,8 +78,7 @@ tag_invoke( { tag_invoke(t, io, dynamic_cast(I), domCorpus); tag_invoke(t, io, dynamic_cast(I), domCorpus); - io.map("src", I.src); - io.map("alt", I.alt); + mapWithDescribe(io, I, domCorpus); } /** Return the @ref ImageInline as a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Expression.hpp b/include/mrdocs/Metadata/Expression.hpp index 871cd7447b..e4ffb65cba 100644 --- a/include/mrdocs/Metadata/Expression.hpp +++ b/include/mrdocs/Metadata/Expression.hpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -13,12 +14,17 @@ #include #include +#include +#include +#include #include #include #include namespace mrdocs { +class DomCorpus; + /** Represents an expression */ struct ExprInfo @@ -90,6 +96,39 @@ static void merge( } } +/** Map an ExprInfo to a @ref dom::Value object. + + @param v The output parameter to receive the dom::Value. + @param expr The expression info to convert. +*/ +inline +void +tag_invoke( + dom::ValueFromTag, + dom::Value& v, + ExprInfo const& expr, + DomCorpus const*) +{ + v = expr.Written; +} + +/** Map an ExprInfo to a @ref dom::Value object. + + @param v The output parameter to receive the dom::Value. + @param expr The expression info to convert. +*/ +inline +void +tag_invoke( + dom::LazyObjectMapTag, + dom::Value& v, + ExprInfo const& expr, + DomCorpus const* +) +{ + v = expr.Written; +} + } // mrdocs #endif diff --git a/include/mrdocs/Metadata/Symbol/Concept.hpp b/include/mrdocs/Metadata/Symbol/Concept.hpp index 4cbbf2de73..97e12c7e64 100644 --- a/include/mrdocs/Metadata/Symbol/Concept.hpp +++ b/include/mrdocs/Metadata/Symbol/Concept.hpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2024 Krystian Stasiowski (sdkrystian@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -11,12 +12,14 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_CONCEPT_HPP #define MRDOCS_API_METADATA_SYMBOL_CONCEPT_HPP +#include #include #include #include #include #include #include +#include #include namespace mrdocs { @@ -49,6 +52,12 @@ struct ConceptSymbol final operator<=>(ConceptSymbol const& other) const; }; +BOOST_DESCRIBE_STRUCT( + ConceptSymbol, + (SymbolCommonBase), + (Template, Constraint) +) + /** Merge another ConceptSymbol into this one. */ MRDOCS_DECL @@ -71,11 +80,8 @@ tag_invoke( DomCorpus const* domCorpus) { tag_invoke(t, io, I.asInfo(), domCorpus); - io.map("template", I.Template); - if (!I.Constraint.Written.empty()) - { - io.map("constraint", I.Constraint.Written); - } + mapWithDescribe(io, I, domCorpus); + } /** Map the ConceptSymbol to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Symbol/Enum.hpp b/include/mrdocs/Metadata/Symbol/Enum.hpp index ddcad03dcd..faf39dfddb 100644 --- a/include/mrdocs/Metadata/Symbol/Enum.hpp +++ b/include/mrdocs/Metadata/Symbol/Enum.hpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -12,11 +13,13 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_ENUM_HPP #define MRDOCS_API_METADATA_SYMBOL_ENUM_HPP +#include #include #include #include #include #include +#include #include namespace mrdocs { @@ -65,6 +68,12 @@ struct EnumSymbol final } }; +BOOST_DESCRIBE_STRUCT( + EnumSymbol, + (SymbolCommonBase), + (Scoped, UnderlyingType, Constants) +) + /** Return the list of enum constants for this symbol. */ inline diff --git a/include/mrdocs/Metadata/Symbol/EnumConstant.hpp b/include/mrdocs/Metadata/Symbol/EnumConstant.hpp index db5f8d699f..9fe77a86ef 100644 --- a/include/mrdocs/Metadata/Symbol/EnumConstant.hpp +++ b/include/mrdocs/Metadata/Symbol/EnumConstant.hpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -11,8 +12,10 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_ENUMCONSTANT_HPP #define MRDOCS_API_METADATA_SYMBOL_ENUMCONSTANT_HPP +#include #include #include +#include #include namespace mrdocs { @@ -36,6 +39,12 @@ struct EnumConstantSymbol final } }; +BOOST_DESCRIBE_STRUCT( + EnumConstantSymbol, + (SymbolCommonBase), + (Initializer) +) + /** Merge another EnumConstantSymbol into this one. @param I Destination symbol to update. @param Other Source symbol providing data. @@ -60,10 +69,7 @@ tag_invoke( DomCorpus const* domCorpus) { tag_invoke(t, io, I.asInfo(), domCorpus); - if (!I.Initializer.Written.empty()) - { - io.map("initializer", I.Initializer.Written); - } + mapWithDescribe(io, I, domCorpus); } /** Map the EnumConstantSymbol to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Symbol/EnumToString.hpp b/include/mrdocs/Metadata/Symbol/EnumToString.hpp new file mode 100644 index 0000000000..92ceae6f82 --- /dev/null +++ b/include/mrdocs/Metadata/Symbol/EnumToString.hpp @@ -0,0 +1,52 @@ +// +// Licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) +// +// Official repository: https://github.com/cppalliance/mrdocs +// + +#ifndef MRDOCS_METADATA_SYMBOL_ENUMTOSTRING_HPP +#define MRDOCS_METADATA_SYMBOL_ENUMTOSTRING_HPP + +#include +#include +#include +#include + +namespace mrdocs { + +/** Convert a Boost.Describe'd enumerator to string form. + + @param e The enumerator to convert. + @return The string form of the enumerator. +*/ +template + requires boost::describe::has_describe_enumerators::value +std::string +toString(Enum e) +{ + std::string result; + boost::mp11::mp_for_each< + boost::describe::describe_enumerators>( + [&](auto const& D) + { + if (D.value == e) + { + result = toKebabCase(D.name); + } + }); + + if (!result.empty()) + { + return result; + } + + MRDOCS_UNREACHABLE(); +} + +} + +#endif diff --git a/include/mrdocs/Metadata/Symbol/ExtractionMode.hpp b/include/mrdocs/Metadata/Symbol/ExtractionMode.hpp index dde53bade7..cebd406fee 100644 --- a/include/mrdocs/Metadata/Symbol/ExtractionMode.hpp +++ b/include/mrdocs/Metadata/Symbol/ExtractionMode.hpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2024 Alan de Freitas (alandefreitas@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -12,7 +13,9 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_EXTRACTIONMODE_HPP #define MRDOCS_API_METADATA_SYMBOL_EXTRACTIONMODE_HPP +#include #include +#include namespace mrdocs { @@ -54,25 +57,8 @@ enum class ExtractionMode Dependency, }; -/** Return the name of the SymbolKind as a string. -*/ -constexpr -std::string_view -toString(ExtractionMode kind) noexcept -{ - switch(kind) - { - case ExtractionMode::Regular: - return "regular"; - case ExtractionMode::SeeBelow: - return "see-below"; - case ExtractionMode::ImplementationDefined: - return "implementation-defined"; - case ExtractionMode::Dependency: - return "dependency"; - } - MRDOCS_UNREACHABLE(); -} +BOOST_DESCRIBE_ENUM( + ExtractionMode, Regular, SeeBelow, ImplementationDefined, Dependency) /** Return the SymbolKind from a @ref dom::Value string. */ diff --git a/include/mrdocs/Metadata/Symbol/FileKind.hpp b/include/mrdocs/Metadata/Symbol/FileKind.hpp index f697b8d73e..c29aed5c1f 100644 --- a/include/mrdocs/Metadata/Symbol/FileKind.hpp +++ b/include/mrdocs/Metadata/Symbol/FileKind.hpp @@ -13,9 +13,11 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_FILEKIND_HPP #define MRDOCS_API_METADATA_SYMBOL_FILEKIND_HPP +#include #include #include #include +#include #include namespace mrdocs { @@ -32,13 +34,7 @@ enum class FileKind Other }; -/** Convert a FileKind to its string form. - @param kind File category to stringify. - @return String view describing the kind. -*/ -MRDOCS_DECL -std::string_view -toString(FileKind kind); +BOOST_DESCRIBE_ENUM(FileKind, Source, System, Other) /** Map a FileKind into a DOM value. @param v Destination value to populate. diff --git a/include/mrdocs/Metadata/Symbol/Friend.hpp b/include/mrdocs/Metadata/Symbol/Friend.hpp index 3d1056afb2..8a21910058 100644 --- a/include/mrdocs/Metadata/Symbol/Friend.hpp +++ b/include/mrdocs/Metadata/Symbol/Friend.hpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -11,7 +12,9 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_FRIEND_HPP #define MRDOCS_API_METADATA_SYMBOL_FRIEND_HPP +#include #include +#include #include #include @@ -42,6 +45,12 @@ struct FriendInfo final Optional> Type = std::nullopt; }; +BOOST_DESCRIBE_STRUCT( + FriendInfo, + (), + (Type) // `id` intentionally omitted +) + MRDOCS_DECL /** Merge another FriendInfo into this one. */ @@ -75,8 +84,8 @@ tag_invoke( io.defer("name", [&]{ return dom::ValueFrom(I.Type, domCorpus).get("name"); }); - io.map("type", I.Type); } + mapWithDescribe(io, I, domCorpus); } /** Map the FriendInfo to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Symbol/Function.hpp b/include/mrdocs/Metadata/Symbol/Function.hpp index 080bc720d4..5a38889daa 100644 --- a/include/mrdocs/Metadata/Symbol/Function.hpp +++ b/include/mrdocs/Metadata/Symbol/Function.hpp @@ -7,6 +7,7 @@ // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) // Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com) // Copyright (c) 2024 Alan de Freitas (alandefreitas@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -14,11 +15,13 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_FUNCTION_HPP #define MRDOCS_API_METADATA_SYMBOL_FUNCTION_HPP +#include #include #include #include #include #include +#include #include #include #include @@ -47,7 +50,7 @@ struct FunctionSymbol final Optional Template; /// The class of function this is - FunctionClass Class = FunctionClass::Normal; + FunctionClass FuncClass = FunctionClass::Normal; /** Exception specification for the function. */ @@ -142,6 +145,18 @@ struct FunctionSymbol final operator<=>(FunctionSymbol const& other) const; }; +BOOST_DESCRIBE_STRUCT( + FunctionSymbol, + (SymbolCommonBase), + (ReturnType, Params, Template, FuncClass, Noexcept, Requires, + IsVariadic, IsDefaulted, IsExplicitlyDefaulted, IsDeleted, + IsDeletedAsWritten, IsNoReturn, HasOverrideAttr, HasTrailingReturn, + IsNodiscard, IsExplicitObjectMemberFunction, Constexpr, + OverloadedOperator, StorageClass, IsRecordMethod, IsVirtual, + IsVirtualAsWritten, IsPure, IsConst, IsVolatile, IsFinal, + RefQualifier, Explicit, Attributes) +) + /** Merge metadata from another function symbol. @param I Destination symbol to update. @param Other Source symbol providing additional data. @@ -166,46 +181,7 @@ tag_invoke( DomCorpus const* domCorpus) { tag_invoke(t, io, I.asInfo(), domCorpus); - io.map("isVariadic", I.IsVariadic); - io.map("isVirtual", I.IsVirtual); - io.map("isVirtualAsWritten", I.IsVirtualAsWritten); - io.map("isPure", I.IsPure); - io.map("isDefaulted", I.IsDefaulted); - io.map("isExplicitlyDefaulted", I.IsExplicitlyDefaulted); - io.map("isDeleted", I.IsDeleted); - io.map("isDeletedAsWritten", I.IsDeletedAsWritten); - io.map("isNoReturn", I.IsNoReturn); - io.map("hasOverrideAttr", I.HasOverrideAttr); - io.map("hasTrailingReturn", I.HasTrailingReturn); - io.map("isConst", I.IsConst); - io.map("isVolatile", I.IsVolatile); - io.map("isFinal", I.IsFinal); - io.map("isNodiscard", I.IsNodiscard); - io.map("isExplicitObjectMemberFunction", I.IsExplicitObjectMemberFunction); - if (I.Constexpr != ConstexprKind::None) - { - io.map("constexprKind", I.Constexpr); - } - if (I.StorageClass != StorageClassKind::None) - { - io.map("storageClass", I.StorageClass); - } - if (I.RefQualifier != ReferenceKind::None) - { - io.map("refQualifier", I.RefQualifier); - } - io.map("functionClass", I.Class); - io.map("params", dom::LazyArray(I.Params, domCorpus)); - io.map("return", I.ReturnType); - io.map("template", I.Template); - io.map("overloadedOperator", I.OverloadedOperator); - io.map("exceptionSpec", I.Noexcept); - io.map("explicitSpec", I.Explicit); - if (!I.Requires.Written.empty()) - { - io.map("requires", I.Requires.Written); - } - io.map("attributes", dom::LazyArray(I.Attributes)); + mapWithDescribe(io, I, domCorpus); } /** Map the FunctionSymbol to a @ref dom::Value object. @@ -225,6 +201,23 @@ tag_invoke( v = dom::LazyObject(I, domCorpus); } +/** Map a vector of parameters to a @ref dom::Value object. + + @param v The output parameter to receive the dom::Value. + @param params The list of parameters to convert. + @param domCorpus The DomCorpus used to resolve references. + */ +inline +void +tag_invoke( + dom::ValueFromTag, + dom::Value& v, + std::vector const& params, + DomCorpus const* domCorpus) +{ + v = dom::LazyArray(params, domCorpus); +} + /** Determine if one function would override the other @param base The base function diff --git a/include/mrdocs/Metadata/Symbol/FunctionClass.hpp b/include/mrdocs/Metadata/Symbol/FunctionClass.hpp index e4ba48a5b8..f778d6a15e 100644 --- a/include/mrdocs/Metadata/Symbol/FunctionClass.hpp +++ b/include/mrdocs/Metadata/Symbol/FunctionClass.hpp @@ -7,6 +7,7 @@ // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) // Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com) // Copyright (c) 2024 Alan de Freitas (alandefreitas@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -14,8 +15,10 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_FUNCTIONCLASS_HPP #define MRDOCS_API_METADATA_SYMBOL_FUNCTIONCLASS_HPP +#include #include #include +#include namespace mrdocs { @@ -33,11 +36,7 @@ enum class FunctionClass Destructor }; -/** Convert a function class to string form. -*/ -MRDOCS_DECL -dom::String -toString(FunctionClass kind) noexcept; +BOOST_DESCRIBE_ENUM(FunctionClass, Normal, Constructor, Conversion, Destructor) /** Return the FunctionClass from a @ref dom::Value string. */ diff --git a/include/mrdocs/Metadata/Symbol/Guide.hpp b/include/mrdocs/Metadata/Symbol/Guide.hpp index cc4a0e0d9e..411fa3c1c3 100644 --- a/include/mrdocs/Metadata/Symbol/Guide.hpp +++ b/include/mrdocs/Metadata/Symbol/Guide.hpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -11,12 +12,14 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_GUIDE_HPP #define MRDOCS_API_METADATA_SYMBOL_GUIDE_HPP +#include #include #include #include #include #include #include +#include #include #include #include @@ -60,6 +63,12 @@ struct GuideSymbol final operator<=>(GuideSymbol const& other) const; }; +BOOST_DESCRIBE_STRUCT( + GuideSymbol, + (SymbolCommonBase), + (Deduced, Template, Params, Explicit) +) + /** Merge another GuideSymbol into this one. @param I Destination symbol to update. @param Other Source symbol providing data. @@ -84,10 +93,7 @@ tag_invoke( DomCorpus const* domCorpus) { tag_invoke(t, io, I.asInfo(), domCorpus); - io.map("params", dom::LazyArray(I.Params, domCorpus)); - io.map("deduced", I.Deduced); - io.map("template", I.Template); - io.map("explicitSpec", I.Explicit); + mapWithDescribe(io, I, domCorpus); } /** Map the GuideSymbol to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Symbol/Location.hpp b/include/mrdocs/Metadata/Symbol/Location.hpp index 48c1c6d960..d16dcba9f6 100644 --- a/include/mrdocs/Metadata/Symbol/Location.hpp +++ b/include/mrdocs/Metadata/Symbol/Location.hpp @@ -6,6 +6,7 @@ // // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) // Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -13,6 +14,7 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_LOCATION_HPP #define MRDOCS_API_METADATA_SYMBOL_LOCATION_HPP +#include #include #include #include @@ -81,6 +83,12 @@ struct MRDOCS_DECL auto operator<=>(Location const&) const = default; }; +BOOST_DESCRIBE_STRUCT( + Location, + (), + (FullPath, ShortPath, SourcePath, LineNumber, ColumnNumber, Documented) +) + /** Serialize a location into a DOM value. */ MRDOCS_DECL diff --git a/include/mrdocs/Metadata/Symbol/Namespace.hpp b/include/mrdocs/Metadata/Symbol/Namespace.hpp index 5f80e3f5f8..61d5abd647 100644 --- a/include/mrdocs/Metadata/Symbol/Namespace.hpp +++ b/include/mrdocs/Metadata/Symbol/Namespace.hpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -12,10 +13,16 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_NAMESPACE_HPP #define MRDOCS_API_METADATA_SYMBOL_NAMESPACE_HPP +#include #include #include #include +#include +#include +#include #include +#include +#include #include namespace mrdocs { @@ -59,6 +66,13 @@ struct NamespaceTranche { auto operator<=>(NamespaceTranche const&) const = default; }; +BOOST_DESCRIBE_STRUCT( + NamespaceTranche, + (), + (Namespaces, NamespaceAliases, Typedefs, Records, Enums, + Functions, Variables, Concepts, Guides, Usings) +) + /** Merge two tranches, appending members from the right-hand side. */ MRDOCS_DECL @@ -107,16 +121,7 @@ tag_invoke( NamespaceTranche const& I, DomCorpus const* domCorpus) { - io.map("namespaces", dom::LazyArray(I.Namespaces, domCorpus)); - io.map("namespaceAliases", dom::LazyArray(I.NamespaceAliases, domCorpus)); - io.map("typedefs", dom::LazyArray(I.Typedefs, domCorpus)); - io.map("records", dom::LazyArray(I.Records, domCorpus)); - io.map("enums", dom::LazyArray(I.Enums, domCorpus)); - io.map("functions", dom::LazyArray(I.Functions, domCorpus)); - io.map("variables", dom::LazyArray(I.Variables, domCorpus)); - io.map("concepts", dom::LazyArray(I.Concepts, domCorpus)); - io.map("guides", dom::LazyArray(I.Guides, domCorpus)); - io.map("usings", dom::LazyArray(I.Usings, domCorpus)); + mapWithDescribe(io, I, domCorpus); } /** Map the NamespaceTranche to a @ref dom::Value object. @@ -166,6 +171,12 @@ struct NamespaceSymbol final operator<=>(NamespaceSymbol const&) const; }; +BOOST_DESCRIBE_STRUCT( + NamespaceSymbol, + (SymbolCommonBase), + (IsInline, IsAnonymous, UsingDirectives, Members) +) + /** Merge two namespaces, keeping existing members stable. */ MRDOCS_DECL @@ -198,10 +209,7 @@ tag_invoke( DomCorpus const* domCorpus) { tag_invoke(t, io, I.asInfo(), domCorpus); - io.map("isInline", I.IsInline); - io.map("isAnonymous", I.IsAnonymous); - io.map("members", I.Members); - io.map("usingDirectives", dom::LazyArray(I.UsingDirectives, domCorpus)); + mapWithDescribe(io, I, domCorpus); } /** Map the NamespaceSymbol to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Symbol/NamespaceAlias.hpp b/include/mrdocs/Metadata/Symbol/NamespaceAlias.hpp index a590ab7414..58d3d6c955 100644 --- a/include/mrdocs/Metadata/Symbol/NamespaceAlias.hpp +++ b/include/mrdocs/Metadata/Symbol/NamespaceAlias.hpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2024 Fernando Pelliccioni (fpelliccioni@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -11,10 +12,12 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_NAMESPACEALIAS_HPP #define MRDOCS_API_METADATA_SYMBOL_NAMESPACEALIAS_HPP +#include #include #include #include #include +#include namespace mrdocs { @@ -40,6 +43,12 @@ struct NamespaceAliasSymbol final } }; +BOOST_DESCRIBE_STRUCT( + NamespaceAliasSymbol, + (SymbolCommonBase), + (AliasedSymbol) +) + /** Merge two alias symbols, preferring existing fields when present. */ MRDOCS_DECL @@ -62,7 +71,7 @@ tag_invoke( DomCorpus const* domCorpus) { tag_invoke(t, io, I.asInfo(), domCorpus); - io.map("aliasedSymbol", I.AliasedSymbol); + mapWithDescribe(io, I, domCorpus); } /** Map the NamespaceAliasSymbol to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Symbol/Overloads.hpp b/include/mrdocs/Metadata/Symbol/Overloads.hpp index 98022eed39..ae4155f016 100644 --- a/include/mrdocs/Metadata/Symbol/Overloads.hpp +++ b/include/mrdocs/Metadata/Symbol/Overloads.hpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -11,9 +12,11 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_OVERLOADS_HPP #define MRDOCS_API_METADATA_SYMBOL_OVERLOADS_HPP +#include #include #include #include +#include namespace mrdocs { @@ -23,7 +26,7 @@ struct OverloadsSymbol final : SymbolCommonBase { /// The class of the functions. - FunctionClass Class = FunctionClass::Normal; + FunctionClass FuncClass = FunctionClass::Normal; /// The overloaded operator, if any. OperatorKind OverloadedOperator = OperatorKind::None; @@ -58,6 +61,12 @@ struct OverloadsSymbol final OverloadsSymbol(SymbolID const& Parent, std::string_view Name, AccessKind Access, bool isStatic) noexcept; }; +BOOST_DESCRIBE_STRUCT( + OverloadsSymbol, + (SymbolCommonBase), + (FuncClass, OverloadedOperator, Members) // ReturnType intentionally omitted. +) + /** Merge overload sets, preserving ordering in `Members`. */ MRDOCS_DECL @@ -95,9 +104,7 @@ tag_invoke( DomCorpus const* domCorpus) { tag_invoke(t, io, I.asInfo(), domCorpus); - io.map("class", I.Class); - io.map("overloadedOperator", I.OverloadedOperator); - io.map("members", dom::LazyArray(I.Members, domCorpus)); + mapWithDescribe(io, I, domCorpus); } /** Map the OverloadsSymbol to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Symbol/Param.hpp b/include/mrdocs/Metadata/Symbol/Param.hpp index f4c4920d1a..2e95cf5c20 100644 --- a/include/mrdocs/Metadata/Symbol/Param.hpp +++ b/include/mrdocs/Metadata/Symbol/Param.hpp @@ -14,6 +14,7 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_PARAM_HPP #define MRDOCS_API_METADATA_SYMBOL_PARAM_HPP +#include #include #include #include @@ -62,6 +63,12 @@ struct Param final operator<=>(Param const&) const = default; }; +BOOST_DESCRIBE_STRUCT( + Param, + (), + (Type, Name, Default) +) + /** Merge two parameters, filling missing pieces from `Other`. */ MRDOCS_DECL diff --git a/include/mrdocs/Metadata/Symbol/Record.hpp b/include/mrdocs/Metadata/Symbol/Record.hpp index 0f1df06316..ab63a36637 100644 --- a/include/mrdocs/Metadata/Symbol/Record.hpp +++ b/include/mrdocs/Metadata/Symbol/Record.hpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -12,12 +13,14 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_RECORD_HPP #define MRDOCS_API_METADATA_SYMBOL_RECORD_HPP +#include #include #include #include #include #include #include +#include #include namespace mrdocs { @@ -87,6 +90,13 @@ struct RecordSymbol final operator<=>(RecordSymbol const& other) const; }; +BOOST_DESCRIBE_STRUCT( + RecordSymbol, + (SymbolCommonBase), + (KeyKind, Template, IsTypeDef, IsFinal, IsFinalDestructor, + Bases, Derived, Interface, Friends) +) + /** Return the default accessibility for a record key kind. */ constexpr @@ -138,15 +148,8 @@ tag_invoke( DomCorpus const* domCorpus) { tag_invoke(t, io, I.asInfo(), domCorpus); - io.map("tag", I.KeyKind); + mapWithDescribe(io, I, domCorpus); io.map("defaultAccess", getDefaultAccessString(I.KeyKind)); - io.map("isFinal", I.IsFinal); - io.map("isTypedef", I.IsTypeDef); - io.map("bases", dom::LazyArray(I.Bases, domCorpus)); - io.map("derived", dom::LazyArray(I.Derived, domCorpus)); - io.map("interface", I.Interface); - io.map("template", I.Template); - io.map("friends", dom::LazyArray(I.Friends, domCorpus)); } /** Map the RecordSymbol to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Symbol/RecordBase.hpp b/include/mrdocs/Metadata/Symbol/RecordBase.hpp index ecd70071b3..5ae5d2da83 100644 --- a/include/mrdocs/Metadata/Symbol/RecordBase.hpp +++ b/include/mrdocs/Metadata/Symbol/RecordBase.hpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -12,6 +13,7 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_RECORDBASE_HPP #define MRDOCS_API_METADATA_SYMBOL_RECORDBASE_HPP +#include #include #include #include @@ -58,6 +60,12 @@ struct BaseInfo } }; +BOOST_DESCRIBE_STRUCT( + BaseInfo, + (), + (Type, Access, IsVirtual) +) + /** Serialize a base description into a DOM value. */ MRDOCS_DECL diff --git a/include/mrdocs/Metadata/Symbol/RecordInterface.hpp b/include/mrdocs/Metadata/Symbol/RecordInterface.hpp index 7c16c36735..a0f1bdc4e5 100644 --- a/include/mrdocs/Metadata/Symbol/RecordInterface.hpp +++ b/include/mrdocs/Metadata/Symbol/RecordInterface.hpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -12,7 +13,9 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_RECORDINTERFACE_HPP #define MRDOCS_API_METADATA_SYMBOL_RECORDINTERFACE_HPP +#include #include +#include #include namespace mrdocs { @@ -61,6 +64,12 @@ class RecordInterface RecordTranche Private; }; +BOOST_DESCRIBE_STRUCT( + RecordInterface, + (), + (Public, Protected, Private) +) + /** Merge two interfaces, combining matching tranches. */ MRDOCS_DECL @@ -80,9 +89,7 @@ tag_invoke( RecordInterface const& I, DomCorpus const*) { - io.map("public", I.Public); - io.map("protected", I.Protected); - io.map("private", I.Private); + mapWithDescribe(io, I, nullptr); } /** Map the RecordInterface to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Symbol/RecordKeyKind.hpp b/include/mrdocs/Metadata/Symbol/RecordKeyKind.hpp index 85238be811..66072dc09f 100644 --- a/include/mrdocs/Metadata/Symbol/RecordKeyKind.hpp +++ b/include/mrdocs/Metadata/Symbol/RecordKeyKind.hpp @@ -5,6 +5,7 @@ // // Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com) // Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -12,8 +13,10 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_RECORDKEYKIND_HPP #define MRDOCS_API_METADATA_SYMBOL_RECORDKEYKIND_HPP +#include #include #include +#include #include namespace mrdocs { @@ -30,11 +33,8 @@ enum class RecordKeyKind Union }; -/** Convert the key kind to its canonical string form. -*/ -MRDOCS_DECL -dom::String -toString(RecordKeyKind kind) noexcept; +BOOST_DESCRIBE_ENUM( + RecordKeyKind, Struct, Class, Union) /** Serialize the record key kind into a DOM value. */ diff --git a/include/mrdocs/Metadata/Symbol/RecordTranche.hpp b/include/mrdocs/Metadata/Symbol/RecordTranche.hpp index 962ed707e9..5cf2aa7637 100644 --- a/include/mrdocs/Metadata/Symbol/RecordTranche.hpp +++ b/include/mrdocs/Metadata/Symbol/RecordTranche.hpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -12,9 +13,11 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_RECORDTRANCHE_HPP #define MRDOCS_API_METADATA_SYMBOL_RECORDTRANCHE_HPP +#include #include #include #include +#include #include #include @@ -66,6 +69,13 @@ struct RecordTranche std::vector Usings; }; +BOOST_DESCRIBE_STRUCT( + RecordTranche, + (), + (NamespaceAliases, Typedefs, Records, Enums, Functions, + StaticFunctions, Variables, StaticVariables, Concepts, Guides, Usings) +) + /** Merge two tranches with the same access level. */ MRDOCS_DECL @@ -116,17 +126,7 @@ tag_invoke( RecordTranche const& I, DomCorpus const* domCorpus) { - io.map("namespaceAliases", dom::LazyArray(I.NamespaceAliases, domCorpus)); - io.map("typedefs", dom::LazyArray(I.Typedefs, domCorpus)); - io.map("records", dom::LazyArray(I.Records, domCorpus)); - io.map("enums", dom::LazyArray(I.Enums, domCorpus)); - io.map("functions", dom::LazyArray(I.Functions, domCorpus)); - io.map("staticFunctions", dom::LazyArray(I.StaticFunctions, domCorpus)); - io.map("variables", dom::LazyArray(I.Variables, domCorpus)); - io.map("staticVariables", dom::LazyArray(I.StaticVariables, domCorpus)); - io.map("concepts", dom::LazyArray(I.Concepts, domCorpus)); - io.map("guides", dom::LazyArray(I.Guides, domCorpus)); - io.map("usings", dom::LazyArray(I.Usings, domCorpus)); + mapWithDescribe(io, I, domCorpus); } /** Map the RecordTranche to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Symbol/SymbolBase.hpp b/include/mrdocs/Metadata/Symbol/SymbolBase.hpp index ae2d13fd34..3bca7da917 100644 --- a/include/mrdocs/Metadata/Symbol/SymbolBase.hpp +++ b/include/mrdocs/Metadata/Symbol/SymbolBase.hpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -12,11 +13,13 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_SYMBOLBASE_HPP #define MRDOCS_API_METADATA_SYMBOL_SYMBOLBASE_HPP +#include #include #include #include #include #include +#include #include #include @@ -174,6 +177,13 @@ struct MRDOCS_VISIBLE Symbol { } }; +BOOST_DESCRIBE_STRUCT( + Symbol, + (), + (Name, Loc, Kind, id, Access, + Extraction, IsCopyFromInherited, Parent) // `doc` intentionally omitted. +) + //------------------------------------------------ /** Base class for providing variant discriminator functions. @@ -253,28 +263,16 @@ tag_invoke( DomCorpus const* domCorpus) { MRDOCS_ASSERT(domCorpus); + mapWithDescribe(io, I, domCorpus); io.map("class", std::string("symbol")); - io.map("kind", I.Kind); - io.map("id", I.id); - if (!I.Name.empty()) - { - io.map("name", I.Name); - } - io.map("access", I.Access); - io.map("extraction", I.Extraction); io.map("isRegular", I.Extraction == ExtractionMode::Regular); io.map("isSeeBelow", I.Extraction == ExtractionMode::SeeBelow); io.map("isImplementationDefined", I.Extraction == ExtractionMode::ImplementationDefined); io.map("isDependency", I.Extraction == ExtractionMode::Dependency); - if (I.Parent) - { - io.map("parent", I.Parent); - } if (I.doc) { io.map("doc", *I.doc); } - io.map("loc", I.Loc); } /** Return the Symbol as a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Symbol/SymbolDescribeMapper.hpp b/include/mrdocs/Metadata/Symbol/SymbolDescribeMapper.hpp new file mode 100644 index 0000000000..fd0d0cb05c --- /dev/null +++ b/include/mrdocs/Metadata/Symbol/SymbolDescribeMapper.hpp @@ -0,0 +1,174 @@ +// +// Licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) +// +// Official repository: https://github.com/cppalliance/mrdocs +// + +#ifndef MRDOCS_METADATA_SYMBOL_SYMBOLDESCRIBEMAPPER_HPP +#define MRDOCS_METADATA_SYMBOL_SYMBOLDESCRIBEMAPPER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mrdocs { + +class DomCorpus; + +namespace detail { + +/** Helper to determine if a member should be mapped based on its value. +*/ +template +constexpr bool +shouldMapValue(T const& value) +{ + if constexpr (std::is_same_v) + { + return !value.empty(); + } + else if constexpr (std::is_same_v) + { + return value != ConstexprKind::None; + } + else if constexpr (std::is_same_v) + { + return value != ReferenceKind::None; + } + else if constexpr (std::is_same_v) + { + return value != StorageClassKind::None; + } + else if constexpr (std::is_same_v) + { + return !value.Written.empty(); + } + else + { + // All other types are always mapped. + return true; + } +} + +/** Convert a member name to the corresponding DOM name. + + E.g.: + - IsVariadic -> isVariadic +*/ +inline +std::string +normalizeMemberName(std::string_view name) +{ + // Special cases. + if (name == "Constexpr") + { + return "constexprKind"; + } + else if (name == "ReturnType") + { + return "return"; + } + else if (name == "Noexcept") + { + return "exceptionSpec"; + } + else if (name == "Explicit") + { + return "explicitSpec"; + } + else if (name == "KeyKind") + { + return "tag"; + } + else if (name == "Class") + { + return "usingClass"; + } + else + { + std::string result(name); + if (!result.empty()) + { + result.front() = std::tolower(result.front(), std::locale::classic()); + } + return result; + } +} + +/** Generic mapper that uses Boost.Describe reflection to map all members. +*/ +template +requires boost::describe::has_describe_members::value +void +mapAllDescribedMembers( + IO& io, + T const& obj, + DomCorpus const* domCorpus) +{ + boost::mp11::mp_for_each>( + [&](auto const& descriptor) { + using Descriptor = std::decay_t; + + constexpr char const* name = Descriptor::name; + auto const& value = obj.*Descriptor::pointer; + + if (shouldMapValue(value)) + { + io.map(normalizeMemberName(name), value); + } + }); +} + +} + +/** Automatically map all Boost.Describe'd members of a type to the DOM. + + This replaces the manual `tag_invoke()` implementations with a single + call that handles all member mappings via reflection. + + @param io The IO object to use for mapping. + @param obj The object to be mapped. + @param domCorpus The DomCorpus used to create the DOM values. + + Usage in a Symbol type: + + @code + template + void tag_invoke( + dom::LazyObjectMapTag t, + IO& io, + FunctionSymbol const& I, + DomCorpus const* domCorpus) + { + // First, map base Symbol members. + tag_invoke(t, io, I.asInfo(), domCorpus); + + // Then, automatically map all FunctionSymbol-specific members. + mapWithDescribe(io, I, domCorpus); + } + @endcode +*/ +template +void +mapWithDescribe( + IO& io, + T const& obj, + DomCorpus const* domCorpus) +{ + detail::mapAllDescribedMembers(io, obj, domCorpus); +} + +} + +#endif diff --git a/include/mrdocs/Metadata/Symbol/Typedef.hpp b/include/mrdocs/Metadata/Symbol/Typedef.hpp index a34275331d..38c4d166bb 100644 --- a/include/mrdocs/Metadata/Symbol/Typedef.hpp +++ b/include/mrdocs/Metadata/Symbol/Typedef.hpp @@ -6,6 +6,7 @@ // // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) // Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -13,10 +14,12 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_TYPEDEF_HPP #define MRDOCS_API_METADATA_SYMBOL_TYPEDEF_HPP +#include #include #include #include #include +#include #include #include @@ -65,6 +68,12 @@ struct TypedefSymbol final }; +BOOST_DESCRIBE_STRUCT( + TypedefSymbol, + (SymbolCommonBase), + (Type, IsUsing, Template) +) + /** Merge typedef symbols, keeping existing info when present. */ MRDOCS_DECL @@ -87,9 +96,7 @@ tag_invoke( DomCorpus const* domCorpus) { tag_invoke(t, io, I.asInfo(), domCorpus); - io.map("type", I.Type); - io.map("template", I.Template); - io.map("isUsing", I.IsUsing); + mapWithDescribe(io, I, domCorpus); } /** Map the TypedefSymbol to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Symbol/Using.hpp b/include/mrdocs/Metadata/Symbol/Using.hpp index b9465f6854..526080f2b9 100644 --- a/include/mrdocs/Metadata/Symbol/Using.hpp +++ b/include/mrdocs/Metadata/Symbol/Using.hpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2024 Fernando Pelliccioni (fpelliccioni@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -11,11 +12,15 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_USING_HPP #define MRDOCS_API_METADATA_SYMBOL_USING_HPP +#include +#include #include #include #include #include +#include #include +#include #include #include @@ -37,18 +42,8 @@ enum class UsingClass Enum // using enum }; -static constexpr -std::string_view -toString(UsingClass const& value) -{ - switch (value) - { - case UsingClass::Normal: return "normal"; - case UsingClass::Typename: return "typename"; - case UsingClass::Enum: return "enum"; - } - return "unknown"; -} +BOOST_DESCRIBE_ENUM( + UsingClass, Normal, Typename, Enum) /** Return the UsingClass as a @ref dom::Value string. @@ -139,6 +134,12 @@ struct UsingSymbol final } }; +BOOST_DESCRIBE_STRUCT( + UsingSymbol, + (SymbolCommonBase), + (Class, IntroducedName, ShadowDeclarations) +) + /** Merge two using-declarations with the same identity. */ MRDOCS_DECL @@ -160,9 +161,7 @@ tag_invoke( DomCorpus const* domCorpus) { tag_invoke(t, io, I.asInfo(), domCorpus); - io.map("usingClass", I.Class); - io.map("shadows", dom::LazyArray(I.ShadowDeclarations, domCorpus)); - io.map("qualifier", I.IntroducedName); + mapWithDescribe(io, I, domCorpus); } /** Map the UsingSymbol to a @ref dom::Value object. diff --git a/include/mrdocs/Metadata/Symbol/Variable.hpp b/include/mrdocs/Metadata/Symbol/Variable.hpp index 07162c2785..4c645bec59 100644 --- a/include/mrdocs/Metadata/Symbol/Variable.hpp +++ b/include/mrdocs/Metadata/Symbol/Variable.hpp @@ -5,6 +5,7 @@ // // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) // Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -12,12 +13,14 @@ #ifndef MRDOCS_API_METADATA_SYMBOL_VARIABLE_HPP #define MRDOCS_API_METADATA_SYMBOL_VARIABLE_HPP +#include #include #include #include #include #include #include +#include #include #include @@ -116,6 +119,15 @@ struct VariableSymbol final operator<=>(VariableSymbol const& other) const; }; +BOOST_DESCRIBE_STRUCT( + VariableSymbol, + (SymbolCommonBase), + (Type, Template, Initializer, StorageClass, IsInline, + IsConstexpr, IsConstinit, IsThreadLocal, Attributes, IsMaybeUnused, + IsDeprecated, HasNoUniqueAddress, IsRecordField, IsMutable, IsVariant, + IsBitfield, BitfieldWidth) +) + /** Merge variable metadata, preserving existing values when set. */ MRDOCS_DECL @@ -138,33 +150,7 @@ tag_invoke( DomCorpus const* domCorpus) { tag_invoke(t, io, I.asInfo(), domCorpus); - io.map("type", I.Type); - io.map("template", I.Template); - if (I.StorageClass != StorageClassKind::None) - { - io.map("storageClass", I.StorageClass); - } - io.map("isInline", I.IsInline); - io.map("isConstexpr", I.IsConstexpr); - io.map("isConstinit", I.IsConstinit); - io.map("isThreadLocal", I.IsThreadLocal); - if (!I.Initializer.Written.empty()) - { - io.map("initializer", I.Initializer.Written); - } - io.map("attributes", dom::LazyArray(I.Attributes)); - io.map("isRecordField", I.IsRecordField); - io.map("isMaybeUnused", I.IsMaybeUnused); - io.map("isDeprecated", I.IsDeprecated); - io.map("isVariant", I.IsVariant); - io.map("isMutable", I.IsMutable); - io.map("isBitfield", I.IsBitfield); - if (I.IsBitfield) - { - io.map("bitfieldWidth", I.BitfieldWidth.Written); - } - io.map("hasNoUniqueAddress", I.HasNoUniqueAddress); - io.map("attributes", dom::LazyArray(I.Attributes)); + mapWithDescribe( io, I, domCorpus); } /** Map the VariableSymbol to a @ref dom::Value object. diff --git a/share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs b/share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs index 0ff8370abc..bf1bb60288 100644 --- a/share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs +++ b/share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs @@ -137,14 +137,14 @@ {{/if}} {{! Using symbols }} -{{#if symbol.shadows}} +{{#if symbol.shadowDeclarations}} {{#> markup/dynamic-level-h }}Introduced Symbols{{/markup/dynamic-level-h~}} -{{#if (any_of_by symbol.shadows "doc")}} +{{#if (any_of_by symbol.shadowDeclarations "doc")}} [cols="1,4"] |=== |Name|Description -{{#each symbol.shadows}} +{{#each symbol.shadowDeclarations}} | {{> symbol/qualified-name . }} | {{> doc/block/inline-brief doc.brief }} {{/each}} @@ -153,7 +153,7 @@ [cols=1] |=== | Name -{{#each symbol.shadows}} +{{#each symbol.shadowDeclarations}} | {{> symbol/qualified-name . }} {{/each}} |=== diff --git a/share/mrdocs/addons/generator/common/partials/symbol/name-text.hbs b/share/mrdocs/addons/generator/common/partials/symbol/name-text.hbs index 3a80cf8ace..45146495dd 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/name-text.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/name-text.hbs @@ -11,7 +11,7 @@ See: https://mrdocs.com/docs/mrdocs/develop/generators.html#dom_reference --}} -{{~#if (and (eq kind "function") (eq functionClass "conversion"))~}} +{{~#if (and (eq kind "function") (eq funcClass "conversion"))~}} {{! Conversion operator: "operator" and the type declarator ~}} operator {{>type/declarator-text return ~}} {{~else if (eq kind "guide")~}} diff --git a/share/mrdocs/addons/generator/common/partials/symbol/name.hbs b/share/mrdocs/addons/generator/common/partials/symbol/name.hbs index a458587acd..088a48ffcf 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/name.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/name.hbs @@ -11,7 +11,7 @@ See: https://mrdocs.com/docs/mrdocs/develop/generators.html#dom_reference --}} -{{~#if (and (eq kind "function") (eq functionClass "conversion"))~}} +{{~#if (and (eq kind "function") (eq funcClass "conversion"))~}} {{! Conversion operator: "operator" and the type declarator ~}} operator {{>type/declarator return ~}} {{~else if (eq kind "guide")~}} diff --git a/share/mrdocs/addons/generator/common/partials/symbol/qualified-name-title.hbs b/share/mrdocs/addons/generator/common/partials/symbol/qualified-name-title.hbs index ed3433e3a3..8421cfa87e 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/qualified-name-title.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/qualified-name-title.hbs @@ -23,7 +23,7 @@ {{~#if (and parent parent.parent)~}} {{~> symbol/qualified-name-title parent is-qualified-name-parent=true ~}}{{#if parent.name }}::{{/if}} {{~/if~}} -{{~#if (and (eq kind "function") (eq functionClass "conversion"))~}} +{{~#if (and (eq kind "function") (eq funcClass "conversion"))~}} {{~> symbol/name . ~}} {{~else if is-qualified-name-parent ~}} {{!~ If this is a parent, we only print it if it really has a name ~}} diff --git a/share/mrdocs/addons/generator/common/partials/symbol/signature/function.hbs b/share/mrdocs/addons/generator/common/partials/symbol/signature/function.hbs index 1c3c8c31a1..149359fb83 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/signature/function.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/signature/function.hbs @@ -12,11 +12,11 @@ {{/if~}} {{#if explicitSpec}}{{explicitSpec}} {{/if~}} -{{#if (eq functionClass "normal")}}{{>type/declarator-prefix return}} +{{#if (eq funcClass "normal")}}{{>type/declarator-prefix return}} {{/if~}} {{~#if force-link~}} {{>symbol/name symbol }} -{{~else if (eq functionClass "conversion")~}} +{{~else if (eq funcClass "conversion")~}} {{>symbol/name symbol }} {{~else if (contains (arr "explicit" "partial") template.kind)~}} {{>symbol/name template.primary ~}}{{>template/args-text args=template.args ~}} @@ -32,7 +32,7 @@ {{#if isVolatile}} volatile{{/if~}} {{#if refQualifier}} {{refQualifier}}{{/if~}} {{#if exceptionSpec}} {{exceptionSpec}}{{/if~}} -{{#if (eq functionClass "normal")}}{{>type/declarator-suffix return}}{{/if~}} +{{#if (eq funcClass "normal")}}{{>type/declarator-suffix return}}{{/if~}} {{#if requires}} requires {{requires}}{{/if~}} diff --git a/share/mrdocs/addons/generator/common/partials/symbol/signature/using.hbs b/share/mrdocs/addons/generator/common/partials/symbol/signature/using.hbs index 58aa6e0e3b..12abccb86d 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/signature/using.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/signature/using.hbs @@ -1,5 +1,5 @@ -using {{#if (contains (arr "typename" "enum") usingClass)}} {{usingClass}} +using {{#if (contains (arr "typename" "enum") class)}} {{class}} {{~/if~}} -{{~#if qualifier~}} - {{>type/name-info qualifier }} +{{~#if introducedName~}} + {{>type/name-info introducedName }} {{~/if}}; \ No newline at end of file diff --git a/share/mrdocs/addons/generator/common/partials/symbol/special-function-suffix.hbs b/share/mrdocs/addons/generator/common/partials/symbol/special-function-suffix.hbs index 8e9b2262bc..1abc410714 100644 --- a/share/mrdocs/addons/generator/common/partials/symbol/special-function-suffix.hbs +++ b/share/mrdocs/addons/generator/common/partials/symbol/special-function-suffix.hbs @@ -15,9 +15,9 @@ {{#if (eq kind "overloads")~}} {{>symbol/special-function-suffix (front members)}} {{~else if (eq kind "function")~}} - {{#if (eq functionClass "constructor")}} + {{#if (eq funcClass "constructor")}} {{#>markup/span class="small"}}[constructor]{{/markup/span}} - {{~else if (eq functionClass "destructor")~}} + {{~else if (eq funcClass "destructor")~}} {{#>markup/span class="small"}}[destructor]{{/markup/span}} {{~/if~}} {{~#if isVirtual~}} diff --git a/share/mrdocs/addons/generator/html/partials/symbol.html.hbs b/share/mrdocs/addons/generator/html/partials/symbol.html.hbs index 476a28988e..516d0a8025 100644 --- a/share/mrdocs/addons/generator/html/partials/symbol.html.hbs +++ b/share/mrdocs/addons/generator/html/partials/symbol.html.hbs @@ -183,10 +183,10 @@ {{/if}} {{! Using symbols }} -{{#if symbol.shadows}} +{{#if symbol.shadowDeclarations}}
{{#> markup/dynamic-level-h level=2 }}Introduced Symbols{{/markup/dynamic-level-h~}} -{{#if (any_of_by symbol.shadows "doc")}} +{{#if (any_of_by symbol.shadowDeclarations "doc")}} @@ -195,7 +195,7 @@ -{{#each symbol.shadows}} +{{#each symbol.shadowDeclarations}} @@ -211,7 +211,7 @@ -{{#each symbol.shadows}} +{{#each symbol.shadowDeclarations}} diff --git a/src/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp index 10f5703615..2c582f7d1d 100644 --- a/src/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -920,7 +920,7 @@ populate( } } - I.Class = toFunctionClass(D->getDeclKind()); + I.FuncClass = toFunctionClass(D->getDeclKind()); // extract the return type in direct dependency mode // if it contains a placeholder type which is diff --git a/src/lib/CorpusImpl.cpp b/src/lib/CorpusImpl.cpp index 59808272a5..bf22ea7a09 100644 --- a/src/lib/CorpusImpl.cpp +++ b/src/lib/CorpusImpl.cpp @@ -583,7 +583,7 @@ lookupImpl( } else if (component.isConversion()) { - MRDOCS_CHECK_OR(M.Class == FunctionClass::Conversion, matchRes); + MRDOCS_CHECK_OR(M.FuncClass == FunctionClass::Conversion, matchRes); MRDOCS_CHECK_OR(component.ConversionType == M.ReturnType, matchRes); } else diff --git a/src/lib/Gen/xml/XMLWriter.cpp b/src/lib/Gen/xml/XMLWriter.cpp index 3aebf8c731..af5e526c0b 100644 --- a/src/lib/Gen/xml/XMLWriter.cpp +++ b/src/lib/Gen/xml/XMLWriter.cpp @@ -187,8 +187,8 @@ writeFunction( constexpr std::string_view functionTagName = "function"; tags_.open(functionTagName, { - { "class", toString(I.Class), - I.Class != FunctionClass::Normal }, + { "class", toString(I.FuncClass), + I.FuncClass != FunctionClass::Normal }, { "name", I.Name }, { I.Access }, { "exception-spec", except_spec, diff --git a/src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp b/src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp index 7fd45175db..a87fb7a107 100644 --- a/src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp +++ b/src/lib/Metadata/Finalizers/BaseMembersFinalizer.cpp @@ -119,8 +119,8 @@ inheritBaseMembers( // Check if we're not attempt to copy a special member function if (auto const *funcPtr = otherInfoPtr->asFunctionPtr()) { MRDOCS_CHECK_OR_CONTINUE( - !is_one_of(funcPtr->Class, {FunctionClass::Constructor, - FunctionClass::Destructor})); + !is_one_of(funcPtr->FuncClass, {FunctionClass::Constructor, + FunctionClass::Destructor})); } // Check if derived class has a member that shadows the base member diff --git a/src/lib/Metadata/Finalizers/DocComment/Function.hpp b/src/lib/Metadata/Finalizers/DocComment/Function.hpp index 17e60423aa..7e3724d28b 100644 --- a/src/lib/Metadata/Finalizers/DocComment/Function.hpp +++ b/src/lib/Metadata/Finalizers/DocComment/Function.hpp @@ -25,14 +25,14 @@ bool isSpecialFunction(FunctionSymbol const& I) { return - I.Class != FunctionClass::Normal || + I.FuncClass != FunctionClass::Normal || I.OverloadedOperator != OperatorKind::None; } bool isDefaultConstructor(FunctionSymbol const& I) { - return I.Class == FunctionClass::Constructor && I.Params.empty(); + return I.FuncClass == FunctionClass::Constructor && I.Params.empty(); } template @@ -41,7 +41,7 @@ isCopyOrMoveConstructorOrAssignment(FunctionSymbol const& I) { if constexpr (!assignment) { - MRDOCS_CHECK_OR(I.Class == FunctionClass::Constructor, false); + MRDOCS_CHECK_OR(I.FuncClass == FunctionClass::Constructor, false); } else { @@ -122,7 +122,7 @@ innermostTypenameString(Polymorphic const& T) bool populateFunctionBriefFromClass(FunctionSymbol& I, CorpusImpl const& corpus) { - switch (I.Class) + switch (I.FuncClass) { case FunctionClass::Normal: return false; @@ -315,7 +315,7 @@ populateFunctionReturnsForSpecial( Polymorphic const& innerR, CorpusImpl const& corpus) { - if (I.Class == FunctionClass::Conversion) + if (I.FuncClass == FunctionClass::Conversion) { if (auto* brief = getInfoBrief(innerR, corpus)) { @@ -529,7 +529,7 @@ setCntrOrAssignParamName( MRDOCS_CHECK_OR(I.Params.size() == 1, false); MRDOCS_CHECK_OR(I.IsRecordMethod, false); MRDOCS_CHECK_OR( - I.Class == FunctionClass::Constructor || + I.FuncClass == FunctionClass::Constructor || I.OverloadedOperator == OperatorKind::Equal, false); auto paramNames = @@ -645,7 +645,7 @@ setCntrOrAssignParamDoc( MRDOCS_CHECK_OR(index == 0, false); MRDOCS_CHECK_OR(I.IsRecordMethod, false); MRDOCS_CHECK_OR( - I.Class == FunctionClass::Constructor || + I.FuncClass == FunctionClass::Constructor || I.OverloadedOperator == OperatorKind::Equal, false); diff --git a/src/lib/Metadata/Finalizers/DocComment/Overloads.hpp b/src/lib/Metadata/Finalizers/DocComment/Overloads.hpp index c48ba576f6..b2ee136380 100644 --- a/src/lib/Metadata/Finalizers/DocComment/Overloads.hpp +++ b/src/lib/Metadata/Finalizers/DocComment/Overloads.hpp @@ -63,7 +63,7 @@ populateOverloadsBriefIfAllSameBrief(OverloadsSymbol& I, Range&& functionsWithBr bool populateOverloadsFromClass(OverloadsSymbol& I) { - switch (I.Class) + switch (I.FuncClass) { case FunctionClass::Normal: return false; diff --git a/src/lib/Metadata/Finalizers/DocCommentFinalizer.cpp b/src/lib/Metadata/Finalizers/DocCommentFinalizer.cpp index 53bd465773..91651c4173 100644 --- a/src/lib/Metadata/Finalizers/DocCommentFinalizer.cpp +++ b/src/lib/Metadata/Finalizers/DocCommentFinalizer.cpp @@ -832,7 +832,7 @@ generateAutoFunctionMetadata(FunctionSymbol& I) const return; } - if (!is_one_of(I.Class, { + if (!is_one_of(I.FuncClass, { FunctionClass::Constructor, FunctionClass::Destructor }) && I.doc->returns.empty()) diff --git a/src/lib/Metadata/Finalizers/SortMembersFinalizer.cpp b/src/lib/Metadata/Finalizers/SortMembersFinalizer.cpp index c6fd50ca72..f769b4c84b 100644 --- a/src/lib/Metadata/Finalizers/SortMembersFinalizer.cpp +++ b/src/lib/Metadata/Finalizers/SortMembersFinalizer.cpp @@ -37,7 +37,7 @@ struct SymbolIDCompareFn std::same_as || std::same_as) { - return I.Class; + return I.FuncClass; } return std::nullopt; } diff --git a/src/lib/Metadata/Source.cpp b/src/lib/Metadata/Source.cpp index 817a5dd662..8b26eaf6b2 100644 --- a/src/lib/Metadata/Source.cpp +++ b/src/lib/Metadata/Source.cpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -14,27 +15,12 @@ #include #include #include +#include #include #include namespace mrdocs { -std::string_view -toString(FileKind kind) -{ - switch(kind) - { - case FileKind::Source: - return "source"; - case FileKind::System: - return "system"; - case FileKind::Other: - return "other"; - default: - MRDOCS_UNREACHABLE(); - }; -} - namespace { template @@ -107,12 +93,7 @@ tag_invoke( IO& io, Location const& loc) { - io.map("fullPath", loc.FullPath); - io.map("shortPath", loc.ShortPath); - io.map("sourcePath", loc.SourcePath); - io.map("line", loc.LineNumber); - io.map("column", loc.ColumnNumber); - io.map("documented", loc.Documented); + mapWithDescribe(io, loc, nullptr); } void diff --git a/src/lib/Metadata/Symbol/Function.cpp b/src/lib/Metadata/Symbol/Function.cpp index 8a2c20ad2f..7d85dcec55 100644 --- a/src/lib/Metadata/Symbol/Function.cpp +++ b/src/lib/Metadata/Symbol/Function.cpp @@ -271,24 +271,6 @@ getOperatorReadableName( MRDOCS_UNREACHABLE(); } -dom::String -toString(FunctionClass const kind) noexcept -{ - switch(kind) - { - case FunctionClass::Normal: - return "normal"; - case FunctionClass::Constructor: - return "constructor"; - case FunctionClass::Conversion: - return "conversion"; - case FunctionClass::Destructor: - return "destructor"; - default: - MRDOCS_UNREACHABLE(); - } -} - void merge(Param& I, Param&& Other) { @@ -387,9 +369,9 @@ merge(FunctionSymbol& I, FunctionSymbol&& Other) { MRDOCS_ASSERT(canMerge(I, Other)); merge(I.asInfo(), std::move(Other.asInfo())); - if (I.Class == FunctionClass::Normal) + if (I.FuncClass == FunctionClass::Normal) { - I.Class = Other.Class; + I.FuncClass = Other.FuncClass; } I.ReturnType = std::move(Other.ReturnType); std::size_t const n = std::min(I.Params.size(), Other.Params.size()); diff --git a/src/lib/Metadata/Symbol/Overloads.cpp b/src/lib/Metadata/Symbol/Overloads.cpp index a6b1b49967..0d505b7318 100644 --- a/src/lib/Metadata/Symbol/Overloads.cpp +++ b/src/lib/Metadata/Symbol/Overloads.cpp @@ -48,7 +48,7 @@ addMember(OverloadsSymbol& I, FunctionSymbol const& Member) I.Name = Member.Name; I.Access = Member.Access; I.Extraction = Member.Extraction; - I.Class = Member.Class; + I.FuncClass = Member.FuncClass; I.OverloadedOperator = Member.OverloadedOperator; I.ReturnType = Member.ReturnType; } diff --git a/src/lib/Metadata/Symbol/Record.cpp b/src/lib/Metadata/Symbol/Record.cpp index 75b464128f..919778df52 100644 --- a/src/lib/Metadata/Symbol/Record.cpp +++ b/src/lib/Metadata/Symbol/Record.cpp @@ -4,6 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // // Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com) +// Copyright (c) 2025 Gennaro Prota (gennaro.prota@gmail.com) // // Official repository: https://github.com/cppalliance/mrdocs // @@ -11,27 +12,11 @@ #include #include #include +#include #include namespace mrdocs { -dom::String -toString( - RecordKeyKind kind) noexcept -{ - switch(kind) - { - case RecordKeyKind::Struct: - return "struct"; - case RecordKeyKind::Class: - return "class"; - case RecordKeyKind::Union: - return "union"; - default: - MRDOCS_UNREACHABLE(); - } -} - namespace { void reduceSymbolIDs( @@ -165,12 +150,10 @@ tag_invoke( BaseInfo const& I, DomCorpus const* domCorpus) { - io.map("access", I.Access); + mapWithDescribe(io, I, domCorpus); io.map("isPublic", I.Access == AccessKind::Public); io.map("isProtected", I.Access == AccessKind::Protected); io.map("isPrivate", I.Access == AccessKind::Private); - io.map("isVirtual", I.IsVirtual); - io.map("type", dom::ValueFrom(I.Type, domCorpus)); } void diff --git a/src/lib/Support/LegibleNames.cpp b/src/lib/Support/LegibleNames.cpp index bca33e95de..5594733924 100644 --- a/src/lib/Support/LegibleNames.cpp +++ b/src/lib/Support/LegibleNames.cpp @@ -49,24 +49,24 @@ getUnnamedInfoName(Symbol const& I) if (auto const* FI = I.asFunctionPtr()) { // don't use the reserved prefix for overloaded operators - if(FI->Class == FunctionClass::Normal && + if(FI->FuncClass == FunctionClass::Normal && FI->OverloadedOperator != OperatorKind::None) { return std::string(getSafeOperatorName( FI->OverloadedOperator, true)); } - func_idx = to_underlying(FI->Class); + func_idx = to_underlying(FI->FuncClass); } if (auto const* FI = I.asOverloadsPtr()) { // don't use the reserved prefix for overloaded operators - if(FI->Class == FunctionClass::Normal && + if(FI->FuncClass == FunctionClass::Normal && FI->OverloadedOperator != OperatorKind::None) { return std::string(getSafeOperatorName( FI->OverloadedOperator, true)); } - func_idx = to_underlying(FI->Class); + func_idx = to_underlying(FI->FuncClass); } MRDOCS_ASSERT(func_idx < std::size(func_reserved)); return std::string(func_reserved[func_idx]); @@ -219,7 +219,7 @@ class LegibleNames::Impl { // functions can be explicitly specialized, // and can be overloaded - if (t.Class != FunctionClass::Normal || + if (t.FuncClass != FunctionClass::Normal || t.OverloadedOperator != OperatorKind::None) { return getUnnamedInfoName(t); diff --git a/third-party/recipes/boost_describe.json b/third-party/recipes/boost_describe.json new file mode 100644 index 0000000000..5e748c797d --- /dev/null +++ b/third-party/recipes/boost_describe.json @@ -0,0 +1,15 @@ +{ + "name": "boost_describe", + "version": "1.89.0", + "source": { + "type": "zip", + "url": "https://github.com/boostorg/describe/archive/refs/tags/boost-1.89.0.zip" + }, + "dependencies": [ + "boost_mp11" + ], + "source_dir": "/boost_describe", + "build_dir": "/boost_describe", + "install_dir": "/boost_describe", + "build_type": "" +} diff --git a/third-party/recipes/boost_mp11.json b/third-party/recipes/boost_mp11.json new file mode 100644 index 0000000000..3765227ea4 --- /dev/null +++ b/third-party/recipes/boost_mp11.json @@ -0,0 +1,13 @@ +{ + "name": "boost_mp11", + "version": "1.89.0", + "source": { + "type": "zip", + "url": "https://github.com/boostorg/mp11/archive/refs/tags/boost-1.89.0.zip" + }, + "dependencies": [], + "source_dir": "/boost_mp11", + "build_dir": "/boost_mp11", + "install_dir": "/boost_mp11", + "build_type": "" +}
{{> symbol/qualified-name . }} {{> doc/block/inline-brief doc.brief }}
{{> symbol/qualified-name . }}