Files
fx/fx.reflection/type.c
T

431 lines
11 KiB
C
Raw Normal View History

#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;
2026-05-28 21:00:23 +01:00
fx_value it_value;
};
struct fx_type_property_iterator_p {
const fx_type_info *it_cur_type;
struct fx_namemap *it_src;
struct fx_namemap_entry *it_cur;
2026-05-28 21:00:23 +01:00
fx_value it_value;
};
/*** PRIVATE FUNCTIONS ********************************************************/
extern struct fx_type_info *fx_type_info_get_by_id(const union fx_type_id *key);
extern struct fx_type_info *fx_type_info_get_by_name(const char *name);
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)
{
return fx_type_info_get_function_by_name(ty->ty_info, name);
}
fx_iterator *type_get_functions(const struct fx_type_p *ty)
{
2026-05-28 21:00:23 +01:00
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) {
2026-05-28 21:00:23 +01:00
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)
{
2026-05-28 21:00:23 +01:00
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;
}
2026-05-28 21:00:23 +01:00
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);
}
2026-05-28 21:00:23 +01:00
struct fx_type_property *prop
= fx_unbox(struct fx_type_property, it->it_cur, p_entry);
it->it_value = FX_VALUE_OBJECT_REF(prop->p_prop);
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)
{
fx_type *out = fx_object_create(FX_REFLECTION_TYPE_TYPE);
if (!out) {
return NULL;
}
2026-05-28 21:00:23 +01:00
struct fx_type_p *p
= fx_object_get_private(out, FX_REFLECTION_TYPE_TYPE);
p->ty_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(
FX_REFLECTION_TYPE_TYPE,
type_get_function,
ty,
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);
return ty ? ty->ty_metatype : NULL;
}
const fx_type *fx_type_get_by_name(const char *name)
{
struct fx_type_info *ty = fx_type_info_get_by_name(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)
{
}
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;
}
2026-05-28 21:00:23 +01:00
fx_value_unset(&it->it_value);
it->it_cur = fx_namemap_next(it->it_src, it->it_cur);
2026-05-28 21:00:23 +01:00
if (!it->it_cur) {
return FX_ERR_NO_DATA;
}
struct fx_type_function *func
= fx_unbox(struct fx_type_function, it->it_cur, f_entry);
it->it_value = FX_VALUE_OBJECT_REF(func->f_func);
return FX_SUCCESS;
}
2026-05-28 21:00:23 +01:00
static const 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) {
2026-05-28 21:00:23 +01:00
return NULL;
}
2026-05-28 21:00:23 +01:00
return &it->it_value;
}
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;
}
2026-05-28 21:00:23 +01:00
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);
}
2026-05-28 21:00:23 +01:00
if (!it->it_cur) {
return FX_ERR_NO_DATA;
}
struct fx_type_property *prop
= fx_unbox(struct fx_type_property, it->it_cur, p_entry);
it->it_value = FX_VALUE_OBJECT_REF(prop->p_prop);
return FX_SUCCESS;
}
2026-05-28 21:00:23 +01:00
static const 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) {
2026-05-28 21:00:23 +01:00
return NULL;
}
2026-05-28 21:00:23 +01:00
struct fx_type_property *prop
= fx_unbox(struct fx_type_property, it->it_cur, p_entry);
2026-05-28 21:00:23 +01:00
return &it->it_value;
}
/*** CLASS DEFINITION *********************************************************/
FX_TYPE_CLASS_BEGIN(fx_type)
FX_TYPE_CLASS_END(fx_type)
FX_TYPE_DEFINITION_BEGIN(fx_type)
FX_TYPE_ID(0xec8b2679, 0x5c73, 0x4ec9, 0xa04e, 0x3f72881b5b5a);
FX_TYPE_NAME("fx.reflection.type");
FX_TYPE_CLASS(fx_type_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_type_p);
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)