}
static Eina_Bool
+_db_fill_inherits(const Eolian_Unit *src, Eolian_Class *cl, Eina_Hash *fhash)
+{
+ if (eina_hash_find(fhash, cl->full_name))
+ return EINA_TRUE;
+
+ Eina_List *il = cl->inherits;
+ Eina_Stringshare *inn = NULL;
+ cl->inherits = NULL;
+ Eina_Bool succ = EINA_TRUE;
+
+ EINA_LIST_FREE(il, inn)
+ {
+ if (!succ)
+ {
+ eina_stringshare_del(inn);
+ continue;
+ }
+ Eolian_Class *icl = eina_hash_find(src->state->unit.classes, inn);
+ if (!icl)
+ {
+ succ = EINA_FALSE;
+ char buf[PATH_MAX];
+ snprintf(buf, sizeof(buf), "unknown inherit '%s' (incorrect case?)", inn);
+ _obj_error(&cl->base, buf);
+ }
+ else
+ {
+ cl->inherits = eina_list_append(cl->inherits, icl);
+ /* recursively fill so the tree is valid */
+ if (!icl->base.validated && !_db_fill_inherits(src, icl, fhash))
+ succ = EINA_FALSE;
+ }
+ eina_stringshare_del(inn);
+ }
+
+ eina_hash_add(fhash, cl->full_name, cl);
+
+ /* make sure impls/ctors are filled first, but do it only once */
+ if (!_db_fill_implements(cl))
+ return EINA_FALSE;
+
+ if (!_db_fill_ctors(cl))
+ return EINA_FALSE;
+
+ return succ;
+}
+
+static Eina_Bool
_validate_implement(const Eolian_Unit *src, Eolian_Implement *impl)
{
if (impl->base.validated)
}
static Eina_Bool
-_validate_class(const Eolian_Unit *src, Eolian_Class *cl, Eina_Hash *nhash)
+_validate_class(const Eolian_Unit *src, Eolian_Class *cl,
+ Eina_Hash *nhash, Eina_Bool ipass)
{
Eina_List *l;
Eolian_Function *func;
Eina_Bool valid = cl->base.validated;
- /* make sure impls/ctors are filled first, but do it only once */
- if (!valid && !_db_fill_implements(cl))
- return EINA_FALSE;
-
- if (!valid && !_db_fill_ctors(cl))
- return EINA_FALSE;
+ /* refill inherits in the current inheritance tree first */
+ if (!valid && !ipass)
+ {
+ Eina_Hash *fhash = eina_hash_stringshared_new(NULL);
+ if (!_db_fill_inherits(src, cl, fhash))
+ {
+ eina_hash_free(fhash);
+ return EINA_FALSE;
+ }
+ eina_hash_free(fhash);
+ }
EINA_LIST_FOREACH(cl->inherits, l, icl)
{
default:
break;
}
- if (!_validate_class(src, icl, nhash))
+ if (!_validate_class(src, icl, nhash, EINA_TRUE))
return EINA_FALSE;
}
EINA_ITERATOR_FOREACH(iter, cl)
{
eina_hash_free_buckets(nhash);
- if (!_validate_class(src, cl, nhash))
+ if (!_validate_class(src, cl, nhash, EINA_FALSE))
{
eina_iterator_free(iter);
eina_hash_free(nhash);
return; /* unreachable (longjmp above), make static analysis shut up */
}
fname = eina_hash_find(ls->state->filenames_eo, fnm);
- free(fnm);
if (!fname)
{
char ebuf[PATH_MAX];
+ free(fnm);
eo_lexer_context_restore(ls);
snprintf(ebuf, sizeof(ebuf), "unknown inherit '%s'", iname);
eo_lexer_syntax_error(ls, ebuf);
+ return;
}
- Eolian_Class *dep = _parse_dep(ls, fname, iname);
- if (!dep)
+
+ Eina_Stringshare *inames = eina_stringshare_add(iname), *oiname = NULL;
+ Eina_List *l;
+ /* never allow duplicate inherits */
+ EINA_LIST_FOREACH(ls->tmp.kls->inherits, l, oiname)
{
- char ebuf[PATH_MAX];
- eo_lexer_context_restore(ls);
- snprintf(ebuf, sizeof(ebuf), "unknown inherit '%s'. Incorrect case?", iname);
- eo_lexer_syntax_error(ls, ebuf);
- return;
+ if (inames == oiname)
+ {
+ char ebuf[PATH_MAX];
+ free(fnm);
+ eina_stringshare_del(inames);
+ eo_lexer_context_restore(ls);
+ snprintf(ebuf, sizeof(ebuf), "duplicate inherit '%s'", iname);
+ eo_lexer_syntax_error(ls, ebuf);
+ return;
+ }
}
- ls->tmp.kls->inherits = eina_list_append(ls->tmp.kls->inherits, dep);
+ eina_hash_set(ls->state->defer, fnm, fname);
+ ls->tmp.kls->inherits = eina_list_append(ls->tmp.kls->inherits, inames);
+ free(fnm);
eo_lexer_context_pop(ls);
}