eolian_cxx: Add protected methods and events to C++ wrappers and fixes

Using eina::string_view in eolian generated interfaces (instead of
std::string) to allow lightweight passing of both C strings and C++
std::string.

Also, No longer using eina::optional in generated headers for types
that already implements the concept of null state (like Eo wrappers
and eina_accessor).

Also fix allocating callback objects require by class methods
(i.e. static) in static vectors so the memory will be freed when the
programs exit.

Added a new test case for testing callbacks on class methods.

Moved method definitions and supplementary code from generated C++
wrappers to auxiliary header file (.eo.impl.hh) generated together
with the main ".eo.hh" file. Updated Makefiles to list such files in
the compilation and cleanup processes. Updated .gitignore to include
these new generated files.

Made general adjustments on the documentation of generated C++ wrappers

Added "PREDEFINED" preprocessor macro definition in the Doxyfile.in in
order to make some adjustments for better documentation in the C++
generated headers.  Excluding generation of documentation for classes
in the "eo_cxx" namespace (the namespace for "abstract" eolian C++
wrappers).  Now generating the documentation for the events too.
Hiding some auxiliary code from being documented. Some aesthetic
adjustments for generated white space. Generate documentation for the
main constructor of C++ wrappers and added auxiliary grammars to list
parameters names.
This commit is contained in:
Vitor Sousa 2015-01-12 12:00:59 -02:00 committed by Felipe Magno de Almeida
parent be58d02cb6
commit d530389898
32 changed files with 622 additions and 125 deletions

1
.gitignore vendored
View File

@ -32,6 +32,7 @@ tags
*.eo.h
*.eo.legacy.h
*.eo.hh
*.eo.impl.hh
*.eo.lua
*.luac
.dir-locals.el

View 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.

View 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)

View 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)

View 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)

View 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)

View 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

View 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 \

View 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)

View 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

View 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),

View 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())
{
efl::eolian::generate(outfile, cls, gen_opts);
outfile.close();
}
else
std::ofstream header_decl;
header_decl.open(header_decl_file_name);
if (!header_decl.good())
{
EINA_CXX_DOM_LOG_ERR(eolian_cxx::domain)
<< "Can't open output file: " << outname << std::endl;
<< "Can't open output file: " << header_decl_file_name << std::endl;
return false;
}
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: " << 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;
}

View 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);

View 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"}},
};
}

View File

@ -21,6 +21,12 @@
#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

View 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

View 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 $@ $<

View File

@ -10,9 +10,12 @@
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);
}
} }

View 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.

View 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))
{

View 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,

View 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;

View 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;
}

View 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);

View File

@ -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

View 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)
{
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;
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(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 {

View 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)

View 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
{

View 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;
}

View 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"

View 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;

View 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);
}