eolian: partially clean up implement filling logic

This commit is contained in:
Daniel Kolesa 2017-01-02 14:35:17 +01:00
parent 692d445dcf
commit 0b2c070b06
2 changed files with 47 additions and 57 deletions

View File

@ -7,44 +7,52 @@
static Eina_Bool static Eina_Bool
_func_error(Eolian_Class *cl, Eolian_Implement *impl) _func_error(Eolian_Class *cl, Eolian_Implement *impl)
{ {
fprintf(stderr, "eolian:%s:%d:%d: '%s%s' not known in class '%s'\n", fprintf(stderr, "eolian:%s:%d:%d: '%s' not known in class '%s'\n",
impl->base.file, impl->base.line, impl->base.column, impl->full_name, impl->base.file, impl->base.line, impl->base.column, impl->full_name,
(impl->is_prop_get ? ".get" : (impl->is_prop_set ? ".set" : "")),
eolian_class_name_get(cl)); eolian_class_name_get(cl));
return EINA_FALSE; return EINA_FALSE;
} }
static Eina_Bool static Eina_Bool
_get_impl_func(Eolian_Class *cl, Eolian_Implement *impl, _get_impl_func(Eolian_Class *cl EINA_UNUSED, Eolian_Implement *impl,
Eolian_Function_Type ftype, Eolian_Function **foo_id) Eolian_Function_Type ftype, Eolian_Function **foo_id)
{ {
size_t cllen = strlen(cl->full_name);
size_t imlen = strlen(impl->full_name); size_t imlen = strlen(impl->full_name);
const char *imstr = impl->full_name; char *clbuf = alloca(imlen + 1);
*foo_id = NULL; memcpy(clbuf, impl->full_name, imlen + 1);
if (imstr[0] == '.')
++imstr; char *ldot = strrchr(clbuf, '.');
else if ((imlen > (cllen + 1)) && (*(imstr + cllen) == '.') if (!ldot)
&& !strncmp(imstr, cl->full_name, cllen)) return EINA_FALSE; /* unreachable in practice, for static analysis */
imstr += cllen + 1;
else *ldot = '\0'; /* split between class name and func name */
return EINA_TRUE; const char *clname = clbuf;
if (strchr(imstr, '.')) const char *fnname = ldot + 1;
return EINA_TRUE;
impl->klass = cl; const Eolian_Class *tcl = eolian_class_get_by_name(clname);
*foo_id = (Eolian_Function*)eolian_class_function_get_by_name(cl, imstr, if (!tcl)
ftype); return EINA_FALSE;
impl->foo_id = *foo_id;
return !!*foo_id; impl->klass = tcl;
const Eolian_Function *fid = eolian_class_function_get_by_name(tcl, fnname, ftype);
if (!fid)
return EINA_FALSE;
*foo_id = (Eolian_Function *)fid;
impl->foo_id = fid;
return EINA_TRUE;
} }
static void static void
_write_impl(Eolian_Function *fid, Eolian_Implement *impl) _write_impl(Eolian_Function *fid, Eolian_Function_Type ftype,
Eolian_Implement *impl)
{ {
if (impl->is_prop_set) if (ftype == EOLIAN_PROP_GET)
fid->set_impl = impl;
else if (impl->is_prop_get)
fid->get_impl = impl; fid->get_impl = impl;
else if (ftype == EOLIAN_PROP_SET)
fid->set_impl = impl;
else else
fid->get_impl = fid->set_impl = impl; fid->get_impl = fid->set_impl = impl;
} }
@ -52,12 +60,12 @@ _write_impl(Eolian_Function *fid, Eolian_Implement *impl)
static Eina_Bool static Eina_Bool
_db_fill_implement(Eolian_Class *cl, Eolian_Implement *impl) _db_fill_implement(Eolian_Class *cl, Eolian_Implement *impl)
{ {
const char *impl_name = impl->full_name;
Eolian_Function *foo_id; Eolian_Function *foo_id;
Eolian_Function_Type ftype = EOLIAN_UNRESOLVED; Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
if (impl->is_prop_get) if (impl->is_prop_get && impl->is_prop_set)
ftype = EOLIAN_PROPERTY;
else if (impl->is_prop_get)
ftype = EOLIAN_PROP_GET; ftype = EOLIAN_PROP_GET;
else if (impl->is_prop_set) else if (impl->is_prop_set)
ftype = EOLIAN_PROP_SET; ftype = EOLIAN_PROP_SET;
@ -66,47 +74,28 @@ _db_fill_implement(Eolian_Class *cl, Eolian_Implement *impl)
{ {
if (!_get_impl_func(cl, impl, ftype, &foo_id)) if (!_get_impl_func(cl, impl, ftype, &foo_id))
return _func_error(cl, impl); return _func_error(cl, impl);
if (!foo_id) foo_id->get_auto = impl->is_prop_get;
goto pasttags; foo_id->set_auto = impl->is_prop_set;
if (impl->is_prop_set) _write_impl(foo_id, ftype, impl);
foo_id->set_auto = EINA_TRUE;
else
foo_id->get_auto = EINA_TRUE;
_write_impl(foo_id, impl);
} }
else if (impl->is_empty) else if (impl->is_empty)
{ {
if (!_get_impl_func(cl, impl, ftype, &foo_id)) if (!_get_impl_func(cl, impl, ftype, &foo_id))
return _func_error(cl, impl); return _func_error(cl, impl);
if (!foo_id) foo_id->get_empty = impl->is_prop_get;
goto pasttags; foo_id->set_empty = impl->is_prop_set;
if (impl->is_prop_set) _write_impl(foo_id, ftype, impl);
foo_id->set_empty = EINA_TRUE;
else
foo_id->get_empty = EINA_TRUE;
_write_impl(foo_id, impl);
} }
else if (!_get_impl_func(cl, impl, ftype, &foo_id)) else if (!_get_impl_func(cl, impl, ftype, &foo_id))
return _func_error(cl, impl); return _func_error(cl, impl);
if (foo_id && foo_id->klass == cl && eolian_function_is_virtual_pure(foo_id, ftype)) if (foo_id && foo_id->klass == cl && eolian_function_is_virtual_pure(foo_id, ftype))
{ {
fprintf(stderr, "eolian:%s:%d:%d: impl of pure virtual '%s%s'\n", fprintf(stderr, "eolian:%s:%d:%d: impl of pure virtual '%s'\n",
impl->base.file, impl->base.line, impl->base.column, impl->full_name, impl->base.file, impl->base.line, impl->base.column, impl->full_name);
(impl->is_prop_get ? ".get" : (impl->is_prop_set ? ".set" : "")));
return EINA_FALSE; return EINA_FALSE;
} }
pasttags:
if (impl_name[0] == '.')
{
impl->full_name = eina_stringshare_printf("%s%s", cl->full_name,
impl_name);
eina_stringshare_del(impl_name);
}
return EINA_TRUE; return EINA_TRUE;
} }

View File

@ -1536,15 +1536,16 @@ parse_implement(Eo_Lexer *ls, Eina_Bool iface)
if (ls->t.token == '.') if (ls->t.token == '.')
{ {
if (!impl->is_auto && !impl->is_empty) if (!impl->is_auto && !impl->is_empty)
goto fullclass; eo_lexer_syntax_error(ls, "class name expected");
check_next(ls, '.'); check_next(ls, '.');
if (ls->t.token != TOK_VALUE) if (ls->t.token != TOK_VALUE)
eo_lexer_syntax_error(ls, "name expected"); eo_lexer_syntax_error(ls, "name expected");
impl->full_name = eina_stringshare_printf(".%s", ls->t.value.s); impl->full_name = eina_stringshare_printf("%s.%s",
ls->tmp.kls->full_name,
ls->t.value.s);
eo_lexer_get(ls); eo_lexer_get(ls);
goto propbeg; goto propbeg;
} }
fullclass:
if (ls->t.token != TOK_VALUE) if (ls->t.token != TOK_VALUE)
eo_lexer_syntax_error(ls, "class name expected"); eo_lexer_syntax_error(ls, "class name expected");
buf = push_strbuf(ls); buf = push_strbuf(ls);