Skip to content

Commit 4393f22

Browse files
committed
refactor: custom ValueFrom for Info types
1 parent de7f589 commit 4393f22

30 files changed

+1428
-785
lines changed

include/mrdocs/Corpus.hpp

+20-13
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,7 @@ class MRDOCS_VISIBLE
119119
template<class T = Info>
120120
requires std::derived_from<T, Info>
121121
T const&
122-
get(
123-
SymbolID const& id) const noexcept;
122+
get(SymbolID const& id) const noexcept;
124123

125124
/** Return the metadata for the global namespace.
126125
@@ -160,18 +159,23 @@ class MRDOCS_VISIBLE
160159
}
161160
}
162161

163-
/** Visit the function members of specified Info.
162+
/** Visit the member overloads of specified ScopeInfo.
164163
165-
This function iterates the members of the specified
166-
ScopeInfo `S`. For each member associated with a
167-
function with the same name as the member, the
168-
function object `f` is invoked with the member
164+
This function iterates the members of the
165+
specified ScopeInfo `S`.
166+
167+
For each member in the scope, we check
168+
if the member is a function with overloads.
169+
170+
If the member is a function with overloads,
171+
we create an @ref OverloadSet object and invoke
172+
the function object `f` with the @ref OverloadSet
169173
as the first argument, followed by `args...`.
170174
171-
When there are more than one member function
172-
with the same name, the function object `f` is
173-
invoked with an @ref OverloadSet as the first
174-
argument, followed by `args...`.
175+
If the member is not a function with overloads,
176+
we invoke the function object `f` with the @ref Info
177+
member as the first argument, followed by `args...`.
178+
175179
*/
176180
template <class F, class... Args>
177181
void traverseOverloads(
@@ -230,6 +234,7 @@ traverseOverloads(
230234
ScopeInfo const& S,
231235
F&& f, Args&&... args) const
232236
{
237+
MRDOCS_ASSERT(S.Members.empty() == S.Lookups.empty());
233238
for(const SymbolID& id : S.Members)
234239
{
235240
const Info& member = get(id);
@@ -244,8 +249,10 @@ traverseOverloads(
244249
return get(elem).isFunction();
245250
#endif
246251
});
247-
if(lookup.size() == 1 ||
248-
first_func == lookup.end())
252+
bool const nonOverloadedFunction = lookup.size() == 1;
253+
bool const notFunction = first_func == lookup.end();
254+
if(nonOverloadedFunction ||
255+
notFunction)
249256
{
250257
visit(member, std::forward<F>(f),
251258
std::forward<Args>(args)...);

include/mrdocs/Dom/Value.hpp

+39-8
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,6 @@ class MRDOCS_DECL
113113

114114
Value(char c) noexcept : Value(std::string_view(&c, 1)) {}
115115

116-
template<class Enum>
117-
requires
118-
std::is_enum_v<Enum> &&
119-
(!std::same_as<Enum, dom::Kind>)
120-
Value(Enum v) noexcept
121-
: Value(static_cast<std::underlying_type_t<Enum>>(v))
122-
{}
123-
124116
template<std::size_t N>
125117
Value(char const(&sz)[N])
126118
: Value(String(sz))
@@ -800,6 +792,45 @@ ValueFrom(T&& t)
800792
return v;
801793
}
802794

795+
/** Convert an object of type `T` to @ref dom::Value with a context
796+
797+
This function attempts to convert an object
798+
of type `T` to @ref dom::Value using
799+
800+
@li a user-provided overload of `tag_invoke`.
801+
802+
@li one of @ref dom::Value's constructors,
803+
804+
Conversion of other types is done by calling an overload of `tag_invoke`
805+
found by argument-dependent lookup. Its signature should be similar to:
806+
807+
@code
808+
void tag_invoke( ValueFromTag, dom::Value&, T );
809+
@endcode
810+
811+
@par Exception Safety
812+
Strong guarantee.
813+
814+
@tparam T The type of the object to convert.
815+
816+
@param t The object to convert.
817+
818+
@return @ref dom::Value out parameter.
819+
820+
@see @ref dom::ValueFromTag,
821+
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1895r0.pdf">
822+
tag_invoke: A general pattern for supporting customisable functions</a>
823+
*/
824+
template <class T, class Context>
825+
requires HasValueFrom<T, Context>
826+
Value
827+
ValueFrom(T&& t, Context const& ctx)
828+
{
829+
dom::Value v;
830+
ValueFrom(static_cast<T&&>(t), ctx, v);
831+
return v;
832+
}
833+
803834
} // dom
804835

805836
template <std::convertible_to<std::string_view> SV>

include/mrdocs/Metadata/Function.hpp

+23
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,19 @@ enum class FunctionClass
6767

6868
MRDOCS_DECL dom::String toString(FunctionClass kind) noexcept;
6969

70+
/** Return the FunctionClass from a @ref dom::Value string.
71+
*/
72+
inline
73+
void
74+
tag_invoke(
75+
dom::ValueFromTag,
76+
dom::Value& v,
77+
FunctionClass kind)
78+
{
79+
v = toString(kind);
80+
}
81+
82+
7083
// KRYSTIAN TODO: attributes (nodiscard, deprecated, and carries_dependency)
7184
// KRYSTIAN TODO: flag to indicate whether this is a function parameter pack
7285
/** Represents a single function parameter */
@@ -97,6 +110,16 @@ struct Param
97110
}
98111
};
99112

113+
/** Return the Param as a @ref dom::Value object.
114+
*/
115+
MRDOCS_DECL
116+
void
117+
tag_invoke(
118+
dom::ValueFromTag,
119+
dom::Value& v,
120+
Param const& p,
121+
DomCorpus const* domCorpus);
122+
100123
// TODO: Expand to allow for documenting templating and default args.
101124
// Info for functions.
102125
struct FunctionInfo

include/mrdocs/Metadata/Info.hpp

+23
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@ MRDOCS_DECL
4747
dom::String
4848
toString(InfoKind kind) noexcept;
4949

50+
/** Return the InfoKind from a @ref dom::Value string.
51+
*/
52+
inline
53+
void
54+
tag_invoke(
55+
dom::ValueFromTag,
56+
dom::Value& v,
57+
InfoKind kind)
58+
{
59+
v = toString(kind);
60+
}
61+
5062
/** Base class with common properties of all symbols
5163
*/
5264
struct MRDOCS_VISIBLE
@@ -203,6 +215,17 @@ concept InfoParent = requires(T const& t) {
203215
requires std::convertible_to<std::ranges::range_value_t<decltype(t.Members)>, SymbolID const&>;
204216
};
205217

218+
/** Return the Info to a @ref dom::Value object.
219+
*/
220+
MRDOCS_DECL
221+
void
222+
tag_invoke(
223+
dom::ValueFromTag,
224+
dom::Value& v,
225+
Info const& I,
226+
DomCorpus const* domCorpus);
227+
228+
206229
} // mrdocs
207230
} // clang
208231

include/mrdocs/Metadata/Interface.hpp

+87-19
Original file line numberDiff line numberDiff line change
@@ -24,51 +24,123 @@ namespace clang {
2424
namespace mrdocs {
2525

2626
/** A group of children that have the same access specifier.
27+
28+
This struct represents a collection of symbols that share
29+
the same access specifier within a scope.
30+
31+
It includes one vector for each info type,
32+
and individual vectors for static functions, types,
33+
and overloads.
34+
35+
The tranche is not part of the Corpus. It is a temporary
36+
structure generated to aggregate the symbols of a scope. This
37+
structure is provided to the user via the DOM.
2738
*/
2839
struct Tranche
2940
{
3041
#define INFO(Type) std::vector<SymbolID> Type;
3142
#include <mrdocs/Metadata/InfoNodesPascalPlural.inc>
3243

44+
/// The types with the same access specifier in a scope.
3345
std::vector<SymbolID> Types;
46+
47+
/// The static functions with the same access specifier in a scope.
3448
std::vector<SymbolID> StaticFunctions;
3549

50+
/// The overloads with the same access specifier in a scope.
3651
ScopeInfo Overloads;
52+
53+
/// The static overloads with the same access specifier in a scope.
3754
ScopeInfo StaticOverloads;
3855
};
3956

57+
/** Return a tranche representing the members of a namespace.
58+
59+
@return The tranche.
60+
61+
@param Derived The namespace to build the tranche for.
62+
63+
@param corpus The complete metadata.
64+
*/
65+
MRDOCS_DECL
66+
Tranche
67+
makeTranche(
68+
NamespaceInfo const& Namespace,
69+
Corpus const& corpus);
70+
71+
/** Return the Tranche as a @ref dom::Value object.
72+
*/
73+
MRDOCS_DECL
74+
void
75+
tag_invoke(
76+
dom::ValueFromTag,
77+
dom::Value& v,
78+
std::shared_ptr<Tranche> const& sp,
79+
DomCorpus const* domCorpus);
80+
4081
/** The aggregated interface for a given struct, class, or union.
82+
83+
This class represents the public, protected, and private
84+
interfaces of a record. It is used to generate the
85+
"interface" value of the DOM for symbols that represent
86+
records or namespaces.
87+
88+
The interface is not part of the Corpus. It is a temporary
89+
structure generated to aggregate the symbols of a record.
90+
This structure is provided to the user via the DOM.
91+
92+
While the members of a Namespace are directly represented
93+
with a Tranche, the members of a Record are represented
94+
with an Interface.
95+
4196
*/
4297
class Interface
4398
{
4499
public:
100+
/// The corpus containing the complete metadata.
45101
Corpus const& corpus;
46102

47103
/** The aggregated public interfaces.
48-
*/
104+
105+
This tranche contains all public members of a record
106+
or namespace.
107+
108+
*/
49109
std::shared_ptr<Tranche> Public;
50110

51111
/** The aggregated protected interfaces.
52-
*/
112+
113+
This tranche contains all protected members of a record
114+
or namespace.
115+
116+
*/
53117
std::shared_ptr<Tranche> Protected;
54118

55119
/** The aggregated private interfaces.
56-
*/
120+
121+
This tranche contains all private members of a record
122+
or namespace.
123+
124+
*/
57125
std::shared_ptr<Tranche> Private;
58126

127+
/** Creates an Interface object for a given record.
128+
129+
@param I The record to create the interface for.
130+
@param corpus The complete metadata.
131+
@return The interface.
132+
*/
59133
MRDOCS_DECL
60134
friend
61135
Interface
62136
makeInterface(
63-
RecordInfo const& Derived,
137+
RecordInfo const& I,
64138
Corpus const& corpus);
65139

66140
private:
67141
explicit Interface(Corpus const&) noexcept;
68142
};
69143

70-
//------------------------------------------------
71-
72144
/** Return the composite interface for a record.
73145
74146
@return The interface.
@@ -82,22 +154,18 @@ class Interface
82154
MRDOCS_DECL
83155
Interface
84156
makeInterface(
85-
RecordInfo const& Derived,
157+
RecordInfo const& I,
86158
Corpus const& corpus);
87159

88-
/** Return a tranche representing the members of a namespace.
89-
90-
@return The tranche.
91-
92-
@param Derived The namespace to build the tranche for.
93-
94-
@param corpus The complete metadata.
95-
*/
160+
/** Return the Tranche as a @ref dom::Value object.
161+
*/
96162
MRDOCS_DECL
97-
Tranche
98-
makeTranche(
99-
NamespaceInfo const& Namespace,
100-
Corpus const& corpus);
163+
void
164+
tag_invoke(
165+
dom::ValueFromTag,
166+
dom::Value& v,
167+
std::shared_ptr<Interface> const& sp,
168+
DomCorpus const* domCorpus);
101169

102170
} // mrdocs
103171
} // clang

include/mrdocs/Metadata/Javadoc.hpp

+10
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,16 @@ class MRDOCS_DECL
10191019
doc::List<doc::Block> blocks_;
10201020
};
10211021

1022+
/** Return the Javadoc as a @ref dom::Value.
1023+
*/
1024+
MRDOCS_DECL
1025+
void
1026+
tag_invoke(
1027+
dom::ValueFromTag,
1028+
dom::Value& v,
1029+
Javadoc const& I,
1030+
DomCorpus const* domCorpus);
1031+
10221032
} // mrdocs
10231033
} // clang
10241034

0 commit comments

Comments
 (0)