src/Palete/Gtk.vala
[app.Builder.js] / src / Palete / GirObject.vala
1 /**
2  * This is the base class for representing the vala API
3  *  
4  * it was originally based on parsing Gir files - but since then
5  * has evolved into using libvala  
6  * 
7  * 
8  */
9
10
11
12 namespace Palete {
13         public errordomain GirError {
14                 INVALID_TYPE,
15                 NEED_IMPLEMENTING,
16                 MISSING_FILE,
17                 INVALID_VALUE,
18                 INVALID_FORMAT
19         }
20         public class GirObject: Object {
21                 public string name;
22                 public string ns;
23                 public string propertyof;
24                 public string type;
25                 public string nodetype;
26                 public string  package;
27                 
28                 public GirObject paramset = null;
29                 public GirObject return_value = null;
30                     
31                 public bool is_instance;
32                 public bool is_array;
33                 public bool  is_varargs;
34                 public bool  ctor_only; // specially added ctor properties..
35                 public  string parent;
36                 public  string value;
37                 // to be filled in...
38          
39                 public  string sig;
40
41                 public bool is_overlaid;
42
43                 public  GirObject gparent;
44                 public Gee.ArrayList<GirObject> params;
45                 public Gee.ArrayList<string> implements;
46                 public Gee.ArrayList<string> inherits; // full list of all classes and interfaces...
47                 public Gee.HashMap<string,GirObject> ctors;
48                 public Gee.HashMap<string,GirObject> methods;
49                 public Gee.HashMap<string,string>    includes;
50                 public Gee.HashMap<string,GirObject> classes;
51                 public Gee.HashMap<string,GirObject> props;
52                 public Gee.HashMap<string,GirObject> consts;
53                 public Gee.HashMap<string,GirObject> signals;
54                 
55                 public Gee.ArrayList<string> optvalues; // used by Roo only..
56                 public string doctxt;
57
58
59                 
60                 public GirObject(string nodetype, string n)
61                 {
62                         this.nodetype = nodetype;
63                         this.name = n;
64                         this.ns = "";
65                         this.parent = "";
66                         this.type = "";
67                         this.propertyof = "";
68                         this.is_array = false;
69                         this.is_instance = false;
70                         this.is_varargs = false;
71                         this.ctor_only  =false;
72                         this.doctxt = "";
73                 
74                         this.sig = "";
75
76                         this.gparent = null;
77                         
78                         this.implements = new Gee.ArrayList<string>();
79                         this.inherits  = new Gee.ArrayList<string>(); // list of all ancestors. (interfaces and parents)
80                         this.includes   = new Gee.HashMap<string,string>();
81
82                         this.params = new Gee.ArrayList<GirObject>();
83                         this.ctors      = new Gee.HashMap<string,GirObject>();
84                         this.methods    =new Gee.HashMap<string,GirObject>();
85
86                         this.classes    = new Gee.HashMap<string,GirObject>();
87                         this.props      = new Gee.HashMap<string,GirObject>();
88                         this.consts     = new Gee.HashMap<string,GirObject>();
89                         this.signals    = new Gee.HashMap<string,GirObject>();
90                         
91                         this.optvalues = new Gee.ArrayList<string>();
92                         this.is_overlaid = false;
93                         this.paramset = null;
94                 }
95
96                 public string[] inheritsToStringArray()
97                 {
98                         string[] ret = {};
99                         for(var i =0;i< this.inherits.size; i++) {
100                                 ret += this.inherits.get(i);
101                         }
102                         return ret;
103
104                 }
105
106                 
107                 public void  overlayParent()
108                 {
109                         
110                         if (this.parent.length < 1 || this.is_overlaid) {
111                                 this.is_overlaid = true;
112                                 return;
113                         }
114                          
115                         //print("Overlaying " +this.name + " with " + this.parent + "\n");
116
117                         var pcls = this.clsToObject( this.parent);
118                         if (pcls == null) {
119                                 return;
120                                 //throw new GirError.INVALID_VALUE("Could not find class : " + 
121                                 //      this.parent + " of " + this.name  + " in " + this.ns);
122                         }
123                         
124                         pcls.overlayParent( );
125                         this.copyFrom(pcls,false);
126                         for(var i=0; i < this.implements.size; i++) {
127                                 var clsname = this.implements.get(i);
128                                 var picls = this.clsToObject(clsname);
129                                 this.copyFrom(picls,true);
130                         }
131                         this.is_overlaid = true;
132                         
133                 }
134
135                 public void overlayCtorProperties() 
136                 {
137                         //print("Check overlay Ctor %s\n", this.name);
138                         if (!this.ctors.has_key("new")) {
139                                 return;
140                         }
141                         var ctor = this.ctors.get("new");
142                         if (ctor.paramset == null || ctor.paramset.params.size < 1) {
143                                 return;
144                         }
145                         //print("Found Ctor\n");
146                         var iter = ctor.paramset.params.list_iterator();
147                         while (iter.next()) {
148                                 var n = iter.get().name;
149                                 
150                                 if (this.props.has_key(n)) {
151                                         continue;
152                                 }
153                                 if (n == "...") {
154                                         continue;
155                                 }
156                                 //print("Adding prop %s\n", n);
157                                 
158                                 // it's a new prop..
159                                 var c = new GirObject("Prop",n);
160                                 c.gparent = this;
161                                 c.ns = this.ns;
162                                 c.propertyof = this.name;
163                                 c.type = iter.get().type;
164                                 c.ctor_only = true;
165                                 this.props.set(n, c);
166                         }
167                         
168
169                 }
170
171
172                 
173                 public string fqn() {
174                         // not sure if fqn really is correct here...
175                         // 
176                         return this.nodetype == "Class" || this.nodetype=="Interface"
177                                         ? this.name : (this.ns + this.name);
178                 }
179                 
180                 public void copyFrom(GirObject pcls, bool is_interface) 
181                 {
182
183                         this.inherits.add(pcls.fqn());
184
185                         var liter = pcls.inherits.list_iterator();
186                         while(liter.next()) {
187                         if (this.inherits.contains(liter.get())) {
188                                         continue;
189                                 }
190                                 this.inherits.add(liter.get()); 
191                         }          
192                         
193                         
194                         var iter = pcls.methods.map_iterator();
195                         while(iter.next()) {
196                         if (null != this.methods.get(iter.get_key())) {
197                                         continue;
198                                 }
199                                 
200                                 this.methods.set(iter.get_key(), iter.get_value());
201                         }
202                         
203                         iter = pcls.props.map_iterator();
204                         while(iter.next()) {
205                                  if (null != this.props.get(iter.get_key())) {
206                                         continue;
207                                 }
208                                 
209                                 this.props.set(iter.get_key(), iter.get_value());
210                         }               
211                         
212                         iter = pcls.signals.map_iterator();
213                         while(iter.next()) {
214                                 if (null != this.signals.get(iter.get_key())) {
215                                                 continue;
216                                 }
217         
218                                 this.signals.set(iter.get_key(), iter.get_value());
219                         }       
220                 }
221                 
222                 public Json.Object toJSON()
223                 {
224                     var r = new Json.Object();
225                     r.set_string_member("nodetype", this.nodetype);
226                     r.set_string_member("name", this.name);
227                                 if (this.propertyof.length > 0) {
228                         r.set_string_member("of", this.propertyof);
229                     }
230                     if (this.type.length > 0) {
231                         r.set_string_member("type", this.type);
232                     }
233                     if (this.parent != null && this.parent.length > 0) {
234                         r.set_string_member("parent", this.parent);
235                     }
236                     if (this.sig.length > 0) {
237                         r.set_string_member("sig", this.sig);
238                     }
239                 
240                     // is_arary / is_instance / is_varargs..
241
242                 
243                         if (this.inherits.size > 0) {
244                         r.set_array_member("inherits", this.toJSONArrayString(this.inherits));
245                     }
246                     
247                     if (this.implements.size > 0) {
248                         r.set_array_member("implements", this.toJSONArrayString(this.implements));
249                     }
250                     
251                     if (this.params.size > 0) {
252                         r.set_array_member("params", this.toJSONArrayObject(this.params));
253                     }
254                     if (this.ctors.size > 0) {
255                         r.set_object_member("ctors", this.toJSONObject(this.ctors));
256                     }
257                     if (this.methods.size > 0) {
258                         r.set_object_member("methods", this.toJSONObject(this.methods));
259                     }
260                     if (this.includes.size > 0) {
261                         r.set_object_member("includes", this.toJSONObjectString(this.includes));
262                     }
263                     if (this.classes.size > 0) {
264                         r.set_object_member("classes", this.toJSONObject(this.classes));
265                     }
266                     if (this.props.size > 0) {
267                         r.set_object_member("props", this.toJSONObject(this.props));
268                     }
269                     if (this.consts.size > 0) {
270                         r.set_object_member("consts", this.toJSONObject(this.consts));
271                     }
272                     if (this.signals.size > 0) {
273                         r.set_object_member("signals", this.toJSONObject(this.signals));
274                     }
275                     if (this.paramset != null) {
276                         r.set_object_member("paramset", this.paramset.toJSON());
277                     }
278                     if (this.return_value != null) {
279                         r.set_object_member("return_value", this.return_value.toJSON());
280                     }
281                     return r;
282                 }
283                 public Json.Object toJSONObject(Gee.HashMap<string,GirObject> map)
284                 {
285                     var r = new Json.Object();
286                     var iter = map.map_iterator();
287                     while(iter.next()) {
288                         r.set_object_member(iter.get_key(), iter.get_value().toJSON());
289                     }
290                     return r;
291                 }
292                 public Json.Object  toJSONObjectString(Gee.HashMap<string,string> map)
293                 {
294                     var r = new Json.Object();
295                     var iter = map.map_iterator();
296                     while(iter.next()) {
297                         r.set_string_member(iter.get_key(), iter.get_value());
298                     }
299                     return r;
300                 }
301                 public Json.Array toJSONArrayString(Gee.ArrayList<string> map)
302                 {
303                     var r = new Json.Array();
304                     for(var i =0;i< map.size;i++) {
305                     
306                         r.add_string_element(map.get(i));
307                     }
308                     return r;
309                 }
310                 public Json.Array toJSONArrayObject(Gee.ArrayList<GirObject> map)
311                 {
312                     var r = new Json.Array();
313                     for(var i =0;i< map.size;i++) {
314                     
315                         r.add_object_element(map.get(i).toJSON());
316                     }
317                     return r;
318                 }
319                 public string asJSONString()
320                 {
321                         var generator = new Json.Generator ();
322                         generator.indent = 4;
323                         generator.pretty = true;
324                         var n = new Json.Node(Json.NodeType.OBJECT);
325                         n.set_object(this.toJSON());
326                         generator.set_root(n);
327         
328                         return generator.to_data(null);
329                 }
330
331  
332                 public GirObject fetchByFqn(string fqn) {
333                         //print("Searching (%s)%s for %s\n", this.nodetype, this.name, fqn);
334                         var bits = fqn.split(".");
335                         
336                         var ret = this.classes.get(bits[0]);
337                         if (ret != null) {
338                                 if (bits.length < 2) {
339                                         return ret;
340                                 }
341                                 return ret.fetchByFqn(fqn.substring(bits[0].length+1));
342                         }
343
344                         ret = this.ctors.get(bits[0]);                  
345                         if (ret != null) {
346                                 if (bits.length < 2) {
347                                         return ret;
348                                 }
349                                 return ret.fetchByFqn(fqn.substring(bits[0].length+1));
350                         }
351
352                         ret = this.methods.get(bits[0]);                        
353                         if (ret != null) {
354                                 if (bits.length < 2) {
355                                         return ret;
356                                 }
357                                 return ret.fetchByFqn(fqn.substring(bits[0].length+1));
358                         }
359                         ret = this.props.get(bits[0]);                  
360                         if (ret != null) {
361                                 if (bits.length < 2) {
362                                         return ret;
363                                 }
364                                 return ret.fetchByFqn(fqn.substring(bits[0].length+1));
365                         }
366                         ret = this.consts.get(bits[0]);                 
367                         if (ret != null) {
368                                 if (bits.length < 2) {
369                                         return ret;
370                                 }
371                                 return ret.fetchByFqn(fqn.substring(bits[0].length+1));
372                         }
373
374                         ret = this.signals.get(bits[0]);                        
375                         if (ret != null) {
376                                 if (bits.length < 2) {
377                                         return ret;
378                                 }
379                                 return ret.fetchByFqn(fqn.substring(bits[0].length+1));
380                         }
381                         if (this.paramset == null) {
382                                 return null;
383                         }
384                         var iter = this.paramset.params.list_iterator();
385                         while (iter.next()) {
386                                 var p = iter.get();
387                                 if (p.name != bits[0]) {
388                                         continue;
389                                 }
390                                 return p;
391                         }
392                                  
393                         // fixme - other queires? - enums?
394                         return null;
395                 }
396                 /**
397                  *  -----------------------------------------------
398                  *  code relating to the structure loader ....
399                  * 
400                  */
401                  
402                 public GirObject clsToObject(string in_pn)
403                 {
404                         var pn = in_pn;
405                         /*
406                         
407                         
408                         var gir = Gir.factory (this.ns);
409                         if (in_pn.contains(".")) {
410                                 gir =  Gir.factory(in_pn.split(".")[0]);
411                                 pn = in_pn.split(".")[1];
412                         }
413                         */
414                         
415                         var gir = Gir.factory (this.ns);
416                         if (in_pn.contains(".")) {
417                                 gir =  Gir.factory(in_pn.split(".")[0]);
418                                 pn = in_pn.split(".")[1];
419                         }
420                         
421                         
422                         return gir.classes.get(pn);
423
424                         
425                 }
426                 public string fqtype() {
427                         return Gir.fqtypeLookup(this.type, this.ns);
428                         
429                         /* return Gir.fqtypeLookup(this.type, this.ns); */
430                 }
431         }
432             
433 }