74a34a5374a9d88a3a6cc3d8c406f5c61d93ea24
[roobuilder] / src / Palete / VapiParser.vala
1
2
3  // valac -g  --pkg libvala-0.26  --pkg gee-1.0 --pkg json-glib-1.0  --pkg gtk+-3.0   VapiParser.vala Gir.vala GirObject.vala -o /tmp/vdoc
4
5 namespace Palete {
6          
7          public errordomain VapiParserError {
8                 PARSE_FAILED 
9         }
10          
11  
12         public class VapiParser : Vala.CodeVisitor {
13                 
14                 Vala.CodeContext context;
15                  
16                 Project.Gtk project;
17                 
18                 public VapiParser(Project.Gtk project) {
19                         base();
20                         this.project = project;
21                         // should not really happen..
22                         if (project.gir_cache == null) {
23                                 project.gir_cache =       new Gee.HashMap<string,Gir>();
24                         }
25                 }
26                  
27                 
28                 public override void visit_namespace (Vala.Namespace element) 
29                 {
30                         if (element == null) {
31                                 
32                                 return;
33                         }
34                          
35                         
36                         //print("parsing namespace %s\n", element.name);
37                         if (element.name == null) {
38                                 element.accept_children(this); // catch sub namespaces..
39                                 return;
40                         }
41                         this.add_namespace(null, element);
42                 }
43                 public void add_namespace(GirObject? parent, Vala.Namespace element)
44                 {
45                         
46                         
47                         var g = new GirObject("Package",element.name) ;
48                         if (parent == null) {
49                                 this.project.gir_cache.set(element.name, (Gir)g);
50                         } else {
51                                 // we add it as a class of the package.. even though its a namespace..
52                                 parent.classes.set(element.name, g);
53                         }
54                         
55                         
56                         foreach(var c in element.get_classes()) {
57                                 this.add_class(g, c);
58                         }
59                         foreach(var c in element.get_enums()) {
60                                 this.add_enum(g, c);
61                         }
62                         foreach(var c in element.get_interfaces()) {
63                                 this.add_interface(g, c);
64                         }
65                         foreach(var c in element.get_namespaces()) {
66                                 this.add_namespace(g, c);
67                         }
68                         foreach(var c in element.get_methods()) {
69                                 this.add_method(g, c);
70                         }
71                         element.accept_children(this); // catch sub namespaces..
72                         
73                         
74                 }
75                  
76                 
77                 public void add_enum(GirObject parent, Vala.Enum cls)
78                 {
79                 
80                         var c = new GirObject("Enum",   cls.name);
81                         parent.consts.set(cls.name, c);
82                         c.ns = parent.name;
83                         
84                         c.gparent = parent;
85                         
86                         foreach(var e in cls.get_values()) {
87                                 var em = new GirObject("EnumMember",e.name);
88                                 em.gparent = c;
89                                 em.ns = c.ns;
90                                 
91 #if VALA_0_56
92                                 em.type  = e.type_reference == null ||  e.type_reference.type_symbol == null ? "" : e.type_reference.type_symbol.get_full_name();                       
93 #elif VALA_0_36
94                                 em.type  = e.type_reference == null ||  e.type_reference.data_type == null ? "" : e.type_reference.data_type.get_full_name();
95 #endif                          
96                                 
97                                 
98                                 // unlikely to get value..
99                                 //c.value = element->get_prop("value");
100                                 c.consts.set(e.name,em);
101                         }
102                         
103                          
104                 }
105                 
106                 public void add_interface(GirObject parent, Vala.Interface cls)
107                 {
108                 
109                         var c = new GirObject("Interface", parent.name + "." + cls.name);
110                         parent.classes.set(cls.name, c);
111                         c.ns = parent.name;
112                         //c.parent = cls.base_class == null ? "" : cls.base_class.get_full_name() ;  // extends...
113                         c.gparent = parent;
114                         
115                         foreach(var p in cls.get_properties()) {
116                                 this.add_property(c, p);
117                         }
118                         // methods...
119                         foreach(var p in cls.get_signals()) {
120                                 this.add_signal(c, p);
121                         }
122                         
123                         foreach(var p in cls.get_methods()) {
124                                 // skip static methods..
125                                 if (p.binding != Vala.MemberBinding.INSTANCE &&
126                                         !(p is Vala.CreationMethod)
127                                 ) {
128                                         continue;
129                                 }
130                                 
131                                 this.add_method(c, p);
132                         }
133                         
134                         //if (cls.base_class != null) {
135                         //      c.inherits.add(cls.base_class.get_full_name());
136                         //}
137                         //foreach(var p in cls.get_base_types()) {
138                         //      if (p.data_type != null) {
139                         //              c.implements.add(p.data_type.get_full_name());
140                         //      }
141                         //}
142                           
143                         
144                         
145                          
146                 }
147                 
148                 public void add_class(GirObject parent, Vala.Class cls)
149                 {
150                 
151                         var c = new GirObject("Class", parent.name + "." + cls.name);
152                         parent.classes.set(cls.name, c);
153                         c.ns = parent.name;
154                         c.parent = cls.base_class == null ? "" : cls.base_class.get_full_name() ;  // extends...
155                         c.gparent = parent;
156                         
157                         foreach(var p in cls.get_properties()) {
158                                 this.add_property(c, p);
159                         }
160                         // methods...
161                         foreach(var p in cls.get_signals()) {
162                                 this.add_signal(c, p);
163                         }
164                         
165                         foreach(var p in cls.get_methods()) {
166                                 // skip static methods..
167                                 if (p.binding != Vala.MemberBinding.INSTANCE &&
168                                         !(p is Vala.CreationMethod)
169                                 ) {
170                                         continue;
171                                 }
172                                 
173                                 this.add_method(c, p);
174                         }
175                         
176                         if (cls.base_class != null) {
177                                 c.inherits.add(cls.base_class.get_full_name());
178                         }
179                         foreach(var p in cls.get_base_types()) {
180 #if VALA_0_56
181                                 if (p.type_symbol != null) {
182                                         c.implements.add(p.type_symbol.get_full_name());
183                                 }
184 #elif VALA_0_36
185                                 if (p.data_type != null) {
186                                         c.implements.add(p.data_type.get_full_name());
187                                 }
188
189 #endif                          
190                                  
191                         }
192                           
193                         
194                         
195                          
196                 }
197                 public void add_property(GirObject parent, Vala.Property prop)
198                 {
199                         var c = new GirObject("Prop",prop.name);
200                         c.gparent = parent;
201                         c.ns = parent.ns;
202                         c.propertyof = parent.name;
203 #if VALA_0_56
204                         c.type  = prop.property_type.type_symbol == null ? "" : prop.property_type.type_symbol.get_full_name();
205 #elif VALA_0_36
206                         c.type  = prop.property_type.data_type == null ? "" : prop.property_type.data_type.get_full_name();             
207 #endif
208                         parent.props.set(prop.name,c);
209
210                         
211                 }
212                 public void add_signal(GirObject parent, Vala.Signal sig)
213                 {
214                         var c = new GirObject("Signal",sig.name);
215                         c.gparent = parent;
216                         c.ns = parent.ns;
217
218 #if VALA_0_56
219                         var dt  = sig.return_type.type_symbol  ;
220 #elif VALA_0_36
221                         var dt  = sig.return_type.data_type;
222 #endif                  
223                          
224                         
225                         if (dt != null) {
226                                 //print("creating return type on signal %s\n", sig.name);
227                                 var cc = new GirObject("Return", "return-value");
228                                 cc.gparent = c;
229                                 cc.ns = c.ns;
230                                 cc.type  =  dt.get_full_name();
231                                 c.return_value = cc;
232                         }
233                         parent.signals.set(sig.name,c);
234                         
235                         var params =  sig.get_parameters() ;
236                         if (params.size < 1) {
237                                 return;
238                         }
239                         var cc = new GirObject("Paramset",sig.name); // what's the name on this?
240                         cc.gparent = c;
241                         cc.ns = c.ns;
242                         c.paramset = cc;
243                         
244                         
245                         foreach(var p in params) {
246                                 this.add_param(cc, p);
247                         }
248                         
249                 }       
250                 
251                 public void add_method(GirObject parent, Vala.Method met)
252                 {
253                         var n = met.name == null ? "" : met.name;
254                         var ty  = "Method";
255                         if (met is Vala.CreationMethod) {
256                                 ty = "Ctor";
257                                 if(n == "" || n == ".new") {
258                                         n = "new";
259                                 }
260                                 
261                         }
262                         //print("add_method :  %s\n", n);
263                         
264                         var c = new GirObject(ty,n);
265                         c.gparent = parent;
266                         c.ns = parent.ns;
267 #if VALA_0_56                                           
268                         if (met.return_type.type_symbol != null) {
269 #elif VALA_0_36
270                         if (met.return_type.data_type != null) {
271 #endif  
272                         
273                         
274                                 //print("creating return type on method %s\n", met.name);
275                                 var cc = new GirObject("Return", "return-value");
276                                 cc.gparent = c;
277                                 cc.ns = c.ns;
278
279 #if VALA_0_56                   
280                                 cc.type  =  met.return_type.type_symbol.get_full_name();
281 #elif VALA_0_36
282                                 cc.type  =  met.return_type.data_type.get_full_name();
283 #endif  
284                                 
285                                 
286                                 
287                                 c.return_value = cc;
288                         }
289                         if (met is Vala.CreationMethod) {
290                                 parent.ctors.set(c.name,c);
291                         } else {
292                                 parent.methods.set(met.name,c);
293                         }
294                         
295                         var params =  met.get_parameters() ;
296                         if (params.size < 1) {
297                                 return;
298                         }
299                         var cc = new GirObject("Paramset",met.name); // what's the name on this?
300                         cc.gparent = c;
301                         cc.ns = c.ns;
302                         c.paramset = cc;
303                         c.sig = "(";
304                         
305                         foreach(var p in params) {
306                                 if (p.name == null && !p.ellipsis) {
307                                         continue;
308                                 }
309                                 var pp = this.add_param(cc, p);
310                                 c.sig += (c.sig == "(" ? "" : ",");
311                                 c.sig += " " + (pp.direction == "in" ? "" : pp.direction) + " " + pp.type + " " + pp.name;
312                         }
313                         c.sig += (c.sig == "(" ? ")" : " )");
314                         
315                 }
316                 
317                 public GirObject add_param(GirObject parent, Vala.Parameter pam)
318                 {
319                         
320                         var n = pam.name;
321                         if (pam.ellipsis) {
322                                 n = "___";
323                         }
324                         var c = new GirObject("Param",n);
325                         c.gparent = parent;
326                         c.ns = parent.ns;
327                         c.direction = "??";
328                         switch (pam.direction) {
329                                 case Vala.ParameterDirection.IN:
330                                         c.direction = "in";
331                                         break;
332                                 case Vala.ParameterDirection.OUT:
333                                         c.direction = "out";
334                                         break;
335                                 case Vala.ParameterDirection.REF:
336                                         c.direction = "ref";
337                                         break;
338                         }
339                         
340                         parent.params.add(c);
341                         
342                         if (!pam.ellipsis) {
343 #if VALA_0_56                   
344                                 c.type = pam.variable_type.type_symbol == null ? "" : pam.variable_type.type_symbol.get_full_name();
345 #elif VALA_0_36
346                                 c.type = pam.variable_type.data_type == null ? "" : pam.variable_type.data_type.get_full_name();
347 #endif                          
348                         }
349                         Gir.checkParamOverride(c); 
350                         return c;
351                         
352                 }
353                 
354                 public void create_valac_tree( )
355                 {
356                         // init context:
357                         context = new Vala.CodeContext ();
358                         Vala.CodeContext.push (context);
359                 
360                         context.experimental = false;
361                         context.experimental_non_null = false;
362 #if VALA_0_56
363                         var ver=56;
364 #elif VALA_0_36
365                         var ver=36;
366 #endif
367                         
368                         for (int i = 2; i <= ver; i += 2) {
369                                 context.add_define ("VALA_0_%d".printf (i));
370                         }
371                         
372                          
373                         //var vapidirs = ((Project.Gtk)this.file.project).vapidirs();
374                         // what's the current version of vala???
375                         
376                         
377                         //vapidirs +=  Path.get_dirname (context.get_vapi_path("glib-2.0")) ;
378                          
379                         var vapidirs = context.vapi_directories;
380                         
381                         vapidirs += (BuilderApplication.configDirectory() + "/resources/vapi");
382                         vapidirs += "/usr/share/vala-0.%d/vapi".printf(ver);
383                         context.vapi_directories = vapidirs;
384                         
385                         // or context.get_vapi_path("glib-2.0"); // should return path..
386                         //context.vapi_directories = vapidirs;
387                         context.report.enable_warnings = true;
388                         context.metadata_directories = { };
389                         context.gir_directories = {};
390                         //context.thread = true; 
391                         
392                         
393                         //this.report = new ValaSourceReport(this.file);
394                         //context.report = this.report;
395                         
396                         
397                         context.basedir = "/tmp"; //Posix.realpath (".");
398                 
399                         context.directory = context.basedir;
400                 
401
402                         // add default packages:
403                         //if (settings.profile == "gobject-2.0" || settings.profile == "gobject" || settings.profile == null) {
404 #if VALA_0_56
405                         context.set_target_profile (Vala.Profile.GOBJECT);
406 #elif VALA_0_36
407                         context.profile = Vala.Profile.GOBJECT;
408 #endif
409                          
410                         var ns_ref = new Vala.UsingDirective (new Vala.UnresolvedSymbol (null, "GLib", null));
411                         context.root.add_using_directive (ns_ref);
412                         
413                         
414                         context.add_external_package ("glib-2.0"); 
415                         context.add_external_package ("gobject-2.0");
416                         // user defined ones..
417                         
418                 var dcg = this.project.compilegroups.get("_default_");
419                 for (var i = 0; i < dcg.packages.size; i++) {
420                 
421                         var pkg = dcg.packages.get(i);
422                         // do not add libvala versions except the one that matches the one we are compiled against..
423                         if (Regex.match_simple("^libvala", pkg) && pkg != ("libvala-0." + ver.to_string())) {
424                                 continue;
425                         }
426                                 //valac += " --pkg " + dcg.packages.get(i);
427                                  if (!this.has_vapi(context.vapi_directories, dcg.packages.get(i))) {
428                                  
429                                         continue;
430                                 }
431                                 GLib.debug("ADD vapi '%s'", dcg.packages.get(i));
432                                 context.add_external_package (dcg.packages.get(i));
433                         }                       
434                         
435                         
436                         
437                          
438                         // core packages we are interested in for the builder..
439                         // some of these may fail... - we probalby need a better way to handle this..
440                         /*
441                         context.add_external_package ("gtk+-3.0");
442                         context.add_external_package ("libsoup-2.4");
443                         if (!context.add_external_package ("webkit2gtk-4.0")) {
444                                 context.add_external_package ("webkit2gtk-3.0");
445                         }
446                         // these are supposed to be in the 'deps' file, but it's not getting read..
447                         context.add_external_package ("cogl-1.0");
448                         context.add_external_package ("json-glib-1.0");
449                         context.add_external_package ("clutter-gtk-1.0");
450
451
452                     
453                         context.add_external_package ("gdl-3.0");
454                         context.add_external_package ("gtksourceview-3.0");
455                         context.add_external_package ("vte-2.90"); //??? -- hopefullly that works..
456                         */
457                         //add_documented_files (context, settings.source_files);
458                 
459                         Vala.Parser parser = new Vala.Parser ();
460                         parser.parse (context);
461                         //gir_parser.parse (context);
462                         if (context.report.get_errors () > 0) {
463                                 
464                                 //throw new VapiParserError.PARSE_FAILED("failed parse VAPIS, so we can not write file correctly");
465                                 
466                                 print("parse got errors");
467                                  
468                                 
469                                 Vala.CodeContext.pop ();
470                                 return ;
471                         }
472
473
474                         
475                         // check context:
476                         context.check ();
477                         if (context.report.get_errors () > 0) {
478                                 GLib.error("failed check VAPIS, so we can not write file correctly");
479                                 // throw new VapiParserError.PARSE_FAILED("failed check VAPIS, so we can not write file correctly");
480                                 Vala.CodeContext.pop ();
481                                  
482                                 return;
483                                 
484                         }
485                          
486                         
487                          
488                         context.accept(this);
489                         
490                         context = null;
491                         // dump the tree for Gtk?
492                         
493                         Vala.CodeContext.pop ();
494                         
495                         print("ALL OK?\n");
496                  
497                 }
498         //
499                 // startpoint:
500                 //
501          public bool has_vapi(string[] dirs,  string vapi) 
502                 {
503                         for(var i =0 ; i < dirs.length; i++) {
504                                 GLib.debug("check VAPI - %s", dirs[i] + "/" + vapi + ".vapi");
505                                 if (!FileUtils.test( dirs[i] + "/" + vapi + ".vapi", FileTest.EXISTS)) {
506                                         continue;
507                                 }   
508                                 return true;
509                         }
510                         return false;
511                         
512                 }
513         }
514 }
515  /*
516 int main (string[] args) {
517         
518         var g = Palete.Gir.factoryFqn("Gtk.SourceView");
519         print("%s\n", g.asJSONString());
520         
521         return 0;
522 }
523  
524
525 */