summaryrefslogblamecommitdiff
path: root/src/bin/eolian_cxx/eolian_wrappers.hh
blob: 65f218d6e4b65b84b8a6527e93295d22765acba9 (plain) (tree)
1
2
3
4
5



                                     
                   





















                                                                                         








                                                                  
                          

                                        

                                    
                                                           
             
             


                  
                                     
 
                                                    


                  
                                          
 
                                                               


                  
                                     
 
                                                      


                  
                                          
 
                                                         

 
                           

                                             
                                                        


                  
                                        
 
                      
                                           













                                    

                                                                     














                                             
                                           
                                     
 
                                                  
                                                                








                                                    
                          




                  
                                               

                 
                                                              
              
                                   



                                            
                           

                                 
                        

 

                                              
 

                                                                              
 





                                                      
 

                                                 
 



                                                                                 


                  

                                          
                                                           


                  
                                          
 
                                                            


                             


                           
                                             
 
                                            

 







                                                 






                                                                             





                                             





                                                               


                                                                                


                                                                       




                                                          
                                                     




                                                
                                                            

 




                                                                           
                  


                                                        

 
                                        
                                                                                                   
 
                                                                           


                                        
                                                                     
 
                                                      


                                        
                                                                     
 
                                                      


                                        
                                                                     
 
                                                      

 
           

                                                                                 


                                                       


                                                               

 








                                                                                   
           





                                                                         
                                               
 
                                                     








                                                                         
                                               
 
                                                     


                  
                                                          
 
                                                                  


           
                                                            
 
                                                                               


                                                                           
                                        
                                                          

                                         
                                                            
                         
                                   
      
                                                                  
                                                       
                           

                                   

                                                                   


               
                            
                                                                   

                               

                                                      



                                                                 
                                                                         
                                                                       
                                             

                                                                                    

                                     




                                         
                                     

                                             
                                                          

                                
      

                                                 
                           


                 

























































                                                                             


                                       
#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 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)
{
   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_beta(Eolian_Function const& func)
{
   return ::eolian_function_is_beta(&func);
}

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)
{
   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
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(&parameter)) + "_";
}

inline bool
parameter_is_out(Eolian_Function_Parameter const& parameter)
{
   Eolian_Parameter_Dir direction = eolian_parameter_direction_get(&parameter);
   return direction == EOLIAN_OUT_PARAM || direction == EOLIAN_INOUT_PARAM;
}

inline efl::eolian::eolian_type_instance
parameter_type(Eolian_Function_Parameter const& parameter)
{
   efl::eolian::eolian_type_instance type
     (type_lookup(::eolian_parameter_type_get(&parameter)));
   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 += "*";
     }
   type.is_optional = ::eolian_parameter_is_optional(&parameter) ||
                      ::eolian_parameter_is_nullable(&parameter);
   return type;
}

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.scope = eolian_scope_cxx(::eolian_event_scope_get(event_));
        event.is_beta = (::eolian_event_is_beta(event_) != EINA_FALSE);
        event.name = normalize_spaces(name_);
        event.eo_name = safe_upper
          (find_replace(class_full_name(klass), ".", "_") + "_EVENT_" + event.name);
        /* FIXME: use doc api */
        event.comment = safe_str("");
     }
   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