summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@samsung.com>2018-11-22 16:21:52 +0100
committerDaniel Kolesa <d.kolesa@samsung.com>2018-11-23 13:57:07 +0100
commit14ce54c30321e3b78b979872427b07d9420d5c66 (patch)
treef5947b26e04a7a162434d9ca250b0cb145bfab03 /src
parentf3eb8d6441af396e61842cb83b9ac7b3af34f527 (diff)
eolian: implement new inherit behavior
Eolian now separates 'parent' and 'extensions'. For regular classes, parent is the first item in the inherits list and extesions is the rest. For interfaces and mixins, parent is NULL and extends is the inherits list. The reason for this is the separation of them in syntax in near future. It also slightly changes the behavior; since for interfaces and mixins, parent is always NULL now, you can freely inherit from all types of classes without needing to manually put an interface type as the first item of the inherits list.
Diffstat (limited to 'src')
-rw-r--r--src/bin/eolian/sources.c12
-rw-r--r--src/bin/eolian_cxx/eolian_cxx.cc12
-rw-r--r--src/bindings/luajit/eolian.lua13
-rw-r--r--src/lib/eolian/Eolian.h26
-rw-r--r--src/lib/eolian/database_check.c7
-rw-r--r--src/lib/eolian/database_class_api.c11
-rw-r--r--src/lib/eolian/database_validate.c94
-rw-r--r--src/lib/eolian/eo_parser.c40
-rw-r--r--src/lib/eolian/eolian_database.h6
-rw-r--r--src/lib/eolian_cxx/grammar/klass_def.hpp12
-rw-r--r--src/scripts/pyolian/eolian.py9
-rw-r--r--src/scripts/pyolian/eolian_lib.py10
-rw-r--r--src/tests/eolian/eolian_parsing.c8
13 files changed, 182 insertions, 78 deletions
diff --git a/src/bin/eolian/sources.c b/src/bin/eolian/sources.c
index 3904d9823d..900b70216b 100644
--- a/src/bin/eolian/sources.c
+++ b/src/bin/eolian/sources.c
@@ -981,11 +981,17 @@ eo_gen_source_gen(const Eolian_Class *cl, Eina_Strbuf *buf)
981 981
982 /* inherits in EFL_DEFINE_CLASS */ 982 /* inherits in EFL_DEFINE_CLASS */
983 { 983 {
984 const Eolian_Class *icl; 984 const Eolian_Class *icl = eolian_class_parent_get(cl);
985 Eina_Iterator *itr = eolian_class_inherits_get(cl);
986 /* no inherits, NULL parent */ 985 /* no inherits, NULL parent */
987 if (!itr) 986 if (!icl)
988 eina_strbuf_append(buf, ", NULL"); 987 eina_strbuf_append(buf, ", NULL");
988 else
989 {
990 Eina_Stringshare *mname = eolian_class_c_name_get(icl);
991 eina_strbuf_append_printf(buf, ", %s", mname);
992 eina_stringshare_del(mname);
993 }
994 Eina_Iterator *itr = eolian_class_extensions_get(cl);
989 EINA_ITERATOR_FOREACH(itr, icl) 995 EINA_ITERATOR_FOREACH(itr, icl)
990 { 996 {
991 Eina_Stringshare *mname = eolian_class_c_name_get(icl); 997 Eina_Stringshare *mname = eolian_class_c_name_get(icl);
diff --git a/src/bin/eolian_cxx/eolian_cxx.cc b/src/bin/eolian_cxx/eolian_cxx.cc
index 70527ddc27..d5e42de830 100644
--- a/src/bin/eolian_cxx/eolian_cxx.cc
+++ b/src/bin/eolian_cxx/eolian_cxx.cc
@@ -120,7 +120,17 @@ generate(const Eolian_Class* klass, eolian_cxx::options_type const& opts,
120 std::function<void(Eolian_Class const*)> klass_function 120 std::function<void(Eolian_Class const*)> klass_function
121 = [&] (Eolian_Class const* klass2) 121 = [&] (Eolian_Class const* klass2)
122 { 122 {
123 for(efl::eina::iterator<Eolian_Class const> inherit_iterator ( ::eolian_class_inherits_get(klass2)) 123 if(::eolian_class_parent_get(klass2))
124 {
125 Eolian_Class const* inherit = ::eolian_class_parent_get(klass2);
126 c_headers.insert(eolian_object_file_get((const Eolian_Object *)inherit) + std::string(".h"));
127 cpp_headers.insert(eolian_object_file_get((const Eolian_Object *)inherit) + std::string(".hh"));
128 efl::eolian::grammar::attributes::klass_def klass3{inherit, opts.unit};
129 forward_klasses.insert(klass3);
130
131 klass_function(inherit);
132 }
133 for(efl::eina::iterator<Eolian_Class const> inherit_iterator ( ::eolian_class_extensions_get(klass2))
124 , inherit_last; inherit_iterator != inherit_last; ++inherit_iterator) 134 , inherit_last; inherit_iterator != inherit_last; ++inherit_iterator)
125 { 135 {
126 Eolian_Class const* inherit = &*inherit_iterator; 136 Eolian_Class const* inherit = &*inherit_iterator;
diff --git a/src/bindings/luajit/eolian.lua b/src/bindings/luajit/eolian.lua
index 07b8728224..99d596106c 100644
--- a/src/bindings/luajit/eolian.lua
+++ b/src/bindings/luajit/eolian.lua
@@ -334,7 +334,8 @@ ffi.cdef [[
334 const char *eolian_class_legacy_prefix_get(const Eolian_Class *klass); 334 const char *eolian_class_legacy_prefix_get(const Eolian_Class *klass);
335 const char *eolian_class_eo_prefix_get(const Eolian_Class *klass); 335 const char *eolian_class_eo_prefix_get(const Eolian_Class *klass);
336 const char *eolian_class_data_type_get(const Eolian_Class *klass); 336 const char *eolian_class_data_type_get(const Eolian_Class *klass);
337 Eina_Iterator *eolian_class_inherits_get(const Eolian_Class *klass); 337 const Eolian_Class *eolian_class_parent_get(const Eolian_Class *klass);
338 Eina_Iterator *eolian_class_extensions_get(const Eolian_Class *klass);
338 Eina_Iterator *eolian_class_functions_get(const Eolian_Class *klass, Eolian_Function_Type func_type); 339 Eina_Iterator *eolian_class_functions_get(const Eolian_Class *klass, Eolian_Function_Type func_type);
339 Eolian_Function_Type eolian_function_type_get(const Eolian_Function *function_id); 340 Eolian_Function_Type eolian_function_type_get(const Eolian_Function *function_id);
340 Eolian_Object_Scope eolian_function_scope_get(const Eolian_Function *function_id, Eolian_Function_Type ftype); 341 Eolian_Object_Scope eolian_function_scope_get(const Eolian_Function *function_id, Eolian_Function_Type ftype);
@@ -1338,9 +1339,15 @@ M.Class = ffi.metatype("Eolian_Class", {
1338 return ffi.string(v) 1339 return ffi.string(v)
1339 end, 1340 end,
1340 1341
1341 inherits_get = function(self) 1342 parent_get = function(self)
1343 local v = eolian.eolian_class_parent_get(self)
1344 if v == nil then return nil end
1345 return v
1346 end,
1347
1348 extensions_get = function(self)
1342 return Ptr_Iterator("const Eolian_Class*", 1349 return Ptr_Iterator("const Eolian_Class*",
1343 eolian.eolian_class_inherits_get(self)) 1350 eolian.eolian_class_extensions_get(self))
1344 end, 1351 end,
1345 1352
1346 functions_get = function(self, func_type) 1353 functions_get = function(self, func_type)
diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h
index b64d2f8f85..d4678715d1 100644
--- a/src/lib/eolian/Eolian.h
+++ b/src/lib/eolian/Eolian.h
@@ -1446,14 +1446,36 @@ EAPI Eina_Stringshare* eolian_class_event_prefix_get(const Eolian_Class *klass);
1446EAPI Eina_Stringshare *eolian_class_data_type_get(const Eolian_Class *klass); 1446EAPI Eina_Stringshare *eolian_class_data_type_get(const Eolian_Class *klass);
1447 1447
1448/* 1448/*
1449 * @brief Returns an iterator to the inherited classes. 1449 * @brief Get the parent class of a class
1450 *
1451 * This is the class the class inherits from. It only applies to classes,
1452 * as Eo follows a single-inheritance model with interfaces. This will be
1453 * NULL for any non-class (i.e. interface or mixin).
1454 *
1455 * @param[in] klass the class
1456 * @return the parent
1457 *
1458 * @see eolian_class_extensions_get
1459 *
1460 * @ingroup Eolian
1461 */
1462EAPI const Eolian_Class *eolian_class_parent_get(const Eolian_Class *klass);
1463
1464/*
1465 * @brief Returns an iterator to the class extensions
1466 *
1467 * For regular classes, extensions are interfaces/mixins for the class, i.e.
1468 * everything past the parent class. For interfaces/mixins, this is everything
1469 * in the inherits list.
1450 * 1470 *
1451 * @param[in] klass the class 1471 * @param[in] klass the class
1452 * @return the iterator 1472 * @return the iterator
1453 * 1473 *
1474 * @see eolian_class_parent_get
1475 *
1454 * @ingroup Eolian 1476 * @ingroup Eolian
1455 */ 1477 */
1456EAPI Eina_Iterator *eolian_class_inherits_get(const Eolian_Class *klass); 1478EAPI Eina_Iterator *eolian_class_extensions_get(const Eolian_Class *klass);
1457 1479
1458/* 1480/*
1459 * @brief Returns an iterator to functions of a class. 1481 * @brief Returns an iterator to functions of a class.
diff --git a/src/lib/eolian/database_check.c b/src/lib/eolian/database_check.c
index c13ca18002..61afa6e281 100644
--- a/src/lib/eolian/database_check.c
+++ b/src/lib/eolian/database_check.c
@@ -116,8 +116,11 @@ _check_class(const Eolian_Class *cl, Eina_Hash *depset, Eina_Hash *chash)
116 116
117 _add_dep(depset, cl->base.unit); 117 _add_dep(depset, cl->base.unit);
118 118
119 Eina_Iterator *itr = eina_list_iterator_new(cl->inherits); 119 const Eolian_Class *icl = cl->parent;
120 const Eolian_Class *icl; 120 if (icl)
121 _add_dep(depset, icl->base.unit);
122
123 Eina_Iterator *itr = eina_list_iterator_new(cl->extends);
121 EINA_ITERATOR_FOREACH(itr, icl) 124 EINA_ITERATOR_FOREACH(itr, icl)
122 _add_dep(depset, icl->base.unit); 125 _add_dep(depset, icl->base.unit);
123 eina_iterator_free(itr); 126 eina_iterator_free(itr);
diff --git a/src/lib/eolian/database_class_api.c b/src/lib/eolian/database_class_api.c
index dad2c77fc7..d96a7d7ecc 100644
--- a/src/lib/eolian/database_class_api.c
+++ b/src/lib/eolian/database_class_api.c
@@ -48,11 +48,18 @@ eolian_class_data_type_get(const Eolian_Class *cl)
48 return cl->data_type; 48 return cl->data_type;
49} 49}
50 50
51EAPI const Eolian_Class *
52eolian_class_parent_get(const Eolian_Class *cl)
53{
54 EINA_SAFETY_ON_NULL_RETURN_VAL(cl, NULL);
55 return cl->parent;
56}
57
51EAPI Eina_Iterator * 58EAPI Eina_Iterator *
52eolian_class_inherits_get(const Eolian_Class *cl) 59eolian_class_extensions_get(const Eolian_Class *cl)
53{ 60{
54 EINA_SAFETY_ON_NULL_RETURN_VAL(cl, NULL); 61 EINA_SAFETY_ON_NULL_RETURN_VAL(cl, NULL);
55 return (cl->inherits ? eina_list_iterator_new(cl->inherits) : NULL); 62 return (cl->extends ? eina_list_iterator_new(cl->extends) : NULL);
56} 63}
57 64
58EAPI Eina_Iterator * 65EAPI Eina_Iterator *
diff --git a/src/lib/eolian/database_validate.c b/src/lib/eolian/database_validate.c
index f18b5c2547..b44fc1221d 100644
--- a/src/lib/eolian/database_validate.c
+++ b/src/lib/eolian/database_validate.c
@@ -497,8 +497,8 @@ _get_impl_class(const Eolian_Class *cl, const char *cln)
497 if (!cl || !strcmp(cl->base.name, cln)) 497 if (!cl || !strcmp(cl->base.name, cln))
498 return cl; 498 return cl;
499 Eina_List *l; 499 Eina_List *l;
500 Eolian_Class *icl; 500 Eolian_Class *icl = cl->parent;
501 EINA_LIST_FOREACH(cl->inherits, l, icl) 501 if (icl)
502 { 502 {
503 /* we can do a depth first search, it's easier and doesn't matter 503 /* we can do a depth first search, it's easier and doesn't matter
504 * which part of the inheritance tree we find the class in 504 * which part of the inheritance tree we find the class in
@@ -507,6 +507,12 @@ _get_impl_class(const Eolian_Class *cl, const char *cln)
507 if (fcl) 507 if (fcl)
508 return fcl; 508 return fcl;
509 } 509 }
510 EINA_LIST_FOREACH(cl->extends, l, icl)
511 {
512 const Eolian_Class *fcl = _get_impl_class(icl, cln);
513 if (fcl)
514 return fcl;
515 }
510 return NULL; 516 return NULL;
511} 517}
512 518
@@ -704,6 +710,29 @@ end:
704} 710}
705 711
706static Eina_Bool 712static Eina_Bool
713_db_swap_inherit(Eolian_Class *cl, Eina_Bool succ, Eina_Stringshare *in_cl,
714 Eolian_Class **out_cl)
715{
716 if (!succ)
717 {
718 eina_stringshare_del(in_cl);
719 return EINA_FALSE;
720 }
721 Eolian_Class *icl = eina_hash_find(cl->base.unit->classes, in_cl);
722 if (!icl)
723 {
724 succ = EINA_FALSE;
725 char buf[PATH_MAX];
726 snprintf(buf, sizeof(buf), "unknown inherit '%s' (incorrect case?)", in_cl);
727 _obj_error(&cl->base, buf);
728 }
729 else
730 *out_cl = icl;
731 eina_stringshare_del(in_cl);
732 return succ;
733}
734
735static Eina_Bool
707_db_fill_inherits(Eolian_Class *cl, Eina_Hash *fhash) 736_db_fill_inherits(Eolian_Class *cl, Eina_Hash *fhash)
708{ 737{
709 if (eina_hash_find(fhash, &cl->base.name)) 738 if (eina_hash_find(fhash, &cl->base.name))
@@ -713,37 +742,32 @@ _db_fill_inherits(Eolian_Class *cl, Eina_Hash *fhash)
713 if (eina_hash_find(cl->base.unit->state->main.unit.classes, cl->base.name)) 742 if (eina_hash_find(cl->base.unit->state->main.unit.classes, cl->base.name))
714 return EINA_TRUE; 743 return EINA_TRUE;
715 744
716 Eina_List *il = cl->inherits; 745 Eina_List *il = cl->extends;
717 Eina_Stringshare *inn = NULL; 746 Eina_Stringshare *inn = NULL;
718 cl->inherits = NULL; 747 cl->extends = NULL;
719 Eina_Bool succ = EINA_TRUE; 748 Eina_Bool succ = EINA_TRUE;
720 749
721 EINA_LIST_FREE(il, inn) 750 if (cl->parent_name)
722 { 751 {
723 if (!succ) 752 succ = _db_swap_inherit(cl, succ, cl->parent_name, &cl->parent);
724 { 753 if (succ)
725 eina_stringshare_del(inn);
726 continue;
727 }
728 Eolian_Class *icl = eina_hash_find(cl->base.unit->classes, inn);
729 if (!icl)
730 {
731 succ = EINA_FALSE;
732 char buf[PATH_MAX];
733 snprintf(buf, sizeof(buf), "unknown inherit '%s' (incorrect case?)", inn);
734 _obj_error(&cl->base, buf);
735 }
736 else
737 { 754 {
738 cl->inherits = eina_list_append(cl->inherits, icl);
739 /* fill if not found, but do not return right away because 755 /* fill if not found, but do not return right away because
740 * the rest of the list needs to be freed in order not to 756 * the rest of the list needs to be freed in order not to
741 * leak any memory 757 * leak any memory
742 */ 758 */
743 if (!_db_fill_inherits(icl, fhash)) 759 succ = _db_fill_inherits(cl->parent, fhash);
744 succ = EINA_FALSE;
745 } 760 }
746 eina_stringshare_del(inn); 761 }
762
763 EINA_LIST_FREE(il, inn)
764 {
765 Eolian_Class *out_cl = NULL;
766 succ = _db_swap_inherit(cl, succ, inn, &out_cl);
767 if (!succ)
768 continue;
769 cl->extends = eina_list_append(cl->extends, out_cl);
770 succ = _db_fill_inherits(out_cl, fhash);
747 } 771 }
748 772
749 /* failed on the way, no point in filling further 773 /* failed on the way, no point in filling further
@@ -800,34 +824,30 @@ _validate_class(Validate_State *vals, Eolian_Class *cl,
800 824
801 Eina_Bool valid = cl->base.validated; 825 Eina_Bool valid = cl->base.validated;
802 826
803 EINA_LIST_FOREACH(cl->inherits, l, icl) 827 if (cl->parent)
804 { 828 {
805 /* first inherit needs some checking done on it */ 829 /* first inherit needs some checking done on it */
806 if (!valid && (l == cl->inherits)) switch (cl->type) 830 if (!valid) switch (cl->type)
807 { 831 {
808 case EOLIAN_CLASS_REGULAR: 832 case EOLIAN_CLASS_REGULAR:
809 case EOLIAN_CLASS_ABSTRACT: 833 case EOLIAN_CLASS_ABSTRACT:
810 if (icl->type != EOLIAN_CLASS_REGULAR && icl->type != EOLIAN_CLASS_ABSTRACT) 834 if (cl->parent->type != EOLIAN_CLASS_REGULAR && cl->parent->type != EOLIAN_CLASS_ABSTRACT)
811 { 835 {
812 char buf[PATH_MAX]; 836 char buf[PATH_MAX];
813 snprintf(buf, sizeof(buf), "regular classes ('%s') cannot inherit from non-regular classes ('%s')", 837 snprintf(buf, sizeof(buf), "regular classes ('%s') cannot inherit from non-regular classes ('%s')",
814 cl->base.name, icl->base.name); 838 cl->base.name, cl->parent->base.name);
815 return _obj_error(&cl->base, buf);
816 }
817 break;
818 case EOLIAN_CLASS_MIXIN:
819 case EOLIAN_CLASS_INTERFACE:
820 if (icl->type != EOLIAN_CLASS_MIXIN && icl->type != EOLIAN_CLASS_INTERFACE)
821 {
822 char buf[PATH_MAX];
823 snprintf(buf, sizeof(buf), "non-regular classes ('%s') cannot inherit from regular classes ('%s')",
824 cl->base.name, icl->base.name);
825 return _obj_error(&cl->base, buf); 839 return _obj_error(&cl->base, buf);
826 } 840 }
827 break; 841 break;
828 default: 842 default:
829 break; 843 break;
830 } 844 }
845 if (!_validate_class(vals, cl->parent, nhash, ehash, chash))
846 return EINA_FALSE;
847 }
848
849 EINA_LIST_FOREACH(cl->extends, l, icl)
850 {
831 if (!_validate_class(vals, icl, nhash, ehash, chash)) 851 if (!_validate_class(vals, icl, nhash, ehash, chash))
832 return EINA_FALSE; 852 return EINA_FALSE;
833 } 853 }
diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c
index e49698261b..858e268710 100644
--- a/src/lib/eolian/eo_parser.c
+++ b/src/lib/eolian/eo_parser.c
@@ -1951,8 +1951,9 @@ parse_class_body(Eo_Lexer *ls, Eolian_Class_Type type)
1951} 1951}
1952 1952
1953static void 1953static void
1954_inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf) 1954_inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf, Eina_Bool parent)
1955{ 1955{
1956 char ebuf[PATH_MAX];
1956 const char *iname; 1957 const char *iname;
1957 char *fnm; 1958 char *fnm;
1958 eina_strbuf_reset(buf); 1959 eina_strbuf_reset(buf);
@@ -1962,7 +1963,6 @@ _inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf)
1962 fnm = database_class_to_filename(iname); 1963 fnm = database_class_to_filename(iname);
1963 if (compare_class_file(fnm, ls->filename)) 1964 if (compare_class_file(fnm, ls->filename))
1964 { 1965 {
1965 char ebuf[PATH_MAX];
1966 free(fnm); 1966 free(fnm);
1967 eo_lexer_context_restore(ls); 1967 eo_lexer_context_restore(ls);
1968 snprintf(ebuf, sizeof(ebuf), "class '%s' cannot inherit from itself", 1968 snprintf(ebuf, sizeof(ebuf), "class '%s' cannot inherit from itself",
@@ -1972,7 +1972,6 @@ _inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf)
1972 } 1972 }
1973 if (!eina_hash_find(ls->state->filenames_eo, fnm)) 1973 if (!eina_hash_find(ls->state->filenames_eo, fnm))
1974 { 1974 {
1975 char ebuf[PATH_MAX];
1976 free(fnm); 1975 free(fnm);
1977 eo_lexer_context_restore(ls); 1976 eo_lexer_context_restore(ls);
1978 snprintf(ebuf, sizeof(ebuf), "unknown inherit '%s'", iname); 1977 snprintf(ebuf, sizeof(ebuf), "unknown inherit '%s'", iname);
@@ -1981,25 +1980,33 @@ _inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf)
1981 } 1980 }
1982 1981
1983 Eina_Stringshare *inames = eina_stringshare_add(iname), *oiname = NULL; 1982 Eina_Stringshare *inames = eina_stringshare_add(iname), *oiname = NULL;
1984 Eina_List *l;
1985 /* never allow duplicate inherits */ 1983 /* never allow duplicate inherits */
1986 EINA_LIST_FOREACH(ls->klass->inherits, l, oiname) 1984 if (!parent)
1987 { 1985 {
1988 if (inames == oiname) 1986 Eina_List *l;
1987 if (inames == ls->klass->parent_name)
1988 goto inherit_dup;
1989 EINA_LIST_FOREACH(ls->klass->extends, l, oiname)
1989 { 1990 {
1990 char ebuf[PATH_MAX]; 1991 if (inames == oiname)
1991 free(fnm); 1992 goto inherit_dup;
1992 eina_stringshare_del(inames);
1993 eo_lexer_context_restore(ls);
1994 snprintf(ebuf, sizeof(ebuf), "duplicate inherit '%s'", iname);
1995 eo_lexer_syntax_error(ls, ebuf);
1996 return;
1997 } 1993 }
1998 } 1994 }
1999 database_defer(ls->state, fnm, EINA_TRUE); 1995 database_defer(ls->state, fnm, EINA_TRUE);
2000 ls->klass->inherits = eina_list_append(ls->klass->inherits, inames); 1996 if (parent)
1997 ls->klass->parent_name = inames;
1998 else
1999 ls->klass->extends = eina_list_append(ls->klass->extends, inames);
2001 free(fnm); 2000 free(fnm);
2002 eo_lexer_context_pop(ls); 2001 eo_lexer_context_pop(ls);
2002 return;
2003
2004inherit_dup:
2005 free(fnm);
2006 eina_stringshare_del(inames);
2007 eo_lexer_context_restore(ls);
2008 snprintf(ebuf, sizeof(ebuf), "duplicate inherit '%s'", iname);
2009 eo_lexer_syntax_error(ls, ebuf);
2003} 2010}
2004 2011
2005static void 2012static void
@@ -2045,9 +2052,10 @@ parse_class(Eo_Lexer *ls, Eolian_Class_Type type)
2045 { 2052 {
2046 Eina_Strbuf *ibuf = eina_strbuf_new(); 2053 Eina_Strbuf *ibuf = eina_strbuf_new();
2047 eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), ibuf); 2054 eo_lexer_dtor_push(ls, EINA_FREE_CB(eina_strbuf_free), ibuf);
2048 _inherit_dep(ls, ibuf); 2055 _inherit_dep(ls, ibuf,
2056 (type == EOLIAN_CLASS_REGULAR) || (type == EOLIAN_CLASS_ABSTRACT));
2049 while (test_next(ls, ',')) 2057 while (test_next(ls, ','))
2050 _inherit_dep(ls, ibuf); 2058 _inherit_dep(ls, ibuf, EINA_FALSE);
2051 eo_lexer_dtor_pop(ls); 2059 eo_lexer_dtor_pop(ls);
2052 } 2060 }
2053 check_match(ls, ')', '(', line, col); 2061 check_match(ls, ')', '(', line, col);
diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h
index b0684f0591..9804449bda 100644
--- a/src/lib/eolian/eolian_database.h
+++ b/src/lib/eolian/eolian_database.h
@@ -180,7 +180,11 @@ struct _Eolian_Class
180 Eina_Stringshare *eo_prefix; 180 Eina_Stringshare *eo_prefix;
181 Eina_Stringshare *ev_prefix; 181 Eina_Stringshare *ev_prefix;
182 Eina_Stringshare *data_type; 182 Eina_Stringshare *data_type;
183 Eina_List *inherits; /* Eolian_Class */ 183 union {
184 Eolian_Class *parent;
185 Eina_Stringshare *parent_name;
186 };
187 Eina_List *extends; /* Eolian_Class */
184 Eina_List *properties; /* Eolian_Function */ 188 Eina_List *properties; /* Eolian_Function */
185 Eina_List *methods; /* Eolian_Function */ 189 Eina_List *methods; /* Eolian_Function */
186 Eina_List *implements; /* Eolian_Implement */ 190 Eina_List *implements; /* Eolian_Implement */
diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp
index 48044d9be7..5a4a753a61 100644
--- a/src/lib/eolian_cxx/grammar/klass_def.hpp
+++ b/src/lib/eolian_cxx/grammar/klass_def.hpp
@@ -1036,7 +1036,9 @@ struct klass_def
1036 functions.push_back({function, EOLIAN_METHOD, NULL, unit}); 1036 functions.push_back({function, EOLIAN_METHOD, NULL, unit});
1037 } catch(std::exception const&) {} 1037 } catch(std::exception const&) {}
1038 } 1038 }
1039 for(efl::eina::iterator<Eolian_Class const> inherit_iterator ( ::eolian_class_inherits_get(klass)) 1039 if(::eolian_class_parent_get(klass))
1040 immediate_inherits.insert({::eolian_class_parent_get(klass), {}});
1041 for(efl::eina::iterator<Eolian_Class const> inherit_iterator ( ::eolian_class_extensions_get(klass))
1040 , inherit_last; inherit_iterator != inherit_last; ++inherit_iterator) 1042 , inherit_last; inherit_iterator != inherit_last; ++inherit_iterator)
1041 { 1043 {
1042 Eolian_Class const* inherit = &*inherit_iterator; 1044 Eolian_Class const* inherit = &*inherit_iterator;
@@ -1045,7 +1047,13 @@ struct klass_def
1045 std::function<void(Eolian_Class const*)> inherit_algo = 1047 std::function<void(Eolian_Class const*)> inherit_algo =
1046 [&] (Eolian_Class const* inherit_klass) 1048 [&] (Eolian_Class const* inherit_klass)
1047 { 1049 {
1048 for(efl::eina::iterator<Eolian_Class const> inherit_iterator ( ::eolian_class_inherits_get(inherit_klass)) 1050 if(::eolian_class_parent_get(inherit_klass))
1051 {
1052 Eolian_Class const* inherit = ::eolian_class_parent_get(inherit_klass);
1053 inherits.insert({inherit, {}});
1054 inherit_algo(inherit);
1055 }
1056 for(efl::eina::iterator<Eolian_Class const> inherit_iterator ( ::eolian_class_extensions_get(inherit_klass))
1049 , inherit_last; inherit_iterator != inherit_last; ++inherit_iterator) 1057 , inherit_last; inherit_iterator != inherit_last; ++inherit_iterator)
1050 { 1058 {
1051 Eolian_Class const* inherit = &*inherit_iterator; 1059 Eolian_Class const* inherit = &*inherit_iterator;
diff --git a/src/scripts/pyolian/eolian.py b/src/scripts/pyolian/eolian.py
index 556f47720d..b87e4fd630 100644
--- a/src/scripts/pyolian/eolian.py
+++ b/src/scripts/pyolian/eolian.py
@@ -686,9 +686,14 @@ class Class(Object):
686 _str_to_bytes(event_name)) 686 _str_to_bytes(event_name))
687 return Event(c_event) if c_event else None 687 return Event(c_event) if c_event else None
688 688
689 @cached_property
690 def parent(self):
691 c_class = lib.eolian_class_parent_get(self)
692 return Class(c_class) if c_class else None
693
689 @property 694 @property
690 def inherits(self): 695 def extensions(self):
691 return Iterator(Class, lib.eolian_class_inherits_get(self)) 696 return Iterator(Class, lib.eolian_class_extensions_get(self))
692 697
693 @cached_property 698 @cached_property
694 def inherits_full(self): 699 def inherits_full(self):
diff --git a/src/scripts/pyolian/eolian_lib.py b/src/scripts/pyolian/eolian_lib.py
index 3cd7bad285..1f6a2f3d71 100644
--- a/src/scripts/pyolian/eolian_lib.py
+++ b/src/scripts/pyolian/eolian_lib.py
@@ -254,9 +254,13 @@ lib.eolian_class_event_prefix_get.restype = c_char_p
254lib.eolian_class_data_type_get.argtypes = (c_void_p,) 254lib.eolian_class_data_type_get.argtypes = (c_void_p,)
255lib.eolian_class_data_type_get.restype = c_char_p 255lib.eolian_class_data_type_get.restype = c_char_p
256 256
257# EAPI Eina_Iterator *eolian_class_inherits_get(const Eolian_Class *klass); 257# EAPI const Eolian_Class *eolian_class_parent_get(const Eolian_Class *klass);
258lib.eolian_class_inherits_get.argtypes = (c_void_p,) 258lib.eolian_class_parent_get.argtypes = (c_void_p,)
259lib.eolian_class_inherits_get.restype = c_void_p 259lib.eolian_class_parent_get.restype = c_void_p
260
261# EAPI Eina_Iterator *eolian_class_extensions_get(const Eolian_Class *klass);
262lib.eolian_class_extensions_get.argtypes = (c_void_p,)
263lib.eolian_class_extensions_get.restype = c_void_p
260 264
261# EAPI Eina_Iterator *eolian_class_functions_get(const Eolian_Class *klass, Eolian_Function_Type func_type); 265# EAPI Eina_Iterator *eolian_class_functions_get(const Eolian_Class *klass, Eolian_Function_Type func_type);
262lib.eolian_class_functions_get.argtypes = (c_void_p, c_int) 266lib.eolian_class_functions_get.argtypes = (c_void_p, c_int)
diff --git a/src/tests/eolian/eolian_parsing.c b/src/tests/eolian/eolian_parsing.c
index 6cb7bb0e92..6df473f24d 100644
--- a/src/tests/eolian/eolian_parsing.c
+++ b/src/tests/eolian/eolian_parsing.c
@@ -61,9 +61,8 @@ EFL_START_TEST(eolian_namespaces)
61 fail_if(eolian_class_namespaces_get(class_no)); 61 fail_if(eolian_class_namespaces_get(class_no));
62 62
63 /* Inherits */ 63 /* Inherits */
64 fail_if(!(iter = eolian_class_inherits_get(class11))); 64 fail_if(eolian_class_parent_get(class11) != class112);
65 fail_if(!(eina_iterator_next(iter, (void**)&iclass))); 65 fail_if(!(iter = eolian_class_extensions_get(class11)));
66 fail_if(iclass != class112);
67 fail_if(!(eina_iterator_next(iter, (void**)&iclass))); 66 fail_if(!(eina_iterator_next(iter, (void**)&iclass)));
68 fail_if(iclass != class21); 67 fail_if(iclass != class21);
69 fail_if(!(eina_iterator_next(iter, (void**)&iclass))); 68 fail_if(!(eina_iterator_next(iter, (void**)&iclass)));
@@ -551,7 +550,8 @@ EFL_START_TEST(eolian_simple_parsing)
551 550
552 /* Class */ 551 /* Class */
553 fail_if(eolian_class_type_get(class) != EOLIAN_CLASS_REGULAR); 552 fail_if(eolian_class_type_get(class) != EOLIAN_CLASS_REGULAR);
554 fail_if(eolian_class_inherits_get(class) != NULL); 553 fail_if(eolian_class_parent_get(class) != NULL);
554 fail_if(eolian_class_extensions_get(class) != NULL);
555 fail_if(strcmp(eolian_class_legacy_prefix_get(class), "evas_object_simple")); 555 fail_if(strcmp(eolian_class_legacy_prefix_get(class), "evas_object_simple"));
556 fail_if(strcmp(eolian_class_eo_prefix_get(class), "efl_canvas_object_simple")); 556 fail_if(strcmp(eolian_class_eo_prefix_get(class), "efl_canvas_object_simple"));
557 fail_if(strcmp(eolian_class_data_type_get(class), "Evas_Simple_Data")); 557 fail_if(strcmp(eolian_class_data_type_get(class), "Evas_Simple_Data"));