summaryrefslogtreecommitdiff
path: root/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
diff options
context:
space:
mode:
authorSavio Sena <savio@expertisesolutions.com.br>2014-05-03 00:55:51 +0200
committerCedric Bail <cedric.bail@free.fr>2014-05-03 00:56:32 +0200
commit46b6e8a563bd429690e7bffba4e98d06aa40798d (patch)
treeb7a2aebfc32bcc6d7a2600072a00d69a9f68d9a1 /src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
parent64c6c63725d96f03baf34b660ca71e13b29078c1 (diff)
eolian_cxx: initial version of the EFL C++ Bindings Generator.
Summary: This patch adds 'eolian_cxx' -- a C++ bindings generator -- to the EFL tree. Eolian Cxx uses Eolian API to read .eo files and generate .eo.hh. It relies/depends on Eo Cxx and Eina Cxx (both non-generated bindings). src/bin/eolian_cxx: The eolian_cxx program. src/lib/eolian_cxx: A header-only library that implements the C++ code generation that binds the .eo classes. =Examples= src/examples/eolian_cxx/eolian_cxx_simple_01.cc: The simplest example, it just uses some "dummy" generated C++ classes. src/examples/eolian_cxx/eolian_cxx_inherit_01.cc: Illustrates how pure C++ classes inherit from .eo generated classes. src/examples/evas/evas_cxx_rectangle.cc: More realistic example using the generated bindings Evas Cxx. Still a bit shallow because we don't have full fledged .eo descriptions yet, but will be improved. =Important= The generated code is not supported and not a stable API/ABI. It is here to gather people interest and get review before we set things in stone for release 1.11. @feature Reviewers: cedric, smohanty, raster, stefan_schmidt CC: felipealmeida, JackDanielZ, cedric, stefan Differential Revision: https://phab.enlightenment.org/D805 Signed-off-by: Cedric Bail <cedric.bail@free.fr>
Diffstat (limited to 'src/lib/eolian_cxx/grammar/inheritance_base_generator.hh')
-rw-r--r--src/lib/eolian_cxx/grammar/inheritance_base_generator.hh382
1 files changed, 382 insertions, 0 deletions
diff --git a/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh b/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
new file mode 100644
index 0000000000..8cc25389a0
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
@@ -0,0 +1,382 @@
1
2#ifndef EOLIAN_CXX_STD_INHERITANCE_GENERATOR_HH
3#define EOLIAN_CXX_STD_INHERITANCE_GENERATOR_HH
4
5#include <iosfwd>
6#include <cassert>
7#include <algorithm>
8
9#include "eo_types.hh"
10#include "tab.hh"
11#include "parameters_generator.hh"
12
13#include "eo_class_functions_generator.hh"
14
15namespace efl { namespace eolian { namespace grammar {
16
17struct inheritance_operation
18{
19 eo_class const& _cls;
20 functions_container_type::size_type _idx;
21 inheritance_operation(eo_class const& cls, functions_container_type::size_type idx)
22 : _cls(cls), _idx(idx)
23 {}
24};
25
26inline std::ostream&
27operator<<(std::ostream& out, inheritance_operation const& x)
28{
29 assert(x._idx < x._cls.functions.size());
30 eo_function const& func = x._cls.functions[x._idx];
31 out << tab(1)
32 << "ops[" << x._idx << "].func = reinterpret_cast<void*>(& ::"
33 << x._cls.name << "_" << func.name << "_wrapper<T>);" << endl
34 << tab(1) << "ops[" << x._idx << "].api_func = reinterpret_cast<void*>(& ::"
35 << func.impl << ");" << endl
36 << tab(1) << "ops[" << x._idx << "].op = EO_OP_OVERRIDE;" << endl
37 << tab(1) << "ops[" << x._idx << "].op_type = EO_OP_TYPE_REGULAR;" << endl // XXX class ops
38 << tab(1) << "ops[" << x._idx << "].doc = NULL;" << endl
39 << endl;
40 return out;
41}
42
43struct inheritance_operations_description
44{
45 eo_class const& _cls;
46 inheritance_operations_description(eo_class const& cls)
47 : _cls(cls)
48 {}
49};
50
51inline std::ostream&
52operator<<(std::ostream& out, inheritance_operations_description const& x)
53{
54 out << "template <typename T>"
55 << endl << "int initialize_operation_description(efl::eo::detail::tag<"
56 << x._cls.name_space << "::" << x._cls.name << ">" << endl
57 << tab(11)
58 << ", Eo_Op_Description* ops)" << endl
59 << "{" << endl
60 << tab(1) << "(void)ops;" << endl;
61 functions_container_type::size_type n_ops = x._cls.functions.size();
62 for (functions_container_type::size_type i=0; i < n_ops; ++i)
63 {
64 out << inheritance_operation(x._cls, i);
65 }
66 out << tab(1) << "return 0;" << endl
67 << "}" << endl;
68
69 return out;
70}
71
72struct inheritance_wrapper
73{
74 eo_class const& _cls;
75 eo_function const& _func;
76 inheritance_wrapper(eo_class const& cls, eo_function const& func)
77 : _cls(cls), _func(func)
78 {}
79};
80
81inline std::ostream&
82operator<<(std::ostream& out, inheritance_wrapper const& x)
83{
84 out << "template <typename T>" << endl
85 << x._func.ret << " " << x._cls.name << "_" << x._func.name
86 << "_wrapper(Eo* objid EINA_UNUSED, "
87 << "efl::eo::detail::Inherit_Private_Data* self"
88 << (x._func.params.size() ? ", " : "")
89 << parameters_declaration(x._func.params)
90 << ")" << endl
91 << "{" << endl
92 << tab(1)
93 << (!function_is_void(x._func) ? "return ": "")
94 << "static_cast<T*>(self->this_)->"
95 << x._func.name << "(" << parameters_list(x._func.params) << ");" << endl
96 << "}" << endl << endl;
97
98 return out;
99}
100
101struct inheritance_wrappers
102{
103 eo_class const& _cls;
104 inheritance_wrappers(eo_class const& cls) : _cls(cls) {}
105};
106
107inline std::ostream&
108operator<<(std::ostream& out, inheritance_wrappers const& x)
109{
110 functions_container_type::const_iterator it,
111 first = x._cls.functions.begin(),
112 last = x._cls.functions.end();
113 for (it = first; it != last; ++it)
114 {
115 eo_function const& func = *it;
116 out << "template <typename T>" << endl
117 << func.ret << " " << x._cls.name << "_" << func.name
118 << "_wrapper(Eo* objid EINA_UNUSED, "
119 << "efl::eo::detail::Inherit_Private_Data* self"
120 << (func.params.size() ? ", " : "")
121 << parameters_declaration(func.params)
122 << ")" << endl
123 << "{" << endl
124 << tab(1)
125 << (!function_is_void(func) ? "return ": "")
126 << "static_cast<T*>(self->this_)->"
127 << func.name << "(" << parameters_list(func.params) << ");" << endl
128 << "}" << endl << endl;
129 }
130 return out;
131}
132
133struct inheritance_base_operations_size
134{
135 eo_class const& _cls;
136 inheritance_base_operations_size(eo_class const& cls)
137 : _cls(cls)
138 {}
139};
140
141inline std::ostream&
142operator<<(std::ostream& out, inheritance_base_operations_size const& x)
143{
144 out << "template<>"
145 << endl << "struct operation_description_class_size< "
146 << x._cls.name_space << "::" << x._cls.name << " >" << endl
147 << "{" << endl
148 << tab(1) << "static const int value = "
149 << x._cls.functions.size()
150 << ";" << endl
151 << "};" << endl
152 << endl;
153 return out;
154}
155
156struct inheritance_base_operations_function
157{
158 eo_class const& _cls;
159 eo_function const& _func;
160 inheritance_base_operations_function(eo_class const& cls, eo_function const& func)
161 : _cls(cls) , _func(func)
162 {}
163};
164
165inline std::ostream&
166operator<<(std::ostream& out, inheritance_base_operations_function const& x)
167{
168 eo_function const& func = x._func;
169 bool is_void = function_is_void(func);
170
171 out << tab(2) << "virtual " << func.ret << " "
172 << func.name << "("
173 << parameters_declaration(func.params) << ")" << endl
174 << tab(2) << "{" << endl;
175 if (!is_void)
176 {
177 out << tab(3) << func.ret << " _tmp_ret = {};" << endl;
178 }
179 out << tab(3)
180 << "eo_do_super(static_cast<T*>(this)->_eo_ptr()" << endl
181 << tab(4) << ", static_cast<T*>(this)->_eo_class()" << endl
182 << tab(4) << ", " << function_call(func)
183 << ");" << endl;
184 if (!is_void)
185 {
186 out << tab(3) << "return _tmp_ret;" << endl;
187 }
188 out << tab(2) << "}" << endl << endl;
189 return out;
190}
191
192struct inheritance_base_operations
193{
194 eo_class const& _cls;
195 inheritance_base_operations(eo_class const& cls) : _cls(cls) {}
196};
197
198inline std::ostream&
199operator<<(std::ostream& out, inheritance_base_operations const& x)
200{
201 out << "template<>" << endl
202 << "struct operations< "
203 << x._cls.name_space << "::" << x._cls.name << " >" << endl
204 << "{" << endl
205 << tab(1) << "template <typename T>" << endl
206 << tab(1) << "struct type" << endl
207 << tab(1) << "{" << endl;
208 functions_container_type::const_iterator it,
209 first = x._cls.functions.begin(),
210 last = x._cls.functions.end();
211 for (it = first; it != last; ++it)
212 {
213 out << inheritance_base_operations_function(x._cls, *it);
214 }
215 out << tab(1) << "};" << endl
216 << "};" << endl << endl;
217 return out;
218}
219
220struct inheritance_call_constructor_arguments
221{
222 parameters_container_type const& _params;
223 inheritance_call_constructor_arguments(parameters_container_type const& params)
224 : _params(params)
225 {}
226};
227
228inline std::ostream&
229operator<<(std::ostream& out, inheritance_call_constructor_arguments const& x)
230{
231 parameters_container_type::size_type i, n = x._params.size();
232 for (i=0; i<n; i++)
233 {
234 if(i!=0) out << ", ";
235 out << "args.get<" << i << ">()";
236 }
237 return out;
238}
239
240struct inheritance_call_constructors
241{
242 eo_class const& _cls;
243 inheritance_call_constructors(eo_class const& cls) : _cls(cls) {}
244};
245
246inline std::ostream&
247operator<<(std::ostream& out, inheritance_call_constructors const& x)
248{
249 constructors_container_type::const_iterator it,
250 first = x._cls.constructors.begin(),
251 last = x._cls.constructors.end();
252 for (it = first; it != last; ++it)
253 {
254 eo_constructor const& ctor = *it;
255 out << "inline void" << endl
256 << "call_constructor(tag< "
257 << x._cls.name_space << "::" << x._cls.name << " >" << endl
258 << tab(5) << ", Eo* eo, Eo_Class const* cls EINA_UNUSED," << endl
259 << tab(5) << "args_class<"
260 << x._cls.name_space << "::" << x._cls.name
261 << ", ::std::tuple<"
262 << parameters_types(ctor.params)
263 << "> > const& args)" << endl
264 << "{" << endl
265 << tab(1) << "(void)args;" << endl
266 << tab(1)
267 << "eo_do_super(eo, cls, ::" << ctor.name
268 << "(" << inheritance_call_constructor_arguments(ctor.params)
269 << "));" << endl
270 << "}" << endl << endl;
271 }
272 return out;
273}
274
275struct inheritance_extension_function
276{
277 eo_function const& _func;
278 inheritance_extension_function(eo_function const& func) : _func(func) {}
279};
280
281inline std::ostream&
282operator<<(std::ostream& out, inheritance_extension_function const& x)
283{
284 bool is_void = function_is_void(x._func);
285 out << tab(2)
286 << x._func.ret << " "
287 << x._func.name << "("
288 << parameters_declaration(x._func.params)
289 << ")" << endl
290 << tab(2) << "{" << endl;
291
292 if (!is_void)
293 {
294 out << tab(3) << x._func.ret << " _tmp_ret = {};" << endl;
295 }
296
297 out << tab(3) << "eo_do(static_cast<T*>(this)->_eo_ptr(), "
298 << function_call(x._func) << ");" << endl;
299
300 if (!is_void)
301 {
302 out << tab(3) << "return _tmp_ret;" << endl;
303 }
304
305 out << tab(2) << "}" << endl
306 << endl;
307
308 return out;
309}
310
311struct inheritance_extension
312{
313 eo_class const& _cls;
314 inheritance_extension(eo_class const& cls) : _cls(cls) {}
315};
316
317inline std::ostream&
318operator<<(std::ostream& out, inheritance_extension const& x)
319{
320 std::string cls = x._cls.name_space + "::" + x._cls.name;
321 out << "template<>" << endl
322 << "struct extension_inheritance< "
323 << cls << ">" << endl
324 << "{" << endl
325 << tab(1) << "template <typename T>" << endl
326 << tab(1) << "struct type" << endl
327 << tab(1) << "{" << endl
328 << tab(2) << "operator " << cls << "() const" << endl
329 << tab(2) << "{" << endl
330 << tab(3) << "return " << cls
331 << "(eo_ref(static_cast<T const*>(this)->_eo_ptr()));" << endl
332 << tab(2) << "}" << endl
333 << endl;
334 functions_container_type::const_iterator it,
335 first = x._cls.functions.begin(),
336 last = x._cls.functions.end();
337 for (it = first; it != last; ++it)
338 {
339 out << inheritance_extension_function(*it);
340 }
341 out << tab(1) << "};" << endl
342 << "};" << endl
343 << endl;
344 return out;
345}
346
347struct inheritance_eo_class_getter
348{
349 eo_class const& _cls;
350 inheritance_eo_class_getter(eo_class const& cls)
351 : _cls(cls)
352 {}
353};
354
355inline std::ostream&
356operator<<(std::ostream& out, inheritance_eo_class_getter const& x)
357{
358 out << "inline Eo_Class const* get_eo_class(tag<"
359 << x._cls.name_space << "::" << x._cls.name << ">)" << endl
360 << "{" << endl
361 << tab(1) << "return (" << x._cls.eo_name << ");" << endl
362 << "}" << endl << endl;
363 return out;
364}
365
366inline void
367eo_inheritance_detail_generator(std::ostream& out, eo_class const& cls)
368{
369 out << inheritance_wrappers(cls)
370 << "namespace efl { namespace eo { namespace detail {" << endl << endl
371 << inheritance_base_operations(cls) << endl
372 << inheritance_base_operations_size(cls)
373 << inheritance_operations_description(cls)
374 << inheritance_call_constructors(cls)
375 << inheritance_extension(cls)
376 << inheritance_eo_class_getter(cls)
377 << "} } }" << endl;
378}
379
380} } } // namespace efl { namespace eolian { namespace grammar {
381
382#endif // EOLIAN_CXX_STD_INHERITANCE_GENERATOR_HH