summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@osg.samsung.com>2015-05-22 15:03:38 +0100
committerDaniel Kolesa <d.kolesa@osg.samsung.com>2015-05-22 15:03:38 +0100
commit9214fa3db97362b65960c85cad92d85e56bc30ca (patch)
tree1be3bb15f756b5657f4c7b8f55ad12128a98644b /src
parentadf445e3bdc290e78e3be05bbaeea54739568205 (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/lib/ecore_con/ecore_con_server.eo3
-rw-r--r--src/lib/eolian/eo_parser.c46
-rw-r--r--src/lib/eolian/eolian_database.c43
-rw-r--r--src/lib/eolian/eolian_database.h10
-rw-r--r--src/lib/evas/canvas/evas_3d_node.eo3
5 files changed, 23 insertions, 82 deletions
diff --git a/src/lib/ecore_con/ecore_con_server.eo b/src/lib/ecore_con/ecore_con_server.eo
index e942d77330..6e404e6afc 100644
--- a/src/lib/ecore_con/ecore_con_server.eo
+++ b/src/lib/ecore_con/ecore_con_server.eo
@@ -51,7 +51,8 @@ class Ecore.Con.Server (Ecore.Con.Base) {
51 get { 51 get {
52 } 52 }
53 values { 53 values {
54 clients: const(list<const(Ecore.Con.Client) *>) *; /*@ The list of clients on this server. */ 54 // FIXME: Ecore.Con.Client is needed, but that introduces a cycle
55 clients: const(list<const(Ecore.Con.Base) *>) *; /*@ The list of clients on this server. */
55 } 56 }
56 } 57 }
57 @property connection_type { 58 @property connection_type {
diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c
index 49c3a845a6..d7c0fde709 100644
--- a/src/lib/eolian/eo_parser.c
+++ b/src/lib/eolian/eo_parser.c
@@ -667,30 +667,22 @@ parse_struct_attrs(Eo_Lexer *ls, Eina_Bool is_enum, Eina_Bool *is_extern,
667} 667}
668 668
669static void 669static void
670_append_dep(Eo_Lexer *ls, const char *fname, const char *name, int line, int col) 670_parse_dep(Eo_Lexer *ls, const char *fname, const char *name)
671{ 671{
672 Eina_Stringshare *cname = eina_stringshare_add(name); 672 if (eina_hash_find(_parsingeos, fname))
673 Eolian_Dependency *dep; 673 {
674 674 char buf[PATH_MAX];
675 Eina_List *deps = eina_hash_find(_depclasses, ls->filename); 675 eo_lexer_context_restore(ls);
676 Eina_List *l; 676 snprintf(buf, sizeof(buf), "cyclic dependency '%s'", name);
677 void *data; 677 eo_lexer_syntax_error(ls, buf);
678 678 }
679 /* check for possible duplicates while building the deplist */ 679 if (!eolian_eo_file_parse(fname))
680 EINA_LIST_FOREACH(deps, l, data) 680 {
681 if (data == cname) 681 char buf[PATH_MAX];
682 { 682 eo_lexer_context_restore(ls);
683 eina_stringshare_del(cname); 683 snprintf(buf, sizeof(buf), "error parsing dependency '%s'", name);
684 return; 684 eo_lexer_syntax_error(ls, buf);
685 } 685 }
686
687 dep = calloc(1, sizeof(Eolian_Dependency));
688 FILL_BASE(dep->base, ls, line, col);
689 dep->filename = eina_stringshare_add(fname);
690 dep->name = cname;
691
692 deps = eina_list_append(deps, dep);
693 eina_hash_set(_depclasses, ls->filename, deps);
694} 686}
695 687
696static Eolian_Type * 688static Eolian_Type *
@@ -799,10 +791,10 @@ parse_type_void(Eo_Lexer *ls)
799 } 791 }
800 else 792 else
801 { 793 {
802 int dline = ls->line_number, dcol = ls->column;
803 const char *bnm, *nm; 794 const char *bnm, *nm;
804 char *fnm; 795 char *fnm;
805 buf = push_strbuf(ls); 796 buf = push_strbuf(ls);
797 eo_lexer_context_push(ls);
806 parse_name(ls, buf); 798 parse_name(ls, buf);
807 nm = eina_strbuf_string_get(buf); 799 nm = eina_strbuf_string_get(buf);
808 bnm = eina_stringshare_ref(ls->filename); 800 bnm = eina_stringshare_ref(ls->filename);
@@ -814,7 +806,7 @@ parse_type_void(Eo_Lexer *ls)
814 free(fnm); 806 free(fnm);
815 if (fname) 807 if (fname)
816 { 808 {
817 _append_dep(ls, fname, nm, dline, dcol); 809 _parse_dep(ls, fname, nm);
818 def->type = EOLIAN_TYPE_CLASS; 810 def->type = EOLIAN_TYPE_CLASS;
819 } 811 }
820 } 812 }
@@ -826,6 +818,7 @@ parse_type_void(Eo_Lexer *ls)
826 } 818 }
827 _fill_name(eina_stringshare_add(nm), &def->full_name, &def->name, 819 _fill_name(eina_stringshare_add(nm), &def->full_name, &def->name,
828 &def->namespaces); 820 &def->namespaces);
821 eo_lexer_context_pop(ls);
829 pop_strbuf(ls); 822 pop_strbuf(ls);
830 } 823 }
831 } 824 }
@@ -1721,7 +1714,6 @@ parse_class_body(Eo_Lexer *ls, Eolian_Class_Type type)
1721static void 1714static void
1722_inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf) 1715_inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf)
1723{ 1716{
1724 int dline = ls->line_number, dcol = ls->column;
1725 const char *fname, *iname; 1717 const char *fname, *iname;
1726 char *fnm; 1718 char *fnm;
1727 eina_strbuf_reset(buf); 1719 eina_strbuf_reset(buf);
@@ -1748,7 +1740,7 @@ _inherit_dep(Eo_Lexer *ls, Eina_Strbuf *buf)
1748 snprintf(ebuf, sizeof(ebuf), "unknown inherit '%s'", iname); 1740 snprintf(ebuf, sizeof(ebuf), "unknown inherit '%s'", iname);
1749 eo_lexer_syntax_error(ls, ebuf); 1741 eo_lexer_syntax_error(ls, ebuf);
1750 } 1742 }
1751 _append_dep(ls, fname, iname, dline, dcol); 1743 _parse_dep(ls, fname, iname);
1752 ls->tmp.kls->inherits = eina_list_append(ls->tmp.kls->inherits, 1744 ls->tmp.kls->inherits = eina_list_append(ls->tmp.kls->inherits,
1753 eina_stringshare_add(iname)); 1745 eina_stringshare_add(iname));
1754 eo_lexer_context_pop(ls); 1746 eo_lexer_context_pop(ls);
diff --git a/src/lib/eolian/eolian_database.c b/src/lib/eolian/eolian_database.c
index a568aa51e1..d9eb110ec4 100644
--- a/src/lib/eolian/eolian_database.c
+++ b/src/lib/eolian/eolian_database.c
@@ -21,7 +21,6 @@ Eina_Hash *_globalsf = NULL;
21Eina_Hash *_constantsf = NULL; 21Eina_Hash *_constantsf = NULL;
22Eina_Hash *_filenames = NULL; 22Eina_Hash *_filenames = NULL;
23Eina_Hash *_tfilenames = NULL; 23Eina_Hash *_tfilenames = NULL;
24Eina_Hash *_depclasses = NULL;
25Eina_Hash *_decls = NULL; 24Eina_Hash *_decls = NULL;
26 25
27Eina_Hash *_parsedeots = NULL; 26Eina_Hash *_parsedeots = NULL;
@@ -35,19 +34,6 @@ _hashlist_free(void *data)
35 eina_list_free((Eina_List*)data); 34 eina_list_free((Eina_List*)data);
36} 35}
37 36
38static void
39_deplist_free(Eina_List *data)
40{
41 Eolian_Dependency *dep;
42 EINA_LIST_FREE(data, dep)
43 {
44 eina_stringshare_del(dep->base.file);
45 eina_stringshare_del(dep->filename);
46 eina_stringshare_del(dep->name);
47 free(dep);
48 }
49}
50
51int 37int
52database_init() 38database_init()
53{ 39{
@@ -67,7 +53,6 @@ database_init()
67 _constantsf = eina_hash_stringshared_new(_hashlist_free); 53 _constantsf = eina_hash_stringshared_new(_hashlist_free);
68 _filenames = eina_hash_string_small_new(free); 54 _filenames = eina_hash_string_small_new(free);
69 _tfilenames = eina_hash_string_small_new(free); 55 _tfilenames = eina_hash_string_small_new(free);
70 _depclasses = eina_hash_stringshared_new(EINA_FREE_CB(_deplist_free));
71 _decls = eina_hash_stringshared_new(free); 56 _decls = eina_hash_stringshared_new(free);
72 _parsedeots = eina_hash_string_small_new(NULL); 57 _parsedeots = eina_hash_string_small_new(NULL);
73 _parsingeos = eina_hash_string_small_new(NULL); 58 _parsingeos = eina_hash_string_small_new(NULL);
@@ -100,7 +85,6 @@ database_shutdown()
100 eina_hash_free(_constantsf); _constantsf = NULL; 85 eina_hash_free(_constantsf); _constantsf = NULL;
101 eina_hash_free(_filenames ); _filenames = NULL; 86 eina_hash_free(_filenames ); _filenames = NULL;
102 eina_hash_free(_tfilenames); _tfilenames = NULL; 87 eina_hash_free(_tfilenames); _tfilenames = NULL;
103 eina_hash_free(_depclasses); _depclasses = NULL;
104 eina_hash_free(_decls ); _decls = NULL; 88 eina_hash_free(_decls ); _decls = NULL;
105 eina_hash_free(_parsedeots); _parsedeots = NULL; 89 eina_hash_free(_parsedeots); _parsedeots = NULL;
106 eina_hash_free(_parsingeos); _parsingeos = NULL; 90 eina_hash_free(_parsingeos); _parsingeos = NULL;
@@ -233,8 +217,6 @@ EAPI Eina_Bool
233eolian_eo_file_parse(const char *filepath) 217eolian_eo_file_parse(const char *filepath)
234{ 218{
235 Eina_Iterator *itr; 219 Eina_Iterator *itr;
236 Eina_List *depl;
237 Eolian_Dependency *dep;
238 220
239 if (_database_init_count <= 0) 221 if (_database_init_count <= 0)
240 return EINA_FALSE; 222 return EINA_FALSE;
@@ -244,7 +226,6 @@ eolian_eo_file_parse(const char *filepath)
244 const Eolian_Class *class = eolian_class_get_by_file(bfilename); 226 const Eolian_Class *class = eolian_class_get_by_file(bfilename);
245 Eolian_Implement *impl; 227 Eolian_Implement *impl;
246 Eolian_Constructor *ctor; 228 Eolian_Constructor *ctor;
247 Eina_Bool failed_dep = EINA_FALSE;
248 if (!class) 229 if (!class)
249 { 230 {
250 const char *full_filepath = eina_hash_find(_filenames, bfilename); 231 const char *full_filepath = eina_hash_find(_filenames, bfilename);
@@ -263,30 +244,6 @@ eolian_eo_file_parse(const char *filepath)
263 } 244 }
264 } 245 }
265 free(bfiledup); 246 free(bfiledup);
266 /* parse dependencies first (that includes inherits) */
267 depl = eina_hash_find(_depclasses, eolian_class_file_get(class));
268 if (!depl)
269 goto impls;
270 eina_hash_set(_depclasses, eolian_class_file_get(class), NULL);
271 EINA_LIST_FREE(depl, dep)
272 {
273 if (failed_dep) goto free;
274 if (!eolian_class_get_by_name(dep->name) &&
275 !eolian_eo_file_parse(dep->filename))
276 {
277 fprintf(stderr, "eolian:%s:%d:%d: failed to parse dependency '%s'\n",
278 dep->base.file, dep->base.line, dep->base.column, dep->name);
279 failed_dep = EINA_TRUE; /* do not parse anymore stuff */
280 }
281free:
282 eina_stringshare_del(dep->base.file);
283 eina_stringshare_del(dep->filename);
284 eina_stringshare_del(dep->name);
285 free(dep);
286 }
287 if (failed_dep)
288 goto error;
289impls:
290 itr = eolian_class_implements_get(class); 247 itr = eolian_class_implements_get(class);
291 EINA_ITERATOR_FOREACH(itr, impl) 248 EINA_ITERATOR_FOREACH(itr, impl)
292 { 249 {
diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h
index 2d8d4d0a8d..6783050d02 100644
--- a/src/lib/eolian/eolian_database.h
+++ b/src/lib/eolian/eolian_database.h
@@ -46,9 +46,6 @@ extern Eina_Hash *_constantsf;
46extern Eina_Hash *_filenames; /* Hash: filename without extension -> full path */ 46extern Eina_Hash *_filenames; /* Hash: filename without extension -> full path */
47extern Eina_Hash *_tfilenames; 47extern Eina_Hash *_tfilenames;
48 48
49/* a hash holding lists of deps */
50extern Eina_Hash *_depclasses;
51
52/* a hash holding all declarations, for redef checking etc */ 49/* a hash holding all declarations, for redef checking etc */
53extern Eina_Hash *_decls; 50extern Eina_Hash *_decls;
54 51
@@ -63,13 +60,6 @@ typedef struct _Eolian_Object
63 int column; 60 int column;
64} Eolian_Object; 61} Eolian_Object;
65 62
66typedef struct _Eolian_Dependency
67{
68 Eolian_Object base;
69 Eina_Stringshare *filename;
70 Eina_Stringshare *name;
71} Eolian_Dependency;
72
73typedef enum { 63typedef enum {
74 EOLIAN_DECL_CLASS, 64 EOLIAN_DECL_CLASS,
75 EOLIAN_DECL_ALIAS, 65 EOLIAN_DECL_ALIAS,
diff --git a/src/lib/evas/canvas/evas_3d_node.eo b/src/lib/evas/canvas/evas_3d_node.eo
index a4d8fdf294..31036ec543 100644
--- a/src/lib/evas/canvas/evas_3d_node.eo
+++ b/src/lib/evas/canvas/evas_3d_node.eo
@@ -493,7 +493,8 @@ class Evas_3D_Node (Evas_3D_Object, Evas.Common_Interface)
493 */ 493 */
494 } 494 }
495 values { 495 values {
496 camera: Evas_3D_Camera *; /*@ The camera */ 496 // FIXME: Evas_3D_Camera is necessary, but that introduces a cycle
497 camera: Evas_3D_Object *; /*@ The camera */
497 } 498 }
498 } 499 }
499 500