eolian_cxx: Add protected methods and events to C++ wrappers and fixes
authorVitor Sousa <vitorsousasilva@gmail.com>
Mon, 12 Jan 2015 14:00:59 +0000 (12:00 -0200)
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>
Tue, 14 Apr 2015 04:06:57 +0000 (01:06 -0300)
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.

32 files changed:
.gitignore
doc/Doxyfile.in
src/Makefile_Ecore_Audio_Cxx.am
src/Makefile_Ecore_Cxx.am
src/Makefile_Edje_Cxx.am
src/Makefile_Efl_Cxx.am
src/Makefile_Eo_Cxx.am
src/Makefile_Eolian_Cxx.am
src/Makefile_Eolian_Cxx_Helper.am
src/Makefile_Evas_Cxx.am
src/bin/eolian_cxx/convert.cc
src/bin/eolian_cxx/eolian_cxx.cc
src/bin/eolian_cxx/eolian_wrappers.hh
src/bin/eolian_cxx/type_lookup_table.cc
src/bindings/eo_cxx/eo_concrete.hh
src/bindings/eo_cxx/eo_cxx_interop.hh
src/examples/eolian_cxx/Makefile.am
src/lib/eolian_cxx/eo_generate.hh
src/lib/eolian_cxx/eo_types.hh
src/lib/eolian_cxx/grammar/comment.hh
src/lib/eolian_cxx/grammar/eo_class_constructors_generator.hh
src/lib/eolian_cxx/grammar/eo_class_events_generator.hh
src/lib/eolian_cxx/grammar/eo_class_functions_generator.hh
src/lib/eolian_cxx/grammar/eo_class_generator.hh
src/lib/eolian_cxx/grammar/eo_class_scope_guard_generator.hh [new file with mode: 0644]
src/lib/eolian_cxx/grammar/eo_header_generator.hh
src/lib/eolian_cxx/grammar/inheritance_base_generator.hh
src/lib/eolian_cxx/grammar/parameters_generator.hh
src/lib/eolian_cxx/grammar/type_generator.hh
src/tests/eolian_cxx/callback.c
src/tests/eolian_cxx/callback.eo
src/tests/eolian_cxx/eolian_cxx_test_callback.cc

index 4f048401f41ad061b9be20e76781b96000c37caa..1da486ee1b3791d3a691f30b8ead04d008d20946 100644 (file)
@@ -32,6 +32,7 @@ tags
 *.eo.h
 *.eo.legacy.h
 *.eo.hh
+*.eo.impl.hh
 *.eo.lua
 *.luac
 .dir-locals.el
index f18cc4f77b0bf6ec0ab3021a47472f8c9b0817c3..b4afaf42e7be53263da83cdb12fc24bbd756c20d 100644 (file)
@@ -667,7 +667,7 @@ EXCLUDE_PATTERNS       = *_private*
 # wildcard * is used, a substring. Examples: ANamespace, AClass,
 # AClass::ANamespace, ANamespace::*Test
 
-EXCLUDE_SYMBOLS        =
+EXCLUDE_SYMBOLS        = eo_cxx::*
 
 # The EXAMPLE_PATH tag can be used to specify one or more files or
 # directories that contain example code fragments that are included (see
@@ -1441,7 +1441,9 @@ PREDEFINED             = EINA_MAGIC_DEBUG \
                          EAPI= \
                          EINA_PURE= \
                          EINA_CONST= \
-                         EINA_UNUSED=
+                         EINA_UNUSED= \
+                         EFL_DOXYGEN=1 \
+                         "EO_CXX_INHERIT(name)=::name"
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
 # this tag can be used to specify a list of macro names that should be expanded.
index 498bcbf887f5e81c363a2f2a04c8416101f04fa8..bf564d2c94a5c4c13065ef03b21e28c9d5b696fd 100644 (file)
@@ -20,6 +20,13 @@ lib/ecore_audio/Ecore_Audio.hh: $(generated_ecore_audio_cxx_bindings)
 
 generated_ecore_audio_cxx_all = \
        $(generated_ecore_audio_cxx_bindings) \
+       lib/ecore_audio/ecore_audio.eo.impl.hh \
+       lib/ecore_audio/ecore_audio_in.eo.impl.hh \
+       lib/ecore_audio/ecore_audio_out.eo.impl.hh \
+       lib/ecore_audio/ecore_audio_in_sndfile.eo.impl.hh \
+       lib/ecore_audio/ecore_audio_out_sndfile.eo.impl.hh \
+       lib/ecore_audio/ecore_audio_out_pulse.eo.impl.hh \
+       lib/ecore_audio/ecore_audio_in_tone.eo.impl.hh \
        lib/ecore_audio/Ecore_Audio.hh
 
 CLEANFILES += $(generated_ecore_audio_cxx_all)
index d81651a6b1aac4e49f6f3fc712a1a304fdd59c7d..b29a1c4868ea9be25f8a46794a87f820019ed3b2 100644 (file)
@@ -22,6 +22,12 @@ lib/ecore/Ecore.eo.hh: $(generated_ecore_cxx_bindings)
 
 generated_ecore_cxx_all = \
        $(generated_ecore_cxx_bindings) \
+       lib/ecore/ecore_poller.eo.impl.hh \
+       lib/ecore/ecore_job.eo.impl.hh \
+       lib/ecore/ecore_idler.eo.impl.hh \
+       lib/ecore/ecore_idle_exiter.eo.impl.hh \
+       lib/ecore/ecore_animator.eo.impl.hh \
+       lib/ecore/ecore_parent.eo.impl.hh \
        lib/ecore/Ecore.eo.hh
 
 CLEANFILES += $(generated_ecore_cxx_all)
index 8d6b068e98f658f165b916d04b81f6482e027aee..0b308b049902d9709825f44ff0e9379055a093a4 100644 (file)
@@ -15,6 +15,8 @@ lib/edje/Edje.hh: $(generated_edje_cxx_bindings)
 
 generated_edje_cxx_all = \
        $(generated_edje_cxx_bindings) \
+       lib/edje/edje_object.eo.impl.hh \
+       lib/edje/edje_edit.eo.impl.hh \
        lib/edje/Edje.hh
 
 CLEANFILES += $(generated_edje_cxx_all)
index 9df7c60bddb6c497c38b3c7a146c53b88cea76f3..c5550157290719e9bd4a7e7e8c34a522a97ff63f 100644 (file)
@@ -26,6 +26,12 @@ lib/efl/Efl.hh: $(generated_efl_cxx_bindings)
 
 generated_efl_cxx_all = \
        $(generated_efl_cxx_bindings) \
+       lib/efl/interfaces/efl_control.eo.impl.hh \
+       lib/efl/interfaces/efl_file.eo.impl.hh \
+       lib/efl/interfaces/efl_image.eo.impl.hh \
+       lib/efl/interfaces/efl_player.eo.impl.hh \
+       lib/efl/interfaces/efl_text.eo.impl.hh \
+       lib/efl/interfaces/efl_text_properties.eo.impl.hh \
        lib/efl/Efl.hh
 
 CLEANFILES += $(generated_efl_cxx_all)
index 2f7dda6ada6727bff7199d052633aa1c1085938b..b6315c87464675cda42971c24a7a5cef978f3452 100644 (file)
@@ -3,7 +3,9 @@
 
 generated_eo_cxx_bindings = \
 lib/eo/eo_base.eo.hh \
-lib/eo/eo_abstract_class.eo.hh
+lib/eo/eo_base.eo.impl.hh \
+lib/eo/eo_abstract_class.eo.hh \
+lib/eo/eo_abstract_class.eo.impl.hh
 
 ### Library
 
index cd58e3e9c13d63ae8e5ff43cd1b75989c64771e5..6dff2671df14b633eba7cf823aa5ee16c4b9a44e 100644 (file)
@@ -15,6 +15,7 @@ lib/eolian_cxx/eo_validate.hh
 installed_eoliancxxgrammarheadersdir = $(includedir)/eolian-cxx-@VMAJ@/grammar/
 dist_installed_eoliancxxgrammarheaders_DATA = \
 lib/eolian_cxx/grammar/comment.hh \
+lib/eolian_cxx/grammar/eo_class_scope_guard_generator.hh \
 lib/eolian_cxx/grammar/eo_class_constructors_generator.hh \
 lib/eolian_cxx/grammar/eo_class_events_generator.hh \
 lib/eolian_cxx/grammar/eo_class_functions_generator.hh \
@@ -95,10 +96,11 @@ tests/eolian_cxx/callback.eo.h \
 tests/eolian_cxx/simple.eo.c \
 tests/eolian_cxx/simple.eo.h \
 tests/eolian_cxx/simple.eo.hh \
-tests/eolian_cxx/a.eo.hh tests/eolian_cxx/a.eo.c tests/eolian_cxx/a.eo.h \
-tests/eolian_cxx/b.eo.hh tests/eolian_cxx/b.eo.c tests/eolian_cxx/b.eo.h \
-tests/eolian_cxx/c.eo.hh tests/eolian_cxx/c.eo.c tests/eolian_cxx/c.eo.h \
-tests/eolian_cxx/d.eo.hh tests/eolian_cxx/d.eo.c tests/eolian_cxx/d.eo.h
+tests/eolian_cxx/simple.eo.impl.hh \
+tests/eolian_cxx/a.eo.hh tests/eolian_cxx/a.eo.impl.hh tests/eolian_cxx/a.eo.c tests/eolian_cxx/a.eo.h \
+tests/eolian_cxx/b.eo.hh tests/eolian_cxx/b.eo.impl.hh tests/eolian_cxx/b.eo.c tests/eolian_cxx/b.eo.h \
+tests/eolian_cxx/c.eo.hh tests/eolian_cxx/c.eo.impl.hh tests/eolian_cxx/c.eo.c tests/eolian_cxx/c.eo.h \
+tests/eolian_cxx/d.eo.hh tests/eolian_cxx/d.eo.impl.hh tests/eolian_cxx/d.eo.c tests/eolian_cxx/d.eo.h
 
 tests_eolian_cxx_eolian_cxx_suite_CXXFLAGS = \
 -I$(top_builddir)/src/lib/efl \
index cb54cc4c12f998e58578ae094bd63a6c52c08c69..bb656c8f286a37cd8930398e50a10c29e85b3696 100644 (file)
@@ -15,4 +15,7 @@ SUFFIXES += .eo.hh
 %.eo.hh: %.eo $(_EOLIAN_CXX_DEP)
        $(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -o $@ $<
 
+%.eo.impl.hh: %.eo.hh $(_EOLIAN_CXX_DEP)
+       true $<
+
 CLEANFILES += $(BUILT_SOURCES)
index 96d5ab13b338a770f4d2275a34b01fb1ee7456e8..abe1aa6a9c4b7ab1351e2fbf075e67cc6f9b1534 100644 (file)
@@ -49,15 +49,48 @@ lib/evas/Evas.hh: $(generated_evas_canvas_cxx_bindings)
        @for i in $(generated_evas_canvas_cxx_bindings); do echo "#include <canvas/$$(basename $$i)>" >> $(top_builddir)/src/lib/evas/Evas.hh; done
        @echo @ECHO_E@ "#endif\n\n#endif\n" >> $(top_builddir)/src/lib/evas/Evas.hh
 
-CLEANFILES += \
+generated_evas_canvas_cxx_all = \
 $(generated_evas_canvas_cxx_bindings) \
+lib/evas/canvas/evas_line.eo.impl.hh \
+lib/evas/canvas/evas_polygon.eo.impl.hh \
+lib/evas/canvas/evas_rectangle.eo.impl.hh \
+lib/evas/canvas/evas_text.eo.impl.hh \
+lib/evas/canvas/evas_textblock.eo.impl.hh \
+lib/evas/canvas/evas_textgrid.eo.impl.hh \
+lib/evas/canvas/evas_signal_interface.eo.impl.hh \
+lib/evas/canvas/evas_object_smart.eo.impl.hh \
+lib/evas/canvas/evas_smart_clipped.eo.impl.hh \
+lib/evas/canvas/evas_table.eo.impl.hh \
+lib/evas/canvas/evas_common_interface.eo.impl.hh \
+lib/evas/canvas/evas_object.eo.impl.hh \
+lib/evas/canvas/evas_canvas.eo.impl.hh \
+lib/evas/canvas/evas_grid.eo.impl.hh \
+lib/evas/canvas/evas_image.eo.impl.hh \
+lib/evas/canvas/evas_out.eo.impl.hh \
+lib/evas/canvas/evas_draggable_interface.eo.impl.hh \
+lib/evas/canvas/evas_clickable_interface.eo.impl.hh \
+lib/evas/canvas/evas_scrollable_interface.eo.impl.hh \
+lib/evas/canvas/evas_selectable_interface.eo.impl.hh \
+lib/evas/canvas/evas_zoomable_interface.eo.impl.hh \
+lib/evas/canvas/evas_box.eo.impl.hh \
+lib/evas/canvas/evas_3d_camera.eo.impl.hh \
+lib/evas/canvas/evas_3d_light.eo.impl.hh \
+lib/evas/canvas/evas_3d_material.eo.impl.hh \
+lib/evas/canvas/evas_3d_mesh.eo.impl.hh \
+lib/evas/canvas/evas_3d_node.eo.impl.hh \
+lib/evas/canvas/evas_3d_object.eo.impl.hh \
+lib/evas/canvas/evas_3d_scene.eo.impl.hh \
+lib/evas/canvas/evas_3d_texture.eo.impl.hh \
 lib/evas/Evas.hh
 
+CLEANFILES += \
+$(generated_evas_canvas_cxx_all)
+
 installed_evascxxmainheadersdir = $(includedir)/evas-cxx-@VMAJ@/
 nodist_installed_evascxxmainheaders_DATA = lib/evas/Evas.hh
 
 installed_evascxxcanvasheadersdir = $(includedir)/evas-cxx-@VMAJ@/canvas
-nodist_installed_evascxxcanvasheaders_DATA = $(generated_evas_canvas_cxx_bindings)
+nodist_installed_evascxxcanvasheaders_DATA = $(generated_evas_canvas_cxx_all)
 
 ### Unit tests
 
index d029999411c03b893930bce980bc8c2ddf6ba62d..22ee22f0e57015f49334650f9db0360dc37b87ad 100644 (file)
@@ -141,6 +141,7 @@ _convert_property_set_to_function(Eolian_Class const& klass,
    efl::eolian::eo_function set_ =
      {
        efl::eolian::eo_function::regular_,
+       function_scope(prop_),
        function_name(prop_) + "_set",
        function_impl(prop_) + "_set",
        function_return_type(prop_, eolian_cxx::setter),
@@ -168,6 +169,7 @@ _convert_property_get_to_function(Eolian_Class const& klass,
    efl::eolian::eo_function get_ =
      {
        efl::eolian::eo_function::regular_,
+       function_scope(prop_),
        function_name(prop_) + "_get",
        function_impl(prop_) + "_get",
        function_return_type(prop_, eolian_cxx::getter),
@@ -291,6 +293,7 @@ convert_eolian_functions(efl::eolian::eo_class& cls, Eolian_Class const& klass)
           {
              cls.functions.push_back({
                  function_type(func),
+                 function_scope(func),
                  function_name(func),
                  function_impl(func),
                  function_return_type(func),
index 93e9e442ab4061b879f67950d45918374e18d0a4..7afa10da10e7cc964036885e4620de55024a8933 100644 (file)
@@ -119,30 +119,58 @@ generate(const Eolian_Class& klass, eolian_cxx::options_type const& opts)
 {
    efl::eolian::eo_class cls = eolian_cxx::convert_eolian_class(klass);
    efl::eolian::eo_generator_options gen_opts = generator_options(klass);
-   std::string outname = opts.out_file.empty() ? (class_base_file(klass) + ".hh") : opts.out_file;
+   std::string header_decl_file_name = opts.out_file.empty() ? (class_base_file(klass) + ".hh") : opts.out_file;
+
+   std::string header_impl_file_name = header_decl_file_name;
+   std::size_t dot_pos = header_impl_file_name.rfind(".hh");
+   if (dot_pos != std::string::npos)
+     header_impl_file_name.insert(dot_pos, ".impl");
+   else
+     header_impl_file_name.insert(header_impl_file_name.size(), ".impl");
+
+   std::size_t slash_pos = header_decl_file_name.rfind('/');
+   gen_opts.header_decl_file_name = (slash_pos == std::string::npos) ?
+                                    header_decl_file_name :
+                                    header_decl_file_name.substr(slash_pos+1);
+
+   slash_pos = header_impl_file_name.rfind('/');
+   gen_opts.header_impl_file_name = (slash_pos == std::string::npos) ?
+                                    header_impl_file_name :
+                                    header_impl_file_name.substr(slash_pos+1);
+
    if (!opts.out_dir.empty())
      {
-        outname = opts.out_dir + "/" + outname;
+        header_decl_file_name = opts.out_dir + "/" + header_decl_file_name;
+        header_impl_file_name = opts.out_dir + "/" + header_impl_file_name;
      }
    if(opts.out_file == "-")
      {
-        efl::eolian::generate(std::cout, cls, gen_opts);
+        efl::eolian::generate(std::cout, std::cout, cls, gen_opts);
      }
    else
      {
-        std::ofstream outfile;
-        outfile.open(outname);
-        if (outfile.good())
+        std::ofstream header_decl;
+        header_decl.open(header_decl_file_name);
+        if (!header_decl.good())
           {
-             efl::eolian::generate(outfile, cls, gen_opts);
-             outfile.close();
+             EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
+               << "Can't open output file: " << header_decl_file_name << std::endl;
+             return false;
           }
-        else
+
+        std::ofstream header_impl;
+        header_impl.open(header_impl_file_name);
+        if (!header_impl.good())
           {
              EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
-               << "Can't open output file: " << outname << std::endl;
+               << "Can't open output file: " << header_impl_file_name << std::endl;
              return false;
           }
+
+        efl::eolian::generate(header_decl, header_impl, cls, gen_opts);
+
+        header_decl.close();
+        header_impl.close();
      }
    return true;
 }
index d1b28a6f5f504f3db3c7ca829ed55beeea761f13..5cad7976c092392b27fba2d9319ea44c911f9345 100644 (file)
@@ -25,6 +25,15 @@ getter_t const getter = {};
 struct method_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_METHOD; };
 method_t const method = {};
 
+inline efl::eolian::eolian_scope
+eolian_scope_cxx(Eolian_Object_Scope s)
+{
+   using efl::eolian::eolian_scope;
+   return s == EOLIAN_SCOPE_PRIVATE ? eolian_scope::private_ :
+          s == EOLIAN_SCOPE_PROTECTED ? eolian_scope::protected_ :
+          eolian_scope::public_;
+}
+
 inline const Eolian_Class*
 class_from_file(std::string const& file)
 {
@@ -195,11 +204,18 @@ function_is_constructor(Eolian_Class const& cls, Eolian_Function const& func)
    return ::eolian_function_is_constructor(&func, &cls);
 }
 
+inline efl::eolian::eolian_scope
+function_scope(Eolian_Function const& func)
+{
+   return eolian_scope_cxx(::eolian_function_scope_get(&func));
+}
+
 inline bool
 function_is_visible(Eolian_Function const& func, Eolian_Function_Type func_type)
 {
-   return (::eolian_function_scope_get(&func) == EOLIAN_SCOPE_PUBLIC &&
-           ! ::eolian_function_is_legacy_only(&func, func_type));
+   Eolian_Object_Scope s = ::eolian_function_scope_get(&func);
+   return ((s == EOLIAN_SCOPE_PUBLIC || s == EOLIAN_SCOPE_PROTECTED) &&
+           !::eolian_function_is_legacy_only(&func, func_type));
 }
 
 inline bool
@@ -388,6 +404,7 @@ event_create(Eolian_Class const& klass, const Eolian_Event *event_)
         std::string name_ = safe_str(name);
         std::transform(name_.begin(), name_.end(), name_.begin(),
                        [](int c) { return c != ',' ? c : '_'; });
+        event.scope = eolian_scope_cxx(::eolian_event_scope_get(event_));
         event.name = normalize_spaces(name_);
         event.eo_name = safe_upper
           (find_replace(class_full_name(klass), ".", "_") + "_EVENT_" + event.name);
index 7fa085e9ba0782958f7a4a3f134e6880618ffe5b..dd005518fb54843f16ad4391f8c71182dacfc810 100644 (file)
@@ -13,25 +13,25 @@ type_lookup_table
   {"Ecore_Task_Cb", eolian_type::callback_, {"Ecore.h"}},
   {"Ecore_Timeline_Cb", eolian_type::callback_, {"Ecore.h"}},
   {"Edje_Signal_Cb", eolian_type::callback_, {"Edje.h"}},
-  {"Eina_Accessor *", eolian_type::complex_, false, false, true, "::efl::eina::accessor", {"eina-cxx/eina_accessor.hh"}},
-  {"Eina_Bool", eolian_type::simple_, false, false, false, "bool", {}},
-  {"Eina_Bool *", eolian_type::simple_, false, false, false, "bool*", {}},
-  {"Eina_Inlist *", eolian_type::complex_, false, false, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
-  {"Eina_Inlist *", eolian_type::complex_, false, true, true, "::efl::eina::inlist", {"eina-cxx/eina_inlist.hh"}},
-  {"Eina_Iterator *", eolian_type::complex_, false, false, true, "::efl::eina::iterator", {"eina-cxx/eina_iterator.hh"}},
-  {"Eina_List *", eolian_type::complex_, false, false, true, "::efl::eina::range_list", {"eina-cxx/eina_list.hh"}},
-  {"Eina_List *", eolian_type::complex_, false, true, true, "::efl::eina::list", {"eina-cxx/eina_list.hh"}},
-  {"const Eina_List *", eolian_type::complex_, true, false, true, "::efl::eina::crange_list", {"eina-cxx/eina_list.hh"}},
+  {"Eina_Accessor *", eolian_type::complex_, false, false, true, false, "::efl::eina::accessor", {"eina-cxx/eina_accessor.hh"}},
+  {"Eina_Bool", eolian_type::simple_, false, false, false, false, "bool", {}},
+  {"Eina_Bool *", eolian_type::simple_, false, false, false, false, "bool*", {}},
+  {"Eina_Inlist *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
+  {"Eina_Inlist *", eolian_type::complex_, false, true, true, true, "::efl::eina::inlist", {"eina-cxx/eina_inlist.hh"}},
+  {"Eina_Iterator *", eolian_type::complex_, false, false, true, true, "::efl::eina::iterator", {"eina-cxx/eina_iterator.hh"}},
+  {"Eina_List *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_list", {"eina-cxx/eina_list.hh"}},
+  {"Eina_List *", eolian_type::complex_, false, true, true, true, "::efl::eina::list", {"eina-cxx/eina_list.hh"}},
+  {"const Eina_List *", eolian_type::complex_, true, false, true, true, "::efl::eina::crange_list", {"eina-cxx/eina_list.hh"}},
   {"Eio_Filter_Direct_Cb", eolian_type::callback_, {"Eio.h"}},
-  {"Emodel *", eolian_type::simple_, false, false, true, "::emodel", {"Emodel.hh"}},
-  {"Eo *", eolian_type::simple_, false, true, true, "::efl::eo::concrete", {"eo_concrete.hh"}},
-  {"Eo *", eolian_type::simple_, false, false, true, "::efl::eo::concrete", {"eo_concrete.hh"}},
+  {"Emodel *", eolian_type::simple_, false, false, true, false, "::emodel", {"Emodel.hh"}},
+  {"Eo *", eolian_type::simple_, false, true, true, false, "::efl::eo::concrete", {"eo_concrete.hh"}},
+  {"Eo *", eolian_type::simple_, false, false, true, false, "::efl::eo::concrete", {"eo_concrete.hh"}},
   //{"Evas_Object_Box_Layout", eolian_type::callback_, {"Evas.h"}},
-  {"Evas_Object *", eolian_type::simple_, false, false, true, "::evas::object", {"canvas/evas_object.eo.hh"}},
-  {"char *", eolian_type::simple_, false, true, true, "std::unique_ptr<char*>", {"memory"}},
-  {"const Eina_Inlist *", eolian_type::complex_, false, false, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
-  {"const Eina_List *", eolian_type::complex_, false, false, true, "::efl::eina::range_list", {"eina-cxx/eina_ptrlist.hh"}},
-  {"const char *", eolian_type::simple_, false, false, true, "std::string", {"string"}},
+  {"Evas_Object *", eolian_type::simple_, false, false, true, false, "::evas::object", {"canvas/evas_object.eo.hh"}},
+  {"char *", eolian_type::simple_, false, true, true, false, "std::unique_ptr<char*>", {"memory"}},
+  {"const Eina_Inlist *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_inlist", {"eina-cxx/eina_inlist.hh"}},
+  {"const Eina_List *", eolian_type::complex_, false, false, true, true, "::efl::eina::range_list", {"eina-cxx/eina_ptrlist.hh"}},
+  {"const char *", eolian_type::simple_, false, false, true, true, "::efl::eina::string_view", {"string"}},
 };
 
 }
index 63029a14e7e2895df11d31128de4e93325935527..9e328b1d92ea4e2b2065a2c67b7eef0d4ff38d83 100644 (file)
 #endif
 #endif
 
+#if !defined(EFL_DOXYGEN) && !defined(EO_CXX_INHERIT)
+# define EO_CXX_INHERIT(name)   ::eo_cxx::name
+#elif !defined(EO_CXX_INHERIT)
+# define EO_CXX_INHERIT(name)   ::name
+#endif
+
 namespace efl { namespace eo {
 
 /// @addtogroup Efl_Cxx_API
index ba6a473fc6725a2a0a5f66df75f50306c984d322..08ca3005baaa8a895e73ca48849a71b2acdb5a91 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <string>
 #include <tuple>
+#include <utility>
 #include <type_traits>
 
 #include <Eina.hh>
@@ -27,6 +28,20 @@ to_c(eina::optional<std::string> const& x)
    return x->c_str();
 }
 
+inline const char*
+to_c(eina::string_view const& x)
+{
+   return x.data();
+}
+
+inline const char*
+to_c(eina::optional<eina::string_view> const& x)
+{
+   if (!x)
+     return nullptr;
+   return x->data();
+}
+
 inline const char*
 to_c(efl::eina::stringshare const& x)
 {
@@ -196,6 +211,20 @@ to_cxx(const char* x, std::tuple<std::false_type>, tag<eina::optional<std::strin
    return std::string(x);
 }
 
+inline eina::string_view
+to_cxx(const char* x, std::tuple<std::false_type>, tag<eina::string_view>)
+{
+   return eina::string_view(x);
+}
+
+inline eina::optional<eina::string_view>
+to_cxx(const char* x, std::tuple<std::false_type>, tag<eina::optional<eina::string_view> >)
+{
+   if (!x)
+     return nullptr;
+   return eina::string_view(x);
+}
+
 template <typename T, typename Enable = void>
 struct traits
 {
@@ -216,6 +245,13 @@ struct traits
    typedef const char* type;
 };
 
+template <typename T>
+struct traits
+ <T, typename std::enable_if<std::is_base_of<::efl::eina::basic_string_view<char>, T>::value>::type>
+{
+   typedef const char* type;
+};
+
 template <typename T, typename ...Args>
 inline efl::eina::range_list<T const>
 to_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
    return EO_CALLBACK_CONTINUE;
 }
 
+template <typename F>
+inline
+std::vector<F>& get_static_callback_vector()
+{
+   static std::vector<F> vec;
+   return vec;
+}
+
+template <typename F>
+inline
+F* alloc_static_callback(F&& f)
+{
+   get_static_callback_vector<F>().push_back(std::forward<F>(f));
+   return &(get_static_callback_vector<F>().back());
+}
+
 } } // namespace efl { namespace eolian {
 
 #endif // EFL_EOLIAN_INTEROP_HH
index a0510f1d57e6cf0ee4c1c6f6b5b779f4be15dafc..78420952a1f3501ecf807d591245996947bac278 100644 (file)
@@ -66,9 +66,11 @@ GENERATED = \
        colourable.eo.c \
        colourable.eo.h \
        colourable.eo.hh \
+       colourable.eo.impl.hh \
        colourablesquare.eo.c \
        colourablesquare.eo.h \
-       colourablesquare.eo.hh
+       colourablesquare.eo.hh \
+       colourablesquare.eo.impl.hh
 
 BUILT_SOURCES = $(GENERATED)
 CLEANFILES += $(BUILT_SOURCES)
@@ -135,6 +137,9 @@ eolian_cxx_complex_types_01_SOURCES = eolian_cxx_complex_types_01.cc
 %.eo.hh: %.eo
        $(AM_V_EOLCXX)$(EOLIAN_CXX) $(EOLIAN_FLAGS) -I${abs_srcdir} -o $@ $<
 
+%.eo.impl.hh: %.eo.hh
+       true $<
+
 %.eo.c: %.eo
        $(AM_V_EOL)$(EOLIAN_GEN) --eo --legacy $(EOLIAN_FLAGS) --gc -o $@ $<
 
index a509201baa0787caa5124b983566698923a39a82..97e53bb9dc25625a7b154ebb1306a0e405eea3f2 100644 (file)
 namespace efl { namespace eolian {
 
 inline void
-generate(std::ostream& out, eo_class const& cls, eo_generator_options const& opts)
+generate(std::ostream& header_decl,
+         std::ostream& header_impl,
+         eo_class const& cls,
+         eo_generator_options const& opts)
 {
-   grammar::eo_header_generator(out, cls, opts);
+   grammar::eo_headers_generator(header_decl, header_impl, cls, opts);
 }
 
 } }
index 38f2d38127074be8494c7b38b0425b0f2ae74142..b50e692ac160c74437b1fd04a9d8db1690856810 100644 (file)
@@ -21,6 +21,12 @@ typedef std::vector<eo_function> functions_container_type;
 typedef std::vector<eo_parameter> parameters_container_type;
 typedef std::vector<eo_event> events_container_type;
 
+
+enum class eolian_scope
+  {
+     public_, protected_, private_
+  };
+
 struct eolian_type
 {
    enum category_type
@@ -34,6 +40,7 @@ struct eolian_type
      , is_const(false)
      , is_own(false)
      , is_class(false)
+     , binding_requires_optional(false)
      , binding()
      , includes()
    {}
@@ -43,6 +50,7 @@ struct eolian_type
                bool is_const_,
                bool is_own_,
                bool is_class_,
+               bool binding_requires_optional_,
                std::string binding_,
                includes_container_type includes_)
      : native(native_)
@@ -50,6 +58,7 @@ struct eolian_type
      , is_const(is_const_)
      , is_own(is_own_)
      , is_class(is_class_)
+     , binding_requires_optional(binding_requires_optional_)
      , binding(binding_)
      , includes(includes_)
    {
@@ -60,7 +69,7 @@ struct eolian_type
    eolian_type(std::string native_,
                category_type category_,
                includes_container_type const& includes_)
-     : eolian_type(native_, category_, false, false, false, "", includes_)
+     : eolian_type(native_, category_, false, false, false, false, "", includes_)
    {
       assert(category == callback_);
    }
@@ -70,6 +79,7 @@ struct eolian_type
    bool is_const;
    bool is_own;
    bool is_class;
+   bool binding_requires_optional;
    std::string binding;
    includes_container_type includes;
 };
@@ -110,7 +120,7 @@ struct eolian_type_instance
 };
 
 const efl::eolian::eolian_type
-void_type { "void", efl::eolian::eolian_type::simple_, false, false, false, "", {} };
+void_type { "void", efl::eolian::eolian_type::simple_, false, false, false, false, "", {} };
 
 inline bool
 type_is_void(eolian_type_instance const& type)
@@ -150,6 +160,19 @@ type_is_class(eolian_type_instance const& type)
    return type_is_class(type.front());
 }
 
+inline bool
+type_binding_requires_optional(eolian_type const& type)
+{
+   return type.binding_requires_optional;
+}
+
+inline bool
+type_binding_requires_optional(eolian_type_instance const& type)
+{
+   assert(!type.empty());
+   return type_binding_requires_optional(type.front());
+}
+
 inline bool
 type_is_nonull(eolian_type_instance const& type)
 {
@@ -212,6 +235,8 @@ type_is_callback(eolian_type_instance const& type_ins)
 
 struct eo_generator_options
 {
+   std::string header_decl_file_name;
+   std::string header_impl_file_name;
    includes_container_type cxx_headers;
    includes_container_type c_headers;
 };
@@ -256,6 +281,7 @@ struct eo_function
        regular_, class_
      };
    eo_function_type type;
+   eolian_scope scope;
    std::string name;
    std::string impl;
    eolian_type_instance ret;
@@ -265,6 +291,7 @@ struct eo_function
 
 struct eo_event
 {
+   eolian_scope scope;
    std::string name;
    std::string eo_name;
    //parameters_container_type params; // XXX desirable.
index 92cc03f35a7681d1ee8dd47e06a20ce82dba2bf8..21fa3ea38d483210c02611585fd3a47ec6d1b2f2 100644 (file)
@@ -19,15 +19,17 @@ struct comment
 {
    std::string _doc;
    int _tab;
-   comment(std::string const& doc, int tab = 0)
-     : _doc(doc), _tab(tab)
+   std::string _if_empty;
+   comment(std::string const& doc, int tab = 0, std::string const& if_empty = "")
+     : _doc(doc), _tab(tab), _if_empty(if_empty)
    {}
 };
 
 inline std::ostream&
 operator<<(std::ostream& out, comment const& x)
 {
-   std::istringstream ss(x._doc);
+   std::string const& doc = !x._doc.empty() ? x._doc : x._if_empty;
+   std::istringstream ss(doc);
    std::string line;
    while(std::getline(ss, line))
      {
index 86a515edb9dc20aab511d369104fdd517a31f8d6..268855284df965a007b6308044793fe391ce7bc7 100644 (file)
@@ -46,7 +46,7 @@ operator<<(std::ostream& out, class_inheritance const& x)
      last = cls.ancestors.cend();
    for (it = first; it != last; ++it)
      {
-        out << tab(2) << ", ::" << abstract_namespace << "::" << *it << endl;
+        out << tab(2) << ", EO_CXX_INHERIT(" << *it << ")" << endl;
      }
    return out;
 }
@@ -115,6 +115,9 @@ operator<<(std::ostream& out, functors_constructor_methods const& x)
      {
         eo_constructor const& c = *it;
 
+        // Hide documentation condition
+        out << comment("@cond LOCAL", 1);
+
         // Struct declaration
         out << template_parameters_declaration(c.params, 1)
             << tab(1) << "struct " << constructor_functor_type_name(c) << endl
@@ -176,7 +179,10 @@ operator<<(std::ostream& out, functors_constructor_methods const& x)
                );
 
         // Close struct
-        out << tab(1) << "};" << endl << endl;
+        out << tab(1) << "};" << endl;
+
+        // End documentation condition
+        out << comment("@endcond", 1) << endl;
      }
 
    return out;
@@ -208,7 +214,7 @@ operator<<(std::ostream& out, constructor_method_function_declarations const& x)
              continue;
           }
 
-        out << comment(c.comment, 0)
+        out << comment(c.comment, 1)
             << template_parameters_declaration(c.params, 1)
             << tab(1) << constructor_functor_type_decl(c) << " " << c.name << "("
             << parameters_declaration(c.params) << ") const;" << endl << endl;
@@ -253,6 +259,51 @@ operator<<(std::ostream& out, constructor_method_function_definitions const& x)
    return out;
 }
 
+struct comment_constructor_with_constructor_methods
+{
+   eo_class const& _cls;
+   comment_constructor_with_constructor_methods(eo_class const& cls)
+     : _cls(cls)
+   {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, comment_constructor_with_constructor_methods const& x)
+{
+   out << tab(1) << "/**" << endl
+       << tab(2) << "@brief Constructs a new " << full_name(x._cls, false) << " object." << endl
+       << endl
+       << tab(2) << "Constructs a new " << full_name(x._cls, false) << " object. If you want this object to be a child" << endl
+       << tab(2) << "of another Eo object, use an @ref efl::eo::parent expression, like the example." << endl
+       << endl;
+
+   if (x._cls.constructors.size())
+     {
+        bool singular = (x._cls.constructors.size() == 1);
+        out << tab(2) << "Since this class have " << (singular ? "a " : "") << "constructor method" << (singular ? "" : "s")
+            <<  ", you must call " << (singular ? "it" : "each one of them") << endl
+            << tab(2) << "in the right place within this constructor parameters." << endl
+            << endl;
+     }
+
+   out << tab(2) << "Example:" << endl
+       << tab(2) << "@code" << endl
+       << tab(2) << full_name(x._cls, false) << " my_" << x._cls.name << "(" << endl;
+
+   for (eo_constructor const& c : x._cls.constructors)
+      out << tab(3) << "my_" << x._cls.name << "." << c.name << "(" << parameters_names(c.params) << ")," << endl;
+
+   out << tab(3) << "efl::eo::parent = parent_object);" << endl
+       << tab(2) << "@endcode" << endl
+       << endl;
+
+   for (eo_constructor const& c : x._cls.constructors)
+     out << tab(2) << "@see " << x._cls.name << "::" << c.name << endl;
+   out << tab(2) << "@see " << x._cls.name << "(Eo* eo)" << endl;
+
+   return out << tab(1) << "*/" << endl;
+}
+
 struct constructor_with_constructor_methods
 {
    eo_class const& _cls;
@@ -274,6 +325,8 @@ operator<<(std::ostream& out, constructor_with_constructor_methods const& x)
         cb_count += parameters_count_callbacks((*it).params);
      }
 
+   out << comment_constructor_with_constructor_methods(x._cls);
+
    if (cb_count != 0)
      {
         out << tab(1) << "template <";
@@ -398,6 +451,8 @@ struct function_call_constructor_methods
 inline std::ostream&
 operator<<(std::ostream& out, function_call_constructor_methods const& x)
 {
+   out << comment("@internal", 1);
+
    unsigned cb_count = 0;
 
    constructors_container_type::const_iterator it,
index 4b7a9b3d4dab8d966668d3b88634c4f1e414d7e3..b86b4c42430e56a6223d982eeccde78b1c718d36 100644 (file)
@@ -5,6 +5,7 @@
 #include <iosfwd>
 
 #include "type_generator.hh"
+#include "eo_class_scope_guard_generator.hh"
 #include "tab.hh"
 #include "comment.hh"
 
@@ -42,7 +43,8 @@ struct event_callback_add
 inline std::ostream&
 operator<<(std::ostream& out, event_callback_add const& x)
 {
-   out << tab(1) << "template <typename F>" << endl
+   out << comment(x._event.comment, 1)
+       << tab(1) << "template <typename F>" << endl
        << tab(1) << "::efl::eo::signal_connection" << endl
        << tab(1) << "callback_" << x._event.name << "_add(F && callback_," << endl
        << tab(8) << "::efl::eo::callback_priority priority_ =" << endl
@@ -75,7 +77,8 @@ struct event_callback_call
 inline std::ostream&
 operator<<(std::ostream& out, event_callback_call const& x)
 {
-   out << tab(1) << "template <typename T>" << endl
+   out << comment(x._event.comment, 1)
+       << tab(1) << "template <typename T>" << endl
        << tab(1) << "void" << endl
        << tab(1) << "callback_" << x._event.name << "_call(T* info)" << endl
        << tab(1) << "{" << endl
@@ -99,8 +102,12 @@ operator<<(std::ostream& out, events const& x)
 {
    for (eo_event const& e : x._events)
      {
+        out << scope_guard_head(x._cls, e);
+
         out << event_callback_add(e, x._cls, x._add_cast_to_t) << endl
            << event_callback_call(e, x._add_cast_to_t);
+
+        out << scope_guard_tail(x._cls, e) << endl;
      }
    out << endl;
    return out;
index 56b450badac3680209ed25dc28ee8a3094919c9b..1a64a8ca984e0266c3ff023a8c36c75cb4181954 100644 (file)
@@ -10,6 +10,7 @@
 #include "parameters_generator.hh"
 #include "type_generator.hh"
 #include "namespace_generator.hh"
+#include "eo_class_scope_guard_generator.hh"
 
 namespace efl { namespace eolian { namespace grammar {
 
@@ -52,7 +53,7 @@ operator<<(std::ostream& out, function_declaration const& x)
 
    out << reinterpret_type(func.ret) << " " << func.name << "("
        << parameters_declaration(func.params)
-       << (is_static ? ");" : ") const;") << endl << endl;
+       << (is_static ? ");" : ") const;") << endl;
 
    return out;
 }
@@ -91,10 +92,7 @@ operator<<(std::ostream& out, function_definition const& x)
      out << tab(1)
          << func.ret.front().native << " _tmp_ret;" << endl;
 
-   if (!is_static)
-      out << callbacks_heap_alloc("_concrete_eo_ptr()", func.params, 1);
-
-   // TODO : register free callback for static methods
+   out << callbacks_heap_alloc("_concrete_eo_ptr()", func.params, is_static, 1);
 
    out << tab(1) << "eo_do("
        << (is_static ? "_eo_class(), " : "_concrete_eo_ptr(), ")
@@ -103,7 +101,7 @@ operator<<(std::ostream& out, function_definition const& x)
    if (!function_is_void(func))
      out << tab(1) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl;
 
-   out << "}" << endl << endl;
+   out << "}" << endl;
    return out;
 }
 
@@ -120,7 +118,9 @@ operator<<(std::ostream& out, function_declarations const& x)
 {
    for (eo_function const& f : x._cls.functions)
      {
-        out << function_declaration(x._cls, f) << endl;
+        out << scope_guard_head(x._cls, f)
+            << function_declaration(x._cls, f)
+            << scope_guard_tail(x._cls, f) << endl;
      }
    return out;
 }
@@ -140,7 +140,9 @@ operator<<(std::ostream& out, function_definitions const& x)
 {
    for (eo_function const& f : x._cls.functions)
      {
-        out << function_definition(x._cls, f, x._concrete) << endl;
+        out << scope_guard_head(x._cls, f)
+            << function_definition(x._cls, f, x._concrete)
+            << scope_guard_tail(x._cls, f) << endl;
      }
    return out;
 }
index 15850abfd3f7540f28a93201b35b7b5b565a68ea..c1d227cbcce417faaaa34241f37c398e11934e7d 100644 (file)
@@ -40,7 +40,8 @@ struct concrete_eo_ptr_getter
 inline std::ostream&
 operator<<(std::ostream& out, concrete_eo_ptr_getter const&)
 {
-   out << tab(1) << "Eo* _concrete_eo_ptr() const" << endl
+   out << comment("@internal", 1)
+       << tab(1) << "Eo* _concrete_eo_ptr() const" << endl
        << tab(1) << "{" << endl
        << tab(2) << "return static_cast<::efl::eo::concrete const*>(static_cast<void const*>(this))->_eo_ptr();" << endl
        << tab(1) << "}" << endl << endl;
@@ -123,6 +124,8 @@ struct abstract_address_of
 inline std::ostream&
 operator<<(std::ostream& out, abstract_address_of const& x)
 {
+   out << comment("@cond LOCAL", 1);
+
    out << tab(1) << "template <typename D>" << endl
        << tab(1) << "struct address_of" << endl
        << tab(1) << "{" << endl
@@ -134,7 +137,9 @@ operator<<(std::ostream& out, abstract_address_of const& x)
        << tab(1) << "struct address_const_of" << endl
        << tab(1) << "{" << endl
        << tab(2) << address_of_to_pointer(x._cls, true) << endl
-       << tab(1) << "};" << endl << endl;
+       << tab(1) << "};" << endl;
+
+   out << comment("@endcond", 1) << endl;
 
    return out;
 }
@@ -168,6 +173,7 @@ struct concrete_address_of
 inline std::ostream&
 operator<<(std::ostream& out, concrete_address_of const& x)
 {
+   out << comment("@cond LOCAL", 1);
    std::vector<std::string> names {"address_of", "address_const_of"};
    for (int is_const = 0; is_const != 2; ++is_const)
      {
@@ -189,16 +195,18 @@ operator<<(std::ostream& out, concrete_address_of const& x)
             << (is_const ? " const" : "")
             << " { return " << name << "(this); }" << endl << endl;
      }
+   out << comment("@endcond", 1) << endl;
 
    return out;
 }
 
 inline void
-eo_class_generator(std::ostream& out, eo_class const& cls)
+eo_class_declarations_generator(std::ostream& out, eo_class const& cls)
 {
    out << namespace_head(cls)
        << "struct " << cls.name << ";" << endl << endl
        << namespace_tail(cls)
+       << comment("@cond EO_CXX_ABSTRACT")
        << "namespace " << abstract_namespace << " {" << endl << endl
        << namespace_head(cls)
        << comment(cls.comment)
@@ -209,12 +217,14 @@ eo_class_generator(std::ostream& out, eo_class const& cls)
        << eo_class_getter(cls)
        << class_implicit_conversion_declaration(cls)
        << abstract_address_of(cls)
-       << "private:" << endl
+       << "private:" << endl << endl
        << concrete_eo_ptr_getter(cls)
        << "};" << endl << endl
        << namespace_tail(cls)
-       << "}" << endl << endl
+       << "}" << endl
+       << comment("@endcond") << endl
        << namespace_head(cls)
+       << comment(cls.comment, 0, "@brief Class " + cls.name)
        << "struct " << cls.name << endl
        << tab(2) << ": ::efl::eo::concrete" << endl
        << class_inheritance(cls)
@@ -229,15 +239,22 @@ eo_class_generator(std::ostream& out, eo_class const& cls)
        << events(cls, cls.concrete_events) << endl
        << eo_class_getter(cls)
        << concrete_address_of(cls)
-        << "private:" << endl
+       << "private:" << endl << endl
        << function_call_constructor_methods(cls)
-       << tab(2) << "Eo* _concrete_eo_ptr() const { return _eo_ptr(); }" << endl
+       << comment("@internal", 1)
+       << tab(1) << "Eo* _concrete_eo_ptr() const { return _eo_ptr(); }" << endl
        << "};" << endl << endl
        << "static_assert(sizeof(" << full_name(cls) << ") == sizeof(Eo*), \"\");" << endl
        << "static_assert(std::is_standard_layout<" << full_name(cls) << ">::value, \"\");" << endl
        << endl
        << namespace_tail(cls)
-       << constructor_method_function_definitions(cls)
+       << endl;
+}
+
+inline void
+eo_class_definitions_generator(std::ostream& out, eo_class const& cls)
+{
+   out << constructor_method_function_definitions(cls)
        << function_definitions(cls, true)
        << function_definitions(cls, false)
        << 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 (file)
index 0000000..9d545c3
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef EOLIAN_CXX_STD_EO_CLASS_SCOPE_GUARD_GENERATOR_HH
+#define EOLIAN_CXX_STD_EO_CLASS_SCOPE_GUARD_GENERATOR_HH
+
+#include <cassert>
+
+#include "type_generator.hh"
+
+namespace efl { namespace eolian { namespace grammar {
+
+template <typename T>
+struct _scope_guard_head
+{
+   eo_class const& _cls;
+   T const& _e;
+   _scope_guard_head(eo_class const& cls, T const& e)
+     : _cls(cls), _e(e) {}
+};
+
+template <typename T>
+_scope_guard_head<T> scope_guard_head(eo_class const& cls, T const& e)
+{
+   return _scope_guard_head<T>(cls, e);
+}
+
+template <typename T>
+inline std::ostream&
+operator<<(std::ostream& out, _scope_guard_head<T> const& x)
+{
+   assert(x._e.scope != eolian_scope::private_);
+   if (x._e.scope == eolian_scope::protected_)
+     out << "#ifdef " << name_upper(x._cls) << "_PROTECTED" << endl;
+   return out;
+}
+
+template <typename T>
+struct _scope_guard_tail
+{
+   eo_class const& _cls;
+   T const& _e;
+   _scope_guard_tail(eo_class const& cls, T const& e)
+     : _cls(cls), _e(e) {}
+};
+
+template <typename T>
+struct _scope_guard_tail<T> scope_guard_tail(eo_class const& cls, T const& e)
+{
+   return _scope_guard_tail<T>(cls, e);
+}
+
+template <typename T>
+inline std::ostream&
+operator<<(std::ostream& out, _scope_guard_tail<T> const& x)
+{
+   if (x._e.scope == eolian_scope::protected_)
+     out << "#endif" << endl;
+   return out;
+}
+
+} } }
+
+#endif
index 56f4e28f97531981b30d28bae5488ccbe978162d..9ec4a3b480732958783743ca26166a5ce21b2f42 100644 (file)
@@ -115,14 +115,30 @@ include_headers(std::ostream& out,
 }
 
 inline void
-eo_header_generator(std::ostream& out, eo_class const& cls, eo_generator_options const& opts)
+include_header_impl(std::ostream& out,
+                eo_class const& cls EINA_UNUSED,
+                eo_generator_options const& opts)
+{
+   out << "#include \"" << opts.header_impl_file_name << "\"" << endl << endl;
+}
+
+inline void
+eo_headers_generator(std::ostream& header_decl,
+                     std::ostream& header_impl,
+                     eo_class const& cls,
+                     eo_generator_options const& opts)
 {
-   onceguard_head(out, cls);
-   include_headers(out, cls, opts);
-   eo_class_generator(out, cls);
-   eo_inheritance_detail_generator(out, cls);
-   onceguard_tail(out, cls);
-   out << endl;
+   onceguard_head(header_decl, cls);
+   include_headers(header_decl, cls, opts);
+   eo_class_declarations_generator(header_decl, cls);
+   include_header_impl(header_decl, cls, opts);
+   onceguard_tail(header_decl, cls);
+   header_decl << endl;
+
+   header_impl << comment("@cond EO_CXX_EO_IMPL") << endl;
+   eo_class_definitions_generator(header_impl, cls);
+   eo_inheritance_detail_generator(header_impl, cls);
+   header_impl << endl << comment("@endcond") << endl;
 }
 
 } } } // namespace efl { namespace eolian { namespace grammar {
index 38382d50929fbedeb952447d17a69185e39c1bb6..11b8f2a29edad7d90c158b033333fed43ae5a6e9 100644 (file)
@@ -30,9 +30,10 @@ _ns_as_prefix(eo_class const& cls)
 struct inheritance_operation
 {
    eo_class const& _cls;
+   eo_function const& _func;
    functions_container_type::size_type _idx;
-   inheritance_operation(eo_class const& cls, functions_container_type::size_type idx)
-     : _cls(cls), _idx(idx)
+   inheritance_operation(eo_class const& cls, eo_function const& func, functions_container_type::size_type idx)
+     : _cls(cls), _func(func), _idx(idx)
    {}
 };
 
@@ -40,7 +41,7 @@ inline std::ostream&
 operator<<(std::ostream& out, inheritance_operation const& x)
 {
    assert(x._idx < x._cls.functions.size());
-   eo_function const& func = x._cls.functions[x._idx];
+   eo_function const& func = x._func;
    out << tab(1)
        << "ops[" << x._idx << "].func = reinterpret_cast<void*>(& ::"
        << _ns_as_prefix(x._cls) << "_"
@@ -74,17 +75,30 @@ operator<<(std::ostream& out, inheritance_operations_description const& x)
        << ", Eo_Op_Description* ops)" << endl
        << "{" << endl
        << tab(1) << "(void)ops;" << endl;
-   functions_container_type::size_type n_ops = x._cls.functions.size();
-   for (functions_container_type::size_type i=0; i < n_ops; ++i)
+
+   auto funcs = x._cls.functions;
+   auto part = std::stable_partition(funcs.begin(), funcs.end(), [](eo_function const& f){ return f.scope == eolian_scope::public_; });
+
+   functions_container_type::size_type op_idx = 0;
+   for (auto it = funcs.begin(); it != part; ++it, ++op_idx)
      {
-        out << inheritance_operation(x._cls, i);
+        out << inheritance_operation(x._cls, *it, op_idx);
+     }
+
+   if (part != funcs.end())
+     {
+        out << scope_guard_head(x._cls, *part);
+        for (auto it = part; it != funcs.end(); ++it, ++op_idx)
+          out << inheritance_operation(x._cls, *it, op_idx);
+        out << scope_guard_tail(x._cls, *part);
      }
 
    for (std::string const& parent : x._cls.parents)
      {
         out << tab(1)
             << "initialize_operation_description<T>(::efl::eo::detail::tag<::"
-            << parent << ">(), &ops[" << x._cls.functions.size() << s << "]);" << endl;
+            << parent << ">(), &ops[operation_description_class_size< "
+            << full_name(x._cls) << " >::value" << s << "]);" << endl;
 
         s += " + operation_description_class_size<::" + parent + ">::value";
      }
@@ -110,6 +124,9 @@ operator<<(std::ostream& out, inheritance_wrappers const& x)
    for (it = first; it != last; ++it)
      {
         eo_function const& func = *it;
+
+        out << scope_guard_head(x._cls, func);
+
         out << "template <typename T>" << endl
             << reinterpret_type(func.ret) << " "
             << _ns_as_prefix(x._cls) << "_"
@@ -140,7 +157,9 @@ operator<<(std::ostream& out, inheritance_wrappers const& x)
         if (!function_is_void(func))
           out << tab(1) << "return _tmp_ret;" << endl;
 
-        out << "}" << endl << endl;
+        out << "}" << endl;
+
+        out << scope_guard_tail(x._cls, func) << endl;
      }
    return out;
 }
@@ -148,8 +167,9 @@ operator<<(std::ostream& out, inheritance_wrappers const& x)
 struct inheritance_base_operations_size
 {
    eo_class const& _cls;
-   inheritance_base_operations_size(eo_class const& cls)
-     : _cls(cls)
+   functions_container_type const& _funcs;
+   inheritance_base_operations_size(eo_class const& cls, functions_container_type const& funcs)
+     : _cls(cls), _funcs(funcs)
    {}
 };
 
@@ -160,8 +180,8 @@ operator<<(std::ostream& out, inheritance_base_operations_size const& x)
        << endl << "struct operation_description_class_size< "
        << full_name(x._cls) << " >" << endl
        << "{" << endl
-       << tab(1) << "static const int value = "
-       << x._cls.functions.size();
+       << tab(1) << "static constexpr int value = "
+       << x._funcs.size();
 
    for (std::string const& parent : x._cls.parents)
      {
@@ -175,6 +195,27 @@ operator<<(std::ostream& out, inheritance_base_operations_size const& x)
    return out;
 }
 
+struct inheritance_base_operations_size_scopes
+{
+   eo_class const& _cls;
+   inheritance_base_operations_size_scopes(eo_class const& cls)
+     : _cls(cls)
+   {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, inheritance_base_operations_size_scopes const& x)
+{
+   auto funcs = x._cls.functions;
+   auto part = std::stable_partition(funcs.begin(), funcs.end(), [](eo_function const& f){ return f.scope == eolian_scope::public_; });
+
+   out << "#ifdef " << name_upper(x._cls) << "_PROTECTED" << endl
+       << inheritance_base_operations_size(x._cls, funcs)
+       << "#else" << endl
+       << inheritance_base_operations_size(x._cls, {funcs.begin(), part})
+       << "#endif" << endl << endl;
+   return out;
+}
 
 struct inheritance_base_operations_extensions
 {
@@ -230,7 +271,7 @@ operator<<(std::ostream& out, inheritance_base_operations_function const& x)
    if (!is_void)
      out << tab(3) << func.ret.front().native << " _tmp_ret = {};"  << endl;
 
-   out << callbacks_heap_alloc("dynamic_cast<T*>(this)->_eo_ptr()", func.params, 3)
+   out << callbacks_heap_alloc("dynamic_cast<T*>(this)->_eo_ptr()", func.params, function_is_static(x._func), 3)
        << endl;
 
    out << tab(3)
@@ -241,7 +282,7 @@ operator<<(std::ostream& out, inheritance_base_operations_function const& x)
    if (!is_void)
      out << tab(4) << "return " << to_cxx(func.ret, "_tmp_ret") << ";" << endl;
 
-   return out << tab(2) << "}" << endl << endl;
+   return out << tab(2) << "}" << endl;
 }
 
 struct inheritance_base_operations
@@ -265,7 +306,9 @@ operator<<(std::ostream& out, inheritance_base_operations const& x)
      last = x._cls.functions.end();
    for (it = first; it != last; ++it)
      {
+        out << scope_guard_head(x._cls, *it);
         out << inheritance_base_operations_function(x._cls, *it);
+        out << scope_guard_tail(x._cls, *it) << endl;
      }
    out << tab(1) << "};" << endl
        << "};" << endl << endl;
@@ -365,7 +408,7 @@ eo_inheritance_detail_generator(std::ostream& out, eo_class const& cls)
      out << inheritance_wrappers(cls)
          << "namespace efl { namespace eo { namespace detail {" << endl << endl
          << inheritance_base_operations(cls) << endl
-         << inheritance_base_operations_size(cls)
+         << inheritance_base_operations_size_scopes(cls)
          << inheritance_operations_description(cls)
          << inheritance_call_constructors(cls)
          << inheritance_eo_class_getter(cls)
index 20f9e99c524187502fd3de93ce646c27067f3ebf..2d590f2b35b0fe903f3ec799088f92ab03f7e0a7 100644 (file)
@@ -105,30 +105,6 @@ operator<<(std::ostream& out, callback_tmp const& x)
    return out << "_tmp_" << x._name;
 }
 
-struct
-callback_parameter_heap_alloc
-{
-   eolian_type_instance const& _type;
-   std::string const& _name;
-   int _tab;
-   callback_parameter_heap_alloc(eolian_type_instance const& type, std::string const& name, int tab)
-     : _type(type)
-     , _name(name)
-     , _tab(tab)
-   {}
-};
-
-inline std::ostream&
-operator<<(std::ostream& out, callback_parameter_heap_alloc const& x)
-{
-   out << tab(x._tab) << parameter_remove_reference_typedef(x._type, x._name) << endl
-       << tab(x._tab) << parameter_no_ref_type(x._type, x._name) << "* "
-       << callback_tmp(x._name) << " = new "
-       << parameter_no_ref_type(x._type, x._name) << "(std::forward<"
-       << template_parameter_type(x._type, x._name) << ">(" << x._name << "));" << endl;
-   return out;
-}
-
 struct
 callback_parameter_free_ev_add
 {
@@ -157,10 +133,12 @@ callbacks_heap_alloc
 {
    std::string const& _eo_raw_expr;
    parameters_container_type const& _params;
+   bool _is_static_func;
    int _tab;
-   callbacks_heap_alloc(std::string const& eo_raw_expr, parameters_container_type const& params, int tab)
+   callbacks_heap_alloc(std::string const& eo_raw_expr, parameters_container_type const& params, bool is_static_func, int tab)
      : _eo_raw_expr(eo_raw_expr)
      , _params(params)
+     , _is_static_func(is_static_func)
      , _tab(tab)
    {}
 };
@@ -171,12 +149,30 @@ operator<<(std::ostream& out, callbacks_heap_alloc const& x)
    auto first = x._params.cbegin(), last = x._params.cend();
    for (auto it = first; it != last; ++it)
      {
-        if (type_is_callback((*it).type) && it+1 != last)
+        auto type = (*it).type;
+        auto name = (*it).name;
+        if (type_is_callback(type) && it+1 != last)
           {
-             out << callback_parameter_heap_alloc((*it).type, (*it).name, x._tab)
-                 << tab(x._tab)
-                 << callback_parameter_free_ev_add(x._eo_raw_expr, (*it).type, (*it).name)
-                 << endl << endl;
+
+             out << tab(x._tab) << parameter_remove_reference_typedef(type, name) << endl
+                 << tab(x._tab) << parameter_no_ref_type(type, name) << "* "
+                 << callback_tmp(name) << " = ";
+
+            if (!x._is_static_func)
+              {
+                 out << "new " << parameter_no_ref_type(type, name)
+                     << "(std::forward< "
+                     << template_parameter_type(type, name) << " >(" << name << "));" << endl
+                     << tab(x._tab)
+                     << callback_parameter_free_ev_add(x._eo_raw_expr, type, name)
+                     << endl << endl;
+              }
+            else
+              {
+                 out << "::efl::eolian::alloc_static_callback< "
+                     << parameter_no_ref_type(type, name) << " >(std::forward< "
+                     << template_parameter_type(type, name) << " >(" << name << "));" << endl;
+              }
              ++it; // skip next.
           }
      }
@@ -272,6 +268,56 @@ operator<<(std::ostream& out, parameters_c_declaration const& x)
    return out;
 }
 
+struct
+parameters_names
+{
+   parameters_container_type const& _params;
+   parameters_names(parameters_container_type const& params)
+     : _params(params)
+   {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, parameters_names const& x)
+{
+   auto first = x._params.cbegin(),
+        last = x._params.cend();
+   for (auto it = first; it != last; ++it)
+     {
+        if (it != first)
+          out << ", ";
+
+        out << it->name;
+
+        if (type_is_callback(it->type) && it+1 != last)
+          ++it; // skip next.
+     }
+   return out;
+}
+
+struct
+parameters_c_names
+{
+   parameters_container_type const& _params;
+   parameters_c_names(parameters_container_type const& params)
+     : _params(params)
+   {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, parameters_c_names const& x)
+{
+   auto first = x._params.cbegin(),
+        last = x._params.cend();
+   for (auto it = first; it != last; ++it)
+     {
+        if (it != first)
+          out << ", ";
+        out << it->name;
+     }
+   return out;
+}
+
 struct
 parameters_types
 {
index 5913330b4267aef166393fca85add9a89cd1d777..193d2ea88a07d2aa57e32d874e5531bebc65d4b8 100644 (file)
@@ -46,6 +46,21 @@ operator<<(std::ostream& out, abstract_full_name const& x)
    return out << abstract_namespace << full_name(x._cls);
 }
 
+struct name_upper
+{
+   eo_class const& _cls;
+   name_upper(eo_class const& cls)
+     : _cls(cls) {}
+};
+
+inline std::ostream&
+operator<<(std::ostream& out, name_upper const& x)
+{
+   std::string key = x._cls.name;
+   std::transform(key.begin(), key.end(), key.begin(), ::toupper);
+   return out << key;
+}
+
 struct c_type
 {
    eolian_type_instance const& _list;
@@ -91,10 +106,13 @@ operator<<(std::ostream& out, efl::eolian::grammar::reinterpret_type const& x)
      }
    assert(!res.empty());
 
-   if (x._type.is_out && type_is_binding(x._type.front()))
-     res += "*";
-   else if (!x._type.is_nonull && x._type.front().is_class)
-     res = "::efl::eina::optional< " + res + " >";
+   if (type_is_binding(x._type.front()))
+     {
+        if (x._type.is_out)
+          res += "*";
+        else if (!x._type.is_nonull && x._type.front().binding_requires_optional)
+          res = "::efl::eina::optional< " + res + " >";
+     }
 
    return out << res;
 }
index 5192fa0a01783e74da56d28dc84dbe3ba4d9ae1a..ef978fbcbeb1e354d8c0ca4330a7431a26774252 100644 (file)
@@ -48,5 +48,11 @@ static void _callback_twocallback(Eo *obj EINA_UNUSED, Callback_Data *pd EINA_UN
   cb(data);
 }
 
+static void _callback_test_global_callbacks(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED
+                                            , Ecore_Cb cb, void *data)
+{
+  cb(data);
+}
+
 #include "callback.eo.c"
 
index 16dd76ee6f5ce4e10fe117f9b61d0ed48cc87665..50583064af3f6a117455882cbb0d0e0724e295c5 100644 (file)
@@ -16,6 +16,12 @@ class Callback (Eo.Base)
            @in Ecore_Cb cb2;
          }
       }
+      test_global_callbacks @class {
+         params {
+           @in Ecore_Cb cb;
+           @in void* data;
+         }
+      }
    }
    implements {
       Eo.Base.constructor;
index 5c5d95f03514bafd88d3ccaa1ce2f397813205fc..2acfd09e63dd36f40a7149fd6d1e3e0b78a98a8d 100644 (file)
@@ -109,10 +109,23 @@ START_TEST(eolian_cxx_test_callback_event_del)
 }
 END_TEST
 
+START_TEST(eolian_cxx_test_global_callback)
+{
+  efl::eo::eo_init i;
+
+  bool called = false;
+
+  callback::test_global_callbacks(std::bind([&called] { called = true; }));
+
+  fail_if(!called);
+}
+END_TEST
+
 void
 eolian_cxx_test_callback(TCase* tc)
 {
    tcase_add_test(tc, eolian_cxx_test_callback_method);
    tcase_add_test(tc, eolian_cxx_test_callback_event_add);
    tcase_add_test(tc, eolian_cxx_test_callback_event_del);
+   tcase_add_test(tc, eolian_cxx_test_global_callback);
 }