aboutsummaryrefslogtreecommitdiff
path: root/source/20-codegen-compiler/CodegenModel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/20-codegen-compiler/CodegenModel.cpp')
-rw-r--r--source/20-codegen-compiler/CodegenModel.cpp732
1 files changed, 0 insertions, 732 deletions
diff --git a/source/20-codegen-compiler/CodegenModel.cpp b/source/20-codegen-compiler/CodegenModel.cpp
deleted file mode 100644
index 303ad4e..0000000
--- a/source/20-codegen-compiler/CodegenModel.cpp
+++ /dev/null
@@ -1,732 +0,0 @@
-#include "CodegenModel.hpp"
-
-#include "CodegenUtils.hpp"
-#include "SQLiteHelper.hpp"
-
-#include <Macros.hpp>
-#include <ScopeGuard.hpp>
-#include <Utils.hpp>
-
-#include <robin_hood.h>
-#include <cassert>
-#include <cstdint>
-#include <stdexcept>
-#include <string>
-#include <variant>
-
-using namespace std::literals;
-
-// TODO only delete unused records from model instead of regenerating all records every time
-
-struct SomeDecl {
- std::variant<DeclStruct, DeclFunction, DeclEnum> v;
-};
-
-class CodegenRuntimeModel::Private {
- friend class CodegenArchiveModel;
-
-public:
- // We want address stability for everything
- robin_hood::unordered_node_map<std::string, SomeDecl, StringHash, StringEqual> decls;
- robin_hood::unordered_node_map<std::string, DeclNamespace, StringHash, StringEqual> namespaces;
-};
-
-// A number for `PRAGMA user_vesrion`, representing the current database version. Increment when the table format changes.
-#define CURRENT_DATABASE_VERSION 1
-constexpr int64_t kGlobalNamespaceId = 1;
-
-namespace {
-void PrintErrMsgIfPresent(char*& errMsg) {
- if (errMsg) {
- printf("SQLite error: %s\n", errMsg);
- sqlite3_free(errMsg);
- }
-}
-} // namespace
-
-class CodegenArchiveModel::Private {
- friend class CodegenRuntimeModel;
-
-public:
- // NOTE: this must be the first field, because we want it to destruct after all other statement fields
- SQLiteDatabase database;
- /* Core Statements */
- SQLiteStatement beginTransactionStmt;
- SQLiteStatement commitTransactionStmt;
- SQLiteStatement rollbackTransactionStmt;
- SQLiteStatement findFileStmt;
- SQLiteStatement storeFileStmt;
- SQLiteStatement findNamespaceStmt;
- SQLiteStatement getNamespaceStmt;
- SQLiteStatement storeNamespaceStmt;
- /* Component Statements, initalized on demand */
- SQLiteStatement storeStructStmt;
- SQLiteStatement storeStructBaseClassStmt;
- SQLiteStatement storeStructPropertyStmt;
- // TODO store method
- SQLiteStatement storeEnumStmt;
- SQLiteStatement storeEnumElmStmt;
- SQLiteStatement deleteFunctionDeclByFilenameStmt;
- SQLiteStatement deleteStructDeclByFilenameStmt;
- SQLiteStatement deleteEnumDeclByFilenameStmt;
- // TODO
- // SQLiteStatement getRootClassStmt;
-
- void InitializeDatabase() {
- char* errMsg = nullptr;
-
- int result = sqlite3_exec(database, "PRAGMA user_version = " STRINGIFY(CURRENT_DATABASE_VERSION), nullptr, nullptr, &errMsg);
- PrintErrMsgIfPresent(errMsg);
- assert(result == SQLITE_OK);
-
- // TODO unique with overloading, and container structs
- result = sqlite3_exec(database, R"""(
-BEGIN TRANSACTION;
-CREATE TABLE Files(
- -- NOTE: SQLite forbids foreign keys referencing the implicit `rowid` column, we have to create an alias for it
- Id INTEGER PRIMARY KEY,
- FileName TEXT,
- UNIQUE (FileName)
-);
-
-CREATE TABLE Namespaces(
- Id INTEGER PRIMARY KEY,
- ParentNamespaceId INTEGER REFERENCES Namespaces(Id),
- Name TEXT,
- UNIQUE (ParentNamespaceId, Name)
-);
-
-CREATE TABLE DeclFunctions(
- Id INTEGER PRIMARY KEY,
- FileId INTEGER REFERENCES Files(Id) ON DELETE CASCADE,
- NamespaceId INTEGER REFERENCES Namespaces(Id),
- Name TEXT
-);
-CREATE TABLE DeclFunctionParameters(
- FunctionId INTEGER REFERENCES DeclFunctions(Id) ON DELETE CASCADE,
- Name TEXT,
- Type TEXT,
- UNIQUE (FunctionId, Name)
-);
-
-CREATE TABLE DeclStructs(
- Id INTEGER PRIMARY KEY,
- FileId INTEGER REFERENCES Files(Id) ON DELETE CASCADE,
- NamespaceId INTEGER REFERENCES Namespaces(Id),
- Name TEXT,
- IsMetadataMarked INTEGER
-);
-CREATE TABLE DeclStructBaseClassRelations(
- StructId INTEGER REFERENCES DeclStructs(Id) ON DELETE CASCADE,
- -- NOTE: intentionally not foreign keys, because we want relations to still exist even if the base class is deleted
- -- we do validation after a complete regeneration pass, on reads
- ParentStructNamespaceId INTEGER,
- ParentStructName TEXT,
- UNIQUE (StructId, ParentStructNamespaceId, ParentStructName)
-);
-CREATE TABLE DeclStructProperties(
- StructId INTEGER REFERENCES DeclStructs(Id) ON DELETE CASCADE,
- Name TEXT,
- Type TEXT,
- -- NOTE: getter and setter may or may not be methods; search the DeclStructMethods table if needed
- GetterName TEXT,
- SetterName TEXT,
- IsPlainField INTEGER GENERATED ALWAYS AS (GetterName = '' AND SetterName = '') VIRTUAL,
- IsMetadataMarked INTEGER
-);
-CREATE TABLE DeclStructMethods(
- Id INTEGER PRIMARY KEY,
- StructId INTEGER REFERENCES DeclStructs(Id) ON DELETE CASCADE,
- Name TEXT,
- Type TEXT,
- IsConst INTEGER,
- IsMetadataMarked INTEGER
-);
-CREATE TABLE DeclStructMethodParameters(
- MethodId INTEGER REFERENCES DeclStructMethods(Id) ON DELETE CASCADE,
- Name TEXT,
- Type TEXT,
- UNIQUE (MethodId, Name)
-);
-
-CREATE TABLE DeclEnums(
- Id INTEGER PRIMARY KEY,
-FileId INTEGER REFERENCES Files(Id) ON DELETE CASCADE,
- NamespaceId INTEGER REFERENCES Namespaces(Id),
- Name TEXT,
- UnderlyingType TEXT
-);
-CREATE TABLE DeclEnumElements(
- EnumId INTEGER REFERENCES DeclEnums(Id) ON DELETE CASCADE,
- Name TEXT,
- Value INTEGER,
- UNIQUE (EnumId, Name)
-);
-
-CREATE INDEX Index_DeclFunctions_FileId ON DeclFunctions(FileId);
-CREATE INDEX Index_DeclStructs_FileId ON DeclStructs(FileId);
-CREATE INDEX Index_DeclEnums_FileId ON DeclEnums(FileId);
-
-CREATE UNIQUE INDEX Index_DeclFunctions_Identity ON DeclFunctions(NamespaceId, Name);
-
-CREATE UNIQUE INDEX Index_DeclStruct_Identity ON DeclStructs(NamespaceId, Name);
-CREATE UNIQUE INDEX Index_DeclStructProperties_Identity ON DeclStructProperties(StructId, Name);
-CREATE UNIQUE INDEX Index_DeclStructMethods_Identity ON DeclStructMethods(StructId, Name);
-
-CREATE UNIQUE INDEX Index_DeclEnums_Identity ON DeclEnums(NamespaceId, Name);
-
--- Special global namespace that has no parent, and Id should always be 1
-INSERT INTO Namespaces(Id, ParentNamespaceId, Name)
-VALUES (1, NULL, '<global namespace>');
-
-COMMIT TRANSACTION;
-)""",
- nullptr,
- nullptr,
- &errMsg);
- PrintErrMsgIfPresent(errMsg);
- assert(result == SQLITE_OK);
- }
-
- void BeginTransaction() {
- int result = sqlite3_step(beginTransactionStmt);
- assert(result == SQLITE_DONE);
- sqlite3_reset(beginTransactionStmt);
- }
-
- void CommitTransaction() {
- int result = sqlite3_step(commitTransactionStmt);
- assert(result == SQLITE_DONE);
- sqlite3_reset(commitTransactionStmt);
- }
-
- void RollbackTransaction() {
- int result = sqlite3_step(rollbackTransactionStmt);
- assert(result == SQLITE_DONE);
- sqlite3_reset(rollbackTransactionStmt);
- }
-
- /// \return Row ID of the namespace, or 0 if it currently doesn't exist.
- int64_t FindNamespace(const DeclNamespace* ns) {
- if (!ns) {
- return kGlobalNamespaceId;
- }
-
- return FindNamespaceImpl(*ns);
- }
-
- /// \return Row ID of the namespace.
- int64_t FindOrStoreNamespace(const DeclNamespace* ns) {
- if (!ns) {
- return kGlobalNamespaceId;
- }
-
- if (auto rowId = FindNamespaceImpl(*ns); rowId != 0) {
- return rowId;
- }
-
- SQLiteRunningStatement rt(storeNamespaceStmt);
- rt.BindArguments(FindOrStoreNamespace(ns->container), ns->name);
-
- rt.StepAndCheck(SQLITE_ROW);
-
- auto [nsId] = rt.ResultColumns<int64_t>();
- return nsId;
- }
-
- std::string GetNamespaceFullName(int64_t nsId) const {
- return GetNamespaceFullNameImpl(nsId, nullptr, 0);
- }
-
- std::string GetDeclFullName(int64_t nsId, std::string_view declName) const {
- return GetNamespaceFullNameImpl(nsId, declName.data(), declName.size());
- }
-
- /// \return Row ID of the file, or 0 if it currently doesn't exist.
- int64_t FindFile(std::string_view filename) {
- SQLiteRunningStatement rt(findFileStmt);
- rt.BindArguments(filename);
-
- int result = rt.Step();
-
- if (result == SQLITE_ROW) {
- auto [fileId] = rt.ResultColumns<int64_t>();
- return fileId;
- } else {
- return 0;
- }
- }
-
- /// \return Row ID of the file
- int64_t FindOrStoreFile(std::string_view filename) {
- if (auto id = FindFile(filename); id != 0) {
- return id;
- }
-
- SQLiteRunningStatement rt(storeFileStmt);
- rt.BindArguments(filename);
-
- rt.StepAndCheck(SQLITE_ROW);
-
- auto [fileId] = rt.ResultColumns<int64_t>();
- return fileId;
- }
-
- /// \return Row ID of the file, or 0 if not found.
- int64_t FindOrStoreFile(/*nullable*/ const SourceFile* file) {
- if (!file) {
- return 0;
- }
- return FindOrStoreFile(file->filename);
- }
-
-private:
- // TODO maybe merge with Utils::MakeFullName?
- std::string GetNamespaceFullNameImpl(int64_t nsId, const char* append, size_t appendLength) const {
- std::vector<std::string> namespaceNames;
- size_t fullnameLength = 0;
-
- sqlite3_stmt* stmt = getNamespaceStmt;
- int64_t currentNsId = nsId;
- while (true) {
- SQLiteRunningStatement rt(getNamespaceStmt);
- rt.BindArguments(currentNsId);
-
- rt.StepAndCheck(SQLITE_ROW);
-
- auto [id, parentNamespaceId, name] = rt.ResultColumns<int64_t, int64_t, std::string>();
- currentNsId = parentNamespaceId;
- fullnameLength += name.size() + 2;
- namespaceNames.push_back(std::move(name));
-
- if (parentNamespaceId == kGlobalNamespaceId) {
- break;
- }
- }
- if (append) {
- // Already has the '::' at the end
- fullnameLength += appendLength;
- } else {
- fullnameLength -= 2;
- }
-
- std::string fullname;
- fullname.reserve(fullnameLength);
-
- for (auto it = namespaceNames.rbegin(); it != namespaceNames.rend(); ++it) {
- fullname.append(*it);
- if (append || std::next(it) != namespaceNames.rend()) {
- fullname.append("::");
- }
- }
- if (append) {
- fullname += std::string_view(append, appendLength);
- }
-
- return fullname;
- }
-
- int64_t FindNamespaceImpl(const DeclNamespace& ns) {
- int64_t parentNsRowId;
- if (ns.container) {
- parentNsRowId = FindNamespaceImpl(*ns.container);
- if (parentNsRowId == 0) {
- // Parent namespace doesn't exist in database, shortcircuit
- return 0;
- }
- } else {
- parentNsRowId = kGlobalNamespaceId;
- }
-
- return FindNamespaceImpl(ns, parentNsRowId);
- }
-
- int64_t FindNamespaceImpl(const DeclNamespace& ns, int64_t parentNsRowId) {
- sqlite3_stmt* stmt = findNamespaceStmt;
- SQLiteRunningStatement rt(findNamespaceStmt);
- rt.BindArguments(parentNsRowId, ns.name);
-
- int result = rt.Step();
- if (result == SQLITE_ROW) {
- auto [nsId] = rt.ResultColumns<int64_t>();
- return nsId;
- } else {
- return 0;
- }
- }
-};
-
-CodegenRuntimeModel::CodegenRuntimeModel()
- : m{ new Private() } //
-{
-}
-
-CodegenRuntimeModel::~CodegenRuntimeModel() {
- delete m;
-}
-
-#define STORE_DECL_OF_TYPE(DeclType, fullname, decl) \
- auto [iter, success] = m->decls.try_emplace(std::move(fullname), SomeDecl{ .v = std::move(decl) }); \
- auto& key = iter->first; \
- auto& val = iter->second; \
- auto& declRef = std::get<DeclType>(val.v); \
- declRef.fullname = &key; \
- return &declRef
-
-DeclEnum* CodegenRuntimeModel::AddEnum(std::string fullname, DeclEnum decl) {
-#if CODEGEN_DEBUG_PRINT
- printf("Committed enum '%s'\n", decl.name.c_str());
- for (auto& elm : decl.elements) {
- printf(" - element %s = %" PRId64 "\n", elm.name.c_str(), elm.value);
- }
-#endif
-
- STORE_DECL_OF_TYPE(DeclEnum, fullname, decl);
-}
-
-DeclStruct* CodegenRuntimeModel::AddStruct(std::string fullname, DeclStruct decl) {
-#if CODEGEN_DEBUG_PRINT
- printf("Committed struct '%s'\n", decl.name.c_str());
- printf(" Base classes:\n");
- for (auto& base : decl.baseClasses) {
- printf(" - %.*s\n", PRINTF_STRING_VIEW(base->name));
- }
-#endif
-
- STORE_DECL_OF_TYPE(DeclStruct, fullname, decl);
-}
-
-#define FIND_DECL_OF_TYPE(DeclType) \
- auto iter = m->decls.find(name); \
- if (iter != m->decls.end()) { \
- auto& some = iter->second.v; \
- if (auto decl = std::get_if<DeclType>(&some)) { \
- return decl; \
- } \
- } \
- return nullptr
-
-const DeclEnum* CodegenRuntimeModel::FindEnum(std::string_view name) const {
- FIND_DECL_OF_TYPE(DeclEnum);
-}
-
-const DeclStruct* CodegenRuntimeModel::FindStruct(std::string_view name) const {
- FIND_DECL_OF_TYPE(DeclStruct);
-}
-
-DeclNamespace* CodegenRuntimeModel::AddNamespace(DeclNamespace ns) {
- auto path = Utils::MakeFullName(""sv, &ns);
- auto [iter, success] = m->namespaces.try_emplace(std::move(path), std::move(ns));
- auto& nsRef = iter->second;
- if (success) {
- nsRef.fullname = &iter->first;
- }
- return &nsRef;
-}
-
-const DeclNamespace* CodegenRuntimeModel::FindNamespace(std::string_view fullname) const {
- auto iter = m->namespaces.find(fullname);
- if (iter != m->namespaces.end()) {
- return &iter->second;
- } else {
- return nullptr;
- }
-}
-
-DeclNamespace* CodegenRuntimeModel::FindNamespace(std::string_view name) {
- return const_cast<DeclNamespace*>(const_cast<const CodegenRuntimeModel*>(this)->FindNamespace(name));
-}
-
-CodegenArchiveModel::CodegenArchiveModel(std::string_view dbPath)
- : m{ new Private() } //
-{
- std::string zstrPath(dbPath);
- int reuslt = sqlite3_open(zstrPath.c_str(), &m->database);
- if (reuslt != SQLITE_OK) {
- std::string msg;
- msg += "Failed to open SQLite3 database, error message:\n";
- msg += sqlite3_errmsg(m->database);
- throw std::runtime_error(msg);
- }
-
- // NOTE: These pragmas are not persistent, so we need to set them every time
- // As of SQLite3 3.38.5, it defaults to foreign_keys = OFF, so we need this to be on for ON DELETE CASCADE and etc. to work
- sqlite3_exec(m->database, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr);
- // This database is used for a buildsystem and can be regenerated at any time. We don't care for the slightest about data integrity, we just want fast updates
- sqlite3_exec(m->database, "PRAGMA synchronous = OFF", nullptr, nullptr, nullptr);
- sqlite3_exec(m->database, "PRAGMA journal_mode = MEMORY", nullptr, nullptr, nullptr);
-
- {
- SQLiteStatement readVersionStmt;
- readVersionStmt.InitializeLazily(m->database, "PRAGMA user_version"sv);
-
- int result = sqlite3_step(readVersionStmt);
- assert(result == SQLITE_ROW);
- int currentDatabaseVersion = sqlite3_column_int(readVersionStmt, 0);
-
- result = sqlite3_step(readVersionStmt);
- assert(result == SQLITE_DONE);
-
- if (currentDatabaseVersion == 0) {
- // Newly created database, initialize it
- m->InitializeDatabase();
- } else if (currentDatabaseVersion == CURRENT_DATABASE_VERSION) {
- // Same version, no need to do anything
- } else {
- INPLACE_FMT(msg, "Incompatbile database versions %d (in file) vs %d (expected).", currentDatabaseVersion, CURRENT_DATABASE_VERSION);
- throw std::runtime_error(msg);
- }
- }
-
- // Initialize core statements
- m->beginTransactionStmt.Initialize(m->database, "BEGIN TRANSACTION");
- m->commitTransactionStmt.Initialize(m->database, "COMMIT TRANSACTION");
- m->rollbackTransactionStmt.Initialize(m->database, "ROLLBACK TRANSACTION");
- m->findFileStmt.Initialize(m->database, "SELECT Id FROM Files WHERE FileName = ?1");
- m->storeFileStmt.Initialize(m->database, "INSERT INTO Files(FileName) VALUES (?1) RETURNING Id");
- m->findNamespaceStmt.Initialize(m->database, "SELECT Id FROM Namespaces WHERE ParentNamespaceId = ?1 AND Name = ?2");
- m->getNamespaceStmt.Initialize(m->database, "SELECT * FROM Namespaces WHERE Id = ?1"sv);
- m->storeNamespaceStmt.Initialize(m->database, "INSERT INTO Namespaces(ParentNamespaceId, Name) VALUES (?1, ?2) RETURNING Id");
-}
-
-CodegenArchiveModel::~CodegenArchiveModel() {
- delete m;
-}
-
-void CodegenArchiveModel::DeleteDeclsRelatedToFile(std::string_view filename) {
- // -Argument- -Description-
- // ?1 The filename to delete
- m->deleteFunctionDeclByFilenameStmt.InitializeLazily(m->database, "DELETE FROM DeclFunctions WHERE FileId = (SELECT Id FROM Files WHERE FileName = ?1)"sv);
- m->deleteStructDeclByFilenameStmt.InitializeLazily(m->database, "DELETE FROM DeclStructs WHERE FileId = (SELECT Id FROM Files WHERE FileName = ?1);"sv);
- m->deleteEnumDeclByFilenameStmt.InitializeLazily(m->database, "DELETE FROM DeclEnums WHERE FileId = (SELECT Id FROM Files WHERE FileName = ?1);"sv);
-
- m->BeginTransaction();
- auto stmtList = {
- m->deleteFunctionDeclByFilenameStmt.stmt,
- m->deleteStructDeclByFilenameStmt.stmt,
- m->deleteEnumDeclByFilenameStmt.stmt,
- };
- for (auto& stmt : stmtList) {
- SQLiteRunningStatement rt(stmt);
- rt.BindArguments(filename);
- rt.StepUntilDone();
- }
- m->CommitTransaction();
-}
-
-void CodegenArchiveModel::Store(const CodegenRuntimeModel& cgModel) {
- auto& cgm = cgModel.GetPimpl();
-
- struct Visiter {
- CodegenArchiveModel* self;
-
- void operator()(const DeclStruct& decl) const {
- self->StoreStruct(decl);
- }
- void operator()(const DeclFunction& decl) const {
- self->StoreFunction(decl);
- }
- void operator()(const DeclEnum& decl) const {
- self->StoreEnum(decl);
- }
- } visiter;
- visiter.self = this;
-
- m->BeginTransaction();
-
- for (auto&& [DISCARD, ns] : cgm.namespaces) {
- // This will insert the namespace if it doesn't exist, or no-op (fetches data) if it already exists
- m->FindOrStoreNamespace(&ns);
- }
- for (auto&& [DISCARD, value] : cgm.decls) {
- std::visit(visiter, value.v);
- }
-
- m->CommitTransaction();
-}
-
-void CodegenArchiveModel::LoadInto(CodegenRuntimeModel& model) const {
- // TODO
-}
-
-CodegenRuntimeModel CodegenArchiveModel::Load() const {
- CodegenRuntimeModel cgModel;
-
- // TODO files
- // TODO namespaces
-
- robin_hood::unordered_map<int64_t, DeclStruct*> structsById;
- robin_hood::unordered_map<int64_t, DeclMemberVariable*> propertiesById;
- robin_hood::unordered_map<int64_t, DeclMemberFunction*> methodsById;
-
- { // Load structs
- SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructs"sv);
- SQLiteRunningStatement rt(stmt);
- while (true) {
- int result = rt.StepAndCheckError();
- if (result == SQLITE_DONE) break;
- assert(result == SQLITE_ROW);
-
- auto [id, fileId, nsId, name] = rt.ResultColumns<int64_t, int64_t, int64_t, std::string_view>();
-
- auto decl = cgModel.AddStruct(m->GetDeclFullName(nsId, name), DeclStruct{});
- structsById.try_emplace(id, decl);
- }
- }
- { // Load struct's base classes
- SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructBaseClassRelations");
- SQLiteRunningStatement rt(stmt);
- while (true) {
- int result = rt.StepAndCheckError();
- if (result == SQLITE_DONE) break;
- assert(result == SQLITE_ROW);
-
- auto [structId, parentStructNsId, parentStructName] = rt.ResultColumns<int64_t, int64_t, std::string_view>();
-
- auto declThis = structsById.at(structId);
- auto declParent = cgModel.FindStruct(parentStructName); // TODO namespace
- declThis->baseClasses.push_back(declParent);
- }
- }
- { // Load struct properties
- SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructProperties"sv);
- SQLiteRunningStatement rt(stmt);
- while (true) {
- int result = rt.StepAndCheckError();
- if (result == SQLITE_DONE) break;
- assert(result == SQLITE_ROW);
-
- // TODO
- }
- }
- { // Load struct methods
- SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructMethods"sv);
- SQLiteRunningStatement rt(stmt);
- while (true) {
- int result = rt.StepAndCheckError();
- if (result == SQLITE_DONE) break;
- assert(result == SQLITE_ROW);
-
- // TODO
- }
- }
- { // Load method params
- SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructMethodParameters"sv);
- SQLiteRunningStatement rt(stmt);
- while (true) {
- int result = rt.StepAndCheckError();
- if (result == SQLITE_DONE) break;
- assert(result == SQLITE_ROW);
-
- // TODO
- }
- }
-
- return cgModel;
-}
-
-void CodegenArchiveModel::StoreStruct(const DeclStruct& decl) {
- // -Argument- -Description-
- // ?1 Namespace ID
- // ?2 Struct name
- // ?3 File ID containing the struct
- // ?4 Is this struct marked for metadata generation?
- m->storeStructStmt.InitializeLazily(m->database, R"""(
-INSERT INTO DeclStructs(NamespaceId, Name, FileId, IsMetadataMarked)
-VALUES (?1, ?2, ?3, ?4)
-ON CONFLICT DO UPDATE SET
- FileId = ?3,
- IsMetadataMarked = ?4
-RETURNING Id
-)"""sv);
-
- // -Argument- -Description-
- // ?1 Struct ID
- // ?2 Parent struct's namespace ID
- // ?3 Parent struct's name
- m->storeStructBaseClassStmt.InitializeLazily(m->database, R"""(
-INSERT INTO DeclStructBaseClassRelations(StructId, ParentStructNamespaceId, ParentStructName)
-VALUES (?1, ?2, ?3)
-)"""sv);
-
- // -Argument- -Description-
- // ?1 Struct ID
- // ?2 Property name
- // ?3 Property type
- // ?4 Getter name (optional)
- // ?5 Setter name (optional)
- // ?6 Is this property marked for metadata generation?
- m->storeStructPropertyStmt.InitializeLazily(m->database, R"""(
-INSERT INTO DeclStructProperties(StructId, Name, Type, GetterName, SetterName, IsMetadataMarked)
-VALUES (?1, ?2, ?3, ?4, ?5, ?6)
-)"""sv);
-
- SQLiteRunningStatement rt(m->storeStructStmt);
- rt.BindArguments(m->FindOrStoreNamespace(decl.container), decl.name, m->FindOrStoreFile(decl.sourceFile), decl.generating);
- rt.StepAndCheck(SQLITE_ROW);
- auto [structId] = rt.ResultColumns<int64_t>();
-
- for (auto& baseClass : decl.baseClasses) {
- SQLiteRunningStatement rt(m->storeStructBaseClassStmt);
- rt.BindArguments(structId, m->FindOrStoreNamespace(baseClass->container), baseClass->name);
- rt.StepUntilDone();
- }
-
- for (auto& property : decl.memberVariables) {
- SQLiteRunningStatement rt(m->storeStructPropertyStmt);
- rt.BindArguments(
- structId,
- property.name,
- property.type,
- property.getterName,
- property.setterName,
- // Since DeclMemberVariable entries currently only exist if it's marked BRUSSEL_PROPERTY
- true);
- rt.StepUntilDone();
- }
-
- for (auto& method : decl.memberFunctions) {
- // TODO
- }
-}
-
-void CodegenArchiveModel::StoreFunction(const DeclFunction& decl) {
- // TODO
-}
-
-void CodegenArchiveModel::StoreEnum(const DeclEnum& decl) {
- // -Argument- -Description-
- // ?1 Namespace ID
- // ?2 Enum name
- // ?3 Enum underlying type
- // ?4 File ID containing the enum
- m->storeEnumStmt.InitializeLazily(m->database, R"""(
-INSERT INTO DeclEnums(NamespaceId, Name, UnderlyingType, FileId)
-VALUES (?1, ?2, ?3, ?4)
-ON CONFLICT DO UPDATE SET
- UnderlyingType = ?3,
- FileId = ?4
-RETURNING Id
-)"""sv);
-
- // -Argument- -Description-
- // ?1 Container enum's id
- // ?2 Enum element name
- // ?3 Enum element value
- m->storeEnumElmStmt.InitializeLazily(m->database, R"""(
-INSERT INTO DeclEnumElements(EnumId, Name, Value)
-VALUES (?1, ?2, ?3)
-ON CONFLICT DO UPDATE SET Value=?3
-)"""sv);
-
- SQLiteRunningStatement rt(m->storeEnumStmt);
- rt.BindArguments(m->FindOrStoreNamespace(decl.container), decl.name, decl.GetUnderlyingTypeName(), m->FindOrStoreFile(decl.sourceFile));
- rt.StepAndCheck(SQLITE_ROW);
- auto [enumId] = rt.ResultColumns<int64_t>();
-
- for (auto& elm : decl.elements) {
- SQLiteRunningStatement rt(m->storeEnumElmStmt);
- rt.BindArguments(enumId, elm.name, elm.value);
- rt.StepUntilDone();
- }
-}