Eolian: add support for typedefs.

It includes parser updates, database fill and tests on basic and complex
types.

One can define types in this way:
type Evas_Coord: int; /* Simple type definition */
type List_Objects: Eina_List * <Eo *>;

@feature
This commit is contained in:
Daniel Zaoui 2014-04-30 12:03:09 +03:00
parent 0f8d20bd31
commit e4444d2518
11 changed files with 2030 additions and 1777 deletions

View File

@ -83,5 +83,6 @@ tests/eolian/data/base.eo \
tests/eolian/data/class_simple.eo \
tests/eolian/data/scope.eo \
tests/eolian/data/ctor_dtor.eo \
tests/eolian/data/complex_type.eo
tests/eolian/data/complex_type.eo \
tests/eolian/data/typedef.eo

View File

@ -638,6 +638,17 @@ EAPI Eina_Bool eolian_class_ctor_enable_get(const char *class_name);
*/
EAPI Eina_Bool eolian_class_dtor_enable_get(const char *class_name);
/*
* @brief Find the type for a certain alias
*
* @param[in] alias alias of the type definition
* @return real type of the type definition
*
* @ingroup Eolian
*/
EAPI Eolian_Type
eolian_type_find_by_alias(const char *alias);
#endif
#ifdef __cplusplus

View File

@ -112,6 +112,17 @@ eo_definitions_impl_def_free(Eo_Implement_Def *impl)
free(impl);
}
void
eo_definitions_type_def_free(Eo_Type_Def *type)
{
if (type->alias)
eina_stringshare_del(type->alias);
if (type->type)
eina_stringshare_del(type->type);
free(type);
}
void
eo_definitions_class_def_free(Eo_Class_Def *kls)
{

View File

@ -130,6 +130,15 @@ typedef struct _eo_class_def
Eina_List *methods;
} Eo_Class_Def;
/* TYPE */
typedef struct _eo_type_def
{
const char *alias;
const char *type;
} Eo_Type_Def;
void eo_definitions_class_def_free(Eo_Class_Def *kls);
void eo_definitions_type_def_free(Eo_Type_Def *type);
#endif /* __EO_DEFINITIONS_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -34,10 +34,13 @@ typedef struct _eo_tokenizer
} saved;
Eina_List *classes;
Eina_List *typedefs;
struct {
Eina_List **params;
Eolian_Class_Type kls_type;
const char *typedef_alias;
Eo_Class_Def *kls;
Eo_Type_Def *type_def;
Eo_Property_Def *prop;
Eo_Method_Def *meth;
Eo_Param_Def *param;

View File

@ -154,6 +154,17 @@ _eo_tokenizer_class_get(Eo_Tokenizer *toknz, char *p)
return kls;
}
static Eo_Type_Def*
_eo_tokenizer_type_get(Eo_Tokenizer *toknz, char *p)
{
Eo_Type_Def *def = calloc(1, sizeof(Eo_Type_Def));
if (def == NULL) ABORT(toknz, "calloc Eo_Type_Def failure");
def->type = _eo_tokenizer_token_get(toknz, p);
return def;
}
static Eo_Property_Def*
_eo_tokenizer_property_get(Eo_Tokenizer *toknz, char *p)
{
@ -958,10 +969,27 @@ _eo_tokenizer_implement_get(Eo_Tokenizer *toknz, char *p)
"abstract" %class_type_set_to_abstract |
"interface" %class_type_set_to_interface) ws+ class_name ws* inherits? ignore* begin_def;
action end_typedef_alias {
toknz->tmp.typedef_alias = _eo_tokenizer_token_get(toknz, fpc);
}
action end_typedef_type{
if (toknz->tmp.typedef_alias == NULL)
ABORT(toknz, "No typedef");
toknz->tmp.type_def = _eo_tokenizer_type_get(toknz, fpc);
toknz->tmp.type_def->alias = toknz->tmp.typedef_alias;
toknz->typedefs = eina_list_append(toknz->typedefs, toknz->tmp.type_def);
}
typedef_type = ('@'|alpha+) >save_fpc (alnum_u | '*' | '@' | '<' | '>' | ws )+;
typedef_alias = ident %end_typedef_alias;
begin_typedef = "type" ws+ typedef_alias ws* colon ws* typedef_type %end_typedef_type end_statement;
main := |*
ignore+; #=> show_ignore;
comment => show_comment;
begin_class => begin_class;
begin_typedef;
any => show_error;
*|;
@ -1095,6 +1123,7 @@ eo_tokenizer_get(void)
toknz->saved.tok = NULL;
toknz->saved.line = 0;
toknz->classes = NULL;
toknz->typedefs = NULL;
return toknz;
}
@ -1303,6 +1332,7 @@ eo_tokenizer_database_fill(const char *filename)
Eina_List *k, *l, *m;
Eo_Class_Def *kls;
Eo_Type_Def *type_def;
Eo_Property_Def *prop;
Eo_Method_Def *meth;
Eo_Param_Def *param;
@ -1531,6 +1561,11 @@ eo_tokenizer_database_fill(const char *filename)
}
EINA_LIST_FOREACH(toknz->typedefs, k, type_def)
{
database_type_add(type_def->alias, _types_extract(type_def->type, strlen(type_def->type)));
}
ret = EINA_TRUE;
end:
if (buffer) free(buffer);
@ -1543,6 +1578,7 @@ void
eo_tokenizer_free(Eo_Tokenizer *toknz)
{
Eo_Class_Def *kls;
Eo_Type_Def *type;
if (toknz->source)
eina_stringshare_del(toknz->source);
@ -1550,6 +1586,9 @@ eo_tokenizer_free(Eo_Tokenizer *toknz)
EINA_LIST_FREE(toknz->classes, kls)
eo_definitions_class_def_free(kls);
EINA_LIST_FREE(toknz->typedefs, type)
eo_definitions_type_def_free(type);
free(toknz);
}

View File

@ -15,6 +15,7 @@
#define EOLIAN_PROP_SET_RETURN_COMMENT "property_set_return_comment"
static Eina_Hash *_classes = NULL;
static Eina_Hash *_types = NULL;
static Eina_Hash *_filenames = NULL; /* Hash: filename without extension -> full path */
static int _database_init_count = 0;
@ -37,6 +38,12 @@ typedef struct
Eina_Bool class_dtor_enable:1;
} Class_desc;
typedef struct
{
Eina_Stringshare *alias;
Eolian_Type type;
} Type_Desc;
typedef struct
{
Eina_Stringshare *name;
@ -171,12 +178,20 @@ _class_del(Class_desc *class)
free(class);
}
void _hash_free_cb(void *data)
static void _class_hash_free_cb(void *data)
{
Class_desc *cl = data;
_class_del(cl);
}
static void _type_hash_free_cb(void *data)
{
Type_Desc *type = data;
eina_stringshare_del(type->alias);
database_type_del(type->type);
free(type);
}
static Class_desc *
_class_get(const char *class_name)
{
@ -192,7 +207,8 @@ database_init()
{
if (_database_init_count > 0) return ++_database_init_count;
eina_init();
_classes = eina_hash_stringshared_new(_hash_free_cb);
_classes = eina_hash_stringshared_new(_class_hash_free_cb);
_types = eina_hash_stringshared_new(_type_hash_free_cb);
_filenames = eina_hash_string_small_new(free);
return ++_database_init_count;
}
@ -210,12 +226,37 @@ database_shutdown()
if (_database_init_count == 0)
{
eina_hash_free(_classes);
eina_hash_free(_types);
eina_hash_free(_filenames);
eina_shutdown();
}
return _database_init_count;
}
Eina_Bool
database_type_add(const char *alias, Eolian_Type type)
{
if (_types)
{
Type_Desc *desc = calloc(1, sizeof(*desc));
desc->alias = eina_stringshare_add(alias);
desc->type = type;
eina_hash_set(_types, desc->alias, desc);
return EINA_TRUE;
}
return EINA_FALSE;
}
EAPI Eolian_Type
eolian_type_find_by_alias(const char *alias)
{
if (!_types) return NULL;
Eina_Stringshare *shr = eina_stringshare_add(alias);
Type_Desc *cl = eina_hash_find(_types, shr);
eina_stringshare_del(shr);
return cl->type;
}
Eina_Bool
database_class_add(const char *class_name, Eolian_Class_Type type)
{

View File

@ -33,6 +33,9 @@ extern int _eolian_log_dom;
int database_init();
int database_shutdown();
/* Add a type in the database */
Eina_Bool database_type_add(const char *alias, Eolian_Type type);
/* Add a class in the database */
Eina_Bool database_class_add(const char *class_name, Eolian_Class_Type type);

View File

@ -0,0 +1,13 @@
type Evas_Coord: int; /* Simple type definition */
type List_Objects: @own Eina_List * < Eo *>; /* A little more complex */
class Dummy {
methods {
foo {
params {
int idx;
}
return @own char *; /*@ comment for method return */
}
}
}

View File

@ -52,6 +52,38 @@ START_TEST(eolian_ctor_dtor)
}
END_TEST
START_TEST(eolian_typedef)
{
Eolian_Type types_list = NULL;
const char *type_name = NULL;
Eina_Bool own = EINA_FALSE;
eolian_init();
/* Parsing */
fail_if(!eolian_eo_file_parse(PACKAGE_DATA_DIR"/data/typedef.eo"));
/* Check that the class Dummy is still readable */
fail_if(!eolian_class_function_find_by_name("Dummy", "foo", EOLIAN_METHOD));
/* Basic type */
fail_if(!(types_list = eolian_type_find_by_alias("Evas_Coord")));
fail_if(eolian_type_information_get(types_list, &type_name, &own));
fail_if(strcmp(type_name, "int"));
fail_if(own != EINA_FALSE);
/* Complex type */
fail_if(!(types_list = eolian_type_find_by_alias("List_Objects")));
fail_if(!(types_list = eolian_type_information_get(types_list, &type_name, &own)));
fail_if(strcmp(type_name, "Eina_List *"));
fail_if(own != EINA_TRUE);
fail_if(eolian_type_information_get(types_list, &type_name, &own));
fail_if(strcmp(type_name, "Eo *"));
fail_if(own != EINA_FALSE);
eolian_shutdown();
}
END_TEST
START_TEST(eolian_complex_type)
{
Eolian_Function fid = NULL;
@ -251,6 +283,7 @@ static void eolian_parsing_test(TCase *tc)
tcase_add_test(tc, eolian_ctor_dtor);
tcase_add_test(tc, eolian_scope);
tcase_add_test(tc, eolian_complex_type);
tcase_add_test(tc, eolian_typedef);
}
static const Eolian_Test_Case etc[] = {