forked from enlightenment/efl
eolian: fine-grained is_auto/is_empty for implements
This commit is contained in:
parent
289287f497
commit
baaa482ebf
|
@ -119,8 +119,8 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
|
|||
Eolian_Function_Type ftype, Eina_Strbuf *buf,
|
||||
const Eolian_Implement *impl, Eina_Strbuf *lbuf)
|
||||
{
|
||||
Eina_Bool is_empty = eolian_implement_is_empty(impl);
|
||||
Eina_Bool is_auto = eolian_implement_is_auto(impl);
|
||||
Eina_Bool is_empty = eolian_implement_is_empty(impl, ftype);
|
||||
Eina_Bool is_auto = eolian_implement_is_auto(impl, ftype);
|
||||
|
||||
if ((ftype != EOLIAN_PROP_GET) && (ftype != EOLIAN_PROP_SET))
|
||||
ftype = eolian_function_type_get(fid);
|
||||
|
|
|
@ -273,9 +273,9 @@ ffi.cdef [[
|
|||
const char *eolian_implement_full_name_get(const Eolian_Implement *impl);
|
||||
const Eolian_Class *eolian_implement_class_get(const Eolian_Implement *impl);
|
||||
const Eolian_Function *eolian_implement_function_get(const Eolian_Implement *impl, Eolian_Function_Type *func_type);
|
||||
Eina_Bool eolian_implement_is_auto(const Eolian_Implement *impl);
|
||||
Eina_Bool eolian_implement_is_empty(const Eolian_Implement *impl);
|
||||
Eina_Bool eolian_implement_is_virtual(const Eolian_Implement *impl);
|
||||
Eina_Bool eolian_implement_is_auto(const Eolian_Implement *impl, Eolian_Function_Type ftype);
|
||||
Eina_Bool eolian_implement_is_empty(const Eolian_Implement *impl, Eolian_Function_Type ftype);
|
||||
Eina_Bool eolian_implement_is_virtual(const Eolian_Implement *impl, Eolian_Function_Type ftype);
|
||||
Eina_Bool eolian_implement_is_prop_get(const Eolian_Implement *impl);
|
||||
Eina_Bool eolian_implement_is_prop_set(const Eolian_Implement *impl);
|
||||
Eina_Iterator *eolian_class_implements_get(const Eolian_Class *klass);
|
||||
|
@ -919,16 +919,16 @@ ffi.metatype("Eolian_Implement", {
|
|||
return v, tp[0]
|
||||
end,
|
||||
|
||||
is_auto = function(self)
|
||||
return eolian.eolian_implement_is_auto(self) ~= 0
|
||||
is_auto = function(self, ftype)
|
||||
return eolian.eolian_implement_is_auto(self, ftype) ~= 0
|
||||
end,
|
||||
|
||||
is_empty = function(self)
|
||||
return eolian.eolian_implement_is_empty(self) ~= 0
|
||||
is_empty = function(self, ftype)
|
||||
return eolian.eolian_implement_is_empty(self, ftype) ~= 0
|
||||
end,
|
||||
|
||||
is_virtual = function(self)
|
||||
return eolian.eolian_implement_is_virtual(self) ~= 0
|
||||
is_virtual = function(self, ftype)
|
||||
return eolian.eolian_implement_is_virtual(self, ftype) ~= 0
|
||||
end,
|
||||
|
||||
is_prop_get = function(self)
|
||||
|
|
|
@ -1056,31 +1056,34 @@ EAPI const Eolian_Function *eolian_implement_function_get(const Eolian_Implement
|
|||
* @brief Get whether an implement is tagged with @auto.
|
||||
*
|
||||
* @param[in] impl the handle of the implement
|
||||
* @param[in] f_type The function type, for property get/set distinction.
|
||||
* @return EINA_TRUE when it is, EINA_FALSE when it's not.
|
||||
*
|
||||
* @ingroup Eolian
|
||||
*/
|
||||
EAPI Eina_Bool eolian_implement_is_auto(const Eolian_Implement *impl);
|
||||
EAPI Eina_Bool eolian_implement_is_auto(const Eolian_Implement *impl, Eolian_Function_Type f_type);
|
||||
|
||||
/*
|
||||
* @brief Get whether an implement is tagged with @empty.
|
||||
*
|
||||
* @param[in] impl the handle of the implement
|
||||
* @param[in] f_type The function type, for property get/set distinction.
|
||||
* @return EINA_TRUE when it is, EINA_FALSE when it's not.
|
||||
*
|
||||
* @ingroup Eolian
|
||||
*/
|
||||
EAPI Eina_Bool eolian_implement_is_empty(const Eolian_Implement *impl);
|
||||
EAPI Eina_Bool eolian_implement_is_empty(const Eolian_Implement *impl, Eolian_Function_Type f_type);
|
||||
|
||||
/*
|
||||
* @brief Get whether an implement is tagged with @virtual.
|
||||
*
|
||||
* @param[in] impl the handle of the implement
|
||||
* @param[in] f_type The function type, for property get/set distinction.
|
||||
* @return EINA_TRUE when it is, EINA_FALSE when it's not.
|
||||
*
|
||||
* @ingroup Eolian
|
||||
*/
|
||||
EAPI Eina_Bool eolian_implement_is_virtual(const Eolian_Implement *impl);
|
||||
EAPI Eina_Bool eolian_implement_is_virtual(const Eolian_Implement *impl, Eolian_Function_Type f_type);
|
||||
|
||||
/*
|
||||
* @brief Get whether an implement references a property getter.
|
||||
|
|
|
@ -66,6 +66,8 @@ _get_impl_func(Eolian_Class *cl, Eolian_Implement *impl,
|
|||
|
||||
Eolian_Function_Type aftype = eolian_function_type_get(fid);
|
||||
|
||||
Eina_Bool auto_empty = (impl->get_auto || impl->get_empty);
|
||||
|
||||
/* match implement type against function type */
|
||||
if (ftype == EOLIAN_PROPERTY)
|
||||
{
|
||||
|
@ -76,6 +78,7 @@ _get_impl_func(Eolian_Class *cl, Eolian_Implement *impl,
|
|||
fprintf(stderr, "function '%s' is not a complete property", fnname);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
auto_empty = auto_empty && (impl->set_auto || impl->set_empty);
|
||||
}
|
||||
else if (ftype == EOLIAN_PROP_SET)
|
||||
{
|
||||
|
@ -86,6 +89,7 @@ _get_impl_func(Eolian_Class *cl, Eolian_Implement *impl,
|
|||
fprintf(stderr, "function '%s' doesn't have a setter\n", fnname);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
auto_empty = (impl->set_auto || impl->set_empty);
|
||||
}
|
||||
else if (ftype == EOLIAN_PROP_GET)
|
||||
{
|
||||
|
@ -104,7 +108,7 @@ _get_impl_func(Eolian_Class *cl, Eolian_Implement *impl,
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if ((fid->klass == cl) && !impl->is_auto && !impl->is_empty)
|
||||
if ((fid->klass == cl) && !auto_empty)
|
||||
{
|
||||
/* only allow explicit implements from other classes, besides auto and
|
||||
* empty... also prevents pure virtuals from being implemented
|
||||
|
@ -137,42 +141,18 @@ _db_fill_implement(Eolian_Class *cl, Eolian_Implement *impl)
|
|||
if (!_get_impl_func(cl, impl, ftype, &foo_id))
|
||||
return EINA_FALSE;
|
||||
|
||||
if (impl->is_auto)
|
||||
foo_id->get_auto = impl->get_auto;
|
||||
foo_id->set_auto = impl->set_auto;
|
||||
foo_id->get_empty = impl->get_empty;
|
||||
foo_id->set_empty = impl->set_empty;
|
||||
if (foo_id->get_auto || foo_id->get_empty)
|
||||
{
|
||||
if (ftype == EOLIAN_PROP_GET)
|
||||
{
|
||||
foo_id->get_impl = impl;
|
||||
foo_id->get_auto = EINA_TRUE;
|
||||
}
|
||||
else if (ftype == EOLIAN_PROP_SET)
|
||||
{
|
||||
foo_id->set_impl = impl;
|
||||
foo_id->set_auto = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
foo_id->get_impl = foo_id->set_impl = impl;
|
||||
foo_id->get_auto = foo_id->set_auto = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
else if (impl->is_empty)
|
||||
{
|
||||
if (ftype == EOLIAN_PROP_GET)
|
||||
{
|
||||
foo_id->get_impl = impl;
|
||||
foo_id->get_empty = EINA_TRUE;
|
||||
}
|
||||
else if (ftype == EOLIAN_PROP_SET)
|
||||
{
|
||||
foo_id->set_impl = impl;
|
||||
foo_id->set_empty = EINA_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
foo_id->get_impl = foo_id->set_impl = impl;
|
||||
foo_id->get_empty = foo_id->set_empty = EINA_TRUE;
|
||||
}
|
||||
if (ftype == EOLIAN_UNRESOLVED)
|
||||
foo_id->set_impl = impl;
|
||||
foo_id->get_impl = impl;
|
||||
}
|
||||
if (foo_id->set_auto || foo_id->set_empty)
|
||||
foo_id->set_impl = impl;
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
@ -205,10 +185,9 @@ _db_build_implement(Eolian_Class *cl, Eolian_Function *foo_id)
|
|||
|
||||
if (foo_id->type == EOLIAN_PROPERTY)
|
||||
{
|
||||
/* FIXME fugly hack, ideally rework the whole implements api altogether */
|
||||
if (foo_id->get_virtual_pure && !foo_id->get_impl)
|
||||
{
|
||||
impl->is_virtual = EINA_TRUE;
|
||||
impl->get_virtual = EINA_TRUE;
|
||||
impl->is_prop_get = EINA_TRUE;
|
||||
foo_id->get_impl = impl;
|
||||
cl->implements = eina_list_append(cl->implements, impl);
|
||||
|
@ -218,7 +197,7 @@ _db_build_implement(Eolian_Class *cl, Eolian_Function *foo_id)
|
|||
}
|
||||
else if (foo_id->set_virtual_pure && !foo_id->set_impl)
|
||||
{
|
||||
impl->is_virtual = EINA_TRUE;
|
||||
impl->set_virtual = EINA_TRUE;
|
||||
impl->is_prop_set = EINA_TRUE;
|
||||
foo_id->set_impl = impl;
|
||||
cl->implements = eina_list_append(cl->implements, impl);
|
||||
|
@ -229,7 +208,7 @@ _db_build_implement(Eolian_Class *cl, Eolian_Function *foo_id)
|
|||
if (foo_id->get_impl)
|
||||
{
|
||||
impl->is_prop_set = EINA_TRUE;
|
||||
impl->is_virtual = foo_id->set_virtual_pure;
|
||||
impl->set_virtual = foo_id->set_virtual_pure;
|
||||
foo_id->set_impl = impl;
|
||||
}
|
||||
else if (foo_id->set_impl)
|
||||
|
@ -243,18 +222,18 @@ _db_build_implement(Eolian_Class *cl, Eolian_Function *foo_id)
|
|||
else if (foo_id->type == EOLIAN_PROP_SET)
|
||||
{
|
||||
impl->is_prop_set = EINA_TRUE;
|
||||
impl->is_virtual = foo_id->get_virtual_pure;
|
||||
impl->get_virtual = foo_id->get_virtual_pure;
|
||||
foo_id->set_impl = impl;
|
||||
}
|
||||
else if (foo_id->type == EOLIAN_PROP_GET)
|
||||
{
|
||||
impl->is_prop_get = EINA_TRUE;
|
||||
impl->is_virtual = foo_id->set_virtual_pure;
|
||||
impl->get_virtual = foo_id->set_virtual_pure;
|
||||
foo_id->get_impl = impl;
|
||||
}
|
||||
else
|
||||
{
|
||||
impl->is_virtual = foo_id->get_virtual_pure;
|
||||
impl->get_virtual = foo_id->get_virtual_pure;
|
||||
foo_id->get_impl = foo_id->set_impl = impl;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,24 +44,39 @@ eolian_implement_function_get(const Eolian_Implement *impl,
|
|||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eolian_implement_is_auto(const Eolian_Implement *impl)
|
||||
eolian_implement_is_auto(const Eolian_Implement *impl, Eolian_Function_Type ftype)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(impl, EINA_FALSE);
|
||||
return impl->is_auto;
|
||||
switch (ftype)
|
||||
{
|
||||
case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return impl->get_auto; break;
|
||||
case EOLIAN_PROP_SET: return impl->set_auto; break;
|
||||
default: return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eolian_implement_is_empty(const Eolian_Implement *impl)
|
||||
eolian_implement_is_empty(const Eolian_Implement *impl, Eolian_Function_Type ftype)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(impl, EINA_FALSE);
|
||||
return impl->is_empty;
|
||||
switch (ftype)
|
||||
{
|
||||
case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return impl->get_empty; break;
|
||||
case EOLIAN_PROP_SET: return impl->set_empty; break;
|
||||
default: return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eolian_implement_is_virtual(const Eolian_Implement *impl)
|
||||
eolian_implement_is_virtual(const Eolian_Implement *impl, Eolian_Function_Type ftype)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(impl, EINA_FALSE);
|
||||
return impl->is_virtual;
|
||||
switch (ftype)
|
||||
{
|
||||
case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return impl->get_virtual; break;
|
||||
case EOLIAN_PROP_SET: return impl->set_virtual; break;
|
||||
default: return EINA_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
|
|
|
@ -1520,14 +1520,15 @@ parse_implement(Eo_Lexer *ls, Eina_Bool iface)
|
|||
impl = calloc(1, sizeof(Eolian_Implement));
|
||||
FILL_BASE(impl->base, ls, iline, icol);
|
||||
ls->tmp.kls->implements = eina_list_append(ls->tmp.kls->implements, impl);
|
||||
Eina_Bool glob_auto = EINA_FALSE, glob_empty = EINA_FALSE;
|
||||
switch (ls->t.kw)
|
||||
{
|
||||
case KW_at_auto:
|
||||
impl->is_auto = EINA_TRUE;
|
||||
glob_auto = EINA_TRUE;
|
||||
eo_lexer_get(ls);
|
||||
break;
|
||||
case KW_at_empty:
|
||||
impl->is_empty = EINA_TRUE;
|
||||
glob_empty = EINA_TRUE;
|
||||
eo_lexer_get(ls);
|
||||
break;
|
||||
default:
|
||||
|
@ -1535,9 +1536,7 @@ parse_implement(Eo_Lexer *ls, Eina_Bool iface)
|
|||
}
|
||||
if (ls->t.token == '.')
|
||||
{
|
||||
if (!impl->is_auto && !impl->is_empty)
|
||||
eo_lexer_syntax_error(ls, "class name expected");
|
||||
check_next(ls, '.');
|
||||
eo_lexer_get(ls);
|
||||
if (ls->t.token != TOK_VALUE)
|
||||
eo_lexer_syntax_error(ls, "name expected");
|
||||
impl->full_name = eina_stringshare_printf("%s.%s",
|
||||
|
@ -1582,12 +1581,36 @@ propbeg:
|
|||
CASE_LOCK(ls, get, "get specifier");
|
||||
eo_lexer_get(ls);
|
||||
impl->is_prop_get = EINA_TRUE;
|
||||
impl->get_auto = glob_auto;
|
||||
impl->get_empty = glob_empty;
|
||||
if (ls->t.kw == KW_at_auto)
|
||||
{
|
||||
impl->get_auto = EINA_TRUE;
|
||||
eo_lexer_get(ls);
|
||||
}
|
||||
else if (ls->t.kw == KW_at_empty)
|
||||
{
|
||||
impl->get_empty = EINA_TRUE;
|
||||
eo_lexer_get(ls);
|
||||
}
|
||||
check_next(ls, ';');
|
||||
break;
|
||||
case KW_set:
|
||||
CASE_LOCK(ls, set, "set specifier");
|
||||
eo_lexer_get(ls);
|
||||
impl->is_prop_set = EINA_TRUE;
|
||||
impl->set_auto = glob_auto;
|
||||
impl->set_empty = glob_empty;
|
||||
if (ls->t.kw == KW_at_auto)
|
||||
{
|
||||
impl->set_auto = EINA_TRUE;
|
||||
eo_lexer_get(ls);
|
||||
}
|
||||
else if (ls->t.kw == KW_at_empty)
|
||||
{
|
||||
impl->set_empty = EINA_TRUE;
|
||||
eo_lexer_get(ls);
|
||||
}
|
||||
check_next(ls, ';');
|
||||
break;
|
||||
default:
|
||||
|
@ -1599,7 +1622,13 @@ propend:
|
|||
check_next(ls, '}');
|
||||
}
|
||||
else
|
||||
check_next(ls, ';');
|
||||
{
|
||||
if (glob_auto)
|
||||
impl->get_auto = impl->set_auto = EINA_TRUE;
|
||||
if (glob_empty)
|
||||
impl->get_empty = impl->set_empty = EINA_TRUE;
|
||||
check_next(ls, ';');
|
||||
}
|
||||
end:
|
||||
if (buf)
|
||||
{
|
||||
|
|
|
@ -201,11 +201,14 @@ struct _Eolian_Implement
|
|||
const Eolian_Class *klass;
|
||||
const Eolian_Function *foo_id;
|
||||
Eina_Stringshare *full_name;
|
||||
Eina_Bool is_virtual :1;
|
||||
Eina_Bool is_prop_get :1;
|
||||
Eina_Bool is_prop_set :1;
|
||||
Eina_Bool is_auto: 1;
|
||||
Eina_Bool is_empty: 1;
|
||||
Eina_Bool get_virtual :1;
|
||||
Eina_Bool set_virtual :1;
|
||||
Eina_Bool get_auto: 1;
|
||||
Eina_Bool set_auto: 1;
|
||||
Eina_Bool get_empty: 1;
|
||||
Eina_Bool set_empty: 1;
|
||||
};
|
||||
|
||||
struct _Eolian_Constructor
|
||||
|
|
|
@ -202,18 +202,18 @@ START_TEST(eolian_override)
|
|||
fail_if(!(iter = eolian_class_implements_get(class)));
|
||||
|
||||
fail_if(!(eina_iterator_next(iter, (void**)&impl)));
|
||||
fail_if(eolian_implement_is_auto(impl));
|
||||
fail_if(eolian_implement_is_empty(impl));
|
||||
fail_if(eolian_implement_is_virtual(impl));
|
||||
fail_if(eolian_implement_is_auto(impl, EOLIAN_METHOD));
|
||||
fail_if(eolian_implement_is_empty(impl, EOLIAN_METHOD));
|
||||
fail_if(eolian_implement_is_virtual(impl, EOLIAN_METHOD));
|
||||
fail_if(!(impl_class = eolian_implement_class_get(impl)));
|
||||
fail_if(!(impl_func = eolian_implement_function_get(impl, NULL)));
|
||||
fail_if(impl_class != base);
|
||||
fail_if(strcmp(eolian_function_name_get(impl_func), "constructor"));
|
||||
|
||||
fail_if(!(eina_iterator_next(iter, (void**)&impl)));
|
||||
fail_if(!eolian_implement_is_auto(impl));
|
||||
fail_if(eolian_implement_is_empty(impl));
|
||||
fail_if(eolian_implement_is_virtual(impl));
|
||||
fail_if(!eolian_implement_is_auto(impl, EOLIAN_PROP_SET));
|
||||
fail_if(eolian_implement_is_empty(impl, EOLIAN_PROP_SET));
|
||||
fail_if(eolian_implement_is_virtual(impl, EOLIAN_PROP_SET));
|
||||
fail_if(!(impl_class = eolian_implement_class_get(impl)));
|
||||
fail_if(!(impl_func = eolian_implement_function_get(impl, NULL)));
|
||||
fail_if(impl_class != class);
|
||||
|
@ -226,9 +226,9 @@ START_TEST(eolian_override)
|
|||
fail_if(eolian_function_is_virtual_pure(impl_func, EOLIAN_PROP_GET));
|
||||
|
||||
fail_if(!(eina_iterator_next(iter, (void**)&impl)));
|
||||
fail_if(eolian_implement_is_auto(impl));
|
||||
fail_if(!eolian_implement_is_empty(impl));
|
||||
fail_if(eolian_implement_is_virtual(impl));
|
||||
fail_if(eolian_implement_is_auto(impl, EOLIAN_METHOD));
|
||||
fail_if(!eolian_implement_is_empty(impl, EOLIAN_METHOD));
|
||||
fail_if(eolian_implement_is_virtual(impl, EOLIAN_METHOD));
|
||||
fail_if(!(impl_class = eolian_implement_class_get(impl)));
|
||||
fail_if(!(impl_func = eolian_implement_function_get(impl, NULL)));
|
||||
fail_if(impl_class != class);
|
||||
|
|
Loading…
Reference in New Issue