Skip to content

fix: specialization title links wrap correct components #898

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions include/mrdocs/Metadata/Info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,10 +341,6 @@ tag_invoke(
if (I.Parent)
{
io.map("parent", I.Parent);
io.defer("parents", [&]
{
return getParents(*domCorpus, I);
});
}
if (I.javadoc)
{
Expand Down
4 changes: 2 additions & 2 deletions share/mrdocs/addons/generator/adoc/partials/symbol.adoc.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
{{#unless @root.config.multipage }}
{{! Single page documentation: symbol is not available to the wrapper but it's available here }}
{{! Include the symbol title at a higher level }}
{{#> markup/h level=1 id=symbol.anchor }}{{> symbol/qualified-name symbol }}{{/markup/h}}
{{#> markup/h level=1 id=symbol.anchor }}{{> symbol/qualified-name-title symbol }}{{/markup/h}}
{{/unless}}
{{! Brief }}
{{#if symbol.doc.brief}}
Expand Down Expand Up @@ -83,7 +83,7 @@
| Description
{{#each symbol.friends }}
{{#if symbol}}
| {{#>markup/code}}{{> symbol/name symbol link=symbol }}{{/markup/code}}
| {{#>markup/code}}{{> symbol/qualified-name symbol }}{{/markup/code}}
| {{> javadoc/inline-brief symbol.doc.brief }}
{{else}}
| {{#>markup/code}}{{> type/declarator type }}{{/markup/code}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
{{~> symbol/name-info . nolink=true~}}
{{~/if~}}
{{~else~}}
{{~#>markup/a href=url}}{{#>markup/code}}{{>symbol/name . nolink=true}}{{/markup/code}}{{/markup/a}} {{>symbol/special-function-suffix .~}}
{{~#>markup/a href=url}}{{#>markup/code}}{{>symbol/name-text .}}{{/markup/code}}{{/markup/a}} {{>symbol/special-function-suffix .~}}
{{~/if~}}
{{~/markup/td}}
{{#if includeBrief~}}
Expand Down
37 changes: 37 additions & 0 deletions share/mrdocs/addons/generator/common/partials/symbol/name-text.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{{!--
Renders the symbol name in an appropriate format for section titles.

This is typically a linked name, but it can also be a special name like
"see-below" or "implementation-defined".

Expected Context: {Symbol Object}

Optional parameters:
nolink: If true, types and symbols will not be linked.
link: Symbol that should be linked to, regardless of the original symbol.

Example:
{{> declarator symbol }}

See: https://mrdocs.com/docs/mrdocs/develop/generators.html#dom_reference
--}}
{{~#if (and (eq kind "function") (eq functionClass "conversion"))~}}
{{! Conversion operator: "operator" and the type declarator ~}}
operator {{>type/declarator return nolink=true~}}
{{~else if (eq kind "guide")~}}
{{! Deduction guide: "deduced" type declarator ~}}
{{>type/declarator deduced nolink=true~}}
{{~else~}}
{{! Symbol with URL: link to the symbol documentation ~}}
{{~#if name~}}
{{~name~}}
{{~else if parent ~}}
Unnamed {{or tag kind~}}
{{~else ~}}
Global namespace
{{~/if~}}
{{~#if (contains (arr "explicit" "partial") template.kind)~}}
{{! Explicit or partial template: render the template arguments ~}}
{{>template/args args=template.args nolink=true~}}
{{~/if~}}
{{~/if~}}
27 changes: 9 additions & 18 deletions share/mrdocs/addons/generator/common/partials/symbol/name.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,20 @@

Optional parameters:
nolink: If true, types and symbols will not be linked.
link: Symbol that should be linked to, regardless of the original symbol.

Example:
{{> declarator symbol }}

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 functionClass "conversion"))~}}
{{! Conversion operator: "operator" and the type declarator ~}}
operator {{>type/declarator return nolink=nolink~}}
{{else if (eq kind "guide")~}}
operator {{>type/declarator return nolink=false~}}
{{~else if (eq kind "guide")~}}
{{! Deduction guide: "deduced" type declarator ~}}
{{>type/declarator deduced nolink=nolink~}}
{{else~}}
{{#if (and link.url (not nolink))~}}
{{! Symbol with URL: link to the symbol documentation ~}}
{{#>markup/a href=link.url}}{{or name "<unnamed>"}}{{/markup/a~}}
{{else~}}
{{! Symbol without URL: plain text ~}}
{{or name "<unnamed>"~}}
{{/if~}}
{{#if (contains (arr "explicit" "partial") template.kind)~}}
{{! Explicit or partial template: render the template arguments ~}}
{{>template/args args=template.args nolink=nolink~}}
{{/if~}}
{{/if}}
{{>type/declarator deduced nolink=false~}}
{{~else if (and url (not nolink))~}}
{{#>markup/a href=url}}{{>symbol/name-text}}{{/markup/a~}}
{{~else~}}
{{~>symbol/name-text~}}
{{~/if~}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{{!--
Renders the qualified symbol name as text only

This partial renders the qualified symbol name as text only.

Expected Context: {Symbol Object}

Example:
{{> symbol/qualified-name symbol }}

See: https://mrdocs.com/docs/mrdocs/develop/generators.html#dom_reference
--}}
{{~#if (and parent parent.parent)~}}
{{~> symbol/qualified-name-text parent ~}}::
{{~/if~}}
{{~#if name ~}}
{{~> symbol/name-text . ~}}
{{~/if~}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{{!--
Renders the qualified symbol in the format used in titles

Titles use a format where all parent namespaces are linked to their documentation.
A parent is included only if it has a name. Unnamed namespaces are not included.

In general, the last symbol name is then appended to the linked namespaces without
any link because it represents the current symbol. However, there are some
exceptions to that:

- If the symbol is a conversion operator, the conversion type is linked.
- If the symbol is a template specialization, the primary template is linked
and the links to the arguments are appended to the name.
- In other cases, the symbol name text is used without any links.

Expected Context: {Symbol Object}

Example:
{{> symbol/title-qualified-name symbol }}

See: https://mrdocs.com/docs/mrdocs/develop/generators.html#dom_reference
--}}
{{~#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"))~}}
{{~> symbol/name . ~}}
{{~else if is-qualified-name-parent ~}}
{{!~ If this is a parent, we only print it if it really has a name ~}}
{{~#if name ~}}
{{~> symbol/name . ~}}
{{~/if~}}
{{~else if (eq kind "guide")~}}
{{>type/declarator deduced nolink=false~}}
{{~else if (contains (arr "explicit" "partial") template.kind)~}}
{{!~ If the last part is a template specialization, we include links to primary template and the arguments. ~}}
{{!~ If the primary template wasn't correctly extracted for some reason, we just print the name as usual. ~}}
{{#if template.primary }}{{~>symbol/name template.primary ~}}{{else}}{{ name }}{{/if}}{{>template/args args=template.args nolink=false~}}
{{~else~}}
{{~> symbol/name-text . ~}}
{{~/if~}}
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
{{!--
Renders the qualified symbol name in an appropriate format for section titles.
Renders the qualified symbol with a link to the symbol's documentation.

This partial renders the symbol name in a format where all parent namespaces
are linked to their documentation. The symbol name is then appended to the
linked namespaces.

It also includes exceptions for unnamed symbols and friend declarations.
Unnamed symbols need to be handled differently as they have no name to display.
Friend declarations need to be handled differently as they are not part of the
symbol hierarchy and need to be linked to the befriended symbol or type.
This partial renders the symbol name in a format where the whole qualified name
is linked to the documentation of the main symbol.

Expected Context: {Symbol Object}

Expand All @@ -17,31 +11,8 @@

See: https://mrdocs.com/docs/mrdocs/develop/generators.html#dom_reference
--}}
{{! We remove whitespace between all tag so the result is in a single line ~}}
{{~#if (ne kind "friend")~}}
{{~#if name~}}
{{! General case: linked parent symbols followed by the symbol name ~}}
{{#each parents~}}
{{#if name~}}
{{>symbol/name . link=. nolink=../nolink}}::
{{~/if}}
{{~/each}}{{>symbol/name .}}
{{~else~}}
{{! Unnamed symbol: use the symbol type in the title ~}}
{{~#if parent~}}
{{! Symbol with no name but with a parent ~}}
Unnamed
{{~else~}}
{{! Symbol with no name and no parent: Global symbol ~}}
Global
{{~/if}} {{or tag kind~}}
{{~/if~}}
{{~#if (and url (not nolink))~}}
{{#>markup/a href=url}}{{>symbol/qualified-name-text}}{{/markup/a~}}
{{~else~}}
{{~#if symbol~}}
{{! Friend symbol: use the befriended symbol ~}}
{{>symbol/qualified-name symbol nolink=nolink ~}}
{{~else~}}
{{! Friend type: use the type name ~}}
{{~>type/declarator type ~}}
{{~/if~}}
{{~>symbol/qualified-name-text~}}
{{~/if~}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{{!--
Renders the qualified symbol name with a link to each component

This partial renders the symbol name in a format where each component
is linked to their documentation.

Expected Context: {Symbol Object}

Example:
{{> symbol/qualified-name symbol }}

See: https://mrdocs.com/docs/mrdocs/develop/generators.html#dom_reference
--}}
{{! We remove whitespace between all tag so the result is in a single line ~}}
{{~#if (and parent parent.parent)~}}
{{~> symbol/qualified-names parent ~}}::
{{~/if~}}
{{~> symbol/name . ~}}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@

See: https://mrdocs.com/docs/mrdocs/develop/generators.html#dom_reference
--}}
{{> (concat 'symbol/signature/' kind) }}
{{> (concat 'symbol/signature/' kind) nolink=nolink }}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{{>template/head template}}

concept {{>symbol/name symbol}} = {{constraint}};
concept {{>symbol/name-text symbol}} = {{constraint}};
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
enum {{#if isScoped}}class {{/if}}{{>symbol/name .~}}
enum {{#if isScoped}}class {{/if}}{{>symbol/name-text .~}}
{{#if type}} : {{>type/declarator type}}{{/if}};
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,15 @@
{{/if~}}
{{#if (eq functionClass "normal")}}{{>type/declarator-prefix return}}
{{/if~}}
{{>symbol/name symbol link=(select link link template.primary)}}
{{~#if force-link~}}
{{>symbol/name symbol }}
{{~else if (eq functionClass "conversion")~}}
{{>symbol/name symbol }}
{{~else if (contains (arr "explicit" "partial") template.kind)~}}
{{>symbol/name template.primary ~}}{{>template/args args=template.args nolink=true~}}
{{~else~}}
{{>symbol/name-text symbol }}
{{~/if~}}
({{#if isExplicitObjectMemberFunction}}this {{/if}}{{#each params}}{{#unless (and @first @last)}}
{{/unless}}{{>type/declarator type decl-name=name~}}
{{#if default}} = {{default}}{{/if~}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{{#if template}}{{>template/head template}}
{{/if~}}
{{#if isFriend}}friend {{/if}}{{tag}} {{>symbol/name symbol link=(select link link template.primary)~}}
{{#if isFriend}}friend {{/if~}}
{{~tag}} {{#if (contains (arr "explicit" "partial") template.kind)~}}
{{>symbol/name template.primary ~}}{{>template/args args=template.args nolink=nolink~}}
{{~else~}}
{{>symbol/name-text symbol ~}}
{{~/if}}
{{#unless bases~}}
{{else if isFriend~}}
{{else}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{{/if~}}
{{#if isThreadLocal}}thread_local
{{/if~}}
{{>type/declarator-prefix type}} {{>symbol/name symbol link=(select link link template.primary)~}}
{{>type/declarator-prefix type}} {{>symbol/name-text symbol ~}}
{{#if isBitfield}} : {{bitfieldWidth}}{{/if~}}
{{#if default}} = {{default}}{{/if~}}
{{>type/declarator-suffix type~}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
{{#each members as | member |}}
{{#if member.doc.brief}}{{> javadoc/brief member.doc.brief }}{{/if}}
{{#> markup/code-block }}
{{> symbol/signature member link=member}}
{{> symbol/signature/function member force-link=true }}
{{/markup/code-block}}
{{#> markup/span class="small" }}{{#> markup/a href=member.url }}{{#>markup/em }}» more{{ str "..." }}{{/markup/em}}{{/markup/a}}{{/markup/span}}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
{{#each symbol.friends }}
<tr>
{{#if symbol}}
<td>{{#>markup/code}}{{> symbol/name symbol link=symbol }}{{/markup/code}}</td>
<td>{{#>markup/code}}{{> symbol/name symbol }}{{/markup/code}}</td>
<td>{{> javadoc/inline-brief symbol.doc.brief }}</td>
{{else}}
<td>{{#>markup/code}}{{> type/declarator type }}{{/markup/code}}</td>
Expand Down
5 changes: 4 additions & 1 deletion src/lib/Metadata/Template.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,10 @@ tag_invoke(
io.defer("kind", [&] {
return toString(I.specializationKind());
});
io.map("primary", I.Primary);
if (I.Primary != SymbolID::invalid)
{
io.map("primary", I.Primary);
}
io.map("params", dom::LazyArray(I.Params, domCorpus));
io.map("args", dom::LazyArray(I.Args, domCorpus));
io.map("requires", dom::stringOrNull(I.Requires.Written));
Expand Down
2 changes: 1 addition & 1 deletion src/lib/Support/LegibleNames.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
}

std::size_t const idx = to_underlying(I.Kind) - 1;
std::string res;
std::string res = "_";
// push idx as two digits
res.push_back(static_cast<char>('0' + (idx / 10)));
res.push_back(static_cast<char>('0' + (idx % 10)));
Expand Down Expand Up @@ -197,7 +197,7 @@
{
Info const* I = corpus_.find(id);
MRDOCS_ASSERT(I);
return getRawUnqualified(*I);

Check warning on line 200 in src/lib/Support/LegibleNames.cpp

View workflow job for this annotation

GitHub Actions / Apple-Clang

Build Warning - clang++ - [-Wreturn-stack-address]

clang++ - returning address of local temporary object ([-Wreturn-stack-address])

Check warning on line 200 in src/lib/Support/LegibleNames.cpp

View workflow job for this annotation

GitHub Actions / Clang 18: C++20

Build Warning - clang++-18 - [-Wreturn-stack-address]

clang++-18 - returning address of local temporary object ([-Wreturn-stack-address])
}

/* @copydoc getRawUnqualified(SymbolID const&)
Expand Down
Loading