fx.reflection: implement retrieving functions and properties from fx_type

This commit is contained in:
2026-05-25 17:25:27 +01:00
parent 82bb20c6af
commit 673bf07cf6
2 changed files with 334 additions and 3 deletions
@@ -1,8 +1,11 @@
#ifndef FX_REFLECTION_TYPE_H_
#define FX_REFLECTION_TYPE_H_
#include <fx/iterator.h>
#include <fx/macros.h>
#include <fx/reflection/assembly.h>
#include <fx/reflection/function.h>
#include <fx/reflection/property.h>
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
+318 -3
View File
@@ -1,11 +1,42 @@
#include "../fx/type.h"
#include <fx/macros.h>
#include <fx/reflection/type.h>
#include <fx/type.h>
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)