diff --git a/include/mrdocs/Metadata/Info/Function.hpp b/include/mrdocs/Metadata/Info/Function.hpp index a4c0f4f867..2cbf08bcc2 100644 --- a/include/mrdocs/Metadata/Info/Function.hpp +++ b/include/mrdocs/Metadata/Info/Function.hpp @@ -127,6 +127,10 @@ struct Param final operator<=>(Param const&) const = default; }; +MRDOCS_DECL +void +merge(Param& I, Param&& Other); + /** Return the Param as a @ref dom::Value object. */ MRDOCS_DECL diff --git a/include/mrdocs/Metadata/Template.hpp b/include/mrdocs/Metadata/Template.hpp index b9572c39c0..a51808441a 100644 --- a/include/mrdocs/Metadata/Template.hpp +++ b/include/mrdocs/Metadata/Template.hpp @@ -412,6 +412,10 @@ struct TemplateInfo operator<=>(TemplateInfo const& other) const; }; +MRDOCS_DECL +void +merge(TemplateInfo& I, TemplateInfo&& Other); + inline auto operator<=>(std::optional const& lhs, std::optional const& rhs) diff --git a/src/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp index 068704feea..d973395f69 100644 --- a/src/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -792,7 +792,7 @@ populate( MRDOCS_SYMBOL_TRACE(P, context_); Param& param = I.Params[i]; - if (!param.Name) + if (!param.Name && !P->getName().empty()) { param.Name = P->getName(); } @@ -804,8 +804,7 @@ populate( Expr const* default_arg = P->hasUninstantiatedDefaultArg() ? P->getUninstantiatedDefaultArg() : P->getInit(); - if (!param.Default && - default_arg) + if (!param.Default && default_arg) { param.Default = getSourceCode(default_arg->getSourceRange()); param.Default = trim(*param.Default); diff --git a/src/lib/Metadata/Info/Concept.cpp b/src/lib/Metadata/Info/Concept.cpp index 66b6144c28..3204acc649 100644 --- a/src/lib/Metadata/Info/Concept.cpp +++ b/src/lib/Metadata/Info/Concept.cpp @@ -63,10 +63,14 @@ merge(ConceptInfo& I, ConceptInfo&& Other) { MRDOCS_ASSERT(canMerge(I, Other)); merge(dynamic_cast(I), std::move(dynamic_cast(Other))); - if(I.Constraint.Written.empty()) + if (I.Constraint.Written.empty()) + { I.Constraint = std::move(Other.Constraint); - if (! I.Template) + } + if (!I.Template) + { I.Template = std::move(Other.Template); + } } } // clang::mrdocs diff --git a/src/lib/Metadata/Info/Enum.cpp b/src/lib/Metadata/Info/Enum.cpp index 0deedd7d6e..d84e249fae 100644 --- a/src/lib/Metadata/Info/Enum.cpp +++ b/src/lib/Metadata/Info/Enum.cpp @@ -39,10 +39,14 @@ merge(EnumInfo& I, EnumInfo&& Other) { MRDOCS_ASSERT(canMerge(I, Other)); merge(dynamic_cast(I), std::move(dynamic_cast(Other))); - if(! I.Scoped) + if (!I.Scoped) + { I.Scoped = Other.Scoped; - if (! I.UnderlyingType) + } + if (!I.UnderlyingType) + { I.UnderlyingType = std::move(Other.UnderlyingType); + } reduceSymbolIDs(I.Constants, std::move(Other.Constants)); } diff --git a/src/lib/Metadata/Info/EnumConstant.cpp b/src/lib/Metadata/Info/EnumConstant.cpp index d8199664b1..98a0188b13 100644 --- a/src/lib/Metadata/Info/EnumConstant.cpp +++ b/src/lib/Metadata/Info/EnumConstant.cpp @@ -20,8 +20,10 @@ merge(EnumConstantInfo& I, EnumConstantInfo&& Other) { MRDOCS_ASSERT(canMerge(I, Other)); merge(dynamic_cast(I), std::move(dynamic_cast(Other))); - if(I.Initializer.Written.empty()) + if (I.Initializer.Written.empty()) + { I.Initializer = std::move(Other.Initializer); + } } } // clang::mrdocs diff --git a/src/lib/Metadata/Info/Field.cpp b/src/lib/Metadata/Info/Field.cpp index f9de78b61c..ae31c6966c 100644 --- a/src/lib/Metadata/Info/Field.cpp +++ b/src/lib/Metadata/Info/Field.cpp @@ -20,10 +20,14 @@ merge(FieldInfo& I, FieldInfo&& Other) { MRDOCS_ASSERT(canMerge(I, Other)); merge(dynamic_cast(I), std::move(dynamic_cast(Other))); - if(! I.Type) + if (!I.Type) + { I.Type = std::move(Other.Type); - if(I.Default.Written.empty()) + } + if (I.Default.Written.empty()) + { I.Default = std::move(Other.Default); + } I.IsBitfield |= Other.IsBitfield; merge(I.BitfieldWidth, std::move(Other.BitfieldWidth)); I.IsVariant |= Other.IsVariant; diff --git a/src/lib/Metadata/Info/Friend.cpp b/src/lib/Metadata/Info/Friend.cpp index dee8b71c84..9a99be0ab8 100644 --- a/src/lib/Metadata/Info/Friend.cpp +++ b/src/lib/Metadata/Info/Friend.cpp @@ -20,10 +20,14 @@ merge(FriendInfo& I, FriendInfo&& Other) { MRDOCS_ASSERT(canMerge(I, Other)); merge(dynamic_cast(I), std::move(dynamic_cast(Other))); - if(! I.FriendSymbol) + if (!I.FriendSymbol) + { I.FriendSymbol = Other.FriendSymbol; - if(! I.FriendType) + } + if (!I.FriendType) + { I.FriendType = std::move(Other.FriendType); + } } } // clang::mrdocs diff --git a/src/lib/Metadata/Info/Function.cpp b/src/lib/Metadata/Info/Function.cpp index 561d942101..df247a7c11 100644 --- a/src/lib/Metadata/Info/Function.cpp +++ b/src/lib/Metadata/Info/Function.cpp @@ -187,6 +187,23 @@ toString( } } +void +merge(Param& I, Param&& Other) +{ + if (!I.Type) + { + I.Type = std::move(Other.Type); + } + if (!I.Name) + { + I.Name = std::move(Other.Name); + } + if (!I.Default) + { + I.Default = std::move(Other.Default); + } +} + template void tag_invoke( @@ -276,14 +293,26 @@ merge(FunctionInfo& I, FunctionInfo&& Other) { I.ReturnType = std::move(Other.ReturnType); } - if (I.Params.empty()) + std::size_t const n = std::min(I.Params.size(), Other.Params.size()); + for (std::size_t i = 0; i < n; ++i) { - I.Params = std::move(Other.Params); + merge(I.Params[i], std::move(Other.Params[i])); + } + if (Other.Params.size() > n) + { + I.Params.insert( + I.Params.end(), + std::make_move_iterator(Other.Params.begin() + n), + std::make_move_iterator(Other.Params.end())); } if (!I.Template) { I.Template = std::move(Other.Template); } + else if (Other.Template) + { + merge(*I.Template, std::move(*Other.Template)); + } if (I.Noexcept.Implicit) { I.Noexcept = std::move(Other.Noexcept); diff --git a/src/lib/Metadata/Info/NamespaceAlias.cpp b/src/lib/Metadata/Info/NamespaceAlias.cpp index 24ce9a85a9..f30eb6738b 100644 --- a/src/lib/Metadata/Info/NamespaceAlias.cpp +++ b/src/lib/Metadata/Info/NamespaceAlias.cpp @@ -20,8 +20,10 @@ merge(NamespaceAliasInfo& I, NamespaceAliasInfo&& Other) { MRDOCS_ASSERT(canMerge(I, Other)); merge(dynamic_cast(I), std::move(dynamic_cast(Other))); - if (! I.AliasedSymbol) + if (!I.AliasedSymbol) + { I.AliasedSymbol = std::move(Other.AliasedSymbol); + } } } // clang::mrdocs diff --git a/src/lib/Metadata/Info/Record.cpp b/src/lib/Metadata/Info/Record.cpp index 8ce55e78c2..2252e023d2 100644 --- a/src/lib/Metadata/Info/Record.cpp +++ b/src/lib/Metadata/Info/Record.cpp @@ -132,8 +132,10 @@ merge(RecordInfo& I, RecordInfo&& Other) I.Bases = std::move(Other.Bases); } merge(I.Interface, std::move(Other.Interface)); - if (! I.Template) + if (!I.Template) + { I.Template = std::move(Other.Template); + } } template diff --git a/src/lib/Metadata/Info/Specialization.cpp b/src/lib/Metadata/Info/Specialization.cpp index b534c27b07..73b1168bc8 100644 --- a/src/lib/Metadata/Info/Specialization.cpp +++ b/src/lib/Metadata/Info/Specialization.cpp @@ -20,10 +20,14 @@ merge(SpecializationInfo& I, SpecializationInfo&& Other) { MRDOCS_ASSERT(canMerge(I, Other)); merge(dynamic_cast(I), std::move(dynamic_cast(Other))); - if(! I.Primary) + if (!I.Primary) + { I.Primary = Other.Primary; - if(I.Args.empty()) + } + if (I.Args.empty()) + { I.Args = std::move(Other.Args); + } } } // clang::mrdocs diff --git a/src/lib/Metadata/Info/Typedef.cpp b/src/lib/Metadata/Info/Typedef.cpp index a310938d9a..e82a6a6fe2 100644 --- a/src/lib/Metadata/Info/Typedef.cpp +++ b/src/lib/Metadata/Info/Typedef.cpp @@ -64,11 +64,17 @@ void merge(TypedefInfo& I, TypedefInfo&& Other) MRDOCS_ASSERT(canMerge(I, Other)); merge(dynamic_cast(I), std::move(dynamic_cast(Other))); if (!I.IsUsing) + { I.IsUsing = Other.IsUsing; - if (! I.Type) + } + if (!I.Type) + { I.Type = std::move(Other.Type); - if(! I.Template) + } + if (!I.Template) + { I.Template = std::move(Other.Template); + } } } // clang::mrdocs diff --git a/src/lib/Metadata/Info/Using.cpp b/src/lib/Metadata/Info/Using.cpp index d60f3fe9eb..e5d76989d8 100644 --- a/src/lib/Metadata/Info/Using.cpp +++ b/src/lib/Metadata/Info/Using.cpp @@ -41,9 +41,13 @@ merge(UsingInfo& I, UsingInfo&& Other) merge(dynamic_cast(I), std::move(dynamic_cast(Other))); reduceSymbolIDs(I.UsingSymbols, std::move(Other.UsingSymbols)); if (I.Class == UsingClass::Normal) + { I.Class = Other.Class; - if (! I.Qualifier) + } + if (!I.Qualifier) + { I.Qualifier = std::move(Other.Qualifier); + } } } // clang::mrdocs diff --git a/src/lib/Metadata/Info/Variable.cpp b/src/lib/Metadata/Info/Variable.cpp index 51b6748306..598b18a1d5 100644 --- a/src/lib/Metadata/Info/Variable.cpp +++ b/src/lib/Metadata/Info/Variable.cpp @@ -63,12 +63,18 @@ merge(VariableInfo& I, VariableInfo&& Other) { MRDOCS_ASSERT(canMerge(I, Other)); merge(dynamic_cast(I), std::move(dynamic_cast(Other))); - if(! I.Type) + if (!I.Type) + { I.Type = std::move(Other.Type); - if(! I.Template) + } + if (!I.Template) + { I.Template = std::move(Other.Template); - if(I.Initializer.Written.empty()) + } + if (I.Initializer.Written.empty()) + { I.Initializer = std::move(Other.Initializer); + } I.IsConstinit |= Other.IsConstinit; I.IsThreadLocal |= Other.IsThreadLocal; I.IsConstexpr |= Other.IsConstexpr; diff --git a/src/lib/Metadata/Template.cpp b/src/lib/Metadata/Template.cpp index 57c407c66e..9ee7f97a6d 100644 --- a/src/lib/Metadata/Template.cpp +++ b/src/lib/Metadata/Template.cpp @@ -273,6 +273,63 @@ operator<=>(TemplateInfo const& other) const { std::tie(Args, Params, other.Requires, other.Primary); } +void +merge(TemplateInfo& I, TemplateInfo&& Other) +{ + std::size_t const pn = std::min(I.Params.size(), Other.Params.size()); + for (std::size_t i = 0; i < pn; ++i) + { + if (!I.Params[i] || I.Params[i]->Kind != Other.Params[i]->Kind) + { + I.Params[i] = std::move(Other.Params[i]); + } + else + { + if (I.Params[i]->Name.empty()) + { + I.Params[i]->Name = std::move(Other.Params[i]->Name); + } + if (!I.Params[i]->Default) + { + I.Params[i]->Default = std::move(Other.Params[i]->Default); + } + } + } + if (Other.Params.size() > pn) + { + I.Params.insert( + I.Params.end(), + std::make_move_iterator(Other.Params.begin() + pn), + std::make_move_iterator(Other.Params.end())); + } + + std::size_t const an = std::min(I.Args.size(), Other.Args.size()); + for (std::size_t i = 0; i < an; ++i) + { + if (!I.Args[i] || I.Args[i]->Kind != Other.Args[i]->Kind) + { + I.Args[i] = std::move(Other.Args[i]); + } + } + if (Other.Args.size() > an) + { + I.Args.insert( + I.Args.end(), + std::make_move_iterator(Other.Args.begin() + an), + std::make_move_iterator(Other.Args.end())); + } + + if (I.Requires.Written.empty()) + { + I.Requires = std::move(Other.Requires); + } + + if (I.Primary == SymbolID::invalid) + { + I.Primary = Other.Primary; + } +} + template void tag_invoke( diff --git a/test-files/golden-tests/symbols/function/merge-params.adoc b/test-files/golden-tests/symbols/function/merge-params.adoc new file mode 100644 index 0000000000..d20cb07cf9 --- /dev/null +++ b/test-files/golden-tests/symbols/function/merge-params.adoc @@ -0,0 +1,55 @@ += Reference +:mrdocs: + +[#index] +== Global namespace + + +=== Functions + +[cols=2] +|=== +| Name +| Description + +| <> +| Function + +|=== + +[#f] +== f + + +Function + +=== Synopsis + + +Declared in `<merge‐params.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +f( + int a, + int b); +---- + +=== Parameters + + +|=== +| Name | Description + +| *a* +| The first parameter. + +| *b* +| The second parameter. + +|=== + + + +[.small]#Created with https://www.mrdocs.com[MrDocs]# diff --git a/test-files/golden-tests/symbols/function/merge-params.cpp b/test-files/golden-tests/symbols/function/merge-params.cpp new file mode 100644 index 0000000000..71d0d4843b --- /dev/null +++ b/test-files/golden-tests/symbols/function/merge-params.cpp @@ -0,0 +1,13 @@ +/** Function + + @param a The first parameter. + @param b The second parameter. + */ +void +f(int,int); + +void +f(int a, int); + +void +f(int, int b); \ No newline at end of file diff --git a/test-files/golden-tests/symbols/function/merge-params.html b/test-files/golden-tests/symbols/function/merge-params.html new file mode 100644 index 0000000000..4b6da2b94a --- /dev/null +++ b/test-files/golden-tests/symbols/function/merge-params.html @@ -0,0 +1,80 @@ + + +Reference + + +
+

Reference

+
+
+

Global namespace

+
+

Functions

+ + + + + + + + + + + + +
NameDescription
f Function +
+
+
+
+

f

+
+Function + + +
+
+
+

Synopsis

+
+Declared in <merge-params.cpp>
+
+
+void
+f(
+    int a,
+    int b);
+
+
+
+
+

Parameters

+ + + + + + + + + + + + + + + + + +
NameDescription
a

The first parameter.

+
b

The second parameter.

+
+
+
+ +
+
+

Created with MrDocs

+
+ + \ No newline at end of file diff --git a/test-files/golden-tests/symbols/function/merge-params.xml b/test-files/golden-tests/symbols/function/merge-params.xml new file mode 100644 index 0000000000..f3be164186 --- /dev/null +++ b/test-files/golden-tests/symbols/function/merge-params.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + Function + + + The first parameter. + + + The second parameter. + + + + + diff --git a/test-files/golden-tests/symbols/function/merge-tparams.adoc b/test-files/golden-tests/symbols/function/merge-tparams.adoc new file mode 100644 index 0000000000..b100826e9a --- /dev/null +++ b/test-files/golden-tests/symbols/function/merge-tparams.adoc @@ -0,0 +1,56 @@ += Reference +:mrdocs: + +[#index] +== Global namespace + + +=== Functions + +[cols=2] +|=== +| Name +| Description + +| <> +| Function + +|=== + +[#f] +== f + + +Function + +=== Synopsis + + +Declared in `<merge‐tparams.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +template< + class T, + class U> +void +f(); +---- + +=== Template Parameters + + +|=== +| Name | Description + +| *T* +| The first template parameter. + +| *U* +| The second template parameter. + +|=== + + + +[.small]#Created with https://www.mrdocs.com[MrDocs]# diff --git a/test-files/golden-tests/symbols/function/merge-tparams.cpp b/test-files/golden-tests/symbols/function/merge-tparams.cpp new file mode 100644 index 0000000000..407bef1c79 --- /dev/null +++ b/test-files/golden-tests/symbols/function/merge-tparams.cpp @@ -0,0 +1,16 @@ +/** Function + + @tparam T The first template parameter. + @tparam U The second template parameter. + */ +template +void +f(); + +template +void +f(); + +template +void +f(); \ No newline at end of file diff --git a/test-files/golden-tests/symbols/function/merge-tparams.html b/test-files/golden-tests/symbols/function/merge-tparams.html new file mode 100644 index 0000000000..83c853e8a1 --- /dev/null +++ b/test-files/golden-tests/symbols/function/merge-tparams.html @@ -0,0 +1,81 @@ + + +Reference + + +
+

Reference

+
+
+

Global namespace

+
+

Functions

+ + + + + + + + + + + + +
NameDescription
f Function +
+
+
+
+

f

+
+Function + + +
+
+
+

Synopsis

+
+Declared in <merge-tparams.cpp>
+
+
+template<
+    class T,
+    class U>
+void
+f();
+
+
+
+
+

Template Parameters

+ + + + + + + + + + + + + + + + + +
NameDescription
T

The first template parameter.

+
U

The second template parameter.

+
+
+
+ +
+
+

Created with MrDocs

+
+ + \ No newline at end of file diff --git a/test-files/golden-tests/symbols/function/merge-tparams.xml b/test-files/golden-tests/symbols/function/merge-tparams.xml new file mode 100644 index 0000000000..66622b56c1 --- /dev/null +++ b/test-files/golden-tests/symbols/function/merge-tparams.xml @@ -0,0 +1,26 @@ + + + + + +