From 673bf07cf601368de507f2be73a2dfe8cb2583ce Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 25 May 2026 17:25:27 +0100 Subject: [PATCH] fx.reflection: implement retrieving functions and properties from fx_type --- fx.reflection/include/fx/reflection/type.h | 16 + fx.reflection/type.c | 321 ++++++++++++++++++++- 2 files changed, 334 insertions(+), 3 deletions(-) diff --git a/fx.reflection/include/fx/reflection/type.h b/fx.reflection/include/fx/reflection/type.h index 3d839b0..36aae1d 100644 --- a/fx.reflection/include/fx/reflection/type.h +++ b/fx.reflection/include/fx/reflection/type.h @@ -1,8 +1,11 @@ #ifndef FX_REFLECTION_TYPE_H_ #define FX_REFLECTION_TYPE_H_ +#include #include +#include #include +#include FX_DECLS_BEGIN; @@ -17,14 +20,27 @@ FX_TYPE_CLASS_DECLARATION_END(fx_type) FX_API fx_type_id fx_type_get_type(); +FX_API const fx_assembly *fx_type_get_assembly(const fx_type *ty); +FX_API fx_status fx_type_set_assembly(fx_type *ty, fx_assembly *assembly); + FX_API const char *fx_type_get_name(const fx_type *ty); +FX_API fx_type_flags fx_type_get_flags(const fx_type *ty); FX_API const fx_function *fx_type_get_function( const fx_type *ty, const char *name); +FX_API fx_iterator *fx_type_get_functions(const fx_type *ty); +FX_API const fx_property *fx_type_get_property( + const fx_type *ty, + const char *name); +FX_API fx_iterator *fx_type_get_properties(const fx_type *ty); FX_API const fx_type *fx_type_get_by_id(fx_type_id id); FX_API const fx_type *fx_type_get_by_name(const char *name); +FX_API fx_type_id fx_type_get_id(const fx_type *ty); +FX_API const fx_type *fx_type_get_parent(const fx_type *ty); +FX_API void *fx_type_get_interface(const fx_type *ty, fx_type_id interface_id); + FX_API fx_type *__fx_type_create(struct fx_type_info *opaque); #endif diff --git a/fx.reflection/type.c b/fx.reflection/type.c index 2de9904..9d081ba 100644 --- a/fx.reflection/type.c +++ b/fx.reflection/type.c @@ -1,11 +1,42 @@ +#include "../fx/type.h" + #include #include #include struct fx_type_registration; +#define FX_REFLECTION_TYPE_TYPE_FUNCTION_ITERATOR \ + (fx_type_function_iterator_get_type()) +#define FX_REFLECTION_TYPE_TYPE_PROPERTY_ITERATOR \ + (fx_type_property_iterator_get_type()) + +FX_DECLARE_TYPE(fx_type_function_iterator); +FX_DECLARE_TYPE(fx_type_property_iterator); + +FX_TYPE_CLASS_DECLARATION_BEGIN(fx_type_function_iterator) +FX_TYPE_CLASS_DECLARATION_END(fx_type_function_iterator) + +FX_TYPE_CLASS_DECLARATION_BEGIN(fx_type_property_iterator) +FX_TYPE_CLASS_DECLARATION_END(fx_type_property_iterator) + +FX_API fx_type_id fx_type_function_iterator_get_type(); +FX_API fx_type_id fx_type_property_iterator_get_type(); + struct fx_type_p { struct fx_type_info *ty_info; + fx_assembly *ty_assembly; +}; + +struct fx_type_function_iterator_p { + struct fx_namemap *it_src; + struct fx_namemap_entry *it_cur; +}; + +struct fx_type_property_iterator_p { + const fx_type_info *it_cur_type; + struct fx_namemap *it_src; + struct fx_namemap_entry *it_cur; }; /*** PRIVATE FUNCTIONS ********************************************************/ @@ -16,11 +47,27 @@ extern fx_function *fx_type_info_get_function_by_name( const struct fx_type_info *ty, const char *name); +static const fx_assembly *type_get_assembly(const struct fx_type_p *ty) +{ + return ty->ty_assembly; +} + +static fx_status type_set_assembly(struct fx_type_p *ty, fx_assembly *assembly) +{ + ty->ty_assembly = assembly; + return FX_SUCCESS; +} + static const char *type_get_name(const struct fx_type_p *ty) { return ty->ty_info->ty_name; } +static fx_type_flags type_get_flags(const struct fx_type_p *ty) +{ + return ty->ty_info->ty_flags; +} + const fx_function *type_get_function( const struct fx_type_p *ty, const char *name) @@ -28,6 +75,98 @@ const fx_function *type_get_function( return fx_type_info_get_function_by_name(ty->ty_info, name); } +fx_iterator *type_get_functions(const struct fx_type_p *ty) +{ + fx_type_function_iterator *it_obj = fx_object_create( + FX_REFLECTION_TYPE_TYPE_FUNCTION_ITERATOR); + struct fx_type_function_iterator_p *it = fx_object_get_private( + it_obj, + FX_REFLECTION_TYPE_TYPE_FUNCTION_ITERATOR); + + it->it_src = &ty->ty_info->ty_functions; + it->it_cur = fx_namemap_first(it->it_src); + + return it_obj; +} + +const fx_property *type_get_property( + const struct fx_type_p *ty, + const char *name) +{ + struct fx_type_info *cur = ty->ty_info; + while (cur) { + const fx_property *prop = fx_type_info_get_property_by_name( + cur, + name); + if (prop) { + return prop; + } + + if (fx_type_id_compare(&cur->ty_id, FX_TYPE_OBJECT) == 0) { + break; + } + + cur = fx_type_info_get_by_id(&cur->ty_parent_id); + } + + return NULL; +} + +static fx_iterator *type_get_properties(const struct fx_type_p *ty) +{ + fx_type_property_iterator *it_obj = fx_object_create( + FX_REFLECTION_TYPE_TYPE_PROPERTY_ITERATOR); + struct fx_type_property_iterator_p *it = fx_object_get_private( + it_obj, + FX_REFLECTION_TYPE_TYPE_PROPERTY_ITERATOR); + + it->it_cur_type = ty->ty_info; + it->it_src = &ty->ty_info->ty_properties; + it->it_cur = fx_namemap_first(it->it_src); + while (!it->it_cur) { + if (fx_type_id_compare(&it->it_cur_type->ty_id, FX_TYPE_OBJECT) + == 0) { + break; + } + + const struct fx_type_info *next_type = fx_type_info_get_by_id( + &it->it_cur_type->ty_parent_id); + if (!next_type) { + break; + } + + it->it_cur_type = next_type; + it->it_cur = fx_namemap_first(&it->it_cur_type->ty_properties); + } + + if (!it->it_cur) { + fx_iterator_set_status(it_obj, FX_ERR_NO_DATA); + } + + return it_obj; +} + +static fx_type_id type_get_id(const struct fx_type_p *ty) +{ + return &ty->ty_info->ty_id; +} + +static const fx_type *type_get_parent(const struct fx_type_p *ty) +{ + if (fx_type_id_compare(&ty->ty_info->ty_id, FX_TYPE_OBJECT) == 0) { + return NULL; + } + + return fx_type_get_by_id(&ty->ty_info->ty_parent_id); +} + +static void *type_get_interface( + const struct fx_type_p *ty, + fx_type_id interface_id) +{ + return fx_class_get_interface(ty->ty_info->ty_class, interface_id); +} + /*** PUBLIC FUNCTIONS *********************************************************/ fx_type *__fx_type_create(struct fx_type_info *type_info) @@ -45,11 +184,33 @@ fx_type *__fx_type_create(struct fx_type_info *type_info) return out; } +const fx_assembly *fx_type_get_assembly(const fx_type *ty) +{ + FX_CLASS_DISPATCH_STATIC_0( + FX_REFLECTION_TYPE_TYPE, + type_get_assembly, + ty); +} + +fx_status fx_type_set_assembly(fx_type *ty, fx_assembly *assembly) +{ + FX_CLASS_DISPATCH_STATIC( + FX_REFLECTION_TYPE_TYPE, + type_set_assembly, + ty, + assembly); +} + const char *fx_type_get_name(const fx_type *ty) { FX_CLASS_DISPATCH_STATIC_0(FX_REFLECTION_TYPE_TYPE, type_get_name, ty); } +fx_type_flags fx_type_get_flags(const fx_type *ty) +{ + FX_CLASS_DISPATCH_STATIC_0(FX_REFLECTION_TYPE_TYPE, type_get_flags, ty); +} + const fx_function *fx_type_get_function(const fx_type *ty, const char *name) { FX_CLASS_DISPATCH_STATIC( @@ -59,6 +220,31 @@ const fx_function *fx_type_get_function(const fx_type *ty, const char *name) name); } +fx_iterator *fx_type_get_functions(const fx_type *ty) +{ + FX_CLASS_DISPATCH_STATIC_0( + FX_REFLECTION_TYPE_TYPE, + type_get_functions, + ty); +} + +const fx_property *fx_type_get_property(const fx_type *ty, const char *name) +{ + FX_CLASS_DISPATCH_STATIC( + FX_REFLECTION_TYPE_TYPE, + type_get_property, + ty, + name); +} + +fx_iterator *fx_type_get_properties(const fx_type *ty) +{ + FX_CLASS_DISPATCH_STATIC_0( + FX_REFLECTION_TYPE_TYPE, + type_get_properties, + ty); +} + const fx_type *fx_type_get_by_id(fx_type_id id) { struct fx_type_info *ty = fx_type_info_get_by_id(id); @@ -71,6 +257,28 @@ const fx_type *fx_type_get_by_name(const char *name) return ty ? ty->ty_metatype : NULL; } +fx_type_id fx_type_get_id(const fx_type *ty) +{ + FX_CLASS_DISPATCH_STATIC_0(FX_REFLECTION_TYPE_TYPE, type_get_id, ty); +} + +const fx_type *fx_type_get_parent(const fx_type *ty) +{ + FX_CLASS_DISPATCH_STATIC_0( + FX_REFLECTION_TYPE_TYPE, + type_get_parent, + ty); +} + +void *fx_type_get_interface(const fx_type *ty, fx_type_id interface_id) +{ + FX_CLASS_DISPATCH_STATIC( + FX_REFLECTION_TYPE_TYPE, + type_get_interface, + ty, + interface_id); +} + /*** VIRTUAL FUNCTIONS ********************************************************/ static void type_init(fx_object *obj, void *priv) @@ -81,12 +289,87 @@ static void type_fini(fx_object *obj, void *priv) { } +/*** ITERATOR FUNCTIONS *******************************************************/ + +static enum fx_status function_iterator_move_next(const fx_iterator *obj) +{ + struct fx_type_function_iterator_p *it = fx_object_get_private( + obj, + FX_REFLECTION_TYPE_TYPE_FUNCTION_ITERATOR); + if (!it->it_cur) { + return FX_ERR_NO_DATA; + } + + it->it_cur = fx_namemap_next(it->it_src, it->it_cur); + return it->it_cur ? FX_SUCCESS : FX_ERR_NO_DATA; +} + +static fx_value function_iterator_get_value(const fx_iterator *obj) +{ + struct fx_type_function_iterator_p *it = fx_object_get_private( + obj, + FX_REFLECTION_TYPE_TYPE_FUNCTION_ITERATOR); + if (!it->it_cur) { + return FX_VALUE_EMPTY; + } + + struct fx_type_function *func = fx_unbox( + struct fx_type_function, + it->it_cur, + f_entry); + + return FX_VALUE_OBJECT(func->f_func); +} + +static enum fx_status property_iterator_move_next(const fx_iterator *obj) +{ + struct fx_type_property_iterator_p *it = fx_object_get_private( + obj, + FX_REFLECTION_TYPE_TYPE_PROPERTY_ITERATOR); + if (!it->it_cur) { + return FX_ERR_NO_DATA; + } + + it->it_cur = fx_namemap_next(it->it_src, it->it_cur); + if (!it->it_cur) { + if (fx_type_id_compare(&it->it_cur_type->ty_id, FX_TYPE_OBJECT) + == 0) { + return FX_ERR_NO_DATA; + } + + const struct fx_type_info *next_type = fx_type_info_get_by_id( + &it->it_cur_type->ty_parent_id); + if (!next_type) { + return FX_ERR_NO_DATA; + } + + it->it_cur_type = next_type; + it->it_cur = fx_namemap_first(&it->it_cur_type->ty_properties); + } + + return it->it_cur ? FX_SUCCESS : FX_ERR_NO_DATA; +} + +static fx_value property_iterator_get_value(const fx_iterator *obj) +{ + struct fx_type_property_iterator_p *it = fx_object_get_private( + obj, + FX_REFLECTION_TYPE_TYPE_PROPERTY_ITERATOR); + if (!it->it_cur) { + return FX_VALUE_EMPTY; + } + + struct fx_type_property *prop = fx_unbox( + struct fx_type_property, + it->it_cur, + p_entry); + + return FX_VALUE_OBJECT(prop->p_prop); +} + /*** CLASS DEFINITION *********************************************************/ FX_TYPE_CLASS_BEGIN(fx_type) - FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT) - FX_INTERFACE_ENTRY(to_string) = NULL; - FX_TYPE_VTABLE_INTERFACE_END(fx_object, FX_TYPE_OBJECT) FX_TYPE_CLASS_END(fx_type) FX_TYPE_DEFINITION_BEGIN(fx_type) @@ -97,3 +380,35 @@ FX_TYPE_DEFINITION_BEGIN(fx_type) FX_TYPE_INSTANCE_INIT(type_init); FX_TYPE_INSTANCE_FINI(type_fini); FX_TYPE_DEFINITION_END(fx_type) + +FX_TYPE_CLASS_BEGIN(fx_type_function_iterator) + FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_iterator, FX_TYPE_ITERATOR) + FX_INTERFACE_ENTRY(it_move_next) = function_iterator_move_next; + FX_INTERFACE_ENTRY(it_erase) = NULL; + FX_INTERFACE_ENTRY(it_get_value) = function_iterator_get_value; + FX_TYPE_VTABLE_INTERFACE_END(fx_iterator, FX_TYPE_ITERATOR) +FX_TYPE_CLASS_END(fx_type_function_iterator) + +FX_TYPE_DEFINITION_BEGIN(fx_type_function_iterator) + FX_TYPE_ID(0xb29012d5, 0x4d6c, 0x4e3c, 0x9fe5, 0x7d1a8a9e1075); + FX_TYPE_NAME("fx.reflection.type.function_iterator"); + FX_TYPE_EXTENDS(FX_TYPE_ITERATOR); + FX_TYPE_CLASS(fx_type_class); + FX_TYPE_INSTANCE_PRIVATE(struct fx_type_function_iterator_p); +FX_TYPE_DEFINITION_END(fx_type_function_iterator) + +FX_TYPE_CLASS_BEGIN(fx_type_property_iterator) + FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_iterator, FX_TYPE_ITERATOR) + FX_INTERFACE_ENTRY(it_move_next) = property_iterator_move_next; + FX_INTERFACE_ENTRY(it_erase) = NULL; + FX_INTERFACE_ENTRY(it_get_value) = property_iterator_get_value; + FX_TYPE_VTABLE_INTERFACE_END(fx_iterator, FX_TYPE_ITERATOR) +FX_TYPE_CLASS_END(fx_type_property_iterator) + +FX_TYPE_DEFINITION_BEGIN(fx_type_property_iterator) + FX_TYPE_ID(0x91fcbdd4, 0x7c54, 0x48c2, 0xa5a4, 0x186f76efd84c); + FX_TYPE_NAME("fx.reflection.type.property_iterator"); + FX_TYPE_EXTENDS(FX_TYPE_ITERATOR); + FX_TYPE_CLASS(fx_type_property_iterator_class); + FX_TYPE_INSTANCE_PRIVATE(struct fx_type_property_iterator_p); +FX_TYPE_DEFINITION_END(fx_type_property_iterator)