return owners;
}
+static const char *
+_get_reflect_initf(const Eolian_Type *abtp)
+{
+ Eolian_Type_Builtin_Type btp = eolian_type_builtin_type_get(abtp);
+ const char *initf = NULL;
+ switch (btp)
+ {
+ case EOLIAN_TYPE_BUILTIN_BYTE:
+ case EOLIAN_TYPE_BUILTIN_CHAR:
+ initf = "char"; break;
+ case EOLIAN_TYPE_BUILTIN_UBYTE:
+ initf = "uchar"; break;
+ case EOLIAN_TYPE_BUILTIN_SHORT:
+ case EOLIAN_TYPE_BUILTIN_USHORT:
+ case EOLIAN_TYPE_BUILTIN_INT:
+ case EOLIAN_TYPE_BUILTIN_UINT:
+ case EOLIAN_TYPE_BUILTIN_LONG:
+ case EOLIAN_TYPE_BUILTIN_ULONG:
+ case EOLIAN_TYPE_BUILTIN_INT64:
+ case EOLIAN_TYPE_BUILTIN_UINT64:
+ case EOLIAN_TYPE_BUILTIN_TIME:
+ case EOLIAN_TYPE_BUILTIN_FLOAT:
+ case EOLIAN_TYPE_BUILTIN_DOUBLE:
+ case EOLIAN_TYPE_BUILTIN_BOOL:
+ case EOLIAN_TYPE_BUILTIN_STRING:
+ case EOLIAN_TYPE_BUILTIN_STRINGSHARE:
+ initf = eolian_type_name_get(abtp); break;
+ default:
+ break;
+ }
+ return initf;
+}
+
+static void
+_gen_reflect_get(Eina_Strbuf *buf, const char *cnamel, const Eolian_Type *valt,
+ const Eolian_Function *fid, Eina_Hash *refh)
+{
+ if (eolian_type_is_ptr(valt))
+ return;
+
+ const Eolian_Type *abtp = eolian_type_aliased_base_get(valt);
+ const char *initf = _get_reflect_initf(abtp);
+ if (!initf)
+ return;
+
+ Eolian_Function_Type et = (Eolian_Function_Type)eina_hash_find(refh, &fid);
+ if (et == EOLIAN_PROP_SET)
+ eina_hash_set(refh, &fid, (void *)EOLIAN_PROPERTY);
+ else
+ eina_hash_set(refh, &fid, (void *)EOLIAN_PROP_GET);
+
+ eina_strbuf_append(buf, "\nstatic Eina_Value\n");
+ eina_strbuf_append_printf(buf, "__eolian_%s_%s_get_reflect(Eo *obj)\n",
+ cnamel, eolian_function_name_get(fid));
+ eina_strbuf_append(buf, "{\n");
+
+ Eina_Stringshare *ct = eolian_type_c_type_get(valt, EOLIAN_C_TYPE_RETURN);
+ const char *starsp = (ct[strlen(ct) - 1] != '*') ? " " : "";
+
+ Eina_Stringshare *fcn = eolian_function_full_c_name_get(fid, EOLIAN_PROP_GET, EINA_FALSE);
+ eina_strbuf_append_printf(buf, " %s%sval = %s(obj);\n", ct, starsp, fcn);
+ eina_stringshare_del(fcn);
+ eina_stringshare_del(ct);
+
+ eina_strbuf_append_printf(buf, " return eina_value_%s_init(val);\n", initf);
+ eina_strbuf_append(buf, "}\n\n");
+}
+
+static void
+_gen_reflect_set(Eina_Strbuf *buf, const char *cnamel, const Eolian_Type *valt,
+ const Eolian_Function *fid, Eina_Hash *refh)
+{
+ if (eolian_type_is_ptr(valt))
+ return;
+
+ const Eolian_Type *abtp = eolian_type_aliased_base_get(valt);
+ const char *initf = _get_reflect_initf(abtp);
+ if (!initf)
+ return;
+
+ Eolian_Function_Type et = (Eolian_Function_Type)eina_hash_find(refh, &fid);
+ if (et == EOLIAN_PROP_GET)
+ eina_hash_set(refh, &fid, (void *)EOLIAN_PROPERTY);
+ else
+ eina_hash_set(refh, &fid, (void *)EOLIAN_PROP_SET);
+
+ eina_strbuf_append(buf, "\nstatic void\n");
+ eina_strbuf_append_printf(buf, "__eolian_%s_%s_set_reflect(Eo *obj, Eina_Value val)\n",
+ cnamel, eolian_function_name_get(fid));
+ eina_strbuf_append(buf, "{\n");
+
+ Eina_Stringshare *ct = eolian_type_c_type_get(valt, EOLIAN_C_TYPE_PARAM);
+ const char *starsp = (ct[strlen(ct) - 1] != '*') ? " " : "";
+ eina_strbuf_append_printf(buf, " %s%scval;\n", ct, starsp);
+ eina_stringshare_del(ct);
+
+ eina_strbuf_append_printf(buf, " eina_value_%s_convert(&val, &cval);\n", initf);
+
+ Eina_Stringshare *fcn = eolian_function_full_c_name_get(fid, EOLIAN_PROP_SET, EINA_FALSE);
+ eina_strbuf_append_printf(buf, " %s(obj, cval);\n", fcn);
+ eina_stringshare_del(fcn);
+
+ eina_strbuf_append(buf, " eina_value_flush(&val);\n");
+
+ eina_strbuf_append(buf, "}\n\n");
+}
static void
_emit_class_function(Eina_Strbuf *buf, const Eolian_Function *fid, const Eolian_Type *rtp, Eina_Strbuf *params_full,
static void
_gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
Eolian_Function_Type ftype, Eina_Strbuf *buf,
- const Eolian_Implement *impl, Eina_Strbuf *lbuf)
+ const Eolian_Implement *impl, Eina_Strbuf *lbuf,
+ Eina_Hash *refh)
{
Eina_Bool is_empty = eolian_implement_is_empty(impl, ftype);
Eina_Bool is_auto = eolian_implement_is_auto(impl, ftype);
Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET);
Eina_Bool var_as_ret = EINA_FALSE;
+ /* assume we're not generating reflection api by default */
+ const Eolian_Type *reflect_type = NULL;
const Eolian_Expression *def_ret = NULL;
const Eolian_Type *rtp = eolian_function_return_type_get(fid, ftype);
{
Eolian_Function_Parameter *pr = d1;
rtp = eolian_parameter_type_get(pr);
+ /* reflect only when returning 1 val */
+ reflect_type = rtp;
var_as_ret = EINA_TRUE;
def_ret = eolian_parameter_default_value_get(pr);
}
}
}
else if (ftype == EOLIAN_PROP_SET)
- func_suffix = "_set";
+ {
+ func_suffix = "_set";
+ Eina_Iterator *itr = eolian_property_values_get(fid, ftype);
+ void *d1, *d2;
+ /* reflect with 1 value */
+ if (eina_iterator_next(itr, &d1) && !eina_iterator_next(itr, &d2))
+ {
+ Eolian_Function_Parameter *pr = d1;
+ reflect_type = eolian_parameter_type_get(pr);
+ }
+ eina_iterator_free(itr);
+ }
Eina_Strbuf *params = eina_strbuf_new(); /* par1, par2, par3, ... */
Eina_Strbuf *params_full = eina_strbuf_new(); /* T par1, U par2, ... for decl */
/* property keys */
{
Eina_Iterator *itr = eolian_property_keys_get(fid, ftype);
+ if (itr) /* has keys: no reflection */
+ reflect_type = NULL;
Eolian_Function_Parameter *pr;
EINA_ITERATOR_FOREACH(itr, pr)
{
if (impl_same_class && !eolian_function_is_class(fid))
{
+ /* generate reflection implementation */
+ if (reflect_type)
+ {
+ if (ftype == EOLIAN_PROP_GET)
+ _gen_reflect_get(buf, cnamel, reflect_type, fid, refh);
+ else
+ _gen_reflect_set(buf, cnamel, reflect_type, fid, refh);
+ }
+
void *data;
Eina_Iterator *itr = eolian_property_keys_get(fid, ftype);
Eina_Bool has_params = eina_iterator_next(itr, &data);
}
static void
-_gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf)
+_gen_reflop(const Eolian_Function *fid, Eina_Strbuf *buf, const char *cnamel, Eina_Hash *refh)
+{
+ Eolian_Function_Type aftype = (Eolian_Function_Type)eina_hash_find(refh, &fid);
+ if (aftype == EOLIAN_UNRESOLVED)
+ return;
+
+ eina_strbuf_append_printf(buf, " {\"%s\", ", eolian_function_name_get(fid));
+
+ if (aftype == EOLIAN_PROP_SET || aftype == EOLIAN_PROPERTY)
+ {
+ eina_strbuf_append_printf(buf, "__eolian_%s_%s_set_reflect, ",
+ cnamel, eolian_function_name_get(fid));
+ }
+ else
+ eina_strbuf_append(buf, "NULL, ");
+
+ if (aftype == EOLIAN_PROP_GET || aftype == EOLIAN_PROPERTY)
+ {
+ eina_strbuf_append_printf(buf, "__eolian_%s_%s_get_reflect},\n",
+ cnamel, eolian_function_name_get(fid));
+ }
+ else
+ eina_strbuf_append(buf, "NULL},\n");
+}
+
+static void
+_gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf, Eina_Hash *refh)
{
char *cnamel = NULL, *cnameu = NULL;
eo_gen_class_names_get(cl, NULL, &cnameu, &cnamel);
eina_strbuf_append(buf, cnamel);
eina_strbuf_append(buf, "_class_initializer(Efl_Class *klass)\n{\n");
eina_strbuf_append(buf, " const Efl_Object_Ops *opsp = NULL;\n\n");
+ eina_strbuf_append(buf, " const Efl_Object_Property_Reflection_Ops *ropsp = NULL;\n\n");
Eina_Strbuf *ops = eina_strbuf_new();
+ Eina_Strbuf *refls = eina_strbuf_new();
/* start over with clean itearator */
const Eolian_Implement *imp;
if (eolian_function_is_class(fid)) continue;
- Eina_Strbuf *obuf = ops;
-
- if (!eina_strbuf_length_get(obuf))
- eina_strbuf_append_printf(obuf, " EFL_OPS_DEFINE(ops,\n");
+ if (!eina_strbuf_length_get(ops))
+ eina_strbuf_append_printf(ops, " EFL_OPS_DEFINE(ops,\n");
Eina_Bool found_get = !!eina_hash_find(_funcs_params_init_get, &imp);
Eina_Bool found_set = !!eina_hash_find(_funcs_params_init_set, &imp);
switch (ftype)
{
case EOLIAN_PROP_GET:
- _gen_opfunc(fid, EOLIAN_PROP_GET, obuf, imp, found_get, cnamel, ocnamel);
+ _gen_opfunc(fid, EOLIAN_PROP_GET, ops, imp, found_get, cnamel, ocnamel);
+ _gen_reflop(fid, refls, cnamel, refh);
break;
case EOLIAN_PROP_SET:
- _gen_opfunc(fid, EOLIAN_PROP_SET, obuf, imp, found_set, cnamel, ocnamel);
+ _gen_opfunc(fid, EOLIAN_PROP_SET, ops, imp, found_set, cnamel, ocnamel);
+ _gen_reflop(fid, refls, cnamel, refh);
break;
case EOLIAN_PROPERTY:
- _gen_opfunc(fid, EOLIAN_PROP_SET, obuf, imp, found_set, cnamel, ocnamel);
- _gen_opfunc(fid, EOLIAN_PROP_GET, obuf, imp, found_get, cnamel, ocnamel);
+ _gen_opfunc(fid, EOLIAN_PROP_SET, ops, imp, found_set, cnamel, ocnamel);
+ _gen_opfunc(fid, EOLIAN_PROP_GET, ops, imp, found_get, cnamel, ocnamel);
+ _gen_reflop(fid, refls, cnamel, refh);
break;
default:
- _gen_opfunc(fid, EOLIAN_METHOD, obuf, imp, found_get, cnamel, ocnamel);
+ _gen_opfunc(fid, EOLIAN_METHOD, ops, imp, found_get, cnamel, ocnamel);
break;
}
eina_strbuf_append(buf, "#endif\n\n");
}
- eina_strbuf_append(buf, " return efl_class_functions_set(klass, opsp, NULL);\n");
+ if (eina_strbuf_length_get(refls))
+ {
+ eina_strbuf_append(buf, " static const Efl_Object_Property_Reflection refl_table[] = {\n");
+ eina_strbuf_append_buffer(buf, refls);
+ eina_strbuf_append(buf, " };\n");
+ eina_strbuf_append(buf, " static const Efl_Object_Property_Reflection_Ops rops = {\n");
+ eina_strbuf_append(buf, " refl_table, EINA_C_ARRAY_LENGTH(refl_table)\n");
+ eina_strbuf_append(buf, " };\n");
+ eina_strbuf_append(buf, " ropsp = &rops;\n\n");
+ }
+
+ eina_strbuf_append(buf, " return efl_class_functions_set(klass, opsp, ropsp);\n");
eina_strbuf_free(ops);
Eina_Strbuf *lbuf = eina_strbuf_new();
+ /* Eolian_Function -> Eolian_Function_Type
+ * maps which parts of which functions are qualified for reflection
+ */
+ Eina_Hash *refh = eina_hash_pointer_new(NULL);
+
/* method section */
{
Eina_Iterator *itr = eolian_class_implements_get(cl);
{
case EOLIAN_PROP_GET:
case EOLIAN_PROP_SET:
- _gen_func(cl, fid, ftype, buf, imp, lbuf);
+ _gen_func(cl, fid, ftype, buf, imp, lbuf, refh);
break;
case EOLIAN_PROPERTY:
- _gen_func(cl, fid, EOLIAN_PROP_SET, buf, imp, lbuf);
- _gen_func(cl, fid, EOLIAN_PROP_GET, buf, imp, lbuf);
+ _gen_func(cl, fid, EOLIAN_PROP_SET, buf, imp, lbuf, refh);
+ _gen_func(cl, fid, EOLIAN_PROP_GET, buf, imp, lbuf, refh);
break;
default:
- _gen_func(cl, fid, EOLIAN_METHOD, buf, imp, lbuf);
+ _gen_func(cl, fid, EOLIAN_METHOD, buf, imp, lbuf, refh);
}
}
eina_iterator_free(itr);
}
/* class initializer - contains method defs */
- _gen_initializer(cl, buf);
+ _gen_initializer(cl, buf, refh);
+ eina_hash_free(refh);
/* class description */
eina_strbuf_append(buf, "static const Efl_Class_Description _");