summaryrefslogtreecommitdiff
path: root/src/bin/eolian/sources.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/eolian/sources.c')
-rw-r--r--src/bin/eolian/sources.c215
1 files changed, 197 insertions, 18 deletions
diff --git a/src/bin/eolian/sources.c b/src/bin/eolian/sources.c
index 76f8c64..e4491a2 100644
--- a/src/bin/eolian/sources.c
+++ b/src/bin/eolian/sources.c
@@ -322,11 +322,118 @@ _gen_function_param_fallback(Eina_Iterator *itr, Eina_Strbuf *fallback_free_owne
322 return owners; 322 return owners;
323} 323}
324 324
325static const char *
326_get_reflect_initf(const Eolian_Type *abtp)
327{
328 Eolian_Type_Builtin_Type btp = eolian_type_builtin_type_get(abtp);
329 const char *initf = NULL;
330 switch (btp)
331 {
332 case EOLIAN_TYPE_BUILTIN_BYTE:
333 case EOLIAN_TYPE_BUILTIN_CHAR:
334 initf = "char"; break;
335 case EOLIAN_TYPE_BUILTIN_UBYTE:
336 initf = "uchar"; break;
337 case EOLIAN_TYPE_BUILTIN_SHORT:
338 case EOLIAN_TYPE_BUILTIN_USHORT:
339 case EOLIAN_TYPE_BUILTIN_INT:
340 case EOLIAN_TYPE_BUILTIN_UINT:
341 case EOLIAN_TYPE_BUILTIN_LONG:
342 case EOLIAN_TYPE_BUILTIN_ULONG:
343 case EOLIAN_TYPE_BUILTIN_INT64:
344 case EOLIAN_TYPE_BUILTIN_UINT64:
345 case EOLIAN_TYPE_BUILTIN_TIME:
346 case EOLIAN_TYPE_BUILTIN_FLOAT:
347 case EOLIAN_TYPE_BUILTIN_DOUBLE:
348 case EOLIAN_TYPE_BUILTIN_BOOL:
349 case EOLIAN_TYPE_BUILTIN_STRING:
350 case EOLIAN_TYPE_BUILTIN_STRINGSHARE:
351 initf = eolian_type_name_get(abtp); break;
352 default:
353 break;
354 }
355 return initf;
356}
357
358static void
359_gen_reflect_get(Eina_Strbuf *buf, const char *cnamel, const Eolian_Type *valt,
360 const Eolian_Function *fid, Eina_Hash *refh)
361{
362 if (eolian_type_is_ptr(valt))
363 return;
364
365 const Eolian_Type *abtp = eolian_type_aliased_base_get(valt);
366 const char *initf = _get_reflect_initf(abtp);
367 if (!initf)
368 return;
369
370 Eolian_Function_Type et = (Eolian_Function_Type)eina_hash_find(refh, &fid);
371 if (et == EOLIAN_PROP_SET)
372 eina_hash_set(refh, &fid, (void *)EOLIAN_PROPERTY);
373 else
374 eina_hash_set(refh, &fid, (void *)EOLIAN_PROP_GET);
375
376 eina_strbuf_append(buf, "\nstatic Eina_Value\n");
377 eina_strbuf_append_printf(buf, "__eolian_%s_%s_get_reflect(Eo *obj)\n",
378 cnamel, eolian_function_name_get(fid));
379 eina_strbuf_append(buf, "{\n");
380
381 Eina_Stringshare *ct = eolian_type_c_type_get(valt, EOLIAN_C_TYPE_RETURN);
382 const char *starsp = (ct[strlen(ct) - 1] != '*') ? " " : "";
383
384 Eina_Stringshare *fcn = eolian_function_full_c_name_get(fid, EOLIAN_PROP_GET, EINA_FALSE);
385 eina_strbuf_append_printf(buf, " %s%sval = %s(obj);\n", ct, starsp, fcn);
386 eina_stringshare_del(fcn);
387 eina_stringshare_del(ct);
388
389 eina_strbuf_append_printf(buf, " return eina_value_%s_init(val);\n", initf);
390 eina_strbuf_append(buf, "}\n\n");
391}
392
393static void
394_gen_reflect_set(Eina_Strbuf *buf, const char *cnamel, const Eolian_Type *valt,
395 const Eolian_Function *fid, Eina_Hash *refh)
396{
397 if (eolian_type_is_ptr(valt))
398 return;
399
400 const Eolian_Type *abtp = eolian_type_aliased_base_get(valt);
401 const char *initf = _get_reflect_initf(abtp);
402 if (!initf)
403 return;
404
405 Eolian_Function_Type et = (Eolian_Function_Type)eina_hash_find(refh, &fid);
406 if (et == EOLIAN_PROP_GET)
407 eina_hash_set(refh, &fid, (void *)EOLIAN_PROPERTY);
408 else
409 eina_hash_set(refh, &fid, (void *)EOLIAN_PROP_SET);
410
411 eina_strbuf_append(buf, "\nstatic void\n");
412 eina_strbuf_append_printf(buf, "__eolian_%s_%s_set_reflect(Eo *obj, Eina_Value val)\n",
413 cnamel, eolian_function_name_get(fid));
414 eina_strbuf_append(buf, "{\n");
415
416 Eina_Stringshare *ct = eolian_type_c_type_get(valt, EOLIAN_C_TYPE_PARAM);
417 const char *starsp = (ct[strlen(ct) - 1] != '*') ? " " : "";
418 eina_strbuf_append_printf(buf, " %s%scval;\n", ct, starsp);
419 eina_stringshare_del(ct);
420
421 eina_strbuf_append_printf(buf, " eina_value_%s_convert(&val, &cval);\n", initf);
422
423 Eina_Stringshare *fcn = eolian_function_full_c_name_get(fid, EOLIAN_PROP_SET, EINA_FALSE);
424 eina_strbuf_append_printf(buf, " %s(obj, cval);\n", fcn);
425 eina_stringshare_del(fcn);
426
427 eina_strbuf_append(buf, " eina_value_flush(&val);\n");
428
429 eina_strbuf_append(buf, "}\n\n");
430}
325 431
326static void 432static void
327_gen_func(const Eolian_Class *cl, const Eolian_Function *fid, 433_gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
328 Eolian_Function_Type ftype, Eina_Strbuf *buf, 434 Eolian_Function_Type ftype, Eina_Strbuf *buf,
329 const Eolian_Implement *impl, Eina_Strbuf *lbuf) 435 const Eolian_Implement *impl, Eina_Strbuf *lbuf,
436 Eina_Hash *refh)
330{ 437{
331 Eina_Bool is_empty = eolian_implement_is_empty(impl, ftype); 438 Eina_Bool is_empty = eolian_implement_is_empty(impl, ftype);
332 Eina_Bool is_auto = eolian_implement_is_auto(impl, ftype); 439 Eina_Bool is_auto = eolian_implement_is_auto(impl, ftype);
@@ -336,6 +443,8 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
336 443
337 Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET); 444 Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET);
338 Eina_Bool var_as_ret = EINA_FALSE; 445 Eina_Bool var_as_ret = EINA_FALSE;
446 /* assume we're not generating reflection api by default */
447 const Eolian_Type *reflect_type = NULL;
339 448
340 const Eolian_Expression *def_ret = NULL; 449 const Eolian_Expression *def_ret = NULL;
341 const Eolian_Type *rtp = eolian_function_return_type_get(fid, ftype); 450 const Eolian_Type *rtp = eolian_function_return_type_get(fid, ftype);
@@ -357,6 +466,8 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
357 { 466 {
358 Eolian_Function_Parameter *pr = d1; 467 Eolian_Function_Parameter *pr = d1;
359 rtp = eolian_parameter_type_get(pr); 468 rtp = eolian_parameter_type_get(pr);
469 /* reflect only when returning 1 val */
470 reflect_type = rtp;
360 var_as_ret = EINA_TRUE; 471 var_as_ret = EINA_TRUE;
361 def_ret = eolian_parameter_default_value_get(pr); 472 def_ret = eolian_parameter_default_value_get(pr);
362 } 473 }
@@ -364,7 +475,18 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
364 } 475 }
365 } 476 }
366 else if (ftype == EOLIAN_PROP_SET) 477 else if (ftype == EOLIAN_PROP_SET)
367 func_suffix = "_set"; 478 {
479 func_suffix = "_set";
480 Eina_Iterator *itr = eolian_property_values_get(fid, ftype);
481 void *d1, *d2;
482 /* reflect with 1 value */
483 if (eina_iterator_next(itr, &d1) && !eina_iterator_next(itr, &d2))
484 {
485 Eolian_Function_Parameter *pr = d1;
486 reflect_type = eolian_parameter_type_get(pr);
487 }
488 eina_iterator_free(itr);
489 }
368 490
369 Eina_Strbuf *params = eina_strbuf_new(); /* par1, par2, par3, ... */ 491 Eina_Strbuf *params = eina_strbuf_new(); /* par1, par2, par3, ... */
370 Eina_Strbuf *params_full = eina_strbuf_new(); /* T par1, U par2, ... for decl */ 492 Eina_Strbuf *params_full = eina_strbuf_new(); /* T par1, U par2, ... for decl */
@@ -375,6 +497,8 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
375 /* property keys */ 497 /* property keys */
376 { 498 {
377 Eina_Iterator *itr = eolian_property_keys_get(fid, ftype); 499 Eina_Iterator *itr = eolian_property_keys_get(fid, ftype);
500 if (itr) /* has keys: no reflection */
501 reflect_type = NULL;
378 Eolian_Function_Parameter *pr; 502 Eolian_Function_Parameter *pr;
379 EINA_ITERATOR_FOREACH(itr, pr) 503 EINA_ITERATOR_FOREACH(itr, pr)
380 { 504 {
@@ -650,6 +774,15 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
650 774
651 if (impl_same_class && !eolian_function_is_class(fid)) 775 if (impl_same_class && !eolian_function_is_class(fid))
652 { 776 {
777 /* generate reflection implementation */
778 if (reflect_type)
779 {
780 if (ftype == EOLIAN_PROP_GET)
781 _gen_reflect_get(buf, cnamel, reflect_type, fid, refh);
782 else
783 _gen_reflect_set(buf, cnamel, reflect_type, fid, refh);
784 }
785
653 void *data; 786 void *data;
654 Eina_Iterator *itr = eolian_property_keys_get(fid, ftype); 787 Eina_Iterator *itr = eolian_property_keys_get(fid, ftype);
655 Eina_Bool has_params = eina_iterator_next(itr, &data); 788 Eina_Bool has_params = eina_iterator_next(itr, &data);
@@ -832,7 +965,33 @@ _gen_opfunc(const Eolian_Function *fid, Eolian_Function_Type ftype,
832} 965}
833 966
834static void 967static void
835_gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf) 968_gen_reflop(const Eolian_Function *fid, Eina_Strbuf *buf, const char *cnamel, Eina_Hash *refh)
969{
970 Eolian_Function_Type aftype = (Eolian_Function_Type)eina_hash_find(refh, &fid);
971 if (aftype == EOLIAN_UNRESOLVED)
972 return;
973
974 eina_strbuf_append_printf(buf, " {\"%s\", ", eolian_function_name_get(fid));
975
976 if (aftype == EOLIAN_PROP_SET || aftype == EOLIAN_PROPERTY)
977 {
978 eina_strbuf_append_printf(buf, "__eolian_%s_%s_set_reflect, ",
979 cnamel, eolian_function_name_get(fid));
980 }
981 else
982 eina_strbuf_append(buf, "NULL, ");
983
984 if (aftype == EOLIAN_PROP_GET || aftype == EOLIAN_PROPERTY)
985 {
986 eina_strbuf_append_printf(buf, "__eolian_%s_%s_get_reflect},\n",
987 cnamel, eolian_function_name_get(fid));
988 }
989 else
990 eina_strbuf_append(buf, "NULL},\n");
991}
992
993static void
994_gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf, Eina_Hash *refh)
836{ 995{
837 char *cnamel = NULL, *cnameu = NULL; 996 char *cnamel = NULL, *cnameu = NULL;
838 eo_gen_class_names_get(cl, NULL, &cnameu, &cnamel); 997 eo_gen_class_names_get(cl, NULL, &cnameu, &cnamel);
@@ -841,8 +1000,10 @@ _gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf)
841 eina_strbuf_append(buf, cnamel); 1000 eina_strbuf_append(buf, cnamel);
842 eina_strbuf_append(buf, "_class_initializer(Efl_Class *klass)\n{\n"); 1001 eina_strbuf_append(buf, "_class_initializer(Efl_Class *klass)\n{\n");
843 eina_strbuf_append(buf, " const Efl_Object_Ops *opsp = NULL;\n\n"); 1002 eina_strbuf_append(buf, " const Efl_Object_Ops *opsp = NULL;\n\n");
1003 eina_strbuf_append(buf, " const Efl_Object_Property_Reflection_Ops *ropsp = NULL;\n\n");
844 1004
845 Eina_Strbuf *ops = eina_strbuf_new(); 1005 Eina_Strbuf *ops = eina_strbuf_new();
1006 Eina_Strbuf *refls = eina_strbuf_new();
846 1007
847 /* start over with clean itearator */ 1008 /* start over with clean itearator */
848 const Eolian_Implement *imp; 1009 const Eolian_Implement *imp;
@@ -855,10 +1016,8 @@ _gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf)
855 1016
856 if (eolian_function_is_class(fid)) continue; 1017 if (eolian_function_is_class(fid)) continue;
857 1018
858 Eina_Strbuf *obuf = ops; 1019 if (!eina_strbuf_length_get(ops))
859 1020 eina_strbuf_append_printf(ops, " EFL_OPS_DEFINE(ops,\n");
860 if (!eina_strbuf_length_get(obuf))
861 eina_strbuf_append_printf(obuf, " EFL_OPS_DEFINE(ops,\n");
862 1021
863 Eina_Bool found_get = !!eina_hash_find(_funcs_params_init_get, &imp); 1022 Eina_Bool found_get = !!eina_hash_find(_funcs_params_init_get, &imp);
864 Eina_Bool found_set = !!eina_hash_find(_funcs_params_init_set, &imp); 1023 Eina_Bool found_set = !!eina_hash_find(_funcs_params_init_set, &imp);
@@ -869,17 +1028,20 @@ _gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf)
869 switch (ftype) 1028 switch (ftype)
870 { 1029 {
871 case EOLIAN_PROP_GET: 1030 case EOLIAN_PROP_GET:
872 _gen_opfunc(fid, EOLIAN_PROP_GET, obuf, imp, found_get, cnamel, ocnamel); 1031 _gen_opfunc(fid, EOLIAN_PROP_GET, ops, imp, found_get, cnamel, ocnamel);
1032 _gen_reflop(fid, refls, cnamel, refh);
873 break; 1033 break;
874 case EOLIAN_PROP_SET: 1034 case EOLIAN_PROP_SET:
875 _gen_opfunc(fid, EOLIAN_PROP_SET, obuf, imp, found_set, cnamel, ocnamel); 1035 _gen_opfunc(fid, EOLIAN_PROP_SET, ops, imp, found_set, cnamel, ocnamel);
1036 _gen_reflop(fid, refls, cnamel, refh);
876 break; 1037 break;
877 case EOLIAN_PROPERTY: 1038 case EOLIAN_PROPERTY:
878 _gen_opfunc(fid, EOLIAN_PROP_SET, obuf, imp, found_set, cnamel, ocnamel); 1039 _gen_opfunc(fid, EOLIAN_PROP_SET, ops, imp, found_set, cnamel, ocnamel);
879 _gen_opfunc(fid, EOLIAN_PROP_GET, obuf, imp, found_get, cnamel, ocnamel); 1040 _gen_opfunc(fid, EOLIAN_PROP_GET, ops, imp, found_get, cnamel, ocnamel);
1041 _gen_reflop(fid, refls, cnamel, refh);
880 break; 1042 break;
881 default: 1043 default:
882 _gen_opfunc(fid, EOLIAN_METHOD, obuf, imp, found_get, cnamel, ocnamel); 1044 _gen_opfunc(fid, EOLIAN_METHOD, ops, imp, found_get, cnamel, ocnamel);
883 break; 1045 break;
884 } 1046 }
885 1047
@@ -907,7 +1069,18 @@ _gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf)
907 eina_strbuf_append(buf, "#endif\n\n"); 1069 eina_strbuf_append(buf, "#endif\n\n");
908 } 1070 }
909 1071
910 eina_strbuf_append(buf, " return efl_class_functions_set(klass, opsp, NULL);\n"); 1072 if (eina_strbuf_length_get(refls))
1073 {
1074 eina_strbuf_append(buf, " static const Efl_Object_Property_Reflection refl_table[] = {\n");
1075 eina_strbuf_append_buffer(buf, refls);
1076 eina_strbuf_append(buf, " };\n");
1077 eina_strbuf_append(buf, " static const Efl_Object_Property_Reflection_Ops rops = {\n");
1078 eina_strbuf_append(buf, " refl_table, EINA_C_ARRAY_LENGTH(refl_table)\n");
1079 eina_strbuf_append(buf, " };\n");
1080 eina_strbuf_append(buf, " ropsp = &rops;\n\n");
1081 }
1082
1083 eina_strbuf_append(buf, " return efl_class_functions_set(klass, opsp, ropsp);\n");
911 1084
912 eina_strbuf_free(ops); 1085 eina_strbuf_free(ops);
913 1086
@@ -951,6 +1124,11 @@ eo_gen_source_gen(const Eolian_Class *cl, Eina_Strbuf *buf)
951 1124
952 Eina_Strbuf *lbuf = eina_strbuf_new(); 1125 Eina_Strbuf *lbuf = eina_strbuf_new();
953 1126
1127 /* Eolian_Function -> Eolian_Function_Type
1128 * maps which parts of which functions are qualified for reflection
1129 */
1130 Eina_Hash *refh = eina_hash_pointer_new(NULL);
1131
954 /* method section */ 1132 /* method section */
955 { 1133 {
956 Eina_Iterator *itr = eolian_class_implements_get(cl); 1134 Eina_Iterator *itr = eolian_class_implements_get(cl);
@@ -963,21 +1141,22 @@ eo_gen_source_gen(const Eolian_Class *cl, Eina_Strbuf *buf)
963 { 1141 {
964 case EOLIAN_PROP_GET: 1142 case EOLIAN_PROP_GET:
965 case EOLIAN_PROP_SET: 1143 case EOLIAN_PROP_SET:
966 _gen_func(cl, fid, ftype, buf, imp, lbuf); 1144 _gen_func(cl, fid, ftype, buf, imp, lbuf, refh);
967 break; 1145 break;
968 case EOLIAN_PROPERTY: 1146 case EOLIAN_PROPERTY:
969 _gen_func(cl, fid, EOLIAN_PROP_SET, buf, imp, lbuf); 1147 _gen_func(cl, fid, EOLIAN_PROP_SET, buf, imp, lbuf, refh);
970 _gen_func(cl, fid, EOLIAN_PROP_GET, buf, imp, lbuf); 1148 _gen_func(cl, fid, EOLIAN_PROP_GET, buf, imp, lbuf, refh);
971 break; 1149 break;
972 default: 1150 default:
973 _gen_func(cl, fid, EOLIAN_METHOD, buf, imp, lbuf); 1151 _gen_func(cl, fid, EOLIAN_METHOD, buf, imp, lbuf, refh);
974 } 1152 }
975 } 1153 }
976 eina_iterator_free(itr); 1154 eina_iterator_free(itr);
977 } 1155 }
978 1156
979 /* class initializer - contains method defs */ 1157 /* class initializer - contains method defs */
980 _gen_initializer(cl, buf); 1158 _gen_initializer(cl, buf, refh);
1159 eina_hash_free(refh);
981 1160
982 /* class description */ 1161 /* class description */
983 eina_strbuf_append(buf, "static const Efl_Class_Description _"); 1162 eina_strbuf_append(buf, "static const Efl_Class_Description _");