src/Palete/ValaSource.vala
[app.Builder.js] / src / Palete / ValaSource.vala
1
2 // valac TreeBuilder.vala --pkg libvala-0.24 --pkg posix -o /tmp/treebuilder
3
4 namespace Palete {
5         
6         public class ValaSourceNotice  : Object {
7                 public string file;
8                 public int line;
9                 public string message;
10                 public string type;
11                 public ValaSourceNotice( string t, string f, int l, string m) {
12                         this.file =f ;
13                         this.line =l;
14                         this.type =t;
15                         this.message = m;
16                 }
17         }
18         
19         public class ValaSourceReport  : Vala.Report {
20
21
22                 
23                 public Gee.HashMap<int,string> line_warnings;
24                 public Gee.HashMap<int,string> line_depr;
25                 public Gee.HashMap<int,string> line_errors;
26
27                 public ValaSourceReport()
28                 {
29                         base();
30                         this.line_errors = new Gee.HashMap<int,string> ();
31                         this.line_depr = new Gee.HashMap<int,string> ();
32                         this.line_warnings = new Gee.HashMap<int,string> ();
33                 }
34                 
35                 public override void warn (Vala.SourceReference? source, string message) {
36                          
37                         if (source == null) {
38                                 return;
39                                 //stderr.printf ("My error: %s\n", message);
40                         }
41                         if (source.file.filename != "~~~~~testfile.vala") {
42                                 print ("Warning: %d:  %s\n", source.begin.line, message);
43                                 return;
44                         }
45                         var pre = "";
46                         if (line_warnings.has_key(source.begin.line)) {
47                                 pre = line_warnings.get(source.begin.line) + "\n";
48                                 
49                         }
50                         line_warnings.set(source.begin.line, pre +  "Warn: " + message);
51                         print ("Test file: Got error WARN: %d: %s\n", source.begin.line, message);
52                 }
53                 public override void depr (Vala.SourceReference? source, string message) {
54                          
55                         if (source == null) {
56                                 return;
57                                 //stderr.printf ("My error: %s\n", message);
58                         }
59                         if (source.file.filename != "~~~~~testfile.vala") {
60                                 print ("Depr: %d:  %s\n", source.begin.line, message);
61                                 return;
62                         }
63                         var pre = "";
64                         if (line_depr.has_key(source.begin.line)) {
65                                 pre = line_depr.get(source.begin.line) + "\n";
66                                 
67                         }
68                         line_depr.set(source.begin.line, pre +  "Warn: " + message);
69                         print ("Test file: Got error DEPR: %d: %s\n", source.begin.line, message);
70                 }
71                 
72                 public override void err (Vala.SourceReference? source, string message) {
73                         errors++;
74                         if (source == null) {
75                                 return;
76                                 //stderr.printf ("My error: %s\n", message);
77                         }
78                         if (source.file.filename != "~~~~~testfile.vala") {
79                                 print ("Other file: Got error error: %d:  %s\n", source.begin.line, message);
80                                 return;
81                         }
82                         var pre = "";
83                         if (line_errors.has_key(source.begin.line)) {
84                                 pre = line_errors.get(source.begin.line) + "\n";
85                                 
86                         }
87                         line_errors.set(source.begin.line, pre +  message);
88                         print ("Test file: Got error error: %d: %s\n", source.begin.line, message);
89                 }
90                 public void dump()
91                 {
92                         var iter = this.line_errors.map_iterator();
93                         while (iter.next()) {
94                                 print ("%d : %s\n\n", iter.get_key(), iter.get_value());
95                         }
96                 }
97
98         }
99
100         public class ValaSource : Vala.CodeVisitor {
101
102                 Vala.CodeContext context;
103                 ValaSourceReport report;
104                 JsRender.JsRender file; 
105                 public ValaSource(JsRender.JsRender file) {
106                         base();
107                         this.file = file;
108                         
109
110                 }
111                 public void dumpCode(string str) {
112                         var ls = str.split("\n");
113                         for (var i=0;i < ls.length; i++) {
114                                 print("%d : %s\n", i+1, ls[i]);
115                         }
116                 }
117                 
118                 public Gee.HashMap<int,string> checkFile()
119                 {
120                         return this.checkString(JsRender.NodeToVala.mungeFile(this.file));
121                 }
122
123                 public async Gee.HashMap<int,string> checkFileWithNodePropChange(
124                                         JsRender.Node node, 
125                                         string prop,
126                                         string ptype,
127                                         string val)
128                 {
129                         Gee.HashMap<int,string> ret = new Gee.HashMap<int,string> ();
130                         var hash = ptype == "listener" ? node.listeners : node.props;
131                         
132                         // untill we get a smarter renderer..
133                         // we have some scenarios where changing the value does not work
134                         if (prop == "* xns" || prop == "xtype") {
135                                 return ret;
136                         }
137                                 
138                         
139                         var old = hash.get(prop);
140                         var newval = "/*--VALACHECK-START--*/ " + val ;
141                         
142                         hash.set(prop, newval);
143                         var tmpstring = JsRender.NodeToVala.mungeFile(this.file);
144                         var bits = tmpstring.split("/*--VALACHECK-START--*/");
145                         var offset =0;
146                         if (bits.length > 0) {
147                                 offset = bits[0].split("\n").length +1;
148                         }
149                         //this.dumpCode(tmpstring);
150                         //print("offset %d\n", offset);
151                         yield this.checkStringThread(tmpstring);
152                         hash.set(prop, old);
153                         // modify report
154                         
155                         var iter = this.report.line_errors.map_iterator();
156                         while (iter.next()) {
157                                 // print("%d : %s\n",iter.get_key() - offset, iter.get_value());
158                                 // we have to prefix the error with the fake line number 
159                                 // so that it's a unique mark..
160                                  ret.set(iter.get_key() - offset, 
161                                        "%d : %s".printf(iter.get_key() - offset,iter.get_value()));
162                         }
163                         return ret;
164                         
165                 }
166                 
167                 public async  Gee.HashMap<int,string> checkStringThread(string contents)
168                 {
169                         SourceFunc callback = checkStringThread.callback;
170                         var ret = new Gee.HashMap<int,string>();
171                         ThreadFunc<void*> run = () => {
172                                  
173                                 // Pass back result and schedule callback
174                                 ret = this.checkString(contents);
175                                 Idle.add((owned) callback);
176                                 return null;
177                         };
178                         Thread.create<void*>(run, false);
179
180                         // Wait for background thread to schedule our callback
181                         yield;
182                         return ret;
183                 }
184                 
185                 
186                 
187                 public Gee.HashMap<int,string> checkString(string contents)
188                 {
189                         // init context:
190                         var valac = "valac " ;
191                         
192                         context = new Vala.CodeContext ();
193                         Vala.CodeContext.push (context);
194                 
195                         context.experimental = false;
196                         context.experimental_non_null = false;
197                         
198 #if VALA_0_28
199                         var ver=28;
200 #elif VALA_0_26 
201                         var ver=26;
202 #elif VALA_0_24
203                         var ver=24;
204 #elif VALA_0_22 
205                         var ver=22;
206 #endif
207                         
208                         for (int i = 2; i <= ver; i += 2) {
209                                 context.add_define ("VALA_0_%d".printf (i));
210                         }
211                         
212                         
213                         
214                         
215                         
216                         
217                         
218                         var vapidirs = ((Project.Gtk)this.file.project).vapidirs();
219                         // what's the current version of vala???
220                         
221                         
222                         vapidirs +=  Path.get_dirname (context.get_vapi_path("glib-2.0")) ;
223                         
224                         for(var i =0 ; i < vapidirs.length; i++) {
225                                 valac += " --vapidir=" + vapidirs[i];
226                         }
227                                 
228                         
229                         // or context.get_vapi_path("glib-2.0"); // should return path..
230                         context.vapi_directories = vapidirs;
231                         context.report.enable_warnings = true;
232                         context.metadata_directories = { };
233                         context.gir_directories = {};
234                         context.thread = true;
235                         
236                         
237                         this.report = new ValaSourceReport();;
238                         context.report = this.report;
239                         
240                         
241                         context.basedir = "/tmp"; //Posix.realpath (".");
242                 
243                         context.directory = context.basedir;
244                 
245
246                         // add default packages:
247                         //if (settings.profile == "gobject-2.0" || settings.profile == "gobject" || settings.profile == null) {
248                         context.profile = Vala.Profile.GOBJECT;
249                          
250                         var ns_ref = new Vala.UsingDirective (new Vala.UnresolvedSymbol (null, "GLib", null));
251                         context.root.add_using_directive (ns_ref);
252
253                         var source_file = new Vala.SourceFile (
254                                 context, 
255                                 Vala.SourceFileType.SOURCE, 
256                                         "~~~~~testfile.vala",
257                                         contents
258                         );
259                         source_file.add_using_directive (ns_ref);
260                         context.add_source_file (source_file);
261                         
262                 // add all the files (except the current one) - this.file.path
263                 var pr = ((Project.Gtk)this.file.project);
264                 if (this.file.build_module.length > 0) {
265                                 var cg =  pr.compilegroups.get(this.file.build_module);
266                                 for (var i = 0; i < cg.sources.size; i++) {
267                                         var path = pr.resolve_path(
268                                 pr.resolve_path_combine_path(pr.firstPath(),cg.sources.get(i)));
269                                 
270                         if (!FileUtils.test(path, FileTest.EXISTS)) {
271                                                 continue;
272                                         }       
273                          
274                                         if (path == this.file.path.replace(".bjs", ".vala")) {
275                                                 valac += " " + path;
276                                                 continue;
277                                         }
278                                         if (FileUtils.test(path, FileTest.IS_DIR)) {
279                                                 continue;
280                                         }
281                                         //print("Add source file %s\n", path);
282                                         
283                                         valac += " " + path;
284                                         
285                                         if (Regex.match_simple("\\.c$", path)) {
286                                                 context.add_c_source_file(path);
287                                                 continue;
288                                         }
289                                         
290                                         
291                                         var xsf = new Vala.SourceFile (
292                                                 context,
293                                                 Vala.SourceFileType.SOURCE, 
294                                                 path
295                                         );
296                                         xsf.add_using_directive (ns_ref);
297                                         context.add_source_file(xsf);
298                                         
299                                 }
300                         }
301                         // default.. packages..
302                         context.add_external_package ("glib-2.0"); 
303                         context.add_external_package ("gobject-2.0");
304                         // user defined ones..
305                         
306                 var dcg = pr.compilegroups.get("_default_");
307                 for (var i = 0; i < dcg.packages.size; i++) {
308                                 valac += " --pkg " + dcg.packages.get(i);
309                                 context.add_external_package (dcg.packages.get(i));
310                         }
311                 
312                          //Vala.Config.PACKAGE_SUFFIX.substring (1)
313                         
314                         // add the modules...
315                         
316                         
317                         
318                         //context.add_external_package ("libvala-0.24");
319                         
320                         
321
322                 
323                         //add_documented_files (context, settings.source_files);
324                 
325                         Vala.Parser parser = new Vala.Parser ();
326                         parser.parse (context);
327                         //gir_parser.parse (context);
328                         if (context.report.get_errors () > 0) {
329                                 print("parse got errors");
330                                 ((ValaSourceReport)context.report).dump();
331                                 Vala.CodeContext.pop ();
332                                 return this.report.line_errors;
333                         }
334
335
336                         
337                         // check context:
338                         context.check ();
339                         if (context.report.get_errors () > 0) {
340                                 print("check got errors");
341                                 ((ValaSourceReport)context.report).dump();
342                                 Vala.CodeContext.pop ();
343                                 return this.report.line_errors;
344                                 
345                         }
346                         
347                         context.codegen = new Vala.GDBusServerModule ();
348                         
349                          
350                         context.output = "/tmp/testbuild";
351                         valac += " -o " +context.output;
352                         context.codegen.emit (context);
353                          
354                         var ccompiler = new Vala.CCodeCompiler ();
355                         var cc_command = Environment.get_variable ("CC");
356                         var pkg_config_command = Environment.get_variable ("PKG_CONFIG");
357 #if VALA_0_28
358                         ccompiler.compile (context, cc_command, new string[] { }, pkg_config_command);
359 #else
360                         ccompiler.compile (context, cc_command, new string[] { });
361 #endif
362
363  
364                         Vala.CodeContext.pop ();
365                         print("%s\n", valac);
366                         print("ALL OK?\n");
367                         return this.report.line_errors;
368                 }
369         //
370                 // startpoint:
371                 //
372          
373         }
374 }
375 /*
376 int main (string[] args) {
377
378         var a = new ValaSource(file);
379         a.create_valac_tree();
380         return 0;
381 }
382 */
383
384