43template <std::meta::info Fn>
48 constexpr std::size_t n{std::meta::parameters_of(Fn).size()};
49 std::array<const char*, n> out{};
50 if constexpr (n != 0) {
52 for (std::size_t i{0}; i < n; ++i)
62template <std::meta::info Fn>
66 for (std::size_t i{0}; i < pds.size(); ++i) {
69 out += pds[i].name ? std::string{pds[i].name}
70 :
"arg" + std::to_string(i + 1);
78template <std::meta::info Fn>
82 for (std::size_t i{0}; i < pds.size(); ++i) {
84 out += pds[i].name ? std::string{pds[i].name}
85 :
"arg" + std::to_string(i + 1);
88 const std::string d{
one_line(pds[i].text)};
103template <std::meta::info Fn>
107 std::string s{
"fun("};
108 for (std::size_t i{0}; i < pds.size(); ++i) {
111 s += pds[i].name ? std::string{pds[i].name} :
"arg" + std::to_string(i + 1);
116 std::string ret{ret_override};
118 if constexpr (!std::meta::is_constructor(Fn)) {
119 using R = [:std::meta::return_type_of(Fn):];
120 if constexpr (!std::is_void_v<R>)
121 ret =
lua_type(std::meta::return_type_of(Fn));
145template <std::meta::info Fn>
151 if (!ret_override.empty()) {
152 o.
ret_line =
"---@return " + ret_override +
'\n';
153 }
else if constexpr (!std::meta::is_constructor(Fn)) {
154 using R = [:std::meta::return_type_of(Fn):];
155 if constexpr (!std::is_void_v<R>) {
173template <
auto Grp, std::size_t... I>
190 const std::vector<func_overload>& sigs) {
191 std::size_t primary{0};
192 for (std::size_t i{0}; i < sigs.size(); ++i)
193 if (!sigs[i].
doc.empty()) {
201 for (std::size_t i{0}; i < sigs.size(); ++i)
203 out +=
"---@overload " + sigs[i].fun_sig +
'\n';
204 out +=
"function " + callee +
"(" + p.
args +
") end\n\n";
233 std::string_view text,
234 const std::vector<std::pair<std::string, std::string>>& renames) {
236 return std::string{text};
237 auto is_name_char = [](
char c) {
238 return c ==
'.' || c ==
'_' || (c >=
'A' && c <=
'Z') ||
239 (c >=
'a' && c <=
'z') || (c >=
'0' && c <=
'9');
242 out.reserve(text.size());
243 for (std::size_t i{0}; i < text.size();) {
244 if (!is_name_char(text[i])) {
249 while (j < text.size() && is_name_char(text[j]))
251 const std::string_view tok{text.substr(i, j - i)};
252 const auto it{std::find_if(renames.begin(), renames.end(),
253 [&](
const auto& r) { return r.first == tok; })};
254 out += (it != renames.end()) ? std::string_view{it->second} : tok;
283 if (t.prefix == prefix) {
288 tables.push_back({std::string{prefix},
doc ?
doc :
""});
303 type_renames.emplace_back(std::string{raw}, std::string{styled});
310 auto depth = [](
const std::string& s) {
311 return std::count(s.begin(), s.end(),
'.');
313 std::vector<table_decl> decls{
tables};
314 std::stable_sort(decls.begin(), decls.end(),
316 return depth(a.prefix) < depth(b.prefix);
318 std::string out{
"---@meta\n\n"};
319 for (
const auto& d : decls) {
321 out += d.prefix +
" = {}\n\n";
366 cls_doc = std::move(o.cls_doc);
367 bases = std::move(o.bases);
368 fields = std::move(o.fields);
369 methods = std::move(o.methods);
371 ctors = std::move(o.ctors);
382 out +=
" : " +
bases;
415 values = std::move(o.values);
Backend-agnostic selection layer: the reflection predicates and selectors that decide what participat...
Language-agnostic documentation layer: read [[=welder::doc(...)]] annotations off reflected entities ...
consteval auto param_types()
A function's parameter types, as a static array of reflections.
void render_overload_group(std::string &out, const std::string &callee, const std::vector< func_overload > &sigs)
Emit one documented function <callee>(…) for overload group sigs, with a ---@overload fun(…) line per...
std::string arg_list()
The comma-joined argument-name list for Fn's declaration line (an unnamed parameter becomes arg<N>).
consteval auto param_lua_types()
The LuaCATS type name of each parameter of Fn, as a splice-ready array parallel to param_docs<Fn>().
consteval const char * lua_type(std::meta::info type)
lua_type_string as a static-storage C string, callable on a constant type reflection.
std::string one_line(const char *text)
A one-line description for a @field/@param/@return tail: newlines in text collapse to spaces (LuaCATS...
std::string fun_signature(const std::string &ret_override)
The fun(<name>: <type>, …): <ret> signature of Fn, for a ---@overload line.
func_overload build_overload(const std::string &ret_override)
Build the func_overload for function/constructor Fn.
std::string apply_type_renames(std::string_view text, const std::vector< std::pair< std::string, std::string > > &renames)
Rewrite every whole dotted-name token of text that is a key in renames to its mapped value.
void collect_overloads(std::vector< func_overload > &out, std::index_sequence< I... >)
Append build_overload for each member of overload group Grp to out.
void emit_params(std::string &out)
Emit the ---@param lines for Fn (name, LuaCATS type, and its doc).
consteval std::string lua_type_string(std::meta::info type)
The LuaCATS type name for a C++ type reflection.
void emit_doc_comment(std::string &out, const char *text)
Append text as --- comment lines (each source line prefixed), so a multiline summary lands as a LuaC...
consteval auto param_docs()
The parameter docs of function Fn, in declaration order.
consteval detail::doc_spec< N > doc(const char(&s)[N])
Attach a docstring to a namespace, class, function, or function parameter.
consteval const char * return_doc_of()
The returns text on function Fn (documentation of its return value), or nullptr.
consteval const char * doc_of()
The doc text on Ent (a class, namespace, function, or parameter), or nullptr.
class_writer & operator=(const class_writer &)=delete
std::string qualified
Dotted LuaCATS class name.
class_writer & operator=(class_writer &&o) noexcept
std::vector< func_overload > ctors
The .new overloads, grouped on flush.
class_writer(class_writer &&o) noexcept
class_writer(const class_writer &)=delete
std::string * sink
Flush target override; null = doc->body.
std::string bases
Comma-joined base names, or empty.
std::string fields
Accumulated ---@field / ---@operator lines.
std::string methods
Accumulated function statements.
std::string cls_doc
The class doc.
std::string trailing
Nested types' flushed blocks (after methods).
The growing LuaCATS document shared by every writer handle.
std::string render() const
The finished stub text: the ---@meta header, the module tables shallowest first, then the accumulated...
std::vector< std::pair< std::string, std::string > > type_renames
Raw C++ dotted name → styled/weld_as bound name, for reconciling type references* with their declarat...
void declare_table(std::string_view prefix, const char *doc=nullptr)
Record (once) a module table to declare, updating its doc if given.
void record_type_name(std::string_view raw, std::string_view styled)
Register a welded type's declared name so references to it are reconciled at render.
std::vector< table_decl > tables
std::string * sink
Flush target override; null = doc->body (a nested enum flushes into its outer's trailing,...
enum_writer & operator=(const enum_writer &)=delete
enum_writer(enum_writer &&o) noexcept
enum_writer(const enum_writer &)=delete
std::string values
Accumulated Name = value, lines.
enum_writer & operator=(enum_writer &&o) noexcept
One overload of a callee, pre-rendered into the pieces a group needs: the summary doc,...
std::string args
The function callee(<args>) name list.
std::string ret_line
The ---@return … line (empty when void).
std::string doc
Summary docstring (may be empty).
std::string fun_sig
The fun(a: T, …): R signature.
std::string params
---@param … lines (may be empty).
A module handle: the shared document plus this (sub)module's dotted table path.
A module/submodule table to declare (prefix = {}), with its optional doc.
std::string prefix
The dotted table path, e.g.
std::string doc
Its namespace doc, if any.
The low-level rendering primitives of the LuaCATS stub backend: the C++→LuaCATS type map**,...