eolian: completely clean up the type system

This commit is contained in:
Daniel Kolesa 2016-03-01 15:37:57 +00:00
parent 1f58ccb49f
commit e061d49aac
9 changed files with 77 additions and 130 deletions

View File

@ -219,10 +219,6 @@ typedef enum
EOLIAN_TYPE_REGULAR,
EOLIAN_TYPE_COMPLEX,
EOLIAN_TYPE_POINTER,
EOLIAN_TYPE_STRUCT,
EOLIAN_TYPE_STRUCT_OPAQUE,
EOLIAN_TYPE_ENUM,
EOLIAN_TYPE_ALIAS,
EOLIAN_TYPE_CLASS,
EOLIAN_TYPE_UNDEFINED
} Eolian_Type_Type;

View File

@ -17,6 +17,21 @@ database_type_del(Eolian_Type *tp)
database_type_del(tp->base_type);
if (tp->name) eina_stringshare_del(tp->name);
if (tp->full_name) eina_stringshare_del(tp->full_name);
if (tp->namespaces) EINA_LIST_FREE(tp->namespaces, sp)
eina_stringshare_del(sp);
if (tp->freefunc) eina_stringshare_del(tp->freefunc);
free(tp);
}
void
database_typedecl_del(Eolian_Typedecl *tp)
{
if (!tp) return;
const char *sp;
if (tp->base.file) eina_stringshare_del(tp->base.file);
database_type_del(tp->base_type);
if (tp->name) eina_stringshare_del(tp->name);
if (tp->full_name) eina_stringshare_del(tp->full_name);
if (tp->fields) eina_hash_free(tp->fields);
if (tp->field_list) eina_list_free(tp->field_list);
if (tp->namespaces) EINA_LIST_FREE(tp->namespaces, sp)
@ -24,105 +39,34 @@ database_type_del(Eolian_Type *tp)
if (tp->legacy) eina_stringshare_del(tp->legacy);
if (tp->freefunc) eina_stringshare_del(tp->freefunc);
database_doc_del(tp->doc);
database_typedecl_del(tp->decl);
free(tp);
}
void
database_typedecl_del(Eolian_Typedecl *tp)
database_type_add(Eolian_Typedecl *def)
{
/* TODO: own storage for typedecls for several fields */
if (!tp) return;
const char *sp;
if (tp->base.file) eina_stringshare_del(tp->base.file);
/*database_type_del(tp->base_type);*/
if (tp->name) eina_stringshare_del(tp->name);
if (tp->full_name) eina_stringshare_del(tp->full_name);
/*if (tp->fields) eina_hash_free(tp->fields);
if (tp->field_list) eina_list_free(tp->field_list);*/
if (tp->namespaces) EINA_LIST_FREE(tp->namespaces, sp)
eina_stringshare_del(sp);
if (tp->legacy) eina_stringshare_del(tp->legacy);
if (tp->freefunc) eina_stringshare_del(tp->freefunc);
/*database_doc_del(tp->doc);*/
free(tp);
}
void
database_typedef_del(Eolian_Type *tp)
{
if (!tp) return;
Eolian_Type *btp = tp->base_type;
/* prevent deletion of named structs/enums as they're deleted later on */
if (btp)
{
if (btp->type == EOLIAN_TYPE_ENUM)
tp->base_type = NULL;
else if ((btp->type == EOLIAN_TYPE_STRUCT
|| btp->type == EOLIAN_TYPE_STRUCT_OPAQUE) && btp->name)
tp->base_type = NULL;
}
database_type_del(tp);
}
static Eolian_Typedecl *
_typedecl_add(Eolian_Type *type)
{
const char *nm;
Eina_List *l;
Eolian_Typedecl *ret = calloc(1, sizeof(Eolian_Typedecl));
ret->base.file = eina_stringshare_ref(type->base.file);
ret->base.line = type->base.line;
ret->base.column = type->base.column;
ret->base_type = type->base_type;
ret->name = eina_stringshare_ref(type->name);
ret->full_name = eina_stringshare_ref(type->full_name);
if (type->namespaces) EINA_LIST_FOREACH(type->namespaces, l, nm)
ret->namespaces = eina_list_append(ret->namespaces, eina_stringshare_ref(nm));
ret->fields = type->fields;
ret->field_list = type->field_list;
ret->doc = type->doc;
ret->legacy = eina_stringshare_ref(type->legacy);
ret->freefunc = eina_stringshare_ref(type->freefunc);
ret->is_extern = type->is_extern;
ret->parent = type;
return ret;
}
void
database_type_add(Eolian_Type *def)
{
def->decl = _typedecl_add(def);
def->decl->type = EOLIAN_TYPEDECL_ALIAS;
eina_hash_set(_aliases, def->full_name, def);
eina_hash_set(_aliasesf, def->base.file, eina_list_append
((Eina_List*)eina_hash_find(_aliasesf, def->base.file), def->decl));
database_decl_add(def->full_name, EOLIAN_DECL_ALIAS, def->base.file, def->decl);
((Eina_List*)eina_hash_find(_aliasesf, def->base.file), def));
database_decl_add(def->full_name, EOLIAN_DECL_ALIAS, def->base.file, def);
}
void
database_struct_add(Eolian_Type *tp)
database_struct_add(Eolian_Typedecl *tp)
{
tp->decl = _typedecl_add(tp);
tp->decl->type = (tp->type == EOLIAN_TYPE_STRUCT_OPAQUE) ? EOLIAN_TYPEDECL_STRUCT_OPAQUE
: EOLIAN_TYPEDECL_STRUCT;
eina_hash_set(_structs, tp->full_name, tp);
eina_hash_set(_structsf, tp->base.file, eina_list_append
((Eina_List*)eina_hash_find(_structsf, tp->base.file), tp->decl));
database_decl_add(tp->full_name, EOLIAN_DECL_STRUCT, tp->base.file, tp->decl);
((Eina_List*)eina_hash_find(_structsf, tp->base.file), tp));
database_decl_add(tp->full_name, EOLIAN_DECL_STRUCT, tp->base.file, tp);
}
void
database_enum_add(Eolian_Type *tp)
database_enum_add(Eolian_Typedecl *tp)
{
tp->decl = _typedecl_add(tp);
tp->decl->type = EOLIAN_TYPEDECL_ENUM;
eina_hash_set(_enums, tp->full_name, tp);
eina_hash_set(_enumsf, tp->base.file, eina_list_append
((Eina_List*)eina_hash_find(_enumsf, tp->base.file), tp->decl));
database_decl_add(tp->full_name, EOLIAN_DECL_ENUM, tp->base.file, tp->decl);
((Eina_List*)eina_hash_find(_enumsf, tp->base.file), tp));
database_decl_add(tp->full_name, EOLIAN_DECL_ENUM, tp->base.file, tp);
}
void

View File

@ -11,10 +11,10 @@ eolian_typedecl_alias_get_by_name(const char *name)
{
if (!_aliases) return NULL;
Eina_Stringshare *shr = eina_stringshare_add(name);
Eolian_Type *tp = eina_hash_find(_aliases, shr);
Eolian_Typedecl *tp = eina_hash_find(_aliases, shr);
eina_stringshare_del(shr);
if (!tp) return NULL;
return tp->decl;
return tp;
}
EAPI const Eolian_Typedecl *
@ -22,10 +22,10 @@ eolian_typedecl_struct_get_by_name(const char *name)
{
if (!_structs) return NULL;
Eina_Stringshare *shr = eina_stringshare_add(name);
Eolian_Type *tp = eina_hash_find(_structs, shr);
Eolian_Typedecl *tp = eina_hash_find(_structs, shr);
eina_stringshare_del(shr);
if (!tp) return NULL;
return tp->decl;
return tp;
}
EAPI const Eolian_Typedecl *
@ -33,10 +33,10 @@ eolian_typedecl_enum_get_by_name(const char *name)
{
if (!_enums) return NULL;
Eina_Stringshare *shr = eina_stringshare_add(name);
Eolian_Type *tp = eina_hash_find(_enums, shr);
Eolian_Typedecl *tp = eina_hash_find(_enums, shr);
eina_stringshare_del(shr);
if (!tp) return NULL;
return tp->decl;
return tp;
}
EAPI Eina_Iterator *

View File

@ -400,10 +400,10 @@ _validate_variable(const Validator *vs, const Eolian_Variable *var)
}
static Eina_Bool
_type_map_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED,
const Eolian_Type *tp, Val_Success *sc)
_typedecl_map_cb(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED,
const Eolian_Typedecl *tp, Val_Success *sc)
{
sc->success = _validate_typedecl(sc->vs, tp->decl);
sc->success = _validate_typedecl(sc->vs, tp);
return sc->success;
}
@ -436,15 +436,15 @@ database_validate(Eina_Bool silent_types)
succ.vs = &vs;
succ.success = EINA_TRUE;
eina_hash_foreach(_aliases, (Eina_Hash_Foreach)_type_map_cb, &succ);
eina_hash_foreach(_aliases, (Eina_Hash_Foreach)_typedecl_map_cb, &succ);
if (!succ.success)
return EINA_FALSE;
eina_hash_foreach(_structs, (Eina_Hash_Foreach)_type_map_cb, &succ);
eina_hash_foreach(_structs, (Eina_Hash_Foreach)_typedecl_map_cb, &succ);
if (!succ.success)
return EINA_FALSE;
eina_hash_foreach(_enums, (Eina_Hash_Foreach)_type_map_cb, &succ);
eina_hash_foreach(_enums, (Eina_Hash_Foreach)_typedecl_map_cb, &succ);
if (!succ.success)
return EINA_FALSE;

View File

@ -1015,6 +1015,7 @@ _temps_free(Eo_Lexer_Temps *tmp)
{
Eina_Strbuf *buf;
Eolian_Type *tp;
Eolian_Typedecl *tpd;
const char *s;
if (tmp->kls)
@ -1027,10 +1028,10 @@ _temps_free(Eo_Lexer_Temps *tmp)
eina_strbuf_free(buf);
EINA_LIST_FREE(tmp->type_defs, tp)
if (tp->type == EOLIAN_TYPE_ALIAS)
database_typedef_del(tp);
else
database_type_del(tp);
database_type_del(tp);
EINA_LIST_FREE(tmp->type_decls, tpd)
database_typedecl_del(tpd);
EINA_LIST_FREE(tmp->strs, s)
if (s) eina_stringshare_del(s);

View File

@ -118,6 +118,7 @@ typedef struct _Eo_Lexer_Temps
Eolian_Variable *var;
Eina_List *str_bufs;
Eina_List *type_defs;
Eina_List *type_decls;
Eina_List *expr_defs;
Eina_List *strs;
} Eo_Lexer_Temps;

View File

@ -117,12 +117,26 @@ push_type(Eo_Lexer *ls)
return def;
}
static Eolian_Typedecl *
push_typedecl(Eo_Lexer *ls)
{
Eolian_Typedecl *def = calloc(1, sizeof(Eolian_Typedecl));
ls->tmp.type_decls = eina_list_prepend(ls->tmp.type_decls, def);
return def;
}
static void
pop_type(Eo_Lexer *ls)
{
ls->tmp.type_defs = eina_list_remove_list(ls->tmp.type_defs, ls->tmp.type_defs);
}
static void
pop_typedecl(Eo_Lexer *ls)
{
ls->tmp.type_decls = eina_list_remove_list(ls->tmp.type_decls, ls->tmp.type_decls);
}
static Eina_Stringshare *
push_str(Eo_Lexer *ls, const char *val)
{
@ -471,15 +485,15 @@ _struct_field_free(Eolian_Struct_Type_Field *def)
free(def);
}
static Eolian_Type *
static Eolian_Typedecl *
parse_struct(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
int line, int column, const char *freefunc)
{
int bline = ls->line_number, bcolumn = ls->column;
Eolian_Type *def = push_type(ls);
Eolian_Typedecl *def = push_typedecl(ls);
def->is_extern = is_extern;
if (name) _fill_name(name, &def->full_name, &def->name, &def->namespaces);
def->type = EOLIAN_TYPE_STRUCT;
def->type = EOLIAN_TYPEDECL_STRUCT;
def->fields = eina_hash_string_small_new(EINA_FREE_CB(_struct_field_free));
def->freefunc = freefunc;
pop_str(ls);
@ -524,15 +538,15 @@ _enum_field_free(Eolian_Enum_Type_Field *def)
free(def);
}
static Eolian_Type *
static Eolian_Typedecl *
parse_enum(Eo_Lexer *ls, const char *name, Eina_Bool is_extern,
int line, int column)
{
int bline = ls->line_number, bcolumn = ls->column;
Eolian_Type *def = push_type(ls);
Eolian_Typedecl *def = push_typedecl(ls);
def->is_extern = is_extern;
_fill_name(name, &def->full_name, &def->name, &def->namespaces);
def->type = EOLIAN_TYPE_ENUM;
def->type = EOLIAN_TYPEDECL_ENUM;
def->fields = eina_hash_string_small_new(EINA_FREE_CB(_enum_field_free));
check_next(ls, '{');
FILL_DOC(ls, def, doc);
@ -843,11 +857,11 @@ parse_type_void(Eo_Lexer *ls)
return parse_type_void_base(ls, EINA_FALSE);
}
static Eolian_Type *
static Eolian_Typedecl *
parse_typedef(Eo_Lexer *ls)
{
Eolian_Declaration *decl;
Eolian_Type *def = push_type(ls);
Eolian_Typedecl *def = push_typedecl(ls);
Eina_Bool has_extern;
const char *freefunc;
Eina_Strbuf *buf;
@ -855,7 +869,7 @@ parse_typedef(Eo_Lexer *ls)
parse_struct_attrs(ls, EINA_FALSE, &has_extern, &freefunc);
def->freefunc = freefunc;
pop_str(ls);
def->type = EOLIAN_TYPE_ALIAS;
def->type = EOLIAN_TYPEDECL_ALIAS;
def->is_extern = has_extern;
buf = push_strbuf(ls);
eo_lexer_context_push(ls);
@ -1856,7 +1870,7 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot)
case KW_type:
{
database_type_add(parse_typedef(ls));
pop_type(ls);
pop_typedecl(ls);
break;
}
case KW_const:
@ -1895,9 +1909,9 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot)
pop_strbuf(ls);
if (!is_enum && ls->t.token == ';')
{
Eolian_Type *def = push_type(ls);
Eolian_Typedecl *def = push_typedecl(ls);
def->is_extern = has_extern;
def->type = EOLIAN_TYPE_STRUCT_OPAQUE;
def->type = EOLIAN_TYPEDECL_STRUCT_OPAQUE;
def->freefunc = freefunc;
pop_str(ls);
_fill_name(name, &def->full_name, &def->name, &def->namespaces);
@ -1905,14 +1919,14 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot)
FILL_DOC(ls, def, doc);
FILL_BASE(def->base, ls, line, col);
database_struct_add(def);
pop_type(ls);
pop_typedecl(ls);
break;
}
if (is_enum)
parse_enum(ls, name, has_extern, line, col);
else
parse_struct(ls, name, has_extern, line, col, freefunc);
pop_type(ls);
pop_typedecl(ls);
break;
}
def:

View File

@ -43,9 +43,9 @@ database_init()
if (_database_init_count > 0) return ++_database_init_count;
eina_init();
_classes = eina_hash_stringshared_new(EINA_FREE_CB(database_class_del));
_aliases = eina_hash_stringshared_new(EINA_FREE_CB(database_typedef_del));
_structs = eina_hash_stringshared_new(EINA_FREE_CB(database_type_del));
_enums = eina_hash_stringshared_new(EINA_FREE_CB(database_type_del));
_aliases = eina_hash_stringshared_new(EINA_FREE_CB(database_typedecl_del));
_structs = eina_hash_stringshared_new(EINA_FREE_CB(database_typedecl_del));
_enums = eina_hash_stringshared_new(EINA_FREE_CB(database_typedecl_del));
_globals = eina_hash_stringshared_new(EINA_FREE_CB(database_var_del));
_constants = eina_hash_stringshared_new(EINA_FREE_CB(database_var_del));
_classesf = eina_hash_stringshared_new(NULL);

View File

@ -170,22 +170,15 @@ struct _Eolian_Type
Eina_Stringshare *name;
Eina_Stringshare *full_name;
Eina_List *namespaces;
Eina_Hash *fields;
Eina_List *field_list;
Eolian_Documentation *doc;
Eina_Stringshare *legacy;
Eina_Stringshare *freefunc;
Eolian_Typedecl *decl;
Eina_Bool is_const :1;
Eina_Bool is_own :1;
Eina_Bool is_extern :1;
};
struct _Eolian_Typedecl
{
Eolian_Object base;
Eolian_Typedecl_Type type;
Eolian_Type *parent;
Eolian_Type *base_type;
Eina_Stringshare *name;
Eina_Stringshare *full_name;
@ -241,7 +234,7 @@ struct _Eolian_Struct_Type_Field
struct _Eolian_Enum_Type_Field
{
Eolian_Type *base_enum;
Eolian_Typedecl *base_enum;
Eina_Stringshare *name;
Eolian_Object base;
Eolian_Expression *value;
@ -299,12 +292,10 @@ void database_doc_del(Eolian_Documentation *doc);
/* types */
void database_type_add(Eolian_Type *def);
void database_struct_add(Eolian_Type *tp);
void database_enum_add(Eolian_Type *tp);
void database_type_add(Eolian_Typedecl *def);
void database_struct_add(Eolian_Typedecl *tp);
void database_enum_add(Eolian_Typedecl *tp);
void database_type_del(Eolian_Type *tp);
void database_typedef_del(Eolian_Type *tp);
void database_typedecl_del(Eolian_Typedecl *tp);
void database_type_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name);