diff --git a/include/mrdocs/Metadata/Javadoc.hpp b/include/mrdocs/Metadata/Javadoc.hpp index 817d2f5b2c..43f2144b7d 100644 --- a/include/mrdocs/Metadata/Javadoc.hpp +++ b/include/mrdocs/Metadata/Javadoc.hpp @@ -123,7 +123,6 @@ enum class NodeKind throws, details, see, - related, precondition, postcondition }; @@ -651,52 +650,6 @@ tag_invoke( v = dom::LazyObject(I, domCorpus); } -/** A reference to a related symbol. -*/ -struct Related final : Reference -{ - static constexpr auto static_kind = NodeKind::related; - - Related(std::string string_ = std::string()) noexcept - : Reference(std::move(string_), NodeKind::related) - { - } - - auto operator<=>(Related const&) const = default; - bool operator==(Related const&) const noexcept = default; - bool equals(Node const& other) const noexcept override - { - return Kind == other.Kind && - *this == dynamic_cast(other); - } -}; - -/** Map the @ref Related to a @ref dom::Object. - */ -template -void -tag_invoke( - dom::LazyObjectMapTag t, - IO& io, - Related const& I, - DomCorpus const* domCorpus) -{ - tag_invoke(t, io, dynamic_cast(I), domCorpus); -} - -/** Return the @ref Related as a @ref dom::Value object. - */ -inline -void -tag_invoke( - dom::ValueFromTag, - dom::Value& v, - Related const& I, - DomCorpus const* domCorpus) -{ - v = dom::LazyObject(I, domCorpus); -} - //------------------------------------------------ // // Block nodes @@ -1632,8 +1585,6 @@ visit( return visitor.template visit(); case NodeKind::postcondition: return visitor.template visit(); - case NodeKind::related: - return visitor.template visit(); default: MRDOCS_UNREACHABLE(); } @@ -1698,15 +1649,26 @@ struct MRDOCS_DECL /// The list of "see also" references. std::vector sees; - /// The list of "related" references. - std::vector related; - /// The list of preconditions. std::vector preconditions; /// The list of postconditions. std::vector postconditions; + /** The list of "relates" references. + + These references are creates with the + \\relates command. + */ + std::vector relates; + + /** The list of "related" references. + + These references are the inverse of + the \\relates command. + */ + std::vector related; + /** Constructor. */ MRDOCS_DECL @@ -1865,6 +1827,9 @@ tag_invoke( io.defer("sees", [&I, domCorpus] { return dom::LazyArray(I.sees, domCorpus); }); + io.defer("relates", [&I, domCorpus] { + return dom::LazyArray(I.relates, domCorpus); + }); io.defer("related", [&I, domCorpus] { return dom::LazyArray(I.related, domCorpus); }); diff --git a/mrdocs.rnc b/mrdocs.rnc index c10ff2d2cb..4c3fef2c49 100644 --- a/mrdocs.rnc +++ b/mrdocs.rnc @@ -390,7 +390,8 @@ grammar BlockNode = ( Admonition | Brief | Code | Heading | ListItem | UnorderedList | Paragraph | Param | Returns | TParam | - Throws | See | Precondition | Postcondition | Details) + Throws | See | Precondition | Postcondition | Details | + Related | Relates) Admonition = Paragraph Brief = element brief { TextNode * } @@ -417,7 +418,10 @@ grammar Postcondition = element post { TextNode * } Details = element details { TextNode * } - TextNode = ( Link | Styled | Text | Reference | Related | Copied ) + Related = element related { Reference * } + Relates = element relates { Reference * } + + TextNode = ( Link | Styled | Text | Reference | Copied ) Link = element link { attribute href { text }, text } Styled = ( @@ -427,7 +431,7 @@ grammar element italic { text } ) Text = element text { text } Reference = element reference { ID ?, text } - Related = element relates { ID ?, text } + Copied = element ( copydoc | diff --git a/share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs b/share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs index 2b9dd428be..8ba038b4da 100644 --- a/share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs +++ b/share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs @@ -46,7 +46,8 @@ [,cols=2] |=== -|Name |Description +| Name +| Description {{#each (filter_by symbol.constants "isRegular" "isSeeBelow")}} {{#if (ne kind "enum-constant")}} |xref:{{{anchor}}}[`{{>symbol/name . nolink=true}}`] @@ -66,7 +67,30 @@ {{/if}} {{! Related symbols }} {{#if symbol.doc.related}} -{{>symbol/members-table members=symbol.doc.related title="Related functions"}} +{{#> markup/dynamic-level-h }}Non-Member Functions{{/markup/dynamic-level-h}} +[,cols=2] +|=== +| Name +| Description +{{#each symbol.doc.related}} +| {{> javadoc/reference }} +| {{> javadoc/inline-brief symbol.doc.brief }} +{{/each}} +|=== + +{{/if}} +{{! Relates symbols }} +{{#if symbol.doc.relates }} +{{#> markup/dynamic-level-h }}Non-Member Of{{/markup/dynamic-level-h}} +[,cols=2] +|=== +| Name +| Description +{{#each symbol.doc.relates }} +| {{> javadoc/reference }} +| {{> javadoc/inline-brief symbol.doc.brief }} +{{/each}} +|=== {{/if}} {{! Description }} diff --git a/share/mrdocs/addons/generator/html/partials/symbol.html.hbs b/share/mrdocs/addons/generator/html/partials/symbol.html.hbs index 097ecbfbc2..d9d3a43dfa 100644 --- a/share/mrdocs/addons/generator/html/partials/symbol.html.hbs +++ b/share/mrdocs/addons/generator/html/partials/symbol.html.hbs @@ -72,7 +72,7 @@ {{else}} {{>symbol/name . nolink=true}} {{/if}} -{{> javadoc/brief doc.brief }} +{{> javadoc/inline-brief doc.brief }} {{/each}} @@ -86,6 +86,44 @@ +{{/if}} +{{! Related symbols }} +{{#if symbol.doc.related}} +
+{{#> markup/dynamic-level-h }}Non-Member Functions{{/markup/dynamic-level-h}} + + + + + + + + +{{#each symbol.doc.related}} + +{{/each}} + +
NameDescription
{{> javadoc/reference }}{{> javadoc/inline-brief symbol.doc.brief }}
+
+{{/if}} +{{! Relates symbols }} +{{#if symbol.doc.relates }} +
+{{#> markup/dynamic-level-h }}Non-Member Of{{/markup/dynamic-level-h}} + + + + + + + + +{{#each symbol.doc.relates }} + +{{/each}} + +
NameDescription
{{> javadoc/reference }}{{> javadoc/inline-brief symbol.doc.brief }}
+
{{/if}} {{! Description }} {{#if symbol.doc.description}} diff --git a/src/lib/AST/ParseJavadoc.cpp b/src/lib/AST/ParseJavadoc.cpp index d430fc2bfc..3f52c7d54c 100644 --- a/src/lib/AST/ParseJavadoc.cpp +++ b/src/lib/AST/ParseJavadoc.cpp @@ -1024,14 +1024,19 @@ visitInlineCommandComment( // KRYSTIAN FIXME: these need to be made inline commands in clang case CommandTraits::KCI_related: case CommandTraits::KCI_relates: + // MrDocs doesn't document members inline, so there's no + // distinction between "related" and "relatedalso" + case CommandTraits::KCI_relatedalso: + case CommandTraits::KCI_relatesalso: + // Member of is a concept used only in C. MrDocs handles + // it as a non-member function is all cases. + case CommandTraits::KCI_memberof: { MRDOCS_CHECK_OR(goodArgCount(1, *C)); std::string ref = C->getArgText(0).str(); std::string leftOver = fixReference(ref); bool const hasExtra = !leftOver.empty(); - emplaceText( - C->hasTrailingNewline() && !hasExtra, - ref); + jd_.relates.emplace_back(std::move(ref)); if (hasExtra) { emplaceText( diff --git a/src/lib/Gen/xml/CXXTags.hpp b/src/lib/Gen/xml/CXXTags.hpp index ac20601141..b9401c9e49 100644 --- a/src/lib/Gen/xml/CXXTags.hpp +++ b/src/lib/Gen/xml/CXXTags.hpp @@ -48,6 +48,8 @@ constexpr auto templateTagName = "template"; constexpr auto tparamTagName = "tparam"; constexpr auto unionTagName = "union"; constexpr auto varTagName = "variable"; +constexpr auto relatedTagName = "related"; +constexpr auto relatesTagName = "relates"; inline dom::String getNameForValue(...) { diff --git a/src/lib/Gen/xml/XMLWriter.cpp b/src/lib/Gen/xml/XMLWriter.cpp index b65f802cde..df3b7c9e14 100644 --- a/src/lib/Gen/xml/XMLWriter.cpp +++ b/src/lib/Gen/xml/XMLWriter.cpp @@ -733,6 +733,18 @@ writeJavadoc( writeNodes(javadoc->sees); writeNodes(javadoc->preconditions); writeNodes(javadoc->postconditions); + if (!javadoc->relates.empty()) + { + tags_.open(relatesTagName); + writeNodes(javadoc->relates); + tags_.close(relatesTagName); + } + if (!javadoc->related.empty()) + { + tags_.open(relatedTagName); + writeNodes(javadoc->related); + tags_.close(relatedTagName); + } tags_.close(javadocTagName); } @@ -788,9 +800,6 @@ writeNode(doc::Node const& node) case doc::NodeKind::copied: writeCopied(dynamic_cast(node)); break; - case doc::NodeKind::related: - writeRelated(dynamic_cast(node)); - break; case doc::NodeKind::throws: writeThrows(dynamic_cast(node)); break; @@ -844,16 +853,6 @@ writeCopied( }); } -void -XMLWriter:: -writeRelated( - doc::Related const& node) -{ - tags_.write("relates", node.string, { - { node.id } - }); -} - void XMLWriter:: writeLink( diff --git a/src/lib/Gen/xml/XMLWriter.hpp b/src/lib/Gen/xml/XMLWriter.hpp index 65e7b14d56..28bd07febe 100644 --- a/src/lib/Gen/xml/XMLWriter.hpp +++ b/src/lib/Gen/xml/XMLWriter.hpp @@ -89,7 +89,6 @@ class XMLWriter void writeTParam(doc::TParam const& node); void writeReference(doc::Reference const& node); void writeCopied(doc::Copied const& node); - void writeRelated(doc::Related const& node); void writeThrows(doc::Throws const& node); void writeSee(doc::See const& node, llvm::StringRef tag = ""); void writePrecondition(doc::Precondition const& node); diff --git a/src/lib/Metadata/Finalizers/JavadocFinalizer.cpp b/src/lib/Metadata/Finalizers/JavadocFinalizer.cpp index f7389a2dc0..32be10f733 100644 --- a/src/lib/Metadata/Finalizers/JavadocFinalizer.cpp +++ b/src/lib/Metadata/Finalizers/JavadocFinalizer.cpp @@ -138,14 +138,6 @@ finalize(doc::Reference& ref, bool const emitWarning) // returns a non-const reference. auto& res = const_cast(resRef->get()); ref.id = res.id; - if(ref.Kind == doc::NodeKind::related) - { - if(! res.javadoc) - res.javadoc.emplace(); - auto& related = res.javadoc->related; - if(std::ranges::find(related, current_context_->id) == related.end()) - related.emplace_back(current_context_->id); - } } else if ( emitWarning && @@ -180,8 +172,7 @@ finalize(doc::Node& node) finalize(N.children); } - if constexpr(std::same_as || - std::same_as) + if constexpr(std::same_as) { finalize(dynamic_cast(N), true); } @@ -205,6 +196,7 @@ finalize(Javadoc& javadoc) finalize(javadoc.sees); finalize(javadoc.preconditions); finalize(javadoc.postconditions); + setRelateIds(javadoc); copyBriefAndDetails(javadoc); setAutoBrief(javadoc); removeTempTextNodes(javadoc); @@ -212,6 +204,54 @@ finalize(Javadoc& javadoc) unindentCodeBlocks(javadoc); } +void +JavadocFinalizer:: +setRelateIds(Javadoc& javadoc) +{ + MRDOCS_CHECK_OR(!javadoc.relates.empty()); + + Info const* currentPtr = corpus_.find(current_context_->id); + MRDOCS_ASSERT(currentPtr); + Info const current = *currentPtr; + + if (!current.isFunction()) + { + this->warn( + "{}: `@relates` only allowed for functions", + corpus_.Corpus::qualifiedName(current)); + javadoc.relates.clear(); + return; + } + + for (doc::Reference& ref: javadoc.relates) + { + finalize(ref, true); + Info* relatedPtr = corpus_.find(ref.id); + MRDOCS_CHECK_OR_CONTINUE(relatedPtr); + Info& related = *relatedPtr; + if (!related.javadoc) + { + related.javadoc.emplace(); + } + if (std::ranges::none_of( + related.javadoc->related, + [this](doc::Reference const& otherRef) { + return otherRef.id == current_context_->id; + })) + { + std::string currentName = corpus_.Corpus::qualifiedName(current); + doc::Reference relatedRef(std::move(currentName)); + relatedRef.id = current_context_->id; + related.javadoc->related.push_back(std::move(relatedRef)); + } + } + + // Erase anything in the javadoc without a valid id + std::erase_if(javadoc.relates, [](doc::Reference const& ref) { + return !ref.id; + }); +} + void JavadocFinalizer:: copyBriefAndDetails(Javadoc& javadoc) @@ -722,7 +762,7 @@ removeTempTextNodes(doc::Block& block) std::erase_if(block.children, [](Polymorphic const& child) { return is_one_of( child->Kind, - { doc::NodeKind::copied, doc::NodeKind::related }); + { doc::NodeKind::copied }); }); } diff --git a/src/lib/Metadata/Finalizers/JavadocFinalizer.hpp b/src/lib/Metadata/Finalizers/JavadocFinalizer.hpp index 4efa46a390..86bba58ba5 100644 --- a/src/lib/Metadata/Finalizers/JavadocFinalizer.hpp +++ b/src/lib/Metadata/Finalizers/JavadocFinalizer.hpp @@ -124,6 +124,11 @@ class JavadocFinalizer void finalize(Javadoc& javadoc); + // Find the ID of "relates" symbols and populate + // the "related" symbol with the inverse. + void + setRelateIds(Javadoc& javadoc); + // Copy brief and details to the current context void copyBriefAndDetails(Javadoc& javadoc); diff --git a/src/lib/Metadata/Javadoc.cpp b/src/lib/Metadata/Javadoc.cpp index c1639e4436..9538877ef0 100644 --- a/src/lib/Metadata/Javadoc.cpp +++ b/src/lib/Metadata/Javadoc.cpp @@ -63,8 +63,6 @@ toString(NodeKind kind) noexcept return "details"; case NodeKind::see: return "see"; - case NodeKind::related: - return "related"; case NodeKind::precondition: return "precondition"; case NodeKind::postcondition: diff --git a/test-files/golden-tests/javadoc/relates/relates.adoc b/test-files/golden-tests/javadoc/relates/relates.adoc index 45b16e7312..af86c0ab41 100644 --- a/test-files/golden-tests/javadoc/relates/relates.adoc +++ b/test-files/golden-tests/javadoc/relates/relates.adoc @@ -40,17 +40,16 @@ Declared in `<relates.cpp>` struct A; ---- -=== Related functions +=== Non-Member Functions -[cols=2] +[,cols=2] |=== | Name | Description -| <> +| <> | A brief for f. |=== - [#B] == B @@ -80,5 +79,15 @@ void f(); ---- +=== Non-Member Of + +[,cols=2] +|=== +| Name +| Description +| <> +| A brief for A. +|=== + [.small]#Created with https://www.mrdocs.com[MrDocs]# diff --git a/test-files/golden-tests/javadoc/relates/relates.html b/test-files/golden-tests/javadoc/relates/relates.html index c2c3570d3c..c7ff7fce55 100644 --- a/test-files/golden-tests/javadoc/relates/relates.html +++ b/test-files/golden-tests/javadoc/relates/relates.html @@ -59,6 +59,20 @@

Synopsis

+
+

Non-Member Functions

+ + + + + + + + + + +
NameDescription
fA brief for f.
+
@@ -100,6 +114,20 @@

Synopsis

+
+

Non-Member Of

+ + + + + + + + + + +
NameDescription
AA brief for A.
+
diff --git a/test-files/golden-tests/javadoc/relates/relates.xml b/test-files/golden-tests/javadoc/relates/relates.xml index 7c941d3a84..e987e5cace 100644 --- a/test-files/golden-tests/javadoc/relates/relates.xml +++ b/test-files/golden-tests/javadoc/relates/relates.xml @@ -8,6 +8,9 @@ A brief for A. + + f + @@ -24,6 +27,9 @@ A brief for f. + + A + diff --git a/test-files/golden-tests/symbols/enum/enum.adoc b/test-files/golden-tests/symbols/enum/enum.adoc index 141883014b..c9bff05218 100644 --- a/test-files/golden-tests/symbols/enum/enum.adoc +++ b/test-files/golden-tests/symbols/enum/enum.adoc @@ -39,7 +39,8 @@ enum E0; [,cols=2] |=== -|Name |Description +| Name +| Description |`e0` |e0 brief. |`e1` @@ -67,7 +68,8 @@ enum E1 : char; [,cols=2] |=== -|Name |Description +| Name +| Description |`e2` | |`e3` @@ -93,7 +95,8 @@ enum class E2 : int; [,cols=2] |=== -|Name |Description +| Name +| Description |`e4` |e4 brief. |`e5` @@ -121,7 +124,8 @@ enum class E3 : char; [,cols=2] |=== -|Name |Description +| Name +| Description |`e6` | |`e7`