Initial revision of lua 'doc' function

This commit is contained in:
2021-12-15 23:03:43 -05:00
parent e0001127c7
commit 1cfdb4fa09
22 changed files with 301 additions and 199 deletions

View File

@@ -15,7 +15,7 @@
#include "source.hpp"
#include "luasnap.hpp"
LuaDefine(source_makeclass, "f") {
LuaDefine(makeclass, "classname", "create a class if it doesn't already exist") {
LuaArg classname;
LuaRet classtab;
LuaStack LS(L, classname, classtab);
@@ -23,7 +23,7 @@ LuaDefine(source_makeclass, "f") {
return LS.result();
}
LuaDefine(source_classname, "f") {
LuaDefine(classname, "classtable", "get the class name from a class table") {
LuaArg table;
LuaRet result;
LuaStack LS(L, table, result);
@@ -36,7 +36,7 @@ LuaDefine(source_classname, "f") {
return LS.result();
}
LuaDefine(source_maketangible, "f") {
LuaDefine(maketangible, "classname", "create a class if it doesn't already exist, and add tangible features") {
LuaArg classname;
LuaRet classtab;
LuaVar subtab;
@@ -46,6 +46,18 @@ LuaDefine(source_maketangible, "f") {
return LS.result();
}
static void get_reg_name(const LuaFunctionReg *reg, std::string &classname, std::string &funcname) {
std::string name = reg->get_name();
size_t upos = name.find('_');
if (upos == std::string::npos) {
funcname = name;
classname = "";
} else {
funcname = name.substr(upos + 1);
classname = name.substr(0, upos);
}
}
// the 'luaopen' function creates a new table.
//
@@ -299,25 +311,16 @@ static void source_load_cfunctions(lua_State *L) {
LuaStack LS(L, classobj);
auto regs = LuaFunctionReg::all();
for (const LuaFunctionReg *r : regs) {
const std::string &name = r->get_name();
size_t upos = name.find('_');
lua_CFunction func = r->get_func();
std::string classname;
std::string funcname;
if (upos == std::string::npos) {
continue;
} else {
funcname = name.substr(upos + 1);
classname = name.substr(0, upos);
}
lua_CFunction func = r->get_func();
std::string mode = r->get_mode();
if (mode.find('c') != std::string::npos) { // Insert into class
LS.makeclass(classobj, classname);
LS.rawset(classobj, funcname, func);
}
if (mode.find('f') != std::string::npos) { // Make global function
get_reg_name(r, classname, funcname);
if (classname.empty()) {
LS.getglobaltable(classobj);
LS.rawset(classobj, funcname, func);
} else {
LS.makeclass(classobj, classname);
LS.rawset(classobj, funcname, func);
}
}
LS.result();
@@ -465,8 +468,80 @@ void SourceDB::deserialize_source(util::LuaSourceVec *sv, StreamBuffer *sb) {
}
}
std::string SourceDB::function_docs(const LuaStack &LS0, LuaSlot fn) {
lua_State *L = LS0.state();
LuaVar sourcedb, fname, finfo, code;
LuaStack LS(L, sourcedb, fname, finfo, code);
if (LS.iscfunction(fn)) {
lua_CFunction cfn = lua_tocfunction(L, fn.index());
const LuaFunctionReg *reg = LuaFunctionReg::lookup(cfn);
if (reg == nullptr) {
return "";
}
std::string classname;
std::string funcname;
get_reg_name(reg, classname, funcname);
std::ostringstream oss;
util::StringVec docs = util::split_lines(reg->get_docs());
for (const std::string &line : docs) {
oss << "-- " << line << std::endl;
}
oss << "function ";
if (!classname.empty()) {
oss << classname << ".";
}
oss << funcname << "(" << reg->get_args() << ")";
return oss.str();
} else if (LS.isfunction(fn)) {
lua_Debug ar;
lua_pushvalue(L, fn.index());
int status = lua_getinfo(L, ">S", &ar);
if (status == 0) return "";
// Get the source database.
LS.rawget(sourcedb, LuaRegistry, "sourcedb");
if (!LS.istable(sourcedb)) {
return "";
}
// Get the finfo table from the source db.
LS.set(fname, std::string(ar.short_src));
LS.rawget(finfo, sourcedb, fname);
if (!LS.istable(finfo)) {
return "";
}
// Get the code from the finfo table.
LS.rawget(code, finfo, "code");
if (!LS.isstring(code)) {
return "";
}
// Split the code into lines.
util::StringVec lines = util::split_lines(LS.ckstring(code));
int linehi = ar.linedefined - 1;
if ((linehi < 0) || (linehi >= int(lines.size()))) {
return "";
}
// Incorporate the function comment.
int linelo = linehi;
while ((linelo > 0) && (util::is_lua_comment(lines[linelo-1]))) linelo -= 1;
// Output the docs.
std::ostringstream result;
for (int i = linelo; i <= linehi; i++) {
result << lines[i] << std::endl;
}
return result.str();
} else {
return "";
}
}
// These should go away eventually. They're for debugging.
LuaDefine(coroutine_setnextid, "c") {
LuaDefine(coroutine_setnextid, "thread,id", "set the next id of a thread (debugging only)") {
LuaArg co, lid;
LuaStack LS(L, co, lid);
lua_State *CO = LS.ckthread(co);
@@ -475,7 +550,7 @@ LuaDefine(coroutine_setnextid, "c") {
return LS.result();
}
LuaDefine(coroutine_getnextid, "c") {
LuaDefine(coroutine_getnextid, "thread", "get the next id of a thread (debugging only)") {
LuaArg co;
LuaRet lid;
LuaStack LS(L, co, lid);
@@ -484,7 +559,7 @@ LuaDefine(coroutine_getnextid, "c") {
return LS.result();
}
LuaDefine(unittests_sourcedb, "c") {
LuaDefine(unittests_sourcedb, "", "some unit tests") {
LuaSnap msnap;
LuaSnap ssnap;
SourceDB mdb;