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