summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitor Sousa <vitorsousasilva@gmail.com>2015-01-12 12:00:59 -0200
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2015-04-14 01:06:57 -0300
commitd53038989886a85b75c81a395269f6f349d7d78f (patch)
treed21410341bfd403ccc503a928687b304a734e9d5
parentbe58d02cb655c244a659abbcdb9ab44e8a5459ce (diff)
eolian_cxx: Add protected methods and events to C++ wrappers and fixes
Using eina::string_view in eolian generated interfaces (instead of std::string) to allow lightweight passing of both C strings and C++ std::string. Also, No longer using eina::optional in generated headers for types that already implements the concept of null state (like Eo wrappers and eina_accessor). Also fix allocating callback objects require by class methods (i.e. static) in static vectors so the memory will be freed when the programs exit. Added a new test case for testing callbacks on class methods. Moved method definitions and supplementary code from generated C++ wrappers to auxiliary header file (.eo.impl.hh) generated together with the main ".eo.hh" file. Updated Makefiles to list such files in the compilation and cleanup processes. Updated .gitignore to include these new generated files. Made general adjustments on the documentation of generated C++ wrappers Added "PREDEFINED" preprocessor macro definition in the Doxyfile.in in order to make some adjustments for better documentation in the C++ generated headers. Excluding generation of documentation for classes in the "eo_cxx" namespace (the namespace for "abstract" eolian C++ wrappers). Now generating the documentation for the events too. Hiding some auxiliary code from being documented. Some aesthetic adjustments for generated white space. Generate documentation for the main constructor of C++ wrappers and added auxiliary grammars to list parameters names.
-rw-r--r--.gitignore1
-rw-r--r--doc/Doxyfile.in6
-rw-r--r--src/Makefile_Ecore_Audio_Cxx.am7
-rw-r--r--src/Makefile_Ecore_Cxx.am6
-rw-r--r--src/Makefile_Edje_Cxx.am2
-rw-r--r--src/Makefile_Efl_Cxx.am6
-rw-r--r--src/Makefile_Eo_Cxx.am4
-rw-r--r--src/Makefile_Eolian_Cxx.am10
-rw-r--r--src/Makefile_Eolian_Cxx_Helper.am3
-rw-r--r--src/Makefile_Evas_Cxx.am37
-rw-r--r--src/bin/eolian_cxx/convert.cc3
-rw-r--r--src/bin/eolian_cxx/eolian_cxx.cc48
-rw-r--r--src/bin/eolian_cxx/eolian_wrappers.hh21
-rw-r--r--src/bin/eolian_cxx/type_lookup_table.cc34
-rw-r--r--src/bindings/eo_cxx/eo_concrete.hh6
-rw-r--r--src/bindings/eo_cxx/eo_cxx_interop.hh52
-rw-r--r--src/examples/eolian_cxx/Makefile.am7
-rw-r--r--src/lib/eolian_cxx/eo_generate.hh7
-rw-r--r--src/lib/eolian_cxx/eo_types.hh31
-rw-r--r--src/lib/eolian_cxx/grammar/comment.hh8
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh61
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_events_generator.hh11
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh18
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_generator.hh33
-rw-r--r--src/lib/eolian_cxx/grammar/eo_class_scope_guard_generator.hh61
-rw-r--r--src/lib/eolian_cxx/grammar/eo_header_generator.hh30
-rw-r--r--src/lib/eolian_cxx/grammar/inheritance_base_generator.hh73
-rw-r--r--src/lib/eolian_cxx/grammar/parameters_generator.hh106
-rw-r--r--src/lib/eolian_cxx/grammar/type_generator.hh26
-rw-r--r--src/tests/eolian_cxx/callback.c6
-rw-r--r--src/tests/eolian_cxx/callback.eo6
-rw-r--r--src/tests/eolian_cxx/eolian_cxx_test_callback.cc13
32 files changed, 620 insertions, 123 deletions
diff --git a/.gitignore b/.gitignore
index 4f04840..1da486e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,7 @@ tags
32*.eo.h 32*.eo.h
33*.eo.legacy.h 33*.eo.legacy.h
34*.eo.hh 34*.eo.hh
35*.eo.impl.hh
35*.eo.lua 36*.eo.lua
36*.luac 37*.luac
37.dir-locals.el 38.dir-locals.el
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index f18cc4f..b4afaf4 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -667,7 +667,7 @@ EXCLUDE_PATTERNS = *_private*
667# wildcard * is used, a substring. Examples: ANamespace, AClass, 667# wildcard * is used, a substring. Examples: ANamespace, AClass,
668# AClass::ANamespace, ANamespace::*Test 668# AClass::ANamespace, ANamespace::*Test
669 669
670EXCLUDE_SYMBOLS = 670EXCLUDE_SYMBOLS = eo_cxx::*
671 671
672# The EXAMPLE_PATH tag can be used to specify one or more files or 672# The EXAMPLE_PATH tag can be used to specify one or more files or
673# directories that contain example code fragments that are included (see 673# directories that contain example code fragments that are included (see
@@ -1441,7 +1441,9 @@ PREDEFINED = EINA_MAGIC_DEBUG \
1441 EAPI= \ 1441 EAPI= \
1442 EINA_PURE= \ 1442 EINA_PURE= \
1443 EINA_CONST= \ 1443 EINA_CONST= \
1444 EINA_UNUSED= 1444 EINA_UNUSED= \
1445 EFL_DOXYGEN=1 \
1446 "EO_CXX_INHERIT(name)=::name"
1445 1447
1446# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 1448# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
1447# this tag can be used to specify a list of macro names that should be expanded. 1449# this tag can be used to specify a list of macro names that should be expanded.
diff --git a/src/Makefile_Ecore_Audio_Cxx.am b/src/Makefile_Ecore_Audio_Cxx.am
index 498bcbf..bf564d2 100644
--- a/src/Makefile_Ecore_Audio_Cxx.am
+++ b/src/Makefile_Ecore_Audio_Cxx.am
@@ -20,6 +20,13 @@ lib/ecore_audio/Ecore_Audio.hh: $(generated_ecore_audio_cxx_bindings)
20 20
21generated_ecore_audio_cxx_all = \ 21generated_ecore_audio_cxx_all = \
22 $(generated_ecore_audio_cxx_bindings) \ 22 $(generated_ecore_audio_cxx_bindings) \
23 lib/ecore_audio/ecore_audio.eo.impl.hh \
24 lib/ecore_audio/ecore_audio_in.eo.impl.hh \
25 lib/ecore_audio/ecore_audio_out.eo.impl.hh \
26 lib/ecore_audio/ecore_audio_in_sndfile.eo.impl.hh \
27 lib/ecore_audio/ecore_audio_out_sndfile.eo.impl.hh \
28 lib/ecore_audio/ecore_audio_out_pulse.eo.impl.hh \
29 lib/ecore_audio/ecore_audio_in_tone.eo.impl.hh \
23 lib/ecore_audio/Ecore_Audio.hh 30 lib/ecore_audio/Ecore_Audio.hh
24 31
25CLEANFILES += $(generated_ecore_audio_cxx_all) 32CLEANFILES += $(generated_ecore_audio_cxx_all)
diff --git a/src/Makefile_Ecore_Cxx.am b/src/Makefile_Ecore_Cxx.am
index d81651a..b29a1c4 100644
--- a/src/Makefile_Ecore_Cxx.am
+++ b/src/Makefile_Ecore_Cxx.am
@@ -22,6 +22,12 @@ lib/ecore/Ecore.eo.hh: $(generated_ecore_cxx_bindings)
22 22
23generated_ecore_cxx_all = \ 23generated_ecore_cxx_all = \
24 $(generated_ecore_cxx_bindings) \ 24 $(generated_ecore_cxx_bindings) \
25 lib/ecore/ecore_poller.eo.impl.hh \
26 lib/ecore/ecore_job.eo.impl.hh \
27 lib/ecore/ecore_idler.eo.impl.hh \
28 lib/ecore/ecore_idle_exiter.eo.impl.hh \
29 lib/ecore/ecore_animator.eo.impl.hh \
30 lib/ecore/ecore_parent.eo.impl.hh \
25 lib/ecore/Ecore.eo.hh 31 lib/ecore/Ecore.eo.hh
26 32
27CLEANFILES += $(generated_ecore_cxx_all) 33CLEANFILES += $(generated_ecore_cxx_all)
diff --git a/src/Makefile_Edje_Cxx.am b/src/Makefile_Edje_Cxx.am
index 8d6b068..0b308b0 100644
--- a/src/Makefile_Edje_Cxx.am
+++ b/src/Makefile_Edje_Cxx.am
@@ -15,6 +15,8 @@ lib/edje/Edje.hh: $(generated_edje_cxx_bindings)
15 15
16generated_edje_cxx_all = \ 16generated_edje_cxx_all = \
17 $(generated_edje_cxx_bindings) \ 17 $(generated_edje_cxx_bindings) \
18 lib/edje/edje_object.eo.impl.hh \
19 lib/edje/edje_edit.eo.impl.hh \
18 lib/edje/Edje.hh 20 lib/edje/Edje.hh
19 21
20CLEANFILES += $(generated_edje_cxx_all) 22CLEANFILES += $(generated_edje_cxx_all)
diff --git a/src/Makefile_Efl_Cxx.am b/src/Makefile_Efl_Cxx.am
index 9df7c60..c555015 100644
--- a/src/Makefile_Efl_Cxx.am
+++ b/src/Makefile_Efl_Cxx.am
@@ -26,6 +26,12 @@ lib/efl/Efl.hh: $(generated_efl_cxx_bindings)
26 26
27generated_efl_cxx_all = \ 27generated_efl_cxx_all = \
28 $(generated_efl_cxx_bindings) \ 28 $(generated_efl_cxx_bindings) \
29 lib/efl/interfaces/efl_control.eo.impl.hh \
30 lib/efl/interfaces/efl_file.eo.impl.hh \
31 lib/efl/interfaces/efl_image.eo.impl.hh \
32 lib/efl/interfaces/efl_player.eo.impl.hh \
33 lib/efl/interfaces/efl_text.eo.impl.hh \
34 lib/efl/interfaces/efl_text_properties.eo.impl.hh \
29 lib/efl/Efl.hh 35 lib/efl/Efl.hh
30 36
31CLEANFILES += $(generated_efl_cxx_all) 37CLEANFILES += $(generated_efl_cxx_all)
diff --git a/src/Makefile_Eo_Cxx.am b/src/Makefile_Eo_Cxx.am
index 2f7dda6..b6315c8 100644
--- a/src/Makefile_Eo_Cxx.am
+++ b/src/Makefile_Eo_Cxx.am
@@ -3,7 +3,9 @@
3 3
4generated_eo_cxx_bindings = \ 4generated_eo_cxx_bindings = \
5lib/eo/eo_base.eo.hh \ 5lib/eo/eo_base.eo.hh \
6lib/eo/eo_abstract_class.eo.hh 6lib/eo/eo_base.eo.impl.hh \
7lib/eo/eo_abstract_class.eo.hh \
8lib/eo/eo_abstract_class.eo.impl.hh
7 9
8### Library 10### Library
9 11
diff --git a/src/Makefile_Eolian_Cxx.am b/src/Makefile_Eolian_Cxx.am
index cd58e3e..6dff267 100644
--- a/src/Makefile_Eolian_Cxx.am
+++ b/src/Makefile_Eolian_Cxx.am
@@ -15,6 +15,7 @@ lib/eolian_cxx/eo_validate.hh
15installed_eoliancxxgrammarheadersdir = $(includedir)/eolian-cxx-@VMAJ@/grammar/ 15installed_eoliancxxgrammarheadersdir = $(includedir)/eolian-cxx-@VMAJ@/grammar/
16dist_installed_eoliancxxgrammarheaders_DATA = \ 16dist_installed_eoliancxxgrammarheaders_DATA = \
17lib/eolian_cxx/grammar/comment.hh \ 17lib/eolian_cxx/grammar/comment.hh \
18lib/eolian_cxx/grammar/eo_class_scope_guard_generator.hh \
18lib/eolian_cxx/grammar/eo_class_constructors_generator.hh \ 19lib/eolian_cxx/grammar/eo_class_constructors_generator.hh \
19lib/eolian_cxx/grammar/eo_class_events_generator.hh \ 20lib/eolian_cxx/grammar/eo_class_events_generator.hh \
20lib/eolian_cxx/grammar/eo_class_functions_generator.hh \ 21lib/eolian_cxx/grammar/eo_class_functions_generator.hh \
@@ -95,10 +96,11 @@ tests/eolian_cxx/callback.eo.h \
95tests/eolian_cxx/simple.eo.c \ 96tests/eolian_cxx/simple.eo.c \
96tests/eolian_cxx/simple.eo.h \ 97tests/eolian_cxx/simple.eo.h \
97tests/eolian_cxx/simple.eo.hh \ 98tests/eolian_cxx/simple.eo.hh \
98tests/eolian_cxx/a.eo.hh tests/eolian_cxx/a.eo.c tests/eolian_cxx/a.eo.h \ 99tests/eolian_cxx/simple.eo.impl.hh \
99tests/eolian_cxx/b.eo.hh tests/eolian_cxx/b.eo.c tests/eolian_cxx/b.eo.h \ 100tests/eolian_cxx/a.eo.hh tests/eolian_cxx/a.eo.impl.hh tests/eolian_cxx/a.eo.c tests/eolian_cxx/a.eo.h \
100tests/eolian_cxx/c.eo.hh tests/eolian_cxx/c.eo.c tests/eolian_cxx/c.eo.h \ 101tests/eolian_cxx/b.eo.hh tests/eolian_cxx/b.eo.impl.hh tests/eolian_cxx/b.eo.c tests/eolian_cxx/b.eo.h \
101tests/eolian_cxx/d.eo.hh tests/eolian_cxx/d.eo.c tests/eolian_cxx/d.eo.h 102tests/eolian_cxx/c.eo.hh tests/eolian_cxx/c.eo.impl.hh tests/eolian_cxx/c.eo.c tests/eolian_cxx/c.eo.h \
103tests/eolian_cxx/d.eo.hh tests/eolian_cxx/d.eo.impl.hh tests/eolian_cxx/d.eo.c tests/eolian_cxx/d.eo.h
102 104
103tests_eolian_cxx_eolian_cxx_suite_CXXFLAGS = \ 105tests_eolian_cxx_eolian_cxx_suite_CXXFLAGS = \
104-I$(top_builddir)/src/lib/efl \ 106-I$(top_builddir)/src/lib/efl \
diff --git a/src/Makefile_Eolian_Cxx_Helper.am b/src/Makefile_Eolian_Cxx_Helper.am
index cb54cc4..bb656c8 100644
--- a/src/Makefile_Eolian_Cxx_Helper.am
+++ b/src/Makefile_Eolian_Cxx_Helper.am
@@ -15,4 +15,7 @@ SUFFIXES += .eo.hh
15%.eo.hh: %.eo $(_EOLIAN_CXX_DEP) 15%.eo.hh: %.eo $(_EOLIAN_CXX_DEP)
16 $(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -o $@ $< 16 $(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -o $@ $<
17 17
18%.eo.impl.hh: %.eo.hh $(_EOLIAN_CXX_DEP)
19 true $<
20
18CLEANFILES += $(BUILT_SOURCES) 21CLEANFILES += $(BUILT_SOURCES)
diff --git a/src/Makefile_Evas_Cxx.am b/src/Makefile_Evas_Cxx.am
index 96d5ab1..abe1aa6 100644
--- a/src/Makefile_Evas_Cxx.am
+++ b/src/Makefile_Evas_Cxx.am
@@ -49,15 +49,48 @@ lib/evas/Evas.hh: $(generated_evas_canvas_cxx_bindings)
49 @for i in $(generated_evas_canvas_cxx_bindings); do echo "#include <canvas/$$(basename $$i)>" >> $(top_builddir)/src/lib/evas/Evas.hh; done 49 @for i in $(generated_evas_canvas_cxx_bindings); do echo "#include <canvas/$$(basename $$i)>" >> $(top_builddir)/src/lib/evas/Evas.hh; done
50 @echo @ECHO_E@ "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/evas/Evas.hh 50 @echo @ECHO_E@ "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/evas/Evas.hh
51 51
52CLEANFILES += \ 52generated_evas_canvas_cxx_all = \
53$(generated_evas_canvas_cxx_bindings) \ 53$(generated_evas_canvas_cxx_bindings) \
54lib/evas/canvas/evas_line.eo.impl.hh \
55lib/evas/canvas/evas_polygon.eo.impl.hh \
56lib/evas/canvas/evas_rectangle.eo.impl.hh \
57lib/evas/canvas/evas_text.eo.impl.hh \
58lib/evas/canvas/evas_textblock.eo.impl.hh \
59lib/evas/canvas/evas_textgrid.eo.impl.hh \
60lib/evas/canvas/evas_signal_interface.eo.impl.hh \
61lib/evas/canvas/evas_object_smart.eo.impl.hh \
62lib/evas/canvas/evas_smart_clipped.eo.impl.hh \
63lib/evas/canvas/evas_table.eo.impl.hh \
64lib/evas/canvas/evas_common_interface.eo.impl.hh \
65lib/evas/canvas/evas_object.eo.impl.hh \
66lib/evas/canvas/evas_canvas.eo.impl.hh \
67lib/evas/canvas/evas_grid.eo.impl.hh \
68lib/evas/canvas/evas_image.eo.impl.hh \
69lib/evas/canvas/evas_out.eo.impl.hh \
70lib/evas/canvas/evas_draggable_interface.eo.impl.hh \
71lib/evas/canvas/evas_clickable_interface.eo.impl.hh \
72lib/evas/canvas/evas_scrollable_interface.eo.impl.hh \
73lib/evas/canvas/evas_selectable_interface.eo.impl.hh \
74lib/evas/canvas/evas_zoomable_interface.eo.impl.hh \
75lib/evas/canvas/evas_box.eo.impl.hh \
76lib/evas/canvas/evas_3d_camera.eo.impl.hh \
77lib/evas/canvas/evas_3d_light.eo.impl.hh \
78lib/evas/canvas/evas_3d_material.eo.impl.hh \
79lib/evas/canvas/evas_3d_mesh.eo.impl.hh \
80lib/evas/canvas/evas_3d_node.eo.impl.hh \
81lib/evas/canvas/evas_3d_object.eo.impl.hh \
82lib/evas/canvas/evas_3d_scene.eo.impl.hh \
83lib/evas/canvas/evas_3d_texture.eo.impl.hh \
54lib/evas/Evas.hh 84lib/evas/Evas.hh
55 85
86CLEANFILES += \
87$(generated_evas_canvas_cxx_all)
88
56installed_evascxxmainheadersdir = $(includedir)/evas-cxx-@VMAJ@/ 89installed_evascxxmainheadersdir = $(includedir)/evas-cxx-@VMAJ@/
57nodist_installed_evascxxmainheaders_DATA = lib/evas/Evas.hh 90nodist_installed_evascxxmainheaders_DATA = lib/evas/Evas.hh
58 91
59installed_evascxxcanvasheadersdir = $(includedir)/evas-cxx-@VMAJ@/canvas 92installed_evascxxcanvasheadersdir = $(includedir)/evas-cxx-@VMAJ@/canvas
60nodist_installed_evascxxcanvasheaders_DATA = $(generated_evas_canvas_cxx_bindings) 93nodist_installed_evascxxcanvasheaders_DATA = $(generated_evas_canvas_cxx_all)
61 94
62### Unit tests 95### Unit tests
63 96
diff --git a/src/bin/eolian_cxx/convert.cc b/src/bin/eolian_cxx/convert.cc
index d029999..22ee22f 100644
--- a/src/bin/eolian_cxx/convert.cc
+++ b/src/bin/eolian_cxx/convert.cc
@@ -141,6 +141,7 @@ _convert_property_set_to_function(Eolian_Class const& klass,
141 efl::eolian::eo_function set_ = 141 efl::eolian::eo_function set_ =
142 { 142 {
143 efl::eolian::eo_function::regular_, 143 efl::eolian::eo_function::regular_,
144 function_scope(prop_),
144 function_name(prop_) + "_set", 145 function_name(prop_) + "_set",
145 function_impl(prop_) + "_set", 146 function_impl(prop_) + "_set",
146 function_return_type(prop_, eolian_cxx::setter), 147 function_return_type(prop_, eolian_cxx::setter),
@@ -168,6 +169,7 @@ _convert_property_get_to_function(Eolian_Class const& klass,
168 efl::eolian::eo_function get_ = 169 efl::eolian::eo_function get_ =
169 { 170 {
170 efl::eolian::eo_function::regular_, 171 efl::eolian::eo_function::regular_,
172 function_scope(prop_),
171 function_name(prop_) + "_get", 173 function_name(prop_) + "_get",
172 function_impl(prop_) + "_get", 174 function_impl(prop_) + "_get",
173 function_return_type(prop_, eolian_cxx::getter), 175 function_return_type(prop_, eolian_cxx::getter),
@@ -291,6 +293,7 @@ convert_eolian_functions(efl::eolian::eo_class& cls, Eolian_Class const& klass)
291 { 293 {
292 cls.functions.push_back({ 294 cls.functions.push_back({
293 function_type(func), 295 function_type(func),
296 function_scope(func),
294 function_name(func), 297 function_name(func),
295 function_impl(func), 298 function_impl(func),
296 function_return_type(func), 299 function_return_type(func),
diff --git a/src/bin/eolian_cxx/eolian_cxx.cc b/src/bin/eolian_cxx/eolian_cxx.cc
index 93e9e44..7afa10d 100644
--- a/src/bin/eolian_cxx/eolian_cxx.cc
+++ b/src/bin/eolian_cxx/eolian_cxx.cc
@@ -119,30 +119,58 @@ generate(const Eolian_Class& klass, eolian_cxx::options_type const& opts)
119{ 119{
120 efl::eolian::eo_class cls = eolian_cxx::convert_eolian_class(klass); 120 efl::eolian::eo_class cls = eolian_cxx::convert_eolian_class(klass);
121 efl::eolian::eo_generator_options gen_opts = generator_options(klass); 121 efl::eolian::eo_generator_options gen_opts = generator_options(klass);
122 std::string outname = opts.out_file.empty() ? (class_base_file(klass) + ".hh") : opts.out_file; 122 std::string header_decl_file_name = opts.out_file.empty() ? (class_base_file(klass) + ".hh") : opts.out_file;
123
124 std::string header_impl_file_name = header_decl_file_name;
125 std::size_t dot_pos = header_impl_file_name.rfind(".hh");
126 if (dot_pos != std::string::npos)
127 header_impl_file_name.insert(dot_pos, ".impl");
128 else
129 header_impl_file_name.insert(header_impl_file_name.size(), ".impl");
130
131 std::size_t slash_pos = header_decl_file_name.rfind('/');
132 gen_opts.header_decl_file_name = (slash_pos == std::string::npos) ?
133 header_decl_file_name :
134 header_decl_file_name.substr(slash_pos+1);
135
136 slash_pos = header_impl_file_name.rfind('/');
137 gen_opts.header_impl_file_name = (slash_pos == std::string::npos) ?
138 header_impl_file_name :
139 header_impl_file_name.substr(slash_pos+1);
140
123 if (!opts.out_dir.empty()) 141 if (!opts.out_dir.empty())
124 { 142 {
125 outname = opts.out_dir + "/" + outname; 143 header_decl_file_name = opts.out_dir + "/" + header_decl_file_name;
144 header_impl_file_name = opts.out_dir + "/" + header_impl_file_name;
126 } 145 }
127 if(opts.out_file == "-") 146 if(opts.out_file == "-")
128 { 147 {
129 efl::eolian::generate(std::cout, cls, gen_opts); 148 efl::eolian::generate(std::cout, std::cout, cls, gen_opts);
130 } 149 }
131 else 150 else
132 { 151 {
133 std::ofstream outfile; 152 std::ofstream header_decl;
134 outfile.open(outname); 153 header_decl.open(header_decl_file_name);
135 if (outfile.good()) 154 if (!header_decl.good())
136 { 155 {
137 efl::eolian::generate(outfile, cls, gen_opts); 156 EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
138 outfile.close(); 157 << "Can't open output file: " << header_decl_file_name << std::endl;
158 return false;
139 } 159 }
140 else 160
161 std::ofstream header_impl;
162 header_impl.open(header_impl_file_name);
163 if (!header_impl.good())
141 { 164 {
142 EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain) 165 EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
143 << "Can't open output file: " << outname << std::endl; 166 << "Can't open output file: " << header_impl_file_name << std::endl;
144 return false; 167 return false;
145 } 168 }
169
170 efl::eolian::generate(header_decl, header_impl, cls, gen_opts);
171
172 header_decl.close();
173 header_impl.close();
146 } 174 }
147 return true; 175 return true;
148} 176}
diff --git a/src/bin/eolian_cxx/eolian_wrappers.hh b/src/bin/eolian_cxx/eolian_wrappers.hh
index d1b28a6..5cad797 100644
--- a/src/bin/eolian_cxx/eolian_wrappers.hh
+++ b/src/bin/eolian_cxx/eolian_wrappers.hh
@@ -25,6 +25,15 @@ getter_t const getter = {};
25struct method_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_METHOD; }; 25struct method_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_METHOD; };
26method_t const method = {}; 26method_t const method = {};
27 27
28inline efl::eolian::eolian_scope
29eolian_scope_cxx(Eolian_Object_Scope s)
30{
31 using efl::eolian::eolian_scope;
32 return s == EOLIAN_SCOPE_PRIVATE ? eolian_scope::private_ :
33 s == EOLIAN_SCOPE_PROTECTED ? eolian_scope::protected_ :
34 eolian_scope::public_;
35}
36
28inline const Eolian_Class* 37inline const Eolian_Class*
29class_from_file(std::string const& file) 38class_from_file(std::string const& file)
30{ 39{
@@ -195,11 +204,18 @@ function_is_constructor(Eolian_Class const& cls, Eolian_Function const& func)
195 return ::eolian_function_is_constructor(&func, &cls); 204 return ::eolian_function_is_constructor(&func, &cls);
196} 205}
197 206
207inline efl::eolian::eolian_scope
208function_scope(Eolian_Function const& func)
209{
210 return eolian_scope_cxx(::eolian_function_scope_get(&func));
211}
212
198inline bool 213inline bool
199function_is_visible(Eolian_Function const& func, Eolian_Function_Type func_type) 214function_is_visible(Eolian_Function const& func, Eolian_Function_Type func_type)
200{ 215{
201 return (::eolian_function_scope_get(&func) == EOLIAN_SCOPE_PUBLIC && 216 Eolian_Object_Scope s = ::eolian_function_scope_get(&func);
202 ! ::eolian_function_is_legacy_only(&func, func_type)); 217 return ((s == EOLIAN_SCOPE_PUBLIC || s == EOLIAN_SCOPE_PROTECTED) &&
218 !::eolian_function_is_legacy_only(&func, func_type));
203} 219}
204 220
205inline bool 221inline bool
@@ -388,6 +404,7 @@ event_create(Eolian_Class const& klass, const Eolian_Event *event_)
388 std::string name_ = safe_str(name); 404 std::string name_ = safe_str(name);
389 std::transform(name_.begin(), name_.end(), name_.begin(), 405 std::transform(name_.begin(), name_.end(), name_.begin(),
390 [](int c) { return c != ',' ? c : '_'; }); 406 [](int c) { return c != ',' ? c : '_'; });
407 event.scope = eolian_scope_cxx(::eolian_event_scope_get(event_));
391 event.name = normalize_spaces(name_); 408 event.name = normalize_spaces(name_);
392 event.eo_name = safe_upper 409 event.eo_name = safe_upper
393 (find_replace(class_full_name(klass), ".", "_") + "_EVENT_" + event.name); 410 (find_replace(class_full_name(klass), ".", "_") + "_EVENT_" + event.name);
diff --git a/src/bin/eolian_cxx/type_lookup_table.cc b/src/bin/eolian_cxx/type_lookup_table.cc
index 7fa085e..dd00551 100644
--- a/src/bin/eolian_cxx/type_lookup_table.cc
+++ b/src/bin/eolian_cxx/type_lookup_table.cc
@@ -13,25 +13,25 @@ type_lookup_table
13 {"Ecore_Task_Cb", eolian_type::callback_, {"Ecore.h"}}, 13 {"Ecore_Task_Cb", eolian_type::callback_, {"Ecore.h"}},
14 {"Ecore_Timeline_Cb", eolian_type::callback_, {"Ecore.h"}}, 14 {"Ecore_Timeline_Cb", eolian_type::callback_, {"Ecore.h"}},
15 {"Edje_Signal_Cb", eolian_type::callback_, {"Edje.h"}}, 15 {"Edje_Signal_Cb", eolian_type::callback_, {"Edje.h"}},
16 {"Eina_Accessor *", eolian_type::complex_, false, false, true, "::efl::eina::accessor", {"eina-cxx/eina_accessor.hh"}}, 16 {"Eina_Accessor *", eolian_type::complex_, false, false, true, false, "::efl::eina::accessor", {"eina-cxx/eina_accessor.hh"}},
17 {"Eina_Bool", eolian_type::simple_, false, false, false, "bool", {}}, 17 {"Eina_Bool", eolian_type::simple_, false, false, false, false, "bool", {}},
18 {"Eina_Bool *", eolian_type::simple_, false, false, false, "bool*", {}}, 18 {"Eina_Bool *", eolian_type::simple_, false, false, false, false, "bool*", {}},
19 {"Eina_Inlist *", eolian_type::complex_, false, false, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}}, 19 {"Eina_Inlist *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
20 {"Eina_Inlist *", eolian_type::complex_, false, true, true, "::efl::eina::inlist", {"eina-cxx/eina_inlist.hh"}}, 20 {"Eina_Inlist *", eolian_type::complex_, false, true, true, true, "::efl::eina::inlist", {"eina-cxx/eina_inlist.hh"}},
21 {"Eina_Iterator *", eolian_type::complex_, false, false, true, "::efl::eina::iterator", {"eina-cxx/eina_iterator.hh"}}, 21 {"Eina_Iterator *", eolian_type::complex_, false, false, true, true, "::efl::eina::iterator", {"eina-cxx/eina_iterator.hh"}},
22 {"Eina_List *", eolian_type::complex_, false, false, true, "::efl::eina::range_list", {"eina-cxx/eina_list.hh"}}, 22 {"Eina_List *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_list", {"eina-cxx/eina_list.hh"}},
23 {"Eina_List *", eolian_type::complex_, false, true, true, "::efl::eina::list", {"eina-cxx/eina_list.hh"}}, 23 {"Eina_List *", eolian_type::complex_, false, true, true, true, "::efl::eina::list", {"eina-cxx/eina_list.hh"}},
24 {"const Eina_List *", eolian_type::complex_, true, false, true, "::efl::eina::crange_list", {"eina-cxx/eina_list.hh"}}, 24 {"const Eina_List *", eolian_type::complex_, true, false, true, true, "::efl::eina::crange_list", {"eina-cxx/eina_list.hh"}},
25 {"Eio_Filter_Direct_Cb", eolian_type::callback_, {"Eio.h"}}, 25 {"Eio_Filter_Direct_Cb", eolian_type::callback_, {"Eio.h"}},
26 {"Emodel *", eolian_type::simple_, false, false, true, "::emodel", {"Emodel.hh"}}, 26 {"Emodel *", eolian_type::simple_, false, false, true, false, "::emodel", {"Emodel.hh"}},
27 {"Eo *", eolian_type::simple_, false, true, true, "::efl::eo::concrete", {"eo_concrete.hh"}}, 27 {"Eo *", eolian_type::simple_, false, true, true, false, "::efl::eo::concrete", {"eo_concrete.hh"}},
28 {"Eo *", eolian_type::simple_, false, false, true, "::efl::eo::concrete", {"eo_concrete.hh"}}, 28 {"Eo *", eolian_type::simple_, false, false, true, false, "::efl::eo::concrete", {"eo_concrete.hh"}},
29 //{"Evas_Object_Box_Layout", eolian_type::callback_, {"Evas.h"}}, 29 //{"Evas_Object_Box_Layout", eolian_type::callback_, {"Evas.h"}},
30 {"Evas_Object *", eolian_type::simple_, false, false, true, "::evas::object", {"canvas/evas_object.eo.hh"}}, 30 {"Evas_Object *", eolian_type::simple_, false, false, true, false, "::evas::object", {"canvas/evas_object.eo.hh"}},
31 {"char *", eolian_type::simple_, false, true, true, "std::unique_ptr<char*>", {"memory"}}, 31 {"char *", eolian_type::simple_, false, true, true, false, "std::unique_ptr<char*>", {"memory"}},
32 {"const Eina_Inlist *", eolian_type::complex_, false, false, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}}, 32 {"const Eina_Inlist *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
33 {"const Eina_List *", eolian_type::complex_, false, false, true, "::efl::eina::range_list", {"eina-cxx/eina_ptrlist.hh"}}, 33 {"const Eina_List *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_list", {"eina-cxx/eina_ptrlist.hh"}},
34 {"const char *", eolian_type::simple_, false, false, true, "std::string", {"string"}}, 34 {"const char *", eolian_type::simple_, false, false, true, true, "::efl::eina::string_view", {"string"}},
35}; 35};
36 36
37} 37}
diff --git a/src/bindings/eo_cxx/eo_concrete.hh b/src/bindings/eo_cxx/eo_concrete.hh
index 63029a1..9e328b1 100644
--- a/src/bindings/eo_cxx/eo_concrete.hh
+++ b/src/bindings/eo_cxx/eo_concrete.hh
@@ -21,6 +21,12 @@
21#endif 21#endif
22#endif 22#endif
23 23
24#if !defined(EFL_DOXYGEN) && !defined(EO_CXX_INHERIT)
25# define EO_CXX_INHERIT(name) ::eo_cxx::name
26#elif !defined(EO_CXX_INHERIT)
27# define EO_CXX_INHERIT(name) ::name
28#endif
29
24namespace efl { namespace eo { 30namespace efl { namespace eo {
25 31
26/// @addtogroup Efl_Cxx_API 32/// @addtogroup Efl_Cxx_API
diff --git a/src/bindings/eo_cxx/eo_cxx_interop.hh b/src/bindings/eo_cxx/eo_cxx_interop.hh
index ba6a473..08ca300 100644
--- a/src/bindings/eo_cxx/eo_cxx_interop.hh
+++ b/src/bindings/eo_cxx/eo_cxx_interop.hh
@@ -4,6 +4,7 @@
4 4
5#include <string> 5#include <string>
6#include <tuple> 6#include <tuple>
7#include <utility>
7#include <type_traits> 8#include <type_traits>
8 9
9#include <Eina.hh> 10#include <Eina.hh>
@@ -28,6 +29,20 @@ to_c(eina::optional<std::string> const& x)
28} 29}
29 30
30inline const char* 31inline const char*
32to_c(eina::string_view const& x)
33{
34 return x.data();
35}
36
37inline const char*
38to_c(eina::optional<eina::string_view> const& x)
39{
40 if (!x)
41 return nullptr;
42 return x->data();
43}
44
45inline const char*
31to_c(efl::eina::stringshare const& x) 46to_c(efl::eina::stringshare const& x)
32{ 47{
33 return x.c_str(); 48 return x.c_str();
@@ -196,6 +211,20 @@ to_cxx(const char* x, std::tuple<std::false_type>, tag<eina::optional<std::strin
196 return std::string(x); 211 return std::string(x);
197} 212}
198 213
214inline eina::string_view
215to_cxx(const char* x, std::tuple<std::false_type>, tag<eina::string_view>)
216{
217 return eina::string_view(x);
218}
219
220inline eina::optional<eina::string_view>
221to_cxx(const char* x, std::tuple<std::false_type>, tag<eina::optional<eina::string_view> >)
222{
223 if (!x)
224 return nullptr;
225 return eina::string_view(x);
226}
227
199template <typename T, typename Enable = void> 228template <typename T, typename Enable = void>
200struct traits 229struct traits
201{ 230{
@@ -216,6 +245,13 @@ struct traits
216 typedef const char* type; 245 typedef const char* type;
217}; 246};
218 247
248template <typename T>
249struct traits
250 <T, typename std::enable_if<std::is_base_of<::efl::eina::basic_string_view<char>, T>::value>::type>
251{
252 typedef const char* type;
253};
254
219template <typename T, typename ...Args> 255template <typename T, typename ...Args>
220inline efl::eina::range_list<T const> 256inline efl::eina::range_list<T const>
221to_cxx(const Eina_List* x, std::tuple<std::false_type, Args...>, tag< efl::eina::range_list<T> >) 257to_cxx(const Eina_List* x, std::tuple<std::false_type, Args...>, tag< efl::eina::range_list<T> >)
@@ -407,6 +443,22 @@ Eina_Bool free_callback_calback(void* data, Eo* obj EINA_UNUSED
407 return EO_CALLBACK_CONTINUE; 443 return EO_CALLBACK_CONTINUE;
408} 444}
409 445
446template <typename F>
447inline
448std::vector<F>& get_static_callback_vector()
449{
450 static std::vector<F> vec;
451 return vec;
452}
453
454template <typename F>
455inline
456F* alloc_static_callback(F&& f)
457{
458 get_static_callback_vector<F>().push_back(std::forward<F>(f));
459 return &(get_static_callback_vector<F>().back());
460}
461
410} } // namespace efl { namespace eolian { 462} } // namespace efl { namespace eolian {
411 463
412#endif // EFL_EOLIAN_INTEROP_HH 464#endif // EFL_EOLIAN_INTEROP_HH
diff --git a/src/examples/eolian_cxx/Makefile.am b/src/examples/eolian_cxx/Makefile.am
index a0510f1..7842095 100644
--- a/src/examples/eolian_cxx/Makefile.am
+++ b/src/examples/eolian_cxx/Makefile.am
@@ -66,9 +66,11 @@ GENERATED = \
66 colourable.eo.c \ 66 colourable.eo.c \
67 colourable.eo.h \ 67 colourable.eo.h \
68 colourable.eo.hh \ 68 colourable.eo.hh \
69 colourable.eo.impl.hh \
69 colourablesquare.eo.c \ 70 colourablesquare.eo.c \
70 colourablesquare.eo.h \ 71 colourablesquare.eo.h \
71 colourablesquare.eo.hh 72 colourablesquare.eo.hh \
73 colourablesquare.eo.impl.hh
72 74
73BUILT_SOURCES = $(GENERATED) 75BUILT_SOURCES = $(GENERATED)
74CLEANFILES += $(BUILT_SOURCES) 76CLEANFILES += $(BUILT_SOURCES)
@@ -135,6 +137,9 @@ eolian_cxx_complex_types_01_SOURCES = eolian_cxx_complex_types_01.cc
135%.eo.hh: %.eo 137%.eo.hh: %.eo
136 $(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -I${abs_srcdir} -o $@ $< 138 $(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -I${abs_srcdir} -o $@ $<
137 139
140%.eo.impl.hh: %.eo.hh
141 true $<
142
138%.eo.c: %.eo 143%.eo.c: %.eo
139 $(AM_V_EOL)$(EOLIAN_GEN) --eo --legacy $(EOLIAN_FLAGS) --gc -o $@ $< 144 $(AM_V_EOL)$(EOLIAN_GEN) --eo --legacy $(EOLIAN_FLAGS) --gc -o $@ $<
140 145
diff --git a/src/lib/eolian_cxx/eo_generate.hh b/src/lib/eolian_cxx/eo_generate.hh
index a509201..97e53bb 100644
--- a/src/lib/eolian_cxx/eo_generate.hh
+++ b/src/lib/eolian_cxx/eo_generate.hh
@@ -10,9 +10,12 @@
10namespace efl { namespace eolian { 10namespace efl { namespace eolian {
11 11
12inline void 12inline void
13generate(std::ostream& out, eo_class const& cls, eo_generator_options const& opts) 13generate(std::ostream& header_decl,
14 std::ostream& header_impl,
15 eo_class const& cls,
16 eo_generator_options const& opts)
14{ 17{
15 grammar::eo_header_generator(out, cls, opts); 18 grammar::eo_headers_generator(header_decl, header_impl, cls, opts);
16} 19}
17 20
18} } 21} }
diff --git a/src/lib/eolian_cxx/eo_types.hh b/src/lib/eolian_cxx/eo_types.hh
index 38f2d38..b50e692 100644
--- a/src/lib/eolian_cxx/eo_types.hh
+++ b/src/lib/eolian_cxx/eo_types.hh
@@ -21,6 +21,12 @@ typedef std::vector<eo_function> functions_container_type;
21typedef std::vector<eo_parameter> parameters_container_type; 21typedef std::vector<eo_parameter> parameters_container_type;
22typedef std::vector<eo_event> events_container_type; 22typedef std::vector<eo_event> events_container_type;
23 23
24
25enum class eolian_scope
26 {
27 public_, protected_, private_
28 };
29
24struct eolian_type 30struct eolian_type
25{ 31{
26 enum category_type 32 enum category_type
@@ -34,6 +40,7 @@ struct eolian_type
34 , is_const(false) 40 , is_const(false)
35 , is_own(false) 41 , is_own(false)
36 , is_class(false) 42 , is_class(false)
43 , binding_requires_optional(false)
37 , binding() 44 , binding()
38 , includes() 45 , includes()
39 {} 46 {}
@@ -43,6 +50,7 @@ struct eolian_type
43 bool is_const_, 50 bool is_const_,
44 bool is_own_, 51 bool is_own_,
45 bool is_class_, 52 bool is_class_,
53 bool binding_requires_optional_,
46 std::string binding_, 54 std::string binding_,
47 includes_container_type includes_) 55 includes_container_type includes_)
48 : native(native_) 56 : native(native_)
@@ -50,6 +58,7 @@ struct eolian_type
50 , is_const(is_const_) 58 , is_const(is_const_)
51 , is_own(is_own_) 59 , is_own(is_own_)
52 , is_class(is_class_) 60 , is_class(is_class_)
61 , binding_requires_optional(binding_requires_optional_)
53 , binding(binding_) 62 , binding(binding_)
54 , includes(includes_) 63 , includes(includes_)
55 { 64 {
@@ -60,7 +69,7 @@ struct eolian_type
60 eolian_type(std::string native_, 69 eolian_type(std::string native_,
61 category_type category_, 70 category_type category_,
62 includes_container_type const& includes_) 71 includes_container_type const& includes_)
63 : eolian_type(native_, category_, false, false, false, "", includes_) 72 : eolian_type(native_, category_, false, false, false, false, "", includes_)
64 { 73 {
65 assert(category == callback_); 74 assert(category == callback_);
66 } 75 }
@@ -70,6 +79,7 @@ struct eolian_type
70 bool is_const; 79 bool is_const;
71 bool is_own; 80 bool is_own;
72 bool is_class; 81 bool is_class;
82 bool binding_requires_optional;
73 std::string binding; 83 std::string binding;
74 includes_container_type includes; 84 includes_container_type includes;
75}; 85};
@@ -110,7 +120,7 @@ struct eolian_type_instance
110}; 120};
111 121
112const efl::eolian::eolian_type 122const efl::eolian::eolian_type
113void_type { "void", efl::eolian::eolian_type::simple_, false, false, false, "", {} }; 123void_type { "void", efl::eolian::eolian_type::simple_, false, false, false, false, "", {} };
114 124
115inline bool 125inline bool
116type_is_void(eolian_type_instance const& type) 126type_is_void(eolian_type_instance const& type)
@@ -151,6 +161,19 @@ type_is_class(eolian_type_instance const& type)
151} 161}
152 162
153inline bool 163inline bool
164type_binding_requires_optional(eolian_type const& type)
165{
166 return type.binding_requires_optional;
167}
168
169inline bool
170type_binding_requires_optional(eolian_type_instance const& type)
171{
172 assert(!type.empty());
173 return type_binding_requires_optional(type.front());
174}
175
176inline bool
154type_is_nonull(eolian_type_instance const& type) 177type_is_nonull(eolian_type_instance const& type)
155{ 178{
156 return type.is_nonull; 179 return type.is_nonull;
@@ -212,6 +235,8 @@ type_is_callback(eolian_type_instance const& type_ins)
212 235
213struct eo_generator_options 236struct eo_generator_options
214{ 237{
238 std::string header_decl_file_name;
239 std::string header_impl_file_name;
215 includes_container_type cxx_headers; 240 includes_container_type cxx_headers;
216 includes_container_type c_headers; 241 includes_container_type c_headers;
217}; 242};
@@ -256,6 +281,7 @@ struct eo_function
256 regular_, class_ 281 regular_, class_
257 }; 282 };
258 eo_function_type type; 283 eo_function_type type;
284 eolian_scope scope;
259 std::string name; 285 std::string name;
260 std::string impl; 286 std::string impl;
261 eolian_type_instance ret; 287 eolian_type_instance ret;
@@ -265,6 +291,7 @@ struct eo_function
265 291
266struct eo_event 292struct eo_event
267{ 293{
294 eolian_scope scope;
268 std::string name; 295 std::string name;
269 std::string eo_name; 296 std::string eo_name;
270 //parameters_container_type params; // XXX desirable. 297 //parameters_container_type params; // XXX desirable.
diff --git a/src/lib/eolian_cxx/grammar/comment.hh b/src/lib/eolian_cxx/grammar/comment.hh
index 92cc03f..21fa3ea 100644
--- a/src/lib/eolian_cxx/grammar/comment.hh
+++ b/src/lib/eolian_cxx/grammar/comment.hh
@@ -19,15 +19,17 @@ struct comment
19{ 19{
20 std::string _doc; 20 std::string _doc;
21 int _tab; 21 int _tab;
22 comment(std::string const& doc, int tab = 0) 22 std::string _if_empty;
23 : _doc(doc), _tab(tab) 23 comment(std::string const& doc, int tab = 0, std::string const& if_empty = "")
24 : _doc(doc), _tab(tab), _if_empty(if_empty)
24 {} 25 {}
25}; 26};
26 27
27inline std::ostream& 28inline std::ostream&
28operator<<(std::ostream& out, comment const& x) 29operator<<(std::ostream& out, comment const& x)
29{ 30{
30 std::istringstream ss(x._doc); 31 std::string const& doc = !x._doc.empty() ? x._doc : x._if_empty;
32 std::istringstream ss(doc);
31 std::string line; 33 std::string line;
32 while(std::getline(ss, line)) 34 while(std::getline(ss, line))
33 { 35 {
diff --git a/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
index 86a515e..2688552 100644
--- a/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
+++ b/src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
@@ -46,7 +46,7 @@ operator<<(std::ostream& out, class_inheritance const& x)
46 last = cls.ancestors.cend(); 46 last = cls.ancestors.cend();
47 for (it = first; it != last; ++it) 47 for (it = first; it != last; ++it)
48 { 48 {
49 out << tab(2) << ", ::" << abstract_namespace << "::" << *it << endl; 49 out << tab(2) << ", EO_CXX_INHERIT(" << *it << ")" << endl;
50 } 50 }
51 return out; 51 return out;
52} 52}
@@ -115,6 +115,9 @@ operator<<(std::ostream& out, functors_constructor_methods const& x)
115 { 115 {
116 eo_constructor const& c = *it; 116 eo_constructor const& c = *it;
117 117
118 // Hide documentation condition
119 out << comment("@cond LOCAL", 1);
120
118 // Struct declaration 121 // Struct declaration
119 out << template_parameters_declaration(c.params, 1) 122 out << template_parameters_declaration(c.params, 1)
120 << tab(1) << "struct " << constructor_functor_type_name(c) << endl 123 << tab(1) << "struct " << constructor_functor_type_name(c) << endl
@@ -176,7 +179,10 @@ operator<<(std::ostream& out, functors_constructor_methods const& x)
176 ); 179 );
177 180
178 // Close struct 181 // Close struct
179 out << tab(1) << "};" << endl << endl; 182 out << tab(1) << "};" << endl;
183
184 // End documentation condition
185 out << comment("@endcond", 1) << endl;
180 } 186 }
181 187
182 return out; 188 return out;
@@ -208,7 +214,7 @@ operator<<(std::ostream& out, constructor_method_function_declarations const& x)
208 continue; 214 continue;
209 } 215 }
210 216
211 out << comment(c.comment, 0) 217 out << comment(c.comment, 1)
212 << template_parameters_declaration(c.params, 1) 218 << template_parameters_declaration(c.params, 1)
213 << tab(1) << constructor_functor_type_decl(c) << " " << c.name << "(" 219 << tab(1) << constructor_functor_type_decl(c) << " " << c.name << "("
214 << parameters_declaration(c.params) << ") const;" << endl << endl; 220 << parameters_declaration(c.params) << ") const;" << endl << endl;
@@ -253,6 +259,51 @@ operator<<(std::ostream& out, constructor_method_function_definitions const& x)
253 return out; 259 return out;
254} 260}
255 261
262struct comment_constructor_with_constructor_methods
263{
264 eo_class const& _cls;
265 comment_constructor_with_constructor_methods(eo_class const& cls)
266 : _cls(cls)
267 {}
268};
269
270inline std::ostream&
271operator<<(std::ostream& out, comment_constructor_with_constructor_methods const& x)
272{
273 out << tab(1) << "/**" << endl
274 << tab(2) << "@brief Constructs a new " << full_name(x._cls, false) << " object." << endl
275 << endl
276 << tab(2) << "Constructs a new " << full_name(x._cls, false) << " object. If you want this object to be a child" << endl
277 << tab(2) << "of another Eo object, use an @ref efl::eo::parent expression, like the example." << endl
278 << endl;
279
280 if (x._cls.constructors.size())
281 {
282 bool singular = (x._cls.constructors.size() == 1);
283 out << tab(2) << "Since this class have " << (singular ? "a " : "") << "constructor method" << (singular ? "" : "s")
284 << ", you must call " << (singular ? "it" : "each one of them") << endl
285 << tab(2) << "in the right place within this constructor parameters." << endl
286 << endl;
287 }
288
289 out << tab(2) << "Example:" << endl
290 << tab(2) << "@code" << endl
291 << tab(2) << full_name(x._cls, false) << " my_" << x._cls.name << "(" << endl;
292
293 for (eo_constructor const& c : x._cls.constructors)
294 out << tab(3) << "my_" << x._cls.name << "." << c.name << "(" << parameters_names(c.params) << ")," << endl;
295
296 out << tab(3) << "efl::eo::parent = parent_object);" << endl
297 << tab(2) << "@endcode" << endl
298 << endl;
299
300 for (eo_constructor const& c : x._cls.constructors)
301 out << tab(2) << "@see " << x._cls.name << "::" << c.name << endl;
302 out << tab(2) << "@see " << x._cls.name << "(Eo* eo)" << endl;
303
304 return out << tab(1) << "*/" << endl;
305}
306
256struct constructor_with_constructor_methods 307struct constructor_with_constructor_methods
257{ 308{
258 eo_class const& _cls; 309 eo_class const& _cls;
@@ -274,6 +325,8 @@ operator<<(std::ostream& out, constructor_with_constructor_methods const& x)
274 cb_count += parameters_count_callbacks((*it).params); 325 cb_count += parameters_count_callbacks((*it).params);
275 } 326 }
276 327
328 out << comment_constructor_with_constructor_methods(x._cls);
329
277 if (cb_count != 0) 330 if (cb_count != 0)
278 { 331 {
279 out << tab(1) << "template <"; 332 out << tab(1) << "template <";
@@ -398,6 +451,8 @@ struct function_call_constructor_methods
398inline std::ostream& 451inline std::ostream&
399operator<<(std::ostream& out, function_call_constructor_methods const& x) 452operator<<(std::ostream& out, function_call_constructor_methods const& x)
400{ 453{
454 out << comment("@internal", 1);
455
401 unsigned cb_count = 0; 456 unsigned cb_count = 0;
402 457
403 constructors_container_type::const_iterator it, 458 constructors_container_type::const_iterator it,
diff --git a/src/lib/eolian_cxx/grammar/eo_class_events_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_events_generator.hh
index 4b7a9b3..b86b4c4 100644
--- a/src/lib/eolian_cxx/grammar/eo_class_events_generator.hh
+++ b/src/lib/eolian_cxx/grammar/eo_class_events_generator.hh
@@ -5,6 +5,7 @@
5#include <iosfwd> 5#include <iosfwd>
6 6
7#include "type_generator.hh" 7#include "type_generator.hh"
8#include "eo_class_scope_guard_generator.hh"
8#include "tab.hh" 9#include "tab.hh"
9#include "comment.hh" 10#include "comment.hh"
10 11
@@ -42,7 +43,8 @@ struct event_callback_add
42inline std::ostream& 43inline std::ostream&
43operator<<(std::ostream& out, event_callback_add const& x) 44operator<<(std::ostream& out, event_callback_add const& x)
44{ 45{
45 out << tab(1) << "template <typename F>" << endl 46 out << comment(x._event.comment, 1)
47 << tab(1) << "template <typename F>" << endl
46 << tab(1) << "::efl::eo::signal_connection" << endl 48 << tab(1) << "::efl::eo::signal_connection" << endl
47 << tab(1) << "callback_" << x._event.name << "_add(F && callback_," << endl 49 << tab(1) << "callback_" << x._event.name << "_add(F && callback_," << endl
48 << tab(8) << "::efl::eo::callback_priority priority_ =" << endl 50 << tab(8) << "::efl::eo::callback_priority priority_ =" << endl
@@ -75,7 +77,8 @@ struct event_callback_call
75inline std::ostream& 77inline std::ostream&
76operator<<(std::ostream& out, event_callback_call const& x) 78operator<<(std::ostream& out, event_callback_call const& x)
77{ 79{
78 out << tab(1) << "template <typename T>" << endl 80 out << comment(x._event.comment, 1)
81 << tab(1) << "template <typename T>" << endl
79 << tab(1) << "void" << endl 82 << tab(1) << "void" << endl
80 << tab(1) << "callback_" << x._event.name << "_call(T* info)" << endl 83 << tab(1) << "callback_" << x._event.name << "_call(T* info)" << endl
81 << tab(1) << "{" << endl 84 << tab(1) << "{" << endl
@@ -99,8 +102,12 @@ operator<<(std::ostream& out, events const& x)
99{ 102{
100 for (eo_event const& e : x._events) 103 for (eo_event const& e : x._events)
101 { 104 {
105 out << scope_guard_head(x._cls, e);
106
102 out << event_callback_add(e, x._cls, x._add_cast_to_t) << endl 107 out << event_callback_add(e, x._cls, x._add_cast_to_t) << endl
103 << event_callback_call(e, x._add_cast_to_t); 108 << event_callback_call(e, x._add_cast_to_t);
109
110 out << scope_guard_tail(x._cls, e) << endl;
104 } 111 }
105 out << endl; 112 out << endl;
106 return out; 113 return out;
diff --git a/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh
index 56b450b..1a64a8c 100644
--- a/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh
+++ b/src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh
@@ -10,6 +10,7 @@
10#include "parameters_generator.hh" 10#include "parameters_generator.hh"
11#include "type_generator.hh" 11#include "type_generator.hh"
12#include "namespace_generator.hh" 12#include "namespace_generator.hh"
13#include "eo_class_scope_guard_generator.hh"
13 14
14namespace efl { namespace eolian { namespace grammar { 15namespace efl { namespace eolian { namespace grammar {
15 16
@@ -52,7 +53,7 @@ operator<<(std::ostream& out, function_declaration const& x)
52 53
53 out << reinterpret_type(func.ret) << " " << func.name << "(" 54 out << reinterpret_type(func.ret) << " " << func.name << "("
54 << parameters_declaration(func.params) 55 << parameters_declaration(func.params)
55 << (is_static ? ");" : ") const;") << endl << endl; 56 << (is_static ? ");" : ") const;") << endl;
56 57
57 return out; 58 return out;
58} 59}
@@ -91,10 +92,7 @@ operator<<(std::ostream& out, function_definition const& x)
91 out << tab(1) 92 out << tab(1)
92 << func.ret.front().native << " _tmp_ret;" << endl; 93 << func.ret.front().native << " _tmp_ret;" << endl;
93 94
94 if (!is_static) 95 out << callbacks_heap_alloc("_concrete_eo_ptr()", func.params, is_static, 1);
95 out << callbacks_heap_alloc("_concrete_eo_ptr()", func.params, 1);
96
97 // TODO : register free callback for static methods
98 96
99 out << tab(1) << "eo_do(" 97 out << tab(1) << "eo_do("
100 << (is_static ? "_eo_class(), " : "_concrete_eo_ptr(), ") 98 << (is_static ? "_eo_class(), " : "_concrete_eo_ptr(), ")
@@ -103,7 +101,7 @@ operator<<(std::ostream& out, function_definition const& x)
103 if (!function_is_void(func)) 101 if (!function_is_void(func))
104 out << tab(1) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl; 102 out << tab(1) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl;
105 103
106 out << "}" << endl << endl; 104 out << "}" << endl;
107 return out; 105 return out;
108} 106}
109 107
@@ -120,7 +118,9 @@ operator<<(std::ostream& out, function_declarations const& x)
120{ 118{
121 for (eo_function const& f : x._cls.functions) 119 for (eo_function const& f : x._cls.functions)
122 { 120 {
123 out << function_declaration(x._cls, f) << endl; 121 out << scope_guard_head(x._cls, f)
122 << function_declaration(x._cls, f)
123 << scope_guard_tail(x._cls, f) << endl;
124 } 124 }
125 return out; 125 return out;
126} 126}
@@ -140,7 +140,9 @@ operator<<(std::ostream& out, function_definitions const& x)
140{ 140{
141 for (eo_function const& f : x._cls.functions) 141 for (eo_function const& f : x._cls.functions)
142 { 142 {
143 out << function_definition(x._cls, f, x._concrete) << endl; 143 out << scope_guard_head(x._cls, f)
144 << function_definition(x._cls, f, x._concrete)
145 << scope_guard_tail(x._cls, f) << endl;
144 } 146 }
145 return out; 147 return out;
146} 148}
diff --git a/src/lib/eolian_cxx/grammar/eo_class_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_generator.hh
index 15850ab..c1d227c 100644
--- a/src/lib/eolian_cxx/grammar/eo_class_generator.hh
+++ b/src/lib/eolian_cxx/grammar/eo_class_generator.hh
@@ -40,7 +40,8 @@ struct concrete_eo_ptr_getter
40inline std::ostream& 40inline std::ostream&
41operator<<(std::ostream& out, concrete_eo_ptr_getter const&) 41operator<<(std::ostream& out, concrete_eo_ptr_getter const&)
42{ 42{
43 out << tab(1) << "Eo* _concrete_eo_ptr() const" << endl 43 out << comment("@internal", 1)
44 << tab(1) << "Eo* _concrete_eo_ptr() const" << endl
44 << tab(1) << "{" << endl 45 << tab(1) << "{" << endl
45 << tab(2) << "return static_cast<::efl::eo::concrete const*>(static_cast<void const*>(this))->_eo_ptr();" << endl 46 << tab(2) << "return static_cast<::efl::eo::concrete const*>(static_cast<void const*>(this))->_eo_ptr();" << endl
46 << tab(1) << "}" << endl << endl; 47 << tab(1) << "}" << endl << endl;
@@ -123,6 +124,8 @@ struct abstract_address_of
123inline std::ostream& 124inline std::ostream&
124operator<<(std::ostream& out, abstract_address_of const& x) 125operator<<(std::ostream& out, abstract_address_of const& x)
125{ 126{
127 out << comment("@cond LOCAL", 1);
128
126 out << tab(1) << "template <typename D>" << endl 129 out << tab(1) << "template <typename D>" << endl
127 << tab(1) << "struct address_of" << endl 130 << tab(1) << "struct address_of" << endl
128 << tab(1) << "{" << endl 131 << tab(1) << "{" << endl
@@ -134,7 +137,9 @@ operator<<(std::ostream& out, abstract_address_of const& x)
134 << tab(1) << "struct address_const_of" << endl 137 << tab(1) << "struct address_const_of" << endl
135 << tab(1) << "{" << endl 138 << tab(1) << "{" << endl
136 << tab(2) << address_of_to_pointer(x._cls, true) << endl 139 << tab(2) << address_of_to_pointer(x._cls, true) << endl
137 << tab(1) << "};" << endl << endl; 140 << tab(1) << "};" << endl;
141
142 out << comment("@endcond", 1) << endl;
138 143
139 return out; 144 return out;
140} 145}
@@ -168,6 +173,7 @@ struct concrete_address_of
168inline std::ostream& 173inline std::ostream&
169operator<<(std::ostream& out, concrete_address_of const& x) 174operator<<(std::ostream& out, concrete_address_of const& x)
170{ 175{
176 out << comment("@cond LOCAL", 1);
171 std::vector<std::string> names {"address_of", "address_const_of"}; 177 std::vector<std::string> names {"address_of", "address_const_of"};
172 for (int is_const = 0; is_const != 2; ++is_const) 178 for (int is_const = 0; is_const != 2; ++is_const)
173 { 179 {
@@ -189,16 +195,18 @@ operator<<(std::ostream& out, concrete_address_of const& x)
189 << (is_const ? " const" : "") 195 << (is_const ? " const" : "")
190 << " { return " << name << "(this); }" << endl << endl; 196 << " { return " << name << "(this); }" << endl << endl;
191 } 197 }
198 out << comment("@endcond", 1) << endl;
192 199
193 return out; 200 return out;
194} 201}
195 202
196inline void 203inline void
197eo_class_generator(std::ostream& out, eo_class const& cls) 204eo_class_declarations_generator(std::ostream& out, eo_class const& cls)
198{ 205{
199 out << namespace_head(cls) 206 out << namespace_head(cls)
200 << "struct " << cls.name << ";" << endl << endl 207 << "struct " << cls.name << ";" << endl << endl
201 << namespace_tail(cls) 208 << namespace_tail(cls)
209 << comment("@cond EO_CXX_ABSTRACT")
202 << "namespace " << abstract_namespace << " {" << endl << endl 210 << "namespace " << abstract_namespace << " {" << endl << endl
203 << namespace_head(cls) 211 << namespace_head(cls)
204 << comment(cls.comment) 212 << comment(cls.comment)
@@ -209,12 +217,14 @@ eo_class_generator(std::ostream& out, eo_class const& cls)
209 << eo_class_getter(cls) 217 << eo_class_getter(cls)
210 << class_implicit_conversion_declaration(cls) 218 << class_implicit_conversion_declaration(cls)
211 << abstract_address_of(cls) 219 << abstract_address_of(cls)
212 << "private:" << endl 220 << "private:" << endl << endl
213 << concrete_eo_ptr_getter(cls) 221 << concrete_eo_ptr_getter(cls)
214 << "};" << endl << endl 222 << "};" << endl << endl
215 << namespace_tail(cls) 223 << namespace_tail(cls)
216 << "}" << endl << endl 224 << "}" << endl
225 << comment("@endcond") << endl
217 << namespace_head(cls) 226 << namespace_head(cls)
227 << comment(cls.comment, 0, "@brief Class " + cls.name)
218 << "struct " << cls.name << endl 228 << "struct " << cls.name << endl
219 << tab(2) << ": ::efl::eo::concrete" << endl 229 << tab(2) << ": ::efl::eo::concrete" << endl
220 << class_inheritance(cls) 230 << class_inheritance(cls)
@@ -229,15 +239,22 @@ eo_class_generator(std::ostream& out, eo_class const& cls)
229 << events(cls, cls.concrete_events) << endl 239 << events(cls, cls.concrete_events) << endl
230 << eo_class_getter(cls) 240 << eo_class_getter(cls)
231 << concrete_address_of(cls) 241 << concrete_address_of(cls)
232 << "private:" << endl 242 << "private:" << endl << endl
233 << function_call_constructor_methods(cls) 243 << function_call_constructor_methods(cls)
234 << tab(2) << "Eo* _concrete_eo_ptr() const { return _eo_ptr(); }" << endl 244 << comment("@internal", 1)
245 << tab(1) << "Eo* _concrete_eo_ptr() const { return _eo_ptr(); }" << endl
235 << "};" << endl << endl 246 << "};" << endl << endl
236 << "static_assert(sizeof(" << full_name(cls) << ") == sizeof(Eo*), \"\");" << endl 247 << "static_assert(sizeof(" << full_name(cls) << ") == sizeof(Eo*), \"\");" << endl
237 << "static_assert(std::is_standard_layout<" << full_name(cls) << ">::value, \"\");" << endl 248 << "static_assert(std::is_standard_layout<" << full_name(cls) << ">::value, \"\");" << endl
238 << endl 249 << endl
239 << namespace_tail(cls) 250 << namespace_tail(cls)
240 << constructor_method_function_definitions(cls) 251 << endl;
252}
253
254inline void
255eo_class_definitions_generator(std::ostream& out, eo_class const& cls)
256{
257 out << constructor_method_function_definitions(cls)
241 << function_definitions(cls, true) 258 << function_definitions(cls, true)
242 << function_definitions(cls, false) 259 << function_definitions(cls, false)
243 << class_implicit_conversion_definition(cls); 260 << class_implicit_conversion_definition(cls);
diff --git a/src/lib/eolian_cxx/grammar/eo_class_scope_guard_generator.hh b/src/lib/eolian_cxx/grammar/eo_class_scope_guard_generator.hh
new file mode 100644
index 0000000..9d545c3
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/eo_class_scope_guard_generator.hh
@@ -0,0 +1,61 @@
1#ifndef EOLIAN_CXX_STD_EO_CLASS_SCOPE_GUARD_GENERATOR_HH
2#define EOLIAN_CXX_STD_EO_CLASS_SCOPE_GUARD_GENERATOR_HH
3
4#include <cassert>
5
6#include "type_generator.hh"
7
8namespace efl { namespace eolian { namespace grammar {
9
10template <typename T>
11struct _scope_guard_head
12{
13 eo_class const& _cls;
14 T const& _e;
15 _scope_guard_head(eo_class const& cls, T const& e)
16 : _cls(cls), _e(e) {}
17};
18
19template <typename T>
20_scope_guard_head<T> scope_guard_head(eo_class const& cls, T const& e)
21{
22 return _scope_guard_head<T>(cls, e);
23}
24
25template <typename T>
26inline std::ostream&
27operator<<(std::ostream& out, _scope_guard_head<T> const& x)
28{
29 assert(x._e.scope != eolian_scope::private_);
30 if (x._e.scope == eolian_scope::protected_)
31 out << "#ifdef " << name_upper(x._cls) << "_PROTECTED" << endl;
32 return out;
33}
34
35template <typename T>
36struct _scope_guard_tail
37{
38 eo_class const& _cls;
39 T const& _e;
40 _scope_guard_tail(eo_class const& cls, T const& e)
41 : _cls(cls), _e(e) {}
42};
43
44template <typename T>
45struct _scope_guard_tail<T> scope_guard_tail(eo_class const& cls, T const& e)
46{
47 return _scope_guard_tail<T>(cls, e);
48}
49
50template <typename T>
51inline std::ostream&
52operator<<(std::ostream& out, _scope_guard_tail<T> const& x)
53{
54 if (x._e.scope == eolian_scope::protected_)
55 out << "#endif" << endl;
56 return out;
57}
58
59} } }
60
61#endif
diff --git a/src/lib/eolian_cxx/grammar/eo_header_generator.hh b/src/lib/eolian_cxx/grammar/eo_header_generator.hh
index 56f4e28..9ec4a3b 100644
--- a/src/lib/eolian_cxx/grammar/eo_header_generator.hh
+++ b/src/lib/eolian_cxx/grammar/eo_header_generator.hh
@@ -115,14 +115,30 @@ include_headers(std::ostream& out,
115} 115}
116 116
117inline void 117inline void
118eo_header_generator(std::ostream& out, eo_class const& cls, eo_generator_options const& opts) 118include_header_impl(std::ostream& out,
119 eo_class const& cls EINA_UNUSED,
120 eo_generator_options const& opts)
121{
122 out << "#include \"" << opts.header_impl_file_name << "\"" << endl << endl;
123}
124
125inline void
126eo_headers_generator(std::ostream& header_decl,
127 std::ostream& header_impl,
128 eo_class const& cls,
129 eo_generator_options const& opts)
119{ 130{
120 onceguard_head(out, cls); 131 onceguard_head(header_decl, cls);
121 include_headers(out, cls, opts); 132 include_headers(header_decl, cls, opts);
122 eo_class_generator(out, cls); 133 eo_class_declarations_generator(header_decl, cls);
123 eo_inheritance_detail_generator(out, cls); 134 include_header_impl(header_decl, cls, opts);
124 onceguard_tail(out, cls); 135 onceguard_tail(header_decl, cls);
125 out << endl; 136 header_decl << endl;
137
138 header_impl << comment("@cond EO_CXX_EO_IMPL") << endl;
139 eo_class_definitions_generator(header_impl, cls);
140 eo_inheritance_detail_generator(header_impl, cls);
141 header_impl << endl << comment("@endcond") << endl;
126} 142}
127 143
128} } } // namespace efl { namespace eolian { namespace grammar { 144} } } // namespace efl { namespace eolian { namespace grammar {
diff --git a/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh b/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
index 38382d5..11b8f2a 100644
--- a/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
+++ b/src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
@@ -30,9 +30,10 @@ _ns_as_prefix(eo_class const& cls)
30struct inheritance_operation 30struct inheritance_operation
31{ 31{
32 eo_class const& _cls; 32 eo_class const& _cls;
33 eo_function const& _func;
33 functions_container_type::size_type _idx; 34 functions_container_type::size_type _idx;
34 inheritance_operation(eo_class const& cls, functions_container_type::size_type idx) 35 inheritance_operation(eo_class const& cls, eo_function const& func, functions_container_type::size_type idx)
35 : _cls(cls), _idx(idx) 36 : _cls(cls), _func(func), _idx(idx)
36 {} 37 {}
37}; 38};
38 39
@@ -40,7 +41,7 @@ inline std::ostream&
40operator<<(std::ostream& out, inheritance_operation const& x) 41operator<<(std::ostream& out, inheritance_operation const& x)
41{ 42{
42 assert(x._idx < x._cls.functions.size()); 43 assert(x._idx < x._cls.functions.size());
43 eo_function const& func = x._cls.functions[x._idx]; 44 eo_function const& func = x._func;
44 out << tab(1) 45 out << tab(1)
45 << "ops[" << x._idx << "].func = reinterpret_cast<void*>(& ::" 46 << "ops[" << x._idx << "].func = reinterpret_cast<void*>(& ::"
46 << _ns_as_prefix(x._cls) << "_" 47 << _ns_as_prefix(x._cls) << "_"
@@ -74,17 +75,30 @@ operator<<(std::ostream& out, inheritance_operations_description const& x)
74 << ", Eo_Op_Description* ops)" << endl 75 << ", Eo_Op_Description* ops)" << endl
75 << "{" << endl 76 << "{" << endl
76 << tab(1) << "(void)ops;" << endl; 77 << tab(1) << "(void)ops;" << endl;
77 functions_container_type::size_type n_ops = x._cls.functions.size(); 78
78 for (functions_container_type::size_type i=0; i < n_ops; ++i) 79 auto funcs = x._cls.functions;
80 auto part = std::stable_partition(funcs.begin(), funcs.end(), [](eo_function const& f){ return f.scope == eolian_scope::public_; });
81
82 functions_container_type::size_type op_idx = 0;
83 for (auto it = funcs.begin(); it != part; ++it, ++op_idx)
79 { 84 {
80 out << inheritance_operation(x._cls, i); 85 out << inheritance_operation(x._cls, *it, op_idx);
86 }
87
88 if (part != funcs.end())
89 {
90 out << scope_guard_head(x._cls, *part);
91 for (auto it = part; it != funcs.end(); ++it, ++op_idx)
92 out << inheritance_operation(x._cls, *it, op_idx);
93 out << scope_guard_tail(x._cls, *part);
81 } 94 }
82 95
83 for (std::string const& parent : x._cls.parents) 96 for (std::string const& parent : x._cls.parents)
84 { 97 {
85 out << tab(1) 98 out << tab(1)
86 << "initialize_operation_description<T>(::efl::eo::detail::tag<::" 99 << "initialize_operation_description<T>(::efl::eo::detail::tag<::"
87 << parent << ">(), &ops[" << x._cls.functions.size() << s << "]);" << endl; 100 << parent << ">(), &ops[operation_description_class_size< "
101 << full_name(x._cls) << " >::value" << s << "]);" << endl;
88 102
89 s += " + operation_description_class_size<::" + parent + ">::value"; 103 s += " + operation_description_class_size<::" + parent + ">::value";
90 } 104 }
@@ -110,6 +124,9 @@ operator<<(std::ostream& out, inheritance_wrappers const& x)
110 for (it = first; it != last; ++it) 124 for (it = first; it != last; ++it)
111 { 125 {
112 eo_function const& func = *it; 126 eo_function const& func = *it;
127
128 out << scope_guard_head(x._cls, func);
129
113 out << "template <typename T>" << endl 130 out << "template <typename T>" << endl
114 << reinterpret_type(func.ret) << " " 131 << reinterpret_type(func.ret) << " "
115 << _ns_as_prefix(x._cls) << "_" 132 << _ns_as_prefix(x._cls) << "_"
@@ -140,7 +157,9 @@ operator<<(std::ostream& out, inheritance_wrappers const& x)
140 if (!function_is_void(func)) 157 if (!function_is_void(func))
141 out << tab(1) << "return _tmp_ret;" << endl; 158 out << tab(1) << "return _tmp_ret;" << endl;
142 159
143 out << "}" << endl << endl; 160 out << "}" << endl;
161
162 out << scope_guard_tail(x._cls, func) << endl;
144 } 163 }
145 return out; 164 return out;
146} 165}
@@ -148,8 +167,9 @@ operator<<(std::ostream& out, inheritance_wrappers const& x)
148struct inheritance_base_operations_size 167struct inheritance_base_operations_size
149{ 168{
150 eo_class const& _cls; 169 eo_class const& _cls;
151 inheritance_base_operations_size(eo_class const& cls) 170 functions_container_type const& _funcs;
152 : _cls(cls) 171 inheritance_base_operations_size(eo_class const& cls, functions_container_type const& funcs)
172 : _cls(cls), _funcs(funcs)
153 {} 173 {}
154}; 174};
155 175
@@ -160,8 +180,8 @@ operator<<(std::ostream& out, inheritance_base_operations_size const& x)
160 << endl << "struct operation_description_class_size< " 180 << endl << "struct operation_description_class_size< "
161 << full_name(x._cls) << " >" << endl 181 << full_name(x._cls) << " >" << endl
162 << "{" << endl 182 << "{" << endl
163 << tab(1) << "static const int value = " 183 << tab(1) << "static constexpr int value = "
164 << x._cls.functions.size(); 184 << x._funcs.size();
165 185
166 for (std::string const& parent : x._cls.parents) 186 for (std::string const& parent : x._cls.parents)
167 { 187 {
@@ -175,6 +195,27 @@ operator<<(std::ostream& out, inheritance_base_operations_size const& x)
175 return out; 195 return out;
176} 196}
177 197
198struct inheritance_base_operations_size_scopes
199{
200 eo_class const& _cls;
201 inheritance_base_operations_size_scopes(eo_class const& cls)
202 : _cls(cls)
203 {}
204};
205
206inline std::ostream&
207operator<<(std::ostream& out, inheritance_base_operations_size_scopes const& x)
208{
209 auto funcs = x._cls.functions;
210 auto part = std::stable_partition(funcs.begin(), funcs.end(), [](eo_function const& f){ return f.scope == eolian_scope::public_; });
211
212 out << "#ifdef " << name_upper(x._cls) << "_PROTECTED" << endl
213 << inheritance_base_operations_size(x._cls, funcs)
214 << "#else" << endl
215 << inheritance_base_operations_size(x._cls, {funcs.begin(), part})
216 << "#endif" << endl << endl;
217 return out;
218}
178 219
179struct inheritance_base_operations_extensions 220struct inheritance_base_operations_extensions
180{ 221{
@@ -230,7 +271,7 @@ operator<<(std::ostream& out, inheritance_base_operations_function const& x)
230 if (!is_void) 271 if (!is_void)
231 out << tab(3) << func.ret.front().native << " _tmp_ret = {};" << endl; 272 out << tab(3) << func.ret.front().native << " _tmp_ret = {};" << endl;
232 273
233 out << callbacks_heap_alloc("dynamic_cast<T*>(this)->_eo_ptr()", func.params, 3) 274 out << callbacks_heap_alloc("dynamic_cast<T*>(this)->_eo_ptr()", func.params, function_is_static(x._func), 3)
234 << endl; 275 << endl;
235 276
236 out << tab(3) 277 out << tab(3)
@@ -241,7 +282,7 @@ operator<<(std::ostream& out, inheritance_base_operations_function const& x)
241 if (!is_void) 282 if (!is_void)
242 out << tab(4) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl; 283 out << tab(4) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl;
243 284
244 return out << tab(2) << "}" << endl << endl; 285 return out << tab(2) << "}" << endl;
245} 286}
246 287
247struct inheritance_base_operations 288struct inheritance_base_operations
@@ -265,7 +306,9 @@ operator<<(std::ostream& out, inheritance_base_operations const& x)
265 last = x._cls.functions.end(); 306 last = x._cls.functions.end();
266 for (it = first; it != last; ++it) 307 for (it = first; it != last; ++it)
267 { 308 {
309 out << scope_guard_head(x._cls, *it);
268 out << inheritance_base_operations_function(x._cls, *it); 310 out << inheritance_base_operations_function(x._cls, *it);
311 out << scope_guard_tail(x._cls, *it) << endl;
269 } 312 }
270 out << tab(1) << "};" << endl 313 out << tab(1) << "};" << endl
271 << "};" << endl << endl; 314 << "};" << endl << endl;
@@ -365,7 +408,7 @@ eo_inheritance_detail_generator(std::ostream& out, eo_class const& cls)
365 out << inheritance_wrappers(cls) 408 out << inheritance_wrappers(cls)
366 << "namespace efl { namespace eo { namespace detail {" << endl << endl 409 << "namespace efl { namespace eo { namespace detail {" << endl << endl
367 << inheritance_base_operations(cls) << endl 410 << inheritance_base_operations(cls) << endl
368 << inheritance_base_operations_size(cls) 411 << inheritance_base_operations_size_scopes(cls)
369 << inheritance_operations_description(cls) 412 << inheritance_operations_description(cls)
370 << inheritance_call_constructors(cls) 413 << inheritance_call_constructors(cls)
371 << inheritance_eo_class_getter(cls) 414 << inheritance_eo_class_getter(cls)
diff --git a/src/lib/eolian_cxx/grammar/parameters_generator.hh b/src/lib/eolian_cxx/grammar/parameters_generator.hh
index 20f9e99..2d590f2 100644
--- a/src/lib/eolian_cxx/grammar/parameters_generator.hh
+++ b/src/lib/eolian_cxx/grammar/parameters_generator.hh
@@ -106,30 +106,6 @@ operator<<(std::ostream& out, callback_tmp const& x)
106} 106}
107 107
108struct 108struct
109callback_parameter_heap_alloc
110{
111 eolian_type_instance const& _type;
112 std::string const& _name;
113 int _tab;
114 callback_parameter_heap_alloc(eolian_type_instance const& type, std::string const& name, int tab)
115 : _type(type)
116 , _name(name)
117 , _tab(tab)
118 {}
119};
120
121inline std::ostream&
122operator<<(std::ostream& out, callback_parameter_heap_alloc const& x)
123{
124 out << tab(x._tab) << parameter_remove_reference_typedef(x._type, x._name) << endl
125 << tab(x._tab) << parameter_no_ref_type(x._type, x._name) << "* "
126 << callback_tmp(x._name) << " = new "
127 << parameter_no_ref_type(x._type, x._name) << "(std::forward<"
128 << template_parameter_type(x._type, x._name) << ">(" << x._name << "));" << endl;
129 return out;
130}
131
132struct
133callback_parameter_free_ev_add 109callback_parameter_free_ev_add
134{ 110{
135 std::string const& _eo_raw_expr; 111 std::string const& _eo_raw_expr;
@@ -157,10 +133,12 @@ callbacks_heap_alloc
157{ 133{
158 std::string const& _eo_raw_expr; 134 std::string const& _eo_raw_expr;
159 parameters_container_type const& _params; 135 parameters_container_type const& _params;
136 bool _is_static_func;
160 int _tab; 137 int _tab;
161 callbacks_heap_alloc(std::string const& eo_raw_expr, parameters_container_type const& params, int tab) 138 callbacks_heap_alloc(std::string const& eo_raw_expr, parameters_container_type const& params, bool is_static_func, int tab)
162 : _eo_raw_expr(eo_raw_expr) 139 : _eo_raw_expr(eo_raw_expr)
163 , _params(params) 140 , _params(params)
141 , _is_static_func(is_static_func)
164 , _tab(tab) 142 , _tab(tab)
165 {} 143 {}
166}; 144};
@@ -171,12 +149,30 @@ operator<<(std::ostream& out, callbacks_heap_alloc const& x)
171 auto first = x._params.cbegin(), last = x._params.cend(); 149 auto first = x._params.cbegin(), last = x._params.cend();
172 for (auto it = first; it != last; ++it) 150 for (auto it = first; it != last; ++it)
173 { 151 {
174 if (type_is_callback((*it).type) && it+1 != last) 152 auto type = (*it).type;
153 auto name = (*it).name;
154 if (type_is_callback(type) && it+1 != last)
175 { 155 {
176 out << callback_parameter_heap_alloc((*it).type, (*it).name, x._tab) 156
177 << tab(x._tab) 157 out << tab(x._tab) << parameter_remove_reference_typedef(type, name) << endl
178 << callback_parameter_free_ev_add(x._eo_raw_expr, (*it).type, (*it).name) 158 << tab(x._tab) << parameter_no_ref_type(type, name) << "* "
179 << endl << endl; 159 << callback_tmp(name) << " = ";
160
161 if (!x._is_static_func)
162 {
163 out << "new " << parameter_no_ref_type(type, name)
164 << "(std::forward< "
165 << template_parameter_type(type, name) << " >(" << name << "));" << endl
166 << tab(x._tab)
167 << callback_parameter_free_ev_add(x._eo_raw_expr, type, name)
168 << endl << endl;
169 }
170 else
171 {
172 out << "::efl::eolian::alloc_static_callback< "
173 << parameter_no_ref_type(type, name) << " >(std::forward< "
174 << template_parameter_type(type, name) << " >(" << name << "));" << endl;
175 }
180 ++it; // skip next. 176 ++it; // skip next.
181 } 177 }
182 } 178 }
@@ -273,6 +269,56 @@ operator<<(std::ostream& out, parameters_c_declaration const& x)
273} 269}
274 270
275struct 271struct
272parameters_names
273{
274 parameters_container_type const& _params;
275 parameters_names(parameters_container_type const& params)
276 : _params(params)
277 {}
278};
279
280inline std::ostream&
281operator<<(std::ostream& out, parameters_names const& x)
282{
283 auto first = x._params.cbegin(),
284 last = x._params.cend();
285 for (auto it = first; it != last; ++it)
286 {
287 if (it != first)
288 out << ", ";
289
290 out << it->name;
291
292 if (type_is_callback(it->type) && it+1 != last)
293 ++it; // skip next.
294 }
295 return out;
296}
297
298struct
299parameters_c_names
300{
301 parameters_container_type const& _params;
302 parameters_c_names(parameters_container_type const& params)
303 : _params(params)
304 {}
305};
306
307inline std::ostream&
308operator<<(std::ostream& out, parameters_c_names const& x)
309{
310 auto first = x._params.cbegin(),
311 last = x._params.cend();
312 for (auto it = first; it != last; ++it)
313 {
314 if (it != first)
315 out << ", ";
316 out << it->name;
317 }
318 return out;
319}
320
321struct
276parameters_types 322parameters_types
277{ 323{
278 parameters_container_type const& _params; 324 parameters_container_type const& _params;
diff --git a/src/lib/eolian_cxx/grammar/type_generator.hh b/src/lib/eolian_cxx/grammar/type_generator.hh
index 5913330..193d2ea 100644
--- a/src/lib/eolian_cxx/grammar/type_generator.hh
+++ b/src/lib/eolian_cxx/grammar/type_generator.hh
@@ -46,6 +46,21 @@ operator<<(std::ostream& out, abstract_full_name const& x)
46 return out << abstract_namespace << full_name(x._cls); 46 return out << abstract_namespace << full_name(x._cls);
47} 47}
48 48
49struct name_upper
50{
51 eo_class const& _cls;
52 name_upper(eo_class const& cls)
53 : _cls(cls) {}
54};
55
56inline std::ostream&
57operator<<(std::ostream& out, name_upper const& x)
58{
59 std::string key = x._cls.name;
60 std::transform(key.begin(), key.end(), key.begin(), ::toupper);
61 return out << key;
62}
63
49struct c_type 64struct c_type
50{ 65{
51 eolian_type_instance const& _list; 66 eolian_type_instance const& _list;
@@ -91,10 +106,13 @@ operator<<(std::ostream& out, efl::eolian::grammar::reinterpret_type const& x)
91 } 106 }
92 assert(!res.empty()); 107 assert(!res.empty());
93 108
94 if (x._type.is_out && type_is_binding(x._type.front())) 109 if (type_is_binding(x._type.front()))
95 res += "*"; 110 {
96 else if (!x._type.is_nonull && x._type.front().is_class) 111 if (x._type.is_out)
97 res = "::efl::eina::optional< " + res + " >"; 112 res += "*";
113 else if (!x._type.is_nonull && x._type.front().binding_requires_optional)
114 res = "::efl::eina::optional< " + res + " >";
115 }
98 116
99 return out << res; 117 return out << res;
100} 118}
diff --git a/src/tests/eolian_cxx/callback.c b/src/tests/eolian_cxx/callback.c
index 5192fa0..ef978fb 100644
--- a/src/tests/eolian_cxx/callback.c
+++ b/src/tests/eolian_cxx/callback.c
@@ -48,5 +48,11 @@ static void _callback_twocallback(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UN
48 cb(data); 48 cb(data);
49} 49}
50 50
51static void _callback_test_global_callbacks(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED
52 , Ecore_Cb cb, void *data)
53{
54 cb(data);
55}
56
51#include "callback.eo.c" 57#include "callback.eo.c"
52 58
diff --git a/src/tests/eolian_cxx/callback.eo b/src/tests/eolian_cxx/callback.eo
index 16dd76e..5058306 100644
--- a/src/tests/eolian_cxx/callback.eo
+++ b/src/tests/eolian_cxx/callback.eo
@@ -16,6 +16,12 @@ class Callback (Eo.Base)
16 @in Ecore_Cb cb2; 16 @in Ecore_Cb cb2;
17 } 17 }
18 } 18 }
19 test_global_callbacks @class {
20 params {
21 @in Ecore_Cb cb;
22 @in void* data;
23 }
24 }
19 } 25 }
20 implements { 26 implements {
21 Eo.Base.constructor; 27 Eo.Base.constructor;
diff --git a/src/tests/eolian_cxx/eolian_cxx_test_callback.cc b/src/tests/eolian_cxx/eolian_cxx_test_callback.cc
index 5c5d95f..2acfd09 100644
--- a/src/tests/eolian_cxx/eolian_cxx_test_callback.cc
+++ b/src/tests/eolian_cxx/eolian_cxx_test_callback.cc
@@ -109,10 +109,23 @@ START_TEST(eolian_cxx_test_callback_event_del)
109} 109}
110END_TEST 110END_TEST
111 111
112START_TEST(eolian_cxx_test_global_callback)
113{
114 efl::eo::eo_init i;
115
116 bool called = false;
117
118 callback::test_global_callbacks(std::bind([&called] { called = true; }));
119
120 fail_if(!called);
121}
122END_TEST
123
112void 124void
113eolian_cxx_test_callback(TCase* tc) 125eolian_cxx_test_callback(TCase* tc)
114{ 126{
115 tcase_add_test(tc, eolian_cxx_test_callback_method); 127 tcase_add_test(tc, eolian_cxx_test_callback_method);
116 tcase_add_test(tc, eolian_cxx_test_callback_event_add); 128 tcase_add_test(tc, eolian_cxx_test_callback_event_add);
117 tcase_add_test(tc, eolian_cxx_test_callback_event_del); 129 tcase_add_test(tc, eolian_cxx_test_callback_event_del);
130 tcase_add_test(tc, eolian_cxx_test_global_callback);
118} 131}