resources/RooUsage.txt
[app.Builder.js] / src / Palete / GirFile.vala
1 /**
2  * This is the old Gir File based API parser..
3  * 
4  */
5 namespace Palete {
6  
7          
8     
9         public class Gir : GirObject {
10     
11                 public Gir (string ns)  
12                 {
13                         base(ns);
14                         this.load();
15                 }
16                         
17                 public   void  load () {
18                         
19                         var xns = ns == "Glade" ? "Gladeui" : this.name;
20                         var gi = GI.Repository.get_default();
21                         gi.require(xns, null, 0);
22                         
23                         var ver = gi.get_version(xns);
24                         unowned GLib.SList<string>  pth = GI.Repository.get_search_path ();
25                         var gir_path = pth.nth_data(0).replace("/lib/girepository-1.0", "/share/gir-1.0");
26                         // 64bit...
27                         gir_path = gir_path.replace("/lib/x86_64-linux-gnu/girepository-1.0", "/share/gir-1.0");
28                         
29                         //console.log(fn);
30
31                         
32                         
33                         var file  = gir_path + "/" + xns + "-" + ver + ".gir";
34                         // print("ns: " + ns + "\n");
35                         // print("ver: " + ver + "\n");
36                         // print(file);
37
38
39                         this.ns = ns;
40                                 //this.nodes = new Gee.Hashmap<string,what>();
41                          
42                         var doc = Xml.Parser.parse_file (file);
43                         var root = doc->get_root_element();
44                         this.walk( root, (GirObject) this );
45
46                         delete doc;
47                 
48                 }
49
50                 public void walk(Xml.Node* element, GirObject? parent)
51                 {
52                     var n = element->get_prop("name");
53                         // ignore null or c:include...
54                     if (n == null || (element->ns->prefix != null && element->ns->prefix == "c")) {
55                                 n = "";
56                     }
57                     //print("%s:%s (%s ==> %s\n", element->ns->prefix , element->name , parent.name , n);
58                     switch (element->name) {
59                         case "repository":
60                             break;
61                         
62                         case "include":
63                             parent.includes.set(n, element->get_prop("version"));
64                             break;
65                         
66                         case "package":
67                             parent.package = n;
68                             break;
69                         
70                         case "c:include":
71                             break;
72                         
73                         case "namespace":
74                             parent.name = n;
75                             break;
76                         
77                         case "alias":
78                             return;
79                             //break; // not handled..
80                         
81                         case "class":
82                                 var c = new GirObject("Class", parent.name + "." + n);
83                                 parent.classes.set(n, c);
84                                 c.ns = this.ns;
85                                 c.parent = element->get_prop("parent");
86                                 c.gparent = parent;
87                                 if (c.parent == null) {
88                                         c.parent = "";
89                                 }
90                                 parent =  c;
91                                 break;
92                         
93                         case "interface":
94                             var c = new GirObject("Interface", parent.name + "." + n);
95                             c.gparent = parent;
96                             parent.classes.set(n, c);
97                                 c.ns = this.ns;
98                                 c.ns = parent.name;
99                                 c.parent = element->get_prop("parent");
100                                 if (c.parent == null) {
101                                         c.parent = "";
102                                 }
103                                 parent =  c;
104                             break;
105                         
106                         
107                         case "doc":
108                             parent.doctxt = element->get_content();
109                             return;
110                         
111                         case "implements":
112                             parent.implements.add(n);
113                 
114                             break;
115                         
116                         case "constructor":
117                             var c = new GirObject("Ctor",n);
118                             c.ns = this.ns;
119                             c.gparent = parent;
120                             parent.ctors.set(n,c);
121                             parent  = c;
122                             break;
123                         
124                         case "return-value":
125                             var c = new GirObject("Return", "return-value");
126                             c.gparent = parent;
127                             c.ns = this.ns;
128                             parent.return_value = c;
129                             parent =  c;
130                             break;
131                         
132                         case "virtual-method": // not sure...
133                             return;
134                         /*
135                             var c = new GirObject("Signal",n);
136                             parent.signals.set(n,c);
137                             parent = c;
138                             break;
139                         */
140                         case "signal": // Glib:signal
141                                 var c = new GirObject("Signal",n.replace("-", "_"));
142                                 c.gparent = parent;
143                                 c.ns = this.ns;
144                                 parent.signals.set(n.replace("-", "_"),c);
145                                 parent = c;
146                                 break;
147                             
148                         
149                       
150                         case "callback": // not sure...
151                             return;
152                         
153                         
154                         case "type":
155                             parent.type = n;
156                                 
157                                                 return; // no children?
158                             //break;
159                         
160                         case "method":
161                                 var c = new GirObject("Method",n);
162                                 c.gparent = parent;
163                                 c.ns = this.ns;
164                                 c.propertyof = parent.name;
165                                 parent.methods.set(n,c);
166                                 parent = c;
167                                 break;
168                         
169                         case "parameters":
170                             var c = new GirObject("Paramset",n);
171                             c.gparent = parent;
172                             c.ns = this.ns;
173                             parent.paramset = c;
174                             parent =  c;
175                             break;
176                         
177                         case "instance-parameter":
178                                         break;
179                                         // looks  like this is the C first arg, that is ignored (as it is 
180                                         // treated as 'this' )
181                                 var c = new GirObject("Param",n);
182                                         c.gparent = parent;
183                                         c.ns = this.ns;
184                                 c.is_instance = true;
185                                 parent.params.add(c);
186                                 parent = c;
187                                 break;
188                         
189                         case "parameter":
190                                 var c = new GirObject("Param",n);
191                                 c.gparent = parent;
192                                 c.ns = this.ns;
193                                 parent.params.add(c);
194                                 parent = c;
195                                 this.checkParamOverride(c);   
196                             break;
197                         
198                         case "property":
199                         case "field":
200                                 var c = new GirObject("Prop",n.replace("-", "_"));
201                                 c.gparent = parent;
202                                 c.ns = this.ns;
203                                 c.propertyof = parent.name;
204                                 parent.props.set(n.replace("-", "_"),c);
205                                 parent = c;
206                                 break;
207                         
208                         case "function":
209                             var c = new GirObject("Function",n);
210                             c.gparent = parent;
211                             c.ns = this.ns;
212                             parent.methods.set(n,c);
213                             parent = c;
214                             break;
215                         
216                         case "array":
217                             parent.is_array = true;  
218                             break; // type is added soon..
219                         
220                         case "varargs":
221                             parent.is_varargs= true;  
222                             return;
223                         
224                         case "constant":
225                             var c = new GirObject("Const",n);
226                             c.gparent = parent;
227                             c.value = element->get_prop("value");
228                                                 c.ns = this.ns;
229                             parent.consts.set(n,c);
230                             parent = c;
231                             return;
232                             //break;
233                         case "bitfield":
234                         case "enumeration":
235                                 var c = new GirObject("Enum",n);
236                                 c.gparent = parent;
237                                 c.ns = this.ns;
238                                 parent.consts.set(n,c);
239                                 
240                                 parent = c;
241                                 break;
242                         
243                         case "member":
244                                 var c = new GirObject("EnumMember",n);
245                                 c.gparent = parent;
246                                 c.ns = this.ns;
247                                 c.value = element->get_prop("value");
248                                 parent.consts.set(n,c);
249                                 return;
250                                 break;
251                         
252                         
253                         case "doc-deprecated":
254                             return;
255                         
256                         case "record": // struct?
257                             return;
258                          
259                                             
260                             return;
261                         case "prerequisite": // ignore?
262                             return;
263                                         case "union": // ignore?
264                             return;
265                                         default:
266                             print("UNHANDLED Gir file element: " + element->name +"\n");
267                             return;
268                     }
269                     /*
270                     if (element->name == "signal") {
271                         path += ".signal";
272                     }
273                     
274                     
275                     if (element->name == "return-value") {
276                         path += ".return-value";
277                     }
278                     print(path + ":"  + element->name + "\n");
279                     */
280                     //var d =   getAttribute(element,'doc');
281                     //if (d) {
282                      //   Seed.print(path + ':' + d);
283                     //    ret[path] = d;
284                     //}
285                     for (Xml.Node* iter = element->children; iter != null; iter = iter->next) {
286                         if (iter->type == Xml.ElementType.TEXT_NODE) {
287                             continue;
288                         }
289                         this.walk(iter, parent);
290                     }
291
292                 }
293                 
294                 
295                 public void checkParamOverride(GirObject c)
296                 {
297                         var parset = c.gparent;
298                         if (parset == null || parset.nodetype != "Paramset") {
299                                 return;
300                         }
301                         var method = parset.gparent;
302                         if (method == null || method.nodetype != "Ctor") {
303                                 return;
304                         }
305                         var cls = method.gparent;
306                         if (cls == null || cls.nodetype != "Class") {
307                                 return;
308                         }
309
310                          
311                 
312                         c.name = this.fetchOverride( cls.name, method.name, c.name);
313                 }
314                 public static bool overrides_loaded = false;
315                 public static Gee.HashMap<string,string> overrides;
316         
317                 public string fetchOverride(  string cls, string method, string param)
318                 {
319                         // overrides should be in a file Gir.overides
320                         // in that "Gtk.Label.new.str" : "label"
321                         this.loadOverrides();
322                         var key = "%s.%s.%s".printf(cls,method,param);
323                         //print("Chekcing for key %s\n", key);
324                         if (!overrides.has_key(key)) {
325                                 return param;
326                         }
327                         return overrides.get(key);
328
329
330                 }
331                 
332                 public void loadOverrides(bool force = false)
333                 {
334                         if (overrides_loaded && ! force) {
335                                 return;
336                         }
337                 
338                         var pa = new Json.Parser();
339                         pa.load_from_file(BuilderApplication.configDirectory() + "/resources/Gir.overides");
340                         var node = pa.get_root();
341                     
342                         if (node.get_node_type () != Json.NodeType.OBJECT) {
343                                 throw new GirError.INVALID_FORMAT ("Error loading gir.overides : Unexpected element type %s", node.type_name ());
344                         }
345                         overrides = new Gee.HashMap<string,string>();
346                 
347                 
348                         var obj = node.get_object ();
349                 
350                 
351                         obj.foreach_member((o , key, value) => {
352                                 //print(key+"\n");
353                                  
354                                 var v = obj.get_string_member(key);
355                         
356                         
357                                 overrides.set(key, v);
358
359                         });
360         
361                         overrides_loaded = true;
362
363                 
364
365                 }
366                 
367                 public string doc(string what)
368                 {
369                         var ar = what.split(".");
370                         var cls = this.classes.get(ar[1]);
371                         if (ar.length == 2) {
372                                 return cls.doctxt != null ? cls.doctxt : "";
373                         }
374                         // return the property.. by default..
375                         var pr = cls.props.get(ar[2]);
376                         return pr.doctxt != null ? pr.doctxt : "";
377
378                 }
379                 
380                 public static Gir?  factory(string ns) 
381                 {
382                         if (cache == null) {
383                                 cache = new Gee.HashMap<string,Gir>();
384                                 var a = new Palete.VapiParser( );
385                                 a.create_valac_tree();
386                                  
387                                 
388                         }
389                         var ret = cache.get(ns);
390                         if (ret == null) {
391
392                                 var add = new Gir(ns);
393                                 
394                                 cache.set(ns, add);
395                         
396                                 var iter = add.classes.map_iterator();
397                                 while(iter.next()) {
398                                         iter.get_value().overlayParent();
399                                 }
400                                 // loop again and add the ctor properties.
401                                 iter = add.classes.map_iterator();
402                                 while(iter.next()) {
403                                         iter.get_value().overlayCtorProperties();
404                                 }       
405
406                                 
407                                 ret = cache.get(ns);
408                         }
409                          
410
411                         return ret;
412                         
413                 }
414                 public static GirObject?  factoryFqn(string fqn)  
415                 {       
416                         var bits = fqn.split(".");
417                         if (bits.length < 1) {
418                                 return null;
419                         }
420                         
421                         var f = (GirObject)factory(bits[0]);
422
423                         if (bits.length == 1 || f ==null) {
424                                 return f;
425                         }
426                         return f.fetchByFqn(fqn.substring(bits[0].length+1)); // since classes are stored in fqn format...?
427                                             
428                         
429                 }
430
431                         
432                 /**
433                  * guess the fqn of a type == eg. gboolean or Widget etc...
434                  */
435                 public static string fqtypeLookup(string type, string ns) {
436                         var g = factory(ns);
437                         if (g.classes.has_key(type)) {
438                                 return ns + "." + type;
439                         }
440                         // enums..
441                         if (g.consts.has_key(type)) {
442                                 return ns + "." + type;
443                         }
444                         
445                         
446                         // look at includes..
447                         var iter = g.includes.map_iterator();
448                         while(iter.next()) {
449                                 // skip empty namespaces on include..?
450                                 if ( iter.get_key() == "") {
451                                         continue;
452                                 }
453                                 var ret = fqtypeLookup(type, iter.get_key());
454                                 if (ret != type) {
455                                         return ret;
456                                 }
457                 }       
458                         return type;
459                 }
460                 
461
462
463                 
464                 // needed still - where's it called form..
465                 public static string guessDefaultValueForType(string type) {
466                         //print("guessDefaultValueForType: %s\n", type);
467                         if (type.length < 1 || type.contains(".")) {
468                                 return "null";
469                         }
470                         switch(type) {
471                                 case "gboolean":
472                                         return "true";
473                                 case "guint":
474                                         return "0";
475                                 case "utf8":
476                                         return "\"\"";
477                                 default:
478                                         return "?"+  type + "?";
479                         }
480
481                 }