forked from enlightenment/efl
470 lines
12 KiB
C++
470 lines
12 KiB
C++
#ifndef EOLIAN_CXX_EOLIAN_WRAPPERS_HH
|
|
#define EOLIAN_CXX_EOLIAN_WRAPPERS_HH
|
|
|
|
#include <cassert>
|
|
#include <libgen.h>
|
|
|
|
#include <Eolian.h>
|
|
|
|
#include "eo_types.hh"
|
|
#include "safe_strings.hh"
|
|
#include "type_lookup.hh"
|
|
|
|
namespace eolian_cxx
|
|
{
|
|
|
|
struct property_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_PROPERTY; };
|
|
property_t const property = {};
|
|
|
|
struct setter_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_PROP_SET; };
|
|
setter_t const setter = {};
|
|
|
|
struct getter_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_PROP_GET; };
|
|
getter_t const getter = {};
|
|
|
|
struct method_t { static constexpr ::Eolian_Function_Type value = ::EOLIAN_METHOD; };
|
|
method_t const method = {};
|
|
|
|
inline const Eolian_Class*
|
|
class_from_file(std::string const& file)
|
|
{
|
|
char *dup = strdup(file.c_str());
|
|
char *bn = basename(dup);
|
|
const Eolian_Class *cl = ::eolian_class_get_by_file(bn);
|
|
free(dup);
|
|
return cl;
|
|
}
|
|
|
|
inline std::string
|
|
class_file(Eolian_Class const& klass)
|
|
{
|
|
return safe_str(::eolian_class_file_get(&klass));
|
|
}
|
|
|
|
inline std::string
|
|
class_base_file(Eolian_Class const& klass)
|
|
{
|
|
return path_base(safe_str(::eolian_class_file_get(&klass)));
|
|
}
|
|
|
|
inline std::string
|
|
class_name(Eolian_Class const& klass)
|
|
{
|
|
return safe_lower(::eolian_class_name_get(&klass));
|
|
}
|
|
|
|
inline std::string
|
|
class_full_name(Eolian_Class const& klass)
|
|
{
|
|
return safe_str(::eolian_class_full_name_get(&klass));
|
|
}
|
|
|
|
inline const Eolian_Class *
|
|
class_from_name(std::string const& classname)
|
|
{
|
|
return ::eolian_class_get_by_name(classname.c_str());
|
|
}
|
|
|
|
inline std::string
|
|
class_eo_name(Eolian_Class const& klass)
|
|
{
|
|
std::string suffix;
|
|
switch (::eolian_class_type_get(&klass))
|
|
{
|
|
case EOLIAN_CLASS_REGULAR:
|
|
case EOLIAN_CLASS_ABSTRACT:
|
|
suffix = "CLASS";
|
|
break;
|
|
case EOLIAN_CLASS_MIXIN:
|
|
suffix = "MIXIN";
|
|
break;
|
|
case EOLIAN_CLASS_INTERFACE:
|
|
suffix = "INTERFACE";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return safe_upper
|
|
(find_replace(class_full_name(klass) + "_" + suffix, ".", "_"));
|
|
}
|
|
|
|
inline std::string
|
|
class_format_cxx(std::string const& fullname)
|
|
{
|
|
std::string s = fullname;
|
|
auto found = s.find(".");
|
|
while (found != std::string::npos)
|
|
{
|
|
s.replace(found, 1, "::");
|
|
found = s.find(".");
|
|
}
|
|
return s;
|
|
}
|
|
|
|
inline efl::eolian::eo_class::eo_class_type
|
|
class_type(Eolian_Class const& klass)
|
|
{
|
|
efl::eolian::eo_class::eo_class_type type = {};
|
|
Eolian_Class_Type cls_type = ::eolian_class_type_get(&klass);
|
|
|
|
if (cls_type == EOLIAN_CLASS_REGULAR)
|
|
type = efl::eolian::eo_class::regular_;
|
|
else if (cls_type == EOLIAN_CLASS_ABSTRACT)
|
|
type = efl::eolian::eo_class::regular_noninst_;
|
|
else if (cls_type == EOLIAN_CLASS_MIXIN)
|
|
type = efl::eolian::eo_class::mixin_;
|
|
else if (cls_type == EOLIAN_CLASS_INTERFACE)
|
|
type = efl::eolian::eo_class::interface_;
|
|
else { assert(false); }
|
|
|
|
return type;
|
|
}
|
|
|
|
inline std::string
|
|
class_namespace_full(Eolian_Class const& klass)
|
|
{
|
|
std::string s;
|
|
Eina_Iterator* itr = ::eolian_class_namespaces_get(&klass);
|
|
void* name;
|
|
EINA_ITERATOR_FOREACH(itr, name)
|
|
{
|
|
s += static_cast<const char*>(name);
|
|
s += "::";
|
|
}
|
|
eina_iterator_free(itr);
|
|
if (s.size() >= 2)
|
|
s = s.substr(0, s.size()-2);
|
|
return safe_lower(s);
|
|
}
|
|
|
|
inline efl::eina::iterator<const Eolian_Class>
|
|
class_list_all()
|
|
{
|
|
return efl::eina::iterator<const Eolian_Class>(::eolian_all_classes_get());
|
|
}
|
|
|
|
inline Eolian_Function const&
|
|
constructor_function(Eolian_Constructor const& ctor)
|
|
{
|
|
assert(!!::eolian_constructor_function_get(&ctor));
|
|
return * ::eolian_constructor_function_get(&ctor);
|
|
}
|
|
|
|
inline efl::eina::iterator<const Eolian_Function>
|
|
functions_get(Eolian_Class const& cls)
|
|
{
|
|
Eina_Iterator *itr = ::eolian_class_functions_get(&cls, EOLIAN_METHOD); // XXX
|
|
return itr
|
|
? efl::eina::iterator<const Eolian_Function>(itr)
|
|
: efl::eina::iterator<const Eolian_Function>();
|
|
}
|
|
|
|
inline std::string
|
|
function_name(Eolian_Function const& func)
|
|
{
|
|
return keyword_avoid(::eolian_function_name_get(&func));
|
|
}
|
|
|
|
inline std::string
|
|
function_impl(Eolian_Function const& func)
|
|
{
|
|
const char *s = ::eolian_function_full_c_name_get(&func);
|
|
std::string ret(s);
|
|
::eina_stringshare_del(s);
|
|
return ret;
|
|
}
|
|
|
|
inline Eolian_Function_Type
|
|
function_op_type(Eolian_Function const& func)
|
|
{
|
|
return ::eolian_function_type_get(&func);
|
|
}
|
|
|
|
inline efl::eolian::eo_function::eo_function_type
|
|
function_type(Eolian_Function const& func)
|
|
{
|
|
return ::eolian_function_is_class(&func)
|
|
? efl::eolian::eo_function::class_
|
|
: efl::eolian::eo_function::regular_
|
|
;
|
|
}
|
|
|
|
inline bool
|
|
function_is_constructor(Eolian_Class const& cls, Eolian_Function const& func)
|
|
{
|
|
return ::eolian_function_is_constructor(&func, &cls);
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
inline bool
|
|
function_is_visible(Eolian_Function const& func, method_t)
|
|
{
|
|
return function_is_visible(func, method_t::value);
|
|
}
|
|
|
|
inline bool
|
|
function_is_visible(Eolian_Function const& func)
|
|
{
|
|
return function_is_visible(func, function_op_type(func));
|
|
}
|
|
|
|
inline bool
|
|
function_is_visible(Eolian_Constructor const& ctor_)
|
|
{
|
|
Eolian_Function const* func = ::eolian_constructor_function_get(&ctor_);
|
|
Eolian_Class const* cls = ::eolian_constructor_class_get(&ctor_);
|
|
assert(!!func);
|
|
assert(!!cls);
|
|
return (::eolian_class_ctor_enable_get(cls) &&
|
|
function_is_visible(*func, method_t::value));
|
|
}
|
|
|
|
inline efl::eolian::eolian_type_instance
|
|
function_return_type(Eolian_Function const& func, Eolian_Function_Type func_type = method_t::value)
|
|
{
|
|
return type_lookup(::eolian_function_return_type_get(&func, func_type));
|
|
}
|
|
|
|
inline efl::eolian::eolian_type_instance
|
|
function_return_type(Eolian_Function const& func, setter_t func_type)
|
|
{
|
|
return function_return_type(func, func_type.value);
|
|
}
|
|
|
|
inline efl::eolian::eolian_type_instance
|
|
function_return_type(Eolian_Function const& func, getter_t func_type)
|
|
{
|
|
return function_return_type(func, func_type.value);
|
|
}
|
|
|
|
inline efl::eolian::eolian_type_instance
|
|
function_return_type(Eolian_Function const& func, method_t func_type)
|
|
{
|
|
return function_return_type(func, func_type.value);
|
|
}
|
|
|
|
inline bool
|
|
function_return_is_explicit_void(Eolian_Function const& func, getter_t func_type)
|
|
{
|
|
// XXX This function shouldn't exist. Eolian should
|
|
// forge functions a priori. Bindings generators
|
|
// shouldn't be required to convert such thing.
|
|
Eolian_Type const* type =
|
|
::eolian_function_return_type_get(&func, func_type.value);
|
|
return !!type && type->type == EOLIAN_TYPE_VOID;
|
|
}
|
|
|
|
inline efl::eina::iterator<const Eolian_Function>
|
|
properties_get(Eolian_Class const& cls)
|
|
{
|
|
Eina_Iterator *itr = ::eolian_class_functions_get(&cls, EOLIAN_PROPERTY); // XXX
|
|
return itr
|
|
? efl::eina::iterator<const Eolian_Function>(itr)
|
|
: efl::eina::iterator<const Eolian_Function>();
|
|
}
|
|
|
|
inline bool
|
|
property_is_getter(Eolian_Function_Type func_type)
|
|
{
|
|
return func_type == property_t::value || func_type == getter_t::value;
|
|
}
|
|
|
|
inline bool
|
|
property_is_getter(Eolian_Function const& func)
|
|
{
|
|
return property_is_getter(function_op_type(func));
|
|
}
|
|
|
|
inline bool
|
|
property_is_setter(Eolian_Function_Type func_type)
|
|
{
|
|
return func_type == property_t::value || func_type == setter_t::value;
|
|
}
|
|
|
|
inline bool
|
|
property_is_setter(Eolian_Function const& func)
|
|
{
|
|
return property_is_setter(function_op_type(func));
|
|
}
|
|
|
|
inline std::string
|
|
parameter_name(Eolian_Function_Parameter const& parameter)
|
|
{
|
|
return safe_str(::eolian_parameter_name_get(¶meter)) + "_";
|
|
}
|
|
|
|
inline bool
|
|
parameter_is_out(Eolian_Function_Parameter const& parameter)
|
|
{
|
|
Eolian_Parameter_Dir direction = eolian_parameter_direction_get(¶meter);
|
|
return direction == EOLIAN_OUT_PARAM || direction == EOLIAN_INOUT_PARAM;
|
|
}
|
|
|
|
inline bool
|
|
parameter_is_const(Eolian_Function_Parameter const& parameter,
|
|
Eolian_Function_Type func_type)
|
|
{
|
|
return ::eolian_parameter_const_attribute_get
|
|
(¶meter, property_is_getter(func_type));
|
|
}
|
|
|
|
inline bool
|
|
parameter_is_const(Eolian_Function_Parameter const& parameter,
|
|
getter_t func_type)
|
|
{
|
|
return ::eolian_parameter_const_attribute_get
|
|
(¶meter, property_is_getter(func_type.value));
|
|
}
|
|
|
|
inline bool
|
|
parameter_is_const(Eolian_Function_Parameter const& parameter,
|
|
setter_t func_type)
|
|
{
|
|
return ::eolian_parameter_const_attribute_get
|
|
(¶meter, property_is_getter(func_type.value));
|
|
}
|
|
|
|
inline bool
|
|
parameter_is_const(Eolian_Function_Parameter const& parameter,
|
|
Eolian_Function const& func)
|
|
{
|
|
assert(function_op_type(func) != EOLIAN_PROPERTY);
|
|
return ::eolian_parameter_const_attribute_get
|
|
(¶meter, property_is_getter(func));
|
|
}
|
|
|
|
inline efl::eolian::eolian_type_instance
|
|
parameter_type(Eolian_Function_Parameter const& parameter,
|
|
Eolian_Function_Type func_type = method_t::value)
|
|
{
|
|
efl::eolian::eolian_type_instance type
|
|
(type_lookup(::eolian_parameter_type_get(¶meter)));
|
|
assert(!type.empty());
|
|
if (parameter_is_out(parameter))
|
|
{
|
|
if (type.front().native.find("char") != std::string::npos)
|
|
type = { efl::eolian::type_to_native(type) };
|
|
type.is_out = true;
|
|
type.front().native += "*";
|
|
}
|
|
if (parameter_is_const(parameter, func_type))
|
|
{
|
|
type.front().native.insert(0, "const ");
|
|
if (!type.front().binding.empty())
|
|
type.front().binding.insert(0, "const ");
|
|
}
|
|
return type;
|
|
}
|
|
|
|
inline efl::eolian::eolian_type_instance
|
|
parameter_type(Eolian_Function_Parameter const& parameter, getter_t func_type)
|
|
{
|
|
return parameter_type(parameter, func_type.value);
|
|
}
|
|
|
|
inline efl::eolian::eolian_type_instance
|
|
parameter_type(Eolian_Function_Parameter const& parameter, setter_t func_type)
|
|
{
|
|
return parameter_type(parameter, func_type.value);
|
|
}
|
|
|
|
inline efl::eolian::eo_event
|
|
event_create(Eolian_Class const& klass, const Eolian_Event *event_)
|
|
{
|
|
efl::eolian::eo_event event;
|
|
const char *name = ::eolian_event_name_get(event_);
|
|
if (name)
|
|
{
|
|
std::string name_ = safe_str(name);
|
|
std::transform(name_.begin(), name_.end(), name_.begin(),
|
|
[](int c) { return c != ',' ? c : '_'; });
|
|
event.name = normalize_spaces(name_);
|
|
event.eo_name = safe_upper
|
|
(find_replace(class_full_name(klass), ".", "_") + "_EVENT_" + event.name);
|
|
event.comment = safe_str(eolian_event_description_get(event_));
|
|
}
|
|
return event;
|
|
}
|
|
|
|
inline efl::eolian::events_container_type
|
|
event_list(Eolian_Class const& klass)
|
|
{
|
|
efl::eolian::events_container_type events;
|
|
Eina_Iterator *itr = ::eolian_class_events_get(&klass);
|
|
Eolian_Event *e;
|
|
EINA_ITERATOR_FOREACH(itr, e)
|
|
{
|
|
events.push_back(event_create(klass, e));
|
|
}
|
|
eina_iterator_free(itr);
|
|
return events;
|
|
}
|
|
|
|
inline efl::eina::iterator<const Eolian_Implement>
|
|
implements_get(Eolian_Class const& cls)
|
|
{
|
|
Eina_Iterator *itr = ::eolian_class_implements_get(&cls);
|
|
return itr
|
|
? efl::eina::iterator<const Eolian_Implement>(itr)
|
|
: efl::eina::iterator<const Eolian_Implement>();
|
|
}
|
|
|
|
inline bool
|
|
implement_is_property_get(Eolian_Implement const& impl)
|
|
{
|
|
return ::eolian_implement_is_prop_get(&impl);
|
|
}
|
|
|
|
inline bool
|
|
implement_is_property_set(Eolian_Implement const& impl)
|
|
{
|
|
return ::eolian_implement_is_prop_set(&impl);
|
|
}
|
|
|
|
inline bool
|
|
implement_is_property(Eolian_Implement const& impl)
|
|
{
|
|
return implement_is_property_get(impl) ||
|
|
implement_is_property_set(impl);
|
|
}
|
|
|
|
inline Eolian_Function const*
|
|
implement_function(Eolian_Implement const& impl)
|
|
{
|
|
return ::eolian_implement_function_get(&impl, nullptr);
|
|
}
|
|
|
|
inline Eolian_Class const*
|
|
implement_class(Eolian_Implement const& impl)
|
|
{
|
|
return ::eolian_implement_class_get(&impl);
|
|
}
|
|
|
|
// XXX This function shouldn't exist. Eolian should provide some way
|
|
// to determine if a method is a destructor.
|
|
inline bool
|
|
implement_is_destructor(Eolian_Implement const& impl)
|
|
{
|
|
return !safe_str
|
|
(::eolian_implement_full_name_get(&impl)).compare("Eo.Base.destructor");
|
|
}
|
|
|
|
inline bool
|
|
implement_is_visible(Eolian_Implement const& impl)
|
|
{
|
|
return function_is_visible(*implement_function(impl)) &&
|
|
!::eolian_implement_is_virtual(&impl) &&
|
|
!::eolian_implement_is_empty(&impl) &&
|
|
!implement_is_destructor(impl);
|
|
}
|
|
|
|
}
|
|
|
|
#endif // EOLIAN_CXX_EOLIAN_WRAPPERS_HH
|