summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@samsung.com>2019-08-30 16:08:31 +0200
committerDaniel Kolesa <d.kolesa@samsung.com>2019-08-30 16:22:20 +0200
commitfbcad90fece71a55391056fdc41d59edd32a1dfd (patch)
treee486bf313a2b5bd74b07cdaad6218c3631d5a18e
parentbbd213bcfb4e8dc3a809b8346cdfba2144f963ed (diff)
downloadefl-fbcad90fece71a55391056fdc41d59edd32a1dfd.tar.gz
eolian: add parsing for @move and @by_ref
The @by_ref qualifier is now allowed on parameters, returns and struct fields in the usual qualifier section. It will mean that this type is passed around by reference, and will only be allowed on types that are not already pointer-like. The @move qualifier will replace @owned as one with a clearer meaning. It means "transfer of ownership". It has the same semantics as the current @owned, i.e. on return values it transfers ownership of the value to the caller, on parameters it transfers ownership to the callee (the inverse is the default when not specified). On struct fields, it means the field will transfer together with the struct that contains it.
-rw-r--r--src/lib/eolian/eo_lexer.h6
-rw-r--r--src/lib/eolian/eo_parser.c54
-rw-r--r--src/lib/eolian/eolian_database.h12
3 files changed, 57 insertions, 15 deletions
diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h
index 836f06152b..96e385952f 100644
--- a/src/lib/eolian/eo_lexer.h
+++ b/src/lib/eolian/eo_lexer.h
@@ -35,9 +35,9 @@ enum Tokens
\
KWAT(auto), KWAT(beta), KWAT(by_ref), KWAT(c_name), KWAT(const), \
KWAT(empty), KWAT(extern), KWAT(free), KWAT(hot), KWAT(in), KWAT(inout), \
- KWAT(no_unused), KWAT(nullable), KWAT(optional), KWAT(out), KWAT(owned), \
- KWAT(private), KWAT(property), KWAT(protected), KWAT(restart), \
- KWAT(pure_virtual), KWAT(static), KWAT(transfer), \
+ KWAT(move), KWAT(no_unused), KWAT(nullable), KWAT(optional), KWAT(out), \
+ KWAT(owned), KWAT(private), KWAT(property), KWAT(protected), KWAT(restart), \
+ KWAT(pure_virtual), KWAT(static), \
\
KWH(version), \
\
diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c
index b24a35152a..e69989aa8c 100644
--- a/src/lib/eolian/eo_parser.c
+++ b/src/lib/eolian/eo_parser.c
@@ -517,8 +517,24 @@ parse_struct(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
FILL_BASE(fdef->base, ls, fline, fcol, STRUCT_FIELD);
fdef->type = eo_lexer_type_release(ls, tp);
fdef->base.name = eina_stringshare_ref(fname);
- if ((fdef->type->owned = (ls->t.kw == KW_at_owned)))
- eo_lexer_get(ls);
+ Eina_Bool has_owned = EINA_FALSE, has_by_ref = EINA_FALSE;
+ for (;;) switch (ls->t.kw)
+ {
+ case KW_at_by_ref:
+ CASE_LOCK(ls, by_ref, "by_ref qualifier");
+ fdef->by_ref = EINA_TRUE;
+ eo_lexer_get(ls);
+ break;
+ case KW_at_owned:
+ case KW_at_move:
+ CASE_LOCK(ls, owned, "owned qualifier");
+ fdef->type->owned = fdef->move = EINA_TRUE;
+ eo_lexer_get(ls);
+ break;
+ default:
+ goto qual_end;
+ }
+qual_end:
check_next(ls, ';');
FILL_DOC(ls, fdef, doc);
}
@@ -758,14 +774,14 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ptr)
def->base_type = eo_lexer_type_release(ls, parse_type(ls, EINA_TRUE));
/* view-only types are not allowed to own the contents */
if (tpid == KW_array || tpid == KW_hash || tpid == KW_list || tpid == KW_future)
- if ((def->base_type->owned = (ls->t.kw == KW_at_owned)))
+ if ((def->base_type->owned = (ls->t.kw == KW_at_owned || ls->t.kw == KW_at_move)))
eo_lexer_get(ls);
if (tpid == KW_hash)
{
check_next(ls, ',');
def->base_type->next_type =
eo_lexer_type_release(ls, parse_type(ls, EINA_TRUE));
- if ((def->base_type->next_type->owned = (ls->t.kw == KW_at_owned)))
+ if ((def->base_type->next_type->owned = (ls->t.kw == KW_at_owned || ls->t.kw == KW_at_move)))
eo_lexer_get(ls);
}
check_match(ls, '>', '<', bline, bcol);
@@ -1006,6 +1022,7 @@ typedef struct _Eo_Ret_Def
Eolian_Expression *default_ret_val;
Eina_Bool no_unused: 1;
Eina_Bool owned: 1;
+ Eina_Bool by_ref: 1;
} Eo_Ret_Def;
static void
@@ -1022,6 +1039,7 @@ parse_return(Eo_Lexer *ls, Eo_Ret_Def *ret, Eina_Bool allow_void,
ret->default_ret_val = NULL;
ret->no_unused = EINA_FALSE;
ret->owned = EINA_FALSE;
+ ret->by_ref = EINA_FALSE;
if (allow_def && (ls->t.token == '('))
{
int line = ls->line_number, col = ls->column;
@@ -1031,7 +1049,8 @@ parse_return(Eo_Lexer *ls, Eo_Ret_Def *ret, Eina_Bool allow_void,
ls->expr_mode = EINA_FALSE;
check_match(ls, ')', '(', line, col);
}
- Eina_Bool has_no_unused = EINA_FALSE, has_owned = EINA_FALSE;
+ Eina_Bool has_no_unused = EINA_FALSE, has_owned = EINA_FALSE,
+ has_by_ref = EINA_FALSE;
if (!is_funcptr) for (;;) switch (ls->t.kw)
{
case KW_at_no_unused:
@@ -1040,10 +1059,16 @@ parse_return(Eo_Lexer *ls, Eo_Ret_Def *ret, Eina_Bool allow_void,
eo_lexer_get(ls);
break;
case KW_at_owned:
+ case KW_at_move:
CASE_LOCK(ls, owned, "owned qualifier");
ret->owned = EINA_TRUE;
eo_lexer_get(ls);
break;
+ case KW_at_by_ref:
+ CASE_LOCK(ls, by_ref, "by_ref qualifier");
+ ret->by_ref = EINA_TRUE;
+ eo_lexer_get(ls);
+ break;
default:
goto end;
}
@@ -1057,7 +1082,8 @@ parse_param(Eo_Lexer *ls, Eina_List **params, Eina_Bool allow_inout,
Eina_Bool is_vals)
{
Eina_Bool has_optional = EINA_FALSE,
- has_owned = EINA_FALSE;
+ has_owned = EINA_FALSE,
+ has_by_ref = EINA_FALSE;
Eolian_Function_Parameter *par = calloc(1, sizeof(Eolian_Function_Parameter));
par->param_dir = EOLIAN_IN_PARAM;
FILL_BASE(par->base, ls, ls->line_number, ls->column, FUNCTION_PARAMETER);
@@ -1106,7 +1132,12 @@ parse_param(Eo_Lexer *ls, Eina_List **params, Eina_Bool allow_inout,
break;
case KW_at_owned:
CASE_LOCK(ls, owned, "owned qualifier");
- par->type->owned = EINA_TRUE;
+ par->type->owned = par->move = EINA_TRUE;
+ eo_lexer_get(ls);
+ break;
+ case KW_at_by_ref:
+ CASE_LOCK(ls, by_ref, "by_ref qualifier");
+ par->by_ref = EINA_TRUE;
eo_lexer_get(ls);
break;
default:
@@ -1224,7 +1255,8 @@ parse_accessor:
prop->get_return_doc = ret.doc;
prop->get_ret_val = ret.default_ret_val;
prop->get_return_no_unused = ret.no_unused;
- prop->get_ret_type->owned = ret.owned;
+ prop->get_return_by_ref = ret.by_ref;
+ prop->get_return_move = prop->get_ret_type->owned = ret.owned;
}
else
{
@@ -1232,7 +1264,8 @@ parse_accessor:
prop->set_return_doc = ret.doc;
prop->set_ret_val = ret.default_ret_val;
prop->set_return_no_unused = ret.no_unused;
- prop->set_ret_type->owned = ret.owned;
+ prop->set_return_by_ref = ret.by_ref;
+ prop->set_return_move = prop->set_ret_type->owned = ret.owned;
}
break;
case KW_keys:
@@ -1543,7 +1576,8 @@ body:
meth->get_return_doc = ret.doc;
meth->get_ret_val = ret.default_ret_val;
meth->get_return_no_unused = ret.no_unused;
- meth->get_ret_type->owned = ret.owned;
+ meth->get_return_by_ref = ret.by_ref;
+ meth->get_return_move = meth->get_ret_type->owned = ret.owned;
break;
case KW_params:
CASE_LOCK(ls, params, "params definition")
diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h
index 1e26e24a38..e66543f6bd 100644
--- a/src/lib/eolian/eolian_database.h
+++ b/src/lib/eolian/eolian_database.h
@@ -227,12 +227,16 @@ struct _Eolian_Function
Eolian_Implement *impl;
Eolian_Documentation *get_return_doc;
Eolian_Documentation *set_return_doc;
+ Eina_List *ctor_of;
+ Eolian_Class *klass;
Eina_Bool obj_is_const :1; /* True if the object has to be const. Useful for a few methods. */
Eina_Bool get_return_no_unused :1; /* also used for methods */
Eina_Bool set_return_no_unused :1;
+ Eina_Bool get_return_move :1;
+ Eina_Bool set_return_move :1;
+ Eina_Bool get_return_by_ref :1;
+ Eina_Bool set_return_by_ref :1;
Eina_Bool is_static :1;
- Eina_List *ctor_of;
- Eolian_Class *klass;
};
struct _Eolian_Part
@@ -255,6 +259,8 @@ struct _Eolian_Function_Parameter
Eolian_Documentation *doc;
Eolian_Parameter_Dir param_dir;
Eina_Bool optional :1; /* True if this argument is optional */
+ Eina_Bool by_ref :1;
+ Eina_Bool move :1;
};
struct _Eolian_Type
@@ -342,6 +348,8 @@ struct _Eolian_Struct_Type_Field
Eolian_Object base;
Eolian_Type *type;
Eolian_Documentation *doc;
+ Eina_Bool move :1;
+ Eina_Bool by_ref :1;
};
struct _Eolian_Enum_Type_Field