eolian: support @ref on returns

This adds basic support for @ref on return types.
This commit is contained in:
Daniel Kolesa 2016-06-07 14:59:36 +01:00
parent 96f6ca336d
commit 1637c21a76
14 changed files with 80 additions and 15 deletions

View File

@ -152,4 +152,15 @@ _get_add_star(Eolian_Function_Type ftype, Eolian_Parameter_Dir pdir)
return "";
}
return "";
}
}
Eina_Stringshare *
_get_rettype(const Eolian_Type *tp, Eina_Bool add_star)
{
Eina_Stringshare *rtp = eolian_type_c_type_get(tp);
if (!add_star || !rtp) return rtp;
char buf[1024];
snprintf(buf, sizeof(buf), "%s%s", rtp, (rtp[strlen(rtp) - 1] == '*') ? "*" : " *");
eina_stringshare_del(rtp);
return eina_stringshare_add(buf);
}

View File

@ -64,5 +64,6 @@ void _class_env_create(const Eolian_Class *class, const char *over_classname, _e
void _class_func_env_create(const Eolian_Class *class, const char *funcname, Eolian_Function_Type ftype EINA_UNUSED, _eolian_class_func_vars *env);
const char *_get_add_star(Eolian_Function_Type ftype, Eolian_Parameter_Dir pdir);
Eina_Stringshare *_get_rettype(const Eolian_Type *tp, Eina_Bool add_star);
#endif

View File

@ -71,6 +71,7 @@ eo_fundef_generate(const Eolian_Class *class, const Eolian_Function *func, Eolia
_class_func_env_create(class, eolian_function_name_get(func), ftype, &func_env);
rettypet = eolian_function_return_type_get(func, ftype);
Eina_Bool add_rstar = eolian_function_return_is_ref(func, ftype);
if (ftype == EOLIAN_PROP_GET && !rettypet)
{
itr = eolian_property_values_get(func, ftype);
@ -143,7 +144,7 @@ eo_fundef_generate(const Eolian_Class *class, const Eolian_Function *func, Eolia
eina_iterator_free(itr);
}
if (rettypet) rettype = eolian_type_c_type_get(rettypet);
if (rettypet) rettype = _get_rettype(rettypet, add_rstar);
eina_strbuf_replace_all(str_func, "@#rettype", rettype ? rettype : "void");
if (!rettype || rettype[strlen(rettype) - 1] != '*')
@ -317,6 +318,7 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
Eina_Strbuf *params_init = eina_strbuf_new(); /* init of variables to default */
rettypet = eolian_function_return_type_get(funcid, ftype);
Eina_Bool add_rstar = eolian_function_return_is_ref(funcid, ftype);
if (rettypet)
{
is_auto = EINA_FALSE; /* We block auto when the function has to return something */
@ -448,7 +450,7 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
eina_iterator_free(itr);
}
if (rettypet) rettype = eolian_type_c_type_get(rettypet);
if (rettypet) rettype = _get_rettype(rettypet, add_rstar);
if (need_implementation)
{

View File

@ -140,6 +140,7 @@ _prototype_generate(const Eolian_Function *foo, Eolian_Function_Type ftype, Eina
printf("Generation of function %s\n", func_name);
const Eolian_Type *rettypet = eolian_function_return_type_get(foo, ftype);
Eina_Bool add_rstar = eolian_function_return_is_ref(foo, ftype);
if (ftype == EOLIAN_PROP_GET && !rettypet)
{
Eina_Iterator *itr = eolian_property_values_get(foo, ftype);
@ -182,7 +183,7 @@ _prototype_generate(const Eolian_Function *foo, Eolian_Function_Type ftype, Eina
}
const char *rettype = NULL;
if (rettypet) rettype = eolian_type_c_type_get(rettypet);
if (rettypet) rettype = _get_rettype(rettypet, add_rstar);
eina_strbuf_append_printf(buffer,
"EOLIAN static %s\n%s(%sEo *obj, %s *pd%s%s)\n{\n%s\n}\n\n",

View File

@ -55,6 +55,7 @@ _eapi_decl_func_generate(const Eolian_Class *class, const Eolian_Function *funci
_class_func_env_create(class, funcname, ftype, &func_env);
rettypet = eolian_function_return_type_get(funcid, ftype);
Eina_Bool add_rstar = eolian_function_return_is_ref(funcid, ftype);
if (ftype == EOLIAN_PROP_GET)
{
if (!rettypet)
@ -149,7 +150,7 @@ _eapi_decl_func_generate(const Eolian_Class *class, const Eolian_Function *funci
if (!eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, "void");
if (flags) eina_strbuf_append_printf(flags, ")");
if (rettypet) rettype = eolian_type_c_type_get(rettypet);
if (rettypet) rettype = _get_rettype(rettypet, add_rstar);
eina_strbuf_replace_all(fbody, "@#params", eina_strbuf_string_get(fparam));
eina_strbuf_reset(fparam);
@ -197,7 +198,8 @@ _eapi_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eo
_class_func_env_create(class, eolian_function_name_get(funcid), ftype, &func_env);
rettypet = eolian_function_return_type_get(funcid, ftype);
if (rettypet) rettype = eolian_type_c_type_get(rettypet);
Eina_Bool add_rstar = eolian_function_return_is_ref(funcid, ftype);
if (rettypet) rettype = _get_rettype(rettypet, add_rstar);
if (rettype && !strcmp(rettype, "void")) ret_is_void = EINA_TRUE;
retname = "ret";
if (ftype == EOLIAN_PROP_GET)
@ -219,7 +221,7 @@ _eapi_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eo
if (func_env.legacy_func[0] == '\0') goto end;
if (!rettype && rettypet) rettype = eolian_type_c_type_get(rettypet);
if (!rettype && rettypet) rettype = _get_rettype(rettypet, add_rstar);
if (rettype && (!ret_is_void))
eina_strbuf_append(fbody, tmpl_eapi_body);

View File

@ -968,6 +968,20 @@ EAPI const Eolian_Documentation *eolian_function_return_documentation_get(const
*/
EAPI Eina_Bool eolian_function_return_is_warn_unused(const Eolian_Function *foo_id, Eolian_Function_Type ftype);
/*
* @brief Indicates if a function returns a ref (pointer).
*
* @param[in] function_id id of the function
* @param[in] ftype type of the function
* @return EINA_TRUE is ref return, EINA_FALSE otherwise.
*
* The type of the function is needed because a given function can represent a
* property, that can be set and get functions.
*
* @ingroup Eolian
*/
EAPI Eina_Bool eolian_function_return_is_ref(const Eolian_Function *foo_id, Eolian_Function_Type ftype);
/*
* @brief Indicates if a function object is const.
*

View File

@ -296,8 +296,21 @@ eolian_function_return_is_warn_unused(const Eolian_Function *fid,
EINA_SAFETY_ON_NULL_RETURN_VAL(fid, EINA_FALSE);
switch (ftype)
{
case EOLIAN_METHOD: case EOLIAN_PROP_GET: case EOLIAN_PROPERTY: return fid->get_return_warn_unused;
case EOLIAN_PROP_SET: return fid->set_return_warn_unused;
case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return fid->get_return_warn_unused;
default: return EINA_FALSE;
}
}
EAPI Eina_Bool
eolian_function_return_is_ref(const Eolian_Function *fid,
Eolian_Function_Type ftype)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(fid, EINA_FALSE);
switch (ftype)
{
case EOLIAN_PROP_SET: return fid->set_return_is_ref;
case EOLIAN_UNRESOLVED: case EOLIAN_METHOD: case EOLIAN_PROPERTY: case EOLIAN_PROP_GET: return fid->get_return_is_ref;
default: return EINA_FALSE;
}
}

View File

@ -972,7 +972,8 @@ typedef struct _Eo_Ret_Def
Eolian_Type *type;
Eolian_Documentation *doc;
Eolian_Expression *default_ret_val;
Eina_Bool warn_unused:1;
Eina_Bool warn_unused: 1;
Eina_Bool is_ref: 1;
} Eo_Ret_Def;
static void
@ -987,6 +988,7 @@ parse_return(Eo_Lexer *ls, Eo_Ret_Def *ret, Eina_Bool allow_void)
ret->doc = NULL;
ret->default_ret_val = NULL;
ret->warn_unused = EINA_FALSE;
ret->is_ref = EINA_FALSE;
if (ls->t.token == '(')
{
int line = ls->line_number, col = ls->column;
@ -996,11 +998,23 @@ parse_return(Eo_Lexer *ls, Eo_Ret_Def *ret, Eina_Bool allow_void)
ls->expr_mode = EINA_FALSE;
check_match(ls, ')', '(', line, col);
}
if (ls->t.kw == KW_at_warn_unused)
Eina_Bool has_warn_unused = EINA_FALSE, has_ref = EINA_FALSE;
for (;;) switch (ls->t.kw)
{
case KW_at_warn_unused:
CASE_LOCK(ls, warn_unused, "warn_unused qualifier");
ret->warn_unused = EINA_TRUE;
eo_lexer_get(ls);
break;
case KW_at_ref:
CASE_LOCK(ls, ref, "ref qualifier");
ret->is_ref = EINA_TRUE;
eo_lexer_get(ls);
break;
default:
goto end;
}
end:
check_next(ls, ';');
FILL_DOC(ls, ret, doc);
}
@ -1175,6 +1189,7 @@ parse_accessor(Eo_Lexer *ls, Eolian_Function *prop)
prop->get_return_doc = ret.doc;
prop->get_ret_val = ret.default_ret_val;
prop->get_return_warn_unused = ret.warn_unused;
prop->get_return_is_ref = ret.is_ref;
}
else
{
@ -1182,6 +1197,7 @@ parse_accessor(Eo_Lexer *ls, Eolian_Function *prop)
prop->set_return_doc = ret.doc;
prop->set_ret_val = ret.default_ret_val;
prop->set_return_warn_unused = ret.warn_unused;
prop->set_return_is_ref = ret.is_ref;
}
break;
case KW_legacy:
@ -1388,6 +1404,7 @@ body:
meth->get_return_doc = ret.doc;
meth->get_ret_val = ret.default_ret_val;
meth->get_return_warn_unused = ret.warn_unused;
meth->get_return_is_ref = ret.is_ref;
break;
case KW_legacy:
CASE_LOCK(ls, legacy, "legacy name")

View File

@ -140,6 +140,8 @@ struct _Eolian_Function
Eina_Bool set_empty :1;
Eina_Bool get_return_warn_unused :1; /* also used for methods */
Eina_Bool set_return_warn_unused :1;
Eina_Bool get_return_is_ref: 1;
Eina_Bool set_return_is_ref: 1;
Eina_Bool get_only_legacy: 1;
Eina_Bool set_only_legacy: 1;
Eina_Bool is_class :1;

View File

@ -36,7 +36,7 @@ class Class_Simple {
params {
x: int;
}
return: int;
return: int @ref;
}
}
}

View File

@ -21,9 +21,9 @@ static char * __eolian_class_simple_foo(Eo *obj, Evas_Simple_Data *pd, int a, ch
EOAPI EO_FUNC_BODYV(evas_obj_simple_foo, char *, NULL, EO_FUNC_CALL(a, b, c, d), int a, char *b, double *c, int *d);
int _class_simple_bar(Eo *obj, Evas_Simple_Data *pd, int x);
int * _class_simple_bar(Eo *obj, Evas_Simple_Data *pd, int x);
EOAPI EO_FUNC_BODYV(evas_obj_simple_bar, int, 0, EO_FUNC_CALL(x), int x);
EOAPI EO_FUNC_BODYV(evas_obj_simple_bar, int *, 0, EO_FUNC_CALL(x), int x);
static const Eo_Op_Description _class_simple_op_desc[] = {
EO_OP_FUNC(evas_obj_simple_a_set, _class_simple_a_set),

View File

@ -64,7 +64,7 @@ EOAPI void evas_obj_simple_b_set(Eo *obj);
EOAPI char *evas_obj_simple_foo(Eo *obj, int a, char *b, double *c, int *d);
#endif
EOAPI int evas_obj_simple_bar(Eo *obj, int x);
EOAPI int *evas_obj_simple_bar(Eo *obj, int x);
#endif

View File

@ -53,6 +53,6 @@ EAPI void evas_object_simple_b_set(Class_Simple *obj);
* @ingroup Class_Simple
*/
EAPI char *evas_object_simple_foo(Class_Simple *obj, int a, char *b, double *c, int *d);
EAPI int evas_object_simple_bar(Class_Simple *obj, int x);
EAPI int *evas_object_simple_bar(Class_Simple *obj, int x);
#endif

View File

@ -606,6 +606,7 @@ START_TEST(eolian_simple_parsing)
/* Method */
fail_if(!(fid = eolian_class_function_get_by_name(class, "foo", EOLIAN_METHOD)));
fail_if(!eolian_function_is_beta(fid));
fail_if(eolian_function_return_is_ref(fid, EOLIAN_METHOD));
/* Function return */
tp = eolian_function_return_type_get(fid, EOLIAN_METHOD);
fail_if(!tp);
@ -651,6 +652,7 @@ START_TEST(eolian_simple_parsing)
fail_if(!eolian_function_is_legacy_only(fid, EOLIAN_METHOD));
fail_if(!eolian_function_is_c_only(fid));
fail_if(eolian_function_is_beta(fid));
fail_if(!eolian_function_return_is_ref(fid, EOLIAN_METHOD));
eolian_shutdown();
}