summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@samsung.com>2018-11-04 18:56:54 +0100
committerDaniel Kolesa <d.kolesa@samsung.com>2018-11-29 13:56:52 +0100
commitbe7d76ece63844f1967ee12d042c920a8540ab4a (patch)
tree847f01a585bf940592d3556926cd25b66286e627
parente93dbf21a26ea05118db1896025f7ad19e603813 (diff)
eolian_aux: add initial eolian_aux APIs
eolian_aux is a set of auxiliary APIs for eolian that build on top of the existing eolian APIs but do not belong in the main library.
-rw-r--r--src/Makefile_Eolian.am6
-rw-r--r--src/lib/eolian/Eolian_Aux.h180
-rw-r--r--src/lib/eolian/eolian_aux.c294
-rw-r--r--src/lib/eolian/meson.build10
-rw-r--r--src/tests/eolian/data_aux/a.eo12
-rw-r--r--src/tests/eolian/data_aux/b.eo2
-rw-r--r--src/tests/eolian/data_aux/c.eo9
-rw-r--r--src/tests/eolian/eolian_aux.c146
-rw-r--r--src/tests/eolian/eolian_suite.c1
-rw-r--r--src/tests/eolian/eolian_suite.h1
-rw-r--r--src/tests/eolian/meson.build1
11 files changed, 658 insertions, 4 deletions
diff --git a/src/Makefile_Eolian.am b/src/Makefile_Eolian.am
index f2c6667822..aa2f2344e8 100644
--- a/src/Makefile_Eolian.am
+++ b/src/Makefile_Eolian.am
@@ -4,7 +4,7 @@
4lib_LTLIBRARIES += lib/eolian/libeolian.la 4lib_LTLIBRARIES += lib/eolian/libeolian.la
5 5
6installed_eolianmainheadersdir = $(includedir)/eolian-@VMAJ@ 6installed_eolianmainheadersdir = $(includedir)/eolian-@VMAJ@
7dist_installed_eolianmainheaders_DATA = lib/eolian/Eolian.h 7dist_installed_eolianmainheaders_DATA = lib/eolian/Eolian.h lib/eolian/Eolian_Aux.h
8 8
9lib_eolian_libeolian_la_SOURCES = \ 9lib_eolian_libeolian_la_SOURCES = \
10 lib/eolian/eo_lexer.c \ 10 lib/eolian/eo_lexer.c \
@@ -36,7 +36,8 @@ lib_eolian_libeolian_la_SOURCES = \
36 lib/eolian/database_var.c \ 36 lib/eolian/database_var.c \
37 lib/eolian/database_var_api.c \ 37 lib/eolian/database_var_api.c \
38 lib/eolian/database_validate.c \ 38 lib/eolian/database_validate.c \
39 lib/eolian/database_check.c 39 lib/eolian/database_check.c \
40 lib/eolian/eolian_aux.c
40 41
41lib_eolian_libeolian_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @EOLIAN_CFLAGS@ \ 42lib_eolian_libeolian_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl @EOLIAN_CFLAGS@ \
42 -DPACKAGE_DATA_DIR=\"$(datadir)/eolian\" 43 -DPACKAGE_DATA_DIR=\"$(datadir)/eolian\"
@@ -109,6 +110,7 @@ tests/eolian/eolian_suite
109 110
110tests_eolian_eolian_suite_SOURCES = \ 111tests_eolian_eolian_suite_SOURCES = \
111tests/eolian/eolian_parsing.c \ 112tests/eolian/eolian_parsing.c \
113tests/eolian/eolian_aux.c \
112tests/eolian/eolian_static.c \ 114tests/eolian/eolian_static.c \
113tests/eolian/eolian_generation.c \ 115tests/eolian/eolian_generation.c \
114tests/eolian/eolian_generated_future.c \ 116tests/eolian/eolian_generated_future.c \
diff --git a/src/lib/eolian/Eolian_Aux.h b/src/lib/eolian/Eolian_Aux.h
new file mode 100644
index 0000000000..4313d49d6d
--- /dev/null
+++ b/src/lib/eolian/Eolian_Aux.h
@@ -0,0 +1,180 @@
1#ifndef EOLIAN_AUX_H
2#define EOLIAN_AUX_H
3
4#include <Eolian.h>
5
6#ifdef EAPI
7# undef EAPI
8#endif
9
10#ifdef _WIN32
11# ifdef EFL_BUILD
12# ifdef DLL_EXPORT
13# define EAPI __declspec(dllexport)
14# else
15# define EAPI
16# endif
17# else
18# define EAPI __declspec(dllimport)
19# endif
20#else
21# ifdef __GNUC__
22# if __GNUC__ >= 4
23# define EAPI __attribute__ ((visibility("default")))
24# else
25# define EAPI
26# endif
27# else
28# define EAPI
29# endif
30#endif
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36/**
37 * @page eolian_aux_main Eolian Auxiliary Library (BETA)
38 *
39 * @date 2018 (created)
40 *
41 * @section toc Table of Contents
42 *
43 * @li @ref eolian_aux_main_intro
44 *
45 * @section eolian_main_intro Introduction
46 *
47 * This is the Eolian auxiliary library, providing API to support generators
48 * and other utilities which do not fit into the primary Eolian library. All
49 * these APIs are built on top of the core Eolian APIs.
50 *
51 * Recommended reading:
52 *
53 * @li @ref Eolian
54 *
55 * @addtogroup Eolian
56 * @{
57 */
58
59#ifdef EFL_BETA_API_SUPPORT
60
61/**
62 * @brief Build reverse children hierarchy of an Eolian state.
63 *
64 * The point of this is basically to figure out reverse inheritance. The
65 * keys of the returned hash will be class pointers and the values will
66 * be lists. If classes A and B both inherit from C, they will be in C's
67 * list after lookup.
68 *
69 * You are responsible for freeing this hash using standard eina_hash_free().
70 *
71 * @param[in] state the Eolian state.
72 * @return a hash containing the hierarchy.
73 *
74 * @ingroup Eolian
75 */
76EAPI Eina_Hash *eolian_aux_state_class_children_find(const Eolian_State *state);
77
78/**
79 * @brief Get all APIs that are usable on the class.
80 *
81 * The @p funcs parameter will contain the functions, while @p events will
82 * contain events. The initial items in the lists will be the funcs and
83 * events defined by the class itself, followed by those defined in the
84 * classes it inherits from.
85 *
86 * Funcs will contain implement pointers, events will contain event pointers.
87 *
88 * The @p ownfuncs param defines how many of the list's items are the classes'
89 * own API. Same happens with @p ownevs for events.
90 *
91 * You are responsible for freeing the returned lists but not their contents.
92 * If you want to skip either of the lists, pass NULL.
93 *
94 * @param[in] klass the class.
95 * @param[out] funcs the functions list reference, NULL if not used.
96 * @param[out] events the event list reference, NULL if not used.
97 * @param[out] ownfuncs the number of own functions, NULL if not used.
98 * @param[out] ownevs the number of own events, NULL if not used.
99 * @return the total number of items written into either list.
100 *
101 * @ingroup Eolian
102 */
103EAPI size_t eolian_aux_class_callables_get(const Eolian_Class *klass, Eina_List **funcs, Eina_List **events, size_t *ownfuncs, size_t *ownevs);
104
105/**
106 * @brief Get all implementations of a function in a state.
107 *
108 * Given a function and a childen hierarchy from
109 * eolian_aux_state_class_children_find(), this will func
110 * all implementations of that function in the system. This
111 * is useful for various utilities. You need to free the list
112 * but not the contents.
113 *
114 * @param[in] func the function.
115 * @param[in] class_children the children hierarchy.
116 * @return a list of implementations.
117 *
118 * @ingroup Eolian
119 */
120EAPI Eina_List *eolian_aux_function_all_implements_get(const Eolian_Function *func, Eina_Hash *class_children);
121
122/**
123 * @brief Get previous implementation in the inheritance hierarchy.
124 *
125 * This performs a depth-first search in the hierarchy, starting with the
126 * specific given implementation. Once it is found, this parent implementation
127 * is returned.
128 *
129 * @param[in] impl the implementation.
130 * @return the parent implementation.
131 *
132 * @ingroup Eolian
133 */
134EAPI const Eolian_Implement *eolian_aux_implement_parent_get(const Eolian_Implement *impl);
135
136/**
137 * @brief Get documentation for an implementaiton.
138 *
139 * This first checks if the implementation has documentation for the given
140 * type. If so, it is returned; if not, parent implementations as specified
141 * in eolian_aux_implement_parent_get() are searched and the first one to
142 * have the documentation is used.
143 *
144 * @param[in] impl the implementation.
145 * @param[in] ftype the function type (method, property, getter, setter).
146 * @return the documentation or NULL.
147 *
148 * @ingroup Eolian
149 */
150EAPI const Eolian_Documentation *eolian_aux_implement_documentation_get(const Eolian_Implement *impl, Eolian_Function_Type ftype);
151
152/**
153 * @brief Get documentation fallback for an implementation.
154 *
155 * This is used when the implement does not have a "common" documentation
156 * block. If the given implement is a getter and not a setter, this returns
157 * the getter's documentation. If it's a setter but not a getter, it returns
158 * the setter documentation. Otherwise, it returns NULL.
159 *
160 * @param[in] impl the implementation.
161 * @return the documentation or NULL.
162 *
163 * @ingroup Eolian
164 */
165EAPI const Eolian_Documentation *eolian_aux_implement_documentation_fallback_get(const Eolian_Implement *impl);
166
167#endif
168
169/**
170 * @}
171 */
172
173#ifdef __cplusplus
174} // extern "C" {
175#endif
176
177#undef EAPI
178#define EAPI
179
180#endif
diff --git a/src/lib/eolian/eolian_aux.c b/src/lib/eolian/eolian_aux.c
new file mode 100644
index 0000000000..a66c02c58e
--- /dev/null
+++ b/src/lib/eolian/eolian_aux.c
@@ -0,0 +1,294 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include "Eolian_Aux.h"
6
7static void
8_hashlist_free(void *ptr)
9{
10 eina_list_free((Eina_List *)ptr);
11}
12
13EAPI Eina_Hash *
14eolian_aux_state_class_children_find(const Eolian_State *state)
15{
16 if (!state)
17 return NULL;
18
19 Eina_Hash *h = eina_hash_pointer_new(_hashlist_free);
20 Eina_Iterator *itr = eolian_state_classes_get(state);
21 if (!itr)
22 return h;
23
24 const Eolian_Class *cl;
25 EINA_ITERATOR_FOREACH(itr, cl)
26 {
27 const Eolian_Class *icl = eolian_class_parent_get(cl);
28 if (icl)
29 eina_hash_set(h, &icl, eina_list_append(eina_hash_find(h, &icl), cl));
30 Eina_Iterator *iitr = eolian_class_extensions_get(cl);
31 EINA_ITERATOR_FOREACH(iitr, icl)
32 {
33 eina_hash_set(h, &icl,
34 eina_list_append(eina_hash_find(h, &icl), cl));
35 }
36 eina_iterator_free(iitr);
37 }
38 eina_iterator_free(itr);
39
40 return h;
41}
42
43static size_t
44_callables_find_body(const Eolian_Class *pcl,
45 Eina_List **funcs, Eina_List **events,
46 Eina_Hash *written)
47{
48 Eina_Iterator *iitr;
49 const Eolian_Implement *imp;
50 const Eolian_Event *ev;
51 size_t total = 0;
52
53 if (!funcs)
54 goto justevs;
55
56 iitr = eolian_class_implements_get(pcl);
57 EINA_ITERATOR_FOREACH(iitr, imp)
58 {
59 const Eolian_Function *ifn =
60 eolian_implement_function_get(imp, NULL);
61 if (eina_hash_find(written, &ifn))
62 continue;
63 *funcs = eina_list_append(*funcs, imp);
64 ++total;
65 }
66 eina_iterator_free(iitr);
67
68 if (!events)
69 return total;
70justevs:
71 iitr = eolian_class_events_get(pcl);
72 EINA_ITERATOR_FOREACH(iitr, ev)
73 {
74 /* events do not override */
75 *events = eina_list_append(*events, ev);
76 ++total;
77 }
78 eina_iterator_free(iitr);
79 return total;
80}
81
82static size_t
83_callables_find(const Eolian_Class *cl, Eina_List **funcs,
84 Eina_List **events, Eina_Hash *written)
85{
86 size_t total = 0;
87 if (!funcs && !events)
88 return total;
89
90 const Eolian_Class *pcl = eolian_class_parent_get(cl);
91 if (pcl)
92 total += _callables_find_body(pcl, funcs, events, written);
93
94 Eina_Iterator *itr = eolian_class_extensions_get(cl);
95 EINA_ITERATOR_FOREACH(itr, pcl)
96 total += _callables_find_body(pcl, funcs, events, written);
97
98 return total;
99}
100
101EAPI size_t
102eolian_aux_class_callables_get(const Eolian_Class *klass,
103 Eina_List **funcs, Eina_List **events,
104 size_t *ownfuncs, size_t *ownevs)
105{
106 size_t of = 0, oe = 0, total = 0;
107 if (!klass || (!funcs && !events))
108 {
109 if (ownfuncs) *ownfuncs = of;
110 if (ownevs) *ownevs = oe;
111 return total;
112 }
113
114 Eina_Hash *written = eina_hash_pointer_new(NULL);
115 if (funcs)
116 {
117 const Eolian_Implement *imp;
118 Eina_Iterator *itr = eolian_class_implements_get(klass);
119 EINA_ITERATOR_FOREACH(itr, imp)
120 {
121 const Eolian_Function *ifn =
122 eolian_implement_function_get(imp, NULL);
123 eina_hash_set(written, &ifn, ifn);
124 *funcs = eina_list_append(*funcs, imp);
125 ++of;
126 }
127 eina_iterator_free(itr);
128 }
129 if (events)
130 {
131 const Eolian_Event *ev;
132 Eina_Iterator *itr = eolian_class_events_get(klass);
133 EINA_ITERATOR_FOREACH(itr, ev)
134 {
135 /* no need to mark in written, events do not override */
136 *events = eina_list_append(*events, ev);
137 ++oe;
138 }
139 }
140 if (ownfuncs) *ownfuncs = of;
141 if (ownevs) *ownevs = oe;
142 total = of + oe;
143 total += _callables_find(klass, funcs, events, written);
144 eina_hash_free(written);
145 return total;
146}
147
148static void
149_all_impls_find(Eina_List **l, const Eolian_Class *cl,
150 const Eolian_Function *func, Eina_Hash *got,
151 Eina_Hash *children)
152{
153 if (eina_hash_find(got, &cl))
154 return;
155 eina_hash_add(got, &cl, cl);
156 Eina_Iterator *itr = eolian_class_implements_get(cl);
157 const Eolian_Implement *imp;
158 EINA_ITERATOR_FOREACH(itr, imp)
159 {
160 const Eolian_Function *ofn = eolian_implement_function_get(imp, NULL);
161 if (ofn == func)
162 {
163 *l = eina_list_append(*l, imp);
164 break;
165 }
166 }
167 eina_iterator_free(itr);
168 Eina_List *tl;
169 const Eolian_Class *icl;
170 EINA_LIST_FOREACH(eina_hash_find(children, &cl), tl, icl)
171 _all_impls_find(l, icl, func, got, children);
172}
173
174EAPI Eina_List *
175eolian_aux_function_all_implements_get(const Eolian_Function *func,
176 Eina_Hash *class_children)
177{
178 if (!class_children)
179 return NULL;
180
181 const Eolian_Class *cl = eolian_implement_class_get(
182 eolian_function_implement_get(func));
183
184 Eina_List *ret = NULL;
185 Eina_Hash *got = eina_hash_pointer_new(NULL);
186 _all_impls_find(&ret, cl, func, got, class_children);
187
188 eina_hash_free(got);
189 return ret;
190}
191
192static const Eolian_Implement * _parent_impl_find(
193 const char *fulln, const Eolian_Class *cl);
194
195static const Eolian_Implement *
196_parent_impl_find_body(const Eolian_Class *icl, const char *fulln)
197{
198 Eina_Iterator *iitr = eolian_class_implements_get(icl);
199 const Eolian_Implement *iimpl;
200 EINA_ITERATOR_FOREACH(iitr, iimpl)
201 {
202 if (eolian_implement_name_get(iimpl) == fulln)
203 {
204 eina_iterator_free(iitr);
205 return iimpl;
206 }
207 }
208 eina_iterator_free(iitr);
209 return _parent_impl_find(fulln, icl);
210 }
211
212static const Eolian_Implement *
213_parent_impl_find(const char *fulln, const Eolian_Class *cl)
214{
215 const Eolian_Implement *iret = NULL;
216 const Eolian_Class *icl = eolian_class_parent_get(cl);
217 if (icl)
218 iret = _parent_impl_find_body(icl, fulln);
219 if (iret)
220 return iret;
221 Eina_Iterator *itr = eolian_class_extensions_get(cl);
222 EINA_ITERATOR_FOREACH(itr, icl)
223 {
224 iret = _parent_impl_find_body(icl, fulln);
225 if (iret)
226 {
227 eina_iterator_free(itr);
228 return iret;
229 }
230 }
231 eina_iterator_free(itr);
232 return NULL;
233}
234
235EAPI const Eolian_Implement *
236eolian_aux_implement_parent_get(const Eolian_Implement *impl)
237{
238 return _parent_impl_find(eolian_implement_name_get(impl),
239 eolian_implement_implementing_class_get(impl));
240}
241
242static const Eolian_Documentation *
243_parent_documentation_find(const Eolian_Implement *impl,
244 Eolian_Function_Type ftype)
245{
246 const Eolian_Implement *pimpl = eolian_aux_implement_parent_get(impl);
247 if (!pimpl)
248 return NULL;
249
250 const Eolian_Documentation *pdoc =
251 eolian_implement_documentation_get(pimpl, ftype);
252 if (!pdoc)
253 return _parent_documentation_find(pimpl, ftype);
254
255 return pdoc;
256}
257
258EAPI const Eolian_Documentation *
259eolian_aux_implement_documentation_get(const Eolian_Implement *impl,
260 Eolian_Function_Type ftype)
261{
262 const Eolian_Documentation *ret =
263 eolian_implement_documentation_get(impl, ftype);
264
265 if (ret)
266 return ret;
267
268 const Eolian_Class *icl = eolian_implement_implementing_class_get(impl);
269 if (eolian_implement_class_get(impl) == icl)
270 return NULL;
271
272 const Eolian_Implement *oimp = eolian_function_implement_get(
273 eolian_implement_function_get(impl, NULL));
274 if ((ftype == EOLIAN_PROP_GET) && !eolian_implement_is_prop_get(oimp))
275 return NULL;
276 if ((ftype == EOLIAN_PROP_SET) && !eolian_implement_is_prop_set(oimp))
277 return NULL;
278
279 return _parent_documentation_find(impl, ftype);
280}
281
282EAPI const Eolian_Documentation *
283eolian_aux_implement_documentation_fallback_get(const Eolian_Implement *impl)
284{
285 Eina_Bool ig = eolian_implement_is_prop_get(impl),
286 is = eolian_implement_is_prop_set(impl);
287
288 if (ig && !is)
289 return eolian_implement_documentation_get(impl, EOLIAN_PROP_GET);
290 else if (is && !ig)
291 return eolian_implement_documentation_get(impl, EOLIAN_PROP_SET);
292
293 return NULL;
294}
diff --git a/src/lib/eolian/meson.build b/src/lib/eolian/meson.build
index 2be0197212..083d5cdaa5 100644
--- a/src/lib/eolian/meson.build
+++ b/src/lib/eolian/meson.build
@@ -31,7 +31,8 @@ eolian_src = [
31'database_expr_api.c', 31'database_expr_api.c',
32'database_var.c', 32'database_var.c',
33'database_var_api.c', 33'database_var_api.c',
34'database_validate.c' 34'database_validate.c',
35'eolian_aux.c'
35] 36]
36 37
37eolian_lib = library('eolian', eolian_src, 38eolian_lib = library('eolian', eolian_src,
@@ -50,6 +51,11 @@ eolian = declare_dependency(
50 51
51eolian_include_dir = join_paths(dir_data, 'eolian', 'include') 52eolian_include_dir = join_paths(dir_data, 'eolian', 'include')
52 53
53install_headers('Eolian.h', 54eolian_header_src = [
55'Eolian.h',
56'Eolian_Aux.h'
57]
58
59install_headers(eolian_header_src,
54 install_dir : dir_package_include 60 install_dir : dir_package_include
55) 61)
diff --git a/src/tests/eolian/data_aux/a.eo b/src/tests/eolian/data_aux/a.eo
new file mode 100644
index 0000000000..f610fcb998
--- /dev/null
+++ b/src/tests/eolian/data_aux/a.eo
@@ -0,0 +1,12 @@
1class A(C) {
2 methods {
3 baz {}
4 }
5 events {
6 test2: void;
7 }
8 implements {
9 C.foo;
10 C.bar;
11 }
12}
diff --git a/src/tests/eolian/data_aux/b.eo b/src/tests/eolian/data_aux/b.eo
new file mode 100644
index 0000000000..3b00c23308
--- /dev/null
+++ b/src/tests/eolian/data_aux/b.eo
@@ -0,0 +1,2 @@
1class B(C) {
2}
diff --git a/src/tests/eolian/data_aux/c.eo b/src/tests/eolian/data_aux/c.eo
new file mode 100644
index 0000000000..999c5cda38
--- /dev/null
+++ b/src/tests/eolian/data_aux/c.eo
@@ -0,0 +1,9 @@
1class C {
2 methods {
3 foo {}
4 bar {}
5 }
6 events {
7 test: void;
8 }
9}
diff --git a/src/tests/eolian/eolian_aux.c b/src/tests/eolian/eolian_aux.c
new file mode 100644
index 0000000000..b7f263f483
--- /dev/null
+++ b/src/tests/eolian/eolian_aux.c
@@ -0,0 +1,146 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Eolian_Aux.h>
6
7#include "eolian_suite.h"
8
9EFL_START_TEST(eolian_aux_children)
10{
11 Eolian_State *eos = eolian_state_new();
12
13 fail_if(!eolian_state_directory_add(eos, TESTS_SRC_DIR"/data_aux"));
14 fail_if(!eolian_state_file_parse(eos, TESTS_SRC_DIR"/data_aux/a.eo"));
15 fail_if(!eolian_state_file_parse(eos, TESTS_SRC_DIR"/data_aux/b.eo"));
16
17 Eina_Hash *chash = eolian_aux_state_class_children_find(eos);
18 fail_if(!chash);
19
20 const Eolian_Class *acl = eolian_state_class_by_name_get(eos, "A");
21 fail_if(!acl);
22
23 const Eolian_Class *bcl = eolian_state_class_by_name_get(eos, "B");
24 fail_if(!bcl);
25
26 const Eolian_Class *ccl = eolian_state_class_by_name_get(eos, "C");
27 fail_if(!ccl);
28
29 Eina_List *cl = eina_hash_find(chash, &ccl);
30 fail_if(!cl);
31
32 fail_if(eina_list_count(cl) != 2);
33 if (eina_list_nth(cl, 0) == bcl)
34 fail_if(eina_list_nth(cl, 1) != acl);
35 else
36 {
37 fail_if(eina_list_nth(cl, 0) != acl);
38 fail_if(eina_list_nth(cl, 1) != bcl);
39 }
40
41 eina_hash_free(chash);
42 eolian_state_free(eos);
43}
44EFL_END_TEST
45
46EFL_START_TEST(eolian_aux_implements)
47{
48 Eolian_State *eos = eolian_state_new();
49
50 fail_if(!eolian_state_directory_add(eos, TESTS_SRC_DIR"/data_aux"));
51 fail_if(!eolian_state_file_parse(eos, TESTS_SRC_DIR"/data_aux/a.eo"));
52 fail_if(!eolian_state_file_parse(eos, TESTS_SRC_DIR"/data_aux/b.eo"));
53
54 Eina_Hash *chash = eolian_aux_state_class_children_find(eos);
55 fail_if(!chash);
56
57 const Eolian_Class *ccl = eolian_state_class_by_name_get(eos, "C");
58 fail_if(!ccl);
59
60 const Eolian_Function *fn = eolian_class_function_by_name_get(ccl, "foo", EOLIAN_METHOD);
61 fail_if(!fn);
62
63 Eina_List *imps = eolian_aux_function_all_implements_get(fn, chash);
64 fail_if(!imps);
65 fail_if(eina_list_count(imps) != 2);
66
67 eina_list_free(imps);
68 eina_hash_free(chash);
69 eolian_state_free(eos);
70}
71EFL_END_TEST
72
73EFL_START_TEST(eolian_aux_callables)
74{
75 Eolian_State *eos = eolian_state_new();
76
77 fail_if(!eolian_state_directory_add(eos, TESTS_SRC_DIR"/data_aux"));
78 fail_if(!eolian_state_file_parse(eos, TESTS_SRC_DIR"/data_aux/a.eo"));
79
80 const Eolian_Class *acl = eolian_state_class_by_name_get(eos, "A");
81 fail_if(!acl);
82
83 Eina_List *funcs = NULL;
84 Eina_List *evs = NULL;
85 size_t ofuncs = 0;
86 size_t oevs = 0;
87
88 size_t clbls = eolian_aux_class_callables_get(acl, &funcs, &evs, &ofuncs, &oevs);
89 fail_if(clbls != 5);
90 fail_if(ofuncs != 3);
91 fail_if(oevs != 1);
92 fail_if(eina_list_count(funcs) != 3);
93 fail_if(eina_list_count(evs) != 2);
94
95 eina_list_free(funcs);
96 eina_list_free(evs);
97 eolian_state_free(eos);
98}
99EFL_END_TEST
100
101EFL_START_TEST(eolian_aux_implparent)
102{
103 Eolian_State *eos = eolian_state_new();
104
105 fail_if(!eolian_state_directory_add(eos, TESTS_SRC_DIR"/data_aux"));
106 fail_if(!eolian_state_file_parse(eos, TESTS_SRC_DIR"/data_aux/a.eo"));
107
108 const Eolian_Class *acl = eolian_state_class_by_name_get(eos, "A");
109 fail_if(!acl);
110
111 const Eolian_Class *ccl = eolian_state_class_by_name_get(eos, "C");
112 fail_if(!ccl);
113
114 const Eolian_Function *fn = eolian_class_function_by_name_get(ccl, "foo", EOLIAN_METHOD);
115 fail_if(!fn);
116
117 const Eolian_Implement *impl = NULL;
118 Eina_Iterator *itr = eolian_class_implements_get(acl);
119 EINA_ITERATOR_FOREACH(itr, impl)
120 {
121 if (eolian_implement_function_get(impl, NULL) == fn)
122 break;
123 }
124 eina_iterator_free(itr);
125
126 fail_if(!impl);
127 fail_if(eolian_implement_function_get(impl, NULL) != fn);
128
129 fail_if(eolian_implement_class_get(impl) != ccl);
130 fail_if(eolian_implement_implementing_class_get(impl) != acl);
131
132 const Eolian_Implement *pimpl = eolian_aux_implement_parent_get(impl);
133 fail_if(eolian_implement_class_get(pimpl) != ccl);
134 fail_if(eolian_implement_implementing_class_get(pimpl) != ccl);
135
136 eolian_state_free(eos);
137}
138EFL_END_TEST
139
140void eolian_aux_test(TCase *tc)
141{
142 tcase_add_test(tc, eolian_aux_children);
143 tcase_add_test(tc, eolian_aux_implements);
144 tcase_add_test(tc, eolian_aux_callables);
145 tcase_add_test(tc, eolian_aux_implparent);
146}
diff --git a/src/tests/eolian/eolian_suite.c b/src/tests/eolian/eolian_suite.c
index 3b6de0a68d..3229be33ce 100644
--- a/src/tests/eolian/eolian_suite.c
+++ b/src/tests/eolian/eolian_suite.c
@@ -14,6 +14,7 @@ static const Efl_Test_Case etc[] = {
14 { "Eolian Parsing", eolian_parsing_test}, 14 { "Eolian Parsing", eolian_parsing_test},
15 { "Eolian Static Analysis", eolian_static_test}, 15 { "Eolian Static Analysis", eolian_static_test},
16 { "Eolian Generation", eolian_generation_test}, 16 { "Eolian Generation", eolian_generation_test},
17 { "Eolian Aux", eolian_aux_test},
17 { NULL, NULL } 18 { NULL, NULL }
18}; 19};
19 20
diff --git a/src/tests/eolian/eolian_suite.h b/src/tests/eolian/eolian_suite.h
index d40b1df924..3b3279ebd5 100644
--- a/src/tests/eolian/eolian_suite.h
+++ b/src/tests/eolian/eolian_suite.h
@@ -4,6 +4,7 @@
4#include <check.h> 4#include <check.h>
5#include "../efl_check.h" 5#include "../efl_check.h"
6void eolian_parsing_test(TCase *tc); 6void eolian_parsing_test(TCase *tc);
7void eolian_aux_test(TCase *tc);
7void eolian_static_test(TCase *tc); 8void eolian_static_test(TCase *tc);
8void eolian_generation_test(TCase *tc); 9void eolian_generation_test(TCase *tc);
9 10
diff --git a/src/tests/eolian/meson.build b/src/tests/eolian/meson.build
index 4c6102a78d..a453974cc0 100644
--- a/src/tests/eolian/meson.build
+++ b/src/tests/eolian/meson.build
@@ -4,6 +4,7 @@ priv_eo_files = [
4 4
5eolian_test_src = [ 5eolian_test_src = [
6'eolian_parsing.c', 6'eolian_parsing.c',
7'eolian_aux.c',
7'eolian_generation.c', 8'eolian_generation.c',
8'eolian_generated_future.c', 9'eolian_generated_future.c',
9'eolian_suite.c', 10'eolian_suite.c',