summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@osg.samsung.com>2018-01-30 17:03:37 +0100
committerDaniel Kolesa <d.kolesa@osg.samsung.com>2018-01-30 17:08:44 +0100
commit5651b2e586e9a9836ebe4f50f9223e237099cf86 (patch)
treee6c8bafbdf6950410b32f8fcbc201dc608a12871
parent7b643f6919529f24d1094d3484a44cc197603b33 (diff)
eolian: deferred parsing of inherits + better static checks
This change finally introduces deferred parsing of inherits to Eolian, after a long time and many iterations. That means instead of parsing inherits directly as part of the main file's parse pass, they're pushed into a queue and parsed later. The validation engine was modified to properly fill in the remaining info afterwards. This may introduce breakages but I haven't noticed any. It also properly unlocks cyclic dependency support in Eolian. Additionally, this also introduces checks for duplicates in class inherits (class Foo(Bar, Bar) is no longer possible) and it adds stricter name checks, so you can no longer have a class Foo.Bar and refer to it as Foo_Bar in implements. This was actually never meant to be supported, but the check was previously broken. @feature
-rw-r--r--src/lib/elementary/efl_ui_legacy.eo2
-rw-r--r--src/lib/elementary/efl_ui_list.eo2
-rw-r--r--src/lib/elementary/elm_genlist.eo2
-rw-r--r--src/lib/eolian/database_validate.c72
-rw-r--r--src/lib/eolian/eo_parser.c29
-rw-r--r--src/lib/evas/canvas/efl_input_key.eo2
6 files changed, 87 insertions, 22 deletions
diff --git a/src/lib/elementary/efl_ui_legacy.eo b/src/lib/elementary/efl_ui_legacy.eo
index e077691310..301bcdc837 100644
--- a/src/lib/elementary/efl_ui_legacy.eo
+++ b/src/lib/elementary/efl_ui_legacy.eo
@@ -1,4 +1,4 @@
1interface EFl.Ui.Legacy (Efl.Interface) 1interface Efl.Ui.Legacy (Efl.Interface)
2{ 2{
3 [[The bg (background) widget is used for setting (solid) background decorations 3 [[The bg (background) widget is used for setting (solid) background decorations
4 4
diff --git a/src/lib/elementary/efl_ui_list.eo b/src/lib/elementary/efl_ui_list.eo
index 2ca88bdf74..64148ee5ff 100644
--- a/src/lib/elementary/efl_ui_list.eo
+++ b/src/lib/elementary/efl_ui_list.eo
@@ -99,7 +99,7 @@ class Efl.Ui.List (Efl.Ui.Layout, Efl.Ui.View, Efl.Ui.Scrollable.Interactive, Ef
99 Efl.Layout.Signal.signal_callback_add; 99 Efl.Layout.Signal.signal_callback_add;
100 Efl.Layout.Signal.signal_callback_del; 100 Efl.Layout.Signal.signal_callback_del;
101// Elm.Interface.Atspi_Accessible.children { get; } 101// Elm.Interface.Atspi_Accessible.children { get; }
102// Elm.Interface.Atspi_Widget_Action.elm_actions { get; } 102// Elm.Interface.Atspi_Widget.Action.elm_actions { get; }
103// Efl.Access.Widget.Action.elm_actions { get; } 103// Efl.Access.Widget.Action.elm_actions { get; }
104 Efl.Access.Selection.selected_children_count { get; } 104 Efl.Access.Selection.selected_children_count { get; }
105 Efl.Access.Selection.selected_child { get; } 105 Efl.Access.Selection.selected_child { get; }
diff --git a/src/lib/elementary/elm_genlist.eo b/src/lib/elementary/elm_genlist.eo
index 2d9a4e2536..45ee52bdd5 100644
--- a/src/lib/elementary/elm_genlist.eo
+++ b/src/lib/elementary/elm_genlist.eo
@@ -3,7 +3,7 @@ import elm_list;
3import elm_genlist_item; 3import elm_genlist_item;
4 4
5class Elm.Genlist (Efl.Ui.Layout, Efl.Ui.Focus.Composition, Elm.Interface_Scrollable, Efl.Ui.Clickable, 5class Elm.Genlist (Efl.Ui.Layout, Efl.Ui.Focus.Composition, Elm.Interface_Scrollable, Efl.Ui.Clickable,
6 Efl.Access.Widget_Action, Efl.Access.Selection, 6 Efl.Access.Widget.Action, Efl.Access.Selection,
7 Efl.Ui.Selectable, Efl.Ui.Legacy) 7 Efl.Ui.Selectable, Efl.Ui.Legacy)
8{ 8{
9 [[Elementary genlist class]] 9 [[Elementary genlist class]]
diff --git a/src/lib/eolian/database_validate.c b/src/lib/eolian/database_validate.c
index 2f316fc653..66cf97fb66 100644
--- a/src/lib/eolian/database_validate.c
+++ b/src/lib/eolian/database_validate.c
@@ -645,6 +645,54 @@ end:
645} 645}
646 646
647static Eina_Bool 647static Eina_Bool
648_db_fill_inherits(const Eolian_Unit *src, Eolian_Class *cl, Eina_Hash *fhash)
649{
650 if (eina_hash_find(fhash, cl->full_name))
651 return EINA_TRUE;
652
653 Eina_List *il = cl->inherits;
654 Eina_Stringshare *inn = NULL;
655 cl->inherits = NULL;
656 Eina_Bool succ = EINA_TRUE;
657
658 EINA_LIST_FREE(il, inn)
659 {
660 if (!succ)
661 {
662 eina_stringshare_del(inn);
663 continue;
664 }
665 Eolian_Class *icl = eina_hash_find(src->state->unit.classes, inn);
666 if (!icl)
667 {
668 succ = EINA_FALSE;
669 char buf[PATH_MAX];
670 snprintf(buf, sizeof(buf), "unknown inherit '%s' (incorrect case?)", inn);
671 _obj_error(&cl->base, buf);
672 }
673 else
674 {
675 cl->inherits = eina_list_append(cl->inherits, icl);
676 /* recursively fill so the tree is valid */
677 if (!icl->base.validated && !_db_fill_inherits(src, icl, fhash))
678 succ = EINA_FALSE;
679 }
680 eina_stringshare_del(inn);
681 }
682
683 eina_hash_add(fhash, cl->full_name, cl);
684
685 /* make sure impls/ctors are filled first, but do it only once */
686 if (!_db_fill_implements(cl))
687 return EINA_FALSE;
688
689 if (!_db_fill_ctors(cl))
690 return EINA_FALSE;
691
692 return succ;
693}
694
695static Eina_Bool
648_validate_implement(const Eolian_Unit *src, Eolian_Implement *impl) 696_validate_implement(const Eolian_Unit *src, Eolian_Implement *impl)
649{ 697{
650 if (impl->base.validated) 698 if (impl->base.validated)
@@ -661,7 +709,8 @@ _validate_implement(const Eolian_Unit *src, Eolian_Implement *impl)
661} 709}
662 710
663static Eina_Bool 711static Eina_Bool
664_validate_class(const Eolian_Unit *src, Eolian_Class *cl, Eina_Hash *nhash) 712_validate_class(const Eolian_Unit *src, Eolian_Class *cl,
713 Eina_Hash *nhash, Eina_Bool ipass)
665{ 714{
666 Eina_List *l; 715 Eina_List *l;
667 Eolian_Function *func; 716 Eolian_Function *func;
@@ -675,12 +724,17 @@ _validate_class(const Eolian_Unit *src, Eolian_Class *cl, Eina_Hash *nhash)
675 724
676 Eina_Bool valid = cl->base.validated; 725 Eina_Bool valid = cl->base.validated;
677 726
678 /* make sure impls/ctors are filled first, but do it only once */ 727 /* refill inherits in the current inheritance tree first */
679 if (!valid && !_db_fill_implements(cl)) 728 if (!valid && !ipass)
680 return EINA_FALSE; 729 {
681 730 Eina_Hash *fhash = eina_hash_stringshared_new(NULL);
682 if (!valid && !_db_fill_ctors(cl)) 731 if (!_db_fill_inherits(src, cl, fhash))
683 return EINA_FALSE; 732 {
733 eina_hash_free(fhash);
734 return EINA_FALSE;
735 }
736 eina_hash_free(fhash);
737 }
684 738
685 EINA_LIST_FOREACH(cl->inherits, l, icl) 739 EINA_LIST_FOREACH(cl->inherits, l, icl)
686 { 740 {
@@ -710,7 +764,7 @@ _validate_class(const Eolian_Unit *src, Eolian_Class *cl, Eina_Hash *nhash)
710 default: 764 default:
711 break; 765 break;
712 } 766 }
713 if (!_validate_class(src, icl, nhash)) 767 if (!_validate_class(src, icl, nhash, EINA_TRUE))
714 return EINA_FALSE; 768 return EINA_FALSE;
715 } 769 }
716 770
@@ -786,7 +840,7 @@ database_validate(Eolian *state, const Eolian_Unit *src)
786 EINA_ITERATOR_FOREACH(iter, cl) 840 EINA_ITERATOR_FOREACH(iter, cl)
787 { 841 {
788 eina_hash_free_buckets(nhash); 842 eina_hash_free_buckets(nhash);
789 if (!_validate_class(src, cl, nhash)) 843 if (!_validate_class(src, cl, nhash, EINA_FALSE))
790 { 844 {
791 eina_iterator_free(iter); 845 eina_iterator_free(iter);
792 eina_hash_free(nhash); 846 eina_hash_free(nhash);
diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c
index 309b2df39d..f7445bf9bf 100644
--- a/src/lib/eolian/eo_parser.c
+++ b/src/lib/eolian/eo_parser.c
@@ -2038,24 +2038,35 @@ _inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf)
2038 return; /* unreachable (longjmp above), make static analysis shut up */ 2038 return; /* unreachable (longjmp above), make static analysis shut up */
2039 } 2039 }
2040 fname = eina_hash_find(ls->state->filenames_eo, fnm); 2040 fname = eina_hash_find(ls->state->filenames_eo, fnm);
2041 free(fnm);
2042 if (!fname) 2041 if (!fname)
2043 { 2042 {
2044 char ebuf[PATH_MAX]; 2043 char ebuf[PATH_MAX];
2044 free(fnm);
2045 eo_lexer_context_restore(ls); 2045 eo_lexer_context_restore(ls);
2046 snprintf(ebuf, sizeof(ebuf), "unknown inherit '%s'", iname); 2046 snprintf(ebuf, sizeof(ebuf), "unknown inherit '%s'", iname);
2047 eo_lexer_syntax_error(ls, ebuf); 2047 eo_lexer_syntax_error(ls, ebuf);
2048 return;
2048 } 2049 }
2049 Eolian_Class *dep = _parse_dep(ls, fname, iname); 2050
2050 if (!dep) 2051 Eina_Stringshare *inames = eina_stringshare_add(iname), *oiname = NULL;
2052 Eina_List *l;
2053 /* never allow duplicate inherits */
2054 EINA_LIST_FOREACH(ls->tmp.kls->inherits, l, oiname)
2051 { 2055 {
2052 char ebuf[PATH_MAX]; 2056 if (inames == oiname)
2053 eo_lexer_context_restore(ls); 2057 {
2054 snprintf(ebuf, sizeof(ebuf), "unknown inherit '%s'. Incorrect case?", iname); 2058 char ebuf[PATH_MAX];
2055 eo_lexer_syntax_error(ls, ebuf); 2059 free(fnm);
2056 return; 2060 eina_stringshare_del(inames);
2061 eo_lexer_context_restore(ls);
2062 snprintf(ebuf, sizeof(ebuf), "duplicate inherit '%s'", iname);
2063 eo_lexer_syntax_error(ls, ebuf);
2064 return;
2065 }
2057 } 2066 }
2058 ls->tmp.kls->inherits = eina_list_append(ls->tmp.kls->inherits, dep); 2067 eina_hash_set(ls->state->defer, fnm, fname);
2068 ls->tmp.kls->inherits = eina_list_append(ls->tmp.kls->inherits, inames);
2069 free(fnm);
2059 eo_lexer_context_pop(ls); 2070 eo_lexer_context_pop(ls);
2060} 2071}
2061 2072
diff --git a/src/lib/evas/canvas/efl_input_key.eo b/src/lib/evas/canvas/efl_input_key.eo
index 45fe094d6f..501a188a3e 100644
--- a/src/lib/evas/canvas/efl_input_key.eo
+++ b/src/lib/evas/canvas/efl_input_key.eo
@@ -1,4 +1,4 @@
1class Efl.Input.Key (Efl.Object, Efl.Input.Event, Efl.Input.State, Efl.Input.Event) 1class Efl.Input.Key (Efl.Object, Efl.Input.Event, Efl.Input.State)
2{ 2{
3 [[Represents a single key event from a keyboard or similar device. 3 [[Represents a single key event from a keyboard or similar device.
4 4