Merge branch 'master' of http://git.roojs.com/roobuilder
[roobuilder] / src / Palete / ValaSource.vala
1
2 // valac TreeBuilder.vala --pkg libvala-0.24 --pkg posix -o /tmp/treebuilder
3
4 /**
5  * 
6  *  This just deals with spawning the compiler and getting the results.
7  * 
8  *  each window should have one of these...
9  * 
10  *  x = new ValaSource();
11  *  x.connect.compiled(... do something with results... );
12  *  
13  * x.
14  * 
15  */
16
17 namespace Palete {
18         
19         public errordomain ValaSourceError {
20                 INVALID_FORMAT 
21         }
22         
23         //public delegate  void ValaSourceResult(Json.Object res);
24         
25          
26
27         public class ValaSource : Object {
28  
29                 
30                 public signal void compiled(Json.Object res);
31                 public signal void compile_output(string str);
32                 public Xcls_MainWindow window;
33                 
34                 JsRender.JsRender file;
35                 public int line_offset = 0;
36                 
37                 public Gee.ArrayList<Spawn> children;
38                 public ValaSource( Xcls_MainWindow window ) 
39                 {
40                         base();
41                         this.window  = window;
42                         this.compiler = null;
43                         this.children = new Gee.ArrayList<Spawn>();
44                         
45                 }
46                 public void dumpCode(string str) 
47                 {
48                         var ls = str.split("\n");
49                         for (var i=0;i < ls.length; i++) {
50                                 print("%d : %s\n", i+1, ls[i]);
51                         }
52                 }
53                 
54                 //public Gee.HashMap<int,string> checkFile()
55                 //{
56                 //      return this.checkString(JsRender.NodeToVala.mungeFile(this.file));
57                 //}
58
59                 public bool checkFileWithNodePropChange(
60                   
61                                         JsRender.JsRender file,
62                                         JsRender.Node node, 
63                                         string prop,
64                                         string ptype,
65                                         string val
66                                  )
67                 {
68                         this.file = file;
69                         
70                         if (this.compiler != null) {
71                                 return false;
72                         }
73                         
74                          
75                         var hash = ptype == "listener" ? node.listeners : node.props;
76                         
77                         // untill we get a smarter renderer..
78                         // we have some scenarios where changing the value does not work
79                         if (prop == "* xns" || prop == "xtype") {
80                                 return  false;
81                         }
82                                 
83                         
84                         var old = hash.get(prop);
85                         var newval = "/*--VALACHECK-START--*/ " + val ;
86                         
87                         hash.set(prop, newval);
88                         var tmpstring = JsRender.NodeToVala.mungeFile(file);
89                         hash.set(prop, old);
90                         //print("%s\n", tmpstring);
91                         var bits = tmpstring.split("/*--VALACHECK-START--*/");
92                         var offset =0;
93                         if (bits.length > 0) {
94                                 offset = bits[0].split("\n").length +1;
95                         }
96                         
97                         this.line_offset = offset;
98                         
99                         //this.dumpCode(tmpstring);
100                         //print("offset %d\n", offset);
101                         return this.checkStringSpawn(tmpstring );
102                         
103                         // modify report
104                         
105                         
106                         
107                 }
108                 Spawn compiler;
109                  
110                 public bool checkStringSpawn(
111                                 string contents 
112                         )
113                 {
114                         
115                         if (this.compiler != null) {
116                                 return false;
117                         }
118                         
119                         FileIOStream iostream;
120                         var tmpfile = File.new_tmp ("test-XXXXXX.vala", out iostream);
121                         tmpfile.ref();
122
123                         OutputStream ostream = iostream.output_stream;
124                         DataOutputStream dostream = new DataOutputStream (ostream);
125                         dostream.put_string (contents);
126                         
127                         var valafn = "";
128                         try {             
129                            var  regex = new Regex("\\.bjs$");
130                         
131                                 valafn = regex.replace(this.file.path,this.file.path.length , 0 , ".vala");
132                          } catch (GLib.RegexError e) {
133                                  
134                             return false;
135                         }   
136                         
137                         string[] args = {};
138                         args += BuilderApplication._self;
139                         args += "--project";
140                         args += this.file.project.fn;
141                         args += "--target";
142                         args += this.file.build_module;
143                         args += "--add-file";
144                         args +=  tmpfile.get_path();
145                         args += "--skip-file";
146                         args += valafn;
147                         
148                          
149                         
150                         this.compiler = new Spawn("/tmp", args);
151                         this.compiler.complete.connect(spawnResult);
152                         this.window.statusbar_compile_spinner.start();
153                         try {
154                                 this.compiler.run(); 
155                         } catch (GLib.SpawnError e) {
156                                 GLib.debug(e.message);
157                                 this.window.statusbar_compile_spinner.stop();
158                                 this.compiler = null;
159                                 return false;
160
161                         }
162                         return true;
163                          
164                 }
165                 
166                 public bool checkFileSpawn(JsRender.JsRender file )
167                 {
168                         // race condition..
169                         if (this.compiler != null) { 
170                                 return false;
171                         }
172                         
173                         this.file = file;
174                         this.line_offset = 0;
175                           
176                         string[] args = {};
177                         args += BuilderApplication._self;
178                         args += "--project";
179                         args += this.file.project.fn;
180                         args += "--target";
181                         args += this.file.build_module;
182                          
183                          
184                         
185                         
186                         try {
187                             this.compiler = new Spawn("/tmp", args);
188                             this.compiler.complete.connect(spawnResult);
189                                 this.window.statusbar_compile_spinner.start();
190                             this.compiler.run(); 
191                         
192                          
193                         } catch (GLib.Error e) {
194                             GLib.debug(e.message);
195                             this.window.statusbar_compile_spinner.stop();
196                             this.compiler = null;
197                             return false;
198                         }
199                         return true;
200                          
201                 }
202                 
203  
204
205                 
206                 
207                 public void spawnExecute(JsRender.JsRender file)
208                 {
209                         // race condition..
210                         if (this.compiler != null) { 
211                                 return;
212                         }
213                         if (!(file.project is Project.Gtk)) {
214                             return;
215                         }
216                         var pr = (Project.Gtk)(file.project);
217                         
218                         
219                         this.file = file;
220                         this.line_offset = 0;
221                           
222                         string[] args = {};
223                         args += BuilderApplication._self;
224                         args += "--project";
225                         args += this.file.project.fn;
226                         args += "--target";
227                         if (this.file.build_module.length > 0 ) {
228                             args += this.file.build_module;
229                         } else {
230                             args += pr.firstBuildModule();
231                         }
232                         //args += "--output"; -- set up by the module -- defaults to testrun
233                         //args += "/tmp/testrun";
234                         
235                         // assume code is in home...
236                         try {
237                             this.compiler = new Spawn( GLib.Environment.get_home_dir(), args);
238                             this.compiler.output_line.connect(compile_output_line);
239                             this.compiler.complete.connect(runResult);
240                             this.window.statusbar_compile_spinner.start();
241                             this.compiler.run(); 
242                                 this.children.add(this.compiler); //keep a reference...
243                          
244                         } catch (GLib.Error e) {
245                                 this.window.statusbar_compile_spinner.stop();
246                             GLib.debug(e.message);
247                             this.compiler = null;
248
249                         }
250                         return;
251                          
252                 }
253                 public void compile_output_line(   string str )
254                 {
255                         this.compile_output(str);
256                 }
257                 /**
258                 * Used to compile a non builder file..
259                 */
260                  
261                  
262                 public bool checkPlainFileSpawn( JsRender.JsRender file, string contents )
263  
264                 {
265                         // race condition..
266                         if (this.compiler != null) { 
267                                 return false;
268                         }
269             i
270                         var pr = (Project.Gtk)(file.project);
271                         
272                         var m = pr.firstBuildModule();
273                         var cg = pr.compilegroups.get(m);
274
275       if (cg == null) {
276           return false;
277       }
278                         var foundit = false;
279                         
280             if (cg.sources is null) {
281                 return false;
282             }
283             for (var i = 0; i < cg.sources.size; i++) {
284                             var path = pr.resolve_path(
285                                     pr.resolve_path_combine_path(pr.firstPath(),cg.sources.get(i)));
286                             if (path == file.path) {
287                                 foundit = true;
288                                 break;
289                                         }
290                         }
291
292                         if (!foundit) {
293                           
294                             this.compiler = null;
295                         
296                             return false; // do not run the compile..
297                         }
298                         // is the file in the module?
299                         
300                         
301                         FileIOStream iostream;
302                         var tmpfile = File.new_tmp ("test-XXXXXX.vala", out iostream);
303                         tmpfile.ref();
304
305                         OutputStream ostream = iostream.output_stream;
306                         DataOutputStream dostream = new DataOutputStream (ostream);
307                         dostream.put_string (contents);
308                         
309                         var target = pr.firstBuildModule();
310                         if (target.length < 1) {
311                                 return false;
312                         }
313                         
314                         this.file = null;
315                         this.line_offset = 0;
316                           
317                         string[] args = {};
318                         args += BuilderApplication._self;
319                         args += "--project";
320                         args +=  file.project.fn;
321                         args += "--target";
322  
323                         args += pr.firstBuildModule();
324                         args += "--add-file";
325                         args +=  tmpfile.get_path();
326                         args += "--skip-file";
327                         args += file.path;
328                          
329                         
330                         
331                         
332                         try {
333                             this.compiler = new Spawn("/tmp", args);
334                             this.compiler.complete.connect(spawnResult);
335                             this.window.statusbar_compile_spinner.start();
336                             this.compiler.run(); 
337                         } catch (GLib.Error e) {
338                             this.window.statusbar_compile_spinner.stop();
339                             this.compiler = null;
340                             return false;
341                         }
342                         return true;
343                          
344                 }
345                  
346                 
347                 public void spawnResult(int res, string output, string stderr)
348                 {
349                          
350                         this.window.statusbar_compile_spinner.stop();   
351                         try { 
352                                 //GLib.debug("GOT output %s", output);
353                                 
354                                 var pa = new Json.Parser();
355                                 pa.load_from_data(output);
356                                 var node = pa.get_root();
357
358                                 if (node.get_node_type () != Json.NodeType.OBJECT) {
359                                         var ret = new Json.Object();
360                                         ret.set_boolean_member("success", false);
361                                         ret.set_string_member("message", 
362                                                 "Compiler returned Unexpected element type %s".printf( 
363                                                         node.type_name ()
364                                                 )
365                                         );
366                                         this.compiled(ret);
367                                         this.compiler = null;
368                                 }
369                                 var ret = node.get_object ();
370                                 ret.set_int_member("line_offset", this.line_offset);
371                                 
372                                 this.compiled(ret);
373                                 
374                                 
375                         } catch (GLib.Error e) {
376                                 var ret = new Json.Object();
377                                 ret.set_boolean_member("success", false);
378                                 ret.set_string_member("message", e.message);
379                                 this.compiled(ret);
380                         }
381                         this.compiler = null;
382                         //compiler.unref();
383                         //tmpfile.unref();
384                          
385                         
386                         
387                 }
388                 
389                 public void runResult(int res, string output, string stderr)
390                 {
391                         this.compiler = null;
392                         var exe = "/tmp/testrun";
393                         var mod = "";
394                         var pr = (Project.Gtk)(this.file.project);
395                         
396                         
397                         
398                         if (this.file.build_module.length > 0 ) {
399                     mod =  this.file.build_module;
400                         } else {
401                             mod =  pr.firstBuildModule();
402                         }
403                         if (mod.length < 1) {
404                                 return;
405                         }
406                         var cg =  pr.compilegroups.get(mod);
407                         if (cg.target_bin.length > 0) {
408                                 exe = cg.target_bin;
409                         }
410                         
411                         
412                         if (!GLib.FileUtils.test(exe, GLib.FileTest.EXISTS)) {
413                                 print("Missing output file: %s\n",exe);
414                                 return;
415                         }
416                         string[] args = "/usr/bin/gnome-terminal -x /usr/bin/gdb -ex=r --args".split(" ");
417
418                         
419                         // runs gnome-terminal, with gdb .. running the application..
420                         // fixme -- need a system/which
421                         
422                         args += exe;
423                         if (cg.execute_args.length > 0) {
424                                 var aa = cg.execute_args.split(" ");
425                                 for (var i =0; i < aa.length; i++) {
426                                         args += aa[i];
427                                 }
428                         }
429
430                     print("OUT: %s\n\n----\nERR:%s\n", output, stderr);
431                     
432                     // should be home directory...
433                     
434                     
435                     
436             var exec = new Spawn(GLib.Environment.get_home_dir() , args);
437             exec.detach = true;
438                     exec.run(); 
439                         
440                 }
441         }
442                  
443 }
444 /*
445 int main (string[] args) {
446
447         var a = new ValaSource(file);
448         a.create_valac_tree();
449         return 0;
450 }
451 */
452
453