Eolian: Support of virtual pure functions.
authorDaniel Zaoui <daniel.zaoui@samsung.com>
Wed, 19 Feb 2014 08:30:02 +0000 (10:30 +0200)
committerDaniel Zaoui <daniel.zaoui@samsung.com>
Mon, 3 Mar 2014 12:09:55 +0000 (14:09 +0200)
Virtual pure can be defined in Eolian format by adding in the section
implements virtual::class_name::func_name[::func_type].

src/bin/eolian/eo1_generator.c
src/lib/eolian/Eolian.h
src/lib/eolian/eo_lexer.c
src/lib/eolian/eo_lexer.rl
src/lib/eolian/eolian_database.c
src/lib/eolian/eolian_database.h

index b686fc6..da6c275 100644 (file)
@@ -306,6 +306,7 @@ eo1_bind_func_generate(const char *classname, Eolian_Function funcid, Eolian_Fun
    const char *retname = NULL;
    Eina_Bool ret_const = EINA_FALSE;
 
+   if (eolian_function_is_virtual_pure(funcid)) return EINA_TRUE;
    Eina_Strbuf *fbody = eina_strbuf_new();
    Eina_Strbuf *va_args = eina_strbuf_new();
    Eina_Strbuf *params = eina_strbuf_new(); /* only variables names */
@@ -606,7 +607,10 @@ eo1_source_end_generate(const char *classname, Eina_Strbuf *buf)
              free(desc);
              eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
 
-             eo1_eo_func_desc_generate(classname, tmpstr, tmpbuf);
+             if (!eolian_function_is_virtual_pure(fn))
+                eo1_eo_func_desc_generate(classname, tmpstr, tmpbuf);
+             else
+                eina_strbuf_reset(tmpbuf);
              eina_strbuf_append(str_func, eina_strbuf_string_get(tmpbuf));
           }
         if (prop_write)
@@ -619,7 +623,10 @@ eo1_source_end_generate(const char *classname, Eina_Strbuf *buf)
              eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
              free(desc);
 
-             eo1_eo_func_desc_generate(classname, tmpstr, tmpbuf);
+             if (!eolian_function_is_virtual_pure(fn))
+                eo1_eo_func_desc_generate(classname, tmpstr, tmpbuf);
+             else
+                eina_strbuf_reset(tmpbuf);
              eina_strbuf_append(str_func, eina_strbuf_string_get(tmpbuf));
           }
      }
@@ -635,7 +642,10 @@ eo1_source_end_generate(const char *classname, Eina_Strbuf *buf)
         free(desc);
         eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
 
-        eo1_eo_func_desc_generate(classname, funcname, tmpbuf);
+        if (!eolian_function_is_virtual_pure(fn))
+           eo1_eo_func_desc_generate(classname, funcname, tmpbuf);
+        else
+           eina_strbuf_reset(tmpbuf);
         eina_strbuf_append(str_func, eina_strbuf_string_get(tmpbuf));
      }
 
index ac38c5d..5402b14 100644 (file)
@@ -251,16 +251,16 @@ EAPI Eolian_Function_Type eolian_function_type_get(Eolian_Function function_id);
 EAPI const char *eolian_function_name_get(Eolian_Function function_id);
 
 /*
- * @brief Indicates if a function of a certain type exists in a class.
+ * @brief Find a function in a class by its name and type
  *
  * @param[in] class_name name of the class
  * @param[in] func_name name of the function
  * @param[in] f_type type of the function
- * @return EINA_TRUE if exists, EINA_FALSE otherwise
+ * @return the function id if found, NULL otherwise.
  *
  * @ingroup Eolian
  */
-EAPI Eina_Bool eolian_class_function_exists(const char *classname, const char *func_name, Eolian_Function_Type f_type);
+EAPI Eolian_Function eolian_class_function_find_by_name(const char *classname, const char *func_name, Eolian_Function_Type f_type);
 
 /*
  * @brief Returns a specific data for a function.
@@ -274,6 +274,16 @@ EAPI Eina_Bool eolian_class_function_exists(const char *classname, const char *f
 EAPI const char *eolian_function_data_get(Eolian_Function function_id, const char *key);
 
 /*
+ * @brief Indicates if a function is virtual pure.
+ *
+ * @param[in] function_id Id of the function
+ * @return EINA_TRUE if virtual pure, EINA_FALSE othrewise..
+ *
+ * @ingroup Eolian
+ */
+EAPI Eina_Bool eolian_function_is_virtual_pure(Eolian_Function function_id);
+
+/*
  * @brief Returns a specific description for a function.
  *
  * @param[in] function_id Id of the function
index 65b28eb..206180d 100644 (file)
@@ -2797,6 +2797,7 @@ eo_tokenizer_database_fill(const char *filename)
         EINA_LIST_FOREACH(kls->implements, l, impl)
           {
              const char *class = impl->meth_name;
+             Eina_Bool virtual_pure = EINA_FALSE;
              if (!strcmp(class, "Eo_Base::constructor"))
                {
                   Eolian_Function foo_id = database_function_new("constructor", DFLT_CONSTRUCTOR);
@@ -2819,6 +2820,7 @@ eo_tokenizer_database_fill(const char *filename)
                   database_class_dtor_enable_set(kls->name, EINA_TRUE);
                   continue;
                }
+             if (!strncmp(class, "virtual::", 9)) virtual_pure = EINA_TRUE;
              char *func = strstr(class, "::");
              if (func) *func = '\0';
              func += 2;
@@ -2830,6 +2832,19 @@ eo_tokenizer_database_fill(const char *filename)
                   if (!strcmp(type_as_str+2, "set")) ftype = SET;
                   else if (!strcmp(type_as_str+2, "get")) ftype = GET;
                }
+             if (virtual_pure)
+               {
+                  /* Search the function into the existing functions of the current class */
+                  Eolian_Function foo_id = eolian_class_function_find_by_name(
+                        kls->name, func, ftype);
+                  if (!foo_id)
+                    {
+                       printf("Error - %s not known in class %s\n", class + 9, kls->name);
+                       return EINA_FALSE;
+                    }
+                  database_function_set_as_virtual_pure(foo_id);
+                  continue;
+               }
              Eolian_Implement impl_desc = database_implement_new(class, func, ftype);
              if (impl->legacy)
                {
index ef6237a..3b7adb7 100644 (file)
@@ -1203,6 +1203,7 @@ eo_tokenizer_database_fill(const char *filename)
         EINA_LIST_FOREACH(kls->implements, l, impl)
           {
              const char *class = impl->meth_name;
+             Eina_Bool virtual_pure = EINA_FALSE;
              if (!strcmp(class, "Eo_Base::constructor"))
                {
                   Eolian_Function foo_id = database_function_new("constructor", DFLT_CONSTRUCTOR);
@@ -1225,6 +1226,7 @@ eo_tokenizer_database_fill(const char *filename)
                   database_class_dtor_enable_set(kls->name, EINA_TRUE);
                   continue;
                }
+             if (!strncmp(class, "virtual::", 9)) virtual_pure = EINA_TRUE;
              char *func = strstr(class, "::");
              if (func) *func = '\0';
              func += 2;
@@ -1236,6 +1238,19 @@ eo_tokenizer_database_fill(const char *filename)
                   if (!strcmp(type_as_str+2, "set")) ftype = SET;
                   else if (!strcmp(type_as_str+2, "get")) ftype = GET;
                }
+             if (virtual_pure)
+               {
+                  /* Search the function into the existing functions of the current class */
+                  Eolian_Function foo_id = eolian_class_function_find_by_name(
+                        kls->name, func, ftype);
+                  if (!foo_id)
+                    {
+                       printf("Error - %s not known in class %s\n", class + 9, kls->name);
+                       return EINA_FALSE;
+                    }
+                  database_function_set_as_virtual_pure(foo_id);
+                  continue;
+               }
              Eolian_Implement impl_desc = database_implement_new(class, func, ftype);
              if (impl->legacy)
                {
index 69a4ad4..e599b21 100644 (file)
@@ -32,6 +32,7 @@ typedef struct
    Eolian_Function_Type type;
    Eina_Hash *data;
    Eina_Bool obj_is_const :1; /* True if the object has to be const. Useful for a few methods. */
+   Eina_Bool virtual_pure :1;
 } _Function_Id;
 
 typedef struct
@@ -460,58 +461,52 @@ eolian_implement_legacy_information_get(const Eolian_Implement_Legacy leg_desc,
    return EINA_TRUE;
 }
 
-EAPI Eina_Bool eolian_class_function_exists(const char *class_name, const char *func_name, Eolian_Function_Type f_type)
+EAPI Eolian_Function eolian_class_function_find_by_name(const char *class_name, const char *func_name, Eolian_Function_Type f_type)
 {
-   Eina_Bool ret = EINA_FALSE;
    Eina_List *itr;
    Eolian_Function foo_id;
    Class_desc *desc = _class_get(class_name);
 
-   switch (f_type)
+   if (f_type == UNRESOLVED || f_type == METHOD_FUNC)
+      EINA_LIST_FOREACH(desc->methods, itr, foo_id)
+        {
+           _Function_Id *fid = (_Function_Id *) foo_id;
+           if (!strcmp(fid->name, func_name))
+              return foo_id;
+        }
+
+   if (f_type == UNRESOLVED || f_type == PROPERTY_FUNC ||
+         f_type == SET || f_type == GET)
      {
-      case METHOD_FUNC:
-      case SET:
-      case GET:
-      case PROPERTY_FUNC:
-           {
-              EINA_LIST_FOREACH(desc->methods, itr, foo_id)
-                {
-                   _Function_Id *fid = (_Function_Id *) foo_id;
-                   if (!strcmp(fid->name, func_name))
-                     return EINA_TRUE;
-                }
-              EINA_LIST_FOREACH(desc->properties, itr, foo_id)
-                {
-                   _Function_Id *fid = (_Function_Id *) foo_id;
-                   if (!strcmp(fid->name, func_name))
-                     return EINA_TRUE;
-                }
-              break;
-           }
-      case CONSTRUCTOR:
-           {
-              EINA_LIST_FOREACH(desc->constructors, itr, foo_id)
-                {
-                   _Function_Id *fid = (_Function_Id *) foo_id;
-                   if (!strcmp(fid->name, func_name))
-                     return EINA_TRUE;
-                }
-              break;
-           }
-      case DESTRUCTOR:
-           {
-              EINA_LIST_FOREACH(desc->destructors, itr, foo_id)
-                {
-                   _Function_Id *fid = (_Function_Id *) foo_id;
-                   if (!strcmp(fid->name, func_name))
-                     return EINA_TRUE;
-                }
-              break;
-           }
-      default:
-         return EINA_FALSE;
+        EINA_LIST_FOREACH(desc->properties, itr, foo_id)
+          {
+             _Function_Id *fid = (_Function_Id *) foo_id;
+             if (!strcmp(fid->name, func_name) && (f_type == UNRESOLVED || f_type == PROPERTY_FUNC || f_type == fid->type))
+                return foo_id;
+          }
      }
-   return ret;
+
+   if (f_type == CONSTRUCTOR)
+     {
+        EINA_LIST_FOREACH(desc->constructors, itr, foo_id)
+          {
+             _Function_Id *fid = (_Function_Id *) foo_id;
+             if (!strcmp(fid->name, func_name))
+                return foo_id;
+          }
+     }
+
+   if (f_type == DESTRUCTOR)
+     {
+        EINA_LIST_FOREACH(desc->destructors, itr, foo_id)
+          {
+             _Function_Id *fid = (_Function_Id *) foo_id;
+             if (!strcmp(fid->name, func_name))
+                return foo_id;
+          }
+     }
+
+   return NULL;
 }
 
 EAPI const Eina_List *
@@ -561,6 +556,23 @@ eolian_function_name_get(Eolian_Function function_id)
    return fid->name;
 }
 
+Eina_Bool
+database_function_set_as_virtual_pure(Eolian_Function function_id)
+{
+   _Function_Id *fid = (_Function_Id *)function_id;
+   if (!fid) return EINA_FALSE;
+   fid->virtual_pure = EINA_TRUE;
+   return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+eolian_function_is_virtual_pure(Eolian_Function function_id)
+{
+   _Function_Id *fid = (_Function_Id *)function_id;
+   if (!fid) return EINA_FALSE;
+   return fid->virtual_pure;
+}
+
 void
 database_function_data_set(Eolian_Function function_id, const char *key, const char *data)
 {
index 79a3412..a307727 100644 (file)
@@ -57,6 +57,9 @@ void database_function_return_type_set(Eolian_Function foo_id, Eolian_Function_T
 
 void database_function_object_set_as_const(Eolian_Function foo_id, Eina_Bool is_const);
 
+Eina_Bool
+database_function_set_as_virtual_pure(Eolian_Function function_id);
+
 /* Need to add API for callbacks and implements */
 
 Eolian_Implement