Palete/Gir.vala
[app.Builder.js] / Palete / Gir.vala
1
2 // valac -g  --pkg gee-1.0 --pkg libxml-2.0 --pkg gobject-introspection-1.0 --pkg json-glib-1.0  Palete/Gir.vala -o /tmp/Gir
3 /* 
4 public static int main (string[] args) {
5     
6     var g = new Palete.Gir("Gtk");
7     var generator = new Json.Generator ();
8     var n = new Json.Node(Json.NodeType.OBJECT);
9     n.set_object(g.toJSON());
10     generator.set_root(n);
11     generator.indent = 4;
12     generator.pretty = true;
13     
14     print(generator.to_data(null));
15     return 0;
16 }
17 */
18 namespace Palete {
19
20     public class GirObject: Object {
21         public string name;
22                 public string ns;
23         public string type;
24         public string nodetype;
25         public string  package;
26         
27         public GirObject paramset = null;
28         public GirObject return_value = null;
29             
30         public bool is_instance;
31         public bool is_array;
32         public bool  is_varargs;
33         public  string parent;
34         public  string value;
35             
36         public Gee.HashMap<string,GirObject> params;
37         public GLib.List<string> implements;
38                 public GLib.List<string> inherits; // full list of all classes and interfaces...
39         public Gee.HashMap<string,GirObject> ctors;
40         public Gee.HashMap<string,GirObject> methods;
41         public Gee.HashMap<string,string>    includes;
42         public Gee.HashMap<string,GirObject> classes;
43         public Gee.HashMap<string,GirObject> props;
44         public Gee.HashMap<string,GirObject> consts;
45         public Gee.HashMap<string,GirObject> signals;
46         public string doc;
47         public GirObject(string nodetype, string n)
48                 {
49             this.nodetype = nodetype;
50             this.name = n;
51                         this.ns = "";
52             this.parent = "";
53             this.type = "";
54             this.is_array = false;
55             this.is_instance = false;
56             this.is_varargs = false;
57             this.implements = new GLib.List<string>();
58                         this.inherits  = new GLib.List<string>();
59             this.includes   = new Gee.HashMap<string,string>();
60             
61             this.params = new Gee.HashMap<string,GirObject>();
62             this.ctors      = new Gee.HashMap<string,GirObject>();
63             this.methods    =new Gee.HashMap<string,GirObject>();
64            
65             this.classes    = new Gee.HashMap<string,GirObject>();
66             this.props      = new Gee.HashMap<string,GirObject>();
67             this.consts     = new Gee.HashMap<string,GirObject>();
68             this.signals    = new Gee.HashMap<string,GirObject>();
69         }
70
71                 public void  overlayParent(Gir in_gir)
72                 {
73                         var gir = in_gir;
74                         if (this.parent.length < 1) {
75                                 return;
76                         }
77                         //print(this.parent);
78
79                         var pcls = this.parentClass(gir);
80                         pcls.overlayParent(gir);
81                         this.copyFrom(pcls,false);
82                         for(var i=0; i < this.implements.length(); i++) {
83                                 var picls = this.parentClass(gir,this.implements.nth_data(i));
84                                 this.copyFrom(picls,true);
85                         }
86  
87                         
88                 }
89                 public GirObject parentClass(Gir in_gir, string in_pn)
90                 {
91                         var pn = in_pn;
92                         var gir = in_gir;
93                         if (this.parent.contains(".")) {
94                                 gir =  Gir.factory(parent.split(".")[0]);
95                                 pn = parent.split(".")[1];
96
97                         }
98                         
99                         return gir.classes.get(pn);
100
101                         
102                 }
103                 public string fqn() {
104                         return this.ns + this.name;
105                 }
106                 
107                 public void copyFrom(GirObject pcls, bool is_interface) 
108                 {
109
110                         this.inherits.append(pcls.fqn());
111                         var iter = pcls.methods.map_iterator();
112                         while(iter.next()) {
113                 if (null == this.methods.get(iter.get_key())) {
114                                         continue;
115                                 }
116                                 
117                                 this.methods.set(iter.get_key(), iter.get_value());
118             }   
119                         iter = pcls.props.map_iterator();
120                         while(iter.next()) {
121                 if (null == this.props.get(iter.get_key())) {
122                                         continue;
123                                 }
124                                 
125                                 this.props.set(iter.get_key(), iter.get_value());
126             }   
127                         iter = pcls.signals.map_iterator();
128                         while(iter.next()) {
129                 if (null == this.signals.get(iter.get_key())) {
130                                         continue;
131                                 }
132                                 
133                                 this.signals.set(iter.get_key(), iter.get_value());
134             }   
135                 }
136                 
137         public Json.Object toJSON()
138         {
139             var r = new Json.Object();
140             r.set_string_member("nodetype", this.nodetype);
141             r.set_string_member("name", this.name);
142             if (this.type.length > 0) {
143                 r.set_string_member("type", this.type);
144             }
145                         if (this.parent != null && this.parent.length > 0) {
146                 r.set_string_member("parent", this.parent);
147             }
148             // is_arary / is_instance / is_varargs..
149             
150             if (this.implements.length() > 0) {
151                 r.set_array_member("length", this.toJSONArrayString(this.implements));
152             }
153             
154             if (this.params.size > 0) {
155                 r.set_object_member("params", this.toJSONObject(this.params));
156             }
157             if (this.ctors.size > 0) {
158                 r.set_object_member("ctors", this.toJSONObject(this.ctors));
159             }
160             if (this.methods.size > 0) {
161                 r.set_object_member("methods", this.toJSONObject(this.methods));
162             }
163             if (this.includes.size > 0) {
164                 r.set_object_member("includes", this.toJSONObjectString(this.includes));
165             }
166             if (this.classes.size > 0) {
167                 r.set_object_member("classes", this.toJSONObject(this.classes));
168             }
169             if (this.props.size > 0) {
170                 r.set_object_member("props", this.toJSONObject(this.props));
171             }
172             if (this.consts.size > 0) {
173                 r.set_object_member("consts", this.toJSONObject(this.consts));
174             }
175             if (this.signals.size > 0) {
176                 r.set_object_member("signals", this.toJSONObject(this.signals));
177             }
178             if (this.paramset != null) {
179                 r.set_object_member("params", this.paramset.toJSON());
180             }
181             if (this.return_value != null) {
182                 r.set_object_member("return_value", this.return_value.toJSON());
183             }
184             return r;
185         }
186         public Json.Object toJSONObject(Gee.HashMap<string,GirObject> map)
187         {
188             var r = new Json.Object();
189             var iter = map.map_iterator();
190             while(iter.next()) {
191                 r.set_object_member(iter.get_key(), iter.get_value().toJSON());
192             }
193             return r;
194         }
195         public Json.Object  toJSONObjectString(Gee.HashMap<string,string> map)
196         {
197             var r = new Json.Object();
198             var iter = map.map_iterator();
199             while(iter.next()) {
200                 r.set_string_member(iter.get_key(), iter.get_value());
201             }
202             return r;
203         }
204         public Json.Array toJSONArrayString(GLib.List<string> map)
205         {
206             var r = new Json.Array();
207             for(var i =0;i< map.length();i++) {
208             
209                 r.add_string_element(map.nth_data(i));
210             }
211             return r;
212         }
213     }
214     
215      
216     
217     
218     
219     public class Gir : GirObject {
220     
221         static  Gee.HashMap<string,Gir> cache = null;
222         //Gee.Hashmap<string,what> nodes;
223                 public static Gir factory(string ns) {
224                         if (cache == null) {
225                                 cache = new Gee.HashMap<string,Gir>();
226                         }
227                         var ret = cache.get(ns);
228                         if (ret != null) {
229                                 return ret;
230                         }
231                         cache.set(ns, new Gir(ns));
232                         return cache.get(ns);
233                         
234                 }
235         public Gir (string ns)  
236         {
237
238                         var gi = GI.Repository.get_default();
239                         gi.require(ns, null, 0);
240                         
241                     var ver = gi.get_version(ns);
242                     unowned GLib.SList<string>  pth = GI.Repository.get_search_path ();
243                     var gir_path = pth.nth_data(0).replace("/lib/girepository-1.0", "/share/gir-1.0");
244                    //console.log(fn);
245                     var file  = gir_path + "/" + ns + "-" + ver + ".gir";
246                         print("ns: " + ns + "\n");
247                         print("ver: " + ver + "\n");
248                     print(file);
249
250
251                         base("Package",ns);
252             //this.nodes = new Gee.Hashmap<string,what>();
253              
254             var doc = Xml.Parser.parse_file (file);
255             var root = doc->get_root_element();
256             this.walk( root, (GirObject) this );
257             delete doc;
258         
259         }
260         public void walk(Xml.Node* element, GirObject? parent)
261         {
262             var n = element->get_prop("name");
263             if (n == null) {
264                 n = "";
265             }
266             //print(element->name + " ("  + parent.name + "==>" + n +")\n");
267             switch (element->name) {
268                 case "repository":
269                     break;
270                 
271                 case "include":
272                     parent.includes.set(n, element->get_prop("version"));
273                     break;
274                 
275                 case "package":
276                     parent.package = n;
277                     break;
278                 
279                 case "c:include":
280                     break;
281                 
282                 case "namespace":
283                     parent.name = n;
284                     break;
285                 
286                 case "alias":
287                     return;
288                     //break; // not handled..
289                 
290                 case "class":
291                     var c = new GirObject("Class", parent.name + "." + n);
292                     parent.classes.set(n, c);
293                                         c.ns = parent.name;
294                     c.parent = element->get_prop("parent");
295                                         if (c.parent == null) {
296                                                 c.parent = "";
297                                         }
298                     parent =  c;
299                     break;
300                 
301                 case "interface":
302                     var c = new GirObject("Interface", parent.name + "." + n);
303                     parent.classes.set(n, c);
304                                         c.ns = parent.name;
305                     c.parent = element->get_prop("parent");
306                                         if (c.parent == null) {
307                                                 c.parent = "";
308                                         }
309                                         parent =  c;
310                     break;
311                 
312                 
313                 case "doc":
314                     parent.doc = element->get_content();
315                     return;
316                 
317                 case "implements":
318                     parent.implements.append(n);
319                     break;
320                 
321                 case "constructor":
322                     var c = new GirObject("Ctor",n);
323                                         c.ns = parent.ns;
324                     parent.ctors.set(n,c);
325                     parent  = c;
326                     break;
327                 
328                 case "return-value":
329                     var c = new GirObject("Return", "return-value");
330                                         c.ns = parent.ns;
331                     parent.return_value = c;
332                     parent =  c;
333                     break;
334                 
335                 case "virtual-method": // not sure...
336                     return;
337                 /*
338                     var c = new GirObject("Signal",n);
339                     parent.signals.set(n,c);
340                     parent = c;
341                     break;
342                 */
343                 case "signal": // Glib:signal
344                     var c = new GirObject("Signal",n);
345                                         c.ns = parent.ns;
346                     parent.signals.set(n,c);
347                     parent = c;
348                     break;
349                     
350                 
351               
352                 case "callback": // not sure...
353                     return;
354                 
355                 
356                 case "type":
357                     parent.type = n;
358                                         return; // no children?
359                     //break;
360                 
361                 case "method":
362                     var c = new GirObject("Method",n);
363                                         c.ns = parent.ns;
364                     parent.methods.set(n,c);
365                     parent = c;
366                     break;
367                 
368                 case "parameters":
369                     var c = new GirObject("Paramset",n);
370                                         c.ns = parent.ns;
371                     parent.paramset = c;
372                     parent =  c;
373                     break;
374                 
375                 case "instance-parameter":
376                     var c = new GirObject("Param",n);
377                                         c.ns = parent.ns;
378                     c.is_instance = true;
379                     parent.params.set(n,c);
380                     parent = c;
381                     break;
382                 
383                 case "parameter":
384                     var c = new GirObject("Param",n);
385                                         c.ns = parent.ns;
386                     parent.params.set(n,c);
387                     parent = c;
388                     break;
389                 
390                 case "property":
391                 case "field":
392                     var c = new GirObject("Prop",n);
393                                         c.ns = parent.ns;
394                     parent.props.set(n,c);
395                     parent = c;
396                     break;
397                 
398                 case "function":
399                     var c = new GirObject("Function",n);
400                                         c.ns = parent.ns;
401                     parent.methods.set(n,c);
402                     parent = c;
403                     break;
404                 
405                 case "array":
406                     parent.is_array = true;  
407                     break; // type is added soon..
408                 
409                 case "varargs":
410                     parent.is_varargs= true;  
411                     return;
412                 
413                 case "constant":
414                     var c = new GirObject("Const",n);
415                     c.value = element->get_prop("value");
416                                         c.ns = parent.ns;
417                     parent.consts.set(n,c);
418                     parent = c;
419                     return;
420                     //break;
421                 
422                 case "enumeration":
423                     var c = new GirObject("Enum",n);
424                                         c.ns = parent.ns;
425                     parent.consts.set(n,c);
426                                         
427                     parent = c;
428                     break;
429                 
430                 case "member":
431                     var c = new GirObject("EnumMember",n);
432                                         c.ns = parent.ns;
433                     c.value = element->get_prop("value");
434                     parent.consts.set(n,c);
435                     return;
436                     break;
437                 
438                 
439                 case "doc-deprecated":
440                     return;
441                 
442                 case "record": // struct?
443                     return;
444                 case "bitfield": // ignore?
445                     return;
446                 case "prerequisite": // ignore?
447                     return;
448                 default:
449                     print("UNHANDLED" + element->name +"\n");
450                     return;
451             }
452             /*
453             if (element->name == "signal") {
454                 path += ".signal";
455             }
456             
457             
458             if (element->name == "return-value") {
459                 path += ".return-value";
460             }
461             print(path + ":"  + element->name + "\n");
462             */
463             //var d =   getAttribute(element,'doc');
464             //if (d) {
465              //   Seed.print(path + ':' + d);
466             //    ret[path] = d;
467             //}
468             for (Xml.Node* iter = element->children; iter != null; iter = iter->next) {
469                 if (iter->type == Xml.ElementType.TEXT_NODE) {
470                     continue;
471                 }
472                 this.walk(iter, parent);
473             }
474             
475         }
476         
477     
478     
479     } 
480         
481 }