feat(autogen): generate basis for instance
This commit is contained in:
parent
85e1efe5b3
commit
8049d45b43
6 changed files with 60 additions and 2 deletions
|
@ -6,6 +6,7 @@ add_executable(autogen
|
|||
src/util.cpp
|
||||
src/cache.cpp
|
||||
src/analysis.cpp
|
||||
src/codegen.cpp
|
||||
)
|
||||
|
||||
set_target_properties(autogen PROPERTIES OUTPUT_NAME "autogen")
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
#include "analysis.h"
|
||||
#include "util.h"
|
||||
#include <clang-c/CXFile.h>
|
||||
#include <clang-c/CXSourceLocation.h>
|
||||
#include <clang-c/Index.h>
|
||||
#include <cstdio>
|
||||
#include <optional>
|
||||
#include <filesystem>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
// Very simple parser
|
||||
// Example format:
|
||||
|
@ -161,14 +165,23 @@ void processField(CXCursor cur, ClassAnalysis* state) {
|
|||
state->properties.push_back(anly);
|
||||
}
|
||||
|
||||
void processClass(CXCursor cur, AnalysisState* state, std::string className) {
|
||||
void processClass(CXCursor cur, AnalysisState* state, std::string className, std::string srcRoot) {
|
||||
ClassAnalysis anly;
|
||||
|
||||
// Find base class
|
||||
std::string baseClass = findBaseClass(cur);
|
||||
|
||||
// Find header file
|
||||
CXSourceLocation loc = clang_getCursorLocation(cur);
|
||||
CXFile file;
|
||||
unsigned line, column, off;
|
||||
clang_getFileLocation(loc, &file, &line, &column, &off);
|
||||
std::string headerName = x_clang_toString(clang_getFileName(file));
|
||||
fs::path headerPath = fs::relative(headerName, srcRoot);
|
||||
|
||||
anly.name = className;
|
||||
anly.baseClass = baseClass;
|
||||
anly.headerPath = headerPath;
|
||||
|
||||
// Add misc flags and options
|
||||
auto instanceDef = findAnnotation(cur, "OB::def_inst");
|
||||
|
@ -237,7 +250,7 @@ bool analyzeClasses(std::string path, std::string srcRoot, AnalysisState* state)
|
|||
if (!findInstanceAnnotation(cur)) return CXChildVisit_Continue; // Class is not "primary" declaration/is not instance, skip
|
||||
if (state->classes.count(className) > 0) return CXChildVisit_Continue; // Class has already been analyzed, skip...
|
||||
|
||||
processClass(cur, state, className);
|
||||
processClass(cur, state, className, srcRoot);
|
||||
|
||||
return CXChildVisit_Continue;
|
||||
});
|
||||
|
|
|
@ -38,6 +38,7 @@ inline PropertyFlags operator|(PropertyFlags a, PropertyFlags b) {
|
|||
struct ClassAnalysis {
|
||||
std::string name;
|
||||
std::string baseClass;
|
||||
std::string headerPath;
|
||||
std::vector<PropertyAnalysis> properties;
|
||||
ClassFlags flags = (ClassFlags)0;
|
||||
std::string explorerIcon;
|
||||
|
|
27
autogen/src/codegen.cpp
Normal file
27
autogen/src/codegen.cpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include "codegen.h"
|
||||
#include "analysis.h"
|
||||
|
||||
void writeCodeForClass(std::ofstream& out, ClassAnalysis& state) {
|
||||
std::string strFlags;
|
||||
if (state.flags & ClassFlag_NotCreatable)
|
||||
strFlags += " | INSTANCE_NOT_CREATABLE";
|
||||
if (state.flags & ClassFlag_Service)
|
||||
strFlags += " | INSTANCE_SERVICE";
|
||||
if (state.flags & ClassFlag_Hidden)
|
||||
strFlags += " | INSTANCE_HIDDEN";
|
||||
if (!strFlags.empty()) strFlags = strFlags.substr(3); // Remove leading pipe
|
||||
else strFlags = "0"; // 0 == No option
|
||||
|
||||
out << "#include \"" << state.headerPath << "\"\n\n";
|
||||
out << "const InstanceType " << state.name << "::TYPE = {\n"
|
||||
<< " .super = &" << state.baseClass << "::TYPE,\n"
|
||||
<< " .className = \"" << state.name << "\",\n"
|
||||
<< " .constructor = &" << state.name << "::CreateGeneric,\n"
|
||||
<< " .explorerIcon = \"" << state.explorerIcon << "\",\n"
|
||||
<< " .flags = " << strFlags << ",\n"
|
||||
<< "};\n\n";
|
||||
|
||||
out << "const InstanceType* " << state.name << "::GetClass() {\n"
|
||||
<< " return &TYPE;\n"
|
||||
<< "};\n\n";
|
||||
}
|
6
autogen/src/codegen.h
Normal file
6
autogen/src/codegen.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "analysis.h"
|
||||
#include <fstream>
|
||||
|
||||
void writeCodeForClass(std::ofstream& out, ClassAnalysis& state);
|
|
@ -4,11 +4,13 @@
|
|||
#include <clang-c/CXString.h>
|
||||
#include <clang-c/Index.h>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
#include "analysis.h"
|
||||
#include "cache.h"
|
||||
#include "codegen.h"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
|
@ -40,6 +42,14 @@ int main(int argc, char** argv) {
|
|||
|
||||
analyzeClasses("../core/src/objects/part.h", argv[1], &state);
|
||||
|
||||
printf("[AUTOGEN] Generating cpp files...\n");
|
||||
for (auto& [_, clazz] : state.classes) {
|
||||
fs::path outPath = fs::path(argv[3]) / ("class_" + clazz.name + ".cpp");
|
||||
std::ofstream outStream(outPath);
|
||||
|
||||
writeCodeForClass(outStream, clazz);
|
||||
outStream.close();
|
||||
}
|
||||
|
||||
// for (auto& [_, clazz] : state.classes) {
|
||||
// printf("Class: %s\n", clazz.name.c_str());
|
||||
|
|
Loading…
Add table
Reference in a new issue