eolian: allow keys/values in property get/set

Sometimes it is necessary to specify a different set of values for a
getter or a setter. This commit allows such specializations. This also
renders @const_get and @const_set useless (soon to be removed).

To function correctly, this required adjustment of several public APIs
as well as deprecation of eolian_function_parameter_get_by_name.

This function was not used in any generator and was pretty much
useless in the first place, so it was removed.

@fix
This commit is contained in:
Daniel Kolesa 2015-05-20 17:42:00 +01:00
parent f64c12dc1d
commit 6b91b1bd12
9 changed files with 100 additions and 66 deletions

View File

@ -213,7 +213,6 @@ ffi.cdef [[
Eina_Bool eolian_function_is_legacy_only(const Eolian_Function *function_id, Eolian_Function_Type ftype);
Eina_Bool eolian_function_is_class(const Eolian_Function *function_id);
Eina_Bool eolian_function_is_c_only(const Eolian_Function *function_id);
const Eolian_Function_Parameter *eolian_function_parameter_get_by_name(const Eolian_Function *function_id, const char *param_name);
Eina_Iterator *eolian_property_keys_get(const Eolian_Function *foo_id, Eolian_Function_Type ftype);
Eina_Iterator *eolian_property_values_get(const Eolian_Function *foo_id, Eolian_Function_Type ftype);
Eina_Iterator *eolian_function_parameters_get(const Eolian_Function *function_id);
@ -671,12 +670,6 @@ M.Function = ffi.metatype("Eolian_Function", {
return eolian.eolian_function_is_c_only(self) ~= 0
end,
parameter_get_by_name = function(self, pname)
local v = eolian.eolian_function_parameter_get_by_name(self, pname)
if v == nil then return nil end
return v
end,
property_keys_get = function(self, ftype)
return Ptr_Iterator("const Eolian_Function_Parameter*",
eolian.eolian_property_keys_get(self, ftype))

View File

@ -14,8 +14,12 @@ database_function_del(Eolian_Function *fid)
if (fid->base.file) eina_stringshare_del(fid->base.file);
eina_stringshare_del(fid->name);
EINA_LIST_FREE(fid->keys, param) database_parameter_del(param);
EINA_LIST_FREE(fid->params, param) database_parameter_del(param);
EINA_LIST_FREE(fid->prop_values, param) database_parameter_del(param);
EINA_LIST_FREE(fid->prop_values_get, param) database_parameter_del(param);
EINA_LIST_FREE(fid->prop_values_set, param) database_parameter_del(param);
EINA_LIST_FREE(fid->prop_keys, param) database_parameter_del(param);
EINA_LIST_FREE(fid->prop_keys_get, param) database_parameter_del(param);
EINA_LIST_FREE(fid->prop_keys_set, param) database_parameter_del(param);
EINA_LIST_FREE(fid->ctor_of, cls_name) eina_stringshare_del(cls_name);
database_type_del(fid->get_ret_type);
database_type_del(fid->set_ret_type);

View File

@ -164,35 +164,44 @@ eolian_function_is_constructor(const Eolian_Function *fid, const Eolian_Class *k
return r;
}
EAPI const Eolian_Function_Parameter *
eolian_function_parameter_get_by_name(const Eolian_Function *fid, const char *param_name)
static Eina_List *
_get_prop_keys(const Eolian_Function *fid, Eolian_Function_Type ftype)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(fid, NULL);
Eina_List *itr;
Eolian_Function_Parameter *param;
EINA_LIST_FOREACH(fid->keys, itr, param)
if (!strcmp(param->name, param_name)) return param;
EINA_LIST_FOREACH(fid->params, itr, param)
if (!strcmp(param->name, param_name)) return param;
return NULL;
Eina_List *l = fid->prop_keys_get;
if (ftype == EOLIAN_PROP_SET) l = fid->prop_keys_set;
if (!l) return fid->prop_keys;
return l;
}
static Eina_List *
_get_prop_values(const Eolian_Function *fid, Eolian_Function_Type ftype)
{
Eina_List *l = fid->prop_values_get;
if (ftype == EOLIAN_PROP_SET) l = fid->prop_values_set;
if (!l) return fid->prop_values;
return l;
}
EAPI Eina_Iterator *
eolian_property_keys_get(const Eolian_Function *fid, Eolian_Function_Type ftype)
{
Eina_List *l = NULL;
EINA_SAFETY_ON_NULL_RETURN_VAL(fid, NULL);
if (ftype != EOLIAN_PROP_GET && ftype != EOLIAN_PROP_SET)
return NULL;
return (fid->keys ? eina_list_iterator_new(fid->keys) : NULL);
l = _get_prop_keys(fid, ftype);
return (l ? eina_list_iterator_new(l) : NULL);
}
EAPI Eina_Iterator *
eolian_property_values_get(const Eolian_Function *fid, Eolian_Function_Type ftype)
{
Eina_List *l = NULL;
EINA_SAFETY_ON_NULL_RETURN_VAL(fid, NULL);
if (ftype != EOLIAN_PROP_GET && ftype != EOLIAN_PROP_SET)
return NULL;
return (fid->params ? eina_list_iterator_new(fid->params) : NULL);
l = _get_prop_values(fid, ftype);
return (l ? eina_list_iterator_new(l) : NULL);
}
EAPI Eina_Iterator *

View File

@ -145,13 +145,19 @@ _validate_function(const Eolian_Function *func)
func->set_ret_type, 0))
return EINA_FALSE;
EINA_LIST_FOREACH(func->keys, l, param)
if (!_validate_param(param))
#define EOLIAN_PARAMS_VALIDATE(params) \
EINA_LIST_FOREACH(params, l, param) \
if (!_validate_param(param)) \
return EINA_FALSE;
EINA_LIST_FOREACH(func->params, l, param)
if (!_validate_param(param))
return EINA_FALSE;
EOLIAN_PARAMS_VALIDATE(func->prop_values);
EOLIAN_PARAMS_VALIDATE(func->prop_values_get);
EOLIAN_PARAMS_VALIDATE(func->prop_values_set);
EOLIAN_PARAMS_VALIDATE(func->prop_keys);
EOLIAN_PARAMS_VALIDATE(func->prop_keys_get);
EOLIAN_PARAMS_VALIDATE(func->prop_keys_set);
#undef EOLIAN_PARAMS_VALIDATE
return EINA_TRUE;
}

View File

@ -1082,12 +1082,26 @@ parse_legacy(Eo_Lexer *ls, const char **out)
check_next(ls, ';');
}
static void
parse_params(Eo_Lexer *ls, Eina_List **params, Eina_Bool allow_inout,
Eina_Bool is_vals)
{
int line, col;
eo_lexer_get(ls);
line = ls->line_number, col = ls->column;
check_next(ls, '{');
while (ls->t.token != '}')
parse_param(ls, params, allow_inout, is_vals);
check_match(ls, '}', '{', line, col);
}
static void
parse_accessor(Eo_Lexer *ls, Eolian_Function *prop)
{
int line, col;
Eina_Bool has_return = EINA_FALSE, has_legacy = EINA_FALSE,
has_eo = EINA_FALSE;
has_eo = EINA_FALSE, has_keys = EINA_FALSE,
has_values = EINA_FALSE;
Eina_Bool is_get = (ls->t.kw == KW_get);
if (is_get)
{
@ -1160,6 +1174,22 @@ parse_accessor(Eo_Lexer *ls, Eolian_Function *prop)
else
prop->set_only_legacy = EINA_TRUE;
break;
case KW_keys:
{
Eina_List **stor;
CASE_LOCK(ls, keys, "keys definition")
stor = is_get ? &prop->prop_keys_get : &prop->prop_keys_set;
parse_params(ls, stor, EINA_FALSE, EINA_FALSE);
break;
}
case KW_values:
{
Eina_List **stor;
CASE_LOCK(ls, values, "values definition")
stor = is_get ? &prop->prop_values_get : &prop->prop_values_set;
parse_params(ls, stor, EINA_FALSE, EINA_TRUE);
break;
}
default:
goto end;
}
@ -1167,19 +1197,6 @@ end:
check_match(ls, '}', '{', line, col);
}
static void
parse_params(Eo_Lexer *ls, Eina_List **params, Eina_Bool allow_inout,
Eina_Bool is_vals)
{
int line, col;
eo_lexer_get(ls);
line = ls->line_number, col = ls->column;
check_next(ls, '{');
while (ls->t.token != '}')
parse_param(ls, params, allow_inout, is_vals);
check_match(ls, '}', '{', line, col);
}
static void
_interface_virtual_set(Eo_Lexer *ls, Eolian_Function *foo_id)
{
@ -1257,11 +1274,11 @@ body:
break;
case KW_keys:
CASE_LOCK(ls, keys, "keys definition")
parse_params(ls, &prop->keys, EINA_FALSE, EINA_FALSE);
parse_params(ls, &prop->prop_keys, EINA_FALSE, EINA_FALSE);
break;
case KW_values:
CASE_LOCK(ls, values, "values definition")
parse_params(ls, &prop->params, EINA_FALSE, EINA_TRUE);
parse_params(ls, &prop->prop_values, EINA_FALSE, EINA_TRUE);
break;
default:
goto end;

View File

@ -111,8 +111,17 @@ struct _Eolian_Function
Eolian_Object base;
Eolian_Object set_base;
Eina_Stringshare *name;
Eina_List *keys; /* list of Eolian_Function_Parameter */
Eina_List *params; /* list of Eolian_Function_Parameter */
union { /* lists of Eolian_Function_Parameter */
Eina_List *params;
struct {
Eina_List *prop_values;
Eina_List *prop_values_get;
Eina_List *prop_values_set;
Eina_List *prop_keys;
Eina_List *prop_keys_get;
Eina_List *prop_keys_set;
};
};
Eolian_Function_Type type;
Eolian_Object_Scope scope;
Eolian_Type *get_ret_type;

View File

@ -1,16 +1,5 @@
class Consts {
methods {
@property a {
set {
return: bool (true); /*@ comment for property set return */
}
get {
}
values {
value: int; /*@ Value description */
buffer: char * @const_get;
}
}
foo @const {
/*@ comment foo */
params {

View File

@ -2,6 +2,9 @@ class Object_Impl (Base) {
methods {
@property a {
set {
values {
value: const(list<int>)*;
}
return: bool (false);
}
get {
@ -10,7 +13,7 @@ class Object_Impl (Base) {
part: const(char)*;
}
values {
value: own(list<int>*) @const_set;
value: own(list<int>*);
}
}
@property b {

View File

@ -265,12 +265,6 @@ START_TEST(eolian_consts)
fail_if(!eolian_eo_file_parse(PACKAGE_DATA_DIR"/data/consts.eo"));
fail_if(!(class = eolian_class_get_by_name("Consts")));
/* Property */
fail_if(!(fid = eolian_class_function_get_by_name(class, "a", EOLIAN_PROPERTY)));
fail_if(!(param = eolian_function_parameter_get_by_name(fid, "buffer")));
fail_if(eolian_parameter_const_attribute_get(param, EINA_FALSE));
fail_if(!eolian_parameter_const_attribute_get(param, EINA_TRUE));
/* Method */
fail_if(!(fid = eolian_class_function_get_by_name(class, "foo", EOLIAN_METHOD)));
fail_if(EINA_FALSE == eolian_function_object_is_const(fid));
@ -1013,6 +1007,7 @@ START_TEST(eolian_null)
const Eolian_Class *class;
const Eolian_Function *func;
const Eolian_Function_Parameter *param;
Eina_Iterator *iter;
eolian_init();
@ -1022,26 +1017,35 @@ START_TEST(eolian_null)
fail_if(!(class = eolian_class_get_by_name("Null")));
fail_if(!(func = eolian_class_function_get_by_name(class, "foo", EOLIAN_METHOD)));
fail_if(!(iter = eolian_function_parameters_get(func)));
/* no qualifiers */
fail_if(!(param = eolian_function_parameter_get_by_name(func, "x")));
fail_if(!(eina_iterator_next(iter, (void**)&param)));
fail_if(strcmp(eolian_parameter_name_get(param), "x"));
fail_if(eolian_parameter_is_nullable(param));
fail_if(eolian_parameter_is_optional(param));
/* nullable */
fail_if(!(param = eolian_function_parameter_get_by_name(func, "y")));
fail_if(!(eina_iterator_next(iter, (void**)&param)));
fail_if(strcmp(eolian_parameter_name_get(param), "y"));
fail_if(!eolian_parameter_is_nullable(param));
fail_if(eolian_parameter_is_optional(param));
/* optional */
fail_if(!(param = eolian_function_parameter_get_by_name(func, "z")));
fail_if(!(eina_iterator_next(iter, (void**)&param)));
fail_if(strcmp(eolian_parameter_name_get(param), "z"));
fail_if(eolian_parameter_is_nullable(param));
fail_if(!eolian_parameter_is_optional(param));
/* both */
fail_if(!(param = eolian_function_parameter_get_by_name(func, "w")));
fail_if(!(eina_iterator_next(iter, (void**)&param)));
fail_if(strcmp(eolian_parameter_name_get(param), "w"));
fail_if(!eolian_parameter_is_nullable(param));
fail_if(!eolian_parameter_is_optional(param));
fail_if(eina_iterator_next(iter, (void**)&param));
eina_iterator_free(iter);
eolian_shutdown();
}
END_TEST