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_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_class(const Eolian_Function *function_id);
Eina_Bool eolian_function_is_c_only(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_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_property_values_get(const Eolian_Function *foo_id, Eolian_Function_Type ftype);
Eina_Iterator *eolian_function_parameters_get(const Eolian_Function *function_id); 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 return eolian.eolian_function_is_c_only(self) ~= 0
end, 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) property_keys_get = function(self, ftype)
return Ptr_Iterator("const Eolian_Function_Parameter*", return Ptr_Iterator("const Eolian_Function_Parameter*",
eolian.eolian_property_keys_get(self, ftype)) 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); if (fid->base.file) eina_stringshare_del(fid->base.file);
eina_stringshare_del(fid->name); eina_stringshare_del(fid->name);
EINA_LIST_FREE(fid->keys, param) database_parameter_del(param); EINA_LIST_FREE(fid->prop_values, param) database_parameter_del(param);
EINA_LIST_FREE(fid->params, 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); EINA_LIST_FREE(fid->ctor_of, cls_name) eina_stringshare_del(cls_name);
database_type_del(fid->get_ret_type); database_type_del(fid->get_ret_type);
database_type_del(fid->set_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; return r;
} }
EAPI const Eolian_Function_Parameter * static Eina_List *
eolian_function_parameter_get_by_name(const Eolian_Function *fid, const char *param_name) _get_prop_keys(const Eolian_Function *fid, Eolian_Function_Type ftype)
{ {
EINA_SAFETY_ON_NULL_RETURN_VAL(fid, NULL); Eina_List *l = fid->prop_keys_get;
Eina_List *itr; if (ftype == EOLIAN_PROP_SET) l = fid->prop_keys_set;
Eolian_Function_Parameter *param; if (!l) return fid->prop_keys;
EINA_LIST_FOREACH(fid->keys, itr, param) return l;
if (!strcmp(param->name, param_name)) return param; }
EINA_LIST_FOREACH(fid->params, itr, param)
if (!strcmp(param->name, param_name)) return param; static Eina_List *
return NULL; _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 * EAPI Eina_Iterator *
eolian_property_keys_get(const Eolian_Function *fid, Eolian_Function_Type ftype) eolian_property_keys_get(const Eolian_Function *fid, Eolian_Function_Type ftype)
{ {
Eina_List *l = NULL;
EINA_SAFETY_ON_NULL_RETURN_VAL(fid, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(fid, NULL);
if (ftype != EOLIAN_PROP_GET && ftype != EOLIAN_PROP_SET) if (ftype != EOLIAN_PROP_GET && ftype != EOLIAN_PROP_SET)
return NULL; 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 * EAPI Eina_Iterator *
eolian_property_values_get(const Eolian_Function *fid, Eolian_Function_Type ftype) eolian_property_values_get(const Eolian_Function *fid, Eolian_Function_Type ftype)
{ {
Eina_List *l = NULL;
EINA_SAFETY_ON_NULL_RETURN_VAL(fid, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(fid, NULL);
if (ftype != EOLIAN_PROP_GET && ftype != EOLIAN_PROP_SET) if (ftype != EOLIAN_PROP_GET && ftype != EOLIAN_PROP_SET)
return NULL; 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 * EAPI Eina_Iterator *

View File

@ -145,13 +145,19 @@ _validate_function(const Eolian_Function *func)
func->set_ret_type, 0)) func->set_ret_type, 0))
return EINA_FALSE; return EINA_FALSE;
EINA_LIST_FOREACH(func->keys, l, param) #define EOLIAN_PARAMS_VALIDATE(params) \
if (!_validate_param(param)) EINA_LIST_FOREACH(params, l, param) \
if (!_validate_param(param)) \
return EINA_FALSE; return EINA_FALSE;
EINA_LIST_FOREACH(func->params, l, param) EOLIAN_PARAMS_VALIDATE(func->prop_values);
if (!_validate_param(param)) EOLIAN_PARAMS_VALIDATE(func->prop_values_get);
return EINA_FALSE; 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; return EINA_TRUE;
} }

View File

@ -1082,12 +1082,26 @@ parse_legacy(Eo_Lexer *ls, const char **out)
check_next(ls, ';'); 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 static void
parse_accessor(Eo_Lexer *ls, Eolian_Function *prop) parse_accessor(Eo_Lexer *ls, Eolian_Function *prop)
{ {
int line, col; int line, col;
Eina_Bool has_return = EINA_FALSE, has_legacy = EINA_FALSE, 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); Eina_Bool is_get = (ls->t.kw == KW_get);
if (is_get) if (is_get)
{ {
@ -1160,6 +1174,22 @@ parse_accessor(Eo_Lexer *ls, Eolian_Function *prop)
else else
prop->set_only_legacy = EINA_TRUE; prop->set_only_legacy = EINA_TRUE;
break; 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: default:
goto end; goto end;
} }
@ -1167,19 +1197,6 @@ end:
check_match(ls, '}', '{', line, col); 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 static void
_interface_virtual_set(Eo_Lexer *ls, Eolian_Function *foo_id) _interface_virtual_set(Eo_Lexer *ls, Eolian_Function *foo_id)
{ {
@ -1257,11 +1274,11 @@ body:
break; break;
case KW_keys: case KW_keys:
CASE_LOCK(ls, keys, "keys definition") 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; break;
case KW_values: case KW_values:
CASE_LOCK(ls, values, "values definition") 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; break;
default: default:
goto end; goto end;

View File

@ -111,8 +111,17 @@ struct _Eolian_Function
Eolian_Object base; Eolian_Object base;
Eolian_Object set_base; Eolian_Object set_base;
Eina_Stringshare *name; Eina_Stringshare *name;
Eina_List *keys; /* list of Eolian_Function_Parameter */ union { /* lists of Eolian_Function_Parameter */
Eina_List *params; /* list 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_Function_Type type;
Eolian_Object_Scope scope; Eolian_Object_Scope scope;
Eolian_Type *get_ret_type; Eolian_Type *get_ret_type;

View File

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

View File

@ -2,6 +2,9 @@ class Object_Impl (Base) {
methods { methods {
@property a { @property a {
set { set {
values {
value: const(list<int>)*;
}
return: bool (false); return: bool (false);
} }
get { get {
@ -10,7 +13,7 @@ class Object_Impl (Base) {
part: const(char)*; part: const(char)*;
} }
values { values {
value: own(list<int>*) @const_set; value: own(list<int>*);
} }
} }
@property b { @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(!eolian_eo_file_parse(PACKAGE_DATA_DIR"/data/consts.eo"));
fail_if(!(class = eolian_class_get_by_name("Consts"))); 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 */ /* Method */
fail_if(!(fid = eolian_class_function_get_by_name(class, "foo", EOLIAN_METHOD))); fail_if(!(fid = eolian_class_function_get_by_name(class, "foo", EOLIAN_METHOD)));
fail_if(EINA_FALSE == eolian_function_object_is_const(fid)); fail_if(EINA_FALSE == eolian_function_object_is_const(fid));
@ -1013,6 +1007,7 @@ START_TEST(eolian_null)
const Eolian_Class *class; const Eolian_Class *class;
const Eolian_Function *func; const Eolian_Function *func;
const Eolian_Function_Parameter *param; const Eolian_Function_Parameter *param;
Eina_Iterator *iter;
eolian_init(); eolian_init();
@ -1022,26 +1017,35 @@ START_TEST(eolian_null)
fail_if(!(class = eolian_class_get_by_name("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(!(func = eolian_class_function_get_by_name(class, "foo", EOLIAN_METHOD)));
fail_if(!(iter = eolian_function_parameters_get(func)));
/* no qualifiers */ /* 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_nullable(param));
fail_if(eolian_parameter_is_optional(param)); fail_if(eolian_parameter_is_optional(param));
/* nullable */ /* 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_nullable(param));
fail_if(eolian_parameter_is_optional(param)); fail_if(eolian_parameter_is_optional(param));
/* optional */ /* 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_nullable(param));
fail_if(!eolian_parameter_is_optional(param)); fail_if(!eolian_parameter_is_optional(param));
/* both */ /* 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_nullable(param));
fail_if(!eolian_parameter_is_optional(param)); fail_if(!eolian_parameter_is_optional(param));
fail_if(eina_iterator_next(iter, (void**)&param));
eina_iterator_free(iter);
eolian_shutdown(); eolian_shutdown();
} }
END_TEST END_TEST