summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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}