From ce0755c247b92f704d4f6883ee0b3141ab20f628 Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Sat, 2 Mar 2024 18:06:59 +0800 Subject: [PATCH] feat update --- CMakeLists.txt | 5 ++-- runtime/reflection.cc | 11 +++++++ runtime/reflection.h | 61 ++++++++++++++++++++++++++++++++++++++ src/clang/cursor.h | 9 +++--- src/clang/cursor_type.h | 12 ++++---- src/language_types/field.h | 15 ++++++++++ src/language_types/type.h | 14 +++++++++ src/main.cc | 18 ++++++----- src/meta/meta_info.h | 21 +++++++------ src/parser/parser.h | 18 +++++++++++ 10 files changed, 155 insertions(+), 29 deletions(-) create mode 100644 runtime/reflection.cc create mode 100644 runtime/reflection.h create mode 100644 src/language_types/field.h create mode 100644 src/language_types/type.h create mode 100644 src/parser/parser.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d16712..751d46b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,8 @@ add_executable(meta set(CLANG_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/LLVM/include") if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - message(FATAL "${CMAKE_SYSTEM_NAME} is not supported") + set(CLANG_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/LLVM/bin/Linux") + set(CLANG_LIB_LIBRARIES "${CLANG_LIB_DIR}/libclang.so.12") elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows") message(FATAL "${CMAKE_SYSTEM_NAME} is not supported") elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin") @@ -30,5 +31,5 @@ elseif (CMAKE_SYSTEM_NAME STREQUAL "Darwin") endif() endif() -target_include_directories(meta PRIVATE ${CLANG_INCLUDE_DIR} src) +target_include_directories(meta PRIVATE ${CLANG_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src) target_link_libraries(meta PRIVATE sled ${CLANG_LIB_LIBRARIES}) diff --git a/runtime/reflection.cc b/runtime/reflection.cc new file mode 100644 index 0000000..4f7e127 --- /dev/null +++ b/runtime/reflection.cc @@ -0,0 +1,11 @@ +#include "reflection.h" + +namespace meta { +std::atomic next_type_id{0}; + +void +NoOp(void *) +{} + +Object::Object() : id_(GetTypeId()), data_(nullptr), deleter_(NoOp) {} +}// namespace meta diff --git a/runtime/reflection.h b/runtime/reflection.h new file mode 100644 index 0000000..ac2c71f --- /dev/null +++ b/runtime/reflection.h @@ -0,0 +1,61 @@ +#pragma once +#ifndef META_RUNTIME_REFLECTION_H +#define META_RUNTIME_REFLECTION_H +#include +#include +#include +#include +#include +#include + +namespace meta { +#define __REFLECTION_PARSER_ +#if defined(__REFLECTION_PARSER_) +#define CLASS(class_name, ...) \ + class __attribute__((annotate(#__VA_ARGS__))) class_name +#define STRUCT(struct_name, ...) \ + struct __attribute__((annotate(#__VA_ARGS__))) struct_name +#else +#define META(...) +#define CLASS(class_name, ...) class class_name +#define STRUCT(struct_name, ...) struct struct_name +#endif// __REFLECTION_PARSER_ + +#define REFLECTION_BODY(class_name) + +#define REFLECT_TYPE(class_name) + +class TypeInterface { +public: + virtual std::string name() const = 0; +}; + +class Class; + +class Method : public TypeInterface { +public: + virtual std::string name() = 0; + + template + ReturnT Invoke(void *instance, Args... args) const + { + std::vector arguments = {args...}; + return sled::any_cast( + std::forward(Invoke(instance, arguments))); + } + + sled::any Invoke(void *instance, std::vector &args) const + { + return InvokeImpl(instance, args); + } + +protected: + virtual sled::any InvokeImpl(void *instance, + std::vector &args) const = 0; +}; + +class Field; + +}// namespace meta + +#endif// META_RUNTIME_REFLECTION_H diff --git a/src/clang/cursor.h b/src/clang/cursor.h index e460a5f..8de9834 100644 --- a/src/clang/cursor.h +++ b/src/clang/cursor.h @@ -11,7 +11,7 @@ public: using List = std::vector; using Visitor = CXCursorVisitor; - Cursor(const CXCursor& handle); + Cursor(const CXCursor &handle); CXCursorKind GetKind(void); std::string GetSpelling(void) const; @@ -20,13 +20,12 @@ public: bool IsDefinition(void) const; CursorType GetType(void) const; List GetChildren(void) const; - void VisitChildren(Visitor visitor, void* data) const; + void VisitChildren(Visitor visitor, void *data) const; private: CXCursor handle_; }; +}// namespace meta -} // namespace meta; - -#endif // META_CLANG_CURSOR_H +#endif// META_CLANG_CURSOR_H diff --git a/src/clang/cursor_type.h b/src/clang/cursor_type.h index 6e65b99..65ce174 100644 --- a/src/clang/cursor_type.h +++ b/src/clang/cursor_type.h @@ -9,12 +9,15 @@ extern "C" { } #endif +#include #include + namespace meta { class Cursor; + class CursorType { public: - CursorType(const CXType& handle); + CursorType(const CXType &handle); std::string GetDisplayName(void) const; int GetArgumentCount(void) const; @@ -27,8 +30,5 @@ public: private: CXType handle_; }; -} -#endif // META_CLANG_CURSOR_TYPE_H - - - +}// namespace meta +#endif// META_CLANG_CURSOR_TYPE_H diff --git a/src/language_types/field.h b/src/language_types/field.h new file mode 100644 index 0000000..4a87240 --- /dev/null +++ b/src/language_types/field.h @@ -0,0 +1,15 @@ +#pragma once +#ifndef META_LANGUAGE_TYPES_FIELD_H +#define META_LANGUAGE_TYPES_FIELD_H +#include "type.h" + +namespace meta { +class Field : public TypeInfo { +public: + virtual bool IsReadable() const; + virtual bool IsWritable() const; + virtual void *GetValue(void *instance) const; + virtual void SetValue(void *instance, void *value); +}; +}// namespace meta +#endif// META_LANGUAGE_TYPES_FIELD_H diff --git a/src/language_types/type.h b/src/language_types/type.h new file mode 100644 index 0000000..7af3a00 --- /dev/null +++ b/src/language_types/type.h @@ -0,0 +1,14 @@ +#pragma once +#ifndef META_LANGUAGE_TYPES_TYPE_H +#define META_LANGUAGE_TYPES_TYPE_H + +#include + +class TypeInfo { +public: + virtual ~TypeInfo() = default; + virtual std::string name() const = 0; + virtual std::string qualified_name() const = 0; +}; + +#endif// META_LANGUAGE_TYPES_TYPE_H diff --git a/src/main.cc b/src/main.cc index 052a8ac..3890166 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,21 +1,25 @@ -#include #include "clang/cursor.h" +#include -const char* kTag = "main"; +const char *kTag = "main"; -int main(int argc, char* argv[]) { +int +main(int argc, char *argv[]) +{ LOGI(kTag, ""); - CXIndex index = clang_createIndex(0, 0); - CXTranslationUnit unit = clang_parseTranslationUnit(index, "/tmp/main.cc", nullptr, 0, nullptr, 0, CXTranslationUnit_None); + CXIndex index = clang_createIndex(0, 0); + CXTranslationUnit unit = clang_parseTranslationUnit( + index, "/tmp/main.cc", nullptr, 0, nullptr, 0, CXTranslationUnit_None); CXString file_name = clang_getTranslationUnitSpelling(unit); LOGI(kTag, "file_name={}", clang_getCString(file_name)); meta::Cursor cursor = clang_getTranslationUnitCursor(unit); - for (auto& child : cursor.GetChildren()) { + for (auto &child : cursor.GetChildren()) { auto kind = child.GetKind(); - if (child.IsDefinition() && (kind == CXCursor_ClassDecl || kind == CXCursor_StructDecl)) { + if (child.IsDefinition() + && (kind == CXCursor_ClassDecl || kind == CXCursor_StructDecl)) { LOGV(kTag, "class={}", child.GetDisplayName()); } } diff --git a/src/meta/meta_info.h b/src/meta/meta_info.h index 52a2777..556820a 100644 --- a/src/meta/meta_info.h +++ b/src/meta/meta_info.h @@ -8,13 +8,16 @@ namespace meta { class MetaInfo { public: - MetaInfo(const Cursor& cursor); - std::string GetProperty(const std::string& key) const; - bool GetFlag(const std::string& key) const; - private: - using Property = std::pair ; - std::unordered_map properties_; - }; -} + MetaInfo(const Cursor &cursor); + std::string GetProperty(const std::string &key) const; + bool GetFlag(const std::string &key) const; -#endif // META_CLANG_META_INFO_H +private: + using Property = std::pair; + std::unordered_map properties_; + + std::vector ExtractProperties(const Cursor &cursor) const; +}; +}// namespace meta + +#endif// META_CLANG_META_INFO_H diff --git a/src/parser/parser.h b/src/parser/parser.h new file mode 100644 index 0000000..1b6812d --- /dev/null +++ b/src/parser/parser.h @@ -0,0 +1,18 @@ +#pragma once +#ifndef META_CLANG_PARSER_PARSER_H +#define META_CLANG_PARSER_PARSER_H +#include +#include + +namespace meta { +class MetaParser { +public: + MetaParser(const std::string &file_name); + ~MetaParser(); + +private: + CXIndex index_; + CXTranslationUnit translation_unit_; +}; +}// namespace meta +#endif// META_CLANG_PARSER_PARSER_H