From 811d377669582a70815b80c4a831b608a2fabedd Mon Sep 17 00:00:00 2001 From: maelstrom Date: Mon, 5 May 2025 13:56:45 +0200 Subject: [PATCH] feat(autogen): add support for constructor --- autogen/src/data/analysis.cpp | 43 +++++++++++++++++++++++++++++++++++ autogen/src/data/codegen.cpp | 8 ++++--- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/autogen/src/data/analysis.cpp b/autogen/src/data/analysis.cpp index 8767685..51765c6 100644 --- a/autogen/src/data/analysis.cpp +++ b/autogen/src/data/analysis.cpp @@ -37,6 +37,45 @@ static std::string toStaticName(std::string orig) { return newName; } +// Constructors are stored the same way as static functions, but with the name "new" +static void processConstructor(CXCursor cur, ClassAnalysis* state) { + std::optional propertyDef = findAnnotation(cur, "OB::def_data_ctor"); + if (!propertyDef) return; + + MethodAnalysis anly; + + auto result = parseAnnotationString(propertyDef.value()); + std::string symbolName = x_clang_toString(clang_getCursorSpelling(cur)); + CXType retType = clang_getCursorResultType(cur); + + anly.name = result["name"]; + anly.functionName = "__ctor"; + anly.returnType = state->name; + + // if name field is not provided, use new + if (anly.name == "") { + anly.name = "new"; + } + + // Populate parameter list + // https://stackoverflow.com/a/45867090/16255372 + + for (int i = 0; i < clang_Cursor_getNumArguments(cur); i++) { + CXCursor paramCur = clang_Cursor_getArgument(cur, i); + + std::string paramName = x_clang_toString(clang_getCursorDisplayName(paramCur)); + std::string paramType = x_clang_toString(clang_getTypeSpelling(clang_getCursorType(paramCur))); + + MethodParameter param; + param.name = paramName; + param.type = paramType; + + anly.parameters.push_back(param); + } + + state->staticMethods.push_back(anly); +} + static void processMethod(CXCursor cur, ClassAnalysis* state) { std::optional propertyDef = findAnnotation(cur, "OB::def_data_method"); if (!propertyDef) return; @@ -134,6 +173,10 @@ static void processClass(CXCursor cur, AnalysisState* state, std::string classNa x_clang_visitChildren(cur, [&](CXCursor cur, CXCursor parent) { CXCursorKind kind = clang_getCursorKind(cur); + + if (kind == CXCursor_Constructor) { + processConstructor(cur, &anly); + } if (kind == CXCursor_CXXMethod || kind == CXCursor_FieldDecl || kind == CXCursor_VarDecl) { processProperty(cur, &anly); diff --git a/autogen/src/data/codegen.cpp b/autogen/src/data/codegen.cpp index fa60b87..0377d20 100644 --- a/autogen/src/data/codegen.cpp +++ b/autogen/src/data/codegen.cpp @@ -109,8 +109,7 @@ static void writeLuaMethodImpls(std::ofstream& out, ClassAnalysis& state) { for (auto& [name, methodImpls] : staticMethods) { std::string methodFqn = getLuaMethodFqn(state.name, name); - out << "static int " << methodFqn << "(lua_State* L) {\n" - " \n"; + out << "static int " << methodFqn << "(lua_State* L) {\n"; // Currently overloads are not supported @@ -125,7 +124,10 @@ static void writeLuaMethodImpls(std::ofstream& out, ClassAnalysis& state) { out << " "; // Call function - out << fqn << "::" << methodImpls[0].functionName << "("; + if (methodImpls[0].functionName == "__ctor") + out << fqn << "("; + else + out << fqn << "::" << methodImpls[0].functionName << "("; for (int i = 0; i < methodImpls[0].parameters.size(); i++) { std::string varname = "arg" + std::to_string(i);