forked from enlightenment/efl
eolian: disallow cyclic dependencies between .eo files
Eo files will now fail to compile if a cycle is detected. This required some temporary changes in existing eo files (we had 2 cycles) for which I added a FIXME (they do not affect C generation). @feature
This commit is contained in:
parent
adf445e3bd
commit
9214fa3db9
|
@ -51,7 +51,8 @@ class Ecore.Con.Server (Ecore.Con.Base) {
|
|||
get {
|
||||
}
|
||||
values {
|
||||
clients: const(list<const(Ecore.Con.Client) *>) *; /*@ The list of clients on this server. */
|
||||
// FIXME: Ecore.Con.Client is needed, but that introduces a cycle
|
||||
clients: const(list<const(Ecore.Con.Base) *>) *; /*@ The list of clients on this server. */
|
||||
}
|
||||
}
|
||||
@property connection_type {
|
||||
|
|
|
@ -667,30 +667,22 @@ parse_struct_attrs(Eo_Lexer *ls, Eina_Bool is_enum, Eina_Bool *is_extern,
|
|||
}
|
||||
|
||||
static void
|
||||
_append_dep(Eo_Lexer *ls, const char *fname, const char *name, int line, int col)
|
||||
_parse_dep(Eo_Lexer *ls, const char *fname, const char *name)
|
||||
{
|
||||
Eina_Stringshare *cname = eina_stringshare_add(name);
|
||||
Eolian_Dependency *dep;
|
||||
|
||||
Eina_List *deps = eina_hash_find(_depclasses, ls->filename);
|
||||
Eina_List *l;
|
||||
void *data;
|
||||
|
||||
/* check for possible duplicates while building the deplist */
|
||||
EINA_LIST_FOREACH(deps, l, data)
|
||||
if (data == cname)
|
||||
{
|
||||
eina_stringshare_del(cname);
|
||||
return;
|
||||
}
|
||||
|
||||
dep = calloc(1, sizeof(Eolian_Dependency));
|
||||
FILL_BASE(dep->base, ls, line, col);
|
||||
dep->filename = eina_stringshare_add(fname);
|
||||
dep->name = cname;
|
||||
|
||||
deps = eina_list_append(deps, dep);
|
||||
eina_hash_set(_depclasses, ls->filename, deps);
|
||||
if (eina_hash_find(_parsingeos, fname))
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
eo_lexer_context_restore(ls);
|
||||
snprintf(buf, sizeof(buf), "cyclic dependency '%s'", name);
|
||||
eo_lexer_syntax_error(ls, buf);
|
||||
}
|
||||
if (!eolian_eo_file_parse(fname))
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
eo_lexer_context_restore(ls);
|
||||
snprintf(buf, sizeof(buf), "error parsing dependency '%s'", name);
|
||||
eo_lexer_syntax_error(ls, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static Eolian_Type *
|
||||
|
@ -799,10 +791,10 @@ parse_type_void(Eo_Lexer *ls)
|
|||
}
|
||||
else
|
||||
{
|
||||
int dline = ls->line_number, dcol = ls->column;
|
||||
const char *bnm, *nm;
|
||||
char *fnm;
|
||||
buf = push_strbuf(ls);
|
||||
eo_lexer_context_push(ls);
|
||||
parse_name(ls, buf);
|
||||
nm = eina_strbuf_string_get(buf);
|
||||
bnm = eina_stringshare_ref(ls->filename);
|
||||
|
@ -814,7 +806,7 @@ parse_type_void(Eo_Lexer *ls)
|
|||
free(fnm);
|
||||
if (fname)
|
||||
{
|
||||
_append_dep(ls, fname, nm, dline, dcol);
|
||||
_parse_dep(ls, fname, nm);
|
||||
def->type = EOLIAN_TYPE_CLASS;
|
||||
}
|
||||
}
|
||||
|
@ -826,6 +818,7 @@ parse_type_void(Eo_Lexer *ls)
|
|||
}
|
||||
_fill_name(eina_stringshare_add(nm), &def->full_name, &def->name,
|
||||
&def->namespaces);
|
||||
eo_lexer_context_pop(ls);
|
||||
pop_strbuf(ls);
|
||||
}
|
||||
}
|
||||
|
@ -1721,7 +1714,6 @@ parse_class_body(Eo_Lexer *ls, Eolian_Class_Type type)
|
|||
static void
|
||||
_inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf)
|
||||
{
|
||||
int dline = ls->line_number, dcol = ls->column;
|
||||
const char *fname, *iname;
|
||||
char *fnm;
|
||||
eina_strbuf_reset(buf);
|
||||
|
@ -1748,7 +1740,7 @@ _inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf)
|
|||
snprintf(ebuf, sizeof(ebuf), "unknown inherit '%s'", iname);
|
||||
eo_lexer_syntax_error(ls, ebuf);
|
||||
}
|
||||
_append_dep(ls, fname, iname, dline, dcol);
|
||||
_parse_dep(ls, fname, iname);
|
||||
ls->tmp.kls->inherits = eina_list_append(ls->tmp.kls->inherits,
|
||||
eina_stringshare_add(iname));
|
||||
eo_lexer_context_pop(ls);
|
||||
|
|
|
@ -21,7 +21,6 @@ Eina_Hash *_globalsf = NULL;
|
|||
Eina_Hash *_constantsf = NULL;
|
||||
Eina_Hash *_filenames = NULL;
|
||||
Eina_Hash *_tfilenames = NULL;
|
||||
Eina_Hash *_depclasses = NULL;
|
||||
Eina_Hash *_decls = NULL;
|
||||
|
||||
Eina_Hash *_parsedeots = NULL;
|
||||
|
@ -35,19 +34,6 @@ _hashlist_free(void *data)
|
|||
eina_list_free((Eina_List*)data);
|
||||
}
|
||||
|
||||
static void
|
||||
_deplist_free(Eina_List *data)
|
||||
{
|
||||
Eolian_Dependency *dep;
|
||||
EINA_LIST_FREE(data, dep)
|
||||
{
|
||||
eina_stringshare_del(dep->base.file);
|
||||
eina_stringshare_del(dep->filename);
|
||||
eina_stringshare_del(dep->name);
|
||||
free(dep);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
database_init()
|
||||
{
|
||||
|
@ -67,7 +53,6 @@ database_init()
|
|||
_constantsf = eina_hash_stringshared_new(_hashlist_free);
|
||||
_filenames = eina_hash_string_small_new(free);
|
||||
_tfilenames = eina_hash_string_small_new(free);
|
||||
_depclasses = eina_hash_stringshared_new(EINA_FREE_CB(_deplist_free));
|
||||
_decls = eina_hash_stringshared_new(free);
|
||||
_parsedeots = eina_hash_string_small_new(NULL);
|
||||
_parsingeos = eina_hash_string_small_new(NULL);
|
||||
|
@ -100,7 +85,6 @@ database_shutdown()
|
|||
eina_hash_free(_constantsf); _constantsf = NULL;
|
||||
eina_hash_free(_filenames ); _filenames = NULL;
|
||||
eina_hash_free(_tfilenames); _tfilenames = NULL;
|
||||
eina_hash_free(_depclasses); _depclasses = NULL;
|
||||
eina_hash_free(_decls ); _decls = NULL;
|
||||
eina_hash_free(_parsedeots); _parsedeots = NULL;
|
||||
eina_hash_free(_parsingeos); _parsingeos = NULL;
|
||||
|
@ -233,8 +217,6 @@ EAPI Eina_Bool
|
|||
eolian_eo_file_parse(const char *filepath)
|
||||
{
|
||||
Eina_Iterator *itr;
|
||||
Eina_List *depl;
|
||||
Eolian_Dependency *dep;
|
||||
|
||||
if (_database_init_count <= 0)
|
||||
return EINA_FALSE;
|
||||
|
@ -244,7 +226,6 @@ eolian_eo_file_parse(const char *filepath)
|
|||
const Eolian_Class *class = eolian_class_get_by_file(bfilename);
|
||||
Eolian_Implement *impl;
|
||||
Eolian_Constructor *ctor;
|
||||
Eina_Bool failed_dep = EINA_FALSE;
|
||||
if (!class)
|
||||
{
|
||||
const char *full_filepath = eina_hash_find(_filenames, bfilename);
|
||||
|
@ -263,30 +244,6 @@ eolian_eo_file_parse(const char *filepath)
|
|||
}
|
||||
}
|
||||
free(bfiledup);
|
||||
/* parse dependencies first (that includes inherits) */
|
||||
depl = eina_hash_find(_depclasses, eolian_class_file_get(class));
|
||||
if (!depl)
|
||||
goto impls;
|
||||
eina_hash_set(_depclasses, eolian_class_file_get(class), NULL);
|
||||
EINA_LIST_FREE(depl, dep)
|
||||
{
|
||||
if (failed_dep) goto free;
|
||||
if (!eolian_class_get_by_name(dep->name) &&
|
||||
!eolian_eo_file_parse(dep->filename))
|
||||
{
|
||||
fprintf(stderr, "eolian:%s:%d:%d: failed to parse dependency '%s'\n",
|
||||
dep->base.file, dep->base.line, dep->base.column, dep->name);
|
||||
failed_dep = EINA_TRUE; /* do not parse anymore stuff */
|
||||
}
|
||||
free:
|
||||
eina_stringshare_del(dep->base.file);
|
||||
eina_stringshare_del(dep->filename);
|
||||
eina_stringshare_del(dep->name);
|
||||
free(dep);
|
||||
}
|
||||
if (failed_dep)
|
||||
goto error;
|
||||
impls:
|
||||
itr = eolian_class_implements_get(class);
|
||||
EINA_ITERATOR_FOREACH(itr, impl)
|
||||
{
|
||||
|
|
|
@ -46,9 +46,6 @@ extern Eina_Hash *_constantsf;
|
|||
extern Eina_Hash *_filenames; /* Hash: filename without extension -> full path */
|
||||
extern Eina_Hash *_tfilenames;
|
||||
|
||||
/* a hash holding lists of deps */
|
||||
extern Eina_Hash *_depclasses;
|
||||
|
||||
/* a hash holding all declarations, for redef checking etc */
|
||||
extern Eina_Hash *_decls;
|
||||
|
||||
|
@ -63,13 +60,6 @@ typedef struct _Eolian_Object
|
|||
int column;
|
||||
} Eolian_Object;
|
||||
|
||||
typedef struct _Eolian_Dependency
|
||||
{
|
||||
Eolian_Object base;
|
||||
Eina_Stringshare *filename;
|
||||
Eina_Stringshare *name;
|
||||
} Eolian_Dependency;
|
||||
|
||||
typedef enum {
|
||||
EOLIAN_DECL_CLASS,
|
||||
EOLIAN_DECL_ALIAS,
|
||||
|
|
|
@ -493,7 +493,8 @@ class Evas_3D_Node (Evas_3D_Object, Evas.Common_Interface)
|
|||
*/
|
||||
}
|
||||
values {
|
||||
camera: Evas_3D_Camera *; /*@ The camera */
|
||||
// FIXME: Evas_3D_Camera is necessary, but that introduces a cycle
|
||||
camera: Evas_3D_Object *; /*@ The camera */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue